The value is configured, stored and labelled as damage per second, but a pulse
applied it whole, so the real rate was damage per interval - it only matched at
the default interval of 20. A pulse now deals the share of a second it covers.
The interval is floored at 5 ticks, which also bounds how often a zone scans;
this replaces the per-tick membership check, which cost 20x the entity queries.
- Hazards only checked who was inside once per damage interval, so the boundary
where damage started and stopped drifted by however far an entity moved in
between - several blocks at sprint speed. Membership is now checked every
tick and damage accrues per entity from the time it actually spends inside.
- Barriers counted elapsed ticks instead of holding a deadline, so every tick
the entity missed extended it past its configured duration. They now expire
on an absolute world time like the other energy entities.
Introduce client-side trap presets and a visual "trigger reveal" for traps, plus related entity/renderer changes.
- AbilityTrap: add TrapPreset enum and applyTrapPresetDefaults; wire a SubGuiTrapPresetSelector hook to apply presets from the GUI; pass visibility into created trap entities.
- EntityAbilityZone: add visible flag, TRIGGER_FLASH_STATUS state, setEntityState usage to notify clients of triggers, handleHealthUpdate to start client-side flash, and adjust construction/serialization accordingly.
- RenderAbilityZone: implement trigger-reveal visuals (revealFade, triggerReveal) that briefly show a burst when traps trigger, skip rendering for invisible traps unless revealing, and tweak flash/timing logic.
- Minor cleanup: remove/condense comment blocks and refactor noisy helpers across AbilityZone/AbilityHazard, plus language entry update and new SubGuiTrapPresetSelector GUI class.
These changes enable preset application for traps and improve client-side feedback when traps trigger.