initial work on hitbox and hurtbox collisions
This commit is contained in:
+116
-13
@@ -6,18 +6,11 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
fighter::{
|
||||
Fighter, FighterAttributes, FighterFacingDirection, FighterTranslation,
|
||||
animation::AnimKind,
|
||||
baked_animation::{FighterBoneMatrices, FixedMat4},
|
||||
hurtbox::FixedAffineCapsule,
|
||||
manifest::FighterManifest,
|
||||
},
|
||||
math::{
|
||||
Fighter, FighterAttributes, FighterFacingDirection, FighterHitboxes, FighterTranslation, animation::{AnimKind, FighterAnimationFrame}, baked_animation::{FighterBoneMatrices, FixedMat4}, hurtbox::{FixedAffineCapsule, FixedCapsule}, manifest::FighterManifest,
|
||||
}, math::{
|
||||
int::{FGi32, FGi32Ext},
|
||||
vec3::FGVec3,
|
||||
},
|
||||
schedule::GameplaySet,
|
||||
scripting::FighterAttackScript,
|
||||
}, schedule::GameplaySet, scripting::FighterAttackScript,
|
||||
};
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||
pub struct FighterDamage(FGi32);
|
||||
@@ -77,17 +70,35 @@ impl AttackAngle {
|
||||
|
||||
#[derive(Serialize, Deserialize, Reflect, PartialEq, Eq, Hash, Clone, Debug)]
|
||||
pub enum AttackKind {
|
||||
NAir,
|
||||
NeutralAir,
|
||||
ForwardAir,
|
||||
BackAir,
|
||||
DownAir,
|
||||
UpAir,
|
||||
Jab,
|
||||
UpTilt,
|
||||
DownTilt,
|
||||
ForwardTilt,
|
||||
UpSmash,
|
||||
DownSmash,
|
||||
ForwardSmash,
|
||||
}
|
||||
|
||||
impl AttackKind {
|
||||
pub fn get_animation(&self) -> AnimKind {
|
||||
match self {
|
||||
AttackKind::NAir => AnimKind::AttackJab1,
|
||||
AttackKind::NeutralAir => AnimKind::AttackJab1,
|
||||
AttackKind::Jab => AnimKind::AttackJab1,
|
||||
AttackKind::UpTilt => AnimKind::AttackUpTilt,
|
||||
AttackKind::ForwardAir => AnimKind::AttackUpTilt,
|
||||
AttackKind::BackAir => AnimKind::AttackUpTilt,
|
||||
AttackKind::DownAir => AnimKind::AttackUpTilt,
|
||||
AttackKind::UpAir => AnimKind::AttackUpTilt,
|
||||
AttackKind::DownTilt => AnimKind::AttackDownTilt,
|
||||
AttackKind::ForwardTilt => AnimKind::AttackForwardTilt,
|
||||
AttackKind::UpSmash => AnimKind::AttackUpTilt,
|
||||
AttackKind::DownSmash => AnimKind::AttackUpTilt,
|
||||
AttackKind::ForwardSmash => AnimKind::AttackUpTilt,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,6 +192,69 @@ pub struct FighterSolvedHurtbox {
|
||||
pub capsule: FixedAffineCapsule,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Hash)]
|
||||
pub struct FighterSolvedHitbox {
|
||||
pub hitbox_idx: usize,
|
||||
pub capsule: FixedCapsule,
|
||||
}
|
||||
|
||||
#[derive(Component, Clone, Debug, Default, Hash)]
|
||||
pub struct FighterSolvedHitboxes(pub Vec<FighterSolvedHitbox>);
|
||||
|
||||
pub fn solve_hitboxes(
|
||||
mut query: Query<(
|
||||
&FighterBoneMatrices,
|
||||
&FighterTranslation,
|
||||
&FighterFacingDirection,
|
||||
&mut FighterHitboxes,
|
||||
&FighterAnimationFrame
|
||||
)>,
|
||||
attack_scripts: Res<Assets<FighterAttackScript>>,
|
||||
) {
|
||||
for (matrices, translation, facing_direction, mut hitboxes, animation_frame) in &mut query {
|
||||
hitboxes.active_hitboxes_solved.clear();
|
||||
if let Some(ref attack_script) = hitboxes.attack_script {
|
||||
let attack_script = attack_scripts.get(attack_script).expect("Attack script should be valid");
|
||||
let fighter_trf = translation.get_3d_transform(facing_direction);
|
||||
let active_hitboxes = hitboxes.active_hitboxes.clone();
|
||||
for hitbox_idx in active_hitboxes {
|
||||
let hitbox = attack_script.hitboxes.get(hitbox_idx).expect("Hitbox IDX should be valid");
|
||||
let matrices = matrices.get(&hitbox.bone);
|
||||
|
||||
if let None = matrices {
|
||||
warn!("Bone {} not found!", hitbox.bone);
|
||||
continue;
|
||||
}
|
||||
|
||||
let (prev_bone_matrix, curr_bone_matrix) = matrices.unwrap();
|
||||
|
||||
let curr_hbox_matrix = fighter_trf.mul(curr_bone_matrix);
|
||||
let curr_hbox_pos = curr_hbox_matrix.transform_point(hitbox.offset);
|
||||
|
||||
if hitbox.start_frame == animation_frame.frame {
|
||||
// Sphere only
|
||||
hitboxes.active_hitboxes_solved.push(
|
||||
FixedCapsule {
|
||||
start: curr_hbox_pos,
|
||||
end: curr_hbox_pos,
|
||||
radius: hitbox.radius
|
||||
}
|
||||
)
|
||||
} else {
|
||||
let prev_hbox_matrix = fighter_trf.mul(prev_bone_matrix);
|
||||
let prev_hbox_pos = prev_hbox_matrix.transform_point(hitbox.offset);
|
||||
hitboxes.active_hitboxes_solved.push(
|
||||
FixedCapsule {
|
||||
start: prev_hbox_pos,
|
||||
end: curr_hbox_pos,
|
||||
radius: hitbox.radius
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Component)]
|
||||
pub struct FighterAttackScriptAssets {
|
||||
pub scripts: HashMap<AttackKind, Handle<FighterAttackScript>>,
|
||||
@@ -229,13 +303,42 @@ pub fn solve_hurtboxes(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intersect_attacks_with_hurtboxes(query: Query<(Entity, &FighterSolvedHurtboxes, &FighterHitboxes)>, attack_scripts: Res<Assets<FighterAttackScript>>) {
|
||||
/*for (entity_hurting, _, hitboxes) in query {
|
||||
if hitboxes.attack_script.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ref attack_script) = hitboxes.attack_script {
|
||||
let attack_script = attack_scripts.get(attack_script);
|
||||
|
||||
if attack_script.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let attack_script = attack_script.unwrap();
|
||||
|
||||
let capsules: Vec<(&AttackHitbox, FixedCapsule)> = hitboxes.active_hitboxes.iter().map(|idx| {
|
||||
(attack_script.hitboxes.get(*idx).unwrap(), )
|
||||
}).collect();
|
||||
|
||||
for (entity_to_hurt, hurtboxes, _) in query {
|
||||
// Self collisions not allowed
|
||||
if entity_to_hurt == entity_hurting {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
pub struct FighterAttackPlugin;
|
||||
|
||||
impl Plugin for FighterAttackPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(
|
||||
GgrsSchedule,
|
||||
solve_hurtboxes
|
||||
(solve_hurtboxes, solve_hitboxes).chain()
|
||||
.after(crate::fighter::baked_animation::update_fighter_bone_matrices)
|
||||
.in_set(GameplaySet::Animation),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user