diff --git a/source/games/sw/src/actor.cpp b/source/games/sw/src/actor.cpp
index 2c4287390..586bcf9ed 100644
--- a/source/games/sw/src/actor.cpp
+++ b/source/games/sw/src/actor.cpp
@@ -555,7 +555,7 @@ KeepActorOnFloor(short SpriteNum)
                 // was swimming but have now stopped
                 RESET(u->Flags, SPR_SWIMMING);
                 RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
-                sp->z = u->loz;
+                u->oz = sp->z = u->loz;
                 sp->backupz();
                 return;
             }
@@ -566,7 +566,7 @@ KeepActorOnFloor(short SpriteNum)
             }
 
             // are swimming
-            sp->z = u->loz - Z(depth);
+            u->oz = sp->z = u->loz - Z(depth);
             sp->backupz();
         }
         else
@@ -575,7 +575,7 @@ KeepActorOnFloor(short SpriteNum)
             if (u->Rot == u->ActorActionSet->Run || u->Rot == u->ActorActionSet->Swim)
             {
                 NewStateGroup(SpriteNum, u->ActorActionSet->Swim);
-                sp->z = u->loz - Z(depth);
+                u->oz = sp->z = u->loz - Z(depth);
                 sp->backupz();
                 SET(u->Flags, SPR_SWIMMING);
                 SET(sp->cstat, CSTAT_SPRITE_YCENTER);
@@ -584,7 +584,7 @@ KeepActorOnFloor(short SpriteNum)
             {
                 RESET(u->Flags, SPR_SWIMMING);
                 RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
-                sp->z = u->loz;
+                u->oz = sp->z = u->loz;
                 sp->backupz();
             }
         }
@@ -599,7 +599,7 @@ KeepActorOnFloor(short SpriteNum)
 #if 1
     if (TEST(u->Flags, SPR_MOVED))
     {
-        sp->z = u->loz;
+        u->oz = sp->z = u->loz;
         sp->backupz();
     }
     else
@@ -608,7 +608,7 @@ KeepActorOnFloor(short SpriteNum)
         FAFgetzrangepoint(sp->x, sp->y, sp->z, sp->sectnum,
                           &ceilz, &ceilhit, &florz, &florhit);
 
-        sp->z = florz;
+        u->oz = sp->z = florz;
         sp->backupz();
     }
 #endif
diff --git a/source/games/sw/src/game.h b/source/games/sw/src/game.h
index 125f6f3ad..0b1a5f583 100644
--- a/source/games/sw/src/game.h
+++ b/source/games/sw/src/game.h
@@ -1143,6 +1143,7 @@ typedef struct
     int Flags;
     int Flags2;
     int Tics;
+    int oz; // serialized copy of sprite.oz
 
     short RotNum;
     short ID;
diff --git a/source/games/sw/src/player.cpp b/source/games/sw/src/player.cpp
index 6cce61c08..78b614554 100644
--- a/source/games/sw/src/player.cpp
+++ b/source/games/sw/src/player.cpp
@@ -6865,6 +6865,7 @@ MoveSkipSavePos(void)
                     continue;
 
                 sp->backuppos();
+                u->oz = sp->oz;
             }
         }
     }
@@ -6887,6 +6888,7 @@ MoveSkipSavePos(void)
                 if (sp == NULL || u == NULL)
                     continue;
                 sp->backuppos();
+                u->oz = sp->oz;
             }
         }
     }
diff --git a/source/games/sw/src/spike.cpp b/source/games/sw/src/spike.cpp
index 4dd62030f..e14235fa9 100644
--- a/source/games/sw/src/spike.cpp
+++ b/source/games/sw/src/spike.cpp
@@ -55,18 +55,18 @@ void ReverseSpike(short SpriteNum)
     }
 
     // moving toward to OFF pos
-    if (u->z_tgt == sp->oz)
+    if (u->z_tgt == u->oz)
     {
-        if (sp->z == sp->oz)
+        if (sp->z == u->oz)
             u->z_tgt = u->sz;
-        else if (u->sz == sp->oz)
+        else if (u->sz == u->oz)
             u->z_tgt = sp->z;
     }
     else if (u->z_tgt == u->sz)
     {
-        if (sp->z == sp->oz)
+        if (sp->z == u->oz)
             u->z_tgt = sp->z;
-        else if (u->sz == sp->oz)
+        else if (u->sz == u->oz)
             u->z_tgt = u->sz;
     }
 
@@ -389,7 +389,7 @@ int DoSpike(short SpriteNum)
         }
 
         // setup to go back to the original z
-        if (*lptr != sp->oz)
+        if (*lptr != u->oz)
         {
             if (u->WaitTics)
                 u->Tics = u->WaitTics;
@@ -398,7 +398,7 @@ int DoSpike(short SpriteNum)
     else // if (*lptr == u->z_tgt)
     {
         // if heading for the OFF (original) position and should NOT CRUSH
-        if (TEST_BOOL3(sp) && u->z_tgt == sp->oz)
+        if (TEST_BOOL3(sp) && u->z_tgt == u->oz)
         {
             int i;
             SPRITEp bsp;
diff --git a/source/games/sw/src/sprite.cpp b/source/games/sw/src/sprite.cpp
index 92f54233a..4a6002369 100644
--- a/source/games/sw/src/sprite.cpp
+++ b/source/games/sw/src/sprite.cpp
@@ -916,6 +916,7 @@ SpawnUser(short SpriteNum, short id, STATEp state)
     u->motion_blur_dist = 256;
 
     sp->backuppos();
+    u->oz = sp->oz;
 
     u->active_range = MIN_ACTIVE_RANGE;
 
@@ -2345,7 +2346,7 @@ SpriteSetup(void)
                         }
 
                         // set orig z
-                        sp->oz = sectp->floorz;
+                        u->oz = sp->oz = sectp->floorz;
                     }
                     else
                     {
@@ -2366,7 +2367,7 @@ SpriteSetup(void)
                         }
 
                         // set orig z
-                        sp->oz = sectp->ceilingz;
+                        u->oz = sp->oz = sectp->ceilingz;
                     }
 
 
@@ -2557,7 +2558,7 @@ SpriteSetup(void)
                         }
 
                         // set orig z
-                        sp->oz = u->zclip;
+                        u->oz = sp->oz = u->zclip;
                     }
                     else
                     {
@@ -2575,7 +2576,7 @@ SpriteSetup(void)
                         }
 
                         // set orig z
-                        sp->oz = u->zclip;
+                        u->oz = sp->oz = u->zclip;
                     }
 
                     change_sprite_stat(SpriteNum, STAT_SPIKE);
@@ -7120,6 +7121,7 @@ void MissileWarpUpdatePos(short SpriteNum, short sectnum)
     USERp u = User[SpriteNum];
     SPRITEp sp = u->SpriteP;
     sp->backuppos();
+    u->oz = sp->oz;
     changespritesect(SpriteNum, sectnum);
     MissileZrange(SpriteNum);
 }
@@ -7129,6 +7131,7 @@ void ActorWarpUpdatePos(short SpriteNum, short sectnum)
     USERp u = User[SpriteNum];
     SPRITEp sp = u->SpriteP;
     sp->backuppos();
+    u->oz = sp->oz;
     changespritesect(SpriteNum, sectnum);
     DoActorZrange(SpriteNum);
 }
diff --git a/source/games/sw/src/track.cpp b/source/games/sw/src/track.cpp
index 1e1d94014..8f911fdb8 100644
--- a/source/games/sw/src/track.cpp
+++ b/source/games/sw/src/track.cpp
@@ -912,6 +912,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop)
                 u->RotNum = 0;
 
                 sp->backuppos();
+                u->oz = sp->oz;
 
                 switch (sp->statnum)
                 {
diff --git a/source/games/sw/src/vator.cpp b/source/games/sw/src/vator.cpp
index dde9a2f56..a03da8124 100644
--- a/source/games/sw/src/vator.cpp
+++ b/source/games/sw/src/vator.cpp
@@ -59,18 +59,18 @@ void ReverseVator(short SpriteNum)
     }
 
     // moving toward to OFF pos
-    if (u->z_tgt == sp->oz)
+    if (u->z_tgt == u->oz)
     {
-        if (sp->z == sp->oz)
+        if (sp->z == u->oz)
             u->z_tgt = u->sz;
-        else if (u->sz == sp->oz)
+        else if (u->sz == u->oz)
             u->z_tgt = sp->z;
     }
     else if (u->z_tgt == u->sz)
     {
-        if (sp->z == sp->oz)
+        if (sp->z == u->oz)
             u->z_tgt = sp->z;
-        else if (u->sz == sp->oz)
+        else if (u->sz == u->oz)
             u->z_tgt = u->sz;
     }
 
@@ -530,7 +530,7 @@ int DoVator(short SpriteNum)
         }
 
         // setup to go back to the original z
-        if (*lptr != sp->oz)
+        if (*lptr != u->oz)
         {
             if (u->WaitTics)
                 u->Tics = u->WaitTics;
@@ -539,7 +539,7 @@ int DoVator(short SpriteNum)
     else // if (*lptr == u->z_tgt)
     {
         // if heading for the OFF (original) position and should NOT CRUSH
-        if (TEST_BOOL3(sp) && u->z_tgt == sp->oz)
+        if (TEST_BOOL3(sp) && u->z_tgt == u->oz)
         {
             int i;
             SPRITEp bsp;
diff --git a/source/games/sw/src/weapon.cpp b/source/games/sw/src/weapon.cpp
index a273d441a..ff6176255 100644
--- a/source/games/sw/src/weapon.cpp
+++ b/source/games/sw/src/weapon.cpp
@@ -10158,6 +10158,7 @@ DoRocket(int16_t Weapon)
     SPRITEp sp = &sprite[Weapon];
     USERp u = User[Weapon];
     int dist,a,b,c;
+    auto pos = sp->pos;
 
 
     if ((u->FlagOwner -= ACTORMOVETICS)<=0 && u->spal == 20)
@@ -10211,7 +10212,7 @@ DoRocket(int16_t Weapon)
         short New;
 
         New = SpawnSprite(STAT_MISSILE, PUFF, s_Puff, sp->sectnum,
-                          sp->ox, sp->oy, sp->oz, sp->ang, 100);
+                          pos.x, pos.y, pos.z, sp->ang, 100);
 
         np = &sprite[New];
         nu = User[New];
@@ -11433,10 +11434,6 @@ SpawnBigGunFlames(int16_t Weapon, int16_t Operator, SECTOR_OBJECTp sop)
     sop->sp_num[sn] = explosion;
     so_setspriteinterpolation(sop, exp);
 
-    // Place sprite exactly where shoot point is
-    //exp->x = eu->ox = sop->xmid - u->sx;
-    //exp->y = eu->oy = sop->ymid - u->sy;
-
     SET(eu->Flags, TEST(u->Flags, SPR_ON_SO_SECTOR|SPR_SO_ATTACHED));
 
     if (TEST(u->Flags, SPR_ON_SO_SECTOR))