mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Refactor stealing & destroying bumpers
- Prevents being able to farm extra bumpers off of karma players - Paves the way for bumper destroy animation later
This commit is contained in:
parent
56a20d05df
commit
827a1b5fca
11 changed files with 229 additions and 149 deletions
|
|
@ -617,7 +617,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
||||||
|
|
||||||
rsp->airtime = (tic_t)LONG(players[i].airtime);
|
rsp->airtime = (tic_t)LONG(players[i].airtime);
|
||||||
|
|
||||||
rsp->bumpers = SHORT(players[i].bumpers);
|
rsp->bumpers = players[i].bumpers;
|
||||||
rsp->karmadelay = SHORT(players[i].karmadelay);
|
rsp->karmadelay = SHORT(players[i].karmadelay);
|
||||||
rsp->eliminated = players[i].eliminated;
|
rsp->eliminated = players[i].eliminated;
|
||||||
|
|
||||||
|
|
@ -765,7 +765,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
||||||
|
|
||||||
players[i].airtime = (tic_t)LONG(rsp->airtime);
|
players[i].airtime = (tic_t)LONG(rsp->airtime);
|
||||||
|
|
||||||
players[i].bumpers = SHORT(rsp->bumpers);
|
players[i].bumpers = rsp->bumpers;
|
||||||
players[i].karmadelay = SHORT(rsp->karmadelay);
|
players[i].karmadelay = SHORT(rsp->karmadelay);
|
||||||
players[i].eliminated = rsp->eliminated;
|
players[i].eliminated = rsp->eliminated;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ typedef struct
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
INT32 kartstuff[NUMKARTSTUFF];
|
INT32 kartstuff[NUMKARTSTUFF];
|
||||||
tic_t airtime;
|
tic_t airtime;
|
||||||
INT16 bumpers;
|
UINT8 bumpers;
|
||||||
INT16 karmadelay;
|
INT16 karmadelay;
|
||||||
boolean eliminated;
|
boolean eliminated;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -524,7 +524,7 @@ typedef struct player_s
|
||||||
waypoint_t *nextwaypoint;
|
waypoint_t *nextwaypoint;
|
||||||
respawnvars_t respawn; // Respawn info
|
respawnvars_t respawn; // Respawn info
|
||||||
tic_t airtime; // Keep track of how long you've been in the air
|
tic_t airtime; // Keep track of how long you've been in the air
|
||||||
INT16 bumpers;
|
UINT8 bumpers;
|
||||||
INT16 karmadelay;
|
INT16 karmadelay;
|
||||||
boolean eliminated;
|
boolean eliminated;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11313,6 +11313,7 @@ struct {
|
||||||
{"DMG_EXPLODE",DMG_EXPLODE},
|
{"DMG_EXPLODE",DMG_EXPLODE},
|
||||||
{"DMG_SQUISH",DMG_SQUISH},
|
{"DMG_SQUISH",DMG_SQUISH},
|
||||||
{"DMG_STING",DMG_STING},
|
{"DMG_STING",DMG_STING},
|
||||||
|
{"DMG_KARMA",DMG_KARMA},
|
||||||
//// Death types
|
//// Death types
|
||||||
{"DMG_INSTAKILL",DMG_INSTAKILL},
|
{"DMG_INSTAKILL",DMG_INSTAKILL},
|
||||||
{"DMG_DEATHPIT",DMG_DEATHPIT},
|
{"DMG_DEATHPIT",DMG_DEATHPIT},
|
||||||
|
|
|
||||||
264
src/k_kart.c
264
src/k_kart.c
|
|
@ -2461,93 +2461,51 @@ void K_DoInstashield(player_t *player)
|
||||||
P_SetTarget(&layerb->target, player->mo);
|
P_SetTarget(&layerb->target, player->mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted)
|
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved)
|
||||||
{
|
{
|
||||||
if (reducewanted == false)
|
UINT8 points = 1;
|
||||||
points = 1; // Force to 1
|
boolean trapItem = false;
|
||||||
|
|
||||||
|
if (player == NULL || victim == NULL)
|
||||||
|
{
|
||||||
|
// Invalid player or victim
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player == victim)
|
||||||
|
{
|
||||||
|
// You cannot give yourself points
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inflictor && !P_MobjWasRemoved(inflictor)) && (inflictor->type == MT_BANANA && inflictor->health > 1))
|
||||||
|
{
|
||||||
|
trapItem = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only apply score bonuses to non-bananas
|
||||||
|
if (trapItem == false)
|
||||||
|
{
|
||||||
|
if (K_IsPlayerWanted(victim))
|
||||||
|
{
|
||||||
|
// +3 points for hitting a wanted player
|
||||||
|
points = 3;
|
||||||
|
}
|
||||||
|
else if (gametyperules & GTR_BUMPERS)
|
||||||
|
{
|
||||||
|
if ((victim->bumpers > 0) && (victim->bumpers <= bumpersRemoved))
|
||||||
|
{
|
||||||
|
// +2 points for finishing off a player
|
||||||
|
points = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gametyperules & GTR_POINTLIMIT)
|
if (gametyperules & GTR_POINTLIMIT)
|
||||||
{
|
{
|
||||||
P_AddPlayerScore(player, points);
|
P_AddPlayerScore(player, points);
|
||||||
K_SpawnBattlePoints(player, victim, points);
|
K_SpawnBattlePoints(player, victim, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gametyperules & GTR_WANTED) && (reducewanted == true))
|
|
||||||
{
|
|
||||||
// Seems a little backwards, but the WANTED system is meant to prevent camping.
|
|
||||||
// If you don't want people to go after you, then be proactive!
|
|
||||||
player->kartstuff[k_wanted] -= wantedreduce;
|
|
||||||
victim->kartstuff[k_wanted] -= (wantedreduce/2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void K_RemoveBumper(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 amount, boolean force)
|
|
||||||
{
|
|
||||||
UINT8 score = 1;
|
|
||||||
boolean trapitem = false;
|
|
||||||
|
|
||||||
if (amount <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(gametyperules & GTR_BUMPERS))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (force == false)
|
|
||||||
{
|
|
||||||
if (player->powers[pw_flashing] || P_PlayerInPain(player))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inflictor && !P_MobjWasRemoved(inflictor))
|
|
||||||
{
|
|
||||||
if (inflictor->type == MT_BANANA && inflictor->health <= 1)
|
|
||||||
{
|
|
||||||
trapitem = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gametyperules & GTR_POINTLIMIT)
|
|
||||||
{
|
|
||||||
if (K_IsPlayerWanted(player))
|
|
||||||
score = 3;
|
|
||||||
else if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= amount))
|
|
||||||
score = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source && source->player && player != source->player)
|
|
||||||
{
|
|
||||||
K_BattleHitPlayer(source->player, player, score, trapitem);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->bumpers > 0)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
karmahitbox->destscale = player->mo->scale;
|
|
||||||
P_SetScale(karmahitbox, player->mo->scale);
|
|
||||||
CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]);
|
|
||||||
}
|
|
||||||
|
|
||||||
player->bumpers -= amount;
|
|
||||||
K_CalculateBattleWanted();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->bumpers <= 0)
|
|
||||||
{
|
|
||||||
player->bumpers = 0;
|
|
||||||
player->karmadelay = comebacktime;
|
|
||||||
|
|
||||||
if (player->kartstuff[k_comebackmode] == 2)
|
|
||||||
{
|
|
||||||
mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE);
|
|
||||||
S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound);
|
|
||||||
player->kartstuff[k_comebackmode] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
K_CheckBumpers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type)
|
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type)
|
||||||
|
|
@ -2660,30 +2618,110 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source)
|
||||||
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_StealBumper(player_t *player, player_t *victim, UINT8 amount)
|
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers)
|
||||||
{
|
{
|
||||||
INT32 intendedamount = player->bumpers + amount;
|
if (!(gametyperules & GTR_BUMPERS))
|
||||||
INT32 newbumper;
|
{
|
||||||
angle_t newangle, diff;
|
// Bumpers aren't being used
|
||||||
fixed_t newx, newy;
|
|
||||||
mobj_t *newmo;
|
|
||||||
|
|
||||||
if (amount <= 0)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: replace all console text print-outs with a real visual
|
||||||
|
|
||||||
|
if (player->bumpers > 0 && prevBumpers == 0)
|
||||||
|
{
|
||||||
|
if (player->kartstuff[k_comebackmode] == 2)
|
||||||
|
{
|
||||||
|
mobj_t *poof = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_EXPLODE);
|
||||||
|
S_StartSound(poof, mobjinfo[MT_KARMAHITBOX].seesound);
|
||||||
|
}
|
||||||
|
|
||||||
|
player->kartstuff[k_comebackmode] = 0;
|
||||||
|
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (player->bumpers == 0 && prevBumpers > 0)
|
||||||
|
{
|
||||||
|
mobj_t *karmahitbox = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_KARMAHITBOX);
|
||||||
|
P_SetTarget(&karmahitbox->target, player->mo);
|
||||||
|
|
||||||
|
karmahitbox->destscale = player->mo->destscale;
|
||||||
|
P_SetScale(karmahitbox, player->mo->scale);
|
||||||
|
|
||||||
|
if (netgame)
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("%s lost all of their bumpers!\n"), player_names[player-players]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player->karmadelay = comebacktime;
|
||||||
|
K_CalculateBattleWanted();
|
||||||
|
K_CheckBumpers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_DestroyBumpers(player_t *player, UINT8 amount)
|
||||||
|
{
|
||||||
|
UINT8 oldBumpers = player->bumpers;
|
||||||
|
|
||||||
if (!(gametyperules & GTR_BUMPERS))
|
if (!(gametyperules & GTR_BUMPERS))
|
||||||
return;
|
|
||||||
|
|
||||||
if (netgame && player->bumpers <= 0)
|
|
||||||
CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]);
|
|
||||||
|
|
||||||
while (player->bumpers < intendedamount)
|
|
||||||
{
|
{
|
||||||
newbumper = player->bumpers;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = min(amount, player->bumpers);
|
||||||
|
|
||||||
|
if (amount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player->bumpers -= amount;
|
||||||
|
|
||||||
|
// TODO: Store a bumperlist on the player mobj,
|
||||||
|
// that way we can do a bumper destruction animation
|
||||||
|
|
||||||
|
K_HandleBumperChanges(player, oldBumpers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount)
|
||||||
|
{
|
||||||
|
UINT8 oldPlayerBumpers = player->bumpers;
|
||||||
|
UINT8 oldVictimBumpers = victim->bumpers;
|
||||||
|
|
||||||
|
UINT8 tookBumpers = 0;
|
||||||
|
|
||||||
|
if (!(gametyperules & GTR_BUMPERS))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = min(amount, victim->bumpers);
|
||||||
|
|
||||||
|
if (amount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((tookBumpers < amount) && (victim->bumpers > 0))
|
||||||
|
{
|
||||||
|
UINT8 newbumper = player->bumpers;
|
||||||
|
|
||||||
|
angle_t newangle, diff;
|
||||||
|
fixed_t newx, newy;
|
||||||
|
|
||||||
|
mobj_t *newmo;
|
||||||
|
|
||||||
if (newbumper <= 1)
|
if (newbumper <= 1)
|
||||||
|
{
|
||||||
diff = 0;
|
diff = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
diff = FixedAngle(360*FRACUNIT/newbumper);
|
diff = FixedAngle(360*FRACUNIT/newbumper);
|
||||||
|
}
|
||||||
|
|
||||||
newangle = player->mo->angle;
|
newangle = player->mo->angle;
|
||||||
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
|
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT);
|
||||||
|
|
@ -2691,36 +2729,42 @@ void K_StealBumper(player_t *player, player_t *victim, UINT8 amount)
|
||||||
|
|
||||||
newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER);
|
newmo = P_SpawnMobj(newx, newy, player->mo->z, MT_BATTLEBUMPER);
|
||||||
newmo->threshold = newbumper;
|
newmo->threshold = newbumper;
|
||||||
|
|
||||||
P_SetTarget(&newmo->tracer, victim->mo);
|
P_SetTarget(&newmo->tracer, victim->mo);
|
||||||
P_SetTarget(&newmo->target, player->mo);
|
P_SetTarget(&newmo->target, player->mo);
|
||||||
|
|
||||||
newmo->angle = (diff * (newbumper-1));
|
newmo->angle = (diff * (newbumper-1));
|
||||||
newmo->color = victim->skincolor;
|
newmo->color = victim->skincolor;
|
||||||
|
|
||||||
if (newbumper+1 < 2)
|
if (newbumper+1 < 2)
|
||||||
|
{
|
||||||
P_SetMobjState(newmo, S_BATTLEBUMPER3);
|
P_SetMobjState(newmo, S_BATTLEBUMPER3);
|
||||||
|
}
|
||||||
else if (newbumper+1 < 3)
|
else if (newbumper+1 < 3)
|
||||||
|
{
|
||||||
P_SetMobjState(newmo, S_BATTLEBUMPER2);
|
P_SetMobjState(newmo, S_BATTLEBUMPER2);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
P_SetMobjState(newmo, S_BATTLEBUMPER1);
|
P_SetMobjState(newmo, S_BATTLEBUMPER1);
|
||||||
|
|
||||||
player->bumpers++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player->bumpers++;
|
||||||
|
victim->bumpers--;
|
||||||
|
tookBumpers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tookBumpers == 0)
|
||||||
|
{
|
||||||
|
// No change occured.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play steal sound
|
||||||
S_StartSound(player->mo, sfx_3db06);
|
S_StartSound(player->mo, sfx_3db06);
|
||||||
|
|
||||||
player->powers[pw_flashing] = K_GetKartFlashing(player);
|
K_HandleBumperChanges(player, oldPlayerBumpers);
|
||||||
player->karmadelay = comebacktime;
|
K_HandleBumperChanges(victim, oldVictimBumpers);
|
||||||
|
|
||||||
/*
|
|
||||||
victim->powers[pw_flashing] = K_GetKartFlashing(victim);
|
|
||||||
victim->karmadelay = comebacktime;
|
|
||||||
*/
|
|
||||||
|
|
||||||
victim->kartstuff[k_instashield] = 15;
|
|
||||||
if (cv_kartdebughuddrop.value && !modeattacking)
|
|
||||||
K_DropItems(victim);
|
|
||||||
else
|
|
||||||
K_DropHnextList(victim, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// source is the mobj that originally threw the bomb that exploded etc.
|
// source is the mobj that originally threw the bomb that exploded etc.
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,14 @@ void K_KartPlayerAfterThink(player_t *player);
|
||||||
angle_t K_MomentumAngle(mobj_t *mo);
|
angle_t K_MomentumAngle(mobj_t *mo);
|
||||||
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics);
|
void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics);
|
||||||
void K_DoInstashield(player_t *player);
|
void K_DoInstashield(player_t *player);
|
||||||
void K_BattleHitPlayer(player_t *player, player_t *victim, UINT8 points, boolean reducewanted);
|
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved);
|
||||||
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_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_SquishPlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||||
void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
void K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||||
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
||||||
void K_StealBumper(player_t *player, player_t *victim, UINT8 amount);
|
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
|
||||||
|
void K_DestroyBumpers(player_t *player, UINT8 amount);
|
||||||
|
void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount);
|
||||||
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
|
void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source);
|
||||||
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
|
void K_SpawnMineExplosion(mobj_t *source, UINT8 color);
|
||||||
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
|
UINT16 K_DriftSparkColor(player_t *player, INT32 charge);
|
||||||
|
|
|
||||||
|
|
@ -3432,7 +3432,7 @@ static int lib_kExplodePlayer(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_kStealBumper(lua_State *L)
|
static int lib_kTakeBumpersFromPlayer(lua_State *L)
|
||||||
{
|
{
|
||||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||||
player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||||
|
|
@ -3442,7 +3442,7 @@ static int lib_kStealBumper(lua_State *L)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
if (!victim)
|
if (!victim)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
K_StealBumper(player, victim, amount);
|
K_TakeBumpersFromPlayer(player, victim, amount);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3919,7 +3919,7 @@ static luaL_Reg lib[] = {
|
||||||
{"K_SpinPlayer",lib_kSpinPlayer},
|
{"K_SpinPlayer",lib_kSpinPlayer},
|
||||||
{"K_SquishPlayer",lib_kSquishPlayer},
|
{"K_SquishPlayer",lib_kSquishPlayer},
|
||||||
{"K_ExplodePlayer",lib_kExplodePlayer},
|
{"K_ExplodePlayer",lib_kExplodePlayer},
|
||||||
{"K_StealBumper",lib_kStealBumper},
|
{"K_TakeBumpersFromPlayer",lib_kTakeBumpersFromPlayer},
|
||||||
{"K_SpawnKartExplosion",lib_kSpawnKartExplosion},
|
{"K_SpawnKartExplosion",lib_kSpawnKartExplosion},
|
||||||
{"K_SpawnMineExplosion",lib_kSpawnMineExplosion},
|
{"K_SpawnMineExplosion",lib_kSpawnMineExplosion},
|
||||||
{"K_SpawnBoostTrail",lib_kSpawnBoostTrail},
|
{"K_SpawnBoostTrail",lib_kSpawnBoostTrail},
|
||||||
|
|
|
||||||
|
|
@ -305,7 +305,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
{
|
{
|
||||||
mobj_t *boom;
|
mobj_t *boom;
|
||||||
|
|
||||||
if (P_DamageMobj(toucher, special, special->target, 1, DMG_EXPLODE) == false)
|
if (P_DamageMobj(toucher, special, special->target, 1, DMG_KARMA) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -323,9 +323,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
|
|
||||||
S_StartSound(boom, special->info->attacksound);
|
S_StartSound(boom, special->info->attacksound);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
|
special->target->player->karthud[khud_yougotem] = 2*TICRATE;
|
||||||
special->target->player->karmadelay = comebacktime;
|
special->target->player->karmadelay = comebacktime;
|
||||||
}
|
}
|
||||||
|
|
@ -1692,7 +1689,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
{
|
{
|
||||||
case DMG_DEATHPIT:
|
case DMG_DEATHPIT:
|
||||||
// Respawn kill types
|
// Respawn kill types
|
||||||
K_RemoveBumper(player, NULL, NULL, 1, true);
|
K_DestroyBumpers(player, 1);
|
||||||
K_DoIngameRespawn(player);
|
K_DoIngameRespawn(player);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
|
|
@ -1733,7 +1730,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source,
|
||||||
P_SetTarget(&boom->target, player->mo);
|
P_SetTarget(&boom->target, player->mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
K_RemoveBumper(player, NULL, NULL, player->bumpers, true);
|
K_DestroyBumpers(player, player->bumpers);
|
||||||
player->eliminated = true;
|
player->eliminated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1923,31 +1920,54 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We successfully hit 'em!
|
// We successfully damaged them! Give 'em some bumpers!
|
||||||
if (type != DMG_STING)
|
if (type != DMG_STING)
|
||||||
{
|
{
|
||||||
UINT8 bumpadd = 1;
|
UINT8 takeBumpers = 1;
|
||||||
|
|
||||||
if (damagetype & DMG_STEAL)
|
if (damagetype & DMG_STEAL)
|
||||||
{
|
{
|
||||||
bumpadd = 2;
|
takeBumpers = 2;
|
||||||
|
|
||||||
|
if (type == DMG_KARMA)
|
||||||
|
{
|
||||||
|
takeBumpers = player->bumpers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == DMG_KARMA)
|
||||||
|
{
|
||||||
|
// Take half of their bumpers for karma comeback damage
|
||||||
|
takeBumpers = max(1, player->bumpers / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source && source != player->mo && source->player)
|
if (source && source != player->mo && source->player)
|
||||||
{
|
{
|
||||||
K_PlayHitEmSound(source);
|
K_PlayHitEmSound(source);
|
||||||
K_StealBumper(source->player, player, bumpadd);
|
|
||||||
|
K_BattleAwardHit(source->player, player, inflictor, takeBumpers);
|
||||||
|
K_TakeBumpersFromPlayer(source->player, player, takeBumpers);
|
||||||
|
|
||||||
|
if (type == DMG_KARMA)
|
||||||
|
{
|
||||||
|
// Destroy any remainder bumpers from the player for karma comeback damage
|
||||||
|
K_DestroyBumpers(player, player->bumpers);
|
||||||
|
}
|
||||||
|
|
||||||
if (damagetype & DMG_STEAL)
|
if (damagetype & DMG_STEAL)
|
||||||
{
|
{
|
||||||
// Give them ALL of your emeralds :)
|
// Give them ALL of your emeralds instantly :)
|
||||||
source->player->powers[pw_emeralds] |= player->powers[pw_emeralds];
|
source->player->powers[pw_emeralds] |= player->powers[pw_emeralds];
|
||||||
player->powers[pw_emeralds] = 0;
|
player->powers[pw_emeralds] = 0;
|
||||||
K_CheckEmeralds(source->player);
|
K_CheckEmeralds(source->player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
K_RemoveBumper(player, inflictor, source, bumpadd, false);
|
{
|
||||||
|
K_DestroyBumpers(player, takeBumpers);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(damagetype & DMG_STEAL))
|
if (!(damagetype & DMG_STEAL))
|
||||||
{
|
{
|
||||||
|
|
@ -1968,6 +1988,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
ringburst = 0;
|
ringburst = 0;
|
||||||
break;
|
break;
|
||||||
case DMG_EXPLODE:
|
case DMG_EXPLODE:
|
||||||
|
case DMG_KARMA:
|
||||||
K_ExplodePlayer(player, inflictor, source);
|
K_ExplodePlayer(player, inflictor, source);
|
||||||
break;
|
break;
|
||||||
case DMG_WIPEOUT:
|
case DMG_WIPEOUT:
|
||||||
|
|
@ -1997,7 +2018,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||||
|
|
||||||
K_PlayPainSound(player->mo);
|
K_PlayPainSound(player->mo);
|
||||||
|
|
||||||
if ((type == DMG_EXPLODE) || (cv_kartdebughuddrop.value && !modeattacking))
|
if ((type == DMG_EXPLODE || type == DMG_KARMA) || (cv_kartdebughuddrop.value && !modeattacking))
|
||||||
{
|
{
|
||||||
K_DropItems(player);
|
K_DropItems(player);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -467,6 +467,7 @@ typedef struct BasicFF_s
|
||||||
#define DMG_EXPLODE 0x02
|
#define DMG_EXPLODE 0x02
|
||||||
#define DMG_SQUISH 0x03
|
#define DMG_SQUISH 0x03
|
||||||
#define DMG_STING 0x04
|
#define DMG_STING 0x04
|
||||||
|
#define DMG_KARMA 0x05 // Karma Bomb explosion -- works like DMG_EXPLODE, but steals half of their bumpers & deletes the rest
|
||||||
//// Death types - cannot be combined with damage types
|
//// Death types - cannot be combined with damage types
|
||||||
#define DMG_INSTAKILL 0x80
|
#define DMG_INSTAKILL 0x80
|
||||||
#define DMG_DEATHPIT 0x81
|
#define DMG_DEATHPIT 0x81
|
||||||
|
|
|
||||||
42
src/p_mobj.c
42
src/p_mobj.c
|
|
@ -5278,15 +5278,23 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_BATTLEBUMPER:
|
case MT_BATTLEBUMPER:
|
||||||
if (mobj->health > 0 && mobj->target && mobj->target->player
|
if (mobj->health <= 0)
|
||||||
&& mobj->target->health > 0 && !mobj->target->player->spectator)
|
|
||||||
{
|
{
|
||||||
|
// DO EXPLODE ANIMATION HERE
|
||||||
|
//CONS_Printf("bumper explosion\n");
|
||||||
|
P_RemoveMobj(mobj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (mobj->target && mobj->target->player && mobj->target->health > 0 && !mobj->target->player->spectator)
|
||||||
|
{
|
||||||
|
// Following a player
|
||||||
|
|
||||||
fixed_t rad = 32*mobj->target->scale;
|
fixed_t rad = 32*mobj->target->scale;
|
||||||
fixed_t offz;
|
fixed_t offz;
|
||||||
angle_t ang, diff;
|
angle_t ang, diff;
|
||||||
|
|
||||||
if (!((mobj->target->player-players) & 1))
|
if (!((mobj->target->player-players) & 1))
|
||||||
ang = (FixedAngle(mobj->info->speed) * -1);
|
ang = -FixedAngle(mobj->info->speed);
|
||||||
else
|
else
|
||||||
ang = FixedAngle(mobj->info->speed);
|
ang = FixedAngle(mobj->info->speed);
|
||||||
|
|
||||||
|
|
@ -5341,21 +5349,20 @@ static void P_MobjSceneryThink(mobj_t *mobj)
|
||||||
P_SetThingPosition(mobj);
|
P_SetThingPosition(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was this so hard?
|
|
||||||
if (mobj->target->player->bumpers <= mobj->threshold)
|
if (mobj->target->player->bumpers <= mobj->threshold)
|
||||||
{
|
{
|
||||||
|
// Sliently remove
|
||||||
P_RemoveMobj(mobj);
|
P_RemoveMobj(mobj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((mobj->health > 0
|
else
|
||||||
&& (!mobj->target || !mobj->target->player || !mobj->target->player->mo || mobj->target->health <= 0 || mobj->target->player->spectator))
|
|
||||||
|| (mobj->health <= 0 && P_IsObjectOnGround(mobj))
|
|
||||||
|| P_CheckDeathPitCollide(mobj)) // When in death state
|
|
||||||
{
|
{
|
||||||
|
// Sliently remove
|
||||||
P_RemoveMobj(mobj);
|
P_RemoveMobj(mobj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MT_PLAYERARROW:
|
case MT_PLAYERARROW:
|
||||||
if (mobj->target && mobj->target->health
|
if (mobj->target && mobj->target->health
|
||||||
|
|
@ -10167,20 +10174,25 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
P_SetScale(mobj, mobj->destscale);
|
P_SetScale(mobj, mobj->destscale);
|
||||||
P_FlashPal(p, 0, 0); // Resets
|
P_FlashPal(p, 0, 0); // Resets
|
||||||
|
|
||||||
if ((gametyperules & GTR_BUMPERS)) // SRB2kart
|
if (gametyperules & GTR_BUMPERS)
|
||||||
{
|
{
|
||||||
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);
|
mobj_t *overheadarrow = P_SpawnMobj(mobj->x, mobj->y, mobj->z + mobj->height + 16*FRACUNIT, MT_PLAYERARROW);
|
||||||
P_SetTarget(&overheadarrow->target, mobj);
|
P_SetTarget(&overheadarrow->target, mobj);
|
||||||
overheadarrow->drawflags |= MFD_DONTDRAW;
|
overheadarrow->drawflags |= MFD_DONTDRAW;
|
||||||
P_SetScale(overheadarrow, mobj->destscale);
|
P_SetScale(overheadarrow, mobj->destscale);
|
||||||
|
|
||||||
if (p->spectator && pcount > 1) // HEY! No being cheap...
|
if (p->spectator)
|
||||||
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?
|
// HEY! No being cheap...
|
||||||
p->bumpers = K_StartingBumperCount(); // Reset those bumpers!
|
p->bumpers = 0;
|
||||||
|
}
|
||||||
|
else if ((p->bumpers > 0) || (leveltime < starttime) || (pcount <= 1))
|
||||||
|
{
|
||||||
|
if ((leveltime < starttime) || (pcount <= 1)) // Start of the map?
|
||||||
|
{
|
||||||
|
// Reset those bumpers!
|
||||||
|
p->bumpers = K_StartingBumperCount();
|
||||||
|
}
|
||||||
|
|
||||||
if (p->bumpers)
|
if (p->bumpers)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
WRITEUINT32(save_p, K_GetWaypointHeapIndex(players[i].nextwaypoint));
|
||||||
WRITEUINT32(save_p, players[i].airtime);
|
WRITEUINT32(save_p, players[i].airtime);
|
||||||
|
|
||||||
WRITEINT16(save_p, players[i].bumpers);
|
WRITEUINT8(save_p, players[i].bumpers);
|
||||||
WRITEINT16(save_p, players[i].karmadelay);
|
WRITEINT16(save_p, players[i].karmadelay);
|
||||||
WRITEUINT8(save_p, players[i].eliminated);
|
WRITEUINT8(save_p, players[i].eliminated);
|
||||||
|
|
||||||
|
|
@ -447,7 +447,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p);
|
players[i].nextwaypoint = (waypoint_t *)(size_t)READUINT32(save_p);
|
||||||
players[i].airtime = READUINT32(save_p);
|
players[i].airtime = READUINT32(save_p);
|
||||||
|
|
||||||
players[i].bumpers = READINT16(save_p);
|
players[i].bumpers = READUINT8(save_p);
|
||||||
players[i].karmadelay = READINT16(save_p);
|
players[i].karmadelay = READINT16(save_p);
|
||||||
players[i].eliminated = (boolean)READUINT8(save_p);
|
players[i].eliminated = (boolean)READUINT8(save_p);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue