Skip to main content

tiger_lib/data/
trigger_localization.rs

1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::{Game, GameFlags};
5use crate::item::{Item, ItemLoader};
6use crate::report::{ErrorKey, warn};
7use crate::token::Token;
8use crate::tooltipped::Tooltipped;
9use crate::validator::Validator;
10
11#[derive(Clone, Debug)]
12pub struct TriggerLocalization {}
13
14inventory::submit! {
15    ItemLoader::Normal(GameFlags::jomini(), Item::TriggerLocalization, TriggerLocalization::add)
16}
17
18impl TriggerLocalization {
19    pub fn add(db: &mut Db, key: Token, block: Block) {
20        db.add(Item::TriggerLocalization, key, block, Box::new(Self {}));
21    }
22
23    pub fn validate_use(
24        key: &Token,
25        block: &Block,
26        data: &Everything,
27        caller: &Token,
28        tooltipped: Tooltipped,
29        negated: bool,
30    ) {
31        if tooltipped.is_tooltipped() {
32            if negated {
33                for field in &["global_not", "first_not", "third_not", "none_not"] {
34                    if block.has_key(field) {
35                        return;
36                    }
37                }
38                for field in &["global", "first", "third"] {
39                    if let Some(token) = block.get_field_value(field) {
40                        let loca = format!("NOT_{token}");
41                        if data.item_exists(Item::Localization, &loca) {
42                            return;
43                        }
44                    }
45                }
46                let msg = format!("missing `NOT_` perspective for {key}");
47                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).loc_msg(key, "here").push();
48            } else {
49                for field in &["global", "first", "third", "none"] {
50                    if block.has_key(field) {
51                        return;
52                    }
53                }
54                let msg = format!("missing positive perspective for {key}");
55                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).loc_msg(key, "here").push();
56            }
57        }
58    }
59}
60
61impl DbKind for TriggerLocalization {
62    fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
63        let mut vd = Validator::new(block, data);
64        vd.field_item("global", Item::Localization);
65        vd.field_item("global_not", Item::Localization);
66        vd.field_item("first", Item::Localization);
67        vd.field_item("first_not", Item::Localization);
68        vd.field_item("third", Item::Localization);
69        vd.field_item("third_not", Item::Localization);
70        vd.field_item("none", Item::Localization);
71        vd.field_item("none_not", Item::Localization);
72        if Game::is_vic3() {
73            vd.field_bool("show_children");
74        }
75    }
76}
77
78pub fn validate_trigger_localization(
79    caller: &Token,
80    data: &Everything,
81    tooltipped: Tooltipped,
82    negated: bool,
83) {
84    if let Some((key, block)) = data.get_key_block(Item::TriggerLocalization, caller.as_str()) {
85        TriggerLocalization::validate_use(key, block, data, caller, tooltipped, negated);
86        return;
87    }
88
89    // As of CK3 1.18, trigger localizations don't have to be defined and can just be present as
90    // localizations.
91    if Game::is_ck3() {
92        if tooltipped.is_tooltipped() {
93            if negated {
94                for sfx in &["global_not", "first_not", "third_not", "none_not"] {
95                    let loca = format!("{caller}_{sfx}");
96                    if data.item_exists(Item::Localization, &loca) {
97                        return;
98                    }
99                }
100                let msg = format!("missing negated perspective for {caller}");
101                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).push();
102            } else {
103                if data.item_exists(Item::Localization, caller.as_str()) {
104                    return;
105                }
106                for sfx in &["global", "first", "third", "none"] {
107                    let loca = format!("{caller}_{sfx}");
108                    if data.item_exists(Item::Localization, &loca) {
109                        return;
110                    }
111                }
112                let msg = format!("missing positive perspective for {caller}");
113                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).push();
114            }
115        }
116    } else {
117        data.verify_exists(Item::TriggerLocalization, caller);
118    }
119}