overlord_event_system/mechanics/
effect_cb.rs

1//! script ports (`behaviors::cast_ability` / `cast_projectile`).
2//!
3//! ones push `add_entity_stat_mod(owner, stat, value)`, which the engine lowers
4//! to `add_entity_attr(owner, "{stat}.mod", value)` → an `EntityIncrAttribute`
5//! those reactions here, keyed by effect **code** (stable across ids):
6//!
7//! | code          | on_apply                                  |
8//! |---------------|-------------------------------------------|
9//! | `empower`     | `add_entity_stat_mod(attack, +5000)`      |
10//! | `weakness`    | `add_entity_stat_mod(attack, -5000)`      |
11//! | `protection`  | `add_entity_stat_mod(received_damage, -5000)` |
12//! | `vulnerability`| `add_entity_stat_mod(received_damage, +5000)` |
13//! | `test_effect` / `stun` / `shield` | `print(...)` — no events |
14//! | (others)      | no `on_apply` at all — no events           |
15//!
16//! `on_change` is only dispatched by `remove_entity_effect` (with
17//! `new_stacks = 0`, `old_stacks = current`). That path is currently reached
18//! from a `behaviors` native script — so the native `on_change` is, in
19//! practice, not exercised today. It is nonetheless ported faithfully below
20//! (rather than left a no-op) so that any future native caller stays
21//!
22//! |---------------|------------------------------------------------------|
23//! | `empower`     | `add_entity_stat_mod(attack, (new-old)*500)`         |
24//! | `weakness`    | `add_entity_stat_mod(attack, (new-old)*-500)`        |
25//! | `vulnerability`| `add_entity_stat_mod(received_damage, (new-old)*500)`|
26//! | `protection`  | `add_entity_stat_mod(received_damage, -5000)` (flat) |
27//! | (others)      | no `on_change` — no events                            |
28//!
29//! If a new effect with an event-producing reaction ships, extend the matches
30//! below.
31
32use essences::entity::Entity;
33
34use crate::mechanics::content_lookups::EffectTpl;
35use crate::mechanics::fight::{EffectCb, FightSink, add_entity_stat_mod};
36
37/// Native effect-callback dispatcher keyed by effect code. Stateless.
38pub struct OverlordEffectCb;
39
40impl EffectCb for OverlordEffectCb {
41    fn on_apply(
42        &mut self,
43        sink: &mut dyn FightSink,
44        effect: &EffectTpl,
45        target: &Entity,
46    ) -> Result<(), anyhow::Error> {
47        match effect.code.as_str() {
48            "empower" => add_entity_stat_mod(sink, target, "attack", 5000),
49            "weakness" => add_entity_stat_mod(sink, target, "attack", -5000),
50            "protection" => add_entity_stat_mod(sink, target, "received_damage", -5000),
51            "vulnerability" => add_entity_stat_mod(sink, target, "received_damage", 5000),
52            _ => Ok(()),
53        }
54    }
55
56    fn on_change(
57        &mut self,
58        sink: &mut dyn FightSink,
59        effect: &EffectTpl,
60        target: &Entity,
61        new_stacks: i64,
62        old_stacks: i64,
63    ) -> Result<(), anyhow::Error> {
64        // keep it in `i64` and pass it straight to `add_entity_stat_mod`
65        let delta = new_stacks - old_stacks;
66        match effect.code.as_str() {
67            "empower" => add_entity_stat_mod(sink, target, "attack", delta * 500),
68            "weakness" => add_entity_stat_mod(sink, target, "attack", delta * -500),
69            "vulnerability" => add_entity_stat_mod(sink, target, "received_damage", delta * 500),
70            // Protection's on_change is a flat `-5000` (it does not use stacks).
71            "protection" => add_entity_stat_mod(sink, target, "received_damage", -5000),
72            _ => Ok(()),
73        }
74    }
75}