Module fight

Source
Expand description

Native Rust fight logic.

These are the pure-Rust fight primitives (attack, try_cast, spawn_wave, …) used by the native combat ports in crate::behaviors. Results are emitted through the FightSink abstraction and effect reactions through the EffectCb abstraction; the shipped reactions live in crate::mechanics::effect_cb::OverlordEffectCb.

Structs§

AttackParams
Typed form of the attack params.
BetweenWaveBehavior
Per-fight behavior selected for a normal wave transition. Dungeon overrides are independent: omitting either field preserves that standard behavior.
NativeSink
Sink that collects fight results as typed values for native callers. Mirrors start_behaviors fill casts.
NoopEffectCb
Effect callback that does nothing — for callers that don’t want effect reactions dispatched.
OriginSink
Sink decorator that stamps the provenance of everything a producer emits, and refuses whatever it cannot stamp.
SpellHealParams
Typed form of the spell_heal params.
WaveEntityPower
WaveFightData
Typed form of the fight_data prepare-fight blob fed to spawn_wave.
WaveSpawn

Enums§

OnceSlot
The independent one-shot budgets a single dispatch can claim.

Constants§

BATTLEFIELD_HEIGHT
BOSS_OUTGOING_EQUIVALENCE_PPM_ATTR
Parts-per-million multiplier preserving A2-BAL-001’s measured, previously shipped boss outgoing budget after the hidden automatic stun was removed. Read only by attack after the full hit payload is composed.
COUNTERATTACK_PROJECTILE
DERIVED_DAMAGE_KEY
Damage-payload key marking a hit as a DERIVED copy of a cast (support-stone Split / Chain / Pierce / Repeat / Pulse) rather than an original Core hit. Anything that reacts to combat events (laws, resonance, mastery, triggers) must skip a payload carrying this key.
FORMATION_ADVANCE_CELLS
Between-wave formation dash distance in logical cells. Advancing fights assign waves 2+ against the player’s landing column (current + this).
GUARD_CHARGES_ATTR
Entity attributes behind the two defensive supports. guard_charges counts pending Fortify charges, guard_reduction is the reduction of the next hit in ×10000 units (3000 = −30%). Shelter needs no attribute of its own: it is a plain timed received_damage.mod.
GUARD_REDUCTION_ATTR
MELEE_COL_OFFSET
RANGED_COL_OFFSET

Traits§

EffectCb
Invokes an effect’s on_apply / on_change reaction.
FightSink
Where a fight method emits its results.

Functions§

add_entity_attr
Native: ctx.add_entity_attr(entity, attr, value) — push an IncrAttribute
add_entity_stat_mod
Native: ctx.add_entity_stat_mod(entity, stat, value) — push an IncrAttribute on "{stat}.mod" by value. Mirrors the engine’s add_entity_stat_mod (which lowers to add_entity_attr(entity, "{stat}.mod", value)); used by the native effect-callback dispatcher to replicate the
apply_entity_effect
Native: apply effect_code to target for duration_seconds (converted to ticks). Effect on_apply reactions are dispatched through effects.
apply_entity_over_time_effect
Native: apply a damage-/heal-over-time effect (kind = "dot" / "hot"), splitting amount over 5 ticks. No effect callbacks, no RNG.
attack
Native: perform an attack from caster on target. Returns the floored damage dealt (None => the no-damage paths: evasion, or no power given). RNG is consumed in the exact original order: evasion, counterattack_chance, deceit (+ randint(0,2) if it lands), crit_chance, then damage_entity’s block roll.
between_wave_behavior
Resolves per-dungeon wave behavior without adding state to ActiveFight. Campaign fights and dungeons without overrides keep the shipped 500 ms spawn pause and formation advance.
cast
Native: queue casts attack actions for caster against valid_targets. Consumes multicast_chance from rng, then (per cast after the first, when there are multiple targets) a randint for target selection. _ability is unused, matching the original signature.
change_entity_effect_duration
Native: add duration ticks of effect_code to target (capped at the effect’s max_duration_ticks), emitting EntityApplyEffect on first application and dispatching the effect’s on_apply reaction.
damage_entity
Native: apply raw_dmg to entity (armor, shield, block roll, received damage multiplier). Returns the floored post-mitigation damage value; None only for the no-damage early-outs (godmode / a missing received_damage base value — a content-extraction regression), which short-circuit before the block roll. When a shield fully absorbs the hit the function still returns Some(floored_damage) (and emits the shield decrement) — this value drives attack’s return / lifesteal, so it must not be None or the caller would discard the shield event. Consumes one block stat_throw from rng when it is reached.
entity_run
Native: move entity toward the enemy line in a single multi-cell run (one StartMove instead of one per cell — every per-cell seam quantizes to the 100ms game tick and gives the client a chance to stutter).
entropy_throw
Entropy-based proc check (PoE-style). Instead of an independent roll per check, each (entity, stat) keeps an accumulator seeded 0..9999 from the fight RNG on first use; every check adds the chance (permyriad) and the proc fires exactly when the accumulator crosses 10000. The expected proc RATE is identical to independent rolls; streaks — lucky and unlucky — are eliminated, which is the variance compensation that makes proc stats (crit/dodge/multicast/ block/counter) safe to value at full expected-value price in the honest scalar (research: PoE entropy, verified 3-0).
entropy_throw_p
Entropy variant for a probability that is already a fraction (0..1) rather than a permyriad stat — the dodge DR curve’s output.
formation_step_duration_ticks
Duration of an ally formation run over cells logical cells (the promotion step, the between-wave dash fallback) at the standard ally pace.
gated_release_row
Row for a death-gated mob at RELEASE time: the least-occupied row of its own column, counting living enemies standing on it, running to it, or parked pending arrival at the same park column (exit-cooldown waiters and same-tick earlier releases — their park y IS their landing row). Ties prefer the mob’s authored row, then the middle — so the freed space is taken instead of stacking onto survivors.
get_entity_stat
ctx.get_entity_stat(entity, "armor") — applies attribute base value (from content_raw), additive bonus, and multiplicative mod (+10000 == +1.0).
heal_entity
Native: heal entity, capping at its missing HP. Returns the applied heal (None if no heal was applied). by_entity_id and source are the breakdown attribution — who healed, and with what.
init_fight
Native: emit the per-entity init events for a fight (regen effect, low-chapter effect, party power adjustment, dungeon/boss talent attack mods). No RNG, no effect callbacks. fight supplies player/party ids + the entity roster + party_adjusted_power; reads talent levels / chapter from state.
later_wave_entrance_floor_ticks
Entrance floor shared by the live slot scheduler and the balance mini-sim. Stationary dungeons have no artificial formation wait.
on_cast
Native: the ability on_cast hook. Rolls bravery; on success applies a random buff (protection/empower). Consumes bravery then (if it lands) a randint(0,2) from rng. Effect on_apply reactions dispatch via effects.
over_time_tick_source
The source an over-time tick of kind carries: the ability recorded by the last applier, or fallback when none was.
remove_entity_effect
Native: remove all stacks of effect_code from target, dispatching the effect’s on_change reaction with (new_stacks=0, old_stacks=current).
screen_shake
Native: emit a screen_shake visual event.
set_entity_attr
Native: ctx.set_entity_attr(entity, attr, value) — push an IncrAttribute that moves the attr TO value (delta = round(value - current)). Emitted
slot_promotion_needed
Slot-model promotion predicate (docs/combat-grid-migration-plan.md §2.2): the ally formation steps one column forward when the near (melee) column holds no living enemy while the far column does. An enemy’s effective column is where it stands or is running to (move_target); units still parked beyond the far column (waiting out their exit cooldown behind the screen edge) do not count — stepping toward them would drag the hero to the spawn edge. Recursion needs no special code: after a step the old far column IS the near column, and the next death/landing re-checks.
spawn_wave
Native: the prepare_fight interpreter. Computes normalised enemy stats from the chapter power curve + the typed wave blob, then emits spawn events for the current wave. RNG is consumed once per spawned enemy (the spawn-entity uuid), in iteration order — identical to the original. fight supplies current_wave + the live entities (for the multi-wave x-offset).
spell_heal
Native: heal target from caster’s attack stat. Returns the applied heal (None when no heal). Consumes crit_chance from rng (unless is_crit is forced), then heal_entity’s path (no RNG).
stat_throw
stat_throw_scaled
stat_throw with the success probability multiplied by scale — the sigmoid-steepening experiments dial down binary per-hit RNG (crit) without touching entity stats. scale = 1.0 is byte-identical to the unscaled throw (same single RNG draw for any positive stat).
touch_enemy
Native: returns whether target is touched (i.e. did NOT evade). Balance v2: dodge probability follows the DR curve ev/(ev+K_DODGE) (asymptote < 100%, no 100%-dodge cliff). Attribute-balance track: the dodge OUTCOME is resolved through the entropy accumulator, not an independent roll — a 20% dodge evades exactly every 5th incoming touch, never streaks (the variance compensation that makes evasion safe to grant as a live stat).
try_cast
Native: attempt to cast ability_id from caster. Picks valid targets and delegates to cast; if there are none and the caster is not static, advances toward the enemy. casts is the natural cast count (default 1). Consumes RNG only via cast / advance_entity.
wave_data_from_config
Convert the typed config mirror (prepare_fight_waves) into the runtime WaveFightData consumed by spawn_wave. This is the native data source for the prepare_fight interpreter.