Heavy stance skill abilities.

This commit is contained in:
Sam 2022-11-16 21:28:19 -05:00
parent 57806d7be9
commit ed0de15a5a
12 changed files with 178 additions and 247 deletions

View File

@ -2,38 +2,24 @@ ComboMelee2(
strikes: [
(
melee_constructor: (
kind: Slash(
damage: 5,
poise: 0,
kind: Bash(
damage: 20,
poise: 50,
knockback: 0,
energy_regen: 5,
energy_regen: 0,
),
range: 3.0,
range: 1.0,
angle: 45.0,
),
buildup_duration: 0.15,
swing_duration: 0.05,
swing_duration: 0.1,
hit_timing: 0.5,
recover_duration: 0.1,
ori_modifier: 0.6,
),
(
melee_constructor: (
kind: Slash(
damage: 10,
poise: 0,
knockback: 0,
energy_regen: 7.5,
),
range: 3.0,
angle: 45.0,
),
buildup_duration: 0.1,
swing_duration: 0.1,
hit_timing: 0.5,
recover_duration: 0.2,
ori_modifier: 0.6,
),
],
energy_cost_per_strike: 0,
energy_cost_per_strike: 25,
meta: (
init_event: Some(EnterStance(Sword(Heavy))),
),
)

View File

@ -3,16 +3,16 @@ ComboMelee2(
(
melee_constructor: (
kind: Slash(
damage: 5,
poise: 0,
damage: 15,
poise: 10,
knockback: 0,
energy_regen: 5,
energy_regen: 0,
),
range: 3.0,
angle: 45.0,
range: 4.0,
angle: 15.0,
),
buildup_duration: 0.15,
swing_duration: 0.05,
buildup_duration: 0.3,
swing_duration: 0.15,
hit_timing: 0.5,
recover_duration: 0.1,
ori_modifier: 0.6,
@ -20,20 +20,24 @@ ComboMelee2(
(
melee_constructor: (
kind: Slash(
damage: 10,
poise: 0,
damage: 22,
poise: 20,
knockback: 0,
energy_regen: 7.5,
energy_regen: 0,
),
range: 3.0,
angle: 45.0,
range: 4.0,
angle: 15.0,
),
buildup_duration: 0.1,
buildup_duration: 0.25,
swing_duration: 0.1,
hit_timing: 0.5,
recover_duration: 0.2,
recover_duration: 0.25,
ori_modifier: 0.6,
),
],
energy_cost_per_strike: 0,
energy_cost_per_strike: 10,
auto_progress: true,
meta: (
init_event: Some(EnterStance(Sword(Heavy))),
),
)

View File

@ -14,36 +14,32 @@
// Sword
(UnlockGroup(Weapon(Sword)), 1),
(Sword(BalancedFinisher), 1),
(Sword(OffensiveStance), 1),
(Sword(OffensiveFinisher), 1),
(Sword(OffensiveAdvance), 1),
(Sword(CripplingStance), 1),
(Sword(CripplingFinisher), 1),
(Sword(CripplingStrike), 1),
(Sword(CripplingGouge), 1),
(Sword(CleavingStance), 1),
(Sword(CleavingFinisher), 1),
(Sword(CleavingSpin), 1),
(Sword(CleavingDive), 1),
(Sword(DefensiveStance), 1),
(Sword(DefensiveBulwark), 1),
(Sword(DefensiveRetreat), 1),
(Sword(ParryingStance), 1),
(Sword(ParryingParry), 1),
(Sword(ParryingRiposte), 1),
(Sword(ParryingCounter), 1),
(Sword(HeavyStance), 1),
(Sword(HeavyFinisher), 1),
(Sword(CrescentSlash), 1),
(Sword(Cascade), 1),
(Sword(CrossCut), 1),
(Sword(Skewer), 1),
(Sword(FellStrike), 1),
(Sword(Finisher), 1),
(Sword(HeavyWindmillSlash), 1),
(Sword(HeavyPommelStrike), 1),
(Sword(HeavyFortitude), 1),
(Sword(MobilityStance), 1),
(Sword(MobilityFeint), 1),
(Sword(MobilityAgility), 1),
(Sword(ReachingStance), 1),
(Sword(ReachingCharge), 1),
(Sword(ReachingFlurry), 1),
(Sword(ReachingSkewer), 1),
(Sword(HeavyPillarThrust), 1),
(Sword(CleavingEarthSplitter), 1),
(Sword(CleavingWhirlwindSlice), 1),
(Sword(CleavingSkySplitter), 1),
(Sword(CleavingBladeFever), 1),
(Sword(AgileQuickDraw), 1),
(Sword(AgileFeint), 1),
(Sword(AgileDancingEdge), 1),
(Sword(AgileFlurry), 1),
(Sword(CripplingHamstring), 1),
(Sword(CripplingGouge), 1),
(Sword(CripplingBloodyGash), 1),
(Sword(CripplingEviscerate), 1),
(Sword(DefensiveRiposte), 1),
(Sword(DefensiveDisengage), 1),
(Sword(DefensiveStalwartSword), 1),
(Sword(DefensiveDeflect), 1),
// Axe
(UnlockGroup(Weapon(Axe)), 1),

View File

@ -470,8 +470,7 @@ impl From<&CharacterState> for CharacterAbilityType {
| CharacterState::UseItem(_)
| CharacterState::SpriteInteract(_)
| CharacterState::Skate(_)
| CharacterState::Wallrun(_)
| CharacterState::BasicStance(_) => Self::Other,
| CharacterState::Wallrun(_) => Self::Other,
}
}
}
@ -577,6 +576,8 @@ pub enum CharacterAbility {
strikes: Vec<combo_melee2::Strike<f32>>,
energy_cost_per_strike: f32,
#[serde(default)]
auto_progress: bool,
#[serde(default)]
meta: AbilityMeta,
},
LeapMelee {
@ -801,12 +802,6 @@ pub enum CharacterAbility {
#[serde(default)]
meta: AbilityMeta,
},
BasicStance {
buildup_duration: f32,
stance: Stance,
#[serde(default)]
meta: AbilityMeta,
},
}
impl Default for CharacterAbility {
@ -907,8 +902,7 @@ impl CharacterAbility {
| CharacterAbility::Blink { .. }
| CharacterAbility::Music { .. }
| CharacterAbility::BasicSummon { .. }
| CharacterAbility::SpriteSummon { .. }
| CharacterAbility::BasicStance { .. } => true,
| CharacterAbility::SpriteSummon { .. } => true,
}
}
@ -1085,6 +1079,7 @@ impl CharacterAbility {
ComboMelee2 {
ref mut strikes,
ref mut energy_cost_per_strike,
auto_progress: _,
meta: _,
} => {
*energy_cost_per_strike /= stats.energy_efficiency;
@ -1462,13 +1457,6 @@ impl CharacterAbility {
*energy_cost /= stats.energy_efficiency;
*melee_constructor = melee_constructor.adjusted_by_stats(stats);
},
BasicStance {
ref mut buildup_duration,
stance: _,
meta: _,
} => {
*buildup_duration /= stats.speed;
},
}
self
}
@ -1510,8 +1498,7 @@ impl CharacterAbility {
| Blink { .. }
| Music { .. }
| BasicSummon { .. }
| SpriteSummon { .. }
| BasicStance { .. } => 0.0,
| SpriteSummon { .. } => 0.0,
}
}
@ -1552,8 +1539,7 @@ impl CharacterAbility {
| Blink { .. }
| Music { .. }
| BasicSummon { .. }
| SpriteSummon { .. }
| BasicStance { .. } => 0,
| SpriteSummon { .. } => 0,
}
}
@ -1586,8 +1572,7 @@ impl CharacterAbility {
| Music { meta, .. }
| DiveMelee { meta, .. }
| RiposteMelee { meta, .. }
| RapidMelee { meta, .. }
| BasicStance { meta, .. } => *meta,
| RapidMelee { meta, .. } => *meta,
}
}
@ -2283,11 +2268,13 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
CharacterAbility::ComboMelee2 {
strikes,
energy_cost_per_strike,
auto_progress,
meta: _,
} => CharacterState::ComboMelee2(combo_melee2::Data {
static_data: combo_melee2::StaticData {
strikes: strikes.iter().map(|s| s.to_duration()).collect(),
energy_cost_per_strike: *energy_cost_per_strike,
auto_progress: *auto_progress,
ability_info,
},
exhausted: false,
@ -2803,18 +2790,6 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
stage_section: StageSection::Buildup,
exhausted: false,
}),
CharacterAbility::BasicStance {
buildup_duration,
stance,
meta: _,
} => CharacterState::BasicStance(basic_stance::Data {
static_data: basic_stance::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
stance: *stance,
ability_info,
},
timer: Duration::default(),
}),
}
}
}
@ -2824,6 +2799,8 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState {
pub struct AbilityMeta {
#[serde(default)]
pub capabilities: Capability,
#[serde(default)]
pub init_event: Option<AbilityInitEvent>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
@ -2857,6 +2834,11 @@ pub enum Stance {
Sword(SwordStance),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AbilityInitEvent {
EnterStance(Stance),
}
impl Default for Stance {
fn default() -> Self { Self::None }
}

View File

@ -143,8 +143,6 @@ pub enum CharacterState {
/// A series of consecutive, identical attacks that only go through buildup
/// and recover once for the entire state
RapidMelee(rapid_melee::Data),
/// Causes the character to enter a new stance, or leave the current stance
BasicStance(basic_stance::Data),
}
impl CharacterState {
@ -184,7 +182,6 @@ impl CharacterState {
| CharacterState::DiveMelee(_)
| CharacterState::RiposteMelee(_)
| CharacterState::RapidMelee(_)
| CharacterState::BasicStance(_)
)
}
@ -266,7 +263,6 @@ impl CharacterState {
| CharacterState::DiveMelee(_)
| CharacterState::RiposteMelee(_)
| CharacterState::RapidMelee(_)
| CharacterState::BasicStance(_)
)
}
@ -402,7 +398,6 @@ impl CharacterState {
| CharacterState::Music(_)
| CharacterState::RiposteMelee(_)
| CharacterState::RapidMelee(_)
| CharacterState::BasicStance(_)
)
}
@ -471,7 +466,6 @@ impl CharacterState {
CharacterState::DiveMelee(data) => data.behavior(j, output_events),
CharacterState::RiposteMelee(data) => data.behavior(j, output_events),
CharacterState::RapidMelee(data) => data.behavior(j, output_events),
CharacterState::BasicStance(data) => data.behavior(j, output_events),
}
}
@ -526,7 +520,6 @@ impl CharacterState {
CharacterState::DiveMelee(data) => data.handle_event(j, output_events, action),
CharacterState::RiposteMelee(data) => data.handle_event(j, output_events, action),
CharacterState::RapidMelee(data) => data.handle_event(j, output_events, action),
CharacterState::BasicStance(data) => data.handle_event(j, output_events, action),
}
}
@ -580,7 +573,6 @@ impl CharacterState {
CharacterState::DiveMelee(data) => Some(data.static_data.ability_info),
CharacterState::RiposteMelee(data) => Some(data.static_data.ability_info),
CharacterState::RapidMelee(data) => Some(data.static_data.ability_info),
CharacterState::BasicStance(data) => Some(data.static_data.ability_info),
}
}
@ -626,7 +618,6 @@ impl CharacterState {
CharacterState::DiveMelee(data) => Some(data.stage_section),
CharacterState::RiposteMelee(data) => Some(data.stage_section),
CharacterState::RapidMelee(data) => Some(data.stage_section),
CharacterState::BasicStance(_) => Some(StageSection::Buildup),
}
}
@ -821,10 +812,6 @@ impl CharacterState {
recover: Some(data.static_data.recover_duration),
..Default::default()
}),
CharacterState::BasicStance(data) => Some(DurationsInfo {
buildup: Some(data.static_data.buildup_duration),
..Default::default()
}),
}
}
@ -870,7 +857,6 @@ impl CharacterState {
CharacterState::DiveMelee(data) => Some(data.timer),
CharacterState::RiposteMelee(data) => Some(data.timer),
CharacterState::RapidMelee(data) => Some(data.timer),
CharacterState::BasicStance(data) => Some(data.timer),
}
}
}

View File

@ -1,52 +0,0 @@
use super::utils::*;
use crate::{
comp::{character_state::OutputEvents, CharacterState, Stance, StateUpdate},
event::ServerEvent,
states::behavior::{CharacterBehavior, JoinData},
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
/// Separated out to condense update portions of character state
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct StaticData {
pub buildup_duration: Duration,
pub stance: Stance,
pub ability_info: AbilityInfo,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Data {
pub static_data: StaticData,
pub timer: Duration,
}
impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
let mut update = StateUpdate::from(data);
handle_orientation(data, &mut update, 1.0, None);
handle_move(data, &mut update, 1.0);
handle_jump(data, output_events, &mut update, 1.0);
handle_interrupts(data, &mut update);
if self.timer < self.static_data.buildup_duration {
if let CharacterState::BasicStance(c) = &mut update.character {
c.timer = tick_attack_or_default(data, self.timer, None);
}
} else {
let stance = if Some(self.static_data.stance) == data.stance.copied() {
Stance::None
} else {
self.static_data.stance
};
output_events.emit_server(ServerEvent::ChangeStance {
entity: data.entity,
stance,
});
end_ability(data, &mut update);
}
update
}
}

View File

@ -76,7 +76,8 @@ pub struct StaticData {
pub strikes: Vec<Strike<Duration>>,
/// The amount of energy consumed with each swing
pub energy_cost_per_strike: f32,
/// What key is used to press ability
/// Whether or not the state should progress through all strikes automatically once the state is entered
pub auto_progress: bool,
pub ability_info: AbilityInfo,
}
/// A sequence of attacks that can incrementally become faster and more
@ -132,7 +133,7 @@ impl CharacterBehavior for Data {
if let Some(movement) = strike_data.movement.swing {
handle_forced_movement(data, &mut update, movement);
}
if input_is_pressed(data, self.static_data.ability_info.input) {
if input_is_pressed(data, self.static_data.ability_info.input) || self.static_data.auto_progress {
if let CharacterState::ComboMelee2(c) = &mut update.character {
// Only have the next strike skip the recover period of this strike if not
// every strike in the combo is complete yet

View File

@ -3,7 +3,6 @@ pub mod basic_beam;
pub mod basic_block;
pub mod basic_melee;
pub mod basic_ranged;
pub mod basic_stance;
pub mod basic_summon;
pub mod behavior;
pub mod blink;

View File

@ -2,7 +2,7 @@ use crate::{
astar::Astar,
combat,
comp::{
ability::{Ability, AbilityInput, AbilityMeta, Capability},
ability::{Ability, AbilityInput, AbilityMeta, Capability, AbilityInitEvent},
arthropod, biped_large, biped_small, bird_medium,
character_state::OutputEvents,
controller::InventoryManip,
@ -1031,7 +1031,7 @@ pub fn handle_jump(
.is_some()
}
fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKind) -> bool {
fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, output_events: &mut OutputEvents, input: InputKind) -> bool {
let context = AbilityContext::from(data.stance);
if let Some(ability_input) = input.into() {
if let Some((ability, from_offhand)) = data
@ -1052,6 +1052,13 @@ fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKin
AbilityInfo::from_input(data, from_offhand, input, ability.ability_meta()),
data,
));
if let Some(init_event) = ability.ability_meta().init_event {
match init_event {
AbilityInitEvent::EnterStance(stance) => {
output_events.emit_server(ServerEvent::ChangeStance { entity: data.entity, stance });
},
}
}
update.used_inputs.push(input);
return true;
}
@ -1067,7 +1074,7 @@ pub fn handle_input(
) {
match input {
InputKind::Primary | InputKind::Secondary | InputKind::Ability(_) => {
handle_ability(data, update, input);
handle_ability(data, update, output_events, input);
},
InputKind::Roll => {
handle_dodge_input(data, update);

View File

@ -2,6 +2,7 @@ use common::{
combat,
comp::{
self,
ability::Stance,
item::MaterialStatManifest,
skills::{GeneralSkill, Skill},
Body, CharacterState, Combo, Energy, Health, Inventory, Poise, Pos, SkillSet, Stats,
@ -140,8 +141,13 @@ impl<'a> System<'a> for Sys {
}
// Update energies and poises
for (character_state, mut energy, mut poise) in
(&read_data.char_states, &mut energies, &mut poises).join()
for (entity, character_state, mut energy, mut poise) in (
&read_data.entities,
&read_data.char_states,
&mut energies,
&mut poises,
)
.join()
{
match character_state {
// Sitting accelerates recharging energy the most
@ -194,8 +200,7 @@ impl<'a> System<'a> for Sys {
| CharacterState::FinisherMelee(_)
| CharacterState::DiveMelee(_)
| CharacterState::RiposteMelee(_)
| CharacterState::RapidMelee(_)
| CharacterState::BasicStance(_) => {
| CharacterState::RapidMelee(_) => {
if energy.needs_regen_rate_reset() {
energy.reset_regen_rate();
}

View File

@ -112,6 +112,92 @@ impl Animation for ComboAnimation {
_ => {},
}
},
Some("common.abilities.sword.heavy_windmill_slash") => {
let (move1, move2) = if strike == current_strike {
match stage_section {
Some(StageSection::Buildup) => (anim_time, 0.0),
Some(StageSection::Action) => (1.0, anim_time),
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
}
} else {
(1.0, 1.0)
};
let move1 = move1 * multi_strike_pullback;
let move2 = move2 * multi_strike_pullback;
match strike {
0 => {
next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2);
next.hand_l.orientation = Quaternion::rotation_x(s_a.shl.3)
* Quaternion::rotation_y(s_a.shl.4);
next.hand_r.position = Vec3::new(
-s_a.sc.0 + 6.0 + move1 * -12.0,
-4.0 + move1 * 3.0,
-2.0,
);
next.hand_r.orientation = Quaternion::rotation_x(0.9 + move1 * 0.5);
next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1, s_a.sc.2);
next.control.orientation = Quaternion::rotation_x(s_a.sc.3);
next.chest.orientation = Quaternion::rotation_z(move1 * 0.2);
next.control.orientation.rotate_x(move1 * 1.3);
next.control.position += Vec3::new(0.0, 0.0, move1 * 6.0);
next.control.orientation.rotate_y(move1 * -0.3);
next.chest.orientation.rotate_z(move2 * -0.3);
next.control.orientation.rotate_x(move2 * -2.5);
next.control.orientation.rotate_z(move2 * -0.4);
next.control.position +=
Vec3::new(move2 * 7.0, move2 * 4.0, move2 * -7.0);
},
1 => {
next.control.position +=
Vec3::new(move1 * 3.0, move1 * -4.0, move1 * 7.0);
next.control.orientation.rotate_x(move1 * 2.5);
next.chest.orientation.rotate_z(move2 * 0.4);
next.control.orientation.rotate_x(move2 * -2.5);
next.control.position +=
Vec3::new(move2 * -5.0, move2 * 4.0, move2 * -7.0);
},
_ => {},
}
},
Some("common.abilities.sword.heavy_pommel_strike") => {
let (move1, move2) = match stage_section {
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0),
Some(StageSection::Action) => (1.0, anim_time.powi(2)),
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
};
let move1 = move1 * multi_strike_pullback;
let move2 = move2 * multi_strike_pullback;
next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2);
next.hand_l.orientation =
Quaternion::rotation_x(s_a.shl.3) * Quaternion::rotation_y(s_a.shl.4);
next.hand_r.position =
Vec3::new(-s_a.sc.0 + 6.0 + move1 * -12.0, -4.0 + move1 * 3.0, -2.0);
next.hand_r.orientation = Quaternion::rotation_x(0.9 + move1 * 0.5);
next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1, s_a.sc.2);
next.control.orientation = Quaternion::rotation_x(s_a.sc.3);
next.chest.orientation = Quaternion::rotation_z(move1 * 0.3);
next.head.orientation = Quaternion::rotation_z(move1 * -0.1);
next.shorts.orientation = Quaternion::rotation_z(move1 * -0.2);
next.belt.orientation = Quaternion::rotation_z(move1 * -0.1);
next.control.orientation.rotate_x(move1 * 2.1);
next.control.position += Vec3::new(0.0, 0.0, move1 * 11.0);
next.control.orientation.rotate_z(move1 * -0.3);
next.chest.orientation.rotate_z(move2 * -0.7);
next.head.orientation.rotate_z(move2 * 0.4);
next.shorts.orientation.rotate_z(move2 * 0.5);
next.belt.orientation.rotate_z(move2 * 0.2);
next.control.position += Vec3::new(move2 * -1.0, move2 * 6.0, move2 * -2.0);
next.control.orientation.rotate_z(move2 * 0.4);
},
Some("common.abilities.sword.offensive_combo") => {
let (move1, move2) = if strike == current_strike {
match stage_section {
@ -791,40 +877,6 @@ impl Animation for ComboAnimation {
_ => {},
}
},
Some("common.abilities.sword.heavy_pommelstrike") => {
let (move1, move2) = match stage_section {
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0),
Some(StageSection::Action) => (1.0, anim_time.powi(2)),
Some(StageSection::Recover) => (1.0, 1.0),
_ => (0.0, 0.0),
};
let move1 = move1 * multi_strike_pullback;
let move2 = move2 * multi_strike_pullback;
next.hand_l.position = Vec3::new(s_a.shl.0, s_a.shl.1, s_a.shl.2);
next.hand_l.orientation =
Quaternion::rotation_x(s_a.shl.3) * Quaternion::rotation_y(s_a.shl.4);
next.hand_r.position =
Vec3::new(-s_a.sc.0 + 6.0 + move1 * -12.0, -4.0 + move1 * 3.0, -2.0);
next.hand_r.orientation = Quaternion::rotation_x(0.9 + move1 * 0.5);
next.control.position = Vec3::new(s_a.sc.0, s_a.sc.1, s_a.sc.2);
next.control.orientation = Quaternion::rotation_x(s_a.sc.3);
next.chest.orientation = Quaternion::rotation_z(move1 * 0.3);
next.head.orientation = Quaternion::rotation_z(move1 * -0.1);
next.shorts.orientation = Quaternion::rotation_z(move1 * -0.2);
next.belt.orientation = Quaternion::rotation_z(move1 * -0.1);
next.control.orientation.rotate_x(move1 * 2.1);
next.control.position += Vec3::new(0.0, 0.0, move1 * 11.0);
next.control.orientation.rotate_z(move1 * -0.3);
next.chest.orientation.rotate_z(move2 * -0.7);
next.head.orientation.rotate_z(move2 * 0.4);
next.shorts.orientation.rotate_z(move2 * 0.5);
next.belt.orientation.rotate_z(move2 * 0.2);
next.control.position += Vec3::new(move2 * -1.0, move2 * 6.0, move2 * -2.0);
next.control.orientation.rotate_z(move2 * 0.4);
},
Some("common.abilities.sword.mobility_combo") => {
let (move1, move2) = if strike == current_strike {
match stage_section {

View File

@ -1791,41 +1791,6 @@ impl FigureMgr {
skeleton_attr,
)
},
CharacterState::BasicStance(_) => {
if physics.in_liquid().is_some() {
anim::character::SwimWieldAnimation::update_skeleton(
&target_base,
(
active_tool_kind,
second_tool_kind,
hands,
rel_vel.magnitude(),
time,
),
state.state_time,
&mut state_animation_rate,
skeleton_attr,
)
} else {
anim::character::WieldAnimation::update_skeleton(
&target_base,
(
(active_tool_kind, active_tool_spec),
second_tool_kind,
hands,
// TODO: Update to use the quaternion.
ori * anim::vek::Vec3::<f32>::unit_y(),
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
look_dir,
rel_vel,
time,
),
state.state_time,
&mut state_animation_rate,
skeleton_attr,
)
}
},
CharacterState::BasicBlock(s) => {
let stage_time = s.timer.as_secs_f32();
let stage_progress = match s.stage_section {