diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 847c22169d5274722c9442209ef0aceb972e73d8..2db27a693cda8f4f4041265cc2c605e1afa0cf77 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -552,7 +552,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
 	rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
 
 	rsp->speed = (fixed_t)LONG(players[i].speed);
-	rsp->jumping = players[i].jumping;
 	rsp->secondjump = players[i].secondjump;
 	rsp->fly1 = players[i].fly1;
 	rsp->glidetime = (tic_t)LONG(players[i].glidetime);
@@ -682,7 +681,6 @@ static void resynch_read_player(resynch_pak *rsp)
 	players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
 
 	players[i].speed = (fixed_t)LONG(rsp->speed);
-	players[i].jumping = rsp->jumping;
 	players[i].secondjump = rsp->secondjump;
 	players[i].fly1 = rsp->fly1;
 	players[i].glidetime = (tic_t)LONG(rsp->glidetime);
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index c2ec1ad58d33538cc52057fd839309d9645cbd32..1ca82fdc517026f314fdd8c16b568e06666e406f 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -196,7 +196,6 @@ typedef struct
 	fixed_t playerspinheight;
 
 	fixed_t speed;
-	UINT8 jumping;
 	UINT8 secondjump;
 	UINT8 fly1;
 	tic_t glidetime;
diff --git a/src/d_player.h b/src/d_player.h
index 8db170089a7ba8226116184a36c03ed057373712..9f8bcd8b419dd0df4e33eb59ec2db6fd6693a565 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -45,6 +45,7 @@ typedef enum
 	SF_MARIODAMAGE      = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
 	SF_MACHINE          = 1<<10, // Beep boop. Are you a robot?
 	SF_DASHMODE         = 1<<11, // Sonic Advance 2 style top speed increase?
+	SF_FASTEDGE         = 1<<12, // Faster edge teeter?
 	// free up to and including 1<<31
 } skinflags_t;
 
@@ -119,9 +120,8 @@ typedef enum
 	// Did you get a time-over?
 	PF_TIMEOVER = 1<<10,
 
-	PF_TEMPSLOT1 = 1<<11,
-
 	// Character action status
+	PF_STARTJUMP = 1<<11,
 	PF_JUMPED    = 1<<12,
 	PF_SPINNING  = 1<<13,
 	PF_STARTDASH = 1<<14,
@@ -133,7 +133,8 @@ typedef enum
 	// Sliding (usually in water) like Labyrinth/Oil Ocean
 	PF_SLIDING   = 1<<17,
 
-	PF_TEMPSLOT2         = 1<<18,
+	// Bouncing
+	PF_BOUNCING  = 1<<18,
 
 	/*** NIGHTS STUFF ***/
 	PF_TRANSFERTOCLOSEST = 1<<19,
@@ -158,10 +159,7 @@ typedef enum
 	// Jump damage?
 	PF_NOJUMPDAMAGE   = 1<<29,
 
-	// Bouncing
-	PF_BOUNCING          = 1<<30
-
-	// 1<<31 is free
+	// up to 1<<31 is free
 } pflags_t;
 
 typedef enum
@@ -381,7 +379,6 @@ typedef struct player_s
 	UINT8 gotcontinue; // Got continue from this stage?
 
 	fixed_t speed; // Player's speed (distance formula of MOMX and MOMY values)
-	UINT8 jumping; // Holding down jump button
 	UINT8 secondjump; // Jump counter
 
 	UINT8 fly1; // Tails flying
diff --git a/src/dehacked.c b/src/dehacked.c
index 590061ea1f775ab99b7e6861efda5af22677d424..2661fc2fd8cb031e0d910f2811e68b51af6b3030 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -5910,14 +5910,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_FOUR2",
 	"S_FIVE2",
 
+	"S_LOCKON",
+
 	// Tag Sign
-	"S_TTAG1",
+	"S_TTAG",
 
 	// Got Flag Sign
-	"S_GOTFLAG1",
-	"S_GOTFLAG2",
-	"S_GOTFLAG3",
-	"S_GOTFLAG4",
+	"S_GOTREDFLAG1",
+	"S_GOTREDFLAG2",
+	"S_GOTBLUEFLAG1",
+	"S_GOTBLUEFLAG2",
+
+	"S_CORK",
 
 	// Red Ring
 	"S_RRNG1",
@@ -6708,9 +6712,10 @@ static const char *const MOBJTYPE_LIST[] = {  // array length left dynamic for s
 	"MT_SCORE", // score logo
 	"MT_DROWNNUMBERS", // Drowning Timer
 	"MT_GOTEMERALD", // Chaos Emerald (intangible)
+	"MT_LOCKON", // Target
 	"MT_TAG", // Tag Sign
-	"MT_GOTFLAG", // Got Flag sign
-	"MT_GOTFLAG2", // Got Flag sign
+	"MT_GOTREDFLAG", // Got Flag sign
+	"MT_GOTBLUEFLAG", // Got Flag sign
 
 	// Ambient Sounds
 	"MT_AWATERA", // Ambient Water Sound 1
@@ -6724,6 +6729,8 @@ static const char *const MOBJTYPE_LIST[] = {  // array length left dynamic for s
 	"MT_RANDOMAMBIENT",
 	"MT_RANDOMAMBIENT2",
 
+	"MT_CORK",
+
 	// Ring Weapons
 	"MT_REDRING",
 	"MT_BOUNCERING",
@@ -6947,9 +6954,8 @@ static const char *const PLAYERFLAG_LIST[] = {
 	// Did you get a time-over?
 	"TIMEOVER",
 
-	"TEMPSLOT1",
-
 	// Character action status
+	"STARTJUMP",
 	"JUMPED",
 	"SPINNING",
 	"STARTDASH",
@@ -6961,7 +6967,8 @@ static const char *const PLAYERFLAG_LIST[] = {
 	// Sliding (usually in water) like Labyrinth/Oil Ocean
 	"SLIDING",
 
-	"TEMPSLOT2",
+	// Bouncing
+	"BOUNCING",
 
 	/*** NIGHTS STUFF ***/
 	"TRANSFERTOCLOSEST",
@@ -6979,7 +6986,6 @@ static const char *const PLAYERFLAG_LIST[] = {
 	"CANCARRY", // Can carry?
 	"SHIELDABILITY", // Thokked with shield ability
 	"NOJUMPDAMAGE", // No jump damage
-	"BOUNCING",
 
 	NULL // stop loop here.
 };
@@ -7381,6 +7387,7 @@ struct {
 	{"SF_MARIODAMAGE",SF_MARIODAMAGE},
 	{"SF_MACHINE",SF_MACHINE},
 	{"SF_DASHMODE",SF_DASHMODE},
+	{"SF_FASTEDGE",SF_FASTEDGE},
 
 	// Character abilities!
 	// Primary
diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c
index cdd778caa372c2f90ed96e86fe52ab063243a040..a49a788e66c59713c6a14038fb36a7e2b2ef3528 100644
--- a/src/hardware/hw_light.c
+++ b/src/hardware/hw_light.c
@@ -404,7 +404,7 @@ light_t *t_lspr[NUMSPRITES] =
 	&lspr[NOLIGHT],     // SPR_SPLA
 	&lspr[NOLIGHT],     // SPR_SMOK
 	&lspr[NOLIGHT],     // SPR_BUBL
-	&lspr[SUPERSPARK_L], // SPR_WZAP
+	&lspr[RINGLIGHT_L], // SPR_WZAP
 	&lspr[SUPERSPARK_L], // SPR_TFOG
 	&lspr[NIGHTSLIGHT_L],     // SPR_SEED // Sonic CD flower seed
 	&lspr[NOLIGHT],     // SPR_PRTL
@@ -412,9 +412,12 @@ light_t *t_lspr[NUMSPRITES] =
 	// Game Indicators
 	&lspr[NOLIGHT],     // SPR_SCOR
 	&lspr[NOLIGHT],     // SPR_DRWN
+	&lspr[NOLIGHT],     // SPR_LCKN
 	&lspr[NOLIGHT],     // SPR_TTAG
 	&lspr[NOLIGHT],     // SPR_GFLG
 
+	&lspr[NOLIGHT],     // SPR_CORK
+
 	// Ring Weapons
 	&lspr[RINGLIGHT_L],     // SPR_RRNG
 	&lspr[RINGLIGHT_L],     // SPR_RNGB
diff --git a/src/info.c b/src/info.c
index e6adb69c35e4d5fb2e658adcae4ea1054f0653e4..491e7cdb0d5c5ba7921ff4b164f250949f1cb28b 100644
--- a/src/info.c
+++ b/src/info.c
@@ -301,9 +301,12 @@ char sprnames[NUMSPRITES + 1][5] =
 	// Game Indicators
 	"SCOR", // Score logo
 	"DRWN", // Drowning Timer
+	"LCKN", // Target
 	"TTAG", // Tag Sign
 	"GFLG", // Got Flag sign
 
+	"CORK",
+
 	// Ring Weapons
 	"RRNG", // Red Ring
 	"RNGB", // Bounce Ring
@@ -507,7 +510,7 @@ state_t states[NUMSTATES] =
 	{SPR_PLAY, SPR2_JUMP,                 1, {NULL}, 0,  0, S_PLAY_JUMP}, // S_PLAY_JUMP
 	{SPR_PLAY, SPR2_SPNG,                 2, {NULL}, 0,  0, S_PLAY_SPRING}, // S_PLAY_SPRING
 	{SPR_PLAY, SPR2_FALL,                 2, {NULL}, 0,  0, S_PLAY_FALL}, // S_PLAY_FALL
-	{SPR_PLAY, SPR2_EDGE|FF_ANIMATE,     -1, {NULL}, 0, 12, S_NULL},      // S_PLAY_EDGE
+	{SPR_PLAY, SPR2_EDGE,                12, {NULL}, 0,  0, S_PLAY_EDGE}, // S_PLAY_EDGE
 	{SPR_PLAY, SPR2_RIDE,                 4, {NULL}, 0,  0, S_PLAY_RIDE}, // S_PLAY_RIDE
 
 	// CA2_SPINDASH
@@ -2527,13 +2530,17 @@ state_t states[NUMSTATES] =
 	{SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
 	{SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
 
-	{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1
+	{SPR_LCKN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LOCKON
+
+	{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG
 
 	// CTF Sign
-	{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG2}, // S_GOTFLAG1
-	{SPR_GFLG, 1, 1, {NULL}, 0, 0, S_NULL},     // S_GOTFLAG2
-	{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTFLAG4}, // S_GOTFLAG3
-	{SPR_GFLG, 2, 1, {NULL}, 0, 0, S_NULL},     // S_GOTFLAG4
+	{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTREDFLAG2}, // S_GOTREDFLAG1
+	{SPR_GFLG, 1, 1, {NULL}, 0, 0, S_NULL},     // S_GOTREDFLAG2
+	{SPR_GFLG, 0, 1, {NULL}, 0, 0, S_GOTBLUEFLAG2}, // S_GOTBLUEFLAG1
+	{SPR_GFLG, 2, 1, {NULL}, 0, 0, S_NULL},     // S_GOTBLUEFLAG2
+
+	{SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK
 
 	// Red Rings (thrown)
 	{SPR_RRNG, FF_FULLBRIGHT,   1, {A_ThrownRing}, 0, 0, S_RRNG2}, // S_RRNG1
@@ -12024,7 +12031,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		8,              // speed
 		8*FRACUNIT,     // radius
 		8*FRACUNIT,     // height
-		0,              // display offset
+		113,            // display offset
 		16,             // mass
 		0,              // damage
 		sfx_None,       // activesound
@@ -12051,7 +12058,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		8,              // speed
 		8*FRACUNIT,     // radius
 		16*FRACUNIT,    // height
-		0,              // display offset
+		112,            // display offset
 		16,             // mass
 		0,              // damage
 		sfx_None,       // activesound
@@ -12059,9 +12066,36 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
+	{           // MT_LOCKON
+		-1,             // doomednum
+		S_LOCKON,       // spawnstate
+		1000,           // spawnhealth
+		S_NULL,         // seestate
+		sfx_None,       // seesound
+		8,              // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		0,              // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_None,       // deathsound
+		8,              // speed
+		16*FRACUNIT,    // radius
+		32*FRACUNIT,    // height
+		111,            // display offset
+		16,             // mass
+		0,              // damage
+		sfx_None,       // activesound
+		MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
+		S_NULL          // raisestate
+	},
+
 	{           // MT_TAG
 		-1,             // doomednum
-		S_TTAG1,        // spawnstate
+		S_TTAG,         // spawnstate
 		1000,           // spawnhealth
 		S_NULL,         // seestate
 		sfx_None,       // seesound
@@ -12078,7 +12112,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		8,              // speed
 		16*FRACUNIT,    // radius
 		32*FRACUNIT,    // height
-		0,              // display offset
+		111,            // display offset
 		16,             // mass
 		0,              // damage
 		sfx_None,       // activesound
@@ -12086,9 +12120,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
-	{           // MT_GOTFLAG
+	{           // MT_GOTREDFLAG
 		-1,             // doomednum
-		S_GOTFLAG1,     // spawnstate
+		S_GOTREDFLAG1,  // spawnstate
 		1000,           // spawnhealth
 		S_NULL,         // seestate
 		sfx_None,       // seesound
@@ -12105,7 +12139,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		8,              // speed
 		64*FRACUNIT,    // radius
 		32*FRACUNIT,    // height
-		0,              // display offset
+		111,            // display offset
 		16,             // mass
 		0,              // damage
 		sfx_None,       // activesound
@@ -12113,9 +12147,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
-	{           // MT_GOTFLAG2
+	{           // MT_GOTBLUEFLAG2
 		-1,             // doomednum
-		S_GOTFLAG3,     // spawnstate
+		S_GOTBLUEFLAG1, // spawnstate
 		1000,           // spawnhealth
 		S_NULL,         // seestate
 		sfx_None,       // seesound
@@ -12132,7 +12166,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		8,              // speed
 		64*FRACUNIT,    // radius
 		32*FRACUNIT,    // height
-		0,              // display offset
+		111,            // display offset
 		16,             // mass
 		0,              // damage
 		sfx_None,       // activesound
@@ -12418,6 +12452,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
+	{           // MT_CORK
+		-1,             // doomednum
+		S_CORK,         // spawnstate
+		1000,           // spawnhealth
+		S_NULL,         // seestate
+		sfx_itemup,     // seesound
+		0,              // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		0,              // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_SMOKE1,       // deathstate
+		S_NULL,         // xdeathstate
+		sfx_itemup,     // deathsound
+		60*FRACUNIT,    // speed
+		16*FRACUNIT,    // radius
+		16*FRACUNIT,    // height
+		0,              // display offset
+		100,            // mass
+		1,              // damage
+		sfx_None,       // activesound
+		MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
+		S_NULL          // raisestate
+	},
+
 	{           // MT_REDRING
 		-1,             // doomednum
 		S_RRNG1,        // spawnstate
diff --git a/src/info.h b/src/info.h
index 78ed505925a364c911eb9e74ccde3137414e57f6..4501357b768475e0e8691278659d60c0ef8f8b00 100644
--- a/src/info.h
+++ b/src/info.h
@@ -450,7 +450,7 @@ typedef enum sprite
 	SPR_ARMB, // Armageddon Shield Ring, Back
 	SPR_WIND, // Whirlwind Shield Orb
 	SPR_MAGN, // Attract Shield Orb
-	SPR_ELEM, // Elemental Shield Orb and Fire
+	SPR_ELEM, // Elemental Shield Orb
 	SPR_FORC, // Force Shield Orb
 	SPR_PITY, // Pity Shield Orb
 	SPR_FIRS, // Flame Shield Orb
@@ -507,9 +507,12 @@ typedef enum sprite
 	// Game Indicators
 	SPR_SCOR, // Score logo
 	SPR_DRWN, // Drowning Timer
+	SPR_LCKN, // Target
 	SPR_TTAG, // Tag Sign
 	SPR_GFLG, // Got Flag sign
 
+	SPR_CORK,
+
 	// Ring Weapons
 	SPR_RRNG, // Red Ring
 	SPR_RNGB, // Bounce Ring
@@ -2717,14 +2720,18 @@ typedef enum state
 	S_FOUR2,
 	S_FIVE2,
 
+	S_LOCKON,
+
 	// Tag Sign
-	S_TTAG1,
+	S_TTAG,
 
 	// Got Flag Sign
-	S_GOTFLAG1,
-	S_GOTFLAG2,
-	S_GOTFLAG3,
-	S_GOTFLAG4,
+	S_GOTREDFLAG1,
+	S_GOTREDFLAG2,
+	S_GOTBLUEFLAG1,
+	S_GOTBLUEFLAG2,
+
+	S_CORK,
 
 	// Red Ring
 	S_RRNG1,
@@ -3534,9 +3541,10 @@ typedef enum mobj_type
 	MT_SCORE, // score logo
 	MT_DROWNNUMBERS, // Drowning Timer
 	MT_GOTEMERALD, // Chaos Emerald (intangible)
+	MT_LOCKON, // Target
 	MT_TAG, // Tag Sign
-	MT_GOTFLAG, // Got Flag sign
-	MT_GOTFLAG2, // Got Flag sign
+	MT_GOTREDFLAG, // Got Flag sign
+	MT_GOTBLUEFLAG, // Got Flag sign
 
 	// Ambient Sounds
 	MT_AWATERA, // Ambient Water Sound 1
@@ -3550,6 +3558,8 @@ typedef enum mobj_type
 	MT_RANDOMAMBIENT,
 	MT_RANDOMAMBIENT2,
 
+	MT_CORK,
+
 	// Ring Weapons
 	MT_REDRING,
 	MT_BOUNCERING,
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 2b4028a0e549967065483c01944b53c3974bd898..53fa9bc55d89d52b4706009d879a6e32e434529a 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -1060,7 +1060,7 @@ static int lib_pLookForEnemies(lua_State *L)
 	INLEVEL
 	if (!player)
 		return LUA_ErrInvalid(L, "player_t");
-	lua_pushboolean(L, P_LookForEnemies(player, nonenemies, bullet));
+	LUA_PushUserdata(L, P_LookForEnemies(player, nonenemies, bullet), META_MOBJ);
 	return 1;
 }
 
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 0900528ed016ab0b62b013392805361af2d6e5d3..6223094257320dd62cd2f6dc12673c922e47b818 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -194,8 +194,6 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->gotcontinue);
 	else if (fastcmp(field,"speed"))
 		lua_pushfixed(L, plr->speed);
-	else if (fastcmp(field,"jumping"))
-		lua_pushboolean(L, plr->jumping);
 	else if (fastcmp(field,"secondjump"))
 		lua_pushinteger(L, plr->secondjump);
 	else if (fastcmp(field,"fly1"))
@@ -459,8 +457,6 @@ static int player_set(lua_State *L)
 		plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"speed"))
 		plr->speed = luaL_checkfixed(L, 3);
-	else if (fastcmp(field,"jumping"))
-		plr->jumping = luaL_checkboolean(L, 3);
 	else if (fastcmp(field,"secondjump"))
 		plr->secondjump = (UINT8)luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"fly1"))
diff --git a/src/p_floor.c b/src/p_floor.c
index f401271d1398c827107bf88ec59f1d8866d02b3c..071ebcb86abd8668ed8932e9b416814bd79a8907 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -1776,9 +1776,10 @@ static mobj_t *SearchMarioNode(msecnode_t *node)
 		case MT_SCORE:
 		case MT_DROWNNUMBERS:
 		case MT_GOTEMERALD:
+		case MT_LOCKON:
 		case MT_TAG:
-		case MT_GOTFLAG:
-		case MT_GOTFLAG2:
+		case MT_GOTREDFLAG:
+		case MT_GOTBLUEFLAG:
 		case MT_HOOP:
 		case MT_HOOPCOLLIDE:
 		case MT_NIGHTSCORE:
diff --git a/src/p_local.h b/src/p_local.h
index 14d96f693d968135c918ea83f205fb9ffab781ee..78ef651926374bcf12606b80a94cd39d4cd20050 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -174,7 +174,7 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move);
 fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move);
 void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move);
 
-boolean P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
+mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
 void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
 void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
 boolean P_SuperReady(player_t *player);
diff --git a/src/p_map.c b/src/p_map.c
index 7ff6301e2878f3ba5de351b442b361a5e491eb12..7e6add39c11de972dab0fe6fb10a5b04c202c859 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -115,7 +115,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 	fixed_t offx, offy;
 	fixed_t vertispeed = spring->info->mass;
 	fixed_t horizspeed = spring->info->damage;
-	UINT8 jumping, secondjump;
+	UINT8 secondjump;
 
 	if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
 		return false;
@@ -214,8 +214,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 			}
 		}
 
-		pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY|PF_BOUNCING); // I still need these.
-		jumping = object->player->jumping;
+		pflags = object->player->pflags & (PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_SHIELDABILITY|PF_BOUNCING); // I still need these.
 		secondjump = object->player->secondjump;
 		P_ResetPlayer(object->player);
 
@@ -230,7 +229,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 			|| (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL)))
 			{
 				object->player->pflags |= pflags;
-				object->player->jumping = jumping;
 				object->player->secondjump = secondjump;
 			}
 			else
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 696a687381bd3b38562998b51832c7ae1151a48f..a235af5b3464c6c80e6687b322f5004ee724a491 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -504,7 +504,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 		mobj->tics = st->tics;
 
 		// Adjust the player's animation speed to match their velocity.
-		if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
+		if (player->panim == PA_EDGE && (player->charflags & SF_FASTEDGE))
+			mobj->tics = 2;
+		else if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST))
 		{
 			fixed_t speed;// = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor));
 			if (player->panim == PA_FALL)
@@ -3263,8 +3265,7 @@ static void P_PlayerZMovement(mobj_t *mo)
 					if (!(mo->player->pflags & PF_GLIDING))
 						mo->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
 
-					mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
-					mo->player->jumping = 0;
+					mo->player->pflags &= ~(PF_STARTJUMP|PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
 					mo->player->secondjump = 0;
 					mo->player->glidetime = 0;
 					mo->player->climbing = 0;
@@ -4253,8 +4254,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
 	}
 	else
 	{
-		if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // "jumping" is used for drilling
-			mobj->player->jumping = 0;
+		if (!(mobj->player->powers[pw_carry] == CR_NIGHTSMODE)) // used for drilling
+			mobj->player->pflags &= ~PF_STARTJUMP;
 		mobj->player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE);
 		if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
 		{
@@ -7002,6 +7003,23 @@ void P_MobjThinker(mobj_t *mobj)
 					return;
 				}
 				break;
+			case MT_LOCKON:
+				if (!mobj->target)
+				{
+					P_RemoveMobj(mobj);
+					return;
+				}
+				mobj->x = mobj->target->x;
+				mobj->y = mobj->target->y;
+
+				mobj->destscale = mobj->target->destscale;
+				P_SetScale(mobj, mobj->target->scale);
+
+				if (!(mobj->target->eflags & MFE_VERTICALFLIP))
+					mobj->z = mobj->target->z + mobj->target->height + FixedMul(16*FRACUNIT, mobj->target->scale);
+				else
+					mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height;
+				break;
 			case MT_DROWNNUMBERS:
 				if (!mobj->target)
 				{
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 6abb4d14c37aa81ff9474aee88be93b315f1e920..3853dc7e63826c08a337de65aeea322a9aba6b94 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -152,7 +152,6 @@ static void P_NetArchivePlayers(void)
 		WRITESINT8(save_p, players[i].xtralife);
 		WRITEUINT8(save_p, players[i].gotcontinue);
 		WRITEFIXED(save_p, players[i].speed);
-		WRITEUINT8(save_p, players[i].jumping);
 		WRITEUINT8(save_p, players[i].secondjump);
 		WRITEUINT8(save_p, players[i].fly1);
 		WRITEUINT8(save_p, players[i].scoreadd);
@@ -332,7 +331,6 @@ static void P_NetUnArchivePlayers(void)
 		players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
 		players[i].gotcontinue = READUINT8(save_p); // got continue from stage
 		players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values)
-		players[i].jumping = READUINT8(save_p); // Jump counter
 		players[i].secondjump = READUINT8(save_p);
 		players[i].fly1 = READUINT8(save_p); // Tails flying
 		players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus
diff --git a/src/p_user.c b/src/p_user.c
index d83cb3139fd434219a7aa6d8d57fed633e2dd7ec..80906e1a4967b0a5c6bae6980450f3ff1f4af723 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -579,9 +579,8 @@ static void P_DeNightserizePlayer(player_t *player)
 	player->powers[pw_carry] = CR_NONE;
 
 	player->powers[pw_underwater] = 0;
-	player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
+	player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
 	player->secondjump = 0;
-	player->jumping = 0;
 	player->homing = 0;
 	player->climbing = 0;
 	player->mo->fuse = 0;
@@ -873,12 +872,11 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
 // Useful when you want to kill everything the player is doing.
 void P_ResetPlayer(player_t *player)
 {
-	player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING);
+	player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_THOKKED|PF_CANCARRY|PF_SHIELDABILITY|PF_BOUNCING);
 
 	if (!(player->powers[pw_carry] == CR_NIGHTSMODE || player->powers[pw_carry] == CR_BRAKGOOP))
 		player->powers[pw_carry] = CR_NONE;
 
-	player->jumping = 0;
 	player->secondjump = 0;
 	player->glidetime = 0;
 	player->homing = 0;
@@ -2345,33 +2343,18 @@ static void P_DoPlayerHeadSigns(player_t *player)
 			}
 		}
 	}
-	else if (gametype == GT_CTF)
+	else if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh).
 	{
-		if (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) // If you have the flag (duh).
+		// Spawn a got-flag message over the head of the player that
+		// has it (but not on your own screen if you have the flag).
+		if (splitscreen || player != &players[consoleplayer])
 		{
-			// Spawn a got-flag message over the head of the player that
-			// has it (but not on your own screen if you have the flag).
-			if (splitscreen || player != &players[consoleplayer])
-			{
-				if (player->gotflag & GF_REDFLAG)
-				{
-					if (!(player->mo->eflags & MFE_VERTICALFLIP))
-						P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
-							player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG);
-					else
-						P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
-							player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG)->eflags |= MFE_VERTICALFLIP;
-				}
-				if (player->gotflag & GF_BLUEFLAG)
-				{
-					if (!(player->mo->eflags & MFE_VERTICALFLIP))
-						P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
-							player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG2);
-					else
-						P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
-							player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG2].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, MT_GOTFLAG2)->eflags |= MFE_VERTICALFLIP;
-				}
-			}
+			if (!(player->mo->eflags & MFE_VERTICALFLIP))
+				P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
+					player->mo->z+P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, ((player->gotflag & GF_REDFLAG) ? MT_GOTREDFLAG : MT_GOTBLUEFLAG));
+			else
+				P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
+					player->mo->z+player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTREDFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale)+player->mo->momz, ((player->gotflag & GF_REDFLAG) ? MT_GOTREDFLAG : MT_GOTBLUEFLAG))->eflags |= MFE_VERTICALFLIP; // yes, MT_GOTREDFLAG's height is used for both of them. Doesn't really matter - they should both always be the same height.
 		}
 	}
 }
@@ -3672,7 +3655,7 @@ void P_DoJump(player_t *player, boolean soundandstate)
 		if (player->mo->eflags & MFE_UNDERWATER)
 			player->mo->momz = FixedMul(player->mo->momz, FixedDiv(117*FRACUNIT, 200*FRACUNIT));
 
-		player->jumping = 1;
+		player->pflags |= PF_STARTJUMP;
 	}
 
 	factor = player->jumpfactor;
@@ -3849,43 +3832,60 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
 				}
 				break;
 			case CA2_GUNSLINGER:
-				if ((cmd->buttons & BT_USE) && !(player->pflags & PF_USEDOWN)
-					&& !player->mo->momz && onground && !player->weapondelay
-						&& canstand)
+				if (!player->mo->momz && onground && !player->weapondelay && canstand)
 				{
-					mobj_t *bullet;
-
-					P_SetPlayerMobjState(player->mo, S_PLAY_FIRE);
-
-#define zpos(posmo) (posmo->z + (posmo->height - mobjinfo[player->revitem].height)/2)
-					if (P_LookForEnemies(player, false, true) && player->mo->tracer)
-					{
-						bullet = P_SpawnPointMissile(player->mo, player->mo->tracer->x, player->mo->tracer->y, zpos(player->mo->tracer), player->revitem, player->mo->x, player->mo->y, zpos(player->mo));
-						if (!demoplayback || P_AnalogMove(player))
-						{
-							if (player == &players[consoleplayer])
-								localangle = player->mo->angle;
-							else if (player == &players[secondarydisplayplayer])
-								localangle2 = player->mo->angle;
-						}
-					}
+					if (player->speed > FixedMul(10<<FRACBITS, player->mo->scale))
+					{}
 					else
 					{
-						bullet = P_SpawnPointMissile(player->mo, player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, FRACUNIT), player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, FRACUNIT), zpos(player->mo), player->revitem, player->mo->x, player->mo->y, zpos(player->mo));
-						if (bullet)
+						mobj_t *lockon = P_LookForEnemies(player, false, true);
+						if (lockon)
 						{
-							bullet->flags &= ~MF_NOGRAVITY;
-							bullet->momx >>= 1;
-							bullet->momy >>= 1;
+							if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
+							{
+								mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON);
+								visual->eflags |= (lockon->eflags & MFE_VERTICALFLIP);
+								visual->target = lockon;
+							}
 						}
-					}
+						if ((cmd->buttons & BT_USE) && !(player->pflags & PF_USEDOWN))
+						{
+							mobj_t *bullet;
+
+							P_SetPlayerMobjState(player->mo, S_PLAY_FIRE);
+
+#define zpos(posmo) (posmo->z + (posmo->height - mobjinfo[player->revitem].height)/2)
+							if (lockon)
+							{
+								player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
+								bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo));
+								if (!demoplayback || P_AnalogMove(player))
+								{
+									if (player == &players[consoleplayer])
+										localangle = player->mo->angle;
+									else if (player == &players[secondarydisplayplayer])
+										localangle2 = player->mo->angle;
+								}
+							}
+							else
+							{
+								bullet = P_SpawnPointMissile(player->mo, player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, FRACUNIT), player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, FRACUNIT), zpos(player->mo), player->revitem, player->mo->x, player->mo->y, zpos(player->mo));
+								if (bullet)
+								{
+									bullet->flags &= ~MF_NOGRAVITY;
+									bullet->momx >>= 1;
+									bullet->momy >>= 1;
+								}
+							}
 #undef zpos
 
-					P_SetTarget(&player->mo->tracer, NULL);
-					player->mo->momx >>= 1;
-					player->mo->momy >>= 1;
-					player->pflags |= PF_USEDOWN;
-					P_SetWeaponDelay(player, TICRATE/2);
+							P_SetTarget(&player->mo->tracer, NULL);
+							player->mo->momx >>= 1;
+							player->mo->momy >>= 1;
+							player->pflags |= PF_USEDOWN;
+							P_SetWeaponDelay(player, TICRATE/2);
+						}
+					}
 				}
 				break;
 			case CA2_MELEE: // Melee attack
@@ -3899,7 +3899,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
 					if ((player->charability == CA_TWINSPIN) && (player->speed > FixedMul(player->runspeed, player->mo->scale)))
 					{
 						P_DoJump(player, false);
-						player->jumping = 0;
+						player->pflags &= ~PF_STARTJUMP;
 						player->mo->momz = FixedMul(player->mo->momz, 3*FRACUNIT/2); // NOT 1.5 times the jump height, but 2.25 times.
 						P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
 						S_StartSound(player->mo, sfx_s3k8b);
@@ -3970,10 +3970,9 @@ void P_DoJumpShield(player_t *player)
 
 	player->pflags &= ~PF_JUMPED;
 	P_DoJump(player, false);
-	player->jumping = 0;
 	player->secondjump = 0;
 	player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
-	player->pflags &= ~(PF_SPINNING|PF_BOUNCING);
+	player->pflags &= ~(PF_STARTJUMP|PF_SPINNING|PF_BOUNCING);
 	if (electric)
 	{
 		mobj_t *spark;
@@ -4013,7 +4012,7 @@ void P_DoBubbleBounce(player_t *player)
 	if (player->charflags & SF_NOJUMPSPIN)
 		P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
 	player->pflags |= PF_THOKKED;
-	player->jumping = 0;
+	player->pflags &= ~PF_STARTJUMP;
 	player->secondjump = UINT8_MAX;
 	player->mo->momz = FixedMul(player->mo->momz, 5*FRACUNIT/4);
 }
@@ -4036,7 +4035,7 @@ void P_DoAbilityBounce(player_t *player, boolean changemomz)
 		else if (player->mo->eflags & MFE_UNDERWATER)
 			prevmomz /= 2;
 		P_DoJump(player, false);
-		player->jumping = 0;
+		player->pflags &= ~(PF_STARTJUMP|PF_JUMPED);
 		player->mo->momz = (FixedMul(player->mo->momz, 3*FRACUNIT/2) + prevmomz)/2;
 	}
 	S_StartSound(player->mo, sfx_boingf);
@@ -4258,14 +4257,19 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
 
 						if (player->charability == CA_HOMINGTHOK && !player->homing)
 						{
-							player->pflags &= ~PF_NOJUMPDAMAGE;
-							if (P_LookForEnemies(player, true, false) && player->mo->tracer)
+							mobj_t *lockon = P_LookForEnemies(player, true, false);
+							if (lockon)
+							{
+								P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
+								player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
 								player->homing = 3*TICRATE;
+							}
 							else
 							{
 								P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
 								player->pflags &= ~PF_JUMPED;
 							}
+							player->pflags &= ~PF_NOJUMPDAMAGE;
 						}
 
 						player->pflags &= ~(PF_SPINNING|PF_STARTDASH);
@@ -4451,10 +4455,10 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
 		}
 
 		// If letting go of the jump button while still on ascent, cut the jump height.
-		if (player->pflags & PF_JUMPED && P_MobjFlip(player->mo)*player->mo->momz > 0 && player->jumping == 1)
+		if (((player->pflags & (PF_JUMPED|PF_STARTJUMP)) == (PF_JUMPED|PF_STARTJUMP)) && (P_MobjFlip(player->mo)*player->mo->momz > 0))
 		{
 			player->mo->momz >>= 1;
-			player->jumping = 0;
+			player->pflags &= ~PF_STARTJUMP;
 		}
 	}
 }
@@ -6042,21 +6046,19 @@ static void P_NiGHTSMovement(player_t *player)
 
 	if (player->bumpertime)
 	{
-		player->jumping = 1;
-		player->pflags |= PF_DRILLING;
+		player->pflags |= (PF_STARTJUMP|PF_DRILLING);
 		newangle = (INT16)player->flyangle;
 	}
 	else if (cmd->buttons & BT_JUMP && player->drillmeter && player->drilldelay == 0)
 	{
-		if (!player->jumping)
+		if (!(player->pflags & PF_STARTJUMP))
 			firstdrill = true;
 
-		player->jumping = 1;
-		player->pflags |= PF_DRILLING;
+		player->pflags |= (PF_STARTJUMP|PF_DRILLING);
 	}
 	else
 	{
-		player->jumping = 0;
+		player->pflags &= ~PF_STARTJUMP;
 
 		if (cmd->sidemove != 0)
 			moved = true;
@@ -6816,8 +6818,7 @@ static void P_MovePlayer(player_t *player)
 	if (onground && player->pflags & PF_JUMPED && !(player->pflags & PF_GLIDING)
 	&& P_MobjFlip(player->mo)*player->mo->momz < 0)
 	{
-		player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY);
-		player->jumping = 0;
+		player->pflags &= ~(PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY);
 		player->secondjump = 0;
 		P_SetPlayerMobjState(player->mo, S_PLAY_STND);
 	}
@@ -7177,8 +7178,7 @@ static void P_MovePlayer(player_t *player)
 					}
 
 					player->mo->momz = 0;
-					player->pflags &= ~PF_SPINNING;
-					player->jumping = 0; // don't cut jump height after bouncing off something
+					player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
 				}
 			}
 			else
@@ -7214,15 +7214,20 @@ static void P_MovePlayer(player_t *player)
 							case SH_ATTRACT:
 								player->pflags |= PF_THOKKED|PF_SHIELDABILITY;
 								player->homing = 2;
-								if (P_LookForEnemies(player, false, false) && player->mo->tracer)
 								{
-									player->pflags &= ~PF_NOJUMPDAMAGE;
-									P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
-									S_StartSound(player->mo, sfx_s3k40);
-									player->homing = 3*TICRATE;
+									mobj_t *lockon = P_LookForEnemies(player, false, false);
+									if (lockon)
+									{
+										P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, lockon));
+										player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y);
+										player->pflags &= ~PF_NOJUMPDAMAGE;
+										P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
+										S_StartSound(player->mo, sfx_s3k40);
+										player->homing = 3*TICRATE;
+									}
+									else
+										S_StartSound(player->mo, sfx_s3ka6);
 								}
-								else
-									S_StartSound(player->mo, sfx_s3ka6);
 								break;
 							// Elemental/Bubblewrap shield activation
 							case SH_ELEMENTAL:
@@ -7864,7 +7869,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
 // If bullet is true, you can look up and the distance is further,
 // but your total angle span you can look is limited to compensate.
 //
-boolean P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
+mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
 {
 	mobj_t *mo;
 	thinker_t *think;
@@ -7880,7 +7885,8 @@ boolean P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
 			continue; // not a mobj thinker
 
 		mo = (mobj_t *)think;
-		if (!(mo->flags & targetmask))
+		if (!(mo->flags & targetmask
+		|| mo->type == MT_FAKEMOBILE)) // hehehehe
 			continue; // not a valid target
 
 		if (mo->health <= 0) // dead
@@ -7903,7 +7909,7 @@ boolean P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
 			dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y);
 			if (bullet)
 			{
-				if ((R_PointToAngle2(0, 0, dist, zdist) + ANGLE_45) > ANGLE_90)
+				if ((R_PointToAngle2(0, 0, dist, zdist) + span) > span*2)
 					continue; // Don't home outside of desired angle!
 			}
 			else // Don't home upwards!
@@ -7942,15 +7948,7 @@ boolean P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
 		closestdist = dist;
 	}
 
-	if (closestmo)
-	{
-		// Found a target monster
-		P_SetTarget(&player->mo->target, P_SetTarget(&player->mo->tracer, closestmo));
-		player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, closestmo->x, closestmo->y);
-		return true;
-	}
-
-	return false;
+	return closestmo;
 }
 
 void P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
diff --git a/src/st_stuff.c b/src/st_stuff.c
index fb28f2378c8ba966f5b6008f2869646a65babeb3..e5d005b2382b8838cdeacfb688b68dc56334891f 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -586,7 +586,7 @@ static void ST_drawDebugInfo(void)
 
 		// Flags
 		V_DrawRightAlignedString(304-92, height - 72, V_MONOSPACE, "PF:");
-		V_DrawString(304-90,             height - 72, (stplyr->jumping) ? V_GREENMAP : V_REDMAP, "JM");
+		V_DrawString(304-90,             height - 72, (stplyr->pflags & PF_STARTJUMP) ? V_GREENMAP : V_REDMAP, "SJ");
 		V_DrawString(304-72,             height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD");
 		V_DrawString(304-54,             height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP");
 		V_DrawString(304-36,             height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST");