* Add a "moveforward" param to P_InternalFlickySpawn, which controls whether to spawn the flicky a little in front or behind of the object making it.

* Expose this via additional upper-16-bits flags of A_FlickySpawn.
* Use this to make Snailers not spawn their flicky inside the wall they're attached to.
* Make the behaviour of Egg Capsules more consistent mechanically regarding the flicky spawning, using the above as one relevant element.
This commit is contained in:
toaster 2019-11-13 20:14:08 +00:00
parent d591554a5d
commit a3de6d21c4
7 changed files with 34 additions and 18 deletions

View File

@ -4667,6 +4667,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Snailer
"S_SNAILER1",
"S_SNAILER_FLICKY",
// Vulture
"S_VULTURE_STND",

View File

@ -1061,6 +1061,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
@ -4644,7 +4645,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

View File

@ -1226,6 +1226,7 @@ typedef enum state
// Snailer
S_SNAILER1,
S_SNAILER_FLICKY,
// Vulture
S_VULTURE_STND,

View File

@ -11557,9 +11557,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)
{
@ -11572,7 +11573,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)
@ -11598,24 +11606,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
@ -11679,7 +11693,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);

View File

@ -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);

View File

@ -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--;

View File

@ -6895,7 +6895,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);