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("prestige_average_threshold");
121 vd.field_numeric("prestige_relative_threshold");
122 vd.field_numeric("infamy_aggressor_scaling");
123 vd.field_numeric("infamy_target_scaling");
124
125 vd.field_list_items("valid_country_types", Item::CountryType);
126
127 vd.field_validated_block("modifier", |block, data| {
128 let vd = Validator::new(block, data);
129 validate_modifs(block, data, ModifKinds::Country, vd);
130 });
131 }
132}
133
134#[derive(Clone, Debug)]
135pub struct CountryFormation {}
136
137inventory::submit! {
138 ItemLoader::Normal(GameFlags::Vic3, Item::CountryFormation, CountryFormation::add)
139}
140
141impl CountryFormation {
142 pub fn add(db: &mut Db, key: Token, block: Block) {
143 db.add(Item::CountryFormation, key, block, Box::new(Self {}));
144 }
145}
146
147impl DbKind for CountryFormation {
148 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
149 let mut vd = Validator::new(block, data);
150 vd.set_case_sensitive(false);
151
152 data.verify_exists(Item::Country, key);
153 vd.field_item("geographic_region", Item::GeographicRegion);
154 vd.field_bool("is_major_formation");
155
156 vd.field_bool("use_culture_states");
157 vd.field_numeric("required_states_fraction");
158 vd.field_list_items("states", Item::StateRegion);
159
160 if block.field_value_is("is_major_formation", "yes") {
161 vd.field_item("unification_play", Item::DiplomaticPlay);
162 vd.field_item("leadership_play", Item::DiplomaticPlay);
163 } else {
164 vd.ban_field("unification_play", || "major formations");
165 vd.ban_field("leadership_play", || "major formations");
166 }
167
168 vd.field_trigger_rooted("ai_will_do", Tooltipped::No, Scopes::Country);
169 vd.field_trigger_rooted("possible", Tooltipped::Yes, Scopes::Country);
170
171 vd.field_integer("max_num_formation_candidates");
174 vd.field_trigger_rooted("can_be_formation_candidate", Tooltipped::No, Scopes::Country);
175 vd.field_trigger_rooted("can_be_unification_target", Tooltipped::Yes, Scopes::Country);
176 vd.field_trigger_rooted("potential", Tooltipped::No, Scopes::Country);
177 }
178}
179
180#[derive(Clone, Debug)]
181pub struct CountryCreation {}
182
183inventory::submit! {
184 ItemLoader::Normal(GameFlags::Vic3, Item::CountryCreation, CountryCreation::add)
185}
186
187impl CountryCreation {
188 pub fn add(db: &mut Db, key: Token, block: Block) {
189 db.add(Item::CountryCreation, key, block, Box::new(Self {}));
190 }
191}
192
193impl DbKind for CountryCreation {
194 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
195 let mut vd = Validator::new(block, data);
196 vd.set_case_sensitive(false);
197 let mut sc = ScopeContext::new(Scopes::Country, key);
198
199 data.verify_exists(Item::Country, key);
200
201 vd.field_bool("use_culture_states");
204 vd.field_integer("required_num_states");
205 vd.field_list_items("states", Item::StateRegion);
206 vd.field_list_items("provinces", Item::Province);
207
208 vd.field_trigger("possible", Tooltipped::Yes, &mut sc);
209 vd.field_trigger("ai_will_do", Tooltipped::No, &mut sc);
210 }
211}