Revert "Merge branch 'BottledByte/ability_design' into 'master'"

This reverts merge request !1264
This commit is contained in:
Imbris 2020-08-06 08:04:03 +00:00
parent a0b1259b7e
commit c2f3e1b47f
9 changed files with 145 additions and 234 deletions

View File

@ -49,7 +49,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Loading-Screen tips - Loading-Screen tips
- Feeding animation for some animals - Feeding animation for some animals
- Power stat to weapons which affects weapon damage - Power stat to weapons which affects weapon damage
- Add IDs to abilities.
### Changed ### Changed

View File

@ -43,63 +43,6 @@ impl From<&CharacterState> for CharacterAbilityType {
} }
} }
/// This enum is used for matching ability to image in GUI.
/// This is beacuse `CharacterAbility` can have more "meanings"
/// (like axe swing and sword swing, both are BasicMelee)
/// and different GUI can be done for each.
///
/// TODO: Dehardcode this in case of modding.
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum AbilityId {
// Sword
SwordCut,
SwordThrust,
// Axe
AxeSwing,
AxeSpin,
// Hammer
HammerSmash,
HammerLeap,
// Bow
BowShot,
BowCharged,
// Staff
StaffSwing,
StaffShot,
StaffFireball,
StaffHeal,
// Dagger
DaggerStab,
DaggerDash,
// Shield
ShieldBash,
ShieldBlock,
// Farming
FarmingAttack,
// Debug
DebugFlyDirection,
DebugFlyUp,
DebugPossesArrow,
// Special
// TODO: Review usage
Roll,
Block,
Empty,
}
/// Unique ability config.
/// It composes from an ID (currently used to inform Client's GUI)
/// and data, which is the actual ability behaviour/config.
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Ability {
pub id: AbilityId,
pub data: CharacterAbility,
}
impl Ability {
pub fn new(id: AbilityId, data: CharacterAbility) -> Ability { Ability { id, data } }
}
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum CharacterAbility { pub enum CharacterAbility {
BasicMelee { BasicMelee {
@ -215,11 +158,11 @@ impl CharacterAbility {
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct ItemConfig { pub struct ItemConfig {
pub item: Item, pub item: Item,
pub ability1: Option<Ability>, pub ability1: Option<CharacterAbility>,
pub ability2: Option<Ability>, pub ability2: Option<CharacterAbility>,
pub ability3: Option<Ability>, pub ability3: Option<CharacterAbility>,
pub block_ability: Option<Ability>, pub block_ability: Option<CharacterAbility>,
pub dodge_ability: Option<Ability>, pub dodge_ability: Option<CharacterAbility>,
} }
#[derive(Arraygen, Clone, PartialEq, Default, Debug, Serialize, Deserialize)] #[derive(Arraygen, Clone, PartialEq, Default, Debug, Serialize, Deserialize)]
@ -417,10 +360,6 @@ impl From<&CharacterAbility> for CharacterState {
} }
} }
impl From<&Ability> for CharacterState {
fn from(ability: &Ability) -> Self { CharacterState::from(&ability.data) }
}
impl Component for Loadout { impl Component for Loadout {
type Storage = FlaggedStorage<Self, IdvStorage<Self>>; type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
} }

View File

@ -2,8 +2,7 @@
// version in voxygen\src\meta.rs in order to reset save files to being empty // version in voxygen\src\meta.rs in order to reset save files to being empty
use crate::comp::{ use crate::comp::{
body::object, projectile, Ability, AbilityId, Body, CharacterAbility, Gravity, LightEmitter, body::object, projectile, Body, CharacterAbility, Gravity, LightEmitter, Projectile,
Projectile,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration; use std::time::Duration;
@ -107,62 +106,62 @@ impl Tool {
Duration::from_millis(self.stats.equip_time_millis as u64) Duration::from_millis(self.stats.equip_time_millis as u64)
} }
pub fn get_abilities(&self) -> Vec<Ability> { pub fn get_abilities(&self) -> Vec<CharacterAbility> {
use CharacterAbility::*; use CharacterAbility::*;
use ToolKind::*; use ToolKind::*;
match &self.kind { match &self.kind {
Sword(_) => vec![ Sword(_) => vec![
Ability::new(AbilityId::SwordCut, TripleStrike { TripleStrike {
base_damage: (60.0 * self.base_power()) as u32, base_damage: (60.0 * self.base_power()) as u32,
needs_timing: false, needs_timing: false,
}), },
Ability::new(AbilityId::SwordThrust, DashMelee { DashMelee {
energy_cost: 700, energy_cost: 700,
buildup_duration: Duration::from_millis(500), buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
base_damage: (120.0 * self.base_power()) as u32, base_damage: (120.0 * self.base_power()) as u32,
}), },
], ],
Axe(_) => vec![ Axe(_) => vec![
Ability::new(AbilityId::AxeSwing, TripleStrike { TripleStrike {
base_damage: (80.0 * self.base_power()) as u32, base_damage: (80.0 * self.base_power()) as u32,
needs_timing: true, needs_timing: true,
}), },
Ability::new(AbilityId::AxeSpin, SpinMelee { SpinMelee {
energy_cost: 100, energy_cost: 100,
buildup_duration: Duration::from_millis(125), buildup_duration: Duration::from_millis(125),
recover_duration: Duration::from_millis(125), recover_duration: Duration::from_millis(125),
base_damage: (60.0 * self.base_power()) as u32, base_damage: (60.0 * self.base_power()) as u32,
}), },
], ],
Hammer(_) => vec![ Hammer(_) => vec![
Ability::new(AbilityId::HammerSmash, BasicMelee { BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(700), buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-120.0 * self.base_power()) as i32, base_healthchange: (-120.0 * self.base_power()) as i32,
range: 3.5, range: 3.5,
max_angle: 60.0, max_angle: 60.0,
}), },
Ability::new(AbilityId::HammerLeap, LeapMelee { LeapMelee {
energy_cost: 800, energy_cost: 800,
movement_duration: Duration::from_millis(500), movement_duration: Duration::from_millis(500),
buildup_duration: Duration::from_millis(1000), buildup_duration: Duration::from_millis(1000),
recover_duration: Duration::from_millis(100), recover_duration: Duration::from_millis(100),
base_damage: (240.0 * self.base_power()) as u32, base_damage: (240.0 * self.base_power()) as u32,
}), },
], ],
Farming(_) => vec![Ability::new(AbilityId::FarmingAttack, BasicMelee { Farming(_) => vec![BasicMelee {
energy_cost: 1, energy_cost: 1,
buildup_duration: Duration::from_millis(700), buildup_duration: Duration::from_millis(700),
recover_duration: Duration::from_millis(150), recover_duration: Duration::from_millis(150),
base_healthchange: (-50.0 * self.base_power()) as i32, base_healthchange: (-50.0 * self.base_power()) as i32,
range: 3.0, range: 3.0,
max_angle: 60.0, max_angle: 60.0,
})], }],
Bow(_) => vec![ Bow(_) => vec![
Ability::new(AbilityId::BowShot, BasicRanged { BasicRanged {
energy_cost: 0, energy_cost: 0,
holdable: true, holdable: true,
prepare_duration: Duration::from_millis(100), prepare_duration: Duration::from_millis(100),
@ -181,8 +180,8 @@ impl Tool {
projectile_body: Body::Object(object::Body::Arrow), projectile_body: Body::Object(object::Body::Arrow),
projectile_light: None, projectile_light: None,
projectile_gravity: Some(Gravity(0.2)), projectile_gravity: Some(Gravity(0.2)),
}), },
Ability::new(AbilityId::BowCharged, ChargedRanged { ChargedRanged {
energy_cost: 0, energy_cost: 0,
energy_drain: 300, energy_drain: 300,
initial_damage: (40.0 * self.base_power()) as u32, initial_damage: (40.0 * self.base_power()) as u32,
@ -194,55 +193,55 @@ impl Tool {
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
projectile_body: Body::Object(object::Body::Arrow), projectile_body: Body::Object(object::Body::Arrow),
projectile_light: None, projectile_light: None,
}), },
], ],
Dagger(_) => vec![ Dagger(_) => vec![
Ability::new(AbilityId::DaggerStab, BasicMelee { BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(100), buildup_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(400), recover_duration: Duration::from_millis(400),
base_healthchange: (-50.0 * self.base_power()) as i32, base_healthchange: (-50.0 * self.base_power()) as i32,
range: 3.5, range: 3.5,
max_angle: 60.0, max_angle: 60.0,
}), },
Ability::new(AbilityId::DaggerDash, DashMelee { DashMelee {
energy_cost: 700, energy_cost: 700,
buildup_duration: Duration::from_millis(500), buildup_duration: Duration::from_millis(500),
recover_duration: Duration::from_millis(500), recover_duration: Duration::from_millis(500),
base_damage: (100.0 * self.base_power()) as u32, base_damage: (100.0 * self.base_power()) as u32,
}), },
], ],
Staff(kind) => { Staff(kind) => {
if kind == "Sceptre" { if kind == "Sceptre" {
vec![ vec![
Ability::new(AbilityId::StaffSwing, BasicMelee { BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-10.0 * self.base_power()) as i32, base_healthchange: (-10.0 * self.base_power()) as i32,
range: 10.0, range: 10.0,
max_angle: 45.0, max_angle: 45.0,
}), },
Ability::new(AbilityId::StaffHeal, BasicMelee { BasicMelee {
energy_cost: 350, energy_cost: 350,
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(1000), recover_duration: Duration::from_millis(1000),
base_healthchange: (150.0 * self.base_power()) as i32, base_healthchange: (150.0 * self.base_power()) as i32,
range: 10.0, range: 10.0,
max_angle: 45.0, max_angle: 45.0,
}), },
] ]
} else { } else {
vec![ vec![
Ability::new(AbilityId::StaffSwing, BasicMelee { BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(100), buildup_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(300), recover_duration: Duration::from_millis(300),
base_healthchange: (-40.0 * self.base_power()) as i32, base_healthchange: (-40.0 * self.base_power()) as i32,
range: 10.0, range: 10.0,
max_angle: 45.0, max_angle: 45.0,
}), },
Ability::new(AbilityId::StaffShot, BasicRanged { BasicRanged {
energy_cost: 0, energy_cost: 0,
holdable: false, holdable: false,
prepare_duration: Duration::from_millis(250), prepare_duration: Duration::from_millis(250),
@ -264,8 +263,8 @@ impl Tool {
}), }),
projectile_gravity: None, projectile_gravity: None,
}), },
Ability::new(AbilityId::StaffFireball, BasicRanged { BasicRanged {
energy_cost: 400, energy_cost: 400,
holdable: true, holdable: true,
prepare_duration: Duration::from_millis(800), prepare_duration: Duration::from_millis(800),
@ -293,33 +292,33 @@ impl Tool {
}), }),
projectile_gravity: None, projectile_gravity: None,
}), },
] ]
} }
}, },
Shield(_) => vec![ Shield(_) => vec![
Ability::new(AbilityId::ShieldBash, BasicMelee { BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(100), buildup_duration: Duration::from_millis(100),
recover_duration: Duration::from_millis(400), recover_duration: Duration::from_millis(400),
base_healthchange: (-40.0 * self.base_power()) as i32, base_healthchange: (-40.0 * self.base_power()) as i32,
range: 3.0, range: 3.0,
max_angle: 120.0, max_angle: 120.0,
}), },
Ability::new(AbilityId::ShieldBlock, BasicBlock), BasicBlock,
], ],
Debug(kind) => { Debug(kind) => {
if kind == "Boost" { if kind == "Boost" {
vec![ vec![
Ability::new(AbilityId::DebugFlyDirection, CharacterAbility::Boost { CharacterAbility::Boost {
duration: Duration::from_millis(50), duration: Duration::from_millis(50),
only_up: false, only_up: false,
}), },
Ability::new(AbilityId::DebugFlyUp, CharacterAbility::Boost { CharacterAbility::Boost {
duration: Duration::from_millis(50), duration: Duration::from_millis(50),
only_up: true, only_up: true,
}), },
Ability::new(AbilityId::DebugPossesArrow, BasicRanged { BasicRanged {
energy_cost: 0, energy_cost: 0,
holdable: false, holdable: false,
prepare_duration: Duration::from_millis(0), prepare_duration: Duration::from_millis(0),
@ -339,20 +338,20 @@ impl Tool {
..Default::default() ..Default::default()
}), }),
projectile_gravity: None, projectile_gravity: None,
}), },
] ]
} else { } else {
vec![] vec![]
} }
}, },
Empty => vec![Ability::new(AbilityId::Empty, BasicMelee { Empty => vec![BasicMelee {
energy_cost: 0, energy_cost: 0,
buildup_duration: Duration::from_millis(0), buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(1000), recover_duration: Duration::from_millis(1000),
base_healthchange: -20, base_healthchange: -20,
range: 5.0, range: 5.0,
max_angle: 60.0, max_angle: 60.0,
})], }],
} }
} }

View File

@ -2,7 +2,7 @@ use crate::{
comp, comp,
comp::{item, item::armor}, comp::{item, item::armor},
}; };
use comp::{Ability, AbilityId, Inventory, Loadout}; use comp::{Inventory, Loadout};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tracing::warn; use tracing::warn;
@ -100,11 +100,8 @@ fn item_config(item: item::Item) -> comp::ItemConfig {
ability1: abilities.next(), ability1: abilities.next(),
ability2: abilities.next(), ability2: abilities.next(),
ability3: abilities.next(), ability3: abilities.next(),
block_ability: Some(Ability::new( block_ability: Some(comp::CharacterAbility::BasicBlock),
AbilityId::Block, dodge_ability: Some(comp::CharacterAbility::Roll),
comp::CharacterAbility::BasicBlock,
)),
dodge_ability: Some(Ability::new(AbilityId::Roll, comp::CharacterAbility::Roll)),
} }
} }

View File

@ -20,9 +20,7 @@ mod stats;
mod visual; mod visual;
// Reexports // Reexports
pub use ability::{ pub use ability::{CharacterAbility, CharacterAbilityType, ItemConfig, Loadout};
Ability, AbilityId, CharacterAbility, CharacterAbilityType, ItemConfig, Loadout,
};
pub use admin::{Admin, AdminList}; pub use admin::{Admin, AdminList};
pub use agent::{Agent, Alignment}; pub use agent::{Agent, Alignment};
pub use body::{ pub use body::{

View File

@ -2,7 +2,7 @@ use crate::{
assets, assets,
comp::{ comp::{
item::{Item, ItemKind}, item::{Item, ItemKind},
Ability, AbilityId, Body, CharacterAbility, ItemConfig, Loadout, Body, CharacterAbility, ItemConfig, Loadout,
}, },
}; };
use std::time::Duration; use std::time::Duration;
@ -67,17 +67,14 @@ impl LoadoutBuilder {
Self(Loadout { Self(Loadout {
active_item: Some(ItemConfig { active_item: Some(ItemConfig {
item: assets::load_expect_cloned("common.items.weapons.empty.empty"), item: assets::load_expect_cloned("common.items.weapons.empty.empty"),
ability1: Some(Ability::new( ability1: Some(CharacterAbility::BasicMelee {
AbilityId::Empty, energy_cost: 10,
CharacterAbility::BasicMelee { buildup_duration: Duration::from_millis(600),
energy_cost: 10, recover_duration: Duration::from_millis(100),
buildup_duration: Duration::from_millis(600), base_healthchange: -(body.base_dmg() as i32),
recover_duration: Duration::from_millis(100), range: body.base_range(),
base_healthchange: -(body.base_dmg() as i32), max_angle: 80.0,
range: body.base_range(), }),
max_angle: 80.0,
},
)),
ability2: None, ability2: None,
ability3: None, ability3: None,
block_ability: None, block_ability: None,
@ -116,11 +113,8 @@ impl LoadoutBuilder {
ability1: ability_drain.next(), ability1: ability_drain.next(),
ability2: ability_drain.next(), ability2: ability_drain.next(),
ability3: ability_drain.next(), ability3: ability_drain.next(),
block_ability: Some(Ability::new( block_ability: Some(CharacterAbility::BasicBlock),
AbilityId::Block, dodge_ability: Some(CharacterAbility::Roll),
CharacterAbility::BasicBlock,
)),
dodge_ability: Some(Ability::new(AbilityId::Roll, CharacterAbility::Roll)),
}); });
} }
} }

View File

@ -203,7 +203,7 @@ pub fn handle_ability1_input(data: &JoinData, update: &mut StateUpdate) {
.active_item .active_item
.as_ref() .as_ref()
.and_then(|i| i.ability1.as_ref()) .and_then(|i| i.ability1.as_ref())
.filter(|ability| ability.data.requirements_paid(data, update)) .filter(|ability| ability.requirements_paid(data, update))
{ {
update.character = ability.into(); update.character = ability.into();
} }
@ -233,7 +233,7 @@ pub fn handle_ability2_input(data: &JoinData, update: &mut StateUpdate) {
.active_item .active_item
.as_ref() .as_ref()
.and_then(|i| i.ability2.as_ref()) .and_then(|i| i.ability2.as_ref())
.filter(|ability| ability.data.requirements_paid(data, update)) .filter(|ability| ability.requirements_paid(data, update))
{ {
update.character = ability.into(); update.character = ability.into();
} }
@ -244,7 +244,7 @@ pub fn handle_ability2_input(data: &JoinData, update: &mut StateUpdate) {
.second_item .second_item
.as_ref() .as_ref()
.and_then(|i| i.ability2.as_ref()) .and_then(|i| i.ability2.as_ref())
.filter(|ability| ability.data.requirements_paid(data, update)) .filter(|ability| ability.requirements_paid(data, update))
{ {
update.character = ability.into(); update.character = ability.into();
} }
@ -262,7 +262,7 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
.active_item .active_item
.as_ref() .as_ref()
.and_then(|i| i.ability3.as_ref()) .and_then(|i| i.ability3.as_ref())
.filter(|ability| ability.data.requirements_paid(data, update)) .filter(|ability| ability.requirements_paid(data, update))
{ {
update.character = ability.into(); update.character = ability.into();
} }
@ -278,7 +278,7 @@ pub fn handle_dodge_input(data: &JoinData, update: &mut StateUpdate) {
.active_item .active_item
.as_ref() .as_ref()
.and_then(|i| i.dodge_ability.as_ref()) .and_then(|i| i.dodge_ability.as_ref())
.filter(|ability| ability.data.requirements_paid(data, update)) .filter(|ability| ability.requirements_paid(data, update))
{ {
if data.character.is_wield() { if data.character.is_wield() {
update.character = ability.into(); update.character = ability.into();

View File

@ -127,26 +127,20 @@ impl<'a> System<'a> for Sys {
ability2: ability_drain.next(), ability2: ability_drain.next(),
ability3: ability_drain.next(), ability3: ability_drain.next(),
block_ability: None, block_ability: None,
dodge_ability: Some(comp::Ability::new( dodge_ability: Some(comp::CharacterAbility::Roll),
comp::AbilityId::Roll,
comp::CharacterAbility::Roll,
)),
}) })
} else { } else {
Some(ItemConfig { Some(ItemConfig {
// We need the empty item so npcs can attack // We need the empty item so npcs can attack
item: assets::load_expect_cloned("common.items.weapons.empty.empty"), item: assets::load_expect_cloned("common.items.weapons.empty.empty"),
ability1: Some(comp::Ability::new( ability1: Some(CharacterAbility::BasicMelee {
comp::AbilityId::Empty, energy_cost: 0,
CharacterAbility::BasicMelee { buildup_duration: Duration::from_millis(0),
energy_cost: 0, recover_duration: Duration::from_millis(400),
buildup_duration: Duration::from_millis(0), base_healthchange: -60,
recover_duration: Duration::from_millis(400), range: 5.0,
base_healthchange: -60, max_angle: 80.0,
range: 5.0, }),
max_angle: 80.0,
},
)),
ability2: None, ability2: None,
ability3: None, ability3: None,
block_ability: None, block_ability: None,
@ -260,17 +254,14 @@ impl<'a> System<'a> for Sys {
item: assets::load_expect_cloned( item: assets::load_expect_cloned(
"common.items.weapons.sword.zweihander_sword_0", "common.items.weapons.sword.zweihander_sword_0",
), ),
ability1: Some(comp::Ability::new( ability1: Some(CharacterAbility::BasicMelee {
comp::AbilityId::Empty, energy_cost: 0,
CharacterAbility::BasicMelee { buildup_duration: Duration::from_millis(800),
energy_cost: 0, recover_duration: Duration::from_millis(200),
buildup_duration: Duration::from_millis(800), base_healthchange: -100,
recover_duration: Duration::from_millis(200), range: 3.5,
base_healthchange: -100, max_angle: 60.0,
range: 3.5, }),
max_angle: 60.0,
},
)),
ability2: None, ability2: None,
ability3: None, ability3: None,
block_ability: None, block_ability: None,

View File

@ -20,7 +20,7 @@ use common::comp::{
tool::{Tool, ToolKind}, tool::{Tool, ToolKind},
Hands, ItemKind, Hands, ItemKind,
}, },
AbilityId, CharacterState, ControllerInputs, Energy, Inventory, Loadout, Stats, CharacterState, ControllerInputs, Energy, Inventory, Loadout, Stats,
}; };
use conrod_core::{ use conrod_core::{
color, color,
@ -181,44 +181,6 @@ impl<'a> Skillbar<'a> {
show, show,
} }
} }
/// Pairs ability with image.
///
/// TODO: Dehardcode this into a .ron file
fn get_ability_image(&self, ability: AbilityId) -> conrod_core::image::Id {
use AbilityId::*;
match ability {
// Sword
SwordCut => self.imgs.twohsword_m1,
SwordThrust => self.imgs.twohsword_m2,
// Axe
AxeSwing => self.imgs.twohaxe_m1,
AxeSpin => self.imgs.axespin,
// Hammer
HammerSmash => self.imgs.twohhammer_m1,
HammerLeap => self.imgs.hammerleap,
// Bow
BowShot => self.imgs.bow_m1,
BowCharged => self.imgs.bow_m2,
// Staff
StaffSwing => self.imgs.staff_m1,
StaffShot => self.imgs.staff_m2,
StaffFireball => self.imgs.fire_spell_1,
StaffHeal => self.imgs.heal_0,
// Dagger
DaggerStab => self.imgs.onehdagger_m1,
DaggerDash => self.imgs.onehdagger_m2,
// Shield
ShieldBash => self.imgs.onehshield_m1,
ShieldBlock => self.imgs.onehshield_m2,
// Debug
DebugFlyDirection => self.imgs.flyingrod_m1,
DebugFlyUp => self.imgs.flyingrod_m2,
DebugPossesArrow => self.imgs.snake_arrow_0,
_ => self.imgs.nothing,
}
}
} }
pub struct State { pub struct State {
@ -646,13 +608,20 @@ impl<'a> Widget for Skillbar<'a> {
.middle_of(state.ids.m1_slot) .middle_of(state.ids.m1_slot)
.set(state.ids.m1_slot_bg, ui); .set(state.ids.m1_slot_bg, ui);
Button::image( Button::image(
match self.loadout.active_item.as_ref().map(|i| &i.ability1) { match self.loadout.active_item.as_ref().map(|i| &i.item.kind) {
Some(ability) => { Some(ItemKind::Tool(Tool { kind, .. })) => match kind {
if let Some(ability) = ability { ToolKind::Sword(_) => self.imgs.twohsword_m1,
self.get_ability_image(ability.id) ToolKind::Dagger(_) => self.imgs.onehdagger_m1,
} else { ToolKind::Shield(_) => self.imgs.onehshield_m1,
self.imgs.nothing ToolKind::Hammer(_) => self.imgs.twohhammer_m1,
} ToolKind::Axe(_) => self.imgs.twohaxe_m1,
ToolKind::Bow(_) => self.imgs.bow_m1,
ToolKind::Staff(_) => self.imgs.staff_m1,
ToolKind::Debug(kind) => match kind.as_ref() {
"Boost" => self.imgs.flyingrod_m1,
_ => self.imgs.nothing,
},
_ => self.imgs.nothing,
}, },
_ => self.imgs.nothing, _ => self.imgs.nothing,
}, },
@ -700,38 +669,63 @@ impl<'a> Widget for Skillbar<'a> {
_ => None, _ => None,
}; };
let active_tool_secondary_ability = let tool_kind = match (
match self.loadout.active_item.as_ref().map(|i| &i.ability2) {
Some(Some(ability)) => Some(ability.id),
_ => None,
};
let second_tool_secondary_ability =
match self.loadout.second_item.as_ref().map(|i| &i.ability2) {
Some(Some(ability)) => Some(ability.id),
_ => None,
};
let used_secondary_ability = match (
active_tool_kind.map(|tk| tk.hands()), active_tool_kind.map(|tk| tk.hands()),
second_tool_kind.map(|tk| tk.hands()), second_tool_kind.map(|tk| tk.hands()),
) { ) {
(Some(Hands::TwoHand), _) => active_tool_secondary_ability, (Some(Hands::TwoHand), _) => active_tool_kind,
(Some(Hands::OneHand), Some(Hands::OneHand)) => second_tool_secondary_ability, (_, Some(Hands::OneHand)) => second_tool_kind,
(_, _) => None, (_, _) => None,
}; };
Image::new(self.imgs.skillbar_slot_big_bg) Image::new(self.imgs.skillbar_slot_big_bg)
.w_h(38.0 * scale, 38.0 * scale) .w_h(38.0 * scale, 38.0 * scale)
.color(Some(BG_COLOR_2)) .color(match tool_kind {
Some(ToolKind::Bow(_)) => Some(BG_COLOR_2),
Some(ToolKind::Staff(_)) => Some(BG_COLOR_2),
_ => Some(BG_COLOR_2),
})
.middle_of(state.ids.m2_slot) .middle_of(state.ids.m2_slot)
.set(state.ids.m2_slot_bg, ui); .set(state.ids.m2_slot_bg, ui);
Button::image(match used_secondary_ability { Button::image(match tool_kind {
Some(ability) => self.get_ability_image(ability), Some(ToolKind::Sword(_)) => self.imgs.twohsword_m2,
Some(ToolKind::Dagger(_)) => self.imgs.onehdagger_m2,
Some(ToolKind::Shield(_)) => self.imgs.onehshield_m2,
Some(ToolKind::Hammer(_)) => self.imgs.hammerleap,
Some(ToolKind::Axe(_)) => self.imgs.axespin,
Some(ToolKind::Bow(_)) => self.imgs.bow_m2,
Some(ToolKind::Staff(kind)) => match kind.as_ref() {
"Sceptre" => self.imgs.heal_0,
_ => self.imgs.staff_m2,
},
Some(ToolKind::Debug(kind)) => match kind.as_ref() {
"Boost" => self.imgs.flyingrod_m2,
_ => self.imgs.nothing,
},
_ => self.imgs.nothing, _ => self.imgs.nothing,
}) })
.w_h(32.0 * scale, 32.0 * scale) .w_h(32.0 * scale, 32.0 * scale)
.middle_of(state.ids.m2_slot_bg) .middle_of(state.ids.m2_slot_bg)
.image_color(match tool_kind {
Some(ToolKind::Sword(_)) => {
if self.energy.current() as f64 >= 200.0 {
Color::Rgba(1.0, 1.0, 1.0, 1.0)
} else {
Color::Rgba(0.3, 0.3, 0.3, 0.8)
}
},
Some(ToolKind::Staff(kind)) => match kind.as_ref() {
"Sceptre" => {
if self.energy.current() as f64 >= 400.0 {
Color::Rgba(1.0, 1.0, 1.0, 1.0)
} else {
Color::Rgba(0.3, 0.3, 0.3, 0.8)
}
},
_ => Color::Rgba(1.0, 1.0, 1.0, 1.0),
},
_ => Color::Rgba(1.0, 1.0, 1.0, 1.0),
})
.set(state.ids.m2_content, ui); .set(state.ids.m2_content, ui);
// Slots // Slots
let content_source = (self.hotbar, self.inventory, self.loadout, self.energy); // TODO: avoid this let content_source = (self.hotbar, self.inventory, self.loadout, self.energy); // TODO: avoid this