1pub use tiger_tables::item::Item;
4
5use crate::block::Block;
6use crate::db::Db;
7#[cfg(feature = "eu5")]
8use crate::eu5::item::injectable_eu5;
9#[cfg(doc)]
10use crate::everything::Everything;
11use crate::game::{Game, GameFlags};
12use crate::pdxfile::PdxEncoding;
13use crate::report::{Confidence, Severity};
14use crate::token::Token;
15#[cfg(feature = "vic3")]
16use crate::vic3::item::injectable_vic3;
17
18pub trait ItemExt {
19 fn confidence(self) -> Confidence;
20 fn severity(self) -> Severity;
21 #[cfg(any(feature = "vic3", feature = "eu5"))]
22 fn injectable(self) -> bool;
23}
24
25impl ItemExt for Item {
26 fn confidence(self) -> Confidence {
29 match self {
30 #[cfg(feature = "jomini")]
31 Item::AccessoryTag => Confidence::Weak,
32
33 Item::GuiType | Item::GuiTemplate | Item::Sound => Confidence::Weak,
36
37 #[cfg(feature = "ck3")]
38 Item::AccoladeCategory
39 | Item::BuildingGfx
40 | Item::ClothingGfx
41 | Item::CoaGfx
42 | Item::CultureParameter
43 | Item::MemoryCategory
44 | Item::UnitGfx => Confidence::Weak,
45
46 #[cfg(feature = "ck3")]
47 Item::SpecialBuilding => Confidence::Reasonable,
48
49 _ => Confidence::Strong,
50 }
51 }
52
53 fn severity(self) -> Severity {
62 match self {
63 Item::GuiType | Item::GuiTemplate => Severity::Untidy,
66
67 Item::File | Item::Localization | Item::MapEnvironment => Severity::Warning,
68
69 #[cfg(feature = "jomini")]
70 Item::Accessory
71 | Item::AccessoryTag
72 | Item::AccessoryVariation
73 | Item::AccessoryVariationLayout
74 | Item::AccessoryVariationTextures
75 | Item::Coa
76 | Item::CoaColorList
77 | Item::CoaColoredEmblemList
78 | Item::CoaPatternList
79 | Item::CoaTemplate
80 | Item::CoaTemplateList
81 | Item::CoaTexturedEmblemList
82 | Item::CustomLocalization
83 | Item::EffectLocalization
84 | Item::Ethnicity
85 | Item::GameConcept
86 | Item::NamedColor
87 | Item::PortraitAnimation
88 | Item::PortraitCamera
89 | Item::PortraitEnvironment
90 | Item::Sound
91 | Item::TextFormat
92 | Item::TextIcon
93 | Item::TextureFile
94 | Item::TriggerLocalization => Severity::Warning,
95
96 #[cfg(feature = "ck3")]
97 Item::AccoladeIcon
98 | Item::ArtifactVisual
99 | Item::BuildingGfx
100 | Item::ClothingGfx
101 | Item::CoaDynamicDefinition
102 | Item::CoaGfx
103 | Item::CultureAesthetic
104 | Item::CultureCreationName
105 | Item::EventBackground
106 | Item::EventTheme
107 | Item::EventTransition
108 | Item::Flavorization
109 | Item::GraphicalFaith
110 | Item::ModifierFormat
111 | Item::MottoInsert
112 | Item::Motto
113 | Item::Music
114 | Item::Nickname
115 | Item::RulerObjectiveType
116 | Item::ScriptedIllustration
117 | Item::UnitGfx => Severity::Warning,
118
119 #[cfg(feature = "vic3")]
120 Item::MapLayer
121 | Item::ModifierTypeDefinition
122 | Item::TerrainManipulator
123 | Item::TerrainMask
124 | Item::TerrainMaterial => Severity::Warning,
125
126 #[cfg(feature = "hoi4")]
127 Item::Sprite => Severity::Warning,
128
129 _ => Severity::Error,
130 }
131 }
132
133 #[cfg(any(feature = "vic3", feature = "eu5"))]
134 fn injectable(self) -> bool {
135 match Game::game() {
136 #[cfg(feature = "vic3")]
137 Game::Vic3 => injectable_vic3(self),
138 #[cfg(feature = "eu5")]
139 Game::Eu5 => injectable_eu5(self),
140 }
141 }
142}
143
144pub(crate) type ItemAdder = fn(&mut Db, Token, Block);
146
147pub(crate) enum ItemLoader {
157 Normal(GameFlags, Item, ItemAdder),
169 Full(GameFlags, Item, PdxEncoding, &'static str, LoadAsFile, Recursive, ItemAdder),
177}
178
179inventory::collect!(ItemLoader);
180
181impl ItemLoader {
182 pub fn for_game(&self, game: Game) -> bool {
183 let game_flags = match self {
184 ItemLoader::Normal(game_flags, _, _)
185 | ItemLoader::Full(game_flags, _, _, _, _, _, _) => game_flags,
186 };
187 game_flags.contains(GameFlags::from(game))
188 }
189
190 pub fn itype(&self) -> Item {
191 match self {
192 ItemLoader::Normal(_, itype, _) | ItemLoader::Full(_, itype, _, _, _, _, _) => *itype,
193 }
194 }
195
196 pub fn encoding(&self) -> PdxEncoding {
197 match self {
198 ItemLoader::Normal(_, _, _) => {
199 #[cfg(feature = "hoi4")]
200 if Game::is_hoi4() {
201 return PdxEncoding::Utf8NoBom;
202 }
203 PdxEncoding::Utf8Bom
204 }
205 ItemLoader::Full(_, _, encoding, _, _, _, _) => *encoding,
206 }
207 }
208
209 pub fn extension(&self) -> &'static str {
210 match self {
211 ItemLoader::Normal(_, _, _) => ".txt",
212 ItemLoader::Full(_, _, _, extension, _, _, _) => extension,
213 }
214 }
215
216 pub fn whole_file(&self) -> bool {
217 match self {
218 ItemLoader::Normal(_, _, _) => false,
219 ItemLoader::Full(_, _, _, _, load_as_file, _, _) => {
220 matches!(load_as_file, LoadAsFile::Yes)
221 }
222 }
223 }
224
225 pub fn recursive(&self) -> bool {
226 match self {
227 ItemLoader::Normal(_, _, _) => {
228 Game::is_ck3() && self.itype().path().starts_with("common/")
229 }
230 ItemLoader::Full(_, _, _, _, _, recursive, _) => match recursive {
231 Recursive::Yes => true,
232 Recursive::No => false,
233 Recursive::Maybe => Game::is_ck3() && self.itype().path().starts_with("common/"),
234 },
235 }
236 }
237
238 pub fn adder(&self) -> ItemAdder {
239 match self {
240 ItemLoader::Normal(_, _, adder) | ItemLoader::Full(_, _, _, _, _, _, adder) => *adder,
241 }
242 }
243}
244
245pub enum LoadAsFile {
246 Yes,
247 No,
248}
249
250pub enum Recursive {
251 Yes,
252 No,
253 #[allow(dead_code)]
254 Maybe,
255}