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 "interests",
109];
110
111const MAP_NAMES: &[&str] = &[
114 "countries",
115 "cultures",
116 "market_areas",
117 "markets",
118 "power_blocs",
119 "religions",
120 "states",
121 "strategic_regions",
122 "theaters",
123 "player",
124];
125
126impl MapMode {
127 pub fn add(db: &mut Db, key: Token, block: Block) {
128 db.add(Item::MapMode, key, block, Box::new(Self {}));
129 }
130}
131
132impl DbKind for MapMode {
133 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
134 let mut vd = Validator::new(block, data);
136
137 data.verify_exists(Item::Localization, key);
138
139 vd.field_item("icon", Item::File);
140
141 vd.field_choice("map_painting_mode", MAP_PAINTING_MODES);
142 vd.field_choice("map_painting_mode_secondary", MAP_PAINTING_MODES);
143 vd.field_choice("map_painting_mode_alternate", MAP_PAINTING_MODES);
144 vd.field_choice("map_names", MAP_NAMES);
145 vd.field_list("map_markers"); vd.field_list("map_mode_lists"); vd.field_choice("map_tooltip_offset", &["state", "strategic_region", "theater"]);
148 vd.field_choice(
149 "map_texture_mode",
150 &["harvest_conditions", "occupation", "power_blocs", "power_blocs_leverage"],
151 );
152
153 vd.field_bool("has_fog_of_war");
154 vd.field_bool("show_occupation");
155 vd.field_bool("show_formation_movement_arrows");
156 vd.field_bool("is_visible");
157 vd.field_bool("is_visible_to_countryless_observer");
158 vd.field_item("gradient_border_settings", Item::GradientBorderSettings);
159 vd.field_bool("use_alternate_country_borders");
160 vd.field_bool("debug");
161
162 vd.multi_field_item("soundeffect", Item::Sound);
163
164 vd.field_bool("use_mapmode_textures");
165 vd.field_bool("primary_red_as_gradient_border");
166 for field in &[
168 "primary_color_red",
169 "primary_color_green",
170 "primary_color_blue",
171 "primary_color_alpha",
172 "secondary_color_red",
173 "secondary_color_green",
174 "secondary_color_blue",
175 "secondary_color_alpha",
176 "alternate_color_red",
177 "alternate_color_green",
178 "alternate_color_blue",
179 "alternate_color_alpha",
180 ] {
181 if let Some(token) = vd.field_value(field) {
182 let pathname = format!("gfx/map/map_painting/{token}");
183 data.verify_exists_implied(Item::File, &pathname, token);
184 }
185 }
186 }
187}
188
189#[derive(Clone, Debug)]
190pub struct MapInteractionType {}
191
192inventory::submit! {
193 ItemLoader::Normal(GameFlags::Vic3, Item::MapInteractionType, MapInteractionType::add)
194}
195
196impl MapInteractionType {
197 pub fn add(db: &mut Db, key: Token, block: Block) {
198 db.add(Item::MapInteractionType, key, block, Box::new(Self {}));
199 }
200}
201
202impl DbKind for MapInteractionType {
203 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
204 let mut vd = Validator::new(block, data);
206
207 vd.field_item("mapmode", Item::MapMode);
208 vd.field_item("clicksound", Item::Sound);
209 vd.field_bool("show_interaction_text_on_click");
210 }
211}
212
213#[derive(Clone, Debug)]
214pub struct GradientBorderSettings {}
215
216inventory::submit! {
217 ItemLoader::Normal(GameFlags::Vic3, Item::GradientBorderSettings, GradientBorderSettings::add)
218}
219
220impl GradientBorderSettings {
221 pub fn add(db: &mut Db, key: Token, block: Block) {
222 db.add(Item::GradientBorderSettings, key, block, Box::new(Self {}));
223 }
224}
225
226impl DbKind for GradientBorderSettings {
227 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
228 let mut vd = Validator::new(block, data);
230
231 vd.field_numeric("gradient_water_borders_zoom");
232 vd.multi_field_validated_block("gradient_parameters", |block, data| {
233 let mut vd = Validator::new(block, data);
234 vd.field_numeric("zoom_step");
235 vd.field_numeric("gradient_alpha_inside");
236 vd.field_numeric("gradient_alpha_outside");
237 vd.field_numeric("gradient_width");
238 vd.field_numeric("gradient_color_mult");
239 vd.field_numeric("edge_width");
240 vd.field_numeric("edge_sharpness");
241 vd.field_numeric("edge_alpha");
242 vd.field_numeric("edge_color_mult");
243 vd.field_numeric("before_lighting_blend");
244 vd.field_numeric("after_lighting_blend");
245 });
246 }
247}
248
249#[derive(Clone, Debug)]
250pub struct MapNotificationType {}
251
252inventory::submit! {
253 ItemLoader::Normal(GameFlags::Vic3, Item::MapNotificationType, MapNotificationType::add)
254}
255
256impl MapNotificationType {
257 pub fn add(db: &mut Db, key: Token, block: Block) {
258 db.add(Item::MapNotificationType, key, block, Box::new(Self {}));
259 }
260}
261
262impl DbKind for MapNotificationType {
263 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
264 let mut vd = Validator::new(block, data);
265
266 vd.field_item("message", Item::Localization);
267 vd.field_item("widget", Item::WidgetName);
268 vd.field_integer("max_height");
269 vd.field_item("sound", Item::Sound);
270 }
271}