acdream/src/AcDream.Core
Erik e44d24cec6 fix(physics): L.2.3i — use FloorZ (not LandingZ) for OnWalkable test
Two parallel research agents converged on this bug. acdream's
ValidateTransition was setting OnWalkable based on `Normal.Z >= LandingZ`
(0.087, ~85° permissive) instead of `Normal.Z >= FloorZ` (0.664, ~49°
strict). Effect: a 60° roof slope (normal.Z = 0.5) was being marked
OnWalkable, letting the player walk freely up surfaces retail blocks.

Per retail PhysicsObj::is_valid_walkable
(acclient_2013_pseudo_c.txt:277180-277193) and ACE
PhysicsObj.cs:2861, the canonical "walkable" predicate is FloorZ.
LandingZ is the more permissive threshold used only in airborne→ground
transitions (Path 6 Collide handler) where we want to accept a brief
landing before the next frame's strict FloorZ check rejects the surface
and CliffSlide kicks in.

Three sites fixed:
1. Step-down branch's `zVal` initial value (was unconditional LandingZ;
   now `oi.GetWalkableZ()` returns FloorZ when OnWalkable, LandingZ
   otherwise — matches retail's transitional_insert step-down OK
   branch at acclient_2013_pseudo_c.txt:273258-273265).
2. ValidateTransition's live-contact OnWalkable test (LandingZ → FloorZ).
3. ValidateTransition's LastKnown-fallback OnWalkable test (LandingZ →
   FloorZ).

After this commit:
  - Walking horizontally INTO a 60° slope: step-up's WalkableAllowance
    is FloorZ (when OnWalkable), find_walkable rejects the slope's
    polygon, step-up fails, StepUpSlide. Player blocked from climbing.
  - Jumping ONTO a 60° roof: Path 6 still uses LandingZ (correct, we
    want to land), so the player lands. Next frame: ValidateTransition
    sees Normal.Z=0.5 < FloorZ → OnWalkable cleared. Player is Contact
    but not OnWalkable. Currently this leaves them STUCK on the roof
    (no CliffSlide yet to push them off). That's still better than
    walking up the roof.

Full slide-off-roof + edge-slide-along-balcony behaviors require
porting CliffSlide + PrecipiceSlide + adding Walkable polygon
reference — that's Phase L.4 (~12-20h, sketched out by both research
agents). This commit unblocks the worst of the steep-walk-up behavior
while the bigger port is being designed.

Test count 825/825 still pass. Build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 19:28:30 +02:00
..
Allegiance feat(allegiance): Phase H.2 AllegianceRequests + AllegianceTree model 2026-04-18 17:17:45 +02:00
Audio feat(audio): Phase E.2 OpenAL engine + SoundTable cookbook + hook wiring 2026-04-18 16:38:26 +02:00
Chat fix(chat): /help client-side handler + System dedup + ThatIsNotAValidCommand template 2026-04-25 21:22:07 +02:00
Combat feat(combat): Phase L.1c wire live attack input 2026-04-28 11:58:57 +02:00
Items feat(items): Phase F.2 ItemRepository + AppraiseRequest round-trip 2026-04-18 16:55:36 +02:00
Lighting feat(lighting): Phase G.2 — Setup.Lights + SetLightHook wiring 2026-04-19 10:46:49 +02:00
Meshing feat(vfx): Phase C.1 — PES particle renderer + post-review fixes 2026-04-28 22:47:11 +02:00
Physics fix(physics): L.2.3i — use FloorZ (not LandingZ) for OnWalkable test 2026-04-29 19:28:30 +02:00
Player feat(player): #6 fold enchantment buffs into vital max via EnchantmentMath 2026-04-25 17:55:15 +02:00
Plugins fix(movement+anim+session): clothing dedup, motion wire format, jump-skill default 2026-04-18 15:01:32 +02:00
Spells fix(player): EnchantmentMask bit fix + Vitae key=0 + absolute Vitals overlay 2026-04-25 18:15:20 +02:00
Terrain fix(terrain): align per-cell triangle geometry with ACE's ConstructPolygons convention 2026-04-21 13:20:59 +02:00
Textures feat(vfx): Phase C.1 — PES particle renderer + post-review fixes 2026-04-28 22:47:11 +02:00
Vfx feat(vfx): Phase C.1 — PES particle renderer + post-review fixes 2026-04-28 22:47:11 +02:00
World fix(scenery): drop non-retail extra-road-vertex suppression 2026-04-29 11:16:49 +02:00
AcDream.Core.csproj feat(vfx): Phase E.3 particle system + hook wiring + registry 2026-04-18 16:48:17 +02:00