From dd5834444e456680f420a4291b6b7a584cdbbb94 Mon Sep 17 00:00:00 2001
From: Mitchell Richters <mjr4077au@gmail.com>
Date: Mon, 21 Nov 2022 14:55:33 +1100
Subject: [PATCH] - Duke: Swap out the internals of the player's pos methods
 and get the game going again.

---
 source/games/duke/src/gameexec.cpp            |  2 +-
 source/games/duke/src/premap.cpp              | 12 ++---
 source/games/duke/src/savegame.cpp            |  5 +-
 source/games/duke/src/sounds.cpp              |  2 +-
 source/games/duke/src/types.h                 | 47 +++++++++----------
 source/games/duke/src/vmexports.cpp           |  1 -
 .../static/zscript/games/duke/actors/crane.zs |  6 +--
 wadsrc/static/zscript/games/duke/dukegame.zs  |  2 -
 8 files changed, 32 insertions(+), 45 deletions(-)

diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp
index 2ade95a01..f587cbdf8 100644
--- a/source/games/duke/src/gameexec.cpp
+++ b/source/games/duke/src/gameexec.cpp
@@ -1980,7 +1980,7 @@ int ParseState::parse(void)
 		break;
 	case concmd_larrybird:
 		insptr++;
-		ps[g_p].GetActor()->spr.pos.Z = ps[g_p].PlayerNowPosition.Z = ps[g_p].GetActor()->sector()->ceilingz;
+		ps[g_p].GetActor()->spr.pos.Z = ps[g_p].GetActor()->sector()->ceilingz;
 		break;
 	case concmd_destroyit:
 		insptr++;
diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp
index 1f1df86cd..71f0a5863 100644
--- a/source/games/duke/src/premap.cpp
+++ b/source/games/duke/src/premap.cpp
@@ -69,7 +69,7 @@ void pickrandomspot(int snum)
 		i = krand()%numplayersprites;
 	else i = snum;
 
-	p->posSet(po[i].opos);
+	p->GetActor()->spr.pos = po[i].opos;
 	p->backupxyz();
 	p->setbobpos();
 	p->angle.oang = p->angle.ang = po[i].oa;
@@ -505,14 +505,14 @@ void resetprestat(int snum,int g)
 //
 //---------------------------------------------------------------------------
 
-void resetpspritevars(int g)
+void resetpspritevars(int g, const DVector3& startpos)
 {
 	int i, j;
 	int circ;
 	int aimmode[MAXPLAYERS];
 	STATUSBARTYPE tsbar[MAXPLAYERS];
 
-	auto newActor = CreateActor(ps[0].cursector, ps[0].posGet(),
+	auto newActor = CreateActor(ps[0].cursector, startpos.plusZ(gs.playerheight),
 		TILE_APLAYER, 0, DVector2(0, 0), ps[0].angle.ang, 0., 0., nullptr, 10);
 
 	newActor->viewzoffset = -gs.playerheight;
@@ -625,10 +625,7 @@ void resetpspritevars(int g)
 			ps[j].frag_ps = j;
 			act->SetOwner(act);
 
-			ps[j].posSet(act->spr.pos);
-			ps[j].backupxyz();
 			ps[j].setbobpos();
-			act->backuppos();
 			ps[j].angle.oang = ps[j].angle.ang = act->spr.angle;
 
 			updatesector(act->spr.pos, &ps[j].cursector);
@@ -979,7 +976,6 @@ static int LoadTheMap(MapRecord *mi, player_struct*p, int gamemode)
 	SpawnSpriteDef sprites;
 	DVector3 pos;
 	loadMap(mi->fileName, isShareware(), &pos, &lbang, &sect, sprites);
-	p->posSet(pos);
 	p->cursector = sect;
 
 	SECRET_SetMapName(mi->DisplayName(), mi->name);
@@ -998,7 +994,7 @@ static int LoadTheMap(MapRecord *mi, player_struct*p, int gamemode)
 	SpawnPortals();
 
 	allignwarpelevators();
-	resetpspritevars(gamemode);
+	resetpspritevars(gamemode, pos);
 
 	if (isRR()) cacheit_r(); else cacheit_d();
 	return 0;
diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp
index afdd82a67..67da17942 100644
--- a/source/games/duke/src/savegame.cpp
+++ b/source/games/duke/src/savegame.cpp
@@ -76,10 +76,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
 {
 	if (arc.BeginObject(keyname))
 	{
-		arc("posx", w.posX())
-			("posy", w.posY())
-			("posz", w.PlayerNowPosition.Z)
-			("angle", w.angle)
+		arc("angle", w.angle)
 			("horizon", w.horizon)
 			.Array("gotweapon", w.gotweapon, MAX_WEAPONS)
 			("pals", w.pals)
diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp
index f171f9b06..491a6fec4 100644
--- a/source/games/duke/src/sounds.cpp
+++ b/source/games/duke/src/sounds.cpp
@@ -318,7 +318,7 @@ void S_GetCamera(DVector3* c, DAngle* ca, sectortype** cs)
 	if (ud.cameraactor == nullptr)
 	{
 		auto p = &ps[screenpeek];
-		if (c) *c = p->posGet();
+		if (c && p->GetActor()) *c = p->posGet();
 		if (cs) *cs = p->cursector;
 		if (ca) *ca = p->angle.ang;
 	}
diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h
index 9cc820676..768bd21c4 100644
--- a/source/games/duke/src/types.h
+++ b/source/games/duke/src/types.h
@@ -176,7 +176,6 @@ struct player_orig
 struct player_struct
 {
 	DVector3 vel;
-	DVector3 PlayerNowPosition, PlayerOldPosition;
 	DVector2 bobpos;
 	DVector2 fric;
 	DVector2 Exit;
@@ -333,103 +332,103 @@ struct player_struct
 
 	void backupxyz()
 	{
-		PlayerOldPosition = PlayerNowPosition;
+		GetActor()->opos = GetActor()->spr.pos;
 	}
 
 	void restorexyz()
 	{
-		PlayerNowPosition = PlayerOldPosition;
+		GetActor()->spr.pos = GetActor()->opos;
 	}
 
 	void backupxy()
 	{
-		PlayerOldPosition.X = PlayerNowPosition.X;
-		PlayerOldPosition.Y = PlayerNowPosition.Y;
+		GetActor()->opos.X = GetActor()->spr.pos.X;
+		GetActor()->opos.Y = GetActor()->spr.pos.Y;
 	}
 
 	void backupz()
 	{
-		PlayerOldPosition.Z = PlayerNowPosition.Z;
+		GetActor()->opos.Z = GetActor()->spr.pos.Z;
 	}
 
 	void setbobpos()
 	{
-		bobpos = PlayerNowPosition.XY();
+		bobpos = GetActor()->spr.pos.XY();
 	}
 
 
 	double& posX()
 	{
-		return PlayerNowPosition.X;
+		return GetActor()->spr.pos.X;
 	}
 	double& posY()
 	{
-		return PlayerNowPosition.Y;
+		return GetActor()->spr.pos.Y;
 	}
 	DVector2& posXY()
 	{
-		return PlayerNowPosition.XY();
+		return GetActor()->spr.pos.XY();
 	}
 
 	void posZset(const double val)
 	{
-		PlayerNowPosition.Z = val;
+		GetActor()->spr.pos.Z = val - GetActor()->viewzoffset;
 	}
 	void posZadd(const double val)
 	{
-		PlayerNowPosition.Z += val;
+		GetActor()->spr.pos.Z += val;
 	}
 	double posZget()
 	{
-		return PlayerNowPosition.Z;
+		return GetActor()->spr.pos.Z + GetActor()->viewzoffset;
 	}
 
 	void posSet(const DVector3& val)
 	{
-		PlayerNowPosition = val;
+		GetActor()->spr.pos = val.plusZ(-GetActor()->viewzoffset);
 	}
 	void posAdd(const DVector3& val)
 	{
-		PlayerNowPosition += val;
+		GetActor()->spr.pos += val;
 	}
 	void posAdd(const DVector2& val)
 	{
-		PlayerNowPosition.XY() += val;
+		GetActor()->spr.pos.XY() += val;
 	}
 	DVector3 posGet()
 	{
-		return PlayerNowPosition;
+		return GetActor()->spr.pos.plusZ(GetActor()->viewzoffset);
 	}
 
 	double& posoldX()
 	{
-		return PlayerOldPosition.X;
+		return GetActor()->opos.X;
 	}
 	double& posoldY()
 	{
-		return PlayerOldPosition.Y;
+		return GetActor()->opos.Y;
 	}
 	DVector2& posoldXY()
 	{
-		return PlayerOldPosition.XY();
+		return GetActor()->opos.XY();
 	}
 
 	void posoldZset(const double val)
 	{
-		PlayerOldPosition.Z = val;
+		GetActor()->opos.Z = val - GetActor()->viewzoffset;
 	}
 	double posoldZget()
 	{
-		return PlayerOldPosition.Z;
+		return GetActor()->opos.Z + GetActor()->viewzoffset;
 	}
 
 	void posoldAdd(const DVector3& val)
 	{
-		PlayerOldPosition += val;
+		GetActor()->opos += val;
 	}
 	DVector3 posoldGet()
 	{
-		return PlayerOldPosition;
+		return GetActor()->opos.plusZ(GetActor()->viewzoffset);
 	}
 };
 
diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp
index e97173d2b..686c63b5f 100644
--- a/source/games/duke/src/vmexports.cpp
+++ b/source/games/duke/src/vmexports.cpp
@@ -513,7 +513,6 @@ DEFINE_FIELD_X(DukePlayer, player_struct, loogcnt)
 DEFINE_FIELD_X(DukePlayer, player_struct, invdisptime)
 //DEFINE_FIELD_X(DukePlayer, player_struct, bobposx)
 //DEFINE_FIELD_X(DukePlayer, player_struct, bobposy)
-DEFINE_FIELD_X(DukePlayer, player_struct, PlayerNowPosition)
 DEFINE_FIELD_X(DukePlayer, player_struct, pyoff)
 DEFINE_FIELD_X(DukePlayer, player_struct, opyoff)
 //DEFINE_FIELD_X(DukePlayer, player_struct, posxv)
diff --git a/wadsrc/static/zscript/games/duke/actors/crane.zs b/wadsrc/static/zscript/games/duke/actors/crane.zs
index fbc847d9a..41e8cbb3e 100644
--- a/wadsrc/static/zscript/games/duke/actors/crane.zs
+++ b/wadsrc/static/zscript/games/duke/actors/crane.zs
@@ -235,10 +235,8 @@ class DukeCrane : DukeActor
 			else if (self.isactive)
 			{
 				let ang = p.angle();
-				p.backupxyz();
-				p.PlayerNowPosition.XY = self.pos.XY - CRANE_STEP * ang.ToVector();
-				p.PlayerNowPosition.Z = self.pos.Z + 2;
-				p.actor.SetPosition(p.PlayerNowPosition);
+				p.actor.backuppos();
+				p.actor.SetPosition((self.pos.XY - CRANE_STEP * ang.ToVector(), self.pos.Z + 2 - p.actor.viewzoffset));
 				p.cursector = p.actor.sector;
 			}
 		}
diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs
index 961a2f4ab..a578bc866 100644
--- a/wadsrc/static/zscript/games/duke/dukegame.zs
+++ b/wadsrc/static/zscript/games/duke/dukegame.zs
@@ -146,8 +146,6 @@ struct Duke native
 
 struct DukePlayer native
 {
-	native Vector3 PlayerNowPosition;
-
 	/*
 	// player's horizon and angle structs.
 	PlayerHorizon horizon;