mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added stance component that persists even after sheathing weapon (does not yet work with M1 replacement).
This commit is contained in:
@ -15,34 +15,34 @@
|
|||||||
Simple(Some(Sword(ReachingCombo)), "common.abilities.sword.reaching_combo"),
|
Simple(Some(Sword(ReachingCombo)), "common.abilities.sword.reaching_combo"),
|
||||||
// Damagey ones
|
// Damagey ones
|
||||||
Contextualized({
|
Contextualized({
|
||||||
Sword(Balanced): (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"),
|
Stance(None): (Some(Sword(BalancedFinisher)), "common.abilities.sword.balanced_finisher"),
|
||||||
Sword(Offensive): (Some(Sword(OffensiveFinisher)), "common.abilities.sword.offensive_finisher"),
|
Stance(Sword(Offensive)): (Some(Sword(OffensiveFinisher)), "common.abilities.sword.offensive_finisher"),
|
||||||
Sword(Crippling): (Some(Sword(CripplingFinisher)), "common.abilities.sword.crippling_finisher"),
|
Stance(Sword(Crippling)): (Some(Sword(CripplingFinisher)), "common.abilities.sword.crippling_finisher"),
|
||||||
Sword(Cleaving): (Some(Sword(CleavingFinisher)), "common.abilities.sword.cleaving_finisher"),
|
Stance(Sword(Cleaving)): (Some(Sword(CleavingFinisher)), "common.abilities.sword.cleaving_finisher"),
|
||||||
Sword(Parrying): (Some(Sword(ParryingCounter)), "common.abilities.sword.parrying_counter"),
|
Stance(Sword(Parrying)): (Some(Sword(ParryingCounter)), "common.abilities.sword.parrying_counter"),
|
||||||
Sword(Heavy): (Some(Sword(HeavyFinisher)), "common.abilities.sword.heavy_finisher"),
|
Stance(Sword(Heavy)): (Some(Sword(HeavyFinisher)), "common.abilities.sword.heavy_finisher"),
|
||||||
Sword(Reaching): (Some(Sword(ReachingFlurry)), "common.abilities.sword.reaching_flurry"),
|
Stance(Sword(Reaching)): (Some(Sword(ReachingFlurry)), "common.abilities.sword.reaching_flurry"),
|
||||||
}),
|
}),
|
||||||
// Movementy ones
|
// Movementy ones
|
||||||
Contextualized({
|
Contextualized({
|
||||||
Sword(Offensive): (Some(Sword(OffensiveAdvance)), "common.abilities.sword.offensive_advance"),
|
Stance(Sword(Offensive)): (Some(Sword(OffensiveAdvance)), "common.abilities.sword.offensive_advance"),
|
||||||
Sword(Crippling): (Some(Sword(CripplingStrike)), "common.abilities.sword.crippling_strike"),
|
Stance(Sword(Crippling)): (Some(Sword(CripplingStrike)), "common.abilities.sword.crippling_strike"),
|
||||||
Sword(Cleaving): (Some(Sword(CleavingDive)), "common.abilities.sword.cleaving_dive"),
|
Stance(Sword(Cleaving)): (Some(Sword(CleavingDive)), "common.abilities.sword.cleaving_dive"),
|
||||||
Sword(Defensive): (Some(Sword(DefensiveRetreat)), "common.abilities.sword.defensive_retreat"),
|
Stance(Sword(Defensive)): (Some(Sword(DefensiveRetreat)), "common.abilities.sword.defensive_retreat"),
|
||||||
Sword(Parrying): (Some(Sword(ParryingRiposte)), "common.abilities.sword.parrying_riposte"),
|
Stance(Sword(Parrying)): (Some(Sword(ParryingRiposte)), "common.abilities.sword.parrying_riposte"),
|
||||||
Sword(Heavy): (Some(Sword(HeavyFortitude)), "common.abilities.sword.heavy_fortitude"),
|
Stance(Sword(Heavy)): (Some(Sword(HeavyFortitude)), "common.abilities.sword.heavy_fortitude"),
|
||||||
Sword(Mobility): (Some(Sword(MobilityFeint)), "common.abilities.sword.mobility_feint"),
|
Stance(Sword(Mobility)): (Some(Sword(MobilityFeint)), "common.abilities.sword.mobility_feint"),
|
||||||
Sword(Reaching): (Some(Sword(ReachingCharge)), "common.abilities.sword.reaching_charge"),
|
Stance(Sword(Reaching)): (Some(Sword(ReachingCharge)), "common.abilities.sword.reaching_charge"),
|
||||||
}),
|
}),
|
||||||
// Utilityy ones
|
// Utilityy ones
|
||||||
Contextualized({
|
Contextualized({
|
||||||
Sword(Crippling): (Some(Sword(CripplingGouge)), "common.abilities.sword.crippling_gouge"),
|
Stance(Sword(Crippling)): (Some(Sword(CripplingGouge)), "common.abilities.sword.crippling_gouge"),
|
||||||
Sword(Cleaving): (Some(Sword(CleavingSpin)), "common.abilities.sword.cleaving_spin"),
|
Stance(Sword(Cleaving)): (Some(Sword(CleavingSpin)), "common.abilities.sword.cleaving_spin"),
|
||||||
Sword(Defensive): (Some(Sword(DefensiveBulwark)), "common.abilities.sword.defensive_bulwark"),
|
Stance(Sword(Defensive)): (Some(Sword(DefensiveBulwark)), "common.abilities.sword.defensive_bulwark"),
|
||||||
Sword(Parrying): (Some(Sword(ParryingParry)), "common.abilities.sword.parrying_parry"),
|
Stance(Sword(Parrying)): (Some(Sword(ParryingParry)), "common.abilities.sword.parrying_parry"),
|
||||||
Sword(Heavy): (Some(Sword(HeavyPommelStrike)), "common.abilities.sword.heavy_pommelstrike"),
|
Stance(Sword(Heavy)): (Some(Sword(HeavyPommelStrike)), "common.abilities.sword.heavy_pommelstrike"),
|
||||||
Sword(Mobility): (Some(Sword(MobilityAgility)), "common.abilities.sword.mobility_agility"),
|
Stance(Sword(Mobility)): (Some(Sword(MobilityAgility)), "common.abilities.sword.mobility_agility"),
|
||||||
Sword(Reaching): (Some(Sword(ReachingSkewer)), "common.abilities.sword.reaching_skewer"),
|
Stance(Sword(Reaching)): (Some(Sword(ReachingSkewer)), "common.abilities.sword.reaching_skewer"),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -37,7 +37,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
energy_cost_per_strike: 0,
|
energy_cost_per_strike: 0,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Balanced)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -14,7 +14,4 @@ FinisherMelee(
|
|||||||
angle: 15.0,
|
angle: 15.0,
|
||||||
),
|
),
|
||||||
minimum_combo: 10,
|
minimum_combo: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Balanced)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -21,7 +21,4 @@ ChargedMelee(
|
|||||||
swing_duration: 0.1,
|
swing_duration: 0.1,
|
||||||
hit_timing: 0.2,
|
hit_timing: 0.2,
|
||||||
recover_duration: 0.2,
|
recover_duration: 0.2,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Balanced)),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
@ -48,8 +48,6 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Cleaving)),
|
||||||
energy_cost_per_strike: 5,
|
energy_cost_per_strike: 5,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Cleaving)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -21,7 +21,4 @@ DiveMelee(
|
|||||||
angle: 15.0,
|
angle: 15.0,
|
||||||
multi_target: Some(Normal),
|
multi_target: Some(Normal),
|
||||||
),
|
),
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Cleaving)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -15,7 +15,4 @@ FinisherMelee(
|
|||||||
multi_target: Some(Scaling(0.5)),
|
multi_target: Some(Scaling(0.5)),
|
||||||
),
|
),
|
||||||
minimum_combo: 10,
|
minimum_combo: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Cleaving)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -21,7 +21,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 20,
|
energy_cost_per_strike: 20,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Cleaving)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -48,8 +48,6 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Crippling)),
|
||||||
energy_cost_per_strike: 4,
|
energy_cost_per_strike: 4,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Crippling)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -24,7 +24,4 @@ FinisherMelee(
|
|||||||
kind: Sqrt,
|
kind: Sqrt,
|
||||||
)),
|
)),
|
||||||
minimum_combo: 10,
|
minimum_combo: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Crippling)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -26,7 +26,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 25,
|
energy_cost_per_strike: 25,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Crippling)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -26,7 +26,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 25,
|
energy_cost_per_strike: 25,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Crippling)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -6,7 +6,4 @@ SelfBuff(
|
|||||||
buff_strength: 0.4,
|
buff_strength: 0.4,
|
||||||
buff_duration: Some(30.0),
|
buff_duration: Some(30.0),
|
||||||
energy_cost: 40,
|
energy_cost: 40,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Defensive)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -36,9 +36,9 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Defensive)),
|
||||||
energy_cost_per_strike: 2,
|
energy_cost_per_strike: 2,
|
||||||
meta: (
|
meta: (
|
||||||
kind: Some(Sword(Defensive)),
|
|
||||||
capabilities: (
|
capabilities: (
|
||||||
// Blocking can interrupt attack
|
// Blocking can interrupt attack
|
||||||
bits: 0b00000010,
|
bits: 0b00000010,
|
||||||
|
@ -25,7 +25,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 10,
|
energy_cost_per_strike: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Defensive)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -36,9 +36,9 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Heavy)),
|
||||||
energy_cost_per_strike: 4,
|
energy_cost_per_strike: 4,
|
||||||
meta: (
|
meta: (
|
||||||
kind: Some(Sword(Heavy)),
|
|
||||||
capabilities: (
|
capabilities: (
|
||||||
// Poise and knockback resistant during attack
|
// Poise and knockback resistant during attack
|
||||||
bits: 0b00011000,
|
bits: 0b00011000,
|
||||||
|
@ -24,7 +24,4 @@ FinisherMelee(
|
|||||||
kind: Linear,
|
kind: Linear,
|
||||||
)),
|
)),
|
||||||
minimum_combo: 10,
|
minimum_combo: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Heavy)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -6,7 +6,4 @@ SelfBuff(
|
|||||||
buff_strength: 0.5,
|
buff_strength: 0.5,
|
||||||
buff_duration: Some(30.0),
|
buff_duration: Some(30.0),
|
||||||
energy_cost: 40,
|
energy_cost: 40,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Heavy)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -20,7 +20,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 15,
|
energy_cost_per_strike: 15,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Heavy)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -6,7 +6,4 @@ SelfBuff(
|
|||||||
buff_strength: 0.2,
|
buff_strength: 0.2,
|
||||||
buff_duration: Some(20.0),
|
buff_duration: Some(20.0),
|
||||||
energy_cost: 40,
|
energy_cost: 40,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Mobility)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -70,9 +70,9 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Mobility)),
|
||||||
energy_cost_per_strike: 2,
|
energy_cost_per_strike: 2,
|
||||||
meta: (
|
meta: (
|
||||||
kind: Some(Sword(Mobility)),
|
|
||||||
capabilities: (
|
capabilities: (
|
||||||
// Rolling can interrupt attack
|
// Rolling can interrupt attack
|
||||||
bits: 0b00000001,
|
bits: 0b00000001,
|
||||||
|
@ -25,7 +25,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 10,
|
energy_cost_per_strike: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Mobility)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -25,7 +25,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 10,
|
energy_cost_per_strike: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Offensive)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -58,8 +58,6 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Offensive)),
|
||||||
energy_cost_per_strike: 3,
|
energy_cost_per_strike: 3,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Offensive)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -24,7 +24,4 @@ FinisherMelee(
|
|||||||
kind: Sqrt,
|
kind: Sqrt,
|
||||||
)),
|
)),
|
||||||
minimum_combo: 10,
|
minimum_combo: 10,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Offensive)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -36,9 +36,9 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Parrying)),
|
||||||
energy_cost_per_strike: 5,
|
energy_cost_per_strike: 5,
|
||||||
meta: (
|
meta: (
|
||||||
kind: Some(Sword(Parrying)),
|
|
||||||
capabilities: (
|
capabilities: (
|
||||||
// Buildup auto parries melee attacks
|
// Buildup auto parries melee attacks
|
||||||
bits: 0b00000100,
|
bits: 0b00000100,
|
||||||
|
@ -26,7 +26,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 15,
|
energy_cost_per_strike: 15,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Parrying)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -9,7 +9,4 @@ BasicBlock(
|
|||||||
),
|
),
|
||||||
energy_cost: 15,
|
energy_cost: 15,
|
||||||
can_hold: false,
|
can_hold: false,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Parrying)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -13,7 +13,4 @@ RiposteMelee(
|
|||||||
range: 4.0,
|
range: 4.0,
|
||||||
angle: 20.0,
|
angle: 20.0,
|
||||||
),
|
),
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Parrying)),
|
|
||||||
)
|
|
||||||
)
|
)
|
@ -24,7 +24,4 @@ DashMelee(
|
|||||||
recover_duration: 0.5,
|
recover_duration: 0.5,
|
||||||
ori_modifier: 0.1,
|
ori_modifier: 0.1,
|
||||||
charge_through: false,
|
charge_through: false,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Reaching)),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
@ -36,8 +36,6 @@ ComboMelee2(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
is_stance: true,
|
is_stance: true,
|
||||||
|
stance: Some(Sword(Reaching)),
|
||||||
energy_cost_per_strike: 4,
|
energy_cost_per_strike: 4,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Reaching)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -14,7 +14,4 @@ RapidMelee(
|
|||||||
),
|
),
|
||||||
energy_cost: 8,
|
energy_cost: 8,
|
||||||
max_strikes: 6,
|
max_strikes: 6,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Reaching)),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
@ -26,7 +26,4 @@ ComboMelee2(
|
|||||||
],
|
],
|
||||||
is_stance: false,
|
is_stance: false,
|
||||||
energy_cost_per_strike: 15,
|
energy_cost_per_strike: 15,
|
||||||
meta: (
|
|
||||||
kind: Some(Sword(Reaching)),
|
|
||||||
),
|
|
||||||
)
|
)
|
@ -43,6 +43,7 @@ macro_rules! synced_components {
|
|||||||
shockwave: Shockwave,
|
shockwave: Shockwave,
|
||||||
beam_segment: BeamSegment,
|
beam_segment: BeamSegment,
|
||||||
alignment: Alignment,
|
alignment: Alignment,
|
||||||
|
stance: Stance,
|
||||||
// TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum
|
// TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum
|
||||||
// from other entities (e.g. just keys needed to show appearance
|
// from other entities (e.g. just keys needed to show appearance
|
||||||
// based on their loadout). Also, it looks like this actually has
|
// 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;
|
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.
|
// These are synced only from the client's own entity.
|
||||||
|
|
||||||
impl NetSync for Admin {
|
impl NetSync for Admin {
|
||||||
|
@ -566,6 +566,7 @@ pub enum CharacterAbility {
|
|||||||
ComboMelee2 {
|
ComboMelee2 {
|
||||||
strikes: Vec<combo_melee2::Strike<f32>>,
|
strikes: Vec<combo_melee2::Strike<f32>>,
|
||||||
is_stance: bool,
|
is_stance: bool,
|
||||||
|
stance: Option<Stance>,
|
||||||
energy_cost_per_strike: f32,
|
energy_cost_per_strike: f32,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
meta: AbilityMeta,
|
meta: AbilityMeta,
|
||||||
@ -1085,6 +1086,7 @@ impl CharacterAbility {
|
|||||||
is_stance: _,
|
is_stance: _,
|
||||||
ref mut energy_cost_per_strike,
|
ref mut energy_cost_per_strike,
|
||||||
meta: _,
|
meta: _,
|
||||||
|
stance: _,
|
||||||
} => {
|
} => {
|
||||||
*energy_cost_per_strike /= stats.energy_efficiency;
|
*energy_cost_per_strike /= stats.energy_efficiency;
|
||||||
*strikes = strikes
|
*strikes = strikes
|
||||||
@ -2273,11 +2275,13 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
strikes,
|
strikes,
|
||||||
energy_cost_per_strike,
|
energy_cost_per_strike,
|
||||||
is_stance,
|
is_stance,
|
||||||
|
stance,
|
||||||
meta: _,
|
meta: _,
|
||||||
} => CharacterState::ComboMelee2(combo_melee2::Data {
|
} => CharacterState::ComboMelee2(combo_melee2::Data {
|
||||||
static_data: combo_melee2::StaticData {
|
static_data: combo_melee2::StaticData {
|
||||||
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
|
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
|
||||||
is_stance: *is_stance,
|
is_stance: *is_stance,
|
||||||
|
stance: *stance,
|
||||||
energy_cost_per_strike: *energy_cost_per_strike,
|
energy_cost_per_strike: *energy_cost_per_strike,
|
||||||
ability_info,
|
ability_info,
|
||||||
},
|
},
|
||||||
@ -2809,21 +2813,12 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct AbilityMeta {
|
pub struct AbilityMeta {
|
||||||
pub kind: Option<AbilityKind>,
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub capabilities: Capability,
|
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)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||||
pub enum SwordStance {
|
pub enum SwordStance {
|
||||||
Balanced,
|
|
||||||
Offensive,
|
Offensive,
|
||||||
Crippling,
|
Crippling,
|
||||||
Cleaving,
|
Cleaving,
|
||||||
@ -2849,3 +2844,17 @@ bitflags::bitflags! {
|
|||||||
const KNOCKBACK_RESISTANT = 0b00010000;
|
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<Self, specs::VecStorage<Self>>;
|
||||||
|
}
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
assets::{self, Asset, AssetExt, AssetHandle},
|
assets::{self, Asset, AssetExt, AssetHandle},
|
||||||
comp::{
|
comp::{ability::Stance, skills::Skill, CharacterAbility},
|
||||||
ability::{AbilityKind, SwordStance},
|
|
||||||
skills::Skill,
|
|
||||||
CharacterAbility, CharacterState,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -333,20 +329,12 @@ impl<T> AuxiliaryAbilityKind<T> {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Copy, Eq, PartialEq, Hash)]
|
||||||
pub enum AbilityContext {
|
pub enum AbilityContext {
|
||||||
Sword(SwordStance),
|
Stance(Stance),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbilityContext {
|
impl AbilityContext {
|
||||||
pub fn try_from(char_state: Option<&CharacterState>) -> Option<Self> {
|
pub fn try_from(stance: Option<&Stance>) -> Option<Self> {
|
||||||
if let Some(AbilityKind::Sword(stance)) = char_state
|
stance.map(|stance| Self::Stance(*stance))
|
||||||
.and_then(|cs| cs.ability_info())
|
|
||||||
.and_then(|info| info.ability_meta)
|
|
||||||
.and_then(|meta| meta.kind)
|
|
||||||
{
|
|
||||||
Some(Self::Sword(stance))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ pub mod visual;
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
ability::{
|
ability::{
|
||||||
Ability, AbilityInput, ActiveAbilities, CharacterAbility, CharacterAbilityType,
|
Ability, AbilityInput, ActiveAbilities, CharacterAbility, CharacterAbilityType, Stance,
|
||||||
MAX_ABILITIES,
|
MAX_ABILITIES,
|
||||||
},
|
},
|
||||||
admin::{Admin, AdminRole},
|
admin::{Admin, AdminRole},
|
||||||
|
@ -238,6 +238,10 @@ pub enum ServerEvent {
|
|||||||
requesting_player_uuid: String,
|
requesting_player_uuid: String,
|
||||||
character_id: CharacterId,
|
character_id: CharacterId,
|
||||||
},
|
},
|
||||||
|
ChangeStance {
|
||||||
|
entity: EcsEntity,
|
||||||
|
stance: comp::Stance,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventBus<E> {
|
pub struct EventBus<E> {
|
||||||
|
@ -5,7 +5,8 @@ use crate::{
|
|||||||
item::{tool::AbilityMap, MaterialStatManifest},
|
item::{tool::AbilityMap, MaterialStatManifest},
|
||||||
ActiveAbilities, Beam, Body, CharacterState, Combo, ControlAction, Controller,
|
ActiveAbilities, Beam, Body, CharacterState, Combo, ControlAction, Controller,
|
||||||
ControllerInputs, Density, Energy, Health, InputAttr, InputKind, Inventory,
|
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,
|
link::Is,
|
||||||
mounting::Rider,
|
mounting::Rider,
|
||||||
@ -144,6 +145,7 @@ pub struct JoinData<'a> {
|
|||||||
pub alignment: Option<&'a comp::Alignment>,
|
pub alignment: Option<&'a comp::Alignment>,
|
||||||
pub terrain: &'a TerrainGrid,
|
pub terrain: &'a TerrainGrid,
|
||||||
pub mount_data: Option<&'a Is<Rider>>,
|
pub mount_data: Option<&'a Is<Rider>>,
|
||||||
|
pub stance: Option<&'a Stance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct JoinStruct<'a> {
|
pub struct JoinStruct<'a> {
|
||||||
@ -170,6 +172,7 @@ pub struct JoinStruct<'a> {
|
|||||||
pub alignment: Option<&'a comp::Alignment>,
|
pub alignment: Option<&'a comp::Alignment>,
|
||||||
pub terrain: &'a TerrainGrid,
|
pub terrain: &'a TerrainGrid,
|
||||||
pub mount_data: Option<&'a Is<Rider>>,
|
pub mount_data: Option<&'a Is<Rider>>,
|
||||||
|
pub stance: Option<&'a Stance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> JoinData<'a> {
|
impl<'a> JoinData<'a> {
|
||||||
@ -210,6 +213,7 @@ impl<'a> JoinData<'a> {
|
|||||||
terrain: j.terrain,
|
terrain: j.terrain,
|
||||||
active_abilities: j.active_abilities,
|
active_abilities: j.active_abilities,
|
||||||
mount_data: j.mount_data,
|
mount_data: j.mount_data,
|
||||||
|
stance: j.stance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,10 @@ use crate::{
|
|||||||
character_state::OutputEvents,
|
character_state::OutputEvents,
|
||||||
slot::{EquipSlot, Slot},
|
slot::{EquipSlot, Slot},
|
||||||
tool::Stats,
|
tool::Stats,
|
||||||
CharacterState, InputAttr, InputKind, InventoryAction, MeleeConstructor, StateUpdate,
|
CharacterState, InputAttr, InputKind, InventoryAction, MeleeConstructor, Stance,
|
||||||
|
StateUpdate,
|
||||||
},
|
},
|
||||||
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
idle,
|
idle,
|
||||||
@ -83,6 +85,9 @@ pub struct StaticData {
|
|||||||
/// Whether or not combo melee should function as a stance (where it remains
|
/// Whether or not combo melee should function as a stance (where it remains
|
||||||
/// in the character state after a strike has finished)
|
/// in the character state after a strike has finished)
|
||||||
pub is_stance: bool,
|
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<Stance>,
|
||||||
/// The amount of energy consumed with each swing
|
/// The amount of energy consumed with each swing
|
||||||
pub energy_cost_per_strike: f32,
|
pub energy_cost_per_strike: f32,
|
||||||
/// What key is used to press ability
|
/// 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 {
|
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
|
||||||
let mut update = StateUpdate::from(data);
|
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
|
// If is a stance, use M1 to control strikes, otherwise use the input that
|
||||||
// activated the ability
|
// activated the ability
|
||||||
let ability_input = if self.static_data.is_stance {
|
let ability_input = if self.static_data.is_stance {
|
||||||
|
@ -1034,7 +1034,7 @@ pub fn handle_jump(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKind) -> bool {
|
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_input) = input.into() {
|
||||||
if let Some((ability, from_offhand)) = data
|
if let Some((ability, from_offhand)) = data
|
||||||
.active_abilities
|
.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 {
|
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
|
/// Checked `Duration` addition. Computes `timer` + `dt`, applying relevant stat
|
||||||
|
@ -209,6 +209,7 @@ impl State {
|
|||||||
ecs.register::<comp::Alignment>();
|
ecs.register::<comp::Alignment>();
|
||||||
ecs.register::<comp::LootOwner>();
|
ecs.register::<comp::LootOwner>();
|
||||||
ecs.register::<comp::Admin>();
|
ecs.register::<comp::Admin>();
|
||||||
|
ecs.register::<comp::Stance>();
|
||||||
|
|
||||||
// Register components send from clients -> server
|
// Register components send from clients -> server
|
||||||
ecs.register::<comp::Controller>();
|
ecs.register::<comp::Controller>();
|
||||||
|
@ -9,7 +9,7 @@ use common::{
|
|||||||
character_state::OutputEvents,
|
character_state::OutputEvents,
|
||||||
inventory::item::{tool::AbilityMap, MaterialStatManifest},
|
inventory::item::{tool::AbilityMap, MaterialStatManifest},
|
||||||
ActiveAbilities, Beam, Body, CharacterState, Combo, Controller, Density, Energy, Health,
|
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,
|
StateUpdate, Stats, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
@ -51,6 +51,7 @@ pub struct ReadData<'a> {
|
|||||||
alignments: ReadStorage<'a, comp::Alignment>,
|
alignments: ReadStorage<'a, comp::Alignment>,
|
||||||
terrain: ReadExpect<'a, TerrainGrid>,
|
terrain: ReadExpect<'a, TerrainGrid>,
|
||||||
inventories: ReadStorage<'a, Inventory>,
|
inventories: ReadStorage<'a, Inventory>,
|
||||||
|
stances: ReadStorage<'a, Stance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ## Character Behavior System
|
/// ## Character Behavior System
|
||||||
@ -200,6 +201,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
alignment: read_data.alignments.get(entity),
|
alignment: read_data.alignments.get(entity),
|
||||||
terrain: &read_data.terrain,
|
terrain: &read_data.terrain,
|
||||||
mount_data: read_data.is_riders.get(entity),
|
mount_data: read_data.is_riders.get(entity),
|
||||||
|
stance: read_data.stances.get(entity),
|
||||||
};
|
};
|
||||||
|
|
||||||
for action in actions {
|
for action in actions {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use crate::{consts::MAX_PATH_DIST, data::*, util::entities_have_line_of_sight};
|
use crate::{consts::MAX_PATH_DIST, data::*, util::entities_have_line_of_sight};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
ability::{self, Ability, AbilityKind, ActiveAbilities, AuxiliaryAbility, Capability},
|
ability::{self, Ability, ActiveAbilities, AuxiliaryAbility, Capability},
|
||||||
buff::BuffKind,
|
buff::BuffKind,
|
||||||
item::tool::AbilityContext,
|
item::tool::AbilityContext,
|
||||||
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill},
|
skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill},
|
||||||
AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, ControlEvent,
|
AbilityInput, Agent, CharacterAbility, CharacterState, ControlAction, ControlEvent,
|
||||||
Controller, InputKind,
|
Controller, InputKind, Stance,
|
||||||
},
|
},
|
||||||
path::TraversalConfig,
|
path::TraversalConfig,
|
||||||
states::{self_buff, sprite_summon, utils::StageSection},
|
states::{self_buff, sprite_summon, utils::StageSection},
|
||||||
@ -476,15 +476,15 @@ impl<'a> AgentData<'a> {
|
|||||||
const INT_COUNTER_STANCE: usize = 0;
|
const INT_COUNTER_STANCE: usize = 0;
|
||||||
use ability::SwordStance;
|
use ability::SwordStance;
|
||||||
let stance = |stance| match stance {
|
let stance = |stance| match stance {
|
||||||
1 => SwordStance::Offensive,
|
1 => Stance::Sword(SwordStance::Offensive),
|
||||||
2 => SwordStance::Defensive,
|
2 => Stance::Sword(SwordStance::Defensive),
|
||||||
3 => SwordStance::Mobility,
|
3 => Stance::Sword(SwordStance::Mobility),
|
||||||
4 => SwordStance::Crippling,
|
4 => Stance::Sword(SwordStance::Crippling),
|
||||||
5 => SwordStance::Cleaving,
|
5 => Stance::Sword(SwordStance::Cleaving),
|
||||||
6 => SwordStance::Parrying,
|
6 => Stance::Sword(SwordStance::Parrying),
|
||||||
7 => SwordStance::Heavy,
|
7 => Stance::Sword(SwordStance::Heavy),
|
||||||
8 => SwordStance::Reaching,
|
8 => Stance::Sword(SwordStance::Reaching),
|
||||||
_ => SwordStance::Balanced,
|
_ => Stance::None,
|
||||||
};
|
};
|
||||||
if !agent.action_state.initialized {
|
if !agent.action_state.initialized {
|
||||||
// TODO: Don't always assume that if they have skill checked for, they have
|
// 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]) {
|
match stance(agent.action_state.int_counters[INT_COUNTER_STANCE]) {
|
||||||
SwordStance::Balanced => {
|
Stance::None => {
|
||||||
// Balanced finisher
|
// Balanced finisher
|
||||||
set_sword_ability(0, 8);
|
set_sword_ability(0, 8);
|
||||||
},
|
},
|
||||||
SwordStance::Offensive => {
|
Stance::Sword(SwordStance::Offensive) => {
|
||||||
// Offensive combo
|
// Offensive combo
|
||||||
set_sword_ability(0, 0);
|
set_sword_ability(0, 0);
|
||||||
// Offensive advance
|
// Offensive advance
|
||||||
@ -531,7 +531,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Offensive finisher
|
// Offensive finisher
|
||||||
set_sword_ability(2, 8);
|
set_sword_ability(2, 8);
|
||||||
},
|
},
|
||||||
SwordStance::Defensive => {
|
Stance::Sword(SwordStance::Defensive) => {
|
||||||
// Defensive combo
|
// Defensive combo
|
||||||
set_sword_ability(0, 3);
|
set_sword_ability(0, 3);
|
||||||
// Defensive retreat
|
// Defensive retreat
|
||||||
@ -539,7 +539,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Defensive bulwark
|
// Defensive bulwark
|
||||||
set_sword_ability(2, 10);
|
set_sword_ability(2, 10);
|
||||||
},
|
},
|
||||||
SwordStance::Mobility => {
|
Stance::Sword(SwordStance::Mobility) => {
|
||||||
// Mobility combo
|
// Mobility combo
|
||||||
set_sword_ability(0, 6);
|
set_sword_ability(0, 6);
|
||||||
// Mobility feint
|
// Mobility feint
|
||||||
@ -547,7 +547,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Mobility agility
|
// Mobility agility
|
||||||
set_sword_ability(2, 10);
|
set_sword_ability(2, 10);
|
||||||
},
|
},
|
||||||
SwordStance::Crippling => {
|
Stance::Sword(SwordStance::Crippling) => {
|
||||||
// Crippling combo
|
// Crippling combo
|
||||||
set_sword_ability(0, 1);
|
set_sword_ability(0, 1);
|
||||||
// Crippling finisher
|
// Crippling finisher
|
||||||
@ -557,7 +557,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Crippling gouge
|
// Crippling gouge
|
||||||
set_sword_ability(3, 10);
|
set_sword_ability(3, 10);
|
||||||
},
|
},
|
||||||
SwordStance::Cleaving => {
|
Stance::Sword(SwordStance::Cleaving) => {
|
||||||
// Cleaving combo
|
// Cleaving combo
|
||||||
set_sword_ability(0, 2);
|
set_sword_ability(0, 2);
|
||||||
// Cleaving finisher
|
// Cleaving finisher
|
||||||
@ -567,7 +567,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Cleaving dive
|
// Cleaving dive
|
||||||
set_sword_ability(3, 9);
|
set_sword_ability(3, 9);
|
||||||
},
|
},
|
||||||
SwordStance::Parrying => {
|
Stance::Sword(SwordStance::Parrying) => {
|
||||||
// Parrying combo
|
// Parrying combo
|
||||||
set_sword_ability(0, 4);
|
set_sword_ability(0, 4);
|
||||||
// Parrying parry
|
// Parrying parry
|
||||||
@ -577,7 +577,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Parrying counter
|
// Parrying counter
|
||||||
set_sword_ability(3, 8);
|
set_sword_ability(3, 8);
|
||||||
},
|
},
|
||||||
SwordStance::Heavy => {
|
Stance::Sword(SwordStance::Heavy) => {
|
||||||
// Heavy combo
|
// Heavy combo
|
||||||
set_sword_ability(0, 5);
|
set_sword_ability(0, 5);
|
||||||
// Heavy finisher
|
// Heavy finisher
|
||||||
@ -587,7 +587,7 @@ impl<'a> AgentData<'a> {
|
|||||||
// Heavy fortitude
|
// Heavy fortitude
|
||||||
set_sword_ability(3, 9);
|
set_sword_ability(3, 9);
|
||||||
},
|
},
|
||||||
SwordStance::Reaching => {
|
Stance::Sword(SwordStance::Reaching) => {
|
||||||
// Reaching combo
|
// Reaching combo
|
||||||
set_sword_ability(0, 7);
|
set_sword_ability(0, 7);
|
||||||
// Reaching charge
|
// Reaching charge
|
||||||
@ -680,20 +680,15 @@ impl<'a> AgentData<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let in_stance = |stance| {
|
let in_stance = |stance| {
|
||||||
if let CharacterState::ComboMelee2(c) = self.char_state {
|
if let Some(Stance::Sword(sword_stance)) = self.stance {
|
||||||
c.static_data.is_stance
|
stance == *sword_stance
|
||||||
&& c.static_data
|
|
||||||
.ability_info
|
|
||||||
.ability_meta
|
|
||||||
.and_then(|meta| meta.kind)
|
|
||||||
.map_or(false, |kind| AbilityKind::Sword(stance) == kind)
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match stance(agent.action_state.int_counters[INT_COUNTER_STANCE]) {
|
match stance(agent.action_state.int_counters[INT_COUNTER_STANCE]) {
|
||||||
SwordStance::Balanced => {
|
Stance::None => {
|
||||||
const BALANCED_FINISHER: FinisherMeleeData = FinisherMeleeData {
|
const BALANCED_FINISHER: FinisherMeleeData = FinisherMeleeData {
|
||||||
range: 2.5,
|
range: 2.5,
|
||||||
angle: 12.5,
|
angle: 12.5,
|
||||||
@ -717,7 +712,7 @@ impl<'a> AgentData<'a> {
|
|||||||
fallback_tactics(agent, controller);
|
fallback_tactics(agent, controller);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Offensive => {
|
Stance::Sword(SwordStance::Offensive) => {
|
||||||
const OFFENSIVE_COMBO: ComboMeleeData = ComboMeleeData {
|
const OFFENSIVE_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.0,
|
max_range: 2.0,
|
||||||
@ -786,7 +781,7 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Defensive => {
|
Stance::Sword(SwordStance::Defensive) => {
|
||||||
const DEFENSIVE_COMBO: ComboMeleeData = ComboMeleeData {
|
const DEFENSIVE_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.5,
|
max_range: 2.5,
|
||||||
@ -898,7 +893,7 @@ impl<'a> AgentData<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Mobility => {
|
Stance::Sword(SwordStance::Mobility) => {
|
||||||
const MOBILITY_COMBO: ComboMeleeData = ComboMeleeData {
|
const MOBILITY_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.5,
|
max_range: 2.5,
|
||||||
@ -998,7 +993,7 @@ impl<'a> AgentData<'a> {
|
|||||||
};
|
};
|
||||||
controller.inputs.move_dir.rotated_z(PI / 4.0 * dir);
|
controller.inputs.move_dir.rotated_z(PI / 4.0 * dir);
|
||||||
},
|
},
|
||||||
SwordStance::Crippling => {
|
Stance::Sword(SwordStance::Crippling) => {
|
||||||
const CRIPPLING_COMBO: ComboMeleeData = ComboMeleeData {
|
const CRIPPLING_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.5,
|
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
|
// TODO: Rewrite cleaving stance tactics when agents can consider multiple
|
||||||
// targets at once. Remove hack to make cleaving AI appear less frequently above
|
// targets at once. Remove hack to make cleaving AI appear less frequently above
|
||||||
// when doing so.
|
// when doing so.
|
||||||
@ -1188,7 +1183,7 @@ impl<'a> AgentData<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Parrying => {
|
Stance::Sword(SwordStance::Parrying) => {
|
||||||
const PARRYING_COMBO: ComboMeleeData = ComboMeleeData {
|
const PARRYING_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.5,
|
max_range: 2.5,
|
||||||
@ -1294,7 +1289,7 @@ impl<'a> AgentData<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Heavy => {
|
Stance::Sword(SwordStance::Heavy) => {
|
||||||
const HEAVY_COMBO: ComboMeleeData = ComboMeleeData {
|
const HEAVY_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 2.5,
|
max_range: 2.5,
|
||||||
@ -1371,7 +1366,7 @@ impl<'a> AgentData<'a> {
|
|||||||
advance(agent, controller, HEAVY_COMBO.max_range, HEAVY_COMBO.angle);
|
advance(agent, controller, HEAVY_COMBO.max_range, HEAVY_COMBO.angle);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
SwordStance::Reaching => {
|
Stance::Sword(SwordStance::Reaching) => {
|
||||||
const REACHING_COMBO: ComboMeleeData = ComboMeleeData {
|
const REACHING_COMBO: ComboMeleeData = ComboMeleeData {
|
||||||
min_range: 0.0,
|
min_range: 0.0,
|
||||||
max_range: 4.5,
|
max_range: 4.5,
|
||||||
@ -1622,7 +1617,7 @@ impl<'a> AgentData<'a> {
|
|||||||
enum ActionStateConditions {
|
enum ActionStateConditions {
|
||||||
ConditionStaffCanShockwave = 0,
|
ConditionStaffCanShockwave = 0,
|
||||||
}
|
}
|
||||||
let context = AbilityContext::try_from(Some(self.char_state));
|
let context = AbilityContext::try_from(self.stance);
|
||||||
let extract_ability = |input: AbilityInput| {
|
let extract_ability = |input: AbilityInput| {
|
||||||
self.active_abilities
|
self.active_abilities
|
||||||
.activate_ability(
|
.activate_ability(
|
||||||
|
@ -4,7 +4,8 @@ use common::{
|
|||||||
group,
|
group,
|
||||||
item::MaterialStatManifest,
|
item::MaterialStatManifest,
|
||||||
ActiveAbilities, Alignment, Body, CharacterState, Combo, Energy, Health, Inventory,
|
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,
|
link::Is,
|
||||||
mounting::Mount,
|
mounting::Mount,
|
||||||
@ -47,6 +48,7 @@ pub struct AgentData<'a> {
|
|||||||
pub buffs: Option<&'a Buffs>,
|
pub buffs: Option<&'a Buffs>,
|
||||||
pub stats: Option<&'a Stats>,
|
pub stats: Option<&'a Stats>,
|
||||||
pub poise: Option<&'a Poise>,
|
pub poise: Option<&'a Poise>,
|
||||||
|
pub stance: Option<&'a Stance>,
|
||||||
pub cached_spatial_grid: &'a common::CachedSpatialGrid,
|
pub cached_spatial_grid: &'a common::CachedSpatialGrid,
|
||||||
pub msm: &'a MaterialStatManifest,
|
pub msm: &'a MaterialStatManifest,
|
||||||
}
|
}
|
||||||
@ -182,6 +184,7 @@ pub struct ReadData<'a> {
|
|||||||
pub loot_owners: ReadStorage<'a, LootOwner>,
|
pub loot_owners: ReadStorage<'a, LootOwner>,
|
||||||
pub msm: ReadExpect<'a, MaterialStatManifest>,
|
pub msm: ReadExpect<'a, MaterialStatManifest>,
|
||||||
pub poises: ReadStorage<'a, Poise>,
|
pub poises: ReadStorage<'a, Poise>,
|
||||||
|
pub stances: ReadStorage<'a, Stance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Path {
|
pub enum Path {
|
||||||
|
@ -1480,3 +1480,14 @@ pub fn handle_make_admin(server: &mut Server, entity: EcsEntity, admin: comp::Ad
|
|||||||
.write_component_ignore_entity_dead(entity, admin);
|
.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::<comp::Stance>()
|
||||||
|
.get_mut(entity)
|
||||||
|
{
|
||||||
|
*stance = new_stance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,8 +13,8 @@ use entity_manipulation::{
|
|||||||
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
handle_aura, handle_bonk, handle_buff, handle_change_ability, handle_combo_change,
|
||||||
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
handle_delete, handle_destroy, handle_energy_change, handle_entity_attacked_hook,
|
||||||
handle_explosion, handle_health_change, handle_knockback, handle_land_on_ground,
|
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_make_admin, handle_parry_hook, handle_poise, handle_respawn, handle_stance_change,
|
||||||
handle_update_map_marker,
|
handle_teleport_to, handle_update_map_marker,
|
||||||
};
|
};
|
||||||
use group_manip::handle_group;
|
use group_manip::handle_group;
|
||||||
use information::handle_site_info;
|
use information::handle_site_info;
|
||||||
@ -300,6 +300,9 @@ impl Server {
|
|||||||
admin,
|
admin,
|
||||||
uuid,
|
uuid,
|
||||||
} => handle_make_admin(self, entity, admin, uuid),
|
} => handle_make_admin(self, entity, admin, uuid),
|
||||||
|
ServerEvent::ChangeStance { entity, stance } => {
|
||||||
|
handle_stance_change(self, entity, stance)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +288,7 @@ impl StateExt for State {
|
|||||||
.with(comp::Buffs::default())
|
.with(comp::Buffs::default())
|
||||||
.with(comp::Combo::default())
|
.with(comp::Combo::default())
|
||||||
.with(comp::Auras::default())
|
.with(comp::Auras::default())
|
||||||
|
.with(comp::Stance::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_object(&mut self, pos: comp::Pos, object: comp::object::Body) -> EcsEntityBuilder {
|
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::Buffs::default());
|
||||||
self.write_component_ignore_entity_dead(entity, comp::Auras::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::Combo::default());
|
||||||
|
self.write_component_ignore_entity_dead(entity, comp::Stance::default());
|
||||||
|
|
||||||
// Make sure physics components are updated
|
// Make sure physics components are updated
|
||||||
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
|
self.write_component_ignore_entity_dead(entity, comp::ForceUpdate::forced());
|
||||||
|
@ -203,6 +203,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
cached_spatial_grid: &read_data.cached_spatial_grid,
|
cached_spatial_grid: &read_data.cached_spatial_grid,
|
||||||
msm: &read_data.msm,
|
msm: &read_data.msm,
|
||||||
poise: read_data.poises.get(entity),
|
poise: read_data.poises.get(entity),
|
||||||
|
stance: read_data.stances.get(entity),
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
use i18n::Localization;
|
use i18n::Localization;
|
||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
comp::{BuffKind, Buffs, CharacterState, Energy, Health},
|
comp::{BuffKind, Buffs, Energy, Health, Stance},
|
||||||
resources::Time,
|
resources::Time,
|
||||||
};
|
};
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
@ -47,7 +47,7 @@ pub struct BuffsBar<'a> {
|
|||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
buffs: &'a Buffs,
|
buffs: &'a Buffs,
|
||||||
char_state: &'a CharacterState,
|
stance: Option<&'a Stance>,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
health: &'a Health,
|
health: &'a Health,
|
||||||
@ -63,7 +63,7 @@ impl<'a> BuffsBar<'a> {
|
|||||||
tooltip_manager: &'a mut TooltipManager,
|
tooltip_manager: &'a mut TooltipManager,
|
||||||
localized_strings: &'a Localization,
|
localized_strings: &'a Localization,
|
||||||
buffs: &'a Buffs,
|
buffs: &'a Buffs,
|
||||||
char_state: &'a CharacterState,
|
stance: Option<&'a Stance>,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
global_state: &'a GlobalState,
|
global_state: &'a GlobalState,
|
||||||
health: &'a Health,
|
health: &'a Health,
|
||||||
@ -78,7 +78,7 @@ impl<'a> BuffsBar<'a> {
|
|||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
localized_strings,
|
localized_strings,
|
||||||
buffs,
|
buffs,
|
||||||
char_state,
|
stance,
|
||||||
pulse,
|
pulse,
|
||||||
global_state,
|
global_state,
|
||||||
health,
|
health,
|
||||||
@ -138,7 +138,7 @@ impl<'a> Widget for BuffsBar<'a> {
|
|||||||
.desc_font_size(self.fonts.cyri.scale(12))
|
.desc_font_size(self.fonts.cyri.scale(12))
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.desc_text_color(TEXT_COLOR);
|
.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 {
|
if let BuffPosition::Bar = buff_position {
|
||||||
let decayed_health = 1.0 - self.health.maximum() / self.health.base_max();
|
let decayed_health = 1.0 - self.health.maximum() / self.health.base_max();
|
||||||
let show_health = self.global_state.settings.interface.always_show_bars
|
let show_health = self.global_state.settings.interface.always_show_bars
|
||||||
|
@ -359,9 +359,7 @@ impl<'a> Widget for Group<'a> {
|
|||||||
let uid_allocator = client_state.ecs().read_resource::<UidAllocator>();
|
let uid_allocator = client_state.ecs().read_resource::<UidAllocator>();
|
||||||
let bodies = client_state.ecs().read_storage::<common::comp::Body>();
|
let bodies = client_state.ecs().read_storage::<common::comp::Body>();
|
||||||
let poises = client_state.ecs().read_storage::<common::comp::Poise>();
|
let poises = client_state.ecs().read_storage::<common::comp::Poise>();
|
||||||
let char_states = client_state
|
let stances = client_state.ecs().read_storage::<common::comp::Stance>();
|
||||||
.ecs()
|
|
||||||
.read_storage::<common::comp::CharacterState>();
|
|
||||||
|
|
||||||
// Keep track of the total number of widget ids we are using for buffs
|
// Keep track of the total number of widget ids we are using for buffs
|
||||||
let mut total_buff_count = 0;
|
let mut total_buff_count = 0;
|
||||||
@ -377,7 +375,7 @@ impl<'a> Widget for Group<'a> {
|
|||||||
let is_leader = uid == leader;
|
let is_leader = uid == leader;
|
||||||
let body = entity.and_then(|entity| bodies.get(entity));
|
let body = entity.and_then(|entity| bodies.get(entity));
|
||||||
let poise = entity.and_then(|entity| poises.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 (
|
if let (
|
||||||
Some(stats),
|
Some(stats),
|
||||||
@ -387,10 +385,8 @@ impl<'a> Widget for Group<'a> {
|
|||||||
Some(energy),
|
Some(energy),
|
||||||
Some(body),
|
Some(body),
|
||||||
Some(poise),
|
Some(poise),
|
||||||
Some(char_state),
|
) = (stats, skill_set, inventory, health, energy, body, poise)
|
||||||
) = (
|
{
|
||||||
stats, skill_set, inventory, health, energy, body, poise, char_state,
|
|
||||||
) {
|
|
||||||
let combat_rating = combat::combat_rating(
|
let combat_rating = combat::combat_rating(
|
||||||
inventory, health, energy, poise, skill_set, *body, self.msm,
|
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)
|
.top_left_with_margins_on(state.ids.member_panels_bg[i], 26.0, 2.0)
|
||||||
.set(state.ids.member_energy[i], ui);
|
.set(state.ids.member_energy[i], ui);
|
||||||
if let Some(buffs) = buffs {
|
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
|
// Limit displayed buffs to 11
|
||||||
let buff_count = buff_icons.len().min(11);
|
let buff_count = buff_icons.len().min(11);
|
||||||
total_buff_count += buff_count;
|
total_buff_count += buff_count;
|
||||||
|
@ -580,29 +580,34 @@ impl<'a> BuffIcon<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn icons_vec(buffs: &comp::Buffs, char_state: &comp::CharacterState) -> Vec<Self> {
|
pub fn icons_vec(buffs: &comp::Buffs, stance: Option<&comp::Stance>) -> Vec<Self> {
|
||||||
buffs
|
buffs
|
||||||
.iter_active()
|
.iter_active()
|
||||||
.filter_map(BuffIcon::from_buffs)
|
.filter_map(BuffIcon::from_buffs)
|
||||||
.chain(BuffIcon::from_char_state(char_state).into_iter())
|
.chain(stance.and_then(BuffIcon::from_stance).into_iter())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_char_state(char_state: &comp::CharacterState) -> Option<Self> {
|
fn from_stance(stance: &comp::Stance) -> Option<Self> {
|
||||||
if let Some(ability_kind) = char_state
|
use comp::ability::{Stance, SwordStance};
|
||||||
.ability_info()
|
let id = match stance {
|
||||||
.and_then(|info| info.ability_meta)
|
Stance::Sword(SwordStance::Offensive) => "common.abilities.sword.offensive_combo",
|
||||||
.and_then(|meta| meta.kind)
|
Stance::Sword(SwordStance::Crippling) => "common.abilities.sword.crippling_combo",
|
||||||
{
|
Stance::Sword(SwordStance::Cleaving) => "common.abilities.sword.cleaving_combo",
|
||||||
let id = util::representative_ability_id(ability_kind);
|
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 {
|
Some(BuffIcon {
|
||||||
kind: BuffIconKind::Ability { ability_id: id },
|
kind: BuffIconKind::Ability { ability_id: id },
|
||||||
is_buff: true,
|
is_buff: true,
|
||||||
end_time: None,
|
end_time: None,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_buffs<'b, I: Iterator<Item = &'b comp::Buff>>(buffs: I) -> Option<Self> {
|
fn from_buffs<'b, I: Iterator<Item = &'b comp::Buff>>(buffs: I) -> Option<Self> {
|
||||||
@ -1489,7 +1494,7 @@ impl Hud {
|
|||||||
let poises = ecs.read_storage::<comp::Poise>();
|
let poises = ecs.read_storage::<comp::Poise>();
|
||||||
let alignments = ecs.read_storage::<comp::Alignment>();
|
let alignments = ecs.read_storage::<comp::Alignment>();
|
||||||
let is_mount = ecs.read_storage::<Is<Mount>>();
|
let is_mount = ecs.read_storage::<Is<Mount>>();
|
||||||
let char_states = ecs.read_storage::<comp::CharacterState>();
|
let stances = ecs.read_storage::<comp::Stance>();
|
||||||
let time = ecs.read_resource::<Time>();
|
let time = ecs.read_resource::<Time>();
|
||||||
|
|
||||||
// Check if there was a persistence load error of the skillset, and if so
|
// Check if there was a persistence load error of the skillset, and if so
|
||||||
@ -2230,7 +2235,7 @@ impl Hud {
|
|||||||
&uids,
|
&uids,
|
||||||
&inventories,
|
&inventories,
|
||||||
poises.maybe(),
|
poises.maybe(),
|
||||||
(alignments.maybe(), is_mount.maybe(), &char_states),
|
(alignments.maybe(), is_mount.maybe(), stances.maybe()),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.filter(|t| {
|
.filter(|t| {
|
||||||
@ -2253,7 +2258,7 @@ impl Hud {
|
|||||||
uid,
|
uid,
|
||||||
inventory,
|
inventory,
|
||||||
poise,
|
poise,
|
||||||
(alignment, is_mount, char_state),
|
(alignment, is_mount, stance),
|
||||||
)| {
|
)| {
|
||||||
// Use interpolated position if available
|
// Use interpolated position if available
|
||||||
let pos = interpolated.map_or(pos.0, |i| i.pos);
|
let pos = interpolated.map_or(pos.0, |i| i.pos);
|
||||||
@ -2304,7 +2309,7 @@ impl Hud {
|
|||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
},
|
},
|
||||||
char_state,
|
stance,
|
||||||
});
|
});
|
||||||
// Only render bubble if nearby or if its me and setting is on
|
// Only render bubble if nearby or if its me and setting is on
|
||||||
let bubble = if (dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) && !is_me)
|
let bubble = if (dist_sqr < SPEECH_BUBBLE_RANGE.powi(2) && !is_me)
|
||||||
@ -2849,7 +2854,6 @@ impl Hud {
|
|||||||
let stats = ecs.read_storage::<comp::Stats>();
|
let stats = ecs.read_storage::<comp::Stats>();
|
||||||
let skill_sets = ecs.read_storage::<comp::SkillSet>();
|
let skill_sets = ecs.read_storage::<comp::SkillSet>();
|
||||||
let buffs = ecs.read_storage::<comp::Buffs>();
|
let buffs = ecs.read_storage::<comp::Buffs>();
|
||||||
let char_states = ecs.read_storage::<comp::CharacterState>();
|
|
||||||
let msm = ecs.read_resource::<MaterialStatManifest>();
|
let msm = ecs.read_resource::<MaterialStatManifest>();
|
||||||
let time = ecs.read_resource::<Time>();
|
let time = ecs.read_resource::<Time>();
|
||||||
|
|
||||||
@ -2968,6 +2972,7 @@ impl Hud {
|
|||||||
let poises = ecs.read_storage::<comp::Poise>();
|
let poises = ecs.read_storage::<comp::Poise>();
|
||||||
let combos = ecs.read_storage::<comp::Combo>();
|
let combos = ecs.read_storage::<comp::Combo>();
|
||||||
let time = ecs.read_resource::<Time>();
|
let time = ecs.read_resource::<Time>();
|
||||||
|
let stances = ecs.read_storage::<comp::Stance>();
|
||||||
// Combo floater stuffs
|
// Combo floater stuffs
|
||||||
self.floaters.combo_floater = self.floaters.combo_floater.map(|mut f| {
|
self.floaters.combo_floater = self.floaters.combo_floater.map(|mut f| {
|
||||||
f.timer -= dt.as_secs_f64();
|
f.timer -= dt.as_secs_f64();
|
||||||
@ -2990,7 +2995,7 @@ impl Hud {
|
|||||||
skillsets.get(entity),
|
skillsets.get(entity),
|
||||||
bodies.get(entity),
|
bodies.get(entity),
|
||||||
) {
|
) {
|
||||||
let context = AbilityContext::try_from(char_states.get(entity));
|
let context = AbilityContext::try_from(stances.get(entity));
|
||||||
match Skillbar::new(
|
match Skillbar::new(
|
||||||
client,
|
client,
|
||||||
&info,
|
&info,
|
||||||
@ -3018,7 +3023,6 @@ impl Hud {
|
|||||||
self.floaters.combo_floater,
|
self.floaters.combo_floater,
|
||||||
context,
|
context,
|
||||||
combos.get(entity),
|
combos.get(entity),
|
||||||
char_states.get(entity),
|
|
||||||
)
|
)
|
||||||
.set(self.ids.skillbar, ui_widgets)
|
.set(self.ids.skillbar, ui_widgets)
|
||||||
{
|
{
|
||||||
@ -3138,11 +3142,10 @@ impl Hud {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buffs
|
// Buffs
|
||||||
if let (Some(player_buffs), Some(health), Some(energy), Some(char_state)) = (
|
if let (Some(player_buffs), Some(health), Some(energy)) = (
|
||||||
buffs.get(info.viewpoint_entity),
|
buffs.get(info.viewpoint_entity),
|
||||||
healths.get(entity),
|
healths.get(entity),
|
||||||
energies.get(entity),
|
energies.get(entity),
|
||||||
char_states.get(entity),
|
|
||||||
) {
|
) {
|
||||||
for event in BuffsBar::new(
|
for event in BuffsBar::new(
|
||||||
&self.imgs,
|
&self.imgs,
|
||||||
@ -3151,7 +3154,7 @@ impl Hud {
|
|||||||
tooltip_manager,
|
tooltip_manager,
|
||||||
i18n,
|
i18n,
|
||||||
player_buffs,
|
player_buffs,
|
||||||
char_state,
|
stances.get(entity),
|
||||||
self.pulse,
|
self.pulse,
|
||||||
global_state,
|
global_state,
|
||||||
health,
|
health,
|
||||||
@ -3463,7 +3466,7 @@ impl Hud {
|
|||||||
bodies.get(entity),
|
bodies.get(entity),
|
||||||
poises.get(entity),
|
poises.get(entity),
|
||||||
) {
|
) {
|
||||||
let context = AbilityContext::try_from(char_states.get(entity));
|
let context = AbilityContext::try_from(stances.get(entity));
|
||||||
for event in Diary::new(
|
for event in Diary::new(
|
||||||
&self.show,
|
&self.show,
|
||||||
client,
|
client,
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
ui::{fonts::Fonts, Ingameable},
|
ui::{fonts::Fonts, Ingameable},
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{Buffs, CharacterState, Energy, Health, SpeechBubble, SpeechBubbleType},
|
comp::{Buffs, Energy, Health, SpeechBubble, SpeechBubbleType, Stance},
|
||||||
resources::Time,
|
resources::Time,
|
||||||
};
|
};
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
@ -72,7 +72,7 @@ pub struct Info<'a> {
|
|||||||
pub buffs: &'a Buffs,
|
pub buffs: &'a Buffs,
|
||||||
pub energy: Option<&'a Energy>,
|
pub energy: Option<&'a Energy>,
|
||||||
pub combat_rating: f32,
|
pub combat_rating: f32,
|
||||||
pub char_state: &'a CharacterState,
|
pub stance: Option<&'a Stance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether to show the healthbar
|
/// Determines whether to show the healthbar
|
||||||
@ -168,9 +168,7 @@ impl<'a> Ingameable for Overhead<'a> {
|
|||||||
self.info.map_or(0, |info| {
|
self.info.map_or(0, |info| {
|
||||||
2 + 1
|
2 + 1
|
||||||
+ if self.bubble.is_none() {
|
+ if self.bubble.is_none() {
|
||||||
2 * BuffIcon::icons_vec(info.buffs, info.char_state)
|
2 * BuffIcon::icons_vec(info.buffs, info.stance).len().min(11)
|
||||||
.len()
|
|
||||||
.min(11)
|
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
@ -209,7 +207,7 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
buffs,
|
buffs,
|
||||||
energy,
|
energy,
|
||||||
combat_rating,
|
combat_rating,
|
||||||
char_state,
|
stance,
|
||||||
}) = self.info
|
}) = self.info
|
||||||
{
|
{
|
||||||
// Used to set healthbar colours based on hp_percentage
|
// Used to set healthbar colours based on hp_percentage
|
||||||
@ -239,7 +237,7 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
};
|
};
|
||||||
// Buffs
|
// Buffs
|
||||||
// Alignment
|
// Alignment
|
||||||
let buff_icons = BuffIcon::icons_vec(buffs, char_state);
|
let buff_icons = BuffIcon::icons_vec(buffs, stance);
|
||||||
let buff_count = buff_icons.len().min(11);
|
let buff_count = buff_icons.len().min(11);
|
||||||
Rectangle::fill_with([168.0, 100.0], color::TRANSPARENT)
|
Rectangle::fill_with([168.0, 100.0], color::TRANSPARENT)
|
||||||
.x_y(-1.0, name_y + 60.0)
|
.x_y(-1.0, name_y + 60.0)
|
||||||
|
@ -30,8 +30,7 @@ use common::comp::{
|
|||||||
ItemDesc, MaterialStatManifest,
|
ItemDesc, MaterialStatManifest,
|
||||||
},
|
},
|
||||||
skillset::SkillGroupKind,
|
skillset::SkillGroupKind,
|
||||||
Ability, ActiveAbilities, Body, CharacterState, Combo, Energy, Health, Inventory, Poise,
|
Ability, ActiveAbilities, Body, Combo, Energy, Health, Inventory, Poise, PoiseState, SkillSet,
|
||||||
PoiseState, SkillSet,
|
|
||||||
};
|
};
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color,
|
color,
|
||||||
@ -313,7 +312,6 @@ pub struct Skillbar<'a> {
|
|||||||
combo_floater: Option<ComboFloater>,
|
combo_floater: Option<ComboFloater>,
|
||||||
context: Option<AbilityContext>,
|
context: Option<AbilityContext>,
|
||||||
combo: Option<&'a Combo>,
|
combo: Option<&'a Combo>,
|
||||||
char_state: Option<&'a CharacterState>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Skillbar<'a> {
|
impl<'a> Skillbar<'a> {
|
||||||
@ -345,7 +343,6 @@ impl<'a> Skillbar<'a> {
|
|||||||
combo_floater: Option<ComboFloater>,
|
combo_floater: Option<ComboFloater>,
|
||||||
context: Option<AbilityContext>,
|
context: Option<AbilityContext>,
|
||||||
combo: Option<&'a Combo>,
|
combo: Option<&'a Combo>,
|
||||||
char_state: Option<&'a CharacterState>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client,
|
client,
|
||||||
@ -375,7 +372,6 @@ impl<'a> Skillbar<'a> {
|
|||||||
combo_floater,
|
combo_floater,
|
||||||
context,
|
context,
|
||||||
combo,
|
combo,
|
||||||
char_state,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,18 +1084,6 @@ impl<'a> Skillbar<'a> {
|
|||||||
.active_abilities
|
.active_abilities
|
||||||
.and_then(|a| Ability::from(a.primary).ability_id(Some(self.inventory), self.context));
|
.and_then(|a| Ability::from(a.primary).ability_id(Some(self.inventory), self.context));
|
||||||
|
|
||||||
let primary_ability_id = if let Some(override_id) = self
|
|
||||||
.char_state
|
|
||||||
.and_then(|cs| cs.ability_info())
|
|
||||||
.and_then(|info| info.ability_meta)
|
|
||||||
.and_then(|meta| meta.kind)
|
|
||||||
.map(util::representative_ability_id)
|
|
||||||
{
|
|
||||||
Some(override_id)
|
|
||||||
} else {
|
|
||||||
primary_ability_id
|
|
||||||
};
|
|
||||||
|
|
||||||
let (primary_ability_title, primary_ability_desc) =
|
let (primary_ability_title, primary_ability_desc) =
|
||||||
util::ability_description(primary_ability_id.unwrap_or(""), self.localized_strings);
|
util::ability_description(primary_ability_id.unwrap_or(""), self.localized_strings);
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use super::img_ids;
|
use super::img_ids;
|
||||||
use common::{
|
use common::{
|
||||||
comp::{
|
comp::{
|
||||||
ability::{AbilityKind, SwordStance},
|
|
||||||
inventory::trade_pricing::TradePricing,
|
inventory::trade_pricing::TradePricing,
|
||||||
item::{
|
item::{
|
||||||
armor::{Armor, ArmorKind, Protection},
|
armor::{Armor, ArmorKind, Protection},
|
||||||
@ -431,17 +430,3 @@ pub fn ability_description<'a>(
|
|||||||
|
|
||||||
(loc.get_msg(&ability), loc.get_attr(&ability, "desc"))
|
(loc.get_msg(&ability), loc.get_attr(&ability, "desc"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn representative_ability_id(ability_kind: AbilityKind) -> &'static str {
|
|
||||||
match ability_kind {
|
|
||||||
AbilityKind::Sword(SwordStance::Balanced) => "common.abilities.sword.balanced_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Offensive) => "common.abilities.sword.offensive_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Crippling) => "common.abilities.sword.crippling_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Cleaving) => "common.abilities.sword.cleaving_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Defensive) => "common.abilities.sword.defensive_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Parrying) => "common.abilities.sword.parrying_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Heavy) => "common.abilities.sword.heavy_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Mobility) => "common.abilities.sword.mobility_combo",
|
|
||||||
AbilityKind::Sword(SwordStance::Reaching) => "common.abilities.sword.reaching_combo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -34,7 +34,7 @@ use common::{
|
|||||||
inventory::slot::EquipSlot,
|
inventory::slot::EquipSlot,
|
||||||
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
|
item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
|
||||||
Body, CharacterState, Collider, Controller, Health, Inventory, Item, ItemKey, Last,
|
Body, CharacterState, Collider, Controller, Health, Inventory, Item, ItemKey, Last,
|
||||||
LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Vel,
|
LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Scale, Stance, Vel,
|
||||||
},
|
},
|
||||||
link::Is,
|
link::Is,
|
||||||
mounting::Rider,
|
mounting::Rider,
|
||||||
@ -747,7 +747,7 @@ impl FigureMgr {
|
|||||||
item,
|
item,
|
||||||
light_emitter,
|
light_emitter,
|
||||||
is_rider,
|
is_rider,
|
||||||
collider,
|
(collider, stance),
|
||||||
),
|
),
|
||||||
) in (
|
) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
@ -765,7 +765,10 @@ impl FigureMgr {
|
|||||||
ecs.read_storage::<Item>().maybe(),
|
ecs.read_storage::<Item>().maybe(),
|
||||||
ecs.read_storage::<LightEmitter>().maybe(),
|
ecs.read_storage::<LightEmitter>().maybe(),
|
||||||
ecs.read_storage::<Is<Rider>>().maybe(),
|
ecs.read_storage::<Is<Rider>>().maybe(),
|
||||||
|
(
|
||||||
ecs.read_storage::<Collider>().maybe(),
|
ecs.read_storage::<Collider>().maybe(),
|
||||||
|
ecs.read_storage::<Stance>().maybe(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -917,7 +920,7 @@ impl FigureMgr {
|
|||||||
let second_tool_spec = second_tool_spec.as_deref();
|
let second_tool_spec = second_tool_spec.as_deref();
|
||||||
let hands = (active_tool_hand, second_tool_hand);
|
let hands = (active_tool_hand, second_tool_hand);
|
||||||
|
|
||||||
let context = AbilityContext::try_from(character);
|
let context = AbilityContext::try_from(stance);
|
||||||
|
|
||||||
let ability_id = character.and_then(|c| {
|
let ability_id = character.and_then(|c| {
|
||||||
c.ability_info()
|
c.ability_info()
|
||||||
|
Reference in New Issue
Block a user