diff --git a/CHANGELOG.md b/CHANGELOG.md index 4466ae1851..fb77d098c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +- Entity-entity pushback is no longer applied in forced movement states like rolling and leaping. ### Removed diff --git a/assets/voxygen/i18n/en/_manifest.ron b/assets/voxygen/i18n/en/_manifest.ron index 737713c4dc..2be067818b 100644 --- a/assets/voxygen/i18n/en/_manifest.ron +++ b/assets/voxygen/i18n/en/_manifest.ron @@ -58,6 +58,7 @@ "You can toggle showing your amount of health on the healthbar in the settings.", "Sit near a campfire (with the 'K' key) to slowly recover from your injuries.", "Need more bags or better armor to continue your journey? Press 'C' to open the crafting menu!", + "Try jumping when rolling through creatures.", ], "npc.speech.villager": [ "Isn't it such a lovely day?", diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 4e40b2ac6c..b21d90008f 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -2,7 +2,7 @@ use crate::{ combat::Attack, comp::{tool::ToolKind, Density, Energy, InputAttr, InputKind, Ori, Pos, Vel}, event::{LocalEvent, ServerEvent}, - states::{behavior::JoinData, *}, + states::{behavior::JoinData, utils::StageSection, *}, }; use serde::{Deserialize, Serialize}; use specs::{Component, DerefFlaggedStorage, VecStorage}; @@ -196,6 +196,15 @@ impl CharacterState { pub fn is_stunned(&self) -> bool { matches!(self, CharacterState::Stunned(_)) } + pub fn is_forced_movement(&self) -> bool { + matches!(self, + CharacterState::ComboMelee(s) if s.stage_section == StageSection::Swing) + || matches!(self, CharacterState::DashMelee(s) if s.stage_section == StageSection::Charge) + || matches!(self, CharacterState::LeapMelee(s) if s.stage_section == StageSection::Movement) + || matches!(self, CharacterState::SpinMelee(s) if s.stage_section == StageSection::Swing) + || matches!(self, CharacterState::Roll(s) if s.stage_section == StageSection::Movement) + } + /// Compares for shallow equality (does not check internal struct equality) pub fn same_variant(&self, other: &Self) -> bool { // Check if state is the same without looking at the inner data diff --git a/common/systems/src/phys.rs b/common/systems/src/phys.rs index 48c36e506d..1f4521496c 100644 --- a/common/systems/src/phys.rs +++ b/common/systems/src/phys.rs @@ -333,6 +333,21 @@ impl<'a> PhysicsData<'a> { }; } + // Don't apply e2e pushback to entities that are in a forced movement state + // (e.g. roll, leapmelee). This allows leaps to work properly (since you won't + // get pushed away before delivering the hit), and allows rolling through an + // enemy when trapped (e.g. with minotaur). This allows using e2e pushback to + // gain speed by jumping out of a roll while in the middle of a collider, this + // is an intentional combat mechanic. + if let Some(cs) = char_state_maybe { + if cs.is_forced_movement() { + return PhysicsMetrics { + entity_entity_collision_checks, + entity_entity_collisions, + }; + } + } + let z_limits = calc_z_limit(char_state_maybe, collider); // Resets touch_entities in physics