use bevy::prelude::*;
use game_library::{
colors, data_loader::storage::GameData, enums::Skill, font_resource::FontResource,
state::Overlay,
};
pub struct SkillBookUiPlugin;
impl Plugin for SkillBookUiPlugin {
fn build(&self, app: &mut App) {
app.add_systems(OnEnter(Overlay::SkillScreen), spawn_skill_book_ui);
app.add_systems(Update, toggle_skill_screen);
}
}
fn toggle_skill_screen(mut next_overlay: ResMut<NextState<Overlay>>, input: Res<Input<KeyCode>>) {
if input.just_pressed(KeyCode::K) {
next_overlay.set(Overlay::SkillScreen);
}
}
#[derive(Component)]
pub struct SkillBlock(pub Skill);
const SKILL_HEIGHT: f32 = 64.0;
const SKILL_WIDTH: f32 = 420.0;
const ICON_MARGIN: f32 = 10.0;
const BACKGROUND_COLOR: Color = colors::SAND_DUNE;
const TEXT_COLOR: Color = colors::DARKER_THUNDER;
const TITLE_FONT_SIZE: f32 = 32.0;
const GAP: f32 = 4.0;
const BORDER_COLOR: Color = colors::THUNDER;
const SKILL_ICON_BACKGROUND: Color = colors::BRIGHT_GRAY;
const SKILL_ICON_BORDER_WIDTH: f32 = 2.0;
const SKILL_ICON_BORDER: Color = colors::ANZAC;
const LEFT_COLUMN_SKILLS: [Skill; 9] = [
Skill::Pyromancy,
Skill::Fulgomancy,
Skill::Hydromancy,
Skill::Geomancy,
Skill::Aeromancy,
Skill::Cryomancy,
Skill::Trudomancy,
Skill::Photomancy,
Skill::Umbramancy,
];
const RIGHT_COLUMN_SKILLS: [Skill; 9] = [
Skill::Arcanomancy,
Skill::Vitomancy,
Skill::Mortomancy,
Skill::Ampiliomancy,
Skill::Diminiomancy,
Skill::Citomancy,
Skill::Necromancy,
Skill::Mutatiomancy,
Skill::Chronomancy,
];
fn add_skill_to_ui(
font: Handle<Font>,
icon_tileset: Handle<TextureAtlas>,
skill: Skill,
commands: &mut Commands,
) -> Entity {
let skill_box = commands
.spawn(NodeBundle {
style: Style {
width: Val::Px(SKILL_WIDTH),
height: Val::Px(SKILL_HEIGHT),
margin: UiRect::bottom(Val::Px(GAP)),
align_content: AlignContent::Stretch,
border: UiRect::all(Val::Px(SKILL_ICON_BORDER_WIDTH)),
..default()
},
background_color: BACKGROUND_COLOR.into(),
border_color: BORDER_COLOR.into(),
..default()
})
.id();
let skill_title = commands
.spawn(TextBundle {
text: Text::from_section(
skill.to_string(),
TextStyle {
font_size: TITLE_FONT_SIZE,
color: TEXT_COLOR,
font,
},
),
style: Style {
align_self: AlignSelf::Start,
..default()
},
..default()
})
.id();
let skill_icon_box = commands
.spawn(NodeBundle {
style: Style {
width: Val::Px(2.0f32.mul_add(-ICON_MARGIN, SKILL_HEIGHT)),
height: Val::Px(2.0f32.mul_add(-ICON_MARGIN, SKILL_HEIGHT)),
margin: UiRect::all(Val::Px(ICON_MARGIN)),
border: UiRect::all(Val::Px(SKILL_ICON_BORDER_WIDTH)),
padding: UiRect::top(Val::Px(2.0)),
..default()
},
background_color: SKILL_ICON_BACKGROUND.into(),
border_color: SKILL_ICON_BORDER.into(),
..default()
})
.id();
let skill_icon = commands
.spawn(AtlasImageBundle {
texture_atlas: icon_tileset,
texture_atlas_image: UiTextureAtlasImage {
index: skill.icon_index(),
..default()
},
..default()
})
.id();
commands.entity(skill_icon_box).push_children(&[skill_icon]);
commands
.entity(skill_box)
.push_children(&[skill_icon_box, skill_title]);
skill_box
}
fn spawn_skill_book_ui(mut commands: Commands, fonts: Res<FontResource>, game_data: Res<GameData>) {
let parent_container = NodeBundle {
style: Style {
width: Val::Percent(95.0),
height: Val::Percent(95.0),
justify_content: JustifyContent::SpaceAround,
align_self: AlignSelf::Center,
padding: UiRect::all(Val::Px(32.0)),
..default()
},
..default()
};
let left_column = NodeBundle {
style: Style {
flex_direction: FlexDirection::Column,
..default()
},
..default()
};
let right_column = NodeBundle {
style: Style {
flex_direction: FlexDirection::Column,
..default()
},
..default()
};
let Some(icon_tileset) = game_data.tile_atlas.get("skill_icons") else {
tracing::error!("spawn_skill_book_ui: Failed to get skill_icons tileset");
return;
};
let parent = commands.spawn(parent_container).id();
let left = commands.spawn(left_column).id();
let right = commands.spawn(right_column).id();
for skill in &LEFT_COLUMN_SKILLS {
let new_entity = add_skill_to_ui(
fonts.interface_font.clone(),
icon_tileset.clone(),
*skill,
&mut commands,
);
commands.entity(left).push_children(&[new_entity]);
}
for skill in &RIGHT_COLUMN_SKILLS {
let new_entity = add_skill_to_ui(
fonts.interface_font.clone(),
icon_tileset.clone(),
*skill,
&mut commands,
);
commands.entity(right).push_children(&[new_entity]);
}
commands.entity(parent).push_children(&[left, right]);
}