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_technologies", Item::Technology);
58 vd.multi_field_list_items("unlocking_production_methods", Item::ProductionMethod);
59 vd.multi_field_list_items("unlocking_global_technologies", Item::Technology);
60 vd.multi_field_list_items("unlocking_principles", Item::Principle);
61 vd.multi_field_item("unlocking_identity", Item::PowerBlocIdentity);
62
63 vd.field_numeric("ai_weight");
66 vd.field_numeric("ai_value");
67 vd.field_numeric("pollution_generation");
68
69 vd.field_integer("city_lights_color_index");
71
72 vd.field_item("replacement_if_valid", Item::ProductionMethod);
75 vd.field_bool("is_hidden_when_unavailable");
76 vd.multi_field_item("required_input_goods", Item::Goods);
77 vd.multi_field_list_choice("unlocking_company_categories", COMPANY_CATEGORIES);
78 vd.multi_field_list_items("unlocking_geographic_regions", Item::GeographicRegion);
79 }
80}
81
82fn validate_modifier_block(block: &Block, data: &Everything, kinds: ModifKinds) {
83 let mut vd = Validator::new(block, data);
84 vd.field_validated_block("workforce_scaled", |block, data| {
85 let vd = Validator::new(block, data);
86 validate_modifs(block, data, kinds, vd);
87 });
88 vd.field_validated_block("level_scaled", |block, data| {
89 let vd = Validator::new(block, data);
90 validate_modifs(block, data, kinds, vd);
91 });
92 vd.field_validated_block("throughput_scaled", |block, data| {
93 let vd = Validator::new(block, data);
94 validate_modifs(block, data, kinds, vd);
95 });
96 vd.field_validated_block("unscaled", |block, data| {
97 let vd = Validator::new(block, data);
98 validate_modifs(block, data, kinds, vd);
99 });
100}
101
102#[derive(Clone, Debug)]
103pub struct ProductionMethodGroup {}
104
105inventory::submit! {
106 ItemLoader::Normal(GameFlags::Vic3, Item::ProductionMethodGroup, ProductionMethodGroup::add)
107}
108
109impl ProductionMethodGroup {
110 pub fn add(db: &mut Db, key: Token, block: Block) {
111 db.add(Item::ProductionMethodGroup, key, block, Box::new(Self {}));
112 }
113
114 #[allow(clippy::unused_self)] pub fn contains_production_method(
116 &self,
117 contains_pm: &Token,
118 block: &Block,
119 _data: &Everything,
120 ) -> bool {
121 block.get_multi_field_list("production_methods").iter().any(|pm| pm == contains_pm)
122 }
123}
124
125impl DbKind for ProductionMethodGroup {
126 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
127 let mut vd = Validator::new(block, data);
128
129 data.verify_exists(Item::Localization, key);
130
131 if !key.is("pmg_dummy") {
132 vd.req_field("texture");
133 }
134 vd.field_item("texture", Item::File);
135 vd.field_bool("is_hidden_when_unavailable");
136
137 vd.req_field("production_methods");
138 vd.multi_field_list_items("production_methods", Item::ProductionMethod);
139
140 vd.field_choice("ai_selection", &["most_profitable", "most_productive"]);
141 }
142}