Skip to main content

wowlab_engine_gamedata/game_data/
resolved_game_data.rs

1//! [`ResolvedGameData`]: Arc-wrapped resolved game data for a single spec.
2
3use std::sync::Arc;
4
5use super::{EffectStore, EnvironmentStore, PassiveStore, ScalingStore, SpellStore};
6
7/// Resolved game data for a single spec. Thread-safe, cheaply cloneable.
8#[derive(Clone, Debug, Default)]
9pub struct ResolvedGameData {
10    pub(super) inner: Arc<ResolvedGameDataInner>,
11}
12
13#[derive(Debug, Default)]
14pub(crate) struct ResolvedGameDataInner {
15    pub effects: EffectStore,
16    pub spells: SpellStore,
17    pub passives: PassiveStore,
18    pub environment: EnvironmentStore,
19    pub scaling: ScalingStore,
20}
21
22impl ResolvedGameData {
23    #[must_use]
24    pub fn new() -> Self {
25        Self::default()
26    }
27
28    /// Builds the minimal resolved environment needed by combat calculations.
29    #[must_use]
30    pub fn from_environment(level: u32, creature_armor: f64, armor_constant: f64) -> Self {
31        let mut builder = Self::builder();
32
33        builder.set_level(level);
34        builder.set_creature_armor(creature_armor);
35        builder.set_armor_constant(armor_constant);
36
37        builder.build()
38    }
39
40    /// Starts a resolved game-data builder.
41    #[must_use]
42    pub fn builder() -> super::ResolvedGameDataBuilder {
43        super::ResolvedGameDataBuilder::new()
44    }
45
46    /// Sorted union of spell identities represented by any resolved store.
47    ///
48    /// This is a cold finalization query used to compile subsystem-local plans.
49    #[must_use]
50    pub fn resolved_spell_ids(&self) -> Vec<wowlab_types::sim::SpellIdx> {
51        wowlab_types::bench_metrics::record_game_data_hot_read();
52
53        let mut spells = Vec::new();
54
55        spells.extend(self.inner.spells.props.keys().copied());
56        spells.extend(self.inner.spells.aura_props.keys().copied());
57        spells.extend(self.inner.spells.labels.keys().copied());
58        spells.extend(self.inner.spells.class_flags.keys().copied());
59        spells.extend(self.inner.effects.school_masks.keys().copied());
60        spells.extend(self.inner.effects.values.keys().map(|effect| effect.spell));
61        spells.extend(self.inner.passives.spell_modifiers.keys().copied());
62        spells.sort_unstable();
63        spells.dedup();
64
65        spells
66    }
67}