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),
/*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),
/*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),
/*11*/(key:"nanny", ability:Thrown, range:60),
/*12*/(key:"panic attack", ability:Turbo),

View File

@@ -10,6 +10,7 @@ use crate::{
aim::AimTarget,
character::CharacterHierarchy,
global_observer,
head::ActiveHead,
heads::ActiveHeads,
heads_database::HeadsDatabase,
physics_layers::GameLayer,
@@ -88,7 +89,7 @@ pub struct TriggerCurver(pub TriggerData);
#[derive(Resource, Default)]
pub struct TriggerStateRes {
cooldown: f32,
next_trigger_timestamp: f32,
active: bool,
}
@@ -116,10 +117,17 @@ pub fn plugin(app: &mut App) {
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);
if !res.active {
res.cooldown = 0.0;
if res.active {
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>,
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 {
return;
};
@@ -166,7 +174,7 @@ fn update(
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 {
dir,

View File

@@ -20,6 +20,7 @@ pub struct AnimationFlags {
pub jumping: bool,
pub just_jumped: bool,
pub shooting: bool,
pub restart_shooting: bool,
pub hit: bool,
}
@@ -110,12 +111,15 @@ fn update_animation(
.animation(anims.run_shoot.unwrap())
.unwrap()
.is_finished()
|| flags.restart_shooting
{
controller
.player
.animation_mut(anims.run_shoot.unwrap())
.unwrap()
.replay();
flags.restart_shooting = false;
}
} else if flags.shooting && anims.shoot.is_some() {
if !controller.is_playing(anims.shoot.unwrap()) {
@@ -130,12 +134,15 @@ fn update_animation(
.animation(anims.shoot.unwrap())
.unwrap()
.is_finished()
|| flags.restart_shooting
{
controller
.player
.animation_mut(anims.shoot.unwrap())
.unwrap()
.replay();
flags.restart_shooting = false;
}
} else if flags.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 shoot = animations
.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
.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);
// Insert a resource with the current scene information

View File

@@ -2,7 +2,9 @@ mod heads_ui;
use crate::{
GameState,
animation::AnimationFlags,
backpack::{BackbackSwapEvent, Backpack},
character::HasCharacterAnimations,
global_observer,
heads_database::HeadsDatabase,
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() {
if !active.reloading() {
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()) {
// only for player?
commands.trigger(PlaySound::Reloaded);
let mut flags = anim_flags.get_mut(*player.collection()).unwrap();
flags.restart_shooting = true;
head.ammo = head.ammo_max;
}
}