overlord_event_system/mechanics/
content_lookups.rs

1//! engine init. Holds fields that the Rust schemas don't carry (`q`, `eff`,
2//! `fixed_power`, `is_boss`, `is_dungeon`, `is_bossfight`, attribute
3//! `base_value`, effect `on_apply`/`on_change` callbacks, ...).
4
5use std::collections::HashMap;
6use std::sync::Arc;
7
8use essences::abilities::{AbilityId, AbilityRarityId};
9use essences::fighting::FightTemplateId;
10use essences::game::EntityTemplate;
11use essences::game::EntityTemplateId;
12use essences::items::{AttributeId, ItemRarityId};
13use uuid::Uuid;
14
15#[derive(Debug, Default, Clone)]
16pub struct ContentLookups {
17    // --- Balance ---
18    pub item_rarity_q: HashMap<ItemRarityId, f64>,
19    pub ability_rarity_eff: HashMap<AbilityRarityId, f64>,
20    pub item_fixed_power: HashMap<Uuid, f64>,
21    /// `ItemTemplate::next_mimic_item_code` (an `i64`) → item template id, for
22    /// `content::get_item_by_code`. Codes are unique across items in the
23    /// shipped content.
24    pub item_id_by_mimic_code: HashMap<i64, Uuid>,
25
26    // --- Fight / AI ---
27    /// Effect templates keyed by their `code`. The effect reactions
28    /// (`on_apply` / `on_change`) are native, dispatched by
29    /// [`crate::mechanics::effect_cb::OverlordEffectCb`] keyed by `code`.
30    pub effects_by_code: HashMap<String, Arc<EffectTpl>>,
31    pub fight_template_is_dungeon: HashMap<FightTemplateId, bool>,
32    pub fight_template_is_bossfight: HashMap<FightTemplateId, bool>,
33    pub entity_template_is_boss: HashMap<EntityTemplateId, bool>,
34
35    /// `attribute.code` → AttributeId, for `get_attribute_by_code` / stat lookups.
36    pub attribute_by_code: HashMap<String, AttributeId>,
37    /// `attribute.base_value` extracted from content_raw (not on Rust schema).
38    pub attribute_base_value: HashMap<AttributeId, f64>,
39
40    // --- Classes ---
41    /// Balance v2 (Phase 5): `class.id` → soft 3-cycle combat role
42    /// (0=Warrior, 1=Rogue, 2=Mage, -1=neutral), derived from the class's
43    /// `main_attribute` code. Drives `balance::class_counter_multiplier`.
44    pub class_counter_role: HashMap<Uuid, i8>,
45
46    // --- Loop tasks / quests ---
47    /// Quest `code` → quest UUID, for `loop_tasks::get_quest_by_code`.
48    pub quest_by_code: HashMap<String, Uuid>,
49
50    // --- Abilities (content_raw extras) ---
51    /// Per-ability `range` (cells), from `content_raw::abilities[id].range`.
52    pub ability_range: HashMap<AbilityId, i64>,
53    /// Per-ability `target_type` string ("Enemy", "Ally", "Self"),
54    /// from `content_raw::abilities[id].target_type`.
55    pub ability_target_type: HashMap<AbilityId, String>,
56}
57
58#[derive(Debug, Clone)]
59pub struct EffectTpl {
60    pub id: Uuid,
61    pub code: String,
62    pub max_duration_ticks: Option<i64>,
63}
64
65/// Pre-cached entity-template wrapper for fast lookup of `width`, `cast_time`.
66#[derive(Debug, Clone)]
67pub struct CachedEntityTemplate {
68    pub width: i64,
69    pub cast_time: i64,
70    pub is_boss: bool,
71}
72
73impl ContentLookups {
74    pub fn entity_template_cache(&self, tpl: &EntityTemplate) -> CachedEntityTemplate {
75        CachedEntityTemplate {
76            width: tpl.width as i64,
77            cast_time: tpl.cast_time as i64,
78            is_boss: self
79                .entity_template_is_boss
80                .get(&tpl.id)
81                .copied()
82                .unwrap_or(false),
83        }
84    }
85}