From 72d77f7fb5a1963cab9a42a9cad171da6dd99ad2 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 8 May 2022 03:43:53 -0400 Subject: [PATCH] Invincibility updates - You flash white while in invincibility - Invincibility is not rainbow UNTIL you go above the initial timer. - Increased visibility of the shield effect around invincible players. - Invincibility sparkles have trailing afterimages. - Disabled invincibility speed lines; they now use the normal speedlines but grey/rainbow. (The code/sprites will be used for something later.) - Using invincibility adds time, instead of setting it. - Player hitbox is finally bigger, to actually match the shadow size. --- src/deh_tables.c | 4 +- src/doomdef.h | 2 + src/info.c | 14 +-- src/k_kart.c | 224 ++++++++++++++++++++++++++++------------------- src/p_enemy.c | 10 ++- src/p_mobj.c | 11 +-- src/p_user.c | 4 +- 7 files changed, 160 insertions(+), 109 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index a8fd4612c..7b77c54a7 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6170,7 +6170,9 @@ const char *COLOR_ENUMS[] = { "CHAOSEMERALD4", "CHAOSEMERALD5", "CHAOSEMERALD6", - "CHAOSEMERALD7" + "CHAOSEMERALD7", + + "INVINCFLASH" }; const char *const KARTHUD_LIST[] = { diff --git a/src/doomdef.h b/src/doomdef.h index 7489e4688..4d16e5547 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -398,6 +398,8 @@ typedef enum SKINCOLOR_CHAOSEMERALD6, SKINCOLOR_CHAOSEMERALD7, + SKINCOLOR_INVINCFLASH, + SKINCOLOR_FIRSTFREESLOT, SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1, diff --git a/src/info.c b/src/info.c index 672c0401d..8ee2f2ca4 100644 --- a/src/info.c +++ b/src/info.c @@ -4232,10 +4232,10 @@ state_t states[NUMSTATES] = {SPR_KINB, FF_FULLBRIGHT|10, 1, {A_InvincSparkleRotate}, 0, 0, S_KARTINVULNB12}, // S_KARTINVULNB11 {SPR_KINB, FF_FULLBRIGHT|11, 1, {A_InvincSparkleRotate}, 0, 0, S_NULL}, // S_KARTINVULNB12 - {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 - {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 - {SPR_KINF, FF_FULLBRIGHT|FF_TRANS90|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 - {SPR_NULL, FF_FULLBRIGHT|FF_TRANS90, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH2}, // S_INVULNFLASH1 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH3}, // S_INVULNFLASH2 + {SPR_KINF, FF_FULLBRIGHT|FF_TRANS80|FF_ADD|1, 1, {NULL}, 0, 0, S_INVULNFLASH4}, // S_INVULNFLASH3 + {SPR_NULL, FF_FULLBRIGHT|FF_TRANS80|FF_ADD, 1, {NULL}, 0, 0, S_INVULNFLASH1}, // S_INVULNFLASH4 {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_KARTINVLINES2}, // S_KARTINVLINES1 {SPR_INVI, FF_FULLBRIGHT|FF_PAPERSPRITE|1, 1, {NULL}, 0, 0, S_KARTINVLINES3}, // S_KARTINVLINES2 @@ -5398,7 +5398,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 1, // speed - 16*FRACUNIT, // radius + 24*FRACUNIT, // radius 48*FRACUNIT, // height 0, // display offset 1000, // mass @@ -29518,7 +29518,9 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Chaos Emerald 4", { 0, 144, 146, 147, 149, 165, 167, 169, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD4 {"Chaos Emerald 5", { 0, 1, 144, 4, 9, 170, 14, 21, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD5 {"Chaos Emerald 6", { 0, 208, 50, 32, 34, 37, 40, 44, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD6 - {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_CHAOSEMERALD7 + {"Chaos Emerald 7", { 0, 120, 121, 140, 133, 135, 149, 156, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_CHAOSEMERALD7 + + {"Invinc Flash", { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, SKINCOLOR_NONE, 0, 0, false} // SKINCOLOR_INVINCFLASH }; /** Patches the mobjinfo, state, and skincolor tables. diff --git a/src/k_kart.c b/src/k_kart.c index 92fda8de3..6c9872867 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2110,26 +2110,42 @@ void K_SpawnNormalSpeedLines(player_t *player) fast->color = SKINCOLOR_RED; fast->colorized = true; } + else if (player->invincibilitytimer) + { + const tic_t defaultTime = itemtime+(2*TICRATE); + if (player->invincibilitytimer > defaultTime) + { + fast->color = player->mo->color; + } + else + { + fast->color = SKINCOLOR_INVINCFLASH; + } + fast->colorized = true; + } } void K_SpawnInvincibilitySpeedLines(mobj_t *mo) { mobj_t *fast = P_SpawnMobjFromMobj(mo, P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(-48, 48) * FRACUNIT, - P_RandomRange(0, 64) * FRACUNIT, - MT_FASTLINE); + P_RandomRange(-48, 48) * FRACUNIT, + P_RandomRange(0, 64) * FRACUNIT, + MT_FASTLINE); + P_SetMobjState(fast, S_KARTINVLINES1); + + P_SetTarget(&fast->target, mo); + P_InitAngle(fast, K_MomentumAngle(mo)); fast->momx = 3*mo->momx/4; fast->momy = 3*mo->momy/4; fast->momz = 3*P_GetMobjZMovement(mo)/4; - P_SetTarget(&fast->target, mo); - P_InitAngle(fast, K_MomentumAngle(mo)); + K_MatchGenericExtraFlags(fast, mo); + fast->color = mo->color; fast->colorized = true; - K_MatchGenericExtraFlags(fast, mo); - P_SetMobjState(fast, S_KARTINVLINES1); + if (mo->player->invincibilitytimer < 10*TICRATE) fast->destscale = 6*((mo->player->invincibilitytimer/TICRATE)*FRACUNIT)/8; } @@ -4468,7 +4484,6 @@ void K_SpawnSparkleTrail(mobj_t *mo) { const INT32 rad = (mo->radius*3)/FRACUNIT; mobj_t *sparkle; - INT32 i; UINT8 invanimnum; // Current sparkle animation number INT32 invtime;// Invincibility time left, in seconds UINT8 index = 0; @@ -4477,13 +4492,6 @@ void K_SpawnSparkleTrail(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - if ((mo->player->sneakertimer - || mo->player->ringboost || mo->player->driftboost - || mo->player->startboost || mo->player->eggmanexplode)) - { - return; - } - if (leveltime & 2) index = 1; @@ -4491,34 +4499,37 @@ void K_SpawnSparkleTrail(mobj_t *mo) //CONS_Printf("%d\n", index); - for (i = 0; i < 8; i++) - { - newx = mo->x + (P_RandomRange(-rad, rad)*FRACUNIT); - newy = mo->y + (P_RandomRange(-rad, rad)*FRACUNIT); - newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT); + newx = mo->x + (P_RandomRange(-rad, rad)*FRACUNIT); + newy = mo->y + (P_RandomRange(-rad, rad)*FRACUNIT); + newz = mo->z + (P_RandomRange(0, mo->height>>FRACBITS)*FRACUNIT); - sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); - P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y)); - sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. - //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); - sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose. - sparkle->extravalue2 = P_RandomRange(0, 1) ? 1 : -1; // Rotation direction? - sparkle->cvmem = P_RandomRange(-25, 25)*mo->scale; // Vertical "angle" - K_FlipFromObject(sparkle, mo); + sparkle = P_SpawnMobj(newx, newy, newz, MT_SPARKLETRAIL); - //if (i == 0) - //P_SetMobjState(sparkle, S_KARTINVULN_LARGE1); + P_InitAngle(sparkle, R_PointToAngle2(mo->x, mo->y, sparkle->x, sparkle->y)); - P_SetTarget(&sparkle->target, mo); - sparkle->destscale = mo->destscale; - P_SetScale(sparkle, mo->scale); - } + sparkle->movefactor = R_PointToDist2(mo->x, mo->y, sparkle->x, sparkle->y); // Save the distance we spawned away from the player. + //CONS_Printf("movefactor: %d\n", sparkle->movefactor/FRACUNIT); + + sparkle->extravalue1 = (sparkle->z - mo->z); // Keep track of our Z position relative to the player's, I suppose. + sparkle->extravalue2 = P_RandomRange(0, 1) ? 1 : -1; // Rotation direction? + sparkle->cvmem = P_RandomRange(-25, 25)*mo->scale; // Vertical "angle" + + K_FlipFromObject(sparkle, mo); + P_SetTarget(&sparkle->target, mo); + + sparkle->destscale = mo->destscale; + P_SetScale(sparkle, mo->scale); invanimnum = (invtime >= 11) ? 11 : invtime; //CONS_Printf("%d\n", invanimnum); + P_SetMobjState(sparkle, K_SparkleTrailStartStates[invanimnum][index]); - sparkle->colorized = true; - sparkle->color = mo->color; + + if (mo->player->invincibilitytimer > itemtime+(2*TICRATE)) + { + sparkle->color = mo->color; + sparkle->colorized = true; + } } void K_SpawnWipeoutTrail(mobj_t *mo) @@ -6948,9 +6959,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) || player->driftboost || player->startboost || player->eggmanexplode || player->trickboost) { +#if 0 if (player->invincibilitytimer) K_SpawnInvincibilitySpeedLines(player->mo); else +#endif K_SpawnNormalSpeedLines(player); } @@ -7030,56 +7043,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - else if (player->eggmanexplode) // You're gonna diiiiie - { - const INT32 flashtime = 4<<(player->eggmanexplode/TICRATE); - if (player->eggmanexplode == 1 || (player->eggmanexplode % (flashtime/2) != 0)) - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - else if (player->eggmanexplode % flashtime == 0) - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_BLACK; - } - else - { - player->mo->colorized = true; - player->mo->color = SKINCOLOR_CRIMSON; - } - } - else if (player->invincibilitytimer) // setting players to use the star colormap and spawning afterimages - { - player->mo->colorized = true; - } - else if (player->growshrinktimer) // Ditto, for grow/shrink - { - if (player->growshrinktimer % 5 == 0) - { - player->mo->colorized = true; - player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); - } - else - { - player->mo->colorized = (player->dye != 0); - player->mo->color = player->dye ? player->dye : player->skincolor; - } - } - else if (player->ringboost && (leveltime & 1)) // ring boosting - { - player->mo->colorized = true; - } - else - { - player->mo->colorized = (player->dye != 0); - } - if (player->itemtype == KITEM_NONE) player->pflags &= ~PF_HOLDREADY; @@ -7426,9 +7389,90 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) void K_KartPlayerAfterThink(player_t *player) { - if (player->curshield - || player->invincibilitytimer - || (player->growshrinktimer != 0 && player->growshrinktimer % 5 == 4)) // 4 instead of 0 because this is afterthink! + boolean fullbright = false; + + if (player->playerstate == PST_DEAD || (player->respawn.state == RESPAWNST_MOVE)) // Ensure these are set correctly here + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + else if (player->eggmanexplode) // You're gonna diiiiie + { + const INT32 flashtime = 4<<(player->eggmanexplode/TICRATE); + if (player->eggmanexplode == 1 || (player->eggmanexplode % (flashtime/2) != 0)) + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + else if (player->eggmanexplode % flashtime == 0) + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_BLACK; + fullbright = true; + } + else + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_CRIMSON; + fullbright = true; + } + } + else if (player->invincibilitytimer) + { + const tic_t defaultTime = itemtime+(2*TICRATE); + tic_t flicker = 2; + + fullbright = true; + + if (player->invincibilitytimer > defaultTime) + { + player->mo->color = K_RainbowColor(leveltime / 2); + player->mo->colorized = true; + } + else + { + player->mo->color = player->skincolor; + player->mo->colorized = false; + + flicker += (defaultTime - player->invincibilitytimer) / TICRATE / 2; + } + + if (leveltime % flicker == 0) + { + player->mo->color = SKINCOLOR_INVINCFLASH; + player->mo->colorized = true; + } + } + else if (player->growshrinktimer) // Ditto, for grow/shrink + { + if (player->growshrinktimer % 5 == 0) + { + player->mo->colorized = true; + player->mo->color = (player->growshrinktimer < 0 ? SKINCOLOR_CREAMSICLE : SKINCOLOR_PERIWINKLE); + fullbright = true; + } + else + { + player->mo->colorized = (player->dye != 0); + player->mo->color = player->dye ? player->dye : player->skincolor; + } + } + else if (player->ringboost && (leveltime & 1)) // ring boosting + { + player->mo->colorized = true; + fullbright = true; + } + else + { + player->mo->colorized = (player->dye != 0); + } + + if (player->curshield) + { + fullbright = true; + } + + if (fullbright == true) { player->mo->frame |= FF_FULLBRIGHT; } @@ -9272,7 +9316,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) overlay->destscale = player->mo->scale; P_SetScale(overlay, player->mo->scale); } - player->invincibilitytimer = itemtime+(2*TICRATE); // 10 seconds + player->invincibilitytimer += itemtime+(2*TICRATE); // 10 seconds if (P_IsLocalPlayer(player) == true) { diff --git a/src/p_enemy.c b/src/p_enemy.c index 0edfbb5e8..4d96fb9a1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4047,7 +4047,7 @@ void A_AttractChase(mobj_t *actor) } else { - fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1); + fixed_t dist = (4*actor->target->scale) * (16 - actor->extravalue1); P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); actor->z = actor->target->z; @@ -14748,6 +14748,7 @@ void A_FlameShieldPaper(mobj_t *actor) void A_InvincSparkleRotate(mobj_t *actor) { fixed_t sx, sy, sz; // Teleport dests. + mobj_t *ghost = NULL; if (LUA_CallAction(A_INVINCSPARKLEROTATE, actor)) return; @@ -14766,4 +14767,11 @@ void A_InvincSparkleRotate(mobj_t *actor) actor->momz = actor->target->momz; // Give momentum for eventual interp builds idk. actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose. + + ghost = P_SpawnGhostMobj(actor); + if (ghost != NULL && P_MobjWasRemoved(ghost) == false) + { + ghost->frame |= FF_ADD; + ghost->fuse = 4; + } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 00744229f..7586a4c75 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7175,15 +7175,6 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_Thrust(smoke, mobj->angle+FixedAngle(P_RandomRange(135, 225)<target->scale); } break; - case MT_SPARKLETRAIL: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return false; - } - mobj->color = mobj->target->color; - mobj->colorized = mobj->target->colorized; - break; case MT_INVULNFLASH: if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->invincibilitytimer)) { @@ -9649,6 +9640,8 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) { case MT_PLAYER: case MT_KART_LEFTOVER: + thing->shadowscale = FRACUNIT; + break; case MT_SMALLMACE: case MT_BIGMACE: case MT_PUMA: diff --git a/src/p_user.c b/src/p_user.c index 8cc74c837..51016d80e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1672,15 +1672,15 @@ static void P_CheckInvincibilityTimer(player_t *player) if (!player->invincibilitytimer) return; - player->mo->color = K_RainbowColor(leveltime); - // Resume normal music stuff. if (player->invincibilitytimer == 1) { player->mo->color = player->skincolor; + player->mo->colorized = false; G_GhostAddColor((INT32) (player - players), GHC_NORMAL); P_RestoreMusic(player); + return; } }