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    }
73}
74
75pub fn validate_trigger_localization(
76    caller: &Token,
77    data: &Everything,
78    tooltipped: Tooltipped,
79    negated: bool,
80) {
81    if let Some((key, block)) = data.get_key_block(Item::TriggerLocalization, caller.as_str()) {
82        TriggerLocalization::validate_use(key, block, data, caller, tooltipped, negated);
83        return;
84    }
85
86    // As of CK3 1.18, trigger localizations don't have to be defined and can just be present as
87    // localizations.
88    if Game::is_ck3() {
89        if tooltipped.is_tooltipped() {
90            if negated {
91                for sfx in &["global_not", "first_not", "third_not", "none_not"] {
92                    let loca = format!("{caller}_{sfx}");
93                    if data.item_exists(Item::Localization, &loca) {
94                        return;
95                    }
96                }
97                let msg = format!("missing negated perspective for {caller}");
98                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).push();
99            } else {
100                if data.item_exists(Item::Localization, caller.as_str()) {
101                    return;
102                }
103                for sfx in &["global", "first", "third", "none"] {
104                    let loca = format!("{caller}_{sfx}");
105                    if data.item_exists(Item::Localization, &loca) {
106                        return;
107                    }
108                }
109                let msg = format!("missing positive perspective for {caller}");
110                warn(ErrorKey::MissingPerspective).msg(msg).loc(caller).push();
111            }
112        }
113    } else {
114        data.verify_exists(Item::TriggerLocalization, caller);
115    }
116}