Sync projectiles animations (#51)

This commit is contained in:
extrawurst
2025-06-25 17:17:21 +02:00
committed by GitHub
parent 63dea78c4f
commit 5d00cede94
5 changed files with 35 additions and 10 deletions

View File

@@ -8,7 +8,7 @@
/*06*/(key:"goblin", ability:Arrow, aps:2, ammo:5, range:90, damage:50), /*06*/(key:"goblin", ability:Arrow, aps:2, ammo:5, range:90, damage:50),
/*07*/(key:"green grocer", ability:Curver, range:60, ammo:10, damage:25, projectile:"carrot"), /*07*/(key:"green grocer", ability:Curver, range:60, ammo:10, damage:25, projectile:"carrot"),
/*08*/(key:"highland hammer thrower", ability:Thrown, aps:2, ammo:10, damage:25, range:80, projectile:"hammer", interrupt_shoot:false), /*08*/(key:"highland hammer thrower", ability:Thrown, aps:2, ammo:10, damage:25, range:80, projectile:"hammer", interrupt_shoot:false),
/*09*/(key:"legionnaire", ability:Gun, aps:1.5, ammo:25, range:60, damage:13), /*09*/(key:"legionnaire", ability:Gun, aps:2, ammo:25, range:60, damage:13, shoot_offset:0.1667),
/*10*/(key:"mig pilot", ability:Missile, ammo:5, range:60, damage:100, controls:Plane), /*10*/(key:"mig pilot", ability:Missile, ammo:5, range:60, damage:100, controls:Plane),
/*11*/(key:"nanny", ability:Thrown, range:60), /*11*/(key:"nanny", ability:Thrown, range:60),
/*12*/(key:"panic attack", ability:Turbo), /*12*/(key:"panic attack", ability:Turbo),

View File

@@ -10,6 +10,7 @@ use crate::{
aim::AimTarget, aim::AimTarget,
character::CharacterHierarchy, character::CharacterHierarchy,
global_observer, global_observer,
head::ActiveHead,
heads::ActiveHeads, heads::ActiveHeads,
heads_database::HeadsDatabase, heads_database::HeadsDatabase,
physics_layers::GameLayer, physics_layers::GameLayer,
@@ -88,7 +89,7 @@ pub struct TriggerCurver(pub TriggerData);
#[derive(Resource, Default)] #[derive(Resource, Default)]
pub struct TriggerStateRes { pub struct TriggerStateRes {
cooldown: f32, next_trigger_timestamp: f32,
active: bool, active: bool,
} }
@@ -116,10 +117,17 @@ pub fn plugin(app: &mut App) {
global_observer!(app, on_trigger_state); global_observer!(app, on_trigger_state);
} }
fn on_trigger_state(trigger: Trigger<TriggerState>, mut res: ResMut<TriggerStateRes>) { fn on_trigger_state(
trigger: Trigger<TriggerState>,
mut res: ResMut<TriggerStateRes>,
player_head: Single<&ActiveHead, With<Player>>,
headdb: Res<HeadsDatabase>,
time: Res<Time>,
) {
res.active = matches!(trigger.event(), TriggerState::Active); res.active = matches!(trigger.event(), TriggerState::Active);
if !res.active { if res.active {
res.cooldown = 0.0; let head_stats = headdb.head_stats(player_head.0);
res.next_trigger_timestamp = time.elapsed_secs() + head_stats.shoot_offset;
} }
} }
@@ -133,7 +141,7 @@ fn update(
time: Res<Time>, time: Res<Time>,
character: CharacterHierarchy, character: CharacterHierarchy,
) { ) {
if res.active && res.cooldown < time.elapsed_secs() { if res.active && res.next_trigger_timestamp < time.elapsed_secs() {
let Some(state) = active_heads.current() else { let Some(state) = active_heads.current() else {
return; return;
}; };
@@ -166,7 +174,7 @@ fn update(
active_heads.use_ammo(time.elapsed_secs()); active_heads.use_ammo(time.elapsed_secs());
res.cooldown = time.elapsed_secs() + (1. / head.aps); res.next_trigger_timestamp = time.elapsed_secs() + (1. / head.aps);
let trigger_state = TriggerData { let trigger_state = TriggerData {
dir, dir,

View File

@@ -20,6 +20,7 @@ pub struct AnimationFlags {
pub jumping: bool, pub jumping: bool,
pub just_jumped: bool, pub just_jumped: bool,
pub shooting: bool, pub shooting: bool,
pub restart_shooting: bool,
pub hit: bool, pub hit: bool,
} }
@@ -110,12 +111,15 @@ fn update_animation(
.animation(anims.run_shoot.unwrap()) .animation(anims.run_shoot.unwrap())
.unwrap() .unwrap()
.is_finished() .is_finished()
|| flags.restart_shooting
{ {
controller controller
.player .player
.animation_mut(anims.run_shoot.unwrap()) .animation_mut(anims.run_shoot.unwrap())
.unwrap() .unwrap()
.replay(); .replay();
flags.restart_shooting = false;
} }
} else if flags.shooting && anims.shoot.is_some() { } else if flags.shooting && anims.shoot.is_some() {
if !controller.is_playing(anims.shoot.unwrap()) { if !controller.is_playing(anims.shoot.unwrap()) {
@@ -130,12 +134,15 @@ fn update_animation(
.animation(anims.shoot.unwrap()) .animation(anims.shoot.unwrap())
.unwrap() .unwrap()
.is_finished() .is_finished()
|| flags.restart_shooting
{ {
controller controller
.player .player
.animation_mut(anims.shoot.unwrap()) .animation_mut(anims.shoot.unwrap())
.unwrap() .unwrap()
.replay(); .replay();
flags.restart_shooting = false;
} }
} else if flags.hit { } else if flags.hit {
if !controller.is_playing(anims.hit) { if !controller.is_playing(anims.hit) {

View File

@@ -199,10 +199,10 @@ fn setup_once_loaded(
let jump = graph.add_clip(animations[ANIM_JUMP].clone(), 1.0, root); let jump = graph.add_clip(animations[ANIM_JUMP].clone(), 1.0, root);
let shoot = animations let shoot = animations
.get(ANIM_SHOOT) .get(ANIM_SHOOT)
.map(|it| graph.add_clip(it.clone(), 1.0, root)); .map(|clip| graph.add_clip(clip.clone(), 1.0, root));
let run_shoot = animations let run_shoot = animations
.get(ANIM_RUN_SHOOT) .get(ANIM_RUN_SHOOT)
.map(|it| graph.add_clip(it.clone(), 1.0, root)); .map(|clip| graph.add_clip(clip.clone(), 1.0, root));
let hit = graph.add_clip(animations[ANIM_HIT].clone(), 1.0, root); let hit = graph.add_clip(animations[ANIM_HIT].clone(), 1.0, root);
// Insert a resource with the current scene information // Insert a resource with the current scene information

View File

@@ -2,7 +2,9 @@ mod heads_ui;
use crate::{ use crate::{
GameState, GameState,
animation::AnimationFlags,
backpack::{BackbackSwapEvent, Backpack}, backpack::{BackbackSwapEvent, Backpack},
character::HasCharacterAnimations,
global_observer, global_observer,
heads_database::HeadsDatabase, heads_database::HeadsDatabase,
hitpoints::Hitpoints, hitpoints::Hitpoints,
@@ -208,7 +210,13 @@ fn sync_hp(mut query: Query<(&mut ActiveHeads, &Hitpoints)>) {
} }
} }
fn reload(mut commands: Commands, mut active: Query<&mut ActiveHeads>, time: Res<Time>) { fn reload(
mut commands: Commands,
mut active: Query<&mut ActiveHeads>,
time: Res<Time>,
player: Single<&HasCharacterAnimations, With<Player>>,
mut anim_flags: Query<&mut AnimationFlags>,
) {
for mut active in active.iter_mut() { for mut active in active.iter_mut() {
if !active.reloading() { if !active.reloading() {
continue; continue;
@@ -222,6 +230,8 @@ fn reload(mut commands: Commands, mut active: Query<&mut ActiveHeads>, time: Res
if !head.has_ammo() && (head.last_use + head.reload_duration <= time.elapsed_secs()) { if !head.has_ammo() && (head.last_use + head.reload_duration <= time.elapsed_secs()) {
// only for player? // only for player?
commands.trigger(PlaySound::Reloaded); commands.trigger(PlaySound::Reloaded);
let mut flags = anim_flags.get_mut(*player.collection()).unwrap();
flags.restart_shooting = true;
head.ammo = head.ammo_max; head.ammo = head.ammo_max;
} }
} }