Replace bumpers completely with health

Adds some functions:

- K_Bumpers, bumper count for the count, intended for
  where player->bumpers was used in HUD and visual
  contexts.
- K_BumpersToHealth, converts bumper count to health
  points.

player->mo->health replaces player->bumpers where it was
used in health contexts.

Removes some functions:

- K_HandleBumperChanges
- K_DestroyBumpers

Everything K_HandleBumperChanges did has either been
removed or moved elsewhere. P_KillMobj also already called
K_CheckBumpers.

K_DestroyBumpers became pointless after player->bumpers
was removed.
This commit is contained in:
James R 2023-03-07 04:41:55 -08:00
parent a1558f1fbd
commit a3c64068e6
15 changed files with 108 additions and 221 deletions

View file

@ -602,7 +602,6 @@ struct player_t
UINT32 roundscore; // battle score this round
UINT8 emeralds;
UINT8 bumpers;
INT16 karmadelay;
INT16 spheres;
tic_t spheredigestion;

View file

@ -2420,7 +2420,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
INT32 itemtype;
INT32 itemamount;
INT32 growshrinktimer;
INT32 bumper;
boolean songcredit = false;
UINT16 nocontrol;
INT32 khudfault;
@ -2492,7 +2491,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
itemtype = 0;
itemamount = 0;
growshrinktimer = 0;
bumper = ((gametyperules & GTR_BUMPERS) ? K_StartingBumperCount() : 0);
if (gametyperules & GTR_SPHERES)
{
rings = 0;
@ -2537,7 +2535,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
else
growshrinktimer = 0;
bumper = players[player].bumpers;
rings = players[player].rings;
spheres = players[player].spheres;
kickstartaccel = players[player].kickstartaccel;
@ -2635,8 +2632,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->itemtype = itemtype;
p->itemamount = itemamount;
p->growshrinktimer = growshrinktimer;
p->bumpers = bumper;
p->karmadelay = comebacktime;
p->karmadelay = 0;
p->eggmanblame = -1;
p->lastdraft = -1;
p->karthud[khud_fault] = khudfault;

View file

@ -113,7 +113,7 @@ void K_CheckBumpers(void)
numingame++;
if (players[i].bumpers <= 0) // if you don't have any bumpers, you're probably not a winner
if (!P_MobjWasRemoved(players[i].mo) && players[i].mo->health <= 0) // if you don't have any bumpers, you're probably not a winner
{
nobumpers++;
}
@ -362,7 +362,7 @@ void K_RunPaperItemSpawners(void)
emeraldsSpawned |= players[i].emeralds;
if ((players[i].exiting > 0 || (players[i].pflags & PF_ELIMINATED))
|| ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0))
|| ((gametyperules & GTR_BUMPERS) && !P_MobjWasRemoved(players[i].mo) && players[i].mo->health <= 0))
{
continue;
}
@ -738,16 +738,20 @@ void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj)
void K_SpawnPlayerBattleBumpers(player_t *p)
{
if (!p->mo || p->bumpers <= 0)
const UINT8 bumpers = K_Bumpers(p);
if (bumpers <= 0)
{
return;
}
{
INT32 i;
angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers);
angle_t diff = FixedAngle(360*FRACUNIT / bumpers);
angle_t newangle = p->mo->angle;
mobj_t *bump;
for (i = 0; i < p->bumpers; i++)
for (i = 0; i < bumpers; i++)
{
bump = P_SpawnMobjFromMobj(p->mo,
P_ReturnThrustX(p->mo, newangle + ANGLE_180, 64*FRACUNIT),
@ -784,21 +788,49 @@ void K_BattleInit(boolean singleplayercontext)
if (gametyperules & GTR_BUMPERS)
{
INT32 maxbumpers = K_StartingBumperCount();
const INT32 startingHealth = K_BumpersToHealth(K_StartingBumperCount());
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
players[i].bumpers = maxbumpers;
if (players[i].mo)
{
players[i].mo->health = maxbumpers;
players[i].mo->health = startingHealth;
}
K_SpawnPlayerBattleBumpers(players+i);
}
}
}
UINT8 K_Bumpers(player_t *player)
{
if ((gametyperules & GTR_BUMPERS) == 0)
{
return 0;
}
if (P_MobjWasRemoved(player->mo))
{
return 0;
}
if (player->mo->health < 1)
{
return 0;
}
if (player->mo->health > UINT8_MAX)
{
return UINT8_MAX;
}
return player->mo->health;
}
INT32 K_BumpersToHealth(UINT8 bumpers)
{
return bumpers;
}

View file

@ -38,6 +38,8 @@ void K_RunBattleOvertime(void);
void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj);
void K_SpawnPlayerBattleBumpers(player_t *p);
void K_BattleInit(boolean singleplayercontext);
UINT8 K_Bumpers(player_t *player);
INT32 K_BumpersToHealth(UINT8 bumpers);
#ifdef __cplusplus
} // extern "C"

View file

@ -154,14 +154,7 @@ boolean K_EggItemCollide(mobj_t *t1, mobj_t *t2)
if (!P_CanPickupItem(t2->player, 2))
return true;
if ((gametyperules & GTR_BUMPERS) && t2->player->bumpers <= 0)
{
return true;
}
else
{
K_StartEggmanRoulette(t2->player);
}
K_StartEggmanRoulette(t2->player);
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
{

View file

@ -1995,10 +1995,12 @@ static boolean K_drawKartPositionFaces(void)
if (LUA_HudEnabled(hud_battlebumpers))
{
if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumpers > 0)
const UINT8 bumpers = K_Bumpers(&players[rankplayer[i]]);
if (bumpers > 0)
{
V_DrawMappedPatch(bumperx-2, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[0], colormap);
for (j = 1; j < players[rankplayer[i]].bumpers; j++)
for (j = 1; j < bumpers; j++)
{
bumperx += 5;
V_DrawMappedPatch(bumperx, Y, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_tinybumper[1], colormap);
@ -2023,7 +2025,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 ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].bumpers <= 0)
if ((gametyperules & GTR_BUMPERS) && players[rankplayer[i]].mo->health <= 0)
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT, kp_ranknobumpers);
else
{
@ -2356,7 +2358,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 ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumpers <= 0)
if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].mo->health <= 0)
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
else
{
@ -2866,14 +2868,16 @@ static void K_drawKartBumpersOrKarma(void)
}
else
{
INT32 maxbumper = K_StartingBumperCount();
const INT32 maxbumper = K_StartingBumperCount();
const UINT8 bumpers = K_Bumpers(stplyr);
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap);
if (stplyr->bumpers > 9 || maxbumper > 9)
if (bumpers > 9 || maxbumper > 9)
{
UINT8 ln[2];
ln[0] = (stplyr->bumpers / 10 % 10);
ln[1] = (stplyr->bumpers % 10);
ln[0] = (bumpers / 10 % 10);
ln[1] = (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]]);
@ -2886,7 +2890,7 @@ static void K_drawKartBumpersOrKarma(void)
}
else
{
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->bumpers) % 10]);
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(bumpers) % 10]);
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]);
}
}
@ -2903,14 +2907,15 @@ static void K_drawKartBumpersOrKarma(void)
}
else
{
INT32 maxbumper = K_StartingBumperCount();
const INT32 maxbumper = K_StartingBumperCount();
const UINT8 bumpers = K_Bumpers(stplyr);
if (stplyr->bumpers > 9 && maxbumper > 9)
if (bumpers > 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->bumpers, maxbumper));
V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", bumpers, maxbumper));
}
}
}
@ -3643,7 +3648,7 @@ static void K_drawKartMinimap(void)
}
// Now we know it's not a display player, handle non-local player exceptions.
if ((gametyperules & GTR_BUMPERS) && players[i].bumpers <= 0)
if ((gametyperules & GTR_BUMPERS) && players[i].mo->health <= 0)
continue;
if (players[i].hyudorotimer > 0)
@ -4151,7 +4156,7 @@ static void K_drawBattleFullscreen(void)
K_drawKartFinish(true);
}
else if (stplyr->bumpers <= 0 && stplyr->karmadelay && !stplyr->spectator && drawcomebacktimer)
else if (stplyr->karmadelay && !stplyr->spectator && drawcomebacktimer)
{
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
@ -4885,8 +4890,7 @@ void K_drawKartHUD(void)
battlefullscreen = (!(gametyperules & GTR_CIRCUIT)
&& (stplyr->exiting
|| ((gametyperules & GTR_BUMPERS) && (stplyr->bumpers <= 0)
&& ((gametyperules & GTR_KARMA) && (stplyr->karmadelay > 0))
|| (((gametyperules & GTR_KARMA) && (stplyr->karmadelay > 0))
&& !(stplyr->pflags & PF_ELIMINATED)
&& stplyr->playerstate == PST_LIVE)));

View file

@ -374,9 +374,6 @@ boolean K_IsPlayerLosing(player_t *player)
if (battlecapsules && numtargets == 0)
return true; // Didn't even TRY?
if (battlecapsules || (gametyperules & GTR_BOSS))
return (player->bumpers <= 0); // anything short of DNF is COOL
if (player->position == 1)
return false;
@ -3636,7 +3633,7 @@ void K_DoPowerClash(player_t *t1, player_t *t2) {
P_SetScale(clash, 3*clash->destscale/2);
}
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved)
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 damage)
{
UINT8 points = 1;
boolean trapItem = false;
@ -3674,7 +3671,7 @@ void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UIN
}
else if (gametyperules & GTR_BUMPERS)
{
if ((victim->bumpers > 0) && (victim->bumpers <= bumpersRemoved))
if ((victim->mo->health > 0) && (victim->mo->health <= damage))
{
// +2 points for finishing off a player
points = 2;
@ -4315,65 +4312,22 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source)
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
}
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers)
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
{
(void)player;
(void)prevBumpers;
if (!(gametyperules & GTR_BUMPERS))
{
// Bumpers aren't being used
return;
}
K_CalculateBattleWanted();
K_CheckBumpers();
}
UINT8 K_DestroyBumpers(player_t *player, UINT8 amount)
{
UINT8 oldBumpers = player->bumpers;
if (!(gametyperules & GTR_BUMPERS))
{
return 0;
}
amount = min(amount, player->bumpers);
if (amount == 0)
{
return 0;
}
player->bumpers -= amount;
K_HandleBumperChanges(player, oldBumpers);
return amount;
}
UINT8 K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
{
UINT8 oldPlayerBumpers = player->bumpers;
UINT8 oldVictimBumpers = victim->bumpers;
const UINT8 oldPlayerBumpers = K_Bumpers(player);
UINT8 tookBumpers = 0;
if (!(gametyperules & GTR_BUMPERS))
{
return 0;
}
amount = min(amount, victim->bumpers);
amount = min(amount, K_Bumpers(victim));
if (amount == 0)
{
return 0;
return;
}
while ((tookBumpers < amount) && (victim->bumpers > 0))
while (tookBumpers < amount)
{
UINT8 newbumper = player->bumpers;
const UINT8 newbumper = (oldPlayerBumpers + tookBumpers);
angle_t newangle, diff;
fixed_t newx, newy;
@ -4415,24 +4369,14 @@ UINT8 K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
P_SetMobjState(newmo, S_BATTLEBUMPER1);
}
player->bumpers++;
victim->bumpers--;
tookBumpers++;
}
if (tookBumpers == 0)
{
// No change occured.
return 0;
}
// :jartcookiedance:
player->mo->health += tookBumpers;
// Play steal sound
S_StartSound(player->mo, sfx_3db06);
K_HandleBumperChanges(player, oldPlayerBumpers);
K_HandleBumperChanges(victim, oldVictimBumpers);
return tookBumpers;
}
#define MINEQUAKEDIST 4096
@ -7048,12 +6992,6 @@ mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
}
else
{
if (player->bumpers <= 0)
{
// Don't pay attention to dead players
continue;
}
// Z pos too high/low
if (abs(player->mo->z - (actor->z + actor->momz)) > FixedMul(RING_DIST/8, mapobjectscale))
{
@ -7813,12 +7751,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (!(gametyperules & GTR_KARMA) || (player->pflags & PF_ELIMINATED))
{
player->karmadelay = comebacktime;
player->karmadelay = 0;
}
else if (player->karmadelay > 0 && !P_PlayerInPain(player))
{
player->karmadelay--;
if (P_IsDisplayPlayer(player) && player->bumpers <= 0 && player->karmadelay <= 0)
if (P_IsDisplayPlayer(player) && player->karmadelay <= 0)
comebackshowninfo = true; // client has already seen the message
}
@ -8011,7 +7949,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->eggmanexplode)
{
if (player->spectator || ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0))
if (player->spectator)
player->eggmanexplode = 0;
else
{
@ -9531,7 +9469,7 @@ void K_KartUpdatePosition(player_t *player)
else if (yourEmeralds == myEmeralds)
{
// Bumpers are the second tier tie breaker
if (players[i].bumpers > player->bumpers)
if (K_Bumpers(&players[i]) > K_Bumpers(player))
{
position++;
}

View file

@ -104,9 +104,7 @@ void K_UpdateStumbleIndicator(player_t *player);
void K_UpdateSliptideZipIndicator(player_t *player);
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_DebtStingPlayer(player_t *player, mobj_t *source);
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
UINT8 K_DestroyBumpers(player_t *player, UINT8 amount);
UINT8 K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
void K_MineFlashScreen(mobj_t *source);
void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay);
void K_RunFinishLineBeam(void);

View file

@ -398,8 +398,6 @@ static int player_get(lua_State *L)
plr->roundscore = luaL_checkinteger(L, 3);
else if (fastcmp(field,"emeralds"))
lua_pushinteger(L, plr->emeralds);
else if (fastcmp(field,"bumpers"))
lua_pushinteger(L, plr->bumpers);
else if (fastcmp(field,"karmadelay"))
lua_pushinteger(L, plr->karmadelay);
else if (fastcmp(field,"spheres"))
@ -782,8 +780,6 @@ static int player_set(lua_State *L)
lua_pushinteger(L, plr->roundscore);
else if (fastcmp(field,"emeralds"))
plr->emeralds = luaL_checkinteger(L, 3);
else if (fastcmp(field,"bumpers"))
plr->bumpers = luaL_checkinteger(L, 3);
else if (fastcmp(field,"karmadelay"))
plr->karmadelay = luaL_checkinteger(L, 3);
else if (fastcmp(field,"spheres"))

View file

@ -13595,7 +13595,7 @@ void A_ReaperThinker(mobj_t *actor)
continue;
player = &players[i];
if (player && player->mo && player->bumpers && player->score >= maxscore)
if (player && player->mo && K_Bumpers(player) && player->score >= maxscore)
{
targetplayermo = player->mo;
maxscore = player->score;

View file

@ -115,13 +115,6 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon)
if (player->exiting || mapreset || (player->pflags & PF_ELIMINATED))
return false;
if ((gametyperules & GTR_BUMPERS) // No bumpers in Match
#ifndef OTHERKARMAMODES
&& !weapon
#endif
&& player->bumpers <= 0)
return false;
if (weapon)
{
// Item slot already taken up
@ -286,9 +279,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!P_CanPickupItem(player, 3) || (player->itemamount && player->itemtype != special->threshold))
return;
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
return;
player->itemtype = special->threshold;
if ((UINT16)(player->itemamount) + special->movecount > 255)
player->itemamount = 255;
@ -321,9 +311,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_KillMobj(special, toucher, toucher, DMG_NORMAL);
return;
case MT_ITEMCAPSULE:
if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0)
return;
if (special->scale < special->extravalue1) // don't break it while it's respawning
return;
@ -351,8 +338,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
if (player == special->target->player)
return;
if (player->bumpers <= 0)
return;
if (special->target->player->exiting || player->exiting)
return;
@ -453,7 +438,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->bumpers <= 0))
if (special->fuse || !P_CanPickupItem(player, 1))
return;
K_StartItemRoulette(player);
@ -1943,8 +1928,10 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
switch (type)
{
case DMG_DEATHPIT:
// Battle
player->mo->health -= K_DestroyBumpers(player, 1);
if (gametyperules & GTR_BUMPERS)
{
player->mo->health--;
}
if (player->mo->health <= 0)
{
@ -2013,8 +2000,6 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
player->pflags |= PF_ELIMINATED;
}
K_DestroyBumpers(player, player->bumpers);
return true;
}
@ -2170,16 +2155,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
boolean invincible = true;
sfxenum_t sfx = sfx_None;
if (gametyperules & GTR_BUMPERS)
{
if (player->bumpers <= 0 && player->karmadelay)
{
// No bumpers & in WAIT, can't be hurt
K_DoInstashield(player);
return false;
}
}
else
if (!(gametyperules & GTR_BUMPERS))
{
if (damagetype & DMG_STEAL)
{
@ -2254,15 +2230,15 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// We successfully damaged them! Give 'em some bumpers!
if (type != DMG_STING && type != DMG_STUMBLE)
{
UINT8 takeBumpers = 1;
damage = 1;
if (damagetype & DMG_STEAL)
{
takeBumpers = 2;
damage = 2;
if (type == DMG_KARMA)
{
takeBumpers = player->bumpers;
damage = K_Bumpers(player);
}
}
else
@ -2270,7 +2246,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (type == DMG_KARMA)
{
// Take half of their bumpers for karma comeback damage
takeBumpers = max(1, player->bumpers / 2);
damage = max(1, K_Bumpers(player) / 2);
}
}
@ -2291,14 +2267,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
K_TryHurtSoundExchange(target, source);
K_BattleAwardHit(source->player, player, inflictor, takeBumpers);
damage = K_TakeBumpersFromPlayer(source->player, player, takeBumpers);
if (type == DMG_KARMA)
{
// Destroy any remainder bumpers from the player for karma comeback damage
damage = K_DestroyBumpers(player, player->bumpers);
}
K_BattleAwardHit(source->player, player, inflictor, damage);
K_TakeBumpersFromPlayer(source->player, player, damage);
if (damagetype & DMG_STEAL)
{
@ -2314,10 +2284,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
Obj_GardenTopDestroy(source->player);
}
}
else
{
damage = K_DestroyBumpers(player, takeBumpers);
}
if (!(damagetype & DMG_STEAL))
{

View file

@ -1390,13 +1390,6 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
return BMIT_CONTINUE;
}
if ((gametyperules & GTR_BUMPERS)
&& ((thing->player->bumpers && !tm.thing->player->bumpers)
|| (tm.thing->player->bumpers && !thing->player->bumpers)))
{
return BMIT_CONTINUE;
}
// The bump has to happen last
if (P_IsObjectOnGround(thing) && tm.thing->momz < 0 && tm.thing->player->trickpanel)
{

View file

@ -4588,9 +4588,6 @@ boolean P_SupermanLook4Players(mobj_t *actor)
if (players[c].mo->health <= 0)
continue; // dead
if ((gametyperules & GTR_BUMPERS) && players[c].bumpers <= 0)
continue; // other dead
playersinthegame[stop] = &players[c];
stop++;
}
@ -6129,6 +6126,8 @@ static void P_MobjSceneryThink(mobj_t *mobj)
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player
&& mobj->target->health > 0 && !mobj->target->player->spectator)
{
const UINT8 bumpers = K_Bumpers(mobj->target->player);
fixed_t rad = 32*mobj->target->scale;
fixed_t offz;
angle_t ang, diff;
@ -6138,10 +6137,10 @@ static void P_MobjSceneryThink(mobj_t *mobj)
else
ang = FixedAngle(mobj->info->speed);
if (mobj->target->player->bumpers <= 1)
if (bumpers <= 1)
diff = 0;
else
diff = FixedAngle(360*FRACUNIT/mobj->target->player->bumpers);
diff = FixedAngle(360*FRACUNIT / bumpers);
ang = (ang*leveltime) + (diff * (mobj->threshold-1));
@ -6178,9 +6177,9 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->color = mobj->target->color;
}
if (mobj->target->player->bumpers < 2)
if (bumpers < 2)
P_SetMobjState(mobj, S_BATTLEBUMPER3);
else if (mobj->target->player->bumpers < 3)
else if (bumpers < 3)
P_SetMobjState(mobj, S_BATTLEBUMPER2);
else
P_SetMobjState(mobj, S_BATTLEBUMPER1);
@ -6197,7 +6196,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
P_SetThingPosition(mobj);
}
if (mobj->target->player->bumpers <= mobj->threshold)
if (bumpers <= mobj->threshold)
{
// Do bumper destruction
P_KillMobj(mobj, NULL, NULL, DMG_NORMAL);
@ -6231,7 +6230,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->color = mobj->target->color;
K_MatchGenericExtraFlags(mobj, mobj->target);
if ((!(gametyperules & GTR_BUMPERS) || mobj->target->player->bumpers <= 0)
if (!(gametyperules & GTR_BUMPERS)
#if 1 // Set to 0 to test without needing to host
|| (P_IsDisplayPlayer(mobj->target->player))
#endif
@ -8428,7 +8427,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
|| (!(gametyperules & GTR_BUMPERS) || mobj->target->player->bumpers))
|| !(gametyperules & GTR_BUMPERS))
{
P_RemoveMobj(mobj);
return false;
@ -11876,38 +11875,15 @@ void P_SpawnPlayer(INT32 playernum)
P_SetScale(overheadarrow, mobj->destscale);
}
if (gametyperules & GTR_BUMPERS)
if ((gametyperules & GTR_BUMPERS) && !p->spectator)
{
if (p->spectator)
// At leveltime == 2, K_TimerInit will get called and reset
// the bumpers to the initial value for the level.
if (leveltime > 2) // Reset those bumpers!
{
// HEY! No being cheap...
p->bumpers = 0;
}
else if ((p->bumpers > 0) || (leveltime < starttime) || (pcount <= 1))
{
if ((leveltime < starttime) || (pcount <= 1)) // Start of the map?
{
if (leveltime > 2) // Reset those bumpers!
{
p->bumpers = K_StartingBumperCount();
K_SpawnPlayerBattleBumpers(p);
}
else // temp, will get overwritten in K_BattleInit
{
p->bumpers = 1;
}
}
}
else if (p->bumpers <= 0)
{
p->bumpers = K_StartingBumperCount();
mobj->health = K_BumpersToHealth(K_StartingBumperCount());
K_SpawnPlayerBattleBumpers(p);
}
if (p->bumpers > 0)
{
mobj->health = p->bumpers;
}
}
// I'm not refactoring the loop at the top of this file.

View file

@ -381,7 +381,6 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT32(save->p, players[i].roundscore);
WRITEUINT8(save->p, players[i].emeralds);
WRITEUINT8(save->p, players[i].bumpers);
WRITEINT16(save->p, players[i].karmadelay);
WRITEINT16(save->p, players[i].spheres);
WRITEUINT32(save->p, players[i].spheredigestion);
@ -757,7 +756,6 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].roundscore = READUINT32(save->p);
players[i].emeralds = READUINT8(save->p);
players[i].bumpers = READUINT8(save->p);
players[i].karmadelay = READINT16(save->p);
players[i].spheres = READINT16(save->p);
players[i].spheredigestion = READUINT32(save->p);

View file

@ -526,10 +526,6 @@ INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres)
if (!(gametyperules & GTR_SPHERES)) // No spheres in Race mode)
return 0;
// Not alive
if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0))
return 0;
if (num_spheres > 40) // Reached the cap, don't waste 'em!
num_spheres = 40;
else if (num_spheres < 0)
@ -4387,7 +4383,7 @@ void P_PlayerThink(player_t *player)
|| player->growshrinktimer > 0 // Grow doesn't flash either.
|| (player->respawn.state != RESPAWNST_NONE && player->respawn.truedeath == true) // Respawn timer (for drop dash effect)
|| (player->pflags & PF_NOCONTEST) // NO CONTEST explosion
|| ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0 && player->karmadelay)))
|| player->karmadelay))
{
if (player->flashing > 1 && player->flashing < K_GetKartFlashing(player)
&& (leveltime & 1))