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}