Skip to main content

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    "interests",
109];
110
111// LAST UPDATED VIC3 VERSION 1.7.1
112// Taken from gfx/map/map_modes/map_modes.txt
113const 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        // This entire item type is undocumented
135        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"); // TODO widget names from gui/map_markers.gui
146        vd.field_list("map_mode_lists"); // unknown list items. panel name?
147        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        // TODO: not sure whether alternate_color blue and alpha are valid
167        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        // This entire item type is undocumented
205        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        // This entire item type is undocumented.
229        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}