tiger_lib/vic3/data/
alerts.rs

1use crate::block::Block;
2use crate::context::ScopeContext;
3use crate::db::{Db, DbKind};
4use crate::everything::Everything;
5use crate::game::GameFlags;
6use crate::item::{Item, ItemLoader};
7use crate::report::{ErrorKey, err};
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validate::validate_possibly_named_color;
12use crate::validator::Validator;
13
14#[derive(Clone, Debug)]
15pub struct Alert {}
16
17inventory::submit! {
18    ItemLoader::Normal(GameFlags::Vic3, Item::Alert, Alert::add)
19}
20
21impl Alert {
22    pub fn add(db: &mut Db, key: Token, block: Block) {
23        db.add(Item::Alert, key, block, Box::new(Self {}));
24    }
25}
26
27impl DbKind for Alert {
28    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
29        let mut vd = Validator::new(block, data);
30
31        let loca = format!("alert_{key}_name");
32        data.verify_exists_implied(Item::Localization, &loca, key);
33        let loca = format!("alert_{key}_hint");
34        data.verify_exists_implied(Item::Localization, &loca, key);
35        let loca = format!("alert_{key}_action");
36        data.verify_exists_implied(Item::Localization, &loca, key);
37        let loca = format!("{key}_setting_name");
38        data.verify_exists_implied(Item::Localization, &loca, key);
39        let loca = format!("alert_{key}_desc");
40        data.localization.suggest(&loca, key);
41
42        vd.req_field("script_context");
43        let mut sc = ScopeContext::new(Scopes::None, key);
44        if let Some(script_context) = vd.field_value("script_context") {
45            let mut found = false;
46            for &(context, s) in SCRIPT_CONTEXTS {
47                if script_context.is(context) {
48                    sc = ScopeContext::new(s, key);
49                    sc.define_name("actor", Scopes::Country, key);
50                    if context == "player_invasion" {
51                        sc.define_name("is_naval_invasion", Scopes::Bool, key);
52                        sc.define_name("attacker", Scopes::Country, key);
53                        sc.define_name("defender", Scopes::Country, key);
54                    }
55                    found = true;
56                    break;
57                }
58            }
59            if !found {
60                let msg = "unknown script context";
61                err(ErrorKey::Choice).msg(msg).loc(script_context).push();
62            }
63        }
64
65        vd.field_item("texture", Item::File);
66        vd.field_trigger("valid", Tooltipped::No, &mut sc);
67        // TODO figure out the valid panel and popup values
68        vd.exclusive_fields(&["open_panel", "open_popup"]);
69        vd.field_value("open_panel");
70        vd.field_value("open_popup");
71        vd.field_choice("type", &["alert", "important_action", "angry_important_action"]);
72        vd.field_item("alert_group", Item::AlertGroup);
73        vd.field_validated("color", validate_possibly_named_color);
74    }
75}
76
77#[derive(Clone, Debug)]
78pub struct AlertGroup {}
79
80inventory::submit! {
81    ItemLoader::Normal(GameFlags::Vic3, Item::AlertGroup, AlertGroup::add)
82}
83
84impl AlertGroup {
85    pub fn add(db: &mut Db, key: Token, block: Block) {
86        db.add(Item::AlertGroup, key, block, Box::new(Self {}));
87    }
88}
89
90impl DbKind for AlertGroup {
91    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
92        // Just check that the alert group is empty
93        Validator::new(block, data);
94
95        let loca = format!("ag_{key}_name");
96        data.verify_exists_implied(Item::Localization, &loca, key);
97        let loca = format!("ag_{key}_desc");
98        data.verify_exists_implied(Item::Localization, &loca, key);
99        let loca = format!("ag_{key}_tooltip");
100        data.verify_exists_implied(Item::Localization, &loca, key);
101    }
102}
103
104// LAST UPDATED VIC3 VERSION 1.12.2
105const SCRIPT_CONTEXTS: &[(&str, Scopes)] = &[
106    ("player_country", Scopes::Country),
107    ("player_decision", Scopes::Country),
108    ("player_country_formation", Scopes::Country),
109    ("player_diplomatic_play", Scopes::DiplomaticPlay),
110    ("player_diplomatic_pact", Scopes::DiplomaticPact),
111    ("player_diplomatic_action", Scopes::DiplomaticAction),
112    ("player_diplomatic_relations", Scopes::DiplomaticRelations),
113    ("player_interest_group", Scopes::InterestGroup),
114    ("player_invaded_state", Scopes::State),
115    ("player_market", Scopes::Market),
116    ("player_invasion", Scopes::Invasion),
117    ("player_state", Scopes::State),
118    ("player_building", Scopes::Building),
119    ("player_market_goods", Scopes::MarketGoods),
120    ("player_commander", Scopes::Character),
121    ("player_military_formation", Scopes::MilitaryFormation),
122    ("player_subject", Scopes::Country),
123    ("player_treaty", Scopes::Treaty),
124    ("player_article", Scopes::TreatyArticle),
125    // undocumented from here
126    ("player_front", Scopes::Front),
127    ("player_war", Scopes::War),
128    ("player_company", Scopes::Company),
129    ("player_state_local_goods", Scopes::StateGoods),
130];