updates?
This commit is contained in:
parent
e7d6b74aab
commit
35413b563c
33 changed files with 10238 additions and 1891 deletions
|
|
@ -1,227 +1,22 @@
|
|||
use bevy_ecs::prelude::*;
|
||||
use rand::distributions::Distribution;
|
||||
use proxisim_models::{
|
||||
bundle::armour::{
|
||||
ArmourBodyPart, ArmourBodyPartSlot, ArmourBodyParts, ArmourCoverage, ArmourValue,
|
||||
ArmourVec, BodyPartCoverage, Immunities, Immunity, PlayerArmour,
|
||||
},
|
||||
hierarchy::HierarchyBuilder,
|
||||
};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::{
|
||||
hierarchy::HierarchyBuilder,
|
||||
player::{
|
||||
status_effect::{
|
||||
ConcussionGrenade, FlashGrenade, PepperSpray, Sand, TearGas, TempDebuffImmunity,
|
||||
},
|
||||
BodyPart,
|
||||
player::status_effect::{
|
||||
ConcussionGrenade, FlashGrenade, PepperSpray, TearGas, TempDebuffImmunity,
|
||||
},
|
||||
Name, Stages,
|
||||
Stages,
|
||||
};
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct Armour;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BodyPartCoverage {
|
||||
pub armour: Entity,
|
||||
pub coverage: f32,
|
||||
pub armour_value: f32,
|
||||
}
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct ArmourCoverage(ArmourVec<f32>);
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct ArmourValue(pub f32);
|
||||
|
||||
#[derive(Component)]
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum Set {
|
||||
Riot,
|
||||
Assault,
|
||||
Dune,
|
||||
Delta,
|
||||
Vanguard,
|
||||
Sentinel,
|
||||
Marauder,
|
||||
Eod,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "json", derive(serde::Deserialize))]
|
||||
#[cfg_attr(feature = "json", serde(rename_all = "snake_case"))]
|
||||
pub enum Immunity {
|
||||
Radiation,
|
||||
TearGas,
|
||||
PepperSpray,
|
||||
NerveGas,
|
||||
Sand,
|
||||
ConcussionGrenades,
|
||||
FlashGrenades,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Immunities(pub Vec<Immunity>);
|
||||
|
||||
#[derive(Bundle, Default)]
|
||||
pub struct ArmourBundle {
|
||||
pub name: Name,
|
||||
pub armour: Armour,
|
||||
pub coverage: ArmourCoverage,
|
||||
pub armour_value: ArmourValue,
|
||||
}
|
||||
|
||||
impl ArmourBundle {
|
||||
pub fn new(name: String, coverage: [f32; 10], armour_value: f32) -> Self {
|
||||
Self {
|
||||
name: Name(name),
|
||||
armour: Armour,
|
||||
coverage: ArmourCoverage(ArmourVec(coverage)),
|
||||
armour_value: ArmourValue(armour_value / 100.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Default, Debug)]
|
||||
pub struct ArmourBodyPart {
|
||||
pub armour_pieces: Vec<BodyPartCoverage>,
|
||||
}
|
||||
|
||||
#[derive(Component, Default)]
|
||||
pub struct EquippedArmour {
|
||||
pub head: Option<Entity>,
|
||||
pub body: Option<Entity>,
|
||||
pub legs: Option<Entity>,
|
||||
pub feet: Option<Entity>,
|
||||
pub hands: Option<Entity>,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct ArmourBodyParts(pub ArmourVec<Entity>);
|
||||
|
||||
enum ArmourIterState {
|
||||
Head,
|
||||
Body,
|
||||
Legs,
|
||||
Feet,
|
||||
Hands,
|
||||
}
|
||||
|
||||
pub struct ArmourIter<'a> {
|
||||
state: ArmourIterState,
|
||||
equipped_armour: &'a EquippedArmour,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ArmourIter<'a> {
|
||||
type Item = Entity;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
let (next, piece) = match self.state {
|
||||
ArmourIterState::Head => (ArmourIterState::Body, self.equipped_armour.head),
|
||||
ArmourIterState::Body => (ArmourIterState::Legs, self.equipped_armour.body),
|
||||
ArmourIterState::Legs => (ArmourIterState::Feet, self.equipped_armour.legs),
|
||||
ArmourIterState::Feet => (ArmourIterState::Hands, self.equipped_armour.feet),
|
||||
ArmourIterState::Hands => return self.equipped_armour.hands,
|
||||
};
|
||||
|
||||
self.state = next;
|
||||
if piece.is_some() {
|
||||
return piece;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a EquippedArmour {
|
||||
type Item = Entity;
|
||||
|
||||
type IntoIter = ArmourIter<'a>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
ArmourIter {
|
||||
state: ArmourIterState::Head,
|
||||
equipped_armour: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Clone, Copy, strum::EnumIter)]
|
||||
pub enum ArmourBodyPartSlot {
|
||||
Arms,
|
||||
Stomach,
|
||||
Heart,
|
||||
Chest,
|
||||
Throat,
|
||||
Hands,
|
||||
Groin,
|
||||
Legs,
|
||||
Head,
|
||||
Feet,
|
||||
}
|
||||
|
||||
impl From<BodyPart> for ArmourBodyPartSlot {
|
||||
fn from(value: BodyPart) -> Self {
|
||||
match value {
|
||||
BodyPart::LeftArm | BodyPart::RightArm => Self::Arms,
|
||||
BodyPart::Stomach => Self::Stomach,
|
||||
BodyPart::Heart => Self::Heart,
|
||||
BodyPart::Chest => Self::Chest,
|
||||
BodyPart::Throat => Self::Throat,
|
||||
BodyPart::LeftHand | BodyPart::RightHand => Self::Hands,
|
||||
BodyPart::Groin => Self::Groin,
|
||||
BodyPart::LeftLeg | BodyPart::RightLeg => Self::Legs,
|
||||
BodyPart::Head => Self::Head,
|
||||
BodyPart::LeftFoot | BodyPart::RightFoot => Self::Feet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct ArmourVec<T>([T; 10]);
|
||||
|
||||
impl<T> std::ops::Index<ArmourBodyPartSlot> for ArmourVec<T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, index: ArmourBodyPartSlot) -> &Self::Output {
|
||||
&self.0[index as usize]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::ops::IndexMut<ArmourBodyPartSlot> for ArmourVec<T> {
|
||||
fn index_mut(&mut self, index: ArmourBodyPartSlot) -> &mut Self::Output {
|
||||
&mut self.0[index as usize]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for ArmourVec<T> {
|
||||
type Item = T;
|
||||
|
||||
type IntoIter = std::array::IntoIter<T, 10>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Distribution<Option<&'a BodyPartCoverage>> for &'a ArmourBodyPart {
|
||||
fn sample<R: rand::prelude::Rng + ?Sized>(&self, rng: &mut R) -> Option<&'a BodyPartCoverage> {
|
||||
let mut current = None;
|
||||
for piece in &self.armour_pieces {
|
||||
// NOTE: This is not strictly speaking correct, but the edge cases where this applies
|
||||
// should be very rare, and it should be a decent enough heuristic to barely make a
|
||||
// difference from the actual pixel comparisons that torn seems to be using for this.
|
||||
if current
|
||||
.map(|c: &BodyPartCoverage| c.armour_value)
|
||||
.unwrap_or_default()
|
||||
< piece.armour_value
|
||||
&& rng.gen_bool(piece.coverage as f64)
|
||||
{
|
||||
current = Some(piece);
|
||||
}
|
||||
}
|
||||
current
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_body_parts(
|
||||
equip_q: Query<(Entity, &EquippedArmour)>,
|
||||
equip_q: Query<(Entity, &PlayerArmour)>,
|
||||
armour_q: Query<(Entity, &ArmourCoverage, &ArmourValue, Option<&Immunities>)>,
|
||||
mut commands: Commands,
|
||||
) {
|
||||
|
|
@ -246,15 +41,15 @@ fn generate_body_parts(
|
|||
Immunity::PepperSpray => {
|
||||
player.insert(TempDebuffImmunity::<PepperSpray>::default());
|
||||
}
|
||||
Immunity::FlashGrenades => {
|
||||
Immunity::FlashGrenade => {
|
||||
player.insert(TempDebuffImmunity::<FlashGrenade>::default());
|
||||
}
|
||||
Immunity::Sand => {
|
||||
player.insert(TempDebuffImmunity::<Sand>::default());
|
||||
}
|
||||
Immunity::ConcussionGrenades => {
|
||||
Immunity::ConcussionGrenade => {
|
||||
player.insert(TempDebuffImmunity::<ConcussionGrenade>::default());
|
||||
}
|
||||
Immunity::Insanity => {
|
||||
// TODO: Insanity
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -264,7 +59,7 @@ fn generate_body_parts(
|
|||
parts[slot].armour_pieces.push(BodyPartCoverage {
|
||||
armour,
|
||||
coverage: coverage.0[slot] / 100.0,
|
||||
armour_value: armour_value.0,
|
||||
armour_value: armour_value.0 / 100.0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -274,7 +69,7 @@ fn generate_body_parts(
|
|||
|
||||
commands
|
||||
.entity(player)
|
||||
.add_children(parts)
|
||||
.add_children(&parts)
|
||||
.insert(ArmourBodyParts(ArmourVec(parts)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue