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