diff --git a/client/src/lib.rs b/client/src/lib.rs index 5606d415ab..7b4bb8dd8b 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -113,6 +113,11 @@ impl Client { // Initialize `State` let mut state = State::default(); + // Client-only components + state + .ecs_mut() + .register::>(); + let entity = state.ecs_mut().apply_entity_package(entity_package); *state.ecs_mut().write_resource() = time_of_day; diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index eb8cd665e0..0d2538aea5 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -182,7 +182,7 @@ impl From<&CharacterAbility> for CharacterState { CharacterAbility::TripleStrike { base_damage } => { CharacterState::TripleStrike(triple_strike::Data { base_damage: *base_damage, - stage: 0, + stage: triple_strike::Stage::First, stage_exhausted: false, stage_time_active: Duration::default(), should_transition: true, diff --git a/common/src/states/climb.rs b/common/src/states/climb.rs index 5beb746345..4614fe6721 100644 --- a/common/src/states/climb.rs +++ b/common/src/states/climb.rs @@ -46,19 +46,7 @@ impl CharacterBehavior for Data { // Expend energy if climbing let energy_use = match data.inputs.climb { Some(Climb::Up) | Some(Climb::Down) => 8, - Some(Climb::Hold) => data - .physics - .on_wall - .map(|wall_dir| { - // Calculate velocity perpendicular to the wall - let vel = update.vel.0; - let perp_vel = - vel - wall_dir * vel.dot(wall_dir) / wall_dir.magnitude_squared(); - // Enegry cost based on magnitude of this velocity - (perp_vel.magnitude() * 8.0) as i32 - }) - // Note: this is currently unreachable - .unwrap_or(0), + Some(Climb::Hold) => 1, // Note: this is currently unreachable None => 0, }; @@ -98,7 +86,8 @@ impl CharacterBehavior for Data { update.vel.0.z = (update.vel.0.z + data.dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED); }, Climb::Hold => { - update.vel.0.z = update.vel.0.z + data.dt.0 * GRAVITY * 1.5; + // Antigrav + update.vel.0.z = (update.vel.0.z + data.dt.0 * GRAVITY * 1.5).min(CLIMB_SPEED); update.vel.0 = Lerp::lerp( update.vel.0, Vec3::zero(), diff --git a/common/src/states/triple_strike.rs b/common/src/states/triple_strike.rs index 7add9a345e..92b09c0309 100644 --- a/common/src/states/triple_strike.rs +++ b/common/src/states/triple_strike.rs @@ -11,6 +11,14 @@ const STAGE_DURATION: u64 = 600; const INITIAL_ACCEL: f32 = 200.0; const BASE_SPEED: f32 = 25.0; + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)] +pub enum Stage { + First, + Second, + Third, +} + /// ### A sequence of 3 incrementally increasing attacks. /// /// While holding down the `primary` button, perform a series of 3 attacks, @@ -21,8 +29,8 @@ const BASE_SPEED: f32 = 25.0; pub struct Data { /// The tool this state will read to handle damage, etc. pub base_damage: u32, - /// `int` denoting what stage (of 3) the attack is in. - pub stage: i8, + /// What stage (of 3) the attack is in. + pub stage: Stage, /// How long current stage has been active pub stage_time_active: Duration, /// Whether current stage has exhausted its attack @@ -42,22 +50,17 @@ impl CharacterBehavior for Data { .checked_add(Duration::from_secs_f32(data.dt.0)) .unwrap_or(Duration::default()); - let mut should_transition = self.should_transition; - let mut initialized = self.initialized; + // If player stops holding input, don't go to the next stage + let should_transition = data.inputs.primary.is_pressed() && self.should_transition; - // If player stops holding input, - if !data.inputs.primary.is_pressed() { - should_transition = false; - } - - if !initialized { + if !self.initialized { update.ori.0 = data.inputs.look_dir.normalized(); update.vel.0 = Vec3::zero(); - initialized = true; } + let initialized = true; // Handling movement - if self.stage == 0 { + if let Stage::First = self.stage { if stage_time_active < Duration::from_millis(STAGE_DURATION / 3) { let adjusted_accel = if data.physics.touch_entity.is_none() { INITIAL_ACCEL @@ -65,7 +68,7 @@ impl CharacterBehavior for Data { 0.0 }; - // Move player forward while in first third of each stage + // Move player forward while in first third of first stage if update.vel.0.magnitude_squared() < BASE_SPEED.powf(2.0) { update.vel.0 = update.vel.0 + Vec2::broadcast(data.dt.0) * data.ori.0 * adjusted_accel; @@ -82,11 +85,13 @@ impl CharacterBehavior for Data { } // Handling attacking - if stage_time_active > Duration::from_millis(STAGE_DURATION / 2) && !self.stage_exhausted { + update.character = if stage_time_active > Duration::from_millis(STAGE_DURATION / 2) + && !self.stage_exhausted + { let dmg = match self.stage { - 1 => self.base_damage, - 2 => (self.base_damage as f32 * 1.5) as u32, - _ => self.base_damage / 2, + Stage::First => self.base_damage / 2, + Stage::Second => self.base_damage, + Stage::Third => (self.base_damage as f32 * 1.5) as u32, }; // Try to deal damage in second half of stage @@ -98,40 +103,44 @@ impl CharacterBehavior for Data { hit_count: 0, }); - update.character = CharacterState::TripleStrike(Data { + CharacterState::TripleStrike(Data { base_damage: self.base_damage, stage: self.stage, stage_time_active, stage_exhausted: true, should_transition, initialized, - }); + }) } else if stage_time_active > Duration::from_millis(STAGE_DURATION) { if should_transition { - update.character = CharacterState::TripleStrike(Data { + CharacterState::TripleStrike(Data { base_damage: self.base_damage, - stage: self.stage + 1, + stage: match self.stage { + Stage::First => Stage::Second, + Stage::Second => Stage::Third, + Stage::Third => Stage::First, + }, stage_time_active: Duration::default(), stage_exhausted: false, should_transition, initialized, - }); + }) } else { - // Done - update.character = CharacterState::Wielding; // Make sure attack component is removed data.updater.remove::(data.entity); + // Done + CharacterState::Wielding } } else { - update.character = CharacterState::TripleStrike(Data { + CharacterState::TripleStrike(Data { base_damage: self.base_damage, stage: self.stage, stage_time_active, stage_exhausted: self.stage_exhausted, should_transition, initialized, - }); - } + }) + }; // Grant energy on successful hit if let Some(attack) = data.attacking { diff --git a/server/src/lib.rs b/server/src/lib.rs index f4b2560393..177e909733 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -83,7 +83,6 @@ impl Server { pub fn new(settings: ServerSettings) -> Result { let mut state = State::default(); state.ecs_mut().insert(EventBus::::default()); - // TODO: anything but this state .ecs_mut() .insert(AuthProvider::new(settings.auth_server_address.clone())); diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index e5745bcc48..d64eeb148f 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -24,6 +24,7 @@ use common::{ Body, CharacterState, ItemKind, Last, Loadout, Ori, PhysicsState, Pos, Scale, Stats, Vel, }, state::State, + states::triple_strike, terrain::TerrainChunk, vol::RectRasterableVol, }; @@ -507,27 +508,33 @@ impl FigureMgr { ) }, CharacterState::TripleStrike(s) => match s.stage { - 0 => anim::character::AttackAnimation::update_skeleton( - &target_base, - (active_tool_kind, vel.0.magnitude(), time), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), - 1 => anim::character::SpinAnimation::update_skeleton( - &target_base, - (active_tool_kind, time), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), - _ => anim::character::AttackAnimation::update_skeleton( - &target_base, - (active_tool_kind, vel.0.magnitude(), time), - state.state_time, - &mut state_animation_rate, - skeleton_attr, - ), + triple_strike::Stage::First => { + anim::character::AttackAnimation::update_skeleton( + &target_base, + (active_tool_kind, vel.0.magnitude(), time), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, + triple_strike::Stage::Second => { + anim::character::SpinAnimation::update_skeleton( + &target_base, + (active_tool_kind, time), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, + triple_strike::Stage::Third => { + anim::character::AttackAnimation::update_skeleton( + &target_base, + (active_tool_kind, vel.0.magnitude(), time), + state.state_time, + &mut state_animation_rate, + skeleton_attr, + ) + }, }, CharacterState::TimedCombo(s) => match s.stage { 0 | 2 => anim::character::AttackAnimation::update_skeleton(