overlord_event_system/mechanics/
content_raw_extract.rs1use std::collections::HashMap;
14use std::sync::Arc;
15
16use configs::game_config::GameConfig;
17
18use super::content_lookups::{ContentLookups, EffectTpl};
19
20pub fn extract(game_config: &GameConfig) -> ContentLookups {
24 ContentLookups {
34 effects_by_code: extract_effects(game_config),
35 attribute_by_code: extract_attribute_by_code(game_config),
36 attribute_base_value: extract_attribute_base_value(game_config),
37 quest_by_code: extract_quest_by_code(game_config),
38 ability_range: extract_ability_range(game_config),
39 ability_target_type: extract_ability_target_type(game_config),
40 item_rarity_q: extract_item_rarity_q(game_config),
41 ability_rarity_eff: extract_ability_rarity_eff(game_config),
42 item_fixed_power: extract_item_fixed_power(game_config),
43 item_id_by_mimic_code: extract_item_id_by_mimic_code(game_config),
44 entity_template_is_boss: extract_entity_template_is_boss(game_config),
45 fight_template_is_dungeon: extract_fight_template_flag(game_config, |f| f.is_dungeon),
46 fight_template_is_bossfight: extract_fight_template_flag(game_config, |f| f.is_bossfight),
47 class_counter_role: extract_class_counter_role(game_config),
48 }
49}
50
51fn extract_class_counter_role(game_config: &GameConfig) -> HashMap<uuid::Uuid, i8> {
54 let code_by_attr: HashMap<uuid::Uuid, &str> = game_config
55 .attributes
56 .iter()
57 .map(|a| (a.id, a.code.as_str()))
58 .collect();
59 game_config
60 .classes
61 .iter()
62 .filter_map(|c| {
63 let code = code_by_attr.get(&c.main_attribute)?;
64 Some((
65 c.id,
66 crate::mechanics::balance::class_counter_role_from_code(code),
67 ))
68 })
69 .collect()
70}
71
72fn extract_item_rarity_q(game_config: &GameConfig) -> HashMap<uuid::Uuid, f64> {
74 game_config
75 .item_rarities
76 .iter()
77 .map(|r| (r.id, r.q as f64))
78 .collect()
79}
80
81fn extract_ability_rarity_eff(game_config: &GameConfig) -> HashMap<uuid::Uuid, f64> {
83 game_config
84 .ability_rarities
85 .iter()
86 .map(|r| (r.id, r.eff))
87 .collect()
88}
89
90fn extract_item_fixed_power(game_config: &GameConfig) -> HashMap<uuid::Uuid, f64> {
93 game_config
94 .items
95 .iter()
96 .filter_map(|i| i.fixed_power.map(|fp| (i.id, fp)))
97 .collect()
98}
99
100fn extract_item_id_by_mimic_code(game_config: &GameConfig) -> HashMap<i64, uuid::Uuid> {
107 game_config
108 .items
109 .iter()
110 .filter_map(|i| i.next_mimic_item_code.map(|code| (code, i.id)))
111 .collect()
112}
113
114fn extract_entity_template_is_boss(game_config: &GameConfig) -> HashMap<uuid::Uuid, bool> {
116 game_config
117 .entities
118 .iter()
119 .map(|e| (e.id, e.is_boss))
120 .collect()
121}
122
123fn extract_fight_template_flag(
125 game_config: &GameConfig,
126 flag: impl Fn(&essences::fighting::FightTemplate) -> bool,
127) -> HashMap<uuid::Uuid, bool> {
128 game_config
129 .fight_templates
130 .iter()
131 .map(|f| (f.id, flag(f)))
132 .collect()
133}
134
135fn extract_attribute_base_value(game_config: &GameConfig) -> HashMap<uuid::Uuid, f64> {
141 game_config
142 .attributes
143 .iter()
144 .filter_map(|a| a.base_value.map(|base| (a.id, base as f64)))
145 .collect()
146}
147
148fn extract_ability_range(game_config: &GameConfig) -> HashMap<uuid::Uuid, i64> {
150 game_config
151 .abilities
152 .iter()
153 .map(|a| (a.id, a.range))
154 .collect()
155}
156
157fn extract_ability_target_type(game_config: &GameConfig) -> HashMap<uuid::Uuid, String> {
160 game_config
161 .abilities
162 .iter()
163 .map(|a| (a.id, a.target_type.as_str().to_string()))
164 .collect()
165}
166
167fn extract_effects(game_config: &GameConfig) -> HashMap<String, Arc<EffectTpl>> {
172 let mut out = HashMap::new();
173 for effect in &game_config.effects {
174 out.insert(
175 effect.code.clone(),
176 Arc::new(EffectTpl {
177 id: effect.id,
178 code: effect.code.clone(),
179 max_duration_ticks: effect.duration.map(|d| d * 1000),
180 }),
181 );
182 }
183 out
184}
185
186fn extract_attribute_by_code(game_config: &GameConfig) -> HashMap<String, uuid::Uuid> {
188 let mut out = HashMap::new();
189 for attribute in &game_config.attributes {
190 out.insert(attribute.code.clone(), attribute.id);
191 }
192 out
193}
194
195fn extract_quest_by_code(game_config: &GameConfig) -> HashMap<String, uuid::Uuid> {
198 let mut out = HashMap::new();
199 for quest in &game_config.quests {
200 if let Some(code) = &quest.code {
201 out.insert(code.clone(), quest.id);
202 }
203 }
204 out
205}
206
207#[cfg(test)]
208mod mimic_code_tests {
209 use super::*;
215 use crate::mechanics::content;
216
217 #[test]
218 fn next_mimic_item_code_is_extracted_and_resolves_via_get_item_by_code() {
219 let mut cfg = configs::tests_game_config::generate_game_config_for_tests();
220 let item_id = cfg.items[0].id;
221 cfg.items[0].next_mimic_item_code = Some(1002);
222
223 let lookups = extract(&cfg);
224 assert_eq!(
225 lookups.item_id_by_mimic_code.get(&1002).copied(),
226 Some(item_id),
227 "extract must source item_id_by_mimic_code from ItemTemplate::next_mimic_item_code"
228 );
229 assert_eq!(lookups.item_id_by_mimic_code.len(), 1);
231
232 let item = content::get_item_by_code(&cfg, &lookups, 1002)
233 .expect("mimic code must resolve to the configured item template");
234 assert_eq!(item.id, item_id);
235 assert!(content::get_item_by_code(&cfg, &lookups, 9999).is_none());
236 }
237}