Fix various minor issues
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use bevy::prelude::*;
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
use crate::fighter::{FighterFacingDirection, FighterVisual};
|
||||
|
||||
@@ -63,7 +64,7 @@ pub fn apply_animation(
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize, Reflect,
|
||||
Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize, Reflect, EnumIter
|
||||
)]
|
||||
pub enum AnimKind {
|
||||
Wait,
|
||||
|
||||
@@ -175,7 +175,7 @@ pub fn update_active_hitbox_list(script: &FighterAttackScript, list: &mut Vec<us
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq, Hash)]
|
||||
pub struct FighterSolvedHurtbox {
|
||||
pub hurtbox_idx: usize,
|
||||
pub capsule: FixedAffineCapsule,
|
||||
@@ -185,7 +185,7 @@ pub struct FighterSolvedHurtbox {
|
||||
pub struct FighterAttackScriptAssets {
|
||||
pub scripts: HashMap<AttackKind, Handle<FighterAttackScript>>,
|
||||
}
|
||||
#[derive(Component, Clone, Debug, Default)]
|
||||
#[derive(Component, Clone, Debug, Default, Hash)]
|
||||
pub struct FighterSolvedHurtboxes(pub Vec<FighterSolvedHurtbox>);
|
||||
|
||||
pub fn solve_hurtboxes(
|
||||
|
||||
@@ -38,7 +38,7 @@ pub const BAKED_ANIMATION_FPS: u32 = 60;
|
||||
|
||||
/// Parent transforms are composed after
|
||||
/// quantization, which makes every runtime sample platform-independent.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||
pub struct FixedMat4 {
|
||||
pub cols: [[FGi32; 4]; 4],
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ pub fn collide_fighter_with_scene(
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AirCollisionWithStageResult {
|
||||
pub line_id: StageLineID,
|
||||
pub hit_position: FGVec2,
|
||||
@@ -45,9 +45,11 @@ pub fn air_collide_with_stage(
|
||||
state_context.translation.0 + state_context.ecb.get_bottom_point(),
|
||||
);
|
||||
|
||||
let mut intersect_results = vec![];
|
||||
|
||||
for (poly_idx, poly) in state_context.stage_collision.stage_polys.iter().enumerate() {
|
||||
if let Some(intersect_result) = poly.intersect_ray(ray_segment) {
|
||||
return Some(AirCollisionWithStageResult {
|
||||
intersect_results.push((AirCollisionWithStageResult {
|
||||
line_id: {
|
||||
StageLineID {
|
||||
polygon: poly_idx,
|
||||
@@ -56,9 +58,14 @@ pub fn air_collide_with_stage(
|
||||
},
|
||||
hit_position: intersect_result.position,
|
||||
hit_normal: intersect_result.normal,
|
||||
}, intersect_result.position.distance_squared(ray_segment.point2())));
|
||||
}
|
||||
}
|
||||
intersect_results.sort_by(| (_, a), (_, b) | {
|
||||
a.cmp(b)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
intersect_results.iter().last().map(|(val, _)| {
|
||||
val.to_owned().clone()
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,14 +5,14 @@ use crate::math::{int::FGi32, vec::FGVec2};
|
||||
/// Environment collision box: the diamond used to resolve a fighter against
|
||||
/// the stage. Purely geometry — the collision response lives in
|
||||
/// [`super::collision`].
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
#[derive(Component, Debug, Clone, Copy, Hash)]
|
||||
#[require(FighterPreviousECB)]
|
||||
pub struct FighterECB {
|
||||
pub vertical_half: FGi32,
|
||||
pub horizontal_half: FGi32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy, Default)]
|
||||
#[derive(Component, Debug, Clone, Copy, Default, Hash)]
|
||||
pub struct FighterPreviousECB {
|
||||
pub vertical_half: FGi32,
|
||||
pub horizontal_half: FGi32,
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
|
||||
/// A capsule after an arbitrary affine transform. Non-uniform scale turns the
|
||||
/// spherical caps and circular cylinder into ellipsoidal geometry.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
|
||||
pub struct FixedAffineCapsule {
|
||||
pub transform: FixedMat4,
|
||||
pub half_length: FGi32,
|
||||
|
||||
@@ -109,13 +109,17 @@ pub fn prepare_fighter_manifests(
|
||||
);
|
||||
return;
|
||||
}
|
||||
if !manifest.animations.contains_key(&AnimKind::Wait) {
|
||||
|
||||
for anim_kind in AnimKind::iter() {
|
||||
if !manifest.animations.contains_key(&anim_kind) {
|
||||
fail(
|
||||
&mut next_state,
|
||||
&format!("{:?} has no Wait animation", manifest.id),
|
||||
&format!("{:?} has no {:?} animation", manifest.id, anim_kind),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if !manifest.camera.is_valid() {
|
||||
fail(
|
||||
&mut next_state,
|
||||
|
||||
+9
-1
@@ -144,13 +144,19 @@ impl Plugin for FighterPlugin {
|
||||
// components; a component simulated here but missing from this list
|
||||
// is a desync waiting to happen.
|
||||
.rollback_component_with_copy::<FighterECB>()
|
||||
.checksum_component_with_hash::<FighterECB>()
|
||||
.rollback_component_with_copy::<ecb::FighterPreviousECB>()
|
||||
.checksum_component_with_hash::<ecb::FighterPreviousECB>()
|
||||
.rollback_component_with_copy::<FighterVelocity>()
|
||||
.checksum_component_with_hash::<FighterVelocity>()
|
||||
.rollback_component_with_copy::<FighterTranslation>()
|
||||
.checksum_component_with_hash::<FighterTranslation>()
|
||||
.rollback_component_with_copy::<FighterPreviousTranslation>()
|
||||
.checksum_component_with_hash::<FighterPreviousTranslation>()
|
||||
.rollback_component_with_copy::<animation::FighterAnimationFrame>()
|
||||
.checksum_component_with_hash::<animation::FighterAnimationFrame>()
|
||||
.rollback_component_with_copy::<Grounded>()
|
||||
.checksum_component_with_hash::<Grounded>()
|
||||
.rollback_component_with_copy::<FighterFacingDirection>()
|
||||
.rollback_resource_with_reflect::<StageCollision>()
|
||||
// Debug views.
|
||||
@@ -176,14 +182,16 @@ impl Plugin for FighterPlugin {
|
||||
)
|
||||
.rollback_component_with_clone::<FighterState>()
|
||||
.rollback_component_with_clone::<FighterHitboxes>()
|
||||
.checksum_component_with_hash::<FighterHitboxes>()
|
||||
.rollback_component_with_clone::<FighterSolvedHurtboxes>()
|
||||
.checksum_component_with_hash::<FighterSolvedHurtboxes>()
|
||||
.checksum_component_with_hash::<FighterState>()
|
||||
.checksum_component_with_hash::<FighterFacingDirection>()
|
||||
.register_type::<FighterFacingDirection>();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Clone)]
|
||||
#[derive(Component, Clone, Hash)]
|
||||
pub struct FighterHitboxes {
|
||||
pub attack_script: Option<Handle<FighterAttackScript>>,
|
||||
pub active_hitboxes: Vec<usize>,
|
||||
|
||||
@@ -10,16 +10,16 @@ use crate::{
|
||||
math::{int::FGi32, vec::FGVec2, vec3::FGVec3},
|
||||
};
|
||||
|
||||
#[derive(Component, Clone, Copy)]
|
||||
#[derive(Component, Clone, Copy, Hash)]
|
||||
pub struct Grounded;
|
||||
|
||||
#[derive(Component, Deref, DerefMut, Default, Debug, Clone, Copy)]
|
||||
#[derive(Component, Deref, DerefMut, Default, Debug, Clone, Copy, Hash)]
|
||||
pub struct FighterVelocity(pub FGVec2);
|
||||
|
||||
#[derive(Component, Deref, DerefMut, Default, Clone, Copy)]
|
||||
#[derive(Component, Deref, DerefMut, Default, Clone, Copy, Hash)]
|
||||
pub struct FighterPreviousTranslation(pub FGVec2);
|
||||
|
||||
#[derive(Component, Deref, DerefMut, Default, Clone, Copy)]
|
||||
#[derive(Component, Deref, DerefMut, Default, Clone, Copy, Hash)]
|
||||
#[require(FighterPreviousTranslation)]
|
||||
pub struct FighterTranslation(pub FGVec2);
|
||||
|
||||
|
||||
@@ -221,11 +221,6 @@ impl FighterStateImpl for JumpState {
|
||||
};
|
||||
|
||||
state_context.velocity.y = vertical_vel;
|
||||
state_context.velocity.x += state_context
|
||||
.fighter_manifest
|
||||
.attributes
|
||||
.jump_horizontal_velocity
|
||||
* movement_stick_x;
|
||||
}
|
||||
|
||||
fn check_collision_interrupt(
|
||||
|
||||
@@ -120,7 +120,7 @@ impl FighterStateContext<'_> {
|
||||
anims_data
|
||||
.frame_count(self.animation_frame.kind)
|
||||
.expect("Current animation should have baked frames")
|
||||
< self.animation_frame.frame
|
||||
<= self.animation_frame.frame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ pub enum FighterCommands {
|
||||
|
||||
/// Frames of life remaining for each buffered command. Indexed by
|
||||
/// [`FighterCommands`] so adding a command is a two-line change here.
|
||||
#[derive(Default, Clone, Copy)]
|
||||
#[derive(Default, Clone, Copy, Hash)]
|
||||
pub struct FighterCommandLifetimes {
|
||||
smash_move_left: u8,
|
||||
smash_move_right: u8,
|
||||
@@ -60,7 +60,7 @@ impl IndexMut<FighterCommands> for FighterCommandLifetimes {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Default, Clone, Copy)]
|
||||
#[derive(Component, Default, Clone, Copy, Hash)]
|
||||
#[require(Rollback)]
|
||||
pub struct FighterInput {
|
||||
command_lifetimes: FighterCommandLifetimes,
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ use crate::math::vec::FGVec2;
|
||||
|
||||
/// One frame of a player's raw input. This is the type GGRS serializes and
|
||||
/// sends over the wire, so keep it small and keep it `PartialEq`.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, Deserialize, Hash)]
|
||||
pub struct FighterInputFrame {
|
||||
pub movement: FGVec2,
|
||||
pub directional_attack: FGVec2,
|
||||
|
||||
+2
-1
@@ -108,7 +108,8 @@ impl Plugin for FighterInputPlugin {
|
||||
GgrsSchedule,
|
||||
buffer::postprocess_input.in_set(GameplaySet::Input),
|
||||
)
|
||||
.rollback_component_with_clone::<FighterInput>();
|
||||
.rollback_component_with_clone::<FighterInput>()
|
||||
.checksum_component_with_hash::<FighterInput>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,12 @@ impl FGVec2 {
|
||||
(to - self).length()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn distance_squared(self, to: Self) -> FGWide {
|
||||
(to - self).length_squared()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn normalize(&self) -> Option<Self> {
|
||||
let x = I32F32::from_num(self.x);
|
||||
|
||||
Reference in New Issue
Block a user