diff --git a/src/d_clisrv.c b/src/d_clisrv.c index b4a6c2d4..7278cc12 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2430,6 +2430,9 @@ static void CL_RemovePlayer(INT32 playernum) } } + if (K_IsPlayerWanted(&players[playernum])) + K_CalculateBattleWanted(); + if (gametype == GT_CTF) P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cda84010..ff6d82b3 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3238,7 +3238,12 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) // Clear player score and rings if a spectator. if (players[playernum].spectator) { - //players[playernum].score = 0; // SRB2kart + if (G_BattleGametype()) // SRB2kart + { + players[playernum].score = 0; + if (K_IsPlayerWanted(&players[playernum])) + K_CalculateBattleWanted(); + } players[playernum].health = 1; if (players[playernum].mo) players[playernum].mo->health = 1; @@ -4040,9 +4045,6 @@ static void Command_ModDetails_f(void) // static void Command_ShowGametype_f(void) { - INT32 j; - const char *gametypestr = NULL; - if (!(netgame || multiplayer)) // print "Single player" instead of "Race" { CONS_Printf(M_GetText("Current gametype is %s\n"), "Single Player"); diff --git a/src/d_player.h b/src/d_player.h index cb60ee6f..cdd1202b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -324,6 +324,7 @@ typedef enum k_balloon, // Number of balloons left k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a balloon k_comebackmode, // 0 = bomb, 1 = item + k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index c8a90d4d..36c0a460 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6604,6 +6604,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAYERARROW_ITEM", "S_PLAYERARROW_NUMBER", "S_PLAYERARROW_X", + "S_PLAYERARROW_WANTED1", + "S_PLAYERARROW_WANTED2", + "S_PLAYERARROW_WANTED3", + "S_PLAYERARROW_WANTED4", + "S_PLAYERARROW_WANTED5", + "S_PLAYERARROW_WANTED6", + "S_PLAYERARROW_WANTED7", "S_PLAYERBOMB", // Player bomb overlay "S_PLAYERITEM", // Player item overlay @@ -7238,6 +7245,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_FIREDITEM", "MT_PLAYERARROW", + "MT_PLAYERWANTED", "MT_KARMAHITBOX", "MT_KARMAWHEEL", diff --git a/src/doomstat.h b/src/doomstat.h index 433cfbd7..2a596087 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -415,6 +415,8 @@ extern INT32 sneakertime; extern INT32 itemtime; extern INT32 comebacktime; extern INT32 bumptime; +extern INT32 wantedreduce; +extern INT32 wantedfrequency; extern UINT8 introtoplay; extern UINT8 creditscutscene; @@ -445,6 +447,7 @@ extern boolean franticitems; extern boolean mirrormode; extern boolean comeback; +extern SINT8 battlewanted[4]; extern tic_t indirectitemcooldown; extern tic_t spbincoming; extern UINT8 spbplayer; diff --git a/src/g_game.c b/src/g_game.c index 8b413360..a43a2f54 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -215,6 +215,8 @@ INT32 sneakertime = TICRATE + (TICRATE/3); INT32 itemtime = 8*TICRATE; INT32 comebacktime = 10*TICRATE; INT32 bumptime = 6; +INT32 wantedreduce = 5*TICRATE; +INT32 wantedfrequency = 10*TICRATE; INT32 gameovertics = 15*TICRATE; @@ -255,6 +257,7 @@ SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls // Server-sided variables +SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t spbincoming; // Timer before SPB hits, can switch targets at this point UINT8 spbplayer; // Player num that used the last SPB @@ -2291,6 +2294,7 @@ void G_PlayerReborn(INT32 player) INT32 starpostwp; INT32 balloon; INT32 comebackpoints; + INT32 wanted; score = players[player].score; lives = players[player].lives; @@ -2347,6 +2351,7 @@ void G_PlayerReborn(INT32 player) starpostwp = players[player].kartstuff[k_starpostwp]; balloon = players[player].kartstuff[k_balloon]; comebackpoints = players[player].kartstuff[k_comebackpoints]; + wanted = players[player].kartstuff[k_wanted]; p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2405,6 +2410,7 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_balloon] = balloon; p->kartstuff[k_comebackpoints] = comebackpoints; p->kartstuff[k_comebacktimer] = comebacktime; + p->kartstuff[k_wanted] = wanted; // Don't do anything immediately p->pflags |= PF_USEDOWN; @@ -3387,8 +3393,13 @@ static void G_DoWorldDone(void) { if (server) { - // SRB2kart: don't reset player between maps - D_MapChange(nextmap+1, deferredgametype, ultimatemode, (deferredgametype != gametype), 0, false, false); + // SRB2Kart + if (G_RaceGametype() && (deferredgametype == gametype)) + // don't reset player between maps in Race + D_MapChange(nextmap+1, deferredgametype, ultimatemode, false, 0, false, false); + else + // resetplayer in Battle for more equality + D_MapChange(nextmap+1, deferredgametype, ultimatemode, true, 0, false, false); } gameaction = ga_nothing; diff --git a/src/info.c b/src/info.c index 4e3078e6..a8d828f7 100644 --- a/src/info.c +++ b/src/info.c @@ -59,7 +59,7 @@ char sprnames[NUMSPRITES + 1][5] = "BANA","GSHE","JAWZ","SSMN","KRBM","BHOG","BLIG","LIGH","SINK","SITR", "KBLN","DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB", "CHOM","SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ARRO", - "ITEM","ITMI","ITMN","PBOM","VIEW" + "ITEM","ITMI","ITMN","WANT","PBOM","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2922,6 +2922,14 @@ state_t states[NUMSTATES] = {SPR_ITEM, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_ITEM {SPR_ITMN, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_NUMBER {SPR_ITMN, FF_FULLBRIGHT|10, 2, {NULL}, 0, 0, S_NULL}, // S_PLAYERARROW_X + {SPR_WANT, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_PLAYERARROW_WANTED2}, // S_PLAYERARROW_WANTED1 + {SPR_WANT, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED3}, // S_PLAYERARROW_WANTED2 + {SPR_WANT, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED4}, // S_PLAYERARROW_WANTED3 + {SPR_WANT, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED5}, // S_PLAYERARROW_WANTED4 + {SPR_WANT, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED6}, // S_PLAYERARROW_WANTED5 + {SPR_WANT, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_PLAYERARROW_WANTED7}, // S_PLAYERARROW_WANTED6 + {SPR_WANT, FF_FULLBRIGHT|6, 3, {NULL}, 0, 0, S_PLAYERARROW_WANTED1}, // S_PLAYERARROW_WANTED7 + {SPR_PBOM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_PLAYERBOMB {SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM @@ -16587,6 +16595,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_PLAYERWANTED + -1, // doomednum + S_PLAYERARROW_WANTED1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 36*FRACUNIT, // radius + 37*FRACUNIT, // height + 0, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, + { // MT_KARMAHITBOX -1, // doomednum S_PLAYERBOMB, // spawnstate diff --git a/src/info.h b/src/info.h index 611e337e..89a33c6c 100644 --- a/src/info.h +++ b/src/info.h @@ -627,6 +627,7 @@ typedef enum sprite SPR_ITEM, SPR_ITMI, SPR_ITMN, + SPR_WANT, SPR_PBOM, // player bomb @@ -3450,6 +3451,13 @@ typedef enum state S_PLAYERARROW_ITEM, S_PLAYERARROW_NUMBER, S_PLAYERARROW_X, + S_PLAYERARROW_WANTED1, + S_PLAYERARROW_WANTED2, + S_PLAYERARROW_WANTED3, + S_PLAYERARROW_WANTED4, + S_PLAYERARROW_WANTED5, + S_PLAYERARROW_WANTED6, + S_PLAYERARROW_WANTED7, S_PLAYERBOMB, S_PLAYERITEM, @@ -4101,6 +4109,7 @@ typedef enum mobj_type MT_FIREDITEM, MT_PLAYERARROW, + MT_PLAYERWANTED, MT_KARMAHITBOX, MT_KARMAWHEEL, diff --git a/src/k_kart.c b/src/k_kart.c index 06876d62..c5d958ea 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -25,6 +25,7 @@ // franticitems is Frantic Mode items, bool // mirrormode is Mirror Mode (duh), bool // comeback is Battle Mode's karma comeback, also bool +// battlewanted is an array of the WANTED player nums, -1 for no player in that slot // indirectitemcooldown is timer before anyone's allowed another Shrink/SPB // spbincoming is the timer before k_deathsentence is cast on the player in 1st // spbplayer is the last player who fired a SPB @@ -428,6 +429,21 @@ boolean K_IsPlayerLosing(player_t *player) return (player->kartstuff[k_position] > winningpos); } +boolean K_IsPlayerWanted(player_t *player) +{ + UINT8 i; + if (!(G_BattleGametype())) + return false; + for (i = 0; i < 4; i++) + { + if (battlewanted[i] == -1) + break; + if (player == &players[battlewanted[i]]) + return true; + } + return false; +} + //{ SRB2kart Roulette Code - Position Based #define NUMKARTODDS 40 @@ -1438,8 +1454,10 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove return finalspeed; } -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type) +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) { + const UINT8 scoremultiply = ((K_IsPlayerWanted(player) && !trapitem) ? 2 : 1); + if (player->health <= 0) return; @@ -1457,7 +1475,14 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type) if (G_BattleGametype()) { if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); + { + P_AddPlayerScore(source->player, scoremultiply); + if (!trapitem) + { + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); + } + } if (player->kartstuff[k_balloon] > 0) { @@ -1468,6 +1493,8 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type) karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } player->kartstuff[k_balloon]--; } @@ -1502,6 +1529,8 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type) void K_SquishPlayer(player_t *player, mobj_t *source) { + const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + if (player->health <= 0) return; @@ -1516,7 +1545,11 @@ void K_SquishPlayer(player_t *player, mobj_t *source) if (G_BattleGametype()) { if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); + { + P_AddPlayerScore(source->player, scoremultiply); + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); + } if (player->kartstuff[k_balloon] > 0) { @@ -1527,6 +1560,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source) karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } player->kartstuff[k_balloon]--; } @@ -1552,6 +1587,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source) void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { + const UINT8 scoremultiply = (K_IsPlayerWanted(player) ? 2 : 1); + if (player->health <= 0) return; @@ -1569,7 +1606,11 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju if (G_BattleGametype()) { if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); + { + P_AddPlayerScore(source->player, scoremultiply); + source->player->kartstuff[k_wanted] -= wantedreduce; + player->kartstuff[k_wanted] -= (wantedreduce/2); + } if (player->kartstuff[k_balloon] > 0) { @@ -1580,6 +1621,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } player->kartstuff[k_balloon]--; } @@ -2091,10 +2134,10 @@ static mobj_t *K_FindLastTrailMobj(player_t *player) { mobj_t *trail; - if (!player || !(trail = player->mo) || !player->mo->hnext) + if (!player || !(trail = player->mo) || !player->mo->hnext || !player->mo->hnext->health) return NULL; - while (trail->hnext && !P_MobjWasRemoved(trail->hnext)) + while (trail->hnext && !P_MobjWasRemoved(trail->hnext) && trail->hnext->health) { trail = trail->hnext; } @@ -2482,13 +2525,13 @@ void K_RepairOrbitChain(mobj_t *orbit) mobj_t *cachenext = orbit->hnext; // First, repair the chain - if (orbit->hnext && !P_MobjWasRemoved(orbit->hnext)) + if (orbit->hnext && orbit->hnext->health && !P_MobjWasRemoved(orbit->hnext)) { P_SetTarget(&orbit->hnext->hprev, orbit->hprev); P_SetTarget(&orbit->hnext, NULL); } - if (orbit->hprev && !P_MobjWasRemoved(orbit->hprev)) + if (orbit->hprev && orbit->hprev->health && !P_MobjWasRemoved(orbit->hprev)) { P_SetTarget(&orbit->hprev->hnext, cachenext); P_SetTarget(&orbit->hprev, NULL); @@ -2537,6 +2580,12 @@ static void K_MoveHeldObjects(player_t *player) const fixed_t radius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(cur->radius, cur->radius); // mobj's distance from its Target, or Radius. fixed_t z; + if (!cur->health) + { + cur = cur->hnext; + continue; + } + cur->angle -= ANGLE_90; cur->angle += FixedAngle(cur->info->speed); @@ -2591,18 +2640,24 @@ static void K_MoveHeldObjects(player_t *player) while (cur && !P_MobjWasRemoved(cur)) { - const fixed_t spacing = FixedMul(3*cur->info->radius/2, player->mo->scale); + const fixed_t radius = FixedHypot(targ->radius, targ->radius) + FixedHypot(cur->radius, cur->radius); angle_t ang; fixed_t targx; fixed_t targy; fixed_t targz; fixed_t speed; - fixed_t dist = spacing; + fixed_t dist = radius/2; + + if (!cur->health) + { + cur = cur->hnext; + continue; + } if (cur != player->mo->hnext) { targ = cur->hprev; - dist = spacing/2; + dist = radius/4; } if (!targ || P_MobjWasRemoved(targ)) @@ -2767,6 +2822,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_tauntvoices]) player->kartstuff[k_tauntvoices]--; + if (G_BattleGametype() && player->kartstuff[k_balloon] > 0) + player->kartstuff[k_wanted]++; + // ??? /* if (player->kartstuff[k_jmp] > 1 && onground) @@ -3591,6 +3649,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_itemtype] == KITEM_SPB || player->kartstuff[k_itemtype] == KITEM_SHRINK + || player->kartstuff[k_growshrinktimer] < 0 || spbincoming) indirectitemcooldown = 20*TICRATE; @@ -3759,15 +3818,125 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } } +void K_CalculateBattleWanted(void) +{ + UINT8 numingame = 0, numwanted = 0; + SINT8 bestballoonplayer = -1, bestballoon = -1; + SINT8 camppos[MAXPLAYERS]; // who is the biggest camper + UINT8 ties = 0, nextcamppos = 0; + UINT8 i, j; + + if (!G_BattleGametype()) + { + for (i = 0; i < 4; i++) + battlewanted[i] = -1; + return; + } + + for (i = 0; i < MAXPLAYERS; i++) + camppos[i] = -1; // initialize + + for (i = 0; i < MAXPLAYERS; i++) + { + UINT8 position = 1; + + if (!playeringame[i] || players[i].spectator) // Not playing + continue; + + if (players[i].exiting) // We're done, don't calculate. + return; + + numingame++; + + if (players[i].kartstuff[k_balloon] <= 0) // Not alive, so don't do anything else + continue; + + if (bestballoon == -1 || players[i].kartstuff[k_balloon] > bestballoon) + { + bestballoon = players[i].kartstuff[k_balloon]; + bestballoonplayer = i; + } + else if (players[i].kartstuff[k_balloon] == bestballoon) + bestballoonplayer = -1; // Tie, no one has best balloon. + + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j] || players[j].spectator) + continue; + if (players[j].kartstuff[k_balloon] <= 0) + continue; + if (j == i) + continue; + if (players[j].kartstuff[k_wanted] == players[i].kartstuff[k_wanted] && players[j].score > players[i].score) + position++; + else if (players[j].kartstuff[k_wanted] > players[i].kartstuff[k_wanted]) + position++; + } + + position--; // Make zero based + + while (camppos[position] != -1) // Port priority! + position++; + + camppos[position] = i; + } + + if (numingame <= 2) + numwanted = 0; + else + numwanted = min(4, 1 + ((numingame-2) / 4)); + + for (i = 0; i < 4; i++) + { + if (i+1 > numwanted) // Not enough players for this slot to be wanted! + battlewanted[i] = -1; + else if (bestballoonplayer != -1) // If there's a player who has a single-handed lead over everyone else, they are the first to be wanted. + { + battlewanted[i] = bestballoonplayer; + bestballoonplayer = -1; // Don't set twice + } + else + { + // Do not add more than 2 wanted times that are tied with others. + // This could theoretically happen very easily if people don't hit each other for a while after the start of a match. + // (I will be sincerely impressed if more than 2 people tie + + if (camppos[nextcamppos] == -1 // Out of entries + || ties >= 2) // Already counted ties + { + battlewanted[i] = -1; + continue; + } + + if (ties < 2) + { + ties = 0; // Reset + for (j = 0; j < 2; j++) + { + if (camppos[nextcamppos+(j+1)] == -1) // Nothing beyond, cancel + break; + if (players[camppos[nextcamppos]].kartstuff[k_wanted] == players[camppos[nextcamppos+(j+1)]].kartstuff[k_wanted]) + ties++; + } + } + + if (ties < 2) // Is it still less than 2 after counting? + { + battlewanted[i] = camppos[nextcamppos]; + nextcamppos++; + } + else + battlewanted[i] = -1; + } + } +} + void K_CheckBalloons(void) { UINT8 i; UINT8 numingame = 0; SINT8 winnernum = -1; - -#if 0 - return; // set to 1 to test comeback mechanics while alone -#endif + INT32 winnerscoreadd = 0; if (!multiplayer) return; @@ -3787,21 +3956,24 @@ void K_CheckBalloons(void) return; numingame++; + winnerscoreadd += players[i].score; if (players[i].kartstuff[k_balloon] <= 0) // if you don't have any balloons, you're probably not a winner continue; else if (winnernum > -1) // TWO winners? that's dumb :V return; + winnernum = i; + winnerscoreadd -= players[i].score; } - if (numingame <= 1) - return; + /*if (numingame <= 1) + return;*/ - if (playeringame[winnernum]) + if (winnernum > -1 && playeringame[winnernum]) { - players[winnernum].score += 1; - CONS_Printf(M_GetText("%s recieved a point for winning!\n"), player_names[winnernum]); + players[winnernum].score += winnerscoreadd; + CONS_Printf(M_GetText("%s recieved %d point%s for winning!\n"), player_names[winnernum], winnerscoreadd, (winnerscoreadd == 1 ? "" : "s")); } for (i = 0; i < MAXPLAYERS; i++) @@ -3847,6 +4019,7 @@ static patch_t *kp_battlewin; static patch_t *kp_battlelose; static patch_t *kp_battlewait; static patch_t *kp_battleinfo; +static patch_t *kp_wanted; static patch_t *kp_itembg[4]; static patch_t *kp_itemmulsticker[2]; @@ -3937,6 +4110,7 @@ void K_LoadKartHUDGraphics(void) kp_battlelose = W_CachePatchName("K_BLOSE", PU_HUDGFX); kp_battlewait = W_CachePatchName("K_BWAIT", PU_HUDGFX); kp_battleinfo = W_CachePatchName("K_BINFO", PU_HUDGFX); + kp_wanted = W_CachePatchName("K_WANTED", PU_HUDGFX); // Kart Item Windows kp_itembg[0] = W_CachePatchName("K_ITBG", PU_HUDGFX); @@ -4022,6 +4196,7 @@ INT32 STCD_X, STCD_Y; // Starting countdown INT32 CHEK_Y; // CHECK graphic INT32 MINI_X, MINI_Y; // Minimap INT32 SPBW_X, SPBW_Y; // SPB warning +INT32 WANT_X, WANT_Y; // Battle WANTED poster static void K_initKartHUD(void) { @@ -4087,8 +4262,11 @@ static void K_initKartHUD(void) MINI_X = BASEVIDWIDTH - 50; // 270 MINI_Y = (BASEVIDHEIGHT/2)-16; // 84 // Blue Shell warning - SPBW_X = BASEVIDWIDTH/2; // 270 - SPBW_Y = BASEVIDHEIGHT- 24; // 176 + SPBW_X = BASEVIDWIDTH/2; // 270 + SPBW_Y = BASEVIDHEIGHT- 24; // 176 + // Battle WANTED poster + WANT_X = BASEVIDWIDTH - 55; // 270 + WANT_Y = BASEVIDHEIGHT- 71; // 176 if (splitscreen) // Splitscreen { @@ -4105,6 +4283,9 @@ static void K_initKartHUD(void) SPBW_Y = (BASEVIDHEIGHT/2)-8; + WANT_X = BASEVIDWIDTH-8; + WANT_Y = (BASEVIDHEIGHT/2)-12; + if (splitscreen > 1) // 3P/4P Small Splitscreen { ITEM_X = -9; @@ -4122,6 +4303,8 @@ static void K_initKartHUD(void) SPBW_X = BASEVIDWIDTH/4; + WANT_X = (BASEVIDWIDTH/2)-8; + if (splitscreen > 2) // 4P-only { MINI_X = (BASEVIDWIDTH/2); @@ -4730,6 +4913,64 @@ fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my return x; } +static void K_drawKartWanted(void) +{ + UINT8 i, numwanted = 0; + UINT8 *colormap = NULL; + + if (splitscreen) // Can't fit the poster on screen, sadly + { + if (K_IsPlayerWanted(stplyr) && leveltime % 10 > 3) + V_DrawRightAlignedString(WANT_X, WANT_Y, K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS|V_REDMAP), "WANTED"); + return; + } + + for (i = 0; i < 4; i++) + { + if (battlewanted[i] == -1) + break; + numwanted++; + } + + if (numwanted <= 0) + return; + + if (battlewanted[0] != -1) + colormap = R_GetTranslationColormap(0, players[battlewanted[0]].skincolor, GTC_CACHE); + V_DrawFixedPatch(WANT_X< 1) + y += 17; + } + + if (players[battlewanted[i]].skincolor == 0) + V_DrawFixedPatch(x*scale, y*scale, scale, V_HUDTRANS|V_SNAPTORIGHT|V_SNAPTOBOTTOM, faceprefix[p->skin], NULL); + else + { + colormap = R_GetTranslationColormap(TC_RAINBOW, p->skincolor, GTC_CACHE); + V_DrawFixedPatch(x*scale, y*scale, scale, V_HUDTRANS|V_SNAPTORIGHT|V_SNAPTOBOTTOM, faceprefix[p->skin], colormap); + } + } +} + static void K_drawKartPlayerCheck(void) { INT32 i; @@ -5192,7 +5433,7 @@ void K_drawKartHUD(void) // This is handled by console/menu values K_initKartHUD(); - // Draw that fun first person HUD! + // Draw that fun first person HUD! Drawn ASAP so it looks more "real". if ((stplyr == &players[displayplayer] && !camera.chase) || ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase) || ((splitscreen > 1 && stplyr == &players[thirddisplayplayer]) && !camera3.chase) @@ -5203,7 +5444,7 @@ void K_drawKartHUD(void) if (leveltime < 15 && stplyr == &players[displayplayer]) { if (leveltime <= 5) - V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,120); // Pure white on first three frames, to hide SRB2's awful level load artifacts + V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,120); // Pure white on first few frames, to hide SRB2's awful level load artifacts else V_DrawFadeScreen(120, 15-leveltime); // Then gradually fade out from there } @@ -5233,6 +5474,10 @@ void K_drawKartHUD(void) // Draw the item window K_drawKartItem(); + // Draw WANTED status + if (G_BattleGametype()) + K_drawKartWanted(); + // If not splitscreen, draw... if (!splitscreen) { diff --git a/src/k_kart.h b/src/k_kart.h index f046652a..ad31ad80 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -19,12 +19,13 @@ UINT8 K_GetKartColorByName(const char *name); void K_RegisterKartStuff(void); boolean K_IsPlayerLosing(player_t *player); +boolean K_IsPlayerWanted(player_t *player); void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); void K_RespawnChecker(player_t *player); void K_KartMoveAnimation(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type); +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source); void K_StealBalloon(player_t *player, player_t *victim, boolean force); @@ -46,6 +47,7 @@ fixed_t K_GetKartAccel(player_t *player); UINT16 K_GetKartFlashing(void); fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove); void K_MoveKartPlayer(player_t *player, boolean onground); +void K_CalculateBattleWanted(void); void K_CheckBalloons(void); INT32 K_calcSplitFlags(INT32 snapflags); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 9a47bf9d..3b91d477 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1993,6 +1993,26 @@ static int lib_kGetKartColorByName(lua_State *L) return 1; } +static int lib_kIsPlayerLosing(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + //HUDSAFE + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_IsPlayerLosing(player); + return 0; +} + +static int lib_kIsPlayerWanted(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + //HUDSAFE + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_IsPlayerWanted(player); + return 0; +} + static int lib_kKartBouncing(lua_State *L) { mobj_t *mobj1 = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -2013,12 +2033,13 @@ static int lib_kSpinPlayer(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); INT32 type = (INT32)luaL_checkinteger(L, 3); + boolean trapitem = luaL_checkboolean(L, 4); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!source) return LUA_ErrInvalid(L, "mobj_t"); - K_SpinPlayer(player, source, type); + K_SpinPlayer(player, source, type, trapitem); return 0; } @@ -2375,6 +2396,8 @@ static luaL_Reg lib[] = { // k_kart {"K_GetKartColorByName",lib_kGetKartColorByName}, + {"K_IsPlayerLosing",lib_kIsPlayerLosing}, + {"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_KartBouncing",lib_kKartBouncing}, {"K_SpinPlayer",lib_kSpinPlayer}, {"K_SquishPlayer",lib_kSquishPlayer}, diff --git a/src/p_inter.c b/src/p_inter.c index e7b5fcb7..c9a57b25 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -455,15 +455,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) boom->color = SKINCOLOR_RED; S_StartSound(boom, special->info->attacksound); - K_ExplodePlayer(player, special->target); - - special->target->player->kartstuff[k_comebackpoints] += 2; + special->target->player->kartstuff[k_comebackpoints] += 2 * (K_IsPlayerWanted(player) ? 2 : 1); if (netgame && cv_hazardlog.value) CONS_Printf(M_GetText("%s bombed %s!\n"), player_names[special->target->player-players], player_names[player-players]); if (special->target->player->kartstuff[k_comebackpoints] >= 3) K_StealBalloon(special->target->player, player, true); - special->target->player->kartstuff[k_comebacktimer] = comebacktime; + + K_ExplodePlayer(player, special->target); } } else if (special->target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, true)) @@ -471,16 +470,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) mobj_t *poof = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_EXPLODE); S_StartSound(poof, special->info->seesound); - player->kartstuff[k_itemroulette] = 1; - player->kartstuff[k_roulettetype] = 1; - special->target->player->kartstuff[k_comebackmode] = 0; special->target->player->kartstuff[k_comebackpoints]++; + if (netgame && cv_hazardlog.value) CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->target->player-players], player_names[player-players]); if (special->target->player->kartstuff[k_comebackpoints] >= 3) K_StealBalloon(special->target->player, player, true); special->target->player->kartstuff[k_comebacktimer] = comebacktime; + + player->kartstuff[k_itemroulette] = 1; + player->kartstuff[k_roulettetype] = 1; } return; // ***************************************** // @@ -2839,6 +2839,8 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) karmahitbox->destscale = player->mo->scale; P_SetScale(karmahitbox, player->mo->scale); CONS_Printf(M_GetText("%s lost all of their balloons!\n"), player_names[player-players]); + if (K_IsPlayerWanted(player)) + K_CalculateBattleWanted(); } player->kartstuff[k_balloon]--; } @@ -2970,6 +2972,8 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage) { + //const UINT8 scoremultiply = ((K_IsWantedPlayer(player) && !trapitem) : 2 ? 1); + if (!(inflictor && ((inflictor->flags & MF_MISSILE) || inflictor->player) && player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds]))) { P_DoPlayerPain(player, source, inflictor); @@ -2980,11 +2984,11 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN S_StartSound(player->mo, sfx_spkdth); } - if (source && source->player && !player->powers[pw_super]) //don't score points against super players + /*if (source && source->player && !player->powers[pw_super]) //don't score points against super players { // Award no points when players shoot each other when cv_friendlyfire is on. if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 1); + P_AddPlayerScore(source->player, scoremultiply); } if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) @@ -2994,9 +2998,9 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN { // Award no points when players shoot each other when cv_friendlyfire is on. if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo)) - P_AddPlayerScore(source->player, 1); + P_AddPlayerScore(source->player, scoremultiply); } - } + }*/ // Ring loss sound plays despite hitting spikes P_PlayRinglossSound(player->mo); // Ringledingle! @@ -3200,7 +3204,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8; // Wipeout - K_SpinPlayer(player, source, 1); + K_SpinPlayer(player, source, 1, false); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); @@ -3270,7 +3274,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da || inflictor->player)) { player->kartstuff[k_sneakertimer] = 0; - K_SpinPlayer(player, source, 1); + K_SpinPlayer(player, source, 1, (inflictor->type == MT_FAKEITEM || inflictor->type == MT_FAKESHIELD)); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); @@ -3283,7 +3287,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - K_SpinPlayer(player, source, 0); + K_SpinPlayer(player, source, 0, false); } return true; } diff --git a/src/p_map.c b/src/p_map.c index af8e7b4f..7fa89b3d 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -844,7 +844,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(thing->player, tmthing->target); else - K_SpinPlayer(thing->player, tmthing->target, 0); + K_SpinPlayer(thing->player, tmthing->target, 0, false); } return true; // This doesn't collide with anything, but we want it to effect the player anyway. @@ -877,7 +877,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PLAYER) { // Player Damage - K_SpinPlayer(thing->player, tmthing->target, 0); + K_SpinPlayer(thing->player, tmthing->target, 0, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD)); // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -1140,7 +1140,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // Player Damage - K_SpinPlayer(tmthing->player, thing->target, 0); + K_SpinPlayer(tmthing->player, thing->target, 0, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD)); // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -1170,7 +1170,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(tmthing->player, thing->target); else - K_SpinPlayer(tmthing->player, thing->target, 0); + K_SpinPlayer(tmthing->player, thing->target, 0, false); return true; } @@ -1648,7 +1648,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { K_StealBalloon(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0); + K_SpinPlayer(thing->player, tmthing, 0, false); } } else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) @@ -1657,7 +1657,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { K_StealBalloon(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0); + K_SpinPlayer(tmthing->player, thing, 0, false); } } else @@ -1668,12 +1668,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer])) { K_StealBalloon(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0); + K_SpinPlayer(tmthing->player, thing, 0, false); } else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer])) { K_StealBalloon(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0); + K_SpinPlayer(thing->player, tmthing, 0, false); } } diff --git a/src/p_mobj.c b/src/p_mobj.c index ec9be7bf..c9d07368 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6891,10 +6891,14 @@ void P_MobjThinker(mobj_t *mobj) fixed_t scale = mobj->target->scale; mobj->color = mobj->target->color; - if (!netgame || G_RaceGametype() + if (G_RaceGametype() || mobj->target->player == &players[displayplayer] || mobj->target->player->kartstuff[k_balloon] <= 0 - || (mobj->target->player->mo->flags2 & MF2_DONTDRAW)) + || (mobj->target->player->mo->flags2 & MF2_DONTDRAW) +#if 1 // Set to 0 to test without needing to host + || !netgame +#endif + ) mobj->flags2 |= MF2_DONTDRAW; else mobj->flags2 &= ~MF2_DONTDRAW; @@ -6935,6 +6939,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->target->player->kartstuff[k_itemroulette]) { P_SetMobjState(mobj, S_PLAYERARROW_BOX); + mobj->tracer->sprite = SPR_ITEM; mobj->tracer->frame = FF_FULLBRIGHT|((mobj->target->player->kartstuff[k_itemroulette] % (13*3)) / 3); } else if (mobj->target->player->kartstuff[k_itemtype]) @@ -6993,6 +6998,18 @@ void P_MobjThinker(mobj_t *mobj) P_SetScale(numx, mobj->scale); numx->destscale = scale; } + + if (K_IsPlayerWanted(mobj->target->player) && mobj->movecount != 1) + { + mobj_t *wanted = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PLAYERWANTED); + P_SetTarget(&wanted->target, mobj->target); + P_SetTarget(&wanted->tracer, mobj); + P_SetScale(wanted, mobj->scale); + wanted->destscale = scale; + mobj->movecount = 1; + } + else if (!K_IsPlayerWanted(mobj->target->player)) + mobj->movecount = 0; } else mobj->tracer->flags2 |= MF2_DONTDRAW; @@ -7003,6 +7020,54 @@ void P_MobjThinker(mobj_t *mobj) return; } break; + case MT_PLAYERWANTED: + if (mobj->target && mobj->target->health && mobj->tracer + && mobj->target->player && !mobj->target->player->spectator + && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD + && players[displayplayer].mo && !players[displayplayer].spectator) + { + fixed_t scale = mobj->target->scale; + + if (!K_IsPlayerWanted(mobj->target->player)) + { + mobj->tracer->movecount = 0; + P_RemoveMobj(mobj); + return; + } + + if (mobj->tracer->flags2 & MF2_DONTDRAW) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + if (!(mobj->target->eflags & MFE_VERTICALFLIP)) + { + mobj->z = mobj->target->z + (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->eflags &= ~MFE_VERTICALFLIP; + } + else + { + mobj->z = mobj->target->z - (P_GetPlayerHeight(mobj->target->player)+16*FRACUNIT+(64*mobj->scale)); + mobj->eflags |= MFE_VERTICALFLIP; + } + P_SetThingPosition(mobj); + + scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, + players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); + if (scale > 16*FRACUNIT) + scale = 16*FRACUNIT; + mobj->destscale = scale; + } + else if (mobj->health > 0) + { + P_KillMobj(mobj, NULL, NULL); + return; + } + break; //} case MT_WATERDROP: P_SceneryCheckWater(mobj); @@ -8121,6 +8186,9 @@ void P_MobjThinker(mobj_t *mobj) } P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + mobj->scalespeed = mobj->target->scalespeed; + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); mobj->color = mobj->target->color; mobj->colorized = (mobj->target->player->kartstuff[k_comebackmode] == 1); @@ -8151,7 +8219,7 @@ void P_MobjThinker(mobj_t *mobj) // Now for the wheels { - const fixed_t rad = mobjinfo[MT_PLAYER].radius; + const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->target->scale); mobj_t *cur = mobj->hnext; while (cur && !P_MobjWasRemoved(cur)) @@ -8165,6 +8233,9 @@ void P_MobjThinker(mobj_t *mobj) offy *= -1; P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z); + cur->scalespeed = mobj->target->scalespeed; + cur->destscale = mobj->target->destscale; + P_SetScale(cur, mobj->target->scale); if (mobj->flags2 & MF2_DONTDRAW) cur->flags2 |= MF2_DONTDRAW; @@ -8937,7 +9008,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_KARMAHITBOX: // SRB2Kart { - const fixed_t rad = mobjinfo[MT_PLAYER].radius; + const fixed_t rad = FixedMul(mobjinfo[MT_PLAYER].radius, mobj->scale); mobj_t *cur, *prev = mobj; INT32 i; @@ -9376,7 +9447,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; -consvar_t cv_itemrespawntime = {"respawnitemtime", "3", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_itemrespawntime = {"respawnitemtime", "2", CV_NETVAR|CV_CHEAT, respawnitemtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}}; consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/p_saveg.c b/src/p_saveg.c index 58d5b991..6be42fc0 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3257,6 +3257,9 @@ static void P_NetArchiveMisc(void) WRITEUINT8(save_p, franticitems); WRITEUINT8(save_p, comeback); + for (i = 0; i < 4; i++) + WRITESINT8(save_p, battlewanted[i]); + WRITEUINT32(save_p, indirectitemcooldown); WRITEUINT32(save_p, spbincoming); WRITEUINT8(save_p, spbplayer); @@ -3357,6 +3360,9 @@ static inline boolean P_NetUnArchiveMisc(void) franticitems = (boolean)READUINT8(save_p); comeback = (boolean)READUINT8(save_p); + for (i = 0; i < 4; i++) + battlewanted[i] = READSINT8(save_p); + indirectitemcooldown = READUINT32(save_p); spbincoming = READUINT32(save_p); spbplayer = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index a67e8a3c..d81e2289 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3006,6 +3006,9 @@ boolean P_SetupLevel(boolean skipprecip) comeback = cv_kartcomeback.value; } + for (i = 0; i < 4; i++) + battlewanted[i] = -1; + indirectitemcooldown = 0; spbincoming = 0; spbplayer = 0; diff --git a/src/p_spec.c b/src/p_spec.c index ecf31480..31ae1263 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3983,7 +3983,7 @@ DoneSection2: case 7: // SRB2kart 190117 - Oil Slick if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { - K_SpinPlayer(player, NULL, 0); + K_SpinPlayer(player, NULL, 0, false); } break; diff --git a/src/p_tick.c b/src/p_tick.c index 4ac56b90..d79d2f59 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -677,6 +677,9 @@ void P_Ticker(boolean run) if (countdown2) countdown2--; + if (G_BattleGametype() && leveltime % wantedfrequency == 0 && leveltime > wantedfrequency) + K_CalculateBattleWanted(); + if (spbincoming && --spbincoming <= 0) { UINT8 best = 0; diff --git a/src/p_user.c b/src/p_user.c index 09e407c3..3585a5ae 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1039,11 +1039,10 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) // Adds to the player's score void P_AddPlayerScore(player_t *player, UINT32 amount) { - UINT32 oldscore; + //UINT32 oldscore; -#if 1 - return; // Nope, still don't need this for Battle even -#endif + if (!(G_BattleGametype())) + return; if (player->bot) player = &players[consoleplayer]; @@ -1051,60 +1050,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) if (player->exiting) // srb2kart return; - // NiGHTS does it different! - if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS) - { - if ((netgame || multiplayer) && G_IsSpecialStage(gamemap)) - { // Pseudo-shared score for multiplayer special stages. - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].pflags & PF_NIGHTSMODE) - { - oldscore = players[i].marescore; - - // Don't go above MAXSCORE. - if (players[i].marescore + amount < MAXSCORE) - players[i].marescore += amount; - else - players[i].marescore = MAXSCORE; - - // Continues are worthless in netgames. - // If that stops being the case uncomment this. -/* if (!ultimatemode && players[i].marescore > 50000 - && oldscore < 50000) - { - players[i].continues += 1; - players[i].gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); - } */ - } - } - else - { - oldscore = player->marescore; - - // Don't go above MAXSCORE. - if (player->marescore + amount < MAXSCORE) - player->marescore += amount; - else - player->marescore = MAXSCORE; - - if (!ultimatemode && !(netgame || multiplayer) && G_IsSpecialStage(gamemap) - && player->marescore >= 50000 && oldscore < 50000) - { - player->continues += 1; - player->gotcontinue = true; - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_flgcap); - } - } - - if (gametype == GT_COOP) - return; - } - - oldscore = player->score; + //oldscore = player->score; // Don't go above MAXSCORE. if (player->score + amount < MAXSCORE) @@ -1113,11 +1059,11 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) player->score = MAXSCORE; // check for extra lives every 50000 pts - if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) + /*if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) { P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000)); P_PlayLivesJingle(player); - } + }*/ // In team match, all awarded points are incremented to the team's running score. if (gametype == GT_TEAMMATCH) @@ -7691,7 +7637,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) continue; if (mo->type == MT_PLAYER) // Players wipe out in Kart - K_SpinPlayer(mo->player, source, 0); + K_SpinPlayer(mo->player, source, 0, false); //} else P_DamageMobj(mo, inflictor, source, 1000); diff --git a/src/sounds.c b/src/sounds.c index 6d793f1e..f9823bcb 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -601,7 +601,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // 3D Blast sounds (the "missing" ones are direct copies of S3K's, no minor differences what-so-ever) - {"3db06", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Bumper stolen + {"3db06", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Bumper stolen {"3db09", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"3db14", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"3db16", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, diff --git a/src/y_inter.c b/src/y_inter.c index b6c9bc11..e8e4d1c1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2430,7 +2430,7 @@ void Y_VoteTicker(void) if (tempvotes[((pickedvote + voteclient.roffset + i) % numvotes)] == pickedvote) { voteclient.rendoff = voteclient.roffset+i; - if (P_RandomChance(FRACUNIT/1024)) // Let it cheat occasionally~ + if (M_RandomChance(FRACUNIT/1024)) // Let it cheat occasionally~ voteclient.rendoff++; S_ChangeMusicInternal("voteeb", false); break; @@ -2586,7 +2586,7 @@ void Y_StartVote(void) for (i = 0; i < 4; i++) { lumpnum_t lumpnum; - INT16 j; + //INT16 j; // set up the str if (strlen(mapheaderinfo[votelevels[i][0]]->zonttl) > 0)