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::modif::validate_modifs;
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validate::validate_possibly_named_color;
12use crate::validator::Validator;
13use crate::vic3::modif::ModifKinds;
14use crate::vic3::tables::modifs::maybe_warn_modifiable_capitalization;
15
16#[derive(Clone, Debug)]
17pub struct Country {}
18
19inventory::submit! {
20 ItemLoader::Normal(GameFlags::Vic3, Item::Country, Country::add)
21}
22
23impl Country {
24 pub fn add(db: &mut Db, key: Token, block: Block) {
25 db.add(Item::Country, key, block, Box::new(Self {}));
26 }
27}
28
29impl DbKind for Country {
30 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
31 let mut vd = Validator::new(block, data);
32
33 data.verify_exists(Item::Localization, key);
34 let loca = format!("{key}_ADJ");
35 data.verify_exists_implied(Item::Localization, &loca, key);
36
37 vd.field_validated("color", validate_possibly_named_color);
38 vd.field_item("country_type", Item::CountryType);
39 vd.field_item("tier", Item::CountryTier);
40 vd.field_item("social_hierarchy", Item::SocialHierarchy);
41 vd.field_list_items("cultures", Item::Culture);
42 vd.field_item("religion", Item::Religion);
43 vd.field_item("capital", Item::StateRegion);
44 vd.field_bool("is_named_from_capital");
45 vd.field_bool("dynamic_country_definition");
46
47 vd.field_validated("primary_unit_color", validate_possibly_named_color);
48 vd.field_validated("secondary_unit_color", validate_possibly_named_color);
49 vd.field_validated("tertiary_unit_color", validate_possibly_named_color);
50
51 vd.field_trigger_rooted(
53 "valid_as_home_country_for_separatists",
54 Tooltipped::No,
55 Scopes::None,
56 );
57 }
58}
59
60#[derive(Clone, Debug)]
61pub struct CountryType {}
62
63inventory::submit! {
64 ItemLoader::Normal(GameFlags::Vic3, Item::CountryType, CountryType::add)
65}
66
67impl CountryType {
68 pub fn add(db: &mut Db, key: Token, block: Block) {
69 db.add(Item::CountryType, key, block, Box::new(Self {}));
70 }
71}
72
73impl DbKind for CountryType {
74 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
75 let mut vd = Validator::new(block, data);
76
77 vd.field_bool("is_colonizable");
78 vd.field_bool("is_unrecognized");
79 vd.field_bool("uses_prestige");
80 vd.field_bool("has_events");
81 vd.field_bool("has_military");
82 vd.field_bool("has_economy");
83 vd.field_bool("has_politics");
84 vd.field_bool("can_research");
85
86 vd.req_field("default_rank");
87 vd.field_item("default_rank", Item::CountryRank);
88 vd.field_item("default_subject_type", Item::SubjectType);
89 }
90}
91
92#[derive(Clone, Debug)]
93pub struct CountryRank {}
94
95inventory::submit! {
96 ItemLoader::Normal(GameFlags::Vic3, Item::CountryRank, CountryRank::add)
97}
98
99impl CountryRank {
100 pub fn add(db: &mut Db, key: Token, block: Block) {
101 db.add(Item::CountryRank, key, block, Box::new(Self {}));
102 }
103}
104
105impl DbKind for CountryRank {
106 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
107 let mut vd = Validator::new(block, data);
108
109 maybe_warn_modifiable_capitalization(key);
110
111 data.verify_exists(Item::Localization, key);
112 let loca = format!("{key}_desc");
113 data.verify_exists_implied(Item::Localization, &loca, key);
114
115 vd.field_integer("rank_value");
116 vd.field_integer("icon_index");
117 vd.field_bool("enforce_subject_rank_check");
118 vd.field_numeric("diplo_pact_cost");
119 vd.field_numeric("treaty_article_cost");
120 vd.field_numeric("ai_pool_character_multiplier");
121 vd.field_numeric("ai_innovation_critical_threshold");
122 vd.field_numeric("prestige_average_threshold");
123 vd.field_numeric("prestige_relative_threshold");
124 vd.field_numeric("infamy_aggressor_scaling");
125 vd.field_numeric("infamy_target_scaling");
126
127 vd.field_list_items("valid_country_types", Item::CountryType);
128
129 vd.field_validated_block("modifier", |block, data| {
130 let vd = Validator::new(block, data);
131 validate_modifs(block, data, ModifKinds::Country, vd);
132 });
133 }
134}
135
136#[derive(Clone, Debug)]
137pub struct CountryFormation {}
138
139inventory::submit! {
140 ItemLoader::Normal(GameFlags::Vic3, Item::CountryFormation, CountryFormation::add)
141}
142
143impl CountryFormation {
144 pub fn add(db: &mut Db, key: Token, block: Block) {
145 db.add(Item::CountryFormation, key, block, Box::new(Self {}));
146 }
147}
148
149impl DbKind for CountryFormation {
150 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
151 let mut vd = Validator::new(block, data);
152 vd.set_case_sensitive(false);
153
154 data.verify_exists(Item::Country, key);
155 vd.field_item("geographic_region", Item::GeographicRegion);
156 vd.field_bool("is_major_formation");
157
158 vd.field_bool("use_culture_states");
159 vd.field_numeric("required_states_fraction");
160 vd.field_list_items("states", Item::StateRegion);
161
162 if block.field_value_is("is_major_formation", "yes") {
163 vd.field_item("unification_play", Item::DiplomaticPlay);
164 vd.field_item("leadership_play", Item::DiplomaticPlay);
165 } else {
166 vd.ban_field("unification_play", || "major formations");
167 vd.ban_field("leadership_play", || "major formations");
168 }
169
170 vd.field_trigger_rooted("ai_will_do", Tooltipped::No, Scopes::Country);
171 vd.field_trigger_rooted("possible", Tooltipped::Yes, Scopes::Country);
172
173 vd.field_integer("max_num_formation_candidates");
176 vd.field_trigger_rooted("can_be_formation_candidate", Tooltipped::No, Scopes::Country);
177 vd.field_trigger_rooted("can_be_unification_target", Tooltipped::Yes, Scopes::Country);
178 vd.field_trigger_rooted("potential", Tooltipped::No, Scopes::Country);
179 }
180}
181
182#[derive(Clone, Debug)]
183pub struct CountryCreation {}
184
185inventory::submit! {
186 ItemLoader::Normal(GameFlags::Vic3, Item::CountryCreation, CountryCreation::add)
187}
188
189impl CountryCreation {
190 pub fn add(db: &mut Db, key: Token, block: Block) {
191 db.add(Item::CountryCreation, key, block, Box::new(Self {}));
192 }
193}
194
195impl DbKind for CountryCreation {
196 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
197 let mut vd = Validator::new(block, data);
198 vd.set_case_sensitive(false);
199 let mut sc = ScopeContext::new(Scopes::Country, key);
200
201 data.verify_exists(Item::Country, key);
202
203 vd.field_bool("use_culture_states");
206 vd.field_integer("required_num_states");
207 vd.field_list_items("states", Item::StateRegion);
208 vd.field_list_items("provinces", Item::Province);
209
210 vd.field_trigger("possible", Tooltipped::Yes, &mut sc);
211 vd.field_trigger("ai_will_do", Tooltipped::No, &mut sc);
212 }
213}