diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp
index c617762dc..3f258bd2b 100644
--- a/source/games/blood/src/actor.cpp
+++ b/source/games/blood/src/actor.cpp
@@ -2543,9 +2543,9 @@ void actInit(TArray<DBloodActor*>& actors)
 
 static void ConcussSprite(DBloodActor* source, DBloodActor* actor, int x, int y, int z, int damage)
 {
-	int dx = actor->spr.pos.X - x;
-	int dy = actor->spr.pos.Y - y;
-	int dz = (actor->spr.pos.Z - z) >> 4;
+	int dx = actor->int_pos().X - x;
+	int dy = actor->int_pos().Y - y;
+	int dz = (actor->int_pos().Z - z) >> 4;
 	int dist2 = 0x40000 + dx * dx + dy * dy + dz * dz;
 	assert(dist2 > 0);
 	damage = Scale(0x40000, damage, dist2);
@@ -2659,9 +2659,9 @@ void actRadiusDamage(DBloodActor* source, int x, int y, int z, sectortype* pSect
 					if (!CheckSector(sectorMap, act2)) continue;
 					if (!CheckProximity(act2, x, y, z, pSector, nDist)) continue;
 
-					int dx = abs(x - act2->spr.pos.X);
-					int dy = abs(y - act2->spr.pos.Y);
-					int dz = abs(z - act2->spr.pos.Z) >> 4;
+					int dx = abs(x - act2->int_pos().X);
+					int dy = abs(y - act2->int_pos().Y);
+					int dz = abs(z - act2->int_pos().Z) >> 4;
 					int dist = ksqrt(dx * dx + dy * dy + dz * dz);
 					if (dist > nDist) continue;
 
@@ -2686,8 +2686,8 @@ void actRadiusDamage(DBloodActor* source, int x, int y, int z, sectortype* pSect
 
 			if (act2->xspr.locked) continue;
 
-			int dx = abs(x - act2->spr.pos.X);
-			int dy = abs(y - act2->spr.pos.Y);
+			int dx = abs(x - act2->int_pos().X);
+			int dy = abs(y - act2->int_pos().Y);
 			int dist = ksqrt(dx * dx + dy * dy);
 			if (dist > nDist) continue;
 
@@ -2716,7 +2716,7 @@ static void actNapalmMove(DBloodActor* actor)
 	if (Chance(0x8000)) actor->spr.cstat |= CSTAT_SPRITE_XFLIP;
 
 	sfxPlay3DSound(actor, 303, 24 + (actor->spr.flags & 3), 1);
-	actRadiusDamage(pOwner, actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, actor->sector(), 128, 0, 60, kDamageExplode, 15, 120);
+	actRadiusDamage(pOwner, actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, actor->sector(), 128, 0, 60, kDamageExplode, 15, 120);
 
 	if (actor->xspr.data4 > 1)
 	{
@@ -2750,8 +2750,8 @@ static void actNapalmMove(DBloodActor* actor)
 static DBloodActor* actSpawnFloor(DBloodActor* actor)
 {
 	auto pSector = actor->sector();
-	int x = actor->spr.pos.X;
-	int y = actor->spr.pos.Y;
+	int x = actor->int_pos().X;
+	int y = actor->int_pos().Y;
 	updatesector(x, y, &pSector);
 	int zFloor = getflorzofslopeptr(pSector, x, y);
 	auto spawned = actSpawnSprite(pSector, x, y, zFloor, 3, 0);
@@ -2875,8 +2875,8 @@ DBloodActor* actDropObject(DBloodActor* actor, int nType)
 	{
 		int top, bottom;
 		GetActorExtents(act2, &top, &bottom);
-		if (bottom >= act2->spr.pos.Z)
-			act2->add_int_z(-(bottom - act2->spr.pos.Z));
+		if (bottom >= act2->int_pos().Z)
+			act2->add_int_z(-(bottom - act2->int_pos().Z));
 	}
 
 	return act2;
@@ -2895,7 +2895,7 @@ bool actHealDude(DBloodActor* actor, int add, int threshold)
 	threshold <<= 4;
 	if (actor->xspr.health < (unsigned)threshold)
 	{
-		if (actor->IsPlayerActor()) sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 780, actor->sector());
+		if (actor->IsPlayerActor()) sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 780, actor->sector());
 		actor->xspr.health = min<uint32_t>(actor->xspr.health + add, threshold);
 		return true;
 	}
@@ -2968,7 +2968,7 @@ static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
 		else
 		{
 			seqKill(actor);
-			DBloodActor* pEffect = gFX.fxSpawnActor((FX_ID)52, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, actor->spr.ang);
+			DBloodActor* pEffect = gFX.fxSpawnActor((FX_ID)52, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, actor->spr.ang);
 			if (pEffect != nullptr)
 			{
 				pEffect->spr.cstat = CSTAT_SPRITE_ALIGNMENT_FACING;
@@ -2986,7 +2986,7 @@ static bool actKillModernDude(DBloodActor* actor, DAMAGE_TYPE damageType)
 
 				int top, bottom;
 				GetActorExtents(actor, &top, &bottom);
-				CGibPosition gibPos(actor->spr.pos.X, actor->spr.pos.Y, top);
+				CGibPosition gibPos(actor->int_pos().X, actor->int_pos().Y, top);
 				CGibVelocity gibVel(actor->vel.X >> 1, actor->vel.Y >> 1, -0xccccc);
 				GibSprite(actor, nGibType, &gibPos, &gibVel);
 			}
@@ -3224,7 +3224,7 @@ static void spawnGibs(DBloodActor* actor, int type, int velz)
 {
 	int top, bottom;
 	GetActorExtents(actor, &top, &bottom);
-	CGibPosition gibPos(actor->spr.pos.X, actor->spr.pos.Y, top);
+	CGibPosition gibPos(actor->int_pos().X, actor->int_pos().Y, top);
 	CGibVelocity gibVel(actor->vel.X >> 1, actor->vel.Y >> 1, velz);
 	GibSprite(actor, GIBTYPE_27, &gibPos, &gibVel);
 }
@@ -3728,7 +3728,7 @@ static int actDamageThing(DBloodActor* source, DBloodActor* actor, int damage, D
 			{
 			case -1:
 				GibSprite(actor, GIBTYPE_14, nullptr, nullptr);
-				sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 312, actor->sector());
+				sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 312, actor->sector());
 				actPostSprite(actor, kStatFree);
 				break;
 
@@ -3880,7 +3880,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 		case 4:
 			if (pWallHit)
 			{
-				auto pFX = gFX.fxSpawnActor(FX_52, missileActor->sector(), missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, 0);
+				auto pFX = gFX.fxSpawnActor(FX_52, missileActor->sector(), missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, 0);
 				if (pFX) pFX->spr.ang = (GetWallAngle(pWallHit) + 512) & 2047;
 			}
 			break;
@@ -3901,7 +3901,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 
 	case kMissileArcGargoyle:
 		sfxKill3DSound(missileActor, -1, -1);
-		sfxPlay3DSound(missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, 306, missileActor->sector());
+		sfxPlay3DSound(missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, 306, missileActor->sector());
 		GibSprite(missileActor, GIBTYPE_6, NULL, NULL);
 
 		if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo))
@@ -3915,7 +3915,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 	case kMissileLifeLeechAltNormal:
 	case kMissileLifeLeechAltSmall:
 		sfxKill3DSound(missileActor, -1, -1);
-		sfxPlay3DSound(missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, 306, missileActor->sector());
+		sfxPlay3DSound(missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, 306, missileActor->sector());
 
 		if (hitCode == 3 && actorHit && (pThingInfo || pDudeInfo))
 		{
@@ -3954,7 +3954,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 					evPostActor(actorHit, 0, kCallbackFXFlameLick);
 
 				actBurnSprite(missileOwner, actorHit, 480);
-				actRadiusDamage(missileOwner, missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, missileActor->sector(), 16, 20, 10, kDamageBullet, 6, 480);
+				actRadiusDamage(missileOwner, missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, missileActor->sector(), 16, 20, 10, kDamageBullet, 6, 480);
 
 				// by NoOne: allow additional bullet damage for Flare Gun
 				if (gGameOptions.weaponsV10x && !VanillaMode())
@@ -3973,8 +3973,8 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 			{
 				missileActor->spr.picnum = 2123;
 				missileActor->SetTarget(actorHit);
-				missileActor->xspr.TargetPos.Z = missileActor->spr.pos.Z - actorHit->spr.pos.Z;
-				missileActor->xspr.goalAng = getangle(missileActor->spr.pos.X - actorHit->spr.pos.X, missileActor->spr.pos.Y - actorHit->spr.pos.Y) - actorHit->spr.ang;
+				missileActor->xspr.TargetPos.Z = missileActor->int_pos().Z - actorHit->int_pos().Z;
+				missileActor->xspr.goalAng = getangle(missileActor->int_pos().X - actorHit->int_pos().X, missileActor->int_pos().Y - actorHit->int_pos().Y) - actorHit->spr.ang;
 				missileActor->xspr.state = 1;
 				actPostSprite(missileActor, kStatFlare);
 				missileActor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
@@ -4029,7 +4029,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 
 	case kMissileEctoSkull:
 		sfxKill3DSound(missileActor, -1, -1);
-		sfxPlay3DSound(missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, 522, missileActor->sector());
+		sfxPlay3DSound(missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, 522, missileActor->sector());
 		actPostSprite(missileActor, kStatDebris);
 		seqSpawn(20, missileActor, -1);
 		if (hitCode == 3 && actorHit && actorHit->hasX())
@@ -4062,7 +4062,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode)
 
 	case kMissileTeslaRegular:
 		sfxKill3DSound(missileActor, -1, -1);
-		sfxPlay3DSound(missileActor->spr.pos.X, missileActor->spr.pos.Y, missileActor->spr.pos.Z, 518, missileActor->sector());
+		sfxPlay3DSound(missileActor->int_pos().X, missileActor->int_pos().Y, missileActor->int_pos().Z, 518, missileActor->sector());
 		GibSprite(missileActor, (hitCode == 2) ? GIBTYPE_23 : GIBTYPE_22, NULL, NULL);
 		evKillActor(missileActor);
 		seqKill(missileActor);
@@ -4168,14 +4168,14 @@ static void checkCeilHit(DBloodActor* actor)
 					if (pThingInfo->flags & 1) actor2->spr.flags |= 1;
 					if (pThingInfo->flags & 2) actor2->spr.flags |= 4;
 					// Inlined ?
-					actor2->vel.X += MulScale(4, actor2->spr.pos.X - actor->spr.pos.X, 2);
-					actor2->vel.Y += MulScale(4, actor2->spr.pos.Y - actor->spr.pos.Y, 2);
+					actor2->vel.X += MulScale(4, actor2->int_pos().X - actor->int_pos().X, 2);
+					actor2->vel.Y += MulScale(4, actor2->int_pos().Y - actor->int_pos().Y, 2);
 				}
 				else
 				{
 					actor2->spr.flags |= 5;
-					actor2->vel.X += MulScale(4, actor2->spr.pos.X - actor->spr.pos.X, 2);
-					actor2->vel.Y += MulScale(4, actor2->spr.pos.Y - actor->spr.pos.Y, 2);
+					actor2->vel.X += MulScale(4, actor2->int_pos().X - actor->int_pos().X, 2);
+					actor2->vel.Y += MulScale(4, actor2->int_pos().Y - actor->int_pos().Y, 2);
 
 #ifdef NOONE_EXTENSIONS
 					// add size shroom abilities
@@ -4296,7 +4296,7 @@ static void checkHit(DBloodActor* actor)
 				break;
 
 			case kThingZombieHead:
-				sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 357, actor->sector());
+				sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 357, actor->sector());
 				actKickObject(actor, actor2);
 				actDamageSprite(nullptr, actor2, kDamageFall, 80);
 				break;
@@ -4374,7 +4374,7 @@ static void checkFloorHit(DBloodActor* actor)
 					pPlayer->kickPower = PlayClock + 60;
 				}
 				actKickObject(actor, actor2);
-				sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 357, actor->sector());
+				sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 357, actor->sector());
 				sfxPlay3DSound(actor, 374, 0, 0);
 				break;
 			case kThingZombieHead:
@@ -4384,7 +4384,7 @@ static void checkFloorHit(DBloodActor* actor)
 					pPlayer->kickPower = PlayClock + 60;
 				}
 				actKickObject(actor, actor2);
-				sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 357, actor->sector());
+				sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 357, actor->sector());
 				actDamageSprite(nullptr, actor2, kDamageFall, 80);
 				break;
 			case kTrapSawCircular:
@@ -4541,8 +4541,8 @@ static Collision MoveThing(DBloodActor* actor)
 		actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
 		if ((actor->GetOwner()) && !cl_bloodvanillaexplosions && !VanillaMode())
 			enginecompatibility_mode = ENGINECOMPATIBILITY_NONE; // improved clipmove accuracy
-		auto pos = actor->spr.pos;
-		ClipMove(pos, &pSector, actor->vel.X >> 12, actor->vel.Y >> 12, actor->spr.clipdist << 2, (actor->spr.pos.Z - top) / 4, (bottom - actor->spr.pos.Z) / 4, CLIPMASK0, lhit);
+		auto pos = actor->int_pos();
+		ClipMove(pos, &pSector, actor->vel.X >> 12, actor->vel.Y >> 12, actor->spr.clipdist << 2, (actor->int_pos().Z - top) / 4, (bottom - actor->int_pos().Z) / 4, CLIPMASK0, lhit);
 		actor->set_int_pos(pos);
 		actor->hit.hit = lhit;
 		enginecompatibility_mode = bakCompat; // restore
@@ -4574,7 +4574,7 @@ static Collision MoveThing(DBloodActor* actor)
 	else
 	{
 		assert(pSector);
-		FindSector(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, &pSector);
+		FindSector(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, &pSector);
 	}
 
 	actor->add_int_z(actor->vel.Z >> 8);
@@ -4590,7 +4590,7 @@ static Collision MoveThing(DBloodActor* actor)
 		actor->vel.Z += 58254;
 		if (actor->spr.type == kThingZombieHead)
 		{
-			auto* fxActor = gFX.fxSpawnActor(FX_27, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0);
+			auto* fxActor = gFX.fxSpawnActor(FX_27, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0);
 			if (fxActor)
 			{
 				int v34 = (PlayClock * 3) & 2047;
@@ -4707,8 +4707,8 @@ static Collision MoveThing(DBloodActor* actor)
 			auto hitActor = coll.actor();
 			if ((hitActor->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FACING)
 			{
-				actor->vel.X += MulScale(4, actor->spr.pos.X - hitActor->spr.pos.X, 2);
-				actor->vel.Y += MulScale(4, actor->spr.pos.Y - hitActor->spr.pos.Y, 2);
+				actor->vel.X += MulScale(4, actor->int_pos().X - hitActor->int_pos().X, 2);
+				actor->vel.Y += MulScale(4, actor->int_pos().Y - hitActor->int_pos().Y, 2);
 				lhit = actor->hit.hit;
 			}
 		}
@@ -4743,8 +4743,8 @@ void MoveDude(DBloodActor* actor)
 	DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type);
 	int top, bottom;
 	GetActorExtents(actor, &top, &bottom);
-	int bz = (bottom - actor->spr.pos.Z) / 4;
-	int tz = (actor->spr.pos.Z - top) / 4;
+	int bz = (bottom - actor->int_pos().Z) / 4;
+	int tz = (actor->int_pos().Z - top) / 4;
 	int wd = actor->spr.clipdist << 2;
 	auto pSector = actor->sector();
 	int nAiStateType = (actor->xspr.aiState) ? actor->xspr.aiState->stateType : -1;
@@ -4756,14 +4756,14 @@ void MoveDude(DBloodActor* actor)
 		if (pPlayer && gNoClip)
 		{
 			actor->add_int_pos({ actor->vel.X >> 12, actor->vel.Y >> 12, 0 });
-			if (!FindSector(actor->spr.pos.X, actor->spr.pos.Y, &pSector))
+			if (!FindSector(actor->int_pos().X, actor->int_pos().Y, &pSector))
 				pSector = actor->sector();
 		}
 		else
 		{
 			auto bakCstat = actor->spr.cstat;
 			actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
-			auto pos = actor->spr.pos;
+			auto pos = actor->int_pos();
 			ClipMove(pos, &pSector, actor->vel.X >> 12, actor->vel.Y >> 12, wd, tz, bz, CLIPMASK0, actor->hit.hit);
 			actor->set_int_pos(pos);
 			if (pSector == nullptr)
@@ -4842,7 +4842,7 @@ void MoveDude(DBloodActor* actor)
 	else
 	{
 		assert(pSector);
-		FindSector(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, &pSector);
+		FindSector(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, &pSector);
 	}
 
 	XSECTOR* pXSector = pSector->hasX() ? &pSector->xs() : nullptr;
@@ -4892,7 +4892,7 @@ void MoveDude(DBloodActor* actor)
 		{
 			if (bUnderwater)
 			{
-				int cz = getceilzofslopeptr(pSector, actor->spr.pos.X, actor->spr.pos.Y);
+				int cz = getceilzofslopeptr(pSector, actor->int_pos().X, actor->int_pos().Y);
 				if (cz > top)
 					vc += ((bottom - cz) * -80099) / (bottom - top);
 				else
@@ -4900,7 +4900,7 @@ void MoveDude(DBloodActor* actor)
 			}
 			else
 			{
-				int fz = getflorzofslopeptr(pSector, actor->spr.pos.X, actor->spr.pos.Y);
+				int fz = getflorzofslopeptr(pSector, actor->int_pos().X, actor->int_pos().Y);
 				if (fz < bottom)
 					vc += ((bottom - fz) * -80099) / (bottom - top);
 			}
@@ -4927,7 +4927,7 @@ void MoveDude(DBloodActor* actor)
 			sfxPlay3DSound(actor, 719, 0, 0);
 		}
 	}
-	vec3_t const oldpos = actor->spr.pos;
+	vec3_t const oldpos = actor->int_pos();
 	int nLink = CheckLink(actor);
 	if (nLink)
 	{
@@ -5096,7 +5096,7 @@ void MoveDude(DBloodActor* actor)
 		int floorZ2 = floorZ;
 		auto floorColl2 = floorColl;
 		GetZRange(actor, &ceilZ, &ceilColl, &floorZ, &floorColl, actor->spr.clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR);
-		if (bottom <= floorZ && actor->spr.pos.Z - floorZ2 < bz)
+		if (bottom <= floorZ && actor->int_pos().Z - floorZ2 < bz)
 		{
 			floorZ = floorZ2;
 			floorColl = floorColl2;
@@ -5135,16 +5135,16 @@ void MoveDude(DBloodActor* actor)
 			switch (tileGetSurfType(floorColl))
 			{
 			case kSurfWater:
-				gFX.fxSpawnActor(FX_9, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, floorZ, 0);
+				gFX.fxSpawnActor(FX_9, actor->sector(), actor->int_pos().X, actor->int_pos().Y, floorZ, 0);
 				break;
 			case kSurfLava:
 			{
-				auto pFX = gFX.fxSpawnActor(FX_10, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, floorZ, 0);
+				auto pFX = gFX.fxSpawnActor(FX_10, actor->sector(), actor->int_pos().X, actor->int_pos().Y, floorZ, 0);
 				if (pFX)
 				{
 					for (int i = 0; i < 7; i++)
 					{
-						auto pFX2 = gFX.fxSpawnActor(FX_14, pFX->sector(), pFX->spr.pos.X, pFX->spr.pos.Y, pFX->spr.pos.Z, 0);
+						auto pFX2 = gFX.fxSpawnActor(FX_14, pFX->sector(), pFX->int_pos().X, pFX->int_pos().Y, pFX->int_pos().Z, 0);
 						if (pFX2)
 						{
 							pFX2->vel.X = Random2(0x6aaaa);
@@ -5189,8 +5189,8 @@ void MoveDude(DBloodActor* actor)
 			auto hitAct = floorColl.actor();
 			if ((hitAct->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == CSTAT_SPRITE_ALIGNMENT_FACING)
 			{
-				actor->vel.X += MulScale(4, actor->spr.pos.X - hitAct->spr.pos.X, 2);
-				actor->vel.Y += MulScale(4, actor->spr.pos.Y - hitAct->spr.pos.Y, 2);
+				actor->vel.X += MulScale(4, actor->int_pos().X - hitAct->int_pos().X, 2);
+				actor->vel.Y += MulScale(4, actor->int_pos().Y - hitAct->int_pos().Y, 2);
 				return;
 			}
 		}
@@ -5237,16 +5237,16 @@ int MoveMissile(DBloodActor* actor)
 
 		if (target->spr.statnum == kStatDude && target->hasX() && target->xspr.health > 0)
 		{
-			int nTargetAngle = getangle(-(target->spr.pos.Y - actor->spr.pos.Y), target->spr.pos.X - actor->spr.pos.X);
+			int nTargetAngle = getangle(-(target->int_pos().Y - actor->int_pos().Y), target->int_pos().X - actor->int_pos().X);
 			int vx = missileInfo[actor->spr.type - kMissileBase].velocity;
 			int vy = 0;
 			RotatePoint(&vx, &vy, (nTargetAngle + 1536) & 2047, 0, 0);
 			actor->vel.X = vx;
 			actor->vel.Y = vy;
-			int dz = target->spr.pos.Z - actor->spr.pos.Z;
+			int dz = target->int_pos().Z - actor->int_pos().Z;
 
 			int deltaz = dz / 10;
-			if (target->spr.pos.Z < actor->spr.pos.Z) deltaz = -deltaz;
+			if (target->int_pos().Z < actor->int_pos().Z) deltaz = -deltaz;
 			actor->vel.Z += deltaz;
 		}
 	}
@@ -5260,7 +5260,7 @@ int MoveMissile(DBloodActor* actor)
 	const bool isFlameSprite = (actor->spr.type == kMissileFlameSpray || actor->spr.type == kMissileFlameHound); // do not use accurate clipmove for flame based sprites (changes damage too much)
 	while (1)
 	{
-		vec3_t pos = actor->spr.pos;
+		vec3_t pos = actor->int_pos();
 		auto pSector2 = actor->sector();
 		const auto bakSpriteCstat = actor->spr.cstat;
 		if (Owner && !isFlameSprite && !cl_bloodvanillaexplosions && !VanillaMode())
@@ -5343,7 +5343,7 @@ int MoveMissile(DBloodActor* actor)
 			vz += ClipLow(ceilZ - top, 0);
 			cliptype = 1;
 		}
-		actor->spr.pos = pos;
+		actor->int_pos() = pos;
 		actor->add_int_z(vz);
 		updatesector(pos.X, pos.Y, &pSector);
 		if (pSector != nullptr && pSector != actor->sector())
@@ -5353,9 +5353,9 @@ int MoveMissile(DBloodActor* actor)
 		}
 		CheckLink(actor);
 		gHitInfo.hitSector = actor->sector();
-		gHitInfo.hitpos.X = actor->spr.pos.X;
-		gHitInfo.hitpos.Y = actor->spr.pos.Y;
-		gHitInfo.hitpos.Z = actor->spr.pos.Z;
+		gHitInfo.hitpos.X = actor->int_pos().X;
+		gHitInfo.hitpos.Y = actor->int_pos().Y;
+		gHitInfo.hitpos.Z = actor->int_pos().Z;
 		break;
 	}
 	if (Owner) Owner->spr.cstat = bakCstat;
@@ -5436,7 +5436,7 @@ void actExplodeSprite(DBloodActor* actor)
 
 	case kThingTNTBarrel:
 	{
-		auto spawned = actSpawnSprite(actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0, 1);
+		auto spawned = actSpawnSprite(actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0, 1);
 		spawned->SetOwner(actor->GetOwner());
 		if (actCheckRespawn(actor))
 		{
@@ -5533,7 +5533,7 @@ void actActivateGibObject(DBloodActor* actor)
 	if (gib1 > 0) GibSprite(actor, (GIBTYPE)(gib1 - 1), nullptr, nullptr);
 	if (gib2 > 0) GibSprite(actor, (GIBTYPE)(gib2 - 1), nullptr, nullptr);
 	if (gib3 > 0 && actor->xspr.burnTime > 0) GibSprite(actor, (GIBTYPE)(gib3 - 1), nullptr, nullptr);
-	if (sound > 0) sfxPlay3DSound(actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, sound, actor->sector());
+	if (sound > 0) sfxPlay3DSound(actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, sound, actor->sector());
 	if (dropmsg > 0) actDropObject(actor, dropmsg);
 
 	if (!(actor->spr.cstat & CSTAT_SPRITE_INVISIBLE) && !(actor->spr.flags & kHitagRespawn))
@@ -5610,7 +5610,7 @@ static void actCheckProximity()
 							proxyDist = 512;
 						}
 
-						if (CheckProximity(dudeactor, actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, actor->sector(), proxyDist))
+						if (CheckProximity(dudeactor, actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, actor->sector(), proxyDist))
 						{
 							switch (actor->spr.type)
 							{
@@ -5676,7 +5676,7 @@ static void actCheckThings()
 			{
 				int top, bottom;
 				GetActorExtents(actor, &top, &bottom);
-				if (getflorzofslopeptr(pSector, actor->spr.pos.X, actor->spr.pos.Y) <= bottom)
+				if (getflorzofslopeptr(pSector, actor->int_pos().X, actor->int_pos().Y) <= bottom)
 				{
 					int angle = pXSector->panAngle;
 					int speed = 0;
@@ -5729,7 +5729,7 @@ static void actCheckThings()
 					case kThingPodGreenBall:
 						if (hit.type == kHitSector)
 						{
-							actRadiusDamage(actor->GetOwner(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, actor->sector(), 200, 1, 20, kDamageExplode, 6, 0);
+							actRadiusDamage(actor->GetOwner(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, actor->sector(), 200, 1, 20, kDamageExplode, 6, 0);
 							evPostActor(actor, 0, kCallbackFXPodBloodSplat);
 						}
 						else if (hit.type == kHitSprite)
@@ -5789,9 +5789,9 @@ static void actCheckExplosion()
 		int nType = actor->spr.type;
 		assert(nType >= 0 && nType < kExplodeMax);
 		const EXPLOSION* pExplodeInfo = &explodeInfo[nType];
-		int x = actor->spr.pos.X;
-		int y = actor->spr.pos.Y;
-		int z = actor->spr.pos.Z;
+		int x = actor->int_pos().X;
+		int y = actor->int_pos().Y;
+		int z = actor->int_pos().Z;
 		auto pSector = actor->sector();
 		int radius = pExplodeInfo->radius;
 
@@ -5865,7 +5865,7 @@ static void actCheckExplosion()
 
 		for (int p = connecthead; p >= 0; p = connectpoint2[p])
 		{
-			auto pos = gPlayer[p].actor->spr.pos;
+			auto pos = gPlayer[p].actor->int_pos();
 			int dx = (x - pos.X) >> 4;
 			int dy = (y - pos.Y) >> 4;
 			int dz = (z - pos.Z) >> 8;
@@ -5949,9 +5949,9 @@ static void actCheckTraps()
 		case kTrapFlame:
 			if (actor->xspr.state && seqGetStatus(actor) < 0)
 			{
-				int x = actor->spr.pos.X;
-				int y = actor->spr.pos.Y;
-				int z = actor->spr.pos.Z;
+				int x = actor->int_pos().X;
+				int y = actor->int_pos().Y;
+				int z = actor->int_pos().Z;
 				int t = (actor->xspr.data1 << 23) / 120;
 				int dx = MulScale(t, Cos(actor->spr.ang), 30);
 				int dy = MulScale(t, Sin(actor->spr.ang), 30);
@@ -6039,7 +6039,7 @@ static void actCheckDudes()
 
 					if (actor2->IsPlayerActor() && (unsigned int)actor2->xspr.health > 0)
 					{
-						if (CheckProximity(actor2, actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, actor->sector(), 128))
+						if (CheckProximity(actor2, actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, actor->sector(), 128))
 							trTriggerSprite(actor, kCmdSpriteProximity, actor2);
 					}
 				}
@@ -6100,7 +6100,7 @@ static void actCheckDudes()
 		{
 			int top, bottom;
 			GetActorExtents(actor, &top, &bottom);
-			if (getflorzofslopeptr(pSector, actor->spr.pos.X, actor->spr.pos.Y) <= bottom)
+			if (getflorzofslopeptr(pSector, actor->int_pos().X, actor->int_pos().Y) <= bottom)
 			{
 				int angle = pXSector->panAngle;
 				int speed = 0;
@@ -6150,9 +6150,9 @@ void actCheckFlares()
 		}
 		if (target->hasX() && target->xspr.health > 0)
 		{
-			int x = target->spr.pos.X + mulscale30r(Cos(actor->xspr.goalAng + target->spr.ang), target->spr.clipdist * 2);
-			int y = target->spr.pos.Y + mulscale30r(Sin(actor->xspr.goalAng + target->spr.ang), target->spr.clipdist * 2);
-			int z = target->spr.pos.Z + actor->xspr.TargetPos.Z;
+			int x = target->int_pos().X + mulscale30r(Cos(actor->xspr.goalAng + target->spr.ang), target->spr.clipdist * 2);
+			int y = target->int_pos().Y + mulscale30r(Sin(actor->xspr.goalAng + target->spr.ang), target->spr.clipdist * 2);
+			int z = target->int_pos().Z + actor->xspr.TargetPos.Z;
 			vec3_t pos = { x, y, z };
 			SetActor(actor, &pos);
 			actor->vel.X = target->vel.X;
@@ -6223,7 +6223,7 @@ DBloodActor* actSpawnSprite(DBloodActor* source, int nStat)
 {
 	DBloodActor* actor = InsertSprite(source->sector(), nStat);
 
-	actor->set_int_pos(source->spr.pos);
+	actor->set_int_pos(source->int_pos());
 	actor->vel = source->vel;
 	actor->spr.flags = 0;
 	actor->addX();
@@ -6246,16 +6246,16 @@ DBloodActor* actSpawnDude(DBloodActor* source, int nType, int a3, int a4)
 	int angle = source->spr.ang;
 	int nDude = nType - kDudeBase;
 	int x, y, z;
-	z = a4 + source->spr.pos.Z;
+	z = a4 + source->int_pos().Z;
 	if (a3 < 0)
 	{
-		x = source->spr.pos.X;
-		y = source->spr.pos.Y;
+		x = source->int_pos().X;
+		y = source->int_pos().Y;
 	}
 	else
 	{
-		x = source->spr.pos.X + mulscale30r(Cos(angle), a3);
-		y = source->spr.pos.Y + mulscale30r(Sin(angle), a3);
+		x = source->int_pos().X + mulscale30r(Cos(angle), a3);
+		y = source->int_pos().Y + mulscale30r(Sin(angle), a3);
 	}
 	spawned->spr.type = nType;
 	if (!VanillaMode())
@@ -6407,12 +6407,12 @@ DBloodActor* actSpawnThing(sectortype* pSector, int x, int y, int z, int nThingT
 DBloodActor* actFireThing(DBloodActor* actor, int a2, int a3, int a4, int thingType, int a6)
 {
 	assert(thingType >= kThingBase && thingType < kThingMax);
-	int x = actor->spr.pos.X + MulScale(a2, Cos(actor->spr.ang + 512), 30);
-	int y = actor->spr.pos.Y + MulScale(a2, Sin(actor->spr.ang + 512), 30);
-	int z = actor->spr.pos.Z + a3;
+	int x = actor->int_pos().X + MulScale(a2, Cos(actor->spr.ang + 512), 30);
+	int y = actor->int_pos().Y + MulScale(a2, Sin(actor->spr.ang + 512), 30);
+	int z = actor->int_pos().Z + a3;
 	x += MulScale(actor->spr.clipdist, Cos(actor->spr.ang), 28);
 	y += MulScale(actor->spr.clipdist, Sin(actor->spr.ang), 28);
-	if (HitScan(actor, z, x - actor->spr.pos.X, y - actor->spr.pos.Y, 0, CLIPMASK0, actor->spr.clipdist) != -1)
+	if (HitScan(actor, z, x - actor->int_pos().X, y - actor->int_pos().Y, 0, CLIPMASK0, actor->spr.clipdist) != -1)
 	{
 		x = gHitInfo.hitpos.X - MulScale(actor->spr.clipdist << 1, Cos(actor->spr.ang), 28);
 		y = gHitInfo.hitpos.Y - MulScale(actor->spr.clipdist << 1, Sin(actor->spr.ang), 28);
@@ -6519,13 +6519,13 @@ DBloodActor* actFireMissile(DBloodActor* actor, int a2, int a3, int a4, int a5,
 	assert(nType >= kMissileBase && nType < kMissileMax);
 	bool impact = false;
 	const MissileType* pMissileInfo = &missileInfo[nType - kMissileBase];
-	int x = actor->spr.pos.X + MulScale(a2, Cos(actor->spr.ang + 512), 30);
-	int y = actor->spr.pos.Y + MulScale(a2, Sin(actor->spr.ang + 512), 30);
-	int z = actor->spr.pos.Z + a3;
+	int x = actor->int_pos().X + MulScale(a2, Cos(actor->spr.ang + 512), 30);
+	int y = actor->int_pos().Y + MulScale(a2, Sin(actor->spr.ang + 512), 30);
+	int z = actor->int_pos().Z + a3;
 	int clipdist = pMissileInfo->clipDist + actor->spr.clipdist;
 	x += MulScale(clipdist, Cos(actor->spr.ang), 28);
 	y += MulScale(clipdist, Sin(actor->spr.ang), 28);
-	int hit = HitScan(actor, z, x - actor->spr.pos.X, y - actor->spr.pos.Y, 0, CLIPMASK0, clipdist);
+	int hit = HitScan(actor, z, x - actor->int_pos().X, y - actor->int_pos().Y, 0, CLIPMASK0, clipdist);
 	if (hit != -1)
 	{
 		if (hit == 3 || hit == 0)
@@ -6653,7 +6653,7 @@ bool actCheckRespawn(DBloodActor* actor)
 			if (!(actor->spr.type >= kDudeBase && actor->spr.type < kDudeMax))
 			{
 				actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
-				actor->spr.pos = actor->basePoint;
+				actor->int_pos() = actor->basePoint;
 			}
 			evPostActor(actor, nRespawnTime, kCallbackRespawn);
 		}
@@ -6706,7 +6706,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 			if (powerupCheck(pPlayer, kPwUpReflectShots))
 			{
 				gHitInfo.hitActor = shooter;
-				gHitInfo.hitpos = shooter->spr.pos;
+				gHitInfo.hitpos = shooter->int_pos();
 			}
 		}
 	}
@@ -6715,7 +6715,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 	int z = gHitInfo.hitpos.Z - MulScale(a6, 256, 14);
 	auto pSector = gHitInfo.hitSector;
 	uint8_t nSurf = kSurfNone;
-	if (nRange == 0 || approxDist(gHitInfo.hitpos.X - shooter->spr.pos.X, gHitInfo.hitpos.Y - shooter->spr.pos.Y) < nRange)
+	if (nRange == 0 || approxDist(gHitInfo.hitpos.X - shooter->int_pos().X, gHitInfo.hitpos.Y - shooter->int_pos().Y) < nRange)
 	{
 		switch (hit)
 		{
@@ -6835,7 +6835,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 					a6 += Random3(4000);
 					if (HitScan(actor, gHitInfo.hitpos.Z, a4, a5, a6, CLIPMASK1, tt) == 0)
 					{
-						if (approxDist(gHitInfo.hitpos.X - actor->spr.pos.X, gHitInfo.hitpos.Y - actor->spr.pos.Y) <= tt)
+						if (approxDist(gHitInfo.hitpos.X - actor->int_pos().X, gHitInfo.hitpos.Y - actor->int_pos().Y) <= tt)
 						{
 							auto pWall = gHitInfo.hitWall;
 							auto pSector1 = gHitInfo.hitSector;
@@ -6942,7 +6942,7 @@ void actFireVector(DBloodActor* shooter, int a2, int a3, int a4, int a5, int a6,
 
 void FireballSeqCallback(int, DBloodActor* actor)
 {
-	auto pFX = gFX.fxSpawnActor(FX_11, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0);
+	auto pFX = gFX.fxSpawnActor(FX_11, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0);
 	if (pFX)
 	{
 		pFX->vel.X = actor->vel.X;
@@ -6953,7 +6953,7 @@ void FireballSeqCallback(int, DBloodActor* actor)
 
 void NapalmSeqCallback(int, DBloodActor* actor)
 {
-	auto pFX = gFX.fxSpawnActor(FX_12, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0);
+	auto pFX = gFX.fxSpawnActor(FX_12, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0);
 	if (pFX)
 	{
 		pFX->vel.X = actor->vel.X;
@@ -6964,7 +6964,7 @@ void NapalmSeqCallback(int, DBloodActor* actor)
 
 void Fx32Callback(int, DBloodActor* actor)
 {
-	auto pFX = gFX.fxSpawnActor(FX_32, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0);
+	auto pFX = gFX.fxSpawnActor(FX_32, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0);
 	if (pFX)
 	{
 		pFX->vel.X = actor->vel.X;
@@ -6975,7 +6975,7 @@ void Fx32Callback(int, DBloodActor* actor)
 
 void Fx33Callback(int, DBloodActor* actor)
 {
-	auto pFX = gFX.fxSpawnActor(FX_33, actor->sector(), actor->spr.pos.X, actor->spr.pos.Y, actor->spr.pos.Z, 0);
+	auto pFX = gFX.fxSpawnActor(FX_33, actor->sector(), actor->int_pos().X, actor->int_pos().Y, actor->int_pos().Z, 0);
 	if (pFX)
 	{
 		pFX->vel.X = actor->vel.X;