ashscript_types/
unit.rs

1use enum_map::EnumMap;
2use hashbrown::HashMap;
3use hexx::Hex;
4use serde::Serialize;
5use uuid::Uuid;
6
7use crate::{
8    constants::{
9        general::UNIT_PART_WEIGHTS,
10        unit::{AGE_PER_GEN_PART, UNIT_AGE_EXP, UNIT_BASE_AGE},
11    },
12    intents::{self, Intent, Intents},
13    objects::{GameObjectKind, HasHealth, HasHex, HasId, HasStorage},
14    player::OwnerId, storage::Storage,
15};
16
17pub type Units = HashMap<Hex, Unit>;
18
19#[derive(Default, Serialize, Clone)]
20pub struct Unit {
21    pub id: Uuid,
22    pub kind: GameObjectKind,
23    pub owner_id: OwnerId,
24    pub health: u32,
25    pub hex: Hex,
26    pub energy: u32,
27    pub age: u32,
28    pub body: UnitBody,
29    pub storage: Storage,
30    #[serde(skip)]
31    pub future_health: u32,
32    #[serde(skip)]
33    pub future_energy: u32,
34    #[serde(skip)]
35    pub future_hex: Hex,
36}
37
38impl HasHealth for Unit {
39    fn health(&self) -> u32 {
40        self.health
41    }
42}
43
44impl HasId for Unit {
45    fn id(&self) -> Uuid {
46        self.id
47    }
48}
49
50impl HasHex for Unit {
51    fn hex(&self) -> Hex {
52        self.hex
53    }
54}
55
56impl HasStorage for Unit {
57    fn storage(&self) -> &Storage {
58        &self.storage
59    }
60}
61
62impl Unit {
63    pub fn new(hex: Hex) -> Self {
64        Self {
65            health: 100,
66            hex,
67            ..Default::default()
68        }
69    }
70
71    pub fn max_age(&self) -> u32 {
72        ((self.body[UnitPart::Generate] * AGE_PER_GEN_PART) as f32).powf(UNIT_AGE_EXP) as u32
73            + UNIT_BASE_AGE
74    }
75
76    pub fn weight(&self) -> u32 {
77        let mut weight = 0;
78
79        for (part, _) in UNIT_PART_WEIGHTS.iter() {
80            weight += UNIT_PART_WEIGHTS[part]
81        }
82
83        weight
84    }
85
86    pub fn range(&self) -> u32 {
87        self.body[UnitPart::Ranged]
88    }
89
90    pub fn damage(&self) -> u32 {
91        self.body[UnitPart::Ranged]
92    }
93
94    pub fn attack_cost(&self) -> u32 {
95        self.body[UnitPart::Ranged]
96    }
97
98    /* pub fn attack<T>(&self, target: T, intents: &mut Intents)
99    where
100        T: HasHealth + HasHex,
101    {
102        intents.push(Intent::UnitAttack(intents::UnitAttack {
103            attacker_hex: self.hex,
104            target_hex: target.hex(),
105        }));
106    }
107
108    pub fn attack_checked<T>(&self, target: T, intents: &mut Intents)
109    where
110        T: HasHealth + HasHex,
111    {
112        // Checks see if the itnent is likely to be converted into an action
113
114        self.attack(target, intents);
115    } */
116}
117
118pub type UnitBody = EnumMap<UnitPart, u32>;
119
120#[derive(enum_map::Enum, Serialize)]
121pub enum UnitPart {
122    Ranged,
123    Harvest,
124    Generate,
125    Work,
126    Battery,
127}