This commit is contained in:
TotallyNot 2025-11-03 16:36:45 +01:00
parent e7d6b74aab
commit 35413b563c
Signed by: pyrite
GPG key ID: 7F1BA9170CD35D15
33 changed files with 10238 additions and 1891 deletions

View file

@ -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);
}
}