updates?
This commit is contained in:
parent
e7d6b74aab
commit
35413b563c
33 changed files with 10238 additions and 1891 deletions
|
|
@ -1,102 +1,26 @@
|
|||
use bevy_ecs::prelude::*;
|
||||
|
||||
use crate::{
|
||||
effect::{Effects, TurnLimitedEffect},
|
||||
hierarchy::{HierarchyBuilder, Parent},
|
||||
player::{
|
||||
stats::{
|
||||
use proxisim_models::{
|
||||
bundle::{
|
||||
bonus::{BonusPartDamageBonus, BonusValue, WeaponBonusType},
|
||||
player::PartDamageBonus,
|
||||
stat::{
|
||||
AdditiveBonus, AmmoControl, Clips, CritRate, DamageBonus, SimpleStatBonus,
|
||||
SimpleStatEffective, Speed, Strength, WeaponAccuracy,
|
||||
},
|
||||
status_effect::{
|
||||
AdditiveStatusEffect, Crippled, Demoralise, Frozen, Motivate, Slow, Weakened, Withered,
|
||||
},
|
||||
BodyPart, PartDamageBonus,
|
||||
},
|
||||
hierarchy::{HierarchyBuilder, Parent},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
Stages,
|
||||
effect::{Effects, TurnLimitedEffect},
|
||||
player::status_effect::{
|
||||
AdditiveStatusEffect, Crippled, Demoralise, Frozen, Motivate, Slow, Weakened, Withered,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{DamageProcEffect, FirstTurnEffect, TurnTriggeredEffect};
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum WeaponBonus {
|
||||
// Weapon passives
|
||||
Berserk,
|
||||
Conserve,
|
||||
Expose,
|
||||
Grace,
|
||||
Powerful,
|
||||
Specialist,
|
||||
|
||||
// Turn triggered passives
|
||||
Empower,
|
||||
Quicken,
|
||||
|
||||
// First turn effects
|
||||
Assassinate,
|
||||
|
||||
// Additive status effects triggered by damaging hits
|
||||
Cripple,
|
||||
Demoralise,
|
||||
Freeze,
|
||||
Motivate,
|
||||
Slow,
|
||||
Toxin,
|
||||
Weaken,
|
||||
Wither,
|
||||
|
||||
// DOT status effects
|
||||
Bleed,
|
||||
Burning,
|
||||
Lacerate,
|
||||
Poison,
|
||||
SevereBurning,
|
||||
|
||||
// Other status effects
|
||||
Eviscerate,
|
||||
Paralyse,
|
||||
Schock,
|
||||
Stun,
|
||||
|
||||
// Multi attack bonuses
|
||||
Blindfire,
|
||||
Fury,
|
||||
DoubleTap,
|
||||
Rage,
|
||||
|
||||
// Body part multipliers
|
||||
Achilles,
|
||||
Crusher,
|
||||
Cupid,
|
||||
Deadeye,
|
||||
Roshambo,
|
||||
Throttle,
|
||||
|
||||
// Attack nullification types
|
||||
Homerun,
|
||||
Parry,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct BonusValue(f32);
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct WeaponBonusBundle {
|
||||
pub bonus: WeaponBonus,
|
||||
pub value: BonusValue,
|
||||
}
|
||||
|
||||
impl WeaponBonusBundle {
|
||||
pub fn new(bonus: WeaponBonus, value: f32) -> Self {
|
||||
Self {
|
||||
bonus,
|
||||
value: BonusValue(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TurnTriggeredBonus {
|
||||
Empower,
|
||||
|
|
@ -188,7 +112,7 @@ impl OpponentStatusEffect {
|
|||
Self::Slow => {
|
||||
effects.spawn(AdditiveStatusEffect::<1, Slow>::default(), target);
|
||||
}
|
||||
Self::Toxin => match rng.gen_range(0..4) {
|
||||
Self::Toxin => match rng.random_range(0..4) {
|
||||
0 => OpponentStatusEffect::Cripple.spawn(target, effects, rng),
|
||||
1 => OpponentStatusEffect::Slow.spawn(target, effects, rng),
|
||||
2 => OpponentStatusEffect::Weaken.spawn(target, effects, rng),
|
||||
|
|
@ -219,7 +143,7 @@ impl SelfStatusEffect {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
/* #[derive(Clone, Copy)]
|
||||
pub enum BonusPartDamageBonus {
|
||||
Achilles,
|
||||
Crusher,
|
||||
|
|
@ -270,21 +194,17 @@ impl BonusPartDamageBonus {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
pub(crate) fn prepare_bonuses(
|
||||
bonus_q: Query<(
|
||||
&Parent,
|
||||
&WeaponBonus,
|
||||
&BonusValue,
|
||||
Option<&SimpleStatEffective<Clips>>,
|
||||
)>,
|
||||
bonus_q: Query<(&Parent, &WeaponBonusType, &BonusValue)>,
|
||||
clips_q: Query<&SimpleStatEffective<Clips>>,
|
||||
mut effects: Effects,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
for (weapon, bonus, value, clips) in bonus_q.iter() {
|
||||
for (weapon, bonus, value) in bonus_q.iter() {
|
||||
match bonus {
|
||||
WeaponBonus::Berserk => {
|
||||
WeaponBonusType::Berserk => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<DamageBonus>::new("beserk", value.0 / 100.0),
|
||||
weapon.get(),
|
||||
|
|
@ -294,19 +214,19 @@ pub(crate) fn prepare_bonuses(
|
|||
weapon.get(),
|
||||
);
|
||||
}
|
||||
WeaponBonus::Conserve => {
|
||||
WeaponBonusType::Conserve => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<AmmoControl>::new("conserve", value.0 / 100.0),
|
||||
weapon.get(),
|
||||
);
|
||||
}
|
||||
WeaponBonus::Expose => {
|
||||
WeaponBonusType::Expose => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<CritRate>::new("expose", (value.0 / 0.5) as u16),
|
||||
weapon.get(),
|
||||
);
|
||||
}
|
||||
WeaponBonus::Grace => {
|
||||
WeaponBonusType::Grace => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<DamageBonus>::new("grace", -value.0 / 2.0 / 100.0),
|
||||
weapon.get(),
|
||||
|
|
@ -316,27 +236,27 @@ pub(crate) fn prepare_bonuses(
|
|||
weapon.get(),
|
||||
);
|
||||
}
|
||||
WeaponBonus::Powerful => {
|
||||
WeaponBonusType::Powerful => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<DamageBonus>::new("powerful", value.0 / 100.0),
|
||||
weapon.get(),
|
||||
);
|
||||
}
|
||||
WeaponBonus::Specialist => {
|
||||
WeaponBonusType::Specialist => {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<DamageBonus>::new("specialist", value.0 / 100.0),
|
||||
weapon.get(),
|
||||
);
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<Clips>::new(
|
||||
"specialist",
|
||||
-clips.map(|c| c.value as i16).unwrap_or_default(),
|
||||
),
|
||||
weapon.get(),
|
||||
);
|
||||
|
||||
if let Ok(clips) = clips_q.get(weapon.get()) {
|
||||
effects.spawn(
|
||||
SimpleStatBonus::<Clips>::new("specialist", -(clips.value as i16)),
|
||||
weapon.get(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WeaponBonus::Empower => {
|
||||
WeaponBonusType::Empower => {
|
||||
commands
|
||||
.spawn(TurnTriggeredEffect::Bonus {
|
||||
value: value.0,
|
||||
|
|
@ -344,7 +264,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Quicken => {
|
||||
WeaponBonusType::Quicken => {
|
||||
commands
|
||||
.spawn(TurnTriggeredEffect::Bonus {
|
||||
value: value.0,
|
||||
|
|
@ -353,7 +273,7 @@ pub(crate) fn prepare_bonuses(
|
|||
.set_parent(weapon.get());
|
||||
}
|
||||
|
||||
WeaponBonus::Assassinate => {
|
||||
WeaponBonusType::Assassinate => {
|
||||
commands
|
||||
.spawn(FirstTurnEffect::Bonus {
|
||||
value: value.0,
|
||||
|
|
@ -362,7 +282,7 @@ pub(crate) fn prepare_bonuses(
|
|||
.set_parent(weapon.get());
|
||||
}
|
||||
|
||||
WeaponBonus::Blindfire => {
|
||||
WeaponBonusType::Blindfire => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::MultiTurn {
|
||||
value: value.0,
|
||||
|
|
@ -370,7 +290,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Fury => {
|
||||
WeaponBonusType::Fury => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::MultiTurn {
|
||||
value: value.0,
|
||||
|
|
@ -378,7 +298,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Rage => {
|
||||
WeaponBonusType::Rage => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::MultiTurn {
|
||||
value: value.0,
|
||||
|
|
@ -386,7 +306,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::DoubleTap => {
|
||||
WeaponBonusType::DoubleTap => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::MultiTurn {
|
||||
value: value.0,
|
||||
|
|
@ -395,7 +315,7 @@ pub(crate) fn prepare_bonuses(
|
|||
.set_parent(weapon.get());
|
||||
}
|
||||
|
||||
WeaponBonus::Achilles => {
|
||||
WeaponBonusType::Achilles => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -403,7 +323,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Cupid => {
|
||||
WeaponBonusType::Cupid => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -411,7 +331,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Crusher => {
|
||||
WeaponBonusType::Crusher => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -419,7 +339,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Deadeye => {
|
||||
WeaponBonusType::Deadeye => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -427,7 +347,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Throttle => {
|
||||
WeaponBonusType::Throttle => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -435,7 +355,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Roshambo => {
|
||||
WeaponBonusType::Roshambo => {
|
||||
commands
|
||||
.spawn(PartDamageBonus::WeaponBonus {
|
||||
value: value.0 / 100.0,
|
||||
|
|
@ -444,7 +364,7 @@ pub(crate) fn prepare_bonuses(
|
|||
.set_parent(weapon.get());
|
||||
}
|
||||
|
||||
WeaponBonus::Cripple => {
|
||||
WeaponBonusType::Cripple => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -452,7 +372,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Demoralise => {
|
||||
WeaponBonusType::Demoralise => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -460,7 +380,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Freeze => {
|
||||
WeaponBonusType::Freeze => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -468,7 +388,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Slow => {
|
||||
WeaponBonusType::Slow => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -476,7 +396,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Toxin => {
|
||||
WeaponBonusType::Toxin => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -484,7 +404,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Weaken => {
|
||||
WeaponBonusType::Weaken => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -492,7 +412,7 @@ pub(crate) fn prepare_bonuses(
|
|||
})
|
||||
.set_parent(weapon.get());
|
||||
}
|
||||
WeaponBonus::Wither => {
|
||||
WeaponBonusType::Wither => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::OpponentEffect {
|
||||
value: value.0,
|
||||
|
|
@ -501,7 +421,7 @@ pub(crate) fn prepare_bonuses(
|
|||
.set_parent(weapon.get());
|
||||
}
|
||||
|
||||
WeaponBonus::Motivate => {
|
||||
WeaponBonusType::Motivate => {
|
||||
commands
|
||||
.spawn(DamageProcEffect::SelfEffect {
|
||||
value: value.0,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,25 @@
|
|||
use bevy_ecs::prelude::*;
|
||||
use proxisim_models::{
|
||||
bundle::{
|
||||
passive::{Education, EducationPartDamageBonus, FactionUpgrades, Merits},
|
||||
player::{Current, PartDamageBonus, Weapons},
|
||||
stat::{
|
||||
AdditiveBonus, AmmoControl, ClipSize, Clips, CritRate, DamageBonus, Dexterity,
|
||||
SimpleStatBonus, SimpleStatEffective, WeaponAccuracy,
|
||||
},
|
||||
weapon::{
|
||||
Ammo, EquippedMods, Experience, Japanese, NeedsReload, Usable, Weapon, WeaponCategory,
|
||||
WeaponMod, WeaponSlot,
|
||||
},
|
||||
},
|
||||
hierarchy::{HierarchyBuilder, Parent},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
effect::{Effects, TurnLimitedEffect},
|
||||
hierarchy::{HierarchyBuilder, Parent},
|
||||
log,
|
||||
log::Logger,
|
||||
passives::{Education, EducationPartDamageBonus, FactionUpgrades, Merits},
|
||||
player::{
|
||||
stats::{
|
||||
AdditiveBonus, AmmoControl, ClipSize, Clips, CritRate, DamageBonus, Dexterity,
|
||||
SimpleStatBonus, SimpleStatBundle, SimpleStatEffective, WeaponAccuracy,
|
||||
},
|
||||
Current, PartDamageBonus, Weapons,
|
||||
},
|
||||
Id, Name, Stages,
|
||||
Stages,
|
||||
};
|
||||
|
||||
use self::bonus::{
|
||||
|
|
@ -23,102 +29,6 @@ use self::bonus::{
|
|||
pub mod bonus;
|
||||
pub mod temp;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Usable;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Weapon;
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum WeaponSlot {
|
||||
Primary,
|
||||
Secondary,
|
||||
Melee,
|
||||
Temporary,
|
||||
Fists,
|
||||
Kick,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy)]
|
||||
pub enum WeaponVerb {
|
||||
Hit,
|
||||
Kicked,
|
||||
Fired,
|
||||
Threw,
|
||||
Exploded,
|
||||
}
|
||||
|
||||
#[derive(Component, Clone, Copy)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum WeaponCategory {
|
||||
HeavyArtillery,
|
||||
MachineGun,
|
||||
Rifle,
|
||||
Smg,
|
||||
Shotgun,
|
||||
Pistol,
|
||||
Clubbing,
|
||||
Piercing,
|
||||
Slashing,
|
||||
Mechanical,
|
||||
Temporary,
|
||||
HandToHand,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct DamageStat(pub f32);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Japanese;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Ammo(pub u16);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct RateOfFire(pub [u16; 2]);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct NeedsReload;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum WeaponMod {
|
||||
ReflexSight,
|
||||
HolographicSight,
|
||||
AcogSight,
|
||||
ThermalSight,
|
||||
Laser1mw,
|
||||
Laser5mw,
|
||||
Laser30mw,
|
||||
Laser100mw,
|
||||
SmallSuppressor,
|
||||
StandardSuppressor,
|
||||
LargeSuppressor,
|
||||
ExtendedMags,
|
||||
HighCapacityMags,
|
||||
ExtraClip,
|
||||
ExtraClip2,
|
||||
AdjustableTrigger,
|
||||
HairTrigger,
|
||||
Bipod,
|
||||
Tripod,
|
||||
CustomGrip,
|
||||
SkeetChoke,
|
||||
ImprovedChoke,
|
||||
FullChoke,
|
||||
RecoilPad,
|
||||
StandardBrake,
|
||||
HeavyDutyBrake,
|
||||
TacticalBrake,
|
||||
SmallLight,
|
||||
PrecisionLight,
|
||||
TacticalIlluminator,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TurnTriggeredMod {
|
||||
Bipod,
|
||||
|
|
@ -247,109 +157,6 @@ pub enum DamageProcEffect {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct EquippedMods(pub Vec<WeaponMod>);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Experience(pub f32);
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct WeaponBundle {
|
||||
pub usable: Usable,
|
||||
pub weapon: Weapon,
|
||||
pub name: Name,
|
||||
pub id: Id,
|
||||
pub verb: WeaponVerb,
|
||||
pub slot: WeaponSlot,
|
||||
}
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct DamagingWeaponBundle {
|
||||
pub crit_rate: SimpleStatBundle<CritRate>,
|
||||
pub dmg: DamageStat,
|
||||
pub acc: SimpleStatBundle<WeaponAccuracy>,
|
||||
pub dmg_bonus: SimpleStatBundle<DamageBonus>,
|
||||
pub equipped_mods: EquippedMods,
|
||||
pub experience: Experience,
|
||||
pub category: WeaponCategory,
|
||||
}
|
||||
|
||||
#[derive(Bundle)]
|
||||
pub struct AmmoWeaponBundle {
|
||||
pub ammo: Ammo,
|
||||
pub clips: SimpleStatBundle<Clips>,
|
||||
pub clip_size: SimpleStatBundle<ClipSize>,
|
||||
pub rate_of_fire: RateOfFire,
|
||||
pub ammo_control: SimpleStatBundle<AmmoControl>,
|
||||
}
|
||||
|
||||
impl WeaponBundle {
|
||||
pub fn new(name: String, id: usize, verb: WeaponVerb, slot: WeaponSlot) -> Self {
|
||||
Self {
|
||||
usable: Usable,
|
||||
weapon: Weapon,
|
||||
name: Name(name),
|
||||
id: Id(id),
|
||||
verb,
|
||||
slot,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fists(id: usize) -> Self {
|
||||
Self::new("Fists".to_owned(), id, WeaponVerb::Hit, WeaponSlot::Fists)
|
||||
}
|
||||
|
||||
pub fn kick(id: usize) -> Self {
|
||||
Self::new("Kick".to_owned(), id, WeaponVerb::Kicked, WeaponSlot::Kick)
|
||||
}
|
||||
}
|
||||
|
||||
impl DamagingWeaponBundle {
|
||||
pub fn new(
|
||||
dmg: f32,
|
||||
acc: f32,
|
||||
mods: Vec<WeaponMod>,
|
||||
exp: f32,
|
||||
category: WeaponCategory,
|
||||
) -> Self {
|
||||
Self {
|
||||
crit_rate: SimpleStatBundle::new(0),
|
||||
dmg: DamageStat(dmg / 10.0),
|
||||
acc: SimpleStatBundle::new((acc - 50.0) / 50.0),
|
||||
dmg_bonus: SimpleStatBundle::new(1.0),
|
||||
equipped_mods: EquippedMods(mods),
|
||||
experience: Experience(exp),
|
||||
category,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fists() -> Self {
|
||||
// NOTE: The accuracy value is taken from the attack page. The damage value here differs
|
||||
// from the one in Proxima's simulator, but in some quick tests 10.0 proofed to be a better fit
|
||||
// This might have changed in the weapon damage update
|
||||
Self::new(10.0, 50.0, Vec::default(), 0.0, WeaponCategory::HandToHand)
|
||||
}
|
||||
|
||||
pub fn kick() -> Self {
|
||||
// NOTE: The accuracy value is taken from the attack page. The damage value here differs
|
||||
// from the one in Proxima's simulator, but in some quick tests 30.0 proofed to be a better fit
|
||||
// This might have changed in the weapon damage update
|
||||
Self::new(30.0, 40.0, Vec::default(), 0.0, WeaponCategory::HandToHand)
|
||||
}
|
||||
}
|
||||
|
||||
impl AmmoWeaponBundle {
|
||||
pub fn new(clips: u16, clip_size: u16, rof: [u16; 2]) -> Self {
|
||||
Self {
|
||||
ammo: Ammo(clip_size),
|
||||
clips: SimpleStatBundle::new(clips - 1),
|
||||
clip_size: SimpleStatBundle::new(clip_size),
|
||||
rate_of_fire: RateOfFire(rof),
|
||||
ammo_control: SimpleStatBundle::new(0.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_owner(weapons_q: Query<(Entity, &Weapons)>, mut commands: Commands) {
|
||||
for (player, weapons) in weapons_q.iter() {
|
||||
if let Some(primary) = weapons.primary {
|
||||
|
|
@ -364,10 +171,8 @@ fn set_owner(weapons_q: Query<(Entity, &Weapons)>, mut commands: Commands) {
|
|||
if let Some(temp) = weapons.temporary {
|
||||
commands.entity(temp).set_parent(player);
|
||||
}
|
||||
commands.entity(weapons.fists.unwrap()).set_parent(player);
|
||||
if let Some(kick) = weapons.kick {
|
||||
commands.entity(kick).set_parent(player);
|
||||
}
|
||||
commands.entity(weapons.fists).set_parent(player);
|
||||
commands.entity(weapons.kick).set_parent(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,202 +1,33 @@
|
|||
use bevy_ecs::prelude::*;
|
||||
use strum::Display;
|
||||
|
||||
use crate::{
|
||||
effect::Effects,
|
||||
player::{
|
||||
status_effect::{
|
||||
ConcussionGrenade, FlashGrenade, PepperSpray, Sand, SmokeGrenade, TearGas,
|
||||
TempDebuffEffect,
|
||||
},
|
||||
Current, CurrentTarget,
|
||||
},
|
||||
Stages,
|
||||
use proxisim_models::bundle::{
|
||||
player::{Current, CurrentTarget, Player},
|
||||
weapon::{BuffingTemp, DebuffingTemp, Usable, Uses},
|
||||
};
|
||||
|
||||
use super::{DamagingWeaponBundle, Usable, WeaponBundle, WeaponCategory, WeaponSlot, WeaponVerb};
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct NonTargeted;
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct Temporary;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Uses(pub u16);
|
||||
|
||||
impl Default for Uses {
|
||||
fn default() -> Self {
|
||||
Self(1)
|
||||
}
|
||||
}
|
||||
use crate::{
|
||||
Stages,
|
||||
effect::Effects,
|
||||
log,
|
||||
log::Logger,
|
||||
player::status_effect::{
|
||||
AdditiveStatusEffect, ConcussionGrenade, FlashGrenade, Hardened, Hastened, PepperSpray,
|
||||
Sharpened, SmokeGrenade, Strengthened, TearGas, TempDebuffEffect,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct AssociatedWeapon(pub Entity);
|
||||
|
||||
#[derive(Component, Debug, Clone, Copy, Display)]
|
||||
pub enum DebuffingTemp {
|
||||
TearGas,
|
||||
SmokeGrenade,
|
||||
PepperSpray,
|
||||
ConcussionGrenade,
|
||||
FlashGrenade,
|
||||
Sand,
|
||||
}
|
||||
|
||||
#[derive(Bundle, Default)]
|
||||
pub struct TemporaryBundle {
|
||||
pub temporary: Temporary,
|
||||
pub uses: Uses,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub enum Temp {
|
||||
Heg,
|
||||
NailBomb,
|
||||
Grenade,
|
||||
Fireworks,
|
||||
ClaymoreMine,
|
||||
TearGas,
|
||||
SmokeGrenade,
|
||||
PepperSpray,
|
||||
ConcussionGrenade,
|
||||
FlashGrenade,
|
||||
Sand,
|
||||
}
|
||||
|
||||
impl Temp {
|
||||
pub fn spawn(self, world: &mut World, id: usize) -> EntityWorldMut<'_> {
|
||||
match self {
|
||||
Self::Heg => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"HEG".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
DamagingWeaponBundle::new(90.00, 116.00, vec![], 0.0, WeaponCategory::Temporary),
|
||||
TemporaryBundle::default(),
|
||||
NonTargeted,
|
||||
)),
|
||||
Self::NailBomb => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Nail Bomb".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
DamagingWeaponBundle::new(99.00, 106.00, vec![], 0.0, WeaponCategory::Temporary),
|
||||
TemporaryBundle::default(),
|
||||
NonTargeted,
|
||||
)),
|
||||
Self::Grenade => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Grenade".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
DamagingWeaponBundle::new(86.00, 106.00, vec![], 0.0, WeaponCategory::Temporary),
|
||||
TemporaryBundle::default(),
|
||||
NonTargeted,
|
||||
)),
|
||||
Self::Fireworks => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Fireworks".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
DamagingWeaponBundle::new(45.00, 34.00, vec![], 0.0, WeaponCategory::Temporary),
|
||||
TemporaryBundle::default(),
|
||||
NonTargeted,
|
||||
)),
|
||||
Self::ClaymoreMine => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Claymore Mine".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
DamagingWeaponBundle::new(83.00, 27.00, vec![], 0.0, WeaponCategory::Temporary),
|
||||
TemporaryBundle::default(),
|
||||
NonTargeted,
|
||||
)),
|
||||
Self::TearGas => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Tear Gas".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::TearGas,
|
||||
)),
|
||||
Self::SmokeGrenade => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Smoke Grenade".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::SmokeGrenade,
|
||||
)),
|
||||
Self::PepperSpray => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Pepper Spray".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::PepperSpray,
|
||||
)),
|
||||
Self::ConcussionGrenade => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Concussion Grenade".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::ConcussionGrenade,
|
||||
)),
|
||||
Self::FlashGrenade => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Flash Grenade".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::FlashGrenade,
|
||||
)),
|
||||
Self::Sand => world.spawn((
|
||||
WeaponBundle::new(
|
||||
"Sand".to_owned(),
|
||||
id,
|
||||
WeaponVerb::Exploded,
|
||||
WeaponSlot::Temporary,
|
||||
),
|
||||
TemporaryBundle::default(),
|
||||
DebuffingTemp::Sand,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn use_debuffing_temp(
|
||||
mut temp_q: Query<(Entity, &DebuffingTemp, &mut Uses), With<Current>>,
|
||||
target_q: Query<Entity, With<CurrentTarget>>,
|
||||
mut effects: Effects,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
let Ok((weapon, temp, mut uses)) = temp_q.get_single_mut() else {
|
||||
let Ok((weapon, temp, mut uses)) = temp_q.single_mut() else {
|
||||
return;
|
||||
};
|
||||
let target = target_q.single();
|
||||
let target = target_q.single().unwrap();
|
||||
|
||||
match temp {
|
||||
DebuffingTemp::TearGas => effects.spawn_and_insert(
|
||||
|
|
@ -224,13 +55,54 @@ fn use_debuffing_temp(
|
|||
target,
|
||||
AssociatedWeapon(weapon),
|
||||
),
|
||||
DebuffingTemp::Sand => effects.spawn_and_insert(
|
||||
TempDebuffEffect::<Sand>::default(),
|
||||
target,
|
||||
};
|
||||
|
||||
uses.0 -= 1;
|
||||
if uses.0 == 0 {
|
||||
commands.entity(weapon).remove::<Usable>();
|
||||
}
|
||||
}
|
||||
|
||||
fn use_buffing_temp(
|
||||
mut temp_q: Query<(Entity, &BuffingTemp, &mut Uses), With<Current>>,
|
||||
current_q: Query<Entity, (With<Current>, With<Player>)>,
|
||||
mut effects: Effects,
|
||||
mut commands: Commands,
|
||||
mut logger: Logger,
|
||||
) {
|
||||
let Ok((weapon, temp, mut uses)) = temp_q.single_mut() else {
|
||||
return;
|
||||
};
|
||||
let current = current_q.single().unwrap();
|
||||
|
||||
match temp {
|
||||
BuffingTemp::Serotonin => effects.spawn_and_insert(
|
||||
AdditiveStatusEffect::<1, Hardened>::default(),
|
||||
current,
|
||||
AssociatedWeapon(weapon),
|
||||
),
|
||||
BuffingTemp::Tyrosine => effects.spawn_and_insert(
|
||||
AdditiveStatusEffect::<1, Sharpened>::default(),
|
||||
current,
|
||||
AssociatedWeapon(weapon),
|
||||
),
|
||||
BuffingTemp::Melatonin => effects.spawn_and_insert(
|
||||
AdditiveStatusEffect::<1, Hastened>::default(),
|
||||
current,
|
||||
AssociatedWeapon(weapon),
|
||||
),
|
||||
BuffingTemp::Epinephrine => effects.spawn_and_insert(
|
||||
AdditiveStatusEffect::<1, Strengthened>::default(),
|
||||
current,
|
||||
AssociatedWeapon(weapon),
|
||||
),
|
||||
};
|
||||
|
||||
log!(logger, "used_buff_temp", {
|
||||
actor: current,
|
||||
weapon: weapon,
|
||||
});
|
||||
|
||||
uses.0 -= 1;
|
||||
if uses.0 == 0 {
|
||||
commands.entity(weapon).remove::<Usable>();
|
||||
|
|
@ -245,5 +117,6 @@ fn restore_uses(mut uses_q: Query<&mut Uses>) {
|
|||
|
||||
pub(crate) fn configure(stages: &mut Stages) {
|
||||
stages.turn.add_systems(use_debuffing_temp);
|
||||
stages.turn.add_systems(use_buffing_temp);
|
||||
stages.restore.add_systems(restore_uses);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue