Skip to content

Fix/freeze blocks movement#957

Closed
Tyluur wants to merge 7 commits intoGregHib:mainfrom
Tyluur:fix/freeze-blocks-movement
Closed

Fix/freeze blocks movement#957
Tyluur wants to merge 7 commits intoGregHib:mainfrom
Tyluur:fix/freeze-blocks-movement

Conversation

@Tyluur
Copy link
Copy Markdown
Contributor

@Tyluur Tyluur commented Apr 22, 2026

Summary

Players could still walk to trees, NPCs, and other interactables while under the freeze effect. Walk packets were blocked, but object/NPC interactions queued a new path on the next tick because the engine Movement never checked the freeze timer.

This PR makes freeze authoritative in the engine and blocks it at the input layer.

Changes

  • content/entity/Movement.kt

    • Reject instruction<Walk> when hasClock("movement_delay") is true
    • Show "A magical force stops you from moving." and return early
  • engine/.../mode/move/Movement.kt

    • Add freeze guard at top of tick()
    • if (character.hasClock("movement_delay")) { character.steps.clear(); return }
    • Removes previous var-based check (get("movement_delay", -5)) which never fired because freeze uses a clock, not a var
    • Always clears steps (no noCollision bypass) – matches 2009-2011 behaviour

Why hasClock?

Freeze starts movement_delay as a clock, not a variable. The engine cannot depend on the game-module player.frozen extension, so we check the clock directly. This keeps engine ↔ game separation clean.

Testing

  1. ::freeze 20 on self
  2. Click ground → blocked with message
  3. Click tree / bank booth / NPC → no movement, no path queued
  4. Start walking to object, cast bind mid-path → stops on current tile next tick
  5. After freeze expires → movement resumes normally

No regressions to forced movement (cutscenes/teleports use noCollision steps but are also cleared – intentional, freeze should override player-controlled forced walks).

Closes the last known freeze bypass.

Tyluur added 7 commits April 20, 2026 10:38
…ements fail

Stop combat swing execution when Magic.castSpell fails due to missing requirements.
Also clear transient spell flags ("spell", "one_time", and "autocast") in failure
paths to prevent follow-up clicks from inheriting stale cast state.
- Add CombatSpellsOnPlayer to handle interface spell clicks via ItemOnPlayerInteract
- Route spell interactions through approach system using wildcard handler
- Dynamically resolve spell names from interface definitions using cast_id
- Support modern (192), ancient (193), lunar (430) spellbooks
- Remove redundant isMagicSpell check from Interact tick loop
- End ItemOnPlayerInteract after initial cast to transfer to Combat mode
- Removes updateInteraction that reset launched flag and re-pathed
- Manual casts now behave like autocast: approach once, stand at range
- Prevents step-forward on each spell click
- Add source parameter to multiTargets() to filter out attacker
- Prevents ice barrage/burst from hitting self in multi when adjacent to target
- Updates spell handler to pass caster reference
- Remove one_time assignment in CombatSpellsOnPlayer
- Reject Walk packets when movement_delay clock is active and show "magical force" message
- Add early return in Movement.tick() to clear steps and skip calculate/step when frozen
- Use hasClock("movement_delay") in engine to avoid game-module dependency
- Fixes object/NPC clicks still pathing during freeze (e.g., trees, doors)

Refs: Freeze effect, PlayerOnObjectInteract
@GregHib
Copy link
Copy Markdown
Owner

GregHib commented Apr 22, 2026

Also closing for #959 the issue was more that movement_delay was being ignored not that there wasn't checks for it

@GregHib GregHib closed this Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants