ability per second db value and hold-down trigger

This commit is contained in:
2025-05-04 12:36:47 +02:00
parent 61918b632e
commit 69f9d73d80
4 changed files with 50 additions and 18 deletions

View File

@@ -1,14 +1,14 @@
([ ([
/*00*/(key:"angry demonstrator", ability:Thrown, ammo: 10, range:90, damage:25, projectile:"molotov"), /*00*/(key:"angry demonstrator", ability:Thrown, aps:2, ammo:10, range:90, damage:25, projectile:"molotov"),
/*01*/(key:"carnival knife thrower", range:60, ammo:5), /*01*/(key:"carnival knife thrower", range:60, ammo:5),
/*02*/(key:"chicago gangster", ability:Gun, ammo:25, range:60), /*02*/(key:"chicago gangster", ability:Gun, ammo:25, range:60),
/*03*/(key:"commando", ability:Gun, ammo: 26, range:60, damage:12), /*03*/(key:"commando", ability:Gun, aps:7.4, ammo:26, range:60, damage:12),
/*04*/(key:"field medic"), /*04*/(key:"field medic"),
/*05*/(key:"geisha"), /*05*/(key:"geisha"),
/*06*/(key:"goblin", ability:Arrow, ammo: 5, range:90, damage:50), /*06*/(key:"goblin", ability:Arrow, aps:2, ammo:5, range:90, damage:50),
/*07*/(key:"green grocer", range:60, ammo:10, damage:25), /*07*/(key:"green grocer", range:60, ammo:10, damage:25),
/*08*/(key:"highland hammer thrower", ability:Thrown, ammo: 10, damage: 25, range:80, projectile:"hammer"), /*08*/(key:"highland hammer thrower", ability:Thrown, aps:2, ammo:10, damage:25, range:80, projectile:"hammer"),
/*09*/(key:"legionnaire", ability:Gun, ammo: 25, range:60, damage: 13), /*09*/(key:"legionnaire", ability:Gun, aps:1.5, ammo:25, range:60, damage:13),
/*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"), /*12*/(key:"panic attack"),

View File

@@ -161,9 +161,13 @@ fn shot_collision(
let shot_entity = if query_shot.contains(*e1) { *e1 } else { *e2 }; let shot_entity = if query_shot.contains(*e1) { *e1 } else { *e2 };
let shot_pos = query_shot.get(shot_entity).unwrap().1.translation; if let Ok(mut entity) = commands.get_entity(shot_entity) {
entity.despawn();
} else {
continue;
}
commands.entity(shot_entity).despawn(); let shot_pos = query_shot.get(shot_entity).unwrap().1.translation;
let texture_atlas = TextureAtlas { let texture_atlas = TextureAtlas {
layout: assets.layout.clone(), layout: assets.layout.clone(),

View File

@@ -4,6 +4,7 @@ mod missile;
mod thrown; mod thrown;
use crate::{ use crate::{
GameState,
aim::AimTarget, aim::AimTarget,
character::CharacterHierarchy, character::CharacterHierarchy,
global_observer, global_observer,
@@ -74,17 +75,34 @@ pub struct TriggerThrow(pub TriggerData);
#[derive(Event, Reflect)] #[derive(Event, Reflect)]
pub struct TriggerMissile(pub TriggerData); pub struct TriggerMissile(pub TriggerData);
#[derive(Resource, Default)]
struct TriggerStateRes {
cooldown: f32,
active: bool,
}
pub fn plugin(app: &mut App) { pub fn plugin(app: &mut App) {
app.init_resource::<TriggerStateRes>();
app.add_plugins(gun::plugin); app.add_plugins(gun::plugin);
app.add_plugins(thrown::plugin); app.add_plugins(thrown::plugin);
app.add_plugins(arrow::plugin); app.add_plugins(arrow::plugin);
app.add_plugins(missile::plugin); app.add_plugins(missile::plugin);
app.add_systems(Update, update.run_if(in_state(GameState::Playing)));
global_observer!(app, on_trigger_state); global_observer!(app, on_trigger_state);
} }
fn on_trigger_state( fn on_trigger_state(trigger: Trigger<TriggerState>, mut res: ResMut<TriggerStateRes>) {
trigger: Trigger<TriggerState>, res.active = matches!(trigger.event(), TriggerState::Active);
if !res.active {
res.cooldown = 0.0;
}
}
fn update(
mut res: ResMut<TriggerStateRes>,
mut commands: Commands, mut commands: Commands,
player_rot: Query<&Transform, With<PlayerBodyMesh>>, player_rot: Query<&Transform, With<PlayerBodyMesh>>,
player_query: Query<(Entity, &AimTarget), With<Player>>, player_query: Query<(Entity, &AimTarget), With<Player>>,
@@ -93,7 +111,7 @@ fn on_trigger_state(
time: Res<Time>, time: Res<Time>,
character: CharacterHierarchy, character: CharacterHierarchy,
) { ) {
if matches!(trigger.event(), TriggerState::Active) { if res.active && res.cooldown < time.elapsed_secs() {
let Some(state) = active_heads.current() else { let Some(state) = active_heads.current() else {
return; return;
}; };
@@ -129,8 +147,11 @@ fn on_trigger_state(
active_heads.use_ammo(time.elapsed_secs()); active_heads.use_ammo(time.elapsed_secs());
let ability = heads_db.head_stats(state.head).ability; let head = heads_db.head_stats(state.head);
match ability {
res.cooldown = time.elapsed_secs() + (1. / head.aps);
match head.ability {
HeadAbility::Thrown => commands.trigger(TriggerThrow(trigger_state)), HeadAbility::Thrown => commands.trigger(TriggerThrow(trigger_state)),
HeadAbility::Gun => commands.trigger(TriggerGun(trigger_state)), HeadAbility::Gun => commands.trigger(TriggerGun(trigger_state)),
HeadAbility::Missile => commands.trigger(TriggerMissile(trigger_state)), HeadAbility::Missile => commands.trigger(TriggerMissile(trigger_state)),

View File

@@ -24,6 +24,13 @@ pub struct HeadStats {
pub ammo: u32, pub ammo: u32,
#[serde(default)] #[serde(default)]
pub damage: u32, pub damage: u32,
// ability per second
#[serde(default = "default_aps")]
pub aps: f32,
}
fn default_aps() -> f32 {
1.
} }
fn default_ammo() -> u32 { fn default_ammo() -> u32 {