diff --git a/src/d_player.h b/src/d_player.h index 6687e76c..f0360f30 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -266,6 +266,7 @@ typedef enum // Some items use timers for their duration or effects k_magnettimer, // Duration of Magnet's item-break and item box pull + k_bootimer, // Duration of the boo offroad effect itself k_bootaketimer, // You are stealing an item, this is your timer k_boostolentimer, // You are being stolen from, this is your timer k_mushroomtimer, // Duration of the Mushroom Boost itself @@ -277,6 +278,7 @@ typedef enum k_laserwisptimer, // The duration and relative angle of the laser k_justbumped, // Prevent players from endlessly bumping into each other k_poweritemtimer, // Battle mode, how long before you're allowed another power item (Star, Megashroom) + k_comebacktimer, // Battle mode, how long before you become a bomb after death // Each item needs its own power slot, for the HUD and held use k_magnet, // 0x1 = Magnet in inventory @@ -304,8 +306,7 @@ typedef enum // 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory k_lightning, // 0x1 = Lightning in inventory k_kitchensink, // 0x1 = Sink in inventory - k_balloon, // 0x1 = 1 hit left, 0x2 = 2 hits left, 0x4 = 3 hits left - // 0x8 = 4 hits left, 0x16 = 5 hits left + k_balloon, // Number of balloons left NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index dba84072..82786d17 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6427,6 +6427,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAYERARROW_MEGASHROOM", "S_PLAYERARROW_KITCHENSINK", "S_PLAYERARROW_EMPTY", + "S_PLAYERARROW_ROULETTE", + + "S_PLAYERBOMB", // Player bomb overlay #ifdef SEENAMES "S_NAMECHECK", diff --git a/src/doomstat.h b/src/doomstat.h index 40295d25..94618c56 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -401,8 +401,10 @@ extern UINT16 extralifetics; // SRB2kart extern INT32 bootime; +extern INT32 boostealtime; extern INT32 mushroomtime; extern INT32 itemtime; +extern INT32 comebacktime; extern UINT8 introtoplay; extern UINT8 creditscutscene; diff --git a/src/g_game.c b/src/g_game.c index 673964be..4d2c386a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -202,8 +202,10 @@ UINT16 extralifetics = 4*TICRATE; // SRB2kart INT32 bootime = 7*TICRATE; +INT32 boostealtime = TICRATE/2; INT32 mushroomtime = TICRATE + (TICRATE/3); INT32 itemtime = 8*TICRATE; +INT32 comebacktime = 5*TICRATE; INT32 gameovertics = 15*TICRATE; diff --git a/src/info.c b/src/info.c index df9579f4..e9e5548e 100644 --- a/src/info.c +++ b/src/info.c @@ -58,7 +58,7 @@ char sprnames[NUMSPRITES + 1][5] = "SPRG","BSPR","RNDM","RPOP","KFRE","DRIF","DSMO","FITM","DFAK","BANA", "DBAN","GSHE","DGSH","RSHE","DRSH","BOMB","BLIG","LIGH","SINK","SITR", "KBLN","LAKI","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB", - "CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO" + "CHOM","SACO","CRAB","SHAD","BUMP","FLEN","CLAS","PSHW","ARRO","PBOM" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2883,6 +2883,9 @@ state_t states[NUMSTATES] = {SPR_ARRO, FF_FULLBRIGHT|14, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_MEGASHROOM {SPR_ARRO, FF_FULLBRIGHT|15, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_KITCHENSINK {SPR_ARRO, FF_FULLBRIGHT|16, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_EMPTY + {SPR_ARRO, FF_FULLBRIGHT|FF_ANIMATE|1, -1, {NULL}, 5, 3, S_NULL}, // S_PLAYERARROW_ROULETTE + + {SPR_PBOM, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERBOMB #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK diff --git a/src/info.h b/src/info.h index f701c5fb..be4a58f2 100644 --- a/src/info.h +++ b/src/info.h @@ -623,6 +623,8 @@ typedef enum sprite SPR_ARRO, // player arrows + SPR_PBOM, // player bomb + SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, NUMSPRITES @@ -3402,6 +3404,9 @@ typedef enum state S_PLAYERARROW_MEGASHROOM, S_PLAYERARROW_KITCHENSINK, S_PLAYERARROW_EMPTY, + S_PLAYERARROW_ROULETTE, + + S_PLAYERBOMB, #ifdef SEENAMES S_NAMECHECK, diff --git a/src/k_kart.c b/src/k_kart.c index 466d7483..d558fc23 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -691,17 +691,17 @@ static INT32 K_KartItemOddsDistance_Retro[NUMKARTITEMS][10] = { //P-Odds 0 1 2 3 4 5 6 7 8 9 /*Magnet*/ { 0, 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Magnet - /*Boo*/ { 0, 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Boo - /*Mushroom*/ { 5, 1, 0, 0, 3, 7, 5, 0, 0, 0 }, // Mushroom + /*Boo*/ { 4, 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Boo + /*Mushroom*/ { 4, 1, 0, 0, 3, 7, 5, 0, 0, 0 }, // Mushroom /*Triple Mushroom*/ { 0, 0, 0, 0, 0, 3,10, 6, 4, 0 }, // Triple Mushroom /*Mega Mushroom*/ { 1, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // Mega Mushroom /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 0, 1, 6, 8,12 }, // Gold Mushroom /*Star*/ { 1, 0, 0, 0, 0, 0, 0, 4, 6, 8 }, // Star /*Triple Banana*/ { 2, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Triple Banana - /*Fake Item*/ { 5, 0, 4, 2, 1, 0, 0, 0, 0, 0 }, // Fake Item - /*Banana*/ { 5, 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana - /*Green Shell*/ { 5, 0, 6, 4, 3, 2, 0, 0, 0, 0 }, // Green Shell + /*Fake Item*/ { 4, 0, 4, 2, 1, 0, 0, 0, 0, 0 }, // Fake Item + /*Banana*/ { 4, 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana + /*Green Shell*/ { 4, 0, 6, 4, 3, 2, 0, 0, 0, 0 }, // Green Shell /*Red Shell*/ { 2, 0, 0, 3, 2, 2, 1, 0, 0, 0 }, // Red Shell /*Triple Green Shell*/ { 2, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, // Triple Green Shell /*Bob-omb*/ { 2, 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Bob-omb @@ -1337,6 +1337,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) && player->kartstuff[k_goldshroomtimer]) player->kartstuff[k_goldshroomtimer]--; + if (player->kartstuff[k_bootimer]) + player->kartstuff[k_bootimer]--; + if (player->kartstuff[k_bootaketimer]) player->kartstuff[k_bootaketimer]--; @@ -1349,18 +1352,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_laserwisptimer]) player->kartstuff[k_laserwisptimer]--; + if (player->kartstuff[k_justbumped]) + player->kartstuff[k_justbumped]--; + if (player->kartstuff[k_poweritemtimer]) player->kartstuff[k_poweritemtimer]--; + if (player->kartstuff[k_comebacktimer]) + player->kartstuff[k_comebacktimer]--; + if (player->kartstuff[k_lapanimation]) player->kartstuff[k_lapanimation]--; if (player->kartstuff[k_sounds]) player->kartstuff[k_sounds]--; - if (player->kartstuff[k_justbumped]) - player->kartstuff[k_justbumped]--; - // ??? /* if (player->kartstuff[k_jmp] > 1 && onground) @@ -1447,7 +1453,7 @@ static fixed_t K_GetKartBoostPower(player_t *player, boolean speed) fixed_t boostvalue = 0; // Offroad is separate, it's difficult to factor it in with a variable value anyway. - if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootaketimer] || player->kartstuff[k_mushroomtimer]) + if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootimer] || player->kartstuff[k_mushroomtimer]) && player->kartstuff[k_offroad] >= 0 && speed) boostpower = FixedDiv(boostpower, player->kartstuff[k_offroad] + FRACUNIT); @@ -1587,21 +1593,26 @@ void K_SpinPlayer(player_t *player, mobj_t *source) return; if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) + || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 + || (gametype != GT_RACE && (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]))) return; player->kartstuff[k_mushroomtimer] = 0; player->kartstuff[k_driftboost] = 0; + player->kartstuff[k_comebacktimer] = comebacktime; if (gametype != GT_RACE) { - player->kartstuff[k_balloon]--; - - if (player->kartstuff[k_balloon] <= 0) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (player->kartstuff[k_balloon] > 0) + { + if (player->kartstuff[k_balloon] == 1) + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + player->kartstuff[k_balloon]--; + } if (source && source->player && player != source->player) P_AddPlayerScore(source->player, 1); + source->player->kartstuff[k_comebacktimer] = comebacktime; K_CheckBalloons(); } @@ -1640,22 +1651,27 @@ void K_SquishPlayer(player_t *player, mobj_t *source) if (player->health <= 0) return; - if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) + if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_startimer] > 0 + || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 + || (gametype != GT_RACE && (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]))) return; player->kartstuff[k_mushroomtimer] = 0; player->kartstuff[k_driftboost] = 0; + player->kartstuff[k_comebacktimer] = comebacktime; if (gametype != GT_RACE) { - player->kartstuff[k_balloon]--; - - if (player->kartstuff[k_balloon] <= 0) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (player->kartstuff[k_balloon] > 0) + { + if (player->kartstuff[k_balloon] == 1) + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + player->kartstuff[k_balloon]--; + } if (source && source->player && player != source->player) P_AddPlayerScore(source->player, 1); + source->player->kartstuff[k_comebacktimer] = comebacktime; K_CheckBalloons(); } @@ -1681,7 +1697,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju return; if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) + || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 + || (gametype != GT_RACE && (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer]))) return; player->mo->momz = 18*FRACUNIT; @@ -1689,16 +1706,20 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju player->kartstuff[k_mushroomtimer] = 0; player->kartstuff[k_driftboost] = 0; + player->kartstuff[k_comebacktimer] = comebacktime; if (gametype != GT_RACE) { - player->kartstuff[k_balloon]--; - - if (player->kartstuff[k_balloon] <= 0) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (player->kartstuff[k_balloon] > 0) + { + if (player->kartstuff[k_balloon] == 1) + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + player->kartstuff[k_balloon]--; + } if (source && source->player && player != source->player) P_AddPlayerScore(source->player, 1); + source->player->kartstuff[k_comebacktimer] = comebacktime; K_CheckBalloons(); } @@ -1743,22 +1764,21 @@ void K_StealBalloon(player_t *player, player_t *victim) return; if ((player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) - || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) + || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootimer] > 0 + || (player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer])) || (victim->powers[pw_flashing] > 0 || victim->kartstuff[k_squishedtimer] > 0 || (victim->kartstuff[k_spinouttimer] > 0 && victim->kartstuff[k_spinout] > 0) - || victim->kartstuff[k_startimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_bootaketimer] > 0)) + || victim->kartstuff[k_startimer] > 0 || victim->kartstuff[k_growshrinktimer] > 0 || victim->kartstuff[k_bootimer] > 0)) return; - victim->kartstuff[k_mushroomtimer] = 0; - victim->kartstuff[k_driftboost] = 0; - CONS_Printf(M_GetText("%s stole a balloon from %s!\n"), player_names[player-players], player_names[victim-players]); newballoon = player->kartstuff[k_balloon]; - newangle = player->mo->angle; if (newballoon <= 1) diff = 0; else diff = FixedAngle(360*FRACUNIT/newballoon); + + newangle = player->mo->angle; newx = player->mo->x + P_ReturnThrustX(player->mo, newangle + ANGLE_180, 64*FRACUNIT); newy = player->mo->y + P_ReturnThrustY(player->mo, newangle + ANGLE_180, 64*FRACUNIT); @@ -1769,40 +1789,14 @@ void K_StealBalloon(player_t *player, player_t *victim) newmo->angle = (diff * (newballoon-1)); newmo->color = victim->skincolor; - if (newballoon+1 <= 1) + if (newballoon+1 < 2) P_SetMobjState(newmo, S_BATTLEBALLOON3); - else if (newballoon+1 == 2) + else if (newballoon+1 < 3) P_SetMobjState(newmo, S_BATTLEBALLOON2); else P_SetMobjState(newmo, S_BATTLEBALLOON1); player->kartstuff[k_balloon]++; - victim->kartstuff[k_balloon]--; - - if (victim->kartstuff[k_balloon] <= 0) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[victim-players]); - - P_AddPlayerScore(player, 1); - K_CheckBalloons(); - - victim->kartstuff[k_spinouttype] = 1; - victim->kartstuff[k_spinouttimer] = 2*TICRATE+(TICRATE/2); - victim->kartstuff[k_spinout] = victim->kartstuff[k_spinouttimer]; - - victim->powers[pw_flashing] = flashingtics; - - if (!(victim->mo->state >= &states[S_KART_SPIN1] && victim->mo->state <= &states[S_KART_SPIN8])) - P_SetPlayerMobjState(victim->mo, S_KART_SPIN1); - - victim->kartstuff[k_spinouttype] = 0; - - P_PlayRinglossSound(victim->mo); - - if (P_IsLocalPlayer(victim)) - { - quake.intensity = 64*FRACUNIT; - quake.time = 5; - } return; } @@ -1966,7 +1960,7 @@ void K_SpawnDriftTrail(player_t *player) for (i = 0; i < 2; i++) { - if (player->kartstuff[k_bootaketimer] != 0) + if (player->kartstuff[k_bootimer] != 0 || (gametype != GT_RACE && player->kartstuff[k_balloon] <= 0)) continue; newx = player->mo->x + P_ReturnThrustX(player->mo, travelangle + ((i&1) ? -1 : 1)*ANGLE_135, FixedMul(24*FRACUNIT, player->mo->scale)); @@ -2209,7 +2203,7 @@ static void K_DoBooSteal(player_t *player) if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE && player != &players[i] && !players[i].exiting && !players[i].powers[pw_super] && !(players[i].spectator) && ((gametype == GT_RACE && players[i].kartstuff[k_position] < player->kartstuff[k_position]) - || (gametype == GT_MATCH && players[i].kartstuff[k_balloon] > 0)) + || (gametype != GT_RACE && players[i].kartstuff[k_balloon] > 0)) && (players[i].kartstuff[k_star] || players[i].kartstuff[k_mushroom] || players[i].kartstuff[k_goldshroom] || players[i].kartstuff[k_megashroom] || players[i].kartstuff[k_lightning] || players[i].kartstuff[k_blueshell] @@ -2228,7 +2222,8 @@ static void K_DoBooSteal(player_t *player) if (player->kartstuff[k_position] == 1 || numplayers < 1) // No-one can be stolen from? Get longer invisibility for nothing { - player->kartstuff[k_bootaketimer] = bootime; + player->kartstuff[k_bootimer] = bootime; + player->kartstuff[k_bootaketimer] = boostealtime; player->kartstuff[k_boo] = 0; return; } @@ -2245,9 +2240,10 @@ static void K_DoBooSteal(player_t *player) { stealplayer -= 1; // stealplayer is +1 so we know if it found there actually WAS a player - player->kartstuff[k_bootaketimer] = bootime; + player->kartstuff[k_bootimer] = bootime; + player->kartstuff[k_bootaketimer] = boostealtime; player->kartstuff[k_boo] = 0; - players[stealplayer].kartstuff[k_boostolentimer] = bootime; + players[stealplayer].kartstuff[k_boostolentimer] = boostealtime; if (players[stealplayer].kartstuff[k_star]) { @@ -2681,10 +2677,12 @@ static void K_StripItems(player_t *player) || player->kartstuff[k_mushroom] || player->kartstuff[k_boo] || player->kartstuff[k_magnet] - //|| player->kartstuff[k_bootaketimer] // uncomment when proper comeback mechanic is in + || player->kartstuff[k_bootimer] + || player->kartstuff[k_bootaketimer] || player->kartstuff[k_boostolentimer] || player->kartstuff[k_goldshroomtimer] || player->kartstuff[k_growshrinktimer] + || player->kartstuff[k_itemroulette] ) player->kartstuff[k_itemclose] = 10; player->kartstuff[k_kitchensink] = 0; player->kartstuff[k_lightning] = 0; @@ -2704,7 +2702,9 @@ static void K_StripItems(player_t *player) player->kartstuff[k_mushroom] = 0; player->kartstuff[k_boo] = 0; player->kartstuff[k_magnet] = 0; - //player->kartstuff[k_bootaketimer] = 0; + player->kartstuff[k_itemroulette] = 0; + player->kartstuff[k_bootimer] = 0; + player->kartstuff[k_bootaketimer] = 0; player->kartstuff[k_boostolentimer] = 0; player->kartstuff[k_goldshroomtimer] = 0; player->kartstuff[k_growshrinktimer] = 0; @@ -3192,11 +3192,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) || player->kartstuff[k_startimer] || player->kartstuff[k_growshrinktimer] > 0)) player->kartstuff[k_poweritemtimer] = 10*TICRATE; - if (player->kartstuff[k_bootaketimer] > 0) + if (player->kartstuff[k_bootimer] > 0) { if ((player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer])) || (!(player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer])) - && (player->kartstuff[k_bootaketimer] < 1*TICRATE/2 || player->kartstuff[k_bootaketimer] > bootime-(1*TICRATE/2)))) + && (player->kartstuff[k_bootimer] < 1*TICRATE/2 || player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) { if (leveltime & 1) player->mo->flags2 |= MF2_DONTDRAW; @@ -3206,14 +3206,35 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else player->mo->flags2 |= MF2_DONTDRAW; - player->powers[pw_flashing] = player->kartstuff[k_bootaketimer]; // We'll do this for now, let's people know about the invisible people through subtle hints + player->powers[pw_flashing] = player->kartstuff[k_bootimer]; // We'll do this for now, let's people know about the invisible people through subtle hints } - else if (player->kartstuff[k_bootaketimer] == 0) + else if (player->kartstuff[k_bootimer] == 0) { player->mo->flags2 &= ~MF2_DONTDRAW; } } + if (gametype != GT_RACE && player->kartstuff[k_balloon] <= 0) // dead in match? you da bomb + { + K_StripItems(player); + player->mo->flags2 |= MF2_DONTDRAW; + + if (player->kartstuff[k_comebacktimer]) + player->powers[pw_flashing] = 2; + + if (!(player->mo->tracer)) + player->mo->tracer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_OVERLAY); + + P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); + P_SetTarget(&player->mo->tracer, player->mo); + player->mo->tracer->color = player->mo->color; + } + else if (player->mo->tracer && player->mo->tracer->state == &states[S_PLAYERBOMB]) + { + player->mo->flags2 &= ~MF2_DONTDRAW; + P_RemoveMobj(player->mo->tracer); + } + if (player->kartstuff[k_growshrinktimer] > 1) player->powers[pw_flashing] = 2; @@ -3280,12 +3301,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->kartstuff[k_boostcharge] = 0; } - - if (gametype == GT_MATCH && player->kartstuff[k_balloon] <= 0) // dead in match? BOO! - { - K_StripItems(player); - player->kartstuff[k_bootaketimer] = bootime; - } } void K_CheckBalloons(void) @@ -3294,7 +3309,13 @@ void K_CheckBalloons(void) UINT8 numingame = 0; INT8 winnernum = -1; - if (gamestate != GS_LEVEL) + if (!(multiplayer || netgame)) + return; + + if (gametype == GT_RACE) + return; + + if (gameaction == ga_completed) return; for (i = 0; i < MAXPLAYERS; i++) @@ -3793,7 +3814,6 @@ static void K_drawKartRetroItem(void) // This shouldn't have any actual baring over how it functions // Boo is first, because we're drawing it on top of the player's current item if ((stplyr->kartstuff[k_bootaketimer] > 0 || stplyr->kartstuff[k_boostolentimer] > 0) - && !(gametype == GT_MATCH && stplyr->kartstuff[k_balloon] <= 0) && (leveltime & 2)) localpatch = kp_boosteal; else if (stplyr->kartstuff[k_boostolentimer] > 0 && !(leveltime & 2)) localpatch = kp_noitem; else if (stplyr->kartstuff[k_kitchensink] == 1) localpatch = kp_kitchensink; @@ -4141,44 +4161,23 @@ static void K_drawKartSpeedometer(void) } } -fixed_t K_FindCheckX(INT32 p, fixed_t mx, fixed_t my) +fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my) { - fixed_t camx, camy, dist, x; - angle_t camangle; - camera_t *c = &camera; + fixed_t dist, x; + angle_t diff; - if (players[p].awayviewtics) - { - camx = players[p].awayviewmobj->x; - camy = players[p].awayviewmobj->y; - camangle = players[p].awayviewmobj->angle; - } - else if (c->chase) - { - camx = c->x; - camy = c->y; - camangle = c->angle; - } - else - { - camx = players[p].mo->x; - camy = players[p].mo->y; - camangle = players[p].mo->angle; - } - - dist = abs(R_PointToDist2(camx, camy, mx, my)); - if (dist > RING_DIST) + dist = abs(R_PointToDist2(px, py, mx, my)); + if (dist > RING_DIST/4) return -320; - camangle = camangle+ANGLE_180; - x = camangle-R_PointToAngle2(camx, camy, mx, my); + diff = R_PointToAngle2(px, py, mx, my) - ang; - if (x > ANGLE_90 || x < ANGLE_270) + if (diff < ANGLE_90 || diff > ANGLE_270) return -320; else - x = FixedMul(FINETANGENT(((x+ANGLE_90)>>ANGLETOFINESHIFT) & FINEMASK), 160<>ANGLETOFINESHIFT) & 4095), 160<>FRACBITS); + return (x>>FRACBITS); } static void K_drawKartPlayerCheck(void) @@ -4191,7 +4190,10 @@ static void K_drawKartPlayerCheck(void) if (splitscreen) return; - if (players[displayplayer].mo == NULL) + if (!(players[displayplayer].mo)) + return; + + if (players[displayplayer].awayviewtics) return; for (i = 0; i < MAXPLAYERS; i++) @@ -4219,8 +4221,8 @@ static void K_drawKartPlayerCheck(void) else localpatch = kp_check; } - - x = K_FindCheckX(displayplayer, players[i].mo->x, players[i].mo->y); + + x = K_FindCheckX(players[displayplayer].mo->x, players[displayplayer].mo->y, players[displayplayer].mo->angle, players[i].mo->x, players[i].mo->y); if (x <= 320 && x >= 0) { if (x < 14) diff --git a/src/p_enemy.c b/src/p_enemy.c index d64a66d7..2a0be039 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3921,7 +3921,8 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) if (thing == grenade->target && !(grenade->threshold == 0)) // Don't blow up at your owner. return true; - if (thing->player && thing->player->kartstuff[k_bootaketimer]) + if (thing->player && (thing->player->kartstuff[k_bootimer] + || (thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer]))) return true; if ((gametype == GT_CTF || gametype == GT_TEAMMATCH) @@ -8207,7 +8208,7 @@ void A_RedShellChase(mobj_t *actor) continue; } - if (!(gametype == GT_RACE)) + if (gametype != GT_RACE) { if (player->kartstuff[k_balloon] <= 0) continue; @@ -8267,6 +8268,9 @@ void A_BobombExplode(mobj_t *actor) if (mo2 == actor || mo2->type == MT_BOMBEXPLOSIONSOUND) // Don't explode yourself! Endless loop! continue; + if (actor->target && actor->target->player && actor->target->player->kartstuff[k_balloon] <= 0 && mo2 == actor->target) + continue; + if (P_AproxDistance(P_AproxDistance(mo2->x - actor->x, mo2->y - actor->y), mo2->z - actor->z) > actor->info->painchance) continue; diff --git a/src/p_inter.c b/src/p_inter.c index 6d8bdd54..3e3899a2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -150,7 +150,11 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) //if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics) // return false; - if (player->kartstuff[k_greenshell] || player->kartstuff[k_triplegreenshell] + if (gametype != GT_RACE && player->kartstuff[k_balloon] <= 0) + return false; + + if (player->kartstuff[k_itemroulette] + || player->kartstuff[k_greenshell] || player->kartstuff[k_triplegreenshell] || player->kartstuff[k_redshell] || player->kartstuff[k_tripleredshell] || player->kartstuff[k_banana] || player->kartstuff[k_triplebanana] || player->kartstuff[k_fakeitem] & 2 || player->kartstuff[k_magnet] @@ -158,7 +162,6 @@ boolean P_CanPickupItem(player_t *player, boolean weapon) || player->kartstuff[k_mushroom] || player->kartstuff[k_fireflower] || player->kartstuff[k_star] || player->kartstuff[k_goldshroom] || player->kartstuff[k_lightning] || player->kartstuff[k_megashroom] - || player->kartstuff[k_itemroulette] || player->kartstuff[k_boo] || player->kartstuff[k_bootaketimer] || player->kartstuff[k_boostolentimer] || player->kartstuff[k_growshrinktimer] > 1 @@ -2745,10 +2748,12 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) if (gametype != GT_RACE) { - player->kartstuff[k_balloon]--; - - if (player->kartstuff[k_balloon] <= 0) - CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (player->kartstuff[k_balloon] > 0) + { + if (player->kartstuff[k_balloon] == 1) + CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + player->kartstuff[k_balloon]--; + } K_CheckBalloons(); } diff --git a/src/p_map.c b/src/p_map.c index 389a1cbc..bc657c9d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1598,15 +1598,55 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->player) // bounce when players collide { if (thing->player->kartstuff[k_growshrinktimer] || thing->player->kartstuff[k_squishedtimer] - || thing->player->kartstuff[k_bootaketimer] || thing->player->kartstuff[k_spinouttimer] + || thing->player->kartstuff[k_bootimer] || thing->player->kartstuff[k_spinouttimer] || thing->player->kartstuff[k_startimer] || thing->player->kartstuff[k_justbumped] + || (gametype != GT_RACE && (thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebacktimer])) || tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer] - || tmthing->player->kartstuff[k_bootaketimer] || tmthing->player->kartstuff[k_spinouttimer] - || tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped]) + || tmthing->player->kartstuff[k_bootimer] || tmthing->player->kartstuff[k_spinouttimer] + || tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped] + || (gametype != GT_RACE && (tmthing->player->kartstuff[k_balloon] <= 0 && tmthing->player->kartstuff[k_comebacktimer]))) { return true; } + if (gametype != GT_RACE) + { + if (thing->player->kartstuff[k_balloon] <= 0 || tmthing->player->kartstuff[k_balloon] <= 0) + { + thing->player->kartstuff[k_justbumped] = 6; + tmthing->player->kartstuff[k_justbumped] = 6; + if (tmthing->player->kartstuff[k_balloon] > 0) + { + if (tmthing->player->kartstuff[k_balloon] == 1) + K_StealBalloon(thing->player, tmthing->player); + thing->player->kartstuff[k_comebacktimer] = comebacktime; + K_ExplodePlayer(tmthing->player, thing); + return true; + } + else if (thing->player->kartstuff[k_balloon] > 0) + { + if (thing->player->kartstuff[k_balloon] == 1) + K_StealBalloon(tmthing->player, thing->player); + tmthing->player->kartstuff[k_comebacktimer] = comebacktime; + K_ExplodePlayer(thing->player, thing); + return true; + } + } + else + { + if (thing->player->kartstuff[k_mushroomtimer] && !(tmthing->player->kartstuff[k_mushroomtimer])) + { + K_StealBalloon(thing->player, tmthing->player); + K_SpinPlayer(tmthing->player, thing); + } + else if (tmthing->player->kartstuff[k_mushroomtimer] && !(thing->player->kartstuff[k_mushroomtimer])) + { + K_StealBalloon(tmthing->player, thing->player); + K_SpinPlayer(thing->player, tmthing); + } + } + } + if (P_IsObjectOnGround(thing) && tmthing->momz < 0) K_KartBilliards(tmthing, thing, true); else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) @@ -1614,14 +1654,6 @@ static boolean PIT_CheckThing(mobj_t *thing) else K_KartBilliards(tmthing, thing, false); - if (gametype != GT_RACE) - { - if (thing->player->kartstuff[k_mushroomtimer] && !(tmthing->player->kartstuff[k_mushroomtimer])) - K_StealBalloon(thing->player, tmthing->player); - else if (tmthing->player->kartstuff[k_mushroomtimer] && !(thing->player->kartstuff[k_mushroomtimer])) - K_StealBalloon(tmthing->player, thing->player); - } - thing->player->kartstuff[k_justbumped] = 6; tmthing->player->kartstuff[k_justbumped] = 6; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 7ad58e00..dcaadcdc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6509,11 +6509,11 @@ void P_MobjThinker(mobj_t *mobj) INT32 HEIGHT; fixed_t radius; - if (mobj->target->player->kartstuff[k_bootaketimer] > 0) + if (mobj->target->player->kartstuff[k_bootimer] > 0) { if ((mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer])) || (!(mobj->target->player == &players[displayplayer] || (splitscreen && mobj->target->player == &players[secondarydisplayplayer])) - && (mobj->target->player->kartstuff[k_bootaketimer] < 1*TICRATE/2 || mobj->target->player->kartstuff[k_bootaketimer] > bootime-(1*TICRATE/2)))) + && (mobj->target->player->kartstuff[k_bootimer] < 1*TICRATE/2 || mobj->target->player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) { if (leveltime & 1) mobj->flags2 |= MF2_DONTDRAW; @@ -6523,7 +6523,7 @@ void P_MobjThinker(mobj_t *mobj) else mobj->flags2 |= MF2_DONTDRAW; } - else if (mobj->target->player->kartstuff[k_bootaketimer] == 0) + else if (mobj->target->player->kartstuff[k_bootimer] == 0) { mobj->flags2 &= ~MF2_DONTDRAW; } @@ -6709,9 +6709,9 @@ void P_MobjThinker(mobj_t *mobj) else mobj->color = mobj->target->color; // but do so if it belongs to you :B - if (mobj->target->player->kartstuff[k_balloon] <= 1) + if (mobj->target->player->kartstuff[k_balloon] < 2) P_SetMobjState(mobj, S_BATTLEBALLOON3); - else if (mobj->target->player->kartstuff[k_balloon] == 2) + else if (mobj->target->player->kartstuff[k_balloon] < 3) P_SetMobjState(mobj, S_BATTLEBALLOON2); else P_SetMobjState(mobj, S_BATTLEBALLOON1); @@ -6759,8 +6759,9 @@ void P_MobjThinker(mobj_t *mobj) mobj->flags2 &= ~MF2_DONTDRAW; if ((splitscreen || !netgame) - || (gametype == GT_RACE) - || (mobj->target->player->kartstuff[k_bootaketimer] > 0)) + || gametype == GT_RACE + || mobj->target->player->kartstuff[k_bootimer] + || (mobj->target->player->kartstuff[k_balloon] <= 0 && mobj->target->player->kartstuff[k_comebacktimer])) mobj->flags2 |= MF2_DONTDRAW; P_UnsetThingPosition(mobj); @@ -6780,7 +6781,12 @@ void P_MobjThinker(mobj_t *mobj) P_SetThingPosition(mobj); // Set it to use the correct states for its condition - if (mobj->target->player->kartstuff[k_kitchensink]) P_SetMobjState(mobj, S_PLAYERARROW_KITCHENSINK); + if (mobj->target->player->kartstuff[k_itemroulette]) + { + if (mobj->state != &states[S_PLAYERARROW_ROULETTE]) // don't reset FF_ANIMATE + P_SetMobjState(mobj, S_PLAYERARROW_ROULETTE); + } + else if (mobj->target->player->kartstuff[k_kitchensink]) P_SetMobjState(mobj, S_PLAYERARROW_KITCHENSINK); else if (mobj->target->player->kartstuff[k_megashroom] == 1 || (mobj->target->player->kartstuff[k_growshrinktimer] > 1 && (leveltime & 1))) P_SetMobjState(mobj, S_PLAYERARROW_MEGASHROOM); @@ -9459,37 +9465,50 @@ void P_SpawnPlayer(INT32 playernum) overheadarrow->flags2 |= MF2_DONTDRAW; P_SetScale(overheadarrow, mobj->destscale); - if (gametype != GT_RACE && ((leveltime < 1 || D_NumPlayers() <= 1) || p->kartstuff[k_balloon] > 0)) // srb2kart + if (gametype != GT_RACE) { INT32 i; - angle_t newangle, diff; - fixed_t newx; - fixed_t newy; - mobj_t *mo; + INT32 pcount = 0; - if (leveltime < 1 || D_NumPlayers() <= 1) // Start of the map? - p->kartstuff[k_balloon] = cv_kartballoons.value; // Reset those balloons! - - if (p->kartstuff[k_balloon] <= 1) - diff = 0; - else - diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_balloon]); - - newangle = mobj->angle; - newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); - newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); - - for (i = 0; i < p->kartstuff[k_balloon]; i++) + for (i = 0; i < MAXPLAYERS; i++) { - mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBALLOON); - mo->threshold = i; - P_SetTarget(&mo->target, mobj); - mo->angle = (diff * (i-1)); - mo->color = mobj->color; - if (mobj->flags2 & MF2_DONTDRAW) - mo->flags2 |= MF2_DONTDRAW; + if (!playeringame[i] || players[i].spectator || &players[i] == p) + continue; + pcount++; + } + + if (p->kartstuff[k_balloon] > 0 || leveltime < 1 || pcount <= 1) // srb2kart + { + angle_t newangle; + angle_t diff; + fixed_t newx; + fixed_t newy; + mobj_t *mo; + + if (leveltime < 1 || pcount <= 1) // Start of the map? + p->kartstuff[k_balloon] = cv_kartballoons.value; // Reset those balloons! + + if (p->kartstuff[k_balloon] <= 1) + diff = 0; else - mo->flags2 &= ~MF2_DONTDRAW; + diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_balloon]); + + newangle = mobj->angle; + newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT); + newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT); + + for (i = 0; i < p->kartstuff[k_balloon]; i++) + { + mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBALLOON); + mo->threshold = i; + P_SetTarget(&mo->target, mobj); + mo->angle = (diff * (i-1)); + mo->color = mobj->color; + if (mobj->flags2 & MF2_DONTDRAW) + mo->flags2 |= MF2_DONTDRAW; + else + mo->flags2 &= ~MF2_DONTDRAW; + } } } } diff --git a/src/p_spec.c b/src/p_spec.c index a68608bc..40c60d9f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7140,7 +7140,7 @@ void T_Friction(friction_t *f) // friction works for all mobj's // (or at least MF_PUSHABLEs, which is all I care about anyway) if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player - && (thing->player->kartstuff[k_startimer] == 0 && thing->player->kartstuff[k_bootaketimer] == 0 + && (thing->player->kartstuff[k_startimer] == 0 && thing->player->kartstuff[k_bootimer] == 0 && thing->player->kartstuff[k_mushroomtimer] == 0 && thing->player->kartstuff[k_growshrinktimer] <= 0))) { if (f->roverfriction) diff --git a/src/p_user.c b/src/p_user.c index fa9daa01..935d61bd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9497,7 +9497,7 @@ void P_PlayerThink(player_t *player) { // SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local. if ((player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer])) - && player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0) + && player->kartstuff[k_bootimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0) { if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1)) player->mo->flags2 |= MF2_DONTDRAW; diff --git a/src/st_stuff.c b/src/st_stuff.c index a05bb686..15343adc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1922,14 +1922,14 @@ static void ST_overlayDrawer(void) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(116), 0, M_GetText("You cannot move while hiding.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); } - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. + /*else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; if (respawntime > 0 && !stplyr->spectator) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, va(M_GetText("Respawn in: %d second%s."), respawntime, respawntime == 1 ? "" : "s")); else V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Jump to respawn.")); - } + }*/ else if (stplyr->spectator #ifdef HAVE_BLUA && LUA_HudEnabled(hud_textspectator)