diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 2dbf822acb..7ae109b5e3 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -15,34 +15,34 @@ Simple(Some(Sword(ReachingCombo)), "common.abilities.sword.reaching_combo"), // Damagey ones Contextualized({ - Sword(Balanced): (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"), - Sword(Offensive): (Some(Sword(OffensiveFinisher)), "common.abilities.sword.offensive_finisher"), - Sword(Crippling): (Some(Sword(CripplingFinisher)), "common.abilities.sword.crippling_finisher"), - Sword(Cleaving): (Some(Sword(CleavingFinisher)), "common.abilities.sword.cleaving_finisher"), - Sword(Parrying): (Some(Sword(ParryingCounter)), "common.abilities.sword.parrying_counter"), - Sword(Heavy): (Some(Sword(HeavyFinisher)), "common.abilities.sword.heavy_finisher"), - Sword(Reaching): (Some(Sword(ReachingFlurry)), "common.abilities.sword.reaching_flurry"), + Stance(None): (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"), + Stance(Sword(Offensive)): (Some(Sword(OffensiveFinisher)), "common.abilities.sword.offensive_finisher"), + Stance(Sword(Crippling)): (Some(Sword(CripplingFinisher)), "common.abilities.sword.crippling_finisher"), + Stance(Sword(Cleaving)): (Some(Sword(CleavingFinisher)), "common.abilities.sword.cleaving_finisher"), + Stance(Sword(Parrying)): (Some(Sword(ParryingCounter)), "common.abilities.sword.parrying_counter"), + Stance(Sword(Heavy)): (Some(Sword(HeavyFinisher)), "common.abilities.sword.heavy_finisher"), + Stance(Sword(Reaching)): (Some(Sword(ReachingFlurry)), "common.abilities.sword.reaching_flurry"), }), // Movementy ones Contextualized({ - Sword(Offensive): (Some(Sword(OffensiveAdvance)), "common.abilities.sword.offensive_advance"), - Sword(Crippling): (Some(Sword(CripplingStrike)), "common.abilities.sword.crippling_strike"), - Sword(Cleaving): (Some(Sword(CleavingDive)), "common.abilities.sword.cleaving_dive"), - Sword(Defensive): (Some(Sword(DefensiveRetreat)), "common.abilities.sword.defensive_retreat"), - Sword(Parrying): (Some(Sword(ParryingRiposte)), "common.abilities.sword.parrying_riposte"), - Sword(Heavy): (Some(Sword(HeavyFortitude)), "common.abilities.sword.heavy_fortitude"), - Sword(Mobility): (Some(Sword(MobilityFeint)), "common.abilities.sword.mobility_feint"), - Sword(Reaching): (Some(Sword(ReachingCharge)), "common.abilities.sword.reaching_charge"), + Stance(Sword(Offensive)): (Some(Sword(OffensiveAdvance)), "common.abilities.sword.offensive_advance"), + Stance(Sword(Crippling)): (Some(Sword(CripplingStrike)), "common.abilities.sword.crippling_strike"), + Stance(Sword(Cleaving)): (Some(Sword(CleavingDive)), "common.abilities.sword.cleaving_dive"), + Stance(Sword(Defensive)): (Some(Sword(DefensiveRetreat)), "common.abilities.sword.defensive_retreat"), + Stance(Sword(Parrying)): (Some(Sword(ParryingRiposte)), "common.abilities.sword.parrying_riposte"), + Stance(Sword(Heavy)): (Some(Sword(HeavyFortitude)), "common.abilities.sword.heavy_fortitude"), + Stance(Sword(Mobility)): (Some(Sword(MobilityFeint)), "common.abilities.sword.mobility_feint"), + Stance(Sword(Reaching)): (Some(Sword(ReachingCharge)), "common.abilities.sword.reaching_charge"), }), // Utilityy ones Contextualized({ - Sword(Crippling): (Some(Sword(CripplingGouge)), "common.abilities.sword.crippling_gouge"), - Sword(Cleaving): (Some(Sword(CleavingSpin)), "common.abilities.sword.cleaving_spin"), - Sword(Defensive): (Some(Sword(DefensiveBulwark)), "common.abilities.sword.defensive_bulwark"), - Sword(Parrying): (Some(Sword(ParryingParry)), "common.abilities.sword.parrying_parry"), - Sword(Heavy): (Some(Sword(HeavyPommelStrike)), "common.abilities.sword.heavy_pommelstrike"), - Sword(Mobility): (Some(Sword(MobilityAgility)), "common.abilities.sword.mobility_agility"), - Sword(Reaching): (Some(Sword(ReachingSkewer)), "common.abilities.sword.reaching_skewer"), + Stance(Sword(Crippling)): (Some(Sword(CripplingGouge)), "common.abilities.sword.crippling_gouge"), + Stance(Sword(Cleaving)): (Some(Sword(CleavingSpin)), "common.abilities.sword.cleaving_spin"), + Stance(Sword(Defensive)): (Some(Sword(DefensiveBulwark)), "common.abilities.sword.defensive_bulwark"), + Stance(Sword(Parrying)): (Some(Sword(ParryingParry)), "common.abilities.sword.parrying_parry"), + Stance(Sword(Heavy)): (Some(Sword(HeavyPommelStrike)), "common.abilities.sword.heavy_pommelstrike"), + Stance(Sword(Mobility)): (Some(Sword(MobilityAgility)), "common.abilities.sword.mobility_agility"), + Stance(Sword(Reaching)): (Some(Sword(ReachingSkewer)), "common.abilities.sword.reaching_skewer"), }), ], ), diff --git a/assets/common/abilities/sword/balanced_combo.ron b/assets/common/abilities/sword/balanced_combo.ron index a232acd766..2f4ff6121a 100644 --- a/assets/common/abilities/sword/balanced_combo.ron +++ b/assets/common/abilities/sword/balanced_combo.ron @@ -37,7 +37,4 @@ ComboMelee2( ], is_stance: true, energy_cost_per_strike: 0, - meta: ( - kind: Some(Sword(Balanced)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/balanced_finisher.ron b/assets/common/abilities/sword/balanced_finisher.ron index 9500f209bc..2e77eaed2a 100644 --- a/assets/common/abilities/sword/balanced_finisher.ron +++ b/assets/common/abilities/sword/balanced_finisher.ron @@ -14,7 +14,4 @@ FinisherMelee( angle: 15.0, ), minimum_combo: 10, - meta: ( - kind: Some(Sword(Balanced)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/balanced_thrust.ron b/assets/common/abilities/sword/balanced_thrust.ron index f74017d3b3..ed70c23311 100644 --- a/assets/common/abilities/sword/balanced_thrust.ron +++ b/assets/common/abilities/sword/balanced_thrust.ron @@ -21,7 +21,4 @@ ChargedMelee( swing_duration: 0.1, hit_timing: 0.2, recover_duration: 0.2, - meta: ( - kind: Some(Sword(Balanced)), - ), ) diff --git a/assets/common/abilities/sword/cleaving_combo.ron b/assets/common/abilities/sword/cleaving_combo.ron index 3eef40a988..d76d9317ee 100644 --- a/assets/common/abilities/sword/cleaving_combo.ron +++ b/assets/common/abilities/sword/cleaving_combo.ron @@ -48,8 +48,6 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Cleaving)), energy_cost_per_strike: 5, - meta: ( - kind: Some(Sword(Cleaving)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/cleaving_dive.ron b/assets/common/abilities/sword/cleaving_dive.ron index 815fe5ac6a..93a81f55ad 100644 --- a/assets/common/abilities/sword/cleaving_dive.ron +++ b/assets/common/abilities/sword/cleaving_dive.ron @@ -21,7 +21,4 @@ DiveMelee( angle: 15.0, multi_target: Some(Normal), ), - meta: ( - kind: Some(Sword(Cleaving)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/cleaving_finisher.ron b/assets/common/abilities/sword/cleaving_finisher.ron index e9f82860ec..fc8b74787d 100644 --- a/assets/common/abilities/sword/cleaving_finisher.ron +++ b/assets/common/abilities/sword/cleaving_finisher.ron @@ -15,7 +15,4 @@ FinisherMelee( multi_target: Some(Scaling(0.5)), ), minimum_combo: 10, - meta: ( - kind: Some(Sword(Cleaving)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/cleaving_spin.ron b/assets/common/abilities/sword/cleaving_spin.ron index 9dc4736fef..f4575e77f8 100644 --- a/assets/common/abilities/sword/cleaving_spin.ron +++ b/assets/common/abilities/sword/cleaving_spin.ron @@ -21,7 +21,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 20, - meta: ( - kind: Some(Sword(Cleaving)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/crippling_combo.ron b/assets/common/abilities/sword/crippling_combo.ron index 4ba69ba6b9..d0e722b6e7 100644 --- a/assets/common/abilities/sword/crippling_combo.ron +++ b/assets/common/abilities/sword/crippling_combo.ron @@ -48,8 +48,6 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Crippling)), energy_cost_per_strike: 4, - meta: ( - kind: Some(Sword(Crippling)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/crippling_finisher.ron b/assets/common/abilities/sword/crippling_finisher.ron index a6cbec2d45..a055a49887 100644 --- a/assets/common/abilities/sword/crippling_finisher.ron +++ b/assets/common/abilities/sword/crippling_finisher.ron @@ -24,7 +24,4 @@ FinisherMelee( kind: Sqrt, )), minimum_combo: 10, - meta: ( - kind: Some(Sword(Crippling)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/crippling_gouge.ron b/assets/common/abilities/sword/crippling_gouge.ron index 4f672467ae..7455d7779c 100644 --- a/assets/common/abilities/sword/crippling_gouge.ron +++ b/assets/common/abilities/sword/crippling_gouge.ron @@ -26,7 +26,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 25, - meta: ( - kind: Some(Sword(Crippling)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/crippling_strike.ron b/assets/common/abilities/sword/crippling_strike.ron index 2e0f8753cf..33b0d692b3 100644 --- a/assets/common/abilities/sword/crippling_strike.ron +++ b/assets/common/abilities/sword/crippling_strike.ron @@ -26,7 +26,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 25, - meta: ( - kind: Some(Sword(Crippling)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/defensive_bulwark.ron b/assets/common/abilities/sword/defensive_bulwark.ron index a6b33867d3..9f303d9772 100644 --- a/assets/common/abilities/sword/defensive_bulwark.ron +++ b/assets/common/abilities/sword/defensive_bulwark.ron @@ -6,7 +6,4 @@ SelfBuff( buff_strength: 0.4, buff_duration: Some(30.0), energy_cost: 40, - meta: ( - kind: Some(Sword(Defensive)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/defensive_combo.ron b/assets/common/abilities/sword/defensive_combo.ron index 383f0b1ae0..f6f85e4203 100644 --- a/assets/common/abilities/sword/defensive_combo.ron +++ b/assets/common/abilities/sword/defensive_combo.ron @@ -36,9 +36,9 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Defensive)), energy_cost_per_strike: 2, meta: ( - kind: Some(Sword(Defensive)), capabilities: ( // Blocking can interrupt attack bits: 0b00000010, diff --git a/assets/common/abilities/sword/defensive_retreat.ron b/assets/common/abilities/sword/defensive_retreat.ron index 612b5ebd43..beef3eb633 100644 --- a/assets/common/abilities/sword/defensive_retreat.ron +++ b/assets/common/abilities/sword/defensive_retreat.ron @@ -25,7 +25,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 10, - meta: ( - kind: Some(Sword(Defensive)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/heavy_combo.ron b/assets/common/abilities/sword/heavy_combo.ron index 9bf369e4d6..a87f747dc4 100644 --- a/assets/common/abilities/sword/heavy_combo.ron +++ b/assets/common/abilities/sword/heavy_combo.ron @@ -36,9 +36,9 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Heavy)), energy_cost_per_strike: 4, meta: ( - kind: Some(Sword(Heavy)), capabilities: ( // Poise and knockback resistant during attack bits: 0b00011000, diff --git a/assets/common/abilities/sword/heavy_finisher.ron b/assets/common/abilities/sword/heavy_finisher.ron index 3f7c64281f..aaa8220e7d 100644 --- a/assets/common/abilities/sword/heavy_finisher.ron +++ b/assets/common/abilities/sword/heavy_finisher.ron @@ -24,7 +24,4 @@ FinisherMelee( kind: Linear, )), minimum_combo: 10, - meta: ( - kind: Some(Sword(Heavy)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/heavy_fortitude.ron b/assets/common/abilities/sword/heavy_fortitude.ron index b567c09306..0531c541f4 100644 --- a/assets/common/abilities/sword/heavy_fortitude.ron +++ b/assets/common/abilities/sword/heavy_fortitude.ron @@ -6,7 +6,4 @@ SelfBuff( buff_strength: 0.5, buff_duration: Some(30.0), energy_cost: 40, - meta: ( - kind: Some(Sword(Heavy)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/heavy_pommelstrike.ron b/assets/common/abilities/sword/heavy_pommelstrike.ron index e212952dec..6dbcde88ce 100644 --- a/assets/common/abilities/sword/heavy_pommelstrike.ron +++ b/assets/common/abilities/sword/heavy_pommelstrike.ron @@ -20,7 +20,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 15, - meta: ( - kind: Some(Sword(Heavy)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/mobility_agility.ron b/assets/common/abilities/sword/mobility_agility.ron index 68b60d5cb5..44e7dc4646 100644 --- a/assets/common/abilities/sword/mobility_agility.ron +++ b/assets/common/abilities/sword/mobility_agility.ron @@ -6,7 +6,4 @@ SelfBuff( buff_strength: 0.2, buff_duration: Some(20.0), energy_cost: 40, - meta: ( - kind: Some(Sword(Mobility)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/mobility_combo.ron b/assets/common/abilities/sword/mobility_combo.ron index 97f6c11d59..60ea4791c4 100644 --- a/assets/common/abilities/sword/mobility_combo.ron +++ b/assets/common/abilities/sword/mobility_combo.ron @@ -70,9 +70,9 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Mobility)), energy_cost_per_strike: 2, meta: ( - kind: Some(Sword(Mobility)), capabilities: ( // Rolling can interrupt attack bits: 0b00000001, diff --git a/assets/common/abilities/sword/mobility_feint.ron b/assets/common/abilities/sword/mobility_feint.ron index dd5f7333ac..93194c7199 100644 --- a/assets/common/abilities/sword/mobility_feint.ron +++ b/assets/common/abilities/sword/mobility_feint.ron @@ -25,7 +25,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 10, - meta: ( - kind: Some(Sword(Mobility)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/offensive_advance.ron b/assets/common/abilities/sword/offensive_advance.ron index 2868807994..cac494b062 100644 --- a/assets/common/abilities/sword/offensive_advance.ron +++ b/assets/common/abilities/sword/offensive_advance.ron @@ -25,7 +25,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 10, - meta: ( - kind: Some(Sword(Offensive)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/offensive_combo.ron b/assets/common/abilities/sword/offensive_combo.ron index e539465757..7d1b9b3d1e 100644 --- a/assets/common/abilities/sword/offensive_combo.ron +++ b/assets/common/abilities/sword/offensive_combo.ron @@ -58,8 +58,6 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Offensive)), energy_cost_per_strike: 3, - meta: ( - kind: Some(Sword(Offensive)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/offensive_finisher.ron b/assets/common/abilities/sword/offensive_finisher.ron index a88bb5b8a6..57ab392145 100644 --- a/assets/common/abilities/sword/offensive_finisher.ron +++ b/assets/common/abilities/sword/offensive_finisher.ron @@ -24,7 +24,4 @@ FinisherMelee( kind: Sqrt, )), minimum_combo: 10, - meta: ( - kind: Some(Sword(Offensive)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/parrying_combo.ron b/assets/common/abilities/sword/parrying_combo.ron index 9c551faf04..b9c0e2d2cb 100644 --- a/assets/common/abilities/sword/parrying_combo.ron +++ b/assets/common/abilities/sword/parrying_combo.ron @@ -36,9 +36,9 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Parrying)), energy_cost_per_strike: 5, meta: ( - kind: Some(Sword(Parrying)), capabilities: ( // Buildup auto parries melee attacks bits: 0b00000100, diff --git a/assets/common/abilities/sword/parrying_counter.ron b/assets/common/abilities/sword/parrying_counter.ron index 835c807e23..b4b2519ff6 100644 --- a/assets/common/abilities/sword/parrying_counter.ron +++ b/assets/common/abilities/sword/parrying_counter.ron @@ -26,7 +26,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 15, - meta: ( - kind: Some(Sword(Parrying)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/parrying_parry.ron b/assets/common/abilities/sword/parrying_parry.ron index e2ed066112..a6c14b93bc 100644 --- a/assets/common/abilities/sword/parrying_parry.ron +++ b/assets/common/abilities/sword/parrying_parry.ron @@ -9,7 +9,4 @@ BasicBlock( ), energy_cost: 15, can_hold: false, - meta: ( - kind: Some(Sword(Parrying)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/parrying_riposte.ron b/assets/common/abilities/sword/parrying_riposte.ron index 06968664bc..e06cfbaafc 100644 --- a/assets/common/abilities/sword/parrying_riposte.ron +++ b/assets/common/abilities/sword/parrying_riposte.ron @@ -13,7 +13,4 @@ RiposteMelee( range: 4.0, angle: 20.0, ), - meta: ( - kind: Some(Sword(Parrying)), - ) ) \ No newline at end of file diff --git a/assets/common/abilities/sword/reaching_charge.ron b/assets/common/abilities/sword/reaching_charge.ron index 88c6d2f90b..e0df6ba67d 100644 --- a/assets/common/abilities/sword/reaching_charge.ron +++ b/assets/common/abilities/sword/reaching_charge.ron @@ -24,7 +24,4 @@ DashMelee( recover_duration: 0.5, ori_modifier: 0.1, charge_through: false, - meta: ( - kind: Some(Sword(Reaching)), - ), ) diff --git a/assets/common/abilities/sword/reaching_combo.ron b/assets/common/abilities/sword/reaching_combo.ron index a364243e75..d5fd92abd8 100644 --- a/assets/common/abilities/sword/reaching_combo.ron +++ b/assets/common/abilities/sword/reaching_combo.ron @@ -36,8 +36,6 @@ ComboMelee2( ), ], is_stance: true, + stance: Some(Sword(Reaching)), energy_cost_per_strike: 4, - meta: ( - kind: Some(Sword(Reaching)), - ), ) \ No newline at end of file diff --git a/assets/common/abilities/sword/reaching_flurry.ron b/assets/common/abilities/sword/reaching_flurry.ron index 0c9740ac35..2181e8912a 100644 --- a/assets/common/abilities/sword/reaching_flurry.ron +++ b/assets/common/abilities/sword/reaching_flurry.ron @@ -14,7 +14,4 @@ RapidMelee( ), energy_cost: 8, max_strikes: 6, - meta: ( - kind: Some(Sword(Reaching)), - ), ) diff --git a/assets/common/abilities/sword/reaching_skewer.ron b/assets/common/abilities/sword/reaching_skewer.ron index bae0547b5d..e587c430c9 100644 --- a/assets/common/abilities/sword/reaching_skewer.ron +++ b/assets/common/abilities/sword/reaching_skewer.ron @@ -26,7 +26,4 @@ ComboMelee2( ], is_stance: false, energy_cost_per_strike: 15, - meta: ( - kind: Some(Sword(Reaching)), - ), ) \ No newline at end of file diff --git a/common/net/src/synced_components.rs b/common/net/src/synced_components.rs index ac28d26da2..299a496ee6 100644 --- a/common/net/src/synced_components.rs +++ b/common/net/src/synced_components.rs @@ -43,6 +43,7 @@ macro_rules! synced_components { shockwave: Shockwave, beam_segment: BeamSegment, alignment: Alignment, + stance: Stance, // TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum // from other entities (e.g. just keys needed to show appearance // based on their loadout). Also, it looks like this actually has @@ -220,6 +221,10 @@ impl NetSync for SkillSet { const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity; } +impl NetSync for Stance { + const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity; +} + // These are synced only from the client's own entity. impl NetSync for Admin { diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index de6bbdc6f7..c328eb1f4f 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -566,6 +566,7 @@ pub enum CharacterAbility { ComboMelee2 { strikes: Vec>, is_stance: bool, + stance: Option, energy_cost_per_strike: f32, #[serde(default)] meta: AbilityMeta, @@ -1085,6 +1086,7 @@ impl CharacterAbility { is_stance: _, ref mut energy_cost_per_strike, meta: _, + stance: _, } => { *energy_cost_per_strike /= stats.energy_efficiency; *strikes = strikes @@ -2273,11 +2275,13 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { strikes, energy_cost_per_strike, is_stance, + stance, meta: _, } => CharacterState::ComboMelee2(combo_melee2::Data { static_data: combo_melee2::StaticData { strikes: strikes.iter().map(|s| s.to_duration()).collect(), is_stance: *is_stance, + stance: *stance, energy_cost_per_strike: *energy_cost_per_strike, ability_info, }, @@ -2809,21 +2813,12 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] #[serde(deny_unknown_fields)] pub struct AbilityMeta { - pub kind: Option, #[serde(default)] pub capabilities: Capability, } -// Only extend this if it is needed to control certain functionality of -// abilities -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum AbilityKind { - Sword(SwordStance), -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] pub enum SwordStance { - Balanced, Offensive, Crippling, Cleaving, @@ -2849,3 +2844,17 @@ bitflags::bitflags! { const KNOCKBACK_RESISTANT = 0b00010000; } } + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] +pub enum Stance { + None, + Sword(SwordStance), +} + +impl Default for Stance { + fn default() -> Self { Self::None } +} + +impl Component for Stance { + type Storage = DerefFlaggedStorage>; +} diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index 78bd405fa1..1d76745219 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -3,11 +3,7 @@ use crate::{ assets::{self, Asset, AssetExt, AssetHandle}, - comp::{ - ability::{AbilityKind, SwordStance}, - skills::Skill, - CharacterAbility, CharacterState, - }, + comp::{ability::Stance, skills::Skill, CharacterAbility}, }; use hashbrown::HashMap; use serde::{Deserialize, Serialize}; @@ -333,20 +329,12 @@ impl AuxiliaryAbilityKind { #[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)] pub enum AbilityContext { - Sword(SwordStance), + Stance(Stance), } impl AbilityContext { - pub fn try_from(char_state: Option<&CharacterState>) -> Option { - if let Some(AbilityKind::Sword(stance)) = char_state - .and_then(|cs| cs.ability_info()) - .and_then(|info| info.ability_meta) - .and_then(|meta| meta.kind) - { - Some(Self::Sword(stance)) - } else { - None - } + pub fn try_from(stance: Option<&Stance>) -> Option { + stance.map(|stance| Self::Stance(*stance)) } } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 9c0db9731d..82a7b1e314 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -51,7 +51,7 @@ pub mod visual; #[cfg(not(target_arch = "wasm32"))] pub use self::{ ability::{ - Ability, AbilityInput, ActiveAbilities, CharacterAbility, CharacterAbilityType, + Ability, AbilityInput, ActiveAbilities, CharacterAbility, CharacterAbilityType, Stance, MAX_ABILITIES, }, admin::{Admin, AdminRole}, diff --git a/common/src/event.rs b/common/src/event.rs index 4e4d2f240f..8c57977df1 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -238,6 +238,10 @@ pub enum ServerEvent { requesting_player_uuid: String, character_id: CharacterId, }, + ChangeStance { + entity: EcsEntity, + stance: comp::Stance, + }, } pub struct EventBus { diff --git a/common/src/states/behavior.rs b/common/src/states/behavior.rs index 592e84fd00..766a1738bc 100644 --- a/common/src/states/behavior.rs +++ b/common/src/states/behavior.rs @@ -5,7 +5,8 @@ use crate::{ item::{tool::AbilityMap, MaterialStatManifest}, ActiveAbilities, Beam, Body, CharacterState, Combo, ControlAction, Controller, ControllerInputs, Density, Energy, Health, InputAttr, InputKind, Inventory, - InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, SkillSet, StateUpdate, Stats, Vel, + InventoryAction, Mass, Melee, Ori, PhysicsState, Pos, SkillSet, Stance, StateUpdate, Stats, + Vel, }, link::Is, mounting::Rider, @@ -144,6 +145,7 @@ pub struct JoinData<'a> { pub alignment: Option<&'a comp::Alignment>, pub terrain: &'a TerrainGrid, pub mount_data: Option<&'a Is>, + pub stance: Option<&'a Stance>, } pub struct JoinStruct<'a> { @@ -170,6 +172,7 @@ pub struct JoinStruct<'a> { pub alignment: Option<&'a comp::Alignment>, pub terrain: &'a TerrainGrid, pub mount_data: Option<&'a Is>, + pub stance: Option<&'a Stance>, } impl<'a> JoinData<'a> { @@ -210,6 +213,7 @@ impl<'a> JoinData<'a> { terrain: j.terrain, active_abilities: j.active_abilities, mount_data: j.mount_data, + stance: j.stance, } } } diff --git a/common/src/states/combo_melee2.rs b/common/src/states/combo_melee2.rs index ca88e8b08e..99780a8726 100644 --- a/common/src/states/combo_melee2.rs +++ b/common/src/states/combo_melee2.rs @@ -3,8 +3,10 @@ use crate::{ character_state::OutputEvents, slot::{EquipSlot, Slot}, tool::Stats, - CharacterState, InputAttr, InputKind, InventoryAction, MeleeConstructor, StateUpdate, + CharacterState, InputAttr, InputKind, InventoryAction, MeleeConstructor, Stance, + StateUpdate, }, + event::ServerEvent, states::{ behavior::{CharacterBehavior, JoinData}, idle, @@ -83,6 +85,9 @@ pub struct StaticData { /// Whether or not combo melee should function as a stance (where it remains /// in the character state after a strike has finished) pub is_stance: bool, + /// If a stance is added, character state will attempt to enter that stance + /// if not already in it + pub stance: Option, /// The amount of energy consumed with each swing pub energy_cost_per_strike: f32, /// What key is used to press ability @@ -116,6 +121,15 @@ impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate { let mut update = StateUpdate::from(data); + if let Some(stance) = self.static_data.stance { + if data.stance != Some(&stance) { + output_events.emit_server(ServerEvent::ChangeStance { + entity: data.entity, + stance, + }); + } + } + // If is a stance, use M1 to control strikes, otherwise use the input that // activated the ability let ability_input = if self.static_data.is_stance { diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 6936557361..efd1e6f6ec 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -1034,7 +1034,7 @@ pub fn handle_jump( } fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKind) -> bool { - let context = AbilityContext::try_from(Some(data.character)); + let context = AbilityContext::try_from(data.stance); if let Some(ability_input) = input.into() { if let Some((ability, from_offhand)) = data .active_abilities @@ -1279,7 +1279,8 @@ pub fn get_buff_strength(data: &JoinData<'_>, ai: AbilityInfo) -> f32 { } pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool { - data.controller.queued_inputs.contains_key(&input) || data.controller.held_inputs.contains_key(&input) + data.controller.queued_inputs.contains_key(&input) + || data.controller.held_inputs.contains_key(&input) } /// Checked `Duration` addition. Computes `timer` + `dt`, applying relevant stat diff --git a/common/state/src/state.rs b/common/state/src/state.rs index 7d44ad4323..e17822f12d 100644 --- a/common/state/src/state.rs +++ b/common/state/src/state.rs @@ -209,6 +209,7 @@ impl State { ecs.register::(); ecs.register::(); ecs.register::(); + ecs.register::(); // Register components send from clients -> server ecs.register::(); diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index 71dd8afff8..9b1c7aa79e 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -9,7 +9,7 @@ use common::{ character_state::OutputEvents, inventory::item::{tool::AbilityMap, MaterialStatManifest}, ActiveAbilities, Beam, Body, CharacterState, Combo, Controller, Density, Energy, Health, - Inventory, InventoryManip, Mass, Melee, Ori, PhysicsState, Poise, Pos, SkillSet, + Inventory, InventoryManip, Mass, Melee, Ori, PhysicsState, Poise, Pos, SkillSet, Stance, StateUpdate, Stats, Vel, }, event::{EventBus, LocalEvent, ServerEvent}, @@ -51,6 +51,7 @@ pub struct ReadData<'a> { alignments: ReadStorage<'a, comp::Alignment>, terrain: ReadExpect<'a, TerrainGrid>, inventories: ReadStorage<'a, Inventory>, + stances: ReadStorage<'a, Stance>, } /// ## Character Behavior System @@ -200,6 +201,7 @@ impl<'a> System<'a> for Sys { alignment: read_data.alignments.get(entity), terrain: &read_data.terrain, mount_data: read_data.is_riders.get(entity), + stance: read_data.stances.get(entity), }; for action in actions { diff --git a/server/agent/src/attack.rs b/server/agent/src/attack.rs index 0f392025f3..fe2d7d1403 100644 --- a/server/agent/src/attack.rs +++ b/server/agent/src/attack.rs @@ -1,12 +1,12 @@ use crate::{consts::MAX_PATH_DIST, data::*, util::entities_have_line_of_sight}; use common::{ comp::{ - ability::{self, Ability, AbilityKind, ActiveAbilities, AuxiliaryAbility, Capability}, + ability::{self, Ability, ActiveAbilities, AuxiliaryAbility, Capability}, buff::BuffKind, item::tool::AbilityContext, skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill}, AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, ControlEvent, - Controller, InputKind, + Controller, InputKind, Stance, }, path::TraversalConfig, states::{self_buff, sprite_summon, utils::StageSection}, @@ -476,15 +476,15 @@ impl<'a> AgentData<'a> { const INT_COUNTER_STANCE: usize = 0; use ability::SwordStance; let stance = |stance| match stance { - 1 => SwordStance::Offensive, - 2 => SwordStance::Defensive, - 3 => SwordStance::Mobility, - 4 => SwordStance::Crippling, - 5 => SwordStance::Cleaving, - 6 => SwordStance::Parrying, - 7 => SwordStance::Heavy, - 8 => SwordStance::Reaching, - _ => SwordStance::Balanced, + 1 => Stance::Sword(SwordStance::Offensive), + 2 => Stance::Sword(SwordStance::Defensive), + 3 => Stance::Sword(SwordStance::Mobility), + 4 => Stance::Sword(SwordStance::Crippling), + 5 => Stance::Sword(SwordStance::Cleaving), + 6 => Stance::Sword(SwordStance::Parrying), + 7 => Stance::Sword(SwordStance::Heavy), + 8 => Stance::Sword(SwordStance::Reaching), + _ => Stance::None, }; if !agent.action_state.initialized { // TODO: Don't always assume that if they have skill checked for, they have @@ -519,11 +519,11 @@ impl<'a> AgentData<'a> { }) }; match stance(agent.action_state.int_counters[INT_COUNTER_STANCE]) { - SwordStance::Balanced => { + Stance::None => { // Balanced finisher set_sword_ability(0, 8); }, - SwordStance::Offensive => { + Stance::Sword(SwordStance::Offensive) => { // Offensive combo set_sword_ability(0, 0); // Offensive advance @@ -531,7 +531,7 @@ impl<'a> AgentData<'a> { // Offensive finisher set_sword_ability(2, 8); }, - SwordStance::Defensive => { + Stance::Sword(SwordStance::Defensive) => { // Defensive combo set_sword_ability(0, 3); // Defensive retreat @@ -539,7 +539,7 @@ impl<'a> AgentData<'a> { // Defensive bulwark set_sword_ability(2, 10); }, - SwordStance::Mobility => { + Stance::Sword(SwordStance::Mobility) => { // Mobility combo set_sword_ability(0, 6); // Mobility feint @@ -547,7 +547,7 @@ impl<'a> AgentData<'a> { // Mobility agility set_sword_ability(2, 10); }, - SwordStance::Crippling => { + Stance::Sword(SwordStance::Crippling) => { // Crippling combo set_sword_ability(0, 1); // Crippling finisher @@ -557,7 +557,7 @@ impl<'a> AgentData<'a> { // Crippling gouge set_sword_ability(3, 10); }, - SwordStance::Cleaving => { + Stance::Sword(SwordStance::Cleaving) => { // Cleaving combo set_sword_ability(0, 2); // Cleaving finisher @@ -567,7 +567,7 @@ impl<'a> AgentData<'a> { // Cleaving dive set_sword_ability(3, 9); }, - SwordStance::Parrying => { + Stance::Sword(SwordStance::Parrying) => { // Parrying combo set_sword_ability(0, 4); // Parrying parry @@ -577,7 +577,7 @@ impl<'a> AgentData<'a> { // Parrying counter set_sword_ability(3, 8); }, - SwordStance::Heavy => { + Stance::Sword(SwordStance::Heavy) => { // Heavy combo set_sword_ability(0, 5); // Heavy finisher @@ -587,7 +587,7 @@ impl<'a> AgentData<'a> { // Heavy fortitude set_sword_ability(3, 9); }, - SwordStance::Reaching => { + Stance::Sword(SwordStance::Reaching) => { // Reaching combo set_sword_ability(0, 7); // Reaching charge @@ -680,20 +680,15 @@ impl<'a> AgentData<'a> { }; let in_stance = |stance| { - if let CharacterState::ComboMelee2(c) = self.char_state { - c.static_data.is_stance - && c.static_data - .ability_info - .ability_meta - .and_then(|meta| meta.kind) - .map_or(false, |kind| AbilityKind::Sword(stance) == kind) + if let Some(Stance::Sword(sword_stance)) = self.stance { + stance == *sword_stance } else { false } }; match stance(agent.action_state.int_counters[INT_COUNTER_STANCE]) { - SwordStance::Balanced => { + Stance::None => { const BALANCED_FINISHER: FinisherMeleeData = FinisherMeleeData { range: 2.5, angle: 12.5, @@ -717,7 +712,7 @@ impl<'a> AgentData<'a> { fallback_tactics(agent, controller); } }, - SwordStance::Offensive => { + Stance::Sword(SwordStance::Offensive) => { const OFFENSIVE_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.0, @@ -786,7 +781,7 @@ impl<'a> AgentData<'a> { } } }, - SwordStance::Defensive => { + Stance::Sword(SwordStance::Defensive) => { const DEFENSIVE_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.5, @@ -898,7 +893,7 @@ impl<'a> AgentData<'a> { ); } }, - SwordStance::Mobility => { + Stance::Sword(SwordStance::Mobility) => { const MOBILITY_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.5, @@ -998,7 +993,7 @@ impl<'a> AgentData<'a> { }; controller.inputs.move_dir.rotated_z(PI / 4.0 * dir); }, - SwordStance::Crippling => { + Stance::Sword(SwordStance::Crippling) => { const CRIPPLING_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.5, @@ -1076,7 +1071,7 @@ impl<'a> AgentData<'a> { ); } }, - SwordStance::Cleaving => { + Stance::Sword(SwordStance::Cleaving) => { // TODO: Rewrite cleaving stance tactics when agents can consider multiple // targets at once. Remove hack to make cleaving AI appear less frequently above // when doing so. @@ -1188,7 +1183,7 @@ impl<'a> AgentData<'a> { ); } }, - SwordStance::Parrying => { + Stance::Sword(SwordStance::Parrying) => { const PARRYING_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.5, @@ -1294,7 +1289,7 @@ impl<'a> AgentData<'a> { ); } }, - SwordStance::Heavy => { + Stance::Sword(SwordStance::Heavy) => { const HEAVY_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 2.5, @@ -1371,7 +1366,7 @@ impl<'a> AgentData<'a> { advance(agent, controller, HEAVY_COMBO.max_range, HEAVY_COMBO.angle); } }, - SwordStance::Reaching => { + Stance::Sword(SwordStance::Reaching) => { const REACHING_COMBO: ComboMeleeData = ComboMeleeData { min_range: 0.0, max_range: 4.5, @@ -1622,7 +1617,7 @@ impl<'a> AgentData<'a> { enum ActionStateConditions { ConditionStaffCanShockwave = 0, } - let context = AbilityContext::try_from(Some(self.char_state)); + let context = AbilityContext::try_from(self.stance); let extract_ability = |input: AbilityInput| { self.active_abilities .activate_ability( diff --git a/server/agent/src/data.rs b/server/agent/src/data.rs index d6f27e7a9e..e6d90eaf2f 100644 --- a/server/agent/src/data.rs +++ b/server/agent/src/data.rs @@ -4,7 +4,8 @@ use common::{ group, item::MaterialStatManifest, ActiveAbilities, Alignment, Body, CharacterState, Combo, Energy, Health, Inventory, - LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Scale, SkillSet, Stats, Vel, + LightEmitter, LootOwner, Ori, PhysicsState, Poise, Pos, Scale, SkillSet, Stance, Stats, + Vel, }, link::Is, mounting::Mount, @@ -47,6 +48,7 @@ pub struct AgentData<'a> { pub buffs: Option<&'a Buffs>, pub stats: Option<&'a Stats>, pub poise: Option<&'a Poise>, + pub stance: Option<&'a Stance>, pub cached_spatial_grid: &'a common::CachedSpatialGrid, pub msm: &'a MaterialStatManifest, } @@ -182,6 +184,7 @@ pub struct ReadData<'a> { pub loot_owners: ReadStorage<'a, LootOwner>, pub msm: ReadExpect<'a, MaterialStatManifest>, pub poises: ReadStorage<'a, Poise>, + pub stances: ReadStorage<'a, Stance>, } pub enum Path { diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 200b205554..6676b4caed 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -1480,3 +1480,14 @@ pub fn handle_make_admin(server: &mut Server, entity: EcsEntity, admin: comp::Ad .write_component_ignore_entity_dead(entity, admin); } } + +pub fn handle_stance_change(server: &mut Server, entity: EcsEntity, new_stance: comp::Stance) { + if let Some(mut stance) = server + .state + .ecs_mut() + .write_storage::() + .get_mut(entity) + { + *stance = new_stance; + } +} diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index 2ff37f5f56..3badeeaa88 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -13,8 +13,8 @@ use entity_manipulation::{ handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change, handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook, handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground, - handle_make_admin, handle_parry_hook, handle_poise, handle_respawn, handle_teleport_to, - handle_update_map_marker, + handle_make_admin, handle_parry_hook, handle_poise, handle_respawn, handle_stance_change, + handle_teleport_to, handle_update_map_marker, }; use group_manip::handle_group; use information::handle_site_info; @@ -300,6 +300,9 @@ impl Server { admin, uuid, } => handle_make_admin(self, entity, admin, uuid), + ServerEvent::ChangeStance { entity, stance } => { + handle_stance_change(self, entity, stance) + }, } } diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index c27781f7b4..c1dd09278d 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -288,6 +288,7 @@ impl StateExt for State { .with(comp::Buffs::default()) .with(comp::Combo::default()) .with(comp::Auras::default()) + .with(comp::Stance::default()) } fn create_object(&mut self, pos: comp::Pos, object: comp::object::Body) -> EcsEntityBuilder { @@ -560,6 +561,7 @@ impl StateExt for State { self.write_component_ignore_entity_dead(entity, comp::Buffs::default()); self.write_component_ignore_entity_dead(entity, comp::Auras::default()); self.write_component_ignore_entity_dead(entity, comp::Combo::default()); + self.write_component_ignore_entity_dead(entity, comp::Stance::default()); // Make sure physics components are updated self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced()); diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index b073eec273..f2789c6aca 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -203,6 +203,7 @@ impl<'a> System<'a> for Sys { cached_spatial_grid: &read_data.cached_spatial_grid, msm: &read_data.msm, poise: read_data.poises.get(entity), + stance: read_data.stances.get(entity), }; /////////////////////////////////////////////////////////// diff --git a/voxygen/src/hud/buffs.rs b/voxygen/src/hud/buffs.rs index 9e501e800f..249b3bfd89 100644 --- a/voxygen/src/hud/buffs.rs +++ b/voxygen/src/hud/buffs.rs @@ -10,7 +10,7 @@ use crate::{ use i18n::Localization; use common::{ - comp::{BuffKind, Buffs, CharacterState, Energy, Health}, + comp::{BuffKind, Buffs, Energy, Health, Stance}, resources::Time, }; use conrod_core::{ @@ -47,7 +47,7 @@ pub struct BuffsBar<'a> { tooltip_manager: &'a mut TooltipManager, localized_strings: &'a Localization, buffs: &'a Buffs, - char_state: &'a CharacterState, + stance: Option<&'a Stance>, pulse: f32, global_state: &'a GlobalState, health: &'a Health, @@ -63,7 +63,7 @@ impl<'a> BuffsBar<'a> { tooltip_manager: &'a mut TooltipManager, localized_strings: &'a Localization, buffs: &'a Buffs, - char_state: &'a CharacterState, + stance: Option<&'a Stance>, pulse: f32, global_state: &'a GlobalState, health: &'a Health, @@ -78,7 +78,7 @@ impl<'a> BuffsBar<'a> { tooltip_manager, localized_strings, buffs, - char_state, + stance, pulse, global_state, health, @@ -138,7 +138,7 @@ impl<'a> Widget for BuffsBar<'a> { .desc_font_size(self.fonts.cyri.scale(12)) .font_id(self.fonts.cyri.conrod_id) .desc_text_color(TEXT_COLOR); - let buff_icons = BuffIcon::icons_vec(self.buffs, self.char_state); + let buff_icons = BuffIcon::icons_vec(self.buffs, self.stance); if let BuffPosition::Bar = buff_position { let decayed_health = 1.0 - self.health.maximum() / self.health.base_max(); let show_health = self.global_state.settings.interface.always_show_bars diff --git a/voxygen/src/hud/group.rs b/voxygen/src/hud/group.rs index 967e3890af..d17efad723 100644 --- a/voxygen/src/hud/group.rs +++ b/voxygen/src/hud/group.rs @@ -359,9 +359,7 @@ impl<'a> Widget for Group<'a> { let uid_allocator = client_state.ecs().read_resource::(); let bodies = client_state.ecs().read_storage::(); let poises = client_state.ecs().read_storage::(); - let char_states = client_state - .ecs() - .read_storage::(); + let stances = client_state.ecs().read_storage::(); // Keep track of the total number of widget ids we are using for buffs let mut total_buff_count = 0; @@ -377,7 +375,7 @@ impl<'a> Widget for Group<'a> { let is_leader = uid == leader; let body = entity.and_then(|entity| bodies.get(entity)); let poise = entity.and_then(|entity| poises.get(entity)); - let char_state = entity.and_then(|entity| char_states.get(entity)); + let stance = entity.and_then(|entity| stances.get(entity)); if let ( Some(stats), @@ -387,10 +385,8 @@ impl<'a> Widget for Group<'a> { Some(energy), Some(body), Some(poise), - Some(char_state), - ) = ( - stats, skill_set, inventory, health, energy, body, poise, char_state, - ) { + ) = (stats, skill_set, inventory, health, energy, body, poise) + { let combat_rating = combat::combat_rating( inventory, health, energy, poise, skill_set, *body, self.msm, ); @@ -509,7 +505,7 @@ impl<'a> Widget for Group<'a> { .top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0) .set(state.ids.member_energy[i], ui); if let Some(buffs) = buffs { - let buff_icons = BuffIcon::icons_vec(buffs, char_state); + let buff_icons = BuffIcon::icons_vec(buffs, stance); // Limit displayed buffs to 11 let buff_count = buff_icons.len().min(11); total_buff_count += buff_count; diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 88671056cd..bd8514e189 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -580,29 +580,34 @@ impl<'a> BuffIcon<'a> { } } - pub fn icons_vec(buffs: &comp::Buffs, char_state: &comp::CharacterState) -> Vec { + pub fn icons_vec(buffs: &comp::Buffs, stance: Option<&comp::Stance>) -> Vec { buffs .iter_active() .filter_map(BuffIcon::from_buffs) - .chain(BuffIcon::from_char_state(char_state).into_iter()) + .chain(stance.and_then(BuffIcon::from_stance).into_iter()) .collect::>() } - fn from_char_state(char_state: &comp::CharacterState) -> Option { - if let Some(ability_kind) = char_state - .ability_info() - .and_then(|info| info.ability_meta) - .and_then(|meta| meta.kind) - { - let id = util::representative_ability_id(ability_kind); - Some(BuffIcon { - kind: BuffIconKind::Ability { ability_id: id }, - is_buff: true, - end_time: None, - }) - } else { - None - } + fn from_stance(stance: &comp::Stance) -> Option { + use comp::ability::{Stance, SwordStance}; + let id = match stance { + Stance::Sword(SwordStance::Offensive) => "common.abilities.sword.offensive_combo", + Stance::Sword(SwordStance::Crippling) => "common.abilities.sword.crippling_combo", + Stance::Sword(SwordStance::Cleaving) => "common.abilities.sword.cleaving_combo", + Stance::Sword(SwordStance::Defensive) => "common.abilities.sword.defensive_combo", + Stance::Sword(SwordStance::Parrying) => "common.abilities.sword.parrying_combo", + Stance::Sword(SwordStance::Heavy) => "common.abilities.sword.heavy_combo", + Stance::Sword(SwordStance::Mobility) => "common.abilities.sword.mobility_combo", + Stance::Sword(SwordStance::Reaching) => "common.abilities.sword.reaching_combo", + Stance::None => { + return None; + }, + }; + Some(BuffIcon { + kind: BuffIconKind::Ability { ability_id: id }, + is_buff: true, + end_time: None, + }) } fn from_buffs<'b, I: Iterator>(buffs: I) -> Option { @@ -1489,7 +1494,7 @@ impl Hud { let poises = ecs.read_storage::(); let alignments = ecs.read_storage::(); let is_mount = ecs.read_storage::>(); - let char_states = ecs.read_storage::(); + let stances = ecs.read_storage::(); let time = ecs.read_resource::