From 9a17d335793546e53d4da385b95beb9e92eec85c Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Thu, 16 Mar 2023 22:15:11 +1100 Subject: [PATCH] - Duke: Ensure spawned player actor has view height baked in up until the first `getzrange()` call. * The original game spawning the player's sprite/actor would set the sprite's pos with the Z matching the player's, which had a height offset already applied. * This baked in height offset was carried through up until the `SetActor()` call in `processinput()`, where the original game would then strip off `gs.playerheight`. * This baked in height offset within the actor is critical on the first tic for pre-activated elevators on level spawn to function right, such as E1L2 and E2L3. * Properly setting the player actor's Z immediately after the initial `getzrange()` call, but before other functions like `movement()`, etc further down in `processinput()` is the best spot. * Fixes #870. --- source/games/duke/src/player_d.cpp | 9 ++++++++- source/games/duke/src/player_r.cpp | 16 ++++++++++------ source/games/duke/src/premap.cpp | 3 +-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 335e0e750..9a3969f30 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2620,6 +2620,13 @@ void processinput_d(int snum) shrunk = (pact->spr.scale.Y < 0.5); getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0); + if (!PlayClock) + { + pact->spr.pos.Z += gs.playerheight; + pact->opos.Z += gs.playerheight; + pact->oviewzoffset = pact->viewzoffset = -gs.playerheight; + } + p->truefz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); @@ -2910,7 +2917,7 @@ HORIZONLY: } // RBG*** - SetActor(pact, p->GetActor()->spr.pos); + SetActor(pact, pact->spr.pos); if (psectlotag < 3) { diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 59a0da549..d678c3bf7 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3235,22 +3235,26 @@ void processinput_r(int snum) p->spritebridge = 0; shrunk = (pact->spr.scale.Y < 0.125); - double tempfz; if (pact->clipdist == 16) { getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0); - tempfz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); } else { getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 0.25, CLIPMASK0); - tempfz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); } - p->truefz = tempfz; + if (!PlayClock) + { + pact->spr.pos.Z += gs.playerheight; + pact->opos.Z += gs.playerheight; + pact->oviewzoffset = pact->viewzoffset = -gs.playerheight; + } + + p->truefz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); - double truefdist = abs(p->GetActor()->getOffsetZ() - tempfz); + double truefdist = abs(p->GetActor()->getOffsetZ() - p->truefz); if (clz.type == kHitSector && psectlotag == 1 && truefdist > gs.playerheight + 16) psectlotag = 0; @@ -3700,7 +3704,7 @@ HORIZONLY: } // RBG*** - SetActor(pact, p->GetActor()->spr.pos); + SetActor(pact, pact->spr.pos); if (psectlotag == 800 && (!isRRRA() || !p->lotag800kill)) { diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index 91051c6d8..cf7b6d72f 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -503,11 +503,10 @@ void resetpspritevars(int g, const DVector3& startpos, const DAngle startang) int aimmode[MAXPLAYERS]; STATUSBARTYPE tsbar[MAXPLAYERS]; - auto newActor = CreateActor(ps[0].cursector, startpos.plusZ(gs.playerheight), + auto newActor = CreateActor(ps[0].cursector, startpos, TILE_APLAYER, 0, DVector2(0, 0), startang, 0., 0., nullptr, 10); newActor->spr.Angles.Pitch = DAngle::fromDeg(-17.354); - newActor->viewzoffset = -gs.playerheight; newActor->backuploc(); if (ud.recstat != 2) for (i = 0; i < MAXPLAYERS; i++)