exit logic corrected from in-game debugging: the leveldoor only sets g101-g105, the llama's script ends the level (material 16, exit cell, near the floor); stale floor record after a position jump explains the hover exit skip in jungle day 2
This commit is contained in:
1 parent
64259ea15b
commit
0568ae7f24
3 files changed
+82
-15
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 157 KiB |
@@ -173,6 +173,11 @@ stairs, platforms register as shadow casters (`solids`). 1.0 = texture colour
|
||||
|
||||
## Exit (LevelDoor) – how it works
|
||||
|
||||
> **Corrected 2026-11-07 (in game, Jungle Day 2):** the listing below was the first reading. The
|
||||
> LevelDoor only sets g101–g105 and checks global 0x21 *once*; the level is ended by the **Llama's
|
||||
> script** (material 16 + exit cell + at most ~0.6 above the floor). See "Exit via stale floor
|
||||
> material" further down and docs/reference/objects.md.
|
||||
|
||||
Strat bytecode (village, STPC 0x430332, 3 parameters, invisible, no model), decoded via the
|
||||
VM `FUN_0054d180` (opcode < 0x45: table 0x5796bc with 16-bit operand, otherwise 0x578ff4+op·4):
|
||||
```
|
||||
@@ -199,6 +204,46 @@ loop: if g21 == 3 ; game state "running"
|
||||
(zone teleport). t1l3m003: 2 of the 4 doors (cells 71,48/71,49) have no pad at all.
|
||||
* Second path (strat code at 0x4252aa, player logic [likely]): floor material 16 and cell =
|
||||
g104/g105 (set by the LevelDoor at start, Llama sets them to −1) → level change(g101..g103).
|
||||
|
||||
### Exit via stale floor material (hover + position jump, t1l4m002) – checked 2026-11-07
|
||||
|
||||
Speedrun video (position/hover hack): Kuzco hovers above a house-door stump, is moved to the exit and
|
||||
the level ends. Reproduced in game (apptest, gdb through `winedbg --gdb`, position written by gdb):
|
||||
* **Jungle Day chapter 2 = t1l4m002** (LNFO 95 coins / 2 secrets; tally "Dschungeltag Kapitel 2,
|
||||
0/95, 0/2"). LevelDoor at 44.5/25.5 (cell 44,25), params (1,4,3); RubyIdolDoor in the same
|
||||
cell. Cell 44,25 (tile 255) has material 16 **only in swap model 95** (pad x 44.67–45.0,
|
||||
z 25.25–25.75, y 2.25); main model 94 has none → with the door closed the exit cannot fire.
|
||||
House-door pads (material 16, main models) in cells 38,20 / 51,0 / 52,5 / 41,24 / 44,27 /
|
||||
50,27 / 41,29 / 57,55 / 41,38 / 41,44 plus swap pads in 22,21 / 26,21 / 23,23 / 50,1 / 43,21 /
|
||||
46,30 / 58,49 / 31,50; the zones pair them (e.g. 44,27 → 50.5/27.5, 50,27 → 44.5/27.5).
|
||||
* **Floor test (FUN_004036d0):** only tiles of the player's own cell; per upward polygon the plane
|
||||
height at (x,z) is compared with a probe point (y + 0.25, or y + (floor record +0x18)/2 with
|
||||
+0xe8 flag 0x200000 as for the llama);
|
||||
the **nearest floor below the probe wins, with no distance limit**. Material 17 is skipped for
|
||||
the llama (+0xe8 = 0x24882a, no 0x8000000). If nothing is below: for the llama (+0xe8 & 0x40000)
|
||||
material/height are **not** updated (stale) and x/z go back to the previous position.
|
||||
In game: llama held at 44.9/**6.0**/27.5 (3.7 above the pad of the stump at 44,27) → floor
|
||||
record h 2.30, **material 16**, tile 282 poly 15, every frame.
|
||||
* **Order per tick (FUN_0054c4a0):** all strat scripts (VM FUN_0054d180) first, then the
|
||||
collision pass (FUN_00403020 for every strat with +0xe8 & 0x8000). A position written after the
|
||||
collision pass is seen by the scripts of the next tick with the **old floor record**.
|
||||
In game: after hovering above the 44,27 pad, llama set to 44.5/2.3/25.5 right after its floor
|
||||
test → next event endLevel `FUN_0054d620` (called from the VM, floor record still 16), before
|
||||
any new floor test → tally (twice with screenshot, once traced). Control: same jump from normal
|
||||
ground (material 0) → no exit; jump written just *before* the floor test → record becomes 0, no exit.
|
||||
* **Who ends the level here: the Llama, not the LevelDoor.** LevelDoor bytecode: wait 5 ticks,
|
||||
g101..g105 = params + cell, then **once** `if global 0x21 != 3 → end` (so "g21 == 3" above is a
|
||||
one-time check, and global 0x21 is not the game state 0x5846e4), then the per-tick loop. In
|
||||
t1l4m002 the LevelDoor was gone from the strat list (scan of 0x6d9e38) while g101..g105 =
|
||||
1,4,3,44,25 and global 0x21 = 0. The Llama block at STPC 0x39ff4c–0x3a0064: if floorMaterial
|
||||
== 16 and health > 0 and (y < floorHeight + 0.6 and global 0x21 != 2, or y < floorHeight + 0.025
|
||||
and (g1 == 0 or global 0x23)): cell == (g104, g105) → level change(g101..g103), else fade-out +
|
||||
`getDoorPos` (op 0x100, zone teleport = house door) + `forceCollision`. The 0.6 limit is why
|
||||
hovering high above a house pad does not trigger the house teleport (bytecode; not separately
|
||||
tested), while landing at floor height in the exit cell with the stale record does.
|
||||
* Not explained: in two sessions with a moved player start (boot-to-level `start` 43.3/25.5) the
|
||||
same jump did not end the level (Llama script ran with record 16 in cell 44,25, no endLevel).
|
||||
* Images: `img/debug/exit-hover-trick.jpg` (top: video; bottom: our pool/door platform, tally).
|
||||
* Parameters in the originals: (1, world, chapter+1) = next chapter; in the last chapter of a
|
||||
world **(7,7,7)** = "world completed" → back to the selection map, unlock the next world.
|
||||
* `FUN_0054d620`: remembers the current level (0x585008..14), sets the next (0x584eb4/b8/bc), shows the
|
||||
|
||||
Reference in new issue
Block a user