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
This commit is contained in:
Sally Coolatta 2020-10-24 11:27:42 -04:00
parent cc1268cdf3
commit 0969ca1af9
17 changed files with 235 additions and 226 deletions

View file

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

View file

@ -281,6 +281,9 @@ typedef struct
// SRB2kart
INT32 kartstuff[NUMKARTSTUFF];
tic_t airtime;
INT16 bumpers;
INT16 karmadelay;
boolean eliminated;
// respawnvars_t
UINT8 respawn_state;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewait, NULL);
if (r_splitscreen > 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<<FRACBITS, ty<<FRACBITS, scale, 0, kp_timeoutsticker, NULL);
V_DrawKartString(x-txoff, ty, 0, va("%d", stplyr->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)));

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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