From 309ab19e8c01b173bf0b40b8223a534c6ffe8394 Mon Sep 17 00:00:00 2001 From: Peter Stockings Date: Tue, 6 Jan 2026 21:23:25 +1100 Subject: [PATCH] Attempting to move into tile that blocks shouldnt result in wait action --- src/core/types.ts | 3 +- .../__tests__/movement_block.test.ts | 63 +++++++++++++++++++ src/engine/simulation/simulation.ts | 4 +- src/scenes/GameScene.ts | 8 ++- 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 src/engine/simulation/__tests__/movement_block.test.ts diff --git a/src/core/types.ts b/src/core/types.ts index 0135a08..f782659 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -26,7 +26,8 @@ export type SimEvent = | { type: "exp-collected"; actorId: EntityId; amount: number; x: number; y: number } | { type: "orb-spawned"; orbId: EntityId; x: number; y: number } | { type: "leveled-up"; actorId: EntityId; level: number; x: number; y: number } - | { type: "enemy-alerted"; enemyId: EntityId; x: number; y: number }; + | { type: "enemy-alerted"; enemyId: EntityId; x: number; y: number } + | { type: "move-blocked"; actorId: EntityId; x: number; y: number }; export type Stats = { diff --git a/src/engine/simulation/__tests__/movement_block.test.ts b/src/engine/simulation/__tests__/movement_block.test.ts new file mode 100644 index 0000000..cb6371d --- /dev/null +++ b/src/engine/simulation/__tests__/movement_block.test.ts @@ -0,0 +1,63 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { applyAction } from '../simulation'; +import type { World, CombatantActor, Action } from '../../../core/types'; +import { TileType } from '../../../core/terrain'; +import { GAME_CONFIG } from '../../../core/config/GameConfig'; + +describe('Movement Blocking Behavior', () => { + let world: World; + let player: CombatantActor; + + beforeEach(() => { + // minimalist world setup + world = { + width: 3, + height: 3, + tiles: new Array(9).fill(TileType.GRASS), + actors: new Map(), + exit: { x: 2, y: 2 } + }; + + // Blocking wall at (1, 0) + world.tiles[1] = TileType.WALL; + + player = { + id: 1, + type: 'player', + category: 'combatant', + isPlayer: true, + pos: { x: 0, y: 0 }, + speed: 100, + energy: 0, + stats: { ...GAME_CONFIG.player.initialStats } + }; + + world.actors.set(player.id, player); + }); + + it('should return move-blocked event when moving into a wall', () => { + const action: Action = { type: 'move', dx: 1, dy: 0 }; // Try to move right into wall at (1,0) + const events = applyAction(world, player.id, action); + + expect(events).toHaveLength(1); + expect(events[0]).toMatchObject({ + type: 'move-blocked', + actorId: player.id, + x: 1, + y: 0 + }); + }); + + it('should return moved event when moving into empty space', () => { + const action: Action = { type: 'move', dx: 0, dy: 1 }; // Move down to (0,1) - valid + const events = applyAction(world, player.id, action); + + expect(events).toHaveLength(1); + expect(events[0]).toMatchObject({ + type: 'moved', + actorId: player.id, + from: { x: 0, y: 0 }, + to: { x: 0, y: 1 } + }); + }); +}); diff --git a/src/engine/simulation/simulation.ts b/src/engine/simulation/simulation.ts index aa2d45e..249fb40 100644 --- a/src/engine/simulation/simulation.ts +++ b/src/engine/simulation/simulation.ts @@ -123,9 +123,9 @@ function handleMove(w: World, actor: Actor, action: { dx: number; dy: number }, } return events; - } else { - return [{ type: "waited", actorId: actor.id }]; } + + return [{ type: "move-blocked", actorId: actor.id, x: nx, y: ny }]; } diff --git a/src/scenes/GameScene.ts b/src/scenes/GameScene.ts index d0413a6..37e3618 100644 --- a/src/scenes/GameScene.ts +++ b/src/scenes/GameScene.ts @@ -405,10 +405,14 @@ export class GameScene extends Phaser.Scene { } private commitPlayerAction(action: Action) { + const playerEvents = applyAction(this.world, this.playerId, action, this.entityManager); + + if (playerEvents.some(ev => ev.type === "move-blocked")) { + return; + } + this.awaitingPlayer = false; this.followPlayer = true; - - const playerEvents = applyAction(this.world, this.playerId, action, this.entityManager); // Check for pickups right after move (before enemy turn, so you get it efficiently) if (action.type === "move") {