From 44666f0c2e0053b62e9e232e265a8955a8e5f7bb Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 11 Mar 2024 01:19:58 -0700 Subject: [PATCH] Add SF_BADNIK flag for characters, spawn an explosion on death - Plays a pop sound too! --- src/d_player.h | 1 + src/deh_tables.c | 6 ++++++ src/info.c | 5 +++++ src/info.h | 5 +++++ src/p_inter.c | 39 +++++++++++++++++++++++++++++++++++++++ src/r_skins.c | 1 + 6 files changed, 57 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index 8112b7bf3..d7c87bc58 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -48,6 +48,7 @@ typedef enum { SF_MACHINE = 1, // Beep boop. Are you a robot? SF_IRONMAN = 1<<1, // Pick a new skin during POSITION. I main Random! + SF_BADNIK = 1<<2, // Explodes on death // free up to and including 1<<31 } skinflags_t; diff --git a/src/deh_tables.c b/src/deh_tables.c index 46e36120e..4dbe6436a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -3038,6 +3038,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi // MT_SCRIPT_THING "S_TALKPOINT", "S_TALKPOINT_ORB", + + "S_BADNIK_EXPLOSION_SHOCKWAVE1", + "S_BADNIK_EXPLOSION_SHOCKWAVE2", + "S_BADNIK_EXPLOSION1", + "S_BADNIK_EXPLOSION2", }; // RegEx to generate this from info.h: ^\tMT_([^,]+), --> \t"MT_\1", @@ -4653,6 +4658,7 @@ struct int_const_s const INT_CONST[] = { // Character flags (skinflags_t) {"SF_MACHINE",SF_MACHINE}, {"SF_IRONMAN",SF_IRONMAN}, + {"SF_BADNIK",SF_BADNIK}, // Sound flags {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, diff --git a/src/info.c b/src/info.c index d5cc66b0a..946272516 100644 --- a/src/info.c +++ b/src/info.c @@ -3561,6 +3561,11 @@ state_t states[NUMSTATES] = // MT_SCRIPT_THING {SPR_TLKP, 0|FF_SEMIBRIGHT|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_NULL}, // S_TALKPOINT {SPR_TLKP, 1|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_TALKPOINT_ORB + + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_BADNIK_EXPLOSION_SHOCKWAVE2}, // S_BADNIK_EXPLOSION_SHOCKWAVE1 + {SPR_NULL, 0, 1, {A_PlaySound}, sfx_s3k3d, 1, S_BATTLEBUMPER_EXBLAST1}, // S_BADNIK_EXPLOSION_SHOCKWAVE2 + {SPR_NULL, 0, 1, {NULL}, 0, 0, S_BADNIK_EXPLOSION2}, // S_BADNIK_EXPLOSION1 + {SPR_WIPD, FF_FULLBRIGHT|FF_RANDOMANIM|FF_ANIMATE, 30, {NULL}, 9, 3, S_NULL}, // S_BADNIK_EXPLOSION2 }; mobjinfo_t mobjinfo[NUMMOBJTYPES] = diff --git a/src/info.h b/src/info.h index 96f06786c..a6f13804c 100644 --- a/src/info.h +++ b/src/info.h @@ -4046,6 +4046,11 @@ typedef enum state S_TALKPOINT, S_TALKPOINT_ORB, + S_BADNIK_EXPLOSION_SHOCKWAVE1, + S_BADNIK_EXPLOSION_SHOCKWAVE2, + S_BADNIK_EXPLOSION1, + S_BADNIK_EXPLOSION2, + S_FIRSTFREESLOT, S_LASTFREESLOT = S_FIRSTFREESLOT + NUMSTATEFREESLOTS - 1, NUMSTATES diff --git a/src/p_inter.c b/src/p_inter.c index 6f3048190..af00fc722 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1634,6 +1634,40 @@ boolean P_CheckRacers(void) return false; } +static void P_SpawnBadnikExplosion(mobj_t *target) +{ + UINT8 count = 24; + angle_t ang = 0; + angle_t step = ANGLE_MAX / count; + fixed_t spd = 8 * mapobjectscale; + for (UINT8 i = 0; i < count; ++i) + { + mobj_t *x = P_SpawnMobjFromMobjUnscaled( + target, + P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale, + P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale, + P_RandomRange(PR_EXPLOSION, -48, 48) * target->scale, + MT_THOK + ); + P_InstaScale(x, 3 * x->scale / 2); + P_InstaThrust(x, ang, spd); + x->momz = P_RandomRange(PR_EXPLOSION, -4, 4) * mapobjectscale; + P_SetMobjStateNF(x, S_BADNIK_EXPLOSION1); + ang += step; + } + // burst effects (copied from MT_ITEMCAPSULE) + ang = FixedAngle(360*P_RandomFixed(PR_ITEM_DEBRIS)); + for (UINT8 i = 0; i < 2; i++) + { + mobj_t *blast = P_SpawnMobjFromMobj(target, 0, 0, target->info->height >> 1, MT_BATTLEBUMPER_BLAST); + blast->angle = ang + i*ANGLE_90; + P_SetScale(blast, 2*blast->scale/3); + blast->destscale = 6*blast->scale; + blast->scalespeed = (blast->destscale - blast->scale) / 30; + P_SetMobjStateNF(blast, S_BADNIK_EXPLOSION_SHOCKWAVE1 + i); + } +} + /** Kills an object. * * \param target The victim. @@ -1901,6 +1935,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetObjectMomZ(target, 20*FRACUNIT, false); P_PlayDeathSound(target); + + if (skins[target->player->skin].flags & SF_BADNIK) + { + P_SpawnBadnikExplosion(target); + } } // Prisons Free Play: don't eliminate P1 for diff --git a/src/r_skins.c b/src/r_skins.c index a7ffc6f89..7ae373015 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -872,6 +872,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value) // 1, true, yes are all valid values GETFLAG(MACHINE) GETFLAG(IRONMAN) + GETFLAG(BADNIK) #undef GETFLAG else // let's check if it's a sound, otherwise error out