initial commit
This commit is contained in:
commit
86f9333aec
21 changed files with 6449 additions and 0 deletions
361
src/dto.rs
Normal file
361
src/dto.rs
Normal file
|
|
@ -0,0 +1,361 @@
|
|||
use bevy_ecs::prelude::*;
|
||||
|
||||
use crate::entity_registry::EntityInfo;
|
||||
pub use crate::passives::{DrugCooldown, Education, FactionUpgrades, Merits};
|
||||
pub use crate::player::PlayerStrategy;
|
||||
use crate::weapon::Japanese;
|
||||
pub use crate::weapon::{bonus::WeaponBonus, temp::Temp, WeaponCategory, WeaponMod, WeaponSlot};
|
||||
use crate::{
|
||||
armour::EquippedArmour,
|
||||
passives::PassiveBundle,
|
||||
player::PlayerBundle,
|
||||
weapon::{AmmoWeaponBundle, DamagingWeaponBundle, WeaponBundle, WeaponVerb},
|
||||
};
|
||||
use crate::{
|
||||
armour::{ArmourBundle, Immunities, Immunity, Set},
|
||||
weapon::bonus::WeaponBonusBundle,
|
||||
};
|
||||
use crate::{
|
||||
hierarchy::HierarchyBuilder,
|
||||
player::stats::{Defence, Dexterity, Speed, StatBundle, Strength},
|
||||
};
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct Stats {
|
||||
pub str: f32,
|
||||
pub def: f32,
|
||||
pub spd: f32,
|
||||
pub dex: f32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct WeaponAmmo {
|
||||
pub clips: u16,
|
||||
pub clip_size: u16,
|
||||
pub rate_of_fire: [u16; 2],
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct WeaponBonusInfo {
|
||||
pub bonus: WeaponBonus,
|
||||
pub value: f32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct Weapon {
|
||||
pub name: String,
|
||||
pub cat: WeaponCategory,
|
||||
pub dmg: f32,
|
||||
pub acc: f32,
|
||||
pub ammo: WeaponAmmo,
|
||||
pub mods: Vec<WeaponMod>,
|
||||
pub bonuses: Vec<WeaponBonusInfo>,
|
||||
pub experience: f32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct MeleeWeapon {
|
||||
pub name: String,
|
||||
pub cat: WeaponCategory,
|
||||
pub japanese: bool,
|
||||
pub dmg: f32,
|
||||
pub acc: f32,
|
||||
pub bonuses: Vec<WeaponBonusInfo>,
|
||||
pub experience: f32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[derive(Default)]
|
||||
pub struct Weapons {
|
||||
pub primary: Option<Weapon>,
|
||||
pub secondary: Option<Weapon>,
|
||||
pub melee: Option<MeleeWeapon>,
|
||||
pub temp: Option<Temp>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[derive(Default)]
|
||||
pub struct Armour {
|
||||
pub armour_value: f32,
|
||||
pub name: String,
|
||||
pub coverage: [f32; 10],
|
||||
pub immunities: Vec<Immunity>,
|
||||
pub set: Option<Set>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[derive(Default)]
|
||||
pub struct ArmourPieces {
|
||||
pub helmet: Option<Armour>,
|
||||
pub body: Option<Armour>,
|
||||
pub pants: Option<Armour>,
|
||||
pub gloves: Option<Armour>,
|
||||
pub boots: Option<Armour>,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
pub struct Player {
|
||||
pub name: String,
|
||||
pub id: usize,
|
||||
pub level: u16,
|
||||
pub stats: Stats,
|
||||
pub merits: Option<Merits>,
|
||||
pub education: Option<Education>,
|
||||
pub weapons: Weapons,
|
||||
pub armour: ArmourPieces,
|
||||
pub faction: Option<FactionUpgrades>,
|
||||
pub drug: Option<DrugCooldown>,
|
||||
pub strategy: PlayerStrategy,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Serialize))]
|
||||
#[derive(Debug)]
|
||||
pub struct Counter {
|
||||
pub value: u64,
|
||||
pub entity: EntityInfo,
|
||||
pub label: &'static str,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Serialize))]
|
||||
#[derive(Debug)]
|
||||
pub struct Histogram {
|
||||
pub values: Vec<u32>,
|
||||
pub entity: EntityInfo,
|
||||
pub label: &'static str,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub(crate) fn spawn(self, world: &mut World) -> EntityWorldMut<'_> {
|
||||
let primary = self.weapons.primary.map(|w| {
|
||||
let primary = world
|
||||
.spawn((
|
||||
WeaponBundle::new(
|
||||
w.name,
|
||||
self.id * 100 + 3,
|
||||
WeaponVerb::Fired,
|
||||
WeaponSlot::Primary,
|
||||
),
|
||||
DamagingWeaponBundle::new(w.dmg, w.acc, w.mods, w.experience, w.cat),
|
||||
AmmoWeaponBundle::new(w.ammo.clips, w.ammo.clip_size, w.ammo.rate_of_fire),
|
||||
))
|
||||
.id();
|
||||
|
||||
if !w.bonuses.is_empty() {
|
||||
for bonus in w.bonuses {
|
||||
world
|
||||
.spawn(WeaponBonusBundle::new(bonus.bonus, bonus.value))
|
||||
.set_parent(primary);
|
||||
}
|
||||
}
|
||||
|
||||
primary
|
||||
});
|
||||
|
||||
let secondary = self.weapons.secondary.map(|w| {
|
||||
let secondary = world
|
||||
.spawn((
|
||||
WeaponBundle::new(
|
||||
w.name,
|
||||
self.id * 100 + 4,
|
||||
WeaponVerb::Fired,
|
||||
WeaponSlot::Secondary,
|
||||
),
|
||||
DamagingWeaponBundle::new(w.dmg, w.acc, w.mods, w.experience, w.cat),
|
||||
AmmoWeaponBundle::new(w.ammo.clips, w.ammo.clip_size, w.ammo.rate_of_fire),
|
||||
))
|
||||
.id();
|
||||
|
||||
if !w.bonuses.is_empty() {
|
||||
for bonus in w.bonuses {
|
||||
world
|
||||
.spawn(WeaponBonusBundle::new(bonus.bonus, bonus.value))
|
||||
.set_parent(secondary);
|
||||
}
|
||||
}
|
||||
|
||||
secondary
|
||||
});
|
||||
|
||||
let melee = self.weapons.melee.map(|w| {
|
||||
let mut melee = world.spawn((
|
||||
WeaponBundle::new(
|
||||
w.name,
|
||||
self.id * 100 + 5,
|
||||
WeaponVerb::Hit,
|
||||
WeaponSlot::Melee,
|
||||
),
|
||||
DamagingWeaponBundle::new(w.dmg, w.acc, Vec::default(), w.experience, w.cat),
|
||||
));
|
||||
if w.japanese {
|
||||
melee.insert(Japanese);
|
||||
}
|
||||
let melee = melee.id();
|
||||
|
||||
if !w.bonuses.is_empty() {
|
||||
for bonus in w.bonuses {
|
||||
world
|
||||
.spawn(WeaponBonusBundle::new(bonus.bonus, bonus.value))
|
||||
.set_parent(melee);
|
||||
}
|
||||
}
|
||||
|
||||
melee
|
||||
});
|
||||
|
||||
let temporary = self
|
||||
.weapons
|
||||
.temp
|
||||
.map(|t| t.spawn(world, self.id * 100 + 2).id());
|
||||
|
||||
let fists = world
|
||||
.spawn((
|
||||
WeaponBundle::fists(self.id * 100),
|
||||
DamagingWeaponBundle::fists(),
|
||||
))
|
||||
.id();
|
||||
|
||||
let kick = world
|
||||
.spawn((
|
||||
WeaponBundle::kick(self.id * 100 + 1),
|
||||
DamagingWeaponBundle::kick(),
|
||||
))
|
||||
.id();
|
||||
|
||||
let weapons = crate::player::Weapons {
|
||||
primary,
|
||||
secondary,
|
||||
melee,
|
||||
temporary,
|
||||
fists: Some(fists),
|
||||
kick: Some(kick),
|
||||
};
|
||||
|
||||
let helmet = self.armour.helmet.map(|h| {
|
||||
let mut helmet = world.spawn(ArmourBundle::new(h.name, h.coverage, h.armour_value));
|
||||
if let Some(set) = h.set {
|
||||
helmet.insert(set);
|
||||
}
|
||||
if !h.immunities.is_empty() {
|
||||
helmet.insert(Immunities(h.immunities));
|
||||
}
|
||||
helmet.id()
|
||||
});
|
||||
|
||||
let body = self.armour.body.map(|b| {
|
||||
let mut body = world.spawn(ArmourBundle::new(b.name, b.coverage, b.armour_value));
|
||||
if let Some(set) = b.set {
|
||||
body.insert(set);
|
||||
}
|
||||
body.id()
|
||||
});
|
||||
|
||||
let pants = self.armour.pants.map(|p| {
|
||||
let mut pants = world.spawn(ArmourBundle::new(p.name, p.coverage, p.armour_value));
|
||||
if let Some(set) = p.set {
|
||||
pants.insert(set);
|
||||
}
|
||||
pants.id()
|
||||
});
|
||||
|
||||
let gloves = self.armour.gloves.map(|g| {
|
||||
let mut gloves = world.spawn(ArmourBundle::new(g.name, g.coverage, g.armour_value));
|
||||
if let Some(set) = g.set {
|
||||
gloves.insert(set);
|
||||
}
|
||||
gloves.id()
|
||||
});
|
||||
|
||||
let boots = self.armour.boots.map(|b| {
|
||||
let mut boots = world.spawn(ArmourBundle::new(b.name, b.coverage, b.armour_value));
|
||||
if let Some(set) = b.set {
|
||||
boots.insert(set);
|
||||
}
|
||||
boots.id()
|
||||
});
|
||||
|
||||
let armour = EquippedArmour {
|
||||
head: helmet,
|
||||
body,
|
||||
legs: pants,
|
||||
hands: gloves,
|
||||
feet: boots,
|
||||
};
|
||||
|
||||
let mut player = world.spawn((
|
||||
PlayerBundle::new(self.name, self.id, self.level, self.strategy),
|
||||
StatBundle::<Strength>::new(self.stats.str),
|
||||
StatBundle::<Defence>::new(self.stats.def),
|
||||
StatBundle::<Speed>::new(self.stats.spd),
|
||||
StatBundle::<Dexterity>::new(self.stats.dex),
|
||||
weapons,
|
||||
armour,
|
||||
PassiveBundle {
|
||||
merits: self.merits.unwrap_or_default(),
|
||||
education: self.education.unwrap_or_default(),
|
||||
faction: self.faction.unwrap_or_default(),
|
||||
},
|
||||
));
|
||||
|
||||
if let Some(drug) = self.drug {
|
||||
player.insert(drug);
|
||||
}
|
||||
|
||||
player
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_spawn_player() {
|
||||
let mut world = World::new();
|
||||
|
||||
let player = Player {
|
||||
name: "Test".to_owned(),
|
||||
id: 0,
|
||||
level: 10,
|
||||
stats: Stats {
|
||||
str: 10.0,
|
||||
def: 10.0,
|
||||
spd: 10.0,
|
||||
dex: 10.0,
|
||||
},
|
||||
merits: Default::default(),
|
||||
education: Default::default(),
|
||||
faction: Default::default(),
|
||||
drug: None,
|
||||
strategy: PlayerStrategy::AlwaysFists,
|
||||
weapons: Weapons {
|
||||
primary: Some(Weapon {
|
||||
name: "Test".to_owned(),
|
||||
cat: WeaponCategory::Rifle,
|
||||
dmg: 50.0,
|
||||
acc: 50.0,
|
||||
ammo: WeaponAmmo {
|
||||
clips: 3,
|
||||
clip_size: 25,
|
||||
rate_of_fire: [3, 5],
|
||||
},
|
||||
mods: Vec::default(),
|
||||
bonuses: Vec::default(),
|
||||
experience: 100.0,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
armour: ArmourPieces {
|
||||
helmet: Some(Armour {
|
||||
name: "Test".to_owned(),
|
||||
armour_value: 50.0,
|
||||
coverage: [0.0, 0.0, 0.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
immunities: Vec::default(),
|
||||
set: None,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
|
||||
player.spawn(&mut world);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue