1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use super::prelude::*;
/// Defines the fundamental behavior and interface for all stat types within the system.
///
/// This trait is implemented by the various internal stat representations (e.g., `Flat`, `Modifiable`, `Tagged`)
/// to provide a consistent way for the `Stats` component and `StatsMutator` to interact with them.
/// It covers creation, initialization, modifier application, direct setting, and value evaluation.
pub trait Stat {
/// Creates a new instance of a stat type based on the provided path and configuration.
///
/// This is called when a stat is first accessed or defined for an entity if it doesn't already exist.
/// The `config` is used to determine the specific kind of stat (e.g., Flat, Tagged) and its properties.
///
/// # Arguments
///
/// * `path`: The `StatPath` identifying the stat being created.
/// * `config`: A reference to the global `Config` resource.
fn new(path: &StatPath) -> Self;
/// Called after a stat is first created and added to an entity's `Stats` component.
/// Allows for any type-specific initialization logic that might require access to the `Stats` component itself.
/// The default implementation does nothing.
///
/// # Arguments
///
/// * `_path`: The `StatPath` of the stat being initialized.
/// * `_stats`: A mutable reference to the parent `Stats` component.
fn initialize(&self, _path: &StatPath, _stats: &mut Stats) {}
/// Adds a modifier to this stat.
///
/// The specifics of how the modifier is stored and applied depend on the implementing stat type.
///
/// # Arguments
///
/// * `path`: The `StatPath` indicating which specific part of the stat (if applicable) the modifier targets.
/// * `modifier`: The `ModifierType` (literal or expression) to add.
/// * `config`: A reference to the global `Config` resource, which might be needed to determine modifier behavior.
fn add_modifier(&mut self, path: &StatPath, modifier: ModifierType);
/// Removes a previously added modifier from this stat.
///
/// The modifier to be removed should match one that was added earlier.
///
/// # Arguments
///
/// * `path`: The `StatPath` indicating where the modifier was applied.
/// * `modifier`: A reference to the `ModifierType` to remove.
fn remove_modifier(&mut self, path: &StatPath, modifier: &ModifierType);
/// Directly sets a value for a stat or a part of it, potentially overwriting existing values or base amounts.
/// The exact behavior is type-dependent. For simple stats like `Flat`, this might set its only value.
/// For more complex stats, this might target a specific component like a base value.
/// The default implementation does nothing.
///
/// # Arguments
///
/// * `_path`: The `StatPath` indicating which stat or part to set.
/// * `_value`: The `f32` value to set.
fn set(&mut self, _path: &StatPath, _value: f32) {}
/// Evaluates the final value of this stat, considering all its current modifiers and internal logic.
///
/// # Arguments
///
/// * `path`: The `StatPath` specifying which aspect of the stat to evaluate (e.g., total value, a specific tagged part).
/// * `stats`: A reference to the parent `Stats` component, providing context (like cached values or source entity data)
/// that might be needed for evaluation.
///
/// # Returns
///
/// An `f32` representing the calculated value of the stat.
fn evaluate(&self, path: &StatPath, stats: &Stats) -> f32;
/// Clears any internal caches that the stat might hold, potentially for a specific path.
/// This is useful when underlying data changes and cached evaluations need to be invalidated.
/// Returns a list of cache keys that should be invalidated in the parent Stats component.
/// The default implementation does nothing and returns an empty list.
fn clear_internal_cache(&mut self, _path: &StatPath) -> Vec<String> { Vec::new() }
}