1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::GameFlags;
5use crate::item::{Item, ItemLoader};
6use crate::modif::validate_modifs;
7use crate::token::Token;
8use crate::validator::Validator;
9use crate::vic3::modif::ModifKinds;
10use crate::vic3::tables::misc::COMPANY_CATEGORIES;
11
12#[derive(Clone, Debug)]
13pub struct ProductionMethod {}
14
15inventory::submit! {
16 ItemLoader::Normal(GameFlags::Vic3, Item::ProductionMethod, ProductionMethod::add)
17}
18
19impl ProductionMethod {
20 pub fn add(db: &mut Db, key: Token, block: Block) {
21 db.add(Item::ProductionMethod, key, block, Box::new(Self {}));
22 }
23}
24
25impl DbKind for ProductionMethod {
26 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
27 let mut vd = Validator::new(block, data);
28
29 data.verify_exists(Item::Localization, key);
30
31 vd.field_item("texture", Item::File);
32 vd.field_bool("is_default");
33 vd.field_bool("low_pop_method");
34
35 vd.field_validated_block("profession_ratio", |block, data| {
36 let mut vd = Validator::new(block, data);
37 vd.validate_item_key_values(Item::PopType, |_, mut vvd| {
38 vvd.numeric();
39 });
40 });
41
42 vd.field_validated_block("country_modifiers", |block, data| {
43 validate_modifier_block(block, data, ModifKinds::Country);
44 });
45 vd.field_validated_block("state_modifiers", |block, data| {
46 validate_modifier_block(block, data, ModifKinds::State);
47 });
48 vd.field_validated_block("building_modifiers", |block, data| {
49 validate_modifier_block(block, data, ModifKinds::Building);
50 });
51 vd.field_list_items("timed_modifiers", Item::Modifier);
52
53 vd.multi_field_list_items("unlocking_laws", Item::LawType);
54 vd.multi_field_list_items("disallowing_laws", Item::LawType);
55 vd.multi_field_list_items("unlocking_religions", Item::Religion);
56 vd.multi_field_list_items("disallowing_religions", Item::Religion);
57 vd.multi_field_list_items("unlocking_amendments", Item::Amendment);
58 vd.multi_field_list_items("disallowing_amendments", Item::Amendment);
59 vd.multi_field_list_items("unlocking_technologies", Item::Technology);
60 vd.multi_field_list_items("unlocking_production_methods", Item::ProductionMethod);
61 vd.multi_field_list_items("unlocking_global_technologies", Item::Technology);
62 vd.multi_field_list_items("unlocking_principles", Item::Principle);
63 vd.multi_field_item("unlocking_identity", Item::PowerBlocIdentity);
64
65 vd.field_numeric("ai_weight");
68 vd.field_numeric("ai_value");
69 vd.field_numeric("pollution_generation");
70
71 vd.field_integer("city_lights_color_index");
73
74 vd.field_item("replacement_if_valid", Item::ProductionMethod);
77 vd.field_bool("is_hidden_when_unavailable");
78 vd.multi_field_item("required_input_goods", Item::Goods);
79 vd.multi_field_list_choice("unlocking_company_categories", COMPANY_CATEGORIES);
80 vd.multi_field_list_items("unlocking_geographic_regions", Item::GeographicRegion);
81 }
82}
83
84fn validate_modifier_block(block: &Block, data: &Everything, kinds: ModifKinds) {
85 let mut vd = Validator::new(block, data);
86 vd.field_validated_block("workforce_scaled", |block, data| {
87 let vd = Validator::new(block, data);
88 validate_modifs(block, data, kinds, vd);
89 });
90 vd.field_validated_block("level_scaled", |block, data| {
91 let vd = Validator::new(block, data);
92 validate_modifs(block, data, kinds, vd);
93 });
94 vd.field_validated_block("throughput_scaled", |block, data| {
95 let vd = Validator::new(block, data);
96 validate_modifs(block, data, kinds, vd);
97 });
98 vd.field_validated_block("unscaled", |block, data| {
99 let vd = Validator::new(block, data);
100 validate_modifs(block, data, kinds, vd);
101 });
102}
103
104#[derive(Clone, Debug)]
105pub struct ProductionMethodGroup {}
106
107inventory::submit! {
108 ItemLoader::Normal(GameFlags::Vic3, Item::ProductionMethodGroup, ProductionMethodGroup::add)
109}
110
111impl ProductionMethodGroup {
112 pub fn add(db: &mut Db, key: Token, block: Block) {
113 db.add(Item::ProductionMethodGroup, key, block, Box::new(Self {}));
114 }
115
116 #[allow(clippy::unused_self)] pub fn contains_production_method(
118 &self,
119 contains_pm: &Token,
120 block: &Block,
121 _data: &Everything,
122 ) -> bool {
123 block.get_multi_field_list("production_methods").iter().any(|pm| pm == contains_pm)
124 }
125}
126
127impl DbKind for ProductionMethodGroup {
128 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
129 let mut vd = Validator::new(block, data);
130
131 data.verify_exists(Item::Localization, key);
132
133 if !key.is("pmg_dummy") {
134 vd.req_field("texture");
135 }
136 vd.field_item("texture", Item::File);
137 vd.field_bool("is_hidden_when_unavailable");
138
139 vd.req_field("production_methods");
140 vd.multi_field_list_items("production_methods", Item::ProductionMethod);
141
142 vd.field_choice("ai_selection", &["most_profitable", "most_productive"]);
143 }
144}