From 452c82cbe2154eabe6b7d9519c603480f5013913 Mon Sep 17 00:00:00 2001
From: MajorCooke <paul.growney22@gmail.com>
Date: Thu, 17 Dec 2015 10:34:38 -0600
Subject: [PATCH 01/23] - Added TF_SENSITIVEZ to A_Teleport. Fail teleportation
 instead of adjusting the actor to fit if they cannot. - When checking whether
 to use spot z or floorz, use spot floorz instead of ref for consistency.

---
 src/thingdef/thingdef_codeptr.cpp  | 19 +++++++++++++++----
 wadsrc/static/actors/constants.txt |  1 +
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 89299e0fa..af40ed342 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -4261,6 +4261,7 @@ enum T_Flags
 	TF_USEACTORFOG =	0x00000100, // Use the actor's TeleFogSourceType and TeleFogDestType fogs.
 	TF_NOJUMP =			0x00000200, // Don't jump after teleporting.
 	TF_OVERRIDE =		0x00000400, // Ignore NOTELEPORT.
+	TF_SENSITIVEZ =		0x00000800, // Fail if the actor wouldn't fit in the position (for Z).
 };
 
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
@@ -4323,6 +4324,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 		return;
 	}
 
+	// [MC] By default, the function adjusts the actor's Z if it's below the floor or above the ceiling.
+	// This can be an issue as actors designed to maintain specific z positions wind up teleporting
+	// anyway when they should not, such as a floor rising above or ceiling lowering below the position
+	// of the spot.
+	if (Flags & TF_SENSITIVEZ)
+	{
+		fixed_t posz = (Flags & TF_USESPOTZ) ? spot->z : spot->floorz;
+		if ((posz + ref->height > spot->ceilingz) || (posz < spot->floorz))
+		{
+			ACTION_SET_RESULT(false);
+			return;
+		}
+	}
 	fixed_t prevX = ref->x;
 	fixed_t prevY = ref->y;
 	fixed_t prevZ = ref->z;
@@ -4378,10 +4392,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 			
 		}
 		
-		if (Flags & TF_USESPOTZ)
-			ref->z = spot->z;
-		else
-			ref->z = ref->floorz;
+		ref->z = (Flags & TF_USESPOTZ) ? spot->z : spot->floorz;
 
 		if (!(Flags & TF_KEEPANGLE))
 			ref->angle = spot->angle;
diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt
index 956ed119f..81a0c1b63 100644
--- a/wadsrc/static/actors/constants.txt
+++ b/wadsrc/static/actors/constants.txt
@@ -204,6 +204,7 @@ enum
 	TF_USEACTORFOG =	0x00000100, // Use the actor's TeleFogSourceType and TeleFogDestType fogs.
 	TF_NOJUMP =			0x00000200, // Don't jump after teleporting.
 	TF_OVERRIDE =		0x00000400, // Ignore NOTELEPORT.
+	TF_SENSITIVEZ =		0x00000800, // Fail if the actor wouldn't fit in the position (for Z).
 
 	TF_KEEPORIENTATION = TF_KEEPVELOCITY|TF_KEEPANGLE,
 	TF_NOFOG = TF_NOSRCFOG|TF_NODESTFOG,

From 9f78bcd1e6e29ca0cb32b382dd7f796b2ff25a51 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Tue, 19 Jan 2016 11:50:07 +0100
Subject: [PATCH 02/23] - Strife game code refactored for coordinates.

---
 src/actor.h                       |  9 ++++++
 src/g_shared/shared_hud.cpp       |  6 ++--
 src/g_shared/shared_sbar.cpp      |  3 +-
 src/g_strife/a_alienspectres.cpp  |  6 ++--
 src/g_strife/a_coin.cpp           |  8 ++---
 src/g_strife/a_crusader.cpp       | 12 +++----
 src/g_strife/a_entityboss.cpp     | 19 +++++------
 src/g_strife/a_inquisitor.cpp     | 20 ++++++------
 src/g_strife/a_loremaster.cpp     | 16 +++++-----
 src/g_strife/a_programmer.cpp     |  4 +--
 src/g_strife/a_rebels.cpp         |  6 ++--
 src/g_strife/a_sentinel.cpp       | 12 +++----
 src/g_strife/a_spectral.cpp       | 15 ++++-----
 src/g_strife/a_stalker.cpp        |  2 +-
 src/g_strife/a_strifestuff.cpp    |  6 ++--
 src/g_strife/a_strifeweapons.cpp  | 52 +++++++++++++++++--------------
 src/g_strife/a_thingstoblowup.cpp |  7 ++---
 src/p_writemap.cpp                |  4 +--
 src/r_plane.cpp                   | 11 ++++---
 src/r_things.cpp                  | 11 ++++---
 src/r_utility.cpp                 | 10 +++---
 21 files changed, 124 insertions(+), 115 deletions(-)

diff --git a/src/actor.h b/src/actor.h
index b371fdaee..52b746ef8 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1252,6 +1252,15 @@ public:
 		fixedvec3 ret = { X(), Y(), Z() };
 		return ret;
 	}
+	fixedvec3 InterpolatedPosition(fixed_t ticFrac) const
+	{
+		fixedvec3 ret;
+
+		ret.x = PrevX + FixedMul (ticFrac, X() - PrevX);
+		ret.y = PrevY + FixedMul (ticFrac, Y() - PrevY);
+		ret.z = PrevZ + FixedMul (ticFrac, Z() - PrevZ);
+		return ret;
+	}
 	fixedvec3 PosPlusZ(fixed_t zadd) const
 	{
 		fixedvec3 ret = { X(), Y(), Z() + zadd };
diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp
index b2f1184ea..0fe8a4588 100644
--- a/src/g_shared/shared_hud.cpp
+++ b/src/g_shared/shared_hud.cpp
@@ -826,9 +826,9 @@ static void DrawCoordinates(player_t * CPlayer)
 	
 	if (!map_point_coordinates || !automapactive) 
 	{
-		x=CPlayer->mo->x;
-		y=CPlayer->mo->y;                     
-		z=CPlayer->mo->z;
+		x=CPlayer->mo->X();
+		y=CPlayer->mo->Y();                     
+		z=CPlayer->mo->Z();
 	}
 	else 
 	{
diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp
index b74350633..b351212d0 100644
--- a/src/g_shared/shared_sbar.cpp
+++ b/src/g_shared/shared_sbar.cpp
@@ -1286,7 +1286,8 @@ void DBaseStatusBar::Draw (EHudState state)
 				y -= height * 2;
 		}
 
-		value = &CPlayer->mo->z;
+		fixedvec3 pos = CPlayer->mo->Pos();
+		value = &pos.z;
 		for (i = 2, value = &CPlayer->mo->z; i >= 0; y -= height, --value, --i)
 		{
 			mysnprintf (line, countof(line), "%c: %d", labels[i], *value >> FRACBITS);
diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp
index 2b9f499e9..c6339f33d 100644
--- a/src/g_strife/a_alienspectres.cpp
+++ b/src/g_strife/a_alienspectres.cpp
@@ -22,7 +22,7 @@ AActor *P_SpawnSubMissile (AActor *source, const PClass *type, AActor *target);
 
 DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall)
 {
-	AActor *foo = Spawn("AlienChunkSmall", self->x, self->y, self->z + 10*FRACUNIT, ALLOW_REPLACE);
+	AActor *foo = Spawn("AlienChunkSmall", self->PosPlusZ(10*FRACUNIT), ALLOW_REPLACE);
 
 	if (foo != NULL)
 	{
@@ -40,7 +40,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkSmall)
 
 DEFINE_ACTION_FUNCTION(AActor, A_SpectreChunkLarge)
 {
-	AActor *foo = Spawn("AlienChunkLarge", self->x, self->y, self->z + 10*FRACUNIT, ALLOW_REPLACE);
+	AActor *foo = Spawn("AlienChunkLarge", self->PosPlusZ(10*FRACUNIT), ALLOW_REPLACE);
 
 	if (foo != NULL)
 	{
@@ -62,7 +62,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Spectre3Attack)
 	if (self->target == NULL)
 		return;
 
-	AActor *foo = Spawn("SpectralLightningV2", self->x, self->y, self->z + 32*FRACUNIT, ALLOW_REPLACE);
+	AActor *foo = Spawn("SpectralLightningV2", self->PosPlusZ(32*FRACUNIT), ALLOW_REPLACE);
 
 	foo->velz = -12*FRACUNIT;
 	foo->target = self;
diff --git a/src/g_strife/a_coin.cpp b/src/g_strife/a_coin.cpp
index dd3610039..36b531001 100644
--- a/src/g_strife/a_coin.cpp
+++ b/src/g_strife/a_coin.cpp
@@ -80,22 +80,22 @@ AInventory *ACoin::CreateTossable ()
 	if (Amount >= 50)
 	{
 		Amount -= 50;
-		tossed = static_cast<ACoin*>(Spawn("Gold50", Owner->x, Owner->y, Owner->z, NO_REPLACE));
+		tossed = static_cast<ACoin*>(Spawn("Gold50", Owner->Pos(), NO_REPLACE));
 	}
 	else if (Amount >= 25)
 	{
 		Amount -= 25;
-		tossed = static_cast<ACoin*>(Spawn("Gold25", Owner->x, Owner->y, Owner->z, NO_REPLACE));
+		tossed = static_cast<ACoin*>(Spawn("Gold25", Owner->Pos(), NO_REPLACE));
 	}
 	else if (Amount >= 10)
 	{
 		Amount -= 10;
-		tossed = static_cast<ACoin*>(Spawn("Gold10", Owner->x, Owner->y, Owner->z, NO_REPLACE));
+		tossed = static_cast<ACoin*>(Spawn("Gold10", Owner->Pos(), NO_REPLACE));
 	}
 	else if (Amount > 1 || (ItemFlags & IF_KEEPDEPLETED))
 	{
 		Amount -= 1;
-		tossed = static_cast<ACoin*>(Spawn("Coin", Owner->x, Owner->y, Owner->z, NO_REPLACE));
+		tossed = static_cast<ACoin*>(Spawn("Coin", Owner->Pos(), NO_REPLACE));
 	}
 	else // Amount == 1 && !(ItemFlags & IF_KEEPDEPLETED)
 	{
diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp
index cf5f03a23..8655e10bc 100644
--- a/src/g_strife/a_crusader.cpp
+++ b/src/g_strife/a_crusader.cpp
@@ -27,18 +27,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose)
 	{
 		A_FaceTarget (self);
 		self->angle -= ANGLE_180/16;
-		P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
+		P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
 	}
 	else
 	{
 		if (P_CheckMissileRange (self))
 		{
 			A_FaceTarget (self);
-			P_SpawnMissileZAimed (self, self->z + 56*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
+			P_SpawnMissileZAimed (self, self->Z() + 56*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
 			self->angle -= ANGLE_45/32;
-			P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
+			P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
 			self->angle += ANGLE_45/16;
-			P_SpawnMissileZAimed (self, self->z + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
+			P_SpawnMissileZAimed (self, self->Z() + 40*FRACUNIT, self->target, PClass::FindClass("CrusaderMissile"));
 			self->angle -= ANGLE_45/16;
 			self->reactiontime += 15;
 		}
@@ -49,7 +49,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderChoose)
 DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft)
 {
 	self->angle += ANGLE_90/16;
-	AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
+	AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
 	if (misl != NULL)
 	{
 		misl->velz += FRACUNIT;
@@ -59,7 +59,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepLeft)
 DEFINE_ACTION_FUNCTION(AActor, A_CrusaderSweepRight)
 {
 	self->angle -= ANGLE_90/16;
-	AActor *misl = P_SpawnMissileZAimed (self, self->z + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
+	AActor *misl = P_SpawnMissileZAimed (self, self->Z() + 48*FRACUNIT, self->target, PClass::FindClass("FastFlameMissile"));
 	if (misl != NULL)
 	{
 		misl->velz += FRACUNIT;
diff --git a/src/g_strife/a_entityboss.cpp b/src/g_strife/a_entityboss.cpp
index fafb3b862..04b586b67 100644
--- a/src/g_strife/a_entityboss.cpp
+++ b/src/g_strife/a_entityboss.cpp
@@ -24,7 +24,7 @@ void A_SpectralMissile (AActor *self, const char *missilename)
 {
 	if (self->target != NULL)
 	{
-		AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, 
+		AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), 
 			self, self->target, PClass::FindClass(missilename), false);
 		if (missile != NULL)
 		{
@@ -70,7 +70,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityAttack)
 
 DEFINE_ACTION_FUNCTION(AActor, A_SpawnEntity)
 {
-	AActor *entity = Spawn("EntityBoss", self->x, self->y, self->z + 70*FRACUNIT, ALLOW_REPLACE);
+	AActor *entity = Spawn("EntityBoss", self->PosPlusZ(70*FRACUNIT), ALLOW_REPLACE);
 	if (entity != NULL)
 	{
 		entity->angle = self->angle;
@@ -89,13 +89,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath)
 	AActor *spot = self->tracer;
 	if (spot == NULL) spot = self;
 
-	fixed_t SpawnX = spot->x;
-	fixed_t SpawnY = spot->y;
-	fixed_t SpawnZ = spot->z + (self->tracer? 70*FRACUNIT : 0);
+	fixedvec3 pos = spot->Vec3Angle(secondRadius, self->angle, self->tracer? 70*FRACUNIT : 0);
 	
 	an = self->angle >> ANGLETOFINESHIFT;
-	second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]),
-		SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE);
+	second = Spawn("EntitySecond", pos, ALLOW_REPLACE);
 	second->CopyFriendliness(self, true);
 	//second->target = self->target;
 	A_FaceTarget (second);
@@ -103,18 +100,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_EntityDeath)
 	second->velx += FixedMul (finecosine[an], 320000);
 	second->vely += FixedMul (finesine[an], 320000);
 
+	pos = spot->Vec3Angle(secondRadius, self->angle + ANGLE_90, self->tracer? 70*FRACUNIT : 0);
 	an = (self->angle + ANGLE_90) >> ANGLETOFINESHIFT;
-	second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]),
-		SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE);
+	second = Spawn("EntitySecond", pos, ALLOW_REPLACE);
 	second->CopyFriendliness(self, true);
 	//second->target = self->target;
 	second->velx = FixedMul (secondRadius, finecosine[an]) << 2;
 	second->vely = FixedMul (secondRadius, finesine[an]) << 2;
 	A_FaceTarget (second);
 
+	pos = spot->Vec3Angle(secondRadius, self->angle - ANGLE_90, self->tracer? 70*FRACUNIT : 0);
 	an = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT;
-	second = Spawn("EntitySecond", SpawnX + FixedMul (secondRadius, finecosine[an]),
-		SpawnY + FixedMul (secondRadius, finesine[an]), SpawnZ, ALLOW_REPLACE);
+	second = Spawn("EntitySecond", pos, ALLOW_REPLACE);
 	second->CopyFriendliness(self, true);
 	//second->target = self->target;
 	second->velx = FixedMul (secondRadius, finecosine[an]) << 2;
diff --git a/src/g_strife/a_inquisitor.cpp b/src/g_strife/a_inquisitor.cpp
index 1a0739d36..b93933422 100644
--- a/src/g_strife/a_inquisitor.cpp
+++ b/src/g_strife/a_inquisitor.cpp
@@ -35,9 +35,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorDecide)
 	{
 		self->SetState (self->FindState("Grenade"));
 	}
-	if (self->target->z != self->z)
+	if (self->target->Z() != self->Z())
 	{
-		if (self->z + self->height + 54*FRACUNIT < self->ceilingz)
+		if (self->Top() + 54*FRACUNIT < self->ceilingz)
 		{
 			self->SetState (self->FindState("Jump"));
 		}
@@ -53,20 +53,20 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorAttack)
 
 	A_FaceTarget (self);
 
-	self->z += 32*FRACUNIT;
+	self->AddZ(32*FRACUNIT);
 	self->angle -= ANGLE_45/32;
-	proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot"));
+	proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindClass("InquisitorShot"));
 	if (proj != NULL)
 	{
 		proj->velz += 9*FRACUNIT;
 	}
 	self->angle += ANGLE_45/16;
-	proj = P_SpawnMissileZAimed (self, self->z, self->target, PClass::FindClass("InquisitorShot"));
+	proj = P_SpawnMissileZAimed (self, self->Z(), self->target, PClass::FindClass("InquisitorShot"));
 	if (proj != NULL)
 	{
 		proj->velz += 16*FRACUNIT;
 	}
-	self->z -= 32*FRACUNIT;
+	self->AddZ(-32*FRACUNIT);
 }
 
 DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump)
@@ -79,7 +79,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump)
 		return;
 
 	S_Sound (self, CHAN_ITEM|CHAN_LOOP, "inquisitor/jump", 1, ATTN_NORM);
-	self->z += 64*FRACUNIT;
+	self->AddZ(64*FRACUNIT);
 	A_FaceTarget (self);
 	an = self->angle >> ANGLETOFINESHIFT;
 	speed = self->Speed * 2/3;
@@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorJump)
 	{
 		dist = 1;
 	}
-	self->velz = (self->target->z - self->z) / dist;
+	self->velz = (self->target->Z() - self->Z()) / dist;
 	self->reactiontime = 60;
 	self->flags |= MF_NOGRAVITY;
 }
@@ -102,7 +102,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorCheckLand)
 	if (self->reactiontime < 0 ||
 		self->velx == 0 ||
 		self->vely == 0 ||
-		self->z <= self->floorz)
+		self->Z() <= self->floorz)
 	{
 		self->SetState (self->SeeState);
 		self->reactiontime = 0;
@@ -119,7 +119,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_InquisitorCheckLand)
 
 DEFINE_ACTION_FUNCTION(AActor, A_TossArm)
 {
-	AActor *foo = Spawn("InquisitorArm", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
+	AActor *foo = Spawn("InquisitorArm", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE);
 	foo->angle = self->angle - ANGLE_90 + (pr_inq.Random2() << 22);
 	foo->velx = FixedMul (foo->Speed, finecosine[foo->angle >> ANGLETOFINESHIFT]) >> 3;
 	foo->vely = FixedMul (foo->Speed, finesine[foo->angle >> ANGLETOFINESHIFT]) >> 3;
diff --git a/src/g_strife/a_loremaster.cpp b/src/g_strife/a_loremaster.cpp
index d984bbdd3..1b12c2436 100644
--- a/src/g_strife/a_loremaster.cpp
+++ b/src/g_strife/a_loremaster.cpp
@@ -21,16 +21,14 @@ IMPLEMENT_CLASS (ALoreShot)
 
 int ALoreShot::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
 {
-	FVector3 thrust;
 	
 	if (victim != NULL && target != NULL && !(victim->flags7 & MF7_DONTTHRUST))
 	{
-		thrust.X = float(target->x - victim->x);
-		thrust.Y = float(target->y - victim->y);
-		thrust.Z = float(target->z - victim->z);
-	
+		fixedvec3 fixthrust = victim->Vec3To(target);
+		TVector3<double> thrust(fixthrust.x, fixthrust.y, fixthrust.z);
+
 		thrust.MakeUnit();
-		thrust *= float((255*50*FRACUNIT) / (victim->Mass ? victim->Mass : 1));
+		thrust *= double((255*50*FRACUNIT) / (victim->Mass ? victim->Mass : 1));
 	
 		victim->velx += fixed_t(thrust.X);
 		victim->vely += fixed_t(thrust.Y);
@@ -42,7 +40,7 @@ int ALoreShot::DoSpecialDamage (AActor *victim, int damage, FName damagetype)
 DEFINE_ACTION_FUNCTION(AActor, A_LoremasterChain)
 {
 	S_Sound (self, CHAN_BODY, "loremaster/active", 1, ATTN_NORM);
-	Spawn("LoreShot2", self->x, self->y, self->z, ALLOW_REPLACE);
-	Spawn("LoreShot2", self->x - (self->velx >> 1), self->y - (self->vely >> 1), self->z - (self->velz >> 1), ALLOW_REPLACE);
-	Spawn("LoreShot2", self->x - self->velx, self->y - self->vely, self->z - self->velz, ALLOW_REPLACE);
+	Spawn("LoreShot2", self->Pos(), ALLOW_REPLACE);
+	Spawn("LoreShot2", self->Vec3Offset(-(self->velx >> 1), -(self->vely >> 1), -(self->velz >> 1)), ALLOW_REPLACE);
+	Spawn("LoreShot2", self->Vec3Offset(-self->velx, -self->vely, -self->velz), ALLOW_REPLACE);
 }
diff --git a/src/g_strife/a_programmer.cpp b/src/g_strife/a_programmer.cpp
index 78689468b..5835b3566 100644
--- a/src/g_strife/a_programmer.cpp
+++ b/src/g_strife/a_programmer.cpp
@@ -104,7 +104,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpotLightning)
 	if (self->target == NULL)
 		return;
 
-	spot = Spawn("SpectralLightningSpot", self->target->x, self->target->y, self->target->floorz, ALLOW_REPLACE);
+	spot = Spawn("SpectralLightningSpot", self->target->X(), self->target->Y(), self->target->floorz, ALLOW_REPLACE);
 	if (spot != NULL)
 	{
 		spot->threshold = 25;
@@ -122,7 +122,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpotLightning)
 
 DEFINE_ACTION_FUNCTION(AActor, A_SpawnProgrammerBase)
 {
-	AActor *foo = Spawn("ProgrammerBase", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
+	AActor *foo = Spawn("ProgrammerBase", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE);
 	if (foo != NULL)
 	{
 		foo->angle = self->angle + ANGLE_180 + (pr_prog.Random2() << 22);
diff --git a/src/g_strife/a_rebels.cpp b/src/g_strife/a_rebels.cpp
index 81490c361..6c8652f7c 100644
--- a/src/g_strife/a_rebels.cpp
+++ b/src/g_strife/a_rebels.cpp
@@ -75,8 +75,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
 	AActor *rebel;
 	angle_t an;
 
-	rebel = Spawn("Rebel1", self->x, self->y, self->floorz, ALLOW_REPLACE);
-	if (!P_TryMove (rebel, rebel->x, rebel->y, true))
+	rebel = Spawn("Rebel1", self->X(), self->Y(), self->floorz, ALLOW_REPLACE);
+	if (!P_TryMove (rebel, rebel->X(), rebel->Y(), true))
 	{
 		rebel->Destroy ();
 		return;
@@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
 	rebel->SetState (rebel->SeeState);
 	rebel->angle = self->angle;
 	an = self->angle >> ANGLETOFINESHIFT;
-	Spawn<ATeleportFog> (rebel->x + 20*finecosine[an], rebel->y + 20*finesine[an], rebel->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+	Spawn<ATeleportFog> (rebel->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE);
 	if (--self->health < 0)
 	{
 		self->SetState(self->FindState(NAME_Death));
diff --git a/src/g_strife/a_sentinel.cpp b/src/g_strife/a_sentinel.cpp
index 74f0e917f..550a89ff7 100644
--- a/src/g_strife/a_sentinel.cpp
+++ b/src/g_strife/a_sentinel.cpp
@@ -27,7 +27,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelBob)
 	{
 		minz = maxz;
 	}
-	if (minz < self->z)
+	if (minz < self->Z())
 	{
 		self->velz -= FRACUNIT;
 	}
@@ -35,7 +35,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelBob)
 	{
 		self->velz += FRACUNIT;
 	}
-	self->reactiontime = (minz >= self->z) ? 4 : 0;
+	self->reactiontime = (minz >= self->Z()) ? 4 : 0;
 }
 
 DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack)
@@ -48,16 +48,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack)
 		return;
 	}
 
-	missile = P_SpawnMissileZAimed (self, self->z + 32*FRACUNIT, self->target, PClass::FindClass("SentinelFX2"));
+	missile = P_SpawnMissileZAimed (self, self->Z() + 32*FRACUNIT, self->target, PClass::FindClass("SentinelFX2"));
 
 	if (missile != NULL && (missile->velx | missile->vely) != 0)
 	{
 		for (int i = 8; i > 1; --i)
 		{
 			trail = Spawn("SentinelFX1",
-				self->x + FixedMul (missile->radius * i, finecosine[missile->angle >> ANGLETOFINESHIFT]),
-				self->y + FixedMul (missile->radius * i, finesine[missile->angle >> ANGLETOFINESHIFT]),
-				missile->z + (missile->velz / 4 * i), ALLOW_REPLACE);
+				self->Vec3Angle(missile->radius*i, missile->angle, (missile->velz / 4 * i)), ALLOW_REPLACE);
 			if (trail != NULL)
 			{
 				trail->target = self;
@@ -67,7 +65,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack)
 				P_CheckMissileSpawn (trail, self->radius);
 			}
 		}
-		missile->z += missile->velz >> 2;
+		missile->AddZ(missile->velz >> 2);
 	}
 }
 
diff --git a/src/g_strife/a_spectral.cpp b/src/g_strife/a_spectral.cpp
index 6f80fe42c..91e43dba9 100644
--- a/src/g_strife/a_spectral.cpp
+++ b/src/g_strife/a_spectral.cpp
@@ -28,7 +28,7 @@ void ASpectralMonster::Touch (AActor *toucher)
 
 DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightningTail)
 {
-	AActor *foo = Spawn("SpectralLightningHTail", self->x - self->velx, self->y - self->vely, self->z, ALLOW_REPLACE);
+	AActor *foo = Spawn("SpectralLightningHTail", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);
 
 	foo->angle = self->angle;
 	foo->FriendPlayer = self->FriendPlayer;
@@ -61,17 +61,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning)
 	self->velx += pr_zap5.Random2(3) << FRACBITS;
 	self->vely += pr_zap5.Random2(3) << FRACBITS;
 
-	x = self->x + pr_zap5.Random2(3) * FRACUNIT * 50;
-	y = self->y + pr_zap5.Random2(3) * FRACUNIT * 50;
+	fixedvec2 pos = self->Vec2Offset(
+		pr_zap5.Random2(3) * FRACUNIT * 50,
+		pr_zap5.Random2(3) * FRACUNIT * 50);
 
 	flash = Spawn (self->threshold > 25 ? PClass::FindClass(NAME_SpectralLightningV2) :
-		PClass::FindClass(NAME_SpectralLightningV1), x, y, ONCEILINGZ, ALLOW_REPLACE);
+		PClass::FindClass(NAME_SpectralLightningV1), pos.x, pos.y, ONCEILINGZ, ALLOW_REPLACE);
 
 	flash->target = self->target;
 	flash->velz = -18*FRACUNIT;
 	flash->FriendPlayer = self->FriendPlayer;
 
-	flash = Spawn(NAME_SpectralLightningV2, self->x, self->y, ONCEILINGZ, ALLOW_REPLACE);
+	flash = Spawn(NAME_SpectralLightningV2, self->X(), self->Y(), ONCEILINGZ, ALLOW_REPLACE);
 
 	flash->target = self->target;
 	flash->velz = -18*FRACUNIT;
@@ -128,11 +129,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer2)
 		}
 		if (dest->height >= 56*FRACUNIT)
 		{
-			slope = (dest->z+40*FRACUNIT - self->z) / dist;
+			slope = (dest->Z()+40*FRACUNIT - self->Z()) / dist;
 		}
 		else
 		{
-			slope = (dest->z + self->height*2/3 - self->z) / dist;
+			slope = (dest->Z() + self->height*2/3 - self->Z()) / dist;
 		}
 		if (slope < self->velz)
 		{
diff --git a/src/g_strife/a_stalker.cpp b/src/g_strife/a_stalker.cpp
index 258cbef3f..6a06bf867 100644
--- a/src/g_strife/a_stalker.cpp
+++ b/src/g_strife/a_stalker.cpp
@@ -17,7 +17,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_StalkerChaseDecide)
 	{
 		self->SetState (self->FindState("SeeFloor"));
 	}
-	else if (self->ceilingz - self->height > self->z)
+	else if (self->ceilingz > self->Top())
 	{
 		self->SetState (self->FindState("Drop"));
 	}
diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp
index 9f3ebb272..3145290ef 100644
--- a/src/g_strife/a_strifestuff.cpp
+++ b/src/g_strife/a_strifestuff.cpp
@@ -580,7 +580,7 @@ IMPLEMENT_CLASS (AMeat)
 DEFINE_ACTION_FUNCTION(AActor, A_TossGib)
 {
 	const char *gibtype = (self->flags & MF_NOBLOOD) ? "Junk" : "Meat";
-	AActor *gib = Spawn (gibtype, self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
+	AActor *gib = Spawn (gibtype, self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE);
 	angle_t an;
 	int speed;
 
@@ -628,7 +628,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain)
 {
 	sector_t *sec = self->Sector;
 
-	if (self->z == sec->floorplane.ZatPoint(self))
+	if (self->Z() == sec->floorplane.ZatPoint(self))
 	{
 		if (sec->special == Damage_InstantDeath)
 		{
@@ -681,7 +681,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns)
 
 DEFINE_ACTION_FUNCTION(AActor, A_DropFire)
 {
-	AActor *drop = Spawn("FireDroplet", self->x, self->y, self->z + 24*FRACUNIT, ALLOW_REPLACE);
+	AActor *drop = Spawn("FireDroplet", self->PosPlusZ(24*FRACUNIT), ALLOW_REPLACE);
 	drop->velz = -FRACUNIT;
 	P_RadiusAttack (self, self, 64, 64, NAME_Fire, 0);
 }
diff --git a/src/g_strife/a_strifeweapons.cpp b/src/g_strife/a_strifeweapons.cpp
index f5d4a3576..a33521087 100644
--- a/src/g_strife/a_strifeweapons.cpp
+++ b/src/g_strife/a_strifeweapons.cpp
@@ -360,8 +360,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_RocketInFlight)
 	AActor *trail;
 
 	S_Sound (self, CHAN_VOICE, "misc/missileinflight", 1, ATTN_NORM);
-	P_SpawnPuff (self, PClass::FindClass("MiniMissilePuff"), self->x, self->y, self->z, self->angle - ANGLE_180, 2, PF_HITTHING);
-	trail = Spawn("RocketTrail", self->x - self->velx, self->y - self->vely, self->z, ALLOW_REPLACE);
+	P_SpawnPuff (self, PClass::FindClass("MiniMissilePuff"), self->Pos(), self->angle - ANGLE_180, 2, PF_HITTHING);
+	trail = Spawn("RocketTrail", self->Vec3Offset(-self->velx, -self->vely, 0), ALLOW_REPLACE);
 	if (trail != NULL)
 	{
 		trail->velz = FRACUNIT;
@@ -516,10 +516,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave)
 	self->angle += ANGLE_180;
 
 	// If the torpedo hit the ceiling, it should still spawn the wave
-	savedz = self->z;
-	if (wavedef && self->ceilingz - self->z < wavedef->height)
+	savedz = self->Z();
+	if (wavedef && self->ceilingz - self->Z() < wavedef->height)
 	{
-		self->z = self->ceilingz - wavedef->height;
+		self->SetZ(self->ceilingz - wavedef->height);
 	}
 
 	for (int i = 0; i < 80; ++i)
@@ -527,12 +527,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaulerTorpedoWave)
 		self->angle += ANGLE_45/10;
 		P_SpawnSubMissile (self, PClass::FindClass("MaulerTorpedoWave"), self->target);
 	}
-	self->z = savedz;
+	self->SetZ(savedz);
 }
 
 AActor *P_SpawnSubMissile (AActor *source, const PClass *type, AActor *target)
 {
-	AActor *other = Spawn (type, source->x, source->y, source->z, ALLOW_REPLACE);
+	AActor *other = Spawn (type, source->Pos(), ALLOW_REPLACE);
 
 	if (other == NULL)
 	{
@@ -619,20 +619,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_Burnination)
 			yofs = -yofs;
 		}
 
-		fixed_t x = self->x + (xofs << FRACBITS);
-		fixed_t y = self->y + (yofs << FRACBITS);
-		sector_t * sector = P_PointInSector(x, y);
+		fixedvec2 pos = self->Vec2Offset(xofs << FRACBITS, yofs << FRACBITS);
+		sector_t * sector = P_PointInSector(pos.x, pos.y);
 
 		// The sector's floor is too high so spawn the flame elsewhere.
-		if (sector->floorplane.ZatPoint(x, y) > self->z + self->MaxStepHeight)
+		if (sector->floorplane.ZatPoint(pos.x, pos.y) > self->Z() + self->MaxStepHeight)
 		{
-			x = self->x;
-			y = self->y;
+			pos.x = self->X();
+			pos.y = self->Y();
 		}
 
 		AActor *drop = Spawn<APhosphorousFire> (
-			x, y,
-			self->z + 4*FRACUNIT, ALLOW_REPLACE);
+			pos.x, pos.y,
+			self->Z() + 4*FRACUNIT, ALLOW_REPLACE);
 		if (drop != NULL)
 		{
 			drop->velx = self->velx + ((pr_phburn.Random2 (7)) << FRACBITS);
@@ -677,9 +676,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade)
 
 	if (grenadetype != NULL)
 	{
-		self->z += 32*FRACUNIT;
+		self->AddZ(32*FRACUNIT);
 		grenade = P_SpawnSubMissile (self, grenadetype, self);
-		self->z -= 32*FRACUNIT;
+		self->AddZ(-32*FRACUNIT);
 		if (grenade == NULL)
 			return;
 
@@ -690,15 +689,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade)
 
 		grenade->velz = FixedMul (finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)], grenade->Speed) + 8*FRACUNIT;
 
+		fixedvec2 offset;
+
 		an = self->angle >> ANGLETOFINESHIFT;
 		tworadii = self->radius + grenade->radius;
-		grenade->x += FixedMul (finecosine[an], tworadii);
-		grenade->y += FixedMul (finesine[an], tworadii);
+		offset.x = FixedMul (finecosine[an], tworadii);
+		offset.y = FixedMul (finesine[an], tworadii);
 
 		an = self->angle + Angle;
 		an >>= ANGLETOFINESHIFT;
-		grenade->x += FixedMul (finecosine[an], 15*FRACUNIT);
-		grenade->y += FixedMul (finesine[an], 15*FRACUNIT);
+		offset.x += FixedMul (finecosine[an], 15*FRACUNIT);
+		offset.y += FixedMul (finesine[an], 15*FRACUNIT);
+
+		fixedvec2 newpos = grenade->Vec2Offset(offset.x, offset.y);
+		grenade->SetOrigin(newpos.x, newpos.y, grenade->Z(), false);
 	}
 }
 
@@ -923,7 +927,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1)
 	P_BulletSlope (self, &linetarget);
 	if (linetarget != NULL)
 	{
-		spot = Spawn("SpectralLightningSpot", linetarget->x, linetarget->y, linetarget->floorz, ALLOW_REPLACE);
+		spot = Spawn("SpectralLightningSpot", linetarget->X(), linetarget->Y(), linetarget->floorz, ALLOW_REPLACE);
 		if (spot != NULL)
 		{
 			spot->tracer = linetarget;
@@ -931,7 +935,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil1)
 	}
 	else
 	{
-		spot = Spawn("SpectralLightningSpot", self->x, self->y, self->z, ALLOW_REPLACE);
+		spot = Spawn("SpectralLightningSpot", self->Pos(), ALLOW_REPLACE);
 		if (spot != NULL)
 		{
 			spot->velx += 28 * finecosine[self->angle >> ANGLETOFINESHIFT];
@@ -989,7 +993,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireSigil3)
 		spot = P_SpawnSubMissile (self, PClass::FindClass("SpectralLightningBall1"), self);
 		if (spot != NULL)
 		{
-			spot->z = self->z + 32*FRACUNIT;
+			spot->SetZ(self->Z() + 32*FRACUNIT);
 		}
 	}
 	self->angle -= (ANGLE_180/20)*10;
diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp
index d27260451..86ae7282e 100644
--- a/src/g_strife/a_thingstoblowup.cpp
+++ b/src/g_strife/a_thingstoblowup.cpp
@@ -20,10 +20,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
 {
 	fixed_t spawnx, spawny;
 
-	spawnx = self->x + (pr_bang4cloud.Random2() & 3) * 10240;
-	spawny = self->y + (pr_bang4cloud.Random2() & 3) * 10240;
+	fixedvec3 pos = self->Vec3Offset((pr_bang4cloud.Random2() & 3) * 10240, (pr_bang4cloud.Random2() & 3) * 10240, 0);
 
-	Spawn("Bang4Cloud", spawnx, spawny, self->z, ALLOW_REPLACE);
+	Spawn("Bang4Cloud", pos, ALLOW_REPLACE);
 }
 
 // -------------------------------------------------------------------
@@ -97,7 +96,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightGoesOut)
 
 	for (int i = 0; i < 8; ++i)
 	{
-		foo = Spawn("Rubble1", self->x, self->y, self->z, ALLOW_REPLACE);
+		foo = Spawn("Rubble1", self->Pos(), ALLOW_REPLACE);
 		if (foo != NULL)
 		{
 			int t = pr_lightout() & 15;
diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp
index e31d2c4c3..8f1a4edfa 100644
--- a/src/p_writemap.cpp
+++ b/src/p_writemap.cpp
@@ -98,8 +98,8 @@ static int WriteTHINGS (FILE *file)
 	mapthinghexen_t mt = { 0, 0, 0, 0, 0, 0, 0, 0, {0} };
 	AActor *mo = players[consoleplayer].mo;
 
-	mt.x = LittleShort(short(mo->x >> FRACBITS));
-	mt.y = LittleShort(short(mo->y >> FRACBITS));
+	mt.x = LittleShort(short(mo->X() >> FRACBITS));
+	mt.y = LittleShort(short(mo->Y() >> FRACBITS));
 	mt.angle = LittleShort(short(MulScale32 (mo->angle >> ANGLETOFINESHIFT, 360)));
 	mt.type = LittleShort((short)1);
 	mt.flags = LittleShort((short)(7|224|MTF_SINGLE));
diff --git a/src/r_plane.cpp b/src/r_plane.cpp
index 96a77930a..84967c164 100644
--- a/src/r_plane.cpp
+++ b/src/r_plane.cpp
@@ -1224,9 +1224,10 @@ void R_DrawSkyBoxes ()
 			extralight = 0;
 			R_SetVisibility (sky->args[0] * 0.25f);
 
-			viewx = sky->PrevX + FixedMul(r_TicFrac, sky->x - sky->PrevX);
-			viewy = sky->PrevY + FixedMul(r_TicFrac, sky->y - sky->PrevY);
-			viewz = sky->PrevZ + FixedMul(r_TicFrac, sky->z - sky->PrevZ);
+			fixedvec3 viewpos = sky->InterpolatedPosition(r_TicFrac);
+			viewx = viewpos.x;
+			viewy = viewpos.y;
+			viewz = viewpos.z;
 			viewangle = savedangle + sky->PrevAngle + FixedMul(r_TicFrac, sky->angle - sky->PrevAngle);
 
 			R_CopyStackedViewParameters();
@@ -1235,8 +1236,8 @@ void R_DrawSkyBoxes ()
 		{
 			extralight = pl->extralight;
 			R_SetVisibility (pl->visibility);
-			viewx = pl->viewx - sky->Mate->x + sky->x;
-			viewy = pl->viewy - sky->Mate->y + sky->y;
+			viewx = pl->viewx - sky->Mate->X() + sky->X();
+			viewy = pl->viewy - sky->Mate->Y() + sky->Y();
 			viewz = pl->viewz;
 			viewangle = pl->viewangle;
 		}
diff --git a/src/r_things.cpp b/src/r_things.cpp
index 8e53fb6d1..8ad5f76a9 100644
--- a/src/r_things.cpp
+++ b/src/r_things.cpp
@@ -670,9 +670,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
 	}
 
 	// [RH] Interpolate the sprite's position to make it look smooth
-	fx = thing->PrevX + FixedMul (r_TicFrac, thing->x - thing->PrevX);
-	fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY);
-	fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac);
+	fixedvec3 pos = thing->InterpolatedPosition(r_TicFrac);
+	fx = pos.x;
+	fy = pos.y;
+	fz = pos.z +thing->GetBobOffset(r_TicFrac);
 
 	tex = NULL;
 	voxel = NULL;
@@ -1145,12 +1146,12 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
 			{
 				if(!(rover->top.plane->a) && !(rover->top.plane->b))
 				{
-					if(rover->top.plane->Zat0() <= thing->z) fakefloor = rover;
+					if(rover->top.plane->Zat0() <= thing->Z()) fakefloor = rover;
 				}
 			}
 			if(!(rover->bottom.plane->a) && !(rover->bottom.plane->b))
 			{
-				if(rover->bottom.plane->Zat0() >= thing->z + thing->height) fakeceiling = rover;
+				if(rover->bottom.plane->Zat0() >= thing->Top()) fakeceiling = rover;
 			}
 		}	
 		R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling);
diff --git a/src/r_utility.cpp b/src/r_utility.cpp
index cfe1767c7..d4d3ec97b 100644
--- a/src/r_utility.cpp
+++ b/src/r_utility.cpp
@@ -587,8 +587,8 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi
 		player - players == consoleplayer &&
 		camera == player->mo &&
 		!demoplayback &&
-		iview->nviewx == camera->x &&
-		iview->nviewy == camera->y && 
+		iview->nviewx == camera->X() &&
+		iview->nviewy == camera->Y() && 
 		!(player->cheats & (CF_TOTALLYFROZEN|CF_FROZEN)) &&
 		player->playerstate == PST_LIVE &&
 		player->mo->reactiontime == 0 &&
@@ -839,9 +839,9 @@ void R_SetupFrame (AActor *actor)
 	}
 	else
 	{
-		iview->nviewx = camera->x;
-		iview->nviewy = camera->y;
-		iview->nviewz = camera->player ? camera->player->viewz : camera->z + camera->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight);
+		iview->nviewx = camera->X();
+		iview->nviewy = camera->Y();
+		iview->nviewz = camera->player ? camera->player->viewz : camera->Z() + camera->GetClass()->Meta.GetMetaFixed(AMETA_CameraHeight);
 		viewsector = camera->Sector;
 		r_showviewer = false;
 	}

From 27aeb6a656958d30c5dd4dc4bcb749b7ee7a16a0 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Tue, 19 Jan 2016 13:26:05 +0100
Subject: [PATCH 03/23] - g_shared refactored

---
 src/g_shared/a_action.cpp         | 15 ++++---
 src/g_shared/a_artifacts.cpp      |  6 +--
 src/g_shared/a_bridge.cpp         | 12 ++----
 src/g_shared/a_camera.cpp         |  9 ++---
 src/g_shared/a_debris.cpp         |  7 +---
 src/g_shared/a_decals.cpp         | 10 ++---
 src/g_shared/a_fastprojectile.cpp | 30 +++++++-------
 src/g_shared/a_morph.cpp          | 16 ++++----
 src/g_shared/a_movingcamera.cpp   | 65 ++++++++++++++++---------------
 src/g_shared/a_pickups.cpp        | 38 +++++++++---------
 src/g_shared/a_quake.cpp          |  2 +-
 src/g_shared/a_randomspawner.cpp  | 12 +++---
 src/g_shared/a_spark.cpp          |  2 +-
 src/g_shared/a_specialspot.cpp    |  6 +--
 src/g_shared/shared_sbar.cpp      |  3 +-
 15 files changed, 111 insertions(+), 122 deletions(-)

diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp
index 1149bc2c3..29f24b47e 100644
--- a/src/g_shared/a_action.cpp
+++ b/src/g_shared/a_action.cpp
@@ -262,14 +262,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
 	i = (pr_freeze.Random2()) % (numChunks/4);
 	for (i = MAX (24, numChunks + i); i >= 0; i--)
 	{
-		mo = Spawn("IceChunk", 
-			self->x + (((pr_freeze()-128)*self->radius)>>7), 
-			self->y + (((pr_freeze()-128)*self->radius)>>7), 
-			self->z + (pr_freeze()*self->height/255), ALLOW_REPLACE);
+		mo = Spawn("IceChunk", self->Vec3Offset(
+			(((pr_freeze()-128)*self->radius)>>7), 
+			(((pr_freeze()-128)*self->radius)>>7), 
+			(pr_freeze()*self->height/255)), ALLOW_REPLACE);
 		if (mo)
 		{
 				mo->SetState (mo->SpawnState + (pr_freeze()%3));
-			mo->velz = FixedDiv(mo->z - self->z, self->height)<<2;
+			mo->velz = FixedDiv(mo->Z() - self->Z(), self->height)<<2;
 			mo->velx = pr_freeze.Random2 () << (FRACBITS-7);
 			mo->vely = pr_freeze.Random2 () << (FRACBITS-7);
 			CALL_ACTION(A_IceSetTics, mo); // set a random tic wait
@@ -279,11 +279,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
 	}
 	if (self->player)
 	{ // attach the player's view to a chunk of ice
-		AActor *head = Spawn("IceChunkHead", self->x, self->y, 
-													self->z + self->player->mo->ViewHeight, ALLOW_REPLACE);
+		AActor *head = Spawn("IceChunkHead", self->PosPlusZ(self->player->mo->ViewHeight), ALLOW_REPLACE);
 		if (head != NULL)
 		{
-			head->velz = FixedDiv(head->z - self->z, self->height)<<2;
+			head->velz = FixedDiv(head->Z() - self->Z(), self->height)<<2;
 			head->velx = pr_freeze.Random2 () << (FRACBITS-7);
 			head->vely = pr_freeze.Random2 () << (FRACBITS-7);
 			head->health = self->health;
diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp
index 2be2e179d..faa5392b7 100644
--- a/src/g_shared/a_artifacts.cpp
+++ b/src/g_shared/a_artifacts.cpp
@@ -965,7 +965,7 @@ void APowerFlight::InitEffect ()
 	Super::InitEffect();
 	Owner->flags2 |= MF2_FLY;
 	Owner->flags |= MF_NOGRAVITY;
-	if (Owner->z <= Owner->floorz)
+	if (Owner->Z() <= Owner->floorz)
 	{
 		Owner->velz = 4*FRACUNIT;	// thrust the player in the air a bit
 	}
@@ -1012,7 +1012,7 @@ void APowerFlight::EndEffect ()
 
 	if (!(Owner->flags7 & MF7_FLYCHEAT))
 	{
-		if (Owner->z != Owner->floorz)
+		if (Owner->Z() != Owner->floorz)
 		{
 			Owner->player->centering = true;
 		}
@@ -1250,7 +1250,7 @@ void APowerSpeed::DoEffect ()
 	if (P_AproxDistance (Owner->velx, Owner->vely) <= 12*FRACUNIT)
 		return;
 
-	AActor *speedMo = Spawn<APlayerSpeedTrail> (Owner->x, Owner->y, Owner->z, NO_REPLACE);
+	AActor *speedMo = Spawn<APlayerSpeedTrail> (Owner->Pos(), NO_REPLACE);
 	if (speedMo)
 	{
 		speedMo->angle = Owner->angle;
diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp
index 4caa56287..eed95d8d2 100644
--- a/src/g_shared/a_bridge.cpp
+++ b/src/g_shared/a_bridge.cpp
@@ -110,9 +110,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit)
 	if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / (100 * FRACUNIT));
 
 	self->angle += rotationspeed;
-	self->x = self->target->x + rotationradius * finecosine[self->angle >> ANGLETOFINESHIFT];
-	self->y = self->target->y + rotationradius * finesine[self->angle >> ANGLETOFINESHIFT];
-	self->z = self->target->z;
+	self->SetOrigin(self->target->Vec3Angle(rotationradius, self->angle, 0), true);
+	self->floorz = self->target->floorz;
+	self->ceilingz = self->target->ceilingz;
 }
 
 
@@ -120,16 +120,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
 {
 	angle_t startangle;
 	AActor *ball;
-	fixed_t cx, cy, cz;
 
 	ACTION_PARAM_START(1);
 	ACTION_PARAM_CLASS(balltype, 0);
 
 	if (balltype == NULL) balltype = PClass::FindClass("BridgeBall");
 
-	cx = self->x;
-	cy = self->y;
-	cz = self->z;
 	startangle = pr_orbit() << 24;
 
 	// Spawn triad into world -- may be more than a triad now.
@@ -137,7 +133,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BridgeInit)
 
 	for (int i = 0; i < ballcount; i++)
 	{
-		ball = Spawn(balltype, cx, cy, cz, ALLOW_REPLACE);
+		ball = Spawn(balltype, self->Pos(), ALLOW_REPLACE);
 		ball->angle = startangle + (ANGLE_45/32) * (256/ballcount) * i;
 		ball->target = self;
 		CALL_ACTION(A_BridgeOrbit, ball);
diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp
index 24363851e..61a155ea7 100644
--- a/src/g_shared/a_camera.cpp
+++ b/src/g_shared/a_camera.cpp
@@ -176,11 +176,10 @@ void AAimingCamera::Tick ()
 		}
 		if (MaxPitchChange)
 		{ // Aim camera's pitch; use floats for precision
-			float dx = FIXED2FLOAT(x - tracer->x);
-			float dy = FIXED2FLOAT(y - tracer->y);
-			float dz = FIXED2FLOAT(z - tracer->z - tracer->height/2);
-			float dist = (float)sqrt (dx*dx + dy*dy);
-			float ang = dist != 0.f ? (float)atan2 (dz, dist) : 0;
+			TVector2<double> vect = tracer->Vec2To(this);
+			double dz = FIXED2DBL(Z() - tracer->Z() - tracer->height/2);
+			double dist = vect.Length();
+			double ang = dist != 0.f ? atan2 (dz, dist) : 0;
 			int desiredpitch = (angle_t)(ang * 2147483648.f / PI);
 			if (abs (desiredpitch - pitch) < MaxPitchChange)
 			{
diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp
index e6fc79b0a..3b34a0d8a 100644
--- a/src/g_shared/a_debris.cpp
+++ b/src/g_shared/a_debris.cpp
@@ -36,17 +36,14 @@ void P_SpawnDirt (AActor *actor, fixed_t radius)
 	AActor *mo;
 	angle_t angle;
 
-	angle = pr_dirt()<<5;		// <<24 >>19
-	x = actor->x + FixedMul(radius,finecosine[angle]);
-	y = actor->y + FixedMul(radius,finesine[angle]);
-	z = actor->z + (pr_dirt()<<9) + FRACUNIT;
+	fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, (pr_dirt() << 9) + FRACUNIT);
 
 	char fmt[8];
 	mysnprintf(fmt, countof(fmt), "Dirt%d", 1 + pr_dirt()%6);
 	dtype = PClass::FindClass(fmt);
 	if (dtype)
 	{
-		mo = Spawn (dtype, x, y, z, ALLOW_REPLACE);
+		mo = Spawn (dtype, pos, ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->velz = pr_dirt()<<10;
diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp
index 29fcbf8cb..64921d647 100644
--- a/src/g_shared/a_decals.cpp
+++ b/src/g_shared/a_decals.cpp
@@ -91,7 +91,7 @@ DBaseDecal::DBaseDecal (int statnum, fixed_t z)
 
 DBaseDecal::DBaseDecal (const AActor *basis)
 : DThinker(STAT_DECAL),
-  WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->z), ScaleX(basis->scaleX), ScaleY(basis->scaleY),
+  WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->Z()), ScaleX(basis->scaleX), ScaleY(basis->scaleY),
   Alpha(basis->alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum),
   RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle)
 {
@@ -817,22 +817,22 @@ void ADecal::BeginPlay ()
 	{
 		if (!tpl->PicNum.Exists())
 		{
-			Printf("Decal actor at (%d,%d) does not have a valid texture\n", x>>FRACBITS, y>>FRACBITS);
+			Printf("Decal actor at (%d,%d) does not have a valid texture\n", X()>>FRACBITS, Y()>>FRACBITS);
 		}
 		else
 		{
 			// Look for a wall within 64 units behind the actor. If none can be
 			// found, then no decal is created, and this actor is destroyed
 			// without effectively doing anything.
-			if (NULL == ShootDecal(tpl, this, Sector, x, y, z, angle + ANGLE_180, 64*FRACUNIT, true))
+			if (NULL == ShootDecal(tpl, this, Sector, X(), Y(), Z(), angle + ANGLE_180, 64*FRACUNIT, true))
 			{
-				DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", x>>FRACBITS, y>>FRACBITS);
+				DPrintf ("Could not find a wall to stick decal to at (%d,%d)\n", X()>>FRACBITS, Y()>>FRACBITS);
 			}
 		}
 	}
 	else
 	{
-		DPrintf ("Decal actor at (%d,%d) does not have a good template\n", x>>FRACBITS, y>>FRACBITS);
+		DPrintf ("Decal actor at (%d,%d) does not have a good template\n", X()>>FRACBITS, Y()>>FRACBITS);
 	}
 	// This actor doesn't need to stick around anymore.
 	Destroy();
diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp
index c019fcbf6..ae7f6a58b 100644
--- a/src/g_shared/a_fastprojectile.cpp
+++ b/src/g_shared/a_fastprojectile.cpp
@@ -25,10 +25,10 @@ void AFastProjectile::Tick ()
 	fixed_t zfrac;
 	int changexy;
 
-	PrevX = x;
-	PrevY = y;
-	PrevZ = z;
-	fixed_t oldz = z;
+	PrevX = X();
+	PrevY = Y();
+	PrevZ = Z();
+	fixed_t oldz = Z();
 	PrevAngle = angle;
 
 	if (!(flags5 & MF5_NOTIMEFREEZE))
@@ -57,7 +57,7 @@ void AFastProjectile::Tick ()
 	}
 
 	// Handle movement
-	if (velx || vely || (z != floorz) || velz)
+	if (velx || vely || (Z() != floorz) || velz)
 	{
 		xfrac = velx >> shift;
 		yfrac = vely >> shift;
@@ -73,14 +73,14 @@ void AFastProjectile::Tick ()
 					tm.LastRipped = NULL;	// [RH] Do rip damage each step, like Hexen
 				}
 				
-				if (!P_TryMove (this, x + xfrac,y + yfrac, true, NULL, tm))
+				if (!P_TryMove (this, X() + xfrac,Y() + yfrac, true, NULL, tm))
 				{ // Blocked move
 					if (!(flags3 & MF3_SKYEXPLODE))
 					{
 						if (tm.ceilingline &&
 							tm.ceilingline->backsector &&
 							tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum &&
-							z >= tm.ceilingline->backsector->ceilingplane.ZatPoint (x, y))
+							Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint (this))
 						{
 							// Hack to prevent missiles exploding against the sky.
 							// Does not handle sky floors.
@@ -99,10 +99,10 @@ void AFastProjectile::Tick ()
 					return;
 				}
 			}
-			z += zfrac;
+			AddZ(zfrac);
 			UpdateWaterLevel (oldz);
-			oldz = z;
-			if (z <= floorz)
+			oldz = Z();
+			if (Z() <= floorz)
 			{ // Hit the floor
 
 				if (floorpic == skyflatnum && !(flags3 & MF3_SKYEXPLODE))
@@ -113,12 +113,12 @@ void AFastProjectile::Tick ()
 					return;
 				}
 
-				z = floorz;
+				SetZ(floorz);
 				P_HitFloor (this);
 				P_ExplodeMissile (this, NULL, NULL);
 				return;
 			}
-			if (z + height > ceilingz)
+			if (Top() > ceilingz)
 			{ // Hit the ceiling
 
 				if (ceilingpic == skyflatnum &&  !(flags3 & MF3_SKYEXPLODE))
@@ -127,7 +127,7 @@ void AFastProjectile::Tick ()
 					return;
 				}
 
-				z = ceilingz - height;
+				SetZ(ceilingz - height);
 				P_ExplodeMissile (this, NULL, NULL);
 				return;
 			}
@@ -160,7 +160,7 @@ void AFastProjectile::Effect()
 		FName name = (ENamedName) this->GetClass()->Meta.GetMetaInt (ACMETA_MissileName, NAME_None);
 		if (name != NAME_None)
 		{
-			fixed_t hitz = z-8*FRACUNIT;
+			fixed_t hitz = Z()-8*FRACUNIT;
 
 			if (hitz < floorz)
 			{
@@ -172,7 +172,7 @@ void AFastProjectile::Effect()
 			const PClass *trail = PClass::FindClass(name);
 			if (trail != NULL)
 			{
-				AActor *act = Spawn (trail, x, y, hitz, ALLOW_REPLACE);
+				AActor *act = Spawn (trail, X(), Y(), hitz, ALLOW_REPLACE);
 				if (act != NULL)
 				{
 					act->angle = this->angle;
diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp
index 4da6eb67b..bc63f7bf0 100644
--- a/src/g_shared/a_morph.cpp
+++ b/src/g_shared/a_morph.cpp
@@ -77,7 +77,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i
 		return false;
 	}
 
-	morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
+	morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->Pos(), NO_REPLACE));
 	EndAllPowerupEffects(actor->Inventory);
 	DObject::StaticPointerSubstitution (actor, morphed);
 	if ((actor->tid != 0) && (style & MORPH_NEWTIDBEHAVIOUR))
@@ -105,7 +105,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i
 	morphed->flags  |= actor->flags & (MF_SHADOW|MF_NOGRAVITY);
 	morphed->flags2 |= actor->flags2 & MF2_FLY;
 	morphed->flags3 |= actor->flags3 & MF3_GHOST;
-	AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+	AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->PosPlusZ(TELEFOGHEIGHT), ALLOW_REPLACE);
 	actor->player = NULL;
 	actor->flags &= ~(MF_SOLID|MF_SHOOTABLE);
 	actor->flags |= MF_UNMORPHED;
@@ -192,7 +192,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
 	}
 
 	mo = barrier_cast<APlayerPawn *>(pmo->tracer);
-	mo->SetOrigin (pmo->x, pmo->y, pmo->z);
+	mo->SetOrigin (pmo->Pos(), false);
 	mo->flags |= MF_SOLID;
 	pmo->flags &= ~MF_SOLID;
 	if (!force && !P_TestMobjLocation (mo))
@@ -310,7 +310,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
 	AActor *eflash = NULL;
 	if (exit_flash != NULL)
 	{
-		eflash = Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+		eflash = Spawn(exit_flash, pmo->Vec3Offset(20*finecosine[angle], 20*finesine[angle], TELEFOGHEIGHT), ALLOW_REPLACE);
 		if (eflash)	eflash->target = mo;
 	}
 	mo->SetupWeaponSlots();		// Use original class's weapon slots.
@@ -381,7 +381,7 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype, int duration, int s
 		return false;
 	}
 
-	morphed = static_cast<AMorphedMonster *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
+	morphed = static_cast<AMorphedMonster *>(Spawn (spawntype, actor->Pos(), NO_REPLACE));
 	DObject::StaticPointerSubstitution (actor, morphed);
 	morphed->tid = actor->tid;
 	morphed->angle = actor->angle;
@@ -410,7 +410,7 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype, int duration, int s
 	actor->flags &= ~(MF_SOLID|MF_SHOOTABLE);
 	actor->flags |= MF_UNMORPHED;
 	actor->renderflags |= RF_INVISIBLE;
-	AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+	AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->PosPlusZ(TELEFOGHEIGHT), ALLOW_REPLACE);
 	if (eflash)
 		eflash->target = morphed;
 	return true;
@@ -436,7 +436,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force)
 		return false;
 	}
 	actor = beast->UnmorphedMe;
-	actor->SetOrigin (beast->x, beast->y, beast->z);
+	actor->SetOrigin (beast->Pos(), false);
 	actor->flags |= MF_SOLID;
 	beast->flags &= ~MF_SOLID;
 	ActorFlags6 beastflags6 = beast->flags6;
@@ -472,7 +472,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force)
 	DObject::StaticPointerSubstitution (beast, actor);
 	const PClass *exit_flash = beast->MorphExitFlash;
 	beast->Destroy ();
-	AActor *eflash = Spawn(exit_flash, beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+	AActor *eflash = Spawn(exit_flash, beast->PosPlusZ(TELEFOGHEIGHT), ALLOW_REPLACE);
 	if (eflash)
 		eflash->target = actor;
 	return true;
diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp
index 0f847fa41..fe4526e16 100644
--- a/src/g_shared/a_movingcamera.cpp
+++ b/src/g_shared/a_movingcamera.cpp
@@ -282,7 +282,7 @@ void APathFollower::Activate (AActor *activator)
 		if (CurrNode != NULL)
 		{
 			NewNode ();
-			SetOrigin (CurrNode->x, CurrNode->y, CurrNode->z);
+			SetOrigin (CurrNode->Pos(), false);
 			Time = 0.f;
 			HoldTime = 0;
 			bJustStepped = true;
@@ -302,9 +302,7 @@ void APathFollower::Tick ()
 		if (CurrNode->args[2])
 		{
 			HoldTime = level.time + CurrNode->args[2] * TICRATE / 8;
-			x = CurrNode->x;
-			y = CurrNode->y;
-			z = CurrNode->z;
+			SetXYZ(CurrNode->X(), CurrNode->Y(), CurrNode->Z());
 		}
 	}
 
@@ -362,31 +360,33 @@ bool APathFollower::Interpolate ()
 
 	if ((args[2] & 8) && Time > 0.f)
 	{
-		dx = x;
-		dy = y;
-		dz = z;
+		dx = X();
+		dy = Y();
+		dz = Z();
 	}
 
 	if (CurrNode->Next==NULL) return false;
 
 	UnlinkFromWorld ();
+	fixed_t x, y, z;
 	if (args[2] & 1)
 	{	// linear
-		x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->x), FIXED2FLOAT(CurrNode->Next->x)));
-		y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->y), FIXED2FLOAT(CurrNode->Next->y)));
-		z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->z), FIXED2FLOAT(CurrNode->Next->z)));
+		x = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->X()), FIXED2FLOAT(CurrNode->Next->X())));
+		y = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Y()), FIXED2FLOAT(CurrNode->Next->Y())));
+		z = FLOAT2FIXED(Lerp (FIXED2FLOAT(CurrNode->Z()), FIXED2FLOAT(CurrNode->Next->Z())));
 	}
 	else
 	{	// spline
 		if (CurrNode->Next->Next==NULL) return false;
 
-		x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->x), FIXED2FLOAT(CurrNode->x),
-								FIXED2FLOAT(CurrNode->Next->x), FIXED2FLOAT(CurrNode->Next->Next->x)));
-		y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->y), FIXED2FLOAT(CurrNode->y),
-								FIXED2FLOAT(CurrNode->Next->y), FIXED2FLOAT(CurrNode->Next->Next->y)));
-		z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->z), FIXED2FLOAT(CurrNode->z),
-								FIXED2FLOAT(CurrNode->Next->z), FIXED2FLOAT(CurrNode->Next->Next->z)));
+		x = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->X()), FIXED2FLOAT(CurrNode->X()),
+								FIXED2FLOAT(CurrNode->Next->X()), FIXED2FLOAT(CurrNode->Next->Next->X())));
+		y = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Y()), FIXED2FLOAT(CurrNode->Y()),
+								FIXED2FLOAT(CurrNode->Next->Y()), FIXED2FLOAT(CurrNode->Next->Next->Y())));
+		z = FLOAT2FIXED(Splerp (FIXED2FLOAT(PrevNode->Z()), FIXED2FLOAT(CurrNode->Z()),
+								FIXED2FLOAT(CurrNode->Next->Z()), FIXED2FLOAT(CurrNode->Next->Next->Z())));
 	}
+	SetXYZ(x, y, z);
 	LinkToWorld ();
 
 	if (args[2] & 6)
@@ -395,9 +395,9 @@ bool APathFollower::Interpolate ()
 		{
 			if (args[2] & 1)
 			{ // linear
-				dx = CurrNode->Next->x - CurrNode->x;
-				dy = CurrNode->Next->y - CurrNode->y;
-				dz = CurrNode->Next->z - CurrNode->z;
+				dx = CurrNode->Next->X() - CurrNode->X();
+				dy = CurrNode->Next->Y() - CurrNode->Y();
+				dz = CurrNode->Next->Z() - CurrNode->Z();
 			}
 			else if (Time > 0.f)
 			{ // spline
@@ -422,6 +422,7 @@ bool APathFollower::Interpolate ()
 				x -= dx;
 				y -= dy;
 				z -= dz;
+				SetXYZ(x, y, z);
 			}
 			if (args[2] & 2)
 			{ // adjust yaw
@@ -548,11 +549,11 @@ bool AActorMover::Interpolate ()
 
 	if (Super::Interpolate ())
 	{
-		fixed_t savedz = tracer->z;
-		tracer->z = z;
-		if (!P_TryMove (tracer, x, y, true))
+		fixed_t savedz = tracer->Z();
+		tracer->SetZ(Z());
+		if (!P_TryMove (tracer, X(), Y(), true))
 		{
-			tracer->z = savedz;
+			tracer->SetZ(savedz);
 			return false;
 		}
 
@@ -589,9 +590,9 @@ void AActorMover::Activate (AActor *activator)
 	// Don't let the renderer interpolate between the actor's
 	// old position and its new position.
 	Interpolate ();
-	tracer->PrevX = tracer->x;
-	tracer->PrevY = tracer->y;
-	tracer->PrevZ = tracer->z;
+	tracer->PrevX = tracer->X();
+	tracer->PrevY = tracer->Y();
+	tracer->PrevZ = tracer->Z();
 	tracer->PrevAngle = tracer->angle;
 }
 
@@ -667,15 +668,15 @@ bool AMovingCamera::Interpolate ()
 
 	if (Super::Interpolate ())
 	{
-		angle = R_PointToAngle2 (x, y, tracer->x, tracer->y);
+		angle = AngleTo(tracer, true);
 
 		if (args[2] & 4)
 		{ // Also aim camera's pitch; use floats for precision
-			float dx = FIXED2FLOAT(x - tracer->x);
-			float dy = FIXED2FLOAT(y - tracer->y);
-			float dz = FIXED2FLOAT(z - tracer->z - tracer->height/2);
-			float dist = (float)sqrt (dx*dx + dy*dy);
-			float ang = dist != 0.f ? (float)atan2 (dz, dist) : 0;
+			double dx = FIXED2DBL(X() - tracer->X());
+			double dy = FIXED2DBL(Y() - tracer->Y());
+			double dz = FIXED2DBL(Z() - tracer->Z() - tracer->height/2);
+			double dist = sqrt (dx*dx + dy*dy);
+			double ang = dist != 0.f ? atan2 (dz, dist) : 0;
 			pitch = (angle_t)(ang * 2147483648.f / PI);
 		}
 
diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp
index eb2831024..9fe31db22 100644
--- a/src/g_shared/a_pickups.cpp
+++ b/src/g_shared/a_pickups.cpp
@@ -331,7 +331,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialDoomThing)
 	{
 		self->SetState (self->SpawnState);
 		S_Sound (self, CHAN_VOICE, "misc/spawn", 1, ATTN_IDLE);
-		Spawn ("ItemFog", self->x, self->y, self->z, ALLOW_REPLACE);
+		Spawn ("ItemFog", self->Pos(), ALLOW_REPLACE);
 	}
 }
 
@@ -351,19 +351,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition)
 	_y = self->SpawnPoint[1];
 
 	self->UnlinkFromWorld();
-	self->x = _x;
-	self->y = _y;
+	self->SetXY(_x, _y);
 	self->LinkToWorld(true);
 	sec = self->Sector;
-	self->z =
 	self->dropoffz =
 	self->floorz = sec->floorplane.ZatPoint(_x, _y);
 	self->ceilingz = sec->ceilingplane.ZatPoint(_x, _y);
+	self->SetZ(self->floorz);
 	P_FindFloorCeiling(self, FFCF_ONLYSPAWNPOS);
 
 	if (self->flags & MF_SPAWNCEILING)
 	{
-		self->z = self->ceilingz - self->height - self->SpawnPoint[2];
+		self->SetZ(self->ceilingz - self->height - self->SpawnPoint[2]);
 	}
 	else if (self->flags2 & MF2_SPAWNFLOAT)
 	{
@@ -371,33 +370,33 @@ DEFINE_ACTION_FUNCTION(AActor, A_RestoreSpecialPosition)
 		if (space > 48*FRACUNIT)
 		{
 			space -= 40*FRACUNIT;
-			self->z = ((space * pr_restore())>>8) + self->floorz + 40*FRACUNIT;
+			self->SetZ(((space * pr_restore())>>8) + self->floorz + 40*FRACUNIT);
 		}
 		else
 		{
-			self->z = self->floorz;
+			self->SetZ(self->floorz);
 		}
 	}
 	else
 	{
-		self->z = self->SpawnPoint[2] + self->floorz;
+		self->SetZ(self->SpawnPoint[2] + self->floorz);
 	}
 	// Redo floor/ceiling check, in case of 3D floors
 	P_FindFloorCeiling(self, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT);
-	if (self->z < self->floorz)
+	if (self->Z() < self->floorz)
 	{ // Do not reappear under the floor, even if that's where we were for the
 	  // initial spawn.
-		self->z = self->floorz;
+		self->SetZ(self->floorz);
 	}
-	if ((self->flags & MF_SOLID) && (self->z + self->height > self->ceilingz))
+	if ((self->flags & MF_SOLID) && (self->Top() > self->ceilingz))
 	{ // Do the same for the ceiling.
-		self->z = self->ceilingz - self->height;
+		self->SetZ(self->ceilingz - self->height);
 	}
 	// Do not interpolate from the position the actor was at when it was
 	// picked up, in case that is different from where it is now.
-	self->PrevX = self->x;
-	self->PrevY = self->y;
-	self->PrevZ = self->z;
+	self->PrevX = self->X();
+	self->PrevY = self->Y();
+	self->PrevZ = self->Z();
 }
 
 int AInventory::StaticLastMessageTic;
@@ -728,8 +727,7 @@ AInventory *AInventory::CreateTossable ()
 		flags &= ~(MF_SPECIAL|MF_SOLID);
 		return this;
 	}
-	copy = static_cast<AInventory *>(Spawn (GetClass(), Owner->x,
-		Owner->y, Owner->z, NO_REPLACE));
+	copy = static_cast<AInventory *>(Spawn (GetClass(), Owner->Pos(), NO_REPLACE));
 	if (copy != NULL)
 	{
 		copy->MaxAmount = MaxAmount;
@@ -994,7 +992,7 @@ void AInventory::Touch (AActor *toucher)
 	// This is the only situation when a pickup flash should ever play.
 	if (PickupFlash != NULL && !ShouldStay())
 	{
-		Spawn(PickupFlash, x, y, z, ALLOW_REPLACE);
+		Spawn(PickupFlash, Pos(), ALLOW_REPLACE);
 	}
 
 	if (!(ItemFlags & IF_QUIET))
@@ -1290,8 +1288,8 @@ bool AInventory::DoRespawn ()
 		if (state != NULL) spot = state->GetRandomSpot(SpawnPointClass);
 		if (spot != NULL) 
 		{
-			SetOrigin (spot->x, spot->y, spot->z);
-			z = floorz;
+			SetOrigin (spot->Pos(), false);
+			SetZ(floorz);
 		}
 	}
 	return true;
diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp
index 195f3ccbf..94a375d3e 100644
--- a/src/g_shared/a_quake.cpp
+++ b/src/g_shared/a_quake.cpp
@@ -131,7 +131,7 @@ void DEarthquake::Tick ()
 
 				dist = m_Spot->AproxDistance (victim, true);
 				// Check if in damage radius
-				if (dist < m_DamageRadius && victim->z <= victim->floorz)
+				if (dist < m_DamageRadius && victim->Z() <= victim->floorz)
 				{
 					if (pr_quake() < 50)
 					{
diff --git a/src/g_shared/a_randomspawner.cpp b/src/g_shared/a_randomspawner.cpp
index 7d000f3d4..2ba445b7b 100644
--- a/src/g_shared/a_randomspawner.cpp
+++ b/src/g_shared/a_randomspawner.cpp
@@ -91,7 +91,7 @@ class ARandomSpawner : public AActor
 			// So now we can spawn the dropped item.
 			if (di == NULL || bouncecount >= MAX_RANDOMSPAWNERS_RECURSION)	// Prevents infinite recursions
 			{
-				Spawn("Unknown", x, y, z, NO_REPLACE);		// Show that there's a problem.
+				Spawn("Unknown", Pos(), NO_REPLACE);		// Show that there's a problem.
 				Destroy();
 				return;
 			}
@@ -144,9 +144,9 @@ class ARandomSpawner : public AActor
 		if (this->flags & MF_MISSILE && target && target->target) // Attempting to spawn a missile.
 		{
 			if ((tracer == NULL) && (flags2 & MF2_SEEKERMISSILE)) tracer = target->target;
-			newmobj = P_SpawnMissileXYZ(x, y, z, target, target->target, cls, false);
+			newmobj = P_SpawnMissileXYZ(Pos(), target, target->target, cls, false);
 		}
-		else newmobj = Spawn(cls, x, y, z, NO_REPLACE);
+		else newmobj = Spawn(cls, Pos(), NO_REPLACE);
 		if (newmobj != NULL)
 		{
 			// copy everything relevant
@@ -179,7 +179,7 @@ class ARandomSpawner : public AActor
 			// Handle special altitude flags
 			if (newmobj->flags & MF_SPAWNCEILING)
 			{
-				newmobj->z = newmobj->ceilingz - newmobj->height - SpawnPoint[2];
+				newmobj->SetZ(newmobj->ceilingz - newmobj->height - SpawnPoint[2]);
 			}
 			else if (newmobj->flags2 & MF2_SPAWNFLOAT) 
 			{
@@ -187,9 +187,9 @@ class ARandomSpawner : public AActor
 				if (space > 48*FRACUNIT)
 				{
 					space -= 40*FRACUNIT;
-					newmobj->z = MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT;
+					newmobj->SetZ(MulScale8 (space, pr_randomspawn()) + newmobj->floorz + 40*FRACUNIT);
 				}
-				newmobj->z += SpawnPoint[2];
+				newmobj->AddZ(SpawnPoint[2]);
 			}
 			if (newmobj->flags & MF_MISSILE)
 				P_CheckMissileSpawn(newmobj, 0);
diff --git a/src/g_shared/a_spark.cpp b/src/g_shared/a_spark.cpp
index 18b27d9ff..eee842f36 100644
--- a/src/g_shared/a_spark.cpp
+++ b/src/g_shared/a_spark.cpp
@@ -50,6 +50,6 @@ IMPLEMENT_CLASS (ASpark)
 void ASpark::Activate (AActor *activator)
 {
 	Super::Activate (activator);
-	P_DrawSplash (args[0] ? args[0] : 32, x, y, z, angle, 1);
+	P_DrawSplash (args[0] ? args[0] : 32, X(), Y(), Z(), angle, 1);
 	S_Sound (this, CHAN_AUTO, "world/spark", 1, ATTN_STATIC);
 }
diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp
index d3994ed84..1d2747ceb 100644
--- a/src/g_shared/a_specialspot.cpp
+++ b/src/g_shared/a_specialspot.cpp
@@ -423,12 +423,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnSingleItem)
 		return;
 	}
 
-	AActor *spawned = Spawn(cls, self->x, self->y, self->z, ALLOW_REPLACE);
+	AActor *spawned = Spawn(cls, self->Pos(), ALLOW_REPLACE);
 
 	if (spawned)
 	{
-		spawned->SetOrigin (spot->x, spot->y, spot->z);
-		spawned->z = spawned->floorz;
+		spawned->SetOrigin (spot->Pos(), false);
+		spawned->SetZ(spawned->floorz);
 		// We want this to respawn.
 		if (!(self->flags & MF_DROPPED)) 
 		{
diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp
index b351212d0..bd2946f2a 100644
--- a/src/g_shared/shared_sbar.cpp
+++ b/src/g_shared/shared_sbar.cpp
@@ -1287,8 +1287,7 @@ void DBaseStatusBar::Draw (EHudState state)
 		}
 
 		fixedvec3 pos = CPlayer->mo->Pos();
-		value = &pos.z;
-		for (i = 2, value = &CPlayer->mo->z; i >= 0; y -= height, --value, --i)
+		for (i = 2, value = &pos.z; i >= 0; y -= height, --value, --i)
 		{
 			mysnprintf (line, countof(line), "%c: %d", labels[i], *value >> FRACBITS);
 			screen->DrawText (SmallFont, CR_GREEN, xpos, y, line, 

From 119c2f36b2d3f3914f9147a3bd0af5400867f8e4 Mon Sep 17 00:00:00 2001
From: Chris <chris@localhost>
Date: Tue, 19 Jan 2016 13:20:32 +0000
Subject: [PATCH 04/23] - Fixed an incorrect memset parameter in wi_stuff.cpp.
 - Removed some whitespace from wi_stuff.h.

---
 src/wi_stuff.cpp |  2 +-
 src/wi_stuff.h   | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp
index 653f6b907..e931b33fd 100644
--- a/src/wi_stuff.cpp
+++ b/src/wi_stuff.cpp
@@ -1228,7 +1228,7 @@ void WI_initDeathmatchStats (void)
 	acceleratestage = 0;
 	memset(playerready, 0, sizeof(playerready));
 	memset(cnt_frags, 0, sizeof(cnt_frags));
-	memset(cnt_deaths, 0, sizeof(cnt_frags));
+	memset(cnt_deaths, 0, sizeof(cnt_deaths));
 	memset(player_deaths, 0, sizeof(player_deaths));
 	total_frags = 0;
 	total_deaths = 0;
diff --git a/src/wi_stuff.h b/src/wi_stuff.h
index dee36e736..a594d17af 100644
--- a/src/wi_stuff.h
+++ b/src/wi_stuff.h
@@ -33,7 +33,7 @@ class FTexture;
 struct wbplayerstruct_t
 {
 	bool		in;			// whether the player is in game
-	
+
 	// Player stats, kills, collected items etc.
 	int			skills;
 	int			sitems;
@@ -41,7 +41,6 @@ struct wbplayerstruct_t
 	int			stime;
 	int			frags[MAXPLAYERS];
 	int			fragcount;	// [RH] Cumulative frags for this player
-
 };
 
 struct wbstartstruct_t
@@ -54,7 +53,7 @@ struct wbstartstruct_t
 
 	FTexture	*LName0;
 	FTexture	*LName1;
-	
+
 	int			maxkills;
 	int			maxitems;
 	int			maxsecret;
@@ -63,19 +62,19 @@ struct wbstartstruct_t
 	// the par time and sucktime
 	int			partime;	// in tics
 	int			sucktime;	// in minutes
-	
+
 	// total time for the entire current game
 	int			totaltime;
 
 	// index of this player in game
-	int			pnum;	
+	int			pnum;
 
 	wbplayerstruct_t	plyr[MAXPLAYERS];
 };
 
 // Intermission stats.
 // Parameters for world map / intermission.
-extern wbstartstruct_t wminfo; 
+extern wbstartstruct_t wminfo;
 
 
 // Called by main loop, animate the intermission.

From 97620b0645985de839696cc15f2b90966c01d3ee Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Tue, 19 Jan 2016 16:09:44 +0100
Subject: [PATCH 05/23] - fixed some leftover unused variable warnings. - match
 the variable names in thingdef_codeptr.cpp to the ones in the scripting
 branch to reduce the amount of merge conflicts in upcoming changes.

---
 src/g_raven/a_minotaur.cpp        |   1 -
 src/g_shared/a_debris.cpp         |   2 -
 src/g_strife/a_spectral.cpp       |   1 -
 src/g_strife/a_thingstoblowup.cpp |   2 -
 src/thingdef/thingdef_codeptr.cpp | 541 ++++++++++++++++--------------
 5 files changed, 289 insertions(+), 258 deletions(-)

diff --git a/src/g_raven/a_minotaur.cpp b/src/g_raven/a_minotaur.cpp
index bf795fb33..5e2edd634 100644
--- a/src/g_raven/a_minotaur.cpp
+++ b/src/g_raven/a_minotaur.cpp
@@ -367,7 +367,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_MinotaurAtk3)
 DEFINE_ACTION_FUNCTION(AActor, A_MntrFloorFire)
 {
 	AActor *mo;
-	fixed_t x, y;
 
 	self->SetZ(self->floorz);
 	fixedvec2 pos = self->Vec2Offset(
diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp
index 3b34a0d8a..c85c0fed9 100644
--- a/src/g_shared/a_debris.cpp
+++ b/src/g_shared/a_debris.cpp
@@ -31,10 +31,8 @@ IMPLEMENT_CLASS(AGlassShard)
 
 void P_SpawnDirt (AActor *actor, fixed_t radius)
 {
-	fixed_t x,y,z;
 	const PClass *dtype = NULL;
 	AActor *mo;
-	angle_t angle;
 
 	fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, (pr_dirt() << 9) + FRACUNIT);
 
diff --git a/src/g_strife/a_spectral.cpp b/src/g_strife/a_spectral.cpp
index 91e43dba9..51ed7b0d0 100644
--- a/src/g_strife/a_spectral.cpp
+++ b/src/g_strife/a_spectral.cpp
@@ -53,7 +53,6 @@ static FRandom pr_zap5 ("Zap5");
 DEFINE_ACTION_FUNCTION(AActor, A_SpectralLightning)
 {
 	AActor *flash;
-	fixed_t x, y;
 
 	if (self->threshold != 0)
 		--self->threshold;
diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp
index 86ae7282e..81dcc9f3e 100644
--- a/src/g_strife/a_thingstoblowup.cpp
+++ b/src/g_strife/a_thingstoblowup.cpp
@@ -18,8 +18,6 @@ extern const PClass *QuestItemClasses[31];
 
 DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
 {
-	fixed_t spawnx, spawny;
-
 	fixedvec3 pos = self->Vec3Offset((pr_bang4cloud.Random2() & 3) * 10240, (pr_bang4cloud.Random2() & 3) * 10240, 0);
 
 	Spawn("Bang4Cloud", pos, ALLOW_REPLACE);
diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 5fcc69f4b..ccfaa2542 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -235,27 +235,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_TransferPointer)
 {
 	ACTION_PARAM_START(5);
 	ACTION_PARAM_INT(ptr_source, 0);
-	ACTION_PARAM_INT(ptr_recepient, 1);
+	ACTION_PARAM_INT(ptr_recipient, 1);
 	ACTION_PARAM_INT(ptr_sourcefield, 2);
-	ACTION_PARAM_INT(ptr_recepientfield, 3);
+	ACTION_PARAM_INT(ptr_recipientfield, 3);
 	ACTION_PARAM_INT(flags, 4);
 
-	AActor *source, *recepient;
+	AActor *source, *recipient;
 
 	// Exchange pointers with actors to whom you have pointers (or with yourself, if you must)
 
 	source = COPY_AAPTR(self, ptr_source);
-	COPY_AAPTR_NOT_NULL(self, recepient, ptr_recepient); // pick an actor to store the provided pointer value
+	COPY_AAPTR_NOT_NULL(self, recipient, ptr_recipient); // pick an actor to store the provided pointer value
 
 	// convert source from dataprovider to data
  
 	source = COPY_AAPTR(source, ptr_sourcefield);
 
-	if (source == recepient) source = NULL; // The recepient should not acquire a pointer to itself; will write NULL
+	if (source == recipient) source = NULL; // The recipient should not acquire a pointer to itself; will write NULL
 
-	if (ptr_recepientfield == AAPTR_DEFAULT) ptr_recepientfield = ptr_sourcefield; // If default: Write to same field as data was read from
+	if (ptr_recipientfield == AAPTR_DEFAULT) ptr_recipientfield = ptr_sourcefield; // If default: Write to same field as data was read from
 
-	ASSIGN_AAPTR(recepient, ptr_recepientfield, source, flags);
+	ASSIGN_AAPTR(recipient, ptr_recipientfield, source, flags);
 }
 
 //==========================================================================
@@ -913,9 +913,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 {
 	ACTION_PARAM_START(7);
 	ACTION_PARAM_CLASS(ti, 0);
-	ACTION_PARAM_FIXED(SpawnHeight, 1);
-	ACTION_PARAM_INT(Spawnofs_XY, 2);
-	ACTION_PARAM_ANGLE(Angle, 3);
+	ACTION_PARAM_FIXED(spawnheight, 1);
+	ACTION_PARAM_INT(spawnofs_xy, 2);
+	ACTION_PARAM_ANGLE(angle, 3);
 	ACTION_PARAM_INT(flags, 4);
 	ACTION_PARAM_ANGLE(pitch, 5);
 	ACTION_PARAM_INT(ptr, 6);
@@ -927,14 +927,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 	AActor * targ;
 	AActor * missile;
 
-	if (ref != NULL || aimmode==2)
+	if (ref != NULL || aimmode == 2)
 	{
 		if (ti) 
 		{
 			angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT;
-			fixed_t x = Spawnofs_XY * finecosine[ang];
-			fixed_t y = Spawnofs_XY * finesine[ang];
-			fixed_t z = SpawnHeight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
+			fixed_t x = spawnofs_xy * finecosine[ang];
+			fixed_t y = spawnofs_xy * finesine[ang];
+			fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
 
 			switch (aimmode)
 			{
@@ -951,13 +951,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 				break;
 
 			case 1:
-				missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + SpawnHeight, self, ref, ti, false);
+				missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + spawnheight, self, ref, ti, false);
 				break;
 
 			case 2:
 				self->x += x;
 				self->y += y;
-				missile = P_SpawnMissileAngleZSpeed(self, self->z + self->GetBobOffset() + SpawnHeight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
+				missile = P_SpawnMissileAngleZSpeed(self, self->z + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
  				self->x -= x;
 				self->y -= y;
 
@@ -966,7 +966,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 				break;
 			}
 
-			if (missile)
+			if (missile != NULL)
 			{
 				// Use the actual velocity instead of the missile's Speed property
 				// so that this can handle missiles with a high vertical velocity 
@@ -999,30 +999,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 					// otherwise affecting the spawned actor.
 				}
 
-				missile->angle = (CMF_ABSOLUTEANGLE & flags) ? Angle : missile->angle + Angle ;
+				missile->angle = (CMF_ABSOLUTEANGLE & flags) ? angle : missile->angle + angle ;
 
 				ang = missile->angle >> ANGLETOFINESHIFT;
-				missile->velx = FixedMul (missilespeed, finecosine[ang]);
-				missile->vely = FixedMul (missilespeed, finesine[ang]);
+				missile->velx = FixedMul(missilespeed, finecosine[ang]);
+				missile->vely = FixedMul(missilespeed, finesine[ang]);
 	
 				// handle projectile shooting projectiles - track the
 				// links back to a real owner
                 if (self->isMissile(!!(flags & CMF_TRACKOWNER)))
                 {
-                	AActor * owner=self ;//->target;
-                	while (owner->isMissile(!!(flags & CMF_TRACKOWNER)) && owner->target) owner=owner->target;
-                	targ=owner;
-                	missile->target=owner;
+                	AActor *owner = self ;//->target;
+                	while (owner->isMissile(!!(flags & CMF_TRACKOWNER)) && owner->target)
+						owner = owner->target;
+                	targ = owner;
+                	missile->target = owner;
 					// automatic handling of seeker missiles
 					if (self->flags2 & missile->flags2 & MF2_SEEKERMISSILE)
 					{
-						missile->tracer=self->tracer;
+						missile->tracer = self->tracer;
 					}
                 }
-				else if (missile->flags2&MF2_SEEKERMISSILE)
+				else if (missile->flags2 & MF2_SEEKERMISSILE)
 				{
 					// automatic handling of seeker missiles
-					missile->tracer=self->target;
+					missile->tracer = self->target;
 				}
 				// we must redo the spectral check here because the owner is set after spawning so the FriendPlayer value may be wrong
 				if (missile->flags4 & MF4_SPECTRAL)
@@ -1043,7 +1044,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 	else if (flags & CMF_CHECKTARGETDEAD)
 	{
 		// Target is dead and the attack shall be aborted.
-		if (self->SeeState != NULL && (self->health > 0 || !(self->flags3 & MF3_ISMONSTER))) self->SetState(self->SeeState);
+		if (self->SeeState != NULL && (self->health > 0 || !(self->flags3 & MF3_ISMONSTER)))
+			self->SetState(self->SeeState);
 	}
 }
 
@@ -1064,27 +1066,28 @@ enum CBA_Flags
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
 {
 	ACTION_PARAM_START(8);
-	ACTION_PARAM_ANGLE(Spread_XY, 0);
-	ACTION_PARAM_ANGLE(Spread_Z, 1);
-	ACTION_PARAM_INT(NumBullets, 2);
-	ACTION_PARAM_INT(DamagePerBullet, 3);
+	ACTION_PARAM_ANGLE(spread_xy, 0);
+	ACTION_PARAM_ANGLE(spread_z, 1);
+	ACTION_PARAM_INT(numbullets, 2);
+	ACTION_PARAM_INT(damageperbullet, 3);
 	ACTION_PARAM_CLASS(pufftype, 4);
-	ACTION_PARAM_FIXED(Range, 5);
-	ACTION_PARAM_INT(Flags, 6);
+	ACTION_PARAM_FIXED(range, 5);
+	ACTION_PARAM_INT(flags, 6);
 	ACTION_PARAM_INT(ptr, 7);
 
 	AActor *ref = COPY_AAPTR(self, ptr);
 
-	if(Range==0) Range=MISSILERANGE;
+	if (range == 0)
+		range = MISSILERANGE;
 
 	int i;
 	int bangle;
 	int bslope = 0;
-	int laflags = (Flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
+	int laflags = (flags & CBAF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
 
-	if (ref || (Flags & CBAF_AIMFACING))
+	if (ref != NULL || (flags & CBAF_AIMFACING))
 	{
-		if (!(Flags & CBAF_AIMFACING))
+		if (!(flags & CBAF_AIMFACING))
 		{
 			A_Face(self, ref);
 		}
@@ -1092,31 +1095,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomBulletAttack)
 
 		if (!pufftype) pufftype = PClass::FindClass(NAME_BulletPuff);
 
-		if (!(Flags & CBAF_NOPITCH)) bslope = P_AimLineAttack (self, bangle, MISSILERANGE);
+		if (!(flags & CBAF_NOPITCH)) bslope = P_AimLineAttack (self, bangle, MISSILERANGE);
 
 		S_Sound (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
-		for (i=0 ; i<NumBullets ; i++)
+		for (i = 0; i < numbullets; i++)
 		{
 			int angle = bangle;
 			int slope = bslope;
 
-			if (Flags & CBAF_EXPLICITANGLE)
+			if (flags & CBAF_EXPLICITANGLE)
 			{
-				angle += Spread_XY;
-				slope += Spread_Z;
+				angle += spread_xy;
+				slope += spread_z;
 			}
 			else
 			{
-				angle += pr_cwbullet.Random2() * (Spread_XY / 255);
-				slope += pr_cwbullet.Random2() * (Spread_Z / 255);
+				angle += pr_cwbullet.Random2() * (spread_xy / 255);
+				slope += pr_cwbullet.Random2() * (spread_z / 255);
 			}
 
-			int damage = DamagePerBullet;
+			int damage = damageperbullet;
 
-			if (!(Flags & CBAF_NORANDOM))
+			if (!(flags & CBAF_NORANDOM))
 				damage *= ((pr_cabullet()%3)+1);
 
-			P_LineAttack(self, angle, Range, slope, damage, NAME_Hitscan, pufftype, laflags);
+			P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
 		}
     }
 }
@@ -1130,12 +1133,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMeleeAttack)
 {
 	ACTION_PARAM_START(5);
 	ACTION_PARAM_INT(damage, 0);
-	ACTION_PARAM_SOUND(MeleeSound, 1);
-	ACTION_PARAM_SOUND(MissSound, 2);
-	ACTION_PARAM_NAME(DamageType, 3);
+	ACTION_PARAM_SOUND(meleesound, 1);
+	ACTION_PARAM_SOUND(misssound, 2);
+	ACTION_PARAM_NAME(damagetype, 3);
 	ACTION_PARAM_BOOL(bleed, 4);
 
-	if (DamageType==NAME_None) DamageType = NAME_Melee;	// Melee is the default type
+	if (damagetype == NAME_None)
+		damagetype = NAME_Melee;	// Melee is the default type
 
 	if (!self->target)
 		return;
@@ -1143,13 +1147,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMeleeAttack)
 	A_FaceTarget (self);
 	if (self->CheckMeleeRange ())
 	{
-		if (MeleeSound) S_Sound (self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM);
-		int newdam = P_DamageMobj (self->target, self, self, damage, DamageType);
-		if (bleed) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
+		if (meleesound)
+			S_Sound (self, CHAN_WEAPON, meleesound, 1, ATTN_NORM);
+		int newdam = P_DamageMobj (self->target, self, self, damage, damagetype);
+		if (bleed)
+			P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
 	}
 	else
 	{
-		if (MissSound) S_Sound (self, CHAN_WEAPON, MissSound, 1, ATTN_NORM);
+		if (misssound)
+			S_Sound (self, CHAN_WEAPON, misssound, 1, ATTN_NORM);
 	}
 }
 
@@ -1162,36 +1169,39 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack)
 {
 	ACTION_PARAM_START(6);
 	ACTION_PARAM_CLASS(ti, 0);
-	ACTION_PARAM_FIXED(SpawnHeight, 1);
+	ACTION_PARAM_FIXED(spawnheight, 1);
 	ACTION_PARAM_INT(damage, 2);
-	ACTION_PARAM_SOUND(MeleeSound, 3);
-	ACTION_PARAM_NAME(DamageType, 4);
+	ACTION_PARAM_SOUND(meleesound, 3);
+	ACTION_PARAM_NAME(damagetype, 4);
 	ACTION_PARAM_BOOL(bleed, 5);
 
 	if (!self->target)
 		return;
 				
 	A_FaceTarget (self);
-	if (self->CheckMeleeRange ())
+	if (self->CheckMeleeRange())
 	{
-		if (DamageType==NAME_None) DamageType = NAME_Melee;	// Melee is the default type
-		if (MeleeSound) S_Sound (self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM);
-		int newdam = P_DamageMobj (self->target, self, self, damage, DamageType);
-		if (bleed) P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
+		if (damagetype == NAME_None)
+			damagetype = NAME_Melee;	// Melee is the default type
+		if (meleesound)
+			S_Sound (self, CHAN_WEAPON, meleesound, 1, ATTN_NORM);
+		int newdam = P_DamageMobj (self->target, self, self, damage, damagetype);
+		if (bleed)
+			P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
 	}
 	else if (ti) 
 	{
 		// This seemingly senseless code is needed for proper aiming.
-		self->z += SpawnHeight + self->GetBobOffset() - 32*FRACUNIT;
+		self->z += spawnheight + self->GetBobOffset() - 32*FRACUNIT;
 		AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false);
-		self->z -= SpawnHeight + self->GetBobOffset() - 32*FRACUNIT;
+		self->z -= spawnheight + self->GetBobOffset() - 32*FRACUNIT;
 
 		if (missile)
 		{
 			// automatic handling of seeker missiles
-			if (missile->flags2&MF2_SEEKERMISSILE)
+			if (missile->flags2 & MF2_SEEKERMISSILE)
 			{
-				missile->tracer=self->target;
+				missile->tracer = self->target;
 			}
 			P_CheckMissileSpawn(missile, self->radius);
 		}
@@ -1237,77 +1247,81 @@ enum FB_Flags
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
 {
 	ACTION_PARAM_START(7);
-	ACTION_PARAM_ANGLE(Spread_XY, 0);
-	ACTION_PARAM_ANGLE(Spread_Z, 1);
-	ACTION_PARAM_INT(NumberOfBullets, 2);
-	ACTION_PARAM_INT(DamagePerBullet, 3);
-	ACTION_PARAM_CLASS(PuffType, 4);
-	ACTION_PARAM_INT(Flags, 5);
-	ACTION_PARAM_FIXED(Range, 6);
+	ACTION_PARAM_ANGLE(spread_xy, 0);
+	ACTION_PARAM_ANGLE(spread_z, 1);
+	ACTION_PARAM_INT(numbullets, 2);
+	ACTION_PARAM_INT(damageperbullet, 3);
+	ACTION_PARAM_CLASS(pufftype, 4);
+	ACTION_PARAM_INT(flags, 5);
+	ACTION_PARAM_FIXED(range, 6);
 
 	if (!self->player) return;
 
-	player_t * player=self->player;
-	AWeapon * weapon=player->ReadyWeapon;
+	player_t *player = self->player;
+	AWeapon *weapon = player->ReadyWeapon;
 
 	int i;
 	int bangle;
 	int bslope = 0;
-	int laflags = (Flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
+	int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
 
-	if ((Flags & FBF_USEAMMO) && weapon)
+	if ((flags & FBF_USEAMMO) && weapon)
 	{
-		if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return;	// out of ammo
+		if (!weapon->DepleteAmmo(weapon->bAltFire, true))
+			return;	// out of ammo
 	}
 	
-	if (Range == 0) Range = PLAYERMISSILERANGE;
+	if (range == 0)
+		range = PLAYERMISSILERANGE;
 
-	if (!(Flags & FBF_NOFLASH)) static_cast<APlayerPawn *>(self)->PlayAttacking2 ();
+	if (!(flags & FBF_NOFLASH)) static_cast<APlayerPawn *>(self)->PlayAttacking2 ();
 
-	if (!(Flags & FBF_NOPITCH)) bslope = P_BulletSlope(self);
+	if (!(flags & FBF_NOPITCH)) bslope = P_BulletSlope(self);
 	bangle = self->angle;
 
-	if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
+	if (pufftype == NULL)
+		pufftype = PClass::FindClass(NAME_BulletPuff);
 
 	if (weapon != NULL)
 	{
-		S_Sound (self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
+		S_Sound(self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
 	}
 
-	if ((NumberOfBullets==1 && !player->refire) || NumberOfBullets==0)
+	if ((numbullets == 1 && !player->refire) || numbullets == 0)
 	{
-		int damage = DamagePerBullet;
+		int damage = damageperbullet;
 
-		if (!(Flags & FBF_NORANDOM))
+		if (!(flags & FBF_NORANDOM))
 			damage *= ((pr_cwbullet()%3)+1);
 
-		P_LineAttack(self, bangle, Range, bslope, damage, NAME_Hitscan, PuffType, laflags);
+		P_LineAttack(self, bangle, range, bslope, damage, NAME_Hitscan, pufftype, laflags);
 	}
 	else 
 	{
-		if (NumberOfBullets == -1) NumberOfBullets = 1;
-		for (i=0 ; i<NumberOfBullets ; i++)
+		if (numbullets < 0)
+			numbullets = 1;
+		for (i = 0; i < numbullets; i++)
 		{
 			int angle = bangle;
 			int slope = bslope;
 
-			if (Flags & FBF_EXPLICITANGLE)
+			if (flags & FBF_EXPLICITANGLE)
 			{
-				angle += Spread_XY;
-				slope += Spread_Z;
+				angle += spread_xy;
+				slope += spread_z;
 			}
 			else
 			{
-				angle += pr_cwbullet.Random2() * (Spread_XY / 255);
-				slope += pr_cwbullet.Random2() * (Spread_Z / 255);
+				angle += pr_cwbullet.Random2() * (spread_xy / 255);
+				slope += pr_cwbullet.Random2() * (spread_z / 255);
 			}
 
-			int damage = DamagePerBullet;
+			int damage = damageperbullet;
 
-			if (!(Flags & FBF_NORANDOM))
+			if (!(flags & FBF_NORANDOM))
 				damage *= ((pr_cwbullet()%3)+1);
 
-			P_LineAttack(self, angle, Range, slope, damage, NAME_Hitscan, PuffType, laflags);
+			P_LineAttack(self, angle, range, slope, damage, NAME_Hitscan, pufftype, laflags);
 		}
 	}
 }
@@ -1328,54 +1342,57 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile)
 {
 	ACTION_PARAM_START(7);
 	ACTION_PARAM_CLASS(ti, 0);
-	ACTION_PARAM_ANGLE(Angle, 1);
-	ACTION_PARAM_BOOL(UseAmmo, 2);
-	ACTION_PARAM_INT(SpawnOfs_XY, 3);
-	ACTION_PARAM_FIXED(SpawnHeight, 4);
-	ACTION_PARAM_INT(Flags, 5);
+	ACTION_PARAM_ANGLE(angle, 1);
+	ACTION_PARAM_BOOL(useammo, 2);
+	ACTION_PARAM_INT(spawnofs_xy, 3);
+	ACTION_PARAM_FIXED(spawnheight, 4);
+	ACTION_PARAM_INT(flags, 5);
 	ACTION_PARAM_ANGLE(pitch, 6);
 
 	if (!self->player) return;
 
 
-	player_t *player=self->player;
-	AWeapon * weapon=player->ReadyWeapon;
+	player_t *player = self->player;
+	AWeapon *weapon = player->ReadyWeapon;
 	AActor *linetarget;
 
 		// Only use ammo if called from a weapon
-	if (UseAmmo && ACTION_CALL_FROM_WEAPON() && weapon)
+	if (useammo && ACTION_CALL_FROM_WEAPON() && weapon)
 	{
-		if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return;	// out of ammo
+		if (!weapon->DepleteAmmo(weapon->bAltFire, true))
+			return;	// out of ammo
 	}
 
 	if (ti) 
 	{
 		angle_t ang = (self->angle - ANGLE_90) >> ANGLETOFINESHIFT;
-		fixed_t x = SpawnOfs_XY * finecosine[ang];
-		fixed_t y = SpawnOfs_XY * finesine[ang];
-		fixed_t z = SpawnHeight;
+		fixed_t x = spawnofs_xy * finecosine[ang];
+		fixed_t y = spawnofs_xy * finesine[ang];
+		fixed_t z = spawnheight;
 		fixed_t shootangle = self->angle;
 
-		if (Flags & FPF_AIMATANGLE) shootangle += Angle;
+		if (flags & FPF_AIMATANGLE) shootangle += angle;
 
 		// Temporarily adjusts the pitch
-		fixed_t SavedPlayerPitch = self->pitch;
+		fixed_t saved_player_pitch = self->pitch;
 		self->pitch -= pitch;
-		AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, (Flags & FPF_NOAUTOAIM) != 0);
-		self->pitch = SavedPlayerPitch;
+		AActor * misl=P_SpawnPlayerMissile (self, x, y, z, ti, shootangle, &linetarget, NULL, false, (flags & FPF_NOAUTOAIM) != 0);
+		self->pitch = saved_player_pitch;
 
 		// automatic handling of seeker missiles
 		if (misl)
 		{
-			if (Flags & FPF_TRANSFERTRANSLATION) misl->Translation = self->Translation;
-			if (linetarget && misl->flags2&MF2_SEEKERMISSILE) misl->tracer=linetarget;
-			if (!(Flags & FPF_AIMATANGLE))
+			if (flags & FPF_TRANSFERTRANSLATION)
+				misl->Translation = self->Translation;
+			if (linetarget && (misl->flags2 & MF2_SEEKERMISSILE))
+				misl->tracer = linetarget;
+			if (!(flags & FPF_AIMATANGLE))
 			{
 				// This original implementation is to aim straight ahead and then offset
 				// the angle from the resulting direction. 
 				FVector3 velocity(misl->velx, misl->vely, 0);
 				fixed_t missilespeed = (fixed_t)velocity.Length();
-				misl->angle += Angle;
+				misl->angle += angle;
 				angle_t an = misl->angle >> ANGLETOFINESHIFT;
 				misl->velx = FixedMul (missilespeed, finecosine[an]);
 				misl->vely = FixedMul (missilespeed, finesine[an]);
@@ -1406,12 +1423,12 @@ enum
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
 {
 	ACTION_PARAM_START(8);
-	ACTION_PARAM_INT(Damage, 0);
+	ACTION_PARAM_INT(damage, 0);
 	ACTION_PARAM_BOOL(norandom, 1);
 	ACTION_PARAM_INT(flags, 2);
-	ACTION_PARAM_CLASS(PuffType, 3);
-	ACTION_PARAM_FIXED(Range, 4);
-	ACTION_PARAM_FIXED(LifeSteal, 5);
+	ACTION_PARAM_CLASS(pufftype, 3);
+	ACTION_PARAM_FIXED(range, 4);
+	ACTION_PARAM_FIXED(lifesteal, 5);
 	ACTION_PARAM_INT(lifestealmax, 6);
 	ACTION_PARAM_CLASS(armorbonustype, 7);
 	ACTION_PARAM_SOUND(MeleeSound, 8);
@@ -1428,22 +1445,26 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
 	AActor *	linetarget;
 	int			actualdamage;
 
-	if (!norandom) Damage *= (pr_cwpunch()%8+1);
+	if (!norandom)
+		damage *= pr_cwpunch() % 8 + 1;
 
 	angle = self->angle + (pr_cwpunch.Random2() << 18);
-	if (Range == 0) Range = MELEERANGE;
-	pitch = P_AimLineAttack (self, angle, Range, &linetarget);
+	if (range == 0)
+		range = MELEERANGE;
+	pitch = P_AimLineAttack (self, angle, range, &linetarget);
 
 	// only use ammo when actually hitting something!
 	if ((flags & CPF_USEAMMO) && linetarget && weapon)
 	{
-		if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return;	// out of ammo
+		if (!weapon->DepleteAmmo(weapon->bAltFire, true))
+			return;	// out of ammo
 	}
 
-	if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
+	if (pufftype == NULL)
+		pufftype = PClass::FindClass(NAME_BulletPuff);
 	int puffFlags = LAF_ISMELEEATTACK | ((flags & CPF_NORANDOMPUFFZ) ? LAF_NORANDOMPUFFZ : 0);
 
-	P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage);
+	P_LineAttack (self, angle, range, pitch, damage, NAME_Melee, pufftype, puffFlags, &linetarget, &actualdamage);
 
 	if (!linetarget)
 	{
@@ -1451,33 +1472,34 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
 	}
 	else
 	{
-		if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
+		if (lifesteal && !(linetarget->flags5 & MF5_DONTDRAIN))
 		{
 			if (flags & CPF_STEALARMOR)
 			{
-				if (!armorbonustype) armorbonustype = PClass::FindClass("ArmorBonus");
-
-				if (armorbonustype->IsDescendantOf (RUNTIME_CLASS(ABasicArmorBonus)))
+				if (armorbonustype == NULL)
 				{
-					ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn (armorbonustype, 0,0,0, NO_REPLACE));
-					armorbonus->SaveAmount *= (actualdamage * LifeSteal) >> FRACBITS;
+					armorbonustype = PClass::FindClass("ArmorBonus");
+				}
+				if (armorbonustype != NULL)
+				{
+					assert(armorbonustype->IsDescendantOf(RUNTIME_CLASS(ABasicArmorBonus)));
+					ABasicArmorBonus *armorbonus = static_cast<ABasicArmorBonus *>(Spawn(armorbonustype, 0,0,0, NO_REPLACE));
+					armorbonus->SaveAmount *= (actualdamage * lifesteal) >> FRACBITS;
 					armorbonus->MaxSaveAmount = lifestealmax <= 0 ? armorbonus->MaxSaveAmount : lifestealmax;
 					armorbonus->flags |= MF_DROPPED;
 					armorbonus->ClearCounters();
 
-					if (!armorbonus->CallTryPickup (self))
+					if (!armorbonus->CallTryPickup(self))
 					{
 						armorbonus->Destroy ();
 					}
 				}
 			}
-
 			else
 			{
-				P_GiveBody (self, (actualdamage * LifeSteal) >> FRACBITS, lifestealmax);
+				P_GiveBody (self, (actualdamage * lifesteal) >> FRACBITS, lifestealmax);
 			}
 		}
-
 		if (weapon != NULL)
 		{
 			if (MeleeSound) S_Sound(self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM);
@@ -1504,52 +1526,53 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack)
 {
 	ACTION_PARAM_START(17);
-	ACTION_PARAM_INT(Damage, 0);
-	ACTION_PARAM_INT(Spawnofs_XY, 1);
-	ACTION_PARAM_BOOL(UseAmmo, 2);
-	ACTION_PARAM_COLOR(Color1, 3);
-	ACTION_PARAM_COLOR(Color2, 4);
-	ACTION_PARAM_INT(Flags, 5);
-	ACTION_PARAM_DOUBLE(MaxDiff, 6);
-	ACTION_PARAM_CLASS(PuffType, 7);
-	ACTION_PARAM_ANGLE(Spread_XY, 8);
-	ACTION_PARAM_ANGLE(Spread_Z, 9);
-	ACTION_PARAM_FIXED(Range, 10);
-	ACTION_PARAM_INT(Duration, 11);
-	ACTION_PARAM_DOUBLE(Sparsity, 12);
-	ACTION_PARAM_DOUBLE(DriftSpeed, 13);
-	ACTION_PARAM_CLASS(SpawnClass, 14);
-	ACTION_PARAM_FIXED(Spawnofs_Z, 15);
+	ACTION_PARAM_INT(damage, 0);
+	ACTION_PARAM_INT(spawnofs_xy, 1);
+	ACTION_PARAM_BOOL(useammo, 2);
+	ACTION_PARAM_COLOR(color1, 3);
+	ACTION_PARAM_COLOR(color2, 4);
+	ACTION_PARAM_INT(flags, 5);
+	ACTION_PARAM_DOUBLE(maxdiff, 6);
+	ACTION_PARAM_CLASS(pufftype, 7);
+	ACTION_PARAM_ANGLE(spread_xy, 8);
+	ACTION_PARAM_ANGLE(spread_z, 9);
+	ACTION_PARAM_FIXED(range, 10);
+	ACTION_PARAM_INT(duration, 11);
+	ACTION_PARAM_DOUBLE(sparsity, 12);
+	ACTION_PARAM_DOUBLE(driftspeed, 13);
+	ACTION_PARAM_CLASS(spawnclass, 14);
+	ACTION_PARAM_FIXED(spawnofs_z, 15);
 	ACTION_PARAM_INT(SpiralOffset, 16);
 	
-	if(Range==0) Range=8192*FRACUNIT;
-	if(Sparsity==0) Sparsity=1.0;
+	if (range == 0) range = 8192*FRACUNIT;
+	if (sparsity == 0) sparsity=1.0;
 
 	if (!self->player) return;
 
-	AWeapon * weapon=self->player->ReadyWeapon;
+	AWeapon *weapon = self->player->ReadyWeapon;
 
 	// only use ammo when actually hitting something!
-	if (UseAmmo)
+	if (useammo)
 	{
-		if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return;	// out of ammo
+		if (!weapon->DepleteAmmo(weapon->bAltFire, true))
+			return;	// out of ammo
 	}
 
 	angle_t angle;
 	angle_t slope;
 
-	if (Flags & RAF_EXPLICITANGLE)
+	if (flags & RAF_EXPLICITANGLE)
 	{
-		angle = Spread_XY;
-		slope = Spread_Z;
+		angle = spread_xy;
+		slope = spread_z;
 	}
 	else
 	{
-		angle = pr_crailgun.Random2() * (Spread_XY / 255);
-		slope = pr_crailgun.Random2() * (Spread_Z / 255);
+		angle = pr_crailgun.Random2() * (spread_xy / 255);
+		slope = pr_crailgun.Random2() * (spread_z / 255);
 	}
 
-	P_RailAttack (self, Damage, Spawnofs_XY, Spawnofs_Z, Color1, Color2, MaxDiff, Flags, PuffType, angle, slope, Range, Duration, Sparsity, DriftSpeed, SpawnClass, SpiralOffset);
+	P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angle, slope, range, duration, sparsity, driftspeed, spawnclass, SpiralOffset);
 }
 
 //==========================================================================
@@ -1568,26 +1591,26 @@ enum
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 {
 	ACTION_PARAM_START(17);
-	ACTION_PARAM_INT(Damage, 0);
-	ACTION_PARAM_INT(Spawnofs_XY, 1);
-	ACTION_PARAM_COLOR(Color1, 2);
-	ACTION_PARAM_COLOR(Color2, 3);
-	ACTION_PARAM_INT(Flags, 4);
+	ACTION_PARAM_INT(damage, 0);
+	ACTION_PARAM_INT(spawnofs_xy, 1);
+	ACTION_PARAM_COLOR(color1, 2);
+	ACTION_PARAM_COLOR(color2, 3);
+	ACTION_PARAM_INT(flags, 4);
 	ACTION_PARAM_INT(aim, 5);
-	ACTION_PARAM_DOUBLE(MaxDiff, 6);
-	ACTION_PARAM_CLASS(PuffType, 7);
-	ACTION_PARAM_ANGLE(Spread_XY, 8);
-	ACTION_PARAM_ANGLE(Spread_Z, 9);
-	ACTION_PARAM_FIXED(Range, 10);
-	ACTION_PARAM_INT(Duration, 11);
-	ACTION_PARAM_DOUBLE(Sparsity, 12);
-	ACTION_PARAM_DOUBLE(DriftSpeed, 13);
-	ACTION_PARAM_CLASS(SpawnClass, 14);
-	ACTION_PARAM_FIXED(Spawnofs_Z, 15);
+	ACTION_PARAM_DOUBLE(maxdiff, 6);
+	ACTION_PARAM_CLASS(pufftype, 7);
+	ACTION_PARAM_ANGLE(spread_xy, 8);
+	ACTION_PARAM_ANGLE(spread_z, 9);
+	ACTION_PARAM_FIXED(range, 10);
+	ACTION_PARAM_INT(duration, 11);
+	ACTION_PARAM_DOUBLE(sparsity, 12);
+	ACTION_PARAM_DOUBLE(driftspeed, 13);
+	ACTION_PARAM_CLASS(spawnclass, 14);
+	ACTION_PARAM_FIXED(spawnofs_z, 15);
 	ACTION_PARAM_INT(SpiralOffset, 16);
 
-	if(Range==0) Range=8192*FRACUNIT;
-	if(Sparsity==0) Sparsity=1.0;
+	if (range == 0) range = 8192*FRACUNIT;
+	if (sparsity == 0) sparsity = 1;
 
 	AActor *linetarget;
 
@@ -1631,9 +1654,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 		{
 			// Tricky: We must offset to the angle of the current position
 			// but then change the angle again to ensure proper aim.
-			self->x += Spawnofs_XY * finecosine[self->angle];
-			self->y += Spawnofs_XY * finesine[self->angle];
-			Spawnofs_XY = 0;
+			self->x += spawnofs_xy * finecosine[self->angle];
+			self->y += spawnofs_xy * finesine[self->angle];
+			spawnofs_xy = 0;
 			self->angle = self->AngleTo(self->target,- self->target->velx * 3, -self->target->vely * 3);
 		}
 
@@ -1650,18 +1673,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 	angle_t angleoffset;
 	angle_t slopeoffset;
 
-	if (Flags & CRF_EXPLICITANGLE)
+	if (flags & CRF_EXPLICITANGLE)
 	{
-		angleoffset = Spread_XY;
-		slopeoffset = Spread_Z;
+		angleoffset = spread_xy;
+		slopeoffset = spread_z;
 	}
 	else
 	{
-		angleoffset = pr_crailgun.Random2() * (Spread_XY / 255);
-		slopeoffset = pr_crailgun.Random2() * (Spread_Z / 255);
+		angleoffset = pr_crailgun.Random2() * (spread_xy / 255);
+		slopeoffset = pr_crailgun.Random2() * (spread_z / 255);
 	}
 
-	P_RailAttack (self, Damage, Spawnofs_XY, Spawnofs_Z, Color1, Color2, MaxDiff, Flags, PuffType, angleoffset, slopeoffset, Range, Duration, Sparsity, DriftSpeed, SpawnClass, SpiralOffset);
+	P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angleoffset, slopeoffset, range, duration, sparsity, driftspeed, spawnclass,SpiralOffset);
 
 	self->x = saved_x;
 	self->y = saved_y;
@@ -1901,7 +1924,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
 		{
 			originator = originator->target;
 		}
-	}	
+	}
 	if (flags & SIXF_TELEFRAG) 
 	{
 		P_TeleportMove(mo, mo->x, mo->y, mo->z, true);
@@ -1958,7 +1981,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
 		mo->tracer = NULL;
 	}
 	if (flags & SIXF_SETMASTER)
-	{
+	{ // don't let it attack you (optional)!
 		mo->master = originator;
 	}
 	if (flags & SIXF_SETTARGET)
@@ -2100,7 +2123,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 	ACTION_PARAM_FIXED(xvel, 4);
 	ACTION_PARAM_FIXED(yvel, 5);
 	ACTION_PARAM_FIXED(zvel, 6);
-	ACTION_PARAM_ANGLE(Angle, 7);
+	ACTION_PARAM_ANGLE(angle, 7);
 	ACTION_PARAM_INT(flags, 8);
 	ACTION_PARAM_INT(chance, 9);
 	ACTION_PARAM_INT(tid, 10);
@@ -2116,14 +2139,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 	// Don't spawn monsters if this actor has been massacred
 	if (self->DamageType == NAME_Massacre && GetDefaultByType(missile)->flags3&MF3_ISMONSTER) return;
 
-	fixed_t x,y;
+	fixed_t x, y;
 
 	if (!(flags & SIXF_ABSOLUTEANGLE))
 	{
-		Angle += self->angle;
+		angle += self->angle;
 	}
 
-	angle_t ang = Angle >> ANGLETOFINESHIFT;
+	angle_t ang = angle >> ANGLETOFINESHIFT;
 
 	if (flags & SIXF_ABSOLUTEPOSITION)
 	{
@@ -2169,7 +2192,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 			mo->vely = yvel;
 			mo->velz = zvel;
 		}
-		mo->angle = Angle;
+		mo->angle = angle;
 	}
 }
 
@@ -2254,8 +2277,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Recoil)
 
 	angle_t angle = self->angle + ANG180;
 	angle >>= ANGLETOFINESHIFT;
-	self->velx += FixedMul (xyvel, finecosine[angle]);
-	self->vely += FixedMul (xyvel, finesine[angle]);
+	self->velx += FixedMul(xyvel, finecosine[angle]);
+	self->vely += FixedMul(xyvel, finesine[angle]);
 }
 
 
@@ -2434,12 +2457,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn)
 	self->RenderStyle.Flags &= ~STYLEF_Alpha1;
 	self->alpha += reduce;
 
-	if (self->alpha >= (FRACUNIT * 1))
+	if (self->alpha >= FRACUNIT)
 	{
 		if (flags & FTF_CLAMP)
-			self->alpha = (FRACUNIT * 1);
+		{
+			self->alpha = FRACUNIT;
+		}
 		if (flags & FTF_REMOVE)
+		{
 			P_RemoveThing(self);
+		}
 	}
 }
 
@@ -2465,9 +2492,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut)
 	if (self->alpha <= 0)
 	{
 		if (flags & FTF_CLAMP)
+		{
 			self->alpha = 0;
+		}
 		if (flags & FTF_REMOVE)
+		{
 			P_RemoveThing(self);
+		}
 	}
 }
 
@@ -2508,10 +2539,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo)
 	}
 	if (flags & FTF_CLAMP)
 	{
-		if (self->alpha > (FRACUNIT * 1))
-			self->alpha = (FRACUNIT * 1);
-		else if (self->alpha < 0)
-			self->alpha = 0;
+		self->alpha = clamp(self->alpha, 0, FRACUNIT);
 	}
 	if (self->alpha == target && (flags & FTF_REMOVE))
 	{
@@ -2579,8 +2607,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris)
 	if (debris == NULL) return;
 
 	// only positive values make sense here
-	if (mult_v<=0) mult_v=FRACUNIT;
-	if (mult_h<=0) mult_h=FRACUNIT;
+	if (mult_v <= 0)
+		mult_v = FRACUNIT;
+	if (mult_h <= 0)
+		mult_h = FRACUNIT;
 	
 	for (i = 0; i < GetDefaultByType(debris)->health; i++)
 	{
@@ -3046,8 +3076,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
 		else
 		{
 			// Don't attack yourself (Re: "Marine targets itself after suicide")
-			if (self->target == self) self->target = NULL;
-			if (self->lastenemy == self) self->lastenemy = NULL;
+			if (self->target == self)
+				self->target = NULL;
+			if (self->lastenemy == self)
+				self->lastenemy = NULL;
 		}
 
 		self->flags  = (defs->flags & ~MF_FRIENDLY) | (self->flags & MF_FRIENDLY);
@@ -3487,9 +3519,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfTargetInLOS)
 			target = self->target;
 		}
 
-		if (!target) return; // [KS] Let's not call P_CheckSight unnecessarily in this case.
+		if (target == NULL)
+			return; // [KS] Let's not call P_CheckSight unnecessarily in this case.
 		
-		if ((flags & JLOSF_DEADNOJUMP) && (target->health <= 0)) return;
+		if ((flags & JLOSF_DEADNOJUMP) && (target->health <= 0))
+		{
+			return;
+		}
 
 		doCheckSight = !(flags & JLOSF_NOSIGHT);
 	}
@@ -3678,10 +3714,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckForReload)
 	else
 	{
 		// We need to reload. However, don't reload if we're out of ammo.
-		weapon->CheckAmmo( false, false );
+		weapon->CheckAmmo(false, false);
 	}
 
-	if(!dontincrement)
+	if (!dontincrement)
 		weapon->ReloadCounter = ReloadCounter;
 }
 
@@ -3922,7 +3958,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_MonsterRefire)
 	if (pr_monsterrefire() < prob)
 		return;
 
-	if (!self->target
+	if (self->target == NULL
 		|| P_HitFriend (self)
 		|| self->target->health <= 0
 		|| !P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) )
@@ -3953,8 +3989,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetAngle)
 	ACTION_PARAM_INT(ptr, 2);
 
 	AActor *ref = COPY_AAPTR(self, ptr);
-
-	if (!ref)
+	if (ref != NULL)
 	{
 		ACTION_SET_RESULT(false);
 		return;
@@ -4235,12 +4270,12 @@ enum T_Flags
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 {
 	ACTION_PARAM_START(7);
-	ACTION_PARAM_STATE(TeleportState, 0);
-	ACTION_PARAM_CLASS(TargetType, 1);
-	ACTION_PARAM_CLASS(FogType, 2);
-	ACTION_PARAM_INT(Flags, 3);
-	ACTION_PARAM_FIXED(MinDist, 4);
-	ACTION_PARAM_FIXED(MaxDist, 5);
+	ACTION_PARAM_STATE(teleport_state, 0);
+	ACTION_PARAM_CLASS(target_type, 1);
+	ACTION_PARAM_CLASS(fog_type, 2);
+	ACTION_PARAM_INT(flags, 3);
+	ACTION_PARAM_FIXED(mindist, 4);
+	ACTION_PARAM_FIXED(maxdist, 5);
 	ACTION_PARAM_INT(ptr, 6);
 
 	AActor *ref = COPY_AAPTR(self, ptr);
@@ -4251,14 +4286,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 		return;
 	}
 
-	if ((ref->flags2 & MF2_NOTELEPORT) && !(Flags & TF_OVERRIDE))
+	if ((ref->flags2 & MF2_NOTELEPORT) && !(flags & TF_OVERRIDE))
 	{
 		ACTION_SET_RESULT(false);
 		return;
 	}
 
 	// Randomly choose not to teleport like A_Srcr2Decide.
-	if (Flags & TF_RANDOMDECIDE)
+	if (flags & TF_RANDOMDECIDE)
 	{
 		static const int chance[] =
 		{
@@ -4282,10 +4317,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 		return;
 	}
 
-	if (!TargetType) 
-		TargetType = PClass::FindClass("BossSpot");
+	if (target_type == NULL)
+	{
+		target_type = PClass::FindClass("BossSpot");
+	}
 
-	AActor * spot = state->GetSpotWithMinMaxDistance(TargetType, ref->x, ref->y, MinDist, MaxDist);
+	AActor * spot = state->GetSpotWithMinMaxDistance(target_type, ref->x, ref->y, mindist, maxdist);
 	if (spot == NULL) 
 	{
 		ACTION_SET_RESULT(false);
@@ -4303,76 +4340,76 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 	else if (spot->z < spot->floorz)
 		finalz = spot->floorz;
 
-
 	//Take precedence and cooperate with telefragging first.
-	bool teleResult = P_TeleportMove(ref, spot->x, spot->y, finalz, Flags & TF_TELEFRAG);
+	bool tele_result = P_TeleportMove(ref, spot->x, spot->y, finalz, flags & TF_TELEFRAG);
 
-	if (!teleResult && (Flags & TF_FORCED))
+	if (!tele_result && (flags & TF_FORCED))
 	{
 		//If for some reason the original move didn't work, regardless of telefrag, force it to move.
 		ref->SetOrigin(spot->x, spot->y, finalz);
-		teleResult = true;
+		tele_result = true;
 	}
 
 	AActor *fog1 = NULL, *fog2 = NULL;
-	if (teleResult)
+	if (tele_result)
 	{
-
 		//If a fog type is defined in the parameter, or the user wants to use the actor's predefined fogs,
 		//and if there's no desire to be fogless, spawn a fog based upon settings.
-		if (FogType || (Flags & TF_USEACTORFOG))
+		if (fog_type || (flags & TF_USEACTORFOG))
 		{ 
-			if (!(Flags & TF_NOSRCFOG))
+			if (!(flags & TF_NOSRCFOG))
 			{
-				if (Flags & TF_USEACTORFOG)
+				if (flags & TF_USEACTORFOG)
 					P_SpawnTeleportFog(ref, prevX, prevY, prevZ, true, true);
 				else
 				{
-					fog1 = Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE);
+					fog1 = Spawn(fog_type, prevX, prevY, prevZ, ALLOW_REPLACE);
 					if (fog1 != NULL)
 						fog1->target = ref;
 				}
 			}
-			if (!(Flags & TF_NODESTFOG))
+			if (!(flags & TF_NODESTFOG))
 			{
-				if (Flags & TF_USEACTORFOG)
+				if (flags & TF_USEACTORFOG)
 					P_SpawnTeleportFog(ref, ref->x, ref->y, ref->z, false, true);
 				else
 				{
-					fog2 = Spawn(FogType, ref->x, ref->y, ref->z, ALLOW_REPLACE);
+					fog2 = Spawn(fog_type, ref->x, ref->y, ref->z, ALLOW_REPLACE);
 					if (fog2 != NULL)
 						fog2->target = ref;
 				}
 			}
-			
 		}
 		
-		if (Flags & TF_USESPOTZ)
+		if (flags & TF_USESPOTZ)
 			ref->z = spot->z;
 		else
 			ref->z = ref->floorz;
 
-		if (!(Flags & TF_KEEPANGLE))
+		self->z = (flags & TF_USESPOTZ) ? spot->z : self->floorz;
+
+		if (!(flags & TF_KEEPANGLE))
 			ref->angle = spot->angle;
 
-		if (!(Flags & TF_KEEPVELOCITY))
+		if (!(flags & TF_KEEPVELOCITY))
 			ref->velx = ref->vely = ref->velz = 0;
 
-		if (!(Flags & TF_NOJUMP)) //The state jump should only happen with the calling actor.
+		if (!(flags & TF_NOJUMP)) //The state jump should only happen with the calling actor.
 		{
 			ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
-			if (TeleportState == NULL)
+			if (teleport_state == NULL)
 			{
 				// Default to Teleport.
-				TeleportState = self->FindState("Teleport");
+				teleport_state = self->FindState("Teleport");
 				// If still nothing, then return.
-				if (!TeleportState) return;
+				if (teleport_state == NULL)
+					return;
 			}
-			ACTION_JUMP(TeleportState);
+			ACTION_JUMP(teleport_state);
 			return;
 		}
 	}
-	ACTION_SET_RESULT(teleResult);
+	ACTION_SET_RESULT(tele_result);
 }
 
 //===========================================================================

From 76581115669ee7d25f6b3b3b118ad8083cc7cc95 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Tue, 19 Jan 2016 20:15:45 +0100
Subject: [PATCH 06/23] - refactoriung of thingdef_codeptr.cpp - probably the
 ugliest file in the entire project...

---
 src/actor.h                       |  15 ++
 src/p_local.h                     |   4 +
 src/p_spec.h                      |   4 +
 src/s_sound.cpp                   |   5 +-
 src/thingdef/thingdef_codeptr.cpp | 282 +++++++++++++++---------------
 5 files changed, 164 insertions(+), 146 deletions(-)

diff --git a/src/actor.h b/src/actor.h
index 52b746ef8..b88aa057c 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1291,6 +1291,21 @@ public:
 		y = yy;
 		z = zz;
 	}
+	void SetXY(const fixedvec2 &npos)
+	{
+		x = npos.x;
+		y = npos.y;
+	}
+	void SetXYZ(const fixedvec3 &npos)
+	{
+		x = npos.x;
+		y = npos.y;
+		z = npos.z;
+	}
+	void SetMovement(fixed_t x, fixed_t y, fixed_t z)
+	{
+		// not yet implemented
+	}
 
 };
 
diff --git a/src/p_local.h b/src/p_local.h
index 4e2172a52..4d6a0d447 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -139,6 +139,10 @@ inline AActor *P_SpawnPuff(AActor *source, const PClass *pufftype, const fixedve
 	return P_SpawnPuff(source, pufftype, pos.x, pos.y, pos.z, dir, updown, flags, vict);
 }
 void	P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator);
+inline void	P_SpawnBlood(const fixedvec3 &pos, angle_t dir, int damage, AActor *originator)
+{
+	P_SpawnBlood(pos.x, pos.y, pos.z, dir, damage, originator);
+}
 void	P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
 void	P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator);
 void	P_RipperBlood (AActor *mo, AActor *bleeder);
diff --git a/src/p_spec.h b/src/p_spec.h
index a95e07ce8..2f99e4889 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -903,6 +903,10 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag);
 // P_TELEPT
 //
 void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false).
+inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTele = true, bool setTarget = false)
+{
+	P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget);
+}
 bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false);
 bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool fog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false);
 bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
diff --git a/src/s_sound.cpp b/src/s_sound.cpp
index f388246a9..8508ff728 100644
--- a/src/s_sound.cpp
+++ b/src/s_sound.cpp
@@ -2640,10 +2640,7 @@ CCMD (loopsound)
 		}
 		else
 		{
-			AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->x,
-				players[consoleplayer].mo->y,
-				players[consoleplayer].mo->z + 32*FRACUNIT,
-				ALLOW_REPLACE);
+			AActor *icon = Spawn("SpeakerIcon", players[consoleplayer].mo->PosPlusZ(32*FRACUNIT), ALLOW_REPLACE);
 			if (icon != NULL)
 			{
 				S_Sound(icon, CHAN_BODY | CHAN_LOOP, id, 1.f, ATTN_IDLE);
diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index ccfaa2542..697aa7711 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -326,9 +326,9 @@ static void DoAttack (AActor *self, bool domelee, bool domissile,
 	else if (domissile && MissileType != NULL)
 	{
 		// This seemingly senseless code is needed for proper aiming.
-		self->z += MissileHeight + self->GetBobOffset() - 32*FRACUNIT;
-		AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, MissileType, false);
-		self->z -= MissileHeight + self->GetBobOffset() - 32*FRACUNIT;
+		self->AddZ(MissileHeight + self->GetBobOffset() - 32*FRACUNIT);
+		AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, MissileType, false);
+		self->AddZ(-(MissileHeight + self->GetBobOffset() - 32*FRACUNIT));
 
 		if (missile)
 		{
@@ -672,8 +672,8 @@ void DoJumpIfCloser(AActor *target, DECLARE_PARAMINFO)
 		return;
 	if (self->AproxDistance(target) < dist &&
 		(noz || 
-		((self->z > target->z && self->z - (target->z + target->height) < dist) ||
-		(self->z <= target->z && target->z - (self->z + self->height) < dist))))
+		((self->Z() > target->Z() && self->Z() - target->Top() < dist) ||
+		(self->Z() <= target->Z() && target->Z() - self->Top() < dist))))
 	{
 		ACTION_JUMP(jump);
 	}
@@ -936,30 +936,25 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomMissile)
 			fixed_t y = spawnofs_xy * finesine[ang];
 			fixed_t z = spawnheight + self->GetBobOffset() - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
 
+			fixedvec3 pos = self->Pos();
 			switch (aimmode)
 			{
 			case 0:
 			default:
 				// same adjustment as above (in all 3 directions this time) - for better aiming!
-				self->x += x;
-				self->y += y;
-				self->z += z;
-				missile = P_SpawnMissileXYZ(self->x, self->y, self->z + 32*FRACUNIT, self, ref, ti, false);
-				self->x -= x;
-				self->y -= y;
-				self->z -= z;
+				self->SetXYZ(self->Vec3Offset(x, y, z));
+				missile = P_SpawnMissileXYZ(self->PosPlusZ(32*FRACUNIT), self, ref, ti, false);
+				self->SetXYZ(pos);
 				break;
 
 			case 1:
-				missile = P_SpawnMissileXYZ(self->x+x, self->y+y, self->z + self->GetBobOffset() + spawnheight, self, ref, ti, false);
+				missile = P_SpawnMissileXYZ(self->Vec3Offset(x, y, self->GetBobOffset() + spawnheight), self, ref, ti, false);
 				break;
 
 			case 2:
-				self->x += x;
-				self->y += y;
-				missile = P_SpawnMissileAngleZSpeed(self, self->z + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
- 				self->x -= x;
-				self->y -= y;
+				self->SetXYZ(self->Vec3Offset(x, y, self->Z()));
+				missile = P_SpawnMissileAngleZSpeed(self, self->Z() + self->GetBobOffset() + spawnheight, ti, self->angle, 0, GetDefaultByType(ti)->Speed, self, false);
+				self->SetXYZ(pos);
 
 				flags |= CMF_ABSOLUTEPITCH;
 
@@ -1192,9 +1187,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomComboAttack)
 	else if (ti) 
 	{
 		// This seemingly senseless code is needed for proper aiming.
-		self->z += spawnheight + self->GetBobOffset() - 32*FRACUNIT;
-		AActor *missile = P_SpawnMissileXYZ (self->x, self->y, self->z + 32*FRACUNIT, self, self->target, ti, false);
-		self->z -= spawnheight + self->GetBobOffset() - 32*FRACUNIT;
+		self->AddZ(spawnheight + self->GetBobOffset() - 32*FRACUNIT);
+		AActor *missile = P_SpawnMissileXYZ (self->PosPlusZ(32*FRACUNIT), self, self->target, ti, false);
+		self->AddZ(-(spawnheight + self->GetBobOffset() - 32*FRACUNIT));
 
 		if (missile)
 		{
@@ -1614,8 +1609,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 
 	AActor *linetarget;
 
-	fixed_t saved_x = self->x;
-	fixed_t saved_y = self->y;
+	fixedvec3 savedpos = self->Pos();
 	angle_t saved_angle = self->angle;
 	fixed_t saved_pitch = self->pitch;
 
@@ -1640,9 +1634,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 	if (linetarget == NULL && aim)
 	{
 		// We probably won't hit the target, but aim at it anyway so we don't look stupid.
-		TVector2<double> xydiff(self->target->x - self->x, self->target->y - self->y);
-		double zdiff = (self->target->z + (self->target->height>>1)) -
-						(self->z + (self->height>>1) - self->floorclip);
+		fixedvec2 pos = self->Vec2To(self->target);
+		TVector2<double> xydiff(pos.x, pos.y);
+		double zdiff = (self->target->Z() + (self->target->height>>1)) -
+						(self->Z() + (self->height>>1) - self->floorclip);
 		self->pitch = int(atan2(zdiff, xydiff.Length()) * ANGLE_180 / -M_PI);
 	}
 	// Let the aim trail behind the player
@@ -1654,8 +1649,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 		{
 			// Tricky: We must offset to the angle of the current position
 			// but then change the angle again to ensure proper aim.
-			self->x += spawnofs_xy * finecosine[self->angle];
-			self->y += spawnofs_xy * finesine[self->angle];
+			self->SetXY(self->Vec2Offset(
+				spawnofs_xy * finecosine[self->angle],
+				spawnofs_xy * finesine[self->angle]));
 			spawnofs_xy = 0;
 			self->angle = self->AngleTo(self->target,- self->target->velx * 3, -self->target->vely * 3);
 		}
@@ -1686,8 +1682,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
 
 	P_RailAttack (self, damage, spawnofs_xy, spawnofs_z, color1, color2, maxdiff, flags, pufftype, angleoffset, slopeoffset, range, duration, sparsity, driftspeed, spawnclass,SpiralOffset);
 
-	self->x = saved_x;
-	self->y = saved_y;
+	self->SetXYZ(savedpos);
 	self->angle = saved_angle;
 	self->pitch = saved_pitch;
 }
@@ -1927,7 +1922,7 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags)
 	}
 	if (flags & SIXF_TELEFRAG) 
 	{
-		P_TeleportMove(mo, mo->x, mo->y, mo->z, true);
+		P_TeleportMove(mo, mo->Pos(), true);
 		// This is needed to ensure consistent behavior.
 		// Otherwise it will only spawn if nothing gets telefragged
 		flags |= SIXF_NOCHECKPOSITION;	
@@ -2096,10 +2091,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
 		if (useammo && !weapon->DepleteAmmo(weapon->bAltFire)) return;
 	}
 
-	AActor * mo = Spawn( missile, 
-					self->x + FixedMul(distance, finecosine[self->angle>>ANGLETOFINESHIFT]), 
-					self->y + FixedMul(distance, finesine[self->angle>>ANGLETOFINESHIFT]), 
-					self->z - self->floorclip + self->GetBobOffset() + zheight, ALLOW_REPLACE);
+	AActor * mo = Spawn( missile, self->Vec3Angle(distance, self->angle, -self->floorclip + self->GetBobOffset() + zheight), ALLOW_REPLACE);
 
 	int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
 	bool res = InitSpawnedItem(self, mo, flags);
@@ -2139,7 +2131,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 	// Don't spawn monsters if this actor has been massacred
 	if (self->DamageType == NAME_Massacre && GetDefaultByType(missile)->flags3&MF3_ISMONSTER) return;
 
-	fixed_t x, y;
+	fixedvec2 pos;
 
 	if (!(flags & SIXF_ABSOLUTEANGLE))
 	{
@@ -2150,15 +2142,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 
 	if (flags & SIXF_ABSOLUTEPOSITION)
 	{
-		x = self->x + xofs;
-		y = self->y + yofs;
+		pos = self->Vec2Offset(xofs, yofs);
 	}
 	else
 	{
 		// in relative mode negative y values mean 'left' and positive ones mean 'right'
 		// This is the inverse orientation of the absolute mode!
-		x = self->x + FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]);
-		y = self->y + FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]);
+		pos = self->Vec2Offset(
+			FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]),
+			FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang]));
 	}
 
 	if (!(flags & SIXF_ABSOLUTEVELOCITY))
@@ -2169,7 +2161,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItemEx)
 		xvel = newxvel;
 	}
 
-	AActor *mo = Spawn(missile, x, y, self->z - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE);
+	AActor *mo = Spawn(missile, pos.x, pos.y, self->Z() - self->floorclip + self->GetBobOffset() + zofs, ALLOW_REPLACE);
 	bool res = InitSpawnedItem(self, mo, flags);
 	ACTION_SET_RESULT(res);	// for an inventory item's use state
 	if (res)
@@ -2226,8 +2218,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade)
 
 	AActor * bo;
 
-	bo = Spawn(missile, self->x, self->y, 
-			self->z - self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0),
+	bo = Spawn(missile, 
+			self->PosPlusZ(-self->floorclip + self->GetBobOffset() + zheight + 35*FRACUNIT + (self->player? self->player->crouchoffset : 0)),
 			ALLOW_REPLACE);
 	if (bo)
 	{
@@ -2614,9 +2606,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris)
 	
 	for (i = 0; i < GetDefaultByType(debris)->health; i++)
 	{
-		mo = Spawn(debris, self->x+((pr_spawndebris()-128)<<12),
-			self->y + ((pr_spawndebris()-128)<<12), 
-			self->z + (pr_spawndebris()*self->height/256+self->GetBobOffset()), ALLOW_REPLACE);
+		mo = Spawn(debris, self->Vec3Offset(
+			((pr_spawndebris()-128)<<12),
+			((pr_spawndebris()-128)<<12), 
+			(pr_spawndebris()*self->height/256+self->GetBobOffset())), ALLOW_REPLACE);
 		if (mo)
 		{
 			if (transfer_translation)
@@ -2683,23 +2676,22 @@ static bool DoCheckSightOrRange(AActor *self, AActor *camera, double range, bool
 		return false;
 	}
 	// Check distance first, since it's cheaper than checking sight.
-	double dx = self->x - camera->x;
-	double dy = self->y - camera->y;
-	double dz;
-	fixed_t eyez = (camera->z + camera->height - (camera->height>>2));	// same eye height as P_CheckSight
-	if (eyez > self->z + self->height)
+	fixedvec2 pos = camera->Vec2To(self);
+	fixed_t dz;
+	fixed_t eyez = (camera->Top() - (camera->height>>2));	// same eye height as P_CheckSight
+	if (eyez > self->Top())
 	{
-		dz = self->z + self->height - eyez;
+		dz = self->Top() - eyez;
 	}
-	else if (eyez < self->z)
+	else if (eyez < self->Z())
 	{
-		dz = self->z - eyez;
+		dz = self->Z() - eyez;
 	}
 	else
 	{
 		dz = 0;
 	}
-	double distance = (dx * dx) + (dy * dy) + (twodi == 0? (dz * dz) : 0);
+	double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0);
 	if (distance <= range){
 		// Within range
 		return true;
@@ -2756,20 +2748,23 @@ static bool DoCheckRange(AActor *self, AActor *camera, double range, bool twodi)
 		return false;
 	}
 	// Check distance first, since it's cheaper than checking sight.
-	double dx = self->x - camera->x;
-	double dy = self->y - camera->y;
-	double dz;
-	fixed_t eyez = (camera->z + camera->height - (camera->height>>2));	// same eye height as P_CheckSight
-	if (eyez > self->z + self->height){
-		dz = self->z + self->height - eyez;
+	fixedvec2 pos = camera->Vec2To(self);
+	fixed_t dz;
+	fixed_t eyez = (camera->Top() - (camera->height>>2));	// same eye height as P_CheckSight
+	if (eyez > self->Top())
+	{
+		dz = self->Top() - eyez;
 	}
-	else if (eyez < self->z){
-		dz = self->z - eyez;
+	else if (eyez < self->Z())
+	{
+		dz = self->Z() - eyez;
 	}
-	else{
+	else
+	{
 		dz = 0;
 	}
-	double distance = (dx * dx) + (dy * dy) + (twodi == 0? (dz * dz) : 0);
+	double distance = ((double)pos.x * pos.x) + ((double)pos.y * pos.y) + (twodi == 0? ((double)dz * dz) : 0);
+
 	if (distance <= range){
 		// Within range
 		return true;
@@ -2929,14 +2924,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
 	i = (pr_burst.Random2()) % (numChunks/4);
 	for (i = MAX (24, numChunks + i); i >= 0; i--)
 	{
-		mo = Spawn(chunk,
-			self->x + (((pr_burst()-128)*self->radius)>>7),
-			self->y + (((pr_burst()-128)*self->radius)>>7),
-			self->z + (pr_burst()*self->height/255 + self->GetBobOffset()), ALLOW_REPLACE);
+		mo = Spawn(chunk, self->Vec3Offset( 
+			(((pr_burst()-128)*self->radius)>>7),
+			(((pr_burst()-128)*self->radius)>>7),
+			(pr_burst()*self->height/255 + self->GetBobOffset())), ALLOW_REPLACE);
 
 		if (mo)
 		{
-			mo->velz = FixedDiv(mo->z - self->z, self->height)<<2;
+			mo->velz = FixedDiv(mo->Z() - self->Z(), self->height)<<2;
 			mo->velx = pr_burst.Random2 () << (FRACBITS-7);
 			mo->vely = pr_burst.Random2 () << (FRACBITS-7);
 			mo->RenderStyle = self->RenderStyle;
@@ -2967,7 +2962,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFloor)
 	ACTION_PARAM_STATE(jump, 0);
 
 	ACTION_SET_RESULT(false);	// Jumps should never set the result for inventory state chains!
-	if (self->z <= self->floorz)
+	if (self->Z() <= self->floorz)
 	{
 		ACTION_JUMP(jump);
 	}
@@ -2987,7 +2982,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckCeiling)
 	ACTION_PARAM_STATE(jump, 0);
 
 	ACTION_SET_RESULT(false);
-	if (self->z+self->height >= self->ceilingz) // Height needs to be counted
+	if (self->Top() >= self->ceilingz) // Height needs to be counted
 	{
 		ACTION_JUMP(jump);
 	}
@@ -3042,9 +3037,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
 	ACTION_PARAM_START(1);
 	ACTION_PARAM_INT(flags, 0);
 	bool oktorespawn = false;
-	fixed_t oldx = self->x;
-	fixed_t oldy = self->y;
-	fixed_t oldz = self->z;
+	fixedvec3 pos = self->Pos();
 	self->flags |= MF_SOLID;
 	self->height = self->GetDefault()->height;
 	self->radius = self->GetDefault()->radius;
@@ -3053,11 +3046,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
 	if (flags & RSF_TELEFRAG)
 	{
 		// [KS] DIE DIE DIE DIE erm *ahem* =)
-		oktorespawn = P_TeleportMove(self, self->x, self->y, self->z, true, false);
+		oktorespawn = P_TeleportMove(self, self->Pos(), true, false);
 	}
 	else
 	{
-		oktorespawn = P_CheckPosition(self, self->x, self->y, true);
+		oktorespawn = P_CheckPosition(self, self->X(), self->Y(), true);
 	}
 
 	if (oktorespawn)
@@ -3094,8 +3087,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn)
 
 		if (flags & RSF_FOG)
 		{
-			P_SpawnTeleportFog(self, oldx, oldy, oldz, true, true);
-			P_SpawnTeleportFog(self, self->x, self->y, self->z, false, true);
+			P_SpawnTeleportFog(self, pos, true, true);
+			P_SpawnTeleportFog(self, self->Pos(), false, true);
 		}
 		if (self->CountsAsKill())
 		{
@@ -3294,9 +3287,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 	*/
 
 	AActor *target;
-	fixed_t
-		x1, y1, z1,
-		vx, vy, vz;
+	fixedvec3 pos;
+	fixed_t	vx, vy, vz;
 
 	ACTION_PARAM_START(9);
 	
@@ -3332,29 +3324,27 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 			offsetwidth = FixedMul(self->radius, offsetwidth);
 		}
 		
-		x1 = self->x;
-		y1 = self->y;
-		z1 = self->z + offsetheight - self->floorclip;
+		pos = self->PosPlusZ(offsetheight - self->floorclip);
 
 		if (!(flags & CLOFF_FROMBASE))
 		{ // default to hitscan origin
 
 			// Synced with hitscan: self->height is strangely NON-conscientious about getting the right actor for player
-			z1 += (self->height >> 1);
+			pos.z += (self->height >> 1);
 			if (self->player != NULL)
 			{
-				z1 += FixedMul (self->player->mo->AttackZOffset, self->player->crouchfactor);
+				pos.z += FixedMul (self->player->mo->AttackZOffset, self->player->crouchfactor);
 			}
 			else
 			{
-				z1 += 8*FRACUNIT;
+				pos.z += 8*FRACUNIT;
 			}
 		}
 
 		if (target)
 		{
 			fixed_t xydist = self->Distance2D(target);
-			fixed_t distance = P_AproxDistance(xydist, target->z - z1);
+			fixed_t distance = P_AproxDistance(xydist, target->Z() - pos.z);
 
 			if (range && !(flags & CLOFF_CHECKPARTIAL))
 			{
@@ -3373,8 +3363,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 				angle += ang;
 				
 				ang >>= ANGLETOFINESHIFT;
-				x1 += FixedMul(offsetwidth, finesine[ang]);
-				y1 -= FixedMul(offsetwidth, finecosine[ang]);
+
+				fixedvec2 xy = self->Vec2Offset(
+					FixedMul(offsetwidth, finesine[ang]),
+					-FixedMul(offsetwidth, finecosine[ang]));
+
+				pos.x = xy.x;
+				pos.y = xy.y;
 			}
 
 			if (flags & CLOFF_NOAIM_VERT)
@@ -3383,11 +3378,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 			}
 			else if (flags & CLOFF_AIM_VERT_NOOFFSET)
 			{
-				pitch += R_PointToAngle2 (0,0, xydist, target->z - z1 + offsetheight + target->height / 2);
+				pitch += R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + offsetheight + target->height / 2);
 			}
 			else
 			{
-				pitch += R_PointToAngle2 (0,0, xydist, target->z - z1 + target->height / 2);
+				pitch += R_PointToAngle2 (0,0, xydist, target->Z() - pos.z + target->height / 2);
 			}
 		}
 		else if (flags & CLOFF_ALLOWNULL)
@@ -3396,8 +3391,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 			pitch += self->pitch;
 
 			angle_t ang = self->angle >> ANGLETOFINESHIFT;
-			x1 += FixedMul(offsetwidth, finesine[ang]);
-			y1 -= FixedMul(offsetwidth, finecosine[ang]);
+
+			fixedvec2 xy = self->Vec2Offset(
+				FixedMul(offsetwidth, finesine[ang]),
+				-FixedMul(offsetwidth, finecosine[ang]));
+
+			pos.x = xy.x;
+			pos.y = xy.y;
 		}
 		else return;
 
@@ -3417,7 +3417,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 		range
 	*/
 
-	sector_t *sec = P_PointInSector(x1, y1);
+	sector_t *sec = P_PointInSector(pos.x, pos.y);
 
 	if (range == 0)
 	{
@@ -3432,7 +3432,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF)
 	lof_data.Flags = flags;
 	lof_data.BadActor = false;
 
-	Trace(x1, y1, z1, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, 0,
+	Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, 0,
 		CheckLOFTraceFunc, &lof_data);
 
 	if (trace.HitType == TRACE_HitActor ||
@@ -4322,31 +4322,29 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 		target_type = PClass::FindClass("BossSpot");
 	}
 
-	AActor * spot = state->GetSpotWithMinMaxDistance(target_type, ref->x, ref->y, mindist, maxdist);
+	AActor * spot = state->GetSpotWithMinMaxDistance(target_type, ref->X(), ref->Y(), mindist, maxdist);
 	if (spot == NULL) 
 	{
 		ACTION_SET_RESULT(false);
 		return;
 	}
 
-	fixed_t prevX = ref->x;
-	fixed_t prevY = ref->y;
-	fixed_t prevZ = ref->z;
-	fixed_t aboveFloor = spot->z - spot->floorz;
+	fixedvec3 prev = ref->Pos();
+	fixed_t aboveFloor = spot->Z() - spot->floorz;
 	fixed_t finalz = spot->floorz + aboveFloor;
 
-	if (spot->z + ref->height > spot->ceilingz)
+	if (spot->Z() + ref->height > spot->ceilingz)
 		finalz = spot->ceilingz - ref->height;
-	else if (spot->z < spot->floorz)
+	else if (spot->Z() < spot->floorz)
 		finalz = spot->floorz;
 
 	//Take precedence and cooperate with telefragging first.
-	bool tele_result = P_TeleportMove(ref, spot->x, spot->y, finalz, flags & TF_TELEFRAG);
+	bool tele_result = P_TeleportMove(ref, spot->X(), spot->Y(), finalz, flags & TF_TELEFRAG);
 
 	if (!tele_result && (flags & TF_FORCED))
 	{
 		//If for some reason the original move didn't work, regardless of telefrag, force it to move.
-		ref->SetOrigin(spot->x, spot->y, finalz);
+		ref->SetOrigin(spot->X(), spot->Y(), finalz, false);
 		tele_result = true;
 	}
 
@@ -4360,10 +4358,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 			if (!(flags & TF_NOSRCFOG))
 			{
 				if (flags & TF_USEACTORFOG)
-					P_SpawnTeleportFog(ref, prevX, prevY, prevZ, true, true);
+					P_SpawnTeleportFog(ref, prev, true, true);
 				else
 				{
-					fog1 = Spawn(fog_type, prevX, prevY, prevZ, ALLOW_REPLACE);
+					fog1 = Spawn(fog_type, prev, ALLOW_REPLACE);
 					if (fog1 != NULL)
 						fog1->target = ref;
 				}
@@ -4371,22 +4369,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 			if (!(flags & TF_NODESTFOG))
 			{
 				if (flags & TF_USEACTORFOG)
-					P_SpawnTeleportFog(ref, ref->x, ref->y, ref->z, false, true);
+					P_SpawnTeleportFog(ref, ref->Pos(), false, true);
 				else
 				{
-					fog2 = Spawn(fog_type, ref->x, ref->y, ref->z, ALLOW_REPLACE);
+					fog2 = Spawn(fog_type, ref->Pos(), ALLOW_REPLACE);
 					if (fog2 != NULL)
 						fog2->target = ref;
 				}
 			}
 		}
 		
-		if (flags & TF_USESPOTZ)
-			ref->z = spot->z;
-		else
-			ref->z = ref->floorz;
-
-		self->z = (flags & TF_USESPOTZ) ? spot->z : self->floorz;
+		ref->SetZ((flags & TF_USESPOTZ) ? spot->Z() : ref->floorz, false);
+		self->SetZ((flags & TF_USESPOTZ) ? spot->Z() : self->floorz, false);
 
 		if (!(flags & TF_KEEPANGLE))
 			ref->angle = spot->angle;
@@ -4487,8 +4481,8 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis
 	if (xydist != 0 && xyspeed != 0)
 	{
 		dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist);
-		newX = self->x - FixedMul (finecosine[angle], dist);
-		newY = self->y - FixedMul (finesine[angle], dist);
+		newX = self->X() - FixedMul (finecosine[angle], dist);
+		newY = self->Y() - FixedMul (finesine[angle], dist);
 		weaveXY = (weaveXY + xyspeed) & 63;
 		dist = MulScale13(finesine[weaveXY << BOBTOFINESHIFT], xydist);
 		newX += FixedMul (finecosine[angle], dist);
@@ -4501,17 +4495,22 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis
 		{
 			self->UnlinkFromWorld ();
 			self->flags |= MF_NOBLOCKMAP;
-			self->x = newX;
-			self->y = newY;
+			// the following 4 lines are for future-proofing this for both interpolation overhaul and line portals.
+			// For portals we need to calculate the destination including the portal offset
+			// and for interpolation we need to set the performed movement explicitly, because SetXY cannot do that.
+			newX -= self->X();
+			newY -= self->Y();
+			self->SetXY(self->Vec2Offset(newX, newY));
+			self->SetMovement(newX, newY, 0);
 			self->LinkToWorld ();
 		}
 		self->WeaveIndexXY = weaveXY;
 	}
 	if (zdist != 0 && zspeed != 0)
 	{
-		self->z -= MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist);
+		self->AddZ(-MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist));
 		weaveZ = (weaveZ + zspeed) & 63;
-		self->z += MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist);
+		self->AddZ(MulScale13(finesine[weaveZ << BOBTOFINESHIFT], zdist));
 		self->WeaveIndexZ = weaveZ;
 	}
 }
@@ -4601,8 +4600,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
 	bool dodge = (P_CheckSight(self->target, self) && (angle>226 || angle<30));
 
 	// Distance check is simplistic
-	fixed_t dx = abs (self->x - self->target->x);
-	fixed_t dy = abs (self->y - self->target->y);
+	fixedvec2 vec = self->Vec2To(self->target);
+	fixed_t dx = abs (vec.x);
+	fixed_t dy = abs (vec.y);
 	fixed_t dz;
 	fixed_t dist = dx > dy ? dx : dy;
 
@@ -4632,13 +4632,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
 	if (pr_cabullet() < hitchance)
 	{
 		// Compute position for spawning blood/puff
-		dx = self->target->x;
-		dy = self->target->y;
-		dz = self->target->z + (self->target->height>>1);
 		angle = self->target->AngleTo(self);
 		
-		dx += FixedMul(self->target->radius, finecosine[angle>>ANGLETOFINESHIFT]);
-		dy += FixedMul(self->target->radius, finesine[angle>>ANGLETOFINESHIFT]);
+		fixedvec3 bloodpos = self->target->Vec3Angle(self->target->radius, angle, self->target->height >> 1);
+
 
 		int damage = flags & WAF_NORANDOM ? maxdamage : (1 + (pr_cabullet() % maxdamage));
 		if (dist >= pointblank)
@@ -4659,7 +4656,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
 			if ((0 && dpuff->flags3 & MF3_PUFFONACTORS) || !spawnblood)
 			{
 				spawnblood = false;
-				P_SpawnPuff(self, pufftype, dx, dy, dz, angle, 0);
+				P_SpawnPuff(self, pufftype, bloodpos, angle, 0);
 			}
 		}
 		else if (self->target->flags3 & MF3_GHOST)
@@ -4669,7 +4666,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
 			int newdam = P_DamageMobj(self->target, self, self, damage, mod, DMG_THRUSTLESS);
 			if (spawnblood)
 			{
-				P_SpawnBlood(dx, dy, dz, angle, newdam > 0 ? newdam : damage, self->target);
+				P_SpawnBlood(bloodpos, angle, newdam > 0 ? newdam : damage, self->target);
 				P_TraceBleed(newdam > 0 ? newdam : damage, self->target, self->AngleTo(dx, dy, self->target), 0);
 			}
 		}
@@ -4917,7 +4914,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
 	{
 		amount = 1;
 	}
-	FBlockThingsIterator it(FBoundingBox(self->x, self->y, distance));
+	FBlockThingsIterator it(FBoundingBox(self->X(), self->Y(), distance));
 
 	AActor *thing;
 	bool given = false;
@@ -4990,11 +4987,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
 		if (selfPass || monsterPass || corpsePass || killedPass || itemPass || objectPass || missilePass || playerPass || voodooPass)
 		{
 
+			fixedvec3 diff = self->Vec3To(thing);
+			diff.z += (thing->height - self->height) / 2;
 			if (flags & RGF_CUBE)
 			{ // check if inside a cube
-				double dx = fabs((double)(thing->x - self->x));
-				double dy = fabs((double)(thing->y - self->y));
-				double dz = fabs((double)(thing->z + thing->height / 2) - (self->z + self->height / 2));
+				double dx = fabs((double)(diff.x));
+				double dy = fabs((double)(diff.y));
+				double dz = fabs((double)(diff.z));
 				double dist = (double)distance;
 				double min = (double)mindist;
 				if ((dx > dist || dy > dist || dz > dist) || (min && (dx < min && dy < min && dz < min)))
@@ -5006,9 +5005,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive)
 			{ // check if inside a sphere
 				double distsquared = double(distance) * double(distance);
 				double minsquared = double(mindist) * double(mindist);
-				TVector3<double> tpos(thing->x, thing->y, thing->z + thing->height / 2);
-				TVector3<double> spos(self->x, self->y, self->z + self->height / 2);
-				if ((tpos - spos).LengthSquared() > distsquared || (minsquared && ((tpos - spos).LengthSquared() < minsquared)))
+				double lengthsquared = TVector3<double>(diff.x, diff.y, diff.z).LengthSquared();
+				if (lengthsquared > distsquared || (minsquared && (lengthsquared < minsquared)))
 				{
 					continue;
 				}
@@ -5834,9 +5832,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower)
 	}
 	ACTION_SET_RESULT(false); //No inventory jump chains please.
 
-	if ((high) && (mobj->z > ((includeHeight ? self->height : 0) + self->z + offsethigh)))
+	if ((high) && (mobj->Z() > ((includeHeight ? self->height : 0) + self->Z() + offsethigh)))
 		ACTION_JUMP(high);
-	else if ((low) && (mobj->z + (includeHeight ? mobj->height : 0)) < (self->z + offsetlow))
+	else if ((low) && (mobj->Z() + (includeHeight ? mobj->height : 0)) < (self->Z() + offsetlow))
 		ACTION_JUMP(low);
 }
 
@@ -5958,8 +5956,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckProximity)
 		//Make sure it's in range and respect the desire for Z or not.
 		if (ref->AproxDistance(mo) < distance &&
 			((flags & CPXF_NOZ) ||
-			((ref->z > mo->z && ref->z - (mo->z + mo->height) < distance) ||
-			(ref->z <= mo->z && mo->z - (ref->z + ref->height) < distance))))
+			((ref->Z() > mo->Z() && ref->Top() < distance) ||
+			(ref->Z() <= mo->Z() && mo->Z() - ref->Top() < distance))))
 		{
 			if (mo->flags6 & MF6_KILLED)
 			{

From 9b9008ecc7b1d6c870273739289fbcc911ed68fb Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@users.noreply.github.com>
Date: Tue, 19 Jan 2016 18:00:46 -0600
Subject: [PATCH 07/23] Restore original offset range for WraithFX5 spawn

---
 src/g_hexen/a_wraith.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp
index 312585cdf..dc7d50009 100644
--- a/src/g_hexen/a_wraith.cpp
+++ b/src/g_hexen/a_wraith.cpp
@@ -215,8 +215,8 @@ void A_WraithFX4 (AActor *self)
 	if (spawn5)
 	{
 		fixedvec3 pos = self->Vec3Offset(
-			(pr_wraithfx4()-128)<<12,
-			(pr_wraithfx4()-128)<<12,
+			(pr_wraithfx4()-128)<<11,
+			(pr_wraithfx4()-128)<<11,
 			(pr_wraithfx4()<<10));
 
 		mo = Spawn ("WraithFX5", pos, ALLOW_REPLACE);

From 7ea3e49332d3ca3e0b312a7ad5e5715719125169 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 01:48:57 +0100
Subject: [PATCH 08/23] - refactored p_mobj.cpp and the first half of
 p_map.cpp.

---
 src/actor.h                       |  31 +++
 src/p_map.cpp                     | 336 +++++++++++++++--------------
 src/p_mobj.cpp                    | 343 +++++++++++++++---------------
 src/po_man.cpp                    |  15 +-
 src/s_sound.cpp                   |  37 ++--
 src/thingdef/thingdef_codeptr.cpp |   1 -
 6 files changed, 403 insertions(+), 360 deletions(-)

diff --git a/src/actor.h b/src/actor.h
index b88aa057c..1d73e1698 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1252,6 +1252,33 @@ public:
 		fixedvec3 ret = { X(), Y(), Z() };
 		return ret;
 	}
+	fixedvec3 PosRelative(AActor *other) const
+	{
+		fixedvec3 ret = { X(), Y(), Z() };
+		return ret;
+	}
+	fixedvec3 PosRelative(sector_t *sec) const
+	{
+		fixedvec3 ret = { X(), Y(), Z() };
+		return ret;
+	}
+	fixedvec3 PosRelative(line_t *line) const
+	{
+		fixedvec3 ret = { X(), Y(), Z() };
+		return ret;
+	}
+	fixed_t SoundX() const
+	{
+		return X();
+	}
+	fixed_t SoundY() const
+	{
+		return Y();
+	}
+	fixed_t SoundZ() const
+	{
+		return Z();
+	}
 	fixedvec3 InterpolatedPosition(fixed_t ticFrac) const
 	{
 		fixedvec3 ret;
@@ -1418,6 +1445,10 @@ inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
 	return ret;
 }
 
+inline fixedvec3 PosRelative(const fixedvec3 &pos, line_t *line, sector_t *refsec = NULL)
+{
+	return pos;
+}
 
 void PrintMiscActorInfo(AActor * query);
 
diff --git a/src/p_map.cpp b/src/p_map.cpp
index 69f8b6c5b..259becd67 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -581,7 +581,7 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
 		friction = FRICTION_FLY;
 	}
 	else if ((!(mo->flags & MF_NOGRAVITY) && mo->waterlevel > 1) ||
-		(mo->waterlevel == 1 && mo->z > mo->floorz + 6 * FRACUNIT))
+		(mo->waterlevel == 1 && mo->Z() > mo->floorz + 6 * FRACUNIT))
 	{
 		friction = secfriction(mo->Sector);
 		movefactor = secmovefac(mo->Sector) >> 1;
@@ -593,8 +593,8 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
 				if (!(rover->flags & FF_EXISTS)) continue;
 				if (!(rover->flags & FF_SWIMMABLE)) continue;
 
-				if (mo->z > rover->top.plane->ZatPoint(mo) ||
-					mo->z < rover->bottom.plane->ZatPoint(mo))
+				if (mo->Z() > rover->top.plane->ZatPoint(mo) ||
+					mo->Z() < rover->bottom.plane->ZatPoint(mo))
 					continue;
 
 				newfriction = secfriction(rover->model, rover->top.isceiling);
@@ -623,13 +623,13 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
 				if (rover->flags & FF_SOLID)
 				{
 					// Must be standing on a solid floor
-					if (mo->z != rover->top.plane->ZatPoint(mo)) continue;
+					if (mo->Z() != rover->top.plane->ZatPoint(mo)) continue;
 				}
 				else if (rover->flags & FF_SWIMMABLE)
 				{
 					// Or on or inside a swimmable floor (e.g. in shallow water)
-					if (mo->z > rover->top.plane->ZatPoint(mo) ||
-						(mo->z + mo->height) < rover->bottom.plane->ZatPoint(mo))
+					if (mo->Z() > rover->top.plane->ZatPoint(mo) ||
+						(mo->Top()) < rover->bottom.plane->ZatPoint(mo))
 						continue;
 				}
 				else
@@ -650,9 +650,9 @@ int P_GetFriction(const AActor *mo, int *frictionfactor)
 			}
 			newfriction = secfriction(sec);
 			if ((newfriction < friction || friction == ORIG_FRICTION) &&
-				(mo->z <= sec->floorplane.ZatPoint(mo) ||
+				(mo->Z() <= sec->floorplane.ZatPoint(mo) ||
 				(sec->GetHeightSec() != NULL &&
-				mo->z <= sec->heightsec->floorplane.ZatPoint(mo))))
+				mo->Z() <= sec->heightsec->floorplane.ZatPoint(mo))))
 			{
 				friction = newfriction;
 				movefactor = secmovefac(sec);
@@ -768,6 +768,7 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
 	bool NotBlocked = ((tm.thing->flags3 & MF3_NOBLOCKMONST)
 		|| ((i_compatflags & COMPATF_NOBLOCKFRIENDS) && (tm.thing->flags & MF_FRIENDLY)));
 
+	fixedvec3 pos = tm.thing->PosRelative(ld);
 	if (!(Projectile) || (ld->flags & (ML_BLOCKEVERYTHING | ML_BLOCKPROJECTILE)))
 	{
 		if (ld->flags & ML_RAILING)
@@ -786,7 +787,7 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
 			}
 			tm.thing->BlockingLine = ld;
 			// Calculate line side based on the actor's original position, not the new one.
-			CheckForPushSpecial(ld, P_PointOnLineSide(tm.thing->x, tm.thing->y, ld), tm.thing, false);
+			CheckForPushSpecial(ld, P_PointOnLineSide(pos.x, pos.y, ld), tm.thing, false);
 			return false;
 		}
 	}
@@ -797,8 +798,8 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
 	{
 		secplane_t frontplane, backplane;
 		// Check 3D floors as well
-		frontplane = P_FindFloorPlane(ld->frontsector, tm.thing->x, tm.thing->y, tm.thing->floorz);
-		backplane = P_FindFloorPlane(ld->backsector, tm.thing->x, tm.thing->y, tm.thing->floorz);
+		frontplane = P_FindFloorPlane(ld->frontsector, pos.x, pos.y, tm.thing->floorz);
+		backplane = P_FindFloorPlane(ld->backsector, pos.x, pos.y, tm.thing->floorz);
 		if (frontplane.c < STEEPSLOPE || backplane.c < STEEPSLOPE)
 		{
 			const msecnode_t *node = tm.thing->touching_sectorlist;
@@ -853,7 +854,7 @@ bool PIT_CheckLine(line_t *ld, const FBoundingBox &box, FCheckPosition &tm)
 		}
 		else if (r >= (1 << 24))
 		{
-			P_LineOpening(open, tm.thing, ld, sx = ld->v2->x, sy = ld->v2->y, tm.thing->x, tm.thing->y);
+			P_LineOpening(open, tm.thing, ld, sx = ld->v2->x, sy = ld->v2->y, pos.x, pos.y);
 		}
 		else
 		{
@@ -1031,8 +1032,9 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 	if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY))
 		return true;	// can't hit thing
 
+	fixedvec3 thingpos = thing->PosRelative(tm.thing);
 	fixed_t blockdist = thing->radius + tm.thing->radius;
-	if (abs(thing->x - tm.x) >= blockdist || abs(thing->y - tm.y) >= blockdist)
+	if (abs(thingpos.x - tm.thing->X()) >= blockdist || abs(thingpos.y - tm.thing->Y()) >= blockdist)
 		return true;
 
 	if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS)
@@ -1042,13 +1044,13 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 		return true;
 
 	tm.thing->BlockingMobj = thing;
-	topz = thing->z + thing->height;
+	topz = thing->Top();
 	if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) &&
 		(thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE))
 	{
 		// [RH] Let monsters walk on actors as well as floors
 		if ((tm.thing->flags3 & MF3_ISMONSTER) &&
-			topz >= tm.floorz && topz <= tm.thing->z + tm.thing->MaxStepHeight)
+			topz >= tm.floorz && topz <= tm.thing->Z() + tm.thing->MaxStepHeight)
 		{
 			// The commented-out if is an attempt to prevent monsters from walking off a
 			// thing further than they would walk off a ledge. I can't think of an easy
@@ -1071,12 +1073,12 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 	{
 		// Both actors already overlap. To prevent them from remaining stuck allow the move if it
 		// takes them further apart or the move does not change the position (when called from P_ChangeSector.)
-		if (tm.x == tm.thing->x && tm.y == tm.thing->y)
+		if (tm.x == tm.thing->X() && tm.y == tm.thing->Y())
 		{
 			unblocking = true;
 		}
-		else if (abs(thing->x - tm.thing->x) < (thing->radius+tm.thing->radius) &&
-				 abs(thing->y - tm.thing->y) < (thing->radius+tm.thing->radius))
+		else if (abs(thingpos.x - tm.thing->X()) < (thing->radius+tm.thing->radius) &&
+				 abs(thingpos.y - tm.thing->Y()) < (thing->radius+tm.thing->radius))
 
 		{
 			fixed_t newdist = thing->AproxDistance(tm.x, tm.y, tm.thing);
@@ -1085,8 +1087,8 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 			if (newdist > olddist)
 			{
 				// ... but not if they did not overlap in z-direction before but would after the move.
-				unblocking = !((tm.thing->z >= thing->z + thing->height && tm.z < thing->z + thing->height) ||
-					(tm.thing->z + tm.thing->height <= thing->z && tm.z + tm.thing->height > thing->z));
+				unblocking = !((tm.thing->Z() >= thingpos.z + thing->height && tm.z < thingpos.z + thing->height) ||
+					(tm.thing->Top() <= thingpos.z && tm.thing->Top() > thingpos.z));
 			}
 		}
 	}
@@ -1104,7 +1106,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 			{ // Some things prefer not to overlap each other, if possible
 				return unblocking;
 			}
-			if ((tm.thing->z >= topz) || (tm.thing->z + tm.thing->height <= thing->z))
+			if ((tm.thing->Z() >= topz) || (tm.thing->Top() <= thing->Z()))
 				return true;
 		}
 	}
@@ -1120,7 +1122,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 			// or different species if DONTHARMSPECIES
 			(!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) &&
 			// touches vertically
-			thing->z + thing->height >= tm.thing->z && tm.thing->z + tm.thing->height >= thing->z &&
+			topz >= tm.thing->Z() && tm.thing->Z() + tm.thing->height >= thingpos.z &&
 			// prevents lost souls from exploding when fired by pain elementals
 			(thing->master != tm.thing && tm.thing->master != thing))
 			// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
@@ -1223,11 +1225,11 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 		}
 
 		// Check if it went over / under
-		if (tm.thing->z > thing->z + clipheight)
+		if (tm.thing->Z() > thingpos.z + clipheight)
 		{ // Over thing
 			return true;
 		}
-		if (tm.thing->z + tm.thing->height < thing->z)
+		if (tm.thing->Top() < thingpos.z)
 		{ // Under thing
 			return true;
 		}
@@ -1335,7 +1337,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 					!(tm.thing->flags3 & MF3_BLOODLESSIMPACT) &&
 					(pr_checkthing() < 192))
 				{
-					P_BloodSplatter(tm.thing->x, tm.thing->y, tm.thing->z, thing);
+					P_BloodSplatter(tm.thing->X(), tm.thing->Y(), tm.thing->Z(), thing);
 				}
 				if (!(tm.thing->flags3 & MF3_BLOODLESSIMPACT))
 				{
@@ -1377,7 +1379,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 		// [RH] The next condition is to compensate for the extra height
 		// that gets added by P_CheckPosition() so that you cannot pick
 		// up things that are above your true height.
-		&& thing->z < tm.thing->z + tm.thing->height - tm.thing->MaxStepHeight)
+		&& thingpos.z < tm.thing->Top() - tm.thing->MaxStepHeight)
 	{ // Can be picked up by tmthing
 		P_TouchSpecialThing(thing, tm.thing);	// can remove thing
 	}
@@ -1464,7 +1466,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo
 		F3DFloor*  rover;
 		fixed_t    delta1;
 		fixed_t    delta2;
-		int        thingtop = thing->z + (thing->height == 0 ? 1 : thing->height);
+		int        thingtop = thing->Z() + (thing->height == 0 ? 1 : thing->height);
 
 		for (unsigned i = 0; i<newsec->e->XFloor.ffloors.Size(); i++)
 		{
@@ -1474,7 +1476,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo
 			fixed_t ff_bottom = rover->bottom.plane->ZatPoint(x, y);
 			fixed_t ff_top = rover->top.plane->ZatPoint(x, y);
 
-			delta1 = thing->z - (ff_bottom + ((ff_top - ff_bottom) / 2));
+			delta1 = thing->Z() - (ff_bottom + ((ff_top - ff_bottom) / 2));
 			delta2 = thingtop - (ff_bottom + ((ff_top - ff_bottom) / 2));
 
 			if (ff_top > tm.floorz && abs(delta1) < abs(delta2))
@@ -1526,17 +1528,17 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo
 					return false;
 				}
 				else if (!BlockingMobj->player && !(thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY)) &&
-					BlockingMobj->z + BlockingMobj->height - thing->z <= thing->MaxStepHeight)
+					BlockingMobj->Top() - thing->Z() <= thing->MaxStepHeight)
 				{
 					if (thingblocker == NULL ||
-						BlockingMobj->z > thingblocker->z)
+						BlockingMobj->Z() > thingblocker->Z())
 					{
 						thingblocker = BlockingMobj;
 					}
 					thing->BlockingMobj = NULL;
 				}
 				else if (thing->player &&
-					thing->z + thing->height - BlockingMobj->z <= thing->MaxStepHeight)
+					thing->Top() - BlockingMobj->Z() <= thing->MaxStepHeight)
 				{
 					if (thingblocker)
 					{ // There is something to step up on. Return this thing as
@@ -1629,10 +1631,10 @@ bool P_TestMobjLocation(AActor *mobj)
 
 	flags = mobj->flags;
 	mobj->flags &= ~MF_PICKUP;
-	if (P_CheckPosition(mobj, mobj->x, mobj->y))
+	if (P_CheckPosition(mobj, mobj->X(), mobj->Y()))
 	{ // XY is ok, now check Z
 		mobj->flags = flags;
-		if ((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz))
+		if ((mobj->Z() < mobj->floorz) || (mobj->Top() > mobj->ceilingz))
 		{ // Bad Z
 			return false;
 		}
@@ -1656,10 +1658,10 @@ AActor *P_CheckOnmobj(AActor *thing)
 	bool good;
 	AActor *onmobj;
 
-	oldz = thing->z;
+	oldz = thing->Z();
 	P_FakeZMovement(thing);
 	good = P_TestMobjZ(thing, false, &onmobj);
-	thing->z = oldz;
+	thing->SetZ(oldz);
 
 	return good ? NULL : onmobj;
 }
@@ -1679,7 +1681,7 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj)
 		return true;
 	}
 
-	FBlockThingsIterator it(FBoundingBox(actor->x, actor->y, actor->radius));
+	FBlockThingsIterator it(FBoundingBox(actor->X(), actor->Y(), actor->radius));
 	AActor *thing;
 
 	while ((thing = it.Next()))
@@ -1721,15 +1723,15 @@ bool P_TestMobjZ(AActor *actor, bool quick, AActor **pOnmobj)
 		{ // Don't clip against whoever shot the missile.
 			continue;
 		}
-		if (actor->z > thing->z + thing->height)
+		if (actor->Z() > thing->Top())
 		{ // over thing
 			continue;
 		}
-		else if (actor->z + actor->height <= thing->z)
+		else if (actor->Top() <= thing->Z())
 		{ // under thing
 			continue;
 		}
-		else if (!quick && onmobj != NULL && thing->z + thing->height < onmobj->z + onmobj->height)
+		else if (!quick && onmobj != NULL && thing->Top() < onmobj->Top())
 		{ // something higher is in the way
 			continue;
 		}
@@ -1753,35 +1755,35 @@ void P_FakeZMovement(AActor *mo)
 	//
 	// adjust height
 	//
-	mo->z += mo->velz;
+	mo->AddZ(mo->velz);
 	if ((mo->flags&MF_FLOAT) && mo->target)
 	{ // float down towards target if too close
 		if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))
 		{
 			fixed_t dist = mo->AproxDistance(mo->target);
-			fixed_t delta = (mo->target->z + (mo->height >> 1)) - mo->z;
+			fixed_t delta = (mo->target->Z() + (mo->height >> 1)) - mo->Z();
 			if (delta < 0 && dist < -(delta * 3))
-				mo->z -= mo->FloatSpeed;
+				mo->AddZ(-mo->FloatSpeed);
 			else if (delta > 0 && dist < (delta * 3))
-				mo->z += mo->FloatSpeed;
+				mo->AddZ(mo->FloatSpeed);
 		}
 	}
-	if (mo->player && mo->flags&MF_NOGRAVITY && (mo->z > mo->floorz) && !mo->IsNoClip2())
+	if (mo->player && mo->flags&MF_NOGRAVITY && (mo->Z() > mo->floorz) && !mo->IsNoClip2())
 	{
-		mo->z += finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8;
+		mo->AddZ(finesine[(FINEANGLES / 80 * level.maptime)&FINEMASK] / 8);
 	}
 
 	//
 	// clip movement
 	//
-	if (mo->z <= mo->floorz)
+	if (mo->Z() <= mo->floorz)
 	{ // hit the floor
-		mo->z = mo->floorz;
+		mo->SetZ(mo->floorz);
 	}
 
-	if (mo->z + mo->height > mo->ceilingz)
+	if (mo->Top() > mo->ceilingz)
 	{ // hit the ceiling
-		mo->z = mo->ceilingz - mo->height;
+		mo->SetZ(mo->ceilingz - mo->height);
 	}
 }
 
@@ -1802,8 +1804,8 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windo
 			fixed_t fzb = line->frontsector->floorplane.ZatPoint(mobj);
 			fixed_t bzt = line->backsector->ceilingplane.ZatPoint(mobj);
 			fixed_t bzb = line->backsector->floorplane.ZatPoint(mobj);
-			if (fzt >= mobj->z + mobj->height && bzt >= mobj->z + mobj->height &&
-				fzb <= mobj->z && bzb <= mobj->z)
+			if (fzt >= mobj->Top() && bzt >= mobj->Top() &&
+				fzb <= mobj->Z() && bzb <= mobj->Z())
 			{
 				// we must also check if some 3D floor in the backsector may be blocking
 				for (unsigned int i = 0; i<line->backsector->e->XFloor.ffloors.Size(); i++)
@@ -1815,7 +1817,7 @@ static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, bool windo
 					fixed_t ff_bottom = rover->bottom.plane->ZatPoint(mobj);
 					fixed_t ff_top = rover->top.plane->ZatPoint(mobj);
 
-					if (ff_bottom < mobj->z + mobj->height && ff_top > mobj->z)
+					if (ff_bottom < mobj->Top() && ff_top > mobj->Z())
 					{
 						goto isblocking;
 					}
@@ -1858,8 +1860,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	FCheckPosition &tm,
 	bool missileCheck)	// [GZ] Fired missiles ignore the drop-off test
 {
-	fixed_t 	oldx;
-	fixed_t 	oldy;
+	fixedvec3	oldpos;
+	sector_t	*oldsector;
 	fixed_t		oldz;
 	int 		side;
 	int 		oldside;
@@ -1868,10 +1870,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	sector_t*	newsec;
 
 	tm.floatok = false;
-	oldz = thing->z;
+	oldz = thing->Z();
 	if (onfloor)
 	{
-		thing->z = onfloor->ZatPoint(x, y);
+		thing->SetZ(onfloor->ZatPoint(x, y));
 	}
 	thing->flags6 |= MF6_INTRYMOVE;
 	if (!P_CheckPosition(thing, x, y, tm))
@@ -1888,19 +1890,16 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 			{
 				goto pushline;
 			}
-			else if (BlockingMobj->z + BlockingMobj->height - thing->z
-				> thing->MaxStepHeight
-				|| (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y)
-				- (BlockingMobj->z + BlockingMobj->height) < thing->height)
-				|| (tm.ceilingz - (BlockingMobj->z + BlockingMobj->height)
-				< thing->height))
+			else if (BlockingMobj->Top() - thing->Z() > thing->MaxStepHeight
+				|| (BlockingMobj->Sector->ceilingplane.ZatPoint(x, y) - (BlockingMobj->Top()) < thing->height)
+				|| (tm.ceilingz - (BlockingMobj->Top()) < thing->height))
 			{
 				goto pushline;
 			}
 		}
 		if (!(tm.thing->flags2 & MF2_PASSMOBJ) || (i_compatflags & COMPATF_NO_PASSMOBJ))
 		{
-			thing->z = oldz;
+			thing->SetZ(oldz);
 			thing->flags6 &= ~MF6_INTRYMOVE;
 			return false;
 		}
@@ -1908,16 +1907,16 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 
 	if (thing->flags3 & MF3_FLOORHUGGER)
 	{
-		thing->z = tm.floorz;
+		thing->SetZ(tm.floorz);
 	}
 	else if (thing->flags3 & MF3_CEILINGHUGGER)
 	{
-		thing->z = tm.ceilingz - thing->height;
+		thing->SetZ(tm.ceilingz - thing->height);
 	}
 
 	if (onfloor && tm.floorsector == thing->floorsector)
 	{
-		thing->z = tm.floorz;
+		thing->SetZ(tm.floorz);
 	}
 	if (!(thing->flags & MF_NOCLIP))
 	{
@@ -1929,7 +1928,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 		tm.floatok = true;
 
 		if (!(thing->flags & MF_TELEPORT)
-			&& tm.ceilingz - thing->z < thing->height
+			&& tm.ceilingz - thing->Z() < thing->height
 			&& !(thing->flags3 & MF3_CEILINGHUGGER)
 			&& (!(thing->flags2 & MF2_FLY) || !(thing->flags & MF_NOGRAVITY)))
 		{
@@ -1938,17 +1937,17 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 		if (thing->flags2 & MF2_FLY && thing->flags & MF_NOGRAVITY)
 		{
 #if 1
-			if (thing->z + thing->height > tm.ceilingz)
+			if (thing->Top() > tm.ceilingz)
 				goto pushline;
 #else
 			// When flying, slide up or down blocking lines until the actor
 			// is not blocked.
-			if (thing->z + thing->height > tm.ceilingz)
+			if (thing->Top() > tm.ceilingz)
 			{
 				thing->velz = -8 * FRACUNIT;
 				goto pushline;
 			}
-			else if (thing->z < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight)
+			else if (thing->Z() < tm.floorz && tm.floorz - tm.dropoffz > thing->MaxDropOffHeight)
 			{
 				thing->velz = 8 * FRACUNIT;
 				goto pushline;
@@ -1957,28 +1956,28 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 		}
 		if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER))
 		{
-			if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > thing->z)
+			if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > thing->Z())
 			{ // [RH] Don't let normal missiles climb steps
 				goto pushline;
 			}
-			if (tm.floorz - thing->z > thing->MaxStepHeight)
+			if (tm.floorz - thing->Z() > thing->MaxStepHeight)
 			{ // too big a step up
 				goto pushline;
 			}
-			else if (thing->z < tm.floorz)
+			else if (thing->Z() < tm.floorz)
 			{ // [RH] Check to make sure there's nothing in the way for the step up
-				fixed_t savedz = thing->z;
+				fixed_t savedz = thing->Z();
 				bool good;
-				thing->z = tm.floorz;
+				thing->SetZ(tm.floorz);
 				good = P_TestMobjZ(thing);
-				thing->z = savedz;
+				thing->SetZ(savedz);
 				if (!good)
 				{
 					goto pushline;
 				}
 				if (thing->flags6 & MF6_STEPMISSILE)
 				{
-					thing->z = tm.floorz;
+					thing->SetZ(tm.floorz);
 					// If moving down, cancel vertical component of the velocity
 					if (thing->velz < 0)
 					{
@@ -2004,7 +2003,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 		}
 
 		if (dropoff == 2 &&  // large jump down (e.g. dogs)
-			(tm.floorz - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->z >tm.dropoffz))
+			(tm.floorz - tm.dropoffz > 128 * FRACUNIT || thing->target == NULL || thing->target->Z() >tm.dropoffz))
 		{
 			dropoff = false;
 		}
@@ -2020,14 +2019,14 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 				// This is so that it does not walk off of things onto a drop off.
 				if (thing->flags2 & MF2_ONMOBJ)
 				{
-					floorz = MAX(thing->z, tm.floorz);
+					floorz = MAX(thing->Z(), tm.floorz);
 				}
 
 				if (floorz - tm.dropoffz > thing->MaxDropOffHeight &&
 					!(thing->flags2 & MF2_BLASTED) && !missileCheck)
 				{ // Can't move over a dropoff unless it's been blasted
 					// [GZ] Or missile-spawned
-					thing->z = oldz;
+					thing->SetZ(oldz);
 					thing->flags6 &= ~MF6_INTRYMOVE;
 					return false;
 				}
@@ -2046,9 +2045,9 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 		}
 		if (thing->flags2 & MF2_CANTLEAVEFLOORPIC
 			&& (tm.floorpic != thing->floorpic
-			|| tm.floorz - thing->z != 0))
+			|| tm.floorz - thing->Z() != 0))
 		{ // must stay within a sector of a certain floor type
-			thing->z = oldz;
+			thing->SetZ(oldz);
 			thing->flags6 &= ~MF6_INTRYMOVE;
 			return false;
 		}
@@ -2063,7 +2062,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 				thing->player->Bot->dest = NULL;
 				thing->velx = 0;
 				thing->vely = 0;
-				thing->z = oldz;
+				thing->SetZ(oldz);
 				thing->flags6 &= ~MF6_INTRYMOVE;
 				return false;
 			}
@@ -2090,7 +2089,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	// Borrowed from MBF: 
 	if (thing->BounceFlags & BOUNCE_MBF &&  // killough 8/13/98
 		!(thing->flags & (MF_MISSILE | MF_NOGRAVITY)) &&
-		!thing->IsSentient() && tm.floorz - thing->z > 16 * FRACUNIT)
+		!thing->IsSentient() && tm.floorz - thing->Z() > 16 * FRACUNIT)
 	{ // too big a step up for MBF bouncers under gravity
 		thing->flags6 &= ~MF6_INTRYMOVE;
 		return false;
@@ -2099,8 +2098,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	// the move is ok, so link the thing into its new position
 	thing->UnlinkFromWorld();
 
-	oldx = thing->x;
-	oldy = thing->y;
+	oldpos = thing->Pos();
+	oldsector = thing->Sector;
 	thing->floorz = tm.floorz;
 	thing->ceilingz = tm.ceilingz;
 	thing->dropoffz = tm.dropoffz;		// killough 11/98: keep track of dropoffs
@@ -2109,8 +2108,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	thing->floorsector = tm.floorsector;
 	thing->ceilingpic = tm.ceilingpic;
 	thing->ceilingsector = tm.ceilingsector;
-	thing->x = x;
-	thing->y = y;
+	thing->SetXY(x, y);
 
 	thing->LinkToWorld();
 
@@ -2124,9 +2122,11 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	{
 		while (spechit.Pop(ld))
 		{
+			fixedvec3 thingpos = thing->PosRelative(ld);
+			fixedvec3 oldrelpos = PosRelative(oldpos, ld, oldsector);
 			// see if the line was crossed
-			side = P_PointOnLineSide(thing->x, thing->y, ld);
-			oldside = P_PointOnLineSide(oldx, oldy, ld);
+			side = P_PointOnLineSide(thingpos.x, thingpos.y, ld);
+			oldside = P_PointOnLineSide(oldrelpos.x, oldrelpos.y, ld);
 			if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER))
 			{
 				if (thing->player && (thing->player->cheats & CF_PREDICTING))
@@ -2171,7 +2171,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 	if (newsec->heightsec && oldsec->heightsec && newsec->SecActTarget)
 	{
 		const sector_t *hs = newsec->heightsec;
-		fixed_t eyez = thing->z + viewheight;
+		fixed_t eyez = thing->Z() + viewheight;
 		fixed_t fakez = hs->floorplane.ZatPoint(x, y);
 
 		if (!oldAboveFakeFloor && eyez > fakez)
@@ -2211,7 +2211,7 @@ pushline:
 		return false;
 	}
 
-	thing->z = oldz;
+	thing->SetZ(oldz);
 	if (!(thing->flags&(MF_TELEPORT | MF_NOCLIP)))
 	{
 		int numSpecHitTemp;
@@ -2225,7 +2225,8 @@ pushline:
 		{
 			// see which lines were pushed
 			ld = spechit[--numSpecHitTemp];
-			side = P_PointOnLineSide(thing->x, thing->y, ld);
+			fixedvec3 pos = thing->PosRelative(ld);
+			side = P_PointOnLineSide(pos.x, pos.y, ld);
 			CheckForPushSpecial(ld, side, thing, true);
 		}
 	}
@@ -2252,7 +2253,7 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
 bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y)
 {
 	FCheckPosition tm;
-	fixed_t		newz = thing->z;
+	fixed_t		newz = thing->Z();
 
 	if (!P_CheckPosition(thing, x, y, tm))
 	{
@@ -2284,7 +2285,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y)
 		}
 		if (thing->flags2 & MF2_FLY && thing->flags & MF_NOGRAVITY)
 		{
-			if (thing->z + thing->height > tm.ceilingz)
+			if (thing->Top() > tm.ceilingz)
 				return false;
 		}
 		if (!(thing->flags & MF_TELEPORT) && !(thing->flags3 & MF3_FLOORHUGGER))
@@ -2299,10 +2300,10 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y)
 			}
 			else if (newz < tm.floorz)
 			{ // [RH] Check to make sure there's nothing in the way for the step up
-				fixed_t savedz = thing->z;
-				thing->z = newz = tm.floorz;
+				fixed_t savedz = thing->Z();
+				thing->SetZ(newz = tm.floorz);
 				bool good = P_TestMobjZ(thing);
-				thing->z = savedz;
+				thing->SetZ(savedz);
 				if (!good)
 				{
 					return false;
@@ -2383,7 +2384,7 @@ void FSlide::HitSlideLine(line_t* ld)
 	icyfloor =
 		(P_AproxDistance(tmxmove, tmymove) > 4 * FRACUNIT) &&
 		var_friction &&  // killough 8/28/98: calc friction on demand
-		slidemo->z <= slidemo->floorz &&
+		slidemo->Z() <= slidemo->floorz &&
 		P_GetFriction(slidemo, NULL) > ORIG_FRICTION;
 
 	if (ld->dx == 0)
@@ -2421,7 +2422,8 @@ void FSlide::HitSlideLine(line_t* ld)
 	// The wall is angled. Bounce if the angle of approach is		// phares
 	// less than 45 degrees.										// phares
 
-	side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
+	fixedvec3 pos = slidemo->PosRelative(ld);
+	side = P_PointOnLineSide(pos.x, pos.y, ld);
 
 	lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);
 
@@ -2473,8 +2475,8 @@ void FSlide::HitSlideLine(line_t* ld)
 
 			P_MakeDivline(ld, &dll);
 
-			dlv.x = slidemo->x;
-			dlv.y = slidemo->y;
+			dlv.x = pos.x;
+			dlv.y = pos.y;
 			dlv.dx = dll.dy;
 			dlv.dy = -dll.dx;
 
@@ -2526,7 +2528,8 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t
 
 		if (!(li->flags & ML_TWOSIDED) || !li->backsector)
 		{
-			if (P_PointOnLineSide(slidemo->x, slidemo->y, li))
+			fixedvec3 pos = slidemo->PosRelative(li);
+			if (P_PointOnLineSide(pos.x, pos.y, li))
 			{
 				// don't hit the back side
 				continue;
@@ -2554,19 +2557,19 @@ void FSlide::SlideTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t
 		if (open.range < slidemo->height)
 			goto isblocking;				// doesn't fit
 
-		if (open.top - slidemo->z < slidemo->height)
+		if (open.top - slidemo->Z() < slidemo->height)
 			goto isblocking;				// mobj is too high
 
-		if (open.bottom - slidemo->z > slidemo->MaxStepHeight)
+		if (open.bottom - slidemo->Z() > slidemo->MaxStepHeight)
 		{
 			goto isblocking;				// too big a step up
 		}
-		else if (slidemo->z < open.bottom)
+		else if (slidemo->Z() < open.bottom)
 		{ // [RH] Check to make sure there's nothing in the way for the step up
-			fixed_t savedz = slidemo->z;
-			slidemo->z = open.bottom;
+			fixed_t savedz = slidemo->Z();
+			slidemo->SetZ(open.bottom);
 			bool good = P_TestMobjZ(slidemo);
-			slidemo->z = savedz;
+			slidemo->SetZ(savedz);
 			if (!good)
 			{
 				goto isblocking;
@@ -2627,24 +2630,24 @@ retry:
 	// trace along the three leading corners
 	if (tryx > 0)
 	{
-		leadx = mo->x + mo->radius;
-		trailx = mo->x - mo->radius;
+		leadx = mo->X() + mo->radius;
+		trailx = mo->X() - mo->radius;
 	}
 	else
 	{
-		leadx = mo->x - mo->radius;
-		trailx = mo->x + mo->radius;
+		leadx = mo->X() - mo->radius;
+		trailx = mo->X() + mo->radius;
 	}
 
 	if (tryy > 0)
 	{
-		leady = mo->y + mo->radius;
-		traily = mo->y - mo->radius;
+		leady = mo->Y() + mo->radius;
+		traily = mo->Y() - mo->radius;
 	}
 	else
 	{
-		leady = mo->y - mo->radius;
-		traily = mo->y + mo->radius;
+		leady = mo->Y() - mo->radius;
+		traily = mo->Y() + mo->radius;
 	}
 
 	bestslidefrac = FRACUNIT + 1;
@@ -2661,11 +2664,11 @@ retry:
 		// killough 3/15/98: Allow objects to drop off ledges
 		xmove = 0, ymove = tryy;
 		walkplane = P_CheckSlopeWalk(mo, xmove, ymove);
-		if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true, walkplane))
+		if (!P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane))
 		{
 			xmove = tryx, ymove = 0;
 			walkplane = P_CheckSlopeWalk(mo, xmove, ymove);
-			P_TryMove(mo, mo->x + xmove, mo->y + ymove, true, walkplane);
+			P_TryMove(mo, mo->X() + xmove, mo->Y() + ymove, true, walkplane);
 		}
 		return;
 	}
@@ -2682,7 +2685,7 @@ retry:
 		const fixed_t startvely = mo->vely;
 
 		// killough 3/15/98: Allow objects to drop off ledges
-		if (!P_TryMove(mo, mo->x + newx, mo->y + newy, true))
+		if (!P_TryMove(mo, mo->X() + newx, mo->Y() + newy, true))
 			goto stairstep;
 
 		if (mo->velx != startvelx || mo->vely != startvely)
@@ -2716,7 +2719,7 @@ retry:
 	walkplane = P_CheckSlopeWalk(mo, tmxmove, tmymove);
 
 	// killough 3/15/98: Allow objects to drop off ledges
-	if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true, walkplane))
+	if (!P_TryMove(mo, mo->X() + tmxmove, mo->Y() + tmymove, true, walkplane))
 	{
 		goto retry;
 	}
@@ -2752,7 +2755,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 
 		fixed_t thisplanez = rover->top.plane->ZatPoint(actor);
 
-		if (thisplanez>planezhere && thisplanez <= actor->z + actor->MaxStepHeight)
+		if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight)
 		{
 			copyplane = *rover->top.plane;
 			if (copyplane.c<0) copyplane.FlipVert();
@@ -2770,7 +2773,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 
 			fixed_t thisplanez = rover->top.plane->ZatPoint(actor);
 
-			if (thisplanez>planezhere && thisplanez <= actor->z + actor->MaxStepHeight)
+			if (thisplanez>planezhere && thisplanez <= actor->Z() + actor->MaxStepHeight)
 			{
 				copyplane = *rover->top.plane;
 				if (copyplane.c<0) copyplane.FlipVert();
@@ -2787,7 +2790,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 			return NULL;
 	}
 
-	if (actor->z - planezhere > FRACUNIT)
+	if (actor->Z() - planezhere > FRACUNIT)
 	{ // not on floor
 		return NULL;
 	}
@@ -2797,9 +2800,9 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 		fixed_t destx, desty;
 		fixed_t t;
 
-		destx = actor->x + xmove;
-		desty = actor->y + ymove;
-		t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->z) + plane->d;
+		destx = actor->X() + xmove;
+		desty = actor->Y() + ymove;
+		t = TMulScale16(plane->a, destx, plane->b, desty, plane->c, actor->Z()) + plane->d;
 		if (t < 0)
 		{ // Desired location is behind (below) the plane
 			// (i.e. Walking up the plane)
@@ -2821,7 +2824,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 							const sector_t *sec = node->m_sector;
 							if (sec->floorplane.c >= STEEPSLOPE)
 							{
-								if (sec->floorplane.ZatPoint(destx, desty) >= actor->z - actor->MaxStepHeight)
+								if (sec->floorplane.ZatPoint(destx, desty) >= actor->Z() - actor->MaxStepHeight)
 								{
 									dopush = false;
 									break;
@@ -2841,19 +2844,19 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, fixed_t &xmove, fixed_t &ymov
 			// so that it lies on the plane's surface
 			destx -= FixedMul(plane->a, t);
 			desty -= FixedMul(plane->b, t);
-			xmove = destx - actor->x;
-			ymove = desty - actor->y;
+			xmove = destx - actor->X();
+			ymove = desty - actor->Y();
 			return (actor->floorsector == actor->Sector) ? plane : NULL;
 		}
 		else if (t > 0)
 		{ // Desired location is in front of (above) the plane
-			if (planezhere == actor->z)
+			if (planezhere == actor->Z())
 			{ // Actor's current spot is on/in the plane, so walk down it
 				// Same principle as walking up, except reversed
 				destx += FixedMul(plane->a, t);
 				desty += FixedMul(plane->b, t);
-				xmove = destx - actor->x;
-				ymove = desty - actor->y;
+				xmove = destx - actor->X();
+				ymove = desty - actor->Y();
 				return (actor->floorsector == actor->Sector) ? plane : NULL;
 			}
 		}
@@ -2892,7 +2895,7 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_
 		}
 		if (!(li->flags&ML_TWOSIDED) || !li->backsector)
 		{
-			if (P_PointOnLineSide(slidemo->x, slidemo->y, li))
+			if (P_PointOnLineSide(slidemo->X(), slidemo->Y(), li))
 				continue;			// don't hit the back side
 			goto bounceblocking;
 		}
@@ -2903,10 +2906,10 @@ bool FSlide::BounceTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_
 		if (open.range < slidemo->height)
 			goto bounceblocking;				// doesn't fit
 
-		if (open.top - slidemo->z < slidemo->height)
+		if (open.top - slidemo->Z() < slidemo->height)
 			goto bounceblocking;				// mobj is too high
 
-		if (open.bottom > slidemo->z)
+		if (open.bottom > slidemo->Z())
 			goto bounceblocking;				// mobj is too low
 
 		continue;			// this line doesn't block movement
@@ -2950,26 +2953,26 @@ bool FSlide::BounceWall(AActor *mo)
 	//
 	if (mo->velx > 0)
 	{
-		leadx = mo->x + mo->radius;
+		leadx = mo->X() + mo->radius;
 	}
 	else
 	{
-		leadx = mo->x - mo->radius;
+		leadx = mo->X() - mo->radius;
 	}
 	if (mo->vely > 0)
 	{
-		leady = mo->y + mo->radius;
+		leady = mo->Y() + mo->radius;
 	}
 	else
 	{
-		leady = mo->y - mo->radius;
+		leady = mo->Y() - mo->radius;
 	}
 	bestslidefrac = FRACUNIT + 1;
 	bestslideline = mo->BlockingLine;
 	if (BounceTraverse(leadx, leady, leadx + mo->velx, leady + mo->vely) && mo->BlockingLine == NULL)
 	{ // Could not find a wall, so bounce off the floor/ceiling instead.
-		fixed_t floordist = mo->z - mo->floorz;
-		fixed_t ceildist = mo->ceilingz - mo->z;
+		fixed_t floordist = mo->Z() - mo->floorz;
+		fixed_t ceildist = mo->ceilingz - mo->Z();
 		if (floordist <= ceildist)
 		{
 			mo->FloorBounceMissile(mo->Sector->floorplane);
@@ -3000,7 +3003,7 @@ bool FSlide::BounceWall(AActor *mo)
 		return true;
 	}
 
-	side = P_PointOnLineSide(mo->x, mo->y, line);
+	side = P_PointOnLineSide(mo->X(), mo->Y(), line);
 	lineangle = R_PointToAngle2(0, 0, line->dx, line->dy);
 	if (side == 1)
 	{
@@ -3015,11 +3018,14 @@ bool FSlide::BounceWall(AActor *mo)
 	movelen = fixed_t(sqrt(double(mo->velx)*mo->velx + double(mo->vely)*mo->vely));
 	movelen = FixedMul(movelen, mo->wallbouncefactor);
 
-	FBoundingBox box(mo->x, mo->y, mo->radius);
+	FBoundingBox box(mo->X(), mo->Y(), mo->radius);
 	if (box.BoxOnLineSide(line) == -1)
 	{
-		mo->SetOrigin(mo->x + FixedMul(mo->radius,
-			finecosine[deltaangle]), mo->y + FixedMul(mo->radius, finesine[deltaangle]), mo->z);
+		fixedvec3 pos = mo->Vec3Offset(
+			FixedMul(mo->radius, finecosine[deltaangle]),
+			FixedMul(mo->radius, finesine[deltaangle]), 0);
+		mo->SetOrigin(pos, true);
+
 	}
 	if (movelen < FRACUNIT)
 	{
@@ -3193,7 +3199,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in)
 		fixed_t trY = trace.y + FixedMul(trace.dy, in->frac);
 		fixed_t dist = FixedMul(attackrange, in->frac);
 
-		frontflag = P_PointOnLineSide(shootthing->x, shootthing->y, li);
+		frontflag = P_PointOnLineSide(shootthing->X(), shootthing->Y(), li);
 
 		// 3D floor check. This is not 100% accurate but normally sufficient when
 		// combined with a final sight check
@@ -3365,7 +3371,7 @@ void aim_t::AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t en
 		{
 			if (lastceilingplane)
 			{
-				fixed_t ff_top = lastceilingplane->ZatPoint(th->x, th->y);
+				fixed_t ff_top = lastceilingplane->ZatPoint(th);
 				fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_top);
 				// upper slope intersects with this 3d-floor
 				if (pitch > toppitch)
@@ -3375,7 +3381,7 @@ void aim_t::AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t en
 			}
 			if (lastfloorplane)
 			{
-				fixed_t ff_bottom = lastfloorplane->ZatPoint(th->x, th->y);
+				fixed_t ff_bottom = lastfloorplane->ZatPoint(th);
 				fixed_t pitch = -(int)R_PointToAngle2(0, shootz, dist, ff_bottom);
 				// lower slope intersects with this 3d-floor
 				if (pitch < bottompitch)
@@ -3387,12 +3393,12 @@ void aim_t::AimTraverse(fixed_t startx, fixed_t starty, fixed_t endx, fixed_t en
 
 		// check angles to see if the thing can be aimed at
 
-		thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->z + th->height);
+		thingtoppitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z() + th->height);
 
 		if (thingtoppitch > bottompitch)
 			continue;					// shot over the thing
 
-		thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->z);
+		thingbottompitch = -(int)R_PointToAngle2(0, shootz, dist, th->Z());
 
 		if (thingbottompitch < toppitch)
 			continue;					// shot under the thing
@@ -3502,9 +3508,9 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, AActor **pL
 	aim.shootthing = t1;
 	aim.friender = (friender == NULL) ? t1 : friender;
 
-	x2 = t1->x + (distance >> FRACBITS)*finecosine[angle];
-	y2 = t1->y + (distance >> FRACBITS)*finesine[angle];
-	aim.shootz = t1->z + (t1->height >> 1) - t1->floorclip;
+	x2 = t1->X() + (distance >> FRACBITS)*finecosine[angle];
+	y2 = t1->Y() + (distance >> FRACBITS)*finesine[angle];
+	aim.shootz = t1->Z() + (t1->height >> 1) - t1->floorclip;
 	if (t1->player != NULL)
 	{
 		aim.shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor);
@@ -3559,15 +3565,15 @@ fixed_t P_AimLineAttack(AActor *t1, angle_t angle, fixed_t distance, AActor **pL
 	for (unsigned i = 0; i<t1->Sector->e->XFloor.ffloors.Size(); i++)
 	{
 		F3DFloor * rover = t1->Sector->e->XFloor.ffloors[i];
-		fixed_t bottomz = rover->bottom.plane->ZatPoint(t1->x, t1->y);
+		fixed_t bottomz = rover->bottom.plane->ZatPoint(t1);
 
-		if (bottomz >= t1->z + t1->height) aim.lastceilingplane = rover->bottom.plane;
+		if (bottomz >= t1->Top()) aim.lastceilingplane = rover->bottom.plane;
 
-		bottomz = rover->top.plane->ZatPoint(t1->x, t1->y);
-		if (bottomz <= t1->z) aim.lastfloorplane = rover->top.plane;
+		bottomz = rover->top.plane->ZatPoint(t1);
+		if (bottomz <= t1->Z()) aim.lastfloorplane = rover->top.plane;
 	}
 
-	aim.AimTraverse(t1->x, t1->y, x2, y2, target);
+	aim.AimTraverse(t1->X(), t1->Y(), x2, y2, target);
 
 	if (!aim.linetarget)
 	{
@@ -3670,7 +3676,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
 	vy = FixedMul(finecosine[pitch], finesine[angle]);
 	vz = -finesine[pitch];
 
-	shootz = t1->z - t1->floorclip + (t1->height >> 1);
+	shootz = t1->Z() - t1->floorclip + (t1->height >> 1);
 	if (t1->player != NULL)
 	{
 		shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor);
@@ -3708,7 +3714,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
 	if (puffDefaults != NULL && puffDefaults->flags6 & MF6_NOTRIGGER) tflags = TRACE_NoSky;
 	else tflags = TRACE_NoSky | TRACE_Impact;
 
-	if (!Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance,
+	if (!Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance,
 		MF_SHOOTABLE, ML_BLOCKEVERYTHING | ML_BLOCKHITSCAN, t1, trace,
 		tflags, CheckForActor, &TData))
 	{ // hit nothing
@@ -3738,8 +3744,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
 			if (trace.HitType != TRACE_HitWall || trace.Line->special != Line_Horizon)
 			{
 				fixed_t closer = trace.Distance - 4 * FRACUNIT;
-				puff = P_SpawnPuff(t1, pufftype, t1->x + FixedMul(vx, closer),
-					t1->y + FixedMul(vy, closer),
+				fixedvec2 pos = t1->Vec2Offset(FixedMul(vx, closer), FixedMul(vy, closer));
+				puff = P_SpawnPuff(t1, pufftype, pos.x, pos.y,
 					shootz + FixedMul(vz, closer), angle - ANG90, 0, puffFlags);
 			}
 
@@ -3775,8 +3781,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
 			{
 				// Using the puff's position is not accurate enough.
 				// Instead make it splash at the actual hit position
-				hitx = t1->x + FixedMul(vx, trace.Distance);
-				hity = t1->y + FixedMul(vy, trace.Distance);
+				hitx = t1->X() + FixedMul(vx, trace.Distance);
+				hity = t1->Y() + FixedMul(vy, trace.Distance);
 				hitz = shootz + FixedMul(vz, trace.Distance);
 				P_HitWater(puff, P_PointInSector(hitx, hity), hitx, hity, hitz);
 			}
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 1c5105235..e2d5a3cf6 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -380,11 +380,11 @@ void AActor::Serialize (FArchive &arc)
 				Speed = GetDefault()->Speed;
 			}
 		}
-		PrevX = x;
-		PrevY = y;
-		PrevZ = z;
+		PrevX = X();
+		PrevY = Y();
+		PrevZ = Z();
 		PrevAngle = angle;
-		UpdateWaterLevel(z, false);
+		UpdateWaterLevel(Z(), false);
 	}
 }
 
@@ -396,12 +396,12 @@ AActor::AActor () throw()
 AActor::AActor (const AActor &other) throw()
 	: DThinker()
 {
-	memcpy (&x, &other.x, (BYTE *)&this[1] - (BYTE *)&x);
+	memcpy (&snext, &other.snext, (BYTE *)&this[1] - (BYTE *)&snext);
 }
 
 AActor &AActor::operator= (const AActor &other)
 {
-	memcpy (&x, &other.x, (BYTE *)&this[1] - (BYTE *)&x);
+	memcpy (&snext, &other.snext, (BYTE *)&this[1] - (BYTE *)&snext);
 	return *this;
 }
 
@@ -738,7 +738,7 @@ AInventory *AActor::DropInventory (AInventory *item)
 		return NULL;
 	}
 	an = angle >> ANGLETOFINESHIFT;
-	drop->SetOrigin(x, y, z + 10*FRACUNIT);
+	drop->SetOrigin(PosPlusZ(10*FRACUNIT), false);
 	drop->angle = angle;
 	drop->velx = velx + 5 * finecosine[an];
 	drop->vely = vely + 5 * finesine[an];
@@ -1165,7 +1165,7 @@ bool AActor::Grind(bool items)
 				return false;
 			}
 
-			AActor *gib = Spawn (i, x, y, z, ALLOW_REPLACE);
+			AActor *gib = Spawn (i, Pos(), ALLOW_REPLACE);
 			if (gib != NULL)
 			{
 				gib->RenderStyle = RenderStyle;
@@ -1284,7 +1284,8 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
 
 	if (line != NULL && cl_missiledecals)
 	{
-		int side = P_PointOnLineSidePrecise (mo->x, mo->y, line);
+		fixedvec3 pos = mo->PosRelative(line);
+		int side = P_PointOnLineSidePrecise (pos.x, pos.y, line);
 		if (line->sidedef[side] == NULL)
 			side ^= 1;
 		if (line->sidedef[side] != NULL)
@@ -1301,7 +1302,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
 				{
 					SDWORD frac;
 
-					num = (SQWORD)(mo->x-line->v1->x)*line->dx+(SQWORD)(mo->y-line->v1->y)*line->dy;
+					num = (SQWORD)(pos.x-line->v1->x)*line->dx+(SQWORD)(pos.y-line->v1->y)*line->dy;
 					if (num <= 0)
 					{
 						frac = 0;
@@ -1317,7 +1318,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
 
 					x = line->v1->x + MulScale30 (line->dx, frac);
 					y = line->v1->y + MulScale30 (line->dy, frac);
-					z = mo->z;
+					z = pos.z;
 
 					F3DFloor * ffloor=NULL;
 					if (line->sidedef[side^1] != NULL)
@@ -1427,7 +1428,7 @@ void AActor::PlayBounceSound(bool onfloor)
 
 bool AActor::FloorBounceMissile (secplane_t &plane)
 {
-	if (z <= floorz && P_HitFloor (this))
+	if (Z() <= floorz && P_HitFloor (this))
 	{
 		// Landed in some sort of liquid
 		if (BounceFlags & BOUNCE_ExplodeOnWater)
@@ -1666,15 +1667,15 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci
 
 		if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
 		{
-			if (actor->z + actor->height < target->z ||
-				target->z + target->height < actor->z)
+			if (actor->Top() < target->Z() ||
+				target->Top() < actor->Z())
 			{ // Need to seek vertically
 				dist = actor->AproxDistance (target) / speed;
 				if (dist < 1)
 				{
 					dist = 1;
 				}
-				actor->velz = ((target->z+target->height/2) - (actor->z+actor->height/2)) / dist;
+				actor->velz = ((target->Z() + target->height / 2) - (actor->Z() + actor->height / 2)) / dist;
 			}
 		}
 	}
@@ -1683,14 +1684,14 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax, bool preci
 		angle_t pitch = 0;
 		if (!(actor->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
 		{ // Need to seek vertically
-			double dist = MAX(1.0, FVector2(target->x - actor->x, target->y - actor->y).Length());
+			double dist = MAX(1.0, FVector2(actor->Vec2To(target)).Length());
 			// Aim at a player's eyes and at the middle of the actor for everything else.
 			fixed_t aimheight = target->height/2;
 			if (target->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
 			{
 				aimheight = static_cast<APlayerPawn *>(target)->ViewHeight;
 			}
-			pitch = R_PointToAngle2(0, actor->z + actor->height/2, xs_CRoundToInt(dist), target->z + aimheight);
+			pitch = R_PointToAngle2(0, actor->Z() + actor->height/2, xs_CRoundToInt(dist), target->Z() + aimheight);
 			pitch >>= ANGLETOFINESHIFT;
 		}
 
@@ -1725,7 +1726,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 	int steps, step, totalsteps;
 	fixed_t startx, starty;
 	fixed_t oldfloorz = mo->floorz;
-	fixed_t oldz = mo->z;
+	fixed_t oldz = mo->Z();
 
 	fixed_t maxmove = (mo->waterlevel < 1) || (mo->flags & MF_MISSILE) || 
 					  (mo->player && mo->player->crouchoffset<-10*FRACUNIT) ? MAXMOVE : MAXMOVE/4;
@@ -1861,8 +1862,8 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 	fixed_t onestepx = startxmove / steps;
 	fixed_t onestepy = startymove / steps;
 
-	startx = mo->x;
-	starty = mo->y;
+	startx = mo->X();
+	starty = mo->Y();
 	step = 1;
 	totalsteps = steps;
 
@@ -1948,8 +1949,8 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 								onestepy = ymove / steps;
 								P_CheckSlopeWalk (mo, xmove, ymove);
 							}
-							startx = mo->x - Scale (xmove, step, steps);
-							starty = mo->y - Scale (ymove, step, steps);
+							startx = mo->X() - Scale (xmove, step, steps);
+							starty = mo->Y() - Scale (ymove, step, steps);
 						}
 					}
 					else
@@ -1962,7 +1963,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 					fixed_t tx, ty;
 					tx = 0, ty = onestepy;
 					walkplane = P_CheckSlopeWalk (mo, tx, ty);
-					if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm))
+					if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm))
 					{
 						mo->velx = 0;
 					}
@@ -1970,7 +1971,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 					{
 						tx = onestepx, ty = 0;
 						walkplane = P_CheckSlopeWalk (mo, tx, ty);
-						if (P_TryMove (mo, mo->x + tx, mo->y + ty, true, walkplane, tm))
+						if (P_TryMove (mo, mo->X() + tx, mo->Y() + ty, true, walkplane, tm))
 						{
 							mo->vely = 0;
 						}
@@ -2033,7 +2034,9 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
 
 								float speed = (float)(mo->Speed);
 								//dest->x - source->x
-								FVector3 velocity(origin->x - mo->x, origin->y - mo->y, (origin->z + (origin->height/2)) - mo->z);
+								fixedvec3 vect = mo->Vec3To(origin);
+								vect.z += origin->height / 2;
+								FVector3 velocity(vect);
 								velocity.Resize(speed);
 								mo->velx = (fixed_t)(velocity.X);
 								mo->vely = (fixed_t)(velocity.Y);
@@ -2077,7 +2080,7 @@ explode:
 					if (tm.ceilingline &&
 						tm.ceilingline->backsector &&
 						tm.ceilingline->backsector->GetTexture(sector_t::ceiling) == skyflatnum &&
-						mo->z >= tm.ceilingline->backsector->ceilingplane.ZatPoint(mo))
+						mo->Z() >= tm.ceilingline->backsector->ceilingplane.ZatPoint(mo))
 					{
 						// Hack to prevent missiles exploding against the sky.
 						// Does not handle sky floors.
@@ -2102,7 +2105,7 @@ explode:
 		}
 		else
 		{
-			if (mo->x != ptryx || mo->y != ptryy)
+			if (mo->X() != ptryx || mo->Y() != ptryy)
 			{
 				// If the new position does not match the desired position, the player
 				// must have gone through a teleporter, so stop moving right now if it
@@ -2114,8 +2117,8 @@ explode:
 				}
 				else
 				{
-					startx = mo->x - Scale (xmove, step, steps);
-					starty = mo->y - Scale (ymove, step, steps);
+					startx = mo->X() - Scale (xmove, step, steps);
+					starty = mo->Y() - Scale (ymove, step, steps);
 				}
 			}
 		}
@@ -2135,7 +2138,7 @@ explode:
 		return oldfloorz;
 	}
 
-	if (mo->z > mo->floorz && !(mo->flags2 & MF2_ONMOBJ) &&
+	if (mo->Z() > mo->floorz && !(mo->flags2 & MF2_ONMOBJ) &&
 		!mo->IsNoClip2() &&
 		(!(mo->flags2 & MF2_FLY) || !(mo->flags & MF_NOGRAVITY)) &&
 		!mo->waterlevel)
@@ -2157,7 +2160,7 @@ explode:
 	// killough 8/11/98: add bouncers
 	// killough 9/15/98: add objects falling off ledges
 	// killough 11/98: only include bouncers hanging off ledges
-	if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->z > mo->dropoffz) || (mo->flags6 & MF6_FALLING))
+	if ((mo->flags & MF_CORPSE) || (mo->BounceFlags & BOUNCE_MBF && mo->Z() > mo->dropoffz) || (mo->flags6 & MF6_FALLING))
 	{ // Don't stop sliding if halfway off a step with some velocity
 		if (mo->velx > FRACUNIT/4 || mo->velx < -FRACUNIT/4 || mo->vely > FRACUNIT/4 || mo->vely < -FRACUNIT/4)
 		{
@@ -2172,7 +2175,7 @@ explode:
 						// if the floor comes from one in the current sector stop sliding the corpse!
 						F3DFloor * rover=mo->Sector->e->XFloor.ffloors[i];
 						if (!(rover->flags&FF_EXISTS)) continue;
-						if (rover->flags&FF_SOLID && rover->top.plane->ZatPoint(mo->x,mo->y)==mo->floorz) break;
+						if (rover->flags&FF_SOLID && rover->top.plane->ZatPoint(mo) == mo->floorz) break;
 					}
 					if (i==mo->Sector->e->XFloor.ffloors.Size()) 
 						return oldfloorz;
@@ -2269,24 +2272,24 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 {
 	fixed_t dist;
 	fixed_t delta;
-	fixed_t oldz = mo->z;
+	fixed_t oldz = mo->Z();
 	fixed_t grav = mo->GetGravity();
 
 //
 // check for smooth step up
 //
-	if (mo->player && mo->player->mo == mo && mo->z < mo->floorz)
+	if (mo->player && mo->player->mo == mo && mo->Z() < mo->floorz)
 	{
-		mo->player->viewheight -= mo->floorz - mo->z;
+		mo->player->viewheight -= mo->floorz - mo->Z();
 		mo->player->deltaviewheight = mo->player->GetDeltaViewHeight();
 	}
 
-	mo->z += mo->velz;
+	mo->AddZ(mo->velz);
 
 //
 // apply gravity
 //
-	if (mo->z > mo->floorz && !(mo->flags & MF_NOGRAVITY))
+	if (mo->Z() > mo->floorz && !(mo->flags & MF_NOGRAVITY))
 	{
 		fixed_t startvelz = mo->velz;
 
@@ -2295,7 +2298,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 		{
 			// [RH] Double gravity only if running off a ledge. Coming down from
 			// an upward thrust (e.g. a jump) should not double it.
-			if (mo->velz == 0 && oldfloorz > mo->floorz && mo->z == oldfloorz)
+			if (mo->velz == 0 && oldfloorz > mo->floorz && mo->Z() == oldfloorz)
 			{
 				mo->velz -= grav + grav;
 			}
@@ -2368,7 +2371,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 	// Do this only if the item was actually spawned by the map above ground to avoid problems.
 	if (mo->special1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB))
 	{
-		mo->z = mo->floorz + mo->special1;
+		mo->SetZ(mo->floorz + mo->special1);
 	}
 
 
@@ -2380,18 +2383,18 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 		if (!(mo->flags & (MF_SKULLFLY | MF_INFLOAT)))
 		{
 			dist = mo->AproxDistance (mo->target);
-			delta = (mo->target->z + (mo->height>>1)) - mo->z;
+			delta = (mo->target->Z() + (mo->height>>1)) - mo->Z();
 			if (delta < 0 && dist < -(delta*3))
-				mo->z -= mo->FloatSpeed;
+				mo->AddZ(-mo->FloatSpeed);
 			else if (delta > 0 && dist < (delta*3))
-				mo->z += mo->FloatSpeed;
+				mo->AddZ(mo->FloatSpeed);
 		}
 	}
-	if (mo->player && (mo->flags & MF_NOGRAVITY) && (mo->z > mo->floorz))
+	if (mo->player && (mo->flags & MF_NOGRAVITY) && (mo->Z() > mo->floorz))
 	{
 		if (!mo->IsNoClip2())
 		{
-			mo->z += finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8;
+			mo->AddZ(finesine[(FINEANGLES/80*level.maptime)&FINEMASK]/8);
 		}
 		mo->velz = FixedMul (mo->velz, FRICTION_FLY);
 	}
@@ -2403,7 +2406,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 //
 // clip movement
 //
-	if (mo->z <= mo->floorz)
+	if (mo->Z() <= mo->floorz)
 	{	// Hit the floor
 		if ((!mo->player || !(mo->player->cheats & CF_PREDICTING)) &&
 			mo->Sector->SecActTarget != NULL &&
@@ -2414,11 +2417,11 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 		P_CheckFor3DFloorHit(mo);
 		// [RH] Need to recheck this because the sector action might have
 		// teleported the actor so it is no longer below the floor.
-		if (mo->z <= mo->floorz)
+		if (mo->Z() <= mo->floorz)
 		{
 			if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP))
 			{
-				mo->z = mo->floorz;
+				mo->AddZ(mo->floorz);
 				if (mo->BounceFlags & BOUNCE_Floors)
 				{
 					mo->FloorBounceMissile (mo->floorsector->floorplane);
@@ -2459,7 +2462,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 					P_MonsterFallingDamage (mo);
 				}
 			}
-			mo->z = mo->floorz;
+			mo->SetZ(mo->floorz);
 			if (mo->velz < 0)
 			{
 				const fixed_t minvel = -8*FRACUNIT;	// landing speed from a jump with normal gravity
@@ -2505,7 +2508,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 		mo->AdjustFloorClip ();
 	}
 
-	if (mo->z + mo->height > mo->ceilingz)
+	if (mo->Top() > mo->ceilingz)
 	{ // hit the ceiling
 		if ((!mo->player || !(mo->player->cheats & CF_PREDICTING)) &&
 			mo->Sector->SecActTarget != NULL &&
@@ -2516,9 +2519,9 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
 		P_CheckFor3DCeilingHit(mo);
 		// [RH] Need to recheck this because the sector action might have
 		// teleported the actor so it is no longer above the ceiling.
-		if (mo->z + mo->height > mo->ceilingz)
+		if (mo->Top() > mo->ceilingz)
 		{
-			mo->z = mo->ceilingz - mo->height;
+			mo->SetZ(mo->ceilingz - mo->height);
 			if (mo->BounceFlags & BOUNCE_Ceilings)
 			{	// ceiling bounce
 				mo->FloorBounceMissile (mo->ceilingsector->ceilingplane);
@@ -2577,12 +2580,12 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh
 			viewheight = mo->height / 2;
 		}
 
-		if (oldz > waterz && mo->z <= waterz)
+		if (oldz > waterz && mo->Z() <= waterz)
 		{ // Feet hit fake floor
 			sec->SecActTarget->TriggerAction (mo, SECSPAC_HitFakeFloor);
 		}
 
-		newz = mo->z + viewheight;
+		newz = mo->Z() + viewheight;
 		if (!oldz_has_viewheight)
 		{
 			oldz += viewheight;
@@ -2684,22 +2687,22 @@ void P_NightmareRespawn (AActor *mobj)
 
 	if (z == ONFLOORZ)
 	{
-		mo->z += mobj->SpawnPoint[2];
-		if (mo->z < mo->floorz)
+		mo->AddZ(mobj->SpawnPoint[2]);
+		if (mo->Z() < mo->floorz)
 		{ // Do not respawn monsters in the floor, even if that's where they
 		  // started. The initial P_ZMovement() call would have put them on
 		  // the floor right away, but we need them on the floor now so we
 		  // can use P_CheckPosition() properly.
-			mo->z = mo->floorz;
+			mo->SetZ(mo->floorz);
 		}
-		if (mo->z + mo->height > mo->ceilingz)
+		if (mo->Top() > mo->ceilingz)
 		{
-			mo->z = mo->ceilingz - mo->height;
+			mo->SetZ(mo->ceilingz - mo->height);
 		}
 	}
 	else if (z == ONCEILINGZ)
 	{
-		mo->z -= mobj->SpawnPoint[2];
+		mo->AddZ(-mobj->SpawnPoint[2]);
 	}
 
 	// If there are 3D floors, we need to find floor/ceiling again.
@@ -2707,21 +2710,21 @@ void P_NightmareRespawn (AActor *mobj)
 
 	if (z == ONFLOORZ)
 	{
-		if (mo->z < mo->floorz)
+		if (mo->Z() < mo->floorz)
 		{ // Do not respawn monsters in the floor, even if that's where they
 		  // started. The initial P_ZMovement() call would have put them on
 		  // the floor right away, but we need them on the floor now so we
 		  // can use P_CheckPosition() properly.
-			mo->z = mo->floorz;
+			mo->SetZ(mo->floorz);
 		}
-		if (mo->z + mo->height > mo->ceilingz)
+		if (mo->Top() > mo->ceilingz)
 		{ // Do the same for the ceiling.
-			mo->z = mo->ceilingz - mo->height;
+			mo->SetZ(mo->ceilingz - mo->height);
 		}
 	}
 
 	// something is occupying its position?
-	if (!P_CheckPosition(mo, mo->x, mo->y, true))
+	if (!P_CheckPosition(mo, mo->X(), mo->Y(), true))
 	{
 		//[GrafZahl] MF_COUNTKILL still needs to be checked here.
 		mo->ClearCounters();
@@ -2729,7 +2732,7 @@ void P_NightmareRespawn (AActor *mobj)
 		return;		// no respawn
 	}
 
-	z = mo->z;
+	z = mo->Z();
 
 	// inherit attributes from deceased one
 	mo->SpawnPoint[0] = mobj->SpawnPoint[0];
@@ -2749,7 +2752,7 @@ void P_NightmareRespawn (AActor *mobj)
 	mo->PrevZ = z;		// Do not interpolate Z position if we changed it since spawning.
 
 	// spawn a teleport fog at old spot because of removal of the body?
-	P_SpawnTeleportFog(mobj, mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, true, true);
+	P_SpawnTeleportFog(mobj, mobj->PosPlusZ(TELEFOGHEIGHT), true, true);
 
 	// spawn a teleport fog at the new spot
 	P_SpawnTeleportFog(mobj, x, y, z + TELEFOGHEIGHT, false, true);
@@ -3196,16 +3199,16 @@ void AActor::Tick ()
 	if (state == NULL)
 	{
 		Printf("Actor of type %s at (%f,%f) left without a state\n", GetClass()->TypeName.GetChars(),
-			x/65536., y/65536.);
+			X()/65536., Y()/65536.);
 		Destroy();
 		return;
 	}
 
 	// This is necessary to properly interpolate movement outside this function
 	// like from an ActorMover
-	PrevX = x;
-	PrevY = y;
-	PrevZ = z;
+	PrevX = X();
+	PrevY = Y();
+	PrevZ = Z();
 	PrevAngle = angle;
 
 	if (flags5 & MF5_NOINTERACTION)
@@ -3231,9 +3234,8 @@ void AActor::Tick ()
 
 		UnlinkFromWorld ();
 		flags |= MF_NOBLOCKMAP;
-		x += velx;
-		y += vely;
-		z += velz;
+		SetXYZ(Vec3Offset(velx, vely, vely));
+		SetMovement(velx, vely, velz);
 		LinkToWorld ();
 	}
 	else
@@ -3280,7 +3282,7 @@ void AActor::Tick ()
 			{
 				// add some smoke behind the rocket 
 				smokecounter = 0;
-				AActor *th = Spawn("RocketSmokeTrail", x-velx, y-vely, z-velz, ALLOW_REPLACE);
+				AActor *th = Spawn("RocketSmokeTrail", Vec3Offset(-velx, -vely, -velz), ALLOW_REPLACE);
 				if (th)
 				{
 					th->tics -= pr_rockettrail()&3;
@@ -3295,10 +3297,10 @@ void AActor::Tick ()
 			{
 				smokecounter = 0;
 				angle_t moveangle = R_PointToAngle2(0,0,velx,vely);
-				AActor * th = Spawn("GrenadeSmokeTrail", 
-					x - FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
-					y - FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
-					z - (height>>3) * (velz>>16) + (2*height)/3, ALLOW_REPLACE);
+				AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(
+					- FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
+					- FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
+					- (height>>3) * (velz>>16) + (2*height)/3), ALLOW_REPLACE);
 				if (th)
 				{
 					th->tics -= pr_rockettrail()&3;
@@ -3308,7 +3310,7 @@ void AActor::Tick ()
 			}
 		}
 
-		fixed_t oldz = z;
+		fixed_t oldz = Z();
 
 		// [RH] Give the pain elemental vertical friction
 		// This used to be in APainElemental::Tick but in order to use
@@ -3520,16 +3522,16 @@ void AActor::Tick ()
 				{
 					continue;
 				}
-				height = sec->floorplane.ZatPoint (x, y);
-				if (z > height)
+				height = sec->floorplane.ZatPoint (this);
+				if (Z() > height)
 				{
 					if (heightsec == NULL)
 					{
 						continue;
 					}
 
-					waterheight = heightsec->floorplane.ZatPoint (x, y);
-					if (waterheight > height && z >= waterheight)
+					waterheight = heightsec->floorplane.ZatPoint (this);
+					if (waterheight > height && Z() >= waterheight)
 					{
 						continue;
 					}
@@ -3561,15 +3563,15 @@ void AActor::Tick ()
 		if ((flags & MF_SOLID) && !(flags & (MF_NOCLIP|MF_NOGRAVITY)) &&
 			!(flags & MF_NOBLOCKMAP) &&
 			velz <= 0 &&
-			floorz == z)
+			floorz == Z())
 		{
 			secplane_t floorplane;
 
 			// Check 3D floors as well
-			floorplane = P_FindFloorPlane(floorsector, x, y, floorz);
+			floorplane = P_FindFloorPlane(floorsector, X(), Y(), floorz);
 
 			if (floorplane.c < STEEPSLOPE &&
-				floorplane.ZatPoint (x, y) <= floorz)
+				floorplane.ZatPoint (this) <= floorz)
 			{
 				const msecnode_t *node;
 				bool dopush = true;
@@ -3581,7 +3583,7 @@ void AActor::Tick ()
 						const sector_t *sec = node->m_sector;
 						if (sec->floorplane.c >= STEEPSLOPE)
 						{
-							if (floorplane.ZatPoint (x, y) >= z - MaxStepHeight)
+							if (floorplane.ZatPoint (this) >= Z() - MaxStepHeight)
 							{
 								dopush = false;
 								break;
@@ -3625,7 +3627,7 @@ void AActor::Tick ()
 			}
 
 		}
-		if (velz || BlockingMobj || z != floorz)
+		if (velz || BlockingMobj || Z() != floorz)
 		{	// Handle Z velocity and gravity
 			if (((flags2 & MF2_PASSMOBJ) || (flags & MF_SPECIAL)) && !(i_compatflags & COMPATF_NO_PASSMOBJ))
 			{
@@ -3644,18 +3646,18 @@ void AActor::Tick ()
 							PlayerLandedOnThing (this, onmo);
 						}
 					}
-					if (onmo->z + onmo->height - z <= MaxStepHeight)
+					if (onmo->Top() - Z() <= MaxStepHeight)
 					{
 						if (player && player->mo == this)
 						{
-							player->viewheight -= onmo->z + onmo->height - z;
+							player->viewheight -= onmo->Top() - Z();
 							fixed_t deltaview = player->GetDeltaViewHeight();
 							if (deltaview > player->deltaviewheight)
 							{
 								player->deltaviewheight = deltaview;
 							}
 						} 
-						z = onmo->z + onmo->height;
+						SetZ(onmo->Top());
 					}
 					// Check for MF6_BUMPSPECIAL
 					// By default, only players can activate things by bumping into them
@@ -3694,7 +3696,7 @@ void AActor::Tick ()
 			if (ObjectFlags & OF_EuthanizeMe)
 				return;		// actor was destroyed
 		}
-		else if (z <= floorz)
+		else if (Z() <= floorz)
 		{
 			Crash();
 		}
@@ -3796,25 +3798,25 @@ void AActor::CheckSectorTransition(sector_t *oldsec)
 		if (Sector->SecActTarget != NULL)
 		{
 			int act = SECSPAC_Enter;
-			if (z <= Sector->floorplane.ZatPoint(x, y))
+			if (Z() <= Sector->floorplane.ZatPoint(this))
 			{
 				act |= SECSPAC_HitFloor;
 			}
-			if (z + height >= Sector->ceilingplane.ZatPoint(x, y))
+			if (Z() + height >= Sector->ceilingplane.ZatPoint(this))
 			{
 				act |= SECSPAC_HitCeiling;
 			}
-			if (Sector->heightsec != NULL && z == Sector->heightsec->floorplane.ZatPoint(x, y))
+			if (Sector->heightsec != NULL && Z() == Sector->heightsec->floorplane.ZatPoint(this))
 			{
 				act |= SECSPAC_HitFakeFloor;
 			}
 			Sector->SecActTarget->TriggerAction(this, act);
 		}
-		if (z == floorz)
+		if (Z() == floorz)
 		{
 			P_CheckFor3DFloorHit(this);
 		}
-		if (z + height == ceilingz)
+		if (Top() == ceilingz)
 		{
 			P_CheckFor3DCeilingHit(this);
 		}
@@ -3851,23 +3853,23 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
 		const sector_t *hsec = Sector->GetHeightSec();
 		if (hsec != NULL)
 		{
-			fh = hsec->floorplane.ZatPoint (x, y);
+			fh = hsec->floorplane.ZatPoint (this);
 			//if (hsec->MoreFlags & SECF_UNDERWATERMASK)	// also check Boom-style non-swimmable sectors
 			{
-				if (z < fh)
+				if (Z() < fh)
 				{
 					waterlevel = 1;
-					if (z + height/2 < fh)
+					if (Z() + height/2 < fh)
 					{
 						waterlevel = 2;
-						if ((player && z + player->viewheight <= fh) ||
-							(z + height <= fh))
+						if ((player && Z() + player->viewheight <= fh) ||
+							(Z() + height <= fh))
 						{
 							waterlevel = 3;
 						}
 					}
 				}
-				else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (z + height > hsec->ceilingplane.ZatPoint (x, y)))
+				else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint (this)))
 				{
 					waterlevel = 3;
 				}
@@ -3893,20 +3895,20 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
 				if (!(rover->flags & FF_EXISTS)) continue;
 				if(!(rover->flags & FF_SWIMMABLE) || rover->flags & FF_SOLID) continue;
 
-				fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y);
-				fixed_t ff_top=rover->top.plane->ZatPoint(x, y);
+				fixed_t ff_bottom=rover->bottom.plane->ZatPoint(this);
+				fixed_t ff_top=rover->top.plane->ZatPoint(this);
 
-				if(ff_top <= z || ff_bottom > (z + (height >> 1))) continue;
+				if(ff_top <= Z() || ff_bottom > (Z() + (height >> 1))) continue;
 				
 				fh=ff_top;
-				if (z < fh)
+				if (Z() < fh)
 				{
 					waterlevel = 1;
-					if (z + height/2 < fh)
+					if (Z() + height/2 < fh)
 					{
 						waterlevel = 2;
-						if ((player && z + player->viewheight <= fh) ||
-							(z + height <= fh))
+						if ((player && Z() + player->viewheight <= fh) ||
+							(Z() + height <= fh))
 						{
 							waterlevel = 3;
 						}
@@ -3970,9 +3972,10 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
 		actor->Conversation = NULL;
 	}
 
-	actor->x = actor->PrevX = ix;
-	actor->y = actor->PrevY = iy;
-	actor->z = actor->PrevZ = iz;
+	actor->PrevX = ix;
+	actor->PrevY = iy;
+	actor->PrevZ = iz;
+	actor->SetXYZ(ix, iy, iz);
 	actor->picnum.SetInvalid();
 	actor->health = actor->SpawnHealth();
 
@@ -4017,11 +4020,11 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
 	// For FLOATRANDZ just use the floor here.
 	if (iz == ONFLOORZ || iz == FLOATRANDZ)
 	{
-		actor->z = actor->floorz;
+		actor->SetZ(actor->floorz, false);
 	}
 	else if (iz == ONCEILINGZ)
 	{
-		actor->z = actor->ceilingz - actor->height;
+		actor->SetZ(actor->ceilingz - actor->height);
 	}
 
 	if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn)))
@@ -4060,11 +4063,11 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
 
 	if (iz == ONFLOORZ)
 	{
-		actor->z = actor->floorz;
+		actor->SetZ(actor->floorz);
 	}
 	else if (iz == ONCEILINGZ)
 	{
-		actor->z = actor->ceilingz - actor->height;
+		actor->SetZ(actor->ceilingz - actor->height);
 	}
 	else if (iz == FLOATRANDZ)
 	{
@@ -4072,16 +4075,16 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
 		if (space > 48*FRACUNIT)
 		{
 			space -= 40*FRACUNIT;
-			actor->z = MulScale8 (space, rng()) + actor->floorz + 40*FRACUNIT;
+			actor->SetZ(MulScale8 (space, rng()) + actor->floorz + 40*FRACUNIT);
 		}
 		else
 		{
-			actor->z = actor->floorz;
+			actor->SetZ(actor->floorz);
 		}
 	}
 	else
 	{
-		actor->SpawnPoint[2] = (actor->z - actor->floorz);
+		actor->SpawnPoint[2] = (actor->Z() - actor->floorz);
 	}
 
 	if (actor->FloatBobPhase == (BYTE)-1) actor->FloatBobPhase = rng();	// Don't make everything bob in sync (unless deliberately told to do)
@@ -4093,7 +4096,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
 	{
 		actor->floorclip = 0;
 	}
-	actor->UpdateWaterLevel (actor->z, false);
+	actor->UpdateWaterLevel (actor->Z(), false);
 	if (!SpawningMapThing)
 	{
 		actor->BeginPlay ();
@@ -4332,8 +4335,8 @@ void AActor::AdjustFloorClip ()
 	fixed_t shallowestclip = FIXED_MAX;
 	const msecnode_t *m;
 
-	// possibly standing on a 3D-floor!
-	if (Sector->e->XFloor.ffloors.Size() && z>Sector->floorplane.ZatPoint(x,y)) floorclip=0;
+	// possibly standing on a 3D-floor
+	if (Sector->e->XFloor.ffloors.Size() && Z()>Sector->floorplane.ZatPoint(this)) floorclip=0;
 
 	// [RH] clip based on shallowest floor player is standing on
 	// If the sector has a deep water effect, then let that effect
@@ -4341,7 +4344,7 @@ void AActor::AdjustFloorClip ()
 	for (m = touching_sectorlist; m; m = m->m_tnext)
 	{
 		sector_t *hsec = m->m_sector->GetHeightSec();
-		if (hsec == NULL && m->m_sector->floorplane.ZatPoint (x, y) == z)
+		if (hsec == NULL && m->m_sector->floorplane.ZatPoint (this) == Z())
 		{
 			fixed_t clip = Terrains[m->m_sector->GetTerrain(sector_t::floor)].FootClip;
 			if (clip < shallowestclip)
@@ -4430,9 +4433,9 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
 		( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) &&
 		( p->mo->Sector->damageamount < TELEFRAG_DAMAGE ))	// this really should be a bit smarter...
 	{
-		spawn_x = p->mo->x;
-		spawn_y = p->mo->y;
-		spawn_z = p->mo->z;
+		spawn_x = p->mo->X();
+		spawn_y = p->mo->Y();
+		spawn_z = p->mo->Z();
 
 		spawn_angle = p->mo->angle;
 	}
@@ -4469,9 +4472,9 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
 	if (level.flags & LEVEL_USEPLAYERSTARTZ)
 	{
 		if (spawn_z == ONFLOORZ)
-			mobj->z += mthing->z;
+			mobj->AddZ(mthing->z);
 		else if (spawn_z == ONCEILINGZ)
-			mobj->z -= mthing->z;
+			mobj->AddZ(-mthing->z);
 		P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT);
 	}
 
@@ -4592,14 +4595,14 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
 	if (multiplayer)
 	{
 		unsigned an = mobj->angle >> ANGLETOFINESHIFT;
-		Spawn ("TeleportFog", mobj->x+20*finecosine[an], mobj->y+20*finesine[an], mobj->z + TELEFOGHEIGHT, ALLOW_REPLACE);
+		Spawn ("TeleportFog", mobj->Vec3Offset(20*finecosine[an], 20*finesine[an], TELEFOGHEIGHT), ALLOW_REPLACE);
 	}
 
 	// "Fix" for one of the starts on exec.wad MAP01: If you start inside the ceiling,
 	// drop down below it, even if that means sinking into the floor.
-	if (mobj->z + mobj->height > mobj->ceilingz)
+	if (mobj->Top() > mobj->ceilingz)
 	{
-		mobj->z = mobj->ceilingz - mobj->height;
+		mobj->SetZ(mobj->ceilingz - mobj->height, false);
 	}
 
 	// [BC] Do script stuff
@@ -4907,14 +4910,14 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 
 	if (z == ONFLOORZ)
 	{
-		mobj->z += mthing->z;
+		mobj->AddZ(mthing->z);
 		if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB))
 		{
 			mobj->special1 = mthing->z;
 		}
 	}
 	else if (z == ONCEILINGZ)
-		mobj->z -= mthing->z;
+		mobj->AddZ(-mthing->z);
 
 	mobj->SpawnPoint[0] = mthing->x;
 	mobj->SpawnPoint[1] = mthing->y;
@@ -5208,7 +5211,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
 	}
 	if (bloodtype >= 1)
 	{
-		P_DrawSplash2 (40, x, y, z, R_PointToAngle2 (x, y, originator->x, originator->y), 2, bloodcolor);
+		P_DrawSplash2 (40, x, y, z, R_PointToAngle2 (x, y, originator->X(), originator->Y()), 2, bloodcolor);
 	}
 }
 
@@ -5248,7 +5251,7 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
 	}
 	if (bloodtype >= 1)
 	{
-		P_DrawSplash2 (100, x, y, z, R_PointToAngle2 (0, 0, originator->x - x, originator->y - y), 2, bloodcolor);
+		P_DrawSplash2 (100, x, y, z, R_PointToAngle2 (0, 0, originator->X() - x, originator->Y() - y), 2, bloodcolor);
 	}
 }
 
@@ -5260,13 +5263,13 @@ void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
 
 void P_RipperBlood (AActor *mo, AActor *bleeder)
 {
-	fixed_t x, y, z;
 	PalEntry bloodcolor = bleeder->GetBloodColor();
 	const PClass *bloodcls = bleeder->GetBloodType();
 
-	x = mo->x + (pr_ripperblood.Random2 () << 12);
-	y = mo->y + (pr_ripperblood.Random2 () << 12);
-	z = mo->z + (pr_ripperblood.Random2 () << 12);
+	fixedvec3 pos = mo->Vec3Offset(
+		(pr_ripperblood.Random2 () << 12),
+		(pr_ripperblood.Random2 () << 12),
+		(pr_ripperblood.Random2 () << 12));
 
 	int bloodtype = cl_bloodtype;
 	
@@ -5276,7 +5279,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
 	if (bloodcls != NULL)
 	{
 		AActor *th;
-		th = Spawn (bloodcls, x, y, z, NO_REPLACE); // GetBloodType already performed the replacement
+		th = Spawn (bloodcls, pos, NO_REPLACE); // GetBloodType already performed the replacement
 		// [NG] Applying PUFFGETSOWNER to the blood will make it target the owner
 		if (th->flags5 & MF5_PUFFGETSOWNER) th->target = bleeder;
 		if (gameinfo.gametype == GAME_Heretic)
@@ -5295,7 +5298,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
 	}
 	if (bloodtype >= 1)
 	{
-		P_DrawSplash2 (28, x, y, z, 0, 0, bloodcolor);
+		P_DrawSplash2 (28, pos.x, pos.y, pos.z, 0, 0, bloodcolor);
 	}
 }
 
@@ -5337,13 +5340,13 @@ bool P_HitWater (AActor * thing, sector_t * sec, fixed_t x, fixed_t y, fixed_t z
 	int terrainnum;
 	sector_t *hsec = NULL;
 	
-	if (x == FIXED_MIN) x = thing->x;
-	if (y == FIXED_MIN) y = thing->y;
-	if (z == FIXED_MIN) z = thing->z;
+	if (x == FIXED_MIN) x = thing->X();
+	if (y == FIXED_MIN) y = thing->Y();
+	if (z == FIXED_MIN) z = thing->Z();
 	// don't splash above the object
 	if (checkabove)
 	{
-		fixed_t compare_z = thing->z + (thing->height >> 1);
+		fixed_t compare_z = thing->Z() + (thing->height >> 1);
 		// Missiles are typically small and fast, so they might
 		// end up submerged by the move that calls P_HitWater.
 		if (thing->flags & MF_MISSILE)
@@ -5493,7 +5496,7 @@ bool P_HitFloor (AActor *thing)
 	// don't splash if landing on the edge above water/lava/etc....
 	for (m = thing->touching_sectorlist; m; m = m->m_tnext)
 	{
-		if (thing->z == m->m_sector->floorplane.ZatPoint(thing))
+		if (thing->Z() == m->m_sector->floorplane.ZatPoint(thing))
 		{
 			break;
 		}
@@ -5505,7 +5508,7 @@ bool P_HitFloor (AActor *thing)
 			if (!(rover->flags & FF_EXISTS)) continue;
 			if (rover->flags & (FF_SOLID|FF_SWIMMABLE))
 			{
-				if (rover->top.plane->ZatPoint(thing) == thing->z)
+				if (rover->top.plane->ZatPoint(thing) == thing->Z())
 				{
 					return P_HitWater (thing, m->m_sector);
 				}
@@ -5530,12 +5533,12 @@ bool P_HitFloor (AActor *thing)
 
 void P_CheckSplash(AActor *self, fixed_t distance)
 {
-	if (self->z <= self->floorz + (distance<<FRACBITS) && self->floorsector == self->Sector && self->Sector->GetHeightSec() == NULL)
+	if (self->Z() <= self->floorz + (distance<<FRACBITS) && self->floorsector == self->Sector && self->Sector->GetHeightSec() == NULL)
 	{
 		// Explosion splashes never alert monsters. This is because A_Explode has
 		// a separate parameter for that so this would get in the way of proper 
 		// behavior.
-		P_HitWater (self, self->Sector, self->x, self->y, self->floorz, false, false);
+		P_HitWater (self, self->Sector, self->X(), self->Y(), self->floorz, false, false);
 	}
 }
 
@@ -5572,9 +5575,10 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist)
 			advance *= 0.5f;
 		}
 		while (TVector2<double>(advance).LengthSquared() >= maxsquared);
-		th->x += FLOAT2FIXED(advance.X);
-		th->y += FLOAT2FIXED(advance.Y);
-		th->z += FLOAT2FIXED(advance.Z);
+		th->SetXYZ(
+			th->X() + FLOAT2FIXED(advance.X),
+			th->Y() + FLOAT2FIXED(advance.Y),
+			th->Z() + FLOAT2FIXED(advance.Z));
 	}
 
 	FCheckPosition tm(!!(th->flags2 & MF2_RIP));
@@ -5598,7 +5602,7 @@ bool P_CheckMissileSpawn (AActor* th, fixed_t maxdist)
 	bool MBFGrenade = (!(th->flags & MF_MISSILE) || (th->BounceFlags & BOUNCE_MBF));
 
 	// killough 3/15/98: no dropoff (really = don't care for missiles)
-	if (!(P_TryMove (th, th->x, th->y, false, NULL, tm, true)))
+	if (!(P_TryMove (th, th->X(), th->Y(), false, NULL, tm, true)))
 	{
 		// [RH] Don't explode ripping missiles that spawn inside something
 		if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP))
@@ -5651,7 +5655,7 @@ void P_PlaySpawnSound(AActor *missile, AActor *spawner)
 			// If there is no spawner use the spawn position.
 			// But not in a silenced sector.
 			if (!(missile->Sector->Flags & SECF_SILENT))
-				S_Sound (missile->x, missile->y, missile->z, CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM);
+				S_Sound (missile->X(), missile->Y(), missile->Z(), CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM);
 		}
 	}
 }
@@ -5680,7 +5684,7 @@ AActor *P_SpawnMissile (AActor *source, AActor *dest, const PClass *type, AActor
 	{
 		return NULL;
 	}
-	return P_SpawnMissileXYZ (source->x, source->y, source->z + 32*FRACUNIT + source->GetBobOffset(),
+	return P_SpawnMissileXYZ (source->X(), source->Y(), source->Z() + 32*FRACUNIT + source->GetBobOffset(),
 		source, dest, type, true, owner);
 }
 
@@ -5690,7 +5694,7 @@ AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, const PClass *
 	{
 		return NULL;
 	}
-	return P_SpawnMissileXYZ (source->x, source->y, z, source, dest, type);
+	return P_SpawnMissileXYZ (source->X(), source->Y(), z, source, dest, type);
 }
 
 AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
@@ -5729,16 +5733,16 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
 	// missile?
 	// Answer: No, because this way, you can set up sets of parallel missiles.
 
-	FVector3 velocity(dest->x - source->x, dest->y - source->y, dest->z - source->z);
+	FVector3 velocity = source->Vec3To(dest);
 	// Floor and ceiling huggers should never have a vertical component to their velocity
 	if (th->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))
 	{
 		velocity.Z = 0;
 	}
 	// [RH] Adjust the trajectory if the missile will go over the target's head.
-	else if (z - source->z >= dest->height)
+	else if (z - source->Z() >= dest->height)
 	{
-		velocity.Z += dest->height - z + source->z;
+		velocity.Z += dest->height - z + source->Z();
 	}
 	velocity.Resize (speed);
 	th->velx = (fixed_t)(velocity.X);
@@ -5776,7 +5780,7 @@ AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const
 	}
 	angle_t an;
 	fixed_t dist;
-	AActor *th = Spawn (type, source->x, source->y, source->z + 4*8*FRACUNIT, ALLOW_REPLACE);
+	AActor *th = Spawn (type, source->PosPlusZ(4*8*FRACUNIT), ALLOW_REPLACE);
 
 	P_PlaySpawnSound(th, source);
 	th->target = owner;		// record missile's originator
@@ -5792,7 +5796,7 @@ AActor * P_OldSpawnMissile(AActor * source, AActor * owner, AActor * dest, const
 	if (dist < 1)
 		dist = 1;
 
-	th->velz = (dest->z - source->z) / dist;
+	th->velz = (dest->Z() - source->Z()) / dist;
 
 	if (th->flags4 & MF4_SPECTRAL)
 	{
@@ -5819,7 +5823,7 @@ AActor *P_SpawnMissileAngle (AActor *source, const PClass *type,
 	{
 		return NULL;
 	}
-	return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(),
+	return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(),
 		type, angle, velz, GetDefaultSpeed (type));
 }
 
@@ -5850,7 +5854,7 @@ AActor *P_SpawnMissileZAimed (AActor *source, fixed_t z, AActor *dest, const PCl
 	dist = source->AproxDistance (dest);
 	speed = GetDefaultSpeed (type);
 	dist /= speed;
-	velz = dist != 0 ? (dest->z - source->z)/dist : speed;
+	velz = dist != 0 ? (dest->Z() - source->Z())/dist : speed;
 	return P_SpawnMissileAngleZSpeed (source, z, type, an, velz, speed);
 }
 
@@ -5870,7 +5874,7 @@ AActor *P_SpawnMissileAngleSpeed (AActor *source, const PClass *type,
 	{
 		return NULL;
 	}
-	return P_SpawnMissileAngleZSpeed (source, source->z + 32*FRACUNIT + source->GetBobOffset(),
+	return P_SpawnMissileAngleZSpeed (source, source->Z() + 32*FRACUNIT + source->GetBobOffset(),
 		type, angle, velz, speed);
 }
 
@@ -5888,7 +5892,7 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z,
 		z -= source->floorclip;
 	}
 
-	mo = Spawn (type, source->x, source->y, z, ALLOW_REPLACE);
+	mo = Spawn (type, source->X(), source->Y(), z, ALLOW_REPLACE);
 
 	P_PlaySpawnSound(mo, source);
 	if (owner == NULL) owner = source;
@@ -5988,7 +5992,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
 	if (z != ONFLOORZ && z != ONCEILINGZ)
 	{
 		// Doom spawns missiles 4 units lower than hitscan attacks for players.
-		z += source->z + (source->height>>1) - source->floorclip;
+		z += source->Z() + (source->height>>1) - source->floorclip;
 		if (source->player != NULL)	// Considering this is for player missiles, it better not be NULL.
 		{
 			z += FixedMul (source->player->mo->AttackZOffset - 4*FRACUNIT, source->player->crouchfactor);
@@ -6003,7 +6007,8 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
 			z = source->floorz;
 		}
 	}
-	AActor *MissileActor = Spawn (type, source->x + x, source->y + y, z, ALLOW_REPLACE);
+	fixedvec2 pos = source->Vec2Offset(x, y);
+	AActor *MissileActor = Spawn (type, pos.x, pos.y, z, ALLOW_REPLACE);
 	if (pMissileActor) *pMissileActor = MissileActor;
 	P_PlaySpawnSound(MissileActor, source);
 	MissileActor->target = source;
@@ -6511,7 +6516,7 @@ void PrintMiscActorInfo(AActor *query)
 			query->args[4],	query->special1, query->special2);
 		Printf("\nTID: %d", query->tid);
 		Printf("\nCoord= x: %f, y: %f, z:%f, floor:%f, ceiling:%f.",
-			FIXED2FLOAT(query->x), FIXED2FLOAT(query->y), FIXED2FLOAT(query->z),
+			FIXED2FLOAT(query->X()), FIXED2FLOAT(query->Y()), FIXED2FLOAT(query->Z()),
 			FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz));
 		Printf("\nSpeed= %f, velocity= x:%f, y:%f, z:%f, combined:%f.\n",
 			FIXED2FLOAT(query->Speed), FIXED2FLOAT(query->velx), FIXED2FLOAT(query->vely), FIXED2FLOAT(query->velz),
diff --git a/src/po_man.cpp b/src/po_man.cpp
index fb1d12519..a0cc4487b 100644
--- a/src/po_man.cpp
+++ b/src/po_man.cpp
@@ -901,7 +901,8 @@ void FPolyObj::ThrustMobj (AActor *actor, side_t *side)
 	actor->vely += thrustY;
 	if (crush)
 	{
-		if (bHurtOnTouch || !P_CheckMove (actor, actor->x + thrustX, actor->y + thrustY))
+		fixedvec2 pos = actor->Vec2Offset(thrustX, thrustY);
+		if (bHurtOnTouch || !P_CheckMove (actor, pos.x, pos.y))
 		{
 			int newdam = P_DamageMobj (actor, NULL, NULL, crush, NAME_Crush);
 			P_TraceBleed (newdam > 0 ? newdam : crush, actor);
@@ -1199,8 +1200,8 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
 							&& !((mobj->flags & MF_FLOAT) && (ld->flags & ML_BLOCK_FLOATERS))
 							&& (!(ld->flags & ML_3DMIDTEX) ||
 								(!P_LineOpening_3dMidtex(mobj, ld, open) &&
-									(mobj->z + mobj->height < open.top)
-								) || (open.abovemidtex && mobj->z > mobj->floorz))
+									(mobj->Top() < open.top)
+								) || (open.abovemidtex && mobj->Z() > mobj->floorz))
 							)
 						{
 							// [BL] We can't just continue here since we must
@@ -1213,7 +1214,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
 							performBlockingThrust = true;
 						}
 
-						FBoundingBox box(mobj->x, mobj->y, mobj->radius);
+						FBoundingBox box(mobj->X(), mobj->Y(), mobj->radius);
 
 						if (box.Right() <= ld->bbox[BOXLEFT]
 							|| box.Left() >= ld->bbox[BOXRIGHT]
@@ -1231,15 +1232,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
 						// Best use the one facing the player and ignore the back side.
 						if (ld->sidedef[1] != NULL)
 						{
-							int side = P_PointOnLineSidePrecise(mobj->x, mobj->y, ld);
+							int side = P_PointOnLineSidePrecise(mobj->X(), mobj->Y(), ld);
 							if (ld->sidedef[side] != sd)
 							{
 								continue;
 							}
 							// [BL] See if we hit below the floor/ceiling of the poly.
 							else if(!performBlockingThrust && (
-									mobj->z < ld->sidedef[!side]->sector->GetSecPlane(sector_t::floor).ZatPoint(mobj) ||
-									mobj->z + mobj->height > ld->sidedef[!side]->sector->GetSecPlane(sector_t::ceiling).ZatPoint(mobj)
+									mobj->Z() < ld->sidedef[!side]->sector->GetSecPlane(sector_t::floor).ZatPoint(mobj) ||
+									mobj->Top() > ld->sidedef[!side]->sector->GetSecPlane(sector_t::ceiling).ZatPoint(mobj)
 								))
 							{
 								performBlockingThrust = true;
diff --git a/src/s_sound.cpp b/src/s_sound.cpp
index 8508ff728..2a9703ae4 100644
--- a/src/s_sound.cpp
+++ b/src/s_sound.cpp
@@ -175,9 +175,10 @@ void S_NoiseDebug (void)
 		return;
 	}
 
-	listener.X = FIXED2FLOAT(players[consoleplayer].camera->x);
-	listener.Y = FIXED2FLOAT(players[consoleplayer].camera->z);
-	listener.Z = FIXED2FLOAT(players[consoleplayer].camera->y);
+
+	listener.X = FIXED2FLOAT(players[consoleplayer].camera->SoundX());
+	listener.Y = FIXED2FLOAT(players[consoleplayer].camera->SoundZ());
+	listener.Z = FIXED2FLOAT(players[consoleplayer].camera->SoundY());
 
 	// Display the oldest channel first.
 	for (chan = Channels; chan->NextChan != NULL; chan = chan->NextChan)
@@ -666,9 +667,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
 
 		if (players[consoleplayer].camera != NULL)
 		{
-			x = players[consoleplayer].camera->x;
-			y = players[consoleplayer].camera->z;
-			z = players[consoleplayer].camera->y;
+			x = players[consoleplayer].camera->SoundX();
+			y = players[consoleplayer].camera->SoundZ();
+			z = players[consoleplayer].camera->SoundY();
 		}
 		else
 		{
@@ -685,9 +686,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
 //			assert(actor != NULL);
 			if (actor != NULL)
 			{
-				x = actor->x;
-				y = actor->z;
-				z = actor->y;
+				x = actor->SoundX();
+				y = actor->SoundZ();
+				z = actor->SoundY();
 			}
 			break;
 
@@ -723,7 +724,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
 		{
 			if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL)
 			{
-				y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
+				y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->SoundZ() : 0;
 			}
 			pos->X = FIXED2FLOAT(x);
 			pos->Y = FIXED2FLOAT(y);
@@ -763,8 +764,8 @@ static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fix
 		// Are we inside the sector? If yes, the closest point is the one we're on.
 		if (P_PointInSector(*x, *y) == sec)
 		{
-			*x = players[consoleplayer].camera->x;
-			*y = players[consoleplayer].camera->y;
+			*x = players[consoleplayer].camera->SoundX();
+			*y = players[consoleplayer].camera->SoundY();
 		}
 		else
 		{
@@ -1567,9 +1568,9 @@ void S_RelinkSound (AActor *from, AActor *to)
 			{
 				chan->Actor = NULL;
 				chan->SourceType = SOURCE_Unattached;
-				chan->Point[0] = FIXED2FLOAT(from->x);
-				chan->Point[1] = FIXED2FLOAT(from->z);
-				chan->Point[2] = FIXED2FLOAT(from->y);
+				chan->Point[0] = FIXED2FLOAT(from->SoundX());
+				chan->Point[1] = FIXED2FLOAT(from->SoundZ());
+				chan->Point[2] = FIXED2FLOAT(from->SoundY());
 			}
 			else
 			{
@@ -1959,9 +1960,9 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor)
 		listener.velocity.Z = listenactor->vely * (TICRATE/65536.f);
 		*/
 		listener.velocity.Zero();
-		listener.position.X = FIXED2FLOAT(listenactor->x);
-		listener.position.Y = FIXED2FLOAT(listenactor->z);
-		listener.position.Z = FIXED2FLOAT(listenactor->y);
+		listener.position.X = FIXED2FLOAT(listenactor->SoundX());
+		listener.position.Y = FIXED2FLOAT(listenactor->SoundZ());
+		listener.position.Z = FIXED2FLOAT(listenactor->SoundY());
 		listener.underwater = listenactor->waterlevel == 3;
 		assert(zones != NULL);
 		listener.Environment = zones[listenactor->Sector->ZoneNumber].Environment;
diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 697aa7711..9b4304c9d 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -4603,7 +4603,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_WolfAttack)
 	fixedvec2 vec = self->Vec2To(self->target);
 	fixed_t dx = abs (vec.x);
 	fixed_t dy = abs (vec.y);
-	fixed_t dz;
 	fixed_t dist = dx > dy ? dx : dy;
 
 	// Some enemies are more precise

From 5c8ebf487dbb1abff83d9705e9bf1d6c91e2ed51 Mon Sep 17 00:00:00 2001
From: Edward Richardson <Edward850@crantime.org>
Date: Wed, 20 Jan 2016 19:14:43 +1300
Subject: [PATCH 09/23] Fixed load order for saves

- Make sure the PRNG tables are restored after the base level is loaded,
otherwise the tables will restore in a modified state.
---
 src/g_game.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/g_game.cpp b/src/g_game.cpp
index ca2233cdb..799a4e7aa 100644
--- a/src/g_game.cpp
+++ b/src/g_game.cpp
@@ -1930,9 +1930,6 @@ void G_DoLoadGame ()
 	}
 
 	G_ReadSnapshots (png);
-	STAT_Read(png);
-	FRandom::StaticReadRNGState (png);
-	P_ReadACSDefereds (png);
 
 	// load a base level
 	savegamerestore = true;		// Use the player actors in the savegame
@@ -1942,6 +1939,9 @@ void G_DoLoadGame ()
 	delete[] map;
 	savegamerestore = false;
 
+	STAT_Read(png);
+	FRandom::StaticReadRNGState(png);
+	P_ReadACSDefereds(png);
 	P_ReadACSVars(png);
 
 	NextSkill = -1;

From e9b23cf8335e36f59b7a1ef45738842548df9b09 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 09:25:30 +0100
Subject: [PATCH 10/23] - keep evaluation order of Random() calls defined.

---
 src/g_heretic/a_hereticweaps.cpp   |  6 +++---
 src/g_heretic/a_knight.cpp         |  7 +++----
 src/g_hexen/a_bishop.cpp           |  9 ++++-----
 src/g_hexen/a_dragon.cpp           |  9 ++++-----
 src/g_hexen/a_fighterquietus.cpp   |  9 ++++-----
 src/g_hexen/a_firedemon.cpp        |  9 ++++-----
 src/g_hexen/a_hexenspecialdecs.cpp | 17 +++++++++--------
 src/g_hexen/a_magelightning.cpp    | 11 +++++------
 src/g_hexen/a_wraith.cpp           | 27 ++++++++++++---------------
 src/g_shared/a_action.cpp          |  8 ++++----
 src/g_shared/a_debris.cpp          |  3 ++-
 src/g_strife/a_thingstoblowup.cpp  |  5 +++--
 src/p_effect.cpp                   |  9 +++++----
 src/p_mobj.cpp                     | 15 +++++++--------
 src/thingdef/thingdef_codeptr.cpp  | 16 ++++++++--------
 15 files changed, 77 insertions(+), 83 deletions(-)

diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp
index 8ec05b75e..ba216a8ba 100644
--- a/src/g_heretic/a_hereticweaps.cpp
+++ b/src/g_heretic/a_hereticweaps.cpp
@@ -1294,9 +1294,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
 	}
 	angle = self->angle;
 
-	fixedvec3 pos = self->Vec3Offset(
-		(pr_fp2.Random2() << 9),
-		(pr_fp2.Random2() << 9),
+	fixed_t xo = (pr_fp2.Random2() << 9);
+	fixed_t yo = (pr_fp2.Random2() << 9);
+	fixedvec3 pos = self->Vec3Offset(xo, yo,
 		26*FRACUNIT + finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] - self->floorclip);
 
 	slope = finetangent[FINEANGLES/4-(self->pitch>>ANGLETOFINESHIFT)] + (FRACUNIT/10);
diff --git a/src/g_heretic/a_knight.cpp b/src/g_heretic/a_knight.cpp
index d845920f9..0ae5a240a 100644
--- a/src/g_heretic/a_knight.cpp
+++ b/src/g_heretic/a_knight.cpp
@@ -23,10 +23,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_DripBlood)
 {
 	AActor *mo;
 
-	fixedvec3 pos = self->Vec3Offset(
-	 (pr_dripblood.Random2 () << 11),
-	 (pr_dripblood.Random2 () << 11), 0);
-	mo = Spawn ("Blood", pos, ALLOW_REPLACE);
+	fixed_t xo = (pr_dripblood.Random2() << 11);
+	fixed_t yo = (pr_dripblood.Random2() << 11);
+	mo = Spawn ("Blood", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE);
 	mo->velx = pr_dripblood.Random2 () << 10;
 	mo->vely = pr_dripblood.Random2 () << 10;
 	mo->gravity = FRACUNIT/8;
diff --git a/src/g_hexen/a_bishop.cpp b/src/g_hexen/a_bishop.cpp
index 8b252e63a..167fae568 100644
--- a/src/g_hexen/a_bishop.cpp
+++ b/src/g_hexen/a_bishop.cpp
@@ -193,11 +193,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_BishopPainBlur)
 		self->SetState (self->FindState ("Blur"));
 		return;
 	}
-	fixedvec3 pos = self->Vec3Offset(
-		(pr_pain.Random2()<<12),
-		(pr_pain.Random2()<<12),
-		(pr_pain.Random2()<<11));
-	mo = Spawn ("BishopPainBlur", pos, ALLOW_REPLACE);
+	fixed_t xo = (pr_pain.Random2() << 12);
+	fixed_t yo = (pr_pain.Random2() << 12);
+	fixed_t zo = (pr_pain.Random2() << 11);
+	mo = Spawn ("BishopPainBlur", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 	if (mo)
 	{
 		mo->angle = self->angle;
diff --git a/src/g_hexen/a_dragon.cpp b/src/g_hexen/a_dragon.cpp
index 7b160a689..9dc577aa9 100644
--- a/src/g_hexen/a_dragon.cpp
+++ b/src/g_hexen/a_dragon.cpp
@@ -252,12 +252,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_DragonFX2)
 	delay = 16+(pr_dragonfx2()>>3);
 	for (i = 1+(pr_dragonfx2()&3); i; i--)
 	{
-		fixedvec3 pos = self->Vec3Offset(
-			((pr_dragonfx2()-128)<<14),
-			((pr_dragonfx2()-128)<<14),
-			((pr_dragonfx2()-128)<<12));
+		fixed_t xo = ((pr_dragonfx2() - 128) << 14);
+		fixed_t yo = ((pr_dragonfx2() - 128) << 14);
+		fixed_t zo = ((pr_dragonfx2() - 128) << 12);
 
-		mo = Spawn ("DragonExplosion", pos, ALLOW_REPLACE);
+		mo = Spawn ("DragonExplosion", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->tics = delay+(pr_dragonfx2()&3)*i*2;
diff --git a/src/g_hexen/a_fighterquietus.cpp b/src/g_hexen/a_fighterquietus.cpp
index ae6df183c..cd3f65607 100644
--- a/src/g_hexen/a_fighterquietus.cpp
+++ b/src/g_hexen/a_fighterquietus.cpp
@@ -112,11 +112,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FSwordFlames)
 
 	for (i = 1+(pr_fswordflame()&3); i; i--)
 	{
-		fixedvec3 pos = self->Vec3Offset(
-			((pr_fswordflame()-128)<<12),
-			((pr_fswordflame()-128)<<12),
-			((pr_fswordflame()-128)<<11));
-		Spawn ("FSwordFlame", pos, ALLOW_REPLACE);
+		fixed_t xo = ((pr_fswordflame() - 128) << 12);
+		fixed_t yo = ((pr_fswordflame() - 128) << 12);
+		fixed_t zo = ((pr_fswordflame() - 128) << 11);
+		Spawn ("FSwordFlame", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 	}
 }
 
diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp
index e33c83896..40f03abbf 100644
--- a/src/g_hexen/a_firedemon.cpp
+++ b/src/g_hexen/a_firedemon.cpp
@@ -54,11 +54,10 @@ void A_FiredSpawnRock (AActor *actor)
 			break;
 	}
 
-	fixedvec3 pos = actor->Vec3Offset(
-		((pr_firedemonrock() - 128) << 12),
-		((pr_firedemonrock() - 128) << 12),
-		( pr_firedemonrock() << 11));
-	mo = Spawn (rtype, pos, ALLOW_REPLACE);
+	fixed_t xo = ((pr_firedemonrock() - 128) << 12);
+	fixed_t yo = ((pr_firedemonrock() - 128) << 12);
+	fixed_t zo = (pr_firedemonrock() << 11);
+	mo = Spawn (rtype, actor->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 	if (mo)
 	{
 		mo->target = actor;
diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp
index 19cb4f752..b79d9f2c2 100644
--- a/src/g_hexen/a_hexenspecialdecs.cpp
+++ b/src/g_hexen/a_hexenspecialdecs.cpp
@@ -197,11 +197,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_LeafSpawn)
 
 	for (i = (pr_leaf()&3)+1; i; i--)
 	{
+		fixed_t xo = (pr_leaf.Random2() << 14);
+		fixed_t yo = (pr_leaf.Random2() << 14);
+		fixed_t zo = (pr_leaf() << 14);
 		mo = Spawn (pr_leaf()&1 ? PClass::FindClass ("Leaf1") : PClass::FindClass ("Leaf2"),
-			self->Vec3Offset(
-			(pr_leaf.Random2()<<14),
-			(pr_leaf.Random2()<<14),
-			(pr_leaf()<<14)), ALLOW_REPLACE);
+			self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
+
 		if (mo)
 		{
 			P_ThrustMobj (mo, self->angle, (pr_leaf()<<9)+3*FRACUNIT);
@@ -278,10 +279,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SoAExplode)
 
 	for (i = 0; i < 10; i++)
 	{
-		mo = Spawn ("ZArmorChunk", self->Vec3Offset(
-			((pr_soaexplode()-128)<<12),
-			((pr_soaexplode()-128)<<12), 
-			(pr_soaexplode()*self->height/256)), ALLOW_REPLACE);
+		fixed_t xo = ((pr_soaexplode() - 128) << 12);
+		fixed_t yo = ((pr_soaexplode() - 128) << 12);
+		fixed_t zo = (pr_soaexplode()*self->height / 256);
+		mo = Spawn ("ZArmorChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->SetState (mo->SpawnState + i);
diff --git a/src/g_hexen/a_magelightning.cpp b/src/g_hexen/a_magelightning.cpp
index 88c6dba8b..c1dd7d7d0 100644
--- a/src/g_hexen/a_magelightning.cpp
+++ b/src/g_hexen/a_magelightning.cpp
@@ -227,12 +227,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_LightningZap)
 	else
 	{
 		deltaZ = -10*FRACUNIT;
-	}
-	mo = Spawn(lightning,
-		self->Vec3Offset(
-			((pr_zap() - 128)*self->radius / 256),
-			((pr_zap() - 128)*self->radius / 256),
-			deltaZ), ALLOW_REPLACE);
+	}			
+	fixed_t xo = ((pr_zap() - 128)*self->radius / 256);
+	fixed_t yo = ((pr_zap() - 128)*self->radius / 256);
+
+	mo = Spawn(lightning, self->Vec3Offset(xo, yo, deltaZ), ALLOW_REPLACE);
 	if (mo)
 	{
 		mo->lastenemy = self;
diff --git a/src/g_hexen/a_wraith.cpp b/src/g_hexen/a_wraith.cpp
index 312585cdf..3bbe567ac 100644
--- a/src/g_hexen/a_wraith.cpp
+++ b/src/g_hexen/a_wraith.cpp
@@ -147,12 +147,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_WraithFX3)
 
 	while (numdropped-- > 0)
 	{
-		fixedvec3 pos = self->Vec3Offset(
-			(pr_wraithfx3()-128)<<11,
-			(pr_wraithfx3()-128)<<11,
-			(pr_wraithfx3()<<10));
+		fixed_t xo = (pr_wraithfx3() - 128) << 11;
+		fixed_t yo = (pr_wraithfx3() - 128) << 11;
+		fixed_t zo = pr_wraithfx3() << 10;
 
-		mo = Spawn ("WraithFX3", pos, ALLOW_REPLACE);
+		mo = Spawn ("WraithFX3", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->floorz = self->floorz;
@@ -199,12 +198,11 @@ void A_WraithFX4 (AActor *self)
 
 	if (spawn4)
 	{
-		fixedvec3 pos = self->Vec3Offset(
-			(pr_wraithfx4()-128)<<12,
-			(pr_wraithfx4()-128)<<12,
-			(pr_wraithfx4()<<10));
+		fixed_t xo = (pr_wraithfx4() - 128) << 12;
+		fixed_t yo = (pr_wraithfx4() - 128) << 12;
+		fixed_t zo = (pr_wraithfx4() << 10);
 
-		mo = Spawn ("WraithFX4", pos, ALLOW_REPLACE);
+		mo = Spawn ("WraithFX4", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->floorz = self->floorz;
@@ -214,12 +212,11 @@ void A_WraithFX4 (AActor *self)
 	}
 	if (spawn5)
 	{
-		fixedvec3 pos = self->Vec3Offset(
-			(pr_wraithfx4()-128)<<12,
-			(pr_wraithfx4()-128)<<12,
-			(pr_wraithfx4()<<10));
+		fixed_t xo = (pr_wraithfx4() - 128) << 11;
+		fixed_t yo = (pr_wraithfx4() - 128) << 11;
+		fixed_t zo = (pr_wraithfx4()<<10);
 
-		mo = Spawn ("WraithFX5", pos, ALLOW_REPLACE);
+		mo = Spawn ("WraithFX5", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			mo->floorz = self->floorz;
diff --git a/src/g_shared/a_action.cpp b/src/g_shared/a_action.cpp
index 29f24b47e..e4b683e97 100644
--- a/src/g_shared/a_action.cpp
+++ b/src/g_shared/a_action.cpp
@@ -262,10 +262,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FreezeDeathChunks)
 	i = (pr_freeze.Random2()) % (numChunks/4);
 	for (i = MAX (24, numChunks + i); i >= 0; i--)
 	{
-		mo = Spawn("IceChunk", self->Vec3Offset(
-			(((pr_freeze()-128)*self->radius)>>7), 
-			(((pr_freeze()-128)*self->radius)>>7), 
-			(pr_freeze()*self->height/255)), ALLOW_REPLACE);
+		fixed_t xo = (((pr_freeze() - 128)*self->radius) >> 7);
+		fixed_t yo = (((pr_freeze() - 128)*self->radius) >> 7);
+		fixed_t zo = (pr_freeze()*self->height / 255);
+		mo = Spawn("IceChunk", self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 				mo->SetState (mo->SpawnState + (pr_freeze()%3));
diff --git a/src/g_shared/a_debris.cpp b/src/g_shared/a_debris.cpp
index c85c0fed9..f60e71595 100644
--- a/src/g_shared/a_debris.cpp
+++ b/src/g_shared/a_debris.cpp
@@ -34,7 +34,8 @@ void P_SpawnDirt (AActor *actor, fixed_t radius)
 	const PClass *dtype = NULL;
 	AActor *mo;
 
-	fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, (pr_dirt() << 9) + FRACUNIT);
+	fixed_t zo = (pr_dirt() << 9) + FRACUNIT;
+	fixedvec3 pos = actor->Vec3Angle(radius, pr_dirt() << 24, zo);
 
 	char fmt[8];
 	mysnprintf(fmt, countof(fmt), "Dirt%d", 1 + pr_dirt()%6);
diff --git a/src/g_strife/a_thingstoblowup.cpp b/src/g_strife/a_thingstoblowup.cpp
index 81dcc9f3e..3e0efe525 100644
--- a/src/g_strife/a_thingstoblowup.cpp
+++ b/src/g_strife/a_thingstoblowup.cpp
@@ -18,9 +18,10 @@ extern const PClass *QuestItemClasses[31];
 
 DEFINE_ACTION_FUNCTION(AActor, A_Bang4Cloud)
 {
-	fixedvec3 pos = self->Vec3Offset((pr_bang4cloud.Random2() & 3) * 10240, (pr_bang4cloud.Random2() & 3) * 10240, 0);
+	fixed_t xo = (pr_bang4cloud.Random2() & 3) * 10240;
+	fixed_t yo = (pr_bang4cloud.Random2() & 3) * 10240;
 
-	Spawn("Bang4Cloud", pos, ALLOW_REPLACE);
+	Spawn("Bang4Cloud", self->Vec3Offset(xo, yo, 0), ALLOW_REPLACE);
 }
 
 // -------------------------------------------------------------------
diff --git a/src/p_effect.cpp b/src/p_effect.cpp
index 2907b0d37..1ff9414bd 100644
--- a/src/p_effect.cpp
+++ b/src/p_effect.cpp
@@ -843,10 +843,11 @@ void P_DisconnectEffect (AActor *actor)
 		if (!p)
 			break;
 
-		fixedvec3 pos = actor->Vec3Offset(
-			((M_Random()-128)<<9) * (actor->radius>>FRACBITS),
-			((M_Random()-128)<<9) * (actor->radius>>FRACBITS),
-			(M_Random()<<8) * (actor->height>>FRACBITS));
+		
+		fixed_t xo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS);
+		fixed_t yo = ((M_Random() - 128) << 9) * (actor->radius >> FRACBITS);
+		fixed_t zo = (M_Random() << 8) * (actor->height >> FRACBITS);
+		fixedvec3 pos = actor->Vec3Offset(xo, yo, zo);
 		p->x = pos.x;
 		p->y = pos.y;
 		p->z = pos.z;
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index e2d5a3cf6..114c026f7 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -3297,10 +3297,9 @@ void AActor::Tick ()
 			{
 				smokecounter = 0;
 				angle_t moveangle = R_PointToAngle2(0,0,velx,vely);
-				AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(
-					- FixedMul (finecosine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
-					- FixedMul (finesine[(moveangle)>>ANGLETOFINESHIFT], radius*2) + (pr_rockettrail()<<10),
-					- (height>>3) * (velz>>16) + (2*height)/3), ALLOW_REPLACE);
+				fixed_t xo = -FixedMul(finecosine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10);
+				fixed_t yo = -FixedMul(finesine[(moveangle) >> ANGLETOFINESHIFT], radius * 2) + (pr_rockettrail() << 10);
+				AActor * th = Spawn("GrenadeSmokeTrail", Vec3Offset(xo, yo, - (height>>3) * (velz>>16) + (2*height)/3), ALLOW_REPLACE);
 				if (th)
 				{
 					th->tics -= pr_rockettrail()&3;
@@ -5266,10 +5265,10 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
 	PalEntry bloodcolor = bleeder->GetBloodColor();
 	const PClass *bloodcls = bleeder->GetBloodType();
 
-	fixedvec3 pos = mo->Vec3Offset(
-		(pr_ripperblood.Random2 () << 12),
-		(pr_ripperblood.Random2 () << 12),
-		(pr_ripperblood.Random2 () << 12));
+	fixed_t xo = (pr_ripperblood.Random2() << 12);
+	fixed_t yo = (pr_ripperblood.Random2() << 12);
+	fixed_t zo = (pr_ripperblood.Random2() << 12);
+	fixedvec3 pos = mo->Vec3Offset(xo, yo, zo);
 
 	int bloodtype = cl_bloodtype;
 	
diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 9b4304c9d..6a33bf595 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -2606,10 +2606,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnDebris)
 	
 	for (i = 0; i < GetDefaultByType(debris)->health; i++)
 	{
-		mo = Spawn(debris, self->Vec3Offset(
-			((pr_spawndebris()-128)<<12),
-			((pr_spawndebris()-128)<<12), 
-			(pr_spawndebris()*self->height/256+self->GetBobOffset())), ALLOW_REPLACE);
+		fixed_t xo = ((pr_spawndebris() - 128) << 12);
+		fixed_t yo = ((pr_spawndebris() - 128) << 12);
+		fixed_t zo = (pr_spawndebris()*self->height / 256 + self->GetBobOffset());
+		mo = Spawn(debris, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 		if (mo)
 		{
 			if (transfer_translation)
@@ -2924,10 +2924,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Burst)
 	i = (pr_burst.Random2()) % (numChunks/4);
 	for (i = MAX (24, numChunks + i); i >= 0; i--)
 	{
-		mo = Spawn(chunk, self->Vec3Offset( 
-			(((pr_burst()-128)*self->radius)>>7),
-			(((pr_burst()-128)*self->radius)>>7),
-			(pr_burst()*self->height/255 + self->GetBobOffset())), ALLOW_REPLACE);
+		fixed_t xo = (((pr_burst() - 128)*self->radius) >> 7);
+		fixed_t yo = (((pr_burst() - 128)*self->radius) >> 7);
+		fixed_t zo = (pr_burst()*self->height / 255 + self->GetBobOffset());
+		mo = Spawn(chunk, self->Vec3Offset(xo, yo, zo), ALLOW_REPLACE);
 
 		if (mo)
 		{

From 500bc2b852de14928696e7d7eccd86317e3ab16a Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 11:39:41 +0100
Subject: [PATCH 11/23] - fixed two refactoring errors:

* A_BridgeOrbit had its radius as an int, not a fixed_t.
* PIT_CheckThing used the wrong coordinate for checking actor distance.
---
 src/g_shared/a_bridge.cpp | 4 ++--
 src/p_map.cpp             | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/g_shared/a_bridge.cpp b/src/g_shared/a_bridge.cpp
index eed95d8d2..27dbb0c6b 100644
--- a/src/g_shared/a_bridge.cpp
+++ b/src/g_shared/a_bridge.cpp
@@ -100,14 +100,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_BridgeOrbit)
 	// Set default values
 	// Every five tics, Hexen moved the ball 3/256th of a revolution.
 	int rotationspeed  = ANGLE_45/32*3/5;
-	int rotationradius = ORBIT_RADIUS;
+	int rotationradius = ORBIT_RADIUS * FRACUNIT;
 	// If the bridge is custom, set non-default values if any.
 
 	// Set angular speed; 1--128: counterclockwise rotation ~=1--180�; 129--255: clockwise rotation ~= 180--1�
 	if (self->target->args[3] > 128) rotationspeed = ANGLE_45/32 * (self->target->args[3]-256) / TICRATE;
 	else if (self->target->args[3] > 0) rotationspeed = ANGLE_45/32 * (self->target->args[3]) / TICRATE;
 	// Set rotation radius
-	if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / (100 * FRACUNIT));
+	if (self->target->args[4]) rotationradius = ((self->target->args[4] * self->target->radius) / 100);
 
 	self->angle += rotationspeed;
 	self->SetOrigin(self->target->Vec3Angle(rotationradius, self->angle, 0), true);
diff --git a/src/p_map.cpp b/src/p_map.cpp
index 259becd67..364656d24 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -1034,7 +1034,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 
 	fixedvec3 thingpos = thing->PosRelative(tm.thing);
 	fixed_t blockdist = thing->radius + tm.thing->radius;
-	if (abs(thingpos.x - tm.thing->X()) >= blockdist || abs(thingpos.y - tm.thing->Y()) >= blockdist)
+	if (abs(thingpos.x - tm.x) >= blockdist || abs(thingpos.y - tm.y) >= blockdist)
 		return true;
 
 	if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS)
@@ -1087,7 +1087,7 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm)
 			if (newdist > olddist)
 			{
 				// ... but not if they did not overlap in z-direction before but would after the move.
-				unblocking = !((tm.thing->Z() >= thingpos.z + thing->height && tm.z < thingpos.z + thing->height) ||
+				unblocking = !((tm.thing->Z() >= topz && tm.z < topz) ||
 					(tm.thing->Top() <= thingpos.z && tm.thing->Top() > thingpos.z));
 			}
 		}

From 35271187a5cb481f4a2326ab9795db6fc170fc97 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 13:48:05 +0100
Subject: [PATCH 12/23] - took care of the rest of p_map.cpp.

---
 src/p_map.cpp    | 208 ++++++++++++++++++++++-------------------------
 src/p_maputl.cpp |   2 +-
 2 files changed, 99 insertions(+), 111 deletions(-)

diff --git a/src/p_map.cpp b/src/p_map.cpp
index 364656d24..43c7f6af0 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -3801,8 +3801,8 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance,
 			fixed_t dist = trace.Distance;
 			// position a bit closer for puffs/blood if using compatibility mode.
 			if (i_compatflags & COMPATF_HITSCAN) dist -= 10 * FRACUNIT;
-			hitx = t1->x + FixedMul(vx, dist);
-			hity = t1->y + FixedMul(vy, dist);
+			hitx = t1->X() + FixedMul(vx, dist);
+			hity = t1->Y() + FixedMul(vy, dist);
 			hitz = shootz + FixedMul(vz, dist);
 
 			
@@ -3943,7 +3943,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch,
 	vy = FixedMul(finecosine[pitch], finesine[angle]);
 	vz = -finesine[pitch];
 
-	shootz = t1->z - t1->floorclip + (t1->height >> 1);
+	shootz = t1->Z() - t1->floorclip + (t1->height >> 1);
 	if (t1->player != NULL)
 	{
 		shootz += FixedMul(t1->player->mo->AttackZOffset, t1->player->crouchfactor);
@@ -3959,7 +3959,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch,
 	TData.Caller = t1;
 	TData.hitGhosts = true;
 	
-	if (Trace(t1->x, t1->y, shootz, t1->Sector, vx, vy, vz, distance,
+	if (Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance,
 		actorMask, wallMask, t1, trace, TRACE_NoSky, CheckForActor, &TData))
 	{
 		if (trace.HitType == TRACE_HitActor)
@@ -4063,7 +4063,7 @@ void P_TraceBleed(int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, an
 
 void P_TraceBleed(int damage, AActor *target, angle_t angle, int pitch)
 {
-	P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2,
+	P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2,
 		target, angle, pitch);
 }
 
@@ -4086,14 +4086,14 @@ void P_TraceBleed(int damage, AActor *target, AActor *missile)
 	{
 		double aim;
 
-		aim = atan((double)missile->velz / (double)P_AproxDistance(missile->x - target->x, missile->y - target->y));
+		aim = atan((double)missile->velz / (double)target->AproxDistance(missile));
 		pitch = -(int)(aim * ANGLE_180 / PI);
 	}
 	else
 	{
 		pitch = 0;
 	}
-	P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2,
+	P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2,
 		target, missile->AngleTo(target),
 		pitch);
 }
@@ -4111,7 +4111,7 @@ void P_TraceBleed(int damage, AActor *target)
 		fixed_t one = pr_tracebleed() << 24;
 		fixed_t two = (pr_tracebleed() - 128) << 16;
 
-		P_TraceBleed(damage, target->x, target->y, target->z + target->height / 2,
+		P_TraceBleed(damage, target->X(), target->Y(), target->Z() + target->height / 2,
 			target, one, two);
 	}
 }
@@ -4174,7 +4174,6 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 {
 	fixed_t vx, vy, vz;
 	angle_t angle, pitch;
-	fixed_t x1, y1;
 	TVector3<double> start, end;
 	FTraceResults trace;
 	fixed_t shootz;
@@ -4188,10 +4187,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 	vy = FixedMul(finecosine[pitch], finesine[angle]);
 	vz = finesine[pitch];
 
-	x1 = source->x;
-	y1 = source->y;
-
-	shootz = source->z - source->floorclip + (source->height >> 1) + offset_z;
+	shootz = source->Z() - source->floorclip + (source->height >> 1) + offset_z;
 
 	if (!(railflags & RAF_CENTERZ))
 	{
@@ -4206,15 +4202,15 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 	}
 
 	angle = ((source->angle + angleoffset) - ANG90) >> ANGLETOFINESHIFT;
-	x1 += offset_xy * finecosine[angle];
-	y1 += offset_xy * finesine[angle];
+
+	fixedvec2 xy = source->Vec2Offset(offset_xy * finecosine[angle], offset_xy * finesine[angle]);
 
 	RailData rail_data;
 	rail_data.Caller = source;
 	
 	rail_data.StopAtOne = !!(railflags & RAF_NOPIERCE);
-	start.X = FIXED2FLOAT(x1);
-	start.Y = FIXED2FLOAT(y1);
+	start.X = FIXED2FLOAT(xy.x);
+	start.Y = FIXED2FLOAT(xy.y);
 	start.Z = FIXED2FLOAT(shootz);
 
 	int flags;
@@ -4225,7 +4221,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 	flags = (puffDefaults->flags6 & MF6_NOTRIGGER) ? 0 : TRACE_PCross | TRACE_Impact;
 	rail_data.StopAtInvul = (puffDefaults->flags3 & MF3_FOILINVUL) ? false : true;
 	rail_data.ThruSpecies = (puffDefaults->flags6 & MF6_MTHRUSPECIES) ? true : false;
-	Trace(x1, y1, shootz, source->Sector, vx, vy, vz,
+	Trace(xy.x, xy.y, shootz, source->Sector, vx, vy, vz,
 		distance, MF_SHOOTABLE, ML_BLOCKEVERYTHING, source, trace,
 		flags, ProcessRailHit, &rail_data);
 
@@ -4236,7 +4232,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 	// used as damage inflictor
 	AActor *thepuff = NULL;
 
-	if (puffclass != NULL) thepuff = Spawn(puffclass, source->x, source->y, source->z, ALLOW_REPLACE);
+	if (puffclass != NULL) thepuff = Spawn(puffclass, source->Pos(), ALLOW_REPLACE);
 
 	for (i = 0; i < rail_data.RailHits.Size(); i++)
 	{
@@ -4250,8 +4246,8 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 		AActor *hitactor = rail_data.RailHits[i].HitActor;
 		fixed_t hitdist = rail_data.RailHits[i].Distance;		
 
-		x = x1 + FixedMul(hitdist, vx);
-		y = y1 + FixedMul(hitdist, vy);
+		x = xy.x + FixedMul(hitdist, vx);
+		y = xy.y + FixedMul(hitdist, vy);
 		z = shootz + FixedMul(hitdist, vz);
 
 		if ((hitactor->flags & MF_NOBLOOD) ||
@@ -4329,7 +4325,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i
 			trace.CrossedWater == NULL &&
 			trace.Sector->heightsec == NULL)
 		{
-			thepuff->SetOrigin(trace.X, trace.Y, trace.Z);
+			thepuff->SetOrigin(trace.X, trace.Y, trace.Z, false);
 			P_HitWater(thepuff, trace.Sector);
 		}
 		if (trace.Crossed3DWater || trace.CrossedWater)
@@ -4367,16 +4363,16 @@ void P_AimCamera(AActor *t1, fixed_t &CameraX, fixed_t &CameraY, fixed_t &Camera
 	vy = FixedMul(finecosine[pitch], finesine[angle]);
 	vz = finesine[pitch];
 
-	sz = t1->z - t1->floorclip + t1->height + (fixed_t)(clamp<double>(chase_height, -1000, 1000) * FRACUNIT);
+	sz = t1->Z() - t1->floorclip + t1->height + (fixed_t)(clamp<double>(chase_height, -1000, 1000) * FRACUNIT);
 
-	if (Trace(t1->x, t1->y, sz, t1->Sector,
+	if (Trace(t1->X(), t1->Y(), sz, t1->Sector,
 		vx, vy, vz, distance, 0, 0, NULL, trace) &&
 		trace.Distance > 10 * FRACUNIT)
 	{
 		// Position camera slightly in front of hit thing
 		fixed_t dist = trace.Distance - 5 * FRACUNIT;
-		CameraX = t1->x + FixedMul(vx, dist);
-		CameraY = t1->y + FixedMul(vy, dist);
+		CameraX = t1->X() + FixedMul(vx, dist);
+		CameraY = t1->Y() + FixedMul(vy, dist);
 		CameraZ = sz + FixedMul(vz, dist);
 	}
 	else
@@ -4443,7 +4439,7 @@ bool P_TalkFacing(AActor *player)
 
 bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline)
 {
-	FPathTraverse it(usething->x, usething->y, endx, endy, PT_ADDLINES | PT_ADDTHINGS);
+	FPathTraverse it(usething->X(), usething->Y(), endx, endy, PT_ADDLINES | PT_ADDTHINGS);
 	intercept_t *in;
 
 	while ((in = it.Next()))
@@ -4492,7 +4488,7 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline
 					return true;
 				}
 
-				sec = P_PointOnLineSide(usething->x, usething->y, in->d.line) == 0 ?
+				sec = P_PointOnLineSide(usething->X(), usething->Y(), in->d.line) == 0 ?
 					in->d.line->frontsector : in->d.line->backsector;
 
 				if (sec != NULL && sec->SecActTarget &&
@@ -4511,7 +4507,7 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline
 			continue;			// not a special line, but keep checking
 		}
 
-		if (P_PointOnLineSide(usething->x, usething->y, in->d.line) == 1)
+		if (P_PointOnLineSide(usething->X(), usething->Y(), in->d.line) == 1)
 		{
 			if (!(in->d.line->activation & SPAC_UseBack))
 			{
@@ -4571,7 +4567,7 @@ bool P_UseTraverse(AActor *usething, fixed_t endx, fixed_t endy, bool &foundline
 
 bool P_NoWayTraverse(AActor *usething, fixed_t endx, fixed_t endy)
 {
-	FPathTraverse it(usething->x, usething->y, endx, endy, PT_ADDLINES);
+	FPathTraverse it(usething->X(), usething->Y(), endx, endy, PT_ADDLINES);
 	intercept_t *in;
 
 	while ((in = it.Next()))
@@ -4586,8 +4582,8 @@ bool P_NoWayTraverse(AActor *usething, fixed_t endx, fixed_t endy)
 		P_LineOpening(open, NULL, ld, it.Trace().x + FixedMul(it.Trace().dx, in->frac),
 			it.Trace().y + FixedMul(it.Trace().dy, in->frac));
 		if (open.range <= 0 ||
-			open.bottom > usething->z + usething->MaxStepHeight ||
-			open.top < usething->z + usething->height) return true;
+			open.bottom > usething->Z() + usething->MaxStepHeight ||
+			open.top < usething->Top()) return true;
 	}
 	return false;
 }
@@ -4602,18 +4598,10 @@ bool P_NoWayTraverse(AActor *usething, fixed_t endx, fixed_t endy)
 
 void P_UseLines(player_t *player)
 {
-	angle_t angle;
-	fixed_t x1, y1, usedist;
-	bool foundline;
-
-	foundline = false;
-
-	angle = player->mo->angle >> ANGLETOFINESHIFT;
-	usedist = player->mo->UseRange;
+	bool foundline = false;
 
 	// [NS] Now queries the Player's UseRange.
-	x1 = player->mo->x + FixedMul(usedist, finecosine[angle]);
-	y1 = player->mo->y + FixedMul(usedist, finesine[angle]);
+	fixedvec2 end = player->mo->Vec2Angle(player->mo->UseRange, player->mo->angle, true);
 
 	// old code:
 	//
@@ -4621,13 +4609,13 @@ void P_UseLines(player_t *player)
 	//
 	// This added test makes the "oof" sound work on 2s lines -- killough:
 
-	if (!P_UseTraverse(player->mo, x1, y1, foundline))
+	if (!P_UseTraverse(player->mo, end.x, end.y, foundline))
 	{ // [RH] Give sector a chance to eat the use
 		sector_t *sec = player->mo->Sector;
 		int spac = SECSPAC_Use;
 		if (foundline) spac |= SECSPAC_UseWall;
 		if ((!sec->SecActTarget || !sec->SecActTarget->TriggerAction(player->mo, spac)) &&
-			P_NoWayTraverse(player->mo, x1, y1))
+			P_NoWayTraverse(player->mo, end.x, end.y))
 		{
 			S_Sound(player->mo, CHAN_VOICE, "*usefail", 1, ATTN_IDLE);
 		}
@@ -4648,8 +4636,8 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType)
 	fixed_t x1, y1, x2, y2, usedist;
 
 	angle = PuzzleItemUser->angle >> ANGLETOFINESHIFT;
-	x1 = PuzzleItemUser->x;
-	y1 = PuzzleItemUser->y;
+	x1 = PuzzleItemUser->X();
+	y1 = PuzzleItemUser->Y();
 
 	// [NS] If it's a Player, get their UseRange.
 	if (PuzzleItemUser->player)
@@ -4680,7 +4668,7 @@ bool P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType)
 				}
 				continue;
 			}
-			if (P_PointOnLineSide(PuzzleItemUser->x, PuzzleItemUser->y, in->d.line) == 1)
+			if (P_PointOnLineSide(PuzzleItemUser->X(), PuzzleItemUser->Y(), in->d.line) == 1)
 			{ // Don't use back sides
 				return false;
 			}
@@ -4747,7 +4735,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
 	double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance);
 	double bombdamagefloat = (double)bombdamage;
 
-	FBlockThingsIterator it(FBoundingBox(bombspot->x, bombspot->y, bombdistance << FRACBITS));
+	FBlockThingsIterator it(FBoundingBox(bombspot->X(), bombspot->Y(), bombdistance << FRACBITS));
 	AActor *thing;
 
 	if (flags & RADF_SOURCEISSPOT)
@@ -4796,24 +4784,25 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
 			fixed_t dx, dy;
 			double boxradius;
 
-			dx = abs(thing->x - bombspot->x);
-			dy = abs(thing->y - bombspot->y);
+			fixedvec2 vec = bombspot->Vec2To(thing);
+			dx = abs(vec.x);
+			dy = abs(vec.y);
 			boxradius = double(thing->radius);
 
 			// The damage pattern is square, not circular.
 			len = double(dx > dy ? dx : dy);
 
-			if (bombspot->z < thing->z || bombspot->z >= thing->z + thing->height)
+			if (bombspot->Z() < thing->Z() || bombspot->Z() >= thing->Top())
 			{
 				double dz;
 
-				if (bombspot->z > thing->z)
+				if (bombspot->Z() > thing->Z())
 				{
-					dz = double(bombspot->z - thing->z - thing->height);
+					dz = double(bombspot->Z() - thing->Top());
 				}
 				else
 				{
-					dz = double(thing->z - bombspot->z);
+					dz = double(thing->Z() - bombspot->Z());
 				}
 				if (len <= boxradius)
 				{
@@ -4870,7 +4859,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
 								{
 									thrust *= selfthrustscale;
 								}
-								velz = (double)(thing->z + (thing->height >> 1) - bombspot->z) * thrust;
+								velz = (double)(thing->Z() + (thing->height >> 1) - bombspot->Z()) * thrust;
 								if (bombsource != thing)
 								{
 									velz *= 0.5f;
@@ -4895,8 +4884,9 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
 			// [RH] Old code just for barrels
 			fixed_t dx, dy, dist;
 
-			dx = abs(thing->x - bombspot->x);
-			dy = abs(thing->y - bombspot->y);
+			fixedvec2 vec = bombspot->Vec2To(thing);
+			dx = abs(vec.x);
+			dy = abs(vec.y);
 
 			dist = dx>dy ? dx : dy;
 			dist = (dist - thing->radius) >> FRACBITS;
@@ -4983,7 +4973,7 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos)
 		thing->flags2 |= MF2_PASSMOBJ;
 	}
 
-	bool isgood = P_CheckPosition(thing, thing->x, thing->y, tm);
+	bool isgood = P_CheckPosition(thing, thing->X(), thing->Y(), tm);
 	thing->floorz = tm.floorz;
 	thing->ceilingz = tm.ceilingz;
 	thing->dropoffz = tm.dropoffz;		// killough 11/98: remember dropoffs
@@ -5014,7 +5004,7 @@ void P_FindAboveIntersectors(AActor *actor)
 		return;
 
 	AActor *thing;
-	FBlockThingsIterator it(FBoundingBox(actor->x, actor->y, actor->radius));
+	FBlockThingsIterator it(FBoundingBox(actor->X(), actor->Y(), actor->radius));
 	while ((thing = it.Next()))
 	{
 		if (!thing->intersects(actor))
@@ -5045,8 +5035,8 @@ void P_FindAboveIntersectors(AActor *actor)
 			// not what is wanted here.
 			continue;
 		}
-		if (thing->z >= actor->z &&
-			thing->z <= actor->z + actor->height)
+		if (thing->Z() >= actor->Z() &&
+			thing->Z() <= actor->Top())
 		{ // Thing intersects above the base
 			intersectors.Push(thing);
 		}
@@ -5068,7 +5058,7 @@ void P_FindBelowIntersectors(AActor *actor)
 		return;
 
 	AActor *thing;
-	FBlockThingsIterator it(FBoundingBox(actor->x, actor->y, actor->radius));
+	FBlockThingsIterator it(FBoundingBox(actor->X(), actor->Y(), actor->radius));
 	while ((thing = it.Next()))
 	{
 		if (!thing->intersects(actor))
@@ -5099,8 +5089,8 @@ void P_FindBelowIntersectors(AActor *actor)
 			// not what is wanted here.
 			continue;
 		}
-		if (thing->z + thing->height <= actor->z + actor->height &&
-			thing->z + thing->height > actor->z)
+		if (thing->Top() <= actor->Top() &&
+			thing->Top() > actor->Z())
 		{ // Thing intersects below the base
 			intersectors.Push(thing);
 		}
@@ -5136,8 +5126,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
 				{
 					AActor *mo;
 
-					mo = Spawn(bloodcls, thing->x, thing->y,
-						thing->z + thing->height / 2, ALLOW_REPLACE);
+					mo = Spawn(bloodcls, thing->PosPlusZ(thing->height / 2), ALLOW_REPLACE);
 
 					mo->velx = pr_crunch.Random2() << 12;
 					mo->vely = pr_crunch.Random2() << 12;
@@ -5153,7 +5142,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
 				an = (M_Random() - 128) << 24;
 				if (cl_bloodtype >= 1)
 				{
-					P_DrawSplash2(32, thing->x, thing->y, thing->z + thing->height / 2, an, 2, bloodcolor);
+					P_DrawSplash2(32, thing->X(), thing->Y(), thing->Z() + thing->height / 2, an, 2, bloodcolor);
 				}
 			}
 			if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound))
@@ -5181,7 +5170,7 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
 	unsigned int lastintersect;
 	int mymass = thing->Mass;
 
-	if (thing->z + thing->height > thing->ceilingz)
+	if (thing->Top() > thing->ceilingz)
 	{
 		return 1;
 	}
@@ -5210,13 +5199,13 @@ int P_PushUp(AActor *thing, FChangePosition *cpos)
 			return 2;
 		}
 		fixed_t oldz;
-		oldz = intersect->z;
+		oldz = intersect->Z();
 		P_AdjustFloorCeil(intersect, cpos);
-		intersect->z = thing->z + thing->height + 1;
+		intersect->SetZ(thing->Top() + 1);
 		if (P_PushUp(intersect, cpos))
 		{ // Move blocked
 			P_DoCrunch(intersect, cpos);
-			intersect->z = oldz;
+			intersect->SetZ(oldz);
 			return 2;
 		}
 	}
@@ -5237,7 +5226,7 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
 	unsigned int lastintersect;
 	int mymass = thing->Mass;
 
-	if (thing->z <= thing->floorz)
+	if (thing->Z() <= thing->floorz)
 	{
 		return 1;
 	}
@@ -5254,15 +5243,15 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
 			// Can't push bridges or things more massive than ourself
 			return 2;
 		}
-		fixed_t oldz = intersect->z;
+		fixed_t oldz = intersect->Z();
 		P_AdjustFloorCeil(intersect, cpos);
-		if (oldz > thing->z - intersect->height)
+		if (oldz > thing->Z() - intersect->height)
 		{ // Only push things down, not up.
-			intersect->z = thing->z - intersect->height;
+			intersect->SetZ(thing->Z() - intersect->height);
 			if (P_PushDown(intersect, cpos))
 			{ // Move blocked
 				P_DoCrunch(intersect, cpos);
-				intersect->z = oldz;
+				intersect->SetZ(oldz);
 				return 2;
 			}
 		}
@@ -5287,24 +5276,24 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
 
 	if (thing->velz == 0 &&
 		(!(thing->flags & MF_NOGRAVITY) ||
-		(thing->z == oldfloorz && !(thing->flags & MF_NOLIFTDROP))))
+		(thing->Z() == oldfloorz && !(thing->flags & MF_NOLIFTDROP))))
 	{
-		fixed_t oldz = thing->z;
+		fixed_t oldz = thing->Z();
 
 		if ((thing->flags & MF_NOGRAVITY) || (thing->flags5 & MF5_MOVEWITHSECTOR) ||
 			(((cpos->sector->Flags & SECF_FLOORDROP) || cpos->moveamt < 9 * FRACUNIT)
-			&& thing->z - thing->floorz <= cpos->moveamt))
+			&& thing->Z() - thing->floorz <= cpos->moveamt))
 		{
-			thing->z = thing->floorz;
+			thing->SetZ(thing->floorz);
 			P_CheckFakeFloorTriggers(thing, oldz);
 		}
 	}
-	else if ((thing->z != oldfloorz && !(thing->flags & MF_NOLIFTDROP)))
+	else if ((thing->Z() != oldfloorz && !(thing->flags & MF_NOLIFTDROP)))
 	{
-		fixed_t oldz = thing->z;
+		fixed_t oldz = thing->Z();
 		if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR))
 		{
-			thing->z = thing->z - oldfloorz + thing->floorz;
+			thing->AddZ(-oldfloorz + thing->floorz);
 			P_CheckFakeFloorTriggers(thing, oldz);
 		}
 	}
@@ -5319,14 +5308,14 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
 void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
 {
 	fixed_t oldfloorz = thing->floorz;
-	fixed_t oldz = thing->z;
+	fixed_t oldz = thing->Z();
 
 	P_AdjustFloorCeil(thing, cpos);
 
 	if (oldfloorz == thing->floorz) return;
 
 	// Move things intersecting the floor up
-	if (thing->z <= thing->floorz)
+	if (thing->Z() <= thing->floorz)
 	{
 		if (thing->flags4 & MF4_ACTLIKEBRIDGE)
 		{
@@ -5334,14 +5323,14 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
 			return; // do not move bridge things
 		}
 		intersectors.Clear();
-		thing->z = thing->floorz;
+		thing->SetZ(thing->floorz);
 	}
 	else
 	{
 		if ((thing->flags & MF_NOGRAVITY) && (thing->flags6 & MF6_RELATIVETOFLOOR))
 		{
 			intersectors.Clear();
-			thing->z = thing->z - oldfloorz + thing->floorz;
+			thing->AddZ(-oldfloorz + thing->floorz);
 		}
 		else return;
 	}
@@ -5356,7 +5345,7 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
 		break;
 	case 2:
 		P_DoCrunch(thing, cpos);
-		thing->z = oldz;
+		thing->SetZ(oldz);
 		break;
 	}
 }
@@ -5371,10 +5360,10 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 {
 	bool onfloor;
 
-	onfloor = thing->z <= thing->floorz;
+	onfloor = thing->Z() <= thing->floorz;
 	P_AdjustFloorCeil(thing, cpos);
 
-	if (thing->z + thing->height > thing->ceilingz)
+	if (thing->Top() > thing->ceilingz)
 	{
 		if (thing->flags4 & MF4_ACTLIKEBRIDGE)
 		{
@@ -5382,14 +5371,14 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 			return; // do not move bridge things
 		}
 		intersectors.Clear();
-		fixed_t oldz = thing->z;
+		fixed_t oldz = thing->Z();
 		if (thing->ceilingz - thing->height >= thing->floorz)
 		{
-			thing->z = thing->ceilingz - thing->height;
+			thing->SetZ(thing->ceilingz - thing->height);
 		}
 		else
 		{
-			thing->z = thing->floorz;
+			thing->SetZ(thing->floorz);
 		}
 		switch (P_PushDown(thing, cpos))
 		{
@@ -5397,7 +5386,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 			// intentional fall-through
 		case 1:
 			if (onfloor)
-				thing->z = thing->floorz;
+				thing->SetZ(thing->floorz);
 			P_DoCrunch(thing, cpos);
 			P_CheckFakeFloorTriggers(thing, oldz);
 			break;
@@ -5423,25 +5412,24 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
 	// For DOOM compatibility, only move things that are inside the floor.
 	// (or something else?) Things marked as hanging from the ceiling will
 	// stay where they are.
-	if (thing->z < thing->floorz &&
-		thing->z + thing->height >= thing->ceilingz - cpos->moveamt &&
+	if (thing->Z() < thing->floorz &&
+		thing->Top() >= thing->ceilingz - cpos->moveamt &&
 		!(thing->flags & MF_NOLIFTDROP))
 	{
-		fixed_t oldz = thing->z;
-		thing->z = thing->floorz;
-		if (thing->z + thing->height > thing->ceilingz)
+		fixed_t oldz = thing->Z();
+		thing->SetZ(thing->floorz);
+		if (thing->Top() > thing->ceilingz)
 		{
-			thing->z = thing->ceilingz - thing->height;
+			thing->SetZ(thing->ceilingz - thing->height);
 		}
 		P_CheckFakeFloorTriggers(thing, oldz);
 	}
-	else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->z + thing->height < thing->ceilingz)
+	else if ((thing->flags2 & MF2_PASSMOBJ) && !isgood && thing->Top() < thing->ceilingz)
 	{
 		AActor *onmobj;
-		if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->z <= thing->z)
+		if (!P_TestMobjZ(thing, true, &onmobj) && onmobj->Z() <= thing->Z())
 		{
-			thing->z = MIN(thing->ceilingz - thing->height,
-				onmobj->z + onmobj->height);
+			thing->SetZ( MIN(thing->ceilingz - thing->height, onmobj->Top()));
 		}
 	}
 }
@@ -5598,8 +5586,8 @@ bool P_ChangeSector(sector_t *sector, int crunch, int amt, int floorOrCeil, bool
 					{
 						n->visited = true; 							// mark thing as processed
 
-						n->m_thing->UpdateWaterLevel(n->m_thing->z, false);
-						P_CheckFakeFloorTriggers(n->m_thing, n->m_thing->z - amt);
+						n->m_thing->UpdateWaterLevel(n->m_thing->Z(), false);
+						P_CheckFakeFloorTriggers(n->m_thing, n->m_thing->Z() - amt);
 					}
 				}
 			} while (n);	// repeat from scratch until all things left are marked valid
@@ -5819,7 +5807,7 @@ void P_CreateSecNodeList(AActor *thing, fixed_t x, fixed_t y)
 		node = node->m_tnext;
 	}
 
-	FBoundingBox box(thing->x, thing->y, thing->radius);
+	FBoundingBox box(thing->X(), thing->Y(), thing->radius);
 	FBlockLinesIterator it(box);
 	line_t *ld;
 
@@ -5922,13 +5910,13 @@ static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff
 	den = TMulScale16(plane->a, vx, plane->b, vy, plane->c, vz);
 	if (den != 0)
 	{
-		num = TMulScale16(plane->a, t1->x, plane->b, t1->y, plane->c, shootz) + plane->d;
+		num = TMulScale16(plane->a, t1->X(), plane->b, t1->Y(), plane->c, shootz) + plane->d;
 		hitdist = FixedDiv(-num, den);
 
 		if (hitdist >= 0 && hitdist <= trace.Distance)
 		{
-			fixed_t hitx = t1->x + FixedMul(vx, hitdist);
-			fixed_t hity = t1->y + FixedMul(vy, hitdist);
+			fixed_t hitx = t1->X() + FixedMul(vx, hitdist);
+			fixed_t hity = t1->Y() + FixedMul(vy, hitdist);
 			fixed_t hitz = shootz + FixedMul(vz, hitdist);
 
 			P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitx, hity), hitx, hity, hitz);
diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp
index 1c7a205a1..28714bef6 100644
--- a/src/p_maputl.cpp
+++ b/src/p_maputl.cpp
@@ -326,7 +326,7 @@ void AActor::LinkToWorld (bool buggy)
 
 	if (!buggy || numgamenodes == 0)
 	{
-		sec = P_PointInSector (x, y);
+		sec = P_PointInSector (X(), Y());
 	}
 	else
 	{

From 25107ed42150927c6b31180d997525e31e7667d3 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 13:49:52 +0100
Subject: [PATCH 13/23] - since I had to shuffle around the first variables in
 AActor, let's better commit that change.

---
 src/actor.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/actor.h b/src/actor.h
index 1d73e1698..8196f478d 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -1007,8 +1007,8 @@ public:
 
 // info for drawing
 // NOTE: The first member variable *must* be x.
-	fixed_t	 		x,y,z;
 	AActor			*snext, **sprev;	// links in sector (if needed)
+	fixed_t	 		x,y,z;
 	angle_t			angle;
 	WORD			sprite;				// used to find patch_t and flip value
 	BYTE			frame;				// sprite frame to draw

From 4d8070927d33a1103523cc34bf0d97b5023d87f1 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 14:04:47 +0100
Subject: [PATCH 14/23] - p_maputl.cpp done.

---
 src/p_maputl.cpp | 82 +++++++++++++++++++++++-------------------------
 1 file changed, 40 insertions(+), 42 deletions(-)

diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp
index 28714bef6..07ce97cca 100644
--- a/src/p_maputl.cpp
+++ b/src/p_maputl.cpp
@@ -344,7 +344,7 @@ void AActor::LinkToWorld (sector_t *sec)
 		return;
 	}
 	Sector = sec;
-	subsector = R_PointInSubsector(x, y);	// this is from the rendering nodes, not the gameplay nodes!
+	subsector = R_PointInSubsector(X(), Y());	// this is from the rendering nodes, not the gameplay nodes!
 
 	if ( !(flags & MF_NOSECTOR) )
 	{
@@ -371,7 +371,7 @@ void AActor::LinkToWorld (sector_t *sec)
 		// When a node is deleted, its sector links (the links starting
 		// at sector_t->touching_thinglist) are broken. When a node is
 		// added, new sector links are created.
-		P_CreateSecNodeList (this, x, y);
+		P_CreateSecNodeList (this, X(), Y());
 		touching_sectorlist = sector_list;	// Attach to thing
 		sector_list = NULL;		// clear for next time
     }
@@ -380,10 +380,10 @@ void AActor::LinkToWorld (sector_t *sec)
 	// link into blockmap (inert things don't need to be in the blockmap)
 	if ( !(flags & MF_NOBLOCKMAP) )
 	{
-		int x1 = GetSafeBlockX(x - radius - bmaporgx);
-		int x2 = GetSafeBlockX(x + radius - bmaporgx);
-		int y1 = GetSafeBlockY(y - radius - bmaporgy);
-		int y2 = GetSafeBlockY(y + radius - bmaporgy);
+		int x1 = GetSafeBlockX(X() - radius - bmaporgx);
+		int x2 = GetSafeBlockX(X() + radius - bmaporgx);
+		int y1 = GetSafeBlockY(Y() - radius - bmaporgy);
+		int y2 = GetSafeBlockY(Y() + radius - bmaporgy);
 
 		if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0)
 		{ // thing is off the map
@@ -496,7 +496,7 @@ sector_t *AActor::LinkToWorldForMapThing ()
 		// that lies directly on a line should always be
 		// considered as "in front" of the line. The orientation
 		// of the line should be irrelevant.
-		node = (node_t *)node->children[R_PointOnSideSlow (x, y, node)];
+		node = (node_t *)node->children[R_PointOnSideSlow (X(), Y(), node)];
 	}
 	while (!((size_t)node & 1));
 
@@ -510,8 +510,8 @@ sector_t *AActor::LinkToWorldForMapThing ()
 		// one-sided line might go into a subsector behind the line, so
 		// the line would not be included as one of its subsector's segs.
 
-		int blockx = GetSafeBlockX(x - bmaporgx);
-		int blocky = GetSafeBlockY(y - bmaporgy);
+		int blockx = GetSafeBlockX(X() - bmaporgx);
+		int blocky = GetSafeBlockY(Y() - bmaporgy);
 
 		if ((unsigned int)blockx < (unsigned int)bmapwidth &&
 			(unsigned int)blocky < (unsigned int)bmapheight)
@@ -536,10 +536,10 @@ sector_t *AActor::LinkToWorldForMapThing ()
 				}
 
 				// Not inside the line's bounding box
-				if (x + radius <= ldef->bbox[BOXLEFT]
-					|| x - radius >= ldef->bbox[BOXRIGHT]
-					|| y + radius <= ldef->bbox[BOXBOTTOM]
-					|| y - radius >= ldef->bbox[BOXTOP] )
+				if (X() + radius <= ldef->bbox[BOXLEFT]
+					|| X() - radius >= ldef->bbox[BOXRIGHT]
+					|| Y() + radius <= ldef->bbox[BOXBOTTOM]
+					|| Y() - radius >= ldef->bbox[BOXTOP] )
 					continue;
 
 				// Get the exact distance to the line
@@ -548,8 +548,8 @@ sector_t *AActor::LinkToWorldForMapThing ()
 
 				P_MakeDivline (ldef, &dll);
 
-				dlv.x = x;
-				dlv.y = y;
+				dlv.x = X();
+				dlv.y = Y();
 				dlv.dx = FixedDiv(dll.dy, linelen);
 				dlv.dy = -FixedDiv(dll.dx, linelen);
 
@@ -558,7 +558,7 @@ sector_t *AActor::LinkToWorldForMapThing ()
 				if (distance < radius)
 				{
 					DPrintf ("%s at (%d,%d) lies on %s line %td, distance = %f\n",
-						this->GetClass()->TypeName.GetChars(), x>>FRACBITS, y>>FRACBITS, 
+						this->GetClass()->TypeName.GetChars(), X()>>FRACBITS, Y()>>FRACBITS, 
 						ldef->dx == 0? "vertical" :	ldef->dy == 0? "horizontal" : "diagonal",
 						ldef-lines, FIXED2FLOAT(distance));
 					angle_t finean = R_PointToAngle2 (0, 0, ldef->dx, ldef->dy);
@@ -574,9 +574,8 @@ sector_t *AActor::LinkToWorldForMapThing ()
 
 					// Get the distance we have to move the object away from the wall
 					distance = radius - distance;
-					x += FixedMul(distance, finecosine[finean]);
-					y += FixedMul(distance, finesine[finean]);
-					return P_PointInSector (x, y);
+					SetXY(X() + FixedMul(distance, finecosine[finean]), Y() + FixedMul(distance, finesine[finean]));
+					return P_PointInSector (X(), Y());
 				}
 			}
 		}
@@ -588,9 +587,8 @@ sector_t *AActor::LinkToWorldForMapThing ()
 void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving)
 {
 	UnlinkFromWorld ();
-	x = ix;
-	y = iy;
-	z = iz;
+	SetXYZ(ix, iy, iz);
+	if (moving) SetMovement(ix - X(), iy - Y(), iz - Z());
 	LinkToWorld ();
 	floorz = Sector->floorplane.ZatPoint (ix, iy);
 	ceilingz = Sector->ceilingplane.ZatPoint (ix, iy);
@@ -878,8 +876,8 @@ AActor *FBlockThingsIterator::Next(bool centeronly)
 				fixed_t blocktop = blockbottom + MAPBLOCKSIZE;
 
 				// only return actors with the center in this block
-				if (me->x >= blockleft && me->x < blockright &&
-					me->y >= blockbottom && me->y < blocktop)
+				if (me->X() >= blockleft && me->X() < blockright &&
+					me->Y() >= blockbottom && me->Y() < blocktop)
 				{
 					return me;
 				}
@@ -1028,29 +1026,29 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
 				switch (i)
 				{
 				case 0:		// Top edge
-					line.x = thing->x + thing->radius;
-					line.y = thing->y + thing->radius;
+					line.x = thing->X() + thing->radius;
+					line.y = thing->Y() + thing->radius;
 					line.dx = -thing->radius * 2;
 					line.dy = 0;
 					break;
 
 				case 1:		// Right edge
-					line.x = thing->x + thing->radius;
-					line.y = thing->y - thing->radius;
+					line.x = thing->X() + thing->radius;
+					line.y = thing->Y() - thing->radius;
 					line.dx = 0;
 					line.dy = thing->radius * 2;
 					break;
 
 				case 2:		// Bottom edge
-					line.x = thing->x - thing->radius;
-					line.y = thing->y - thing->radius;
+					line.x = thing->X() - thing->radius;
+					line.y = thing->Y() - thing->radius;
 					line.dx = thing->radius * 2;
 					line.dy = 0;
 					break;
 
 				case 3:		// Left edge
-					line.x = thing->x - thing->radius;
-					line.y = thing->y + thing->radius;
+					line.x = thing->X() - thing->radius;
+					line.y = thing->Y() + thing->radius;
 					line.dx = 0;
 					line.dy = thing->radius * -2;
 					break;
@@ -1107,19 +1105,19 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
 			// check a corner to corner crossection for hit
 			if (tracepositive)
 			{
-				x1 = thing->x - thing->radius;
-				y1 = thing->y + thing->radius;
+				x1 = thing->X() - thing->radius;
+				y1 = thing->Y() + thing->radius;
 						
-				x2 = thing->x + thing->radius;
-				y2 = thing->y - thing->radius;					
+				x2 = thing->X() + thing->radius;
+				y2 = thing->Y() - thing->radius;					
 			}
 			else
 			{
-				x1 = thing->x - thing->radius;
-				y1 = thing->y - thing->radius;
+				x1 = thing->X() - thing->radius;
+				y1 = thing->Y() - thing->radius;
 						
-				x2 = thing->x + thing->radius;
-				y2 = thing->y + thing->radius;					
+				x2 = thing->X() + thing->radius;
+				y2 = thing->Y() + thing->radius;					
 			}
 			
 			s1 = P_PointOnDivlineSide (x1, y1, &trace);
@@ -1422,8 +1420,8 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in
 	int count;
 	AActor *target;
 
-	startX = GetSafeBlockX(mo->x-bmaporgx);
-	startY = GetSafeBlockY(mo->y-bmaporgy);
+	startX = GetSafeBlockX(mo->X()-bmaporgx);
+	startY = GetSafeBlockY(mo->Y()-bmaporgy);
 	validcount++;
 	
 	if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight)

From 13e25faea7da696b3bfb7794bf051bd217dda6b9 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 14:20:14 +0100
Subject: [PATCH 15/23] - p_sight.cpp, p_spec.cpp and p_switch.cpp refactored.

---
 src/p_sight.cpp  | 32 ++++++++++++++++----------------
 src/p_spec.cpp   | 20 ++++++++++----------
 src/p_switch.cpp | 25 +++++++++++++------------
 3 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/src/p_sight.cpp b/src/p_sight.cpp
index 2d465aab5..259b3baa8 100644
--- a/src/p_sight.cpp
+++ b/src/p_sight.cpp
@@ -68,11 +68,11 @@ public:
 
 	SightCheck(const AActor * t1, const AActor * t2, int flags)
 	{
-		lastztop = lastzbottom = sightzstart = t1->z + t1->height - (t1->height>>2);
+		lastztop = lastzbottom = sightzstart = t1->Z() + t1->height - (t1->height>>2);
 		lastsector = t1->Sector;
 		sightthing=t1;
 		seeingthing=t2;
-		bottomslope = t2->z - sightzstart;
+		bottomslope = t2->Z() - sightzstart;
 		topslope = bottomslope + t2->height;
 		Flags = flags;
 
@@ -132,7 +132,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
 	{
 		int  frontflag;
 		
-		frontflag = P_PointOnLineSidePrecise(sightthing->x, sightthing->y, li);
+		frontflag = P_PointOnLineSidePrecise(sightthing->X(), sightthing->Y(), li);
 		
 		//Check 3D FLOORS!
 		for(int i=1;i<=2;i++)
@@ -413,8 +413,8 @@ bool SightCheck::P_SightTraverseIntercepts ()
 			if((rover->flags & FF_SOLID) == myseethrough || !(rover->flags & FF_EXISTS)) continue;
 			if ((Flags & SF_IGNOREWATERBOUNDARY) && (rover->flags & FF_SOLID) == 0) continue;
 			
-			fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing->x, seeingthing->y);
-			fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing->x, seeingthing->y);
+			fixed_t ff_bottom=rover->bottom.plane->ZatPoint(seeingthing);
+			fixed_t ff_top=rover->top.plane->ZatPoint(seeingthing);
 
 			if (lastztop<=ff_bottom && topz>ff_bottom && lastzbottom<=ff_bottom && bottomz>ff_bottom) return false;
 			if (lastzbottom>=ff_top && bottomz<ff_top && lastztop>=ff_top && topz<ff_top) return false;
@@ -458,8 +458,8 @@ bool SightCheck::P_SightPathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_
 
 		if(!(rover->flags & FF_EXISTS)) continue;
 		
-		fixed_t ff_bottom=rover->bottom.plane->ZatPoint(sightthing->x, sightthing->y);
-		fixed_t ff_top=rover->top.plane->ZatPoint(sightthing->x, sightthing->y);
+		fixed_t ff_bottom=rover->bottom.plane->ZatPoint(sightthing);
+		fixed_t ff_top=rover->top.plane->ZatPoint(sightthing);
 
 		if (sightzstart < ff_top && sightzstart >= ff_bottom) 
 		{
@@ -691,16 +691,16 @@ sightcounts[0]++;
 	if (!(flags & SF_IGNOREWATERBOUNDARY))
 	{
 		if ((s1->GetHeightSec() &&
-			((t1->z + t1->height <= s1->heightsec->floorplane.ZatPoint (t1->x, t1->y) &&
-			  t2->z >= s1->heightsec->floorplane.ZatPoint (t2->x, t2->y)) ||
-			 (t1->z >= s1->heightsec->ceilingplane.ZatPoint (t1->x, t1->y) &&
-			  t2->z + t1->height <= s1->heightsec->ceilingplane.ZatPoint (t2->x, t2->y))))
+			((t1->Z() + t1->height <= s1->heightsec->floorplane.ZatPoint(t1) &&
+			  t2->Z() >= s1->heightsec->floorplane.ZatPoint(t2)) ||
+			 (t1->Z() >= s1->heightsec->ceilingplane.ZatPoint(t1) &&
+			  t2->Z() + t1->height <= s1->heightsec->ceilingplane.ZatPoint(t2))))
 			||
 			(s2->GetHeightSec() &&
-			 ((t2->z + t2->height <= s2->heightsec->floorplane.ZatPoint (t2->x, t2->y) &&
-			   t1->z >= s2->heightsec->floorplane.ZatPoint (t1->x, t1->y)) ||
-			  (t2->z >= s2->heightsec->ceilingplane.ZatPoint (t2->x, t2->y) &&
-			   t1->z + t2->height <= s2->heightsec->ceilingplane.ZatPoint (t1->x, t1->y)))))
+			 ((t2->Z() + t2->height <= s2->heightsec->floorplane.ZatPoint(t2) &&
+			   t1->Z() >= s2->heightsec->floorplane.ZatPoint(t1)) ||
+			  (t2->Z() >= s2->heightsec->ceilingplane.ZatPoint(t2) &&
+			   t1->Z() + t2->height <= s2->heightsec->ceilingplane.ZatPoint(t1)))))
 		{
 			res = false;
 			goto done;
@@ -713,7 +713,7 @@ sightcounts[0]++;
 	validcount++;
 	{
 		SightCheck s(t1, t2, flags);
-		res = s.P_SightPathTraverse (t1->x, t1->y, t2->x, t2->y);
+		res = s.P_SightPathTraverse (t1->X(), t1->Y(), t2->X(), t2->Y());
 	}
 
 done:
diff --git a/src/p_spec.cpp b/src/p_spec.cpp
index baec6d9e1..523295642 100644
--- a/src/p_spec.cpp
+++ b/src/p_spec.cpp
@@ -430,7 +430,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector)
 	{
 		// Falling, not all the way down yet?
 		sector = player->mo->Sector;
-		if (player->mo->z != sector->floorplane.ZatPoint(player->mo)
+		if (player->mo->Z() != sector->floorplane.ZatPoint(player->mo)
 			&& !player->mo->waterlevel)
 		{
 			return;
@@ -507,7 +507,7 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type,
 	if (!(flags & DAMAGE_PLAYERS) && actor->player != NULL)
 		return;
 
-	if (!(flags & DAMAGE_IN_AIR) && actor->z != sec->floorplane.ZatPoint(actor) && !actor->waterlevel)
+	if (!(flags & DAMAGE_IN_AIR) && actor->Z() != sec->floorplane.ZatPoint(actor) && !actor->waterlevel)
 		return;
 
 	if (protectClass != NULL)
@@ -553,12 +553,12 @@ void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass,
 					z1 = z2;
 					z2 = zz;
 				}
-				if (actor->z + actor->height > z1)
+				if (actor->Z() + actor->height > z1)
 				{
 					// If DAMAGE_IN_AIR is used, anything not beneath the 3D floor will be
 					// damaged (so, anything touching it or above it). Other 3D floors between
 					// the actor and this one will not stop this effect.
-					if ((flags & DAMAGE_IN_AIR) || actor->z <= z2)
+					if ((flags & DAMAGE_IN_AIR) || actor->Z() <= z2)
 					{
 						// Here we pass the DAMAGE_IN_AIR flag to disable the floor check, since it
 						// only works with the real sector's floor. We did the appropriate height checks
@@ -1058,7 +1058,7 @@ void P_SpawnSkybox(ASkyViewpoint *origin)
 	if (Sector == NULL)
 	{
 		Printf("Sector not initialized for SkyCamCompat\n");
-		origin->Sector = Sector = P_PointInSector(origin->x, origin->y);
+		origin->Sector = Sector = P_PointInSector(origin->X(), origin->Y());
 	}
 	if (Sector)
 	{
@@ -2152,8 +2152,8 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
 	if (source) // point source exist?
 	{
 		m_Radius = (m_Magnitude) << (FRACBITS+1); // where force goes to zero
-		m_X = m_Source->x;
-		m_Y = m_Source->y;
+		m_X = m_Source->X();
+		m_Y = m_Source->Y();
 	}
 	m_Affectee = affectee;
 }
@@ -2268,7 +2268,7 @@ void DPusher::Tick ()
 		{
 			if (hsec == NULL)
 			{ // NOT special water sector
-				if (thing->z > thing->floorz) // above ground
+				if (thing->Z() > thing->floorz) // above ground
 				{
 					xspeed = m_Xmag; // full force
 					yspeed = m_Ymag;
@@ -2282,7 +2282,7 @@ void DPusher::Tick ()
 			else // special water sector
 			{
 				ht = hsec->floorplane.ZatPoint(thing);
-				if (thing->z > ht) // above ground
+				if (thing->Z() > ht) // above ground
 				{
 					xspeed = m_Xmag; // full force
 					yspeed = m_Ymag;
@@ -2310,7 +2310,7 @@ void DPusher::Tick ()
 			{ // special water sector
 				floor = &hsec->floorplane;
 			}
-			if (thing->z > floor->ZatPoint(thing))
+			if (thing->Z() > floor->ZatPoint(thing))
 			{ // above ground
 				xspeed = yspeed = 0; // no force
 			}
diff --git a/src/p_switch.cpp b/src/p_switch.cpp
index 984794c8a..1ae0c43ea 100644
--- a/src/p_switch.cpp
+++ b/src/p_switch.cpp
@@ -138,8 +138,9 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 
 	P_MakeDivline (line, &dll);
 
-	dlu.x = user->x;
-	dlu.y = user->y;
+	fixedvec3 pos = user->PosRelative(line);
+	dlu.x = pos.x;
+	dlu.y = pos.y;
 	dlu.dx = finecosine[user->angle >> ANGLETOFINESHIFT];
 	dlu.dy = finesine[user->angle >> ANGLETOFINESHIFT];
 	inter = P_InterceptVector(&dll, &dlu);
@@ -167,11 +168,11 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 	onesided:
 		fixed_t sectorc = front->ceilingplane.ZatPoint(checkx, checky);
 		fixed_t sectorf = front->floorplane.ZatPoint(checkx, checky);
-		return (user->z + user->height >= sectorf && user->z <= sectorc);
+		return (user->Top() >= sectorf && user->Z() <= sectorc);
 	}
 
 	// Now get the information from the line.
-	P_LineOpening(open, NULL, line, checkx, checky, user->x, user->y);
+	P_LineOpening(open, NULL, line, checkx, checky, pos.x, pos.y);
 	if (open.range <= 0)
 		goto onesided;
 
@@ -187,8 +188,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 				if (!(rover->flags & FF_EXISTS)) continue;
 				if (!(rover->flags & FF_UPPERTEXTURE)) continue;
 
-				if (user->z > rover->top.plane->ZatPoint(checkx, checky) ||
-					user->z + user->height < rover->bottom.plane->ZatPoint(checkx, checky))
+				if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) ||
+					user->Top() < rover->bottom.plane->ZatPoint(checkx, checky))
 					continue;
 
 				// This 3D floor depicts a switch texture in front of the player's eyes
@@ -196,7 +197,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 			}
 		}
 
-		return (user->z + user->height > open.top);
+		return (user->Top() > open.top);
 	}
 	else if ((TexMan.FindSwitch(side->GetTexture(side_t::bottom))) != NULL)
 	{
@@ -209,8 +210,8 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 				if (!(rover->flags & FF_EXISTS)) continue;
 				if (!(rover->flags & FF_LOWERTEXTURE)) continue;
 
-				if (user->z > rover->top.plane->ZatPoint(checkx, checky) ||
-					user->z + user->height < rover->bottom.plane->ZatPoint(checkx, checky))
+				if (user->Z() > rover->top.plane->ZatPoint(checkx, checky) ||
+					user->Top() < rover->bottom.plane->ZatPoint(checkx, checky))
 					continue;
 
 				// This 3D floor depicts a switch texture in front of the player's eyes
@@ -218,7 +219,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 			}
 		}
 
-		return (user->z < open.bottom);
+		return (user->Z() < open.bottom);
 	}
 	else if ((flags & ML_3DMIDTEX) || (TexMan.FindSwitch(side->GetTexture(side_t::mid))) != NULL)
 	{
@@ -226,12 +227,12 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno)
 		// to keep compatibility with Eternity's implementation.
 		if (!P_GetMidTexturePosition(line, sideno, &checktop, &checkbot))
 			return false;
-		return user->z < checktop && user->z + user->height > checkbot;
+		return user->Z() < checktop && user->Top() > checkbot;
 	}
 	else
 	{
 		// no switch found. Check whether the player can touch either top or bottom texture
-		return (user->z + user->height > open.top) || (user->z < open.bottom);
+		return (user->Top() > open.top) || (user->Z() < open.bottom);
 	}
 }
 

From 68c0f929dcd573f218e30a3115be45f754527d1b Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Wed, 20 Jan 2016 15:12:51 +0100
Subject: [PATCH 16/23] - refactoring complete. The source compiles again with
 the renamed position variable.

---
 src/actor.h                          | 87 ++++++++++++++--------------
 src/p_mobj.cpp                       |  6 +-
 src/p_teleport.cpp                   | 46 +++++++--------
 src/p_things.cpp                     | 48 ++++++++-------
 src/p_trace.cpp                      | 16 ++---
 src/p_user.cpp                       | 55 +++++++++---------
 src/thingdef/thingdef_expression.cpp |  6 +-
 7 files changed, 128 insertions(+), 136 deletions(-)

diff --git a/src/actor.h b/src/actor.h
index 8196f478d..3a474bc6f 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -844,12 +844,6 @@ public:
 		return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY);
 	}
 
-	bool intersects(AActor *other) const
-	{
-		fixed_t blockdist = radius + other->radius;
-		return ( abs(x - other->x) < blockdist && abs(y - other->y) < blockdist);
-	}
-
 	PalEntry GetBloodColor() const
 	{
 		return (PalEntry)GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
@@ -884,103 +878,109 @@ public:
 		return bloodcls;
 	}
 
+	bool intersects(AActor *other) const
+	{
+		fixed_t blockdist = radius + other->radius;
+		return ( abs(X() - other->Y()) < blockdist && abs(Y() - other->Y()) < blockdist);
+	}
+
 	// 'absolute' is reserved for a linked portal implementation which needs
 	// to distinguish between portal-aware and portal-unaware distance calculation.
 	fixed_t AproxDistance(AActor *other, bool absolute = false)
 	{
-		return P_AproxDistance(x - other->x, y - other->y);
+		return P_AproxDistance(X() - other->X(), Y() - other->Y());
 	}
 
 	// same with 'ref' here.
 	fixed_t AproxDistance(fixed_t otherx, fixed_t othery, AActor *ref = NULL)
 	{
-		return P_AproxDistance(x - otherx, y - othery);
+		return P_AproxDistance(X() - otherx, Y() - othery);
 	}
 
 	fixed_t AproxDistance(AActor *other, fixed_t xadd, fixed_t yadd, bool absolute = false)
 	{
-		return P_AproxDistance(x - other->x + xadd, y - other->y + yadd);
+		return P_AproxDistance(X() - other->X() + xadd, Y() - other->Y() + yadd);
 	}
 
 	fixed_t AproxDistance3D(AActor *other, bool absolute = false)
 	{
-		return P_AproxDistance(AproxDistance(other), z - other->z);
+		return P_AproxDistance(AproxDistance(other), Z() - other->Z());
 	}
 
 	// more precise, but slower version, being used in a few places
 	fixed_t Distance2D(AActor *other, bool absolute = false)
 	{
-		return xs_RoundToInt(FVector2(x - other->x, y - other->y).Length());
+		return xs_RoundToInt(FVector2(X() - other->X(), Y() - other->Y()).Length());
 	}
 
 	// a full 3D version of the above
 	fixed_t Distance3D(AActor *other, bool absolute = false)
 	{
-		return xs_RoundToInt(FVector3(x - other->x, y - other->y, z - other->z).Length());
+		return xs_RoundToInt(FVector3(X() - other->X(), Y() - other->Y(), Z() - other->Z()).Length());
 	}
 
 	angle_t AngleTo(AActor *other, bool absolute = false) const
 	{
-		return R_PointToAngle2(x, y, other->x, other->y);
+		return R_PointToAngle2(X(), Y(), other->X(), other->Y());
 	}
 
 	angle_t AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const
 	{
-		return R_PointToAngle2(x, y, other->x + oxofs, other->y + oyofs);
+		return R_PointToAngle2(X(), Y(), other->X() + oxofs, other->Y() + oyofs);
 	}
 
 	fixed_t AngleTo(fixed_t otherx, fixed_t othery, AActor *ref = NULL)
 	{
-		return R_PointToAngle2(x, y, otherx, othery);
+		return R_PointToAngle2(X(), Y(), otherx, othery);
 	}
 
 	fixed_t AngleXYTo(fixed_t myx, fixed_t myy, AActor *other, bool absolute = false)
 	{
-		return R_PointToAngle2(myx, myy, other->x, other->y);
+		return R_PointToAngle2(myx, myy, other->X(), other->Y());
 	}
 
 	fixedvec2 Vec2To(AActor *other) const
 	{
-		fixedvec2 ret = { other->x - x, other->y - y };
+		fixedvec2 ret = { other->X() - X(), other->Y() - Y() };
 		return ret;
 	}
 
 	fixedvec3 Vec3To(AActor *other) const
 	{
-		fixedvec3 ret = { other->x - x, other->y - y, other->z - z };
+		fixedvec3 ret = { other->X() - X(), other->Y() - Y(), other->Z() - Z() };
 		return ret;
 	}
 
 	fixedvec2 Vec2Offset(fixed_t dx, fixed_t dy, bool absolute = false) const
 	{
-		fixedvec2 ret = { x + dx, y + dy };
+		fixedvec2 ret = { X() + dx, Y() + dy };
 		return ret;
 	}
 
 
 	fixedvec2 Vec2Angle(fixed_t length, angle_t angle, bool absolute = false) const
 	{
-		fixedvec2 ret = { x + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
-						  y + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
+		fixedvec2 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
+						  Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
 		return ret;
 	}
 
 	fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false) const
 	{
-		fixedvec3 ret = { x + dx, y + dy, z + dz };
+		fixedvec3 ret = { X() + dx, Y() + dy, Z() + dz };
 		return ret;
 	}
 
 	fixedvec3 Vec3Angle(fixed_t length, angle_t angle, fixed_t dz, bool absolute = false) const
 	{
-		fixedvec3 ret = { x + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
-						  y + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), z + dz };
+		fixedvec3 ret = { X() + FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
+						  Y() + FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]), Z() + dz };
 		return ret;
 	}
 
 	void Move(fixed_t dx, fixed_t dy, fixed_t dz)
 	{
-		SetOrigin(x + dx, y + dy, z + dz, true);
+		SetOrigin(X() + dx, Y() + dy, Z() + dz, true);
 	}
 
 	void SetOrigin(const fixedvec3 & npos, bool moving)
@@ -1006,9 +1006,10 @@ public:
 	void CheckSectorTransition(sector_t *oldsec);
 
 // info for drawing
-// NOTE: The first member variable *must* be x.
+// NOTE: The first member variable *must* be snext.
 	AActor			*snext, **sprev;	// links in sector (if needed)
-	fixed_t	 		x,y,z;
+	fixedvec3		__pos;				// double underscores so that it won't get used by accident. Access to this should be exclusively through the designated access functions.
+
 	angle_t			angle;
 	WORD			sprite;				// used to find patch_t and flip value
 	BYTE			frame;				// sprite frame to draw
@@ -1237,15 +1238,15 @@ public:
 
 	fixed_t X() const
 	{
-		return x;
+		return __pos.x;
 	}
 	fixed_t Y() const
 	{
-		return y;
+		return __pos.y;
 	}
 	fixed_t Z() const
 	{
-		return z;
+		return __pos.z;
 	}
 	fixedvec3 Pos() const
 	{
@@ -1295,39 +1296,39 @@ public:
 	}
 	fixed_t Top() const
 	{
-		return z + height;
+		return Z() + height;
 	}
 	void SetZ(fixed_t newz, bool moving = true)
 	{
-		z = newz;
+		__pos.z = newz;
 	}
 	void AddZ(fixed_t newz, bool moving = true)
 	{
-		z += newz;
+		__pos.z += newz;
 	}
 
 	// These are not for general use as they do not link the actor into the world!
 	void SetXY(fixed_t xx, fixed_t yy)
 	{
-		x = xx;
-		y = yy;
+		__pos.x = xx;
+		__pos.y = yy;
 	}
 	void SetXYZ(fixed_t xx, fixed_t yy, fixed_t zz)
 	{
-		x = xx;
-		y = yy;
-		z = zz;
+		__pos.x = xx;
+		__pos.y = yy;
+		__pos.z = zz;
 	}
 	void SetXY(const fixedvec2 &npos)
 	{
-		x = npos.x;
-		y = npos.y;
+		__pos.x = npos.x;
+		__pos.y = npos.y;
 	}
 	void SetXYZ(const fixedvec3 &npos)
 	{
-		x = npos.x;
-		y = npos.y;
-		z = npos.z;
+		__pos.x = npos.x;
+		__pos.y = npos.y;
+		__pos.z = npos.z;
 	}
 	void SetMovement(fixed_t x, fixed_t y, fixed_t z)
 	{
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 114c026f7..8dda50de6 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -156,9 +156,9 @@ void AActor::Serialize (FArchive &arc)
 		sprite = arc.ReadSprite ();
 	}
 
-	arc << x
-		<< y
-		<< z
+	arc << __pos.x
+		<< __pos.y
+		<< __pos.z
 		<< angle
 		<< frame
 		<< scaleX
diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp
index 380f5572d..ab860bfe9 100644
--- a/src/p_teleport.cpp
+++ b/src/p_teleport.cpp
@@ -101,9 +101,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
 {
 	bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));
 
-	fixed_t oldx;
-	fixed_t oldy;
-	fixed_t oldz;
+	fixedvec3 old;
 	fixed_t aboveFloor;
 	player_t *player;
 	angle_t an;
@@ -112,10 +110,8 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
 	fixed_t floorheight, ceilingheight;
 	fixed_t missilespeed;
 
-	oldx = thing->x;
-	oldy = thing->y;
-	oldz = thing->z;
-	aboveFloor = thing->z - thing->floorz;
+	old = thing->Pos();
+	aboveFloor = thing->Z() - thing->floorz;
 	destsect = P_PointInSector (x, y);
 	// killough 5/12/98: exclude voodoo dolls:
 	player = thing->player;
@@ -171,7 +167,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
 	}
 	if (player)
 	{
-		player->viewz = thing->z + player->viewheight;
+		player->viewz = thing->Z() + player->viewheight;
 		if (resetpitch)
 		{
 			player->mo->pitch = 0;
@@ -188,7 +184,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
 	// Spawn teleport fog at source and destination
 	if (sourceFog && !predicting)
 	{
-		P_SpawnTeleportFog(thing, oldx, oldy, oldz, true, true); //Passes the actor through which then pulls the TeleFog metadata types based on properties.
+		P_SpawnTeleportFog(thing, old, true, true); //Passes the actor through which then pulls the TeleFog metadata types based on properties.
 	}
 	if (useFog)
 	{
@@ -196,7 +192,7 @@ bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
 		{
 			fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
 			an = angle >> ANGLETOFINESHIFT;
-			P_SpawnTeleportFog(thing, x + 20 * finecosine[an], y + 20 * finesine[an], thing->z + fogDelta, false, true);
+			P_SpawnTeleportFog(thing, x + 20 * finecosine[an], y + 20 * finesine[an], thing->Z() + fogDelta, false, true);
 
 		}
 		if (thing->player)
@@ -372,11 +368,11 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
 		velx = thing->velx;
 		vely = thing->vely;
 
-		z = searcher->z;
+		z = searcher->Z();
 	}
 	else if (searcher->IsKindOf (PClass::FindClass(NAME_TeleportDest2)))
 	{
-		z = searcher->z;
+		z = searcher->Z();
 	}
 	else
 	{
@@ -386,7 +382,7 @@ bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, bool
 	{
 		badangle = 1 << ANGLETOFINESHIFT;
 	}
-	if (P_Teleport (thing, searcher->x, searcher->y, z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity, keepHeight))
+	if (P_Teleport (thing, searcher->X(), searcher->Y(), z, searcher->angle + badangle, fog, sourceFog, keepOrientation, haltVelocity, keepHeight))
 	{
 		// [RH] Lee Killough's changes for silent teleporters from BOOM
 		if (!fog && line && keepOrientation)
@@ -447,8 +443,8 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
 				}
 				else
 				{
-					SQWORD num = (SQWORD)(thing->x-line->v1->x)*line->dx + 
-								 (SQWORD)(thing->y-line->v1->y)*line->dy;
+					SQWORD num = (SQWORD)(thing->X()-line->v1->x)*line->dx + 
+								 (SQWORD)(thing->Y()-line->v1->y)*line->dy;
 					if (num <= 0)
 					{
 						pos = 0;
@@ -461,8 +457,8 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
 					{
 						pos = (SDWORD)(num / (den>>30));
 					}
-					nposx = thing->x - line->v1->x - MulScale30 (line->dx, pos);
-					nposy = thing->y - line->v1->y - MulScale30 (line->dy, pos);
+					nposx = thing->X() - line->v1->x - MulScale30 (line->dx, pos);
+					nposy = thing->Y() - line->v1->y - MulScale30 (line->dy, pos);
 				}
 			}
 
@@ -502,7 +498,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
 			bool stepdown = l->frontsector->floorplane.ZatPoint(x, y) < l->backsector->floorplane.ZatPoint(x, y);
 
 			// Height of thing above ground
-			fixed_t z = thing->z - thing->floorz;
+			fixed_t z = thing->Z() - thing->floorz;
 
 			// Side to exit the linedef on positionally.
 			//
@@ -615,16 +611,16 @@ bool EV_TeleportOther (int other_tid, int dest_tid, bool fog)
 static bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool floorz, bool fog)
 {
 	int an = (dest->angle - source->angle) >> ANGLETOFINESHIFT;
-	fixed_t offX = victim->x - source->x;
-	fixed_t offY = victim->y - source->y;
+	fixed_t offX = victim->X() - source->X();
+	fixed_t offY = victim->Y() - source->Y();
 	angle_t offAngle = victim->angle - source->angle;
 	fixed_t newX = DMulScale16 (offX, finecosine[an], -offY, finesine[an]);
 	fixed_t newY = DMulScale16 (offX, finesine[an], offY, finecosine[an]);
 
 	bool res =
-		P_Teleport (victim, dest->x + newX,
-							dest->y + newY,
-							floorz ? ONFLOORZ : dest->z + victim->z - source->z,
+		P_Teleport (victim, dest->X() + newX,
+							dest->Y() + newY,
+							floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(),
 							0, fog, fog, !fog);
 	// P_Teleport only changes angle if fog is true
 	victim->angle = dest->angle + offAngle;
@@ -692,8 +688,8 @@ bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_t
 	if (moveSource && didSomething)
 	{
 		didSomething |=
-			P_Teleport (sourceOrigin, destOrigin->x, destOrigin->y,
-				floorz ? ONFLOORZ : destOrigin->z, 0, false, false, true);
+			P_Teleport (sourceOrigin, destOrigin->X(), destOrigin->Y(),
+				floorz ? ONFLOORZ : destOrigin->Z(), 0, false, false, true);
 		sourceOrigin->angle = destOrigin->angle;
 	}
 
diff --git a/src/p_things.cpp b/src/p_things.cpp
index f487128e8..85d7961af 100644
--- a/src/p_things.cpp
+++ b/src/p_things.cpp
@@ -691,9 +691,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs,
 		caller = temp;
 	}
 
-	fixed_t	oldx = caller->X();
-	fixed_t	oldy = caller->Y();
-	fixed_t	oldz = caller->z;
+	fixedvec3 old = caller->Pos();
 	zofs += FixedMul(reference->height, heightoffset);
 	
 
@@ -725,18 +723,18 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs,
 			// now the caller's floorz should be appropriate for the assigned xy-position
 			// assigning position again with.
 			// extra unlink, link and environment calculation
-			caller->SetOrigin(
-				reference->x + xofs + FixedMul(rad, finecosine[fineangle]),
-				reference->y + yofs + FixedMul(rad, finesine[fineangle]),
-				reference->z);
-			caller->z = caller->floorz + zofs;
+			caller->SetOrigin(reference->Vec3Offset(
+				xofs + FixedMul(rad, finecosine[fineangle]),
+				yofs + FixedMul(rad, finesine[fineangle]),
+				0), true);
+			caller->SetZ(caller->floorz + zofs);
 		}
 		else
 		{
-			caller->SetOrigin(
-				reference->x + xofs + FixedMul(rad, finecosine[fineangle]),
-				reference->y + yofs + FixedMul(rad, finesine[fineangle]),
-				reference->z + zofs);
+			caller->SetOrigin(reference->Vec3Offset(
+				 xofs + FixedMul(rad, finecosine[fineangle]),
+				 yofs + FixedMul(rad, finesine[fineangle]),
+				 zofs), true);
 		}
 	}
 	else // [MC] The idea behind "absolute" is meant to be "absolute". Override everything, just like A_SpawnItemEx's.
@@ -744,7 +742,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs,
 		if (flags & WARPF_TOFLOOR)
 		{
 			caller->SetOrigin(xofs + FixedMul(rad, finecosine[fineangle]), yofs + FixedMul(rad, finesine[fineangle]), zofs);
-			caller->z = caller->floorz + zofs;
+			caller->SetZ(caller->floorz + zofs);
 		}
 		else
 		{
@@ -756,7 +754,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs,
 	{
 		if (flags & WARPF_TESTONLY)
 		{
-			caller->SetOrigin(oldx, oldy, oldz);
+			caller->SetOrigin(old, true);
 		}
 		else
 		{
@@ -783,29 +781,29 @@ int P_Thing_Warp(AActor *caller, AActor *reference, fixed_t xofs, fixed_t yofs,
 
 			if (flags & WARPF_WARPINTERPOLATION)
 			{
-				caller->PrevX += caller->x - oldx;
-				caller->PrevY += caller->y - oldy;
-				caller->PrevZ += caller->z - oldz;
+				caller->PrevX += caller->X() - old.x;
+				caller->PrevY += caller->Y() - old.y;
+				caller->PrevZ += caller->Z() - old.z;
 			}
 			else if (flags & WARPF_COPYINTERPOLATION)
 			{
-				caller->PrevX = caller->x + reference->PrevX - reference->x;
-				caller->PrevY = caller->y + reference->PrevY - reference->y;
-				caller->PrevZ = caller->z + reference->PrevZ - reference->z;
+				caller->PrevX = caller->X() + reference->PrevX - reference->X();
+				caller->PrevY = caller->Y() + reference->PrevY - reference->Y();
+				caller->PrevZ = caller->Z() + reference->PrevZ - reference->Z();
 			}
 			else if (!(flags & WARPF_INTERPOLATE))
 			{
-				caller->PrevX = caller->x;
-				caller->PrevY = caller->y;
-				caller->PrevZ = caller->z;
+				caller->PrevX = caller->X();
+				caller->PrevY = caller->Y();
+				caller->PrevZ = caller->Z();
 			}
 			if ((flags & WARPF_BOB) && (reference->flags2 & MF2_FLOATBOB))
 			{
-				caller->z += reference->GetBobOffset();
+				caller->AddZ(reference->GetBobOffset());
 			}
 		}
 		return true;
 	}
-	caller->SetOrigin(oldx, oldy, oldz);
+	caller->SetOrigin(old, true);
 	return false;
 }
\ No newline at end of file
diff --git a/src/p_trace.cpp b/src/p_trace.cpp
index 4b4683be5..619a61361 100644
--- a/src/p_trace.cpp
+++ b/src/p_trace.cpp
@@ -524,12 +524,12 @@ cont:
 		hity = StartY + FixedMul (Vy, dist);
 		hitz = StartZ + FixedMul (Vz, dist);
 
-		if (hitz > in->d.thing->z + in->d.thing->height)
+		if (hitz > in->d.thing->Top())
 		{ // trace enters above actor
 			if (Vz >= 0) continue;      // Going up: can't hit
 			
 			// Does it hit the top of the actor?
-			dist = FixedDiv(in->d.thing->z + in->d.thing->height - StartZ, Vz);
+			dist = FixedDiv(in->d.thing->Top() - StartZ, Vz);
 
 			if (dist > MaxDist) continue;
 			in->frac = FixedDiv(dist, MaxDist);
@@ -539,15 +539,15 @@ cont:
 			hitz = StartZ + FixedMul (Vz, dist);
 
 			// calculated coordinate is outside the actor's bounding box
-			if (abs(hitx - in->d.thing->x) > in->d.thing->radius ||
-				abs(hity - in->d.thing->y) > in->d.thing->radius) continue;
+			if (abs(hitx - in->d.thing->X()) > in->d.thing->radius ||
+				abs(hity - in->d.thing->Y()) > in->d.thing->radius) continue;
 		}
-		else if (hitz < in->d.thing->z)
+		else if (hitz < in->d.thing->Z())
 		{ // trace enters below actor
 			if (Vz <= 0) continue;      // Going down: can't hit
 			
 			// Does it hit the bottom of the actor?
-			dist = FixedDiv(in->d.thing->z - StartZ, Vz);
+			dist = FixedDiv(in->d.thing->Z() - StartZ, Vz);
 			if (dist > MaxDist) continue;
 			in->frac = FixedDiv(dist, MaxDist);
 
@@ -556,8 +556,8 @@ cont:
 			hitz = StartZ + FixedMul (Vz, dist);
 
 			// calculated coordinate is outside the actor's bounding box
-			if (abs(hitx - in->d.thing->x) > in->d.thing->radius ||
-				abs(hity - in->d.thing->y) > in->d.thing->radius) continue;
+			if (abs(hitx - in->d.thing->X()) > in->d.thing->radius ||
+				abs(hity - in->d.thing->Y()) > in->d.thing->radius) continue;
 		}
 
 		// check for extrafloors first
diff --git a/src/p_user.cpp b/src/p_user.cpp
index ba987d393..c4c594858 100644
--- a/src/p_user.cpp
+++ b/src/p_user.cpp
@@ -671,10 +671,10 @@ void APlayerPawn::PostBeginPlay()
 	// Voodoo dolls: restore original floorz/ceilingz logic
 	if (player == NULL || player->mo != this)
 	{
-		dropoffz = floorz = Sector->floorplane.ZatPoint(x, y);
-		ceilingz = Sector->ceilingplane.ZatPoint(x, y);
+		dropoffz = floorz = Sector->floorplane.ZatPoint(this);
+		ceilingz = Sector->ceilingplane.ZatPoint(this);
 		P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
-		z = floorz;
+		SetZ(floorz);
 	}
 	else
 	{
@@ -1553,7 +1553,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SkullPop)
 	}
 
 	self->flags &= ~MF_SOLID;
-	mo = (APlayerPawn *)Spawn (spawntype, self->x, self->y, self->z + 48*FRACUNIT, NO_REPLACE);
+	mo = (APlayerPawn *)Spawn (spawntype, self->PosPlusZ(48*FRACUNIT), NO_REPLACE);
 	//mo->target = self;
 	mo->velx = pr_skullpop.Random2() << 9;
 	mo->vely = pr_skullpop.Random2() << 9;
@@ -1762,7 +1762,7 @@ void P_CalcHeight (player_t *player)
 
 	if (player->cheats & CF_NOVELOCITY)
 	{
-		player->viewz = player->mo->z + defaultviewheight;
+		player->viewz = player->mo->Z() + defaultviewheight;
 
 		if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
 			player->viewz = player->mo->ceilingz-4*FRACUNIT;
@@ -1818,9 +1818,9 @@ void P_CalcHeight (player_t *player)
 	{
 		bob = 0;
 	}
-	player->viewz = player->mo->z + player->viewheight + bob;
+	player->viewz = player->mo->Z() + player->viewheight + bob;
 	if (player->mo->floorclip && player->playerstate != PST_DEAD
-		&& player->mo->z <= player->mo->floorz)
+		&& player->mo->Z() <= player->mo->floorz)
 	{
 		player->viewz -= player->mo->floorclip;
 	}
@@ -1863,7 +1863,7 @@ void P_MovePlayer (player_t *player)
 		mo->angle += cmd->ucmd.yaw << 16;
 	}
 
-	player->onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2);
+	player->onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2);
 
 	// killough 10/98:
 	//
@@ -1920,7 +1920,7 @@ void P_MovePlayer (player_t *player)
 		{
 			fprintf (debugfile, "move player for pl %d%c: (%d,%d,%d) (%d,%d) %d %d w%d [", int(player-players),
 				player->cheats&CF_PREDICTING?'p':' ',
-				player->mo->x, player->mo->y, player->mo->z,forwardmove, sidemove, movefactor, friction, player->mo->waterlevel);
+				player->mo->X(), player->mo->Y(), player->mo->Z(),forwardmove, sidemove, movefactor, friction, player->mo->waterlevel);
 			msecnode_t *n = player->mo->touching_sectorlist;
 			while (n != NULL)
 			{
@@ -2052,7 +2052,7 @@ void P_DeathThink (player_t *player)
 
 	P_MovePsprites (player);
 
-	player->onground = (player->mo->z <= player->mo->floorz);
+	player->onground = (player->mo->Z() <= player->mo->floorz);
 	if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk)))
 	{ // Flying bloody skull or flying ice chunk
 		player->viewheight = 6 * FRACUNIT;
@@ -2165,7 +2165,7 @@ void P_CrouchMove(player_t * player, int direction)
 
 	// check whether the move is ok
 	player->mo->height = FixedMul(defaultheight, player->crouchfactor);
-	if (!P_TryMove(player->mo, player->mo->x, player->mo->y, false, NULL))
+	if (!P_TryMove(player->mo, player->mo->X(), player->mo->Y(), false, NULL))
 	{
 		player->mo->height = savedheight;
 		if (direction > 0)
@@ -2182,7 +2182,7 @@ void P_CrouchMove(player_t * player, int direction)
 	player->crouchviewdelta = player->viewheight - player->mo->ViewHeight;
 
 	// Check for eyes going above/below fake floor due to crouching motion.
-	P_CheckFakeFloorTriggers(player->mo, player->mo->z + oldheight, true);
+	P_CheckFakeFloorTriggers(player->mo, player->mo->Z() + oldheight, true);
 }
 
 //----------------------------------------------------------------------------
@@ -2203,7 +2203,7 @@ void P_PlayerThink (player_t *player)
 	if (debugfile && !(player->cheats & CF_PREDICTING))
 	{
 		fprintf (debugfile, "tic %d for pl %td: (%d, %d, %d, %u) b:%02x p:%d y:%d f:%d s:%d u:%d\n",
-			gametic, player-players, player->mo->x, player->mo->y, player->mo->z,
+			gametic, player-players, player->mo->X(), player->mo->Y(), player->mo->Z(),
 			player->mo->angle>>ANGLETOFINESHIFT, player->cmd.ucmd.buttons,
 			player->cmd.ucmd.pitch, player->cmd.ucmd.yaw, player->cmd.ucmd.forwardmove,
 			player->cmd.ucmd.sidemove, player->cmd.ucmd.upmove);
@@ -2329,7 +2329,7 @@ void P_PlayerThink (player_t *player)
 				player->crouching = 0;
 			}
 			if (crouchdir == 1 && player->crouchfactor < FRACUNIT &&
-				player->mo->z + player->mo->height < player->mo->ceilingz)
+				player->mo->Top() < player->mo->ceilingz)
 			{
 				P_CrouchMove(player, 1);
 			}
@@ -2542,8 +2542,7 @@ void P_PlayerThink (player_t *player)
 		P_PlayerOnSpecial3DFloor (player);
 		P_PlayerInSpecialSector (player);
 
-		if (player->mo->z <= player->mo->Sector->floorplane.ZatPoint(
-			player->mo->x, player->mo->y) ||
+		if (player->mo->Z() <= player->mo->Sector->floorplane.ZatPoint(player->mo) ||
 			player->mo->waterlevel)
 		{
 			// Player must be touching the floor
@@ -2697,7 +2696,7 @@ void P_PredictPlayer (player_t *player)
 	PredictionPlayerBackup = *player;
 
 	APlayerPawn *act = player->mo;
-	memcpy(PredictionActorBackup, &act->x, sizeof(APlayerPawn) - ((BYTE *)&act->x - (BYTE *)act));
+	memcpy(PredictionActorBackup, &act->snext, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act));
 
 	act->flags &= ~MF_PICKUP;
 	act->flags2 &= ~MF2_PUSHWALL;
@@ -2769,16 +2768,16 @@ void P_PredictPlayer (player_t *player)
 		{
 			// Z is not compared as lifts will alter this with no apparent change
 			// Make lerping less picky by only testing whole units
-			DoLerp = ((PredictionLast.x >> 16) != (player->mo->x >> 16) ||
-				(PredictionLast.y >> 16) != (player->mo->y >> 16));
+			DoLerp = ((PredictionLast.x >> 16) != (player->mo->X() >> 16) ||
+				(PredictionLast.y >> 16) != (player->mo->Y() >> 16));
 
 			// Aditional Debug information
 			if (developer && DoLerp)
 			{
 				DPrintf("Lerp! Ltic (%d) && Ptic (%d) | Lx (%d) && Px (%d) | Ly (%d) && Py (%d)\n",
 					PredictionLast.gametic, i,
-					(PredictionLast.x >> 16), (player->mo->x >> 16),
-					(PredictionLast.y >> 16), (player->mo->y >> 16));
+					(PredictionLast.x >> 16), (player->mo->X() >> 16),
+					(PredictionLast.y >> 16), (player->mo->Y() >> 16));
 			}
 		}
 	}
@@ -2796,9 +2795,9 @@ void P_PredictPlayer (player_t *player)
 		}
 
 		PredictionLast.gametic = maxtic - 1;
-		PredictionLast.x = player->mo->x;
-		PredictionLast.y = player->mo->y;
-		PredictionLast.z = player->mo->z;
+		PredictionLast.x = player->mo->X();
+		PredictionLast.y = player->mo->Y();
+		PredictionLast.z = player->mo->Z();
 
 		if (PredictionLerptics > 0)
 		{
@@ -2806,9 +2805,7 @@ void P_PredictPlayer (player_t *player)
 				P_LerpCalculate(PredictionLerpFrom, PredictionLast, PredictionLerpResult, (float)PredictionLerptics * cl_predict_lerpscale))
 			{
 				PredictionLerptics++;
-				player->mo->x = PredictionLerpResult.x;
-				player->mo->y = PredictionLerpResult.y;
-				player->mo->z = PredictionLerpResult.z;
+				player->mo->SetXYZ(PredictionLerpResult.x, PredictionLerpResult.y, PredictionLerpResult.z);
 			}
 			else
 			{
@@ -2840,7 +2837,7 @@ void P_UnPredictPlayer ()
 		player->camera = savedcamera;
 
 		act->UnlinkFromWorld();
-		memcpy(&act->x, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->x - (BYTE *)act));
+		memcpy(&act->snext, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act));
 
 		// The blockmap ordering needs to remain unchanged, too.
 		// Restore sector links and refrences.
@@ -3114,7 +3111,7 @@ void player_t::Serialize (FArchive &arc)
 	}
 	else
 	{
-		onground = (mo->z <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2);
+		onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (cheats & CF_NOCLIP2);
 	}
 
 	if (SaveVersion < 4514 && IsBot)
diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp
index 3746a6ca7..6267ae6d9 100644
--- a/src/thingdef/thingdef_expression.cpp
+++ b/src/thingdef/thingdef_expression.cpp
@@ -69,9 +69,9 @@ DEFINE_MEMBER_VARIABLE(special2, AActor)
 DEFINE_MEMBER_VARIABLE(tid, AActor)
 DEFINE_MEMBER_VARIABLE(TIDtoHate, AActor)
 DEFINE_MEMBER_VARIABLE(waterlevel, AActor)
-DEFINE_MEMBER_VARIABLE(x, AActor)
-DEFINE_MEMBER_VARIABLE(y, AActor)
-DEFINE_MEMBER_VARIABLE(z, AActor)
+DEFINE_MEMBER_VARIABLE_ALIAS(x, __pos.x, AActor)
+DEFINE_MEMBER_VARIABLE_ALIAS(y, __pos.y, AActor)
+DEFINE_MEMBER_VARIABLE_ALIAS(z, __pos.z, AActor)
 DEFINE_MEMBER_VARIABLE(velx, AActor)
 DEFINE_MEMBER_VARIABLE(vely, AActor)
 DEFINE_MEMBER_VARIABLE(velz, AActor)

From 1a356dfa51d929d67ab844f68c34f50ff2da8ba1 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@users.noreply.github.com>
Date: Wed, 20 Jan 2016 14:53:56 -0600
Subject: [PATCH 17/23] Fixed: MIDI meta events were completely discarded,
 including their delays

(unless the event was for setting the tempo) This left the following
events in the track to happen at the wrong time.
---
 src/sound/music_smf_midiout.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/sound/music_smf_midiout.cpp b/src/sound/music_smf_midiout.cpp
index 43755eb08..6284c504b 100644
--- a/src/sound/music_smf_midiout.cpp
+++ b/src/sound/music_smf_midiout.cpp
@@ -661,6 +661,16 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 					events[2] = (MEVT_TEMPO << 24) | Tempo;
 					events += 3;
 					break;
+
+				default:
+					if (delay != 0)
+					{
+						events[0] = delay;
+						events[1] = 0;
+						events[2] = MEVT_NOP << 24;
+						events += 3;
+					}
+					break;
 				}
 				track->TrackP += len;
 				if (track->TrackP == track->MaxTrackP)

From 7f6b421e87972904434c4551863e593fd42b49b5 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@users.noreply.github.com>
Date: Wed, 20 Jan 2016 18:00:48 -0600
Subject: [PATCH 18/23] Make sure all unhandled delayed MIDI events generate
 NOPs

- Looking over the code again, I see that discarded SysEx messages can
  cause the same issue as unhandled meta events, so generalize the
  returning of a NOP for everything.
---
 src/sound/music_smf_midiout.cpp | 38 +++++++++++++++------------------
 1 file changed, 17 insertions(+), 21 deletions(-)

diff --git a/src/sound/music_smf_midiout.cpp b/src/sound/music_smf_midiout.cpp
index 6284c504b..918639399 100644
--- a/src/sound/music_smf_midiout.cpp
+++ b/src/sound/music_smf_midiout.cpp
@@ -384,6 +384,11 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 	event = track->TrackBegin[track->TrackP++];
 	CHECK_FINISHED
 
+	// The actual event type will be filled in below.
+	events[0] = delay;
+	events[1] = 0;
+	events[2] = MEVT_NOP << 24;
+
 	if (event != MIDI_SYSEX && event != MIDI_META && event != MIDI_SYSEXEND)
 	{
 		// Normal short message
@@ -582,17 +587,10 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 				break;
 			}
 		}
-		events[0] = delay;
-		events[1] = 0;
 		if (event != MIDI_META && (!track->Designated || (track->Designation & DesignationMask)))
 		{
 			events[2] = event | (data1<<8) | (data2<<16);
 		}
-		else
-		{
-			events[2] = MEVT_NOP << 24;
-		}
-		events += 3;
 	}
 	else
 	{
@@ -612,8 +610,6 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 			}
 			else
 			{
-				events[0] = delay;
-				events[1] = 0;
 				BYTE *msg = (BYTE *)&events[3];
 				if (event == MIDI_SYSEX)
 				{ // Need to add the SysEx marker to the message.
@@ -631,7 +627,6 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 				{
 					*msg++ = 0;
 				}
-				events = (DWORD *)msg;
 				track->TrackP += len;
 			}
 		}
@@ -659,17 +654,6 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 					events[0] = delay;
 					events[1] = 0;
 					events[2] = (MEVT_TEMPO << 24) | Tempo;
-					events += 3;
-					break;
-
-				default:
-					if (delay != 0)
-					{
-						events[0] = delay;
-						events[1] = 0;
-						events[2] = MEVT_NOP << 24;
-						events += 3;
-					}
 					break;
 				}
 				track->TrackP += len;
@@ -688,6 +672,18 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
 	{
 		track->Delay = track->ReadVarLen();
 	}
+	// Advance events pointer unless this is a non-delaying NOP.
+	if (events[0] != 0 || MEVT_EVENTTYPE(events[2]) != MEVT_NOP)
+	{
+		if (MEVT_EVENTTYPE(events[2]) == MEVT_LONGMSG)
+		{
+			events += 3 + ((MEVT_EVENTPARM(events[2]) + 3) >> 2);
+		}
+		else
+		{
+			events += 3;
+		}
+	}
 	return events;
 }
 

From 710fa552887ed4dd49b5c35ae3e597b8f34e25bd Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@users.noreply.github.com>
Date: Wed, 20 Jan 2016 18:37:05 -0600
Subject: [PATCH 19/23] Port recent SMF changes to XMI and HMI:

- Handle SysEx messages instead of ignoring them.
- Don't lose time for unhandled events with delays.
---
 src/sound/i_musicinterns.h      | 10 ++---
 src/sound/music_hmi_midiout.cpp | 75 +++++++++++++++++++++++++++------
 src/sound/music_xmi_midiout.cpp | 73 +++++++++++++++++++++++++++-----
 3 files changed, 128 insertions(+), 30 deletions(-)

diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h
index 52364ab58..ccbab55f7 100644
--- a/src/sound/i_musicinterns.h
+++ b/src/sound/i_musicinterns.h
@@ -600,9 +600,9 @@ public:
 protected:
 	void Heapify();
 
-	unsigned int Parent(unsigned int i) { return (i + 1u) / 2u - 1u; }
-	unsigned int Left(unsigned int i) { return (i + 1u) * 2u - 1u; }
-	unsigned int Right(unsigned int i) { return (i + 1u) * 2u; }
+	unsigned int Parent(unsigned int i) const { return (i + 1u) / 2u - 1u; }
+	unsigned int Left(unsigned int i) const { return (i + 1u) * 2u - 1u; }
+	unsigned int Right(unsigned int i) const { return (i + 1u) * 2u; }
 };
 
 class HMISong : public MIDIStreamer
@@ -630,7 +630,7 @@ protected:
 	struct TrackInfo;
 
 	void ProcessInitialMetaEvents ();
-	DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay);
+	DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom);
 	TrackInfo *FindNextDue ();
 
 	static DWORD ReadVarLenHMI(TrackInfo *);
@@ -673,7 +673,7 @@ protected:
 	void AdvanceSong(DWORD time);
 
 	void ProcessInitialMetaEvents();
-	DWORD *SendCommand (DWORD *event, EventSource track, DWORD delay);
+	DWORD *SendCommand (DWORD *event, EventSource track, DWORD delay, ptrdiff_t room, bool &sysex_noroom);
 	EventSource FindNextDue();
 
 	BYTE *MusHeader;
diff --git a/src/sound/music_hmi_midiout.cpp b/src/sound/music_hmi_midiout.cpp
index ca3ae0905..1796b1372 100644
--- a/src/sound/music_hmi_midiout.cpp
+++ b/src/sound/music_hmi_midiout.cpp
@@ -523,7 +523,12 @@ DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
 			// Play all events for this tick.
 			do
 			{
-				DWORD *new_events = SendCommand(events, TrackDue, time);
+				bool sysex_noroom = false;
+				DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom);
+				if (sysex_noroom)
+				{
+					return events;
+				}
 				TrackDue = FindNextDue();
 				if (new_events != events)
 				{
@@ -568,7 +573,7 @@ void HMISong::AdvanceTracks(DWORD time)
 //
 //==========================================================================
 
-DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
+DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom)
 {
 	DWORD len;
 	BYTE event, data1 = 0, data2 = 0;
@@ -584,10 +589,20 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
 		return events + 3;
 	}
 
+	sysex_noroom = false;
+	size_t start_p = track->TrackP;
+
 	CHECK_FINISHED
 	event = track->TrackBegin[track->TrackP++];
 	CHECK_FINISHED
 
+	// The actual event type will be filled in below. If it's not a NOP,
+	// the events pointer will be advanced once the actual event is written.
+	// Otherwise, we do it at the end of the function.
+	events[0] = delay;
+	events[1] = 0;
+	events[2] = MEVT_NOP << 24;
+
 	if (event != MIDI_SYSEX && event != MIDI_META && event != MIDI_SYSEXEND && event != 0xFe)
 	{
 		// Normal short message
@@ -626,17 +641,10 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
 			data2 = VolumeControllerChange(event & 15, data2);
 		}
 
-		events[0] = delay;
-		events[1] = 0;
 		if (event != MIDI_META)
 		{
 			events[2] = event | (data1<<8) | (data2<<16);
 		}
-		else
-		{
-			events[2] = MEVT_NOP << 24;
-		}
-		events += 3;
 
 		if (ReadVarLen == ReadVarLenHMI && (event & 0x70) == (MIDI_NOTEON & 0x70))
 		{ // HMI note on events include the time until an implied note off event.
@@ -645,13 +653,41 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
 	}
 	else
 	{
-		// Skip SysEx events just because I don't want to bother with them.
-		// The old MIDI player ignored them too, so this won't break
-		// anything that played before.
+		// SysEx events could potentially not have enough room in the buffer...
 		if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
 		{
 			len = ReadVarLen(track);
-			track->TrackP += len;
+			if (len >= (MAX_EVENTS-1)*3*4)
+			{ // This message will never fit. Throw it away.
+				track->TrackP += len;
+			}
+			else if (len + 12 >= (size_t)room * 4)
+			{ // Not enough room left in this buffer. Backup and wait for the next one.
+				track->TrackP = start_p;
+				sysex_noroom = true;
+				return events;
+			}
+			else
+			{
+				BYTE *msg = (BYTE *)&events[3];
+				if (event == MIDI_SYSEX)
+				{ // Need to add the SysEx marker to the message.
+					events[2] = (MEVT_LONGMSG << 24) | (len + 1);
+					*msg++ = MIDI_SYSEX;
+				}
+				else
+				{
+					events[2] = (MEVT_LONGMSG << 24) | len;
+				}
+				memcpy(msg, &track->TrackBegin[track->TrackP], len);
+				msg += len;
+				// Must pad with 0
+				while ((size_t)msg & 3)
+				{
+					*msg++ = 0;
+				}
+				track->TrackP += len;
+			}
 		}
 		else if (event == MIDI_META)
 		{
@@ -677,7 +713,6 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
 					events[0] = delay;
 					events[1] = 0;
 					events[2] = (MEVT_TEMPO << 24) | Tempo;
-					events += 3;
 					break;
 				}
 				track->TrackP += len;
@@ -720,6 +755,18 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
 	{
 		track->Delay = ReadVarLen(track);
 	}
+	// Advance events pointer unless this is a non-delaying NOP.
+	if (events[0] != 0 || MEVT_EVENTTYPE(events[2]) != MEVT_NOP)
+	{
+		if (MEVT_EVENTTYPE(events[2]) == MEVT_LONGMSG)
+		{
+			events += 3 + ((MEVT_EVENTPARM(events[2]) + 3) >> 2);
+		}
+		else
+		{
+			events += 3;
+		}
+	}
 	return events;
 }
 
diff --git a/src/sound/music_xmi_midiout.cpp b/src/sound/music_xmi_midiout.cpp
index 71246f518..fbbf4db53 100644
--- a/src/sound/music_xmi_midiout.cpp
+++ b/src/sound/music_xmi_midiout.cpp
@@ -337,7 +337,12 @@ DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time)
 			// Play all events for this tick.
 			do
 			{
-				DWORD *new_events = SendCommand(events, EventDue, time);
+				bool sysex_noroom = false;
+				DWORD *new_events = SendCommand(events, EventDue, time, max_event_p - events, sysex_noroom);
+				if (sysex_noroom)
+				{
+					return events;
+				}
 				EventDue = FindNextDue();
 				if (new_events != events)
 				{
@@ -382,7 +387,7 @@ void XMISong::AdvanceSong(DWORD time)
 //
 //==========================================================================
 
-DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay)
+DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay, ptrdiff_t room, bool &sysex_noroom)
 {
 	DWORD len;
 	BYTE event, data1 = 0, data2 = 0;
@@ -399,10 +404,20 @@ DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay)
 
 	TrackInfo *track = CurrSong;
 
+	sysex_noroom = false;
+	size_t start_p = track->EventP;
+
 	CHECK_FINISHED
 	event = track->EventChunk[track->EventP++];
 	CHECK_FINISHED
 
+	// The actual event type will be filled in below. If it's not a NOP,
+	// the events pointer will be advanced once the actual event is written.
+	// Otherwise, we do it at the end of the function.
+	events[0] = delay;
+	events[1] = 0;
+	events[2] = MEVT_NOP << 24;
+
 	if (event != MIDI_SYSEX && event != MIDI_META && event != MIDI_SYSEXEND)
 	{
 		// Normal short message
@@ -499,10 +514,6 @@ DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay)
 		{
 			events[2] = event | (data1<<8) | (data2<<16);
 		}
-		else
-		{
-			events[2] = MEVT_NOP << 24;
-		}
 		events += 3;
 
 
@@ -513,13 +524,41 @@ DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay)
 	}
 	else
 	{
-		// Skip SysEx events just because I don't want to bother with them.
-		// The old MIDI player ignored them too, so this won't break
-		// anything that played before.
+		// SysEx events could potentially not have enough room in the buffer...
 		if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
 		{
-			len = track->ReadVarLen ();
-			track->EventP += len;
+			len = track->ReadVarLen();
+			if (len >= (MAX_EVENTS-1)*3*4)
+			{ // This message will never fit. Throw it away.
+				track->EventP += len;
+			}
+			else if (len + 12 >= (size_t)room * 4)
+			{ // Not enough room left in this buffer. Backup and wait for the next one.
+				track->EventP = start_p;
+				sysex_noroom = true;
+				return events;
+			}
+			else
+			{
+				BYTE *msg = (BYTE *)&events[3];
+				if (event == MIDI_SYSEX)
+				{ // Need to add the SysEx marker to the message.
+					events[2] = (MEVT_LONGMSG << 24) | (len + 1);
+					*msg++ = MIDI_SYSEX;
+				}
+				else
+				{
+					events[2] = (MEVT_LONGMSG << 24) | len;
+				}
+				memcpy(msg, &track->EventChunk[track->EventP++], len);
+				msg += len;
+				// Must pad with 0
+				while ((size_t)msg & 3)
+				{
+					*msg++ = 0;
+				}
+				track->EventP += len;
+			}
 		}
 		else if (event == MIDI_META)
 		{
@@ -551,6 +590,18 @@ DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay)
 	{
 		track->Delay = track->ReadDelay();
 	}
+	// Advance events pointer unless this is a non-delaying NOP.
+	if (events[0] != 0 || MEVT_EVENTTYPE(events[2]) != MEVT_NOP)
+	{
+		if (MEVT_EVENTTYPE(events[2]) == MEVT_LONGMSG)
+		{
+			events += 3 + ((MEVT_EVENTPARM(events[2]) + 3) >> 2);
+		}
+		else
+		{
+			events += 3;
+		}
+	}
 	return events;
 }
 

From 09733d808348ebc4d2e70be59cb86af60483862e Mon Sep 17 00:00:00 2001
From: MajorCooke <paul.growney22@gmail.com>
Date: Wed, 20 Jan 2016 18:50:30 -0600
Subject: [PATCH 20/23] - Don't set both self and pointer's z to spotz when
 teleporting.

---
 src/thingdef/thingdef_codeptr.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp
index 6a33bf595..e9d85686b 100644
--- a/src/thingdef/thingdef_codeptr.cpp
+++ b/src/thingdef/thingdef_codeptr.cpp
@@ -4380,7 +4380,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport)
 		}
 		
 		ref->SetZ((flags & TF_USESPOTZ) ? spot->Z() : ref->floorz, false);
-		self->SetZ((flags & TF_USESPOTZ) ? spot->Z() : self->floorz, false);
 
 		if (!(flags & TF_KEEPANGLE))
 			ref->angle = spot->angle;

From 03d7418f51ac6016ea0b0ccf24a7b16475651ad2 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Thu, 21 Jan 2016 10:23:20 +0100
Subject: [PATCH 21/23] - fixed: Since sector movement is done after
 P_PlayerThink is called, any player position change induced by this is not
 factored into player_t::viewz and needs to be added explicitly.

This fixes the infamous 'view squats down a bit when riding up an elevator' effect. It is also there in the other cases but far less pronounced.
---
 src/p_map.cpp | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/p_map.cpp b/src/p_map.cpp
index 43c7f6af0..d096beb0d 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -5268,6 +5268,7 @@ int P_PushDown(AActor *thing, FChangePosition *cpos)
 void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
 {
 	fixed_t oldfloorz = thing->floorz;
+	fixed_t oldz = thing->Z();
 
 	P_AdjustFloorCeil(thing, cpos);
 
@@ -5297,6 +5298,10 @@ void PIT_FloorDrop(AActor *thing, FChangePosition *cpos)
 			P_CheckFakeFloorTriggers(thing, oldz);
 		}
 	}
+	if (thing->player && thing->player->mo == thing)
+	{
+		thing->player->viewz += thing->Z() - oldz;
+	}
 }
 
 //=============================================================================
@@ -5348,6 +5353,10 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
 		thing->SetZ(oldz);
 		break;
 	}
+	if (thing->player && thing->player->mo == thing)
+	{
+		thing->player->viewz += thing->Z() - oldz;
+	}
 }
 
 //=============================================================================
@@ -5359,6 +5368,7 @@ void PIT_FloorRaise(AActor *thing, FChangePosition *cpos)
 void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 {
 	bool onfloor;
+	fixed_t oldz = thing->Z();
 
 	onfloor = thing->Z() <= thing->floorz;
 	P_AdjustFloorCeil(thing, cpos);
@@ -5395,6 +5405,10 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 			break;
 		}
 	}
+	if (thing->player && thing->player->mo == thing)
+	{
+		thing->player->viewz += thing->Z() - oldz;
+	}
 }
 
 //=============================================================================
@@ -5406,6 +5420,7 @@ void PIT_CeilingLower(AActor *thing, FChangePosition *cpos)
 void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
 {
 	bool isgood = P_AdjustFloorCeil(thing, cpos);
+	fixed_t oldz = thing->Z();
 
 	if (thing->flags4 & MF4_ACTLIKEBRIDGE) return; // do not move bridge things
 
@@ -5432,6 +5447,10 @@ void PIT_CeilingRaise(AActor *thing, FChangePosition *cpos)
 			thing->SetZ( MIN(thing->ceilingz - thing->height, onmobj->Top()));
 		}
 	}
+	if (thing->player && thing->player->mo == thing)
+	{
+		thing->player->viewz += thing->Z() - oldz;
+	}
 }
 
 //=============================================================================

From d347415aee61d6509240719e540c2423614ffff1 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Thu, 21 Jan 2016 11:36:37 +0100
Subject: [PATCH 22/23] - fixed some garbage collection issues with
 interpolations:

* FInterpolator depended on external references to prevent its content from getting GC'd.
* none of the pointers in the interpolation objects were declared to the GC.

The result of these issues was that changing anything about the life cycle of interpolation objects caused corrupted memory crashes when a level was changed.
---
 src/dobject.h                |  5 +++++
 src/dobjgc.cpp               |  1 +
 src/p_setup.cpp              |  2 +-
 src/r_data/r_interpolate.cpp | 32 +++++++++++++++++++++-----------
 src/r_data/r_interpolate.h   |  7 ++++---
 5 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/src/dobject.h b/src/dobject.h
index 40b47ee5c..74371c0d6 100644
--- a/src/dobject.h
+++ b/src/dobject.h
@@ -203,6 +203,11 @@ private: \
 #define IMPLEMENT_ABSTRACT_CLASS(cls) \
 	_IMP_PCLASS(cls,NULL,NULL)
 
+#define IMPLEMENT_ABSTRACT_POINTY_CLASS(cls) \
+	_IMP_PCLASS(cls,cls::PointerOffsets,NULL) \
+	const size_t cls::PointerOffsets[] = {
+
+
 enum EObjectFlags
 {
 	// GC flags
diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp
index 3812c0b08..2efb5a15e 100644
--- a/src/dobjgc.cpp
+++ b/src/dobjgc.cpp
@@ -335,6 +335,7 @@ static void MarkRoot()
 		SectorMarker->SecNum = 0;
 	}
 	Mark(SectorMarker);
+	Mark(interpolator.Head);
 	// Mark bot stuff.
 	Mark(bglobal.firstthing);
 	Mark(bglobal.body1);
diff --git a/src/p_setup.cpp b/src/p_setup.cpp
index 3749e97aa..c915c31ec 100644
--- a/src/p_setup.cpp
+++ b/src/p_setup.cpp
@@ -3353,6 +3353,7 @@ extern polyblock_t **PolyBlockMap;
 
 void P_FreeLevelData ()
 {
+	interpolator.ClearInterpolations();	// [RH] Nothing to interpolate on a fresh level.
 	Renderer->CleanLevelData();
 	FPolyObj::ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process.
 	SN_StopAllSequences ();
@@ -3584,7 +3585,6 @@ void P_SetupLevel (const char *lumpname, int position)
 
 	// Free all level data from the previous map
 	P_FreeLevelData ();
-	interpolator.ClearInterpolations();	// [RH] Nothing to interpolate on a fresh level.
 
 	MapData *map = P_OpenMapData(lumpname, true);
 	if (map == NULL)
diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp
index 3ca3b557c..268dd4aa0 100644
--- a/src/r_data/r_interpolate.cpp
+++ b/src/r_data/r_interpolate.cpp
@@ -157,7 +157,10 @@ public:
 //
 //==========================================================================
 
-IMPLEMENT_ABSTRACT_CLASS(DInterpolation)
+IMPLEMENT_ABSTRACT_POINTY_CLASS(DInterpolation)
+DECLARE_POINTER(Next)
+DECLARE_POINTER(Prev)
+END_POINTERS
 IMPLEMENT_CLASS(DSectorPlaneInterpolation)
 IMPLEMENT_CLASS(DSectorScrollInterpolation)
 IMPLEMENT_CLASS(DWallScrollInterpolation)
@@ -213,9 +216,9 @@ void FInterpolator::UpdateInterpolations()
 void FInterpolator::AddInterpolation(DInterpolation *interp)
 {
 	interp->Next = Head;
-	if (Head != NULL) Head->Prev = &interp->Next;
+	if (Head != NULL) Head->Prev = interp;
+	interp->Prev = NULL;
 	Head = interp;
-	interp->Prev = &Head;
 	count++;
 }
 
@@ -227,14 +230,19 @@ void FInterpolator::AddInterpolation(DInterpolation *interp)
 
 void FInterpolator::RemoveInterpolation(DInterpolation *interp)
 {
-	if (interp->Prev != NULL)
+	if (Head == interp)
 	{
-		*interp->Prev = interp->Next;
-		if (interp->Next != NULL) interp->Next->Prev = interp->Prev;
-		interp->Next = NULL;
-		interp->Prev = NULL;
-		count--;
+		Head = interp->Next;
+		if (Head != NULL) Head->Prev = NULL;
 	}
+	else
+	{
+		if (interp->Prev != NULL) interp->Prev->Next = interp->Next;
+		if (interp->Next != NULL) interp->Next->Prev = interp->Prev;
+	}
+	interp->Next = NULL;
+	interp->Prev = NULL;
+	count--;
 }
 
 //==========================================================================
@@ -285,13 +293,15 @@ void FInterpolator::RestoreInterpolations()
 
 void FInterpolator::ClearInterpolations()
 {
-	for (DInterpolation *probe = Head; probe != NULL; )
+	DInterpolation *probe = Head;
+	Head = NULL;
+	while (probe != NULL)
 	{
 		DInterpolation *next = probe->Next;
+		probe->Next = probe->Prev = NULL;
 		probe->Destroy();
 		probe = next;
 	}
-	Head = NULL;
 }
 
 
diff --git a/src/r_data/r_interpolate.h b/src/r_data/r_interpolate.h
index bbd2438d8..9f28b04d0 100644
--- a/src/r_data/r_interpolate.h
+++ b/src/r_data/r_interpolate.h
@@ -13,9 +13,10 @@ class DInterpolation : public DObject
 	friend struct FInterpolator;
 
 	DECLARE_ABSTRACT_CLASS(DInterpolation, DObject)
+	HAS_OBJECT_POINTERS
 
-	DInterpolation *Next;
-	DInterpolation **Prev;
+	TObjPtr<DInterpolation> Next;
+	TObjPtr<DInterpolation> Prev;
 	int refcount;
 
 protected:
@@ -40,7 +41,7 @@ public:
 
 struct FInterpolator
 {
-	DInterpolation *Head;
+	TObjPtr<DInterpolation> Head;
 	bool didInterp;
 	int count;
 

From cf2ee1eb3f31178095e5483ce28a9364cb8c2312 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <c.oelckers@zdoom.fake>
Date: Thu, 21 Jan 2016 11:58:44 +0100
Subject: [PATCH 23/23] - fixed: Interpolations were deleted too early.

They were immediately deleted when the associated thinker was destroyed. But this was too early because it missed the final tic of movement, resulting in a visible jump when a moving platform with a player on it came to a halt.
Changed it so that DelRef no longer destroys the interpolation itself. Instead the ::Interpolate method will check if the reference count is 0, and if so and there was no more movement, will then destroy the interpolation.
This ensures that it keeps running until it has interpolated all remaining bits of movement induced by the thinker.

Now moving up a lift is 100% smooth, even with movement interpolation on.
---
 src/r_data/r_interpolate.cpp | 65 ++++++++++++++++++++++++++----------
 src/r_data/r_interpolate.h   |  3 +-
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp
index 268dd4aa0..c46e17f9c 100644
--- a/src/r_data/r_interpolate.cpp
+++ b/src/r_data/r_interpolate.cpp
@@ -344,10 +344,6 @@ int DInterpolation::AddRef()
 int DInterpolation::DelRef()
 {
 	if (refcount > 0) --refcount;
-	if (refcount <= 0 && !(ObjectFlags & OF_EuthanizeMe))
-	{
-		Destroy();
-	}
 	return refcount;
 }
 
@@ -496,9 +492,16 @@ void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio)
 	bakheight = *pheight;
 	baktexz = sector->GetPlaneTexZ(pos);
 
-	*pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio);
-	sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio));
-	P_RecalculateAttached3DFloors(sector);
+	if (refcount == 0 && oldheight == bakheight)
+	{
+		Destroy();
+	}
+	else
+	{
+		*pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio);
+		sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio));
+		P_RecalculateAttached3DFloors(sector);
+	}
 }
 
 //==========================================================================
@@ -622,8 +625,15 @@ void DSectorScrollInterpolation::Interpolate(fixed_t smoothratio)
 	bakx = sector->GetXOffset(ceiling);
 	baky = sector->GetYOffset(ceiling, false);
 
-	sector->SetXOffset(ceiling, oldx + FixedMul(bakx - oldx, smoothratio));
-	sector->SetYOffset(ceiling, oldy + FixedMul(baky - oldy, smoothratio));
+	if (refcount == 0 && oldx == bakx && oldy == baky)
+	{
+		Destroy();
+	}
+	else
+	{
+		sector->SetXOffset(ceiling, oldx + FixedMul(bakx - oldx, smoothratio));
+		sector->SetYOffset(ceiling, oldy + FixedMul(baky - oldy, smoothratio));
+	}
 }
 
 //==========================================================================
@@ -706,8 +716,15 @@ void DWallScrollInterpolation::Interpolate(fixed_t smoothratio)
 	bakx = side->GetTextureXOffset(part);
 	baky = side->GetTextureYOffset(part);
 
-	side->SetTextureXOffset(part, oldx + FixedMul(bakx - oldx, smoothratio));
-	side->SetTextureYOffset(part, oldy + FixedMul(baky - oldy, smoothratio));
+	if (refcount == 0 && oldx == bakx && oldy == baky)
+	{
+		Destroy();
+	}
+	else
+	{
+		side->SetTextureXOffset(part, oldx + FixedMul(bakx - oldx, smoothratio));
+		side->SetTextureYOffset(part, oldy + FixedMul(baky - oldy, smoothratio));
+	}
 }
 
 //==========================================================================
@@ -798,6 +815,7 @@ void DPolyobjInterpolation::Restore()
 
 void DPolyobjInterpolation::Interpolate(fixed_t smoothratio)
 {
+	bool changed = false;
 	for(unsigned int i = 0; i < poly->Vertices.Size(); i++)
 	{
 		fixed_t *px = &poly->Vertices[i]->x;
@@ -806,15 +824,26 @@ void DPolyobjInterpolation::Interpolate(fixed_t smoothratio)
 		bakverts[i*2  ] = *px;
 		bakverts[i*2+1] = *py;
 
-		*px = oldverts[i*2  ] + FixedMul(bakverts[i*2  ] - oldverts[i*2  ], smoothratio);
-		*py = oldverts[i*2+1] + FixedMul(bakverts[i*2+1] - oldverts[i*2+1], smoothratio);
+		if (bakverts[i * 2] != oldverts[i * 2] || bakverts[i * 2 + i] != oldverts[i * 2 + 1])
+		{
+			changed = true;
+			*px = oldverts[i * 2] + FixedMul(bakverts[i * 2] - oldverts[i * 2], smoothratio);
+			*py = oldverts[i * 2 + 1] + FixedMul(bakverts[i * 2 + 1] - oldverts[i * 2 + 1], smoothratio);
+		}
 	}
-	bakcx = poly->CenterSpot.x;
-	bakcy = poly->CenterSpot.y;
-	poly->CenterSpot.x = bakcx + FixedMul(bakcx - oldcx, smoothratio);
-	poly->CenterSpot.y = bakcy + FixedMul(bakcy - oldcy, smoothratio);
+	if (refcount == 0 && !changed)
+	{
+		Destroy();
+	}
+	else
+	{
+		bakcx = poly->CenterSpot.x;
+		bakcy = poly->CenterSpot.y;
+		poly->CenterSpot.x = bakcx + FixedMul(bakcx - oldcx, smoothratio);
+		poly->CenterSpot.y = bakcy + FixedMul(bakcy - oldcy, smoothratio);
 
-	poly->ClearSubsectorLinks();
+		poly->ClearSubsectorLinks();
+	}
 }
 
 //==========================================================================
diff --git a/src/r_data/r_interpolate.h b/src/r_data/r_interpolate.h
index 9f28b04d0..29e8a6171 100644
--- a/src/r_data/r_interpolate.h
+++ b/src/r_data/r_interpolate.h
@@ -17,9 +17,10 @@ class DInterpolation : public DObject
 
 	TObjPtr<DInterpolation> Next;
 	TObjPtr<DInterpolation> Prev;
-	int refcount;
 
 protected:
+	int refcount;
+
 	DInterpolation();
 
 public: