diff --git a/src/dehacked.c b/src/dehacked.c
index 4fb0bc7f8e62bc838695a15258493e9babe8691f..fff9dbee87976b290b839fee99cc7569414cc72d 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -4866,6 +4866,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 
 	// Snailer
 	"S_SNAILER1",
+	"S_SNAILER_FLICKY",
 
 	// Vulture
 	"S_VULTURE_STND",
diff --git a/src/info.c b/src/info.c
index 2579f95af2da1c79b85c9209015b2aee8ddf3ade..3ab89534178adaa1aa3fc56d44e50d897ac4d90a 100644
--- a/src/info.c
+++ b/src/info.c
@@ -986,6 +986,7 @@ state_t states[NUMSTATES] =
 
 	// Snailer
 	{SPR_SNLR, 0, 1, {A_SnailerThink}, 0, 0, S_SNAILER1}, // S_SNAILER1
+	{SPR_BOM1, 0, 0, {A_FlickySpawn}, 1<<17, 0, S_XPLD1}, // S_SNAILER_FLICKY
 
 	// Vulture
 	{SPR_VLTR, 4, 35,        {A_Look},         1, 0, S_VULTURE_STND},  // S_VULTURE_STND
@@ -4575,7 +4576,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		sfx_None,       // painsound
 		S_NULL,         // meleestate
 		S_NULL,         // missilestate
-		S_XPLD_FLICKY,  // deathstate
+		S_SNAILER_FLICKY, // deathstate
 		S_NULL,         // xdeathstate
 		sfx_pop,        // deathsound
 		FRACUNIT,       // speed
diff --git a/src/info.h b/src/info.h
index b76d857fa69dd5244da599b99d96df459e221eb7..bbb6a21fcd37d44b219705c31b1dcfef0f168ad9 100644
--- a/src/info.h
+++ b/src/info.h
@@ -1180,6 +1180,7 @@ typedef enum state
 
 	// Snailer
 	S_SNAILER1,
+	S_SNAILER_FLICKY,
 
 	// Vulture
 	S_VULTURE_STND,
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 3ef099e1b2a513e703163630b633852e13902a79..1928821ad793e61f33e17c241c8ef2c62bc5a4c9 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -11671,9 +11671,10 @@ void A_SpawnFreshCopy(mobj_t *actor)
 }
 
 // Internal Flicky spawning function.
-mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers)
+mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward)
 {
 	mobj_t *flicky;
+	fixed_t offsx = 0, offsy = 0;
 
 	if (!flickytype)
 	{
@@ -11686,7 +11687,14 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
 		}
 	}
 
-	flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, flickytype);
+	if (moveforward)
+	{
+		fixed_t scal = mobjinfo[flickytype].radius*((fixed_t)moveforward);
+		offsx = P_ReturnThrustX(actor, actor->angle, scal);
+		offsy = P_ReturnThrustY(actor, actor->angle, scal);
+	}
+
+	flicky = P_SpawnMobjFromMobj(actor, offsx, offsy, 0, flickytype);
 	flicky->angle = actor->angle;
 
 	if (flickytype == MT_SEED)
@@ -11712,24 +11720,30 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
 //
 // var1:
 //		lower 16 bits: if 0, spawns random flicky based on level header. Else, spawns the designated thing type.
-//		upper 16 bits: if 0, no sound is played. Else, A_Scream is called.
+//		bit 17: if 0, no sound is played. Else, A_Scream is called.
+//		bit 18: if 1, spawn flicky slightly forward from spawn position, to avoid being stuck in wall. doesn't stack with 19. (snailers)
+//		bit 19: if 1, spawn flicky slightly backward from spawn position. doesn't stack with 18.
 // var2 = upwards thrust for spawned flicky. If zero, default value is provided.
 //
 void A_FlickySpawn(mobj_t *actor)
 {
-	INT32 locvar1 = var1;
+	INT32 locvar1 = var1 & 65535;
 	INT32 locvar2 = var2;
+	INT32 test = (var1 >> 16);
+	SINT8 moveforward = 0;
 #ifdef HAVE_BLUA
 	if (LUA_CallAction("A_FlickySpawn", actor))
 		return;
 #endif
 
-	if (locvar1 >> 16) {
+	if (test & 1)
 		A_Scream(actor); // A shortcut for the truly lazy.
-		locvar1 &= 65535;
-	}
+	if (test & 2)
+		moveforward = 1;
+	else if (test & 4)
+		moveforward = -1;
 
-	P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true);
+	P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true, moveforward);
 }
 
 // Internal Flicky color setting
@@ -11793,7 +11807,7 @@ void A_FlickyCenter(mobj_t *actor)
 
 	if (!actor->tracer)
 	{
-		mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false);
+		mobj_t *flicky = P_InternalFlickySpawn(actor, locvar1, 1, false, 0);
 		P_SetTarget(&flicky->target, actor);
 		P_SetTarget(&actor->tracer, flicky);
 
diff --git a/src/p_local.h b/src/p_local.h
index 02f497850d23b02d0331501ab80908e358d64916..17a1c32d2de8c787f991641b1881d31b955b9404 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -357,7 +357,7 @@ boolean P_CheckMissileRange(mobj_t *actor);
 void P_NewChaseDir(mobj_t *actor);
 boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed_t dist);
 
-mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers);
+mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers, SINT8 moveforward);
 void P_InternalFlickySetColor(mobj_t *actor, UINT8 extrainfo);
 #define P_IsFlickyCenter(type) (type > MT_FLICKY_01 && type < MT_SEED && (type - MT_FLICKY_01) % 2 ? 1 : 0)
 void P_InternalFlickyBubble(mobj_t *actor);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 126de9671d6474ca1077400992418b9546b3e0c0..5d6a8a10f65ffbd412312d7c0c84c0d096ebd9b2 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -8227,8 +8227,7 @@ void P_MobjThinker(mobj_t *mobj)
 			mobj->flags2 ^= MF2_DONTDRAW;
 			break;
 		case MT_EGGTRAP: // Egg Capsule animal release
-			if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7)
-				&& (mobj->fuse & 3))
+			if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7))
 			{
 				INT32 i;
 				fixed_t x,y,z;
@@ -8236,7 +8235,7 @@ void P_MobjThinker(mobj_t *mobj)
 				mobj_t *mo2;
 				mobj_t *flicky;
 
-				z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT);
+				z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64)<<FRACBITS);
 				for (i = 0; i < 2; i++)
 				{
 					const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK;
@@ -8249,18 +8248,18 @@ void P_MobjThinker(mobj_t *mobj)
 					ns = 4 * FRACUNIT;
 					mo2->momx = FixedMul(FINESINE(fa),ns);
 					mo2->momy = FixedMul(FINECOSINE(fa),ns);
+					mo2->angle = fa << ANGLETOFINESHIFT;
 
-					if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack!
+					if (!i && !(mobj->fuse & 2))
 						S_StartSound(mo2, mobj->info->deathsound);
 
-					flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false);
+					flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false, -1);
 					if (!flicky)
 						break;
 
 					P_SetTarget(&flicky->target, mo2);
 					flicky->momx = mo2->momx;
 					flicky->momy = mo2->momy;
-					flicky->angle = fa << ANGLETOFINESHIFT;
 				}
 
 				mobj->fuse--;
diff --git a/src/p_user.c b/src/p_user.c
index 5b788fcc12b764dc9e57fe808c0088d5cee8fde1..3c481e7e2f34fc7e6765b8cb9a692d0faa1e7d3e 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -6906,7 +6906,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
 				{
 					/*for (i = 0; i < 16; i++)
 					{
-						mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true);
+						mobj_t *flicky = P_InternalFlickySpawn(player->capsule, 0, ((i%4) + 1)*2*FRACUNIT, true, 0);
 						flicky->z += player->capsule->height/2;
 						flicky->angle = (i*(ANGLE_MAX/16));
 						P_InstaThrust(flicky, flicky->angle, 8*FRACUNIT);