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, warn};
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validate::validate_duration;
12use crate::validator::Validator;
13
14#[derive(Clone, Debug)]
15pub struct PoliticalLobby {}
16
17inventory::submit! {
18 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalLobby, PoliticalLobby::add)
19}
20
21impl PoliticalLobby {
22 pub fn add(db: &mut Db, key: Token, block: Block) {
23 db.add(Item::PoliticalLobby, key, block, Box::new(Self {}));
24 }
25}
26
27impl DbKind for PoliticalLobby {
28 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
29 fn sc_no_lobby(key: &Token) -> ScopeContext {
30 let mut sc = ScopeContext::new(Scopes::InterestGroup, key);
31 sc.define_name("target_country", Scopes::Country, key);
33 sc
34 }
35
36 fn sc_with_lobby(key: &Token) -> ScopeContext {
37 let mut sc = ScopeContext::new(Scopes::Country, key);
38 sc.define_name("target_country", Scopes::Country, key);
39 sc.define_name("political_lobby", Scopes::PoliticalLobby, key);
40 sc
41 }
42
43 fn sc_rtm(key: &Token) -> ScopeContext {
46 let mut sc = ScopeContext::new(Scopes::Country, key);
47 sc.define_name("target_country", Scopes::Country, key);
48 sc.define_name("political_lobby", Scopes::PoliticalLobby, key);
49 sc
50 }
51
52 fn sc_jw(key: &Token) -> ScopeContext {
53 let mut sc = ScopeContext::new(Scopes::InterestGroup, key);
54 sc.define_name("country", Scopes::Country, key);
55 sc.define_name("target_country", Scopes::Country, key);
56 sc.define_name("political_lobby", Scopes::PoliticalLobby, key);
57 sc
58 }
59
60 let mut vd = Validator::new(block, data);
61
62 data.verify_exists(Item::Localization, key);
63 let loca = format!("{key}_name");
64 data.verify_exists_implied(Item::Localization, &loca, key);
65 let loca = format!("{key}_icon");
66 data.verify_exists_implied(Item::Localization, &loca, key);
67
68 vd.field_choice("category", &["foreign_pro_country", "foreign_anti_country", "foreign"]);
69 vd.field_item("texture", Item::File);
70
71 vd.field_trigger_builder("can_create", Tooltipped::No, sc_no_lobby);
72 vd.field_effect_builder("on_created", Tooltipped::No, sc_with_lobby);
73
74 vd.multi_field_validated_block("requirement_to_maintain", |block, data| {
75 let mut vd = Validator::new(block, data);
76 vd.field_trigger_builder("trigger", Tooltipped::No, sc_rtm);
77 vd.field_effect_builder("on_failed", Tooltipped::No, sc_rtm);
78 vd.field_item("swap_type_on_failed", Item::PoliticalLobby);
79 });
80
81 let appeasement_factors_validation = |value: &Token, data: &Everything| {
82 data.verify_exists(Item::PoliticalLobbyAppeasement, value);
83 if data.item_has_property(
84 Item::PoliticalLobbyAppeasement,
85 value.as_str(),
86 "is_always_usable",
87 ) {
88 let msg = "cannot contain appeasement factors marked as `is_always_usable`";
89 warn(ErrorKey::Validation).msg(msg).loc(value).push();
90 }
91 };
92
93 vd.field_validated_list("appeasement_factors_pro", appeasement_factors_validation);
94 vd.field_validated_list("appeasement_factors_anti", appeasement_factors_validation);
95
96 vd.field_trigger_builder("available_for_interest_group", Tooltipped::No, sc_no_lobby);
97
98 vd.field_script_value_no_breakdown_builder("join_weight", sc_jw);
99 }
100}
101
102#[derive(Clone, Debug)]
103pub struct PoliticalLobbyAppeasement {}
104
105inventory::submit! {
106 ItemLoader::Normal(GameFlags::Vic3, Item::PoliticalLobbyAppeasement, PoliticalLobbyAppeasement::add)
107}
108
109impl PoliticalLobbyAppeasement {
110 pub fn add(db: &mut Db, key: Token, block: Block) {
111 db.add(Item::PoliticalLobbyAppeasement, key, block, Box::new(Self {}));
112 }
113}
114
115impl DbKind for PoliticalLobbyAppeasement {
116 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
117 let mut vd = Validator::new(block, data);
118
119 data.verify_exists(Item::Localization, key);
120 let loca = format!("{key}_desc");
121 data.verify_exists_implied(Item::Localization, &loca, key);
122
123 let mut sc = ScopeContext::new(Scopes::PoliticalLobby, key);
125
126 vd.field_validated_block_sc("duration_to_show", &mut sc, validate_duration);
127 vd.field_bool("is_always_usable");
128 }
129
130 fn has_property(
131 &self,
132 _key: &Token,
133 block: &Block,
134 property: &str,
135 _data: &Everything,
136 ) -> bool {
137 block.get_field_bool(property).unwrap_or_default()
138 }
139}