Skip to main content

rpfm_lib/files/group_formations/versions/
v2.rs

1//---------------------------------------------------------------------------//
2// Copyright (c) 2017-2026 Ismael Gutiérrez González. All rights reserved.
3//
4// This file is part of the Rusted PackFile Manager (RPFM) project,
5// which can be found here: https://github.com/Frodo45127/rpfm.
6//
7// This file is licensed under the MIT license, which can be found here:
8// https://github.com/Frodo45127/rpfm/blob/master/LICENSE.
9//---------------------------------------------------------------------------//
10
11//! Shared data types for v2 (Rome 2 and later) group formations.
12//!
13//! Used by: Rome 2, Attila, Warhammer, Warhammer 2, Thrones of Britannia,
14//! Three Kingdoms, Troy, Pharaoh, Warhammer 3.
15
16use std::fmt::Display;
17
18use bitflags::bitflags;
19use serde_derive::{Serialize, Deserialize};
20
21use crate::error::{Result, RLibError};
22
23bitflags! {
24
25    // Names taken from the Attila Assembly Kit. Later games may use the unknown bits.
26    #[derive(Default, PartialEq, Clone, Debug, Serialize, Deserialize)]
27    pub struct AIPurposeFlags: u32 {
28        const ATTACK                        = 0b0000_0000_0000_0000_0000_0000_0000_0001;
29        const DEFEND                        = 0b0000_0000_0000_0000_0000_0000_0000_0010;
30        const RIVER_ATTACK                  = 0b0000_0000_0000_0000_0000_0000_0000_0100;
31        const RIVER_DEFEND                  = 0b0000_0000_0000_0000_0000_0000_0000_1000;
32        const UK_4                          = 0b0000_0000_0000_0000_0000_0000_0001_0000;
33        const AMBUSH_DEFENCE_BLOCK          = 0b0000_0000_0000_0000_0000_0000_0010_0000;
34        const SETTLEMENT_ASSAULT            = 0b0000_0000_0000_0000_0000_0000_0100_0000;
35        const SETTLEMENT_AREA_DEFEND_NARROW = 0b0000_0000_0000_0000_0000_0000_1000_0000;
36        const SETTLEMENT_AREA_DEFEND_WIDE   = 0b0000_0000_0000_0000_0000_0001_0000_0000;
37        const SETTLEMENT_AREA_ATTACK_NARROW = 0b0000_0000_0000_0000_0000_0010_0000_0000;
38        const SETTLEMENT_AREA_ATTACK_WIDE   = 0b0000_0000_0000_0000_0000_0100_0000_0000;
39        const UK_11                         = 0b0000_0000_0000_0000_0000_1000_0000_0000;
40        const NAVAL_ATTACK                  = 0b0000_0000_0000_0000_0001_0000_0000_0000;
41        const NAVAL_DEFEND                  = 0b0000_0000_0000_0000_0010_0000_0000_0000;
42        const DEFAULT_DEPLOYMENT            = 0b0000_0000_0000_0000_0100_0000_0000_0000;
43        const NAVAL_DEFAULT_DEPLOYMENT      = 0b0000_0000_0000_0000_1000_0000_0000_0000;
44        const UK_16                         = 0b0000_0000_0000_0001_0000_0000_0000_0000;
45        const UK_17                         = 0b0000_0000_0000_0010_0000_0000_0000_0000;
46        const UK_18                         = 0b0000_0000_0000_0100_0000_0000_0000_0000;
47        const UK_19                         = 0b0000_0000_0000_1000_0000_0000_0000_0000;
48        const UK_20                         = 0b0000_0000_0001_0000_0000_0000_0000_0000;
49        const UK_21                         = 0b0000_0000_0010_0000_0000_0000_0000_0000;
50        const UK_22                         = 0b0000_0000_0100_0000_0000_0000_0000_0000;
51        const UK_23                         = 0b0000_0000_1000_0000_0000_0000_0000_0000;
52        const UK_24                         = 0b0000_0001_0000_0000_0000_0000_0000_0000;
53        const UK_25                         = 0b0000_0010_0000_0000_0000_0000_0000_0000;
54        const UK_26                         = 0b0000_0100_0000_0000_0000_0000_0000_0000;
55        const UK_27                         = 0b0000_1000_0000_0000_0000_0000_0000_0000;
56        const UK_28                         = 0b0001_0000_0000_0000_0000_0000_0000_0000;
57        const UK_29                         = 0b0010_0000_0000_0000_0000_0000_0000_0000;
58        const UK_30                         = 0b0100_0000_0000_0000_0000_0000_0000_0000;
59        const UK_31                         = 0b1000_0000_0000_0000_0000_0000_0000_0000;
60    }
61}
62
63/// Entity types for Rome 2 and later formations.
64///
65/// These are abstract unit class identifiers shared across Rome 2, Attila,
66/// Warhammer series, Three Kingdoms, Troy, and Pharaoh.
67#[derive(Default, Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
68#[repr(u32)]
69pub enum EntityType {
70    InfMel = 0,
71    InfSpr = 1,
72    InfPik = 2,
73    InfMis = 3,
74    #[default] Com = 4,
75    CavShk = 5,
76    CavMel = 6,
77    CavMis = 7,
78    Chariot = 8,
79    Elph = 9,
80    Spcl = 10,
81    ArtFld = 11,
82    ArtFix = 12,
83    ArtSiege = 13,
84    ShpMel = 14,
85    ShpMis = 15,
86    ShpArt = 16,
87    ShpTrn = 17,
88    ShpStk = 18,
89    ShpFir = 19,
90    Invalid = 20,
91    Uk21 = 21,
92    Uk22 = 22,
93    Uk23 = 23,
94    Uk24 = 24,
95}
96
97impl EntityType {
98
99    /// All the possible values, in their binary order.
100    pub const ALL: [Self; 25] = [
101        Self::InfMel, Self::InfSpr, Self::InfPik, Self::InfMis, Self::Com, Self::CavShk, Self::CavMel, Self::CavMis,
102        Self::Chariot, Self::Elph, Self::Spcl, Self::ArtFld, Self::ArtFix, Self::ArtSiege, Self::ShpMel, Self::ShpMis,
103        Self::ShpArt, Self::ShpTrn, Self::ShpStk, Self::ShpFir, Self::Invalid, Self::Uk21, Self::Uk22, Self::Uk23, Self::Uk24,
104    ];
105}
106
107impl TryFrom<u32> for EntityType {
108    type Error = RLibError;
109    fn try_from(value: u32) -> Result<Self> {
110        match value {
111            _ if value == Self::InfMel as u32 => Ok(Self::InfMel),
112            _ if value == Self::InfSpr as u32 => Ok(Self::InfSpr),
113            _ if value == Self::InfPik as u32 => Ok(Self::InfPik),
114            _ if value == Self::InfMis as u32 => Ok(Self::InfMis),
115            _ if value == Self::Com as u32 => Ok(Self::Com),
116            _ if value == Self::CavShk as u32 => Ok(Self::CavShk),
117            _ if value == Self::CavMel as u32 => Ok(Self::CavMel),
118            _ if value == Self::CavMis as u32 => Ok(Self::CavMis),
119            _ if value == Self::Chariot as u32 => Ok(Self::Chariot),
120            _ if value == Self::Elph as u32 => Ok(Self::Elph),
121            _ if value == Self::Spcl as u32 => Ok(Self::Spcl),
122            _ if value == Self::ArtFld as u32 => Ok(Self::ArtFld),
123            _ if value == Self::ArtFix as u32 => Ok(Self::ArtFix),
124            _ if value == Self::ArtSiege as u32 => Ok(Self::ArtSiege),
125            _ if value == Self::ShpMel as u32 => Ok(Self::ShpMel),
126            _ if value == Self::ShpMis as u32 => Ok(Self::ShpMis),
127            _ if value == Self::ShpArt as u32 => Ok(Self::ShpArt),
128            _ if value == Self::ShpTrn as u32 => Ok(Self::ShpTrn),
129            _ if value == Self::ShpStk as u32 => Ok(Self::ShpStk),
130            _ if value == Self::ShpFir as u32 => Ok(Self::ShpFir),
131            _ if value == Self::Invalid as u32 => Ok(Self::Invalid),
132            _ if value == Self::Uk21 as u32 => Ok(Self::Uk21),
133            _ if value == Self::Uk22 as u32 => Ok(Self::Uk22),
134            _ if value == Self::Uk23 as u32 => Ok(Self::Uk23),
135            _ if value == Self::Uk24 as u32 => Ok(Self::Uk24),
136            _ => Err(RLibError::DecodingGroupFormationsUnknownEnumValue("EntityType(v2)".to_string(), value)),
137        }
138    }
139}
140
141impl From<EntityType> for u32 {
142    fn from(value: EntityType) -> u32 {
143        value as u32
144    }
145}
146
147impl Display for EntityType {
148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149        match self {
150            Self::InfMel => write!(f, "Melee Infantry"),
151            Self::InfSpr => write!(f, "Spear Infantry"),
152            Self::InfPik => write!(f, "Pike Infantry"),
153            Self::InfMis => write!(f, "Missile Infantry"),
154            Self::Com => write!(f, "Command"),
155            Self::CavShk => write!(f, "Shock Cavalry"),
156            Self::CavMel => write!(f, "Melee Cavalry"),
157            Self::CavMis => write!(f, "Missile Cavalry"),
158            Self::Chariot => write!(f, "Chariot"),
159            Self::Elph => write!(f, "Elephant"),
160            Self::Spcl => write!(f, "Special"),
161            Self::ArtFld => write!(f, "Field Artillery"),
162            Self::ArtFix => write!(f, "Fixed Artillery"),
163            Self::ArtSiege => write!(f, "Siege Artillery"),
164            Self::ShpMel => write!(f, "Melee Ship"),
165            Self::ShpMis => write!(f, "Missile Ship"),
166            Self::ShpArt => write!(f, "Artillery Ship"),
167            Self::ShpTrn => write!(f, "Transport Ship"),
168            Self::ShpStk => write!(f, "Ramming Ship"),
169            Self::ShpFir => write!(f, "Fire Ship"),
170            Self::Invalid => write!(f, "Invalid"),
171            Self::Uk21 => write!(f, "Uk21"),
172            Self::Uk22 => write!(f, "Uk22"),
173            Self::Uk23 => write!(f, "Uk23"),
174            Self::Uk24 => write!(f, "Uk24"),
175        }
176    }
177}