tiger_lib/vic3/data/
map.rs

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        // This function warns at `untidy` level because if map layers are actually missing,
20        // they will be warned about by their users.
21        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"); // this is the key
38
39        vd.field_integer("fade_in");
40        vd.field_integer("fade_out");
41
42        // None of the following have examples in vanilla
43        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
56// LAST UPDATED VIC3 VERSION 1.8.1
57// Taken from gfx/map/map_modes/map_modes.txt
58const 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
110// LAST UPDATED VIC3 VERSION 1.7.1
111// Taken from gfx/map/map_modes/map_modes.txt
112const 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        // This entire item type is undocumented
134        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"); // TODO widget names from gui/map_markers.gui
145        vd.field_list("map_mode_lists"); // unknown list items. panel name?
146        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        // TODO: not sure whether alternate_color blue and alpha are valid
166        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        // This entire item type is undocumented
204        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        // This entire item type is undocumented.
228        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}