From 0969ca1af928438dd9c0ead327faf39bc1dbae8a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 24 Oct 2020 11:27:42 -0400 Subject: [PATCH] Karma bombs rework - Fixed the bugs with them in our last netgame - Karma bombs are no longer slippery or have stat changes - Karma bombs cannot pick up spheres. Their remaining spheres before they died are removed 1 per tic. - Karma bombs are out of the game permanently when touching the overtime barrier - When successfully hurting another player, instead of getting 0.5 bumpers, they steal ALL of the opponent's bumpers, effectively swapping places with them. One bumper is lost in the process, meaning bumpers are slowly flitered out the more people need to come back. - Removed karma items/eggboxes... hopefully this is temporary and we can bring them back later, but currently we don't have a design for how they should work under the new rules :x. They are still in the code behind the `OTHERKARMAMODES` define - Bumpers & comeback timer are now player_t variables instead of kartstuff shit - eliminated boolean on player_t for checking when a player touched the barrier --- src/d_clisrv.c | 8 +++ src/d_clisrv.h | 3 + src/d_player.h | 3 + src/doomdef.h | 3 + src/g_game.c | 16 +++--- src/k_battle.c | 12 ++-- src/k_collide.c | 10 +++- src/k_hud.c | 95 +++++++++++++------------------ src/k_kart.c | 139 ++++++++++++++++++++++------------------------ src/k_kart.h | 2 +- src/lua_baselib.c | 3 +- src/p_enemy.c | 8 +-- src/p_inter.c | 113 ++++++++++++++++++------------------- src/p_map.c | 4 +- src/p_mobj.c | 32 +++++------ src/p_saveg.c | 8 +++ src/p_user.c | 2 +- 17 files changed, 235 insertions(+), 226 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 867a3e006..a3764913e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -616,6 +616,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->airtime = (tic_t)LONG(players[i].airtime); + rsp->bumpers = SHORT(players[i].bumpers); + rsp->karmadelay = SHORT(players[i].karmadelay); + rsp->eliminated = players[i].eliminated; + // respawnvars_t rsp->respawn_state = players[i].respawn.state; rsp->respawn_pointx = (fixed_t)LONG(players[i].respawn.pointx); @@ -760,6 +764,10 @@ static void resynch_read_player(resynch_pak *rsp) players[i].airtime = (tic_t)LONG(rsp->airtime); + players[i].bumpers = SHORT(rsp->bumpers); + players[i].karmadelay = SHORT(rsp->karmadelay); + players[i].eliminated = rsp->eliminated; + // respawnvars_t players[i].respawn.state = rsp->respawn_state; players[i].respawn.pointx = (fixed_t)LONG(rsp->respawn_pointx); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 573c98dc8..4adfda142 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -281,6 +281,9 @@ typedef struct // SRB2kart INT32 kartstuff[NUMKARTSTUFF]; tic_t airtime; + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // respawnvars_t UINT8 respawn_state; diff --git a/src/d_player.h b/src/d_player.h index 36829fecc..77e5e35a3 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -509,6 +509,9 @@ typedef struct player_s waypoint_t *nextwaypoint; respawnvars_t respawn; // Respawn info tic_t airtime; // Keep track of how long you've been in the air + INT16 bumpers; + INT16 karmadelay; + boolean eliminated; // Bit flags. // See pflags_t, above. diff --git a/src/doomdef.h b/src/doomdef.h index b1960b507..6cfbd7105 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -655,6 +655,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Camera always has noclip. #define NOCLIPCAM +/// Other karma comeback modes +//#define OTHERKARMAMODES + /// MIDI support is really shitty -- we don't use it anyway, so lets throw it behind a define #define NO_MIDI diff --git a/src/g_game.c b/src/g_game.c index 7b91c0e85..40f8a9b67 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1575,7 +1575,7 @@ boolean G_CouldView(INT32 playernum) // I don't know if we want this actually, but I'll humor the suggestion anyway if ((gametyperules & GTR_BUMPERS) && !demo.playback) { - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return false; } @@ -2072,9 +2072,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) INT32 roulettetype; INT32 growshrinktimer; INT32 bumper; - INT32 comebackpoints; INT32 wanted; boolean songcredit = false; + boolean eliminated; score = players[player].score; marescore = players[player].marescore; @@ -2143,7 +2143,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0); rings = ((gametyperules & GTR_SPHERES) ? 0 : 5); spheres = 0; - comebackpoints = 0; + eliminated = false; wanted = 0; } else @@ -2168,10 +2168,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) else growshrinktimer = 0; - bumper = players[player].kartstuff[k_bumper]; + bumper = players[player].bumpers; rings = players[player].rings; spheres = players[player].spheres; - comebackpoints = players[player].kartstuff[k_comebackpoints]; + eliminated = players[player].eliminated; wanted = players[player].kartstuff[k_wanted]; } @@ -2230,9 +2230,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->kartstuff[k_itemtype] = itemtype; p->kartstuff[k_itemamount] = itemamount; p->kartstuff[k_growshrinktimer] = growshrinktimer; - p->kartstuff[k_bumper] = bumper; - p->kartstuff[k_comebackpoints] = comebackpoints; - p->kartstuff[k_comebacktimer] = comebacktime; + p->bumpers = bumper; + p->karmadelay = comebacktime; + p->eliminated = eliminated; p->kartstuff[k_wanted] = wanted; p->kartstuff[k_eggmanblame] = -1; p->kartstuff[k_lastdraft] = -1; diff --git a/src/k_battle.c b/src/k_battle.c index ddbf649bd..518ae260f 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -89,24 +89,24 @@ void K_CalculateBattleWanted(void) numplaying++; - if (players[i].kartstuff[k_bumper] <= 0) // Not alive, so don't do anything else + if (players[i].bumpers <= 0) // Not alive, so don't do anything else continue; numingame++; - if (bestbumper == -1 || players[i].kartstuff[k_bumper] > bestbumper) + if (bestbumper == -1 || players[i].bumpers > bestbumper) { - bestbumper = players[i].kartstuff[k_bumper]; + bestbumper = players[i].bumpers; bestbumperplayer = i; } - else if (players[i].kartstuff[k_bumper] == bestbumper) + else if (players[i].bumpers == bestbumper) bestbumperplayer = -1; // Tie, no one has best bumper. for (j = 0; j < MAXPLAYERS; j++) { if (!playeringame[j] || players[j].spectator) continue; - if (players[j].kartstuff[k_bumper] <= 0) + if (players[j].bumpers <= 0) continue; if (j == i) continue; @@ -230,7 +230,7 @@ void K_CheckBumpers(void) numingame++; winnerscoreadd += players[i].marescore; - if (players[i].kartstuff[k_bumper] <= 0) // if you don't have any bumpers, you're probably not a winner + if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner { nobumpers = true; continue; diff --git a/src/k_collide.c b/src/k_collide.c index 56747a47f..963ec4e64 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -219,11 +219,15 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (!P_CanPickupItem(t2->player, 2)) return true; - if ((gametyperules & GTR_BUMPERS) && t2->player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0) { - if (t2->player->kartstuff[k_comebackmode] || t2->player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (t2->player->kartstuff[k_comebackmode] || t2->player->karmadelay) return true; t2->player->kartstuff[k_comebackmode] = 2; +#else + return true; +#endif } else { @@ -253,7 +257,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2) if (t1->target && t1->target->player) { - if ((gametyperules & GTR_CIRCUIT) || t1->target->player->kartstuff[k_bumper] > 0) + if ((gametyperules & GTR_CIRCUIT) || t1->target->player->bumpers > 0) t2->player->kartstuff[k_eggmanblame] = t1->target->player-players; else t2->player->kartstuff[k_eggmanblame] = t2->player-players; diff --git a/src/k_hud.c b/src/k_hud.c index ee33034a6..73e656fcb 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1609,10 +1609,10 @@ static boolean K_drawKartPositionFaces(void) if (LUA_HudEnabled(hud_battlebumpers)) { - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] > 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers > 0) { V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap); - for (j = 1; j < players[rankplayer[i]].kartstuff[k_bumper]; j++) + for (j = 1; j < players[rankplayer[i]].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap); @@ -1624,7 +1624,7 @@ static boolean K_drawKartPositionFaces(void) if (i == strank) V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[rankplayer[i]].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[rankplayer[i]].bumpers <= 0) V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers); else { @@ -1722,11 +1722,11 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE); V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap); - /*if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this + /*if (gametype == GT_BATTLE && players[tab[i].num].bumpers > 0) -- not enough space for this { INT32 bumperx = x+19; V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap); - for (j = 1; j < players[tab[i].num].kartstuff[k_bumper]; j++) + for (j = 1; j < players[tab[i].num].bumpers; j++) { bumperx += 5; V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap); @@ -1737,7 +1737,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN if (tab[i].num == whiteplayer) V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]); - if (gametype == GT_BATTLE && players[tab[i].num].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[tab[i].num].bumpers <= 0) V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers); else { @@ -2088,37 +2088,28 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) + INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); + + if (stplyr->bumpers > 9 || maxbumper > 9) { - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitkarmabomb, colormap); - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_comebackpoints]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[2]); + UINT8 ln[2]; + ln[0] = ((abs(stplyr->bumpers) / 10) % 10); + ln[1] = (abs(stplyr->bumpers) % 10); + + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); + + ln[0] = ((abs(maxbumper) / 10) % 10); + ln[1] = (abs(maxbumper) % 10); + + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); + V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); } else { - INT32 maxbumper = K_StartingBumperCount(); - V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); - - if (stplyr->kartstuff[k_bumper] > 9 || maxbumper > 9) - { - UINT8 ln[2]; - ln[0] = ((abs(stplyr->kartstuff[k_bumper]) / 10) % 10); - ln[1] = (abs(stplyr->kartstuff[k_bumper]) % 10); - - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - - ln[0] = ((abs(maxbumper) / 10) % 10); - ln[1] = (abs(maxbumper) % 10); - - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); - V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); - } - else - { - V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->kartstuff[k_bumper]) % 10]); - V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); - } + V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->bumpers) % 10]); + V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]); } } } @@ -2134,22 +2125,14 @@ static void K_drawKartBumpersOrKarma(void) } else { - if (stplyr->kartstuff[k_bumper] <= 0) - { - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_karmasticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/2", stplyr->kartstuff[k_comebackpoints])); - } + INT32 maxbumper = K_StartingBumperCount(); + + if (stplyr->bumpers > 9 && maxbumper > 9) + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); else - { - INT32 maxbumper = K_StartingBumperCount(); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - if (stplyr->kartstuff[k_bumper] > 9 && maxbumper > 9) - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); - else - V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->kartstuff[k_bumper], maxbumper)); - } + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper)); } } } @@ -2894,7 +2877,7 @@ static void K_drawKartMinimap(void) if (i != displayplayers[0] || r_splitscreen) { - if (gametype == GT_BATTLE && players[i].kartstuff[k_bumper] <= 0) + if (gametype == GT_BATTLE && players[i].bumpers <= 0) continue; if (players[i].kartstuff[k_hyudorotimer] > 0) @@ -3330,9 +3313,9 @@ static void K_drawBattleFullscreen(void) else K_drawKartFinish(); } - else if (stplyr->kartstuff[k_bumper] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback && !stplyr->spectator && drawcomebacktimer) + else if (stplyr->bumpers <= 0 && stplyr->karmadelay && comeback && !stplyr->spectator && drawcomebacktimer) { - UINT16 t = stplyr->kartstuff[k_comebacktimer]/(10*TICRATE); + UINT16 t = stplyr->karmadelay/(10*TICRATE); INT32 txoff, adjust = (r_splitscreen > 1) ? 4 : 6; // normal string is 8, kart string is 12, half of that for ease INT32 ty = (BASEVIDHEIGHT/2)+66; @@ -3362,11 +3345,11 @@ static void K_drawBattleFullscreen(void) V_DrawFixedPatch(x< 1) - V_DrawString(x-txoff, ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); else { V_DrawFixedPatch(x<kartstuff[k_comebacktimer]/TICRATE)); + V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->karmadelay/TICRATE)); } } @@ -3787,8 +3770,8 @@ static void K_drawDistributionDebugger(void) if (!playeringame[i] || players[i].spectator) continue; pingame++; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // lovely double loop...... @@ -3911,8 +3894,8 @@ void K_drawKartHUD(void) battlefullscreen = ((gametype == GT_BATTLE) && (stplyr->exiting - || (stplyr->kartstuff[k_bumper] <= 0 - && stplyr->kartstuff[k_comebacktimer] + || (stplyr->bumpers <= 0 + && stplyr->karmadelay && comeback && stplyr->playerstate == PST_LIVE))); diff --git a/src/k_kart.c b/src/k_kart.c index 6e3d11a9a..80d9546d1 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -207,7 +207,7 @@ boolean K_IsPlayerLosing(player_t *player) INT32 winningpos = 1; UINT8 i, pcount = 0; - if (battlecapsules && player->kartstuff[k_bumper] <= 0) + if (battlecapsules && player->bumpers <= 0) return true; // DNF in break the capsules if (player->kartstuff[k_position] == 1) @@ -456,7 +456,7 @@ INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean spbrush, if (!playeringame[i] || players[i].spectator) continue; - if (!(gametyperules & GTR_BUMPERS) || players[i].kartstuff[k_bumper]) + if (!(gametyperules & GTR_BUMPERS) || players[i].bumpers) pingame++; if (players[i].exiting) @@ -735,8 +735,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) pingame++; if (players[i].exiting) dontforcespb = true; - if (players[i].kartstuff[k_bumper] > bestbumper) - bestbumper = players[i].kartstuff[k_bumper]; + if (players[i].bumpers > bestbumper) + bestbumper = players[i].bumpers; } // No forced SPB in 1v1s, it has to be randomly rolled @@ -2218,12 +2218,8 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed) fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) { fixed_t finalspeed; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - finalspeed = K_GetKartSpeedFromStat(kartspeed); + finalspeed = K_GetKartSpeedFromStat(player->kartspeed); if (player->spheres > 0) { @@ -2234,7 +2230,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) if (K_PlayerUsesBotMovement(player)) { // Give top speed a buff for bots, since it's a fairly weak stat without drifting - fixed_t speedmul = ((kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 + fixed_t speedmul = ((player->kartspeed-1) * FRACUNIT / 8) / 10; // +10% for speed 9 if (player->botvars.rival == true) { @@ -2263,13 +2259,9 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower) fixed_t K_GetKartAccel(player_t *player) { fixed_t k_accel = 32; // 36; - UINT8 kartspeed = player->kartspeed; - if ((gametyperules & (GTR_BUMPERS|GTR_KARMA)) == (GTR_BUMPERS|GTR_KARMA) && player->kartstuff[k_bumper] <= 0) - kartspeed = 1; - - //k_accel += 3 * (9 - kartspeed); // 36 - 60 - k_accel += 4 * (9 - kartspeed); // 32 - 64 + //k_accel += 3 * (9 - player->kartspeed); // 36 - 60 + k_accel += 4 * (9 - player->kartspeed); // 32 - 64 if (player->spheres > 0) { @@ -2417,7 +2409,7 @@ void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean } } -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount) +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force) { UINT8 score = 1; boolean trapitem = false; @@ -2428,8 +2420,11 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a if (!(gametyperules & GTR_BUMPERS)) return; - if (player->powers[pw_flashing] || P_PlayerInPain(player)) - return; + if (force == false) + { + if (player->powers[pw_flashing] || P_PlayerInPain(player)) + return; + } if (inflictor && !P_MobjWasRemoved(inflictor)) { @@ -2443,7 +2438,7 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a { if (K_IsPlayerWanted(player)) score = 3; - else if ((gametyperules & GTR_BUMPERS) && (player->kartstuff[k_bumper] <= amount)) + else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount)) score = 2; } @@ -2452,9 +2447,9 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a K_BattleHitPlayer(source->player, player, score, trapitem); } - if (player->kartstuff[k_bumper] > 0) + if (player->bumpers > 0) { - if (player->kartstuff[k_bumper] <= amount) + if (player->bumpers <= amount) { mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, player->mo); @@ -2463,16 +2458,16 @@ void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 a CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]); } - player->kartstuff[k_bumper] -= amount; + player->bumpers -= amount; if (K_IsPlayerWanted(player)) K_CalculateBattleWanted(); } - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) { - player->kartstuff[k_bumper] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->bumpers = 0; + player->karmadelay = comebacktime; if (player->kartstuff[k_comebackmode] == 2) { @@ -2597,7 +2592,7 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) { - INT32 intendedamount = player->kartstuff[k_bumper] + amount; + INT32 intendedamount = player->bumpers + amount; INT32 newbumper; angle_t newangle, diff; fixed_t newx, newy; @@ -2609,12 +2604,12 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) if (!(gametyperules & GTR_BUMPERS)) return; - if (netgame && player->kartstuff[k_bumper] <= 0) + if (netgame && player->bumpers <= 0) CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]); - while (player->kartstuff[k_bumper] < intendedamount) + while (player->bumpers < intendedamount) { - newbumper = player->kartstuff[k_bumper]; + newbumper = player->bumpers; if (newbumper <= 1) diff = 0; else @@ -2638,18 +2633,17 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount) else P_SetMobjState(newmo, S_BATTLEBUMPER1); - player->kartstuff[k_bumper]++; + player->bumpers++; } S_StartSound(player->mo, sfx_3db06); - player->kartstuff[k_comebackpoints] = 0; player->powers[pw_flashing] = K_GetKartFlashing(player); - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; /* victim->powers[pw_flashing] = K_GetKartFlashing(victim); - victim->kartstuff[k_comebacktimer] = comebacktime; + victim->karmadelay = comebacktime; */ victim->kartstuff[k_instashield] = 15; @@ -3194,7 +3188,7 @@ void K_SpawnBoostTrail(player_t *player) if (!P_IsObjectOnGround(player->mo) || player->kartstuff[k_hyudorotimer] != 0 - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer])) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)) return; if (player->mo->eflags & MFE_VERTICALFLIP) @@ -3878,7 +3872,7 @@ static void K_DoHyudoroSteal(player_t *player) // Can steal from this player && (gametype == GT_RACE //&& players[i].kartstuff[k_position] < player->kartstuff[k_position]) - || ((gametyperules & GTR_BUMPERS) && players[i].kartstuff[k_bumper] > 0)) + || ((gametyperules & GTR_BUMPERS) && players[i].bumpers > 0)) // Has an item && (players[i].kartstuff[k_itemtype] @@ -4958,7 +4952,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) thisang = InvAngle(thisang); // Jawz only go after the person directly ahead of you in race... sort of literally now! - if (gametype == GT_RACE) + if (gametyperules & GTR_CIRCUIT) { // Don't go for people who are behind you if (thisang > ANGLE_67h) @@ -4982,7 +4976,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source) continue; // Don't pay attention to dead players - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) continue; // Z pos too high/low @@ -5259,7 +5253,7 @@ void K_KartPlayerHUDUpdate(player_t *player) player->karthud[khud_ringspblock] = (leveltime % 14); // reset to normal anim next time } - if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->kartstuff[k_comebacktimer])) + if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->karmadelay)) { if (player->exiting) { @@ -5272,9 +5266,9 @@ void K_KartPlayerHUDUpdate(player_t *player) } else { - if (player->kartstuff[k_comebacktimer] < 6*TICRATE) + if (player->karmadelay < 6*TICRATE) player->karthud[khud_cardanimation] -= ((164-player->karthud[khud_cardanimation])/8)+1; - else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) + else if (player->karmadelay < 9*TICRATE) player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1; } @@ -5627,14 +5621,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_wipeoutslow] >= 1) player->mo->friction = ORIG_FRICTION; player->kartstuff[k_wipeoutslow] = 0; - if (!comeback) - player->kartstuff[k_comebacktimer] = comebacktime; - else if (player->kartstuff[k_comebacktimer]) - { - player->kartstuff[k_comebacktimer]--; - if (P_IsDisplayPlayer(player) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - comebackshowninfo = true; // client has already seen the message - } } if (player->rings > 20) @@ -5642,14 +5628,34 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) else if (player->rings < -20) player->rings = -20; - if ((leveltime % TICRATE) == 0) + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + { + // Deplete 1 every tic when removed from the game. player->spheres--; + } + else + { + // Deplete 1 every second when playing. + if ((leveltime % TICRATE) == 0) + player->spheres--; + } if (player->spheres > 40) player->spheres = 40; else if (player->spheres < 0) player->spheres = 0; + if (comeback == false || !(gametyperules & GTR_KARMA) || player->eliminated == true) + { + player->karmadelay = comebacktime; + } + else if (player->karmadelay > 0 && !P_PlayerInPain(player)) + { + player->karmadelay--; + if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0) + comebackshowninfo = true; // client has already seen the message + } + if (player->kartstuff[k_ringdelay]) player->kartstuff[k_ringdelay]--; @@ -5764,7 +5770,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_KartPlayerHUDUpdate(player); - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) + if ((gametyperules & GTR_BUMPERS) && player->bumpers > 0 && !P_PlayerInPain(player) && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; @@ -5779,9 +5785,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (distanceToBarrier > battleovertime.radius) { - //P_KillMobj(player->mo, NULL, NULL, DMG_NORMAL); - player->kartstuff[k_bumper] = 0; - P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL); + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); } } } @@ -5794,7 +5798,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_eggmanexplode]) { - if (player->spectator || (gametype == GT_BATTLE && !player->kartstuff[k_bumper])) + if (player->spectator || (gametype == GT_BATTLE && !player->bumpers)) player->kartstuff[k_eggmanexplode] = 0; else { @@ -5837,7 +5841,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_FlameDashLeftoverSmoke(player->mo); } - if (player->kartstuff[k_comebacktimer]) + if (player->karmadelay) player->kartstuff[k_comebackmode] = 0; if (P_IsObjectOnGround(player->mo) && player->kartstuff[k_pogospring]) @@ -6411,10 +6415,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) INT32 K_GetKartDriftSparkValue(player_t *player) { - UINT8 kartspeed = (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - ? 1 - : player->kartspeed; - return (26*4 + kartspeed*2 + (9 - player->kartweight))*8; + return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8; } /* @@ -6732,8 +6733,8 @@ void K_KartUpdatePosition(player_t *player) { // I have less points than but the same bumpers as this player OR // I have less bumpers than this player - if ((players[i].kartstuff[k_bumper] == player->kartstuff[k_bumper] && players[i].marescore > player->marescore) - || (players[i].kartstuff[k_bumper] > player->kartstuff[k_bumper])) + if ((players[i].bumpers == player->bumpers && players[i].marescore > player->marescore) + || (players[i].bumpers > player->bumpers)) position++; } } @@ -6936,12 +6937,6 @@ void K_AdjustPlayerFriction(player_t *player) } */ - // Karma ice physics - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) - { - player->mo->friction += 1228; - } - // Water gets ice physics too if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) { @@ -7061,7 +7056,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) newitem->fuse = 15*TICRATE; // selected randomly. player->kartstuff[k_comebackmode] = 0; - player->kartstuff[k_comebacktimer] = comebacktime; + player->karmadelay = comebacktime; S_StartSound(player->mo, sfx_s254); } } @@ -7650,14 +7645,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->drawflags &= ~MFD_DONTDRAW; } - if (gametype == GT_BATTLE && player->kartstuff[k_bumper] <= 0) // dead in match? you da bomb + if (gametype == GT_BATTLE && player->bumpers <= 0) // dead in match? you da bomb { K_DropItems(player); //K_StripItems(player); K_StripOther(player); player->mo->drawflags |= MFD_SHADOW; - player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; + player->powers[pw_flashing] = player->karmadelay; } - else if (gametype == GT_RACE || player->kartstuff[k_bumper] > 0) + else if (gametype == GT_RACE || player->bumpers > 0) { player->mo->drawflags &= ~(MFD_TRANSMASK|MFD_BRIGHTMASK); } diff --git a/src/k_kart.h b/src/k_kart.h index 2d682511a..0a4765b32 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -41,7 +41,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted); -void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount); +void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); void K_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9ddbd868e..a7bad0390 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3382,12 +3382,13 @@ static int lib_kStealBumper(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); + UINT8 amount = (UINT8)luaL_optinteger(L, 3, 1); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!victim) return LUA_ErrInvalid(L, "player_t"); - K_StealBumper(player, victim); + K_StealBumper(player, victim, amount); return 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 605ba24b0..fe7bd65aa 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4428,7 +4428,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) return true; if (thing->player && (thing->player->kartstuff[k_hyudorotimer] - || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + || ((gametyperules & GTR_BUMPERS) && thing->player && thing->player->bumpers <= 0 && thing->player->karmadelay))) return true; // see if it went over / under @@ -4493,7 +4493,7 @@ static inline boolean PIT_MineExplode(mobj_t *thing) if (netgame && thing->player && thing->player->spectator) return true; - if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->kartstuff[k_bumper] <= 0 && thing == grenade->target) + if ((gametyperules & GTR_BUMPERS) && grenade->target && grenade->target->player && grenade->target->player->bumpers <= 0 && thing == grenade->target) return true; // see if it went over / under @@ -8641,7 +8641,7 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - if (!((gametyperules & GTR_BUMPERS) && actor->target->player->kartstuff[k_bumper] <= 0)) + if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0)) actor->target->player->kartstuff[k_itemroulette] = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -9707,7 +9707,7 @@ void A_ReaperThinker(mobj_t *actor) continue; player = &players[i]; - if (player && player->mo && player->kartstuff[k_bumper] && player->score >= maxscore) + if (player && player->mo && player->bumpers && player->score >= maxscore) { targetplayermo = player->mo; maxscore = player->score; diff --git a/src/p_inter.c b/src/p_inter.c index 82a11f3df..c23221ae1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -111,7 +111,7 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) if (player->exiting || mapreset) return false; - /*if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) // No bumpers in Match + /*if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) // No bumpers in Match return false;*/ if (weapon) @@ -235,7 +235,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 3) || (player->kartstuff[k_itemamount] && player->kartstuff[k_itemtype] != special->threshold)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return; player->kartstuff[k_itemtype] = special->threshold; @@ -256,11 +256,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!P_CanPickupItem(player, 1)) return; - if ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0) + if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) { - if (player->kartstuff[k_comebackmode] || player->kartstuff[k_comebacktimer]) +#ifdef OTHERKARMAMODES + if (player->kartstuff[k_comebackmode] || player->karmadelay) return; player->kartstuff[k_comebackmode] = 1; +#else + return; +#endif } special->momx = special->momy = special->momz = 0; @@ -272,7 +276,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (player == special->target->player) return; - if (player->kartstuff[k_bumper] <= 0) + if (player->bumpers <= 0) return; if (special->target->player->exiting || player->exiting) return; @@ -280,53 +284,41 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (P_PlayerInPain(special->target->player)) return; + if (special->target->player->karmadelay > 0) + return; + +#ifdef OTHERKARMAMODES if (!special->target->player->kartstuff[k_comebackmode]) { - if (player->kartstuff[k_growshrinktimer] || player->kartstuff[k_squishedtimer] - || player->kartstuff[k_hyudorotimer] || P_PlayerInPain(player) - || player->kartstuff[k_invincibilitytimer] || player->powers[pw_flashing]) - return; - else +#endif { - mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); - UINT8 ptadd = (K_IsPlayerWanted(player) ? 2 : 1); + mobj_t *boom; + + if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false) + { + return; + } + + boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); boom->scale = special->target->scale; boom->destscale = special->target->scale; boom->momz = 5*FRACUNIT; + if (special->target->color) boom->color = special->target->color; else boom->color = SKINCOLOR_KETCHUP; + S_StartSound(boom, special->info->attacksound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 - { - INT32 numingame = 0; + K_StealBumper(special->target->player, player, max(1, player->bumpers-1)); // bumpers-1 to slowly remove bumpers from the economy + K_RemoveBumper(player, special->target, special->target, player->bumpers, true); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) - continue; - numingame++; - } - - if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill - ptadd++; - } - - special->target->player->kartstuff[k_comebackpoints] += ptadd; - - if (ptadd > 1) - special->target->player->karthud[khud_yougotem] = 2*TICRATE; - - if (special->target->player->kartstuff[k_comebackpoints] >= 2) - K_StealBumper(special->target->player, player, 1); - - special->target->player->kartstuff[k_comebacktimer] = comebacktime; - - P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE); + special->target->player->karthud[khud_yougotem] = 2*TICRATE; + special->target->player->karmadelay = comebacktime; } +#ifdef OTHERKARMAMODES } else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) { @@ -350,7 +342,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; player->kartstuff[k_itemroulette] = 1; player->kartstuff[k_roulettetype] = 1; @@ -362,13 +354,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(poof, special->info->seesound); - if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 + if (player->bumpers == 1) // If you have only one bumper left, and see if it's a 1v1 { INT32 numingame = 0; for (i = 0; i < MAXPLAYERS; i++) { - if (!playeringame[i] || players[i].spectator || players[i].kartstuff[k_bumper] <= 0) + if (!playeringame[i] || players[i].spectator || players[i].bumpers <= 0) continue; numingame++; } @@ -386,7 +378,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->target->player->kartstuff[k_comebackpoints] >= 2) K_StealBumper(special->target->player, player, 1); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + special->target->player->karmadelay = comebacktime; K_DropItems(player); //K_StripItems(player); //K_StripOther(player); @@ -404,6 +396,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->target->player->kartstuff[k_eggmanblame] = -1; } +#endif return; case MT_SPB: if ((special->target == toucher || special->target == toucher->target) && (special->threshold > 0)) @@ -474,7 +467,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(special, sfx_s1a2); return; case MT_CDUFO: // SRB2kart - if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0)) + if (special->fuse || !P_CanPickupItem(player, 1) || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)) return; player->kartstuff[k_itemroulette] = 1; @@ -561,6 +554,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->spheres >= 40) return; + // Not alive + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + return; + special->momx = special->momy = special->momz = 0; player->spheres++; break; @@ -1665,7 +1662,7 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) { case DMG_DEATHPIT: // Respawn kill types - K_RemoveBumper(player, NULL, NULL, 1); + K_RemoveBumper(player, NULL, NULL, 1, true); K_DoIngameRespawn(player); return false; default: @@ -1673,8 +1670,6 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) break; } - K_RemoveBumper(player, NULL, NULL, player->kartstuff[k_bumper]); - player->pflags &= ~PF_SLIDING; player->powers[pw_carry] = CR_NONE; @@ -1690,17 +1685,23 @@ static boolean P_KillPlayer(player_t *player, UINT8 type) P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if ((type == DMG_TIMEOVER) && (gametype == GT_RACE)) + if (type == DMG_TIMEOVER) { - mobj_t *boom; + if (gametyperules & GTR_CIRCUIT) + { + mobj_t *boom; - player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); - player->mo->drawflags |= MFD_DONTDRAW; + player->mo->flags |= (MF_NOGRAVITY|MF_NOCLIP); + player->mo->drawflags |= MFD_DONTDRAW; - boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); - boom->scale = player->mo->scale; - boom->angle = player->mo->angle; - P_SetTarget(&boom->target, player->mo); + boom = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_FZEROBOOM); + boom->scale = player->mo->scale; + boom->angle = player->mo->angle; + P_SetTarget(&boom->target, player->mo); + } + + K_RemoveBumper(player, NULL, NULL, player->bumpers, true); + player->eliminated = true; } return true; @@ -1849,9 +1850,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (gametyperules & GTR_BUMPERS) { - if ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || (player->kartstuff[k_comebackmode] == 1)) + if ((player->bumpers <= 0 && player->karmadelay) || (player->kartstuff[k_comebackmode] == 1)) { - // No bumpers, can't be hurt + // No bumpers & in WAIT, can't be hurt K_DoInstashield(player); return false; } @@ -1900,7 +1901,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da K_StealBumper(source->player, player, bumpadd); } - K_RemoveBumper(player, inflictor, source, bumpadd); + K_RemoveBumper(player, inflictor, source, bumpadd, false); } player->kartstuff[k_sneakertimer] = player->kartstuff[k_numsneakers] = 0; diff --git a/src/p_map.c b/src/p_map.c index 4a33b5427..f213c2d37 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1294,8 +1294,8 @@ static boolean PIT_CheckThing(mobj_t *thing) } if ((gametyperules & GTR_BUMPERS) - && ((thing->player->kartstuff[k_bumper] && !tmthing->player->kartstuff[k_bumper]) - || (tmthing->player->kartstuff[k_bumper] && !thing->player->kartstuff[k_bumper]))) + && ((thing->player->bumpers && !tmthing->player->bumpers) + || (tmthing->player->bumpers && !thing->player->bumpers))) { return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 9957f4114..7eecebb62 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5286,10 +5286,10 @@ static void P_MobjSceneryThink(mobj_t *mobj) else ang = FixedAngle(mobj->info->speed); - if (mobj->target->player->kartstuff[k_bumper] <= 1) + if (mobj->target->player->bumpers <= 1) diff = 0; else - diff = FixedAngle(360*FRACUNIT/mobj->target->player->kartstuff[k_bumper]); + diff = FixedAngle(360*FRACUNIT/mobj->target->player->bumpers); ang = (ang*leveltime) + (diff * (mobj->threshold-1)); @@ -5318,9 +5318,9 @@ static void P_MobjSceneryThink(mobj_t *mobj) else mobj->color = mobj->target->color; // but do so if it belongs to you :B - if (mobj->target->player->kartstuff[k_bumper] < 2) + if (mobj->target->player->bumpers < 2) P_SetMobjState(mobj, S_BATTLEBUMPER3); - else if (mobj->target->player->kartstuff[k_bumper] < 3) + else if (mobj->target->player->bumpers < 3) P_SetMobjState(mobj, S_BATTLEBUMPER2); else P_SetMobjState(mobj, S_BATTLEBUMPER1); @@ -5338,7 +5338,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) } // Was this so hard? - if (mobj->target->player->kartstuff[k_bumper] <= mobj->threshold) + if (mobj->target->player->bumpers <= mobj->threshold) { P_RemoveMobj(mobj); return; @@ -5363,7 +5363,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->color = mobj->target->color; K_MatchGenericExtraFlags(mobj, mobj->target); - if ((gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper] <= 0) + if ((gametype == GT_RACE || mobj->target->player->bumpers <= 0) #if 1 // Set to 0 to test without needing to host || (P_IsDisplayPlayer(mobj->target->player)) #endif @@ -7019,7 +7019,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) statenum_t state = (mobj->state-states); if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator - || (gametype == GT_RACE || mobj->target->player->kartstuff[k_bumper])) + || (gametype == GT_RACE || mobj->target->player->bumpers)) { P_RemoveMobj(mobj); return false; @@ -7040,11 +7040,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->radius = 24*mobj->target->scale; mobj->height = 2*mobj->radius; - if (mobj->target->player->kartstuff[k_comebacktimer] > 0) + if (mobj->target->player->karmadelay > 0) { if (state < S_PLAYERBOMB1 || state > S_PLAYERBOMB20) P_SetMobjState(mobj, S_PLAYERBOMB1); - if (mobj->target->player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) + if (mobj->target->player->karmadelay < TICRATE && (leveltime & 1)) mobj->drawflags &= ~MFD_DONTDRAW; else mobj->drawflags |= MFD_DONTDRAW; @@ -10153,22 +10153,22 @@ void P_SpawnPlayer(INT32 playernum) P_SetScale(overheadarrow, mobj->destscale); if (p->spectator && pcount > 1) // HEY! No being cheap... - p->kartstuff[k_bumper] = 0; - else if (p->kartstuff[k_bumper] > 0 || leveltime < 1 + p->bumpers = 0; + else if (p->bumpers > 0 || leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) { if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map? - p->kartstuff[k_bumper] = K_StartingBumperCount(); // Reset those bumpers! + p->bumpers = K_StartingBumperCount(); // Reset those bumpers! - if (p->kartstuff[k_bumper]) + if (p->bumpers) { - angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]); + angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers); angle_t newangle = mobj->angle; fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); mobj_t *mo; - for (i = 0; i < p->kartstuff[k_bumper]; i++) + for (i = 0; i < p->bumpers; i++) { mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER); mo->threshold = i; @@ -10182,7 +10182,7 @@ void P_SpawnPlayer(INT32 playernum) } } } - else if (p->kartstuff[k_bumper] <= 0) + else if (p->bumpers <= 0) { mobj_t *karmahitbox = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_KARMAHITBOX); // Player hitbox is too small!! P_SetTarget(&karmahitbox->target, mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index c9797000e..b3ea81ecd 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -255,6 +255,10 @@ static void P_NetArchivePlayers(void) WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint)); WRITEUINT32(save_p, players[i].airtime); + WRITEINT16(save_p, players[i].bumpers); + WRITEINT16(save_p, players[i].karmadelay); + WRITEUINT8(save_p, players[i].eliminated); + // respawnvars_t WRITEUINT8(save_p, players[i].respawn.state); WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].respawn.wp)); @@ -441,6 +445,10 @@ static void P_NetUnArchivePlayers(void) players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p); players[i].airtime = READUINT32(save_p); + players[i].bumpers = READINT16(save_p); + players[i].karmadelay = READINT16(save_p); + players[i].eliminated = (boolean)READUINT8(save_p); + // respawnvars_t players[i].respawn.state = READUINT8(save_p); players[i].respawn.wp = (waypoint_t *)(size_t)READUINT32(save_p); diff --git a/src/p_user.c b/src/p_user.c index 2a67d8360..9cf365ab5 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4515,7 +4515,7 @@ void P_PlayerThink(player_t *player) || player->kartstuff[k_growshrinktimer] > 0 // Grow doesn't flash either. || (player->respawn.state != RESPAWNST_NONE) // Respawn timer (for drop dash effect) || (player->pflags & PF_GAMETYPEOVER) // NO CONTEST explosion - || ((gametyperules & GTR_BUMPERS) && player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) + || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay) || leveltime < starttime)) // Level intro { if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < K_GetKartFlashing(player)