diff --git a/src/dehacked.c b/src/dehacked.c index dd1f301e..f2caf154 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3082,7 +3082,7 @@ static void readmaincfg(MYFILE *f) if (!GoodDataFileName(word2)) I_Error("Maincfg: bad data file name '%s'\n", word2); - G_SaveGameData(); + G_SaveGameData(false); DEH_WriteUndoline(word, gamedatafilename, UNDO_NONE); strlcpy(gamedatafilename, word2, sizeof (gamedatafilename)); strlwr(gamedatafilename); @@ -6608,6 +6608,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAYERARROW_X", "S_PLAYERBOMB", // Player bomb overlay + "S_PLAYERITEM", // Player item overlay "S_PLAYERBOMB_WHEEL", #ifdef SEENAMES diff --git a/src/f_finale.c b/src/f_finale.c index 710ff78f..e6cd6d0e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -41,6 +41,7 @@ static INT32 timetonext; // Delay between screen changes static INT32 continuetime; // Short delay when continuing static tic_t animtimer; // Used for some animation timings +static tic_t credbgtimer; // Credits background static INT32 roidtics; // Asteroid spinning static tic_t stoptimer; @@ -451,128 +452,77 @@ boolean F_IntroResponder(event_t *event) // CREDITS // ========= static const char *credits[] = { - "\1Sonic Robo Blast II", + "\1SRB2 Kart", "\1Credits", "", "\1Game Design", - "Ben \"Mystic\" Geyer", - "\"SSNTails\"", - "Johnny \"Sonikku\" Wallbank", + "\"Chaos Zero 64\"", + "\"Iceman404\" aka \"VelocitOni\"", + "\"ZarroTsu\"", "", "\1Programming", - "Alam \"GBC\" Arias", - "Logan \"GBA\" Arias", - "Tim \"RedEnchilada\" Bordelon", - "Callum Dickinson", - "Scott \"Graue\" Feeney", - "Nathan \"Jazz\" Giroux", - "Thomas \"Shadow Hog\" Igoe", - "Iestyn \"Monster Iestyn\" Jealous", - "Ronald \"Furyhunter\" Kinard", // The SDL2 port - "John \"JTE\" Muniz", - "Ehab \"Wolfy\" Saeed", - "\"SSNTails\"", - "Matthew \"Inuyasha\" Walsh", - "", - "\1Programming", - "\1Assistance", - "\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom) - "Andrew \"orospakr\" Clunis", - "Gregor \"Oogaland\" Dick", - "Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol) + "\"Chaos Zero 64\"", + "Sally \"TehRealSalt\" Cochenour", "Vivian \"toaster\" Grannell", - "Julio \"Chaos Zero 64\" Guir", - "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog - "Matthew \"Shuffle\" Marsalko", - "Steven \"StroggOnMeth\" McGranahan", - "\"Morph\"", // For SRB2Morphed stuff - "Colin \"Sonict\" Pfaff", - "Sean \"Sryder13\" Ryder", - "Ben \"Cue\" Woodford", + "\"Lat\'\"", + "\"Monster Iestyn\"", + "Sean \"Sryder\" Ryder", + "Ehab \"wolfs\" Saeed", + "\"ZarroTsu\"", "", - "\1Sprite Artists", - "Odi \"Iceman404\" Atunzu", - "Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D: - "Jim \"MotorRoach\" DeMello", + "\1Artists", + "\"Chaos Zero 64\"", + "Sally \"TehRealSalt\" Cochenour", "Desmond \"Blade\" DesJardins", - "Sherman \"CoatRack\" DesJardins", - "Andrew \"Senku Niola\" Moran", - "David \"Instant Sonic\" Spencer Jr.", - "\"SSNTails\"", - "", - "\1Texture Artists", - "Ryan \"Blaze Hedgehog\" Bloom", - "Buddy \"KinkaJoy\" Fischer", - "Vivian \"toaster\" Grannell", - "Kepa \"Nev3r\" Iceta", - "Jarrett \"JEV3\" Voight", + "Sherman \"CoatRack\" DesJardin", + "Wesley \"Charyb\" Gillebaard", + "James \"SeventhSentinel\" Hall", + "\"Iceman404\"", + "\"MotorRoach\"", + "\"VAdaPEGA\"", + "\"ZarroTsu\"", "", "\1Music and Sound", - "\1Production", - "Malcolm \"RedXVI\" Brown", - "David \"Bulmybag\" Bulmer", - "Paul \"Boinciel\" Clempson", - "Cyan Helkaraxe", - "Kepa \"Nev3r\" Iceta", - "Iestyn \"Monster Iestyn\" Jealous", - "Jarel \"Arrow\" Jones", - "Stefan \"Stuf\" Rimalia", - "Shane Mychal Sexton", - "\"Spazzo\"", - "David \"Big Wave Dave\" Spencer Sr.", - "David \"Instant Sonic\" Spencer Jr.", - "\"SSNTails\"", + "Karl Brueggemann", + "Wesley \"Charyb\" Gillebaard", + "James \"SeventhSentinel\" Hall", + "\"MaxieDaMan\"", "", "\1Level Design", - "Matthew \"Fawfulfan\" Chapman", + "\"Blitz-T\"", + "\"D00D64-X\"", + "\"Chaos Zero 64\"", "Paul \"Boinciel\" Clempson", + "Sally \"TehRealSalt\" Cochenour", "Desmond \"Blade\" DesJardins", - "Sherman \"CoatRack\" DesJardins", - "Ben \"Mystic\" Geyer", - "Nathan \"Jazz\" Giroux", - "Dan \"Blitzzo\" Hagerstrand", - "Kepa \"Nev3r\" Iceta", - "Thomas \"Shadow Hog\" Igoe", - "Erik \"Torgo\" Nielsen", - "Wessel \"Spherallic\" Smit", - "\"Spazzo\"", - "\"SSNTails\"", - "Rob Tisdell", - "Jarrett \"JEV3\" Voight", - "Johnny \"Sonikku\" Wallbank", - "Matthew \"Inuyasha\" Walsh", - "Marco \"Digiku\" Zafra", - "", - "\1Boss Design", - "Ben \"Mystic\" Geyer", - "Thomas \"Shadow Hog\" Igoe", - "John \"JTE\" Muniz", - "Samuel \"Prime 2.0\" Peters", - "\"SSNTails\"", - "Johnny \"Sonikku\" Wallbank", + "Sherman \"CoatRack\" DesJardin", + "James \"SeventhSentinel\" Hall", + "Sean \"Sryder\" Ryder", + "\"Ryuspark\"", + "Jeffery \"Chromatian\" Scott", + "\"Simsmagic\"", + "\"Tyrannosaur Chao\" aka \"Chaotic Chao\"", + "\"ZarroTsu\"", "", "\1Testing", - "Hank \"FuriousFox\" Brannock", - "Cody \"SRB2 Playah\" Koester", - "Skye \"OmegaVelocity\" Meredith", - "Stephen \"HEDGESMFG\" Moellering", - "Nick \"ST218\" Molina", - "Samuel \"Prime 2.0\" Peters", - "Colin \"Sonict\" Pfaff", - "Bill \"Tets\" Reed", + "\"CyberIF\"", + "\"Dani\"", + "Karol \"Fooruman\" D""\x1E""browski", // Dąbrowski, accents in srb2 :ytho: + "Jesse \"Jeck Jims\" Emerick", + "\"VirtAnderson\"", "", "\1Special Thanks", - "Doom Legacy Project", - "iD Software", - "Alex \"MistaED\" Fuller", - "FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak - "Randi Heit ()", // For their MSPaint sprite that we nicked + "Sonic Team Jr. & SRB2", + "Bandit \"Bobby\" Cochenour", // i <3 my dog + "\"Nev3r\"", + "\"Ritz\"", + "\"Spherallic\"", "", "\1Produced By", - "Sonic Team Junior", + "Kart Krew", "", - "\1Published By", - "A 28K dialup modem", + "\1In Memory of", + "\"Tyler52\"", "", "\1Thank you", "\1for playing!", @@ -583,7 +533,7 @@ static struct { UINT32 x, y; const char *patch; } credits_pics[] = { - { 8, 80+200* 1, "CREDIT01"}, + /*{ 8, 80+200* 1, "CREDIT01"}, { 4, 80+200* 2, "CREDIT13"}, {250, 80+200* 3, "CREDIT12"}, { 8, 80+200* 4, "CREDIT03"}, @@ -591,10 +541,8 @@ static struct { { 8, 80+200* 6, "CREDIT04"}, {112, 80+200* 7, "CREDIT10"}, {240, 80+200* 8, "CREDIT05"}, - {120, 80+200* 9, "CREDIT06"}, - { 8, 80+200*10, "CREDIT07"}, - { 8, 80+200*11, "CREDIT08"}, - {112, 80+200*12, "CREDIT09"}, + {120, 80+200* 9, "CREDIT06"},*/ + {112, 80+200*10, "TYLER52"}, {0, 0, NULL} }; @@ -636,7 +584,13 @@ void F_CreditDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - // Draw background pictures first + // Draw background + V_DrawSciencePatch(0, 0 - FixedMul(32<>1); @@ -677,6 +631,8 @@ void F_CreditTicker(void) else animtimer++; + credbgtimer++; + if (finalecount && --finalecount == 0) F_StartGameEvaluation(); } @@ -718,8 +674,8 @@ boolean F_CreditResponder(event_t *event) break; } - if (!(timesBeaten) && !(netgame || multiplayer)) - return false; + /*if (!(timesBeaten) && !(netgame || multiplayer)) + return false;*/ if (event->type != ev_keydown) return false; @@ -819,10 +775,10 @@ void F_GameEvaluationDrawer(void) /*if (ultimatemode) ++timesBeatenUltimate;*/ - if (M_UpdateUnlockablesAndExtraEmblems()) + if (M_UpdateUnlockablesAndExtraEmblems(false)) S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(); + G_SaveGameData(false); } } diff --git a/src/g_game.c b/src/g_game.c index c1e1cd41..0263b2a7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2259,10 +2259,10 @@ static inline void G_PlayerFinishLevel(INT32 player) if (legitimateexit && !demoplayback) // (yes you're allowed to unlock stuff this way when the game is modified) { matchesplayed++; - if (M_UpdateUnlockablesAndExtraEmblems()) + if (M_UpdateUnlockablesAndExtraEmblems(true)) { S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(); // only save if unlocked something + G_SaveGameData(true); // only save if unlocked something } } @@ -3385,12 +3385,8 @@ static void G_DoWorldDone(void) { if (server) { - if (G_RaceGametype()) - // SRB2kart: don't reset player between maps - D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); - else - // resetplayer in match/tag/CTF for more equality - D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false); + // SRB2kart: don't reset player between maps + D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); } gameaction = ga_nothing; @@ -3647,7 +3643,7 @@ void G_LoadGameData(void) // G_SaveGameData // Saves the main data file, which stores information such as emblems found, etc. -void G_SaveGameData(void) +void G_SaveGameData(boolean force) { size_t length; INT32 i, j; @@ -3665,7 +3661,8 @@ void G_SaveGameData(void) return; } - if (modifiedgame && !savemoddata) + if (modifiedgame && !savemoddata + && !force) // SRB2Kart: for enabling unlocks online in modified servers { free(savebuffer); save_p = savebuffer = NULL; @@ -3967,6 +3964,7 @@ void G_SaveGame(UINT32 savegameslot) // void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, UINT8 ssplayers, boolean FLS) { + INT32 i; UINT8 color = 0; paused = false; @@ -3974,6 +3972,9 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, U COM_BufAddText("stopdemo\n"); ghosts = NULL; + for (i = 0; i < NUMMAPS; i++) + randmapbuffer[i] = -1; + // this leave the actual game if needed SV_StartSinglePlayerServer(); diff --git a/src/g_game.h b/src/g_game.h index 78f08e36..f59641fb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -127,7 +127,7 @@ void G_DeferedPlayDemo(const char *demo); // Can be called by the startup code or M_Responder, calls P_SetupLevel. void G_LoadGame(UINT32 slot, INT16 mapoverride); -void G_SaveGameData(void); +void G_SaveGameData(boolean force); void G_SaveGame(UINT32 slot); diff --git a/src/hu_stuff.h b/src/hu_stuff.h index 21bc40a8..451cc8d8 100644 --- a/src/hu_stuff.h +++ b/src/hu_stuff.h @@ -21,7 +21,7 @@ //------------------------------------ // heads up font //------------------------------------ -#define HU_FONTSTART '\x1F' // the first font character +#define HU_FONTSTART '\x1E' // the first font character #define HU_FONTEND '~' #define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1) diff --git a/src/info.c b/src/info.c index 67b9fddb..b5533cfe 100644 --- a/src/info.c +++ b/src/info.c @@ -2915,7 +2915,8 @@ state_t states[NUMSTATES] = {SPR_ITMN, FF_FULLBRIGHT|10, -1, {NULL}, 16, 3, S_NULL}, // S_PLAYERARROW_X {SPR_PBOM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_PLAYERBOMB - {SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERBOMB_WHEEL + {SPR_RNDM, FF_ANIMATE, -1, {NULL}, 23, 3, S_NULL}, // S_PLAYERITEM + {SPR_PBOM, 4, -1, {NULL}, 0, 0, S_NULL}, // S_PLAYERWHEEL #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK diff --git a/src/info.h b/src/info.h index e6389fb1..97a40755 100644 --- a/src/info.h +++ b/src/info.h @@ -3440,7 +3440,8 @@ typedef enum state S_PLAYERARROW_X, S_PLAYERBOMB, - S_PLAYERBOMB_WHEEL, + S_PLAYERITEM, + S_PLAYERWHEEL, #ifdef SEENAMES S_NAMECHECK, diff --git a/src/k_kart.c b/src/k_kart.c index 944331b5..af9e58c5 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1012,7 +1012,7 @@ void K_LakituChecker(player_t *player) player->kartstuff[k_lakitu]--; // Quick! You only have three tics to boost! if (cmd->buttons & BT_ACCELERATE) - K_DoSneaker(player, true, false); + K_DoSneaker(player, true); } } } @@ -1458,8 +1458,8 @@ void K_SpinPlayer(player_t *player, mobj_t *source) if (G_BattleGametype()) { - if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); + /*if (source && source->player && player != source->player) + P_AddPlayerScore(source->player, 1);*/ if (player->kartstuff[k_balloon] > 0) { @@ -1516,8 +1516,8 @@ void K_SquishPlayer(player_t *player, mobj_t *source) if (G_BattleGametype()) { - if (source && source->player && player != source->player) - P_AddPlayerScore(source->player, 1); + /*if (source && source->player && player != source->player) + P_AddPlayerScore(source->player, 1);*/ if (player->kartstuff[k_balloon] > 0) { @@ -1573,7 +1573,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we ju if (source->player->kartstuff[k_comebackpoints] >= 3) K_StealBalloon(source->player, player, true); } - P_AddPlayerScore(source->player, 1); + //P_AddPlayerScore(source->player, 1); } if (player->kartstuff[k_balloon] > 0) @@ -2230,14 +2230,10 @@ static void K_DoHyudoroSteal(player_t *player) } } -void K_DoSneaker(player_t *player, boolean doPFlag, boolean startboost) +void K_DoSneaker(player_t *player, boolean doPFlag) { - sfxenum_t boostsound = sfx_mush; - if (startboost) - boostsound = sfx_sboost; - if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) - S_StartSound(player->mo, boostsound); + S_StartSound(player->mo, sfx_mush); player->kartstuff[k_sneakertimer] = sneakertime; @@ -2723,7 +2719,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->kartstuff[k_rocketsneakertimer] > 1) { - K_DoSneaker(player, true, false); + K_DoSneaker(player, true); player->kartstuff[k_rocketsneakertimer] -= 5; if (player->kartstuff[k_rocketsneakertimer] < 1) player->kartstuff[k_rocketsneakertimer] = 1; @@ -2735,7 +2731,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) case KITEM_SNEAKER: if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO) { - K_DoSneaker(player, true, false); + K_DoSneaker(player, true); player->kartstuff[k_itemamount]--; } break; @@ -2743,7 +2739,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO && player->kartstuff[k_rocketsneakertimer] == 0) { - K_DoSneaker(player, true, false); + K_DoSneaker(player, true); player->kartstuff[k_rocketsneakertimer] = itemtime; player->kartstuff[k_itemamount]--; } @@ -3131,14 +3127,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_hyudorotimer] > 0) { - if ((player == &players[displayplayer] - || (splitscreen && player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && player == &players[thirddisplayplayer]) - || (splitscreen > 2 && player == &players[fourthdisplayplayer])) - || (!(player == &players[displayplayer] - || (splitscreen && player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && player == &players[thirddisplayplayer]) - || (splitscreen > 2 && player == &players[fourthdisplayplayer])) + if ((player == &players[displayplayer] && !splitscreen) + || (!(player == &players[displayplayer] && !splitscreen) && (player->kartstuff[k_hyudorotimer] < 1*TICRATE/2 || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)))) { if (leveltime & 1) @@ -3172,6 +3162,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_comebacktimer] > 0) { + if (player->mo->tracer->state != &states[S_PLAYERBOMB]) + P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); + if (player->kartstuff[k_comebacktimer] < TICRATE && (leveltime & 1)) player->mo->tracer->flags2 &= ~MF2_DONTDRAW; else @@ -3179,15 +3172,23 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->powers[pw_flashing] = player->kartstuff[k_comebacktimer]; } - else if (player->kartstuff[k_comebackmode] != 0) - player->mo->tracer->flags2 |= MF2_DONTDRAW; else + { + if (player->kartstuff[k_comebackmode] == 0 + && player->mo->tracer->state != &states[S_PLAYERBOMB]) + P_SetMobjState(player->mo->tracer, S_PLAYERBOMB); + else if (player->kartstuff[k_comebackmode] == 1 + && player->mo->tracer->state != &states[S_PLAYERITEM]) + P_SetMobjState(player->mo->tracer, S_PLAYERITEM); player->mo->tracer->flags2 &= ~MF2_DONTDRAW; + } } else if (G_RaceGametype() || player->kartstuff[k_balloon] > 0) { player->mo->flags2 &= ~MF2_SHADOW; - if (player->mo->tracer && player->mo->tracer->state == &states[S_PLAYERBOMB]) + if (player->mo->tracer + && (player->mo->tracer->state == &states[S_PLAYERBOMB] + || player->mo->tracer->state == &states[S_PLAYERITEM])) P_RemoveMobj(player->mo->tracer); } } @@ -3265,24 +3266,33 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (leveltime == (TICRATE)*4) S_StartSound(NULL, sfx_lkt2); // Start charging once you're given the opportunity. - if (leveltime >= 70 && leveltime <= 140 && cmd->buttons & BT_ACCELERATE && leveltime % 5 == 0) + if (leveltime >= 70 && leveltime <= 140 && cmd->buttons & BT_ACCELERATE) player->kartstuff[k_boostcharge]++; if (leveltime >= 70 && leveltime <= 140 && !(cmd->buttons & BT_ACCELERATE)) player->kartstuff[k_boostcharge] = 0; // Increase your size while charging your engine. if (leveltime < 150) - player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*655); + player->mo->destscale = (mapheaderinfo[gamemap-1]->mobj_scale) + (player->kartstuff[k_boostcharge]*131); // Determine the outcome of your charge. if (leveltime > 140 && player->kartstuff[k_boostcharge]) { // Get an instant boost! - if (player->kartstuff[k_boostcharge] >= 7 && player->kartstuff[k_boostcharge] <= 10) + if (player->kartstuff[k_boostcharge] >= 35 && player->kartstuff[k_boostcharge] <= 50) { - K_DoSneaker(player, false, true); + if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) + S_StartSound(player->mo, sfx_sboost); + + player->kartstuff[k_sneakertimer] = -((21*(player->kartstuff[k_boostcharge]*player->kartstuff[k_boostcharge]))/425)+131; // max time is 70, min time is 7; yay parabooolas + + if (!player->kartstuff[k_sounds]) // Prevents taunt sounds from playing every time the button is pressed + { + K_PlayTauntSound(player->mo); + player->kartstuff[k_sounds] = 50; + } } // You overcharged your engine? Those things are expensive!!! - if (player->kartstuff[k_boostcharge] > 10) + else if (player->kartstuff[k_boostcharge] > 50) { player->powers[pw_nocontrol] = 40; S_StartSound(player->mo, sfx_slip); @@ -3333,8 +3343,8 @@ void K_CheckBalloons(void) if (playeringame[winnernum]) { - P_AddPlayerScore(&players[winnernum], numingame); - CONS_Printf(M_GetText("%s recieved %d points for winning!\n"), player_names[winnernum], numingame*2); + P_AddPlayerScore(&players[winnernum], 1); + CONS_Printf(M_GetText("%s recieved a point for winning!\n")); } for (i = 0; i < MAXPLAYERS; i++) @@ -4392,7 +4402,7 @@ static void K_drawKartMinimap(void) x = MINI_X - (AutomapPic->width/2); y = MINI_Y - (AutomapPic->height/2); - if (splitscreen == 2) + if (splitscreen) splitflags = 0; if (mirrormode) @@ -4400,7 +4410,7 @@ static void K_drawKartMinimap(void) else V_DrawScaledPatch(x, y, splitflags, AutomapPic); - if (splitscreen != 2) + if (!splitscreen) { splitflags &= ~minimaptrans; splitflags |= V_HUDTRANSHALF; @@ -4409,13 +4419,28 @@ static void K_drawKartMinimap(void) // Player's tiny icons on the Automap. for (i = 0; i < MAXPLAYERS; i++) { - if (i == displayplayer && splitscreen != 2) + if (i == displayplayer && !splitscreen) continue; // Do displayplayer later if (players[i].mo && !players[i].spectator) + { + if (G_BattleGametype() && players[i].kartstuff[k_balloon] <= 0) + continue; + + if (players[i].kartstuff[k_hyudorotimer] > 0) + { + if ((players[i].kartstuff[k_hyudorotimer] < 1*TICRATE/2 + || players[i].kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2)) + && !(leveltime & 1)) + ; + else + continue; + } + K_drawKartMinimapHead(&players[i], x, y, splitflags, AutomapPic); + } } - if (splitscreen == 2) + if (splitscreen) return; // Don't need this for splits splitflags &= ~V_HUDTRANSHALF; @@ -4428,13 +4453,18 @@ static void K_drawBattleFullscreen(void) { INT32 x = BASEVIDWIDTH/2; INT32 y = -64+(stplyr->kartstuff[k_cardanimation]); // card animation goes from 0 to 164, 164 is the middle of the screen + INT32 splitflags = V_SNAPTOTOP; // I don't feel like properly supporting non-green resolutions, so you can have a misuse of SNAPTO instead fixed_t scale = FRACUNIT; if (splitscreen) { if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer]) - || (splitscreen > 1 && (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]))) + || (splitscreen > 1 && (stplyr == &players[thirddisplayplayer] + || (stplyr == &players[fourthdisplayplayer] && splitscreen > 2)))) + { y = 232-(stplyr->kartstuff[k_cardanimation]/2); + splitflags = V_SNAPTOBOTTOM; + } else y = -32+(stplyr->kartstuff[k_cardanimation]/2); @@ -4442,7 +4472,8 @@ static void K_drawBattleFullscreen(void) { scale /= 2; - if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + if (stplyr == &players[secondarydisplayplayer] + || (stplyr == &players[fourthdisplayplayer] && splitscreen > 2)) x = 3*BASEVIDWIDTH/4; else x = BASEVIDWIDTH/4; @@ -4461,9 +4492,9 @@ static void K_drawBattleFullscreen(void) if (stplyr == &players[displayplayer]) V_DrawFadeScreen(); if (stplyr->kartstuff[k_balloon]) - V_DrawFixedPatch(x<kartstuff[k_balloon] <= 0 && stplyr->kartstuff[k_comebacktimer] && comeback) { @@ -4487,22 +4518,23 @@ static void K_drawBattleFullscreen(void) if (splitscreen > 2) ty = (BASEVIDHEIGHT/4)+33; if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer]) - || stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + || (stplyr == &players[thirddisplayplayer] && splitscreen > 1) + || (stplyr == &players[fourthdisplayplayer] && splitscreen > 2)) ty += (BASEVIDHEIGHT/2); } else V_DrawFadeScreen(); if (!comebackshowninfo) - V_DrawFixedPatch(x< 1) V_DrawString(x-(txoff/2), ty, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); else { - V_DrawFixedPatch(x<kartstuff[k_comebacktimer]/TICRATE)); } } @@ -4625,6 +4657,9 @@ void K_drawKartHUD(void) // This is handled by console/menu values K_initKartHUD(); + if (splitscreen == 2) // Player 4 in 3P is basically the minimap :p + K_drawKartMinimap(); + // Draw full screen stuff that turns off the rest of the HUD if ((G_BattleGametype()) && (stplyr->exiting @@ -4653,8 +4688,8 @@ void K_drawKartHUD(void) K_drawKartPlayerCheck(); } - if ((splitscreen == 0 && cv_kartminimap.value) || splitscreen == 2) - K_drawKartMinimap(); + if (splitscreen == 0 && cv_kartminimap.value) + K_drawKartMinimap(); // 3P splitscreen is handled above // Draw the item window K_drawKartItem(); diff --git a/src/k_kart.h b/src/k_kart.h index bce8f9db..bf6738e0 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -31,7 +31,7 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_SpawnDriftTrail(player_t *player); void K_SpawnSparkleTrail(player_t *player); -void K_DoSneaker(player_t *player, boolean doPFlag, boolean startboost); +void K_DoSneaker(player_t *player, boolean doPFlag); void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 36241f7e..0b917ade 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2104,11 +2104,10 @@ static int lib_kDoSneaker(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); boolean doPFlag = luaL_checkboolean(L, 2); - boolean startboost = luaL_checkboolean(L, 3); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); - K_DoSneaker(player, doPFlag, startboost); + K_DoSneaker(player, doPFlag); return 0; } diff --git a/src/m_cond.c b/src/m_cond.c index 72932365..f2b163ea 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -197,7 +197,7 @@ void M_ClearSecrets(void) // ---------------------- // Condition set checking // ---------------------- -static UINT8 M_CheckCondition(condition_t *cn) +UINT8 M_CheckCondition(condition_t *cn) { switch (cn->type) { @@ -295,13 +295,14 @@ void M_CheckUnlockConditions(void) } } -UINT8 M_UpdateUnlockablesAndExtraEmblems(void) +UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force) { INT32 i; char cechoText[992] = ""; UINT8 cechoLines = 0; - if (modifiedgame && !savemoddata) + if (modifiedgame && !savemoddata + && !force) // SRB2Kart: for enabling unlocks online in modified servers return false; M_CheckUnlockConditions(); diff --git a/src/m_cond.h b/src/m_cond.h index d34b2cbf..052c31f2 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -151,7 +151,8 @@ void M_ClearSecrets(void); // Updating conditions and unlockables void M_CheckUnlockConditions(void); -UINT8 M_UpdateUnlockablesAndExtraEmblems(void); +UINT8 M_CheckCondition(condition_t *cn); +UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force); void M_SilentUpdateUnlockablesAndEmblems(void); UINT8 M_CheckLevelEmblems(void); diff --git a/src/m_menu.c b/src/m_menu.c index f2ed0002..007ea1d9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -217,6 +217,7 @@ static void M_LevelSelectWarp(INT32 choice); static void M_Credits(INT32 choice); static void M_PandorasBox(INT32 choice); static void M_EmblemHints(INT32 choice); +static char *M_GetConditionString(condition_t cond); menu_t SR_MainDef, SR_UnlockChecklistDef; // Misc. Main Menu @@ -4263,10 +4264,56 @@ static void M_LevelSelectWarp(INT32 choice) UINT8 skyRoomMenuTranslations[MAXUNLOCKABLES]; -#define NUMCHECKLIST 8 +static char *M_GetConditionString(condition_t cond) +{ + switch(cond.type) + { + case UC_PLAYTIME: + return va("Play for %i:%02i:%02i", + G_TicsToHours(cond.requirement), + G_TicsToMinutes(cond.requirement, false), + G_TicsToSeconds(cond.requirement)); + case UC_MATCHESPLAYED: + return va("Play %d matches", cond.requirement); + case UC_GAMECLEAR: + if (cond.requirement > 1) + return va("Beat game %d times", cond.requirement); + else + return va("Beat the game"); + case UC_ALLEMERALDS: + if (cond.requirement > 1) + return va("Beat game w/ all emeralds %d times", cond.requirement); + else + return va("Beat game w/ all emeralds"); + case UC_OVERALLTIME: + return va("Get overall time of %i:%02i:%02i", + G_TicsToHours(cond.requirement), + G_TicsToMinutes(cond.requirement, false), + G_TicsToSeconds(cond.requirement)); + case UC_MAPVISITED: + return va("Visit %s", G_BuildMapTitle(cond.requirement-1)); + case UC_MAPBEATEN: + return va("Beat %s", G_BuildMapTitle(cond.requirement-1)); + case UC_MAPALLEMERALDS: + return va("Beat %s w/ all emeralds", G_BuildMapTitle(cond.requirement-1)); + case UC_MAPTIME: + return va("Beat %s in %i:%02i.%02i", G_BuildMapTitle(cond.extrainfo1-1), + G_TicsToMinutes(cond.requirement, true), + G_TicsToSeconds(cond.requirement), + G_TicsToCentiseconds(cond.requirement)); + case UC_TOTALEMBLEMS: + return va("Get %d emblems", cond.requirement); + case UC_EXTRAEMBLEM: + return va("Get \"%s\" emblem", extraemblems[cond.requirement-1].name); + default: + return ""; + } +} + +#define NUMCHECKLIST 23 static void M_DrawChecklist(void) { - INT32 i, j = 0; + INT32 i, line = 0, c, lastid; for (i = 0; i < MAXUNLOCKABLES; i++) { @@ -4274,18 +4321,47 @@ static void M_DrawChecklist(void) || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS) continue; - V_DrawString(8, 8+(24*j), V_RETURN8, unlockables[i].name); - V_DrawString(160, 8+(24*j), V_RETURN8, V_WordWrap(160, 292, 0, unlockables[i].objective)); + ++line; + V_DrawString(8, (line*8), V_RETURN8|(unlockables[i].unlocked ? V_GREENMAP : V_REDMAP), unlockables[i].name); - if (unlockables[i].unlocked) - V_DrawString(308, 8+(24*j), V_YELLOWMAP, "Y"); - else - V_DrawString(308, 8+(24*j), V_YELLOWMAP, "N"); + if (conditionSets[unlockables[i].conditionset - 1].numconditions) + { + c = 0; + lastid = -1; - if (++j >= NUMCHECKLIST) + for (c = 0; c < conditionSets[unlockables[i].conditionset - 1].numconditions; c++) + { + condition_t cond = conditionSets[unlockables[i].conditionset - 1].condition[c]; + UINT8 achieved = M_CheckCondition(&cond); + char *str = M_GetConditionString(cond); + + if (!str) + continue; + + ++line; + + if (cond.id != lastid) + { + V_DrawString(16, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "*"); + V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str); + } + else + { + V_DrawString(32, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), "&"); + V_DrawString(48, (line*8), V_MONOSPACE|V_ALLOWLOWERCASE|(achieved ? V_YELLOWMAP : 0), str); + } + + lastid = cond.id; + } + } + + ++line; + + if (line >= NUMCHECKLIST) break; } } +#undef NUMCHECKLIST #define NUMHINTS 5 static void M_EmblemHints(INT32 choice) diff --git a/src/p_enemy.c b/src/p_enemy.c index 681c4246..d1716fbd 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3634,8 +3634,6 @@ void A_AttractChase(mobj_t *actor) || !P_CheckSight(actor, actor->tracer)) // You have to be able to SEE it...sorta { // Lost attracted rings don't through walls anymore. - if (actor->tracer && actor->tracer->player) - actor->tracer->player->kartstuff[k_comebackmode] = 0; actor->flags &= ~MF_NOCLIP; P_SetTarget(&actor->tracer, NULL); return; @@ -8147,7 +8145,8 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - actor->target->player->kartstuff[k_itemroulette] = 1; + if (!(G_BattleGametype() && actor->target->player->kartstuff[k_balloon] <= 0)) + actor->target->player->kartstuff[k_itemroulette] = 1; remains->flags2 &= ~MF2_AMBUSH; diff --git a/src/p_floor.c b/src/p_floor.c index f67d59ae..f92937ce 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1787,8 +1787,8 @@ static mobj_t *SearchMarioNode(msecnode_t *node) break; } // Ignore popped monitors, too. - if (node->m_thing->flags & MF_MONITOR || node->m_thing->type == MT_RANDOMITEM - && node->m_thing->threshold == 68) + if ((node->m_thing->flags & MF_MONITOR || node->m_thing->type == MT_RANDOMITEM) + && node->m_thing->threshold == 68) continue; // Okay, we found something valid. if (!thing // take either the first thing diff --git a/src/p_inter.c b/src/p_inter.c index 7d480cd0..60f6596e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -152,23 +152,20 @@ void P_ResetStarposts(void) // boolean P_CanPickupItem(player_t *player, boolean weapon) { - if (player->bot && weapon) - return false; + /*if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // No balloons in Match + return false;*/ - //if (player->powers[pw_flashing] > (flashingtics/4)*3 && player->powers[pw_flashing] <= flashingtics) - // return false; + if (weapon) + { + if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] + || player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off + return false; - if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // No balloons in Match - return false; - - if (player->kartstuff[k_stealingtimer] || player->kartstuff[k_stolentimer] - || player->kartstuff[k_growshrinktimer] > 1 || player->kartstuff[k_rocketsneakertimer]) // Item-specific timer going off - return false; - - if (player->kartstuff[k_itemroulette] - || player->kartstuff[k_itemamount] - || player->kartstuff[k_itemheld]) // Item slot already taken up - return false; + if (player->kartstuff[k_itemroulette] + || player->kartstuff[k_itemamount] + || player->kartstuff[k_itemheld]) // Item slot already taken up + return false; + } return true; } @@ -407,34 +404,15 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) switch (special->type) { case MT_RANDOMITEM: // SRB2kart + if (!P_CanPickupItem(player, true)) + return; + if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) { - if (player->kartstuff[k_comebackmode] == 0 && !player->kartstuff[k_comebacktimer]) - { - if (special->tracer) - return; - P_SetTarget(&special->tracer, toucher); + if (player->kartstuff[k_comebackmode] == 1 || player->kartstuff[k_comebacktimer]) + return; + if (player->kartstuff[k_comebackmode] == 0) player->kartstuff[k_comebackmode] = 1; - } - return; - } - - if (!P_CanPickupItem(player, false) && special->tracer != toucher) - return; - - if (G_BattleGametype() && special->tracer && special->tracer->player) - { - special->tracer->player->kartstuff[k_comebackmode] = 0; - - special->tracer->player->kartstuff[k_comebackpoints]++; - - if (netgame && cv_hazardlog.value) - CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->tracer->player-players], player_names[player-players]); - - if (special->tracer->player->kartstuff[k_comebackpoints] >= 3) - K_StealBalloon(special->tracer->player, player, true); - - special->tracer->player->kartstuff[k_comebacktimer] = comebacktime; } special->momx = special->momy = special->momz = 0; @@ -622,9 +600,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; emblemlocations[special->health-1].collected = true; - M_UpdateUnlockablesAndExtraEmblems(); + M_UpdateUnlockablesAndExtraEmblems(false); - G_SaveGameData(); + G_SaveGameData(false); break; } @@ -2104,7 +2082,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) { P_SetTarget(&target->target, source); source->player->numboxes++; - if ((cv_itemrespawn.value && gametype != GT_COOP && (modifiedgame || netgame || multiplayer))) + if (cv_itemrespawn.value && (netgame || multiplayer)) { target->fuse = cv_itemrespawntime.value*TICRATE + 2; // Random box generation } diff --git a/src/p_local.h b/src/p_local.h index 1bf1471b..47cb545e 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -211,7 +211,6 @@ extern size_t iquehead, iquetail; extern consvar_t cv_gravity, cv_viewheight; void P_RespawnSpecials(void); -void P_RespawnBattleSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); diff --git a/src/p_map.c b/src/p_map.c index bdd97655..6be4be7e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1634,33 +1634,60 @@ static boolean PIT_CheckThing(mobj_t *thing) || thing->player->kartstuff[k_hyudorotimer] || thing->player->kartstuff[k_spinouttimer] || thing->player->kartstuff[k_invincibilitytimer] || thing->player->kartstuff[k_justbumped] || (G_BattleGametype() && (thing->player->kartstuff[k_balloon] <= 0 - && (thing->player->kartstuff[k_comebacktimer] || thing->player->kartstuff[k_comebackmode] == 1))) + && (thing->player->kartstuff[k_comebacktimer]))) || tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer] || tmthing->player->kartstuff[k_hyudorotimer] || tmthing->player->kartstuff[k_spinouttimer] || tmthing->player->kartstuff[k_invincibilitytimer] || tmthing->player->kartstuff[k_justbumped] || (G_BattleGametype() && (tmthing->player->kartstuff[k_balloon] <= 0 - && (tmthing->player->kartstuff[k_comebacktimer] || tmthing->player->kartstuff[k_comebackmode] == 1)))) + && (tmthing->player->kartstuff[k_comebacktimer])))) { return true; } if (G_BattleGametype()) { - if ((thing->player->kartstuff[k_balloon] <= 0 && thing->player->kartstuff[k_comebackmode] == 0) - || (tmthing->player->kartstuff[k_balloon] <= 0 && tmthing->player->kartstuff[k_comebackmode] == 0)) + if (thing->player->kartstuff[k_balloon] <= 0 || tmthing->player->kartstuff[k_balloon] <= 0) { - if (tmthing->player->kartstuff[k_balloon] > 0) + if (thing->player->kartstuff[k_comebackmode] == 0 + && tmthing->player->kartstuff[k_balloon] > 0) { K_ExplodePlayer(tmthing->player, thing); thing->player->kartstuff[k_comebacktimer] = comebacktime; return true; } - else if (thing->player->kartstuff[k_balloon] > 0) + else if (tmthing->player->kartstuff[k_comebackmode] == 0 + && thing->player->kartstuff[k_balloon] > 0) { K_ExplodePlayer(thing->player, tmthing); tmthing->player->kartstuff[k_comebacktimer] = comebacktime; return true; } + else if (thing->player->kartstuff[k_comebackmode] == 1 + && (tmthing->player->kartstuff[k_balloon] > 0 && P_CanPickupItem(tmthing->player, true))) + { + thing->player->kartstuff[k_comebackmode] = 0; + thing->player->kartstuff[k_comebackpoints]++; + if (netgame && cv_hazardlog.value) + CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[thing->player-players], player_names[tmthing->player-players]); + tmthing->player->kartstuff[k_itemroulette] = 1; + if (thing->player->kartstuff[k_comebackpoints] >= 3) + K_StealBalloon(thing->player, tmthing->player, true); + thing->player->kartstuff[k_comebacktimer] = comebacktime; + return true; + } + else if (tmthing->player->kartstuff[k_comebackmode] == 1 + && (thing->player->kartstuff[k_balloon] > 0 && P_CanPickupItem(thing->player, true))) + { + tmthing->player->kartstuff[k_comebackmode] = 0; + tmthing->player->kartstuff[k_comebackpoints]++; + if (netgame && cv_hazardlog.value) + CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[tmthing->player-players], player_names[thing->player-players]); + thing->player->kartstuff[k_itemroulette] = 1; + if (tmthing->player->kartstuff[k_comebackpoints] >= 3) + K_StealBalloon(tmthing->player, thing->player, true); + tmthing->player->kartstuff[k_comebacktimer] = comebacktime; + return true; + } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index b0fa24ad..54cce299 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5969,13 +5969,6 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y if (!dest || dest->health <= 0 || !dest->player || !source->tracer) return; - if (dest->player && dest->player->kartstuff[k_comebackmode] == 1) - { - P_TeleportMove(source, dest->x+dest->momx, dest->y+dest->momy, dest->z+dest->momz); - source->angle = dest->angle; - return; - } - // change angle source->angle = R_PointToAngle2(source->x, source->y, tx, ty); @@ -8329,6 +8322,9 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s P_RemoveMobj(mobj); // make sure they disappear return; case MT_RANDOMITEM: + if (G_BattleGametype()) + break; + // Respawn from mapthing if you have one! if (mobj->spawnpoint) { @@ -9416,10 +9412,39 @@ void P_RespawnSpecials(void) mobj_t *mo = NULL; mapthing_t *mthing = NULL; - if (G_BattleGametype()) // Battle Mode vers + if (G_BattleGametype() && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way { - P_RespawnBattleSpecials(); - return; + thinker_t *th; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + mobj_t *box; + mobj_t *newmobj; + + if (th->function.acp1 != (actionf_p1)P_MobjThinker) // not a mobj + continue; + + box = (mobj_t *)th; + + if (box->type != MT_RANDOMITEM || box->threshold != 68 || box->fuse) // only popped items + continue; + + // Respawn from mapthing if you have one! + if (box->spawnpoint) + { + P_SpawnMapThing(box->spawnpoint); + newmobj = box->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + } + else + newmobj = P_SpawnMobj(box->x, box->y, box->z, box->type); + + // Transfer flags2 (strongbox, objectflip) + newmobj->flags2 = box->flags2; + P_RemoveMobj(box); // make sure they disappear + continue; + } + + numgotboxes = 0; } // only respawn items when cv_itemrespawn is on @@ -9513,97 +9538,6 @@ void P_RespawnSpecials(void) iquetail = (iquetail+1)&(ITEMQUESIZE-1); } -// -// P_RespawnBattleSpecials -// -void P_RespawnBattleSpecials(void) -{ - fixed_t x, y, z; - subsector_t *ss; - mobj_t *mo = NULL; - mapthing_t *mthing = NULL; - - // only respawn items when cv_itemrespawn is on - if (!cv_itemrespawn.value) - return; - - // Didn't collect enough boxes - if (numgotboxes < (4*nummapboxes/5)) - return; - - // wait a teeeensy bit after collecting everything - if (leveltime - itemrespawntime[iquehead-1] < (tic_t)cv_itemrespawntime.value*(5*TICRATE)) - return; - - while (iquehead != iquetail) // respawn EVERYTHING in que! - { - mthing = itemrespawnque[iquetail]; - -#ifdef PARANOIA - if (!mthing) - I_Error("itemrespawnque[iquetail] is NULL!"); -#endif - - if (mthing) - { - mobjtype_t i; - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - ss = R_PointInSubsector(x, y); - - // find which type to spawn - for (i = 0; i < NUMMOBJTYPES; i++) - if (mthing->type == mobjinfo[i].doomednum) - break; - - //CTF rings should continue to respawn as normal rings outside of CTF. - if (gametype != GT_CTF) - { - if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING) - i = MT_RING; - } - - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif - ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; - if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) - z -= 24*FRACUNIT; - z -= mobjinfo[i].height; // Don't forget the height! - } - else - { - z = ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; - if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || P_WeaponOrPanel(i))) - z += 24*FRACUNIT; - } - - mo = P_SpawnMobj(x, y, z, i); - mo->spawnpoint = mthing; - mo->angle = ANGLE_45 * (mthing->angle/45); - - if (mthing->options & MTF_OBJECTFLIP) - { - mo->eflags |= MFE_VERTICALFLIP; - mo->flags2 |= MF2_OBJECTFLIP; - } - } - // pull it from the que - iquetail = (iquetail+1)&(ITEMQUESIZE-1); - } - - numgotboxes = 0; -} - // // P_SpawnPlayer // Called when a player is spawned on the level. diff --git a/src/p_setup.c b/src/p_setup.c index 4cecb941..1986380d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -991,7 +991,7 @@ static void P_LoadThings(void) || mt->type == 1702) // MT_AXISTRANSFERLINE continue; // These were already spawned - if (mt->type == MT_RANDOMITEM) // MT_RANDOMITEM + if (mt->type == mobjinfo[MT_RANDOMITEM].doomednum) nummapboxes++; mt->mobj = NULL; diff --git a/src/p_spec.c b/src/p_spec.c index 7e79291f..f319f211 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3015,10 +3015,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) unlocktriggers |= 1 << trigid; // Unlocked something? - if (M_UpdateUnlockablesAndExtraEmblems()) + if (M_UpdateUnlockablesAndExtraEmblems(false)) { S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(); // only save if unlocked something + G_SaveGameData(false); // only save if unlocked something } } } @@ -3966,7 +3966,7 @@ DoneSection2: player->kartstuff[k_floorboost] = 3; else player->kartstuff[k_floorboost] = 2; - K_DoSneaker(player, false, false); + K_DoSneaker(player, false); } break; diff --git a/src/p_user.c b/src/p_user.c index dde78f0f..dba8e6d2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1650,7 +1650,7 @@ void P_DoPlayerExit(player_t *player) || (splitscreen && player == &players[secondarydisplayplayer]) || (splitscreen > 1 && player == &players[thirddisplayplayer]) || (splitscreen > 2 && player == &players[fourthdisplayplayer])) - && (!player->spectator && ((!modifiedgame || savemoddata) && !demoplayback))) + && (!player->spectator && !demoplayback)) legitimateexit = true; if (G_RaceGametype()) // If in Race Mode, allow @@ -9286,6 +9286,13 @@ void P_PlayerThink(player_t *player) player->pflags |= PF_TIMEOVER; + if ((player == &players[consoleplayer] + || (splitscreen && player == &players[secondarydisplayplayer]) + || (splitscreen > 1 && player == &players[thirddisplayplayer]) + || (splitscreen > 2 && player == &players[fourthdisplayplayer])) + && !demoplayback) + legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p + if (player->pflags & PF_NIGHTSMODE) { P_DeNightserizePlayer(player); diff --git a/src/s_sound.c b/src/s_sound.c index 513415d1..b2786cbf 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -585,6 +585,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); } +dontplay: + if (splitscreen > 1 && listenmobj3) // Copy the sound for the third player { // Check to see if it is audible, and if not, modify the params @@ -594,7 +596,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) rc = S_AdjustSoundParams(listenmobj3, origin, &volume, &sep, &pitch, sfx); if (!rc) - goto dontplay; // Maybe the other player can hear it... + goto dontplay3; // Maybe the other player can hear it... if (origin->x == listener3.x && origin->y == listener3.y) sep = NORM_SEP; @@ -603,7 +605,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Do not play origin-less sounds for the second player. // The first player will be able to hear it just fine, // we really don't want it playing twice. - goto dontplay; + goto dontplay3; else sep = NORM_SEP; @@ -639,6 +641,8 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); } +dontplay3: + if (splitscreen > 2 && listenmobj4) // Copy the sound for the split player { // Check to see if it is audible, and if not, modify the params @@ -648,7 +652,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) rc = S_AdjustSoundParams(listenmobj4, origin, &volume, &sep, &pitch, sfx); if (!rc) - goto dontplay; // Maybe the other player can hear it... + goto dontplay4; // Maybe the other player can hear it... if (origin->x == listener4.x && origin->y == listener4.y) sep = NORM_SEP; @@ -657,7 +661,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) // Do not play origin-less sounds for the second player. // The first player will be able to hear it just fine, // we really don't want it playing twice. - goto dontplay; + goto dontplay4; else sep = NORM_SEP; @@ -693,7 +697,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); } -dontplay: +dontplay4: // Check to see if it is audible, and if not, modify the params if (origin && origin != listenmobj) @@ -1015,83 +1019,69 @@ void S_UpdateSounds(void) || (splitscreen > 2 && c->origin != players[fourthdisplayplayer].mo))) { // Whomever is closer gets the sound, but only in splitscreen. - if (listenmobj && listenmobj2 && splitscreen) + if (splitscreen) { const mobj_t *soundmobj = c->origin; + fixed_t recdist = -1; + INT32 i, p = -1; - fixed_t dist1, dist2; - dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - dist2 = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); + for (i = 0; i < 4; i++) + { + fixed_t thisdist = -1; - if (dist1 <= dist2) - { - // Player 1 gets the sound - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - else - { - // Player 2 gets the sound - audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, - c->sfxinfo); + if (i > splitscreen) + break; + + if (i == 0 && listenmobj) + thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); + else if (i == 1 && listenmobj2) + thisdist = P_AproxDistance(listener2.x-soundmobj->x, listener2.y-soundmobj->y); + else if (i == 2 && listenmobj3) + thisdist = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y); + else if (i == 3 && listenmobj4) + thisdist = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y); + else + continue; + + if (recdist == -1 || (thisdist != -1 && thisdist < recdist)) + { + recdist = thisdist; + p = i; + } } - if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); - else - S_StopChannel(cnum); - } - else if (listenmobj && listenmobj3 && splitscreen > 1) // TODO: make 3/4P compare their distances with all players, not just the first player and themselves V: - { - const mobj_t *soundmobj = c->origin; - - fixed_t dist1, dist2; - dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - dist2 = P_AproxDistance(listener3.x-soundmobj->x, listener3.y-soundmobj->y); - - if (dist1 <= dist2) + if (p != -1) { - // Player 1 gets the sound - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, + if (p == 1) + { + // Player 2 gets the sound + audible = S_AdjustSoundParams(listenmobj2, c->origin, &volume, &sep, &pitch, + c->sfxinfo); + } + else if (p == 2) + { + // Player 3 gets the sound + audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch, c->sfxinfo); - } - else - { - // Player 3 gets the sound - audible = S_AdjustSoundParams(listenmobj3, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } + } + else if (p == 3) + { + // Player 4 gets the sound + audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch, + c->sfxinfo); + } + else + { + // Player 1 gets the sound + audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, + c->sfxinfo); + } - if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); - else - S_StopChannel(cnum); - } - else if (listenmobj && listenmobj4 && splitscreen > 2) - { - const mobj_t *soundmobj = c->origin; - - fixed_t dist1, dist2; - dist1 = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y); - dist2 = P_AproxDistance(listener4.x-soundmobj->x, listener4.y-soundmobj->y); - - if (dist1 <= dist2) - { - // Player 1 gets the sound - audible = S_AdjustSoundParams(listenmobj, c->origin, &volume, &sep, &pitch, - c->sfxinfo); + if (audible) + I_UpdateSoundParams(c->handle, volume, sep, pitch); + else + S_StopChannel(cnum); } - else - { - // Player 4 gets the sound - audible = S_AdjustSoundParams(listenmobj4, c->origin, &volume, &sep, &pitch, - c->sfxinfo); - } - - if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); - else - S_StopChannel(cnum); } else if (listenmobj && !splitscreen) { diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 4a987609..9ee17cc3 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2770,7 +2770,7 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif - G_SaveGameData(); // Tails 12-08-2002 + G_SaveGameData(false); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. @@ -2853,7 +2853,7 @@ void I_Error(const char *error, ...) if (errorcount == 9) { M_SaveConfig(NULL); - G_SaveGameData(); + G_SaveGameData(false); } if (errorcount > 20) { @@ -2887,7 +2887,7 @@ void I_Error(const char *error, ...) #ifndef NONET D_SaveBan(); // save the ban list #endif - G_SaveGameData(); // Tails 12-08-2002 + G_SaveGameData(false); // Tails 12-08-2002 // Shutdown. Here might be other errors. if (demorecording) diff --git a/src/y_inter.c b/src/y_inter.c index d3723f9e..b61ecf74 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -781,10 +781,10 @@ void Y_Ticker(void) // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) { - if (M_UpdateUnlockablesAndExtraEmblems()) + if (M_UpdateUnlockablesAndExtraEmblems(false)) S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(); + G_SaveGameData(false); } } else if (!(intertic & 1)) @@ -848,10 +848,10 @@ void Y_Ticker(void) // Update when done with tally if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && !demoplayback) { - if (M_UpdateUnlockablesAndExtraEmblems()) + if (M_UpdateUnlockablesAndExtraEmblems(false)) S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(); + G_SaveGameData(false); } } else if (!(intertic & 1))