1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::GameFlags;
5use crate::item::{Item, ItemLoader};
6use crate::report::{ErrorKey, untidy};
7use crate::token::Token;
8use crate::validator::Validator;
9
10#[derive(Clone, Debug)]
11pub struct MapLayer {}
12
13inventory::submit! {
14 ItemLoader::Normal(GameFlags::Vic3, Item::MapLayer, MapLayer::add)
15}
16
17impl MapLayer {
18 pub fn add(db: &mut Db, key: Token, block: Block) {
19 if key.is("layer") {
22 if let Some(name) = block.get_field_value("name") {
23 db.add_exact_dup_ok(Item::MapLayer, name.clone(), block, Box::new(Self {}));
24 } else {
25 untidy(ErrorKey::FieldMissing).msg("unnamed map layer").loc(key).push();
26 }
27 } else {
28 untidy(ErrorKey::UnknownField).weak().msg("unknown map layer item").loc(key).push();
29 }
30 }
31}
32
33impl DbKind for MapLayer {
34 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
35 let mut vd = Validator::new(block, data);
36
37 vd.field_value("name"); vd.field_integer("fade_in");
40 vd.field_integer("fade_out");
41
42 vd.field_value("category");
44 vd.field_value("masks");
45 vd.field_value("visibility_tags");
46 }
47}
48
49#[derive(Clone, Debug)]
50pub struct MapMode {}
51
52inventory::submit! {
53 ItemLoader::Normal(GameFlags::Vic3, Item::MapMode, MapMode::add)
54}
55
56const MAP_PAINTING_MODES: &[&str] = &[
59 "clout_nationally",
60 "colonizable_provinces",
61 "countries",
62 "country_attitude",
63 "country_infamy",
64 "country_relations",
65 "culture_overview",
66 "culture_overview_minority",
67 "culture_population",
68 "gdp",
69 "gdp_nationally",
70 "gdp_ownership_ratio",
71 "global_starvation",
72 "goods_consumption",
73 "goods_local_prices",
74 "goods_production",
75 "harvest_conditions",
76 "ig_strength",
77 "literacy",
78 "loyalists",
79 "market_access",
80 "market_areas",
81 "mass_migration_pull",
82 "migration",
83 "migration_pull",
84 "none",
85 "obstinance",
86 "player_alliances",
87 "player_culture_population",
88 "player_goods_potentials",
89 "player_military_access",
90 "player_population",
91 "player_religion_population",
92 "player_theaters",
93 "pollution",
94 "population",
95 "power_blocs",
96 "province_terrain",
97 "radicals",
98 "religion_overview",
99 "religion_overview_minority",
100 "religion_population",
101 "standard_of_living",
102 "state_gradient",
103 "state_mass_migration_pull",
104 "states",
105 "strategic_regions",
106 "technology_progress",
107 "player_country",
108];
109
110const MAP_NAMES: &[&str] = &[
113 "countries",
114 "cultures",
115 "market_areas",
116 "markets",
117 "power_blocs",
118 "religions",
119 "states",
120 "strategic_regions",
121 "theaters",
122 "player",
123];
124
125impl MapMode {
126 pub fn add(db: &mut Db, key: Token, block: Block) {
127 db.add(Item::MapMode, key, block, Box::new(Self {}));
128 }
129}
130
131impl DbKind for MapMode {
132 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
133 let mut vd = Validator::new(block, data);
135
136 data.verify_exists(Item::Localization, key);
137
138 vd.field_item("icon", Item::File);
139
140 vd.field_choice("map_painting_mode", MAP_PAINTING_MODES);
141 vd.field_choice("map_painting_mode_secondary", MAP_PAINTING_MODES);
142 vd.field_choice("map_painting_mode_alternate", MAP_PAINTING_MODES);
143 vd.field_choice("map_names", MAP_NAMES);
144 vd.field_list("map_markers"); vd.field_list("map_mode_lists"); vd.field_choice("map_tooltip_offset", &["state", "strategic_region", "theater"]);
147 vd.field_choice(
148 "map_texture_mode",
149 &["harvest_conditions", "occupation", "power_blocs", "power_blocs_leverage"],
150 );
151
152 vd.field_bool("has_fog_of_war");
153 vd.field_bool("show_occupation");
154 vd.field_bool("show_formation_movement_arrows");
155 vd.field_bool("is_visible");
156 vd.field_bool("is_visible_to_countryless_observer");
157 vd.field_item("gradient_border_settings", Item::GradientBorderSettings);
158 vd.field_bool("use_alternate_country_borders");
159 vd.field_bool("debug");
160
161 vd.multi_field_item("soundeffect", Item::Sound);
162
163 vd.field_bool("use_mapmode_textures");
164 vd.field_bool("primary_red_as_gradient_border");
165 for field in &[
167 "primary_color_red",
168 "primary_color_green",
169 "primary_color_blue",
170 "primary_color_alpha",
171 "secondary_color_red",
172 "secondary_color_green",
173 "secondary_color_blue",
174 "secondary_color_alpha",
175 "alternate_color_red",
176 "alternate_color_green",
177 "alternate_color_blue",
178 "alternate_color_alpha",
179 ] {
180 if let Some(token) = vd.field_value(field) {
181 let pathname = format!("gfx/map/map_painting/{token}");
182 data.verify_exists_implied(Item::File, &pathname, token);
183 }
184 }
185 }
186}
187
188#[derive(Clone, Debug)]
189pub struct MapInteractionType {}
190
191inventory::submit! {
192 ItemLoader::Normal(GameFlags::Vic3, Item::MapInteractionType, MapInteractionType::add)
193}
194
195impl MapInteractionType {
196 pub fn add(db: &mut Db, key: Token, block: Block) {
197 db.add(Item::MapInteractionType, key, block, Box::new(Self {}));
198 }
199}
200
201impl DbKind for MapInteractionType {
202 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
203 let mut vd = Validator::new(block, data);
205
206 vd.field_item("mapmode", Item::MapMode);
207 vd.field_item("clicksound", Item::Sound);
208 vd.field_bool("show_interaction_text_on_click");
209 }
210}
211
212#[derive(Clone, Debug)]
213pub struct GradientBorderSettings {}
214
215inventory::submit! {
216 ItemLoader::Normal(GameFlags::Vic3, Item::GradientBorderSettings, GradientBorderSettings::add)
217}
218
219impl GradientBorderSettings {
220 pub fn add(db: &mut Db, key: Token, block: Block) {
221 db.add(Item::GradientBorderSettings, key, block, Box::new(Self {}));
222 }
223}
224
225impl DbKind for GradientBorderSettings {
226 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
227 let mut vd = Validator::new(block, data);
229
230 vd.field_numeric("gradient_water_borders_zoom");
231 vd.multi_field_validated_block("gradient_parameters", |block, data| {
232 let mut vd = Validator::new(block, data);
233 vd.field_numeric("zoom_step");
234 vd.field_numeric("gradient_alpha_inside");
235 vd.field_numeric("gradient_alpha_outside");
236 vd.field_numeric("gradient_width");
237 vd.field_numeric("gradient_color_mult");
238 vd.field_numeric("edge_width");
239 vd.field_numeric("edge_sharpness");
240 vd.field_numeric("edge_alpha");
241 vd.field_numeric("edge_color_mult");
242 vd.field_numeric("before_lighting_blend");
243 vd.field_numeric("after_lighting_blend");
244 });
245 }
246}
247
248#[derive(Clone, Debug)]
249pub struct MapNotificationType {}
250
251inventory::submit! {
252 ItemLoader::Normal(GameFlags::Vic3, Item::MapNotificationType, MapNotificationType::add)
253}
254
255impl MapNotificationType {
256 pub fn add(db: &mut Db, key: Token, block: Block) {
257 db.add(Item::MapNotificationType, key, block, Box::new(Self {}));
258 }
259}
260
261impl DbKind for MapNotificationType {
262 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
263 let mut vd = Validator::new(block, data);
264
265 vd.field_item("message", Item::Localization);
266 vd.field_item("widget", Item::WidgetName);
267 vd.field_integer("max_height");
268 vd.field_item("sound", Item::Sound);
269 }
270}