Integrate basic attack script debug.
This commit is contained in:
@@ -149,4 +149,8 @@ pub enum AnimKind {
|
||||
AirDodge,
|
||||
Fall,
|
||||
Turn,
|
||||
|
||||
// Attacks
|
||||
|
||||
AttackJab1,
|
||||
}
|
||||
|
||||
+27
-4
@@ -1,7 +1,9 @@
|
||||
use bevy::reflect::Reflect;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use bevy::{asset::Handle, ecs::component::Component, reflect::Reflect};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::math::{int::FGi32, vec3::FGVec3};
|
||||
use crate::{fighter::animation::AnimKind, math::{int::FGi32, vec3::FGVec3}, scripting::FighterAttackScript};
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct FighterDamage(FGi32);
|
||||
|
||||
@@ -59,9 +61,19 @@ impl AttackAngle {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Reflect, PartialEq, Eq, Hash, Clone)]
|
||||
#[derive(Serialize, Deserialize, Reflect, PartialEq, Eq, Hash, Clone, Debug)]
|
||||
pub enum AttackKind {
|
||||
NAir
|
||||
NAir,
|
||||
Jab
|
||||
}
|
||||
|
||||
impl AttackKind {
|
||||
pub fn get_animation(&self) -> AnimKind {
|
||||
match self {
|
||||
AttackKind::NAir => AnimKind::AttackJab1,
|
||||
AttackKind::Jab => AnimKind::AttackJab1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Reflect, Serialize, Deserialize)]
|
||||
@@ -78,4 +90,15 @@ pub struct AttackHitbox {
|
||||
pub knockback_growth: FGi32,
|
||||
pub start_frame: u32,
|
||||
pub end_frame: u32
|
||||
}
|
||||
|
||||
pub fn update_active_hitbox_list(script: &FighterAttackScript, list: &mut Vec<usize>, frame: u32) {
|
||||
*list = script.hitboxes.iter().enumerate().filter(|(i, hb)| {
|
||||
hb.start_frame <= frame && hb.end_frame > frame
|
||||
}).map(|(i, _)| i).collect()
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct FighterAttackScriptAssets {
|
||||
pub scripts: HashMap<AttackKind, Handle<FighterAttackScript>>
|
||||
}
|
||||
@@ -20,7 +20,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
fighter::{animation::AnimKind, manifest::FighterManifest},
|
||||
math::int::{FGWide, FGi32},
|
||||
math::{
|
||||
int::{FGWide, FGi32},
|
||||
vec3::FGVec3,
|
||||
},
|
||||
};
|
||||
|
||||
pub const BAKED_ANIMATION_FPS: u32 = 60;
|
||||
@@ -33,6 +36,14 @@ pub struct FixedMat4 {
|
||||
}
|
||||
|
||||
impl FixedMat4 {
|
||||
pub const IDENTITY: Self = Self {
|
||||
cols: [
|
||||
[FGi32::ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ONE, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ZERO, FGi32::ONE],
|
||||
]
|
||||
};
|
||||
fn from_mat4(matrix: Mat4) -> io::Result<Self> {
|
||||
let values = matrix.to_cols_array();
|
||||
let mut cols = [[FGi32::ZERO; 4]; 4];
|
||||
@@ -47,7 +58,7 @@ impl FixedMat4 {
|
||||
Ok(Self { cols })
|
||||
}
|
||||
|
||||
fn mul(self, rhs: Self) -> Self {
|
||||
pub fn mul(self, rhs: Self) -> Self {
|
||||
let mut cols = [[FGi32::ZERO; 4]; 4];
|
||||
for column in 0..4 {
|
||||
for row in 0..4 {
|
||||
@@ -61,6 +72,67 @@ impl FixedMat4 {
|
||||
}
|
||||
Self { cols }
|
||||
}
|
||||
|
||||
pub fn transform_point(self, point: FGVec3) -> FGVec3 {
|
||||
let input = [point.x, point.y, point.z, FGi32::ONE];
|
||||
let mut output = [FGi32::ZERO; 3];
|
||||
for row in 0..3 {
|
||||
let mut value = FGWide::ZERO;
|
||||
for (column, input) in input.into_iter().enumerate() {
|
||||
value += FGWide::from_num(self.cols[column][row]) * FGWide::from_num(input);
|
||||
}
|
||||
output[row] = FGi32::from_num(value);
|
||||
}
|
||||
FGVec3 {
|
||||
x: output[0],
|
||||
y: output[1],
|
||||
z: output[2],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translate(&mut self, translation: FGVec3) {
|
||||
self.cols[3][0] = translation.x;
|
||||
self.cols[3][1] = translation.y;
|
||||
self.cols[3][2] = translation.z;
|
||||
}
|
||||
|
||||
pub fn rotate_y(self, quarter_turns: u8) -> Self {
|
||||
let rotation = match quarter_turns % 4 {
|
||||
0 => Self {
|
||||
cols: [
|
||||
[FGi32::ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ONE, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ZERO, FGi32::ONE],
|
||||
],
|
||||
},
|
||||
1 => Self {
|
||||
cols: [
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::NEG_ONE, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ZERO, FGi32::ONE],
|
||||
],
|
||||
},
|
||||
2 => Self {
|
||||
cols: [
|
||||
[FGi32::NEG_ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::NEG_ONE, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ZERO, FGi32::ONE],
|
||||
],
|
||||
},
|
||||
_ => Self {
|
||||
cols: [
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ONE, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::NEG_ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ZERO, FGi32::ONE],
|
||||
],
|
||||
},
|
||||
};
|
||||
self.mul(rotation)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@@ -525,4 +597,50 @@ mod tests {
|
||||
baked.bone_names.len()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fixed_matrix_transforms_points() {
|
||||
let transform = FixedMat4 {
|
||||
cols: [
|
||||
[FGi32::lit("2"), FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::lit("3"), FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::lit("4"), FGi32::ZERO],
|
||||
[
|
||||
FGi32::lit("10"),
|
||||
FGi32::lit("-5"),
|
||||
FGi32::lit("1.5"),
|
||||
FGi32::ONE,
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
transform.transform_point(FGVec3::lit("1.25", "-2", "0.5")),
|
||||
FGVec3::lit("12.5", "-11", "3.5")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fixed_matrix_rotates_points_around_y() {
|
||||
let transform = FixedMat4 {
|
||||
cols: [
|
||||
[FGi32::ONE, FGi32::ZERO, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ONE, FGi32::ZERO, FGi32::ZERO],
|
||||
[FGi32::ZERO, FGi32::ZERO, FGi32::ONE, FGi32::ZERO],
|
||||
[
|
||||
FGi32::lit("10"),
|
||||
FGi32::lit("2"),
|
||||
FGi32::lit("-3"),
|
||||
FGi32::ONE,
|
||||
],
|
||||
],
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
transform
|
||||
.rotate_y(5)
|
||||
.transform_point(FGVec3::lit("1", "0", "0")),
|
||||
FGVec3::lit("10", "2", "-4")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+41
-3
@@ -10,10 +10,11 @@ use crate::fighter::ecb::FighterPreviousECB;
|
||||
use crate::fighter::state::StateNameDebug;
|
||||
use crate::fighter::visual::FighterAnimations;
|
||||
use crate::fighter::{
|
||||
FighterECB, FighterPreviousTranslation, FighterTranslation,
|
||||
FighterVelocity,
|
||||
FighterECB, FighterFacingDirection, FighterHitboxes, FighterPreviousTranslation, FighterTranslation, FighterVelocity,
|
||||
};
|
||||
use crate::input::FighterInput;
|
||||
use crate::math::vec3::FGVec3;
|
||||
use crate::scripting::FighterAttackScript;
|
||||
|
||||
pub fn debug_draw_ecb(
|
||||
ecbs: Query<(
|
||||
@@ -60,14 +61,51 @@ pub fn animation_debug(
|
||||
.get(&anims.baked)
|
||||
.expect("Baked anims should be in");
|
||||
for bone in &baked.bone_names {
|
||||
let out = anims.sample_bone(&baked_anims, *frame, bone);
|
||||
if bone != "Bone_30" {
|
||||
continue;
|
||||
}
|
||||
let out = anims.sample_bone(&baked_anims, frame, bone);
|
||||
if let Some(out) = out {
|
||||
let pos = global_transform.transform_point(Vec3::new(
|
||||
out.cols[3][0].to_num(),
|
||||
out.cols[3][1].to_num(),
|
||||
out.cols[3][2].to_num(),
|
||||
));
|
||||
//gizmos.text(pos, bone, 1.0, Vec2::new(0.0, 0.0), bevy::color::palettes::css::BLACK);
|
||||
gizmos.cross(pos, 0.5, bevy::color::palettes::css::RED);
|
||||
gizmos.axes(*global_transform, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attack_debug(
|
||||
query: Query<(&FighterHitboxes, &FighterAnimationFrame, &FighterAnimations, &FighterTranslation, &FighterFacingDirection)>,
|
||||
baked_anims: Res<Assets<BakedFighterAnimations>>,
|
||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||
mut gizmos: Gizmos,
|
||||
) {
|
||||
for (hitboxes, frame, animations, translation, facing_direction) in query {
|
||||
if let Some(script) = &hitboxes.attack_script {
|
||||
let script = attack_scripts.get(script).expect("Script ref should be valid");
|
||||
let player_trf = translation.get_3d_transform(facing_direction);
|
||||
|
||||
for i in hitboxes.active_hitboxes.iter() {
|
||||
let offset = script.hitboxes[*i].offset;
|
||||
let radius = script.hitboxes[*i].radius;
|
||||
let bone = &script.hitboxes[*i].bone;
|
||||
|
||||
let trf = animations.sample_bone(&baked_anims, frame, bone);
|
||||
if let Some(trf) = trf {
|
||||
let trf = player_trf.mul(trf);
|
||||
let start = player_trf.transform_point(FGVec3::lit("0.0", "1.0", "0.0"));
|
||||
let end = player_trf.transform_point(FGVec3::lit("0.0", "1.0", "1.0"));
|
||||
let pos = trf.transform_point(offset);
|
||||
let pos_draw = Vec3::new(pos.x.to_num(), pos.y.to_num(), pos.z.to_num());
|
||||
gizmos.sphere(pos_draw, radius.to_num(), bevy::color::palettes::css::RED);
|
||||
|
||||
gizmos.arrow(start.to_vec3(), end.to_vec3(),bevy::color::palettes::css::RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -29,16 +29,8 @@ pub use motion::{FighterPreviousTranslation, FighterTranslation, FighterVelocity
|
||||
|
||||
use crate::{
|
||||
fighter::{
|
||||
animation::animation_init,
|
||||
manifest::FighterManifest,
|
||||
state::{FighterState, fall::FallState},
|
||||
visual::FighterAnimations,
|
||||
},
|
||||
input::FighterInput,
|
||||
math::{int::FGi32, vec::FGVec2},
|
||||
player::Player,
|
||||
schedule::GameplaySet,
|
||||
stage::line::StageCollision,
|
||||
animation::animation_init, attack::FighterAttackScriptAssets, manifest::FighterManifest, state::{FighterState, fall::FallState}, visual::FighterAnimations,
|
||||
}, input::FighterInput, math::{int::FGi32, vec::FGVec2}, player::Player, schedule::GameplaySet, scripting::FighterAttackScript, stage::line::StageCollision,
|
||||
};
|
||||
use state::state_interrupt_system;
|
||||
|
||||
@@ -158,20 +150,29 @@ impl Plugin for FighterPlugin {
|
||||
.add_systems(FixedPostUpdate, debug::debug_draw_ecb)
|
||||
.add_systems(EguiPrimaryContextPass, debug::fighter_debug)
|
||||
.add_systems(FixedPostUpdate, debug::animation_debug)
|
||||
.add_systems(FixedPostUpdate, debug::attack_debug)
|
||||
.add_systems(EguiPrimaryContextPass, debug::update_config)
|
||||
.rollback_component_with_clone::<FighterState>()
|
||||
.rollback_component_with_clone::<FighterHitboxes>()
|
||||
.checksum_component_with_hash::<FighterState>()
|
||||
.checksum_component_with_hash::<FighterFacingDirection>()
|
||||
.register_type::<FighterFacingDirection>();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Clone)]
|
||||
pub struct FighterHitboxes {
|
||||
pub attack_script: Option<Handle<FighterAttackScript>>,
|
||||
pub active_hitboxes: Vec<usize>
|
||||
}
|
||||
|
||||
pub fn spawn_fighter(
|
||||
commands: &mut Commands,
|
||||
player_handle: usize,
|
||||
spawn_position: FGVec2,
|
||||
manifest: Handle<FighterManifest>,
|
||||
animations: FighterAnimations,
|
||||
attack_scripts: FighterAttackScriptAssets,
|
||||
visual_root: WorldAssetRoot,
|
||||
) {
|
||||
commands.spawn((
|
||||
@@ -183,14 +184,19 @@ pub fn spawn_fighter(
|
||||
manifest: manifest,
|
||||
},
|
||||
FighterFacingDirection::Right,
|
||||
FighterECB {
|
||||
(FighterECB {
|
||||
vertical_half: FGi32::lit("5.0"),
|
||||
horizontal_half: FGi32::lit("2.5"),
|
||||
},
|
||||
FighterHitboxes {
|
||||
attack_script: None,
|
||||
active_hitboxes: vec![]
|
||||
}),
|
||||
FighterVelocity::default(),
|
||||
FighterTranslation(spawn_position),
|
||||
visual_root,
|
||||
animations,
|
||||
attack_scripts,
|
||||
FighterState::Fall(FallState),
|
||||
animation::FighterAnimationFrame::new(animation::AnimKind::Wait, true),
|
||||
FighterVisual,
|
||||
|
||||
+13
-1
@@ -2,8 +2,9 @@
|
||||
//! this module is what turns that into a position.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use fixed::types::I16F16;
|
||||
|
||||
use crate::math::vec::FGVec2;
|
||||
use crate::{fighter::{FighterFacingDirection, baked_animation::FixedMat4}, math::{int::FGi32, vec::FGVec2, vec3::FGVec3}};
|
||||
|
||||
#[derive(Component, Clone, Copy)]
|
||||
pub struct Grounded;
|
||||
@@ -18,6 +19,17 @@ pub struct FighterPreviousTranslation(pub FGVec2);
|
||||
#[require(FighterPreviousTranslation)]
|
||||
pub struct FighterTranslation(pub FGVec2);
|
||||
|
||||
impl FighterTranslation {
|
||||
pub fn get_3d_transform(&self, facing_dir: &FighterFacingDirection) -> FixedMat4 {
|
||||
let mut o = match facing_dir {
|
||||
FighterFacingDirection::Left => FixedMat4::IDENTITY.rotate_y(3),
|
||||
FighterFacingDirection::Right => FixedMat4::IDENTITY.rotate_y(1),
|
||||
};
|
||||
o.translate(FGVec3::new(self.0.x, self.0.y, FGi32::ZERO));
|
||||
o
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_air_motion(
|
||||
fighters: Query<(
|
||||
&FighterVelocity,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//! ECS types so it stays cheap to reason about and to unit-test — it has to be
|
||||
//! bit-for-bit deterministic for rollback.
|
||||
|
||||
use crate::fighter::state::{FighterState, FighterStateContext, dash, turn, wait, walk};
|
||||
use crate::fighter::state::{FighterState, FighterStateContext, dash, ground_attack, turn, wait, walk};
|
||||
use crate::fighter::{
|
||||
FighterAttributes, FighterPreviousTranslation, FighterTranslation, FighterVelocity,
|
||||
};
|
||||
@@ -151,7 +151,9 @@ pub fn grounded_movement_standstill_common_interrupts(
|
||||
state_context: &FighterStateContext,
|
||||
ground_common: &GroundedStateCommon,
|
||||
) -> Option<FighterState> {
|
||||
if let Some(state) = dash::check_input(state_context, &ground_common) {
|
||||
if let Some(state) = ground_attack::check_interrupt(state_context, &ground_common) {
|
||||
Some(state)
|
||||
} else if let Some(state) = dash::check_input(state_context, &ground_common) {
|
||||
Some(state)
|
||||
} else if let Some(state) = turn::check_input(state_context, &ground_common) {
|
||||
Some(state)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use crate::fighter::{attack::{AttackKind, update_active_hitbox_list}, state::{FighterState, FighterStateImpl, ground::GroundedStateCommon, wait::WaitState}};
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, Hash)]
|
||||
pub struct GroundAttackState {
|
||||
pub attack_kind: AttackKind,
|
||||
pub grounded_common: GroundedStateCommon,
|
||||
}
|
||||
|
||||
impl FighterStateImpl for GroundAttackState {
|
||||
const NAME: &'static str = "GroundAttack";
|
||||
|
||||
fn check_interrupt(&self, state_context: &mut super::FighterStateContext) -> Option<FighterState> {
|
||||
if state_context.is_current_animation_finished() {
|
||||
Some(FighterState::Wait(WaitState {
|
||||
grounded_common: self.grounded_common.clone()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn update(&mut self, state_context: &mut super::FighterStateContext) {
|
||||
let script = state_context.attack_scripts.get(&state_context.attack_script_assets.scripts[&self.attack_kind]);
|
||||
if let Some(script) = script {
|
||||
let animation_frame = state_context.get_current_animation_frame();
|
||||
update_active_hitbox_list(script, &mut state_context.hitboxes.active_hitboxes, animation_frame);
|
||||
}
|
||||
}
|
||||
|
||||
fn on_enter(&mut self, state_context: &mut super::FighterStateContext) {
|
||||
state_context.play_animation(self.attack_kind.get_animation(), false);
|
||||
state_context.hitboxes.attack_script = Some(state_context.attack_script_assets.scripts[&self.attack_kind].clone());
|
||||
state_context.hitboxes.active_hitboxes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_interrupt(state_context: &super::FighterStateContext, grounded_common: &GroundedStateCommon) -> Option<FighterState> {
|
||||
if state_context.input.has_command(crate::input::FighterCommands::Attack) {
|
||||
Some(FighterState::GroundAttack(GroundAttackState {
|
||||
attack_kind: AttackKind::Jab,
|
||||
grounded_common: grounded_common.clone()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,18 @@ use bevy::ecs::query::QueryData;
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::fighter::animation::{AnimKind, FighterAnimationFrame, FighterAnimationPlayerLink};
|
||||
use crate::fighter::attack::FighterAttackScriptAssets;
|
||||
use crate::fighter::baked_animation::{BakedFighterAnimations, FixedMat4};
|
||||
use crate::fighter::ecb::FighterPreviousECB;
|
||||
use crate::fighter::manifest::FighterManifest;
|
||||
use crate::fighter::state::ground_attack::GroundAttackState;
|
||||
use crate::fighter::visual::FighterAnimations;
|
||||
use crate::fighter::{
|
||||
Fighter, FighterECB, FighterFacingDirection, FighterPreviousTranslation,
|
||||
FighterTranslation, FighterVelocity,
|
||||
Fighter, FighterECB, FighterFacingDirection, FighterHitboxes, FighterPreviousTranslation, FighterTranslation, FighterVelocity,
|
||||
};
|
||||
use crate::game_settings::GameSettings;
|
||||
use crate::input::FighterInput;
|
||||
use crate::scripting::FighterAttackScript;
|
||||
use crate::stage::line::StageCollision;
|
||||
|
||||
pub mod air;
|
||||
@@ -29,6 +31,7 @@ pub mod run;
|
||||
pub mod turn;
|
||||
pub mod wait;
|
||||
pub mod walk;
|
||||
pub mod ground_attack;
|
||||
|
||||
macro_rules! fighter_states {
|
||||
($($variant:ident => $ty:ty),* $(,)?) => {
|
||||
@@ -80,6 +83,7 @@ pub struct FighterStateContext<'a> {
|
||||
pub translation: &'a mut FighterTranslation,
|
||||
pub prev_translation: &'a mut FighterPreviousTranslation,
|
||||
pub input: &'a mut FighterInput,
|
||||
pub hitboxes: &'a mut FighterHitboxes,
|
||||
pub velocity: &'a mut FighterVelocity,
|
||||
pub ecb: &'a mut FighterECB,
|
||||
pub prev_ecb: &'a mut FighterPreviousECB,
|
||||
@@ -91,7 +95,9 @@ pub struct FighterStateContext<'a> {
|
||||
pub animation_transitions: &'a mut AnimationTransitions,
|
||||
pub animation_frame: &'a mut FighterAnimationFrame,
|
||||
pub baked_animations: &'a Assets<BakedFighterAnimations>,
|
||||
pub attack_scripts: &'a Assets<FighterAttackScript>,
|
||||
pub fighter_manifest: &'a FighterManifest,
|
||||
pub attack_script_assets: &'a FighterAttackScriptAssets,
|
||||
}
|
||||
|
||||
impl FighterStateContext<'_> {
|
||||
@@ -124,7 +130,7 @@ impl FighterStateContext<'_> {
|
||||
|
||||
pub fn sample_bone(&self, bone: &str) -> Option<FixedMat4> {
|
||||
self.animations
|
||||
.sample_bone(self.baked_animations, *self.animation_frame, bone)
|
||||
.sample_bone(self.baked_animations, self.animation_frame, bone)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +144,8 @@ fighter_states! {
|
||||
Jump => jump::JumpState,
|
||||
Land => land::LandingState,
|
||||
AirDodge => air_dodge::AirDodgeState,
|
||||
Turn => turn::TurnState
|
||||
Turn => turn::TurnState,
|
||||
GroundAttack => ground_attack::GroundAttackState,
|
||||
}
|
||||
|
||||
#[derive(QueryData)]
|
||||
@@ -147,6 +154,7 @@ pub struct FighterFrameQuery {
|
||||
pub translation: &'static mut FighterTranslation,
|
||||
pub prev_translation: &'static mut FighterPreviousTranslation,
|
||||
pub input: &'static mut FighterInput,
|
||||
pub hitboxes: &'static mut FighterHitboxes,
|
||||
pub velocity: &'static mut FighterVelocity,
|
||||
pub ecb: &'static mut FighterECB,
|
||||
pub prev_ecb: &'static mut FighterPreviousECB,
|
||||
@@ -164,12 +172,15 @@ impl<'w, 's> FighterFrameQueryItem<'w, 's> {
|
||||
animation_player: &'a mut AnimationPlayer,
|
||||
animation_transitions: &'a mut AnimationTransitions,
|
||||
baked_animations: &'a Assets<BakedFighterAnimations>,
|
||||
attack_scripts: &'a Assets<FighterAttackScript>,
|
||||
attack_script_assets: &'a FighterAttackScriptAssets,
|
||||
manifest: &'a FighterManifest,
|
||||
) -> FighterStateContext<'a> {
|
||||
FighterStateContext {
|
||||
translation: &mut self.translation,
|
||||
prev_translation: &mut self.prev_translation,
|
||||
input: &mut self.input,
|
||||
hitboxes: &mut self.hitboxes,
|
||||
velocity: &mut self.velocity,
|
||||
ecb: &mut self.ecb,
|
||||
prev_ecb: &mut self.prev_ecb,
|
||||
@@ -181,6 +192,8 @@ impl<'w, 's> FighterFrameQueryItem<'w, 's> {
|
||||
animation_transitions,
|
||||
animation_frame: &mut self.animation_frame,
|
||||
baked_animations,
|
||||
attack_scripts,
|
||||
attack_script_assets,
|
||||
fighter_manifest: manifest,
|
||||
}
|
||||
}
|
||||
@@ -195,6 +208,7 @@ pub struct StatefulFighterQuery {
|
||||
pub animations: &'static FighterAnimations,
|
||||
pub animation_player_link: &'static FighterAnimationPlayerLink,
|
||||
pub fighter: &'static Fighter,
|
||||
pub attack_script_assets: &'static FighterAttackScriptAssets,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
@@ -212,6 +226,7 @@ pub fn state_update_system(
|
||||
stage_collision: Res<StageCollision>,
|
||||
game_settings: Res<GameSettings>,
|
||||
baked_animations: Res<Assets<BakedFighterAnimations>>,
|
||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||
manifests: Res<Assets<FighterManifest>>,
|
||||
) {
|
||||
for fighter in &mut query {
|
||||
@@ -235,6 +250,8 @@ pub fn state_update_system(
|
||||
&mut animation_player,
|
||||
&mut animation_transitions,
|
||||
&baked_animations,
|
||||
&attack_scripts,
|
||||
&fighter.attack_script_assets,
|
||||
&manifests
|
||||
.get(&(fighter.fighter.manifest))
|
||||
.expect("Fighter manifest should be valid"),
|
||||
@@ -250,6 +267,7 @@ pub fn state_interrupt_system(
|
||||
game_settings: Res<GameSettings>,
|
||||
baked_animations: Res<Assets<BakedFighterAnimations>>,
|
||||
fighter_manifests: Res<Assets<FighterManifest>>,
|
||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for fighter in &mut query {
|
||||
@@ -260,6 +278,7 @@ pub fn state_interrupt_system(
|
||||
animations,
|
||||
animation_player_link,
|
||||
fighter,
|
||||
attack_script_assets
|
||||
} = fighter;
|
||||
let Ok((mut animation_player, mut animation_transitions)) =
|
||||
animation_players.get_mut(animation_player_link.player())
|
||||
@@ -273,6 +292,8 @@ pub fn state_interrupt_system(
|
||||
&mut animation_player,
|
||||
&mut animation_transitions,
|
||||
&baked_animations,
|
||||
&attack_scripts,
|
||||
attack_script_assets,
|
||||
fighter_manifests
|
||||
.get(&fighter.manifest)
|
||||
.expect("Fighter manifest should be valid"),
|
||||
@@ -297,6 +318,7 @@ pub fn state_collision_interrupt_system(
|
||||
game_settings: Res<GameSettings>,
|
||||
baked_animations: Res<Assets<BakedFighterAnimations>>,
|
||||
fighter_manifests: Res<Assets<FighterManifest>>,
|
||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for fighter in &mut query {
|
||||
@@ -307,6 +329,7 @@ pub fn state_collision_interrupt_system(
|
||||
animations,
|
||||
animation_player_link,
|
||||
fighter,
|
||||
attack_script_assets,
|
||||
} = fighter;
|
||||
let Ok((mut animation_player, mut animation_transitions)) =
|
||||
animation_players.get_mut(animation_player_link.player())
|
||||
@@ -320,6 +343,8 @@ pub fn state_collision_interrupt_system(
|
||||
&mut animation_player,
|
||||
&mut animation_transitions,
|
||||
&baked_animations,
|
||||
&attack_scripts,
|
||||
&attack_script_assets,
|
||||
fighter_manifests
|
||||
.get(&fighter.manifest)
|
||||
.expect("Fighter manifest should be valid"),
|
||||
|
||||
@@ -16,7 +16,7 @@ impl FighterAnimations {
|
||||
pub fn sample_bone(
|
||||
&self,
|
||||
baked_assets: &Assets<BakedFighterAnimations>,
|
||||
frame: FighterAnimationFrame,
|
||||
frame: &FighterAnimationFrame,
|
||||
bone: &str,
|
||||
) -> Option<crate::fighter::baked_animation::FixedMat4> {
|
||||
let baked = baked_assets.get(&self.baked)?;
|
||||
|
||||
Reference in New Issue
Block a user