diff --git a/docs/translation_log.md b/docs/translation_log.md index 0f33b75d..93568a92 100644 --- a/docs/translation_log.md +++ b/docs/translation_log.md @@ -660,12 +660,19 @@ worked around this by priming `wPlayerLastStopDirection = PLAYER_DIR_DOWN` in `.handleDirection`, before the turn-delay check. Removed the `wPlayerLastStopDirection` prime from `PlayerStepOutFromDoor`. -### Cleanup — `LoadCurrentMapView` removed from `CollisionCheckOnLand` +### `LoadCurrentMapView` in `CollisionCheckOnLand` — why it's required -The previous session added `call LoadCurrentMapView` inside `CollisionCheckOnLand`, -called on every direction press. `wTileMap` is always current at that point (built -by `LoadWarpDestination` on map load, and by `AdvancePlayerSprite` on every -block-boundary crossing), so the call was redundant every idle frame. +`LoadCurrentMapView` rebuilds `wSurroundingTiles` from the block map AND copies a +sub-block-offset viewport into `wTileMap` based on `W_Y_BLOCK_COORD`/`W_X_BLOCK_COORD`. +`AdvancePlayerSprite` only calls it on block-boundary crossings. Between crossings +YBC/XBC can advance 0→1 without triggering a rebuild, leaving `wTileMap` at the +previous sub-block viewport offset. `GetTileInFrontOfPlayer` then reads the wrong tile. + +Symptom: walking toward a 2×2 cluster of impassable tiles (route 1 bushes, building +outer walls, ledges) sporadically passes through — at the half-block sub-step the +tile read lands on the adjacent passable tile instead of the correct one. The call is +retained in `CollisionCheckOnLand`. A future optimisation could split out just the +viewport-copy step (lines 1114–1135) since `wSurroundingTiles` is already current. ### Also in this commit diff --git a/dos_port/src/overworld/overworld.asm b/dos_port/src/overworld/overworld.asm index 41772d13..2b52c7d6 100644 --- a/dos_port/src/overworld/overworld.asm +++ b/dos_port/src/overworld/overworld.asm @@ -1369,6 +1369,11 @@ CollisionCheckOnLand: push eax push ecx push esi + ; wTileMap is a sub-block viewport into wSurroundingTiles, offset by W_Y_BLOCK_COORD / + ; W_X_BLOCK_COORD. AdvancePlayerSprite only calls LoadCurrentMapView on block-boundary + ; crossings, so the viewport can be stale within a block (YBC/XBC changed but wTileMap + ; not rebuilt). Rebuild here to apply the current sub-block offset before the tile read. + call LoadCurrentMapView call GetTileInFrontOfPlayer ; CL = tile in front call IsTilePassable ; CF = 1 if not passable pop esi