tiger_lib/imperator/data/
decisions.rs

1use std::path::PathBuf;
2
3use crate::block::Block;
4use crate::context::ScopeContext;
5use crate::everything::Everything;
6use crate::fileset::{FileEntry, FileHandler};
7use crate::helpers::TigerHashMap;
8use crate::item::Item;
9use crate::parse::ParserMemory;
10use crate::pdxfile::PdxFile;
11use crate::scopes::Scopes;
12use crate::token::Token;
13use crate::tooltipped::Tooltipped;
14use crate::validate::validate_modifiers_with_base;
15use crate::validator::Validator;
16use crate::variables::Variables;
17
18#[derive(Clone, Debug, Default)]
19pub struct Decisions {
20    decisions: TigerHashMap<&'static str, Decision>,
21}
22
23impl Decisions {
24    pub fn load_item(&mut self, key: &Token, block: &Block) {
25        if key.is("country_decisions") {
26            for (key, block) in block.iter_definitions_warn() {
27                self.decisions.insert(key.as_str(), Decision::new(key.clone(), block.clone()));
28            }
29        }
30    }
31
32    pub fn scan_variables(&self, registry: &mut Variables) {
33        for item in self.decisions.values() {
34            registry.scan(&item.block);
35        }
36    }
37
38    pub fn exists(&self, key: &str) -> bool {
39        self.decisions.contains_key(key)
40    }
41
42    pub fn iter_keys(&self) -> impl Iterator<Item = &Token> {
43        self.decisions.values().map(|item| &item.key)
44    }
45    pub fn validate(&self, data: &Everything) {
46        for item in self.decisions.values() {
47            item.validate(data);
48        }
49    }
50}
51
52impl FileHandler<Block> for Decisions {
53    fn subpath(&self) -> PathBuf {
54        PathBuf::from("decisions/")
55    }
56
57    fn load_file(&self, entry: &FileEntry, parser: &ParserMemory) -> Option<Block> {
58        if !entry.filename().to_string_lossy().ends_with(".txt") {
59            return None;
60        }
61
62        PdxFile::read(entry, parser)
63    }
64
65    fn handle_file(&mut self, _entry: &FileEntry, mut block: Block) {
66        for (key, block) in block.drain_definitions_warn() {
67            self.load_item(&key, &block);
68        }
69    }
70}
71
72#[derive(Clone, Debug)]
73pub struct Decision {
74    key: Token,
75    block: Block,
76}
77
78impl Decision {
79    pub fn new(key: Token, block: Block) -> Self {
80        Self { key, block }
81    }
82    fn validate(&self, data: &Everything) {
83        let mut vd = Validator::new(&self.block, data);
84        let mut sc = ScopeContext::new(Scopes::Country, &self.key);
85
86        data.verify_exists(Item::Localization, &self.key);
87        let loca = format!("{}_desc", self.key);
88        data.verify_exists_implied(Item::Localization, &loca, &self.key);
89
90        vd.field_trigger("potential", Tooltipped::No, &mut sc);
91        vd.field_trigger_builder("highlight", Tooltipped::Yes, |key| {
92            let mut sc = ScopeContext::new(Scopes::Country, key);
93            sc.define_name("province", Scopes::Province, key);
94            sc
95        });
96        vd.field_trigger("allow", Tooltipped::Yes, &mut sc);
97        vd.field_effect("effect", Tooltipped::Yes, &mut sc);
98        vd.field_validated_block_sc("ai_will_do", &mut sc, validate_modifiers_with_base);
99    }
100}