diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dd760e5e5..5cdaa41841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The inventory can now be expanded to fill the whole window - Added /dropall admin command (drops all inventory items on the ground) - Skill trees +- Lactose tolerant golems ### Changed diff --git a/assets/common/abilities/axe/spin.ron b/assets/common/abilities/axe/spin.ron index e9660d27d4..beade00a33 100644 --- a/assets/common/abilities/axe/spin.ron +++ b/assets/common/abilities/axe/spin.ron @@ -7,7 +7,7 @@ SpinMelee( range: 3.5, energy_cost: 100, is_infinite: true, - is_helicopter: true, + is_helicopter: Yes, is_interruptible: false, forward_speed: 0.0, num_spins: 1, diff --git a/assets/common/abilities/sword/spin.ron b/assets/common/abilities/sword/spin.ron index 237bd7fdcc..907a1f3ef7 100644 --- a/assets/common/abilities/sword/spin.ron +++ b/assets/common/abilities/sword/spin.ron @@ -7,7 +7,7 @@ SpinMelee( range: 3.5, energy_cost: 150, is_infinite: false, - is_helicopter: false, + is_helicopter: No, is_interruptible: true, forward_speed: 1.0, num_spins: 3, diff --git a/assets/common/abilities/unique/stonegolemfist/shockwave.ron b/assets/common/abilities/unique/stonegolemfist/shockwave.ron index ac29382ee5..d161a02d62 100644 --- a/assets/common/abilities/unique/stonegolemfist/shockwave.ron +++ b/assets/common/abilities/unique/stonegolemfist/shockwave.ron @@ -6,9 +6,9 @@ Shockwave( damage: 500, knockback: TowardsUp(40.0), shockwave_angle: 90.0, - shockwave_vertical_angle: 15.0, - shockwave_speed: 20.0, - shockwave_duration: 2000, + shockwave_vertical_angle: 90.0, + shockwave_speed: 50.0, + shockwave_duration: 1000, requires_ground: true, move_efficiency: 0.05, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/stonegolemfist/spin.ron b/assets/common/abilities/unique/stonegolemfist/spin.ron new file mode 100644 index 0000000000..b55747e0f8 --- /dev/null +++ b/assets/common/abilities/unique/stonegolemfist/spin.ron @@ -0,0 +1,14 @@ +SpinMelee( + buildup_duration: 100, + swing_duration: 400, + recover_duration: 100, + base_damage: 500, + knockback: 0.0, + range: 7.5, + energy_cost: 0, + is_infinite: false, + is_helicopter: Golem, + is_interruptible: false, + forward_speed: 0.0, + num_spins: 1, +) \ No newline at end of file diff --git a/assets/common/abilities/weapon_ability_manifest.ron b/assets/common/abilities/weapon_ability_manifest.ron index b478222f92..bf0d1dc533 100644 --- a/assets/common/abilities/weapon_ability_manifest.ron +++ b/assets/common/abilities/weapon_ability_manifest.ron @@ -54,7 +54,9 @@ Unique(StoneGolemFist): ( primary: "common.abilities.unique.stonegolemfist.basic", secondary: "common.abilities.unique.stonegolemfist.shockwave", - skills: [], + skills: [ + "common.abilities.unique.stonegolemfist.spin", + ], ), Unique(BeastClaws): ( primary: "common.abilities.unique.beastclaws.basic", diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index c78f5d4cfc..85170c0c82 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -152,7 +152,7 @@ pub enum CharacterAbility { range: f32, energy_cost: u32, is_infinite: bool, - is_helicopter: bool, + is_helicopter: spin_melee::Helicopter, is_interruptible: bool, forward_speed: f32, num_spins: u32, @@ -657,7 +657,11 @@ impl CharacterAbility { .. } => { *is_infinite = skillset.has_skill(Axe(SInfinite)); - *is_helicopter = skillset.has_skill(Axe(SHelicopter)); + *is_helicopter = if skillset.has_skill(Axe(SHelicopter)) { + spin_melee::Helicopter::Yes + } else { + spin_melee::Helicopter::No + }; if let Ok(Some(level)) = skillset.skill_level(Axe(SDamage)) { *base_damage = (*base_damage as f32 * 1.3_f32.powi(level.into())) as u32; diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs index f2c1ad16d8..6c5255e667 100644 --- a/common/src/states/spin_melee.rs +++ b/common/src/states/spin_melee.rs @@ -31,7 +31,7 @@ pub struct StaticData { /// Whether spin state is infinite pub is_infinite: bool, /// Used to maintain classic axe spin physics - pub is_helicopter: bool, + pub is_helicopter: Helicopter, /// Whether the state can be interrupted by other abilities pub is_interruptible: bool, /// Used for forced forward movement @@ -61,9 +61,15 @@ impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData) -> StateUpdate { let mut update = StateUpdate::from(data); - if self.static_data.is_helicopter { - let new_vel_z = update.vel.0.z + GRAVITY * data.dt.0 * 0.5; - update.vel.0 = Vec3::new(0.0, 0.0, new_vel_z) + data.inputs.move_dir * 5.0; + match self.static_data.is_helicopter { + Helicopter::No => {}, + Helicopter::Yes => { + let new_vel_z = update.vel.0.z + GRAVITY * data.dt.0 * 0.5; + update.vel.0 = Vec3::new(0.0, 0.0, new_vel_z) + data.inputs.move_dir * 5.0; + }, + Helicopter::Golem => { + update.vel.0 = Vec3::new(0.0, 0.0, 10.0) + data.inputs.move_dir * 20.0; + }, } if !ability_key_is_pressed(data, self.static_data.ability_key) { @@ -116,7 +122,7 @@ impl CharacterBehavior for Data { knockback: Knockback::Away(self.static_data.knockback), }); } else if self.timer < self.static_data.swing_duration { - if !self.static_data.is_helicopter { + if matches!(self.static_data.is_helicopter, Helicopter::No) { handle_forced_movement( data, &mut update, @@ -194,3 +200,10 @@ impl CharacterBehavior for Data { update } } + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum Helicopter { + No, + Yes, + Golem, +} diff --git a/common/sys/src/agent.rs b/common/sys/src/agent.rs index a6e263d33b..a5337d8585 100644 --- a/common/sys/src/agent.rs +++ b/common/sys/src/agent.rs @@ -896,6 +896,9 @@ impl<'a> System<'a> for Sys { } else if dist_sqrd < MAX_CHASE_DIST.powi(2) || (dist_sqrd < SIGHT_DIST.powi(2) && !*been_close) { + if vel.0.is_approx_zero() { + inputs.ability3.set_state(true); + } if dist_sqrd < MAX_CHASE_DIST.powi(2) { *been_close = true; } @@ -909,7 +912,9 @@ impl<'a> System<'a> for Sys { ..traversal_config }, ) { - if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + if matches!(char_states.get(entity), Some(CharacterState::SpinMelee(_))) { + inputs.move_dir = (tgt_pos.0 - pos.0).xy().try_normalized().unwrap_or(Vec2::zero()); + } else if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { inputs.move_dir = bearing .xy() .try_normalized()