feat: added parry and homerun

This commit is contained in:
TotallyNot 2025-11-05 19:40:16 +01:00
parent 71169690b7
commit 67131c7985
Signed by: pyrite
GPG key ID: 7F1BA9170CD35D15
9 changed files with 440 additions and 181 deletions

View file

@ -1,11 +1,12 @@
use bevy_ecs::prelude::*;
use proxisim_models::bundle::{
bonus::{ArmourBypassBonus, BonusPartDamageBonus, BonusValue, MiscBonus, WeaponBonusType},
player::PartDamageBonus,
player::{ActionNullification, PartDamageBonus},
stat::{
AdditiveBonus, AmmoControl, Clips, CritRate, DamageBonus, SimpleStatBonus,
SimpleStatEffective, Speed, Strength, WeaponAccuracy,
},
weapon::Weapon,
};
use crate::{
@ -197,10 +198,11 @@ impl BonusPartDamageBonus {
pub(crate) fn prepare_bonuses(
bonus_q: Query<(&ChildOf, &WeaponBonusType, &BonusValue)>,
clips_q: Query<&SimpleStatEffective<Clips>>,
weapon_q: Query<&ChildOf, With<Weapon>>,
mut effects: Effects,
mut commands: Commands,
) {
for (weapon, bonus, value) in bonus_q.iter() {
for (weapon, bonus, value) in bonus_q {
match bonus {
WeaponBonusType::Berserk => {
effects.spawn(
@ -495,6 +497,23 @@ pub(crate) fn prepare_bonuses(
chance: value.0 as f64 / 100.0,
});
}
WeaponBonusType::Parry => {
let player = weapon_q.get(weapon.parent()).unwrap();
commands
.entity(player.parent())
.with_child(ActionNullification::Parry {
chance: value.0 as f64 / 100.0,
});
}
WeaponBonusType::Homerun => {
let player = weapon_q.get(weapon.parent()).unwrap();
commands
.entity(player.parent())
.with_child(ActionNullification::Homerun {
chance: value.0 as f64 / 100.0,
});
}
val => unimplemented!("{val:?}"),
}
}

View file

@ -540,12 +540,15 @@ pub(crate) fn configure(stages: &mut Stages) {
// running this in the snapshot layer ensures that the stat increases aren't restored at the
// end of the run
stages.snapshot.add_systems(apply_first_turn_effects);
stages.equip.add_systems(apply_passives);
stages
.equip
.add_systems((apply_passives, restore_usability));
stages.turn.add_systems(reload_weapon);
stages.post_turn.add_systems(unset_current);
stages
.restore
.add_systems((restore_ammo, restore_usability, apply_first_turn_effects));
.post_fight
.add_systems((restore_usability, restore_ammo));
stages.restore.add_systems(apply_first_turn_effects);
temp::configure(stages);
bonus::configure(stages);

View file

@ -1,11 +1,12 @@
use bevy_ecs::prelude::*;
use proxisim_models::bundle::{
player::{Current, CurrentTarget, HealthChange, Player},
weapon::{BuffingTemp, DebuffingTemp, Usable, Uses},
player::{ActionNullification, Current, CurrentTarget, HealthChange, PickedAction, Player},
weapon::{BuffingTemp, DebuffingTemp, Usable, Uses, WeaponSlot},
};
use rand::Rng as _;
use crate::{
Stages,
Rng, Stages,
effect::Effects,
log,
log::Logger,
@ -19,15 +20,39 @@ use crate::{
pub struct AssociatedWeapon(pub Entity);
fn use_debuffing_temp(
mut temp_q: Query<(Entity, &DebuffingTemp, &mut Uses), With<Current>>,
target_q: Query<Entity, With<CurrentTarget>>,
mut temp_q: Query<(Entity, &DebuffingTemp, &mut Uses, &ChildOf), With<Current>>,
target_q: Query<(Entity, &Children, &PickedAction), With<CurrentTarget>>,
nullification_q: Query<&ActionNullification>,
mut effects: Effects,
mut commands: Commands,
mut rng: ResMut<Rng>,
mut logger: Logger,
) {
let Ok((weapon, temp, mut uses)) = temp_q.single_mut() else {
let Ok((weapon, temp, mut uses, player)) = temp_q.single_mut() else {
return;
};
let target = target_q.single().unwrap();
let (target, children, picked_action) = target_q.single().unwrap();
uses.0 -= 1;
if uses.0 == 0 {
commands.entity(weapon).remove::<Usable>();
}
for bonus in nullification_q.iter_many(children) {
if let ActionNullification::Homerun { chance } = bonus
&& picked_action.0 == WeaponSlot::Melee
&& (*chance >= 1.0 || rng.random_bool(*chance))
{
log!(logger, "nullified", {
actor: player.parent(),
recipient: target,
kind: "homerun",
weapon,
});
return;
}
}
match temp {
DebuffingTemp::TearGas => effects.spawn_and_insert(
@ -56,11 +81,6 @@ fn use_debuffing_temp(
AssociatedWeapon(weapon),
),
};
uses.0 -= 1;
if uses.0 == 0 {
commands.entity(weapon).remove::<Usable>();
}
}
fn use_buffing_temp(