diff --git a/src/dehacked.c b/src/dehacked.c index 00ee61d38..9e221d995 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1166,7 +1166,7 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->numFlickies++; } while ((tmp = strtok(NULL,",")) != NULL); - if (mapheaderinfo[num-1]->numFlickies) // now let's do it again - except this time we add them to the list! + if (mapheaderinfo[num-1]->numFlickies) { size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num-1]->numFlickies; mapheaderinfo[num-1]->flickies = Z_Realloc(mapheaderinfo[num-1]->flickies, newsize, PU_STATIC, NULL); @@ -6174,8 +6174,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_XPLD_FLICKY", "S_XPLD1", "S_XPLD2", - "S_XPLD3", - "S_XPLD4", + "S_XPLD_EGGTRAP", // Underwater Explosion "S_WPLD1", diff --git a/src/info.c b/src/info.c index a5f24d805..e7afde710 100644 --- a/src/info.c +++ b/src/info.c @@ -2847,11 +2847,11 @@ state_t states[NUMSTATES] = {SPR_SPRK, FF_TRANS90|3, 1, {NULL}, 0, 0, S_NULL}, // S_SPRK16 // Robot Explosion - {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY - {SPR_BOM1, 0, 1, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 - {SPR_BOM1, 1, 5, {NULL}, 0, 0, S_XPLD3}, // S_XPLD2 - {SPR_BOM1, 2, 5, {NULL}, 0, 0, S_XPLD4}, // S_XPLD3 - {SPR_BOM1, 3, 5, {NULL}, 0, 0, S_NULL}, // S_XPLD4 + {SPR_BOM1, 0, 0, {A_FlickySpawn}, 0, 0, S_XPLD1}, // S_XPLD_FLICKY + {SPR_BOM1, 0, 1, {A_Scream}, 0, 0, S_XPLD2}, // S_XPLD1 + {SPR_BOM1, FF_ANIMATE|1, 15, {NULL}, 2, 5, S_NULL}, // S_XPLD2 + + {SPR_BOM1, FF_ANIMATE, 20, {NULL}, 3, 5, S_INVISIBLE}, // S_XPLD_EGGTRAP // Underwater Explosion {SPR_BOM4, 0, 3, {A_Scream}, 0, 0, S_WPLD2}, // S_WPLD1 diff --git a/src/info.h b/src/info.h index 8c1b7f325..1b337d417 100644 --- a/src/info.h +++ b/src/info.h @@ -2982,8 +2982,7 @@ typedef enum state S_XPLD_FLICKY, S_XPLD1, S_XPLD2, - S_XPLD3, - S_XPLD4, + S_XPLD_EGGTRAP, // Underwater Explosion S_WPLD1, diff --git a/src/p_enemy.c b/src/p_enemy.c index 0b1cbfaac..d3592b12b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -10338,6 +10338,49 @@ void A_SpawnFreshCopy(mobj_t *actor) S_StartSound(newObject, newObject->info->seesound); } +// Internal Flicky spawning function. + +mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz, boolean lookforplayers) +{ + mobj_t *flicky; + + if (mariomode) // No flickies in Mario mode + return NULL; + + if (cv_soniccd.value) + flickytype = MT_SEED; // MT_CDSEED + else if (!flickytype) + { + if (!mapheaderinfo[gamemap-1] || !mapheaderinfo[gamemap-1]->numFlickies) // No mapheader, no shoes, no service. + return NULL; + else + { + INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies); + flickytype = mapheaderinfo[gamemap-1]->flickies[prandom]; + } + } + + if (flickytype == MT_SEED) // MT_CDSEED + { + flicky = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2) - FixedMul(mobjinfo[flickytype].height / 2, actor->scale), flickytype); + flicky->destscale = actor->scale; + P_SetScale(flicky, flicky->destscale); + return flicky; + } + + flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, flickytype); + flicky->angle = actor->angle; + + P_SetObjectMomZ(flicky, momz, false); + flicky->movedir = P_RandomChance(FRACUNIT/2) ? -1 : 1; + flicky->fuse = P_RandomRange(595, 700); // originally 300, 350 + + if (lookforplayers) + P_LookForPlayers(flicky, true, false, 0); + + return flicky; +} + // Function: A_FlickySpawn // // Description: Flicky spawning function. @@ -10345,51 +10388,21 @@ void A_SpawnFreshCopy(mobj_t *actor) // 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. -// var2 = upwards thrust for spawned flicky +// var2 = upwards thrust for spawned flicky. If zero, default value is provided. // void A_FlickySpawn(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - mobj_t *flicky; #ifdef HAVE_BLUA if (LUA_CallAction("A_FlickySpawn", actor)) return; #endif - if (!mapheaderinfo[gamemap-1]) // No mapheader, no shoes, no service. - return; - - if (mariomode) // No flickies in Mario mode - return; if (locvar1 >> 16) { A_Scream(actor); // A shortcut for the truly lazy. locvar1 &= 65535; } - if (cv_soniccd.value) - locvar1 = MT_SEED; // MT_CDSEED - else if (!locvar1) { - if (!mapheaderinfo[gamemap-1]->numFlickies) - return; - else { - INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies); - locvar1 = mapheaderinfo[gamemap-1]->flickies[prandom]; - } - } - if (locvar1 == MT_SEED) // MT_CDSEED - { - flicky = P_SpawnMobj(actor->x, actor->y, actor->z + (actor->height / 2) - FixedMul(mobjinfo[locvar1].height / 2, actor->scale), locvar1); - flicky->destscale = actor->scale; - P_SetScale(flicky,flicky->destscale); - return; - } - flicky = P_SpawnMobjFromMobj(actor, 0, 0, 0, locvar1); - flicky->angle = actor->angle; - - P_SetObjectMomZ(flicky, (locvar2) ? locvar2 : 8*FRACUNIT, false); - P_LookForPlayers(flicky, true, false, 0); - - flicky->movedir = P_RandomChance(FRACUNIT/2) ? -1 : 1; - flicky->fuse = P_RandomRange(595, 700); // originally 300, 350 + P_InternalFlickySpawn(actor, locvar1, ((locvar2) ? locvar2 : 8*FRACUNIT), true); } diff --git a/src/p_local.h b/src/p_local.h index df9b20a54..aeb14d480 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -295,6 +295,8 @@ 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); + // // P_MAP // diff --git a/src/p_mobj.c b/src/p_mobj.c index 97147d642..1f163a958 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7198,14 +7198,14 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->fuse > 0 && mobj->fuse < 2*TICRATE-(TICRATE/7) && (mobj->fuse & 3)) { - INT32 i,j; + INT32 i; fixed_t x,y,z; fixed_t ns; mobj_t *mo2; + mobj_t *flicky; - i = P_RandomByte(); z = mobj->subsector->sector->floorheight + ((P_RandomByte()&63)*FRACUNIT); - for (j = 0; j < 2; j++) + for (i = 0; i < 2; i++) { const angle_t fa = (P_RandomByte()*FINEANGLES/16) & FINEMASK; ns = 64 * FRACUNIT; @@ -7213,25 +7213,21 @@ void P_MobjThinker(mobj_t *mobj) y = mobj->y + FixedMul(FINECOSINE(fa),ns); mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + P_SetMobjStateNF(mo2, S_XPLD_EGGTRAP); ns = 4 * FRACUNIT; mo2->momx = FixedMul(FINESINE(fa),ns); mo2->momy = FixedMul(FINECOSINE(fa),ns); - i = P_RandomByte(); - - if (i % 5 == 0) - P_SpawnMobj(x, y, z, MT_CHICKEN); - else if (i % 4 == 0) - P_SpawnMobj(x, y, z, MT_COW); - else if (i % 3 == 0) - { - P_SpawnMobj(x, y, z, MT_BIRD); + if (P_RandomChance(FRACUNIT/4)) // I filled a spreadsheet trying to get the equivalent chance to the original P_RandomByte hack! S_StartSound(mo2, mobj->info->deathsound); - } - else if ((i & 1) == 0) - P_SpawnMobj(x, y, z, MT_BUNNY); - else - P_SpawnMobj(x, y, z, MT_MOUSE); + + flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false); + if (!flicky) + break; + + P_SetTarget(&flicky->target, mo2); + flicky->momx = mo2->momx; + flicky->momy = mo2->momy; } mobj->fuse--;