diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h
index 88786bc112ae459eb8826fc14ab551d8f479ce98..83dff02f877e17db254f5e0e35bb47095bc7c18e 100644
--- a/src/hardware/hw_glob.h
+++ b/src/hardware/hw_glob.h
@@ -79,6 +79,7 @@ typedef struct gr_vissprite_s
 	boolean vflip;
    //Hurdler: 25/04/2000: now support colormap in hardware mode
 	UINT8 *colormap;
+	INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
 } gr_vissprite_t;
 
 // --------
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 820eb25fc6509a1087c1e083f7c35249367b84d8..0574a57197953f35018d325eab0d37cb00d94226 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3998,6 +3998,7 @@ static void HWR_SortVisSprites(void)
 	gr_vissprite_t *best = NULL;
 	gr_vissprite_t unsorted;
 	float bestdist;
+	INT32 bestdispoffset;
 
 	if (!gr_visspritecount)
 		return;
@@ -4025,11 +4026,19 @@ static void HWR_SortVisSprites(void)
 	for (i = 0; i < gr_visspritecount; i++)
 	{
 		bestdist = ZCLIP_PLANE-1;
+		bestdispoffset = INT32_MAX;
 		for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
 		{
 			if (ds->tz > bestdist)
 			{
 				bestdist = ds->tz;
+				bestdispoffset = ds->dispoffset;
+				best = ds;
+			}
+			// order visprites of same scale by dispoffset, smallest first
+			else if (ds->tz == bestdist && ds->dispoffset < bestdispoffset)
+			{
+				bestdispoffset = ds->dispoffset;
 				best = ds;
 			}
 		}
@@ -4653,6 +4662,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
 #endif
 	vis->x2 = tx;
 	vis->tz = tz;
+	vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
 	vis->patchlumpnum = sprframe->lumppat[rot];
 	vis->flip = flip;
 	vis->mobj = thing;
@@ -4769,6 +4779,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
 	vis->x1 = x1;
 	vis->x2 = tx;
 	vis->tz = tz;
+	vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
 	vis->patchlumpnum = sprframe->lumppat[rot];
 	vis->flip = flip;
 	vis->mobj = (mobj_t *)thing;
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 915c742e8f28a820696d1ffbccfac2d57818dbb1..9bf2049c6b8b6542f9ceb66f895943ec2215d33f 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -5924,8 +5924,6 @@ static void P_NightsItemChase(mobj_t *thing)
 
 static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
 {
-	fixed_t destx, desty;
-
 	if (!thing->target || thing->target->health <= 0 || !thing->target->player
 		|| (thing->target->player->powers[pw_shield] & SH_NOSTACK) == SH_NONE || thing->target->player->powers[pw_super]
 		|| thing->target->player->powers[pw_invulnerability] > 1)
@@ -5950,26 +5948,6 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
 		return false;
 	}
 
-	if (!splitscreen && rendermode != render_soft)
-	{
-		angle_t viewingangle;
-
-		if (players[displayplayer].awayviewtics)
-			viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
-		else if (!camera.chase && players[displayplayer].mo)
-			viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
-		else
-			viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, camera.x, camera.y);
-
-		destx = thing->target->x + P_ReturnThrustX(thing->target, viewingangle, FixedMul(FRACUNIT, thing->scale));
-		desty = thing->target->y + P_ReturnThrustY(thing->target, viewingangle, FixedMul(FRACUNIT, thing->scale));
-	}
-	else
-	{
-		destx = thing->target->x;
-		desty = thing->target->y;
-	}
-
 	if (shield == SH_FORCE && thing->movecount != (thing->target->player->powers[pw_shield] & 0xFF))
 	{
 		thing->movecount = (thing->target->player->powers[pw_shield] & 0xFF);
@@ -5994,8 +5972,8 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
 
 	P_SetScale(thing, thing->target->scale);
 	P_UnsetThingPosition(thing);
-	thing->x = destx;
-	thing->y = desty;
+	thing->x = thing->target->x;
+	thing->y = thing->target->y;
 	if (thing->eflags & MFE_VERTICALFLIP)
 		thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale);
 	else
diff --git a/src/p_user.c b/src/p_user.c
index 8854d8d645af1cb3f70af0d22294029a9436853f..51318f67451e991a1645aa860e4bdf6a327f8766 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -2115,30 +2115,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
 		player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
 	else if (leveltime % (TICRATE/7) == 0)
 	{
-		fixed_t destx, desty;
-		mobj_t *sparkle;
-
-		if (!splitscreen && rendermode != render_soft)
-		{
-			angle_t viewingangle;
-
-			if (players[displayplayer].awayviewtics)
-				viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
-			else if (!camera.chase && players[displayplayer].mo)
-				viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
-			else
-				viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, camera.x, camera.y);
-
-			destx = player->mo->x + P_ReturnThrustX(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale));
-			desty = player->mo->y + P_ReturnThrustY(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale));
-		}
-		else
-		{
-			destx = player->mo->x;
-			desty = player->mo->y;
-		}
-
-		sparkle = P_SpawnMobj(destx, desty, player->mo->z, MT_IVSP);
+		mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
 		sparkle->destscale = player->mo->scale;
 		P_SetScale(sparkle, player->mo->scale);
 	}
diff --git a/src/r_things.c b/src/r_things.c
index 60fbad1af0d7f4a1a18b288d444a03fe0ded3a29..dff0317fb00b452b83fdd45d7f6a517b34a40870 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1266,7 +1266,8 @@ static void R_ProjectSprite(mobj_t *thing)
 	vis = R_NewVisSprite();
 	vis->heightsec = heightsec; //SoM: 3/17/2000
 	vis->mobjflags = thing->flags;
-	vis->scale = yscale + thing->info->dispoffset;           //<<detailshift;
+	vis->scale = yscale; //<<detailshift;
+	vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15
 	vis->gx = thing->x;
 	vis->gy = thing->y;
 	vis->gz = gz;
@@ -1482,6 +1483,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
 	// store information in a vissprite
 	vis = R_NewVisSprite();
 	vis->scale = yscale; //<<detailshift;
+	vis->dispoffset = 0; // Monster Iestyn: 23/11/15
 	vis->gx = thing->x;
 	vis->gy = thing->y;
 	vis->gz = gz;
@@ -1633,6 +1635,7 @@ void R_SortVisSprites(void)
 	vissprite_t *best = NULL;
 	vissprite_t  unsorted;
 	fixed_t      bestscale;
+	INT32        bestdispoffset;
 
 	if (!visspritecount)
 		return;
@@ -1663,12 +1666,19 @@ void R_SortVisSprites(void)
 	vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
 	for (i = 0; i < visspritecount; i++)
 	{
-		bestscale = INT32_MAX;
+		bestscale = bestdispoffset = INT32_MAX;
 		for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
 		{
 			if (ds->scale < bestscale)
 			{
 				bestscale = ds->scale;
+				bestdispoffset = ds->dispoffset;
+				best = ds;
+			}
+			// order visprites of same scale by dispoffset, smallest first
+			else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset)
+			{
+				bestdispoffset = ds->dispoffset;
 				best = ds;
 			}
 		}
@@ -1920,7 +1930,8 @@ static void R_CreateDrawNodes(void)
 				if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt)
 					continue;
 
-				if (r2->sprite->scale > rover->scale)
+				if (r2->sprite->scale > rover->scale
+				 || (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset))
 				{
 					entry = R_CreateDrawNode(NULL);
 					(entry->prev = r2->prev)->next = entry;
diff --git a/src/r_things.h b/src/r_things.h
index 054a6497d04340260d86ed5f04c58d0c5756d34f..3e2d13fd7604218943666a1b834a3b1bd0359602 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -162,6 +162,7 @@ typedef struct vissprite_s
 	boolean precip;
 	boolean vflip; // Flip vertically
 	boolean isScaled;
+	INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
 } vissprite_t;
 
 // A drawnode is something that points to a 3D floor, 3D side, or masked