diff --git a/src/info.c b/src/info.c
index abb191abf154aa0e6b73c8eac7e39477e441b4d9..df9237d89834955c3075329df5da5c3163bea92e 100644
--- a/src/info.c
+++ b/src/info.c
@@ -682,6 +682,7 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
 	0, // SPR2_XTRA (should never be referenced)
 };
 
+// Doesn't work with VC
 #define STATE(sprite, frame, duration, action, var1, var2, nextstate) \
 	{ sprite, frame, duration, action, { ACTION_INTEGER_VAL(var1), ACTION_INTEGER_VAL(var2) }, nextstate }
 
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index 24fd36974711d54064935a652a8583ede9958e33..34387e5353675c4fca07cb96f0f5725fda1b7a8b 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -33,8 +33,6 @@
 
 extern CV_PossibleValue_t Color_cons_t[];
 
-boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
-
 state_t *astate;
 
 boolean LUA_ValueIsValidActionVal(lua_State *L, int i)
diff --git a/src/lua_script.h b/src/lua_script.h
index 406a3a1ec6e501794165e5975d73f1775cbda222..6738cc2e21d3136b33028e37150a6aa67feb452e 100644
--- a/src/lua_script.h
+++ b/src/lua_script.h
@@ -49,7 +49,7 @@ int LUA_Call(lua_State *L, int nargs, int nresults, int errorhandlerindex);
 boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor, action_val_t *args, unsigned argcount);
 boolean LUA_ValueIsValidActionVal(lua_State *L, int i);
 void LUA_ValueToActionVal(lua_State *L, int i, action_val_t *val);
-void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults);
+boolean LUA_LoadLump(UINT16 wad, UINT16 lump);
 void LUA_DoLump(UINT16 wad, UINT16 lump, boolean noresults);
 #ifdef LUA_ALLOW_BYTECODE
 void LUA_DumpFile(const char *filename);
diff --git a/src/p_action.c b/src/p_action.c
index 008e6559be2001f11f71df3a9e6cefc794749627..b84e5c0feafb65f0d133ff2ad6a4812ddf2e2513 100644
--- a/src/p_action.c
+++ b/src/p_action.c
@@ -2909,7 +2909,7 @@ void A_1upThinker(mobj_t *actor, action_val_t *args, unsigned argcount)
 		}
 	}
 
-	if (closestplayer == -1 || skins[players[closestplayer].skin].sprites[SPR2_LIFE].numframes == 0)
+	if (closestplayer == -1 || skins[players[closestplayer].skin]->sprites[SPR2_LIFE].numframes == 0)
 	{ // Closest player not found (no players in game?? may be empty dedicated server!), or does not have correct sprite.
 		if (actor->tracer)
 		{
@@ -3285,7 +3285,7 @@ static void P_DoBossVictory(mobj_t *mo)
 		{
 			if (!playeringame[i])
 				continue;
-			P_DoPlayerExit(&players[i]);
+			P_DoPlayerExit(&players[i], false );
 		}
 	}
 	else
@@ -8534,6 +8534,26 @@ void A_Dye(mobj_t *actor, action_val_t *args, unsigned argcount)
 	}
 }
 
+// Function: A_SetTranslation
+//
+// Description: Changes the translation of an actor.
+//
+// var1 = translation ID
+// var2 = unused
+//
+void A_SetTranslation(mobj_t *actor, action_val_t *args, unsigned argcount)
+{
+	INT32 locvar1 = GET_ARG(GetInteger, 0);
+
+	if (LUA_CallAction(A_SETTRANSLATION, actor, args, argcount))
+		return;
+
+	if (R_TranslationIsValid(locvar1))
+		actor->translation = (UINT32)locvar1;
+	else
+		actor->translation = 0;
+}
+
 // Function: A_MoveRelative
 //
 // Description: Moves an object (wrapper for P_Thrust)
@@ -10297,7 +10317,7 @@ void A_ForceWin(mobj_t *actor, action_val_t *args, unsigned argcount)
 	{
 		if (!playeringame[i])
 			continue;
-		P_DoPlayerExit(&players[i]);
+		P_DoPlayerExit(&players[i], false);
 	}
 }
 
diff --git a/src/p_action.h b/src/p_action.h
index 49c5e298f6ed111404af5d60ba5e78ffe3dce6c7..ad4e44a6e0106adc9ca463a77d18de1450e993a1 100644
--- a/src/p_action.h
+++ b/src/p_action.h
@@ -175,6 +175,7 @@ void A_SetRandomTics(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_ChangeColorRelative(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_ChangeColorAbsolute(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_Dye(mobj_t *actor, action_val_t *args, unsigned argcount);
+void A_SetTranslation(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_MoveRelative(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_MoveAbsolute(mobj_t *actor, action_val_t *args, unsigned argcount);
 void A_Thrust(mobj_t *actor, action_val_t *args, unsigned argcount);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index cdcedacbaaad5a0a5271d268e47dcb9fffe9f4e7..d3a6f334ca84709f2aed370b2c578a059068e7d2 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -6917,32 +6917,6 @@ void P_RunOverlays(void)
 			continue;
 		}
 
-		if (!splitscreen /*&& rendermode != render_soft*/)
-		{
-			angle_t viewingangle;
-
-			if (players[displayplayer].awayviewtics && players[displayplayer].awayviewmobj != NULL && !P_MobjWasRemoved(players[displayplayer].awayviewmobj))
-				viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
-			else if (!camera.chase && players[displayplayer].mo)
-				viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
-			else
-				viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
-
-			if (!(mo->state->frame & FF_ANIMATE))
-			{
-				INT32 var1 = Action_ValueToInteger(mo->state->vars[0]);
-				if (var1)
-					viewingangle += ANGLE_180;
-			}
-			destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
-			desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
-		}
-		else
-		{
-			destx = mo->target->x;
-			desty = mo->target->y;
-		}
-
 		mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
 		mo->scale = mo->destscale = mo->target->scale;
 		mo->old_scale = mo->target->old_scale;
@@ -6965,21 +6939,22 @@ void P_RunOverlays(void)
 		mo->height = mo->target->height;
 		if (mo->eflags & MFE_VERTICALFLIP)
 		{
-			mo->z         = (mo->target->z     + mo->target->height - mo->height) - zoffs;
+			mo->z         = mo->target->z     + mo->target->height - mo->height - zoffs;
 			if (mo->scale == mo->old_scale)
 				mo->old_z = mo->target->old_z + mo->target->height - mo->height - zoffs;
 			else // Interpolate height scale changes - mo and mo->target have the same scales here, so don't interpolate them individually
 				mo->old_z = mo->target->old_z + FixedMul(mo->target->height - mo->height, FixedDiv(mo->old_scale, mo->scale)) - zoffs;
 		}
 		else
-			mo->z = mo->target->z + zoffs;
-		if (Action_ValueToInteger(mo->state->vars[0]))
 		{
 			mo->z     = mo->target->z     + zoffs;
 			mo->old_z = mo->target->old_z + zoffs;
 		}
-		if (!(mo->state->frame & FF_ANIMATE) && Action_ValueToInteger(mo->state->vars[0]))
-			P_SetUnderlayPosition(mo);
+		if (!(mo->state->frame & FF_ANIMATE))
+		{
+			if (Action_ValueToInteger(mo->state->vars[0]))
+				P_SetUnderlayPosition(mo);
+		}
 		else
 			P_SetThingPosition(mo);
 		P_CheckPosition(mo, mo->x, mo->y);
diff --git a/src/r_things.c b/src/r_things.c
index d6ef72b9d29980134757df4547ffd03837379957..fab0f2d0ee1fea30d1e72ba63f63ab92eb31b957 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -3518,7 +3518,7 @@ void R_ThingOffsetOverlay(mobj_t *thing, fixed_t *x, fixed_t *y)
 	do // Get the overlay's offset
 	{
 		// Does the overlay use FF_ANIMATE? If not, if var1 is non-zero, it's an underlay instead of an overlay
-		if (!(mobj->state->frame & FF_ANIMATE) && mobj->state->var1)
+		if (!(mobj->state->frame & FF_ANIMATE) && Action_ValueToInteger(mobj->state->vars[0]))
 			offset += 1; // Underlay below the target, away from the camera
 		else
 			offset -= 1; // Overlay on top of the target, towards the camera