From b8696fc0ffc7366f926eb2a6ba67ad05c2470707 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 20 Nov 2018 00:13:08 -0500 Subject: [PATCH 01/41] Random map buffer only gets added to when Needs another temporary buffer for the vote screen so that it doesn't roll dupes --- src/d_netcmd.c | 7 ++++--- src/f_finale.c | 2 +- src/g_game.c | 28 ++++++++++++++-------------- src/g_game.h | 3 ++- src/m_menu.c | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2dc94a450..47f47451c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2066,6 +2066,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r chmappending++; if (netgame) WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed + G_AddMapToBuffer(mapnum-1); SendNetXCmd(XD_MAP, buf, buf_p - buf); } } @@ -2087,11 +2088,11 @@ void D_SetupVote(void) for (i = 0; i < 5; i++) { if (i == 2) // sometimes a different gametype - WRITEUINT16(p, G_RandMap(G_TOLFlag(secondgt), prevmap, false, false, 0, true)); + WRITEUINT16(p, G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true)); else if (i >= 3) // unknown-random and force-unknown MAP HELL - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, true, false, (i-2), (i < 4))); + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, (i-2), (i < 4))); else - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, true)); + WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, true)); } SendNetXCmd(XD_SETUPVOTE, buf, p - buf); diff --git a/src/f_finale.c b/src/f_finale.c index ea89b2b7b..b84289be6 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1068,7 +1068,7 @@ void F_TitleScreenTicker(boolean run) return; }*/ - mapname = G_BuildMapName(G_RandMap(TOL_RACE, -2, false, false, 0, false)+1); + mapname = G_BuildMapName(G_RandMap(TOL_RACE, -2, false, 0, false)+1); numstaff = 1; while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",mapname,numstaff+1))) != LUMPERROR) diff --git a/src/g_game.c b/src/g_game.c index 517e5bcba..ba6bf5a37 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -779,7 +779,7 @@ const char *G_BuildMapName(INT32 map) map = gamemap-1; else map = prevmap; - map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, false, false, 0, false)+1; + map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, false, 0, false)+1; } if (map < 100) @@ -3268,7 +3268,7 @@ static INT32 TOLMaps(INT16 tolflags) * \author Graue */ static INT16 *okmaps = NULL; -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon) +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon) { INT32 numokmaps = 0; INT16 ix, bufx; @@ -3329,20 +3329,20 @@ tryagain: if (randmapbuffer[3] == -1) // Is the buffer basically empty? { ignorebuffer = true; // This will probably only help in situations where there's very few maps, but it's folly not to at least try it - goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, true, maphell, callagainsoon); + goto tryagain; //return G_RandMap(tolflags, pprevmap, true, maphell, callagainsoon); } for (bufx = 3; bufx < NUMMAPS; bufx++) // Let's clear all but the three most recent maps... randmapbuffer[bufx] = -1; if (cv_kartvoterulechanges.value == 1) // sometimes randmapbuffer[NUMMAPS] = 0; - goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, ignorebuffer, maphell, callagainsoon); + goto tryagain; //return G_RandMap(tolflags, pprevmap, ignorebuffer, maphell, callagainsoon); } if (maphell) // Any wiggle room to loosen our restrictions here? { maphell--; - goto tryagain; //return G_RandMap(tolflags, pprevmap, dontadd, true, maphell-1, callagainsoon); + goto tryagain; //return G_RandMap(tolflags, pprevmap, true, maphell-1, callagainsoon); } ix = 0; // Sorry, none match. You get MAP01. @@ -3350,15 +3350,7 @@ tryagain: randmapbuffer[bufx] = -1; // if we're having trouble finding a map we should probably clear it } else - { ix = okmaps[M_RandomKey(numokmaps)]; - if (!dontadd) - { - for (bufx = NUMMAPS-1; bufx > 0; bufx--) - randmapbuffer[bufx] = randmapbuffer[bufx-1]; - randmapbuffer[0] = ix; - } - } if (!callagainsoon) { @@ -3369,6 +3361,14 @@ tryagain: return ix; } +void G_AddMapToBuffer(INT16 map) +{ + INT16 bufx; + for (bufx = NUMMAPS-1; bufx > 0; bufx--) + randmapbuffer[bufx] = randmapbuffer[bufx-1]; + randmapbuffer[0] = map; +} + // // G_DoCompleted // @@ -3519,7 +3519,7 @@ static void G_DoCompleted(void) if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. - nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, false, 0, false); + nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false); } // We are committed to this map now. diff --git a/src/g_game.h b/src/g_game.h index 621da3f8f..27f961d3b 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -255,6 +255,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean dontadd, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon); +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon); +void G_AddMapToBuffer(INT16 map); #endif diff --git a/src/m_menu.c b/src/m_menu.c index 7d7c1fbf9..9b1eb62c6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7454,7 +7454,7 @@ static void M_StartServer(INT32 choice) G_StopMetalDemo(); if (!cv_nextmap.value) - CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, false, false, 0, false)+1); + CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, false, 0, false)+1); if (cv_maxplayers.value < ssplayers+1) CV_SetValue(&cv_maxplayers, ssplayers+1); From 0fc427a6638c3ed7d019693d16e9c4ce3f7e1900 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 22 Nov 2018 17:10:36 +0000 Subject: [PATCH 02/41] The oft-promised buffer fixes. Also, making it so the gametype switch for "Sometimes" is every 10 maps, not a full buffer round (now that it doesn't add to the buffer when you first see it). Unfortunately, the code didn't turn out nearly as nice as I'd desired, but things don't always work out. In addition: For some reason, I rolled Tinkerer's Arena twice within three hits of the Dice voting option, so something's wrong and this branch needs proper, rigorous investigative testing but I don't know what and I'm way too tired (both physically and metaphysically) to investigate any further. --- src/d_netcmd.c | 1 - src/g_game.c | 49 +++++++++++++++++++++++++++++++++++++++---------- src/p_setup.c | 2 ++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 47f47451c..4a08a1af0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2066,7 +2066,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r chmappending++; if (netgame) WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed - G_AddMapToBuffer(mapnum-1); SendNetXCmd(XD_MAP, buf, buf_p - buf); } } diff --git a/src/g_game.c b/src/g_game.c index ba6bf5a37..f9f156a81 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3137,8 +3137,7 @@ INT16 G_SometimesGetDifferentGametype(void) if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3)) { - if (cv_kartvoterulechanges.value != 1) - randmapbuffer[NUMMAPS]--; + randmapbuffer[NUMMAPS]--; if (encorepossible) { switch (cv_kartvoterulechanges.value) @@ -3166,6 +3165,8 @@ INT16 G_SometimesGetDifferentGametype(void) randmapbuffer[NUMMAPS] = 1; // every other vote (or always if !encorepossible) break; case 1: // sometimes + randmapbuffer[NUMMAPS] = 10; // ...every two cups? + break; default: // fallthrough - happens when clearing buffer, but needs a reasonable countdown if cvar is modified case 2: // frequent @@ -3268,6 +3269,7 @@ static INT32 TOLMaps(INT16 tolflags) * \author Graue */ static INT16 *okmaps = NULL; +static INT16 votebuffer[3] = {-1, -1, -1}; INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon) { INT32 numokmaps = 0; @@ -3297,6 +3299,26 @@ tryagain: if (!ignorebuffer) { + if (votebuffer[0] != -1) + { + if (ix == votebuffer[0]) + continue; + + for (bufx = 1; bufx < 3; bufx++) + { + if (votebuffer[bufx] == -1) // Rest of buffer SHOULD be empty + break; + if (ix == votebuffer[bufx]) + { + isokmap = false; + break; + } + } + + if (!isokmap) + continue; + } + for (bufx = 0; bufx < (maphell ? 3 : NUMMAPS); bufx++) { if (randmapbuffer[bufx] == -1) // Rest of buffer SHOULD be empty @@ -3307,12 +3329,12 @@ tryagain: break; } } + + if (!isokmap) + continue; } - if (!isokmap) - continue; - - if (pprevmap == -2) // title demos + if (pprevmap == -2) // title demo hack { lumpnum_t l; if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(ix+1)))) == LUMPERROR) @@ -3334,8 +3356,6 @@ tryagain: for (bufx = 3; bufx < NUMMAPS; bufx++) // Let's clear all but the three most recent maps... randmapbuffer[bufx] = -1; - if (cv_kartvoterulechanges.value == 1) // sometimes - randmapbuffer[NUMMAPS] = 0; goto tryagain; //return G_RandMap(tolflags, pprevmap, ignorebuffer, maphell, callagainsoon); } @@ -3356,6 +3376,17 @@ tryagain: { Z_Free(okmaps); okmaps = NULL; + for (bufx = 0; bufx < 3; bufx++) + votebuffer[bufx] = -1; + } + else if (votebuffer[2] == -1) + { + for (bufx = 0; bufx < 3; bufx++) + if (votebuffer[bufx] == -1) + { + votebuffer[bufx] = ix; + break; + } } return ix; @@ -3509,8 +3540,6 @@ static void G_DoCompleted(void) { for (i = 3; i < NUMMAPS; i++) // Let's clear all but the three most recent maps... randmapbuffer[i] = -1; - if (cv_kartvoterulechanges.value == 1) // sometimes - randmapbuffer[NUMMAPS] = 0; } #endif diff --git a/src/p_setup.c b/src/p_setup.c index 68cdc797b..533bba14f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3113,6 +3113,8 @@ boolean P_SetupLevel(boolean skipprecip) #endif } + G_AddMapToBuffer(gamemap-1); + return true; } From 9bec65ca03afdf7beb991eff6a6f4aee83b9240f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 22 Nov 2018 23:38:54 -0500 Subject: [PATCH 03/41] Franticized items for 2nd place VS SPB'd 1st --- src/dehacked.c | 3 +++ src/doomstat.h | 1 + src/g_game.c | 1 + src/k_kart.c | 19 ++++++++++++------- src/p_mobj.c | 4 ++++ src/p_saveg.c | 2 ++ src/p_setup.c | 1 + src/p_user.c | 3 +++ 8 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index cfa08b454..27d531cc3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9770,6 +9770,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"thwompsactive")) { lua_pushboolean(L, thwompsactive); return 1; + } else if (fastcmp(word,"spbexists")) { + lua_pushboolean(L, spbexists); + return 1; } return 0; diff --git a/src/doomstat.h b/src/doomstat.h index 34456b321..aa2ebe311 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -461,6 +461,7 @@ extern tic_t indirectitemcooldown; extern tic_t mapreset; extern UINT8 nospectategrief; extern boolean thwompsactive; +extern boolean spbexists; extern boolean legitimateexit; extern boolean comebackshowninfo; diff --git a/src/g_game.c b/src/g_game.c index e9309b807..cba9d26ce 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -267,6 +267,7 @@ tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any othe tic_t mapreset; // Map reset delay when enough players have joined an empty game UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing boolean thwompsactive; // Thwomps activate on lap 2 +boolean spbexists; // SPB exists, give 2nd place better items // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? diff --git a/src/k_kart.c b/src/k_kart.c index 8bd08e264..94fa3f328 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -574,8 +574,10 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) player->kartstuff[k_itemtype] = KITEM_JAWZ; player->kartstuff[k_itemamount] = 2; break; - case KITEM_SPB: // Indirect items - case KITEM_SHRINK: + case KITEM_SPB: + spbexists = true; + /* FALLTHRU */ + case KITEM_SHRINK: // Indirect items indirectitemcooldown = 30*TICRATE; /* FALLTHRU */ default: @@ -599,7 +601,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) \return void */ -static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) +static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean insecondplace) { const INT32 distvar = (64*14); INT32 newodds; @@ -648,13 +650,16 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) // POWERITEMODDS handles all of the "frantic item" related functionality, for all of our powerful items. // First, it multiplies it by 2 if franticitems is true; easy-peasy. - // Then, it multiplies it further if there's less than 5 players in game. + // Next, it multiplies it again if it's in SPB mode and 2nd needs to apply pressure to 1st. + // Then, it multiplies it further if there's less than 8 players in game. // This is done to make low player count races more fair & interesting. (1v1s are basically the same as franticitems false in a normal race) // Lastly, it *divides* it by your mashed value, which was determined in K_KartItemRoulette, to punish those who are impatient. // The last two are very fractional and complicated, very sorry! #define POWERITEMODDS(odds) \ if (franticitems) \ odds *= 2; \ + if (spbexists && insecondplace) \ + odds *= 2; \ if (pingame < 8 && !G_BattleGametype()) \ odds = FixedMul(odds*FRACUNIT, FRACUNIT+min((8-pingame)*(FRACUNIT/25), FRACUNIT))/FRACUNIT; \ if (mashed > 0) \ @@ -782,7 +787,7 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 for (j = 0; j < NUMKARTRESULTS; j++) { - if (K_KartGetItemOdds(i, j, mashed) > 0) + if (K_KartGetItemOdds(i, j, mashed, (player->kartstuff[k_position] == 2)) > 0) { available = true; break; @@ -974,7 +979,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) useodds = K_FindUseodds(player, mashed, pingame, bestbumper); #define SETITEMRESULT(itemnum) \ - for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed); chance++) \ + for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed, (player->kartstuff[k_position] == 2)); chance++) \ spawnchance[numchoices++] = itemnum for (i = 1; i < NUMKARTRESULTS; i++) @@ -7811,7 +7816,7 @@ static void K_drawDistributionDebugger(void) for (i = 1; i < NUMKARTRESULTS; i++) { - const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0); + const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0, (stplyr->kartstuff[k_position] == 2)); if (itemodds <= 0) continue; diff --git a/src/p_mobj.c b/src/p_mobj.c index 2cb12791f..ba0a0c113 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8155,6 +8155,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_SPB: indirectitemcooldown = 30*TICRATE; + spbexists = true; /* FALLTHRU */ case MT_BALLHOG: P_SpawnGhostMobj(mobj)->fuse = 3; @@ -10378,6 +10379,9 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->type == MT_SHADOW) P_RemoveShadow(mobj); + if (mobj->type == MT_SPB) + spbexists = false; + mobj->health = 0; // Just because // unlink from sector and block lists diff --git a/src/p_saveg.c b/src/p_saveg.c index 1b4314b8e..447310006 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3287,6 +3287,7 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, mapreset); WRITEUINT8(save_p, nospectategrief); WRITEUINT8(save_p, thwompsactive); + WRITEUINT8(save_p, spbexists); // Is it paused? if (paused) @@ -3393,6 +3394,7 @@ static inline boolean P_NetUnArchiveMisc(void) mapreset = READUINT32(save_p); nospectategrief = READUINT8(save_p); thwompsactive = (boolean)READUINT8(save_p); + spbexists = (boolean)READUINT8(save_p); // Is it paused? if (READUINT8(save_p) == 0x2f) diff --git a/src/p_setup.c b/src/p_setup.c index 68cdc797b..fa8e263c6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3046,6 +3046,7 @@ boolean P_SetupLevel(boolean skipprecip) mapreset = 0; nospectategrief = 0; thwompsactive = false; + spbexists = false; // clear special respawning que iquehead = iquetail = 0; diff --git a/src/p_user.c b/src/p_user.c index b2849c857..d17a7c801 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7758,7 +7758,10 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) } if (mo->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown. + { + spbexists = false; indirectitemcooldown = 0; + } if (mo == inflictor) // Don't nuke yourself, dummy! continue; From c2941d6ea5daab2798a3f57f85c8654dde10e1d1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 23 Nov 2018 19:15:14 -0500 Subject: [PATCH 04/41] Item roulette fun-times - Colorize items, Combi-Catcher style, while the roulette is still going. Nice Chaotix reference, and tells you when the game's just lagged. - Items blink when you first get them! They blink white when you wait out the whole roulette, red when you mash, or rainbow for enhanced items! Blinking prevents items from being stolen too, so items can't be literally stolen before you even have a chance to see what it was. - New item roulette sound for mashing - Fix TC_ limits in Lua --- src/d_player.h | 4 + src/dehacked.c | 3 + src/k_kart.c | 222 +++++++++++++++++++++++++++++++++++++---------- src/lua_hudlib.c | 4 +- src/r_draw.c | 2 + src/r_draw.h | 1 + src/sounds.c | 1 + src/sounds.h | 1 + 8 files changed, 191 insertions(+), 47 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index a59076466..c87437171 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -348,6 +348,10 @@ typedef enum k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly + // v1.0.2 vars + k_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator + k_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items) + NUMKARTSTUFF } kartstufftype_t; //} diff --git a/src/dehacked.c b/src/dehacked.c index 27d531cc3..c1195849e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8270,6 +8270,9 @@ static const char *const KARTSTUFF_LIST[] = { "COMEBACKMODE", "WANTED", "YOUGOTEM", + + "ITEMBLINK", + "ITEMBLINKMODE" }; static const char *const HUDITEMS_LIST[] = { diff --git a/src/k_kart.c b/src/k_kart.c index 94fa3f328..e4c0f39ef 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -326,12 +326,20 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) INT32 starttranscolor; // Handle a couple of simple special cases - if (skinnum == TC_BOSS || skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || color == SKINCOLOR_NONE) + if (skinnum == TC_BOSS + || skinnum == TC_ALLWHITE + || skinnum == TC_METALSONIC + || skinnum == TC_BLINK + || color == SKINCOLOR_NONE) { for (i = 0; i < NUM_PALETTE_ENTRIES; i++) { - if (skinnum == TC_ALLWHITE) dest_colormap[i] = 0; - else dest_colormap[i] = (UINT8)i; + if (skinnum == TC_ALLWHITE) + dest_colormap[i] = 0; + else if (skinnum == TC_BLINK) + dest_colormap[i] = colortranslations[color][7]; + else + dest_colormap[i] = (UINT8)i; } // White! @@ -953,6 +961,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_roulettetype] == 2) // Fake items { player->kartstuff[k_eggmanexplode] = 4*TICRATE; + //player->kartstuff[k_itemblink] = TICRATE; + //player->kartstuff[k_itemblinkmode] = 1; player->kartstuff[k_itemroulette] = 0; player->kartstuff[k_roulettetype] = 0; if (P_IsLocalPlayer(player)) @@ -964,6 +974,8 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) { K_KartGetItemResult(player, cv_kartdebugitem.value); player->kartstuff[k_itemamount] = cv_kartdebugamount.value; + player->kartstuff[k_itemblink] = TICRATE; + player->kartstuff[k_itemblinkmode] = 2; player->kartstuff[k_itemroulette] = 0; player->kartstuff[k_roulettetype] = 0; if (P_IsLocalPlayer(player)) @@ -996,11 +1008,13 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemamount] = 1; } + player->kartstuff[k_itemblink] = TICRATE; + player->kartstuff[k_itemblinkmode] = ((player->kartstuff[k_roulettetype] == 1) ? 2 : (mashed ? 1 : 0)); player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number player->kartstuff[k_roulettetype] = 0; // This too if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_itrolf); + S_StartSound(NULL, (mashed ? sfx_itrolm : sfx_itrolf)); } //} @@ -3038,7 +3052,8 @@ static void K_DoHyudoroSteal(player_t *player) // Has an item && (players[i].kartstuff[k_itemtype] && players[i].kartstuff[k_itemamount] - && !players[i].kartstuff[k_itemheld])) + && !players[i].kartstuff[k_itemheld] + && !players[i].kartstuff[k_itemblink])) { playerswappable[numplayers] = i; numplayers++; @@ -4244,6 +4259,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_yougotem]) player->kartstuff[k_yougotem]--; + if (player->kartstuff[k_itemblink] && player->kartstuff[k_itemblink]-- <= 0) + { + player->kartstuff[k_itemblinkmode] = 0; + player->kartstuff[k_itemblink] = 0; + } + if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) { if (player->exiting) @@ -6239,29 +6260,84 @@ static void K_drawKartItem(void) INT32 splitflags = K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOLEFT); const INT32 numberdisplaymin = ((!offset && stplyr->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); INT32 itembar = 0; + UINT8 localcolor = SKINCOLOR_NONE; + SINT8 colormode = TC_RAINBOW; + UINT8 *colmap = NULL; if (stplyr->kartstuff[k_itemroulette]) { - switch((stplyr->kartstuff[k_itemroulette] % (13*3)) / 3) + if (stplyr->skincolor) + localcolor = stplyr->skincolor; + + switch((stplyr->kartstuff[k_itemroulette] % (14*3)) / 3) { // Each case is handled in threes, to give three frames of in-game time to see the item on the roulette - case 0: localpatch = kp_sneaker[offset]; break; // Sneaker - case 1: localpatch = kp_banana[offset]; break; // Banana - case 2: localpatch = kp_orbinaut[3+offset]; break; // Orbinaut - case 3: localpatch = kp_mine[offset]; break; // Mine - case 4: localpatch = kp_grow[offset]; break; // Grow - case 5: localpatch = kp_hyudoro[offset]; break; // Hyudoro - case 6: localpatch = kp_rocketsneaker[offset]; break; // Rocket Sneaker - case 7: localpatch = kp_jawz[offset]; break; // Jawz - case 8: localpatch = kp_selfpropelledbomb[offset]; break; // Self-Propelled Bomb - case 9: localpatch = kp_shrink[offset]; break; // Shrink - case 10: localpatch = localinv; break; // Invincibility - case 11: localpatch = kp_eggman[offset]; break; // Eggman Monitor - case 12: localpatch = kp_ballhog[offset]; break; // Ballhog - case 13: localpatch = kp_thundershield[offset]; break; // Thunder Shield - //case 14: localpatch = kp_pogospring[offset]; break; // Pogo Spring - //case 15: localpatch = kp_kitchensink[offset]; break; // Kitchen Sink - default: break; + case 0: // Sneaker + localpatch = kp_sneaker[offset]; + //localcolor = SKINCOLOR_RASPBERRY; + break; + case 1: // Banana + localpatch = kp_banana[offset]; + //localcolor = SKINCOLOR_YELLOW; + break; + case 2: // Orbinaut + localpatch = kp_orbinaut[3+offset]; + //localcolor = SKINCOLOR_STEEL; + break; + case 3: // Mine + localpatch = kp_mine[offset]; + //localcolor = SKINCOLOR_JET; + break; + case 4: // Grow + localpatch = kp_grow[offset]; + //localcolor = SKINCOLOR_TEAL; + break; + case 5: // Hyudoro + localpatch = kp_hyudoro[offset]; + //localcolor = SKINCOLOR_STEEL; + break; + case 6: // Rocket Sneaker + localpatch = kp_rocketsneaker[offset]; + //localcolor = SKINCOLOR_TANGERINE; + break; + case 7: // Jawz + localpatch = kp_jawz[offset]; + //localcolor = SKINCOLOR_JAWZ; + break; + case 8: // Self-Propelled Bomb + localpatch = kp_selfpropelledbomb[offset]; + //localcolor = SKINCOLOR_JET; + break; + case 9: // Shrink + localpatch = kp_shrink[offset]; + //localcolor = SKINCOLOR_ORANGE; + break; + case 10: // Invincibility + localpatch = localinv; + //localcolor = SKINCOLOR_GREY; + break; + case 11: // Eggman Monitor + localpatch = kp_eggman[offset]; + //localcolor = SKINCOLOR_ROSE; + break; + case 12: // Ballhog + localpatch = kp_ballhog[offset]; + //localcolor = SKINCOLOR_LILAC; + break; + case 13: // Thunder Shield + localpatch = kp_thundershield[offset]; + //localcolor = SKINCOLOR_CYAN; + break; + /*case 14: // Pogo Spring + localpatch = kp_pogospring[offset]; + localcolor = SKINCOLOR_TANGERINE; + break; + case 15: // Kitchen Sink + localpatch = kp_kitchensink[offset]; + localcolor = SKINCOLOR_STEEL; + break;*/ + default: + break; } } else @@ -6317,41 +6393,97 @@ static void K_drawKartItem(void) switch(stplyr->kartstuff[k_itemtype]) { - case KITEM_SNEAKER: localpatch = kp_sneaker[offset]; break; - case KITEM_ROCKETSNEAKER: localpatch = kp_rocketsneaker[offset]; break; - case KITEM_INVINCIBILITY: localpatch = localinv; localbg = kp_itembg[offset+1]; break; - case KITEM_BANANA: localpatch = kp_banana[offset]; break; - case KITEM_EGGMAN: localpatch = kp_eggman[offset]; break; - case KITEM_ORBINAUT: - localpatch = kp_orbinaut[(offset ? 4 - : min(stplyr->kartstuff[k_itemamount]-1, 3))]; + case KITEM_SNEAKER: + localpatch = kp_sneaker[offset]; break; - case KITEM_JAWZ: localpatch = kp_jawz[offset]; break; - case KITEM_MINE: localpatch = kp_mine[offset]; break; - case KITEM_BALLHOG: localpatch = kp_ballhog[offset]; break; - case KITEM_SPB: localpatch = kp_selfpropelledbomb[offset]; localbg = kp_itembg[offset+1]; break; - case KITEM_GROW: localpatch = kp_grow[offset]; break; - case KITEM_SHRINK: localpatch = kp_shrink[offset]; break; - case KITEM_THUNDERSHIELD: localpatch = kp_thundershield[offset]; localbg = kp_itembg[offset+1]; break; - case KITEM_HYUDORO: localpatch = kp_hyudoro[offset]; break; - case KITEM_POGOSPRING: localpatch = kp_pogospring[offset]; break; - case KITEM_KITCHENSINK: localpatch = kp_kitchensink[offset]; break; - case KITEM_SAD: localpatch = kp_sadface[offset]; break; - default: return; + case KITEM_ROCKETSNEAKER: + localpatch = kp_rocketsneaker[offset]; + break; + case KITEM_INVINCIBILITY: + localpatch = localinv; + localbg = kp_itembg[offset+1]; + break; + case KITEM_BANANA: + localpatch = kp_banana[offset]; + break; + case KITEM_EGGMAN: + localpatch = kp_eggman[offset]; + break; + case KITEM_ORBINAUT: + localpatch = kp_orbinaut[(offset ? 4 : min(stplyr->kartstuff[k_itemamount]-1, 3))]; + break; + case KITEM_JAWZ: + localpatch = kp_jawz[offset]; + break; + case KITEM_MINE: + localpatch = kp_mine[offset]; + break; + case KITEM_BALLHOG: + localpatch = kp_ballhog[offset]; + break; + case KITEM_SPB: + localpatch = kp_selfpropelledbomb[offset]; + localbg = kp_itembg[offset+1]; + break; + case KITEM_GROW: + localpatch = kp_grow[offset]; + break; + case KITEM_SHRINK: + localpatch = kp_shrink[offset]; + break; + case KITEM_THUNDERSHIELD: + localpatch = kp_thundershield[offset]; + localbg = kp_itembg[offset+1]; + break; + case KITEM_HYUDORO: + localpatch = kp_hyudoro[offset]; + break; + case KITEM_POGOSPRING: + localpatch = kp_pogospring[offset]; + break; + case KITEM_KITCHENSINK: + localpatch = kp_kitchensink[offset]; + break; + case KITEM_SAD: + localpatch = kp_sadface[offset]; + break; + default: + return; } if (stplyr->kartstuff[k_itemheld] && !(leveltime & 1)) localpatch = kp_nodraw; } + + if (stplyr->kartstuff[k_itemblink] && (leveltime & 1)) + { + colormode = TC_BLINK; + + switch (stplyr->kartstuff[k_itemblinkmode]) + { + case 2: + localcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + break; + case 1: + localcolor = SKINCOLOR_RED; + break; + default: + localcolor = SKINCOLOR_WHITE; + break; + } + } } + if (localcolor != SKINCOLOR_NONE) + colmap = R_GetTranslationColormap(colormode, localcolor, 0); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localbg); // Then, the numbers: if (stplyr->kartstuff[k_itemamount] >= numberdisplaymin && !stplyr->kartstuff[k_itemroulette]) { V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, kp_itemmulsticker[offset]); - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); + V_DrawFixedPatch(ITEM_X<kartstuff[k_itemamount])); else @@ -6361,7 +6493,7 @@ static void K_drawKartItem(void) } } else - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); + V_DrawFixedPatch(ITEM_X<= MAXSKINS) - return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_ALLWHITE, MAXSKINS-1); + if (skinnum < TC_BLINK || skinnum >= MAXSKINS) + return luaL_error(L, "skin number %d is out of range (%d - %d)", skinnum, TC_BLINK, MAXSKINS-1); } else // skin name { diff --git a/src/r_draw.c b/src/r_draw.c index 609274340..560f30637 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -136,6 +136,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) +#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define SKIN_RAMP_LENGTH 16 #define DEFAULT_STARTTRANSCOLOR 160 #define NUM_PALETTE_ENTRIES 256 @@ -530,6 +531,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags) else if (skinnum == TC_METALSONIC) skintableindex = METALSONIC_TT_CACHE_INDEX; else if (skinnum == TC_ALLWHITE) skintableindex = ALLWHITE_TT_CACHE_INDEX; else if (skinnum == TC_RAINBOW) skintableindex = RAINBOW_TT_CACHE_INDEX; + else if (skinnum == TC_BLINK) skintableindex = BLINK_TT_CACHE_INDEX; else skintableindex = skinnum; if (flags & GTC_CACHE) diff --git a/src/r_draw.h b/src/r_draw.h index 0ff19bc74..c43d15797 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -108,6 +108,7 @@ extern lumpnum_t viewborderlump[8]; #define TC_METALSONIC -3 // For Metal Sonic battle #define TC_ALLWHITE -4 // For Cy-Brak-demon #define TC_RAINBOW -5 // For invincibility power +#define TC_BLINK -6 // For item blinking // Initialize color translation tables, for player rendering etc. void R_InitTranslationTables(void); diff --git a/src/sounds.c b/src/sounds.c index 5531e7a3d..900c88f9c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -792,6 +792,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"itrol7", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"itrol8", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"itrolf", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end + {"itrolm", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end (mashed) {"itrole", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end (Eggman) {"vroom", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Krew opening vroom {"chaooo", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Chao audience cheer diff --git a/src/sounds.h b/src/sounds.h index e93a17a47..1e287a6b8 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -867,6 +867,7 @@ typedef enum sfx_itrol7, sfx_itrol8, sfx_itrolf, + sfx_itrolm, sfx_itrole, sfx_vroom, sfx_chaooo, From b1ee5de0580c8af76707a1f845792ad8fff0bb07 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 02:56:39 -0500 Subject: [PATCH 05/41] Change how SPB rush works Instead of enabling Frantic for the person in 2nd, it doubles the gap between them. Now it's 2nd's job to catch up and ruin 1st's day. --- src/k_kart.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e4c0f39ef..f22f8aba2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -609,7 +609,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) \return void */ -static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean insecondplace) +static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) { const INT32 distvar = (64*14); INT32 newodds; @@ -666,8 +666,6 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean in #define POWERITEMODDS(odds) \ if (franticitems) \ odds *= 2; \ - if (spbexists && insecondplace) \ - odds *= 2; \ if (pingame < 8 && !G_BattleGametype()) \ odds = FixedMul(odds*FRACUNIT, FRACUNIT+min((8-pingame)*(FRACUNIT/25), FRACUNIT))/FRACUNIT; \ if (mashed > 0) \ @@ -773,7 +771,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean in //{ SRB2kart Roulette Code - Distance Based, no waypoints -static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper) +static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT32 bestbumper, boolean spbrush) { const INT32 distvar = (64*14); INT32 i; @@ -795,7 +793,7 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 for (j = 0; j < NUMKARTRESULTS; j++) { - if (K_KartGetItemOdds(i, j, mashed, (player->kartstuff[k_position] == 2)) > 0) + if (K_KartGetItemOdds(i, j, mashed) > 0) { available = true; break; @@ -853,9 +851,11 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 if (oddsvalid[8]) SETUPDISTTABLE(8,1); if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items - pdis = (15*pdis/14); - if (pingame < 8 && !G_BattleGametype()) - pdis = ((28+(8-pingame))*pdis/28); + pdis = (15*pdis)/14; + if (spbrush) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell + pdis *= 2; + if (pingame < 8) + pdis = ((28+(8-pingame))*pdis)/28; if (pingame == 1 && oddsvalid[0]) // Record Attack, or just alone useodds = 0; @@ -988,10 +988,10 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) spawnchance[i] = 0; // Split into another function for a debug function below - useodds = K_FindUseodds(player, mashed, pingame, bestbumper); + useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (player->kartstuff[k_position] == 2 && spbexists)); #define SETITEMRESULT(itemnum) \ - for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed, (player->kartstuff[k_position] == 2)); chance++) \ + for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed); chance++) \ spawnchance[numchoices++] = itemnum for (i = 1; i < NUMKARTRESULTS; i++) @@ -7944,11 +7944,11 @@ static void K_drawDistributionDebugger(void) bestbumper = players[i].kartstuff[k_bumper]; } - useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper); + useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (player->kartstuff[k_position] == 2 && spbexists)); for (i = 1; i < NUMKARTRESULTS; i++) { - const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0, (stplyr->kartstuff[k_position] == 2)); + const INT32 itemodds = K_KartGetItemOdds(useodds, i, 0); if (itemodds <= 0) continue; From 4c003cabe10f175dfa495729a1b5ed1d15fec8f0 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 03:42:25 -0500 Subject: [PATCH 06/41] More SPB tweaks - SPB can switch off if its target if that person lost the lead for 7 seconds - Make sure lastlook gets reset when going back to SEEKING --- src/p_enemy.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_enemy.c b/src/p_enemy.c index a78957b06..b81f1ea9a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8369,11 +8369,19 @@ void A_SPBChase(mobj_t *actor) if (actor->tracer->player) // 7/8ths max speed for Knuckles, 3/4ths max speed for min accel, exactly max speed for max accel { actor->lastlook = actor->tracer->player-players; // Save the player num for death scumming... + if (!P_IsObjectOnGround(actor->tracer) /*&& !actor->tracer->player->kartstuff[k_pogospring]*/) defspeed = (7*actor->tracer->player->speed)/8; // In the air you have no control; basically don't hit unless you make a near complete stop else defspeed = ((33 - actor->tracer->player->kartspeed) * K_GetKartSpeed(actor->tracer->player, false)) / 32; + defspeed -= (9*R_PointToDist2(0, 0, actor->tracer->player->cmomx, actor->tracer->player->cmomy))/8; // Be fairer on conveyors + + // Switch targets if you're no longer 1st for long enough + if (actor->tracer->player->kartstuff[k_position] == 1) + actor->extravalue2 = 7*TICRATE; + else if (actor->extravalue2-- <= 0) + actor->extravalue1 = 0; // back to SEEKING } // Play the intimidating gurgle @@ -8464,6 +8472,7 @@ void A_SPBChase(mobj_t *actor) { P_SetTarget(&actor->tracer, players[actor->lastlook].mo); actor->extravalue1 = 1; // TARGETING + actor->extravalue2 = 7*TICRATE; } else actor->extravalue1 = 0; // SEEKING @@ -8472,6 +8481,8 @@ void A_SPBChase(mobj_t *actor) } else // MODE: SEEKING { + actor->lastlook = -1; // Just make sure this is reset + // Find the player with the best rank for (i = 0; i < MAXPLAYERS; i++) { @@ -8560,6 +8571,7 @@ void A_SPBChase(mobj_t *actor) { S_StartSound(actor, actor->info->attacksound); // Siren sound; might not need this anymore, but I'm keeping it for now just for debugging. actor->extravalue1 = 1; // TARGET ACQUIRED + actor->extravalue2 = 7*TICRATE; } } From 1acbb77efb39a6291886d6b278c9302b3ff80df4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 17:27:48 -0500 Subject: [PATCH 07/41] Wrong var here --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index f22f8aba2..3b6b68506 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7944,7 +7944,7 @@ static void K_drawDistributionDebugger(void) bestbumper = players[i].kartstuff[k_bumper]; } - useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (player->kartstuff[k_position] == 2 && spbexists)); + useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (stplyr->kartstuff[k_position] == 2 && spbexists)); for (i = 1; i < NUMKARTRESULTS; i++) { From 5767a25b14d14bdf6a87e636d362b8b0b03e8b9f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 17:28:53 -0500 Subject: [PATCH 08/41] Infinite wall bump fix(?) Couldn't replicate it at all after this change, but I also have trouble replicating it before it :v --- src/p_map.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index ba6e64540..66928bf66 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3844,7 +3844,7 @@ void P_BouncePlayerMove(mobj_t *mo) if (!mo->player) return; - if ((mo->eflags & MFE_JUSTBOUNCEDWALL) || (mo->player->spectator)) + if (mo->player->spectator) { P_SlideMove(mo, true); return; @@ -3898,8 +3898,16 @@ void P_BouncePlayerMove(mobj_t *mo) if (bestslidefrac <= 0) return; - tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); - tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + if (mo->eflags & MFE_JUSTBOUNCEDWALL) // Stronger push-out + { + tmxmove = mmomx; + tmymove = mmomy; + } + else + { + tmxmove = FixedMul(mmomx, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); + } { mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); @@ -3936,18 +3944,18 @@ void P_BounceMove(mobj_t *mo) INT32 hitcount; fixed_t mmomx = 0, mmomy = 0; - if (mo->eflags & MFE_JUSTBOUNCEDWALL) - { - P_SlideMove(mo, true); - return; - } - if (mo->player) { P_BouncePlayerMove(mo); return; } + if (mo->eflags & MFE_JUSTBOUNCEDWALL) + { + P_SlideMove(mo, true); + return; + } + slidemo = mo; hitcount = 0; From 0846d2cb2c04ccb933f3a43db2f47356a115cdf7 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 18:00:27 -0500 Subject: [PATCH 09/41] colorize arrow roulette --- src/p_mobj.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index ba0a0c113..f6ef4ba52 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6832,6 +6832,18 @@ void P_MobjThinker(mobj_t *mobj) P_SetScale(mobj->tracer, (mobj->tracer->destscale = mobj->scale)); } + // Do this in an easy way + if (mobj->target->player->kartstuff[k_itemroulette]) + { + mobj->tracer->color = mobj->target->player->skincolor; + mobj->tracer->colorized = true; + } + else + { + mobj->tracer->color = SKINCOLOR_NONE; + mobj->tracer->colorized = false; + } + if (!(mobj->flags2 & MF2_DONTDRAW)) { const INT32 numberdisplaymin = ((mobj->target->player->kartstuff[k_itemtype] == KITEM_ORBINAUT) ? 5 : 2); From 82988cdb0c52931a9013c841966f6d730747ff5e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 19:49:18 -0500 Subject: [PATCH 10/41] Weaken slightly --- src/k_kart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8fad8a6f0..03030f236 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -853,13 +853,13 @@ static INT32 K_FindUseodds(player_t *player, fixed_t mashed, INT32 pingame, INT3 if (franticitems) // Frantic items make the distances between everyone artifically higher, for crazier items pdis = (15*pdis)/14; if (spbrush) // SPB Rush Mode: It's 2nd place's job to catch-up items and make 1st place's job hell - pdis *= 2; + pdis = (3*pdis)/2; if (pingame < 8) pdis = ((28+(8-pingame))*pdis)/28; if (pingame == 1 && oddsvalid[0]) // Record Attack, or just alone useodds = 0; - else if (pdis <= 0) // (64*14) * 0 = 0 + else if (pdis <= 0) // (64*14) * 0 = 0 useodds = disttable[0]; else if (pdis > distvar * ((12 * distlen) / 14)) // (64*14) * 12 = 10752 useodds = disttable[distlen-1]; From d3fb778a521ccf6ec18c372d07bc68f9576ffa2c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 20:41:17 -0500 Subject: [PATCH 11/41] Keep track of the place SPB is following This makes it so that if the SPB'd person is passed, then the person who's getting SPB'd won't get the increased item odds for the weird feedback loop. --- src/dehacked.c | 4 ++-- src/doomstat.h | 2 +- src/g_game.c | 2 +- src/k_kart.c | 6 ++---- src/p_enemy.c | 6 ++++++ src/p_mobj.c | 3 +-- src/p_saveg.c | 4 ++-- src/p_setup.c | 2 +- src/p_user.c | 2 +- 9 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index c1195849e..95cd30a24 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9773,8 +9773,8 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"thwompsactive")) { lua_pushboolean(L, thwompsactive); return 1; - } else if (fastcmp(word,"spbexists")) { - lua_pushboolean(L, spbexists); + } else if (fastcmp(word,"spbplace")) { + lua_pushinteger(L, spbplace); return 1; } diff --git a/src/doomstat.h b/src/doomstat.h index aa2ebe311..a002bb34d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -461,7 +461,7 @@ extern tic_t indirectitemcooldown; extern tic_t mapreset; extern UINT8 nospectategrief; extern boolean thwompsactive; -extern boolean spbexists; +extern SINT8 spbplace; extern boolean legitimateexit; extern boolean comebackshowninfo; diff --git a/src/g_game.c b/src/g_game.c index cba9d26ce..d44ad266e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -267,7 +267,7 @@ tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any othe tic_t mapreset; // Map reset delay when enough players have joined an empty game UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing boolean thwompsactive; // Thwomps activate on lap 2 -boolean spbexists; // SPB exists, give 2nd place better items +SINT8 spbplace; // SPB exists, give the person behind better items // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? diff --git a/src/k_kart.c b/src/k_kart.c index 03030f236..8b2e62bd7 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -583,8 +583,6 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) player->kartstuff[k_itemamount] = 2; break; case KITEM_SPB: - spbexists = true; - /* FALLTHRU */ case KITEM_SHRINK: // Indirect items indirectitemcooldown = 30*TICRATE; /* FALLTHRU */ @@ -988,7 +986,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) spawnchance[i] = 0; // Split into another function for a debug function below - useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (player->kartstuff[k_position] == 2 && spbexists)); + useodds = K_FindUseodds(player, mashed, pingame, bestbumper, (spbplace != -1 && player->kartstuff[k_position] == spbplace+1)); #define SETITEMRESULT(itemnum) \ for (chance = 0; chance < K_KartGetItemOdds(useodds, itemnum, mashed); chance++) \ @@ -7944,7 +7942,7 @@ static void K_drawDistributionDebugger(void) bestbumper = players[i].kartstuff[k_bumper]; } - useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (stplyr->kartstuff[k_position] == 2 && spbexists)); + useodds = K_FindUseodds(stplyr, 0, pingame, bestbumper, (spbplace != -1 && stplyr->kartstuff[k_position] == spbplace+1)); for (i = 1; i < NUMKARTRESULTS; i++) { diff --git a/src/p_enemy.c b/src/p_enemy.c index b81f1ea9a..d8735d9bb 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8354,6 +8354,7 @@ void A_SPBChase(mobj_t *actor) if (actor->threshold) // Just fired, go straight. { actor->lastlook = -1; + spbplace = -1; P_InstaThrust(actor, actor->angle, wspeed); return; } @@ -8382,6 +8383,8 @@ void A_SPBChase(mobj_t *actor) actor->extravalue2 = 7*TICRATE; else if (actor->extravalue2-- <= 0) actor->extravalue1 = 0; // back to SEEKING + + spbplace = actor->tracer->player->kartstuff[k_position]; } // Play the intimidating gurgle @@ -8466,6 +8469,8 @@ void A_SPBChase(mobj_t *actor) else if (actor->extravalue1 == 2) // MODE: WAIT... { actor->momx = actor->momy = actor->momz = 0; // Stoooop + spbplace = -1; + if (actor->extravalue2-- <= 0) { if (actor->lastlook != -1 && playeringame[actor->lastlook] && players[actor->lastlook].mo) @@ -8482,6 +8487,7 @@ void A_SPBChase(mobj_t *actor) else // MODE: SEEKING { actor->lastlook = -1; // Just make sure this is reset + spbplace = -1; // Find the player with the best rank for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_mobj.c b/src/p_mobj.c index f6ef4ba52..7c6987a7d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8167,7 +8167,6 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_SPB: indirectitemcooldown = 30*TICRATE; - spbexists = true; /* FALLTHRU */ case MT_BALLHOG: P_SpawnGhostMobj(mobj)->fuse = 3; @@ -10392,7 +10391,7 @@ void P_RemoveMobj(mobj_t *mobj) P_RemoveShadow(mobj); if (mobj->type == MT_SPB) - spbexists = false; + spbplace = -1; mobj->health = 0; // Just because diff --git a/src/p_saveg.c b/src/p_saveg.c index 447310006..e702d460f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3287,7 +3287,7 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, mapreset); WRITEUINT8(save_p, nospectategrief); WRITEUINT8(save_p, thwompsactive); - WRITEUINT8(save_p, spbexists); + WRITESINT8(save_p, spbplace); // Is it paused? if (paused) @@ -3394,7 +3394,7 @@ static inline boolean P_NetUnArchiveMisc(void) mapreset = READUINT32(save_p); nospectategrief = READUINT8(save_p); thwompsactive = (boolean)READUINT8(save_p); - spbexists = (boolean)READUINT8(save_p); + spbplace = READSINT8(save_p); // Is it paused? if (READUINT8(save_p) == 0x2f) diff --git a/src/p_setup.c b/src/p_setup.c index fa8e263c6..bd3856d6e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3046,7 +3046,7 @@ boolean P_SetupLevel(boolean skipprecip) mapreset = 0; nospectategrief = 0; thwompsactive = false; - spbexists = false; + spbplace = -1; // clear special respawning que iquehead = iquetail = 0; diff --git a/src/p_user.c b/src/p_user.c index d17a7c801..7b4ef789c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7759,7 +7759,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) if (mo->type == MT_SPB) // If you destroy a SPB, you don't get the luxury of a cooldown. { - spbexists = false; + spbplace = -1; indirectitemcooldown = 0; } From 0a303dfde930bb58a13d162a3aa810be7eeb0f88 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 20:48:21 -0500 Subject: [PATCH 12/41] Make absolute sure spbplace is set in the right places --- src/p_enemy.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index d8735d9bb..6e8668b8a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8469,7 +8469,11 @@ void A_SPBChase(mobj_t *actor) else if (actor->extravalue1 == 2) // MODE: WAIT... { actor->momx = actor->momy = actor->momz = 0; // Stoooop - spbplace = -1; + + if (actor->lastlook == -1) + spbplace = -1; + else + spbplace = players[actor->lastlook].kartstuff[k_position]; if (actor->extravalue2-- <= 0) { @@ -8487,7 +8491,6 @@ void A_SPBChase(mobj_t *actor) else // MODE: SEEKING { actor->lastlook = -1; // Just make sure this is reset - spbplace = -1; // Find the player with the best rank for (i = 0; i < MAXPLAYERS; i++) @@ -8511,6 +8514,8 @@ void A_SPBChase(mobj_t *actor) } } + spbplace = bestrank; // While seeking, it's trying to go for first place. + // No one there? if (player == NULL || !player->mo) { From d5270a8b91e2cc98d90a2ac14f7e6d01da8fc2ed Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 24 Nov 2018 20:59:22 -0500 Subject: [PATCH 13/41] More in-depth countdown calculation Hooooopefully this makes sure time over doesn't happen prematurely at random --- src/p_inter.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index baae2701f..f75bd4d08 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2003,19 +2003,6 @@ boolean P_CheckRacers(void) countdown = countdown2 = 0; return true; } - else if (!countdown) // Check to see if the winners have finished, to set countdown. - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - if (players[i].exiting || K_IsPlayerLosing(&players[i])) // Only start countdown when all winners are declared - continue; - break; - } - if (i == MAXPLAYERS) - countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going! - } if (cv_karteliminatelast.value) { @@ -2046,6 +2033,28 @@ boolean P_CheckRacers(void) } } + if (!countdown) // Check to see if the winners have finished, to set countdown. + { + UINT8 numingame = 0, numexiting = 0; + UINT8 winningpos = 1; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + numingame++; + if (players[i].exiting) + numexiting++; + } + + winningpos = max(1, numingame/2); + if (numingame % 2) // any remainder? + winningpos++; + + if (numexiting >= winningpos) + countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going! + } + return false; } From 2485e25268a214e3f5fd3a4d4d9340c5840a3586 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 02:24:33 -0500 Subject: [PATCH 14/41] Game saves when you use the cheat Because of other G_SaveGameData instances added in the last patch, this cheat can get saved anyway. Since this is just supposed to be convenience for server hosts, we might as well make it work like other console Kart racers and just make it save anyway! --- src/m_cheat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index e57a85ae2..3992147c1 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -97,7 +97,7 @@ static UINT8 cheatf_warp(void) if (success) { - G_SetGameModified(false); + G_SaveGameData(true); //G_SetGameModified(false); S_StartSound(0, sfx_kc42); } From 4edcc94c080cd15b8baf2c285a63986cef69bc01 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 02:30:08 -0500 Subject: [PATCH 15/41] Unlock all secrets for dedicated If wanted we can just add dedicated checks to Encore & Hard Mode, but I figured this would be quicker and more future-proof. --- src/m_cond.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/m_cond.c b/src/m_cond.c index 5a9d4f2a8..9c56124e3 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -535,6 +535,12 @@ UINT8 M_AnySecretUnlocked(void) UINT8 M_SecretUnlocked(INT32 type) { INT32 i; + +#if 1 + if (dedicated) + return true; +#endif + for (i = 0; i < MAXUNLOCKABLES; ++i) { if (unlockables[i].type == type && unlockables[i].unlocked) From 4acadbf66f1c05ea807eb0c308ace32d3d0fac16 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 05:43:17 -0500 Subject: [PATCH 16/41] Mess with display offset for some Battle objects --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index fa241ad72..7f29b157e 100644 --- a/src/info.c +++ b/src/info.c @@ -17282,7 +17282,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // speed 36*FRACUNIT, // radius 37*FRACUNIT, // height - 0, // display offset + -2, // display offset 16, // mass 0, // damage sfx_None, // activesound @@ -17309,7 +17309,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // speed 36*FRACUNIT, // radius 37*FRACUNIT, // height - 0, // display offset + -2, // display offset 16, // mass 0, // damage sfx_None, // activesound @@ -17363,7 +17363,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // speed 8*FRACUNIT, // radius 16*FRACUNIT, // height - 0, // display offset + -1, // display offset 0, // mass 0, // damage sfx_None, // activesound From 5af6c33ca6ba64ff6e32928d47a37dbed405f0cc Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 07:10:45 -0500 Subject: [PATCH 17/41] Quick patch-over to dedicated server husk bug Whenever a 16th player would join, it would wrap around and overwrite the dedicated server ghost host player. This is possibly a bug in vanilla as well, but it'd only occur at 32 players so it's no wonder no one figured that out. :V As a quick patch, I just capped cv_maxplayers to MAXPLAYERS-1 in dedicated servers only. To fix this for real, we'd need to give dedicated servers their own player & node instead of clumping in into the start of the normal ones. --- src/d_clisrv.c | 29 +++++++++++++++++------------ src/d_netcmd.c | 2 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d35039713..11be98177 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1304,7 +1304,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); - netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; + netbuffer->u.serverinfo.maxplayer = (UINT8)(min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value)); netbuffer->u.serverinfo.gametype = (UINT8)(G_BattleGametype() ? VANILLA_GT_MATCH : VANILLA_GT_RACE); // SRB2Kart: Vanilla's gametype constants for MS support netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); @@ -3343,6 +3343,7 @@ static boolean SV_AddWaitingPlayers(void) UINT8 newplayernum = 0; // What is the reason for this? Why can't newplayernum always be 0? + // Sal: Because the dedicated player is stupidly forced into players[0]..... if (dedicated) newplayernum = 1; @@ -3529,6 +3530,11 @@ static size_t TotalTextCmdPerTic(tic_t tic) */ static void HandleConnect(SINT8 node) { + // Sal: Dedicated mode is INCREDIBLY hacked together. + // If a server filled out, then it'd overwrite the host and turn everyone into weird husks..... + // It's too much effort to legimately fix right now. Just prevent it from reaching that state. + UINT8 maxplayers = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxplayers.value); + if (bannednode && bannednode[node]) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); else if (netbuffer->u.clientcfg.version != VERSION @@ -3536,10 +3542,10 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); else if (!cv_allownewplayer.value && node) SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); - else if (D_NumPlayers() >= cv_maxplayers.value) - SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); - else if (netgame && D_NumPlayers() + netbuffer->u.clientcfg.localplayers > cv_maxplayers.value) - SV_SendRefuse(node, va(M_GetText("Number of local players\nwould exceed maximum: %d"), cv_maxplayers.value)); + else if (D_NumPlayers() >= maxplayers) + SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), maxplayers)); + else if (netgame && D_NumPlayers() + netbuffer->u.clientcfg.localplayers > maxplayers) + SV_SendRefuse(node, va(M_GetText("Number of local players\nwould exceed maximum: %d"), maxplayers)); else if (netgame && netbuffer->u.clientcfg.localplayers > 4) // Hacked client? SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? @@ -4557,31 +4563,30 @@ static void CL_SendClientCmd(void) } else if (gamestate != GS_NULL) { + packetsize = sizeof (clientcmd_pak); G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); if (splitscreen || botingame) // Send a special packet with 2 cmd for splitscreen { netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD); + packetsize = sizeof (client2cmd_pak); G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); + if (splitscreen > 1) { netbuffer->packettype = (mis ? PT_CLIENT3MIS : PT_CLIENT3CMD); + packetsize = sizeof (client3cmd_pak); G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds3, 1); + if (splitscreen > 2) { netbuffer->packettype = (mis ? PT_CLIENT4MIS : PT_CLIENT4CMD); - G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds4, 1); packetsize = sizeof (client4cmd_pak); + G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds4, 1); } - else - packetsize = sizeof (client3cmd_pak); } - else - packetsize = sizeof (client2cmd_pak); } - else - packetsize = sizeof (clientcmd_pak); HSendPacket(servernode, false, 0, packetsize); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8427b6732..9eafc73e1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1206,7 +1206,7 @@ static void ForceAllSkins(INT32 forcedskin) SetPlayerSkinByNum(i, forcedskin); - // If it's me (or my brother), set appropriate skin value in cv_skin/cv_skin2 + // If it's me (or my brother (or my sister (or my trusty pet dog))), set appropriate skin value in cv_skin if (!dedicated) // But don't do this for dedicated servers, of course. { if (i == consoleplayer) From 3cbf6962d3e16f1916e0eca8bd12b2118d8ec3d8 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 25 Nov 2018 13:30:43 +0000 Subject: [PATCH 18/41] Sound volume distance indication now scales with mapheader scale. --- src/k_kart.c | 2 ++ src/s_sound.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4403dd4a6..a63b72300 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3966,6 +3966,8 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd) dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x, player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2; + dist = FixedDiv(dist, mapheaderinfo[gamemap-1]->mobj_scale); + if (dist > 1536<mobj_scale); // approx_dist } // From 151404f33fd7e92a062fe9ae29f70e5e653021ab Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 25 Nov 2018 13:48:46 +0000 Subject: [PATCH 19/41] Update HUD anim counters when dead. * Split out the HUD-related counters from K_KartPlayerThink() into their own function. * Called this function in P_DeathThink(). --- src/k_kart.c | 79 ++++++++++++++++++++++++++++------------------------ src/k_kart.h | 1 + src/p_user.c | 10 ++++++- 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4403dd4a6..3f3f80ee4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4023,6 +4023,47 @@ static void K_UpdateInvincibilitySounds(player_t *player) #undef STOPTHIS } +void K_KartPlayerHUDUpdate(player_t *player) +{ + if (player->kartstuff[k_lapanimation]) + player->kartstuff[k_lapanimation]--; + + if (player->kartstuff[k_yougotem]) + player->kartstuff[k_yougotem]--; + + if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) + { + if (player->exiting) + { + if (player->exiting < 6*TICRATE) + player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; + else if (player->exiting == 6*TICRATE) + player->kartstuff[k_cardanimation] = 0; + else if (player->kartstuff[k_cardanimation] < 2*TICRATE) + player->kartstuff[k_cardanimation]++; + } + else + { + if (player->kartstuff[k_comebacktimer] < 6*TICRATE) + player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1; + else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) + player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; + } + + if (player->kartstuff[k_cardanimation] > 164) + player->kartstuff[k_cardanimation] = 164; + if (player->kartstuff[k_cardanimation] < 0) + player->kartstuff[k_cardanimation] = 0; + } + else if (G_RaceGametype() && player->exiting) + { + if (player->kartstuff[k_cardanimation] < 2*TICRATE) + player->kartstuff[k_cardanimation]++; + } + else + player->kartstuff[k_cardanimation] = 0; +} + /** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c \param player player object passed from P_PlayerThink @@ -4233,43 +4274,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_justbumped]) player->kartstuff[k_justbumped]--; - if (player->kartstuff[k_lapanimation]) - player->kartstuff[k_lapanimation]--; - - if (player->kartstuff[k_yougotem]) - player->kartstuff[k_yougotem]--; - - if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) - { - if (player->exiting) - { - if (player->exiting < 6*TICRATE) - player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; - else if (player->exiting == 6*TICRATE) - player->kartstuff[k_cardanimation] = 0; - else if (player->kartstuff[k_cardanimation] < 2*TICRATE) - player->kartstuff[k_cardanimation]++; - } - else - { - if (player->kartstuff[k_comebacktimer] < 6*TICRATE) - player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1; - else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) - player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; - } - - if (player->kartstuff[k_cardanimation] > 164) - player->kartstuff[k_cardanimation] = 164; - if (player->kartstuff[k_cardanimation] < 0) - player->kartstuff[k_cardanimation] = 0; - } - else if (G_RaceGametype() && player->exiting) - { - if (player->kartstuff[k_cardanimation] < 2*TICRATE) - player->kartstuff[k_cardanimation]++; - } - else - player->kartstuff[k_cardanimation] = 0; + K_KartPlayerHUDUpdate(player); if (player->kartstuff[k_voices]) player->kartstuff[k_voices]--; diff --git a/src/k_kart.h b/src/k_kart.h index 8f8cd100a..3edbf0bd7 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -24,6 +24,7 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master); void K_RespawnChecker(player_t *player); void K_KartMoveAnimation(player_t *player); +void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); diff --git a/src/p_user.c b/src/p_user.c index b2849c857..4f8b42347 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7946,6 +7946,8 @@ static void P_DeathThink(player_t *player) else player->kartstuff[k_timeovercam] = 0; + K_KartPlayerHUDUpdate(player); + if (player->deadtimer < INT32_MAX) player->deadtimer++; @@ -7984,6 +7986,9 @@ static void P_DeathThink(player_t *player) if (!player->mo) return; + player->mo->colorized = false; + player->mo->color = player->skincolor; + P_CalcHeight(player); } @@ -9098,7 +9103,10 @@ void P_PlayerThink(player_t *player) if (player->playerstate == PST_DEAD) { - player->mo->flags2 &= ~MF2_SHADOW; + if (player->spectator) + player->mo->flags2 |= MF2_SHADOW; + else + player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); return; From fa24e37526b0b43173ad30746a520eb0854ee524 Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 26 Nov 2018 00:17:34 +0000 Subject: [PATCH 20/41] Rotate All MD2s to match their standing slopes Needs to be tested in gravity flip Also flips the normal on linedef based slopes so that it's facing the correct direction Also makes it so slopelaunch doesn't always remove the standingslope (going down some slopes would cause it to be constantly unset and reset) --- src/hardware/hw_defs.h | 2 +- src/hardware/hw_main.c | 2 ++ src/hardware/hw_md2.c | 14 +++++++++++++- src/hardware/r_opengl/r_opengl.c | 3 ++- src/p_map.c | 2 +- src/p_slopes.c | 6 +++--- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 2d3468781..ece627d3c 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -104,7 +104,7 @@ typedef struct typedef struct { FLOAT x,y,z; // position - FLOAT anglex,angley; // aimingangle / viewangle + FLOAT anglex,angley,anglez; // aimingangle / viewangle FLOAT scalex,scaley,scalez; FLOAT fovxangle, fovyangle; UINT8 splitscreen; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 68915e97f..894a4a8c1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5968,6 +5968,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) // It should replace all other gr_viewxxx when finished atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + atransform.anglez = 0.0f; if (*type == postimg_flip) atransform.flip = true; @@ -6230,6 +6231,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // It should replace all other gr_viewxxx when finished atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + atransform.anglez = 0.0f; if (*type == postimg_flip) atransform.flip = true; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index c545cb806..2856cada3 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -963,7 +963,7 @@ spritemd2found: // (See this same define in k_kart.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) - + static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { UINT8 i; @@ -1389,6 +1389,18 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.angley = FIXED_TO_FLOAT(anglef); } p.anglex = 0.0f; + p.anglez = 0.0f; + if (spr->mobj->standingslope) + { + fixed_t tempz = spr->mobj->standingslope->normal.z; + fixed_t tempy = spr->mobj->standingslope->normal.y; + fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); + p.anglez = FIXED_TO_FLOAT(tempangle); + tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); + p.anglex = FIXED_TO_FLOAT(tempangle); + } + color[0] = Surf.FlatColor.s.red; color[1] = Surf.FlatColor.s.green; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index ce5431585..5f2cd0322 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1962,8 +1962,9 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, pglTranslatef(pos->x, pos->z, pos->y); if (flipped) scaley = -scaley; - pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); + pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f); + pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); val = *gl_cmd_buffer++; diff --git a/src/p_map.c b/src/p_map.c index ba6e64540..b289b3157 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1423,7 +1423,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person. && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) { - + if (tmthing->scale > thing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) // SRB2kart - Handle squishes first! K_SquishPlayer(thing->player, tmthing); else if (thing->scale > tmthing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) diff --git a/src/p_slopes.c b/src/p_slopes.c index 9513cac05..ea85f797f 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -31,8 +31,8 @@ static UINT16 slopecount = 0; // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); - slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); - slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); + slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.x); + slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), -slope->d.y); } // With a vertex slope that has its vertices set, configure relevant slope info @@ -812,10 +812,10 @@ void P_SlopeLaunch(mobj_t *mo) mo->momy = slopemom.y; mo->momz = slopemom.z; #endif - } //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; + } } // Function to help handle landing on slopes From e4e70835c6061b51074b6f471cd4423f886531ac Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 20:14:01 -0500 Subject: [PATCH 21/41] Shrink no longer causes old-style wipeout, getting squished reduces the timer on it. Maybe this might help some of the desyncing, too! Mainly done for gameplay reasons, though :p --- src/k_kart.c | 46 ++++++++++++++-------------------------------- src/p_mobj.c | 2 +- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 8b2e62bd7..c7e9375c2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -584,7 +584,7 @@ static void K_KartGetItemResult(player_t *player, SINT8 getitem) break; case KITEM_SPB: case KITEM_SHRINK: // Indirect items - indirectitemcooldown = 30*TICRATE; + indirectitemcooldown = 20*TICRATE; /* FALLTHRU */ default: if (getitem <= 0 || getitem >= NUMKARTRESULTS) // Sad (Fallback) @@ -2027,6 +2027,14 @@ void K_SquishPlayer(player_t *player, mobj_t *source) player->kartstuff[k_squishedtimer] = TICRATE; + // Reduce Shrink timer + if (player->kartstuff[k_growshrinktimer] < 0) + { + player->kartstuff[k_growshrinktimer] += TICRATE; + if (player->kartstuff[k_growshrinktimer] > -2) + player->kartstuff[k_growshrinktimer] = -2; + } + player->powers[pw_flashing] = K_GetKartFlashing(player); player->mo->flags |= MF_NOCLIP; @@ -3182,44 +3190,17 @@ static void K_DoShrink(player_t *user) continue; if (players[i].kartstuff[k_position] < user->kartstuff[k_position]) { - //P_FlashPal(&players[i], PAL_NUKE, 10); - - if (!players[i].kartstuff[k_invincibilitytimer] // Don't hit while invulnerable! + // Don't hit while invulnerable! + if (!players[i].kartstuff[k_invincibilitytimer] && players[i].kartstuff[k_growshrinktimer] <= 0 && !players[i].kartstuff[k_hyudorotimer]) { // Start shrinking! + K_DropItems(&players[i]); players[i].mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE; players[i].mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8; if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot) players[i].mo->destscale = 6*players[i].mo->destscale/8; - - if (!players[i].powers[pw_flashing] && !players[i].kartstuff[k_squishedtimer] && !players[i].kartstuff[k_spinouttimer]) - P_PlayerRingBurst(&players[i], 5); - - // Wipeout - K_DropItems(&players[i]); - K_SpinPlayer(&players[i], user->mo, 1, false); - - // P_RingDamage - P_DoPlayerPain(&players[i], user->mo, user->mo); - P_ForceFeed(&players[i], 40, 10, TICRATE, 40 + min((players[i].mo->health-1), 100)*2); - P_PlayRinglossSound(players[i].mo); // Ringledingle! - - players[i].mo->momx = players[i].mo->momy = 0; - if (P_IsLocalPlayer(&players[i])) - { - quake.intensity = 32*FRACUNIT; - quake.time = 5; - } - - players[i].kartstuff[k_sneakertimer] = 0; - players[i].kartstuff[k_driftboost] = 0; - - players[i].kartstuff[k_drift] = 0; - players[i].kartstuff[k_driftcharge] = 0; - players[i].kartstuff[k_pogospring] = 0; - players[i].kartstuff[k_growshrinktimer] -= (200+(40*(MAXPLAYERS-players[i].kartstuff[k_position]))); } @@ -3227,6 +3208,7 @@ static void K_DoShrink(player_t *user) if (players[i].kartstuff[k_growshrinktimer] > 0) players[i].kartstuff[k_growshrinktimer] = 2; + //P_FlashPal(&players[i], PAL_NUKE, 10); S_StartSound(players[i].mo, sfx_kc59); } } @@ -5278,7 +5260,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) - indirectitemcooldown = 30*TICRATE; + indirectitemcooldown = 20*TICRATE; if (player->kartstuff[k_hyudorotimer] > 0) { diff --git a/src/p_mobj.c b/src/p_mobj.c index 7c6987a7d..61781aeec 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8166,7 +8166,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->threshold--; break; case MT_SPB: - indirectitemcooldown = 30*TICRATE; + indirectitemcooldown = 20*TICRATE; /* FALLTHRU */ case MT_BALLHOG: P_SpawnGhostMobj(mobj)->fuse = 3; From 49d653adeaad4d6633fb6cc7860288d4f52d21d9 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 20:23:09 -0500 Subject: [PATCH 22/41] Make the WAIT phase work better with SPB rush --- src/p_enemy.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 6e8668b8a..e77e82820 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8470,22 +8470,22 @@ void A_SPBChase(mobj_t *actor) { actor->momx = actor->momy = actor->momz = 0; // Stoooop - if (actor->lastlook == -1) - spbplace = -1; - else - spbplace = players[actor->lastlook].kartstuff[k_position]; - - if (actor->extravalue2-- <= 0) + if (actor->lastlook != -1 && playeringame[actor->lastlook] && players[actor->lastlook].mo) { - if (actor->lastlook != -1 && playeringame[actor->lastlook] && players[actor->lastlook].mo) + spbplace = players[actor->lastlook].kartstuff[k_position]; + if (actor->extravalue2-- <= 0) { P_SetTarget(&actor->tracer, players[actor->lastlook].mo); actor->extravalue1 = 1; // TARGETING actor->extravalue2 = 7*TICRATE; + actor->extravalue2 = 0; } - else - actor->extravalue1 = 0; // SEEKING + } + else + { + actor->extravalue1 = 0; // SEEKING actor->extravalue2 = 0; + spbplace = -1; } } else // MODE: SEEKING From 2f79e6514426daa16852ae32f68bafaa10436e71 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 20:24:47 -0500 Subject: [PATCH 23/41] Make sure spbplace is set better during SEEKING --- src/p_enemy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index e77e82820..dd68a02c1 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8514,8 +8514,6 @@ void A_SPBChase(mobj_t *actor) } } - spbplace = bestrank; // While seeking, it's trying to go for first place. - // No one there? if (player == NULL || !player->mo) { @@ -8531,11 +8529,13 @@ void A_SPBChase(mobj_t *actor) #else actor->momx = actor->momy = actor->momz = 0; #endif + spbplace = -1; return; } // Found someone, now get close enough to initiate the slaughter... P_SetTarget(&actor->tracer, player->mo); + spbplace = bestrank; dist = P_AproxDistance(P_AproxDistance(actor->x-actor->tracer->x, actor->y-actor->tracer->y), actor->z-actor->tracer->z); From 1419eef5db2a50a5efb5bea10b59cf788b0bc0f6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 02:17:14 -0500 Subject: [PATCH 24/41] Karma fireworks Additionally: - FZ boom no longer has that weird smoke bit before it spawns the smoke column - Item blinking color is brighter --- src/dehacked.c | 8 ++ src/info.c | 193 +++++++++++++++++++++++++++++-------------------- src/info.h | 10 +++ src/k_kart.c | 2 +- src/p_inter.c | 11 ++- src/p_mobj.c | 39 ++++++---- 6 files changed, 165 insertions(+), 98 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 95cd30a24..4380772a5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7092,6 +7092,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_LIZARDMAN", "S_LIONMAN", + "S_KARMAFIREWORK1", + "S_KARMAFIREWORK2", + "S_KARMAFIREWORK3", + "S_KARMAFIREWORK4", + "S_KARMAFIREWORKTRAIL", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -7877,6 +7883,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_LIZARDMAN", "MT_LIONMAN", + "MT_KARMAFIREWORK", + #ifdef SEENAMES "MT_NAMECHECK", #endif diff --git a/src/info.c b/src/info.c index 7f29b157e..c26b83bc2 100644 --- a/src/info.c +++ b/src/info.c @@ -68,8 +68,8 @@ char sprnames[NUMSPRITES + 1][5] = "FROG","CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB", "CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS","ZTCH", "MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH","BFRT", - "OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","XMS4", - "XMS5","VIEW" + "OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","FWRK", + "XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3293,100 +3293,106 @@ state_t states[NUMSTATES] = {SPR_ICEB, 3, 10, {NULL}, 0, 0, S_NULL}, // S_SMK_ICEBLOCK_DEBRIS2 // Ezo's maps - {SPR_CNDL, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE2}, // S_BLUEFIRE1 - {SPR_CNDL, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE3}, // S_BLUEFIRE2 - {SPR_CNDL, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE4}, // S_BLUEFIRE3 - {SPR_CNDL, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE1}, // S_BLUEFIRE4 + {SPR_CNDL, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE2}, // S_BLUEFIRE1 + {SPR_CNDL, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE3}, // S_BLUEFIRE2 + {SPR_CNDL, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE4}, // S_BLUEFIRE3 + {SPR_CNDL, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_BLUEFIRE1}, // S_BLUEFIRE4 - {SPR_CNDL, 4|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE2}, // S_GREENFIRE1 - {SPR_CNDL, 5|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE3}, // S_GREENFIRE2 - {SPR_CNDL, 6|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE4}, // S_GREENFIRE3 - {SPR_CNDL, 7|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE1}, // S_GREENFIRE4 + {SPR_CNDL, 4|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE2}, // S_GREENFIRE1 + {SPR_CNDL, 5|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE3}, // S_GREENFIRE2 + {SPR_CNDL, 6|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE4}, // S_GREENFIRE3 + {SPR_CNDL, 7|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_GREENFIRE1}, // S_GREENFIRE4 - {SPR_CHES, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REGALCHEST - {SPR_CHIM, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CHIMERASTATUE - {SPR_DRGN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_DRAGONSTATUE - {SPR_LZMN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LIZARDMANSTATUE - {SPR_PGSS, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PEGASUSSTATUE + {SPR_CHES, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REGALCHEST + {SPR_CHIM, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_CHIMERASTATUE + {SPR_DRGN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_DRAGONSTATUE + {SPR_LZMN, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LIZARDMANSTATUE + {SPR_PGSS, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_PEGASUSSTATUE - {SPR_ZTCH, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE2}, // S_ZELDAFIRE1 - {SPR_ZTCH, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE3}, // S_ZELDAFIRE2 - {SPR_ZTCH, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE4}, // S_ZELDAFIRE3 - {SPR_ZTCH, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE1}, // S_ZELDAFIRE4 + {SPR_ZTCH, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE2}, // S_ZELDAFIRE1 + {SPR_ZTCH, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE3}, // S_ZELDAFIRE2 + {SPR_ZTCH, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE4}, // S_ZELDAFIRE3 + {SPR_ZTCH, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_ZELDAFIRE1}, // S_ZELDAFIRE4 - {SPR_DOCH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBARETHING - {SPR_DUCK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBAREDUCK - {SPR_GTRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBARETREE + {SPR_DOCH, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBARETHING + {SPR_DUCK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBAREDUCK + {SPR_GTRE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GANBARETREE - {SPR_MKMA, 1, 2, {A_Look}, (256<<16)|1, 0, S_MONOIDLE}, // S_MONOIDLE - {SPR_MKMA, 0, 3, {A_Chase}, 3, 0, S_MONOCHASE2}, // S_MONOCHASE1 - {SPR_MKMA, 1, 3, {A_Chase}, 3, 0, S_MONOCHASE3}, // S_MONOCHASE2 - {SPR_MKMA, 2, 3, {A_Chase}, 3, 0, S_MONOCHASE4}, // S_MONOCHASE3 - {SPR_MKMA, 3, 3, {A_Chase}, 3, 0, S_MONOCHASE1}, // S_MONOCHASE4 - {SPR_MKMP, 0, 24, {A_Pain}, 3, 0, S_MONOIDLE}, // S_MONOPAIN + {SPR_MKMA, 1, 2, {A_Look}, (256<<16)|1, 0, S_MONOIDLE}, // S_MONOIDLE + {SPR_MKMA, 0, 3, {A_Chase}, 3, 0, S_MONOCHASE2}, // S_MONOCHASE1 + {SPR_MKMA, 1, 3, {A_Chase}, 3, 0, S_MONOCHASE3}, // S_MONOCHASE2 + {SPR_MKMA, 2, 3, {A_Chase}, 3, 0, S_MONOCHASE4}, // S_MONOCHASE3 + {SPR_MKMA, 3, 3, {A_Chase}, 3, 0, S_MONOCHASE1}, // S_MONOCHASE4 + {SPR_MKMP, 0, 24, {A_Pain}, 3, 0, S_MONOIDLE}, // S_MONOPAIN - {SPR_RTCH, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE2}, // S_REDZELDAFIRE1 - {SPR_RTCH, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE3}, // S_REDZELDAFIRE2 - {SPR_RTCH, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE4}, // S_REDZELDAFIRE3 - {SPR_RTCH, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE1}, // S_REDZELDAFIRE4 + {SPR_RTCH, FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE2}, // S_REDZELDAFIRE1 + {SPR_RTCH, 1|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE3}, // S_REDZELDAFIRE2 + {SPR_RTCH, 2|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE4}, // S_REDZELDAFIRE3 + {SPR_RTCH, 3|FF_FULLBRIGHT|FF_TRANS50, 3, {NULL}, 0, 0, S_REDZELDAFIRE1}, // S_REDZELDAFIRE4 - {SPR_BOWL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BOWLINGPIN - {SPR_BOWH, 0, 4, {A_BunnyHop}, 5, 20, S_BOWLINGHIT2}, // S_BOWLINGHIT1 - {SPR_BOWH, 1, 2, {NULL}, 0, 0, S_BOWLINGHIT3}, // S_BOWLINGHIT2 - {SPR_BOWH, 2, 2, {NULL}, 0, 0, S_BOWLINGHIT4}, // S_BOWLINGHIT3 - {SPR_BOWH, 3, 2, {NULL}, 0, 0, S_NULL}, // S_BOWLINGHIT4 + {SPR_BOWL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BOWLINGPIN + {SPR_BOWH, 0, 4, {A_BunnyHop}, 5, 20, S_BOWLINGHIT2}, // S_BOWLINGHIT1 + {SPR_BOWH, 1, 2, {NULL}, 0, 0, S_BOWLINGHIT3}, // S_BOWLINGHIT2 + {SPR_BOWH, 2, 2, {NULL}, 0, 0, S_BOWLINGHIT4}, // S_BOWLINGHIT3 + {SPR_BOWH, 3, 2, {NULL}, 0, 0, S_NULL}, // S_BOWLINGHIT4 - {SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDTOAD - {SPR_TOAH, 0, 4, {A_BunnyHop}, 10, 60, S_TOADHIT2}, // S_TOADHIT1 - {SPR_TOAH, 1, 3, {NULL}, 0, 0, S_TOADHIT3}, // S_TOADHIT2 - {SPR_TOAH, 2, 3, {NULL}, 0, 0, S_TOADHIT4}, // S_TOADHIT3 - {SPR_TOAH, 3, 3, {NULL}, 0, 0, S_EBARREL18}, // S_TOADHIT4 + {SPR_TOAD, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ARIDTOAD + {SPR_TOAH, 0, 4, {A_BunnyHop}, 10, 60, S_TOADHIT2}, // S_TOADHIT1 + {SPR_TOAH, 1, 3, {NULL}, 0, 0, S_TOADHIT3}, // S_TOADHIT2 + {SPR_TOAH, 2, 3, {NULL}, 0, 0, S_TOADHIT4}, // S_TOADHIT3 + {SPR_TOAH, 3, 3, {NULL}, 0, 0, S_EBARREL18}, // S_TOADHIT4 - {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE - {SPR_BRRR, 0, 4, {NULL}, 0, 0, S_EBARREL2}, // S_EBARREL1 - {SPR_BRRR, 1, 4, {NULL}, 0, 0, S_EBARREL3}, // S_EBARREL2 - {SPR_BRRR, 2, 4, {NULL}, 0, 0, S_EBARREL4}, // S_EBARREL3 - {SPR_BRRR, 3, 4, {NULL}, 0, 0, S_EBARREL5}, // S_EBARREL4 - {SPR_BRRR, 4, 4, {NULL}, 0, 0, S_EBARREL6}, // S_EBARREL5 - {SPR_BRRR, 5, 4, {NULL}, 0, 0, S_EBARREL7}, // S_EBARREL6 - {SPR_BRRR, 6, 4, {NULL}, 0, 0, S_EBARREL8}, // S_EBARREL7 - {SPR_BRRR, 7, 4, {NULL}, 0, 0, S_EBARREL9}, // S_EBARREL8 - {SPR_BRRR, 8, 4, {NULL}, 0, 0, S_EBARREL10}, // S_EBARREL9 - {SPR_BRRR, 9, 4, {NULL}, 0, 0, S_EBARREL11}, // S_EBARREL10 - {SPR_BRRR, 10, 4, {NULL}, 0, 0, S_EBARREL12}, // S_EBARREL11 - {SPR_BRRR, 11, 4, {NULL}, 0, 0, S_EBARREL13}, // S_EBARREL12 - {SPR_BRRR, 12, 4, {NULL}, 0, 0, S_EBARREL14}, // S_EBARREL13 - {SPR_BRRR, 13, 4, {NULL}, 0, 0, S_EBARREL15}, // S_EBARREL14 - {SPR_BRRR, 14, 4, {NULL}, 0, 0, S_EBARREL16}, // S_EBARREL15 - {SPR_BRRR, 15, 4, {NULL}, 0, 0, S_EBARREL17}, // S_EBARREL16 - {SPR_BRRR, 16, 4, {NULL}, 0, 0, S_EBARREL18}, // S_EBARREL17 - {SPR_BRRR, 16, 0, {A_MineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_EBARREL18 + {SPR_BRRL, 0, 1, {A_Look}, (96<<16)|1, 0, S_EBARRELIDLE}, // S_EBARRELIDLE + {SPR_BRRR, 0, 4, {NULL}, 0, 0, S_EBARREL2}, // S_EBARREL1 + {SPR_BRRR, 1, 4, {NULL}, 0, 0, S_EBARREL3}, // S_EBARREL2 + {SPR_BRRR, 2, 4, {NULL}, 0, 0, S_EBARREL4}, // S_EBARREL3 + {SPR_BRRR, 3, 4, {NULL}, 0, 0, S_EBARREL5}, // S_EBARREL4 + {SPR_BRRR, 4, 4, {NULL}, 0, 0, S_EBARREL6}, // S_EBARREL5 + {SPR_BRRR, 5, 4, {NULL}, 0, 0, S_EBARREL7}, // S_EBARREL6 + {SPR_BRRR, 6, 4, {NULL}, 0, 0, S_EBARREL8}, // S_EBARREL7 + {SPR_BRRR, 7, 4, {NULL}, 0, 0, S_EBARREL9}, // S_EBARREL8 + {SPR_BRRR, 8, 4, {NULL}, 0, 0, S_EBARREL10}, // S_EBARREL9 + {SPR_BRRR, 9, 4, {NULL}, 0, 0, S_EBARREL11}, // S_EBARREL10 + {SPR_BRRR, 10, 4, {NULL}, 0, 0, S_EBARREL12}, // S_EBARREL11 + {SPR_BRRR, 11, 4, {NULL}, 0, 0, S_EBARREL13}, // S_EBARREL12 + {SPR_BRRR, 12, 4, {NULL}, 0, 0, S_EBARREL14}, // S_EBARREL13 + {SPR_BRRR, 13, 4, {NULL}, 0, 0, S_EBARREL15}, // S_EBARREL14 + {SPR_BRRR, 14, 4, {NULL}, 0, 0, S_EBARREL16}, // S_EBARREL15 + {SPR_BRRR, 15, 4, {NULL}, 0, 0, S_EBARREL17}, // S_EBARREL16 + {SPR_BRRR, 16, 4, {NULL}, 0, 0, S_EBARREL18}, // S_EBARREL17 + {SPR_BRRR, 16, 0, {A_MineExplode}, MT_MINEEXPLOSION, 0, S_NULL}, // S_EBARREL18 - {SPR_HRSE, 0, 230, {A_PlaySeeSound}, 0, 0, S_MERRYHORSE}, // S_MERRYHORSE + {SPR_HRSE, 0, 230, {A_PlaySeeSound}, 0, 0, S_MERRYHORSE}, // S_MERRYHORSE - {SPR_BFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEFRUIT - {SPR_OFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ORANGEFRUIT - {SPR_RFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDFRUIT - {SPR_PFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PINKFRUIT + {SPR_BFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUEFRUIT + {SPR_OFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ORANGEFRUIT + {SPR_RFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDFRUIT + {SPR_PFRT, 0, -1, {NULL}, 0, 0, S_NULL}, // S_PINKFRUIT - {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEA2}, // S_ADVENTURESPIKEA1 - {SPR_ASPK, 0, 50, {A_BunnyHop}, 20, 0, S_ADVENTURESPIKEA1}, // S_ADVENTURESPIKEA2 - {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEB2}, // S_ADVENTURESPIKEB1 - {SPR_ASPK, 0, 35, {A_BunnyHop}, 15, 0, S_ADVENTURESPIKEB1}, // S_ADVENTURESPIKEB2 - {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEC2}, // S_ADVENTURESPIKEC1 - {SPR_ASPK, 0, 65, {A_BunnyHop}, 25, 0, S_ADVENTURESPIKEC1}, // S_ADVENTURESPIKEC1 + {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEA2}, // S_ADVENTURESPIKEA1 + {SPR_ASPK, 0, 50, {A_BunnyHop}, 20, 0, S_ADVENTURESPIKEA1}, // S_ADVENTURESPIKEA2 + {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEB2}, // S_ADVENTURESPIKEB1 + {SPR_ASPK, 0, 35, {A_BunnyHop}, 15, 0, S_ADVENTURESPIKEB1}, // S_ADVENTURESPIKEB2 + {SPR_ASPK, 0, 50, {A_PlayAttackSound}, 0, 0, S_ADVENTURESPIKEC2}, // S_ADVENTURESPIKEC1 + {SPR_ASPK, 0, 65, {A_BunnyHop}, 25, 0, S_ADVENTURESPIKEC1}, // S_ADVENTURESPIKEC1 - {SPR_HBST, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTPROMPT2}, // S_BOOSTPROMPT1 - {SPR_HBST, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTPROMPT1}, // S_BOOSTPROMPT2 + {SPR_HBST, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTPROMPT2}, // S_BOOSTPROMPT1 + {SPR_HBST, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTPROMPT1}, // S_BOOSTPROMPT2 - {SPR_HBSF, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTOFF2}, // S_BOOSTOFF1 - {SPR_HBSF, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTOFF1}, // S_BOOSTOFF2 + {SPR_HBSF, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTOFF2}, // S_BOOSTOFF1 + {SPR_HBSF, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTOFF1}, // S_BOOSTOFF2 - {SPR_HBSO, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTON2}, // S_BOOSTON1 - {SPR_HBSO, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTON1}, // S_BOOSTON2 + {SPR_HBSO, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTON2}, // S_BOOSTON1 + {SPR_HBSO, 1|FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_BOOSTON1}, // S_BOOSTON2 - {SPR_WBLZ, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIZARDMAN - {SPR_WBLN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIONMAN + {SPR_WBLZ, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIZARDMAN + {SPR_WBLN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIONMAN + + {SPR_FWRK, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK2}, // S_KARMAFIREWORK1 + {SPR_FWRK, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK3}, // S_KARMAFIREWORK2 + {SPR_FWRK, 2|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK4}, // S_KARMAFIREWORK3 + {SPR_FWRK, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4 + {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -20019,6 +20025,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_KARMAFIREWORK + -1, // doomednum + S_KARMAFIREWORK1, // 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 + 0, // speed + 8<target->player->kartstuff[k_comebackmode] == 1 && P_CanPickupItem(player, 1)) { - mobj_t *poof = P_SpawnMobj(tmthing->x, tmthing->y, tmthing->z, MT_EXPLODE); + mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE); S_StartSound(poof, special->info->seesound); + // Karma fireworks + for (i = 0; i < 5; i++) + { + mobj_t *firework = P_SpawnMobj(special->x, special->y, special->z, MT_KARMAFIREWORK); + P_Thrust(firework, FixedAngle((72*i)<scale); + P_SetObjectMomZ(firework, P_RandomRange(1,8)*special->scale, false); + firework->color = special->target->color; + } + special->target->player->kartstuff[k_comebackmode] = 0; special->target->player->kartstuff[k_comebackpoints]++; diff --git a/src/p_mobj.c b/src/p_mobj.c index 61781aeec..96eb3b52c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1413,6 +1413,9 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_SIGN: gravityadd /= 8; break; + case MT_KARMAFIREWORK: + gravityadd /= 3; + break; default: break; } @@ -2523,7 +2526,7 @@ static boolean P_ZMovement(mobj_t *mo) if (P_MobjFlip(mo)*mom.z < 0) { // If going slower than a fracunit, just stop. - if (abs(mom.z) < FixedMul(FRACUNIT, mo->scale)) + if (abs(mom.z) < mo->scale) { mom.x = mom.y = mom.z = 0; @@ -8611,7 +8614,9 @@ void P_MobjThinker(mobj_t *mobj) if (!S_SoundPlaying(mobj, mobj->info->attacksound)) S_StartSound(mobj, mobj->info->attacksound); - if (mobj->extravalue2 > 70) // fire + smoke pillar + if (mobj->extravalue2 <= 8) // Short delay + mobj->extravalue2++; // flametimer + else // fire + smoke pillar { UINT8 i; mobj_t *fire = P_SpawnMobj(mobj->x + (P_RandomRange(-32, 32)*mobj->scale), mobj->y + (P_RandomRange(-32, 32)*mobj->scale), mobj->z, MT_THOK); @@ -8635,20 +8640,6 @@ void P_MobjThinker(mobj_t *mobj) smoke->scalespeed = mobj->scale/24; } } - else - { - mobj->extravalue2++; // flametimer - - if (mobj->extravalue2 > 8) - { - mobj_t *smoke = P_SpawnMobj(mobj->x + (P_RandomRange(-31, 31)*mobj->scale), mobj->y + (P_RandomRange(-31, 31)*mobj->scale), - mobj->z + (P_RandomRange(0, 48)*mobj->scale), MT_THOK); - - P_SetMobjState(smoke, S_FZEROSMOKE1); - smoke->tics += P_RandomRange(-3, 4); - smoke->scale = mobj->scale*2; - } - } break; case MT_EZZPROPELLER: if (mobj->hnext) @@ -9093,6 +9084,22 @@ void P_MobjThinker(mobj_t *mobj) } } break; + case MT_KARMAFIREWORK: + if (mobj->momz == 0) + { + P_RemoveMobj(mobj); + return; + } + else + { + mobj_t *trail = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_THOK); + P_SetMobjState(trail, S_KARMAFIREWORKTRAIL); + P_SetScale(trail, mobj->scale); + trail->destscale = 1; + trail->scalespeed = mobj->scale/12; + trail->color = mobj->color; + } + break; //} case MT_TURRET: P_MobjCheckWater(mobj); From f020441049b4867b8331bf891bc2db1a7a3eba43 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 03:12:22 -0500 Subject: [PATCH 25/41] Add confirmation to reset controls --- src/m_menu.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 8e49b2155..c4e0f88b2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1097,8 +1097,8 @@ static menuitem_t OP_ControlsMenu[] = static menuitem_t OP_AllControlsMenu[] = { - {IT_CALL|IT_STRING, NULL, "Reset to defaults", M_ResetControls, 0}, - {IT_SUBMENU|IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def, 8}, + {IT_SUBMENU|IT_STRING, NULL, "Gamepad Options...", &OP_Joystick1Def, 0}, + {IT_CALL|IT_STRING, NULL, "Reset to defaults", M_ResetControls, 8}, //{IT_SPACE, NULL, NULL, NULL, 0}, {IT_HEADER, NULL, "Gameplay Controls", NULL, 0}, {IT_SPACE, NULL, NULL, NULL, 0}, @@ -8600,7 +8600,7 @@ static void M_Setup1PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[1].itemaction = &OP_Joystick1Def; + OP_AllControlsMenu[0].itemaction = &OP_Joystick1Def; // Unhide P1-only controls OP_AllControlsMenu[15].status = IT_CONTROL; // Chat @@ -8632,7 +8632,7 @@ static void M_Setup2PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[1].itemaction = &OP_Joystick2Def; + OP_AllControlsMenu[0].itemaction = &OP_Joystick2Def; // Hide P1-only controls OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat @@ -8664,7 +8664,7 @@ static void M_Setup3PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[1].itemaction = &OP_Joystick3Def; + OP_AllControlsMenu[0].itemaction = &OP_Joystick3Def; // Hide P1-only controls OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat @@ -8696,7 +8696,7 @@ static void M_Setup4PControlsMenu(INT32 choice) currentMenu->lastOn = itemOn; // Set proper gamepad options - OP_AllControlsMenu[1].itemaction = &OP_Joystick4Def; + OP_AllControlsMenu[0].itemaction = &OP_Joystick4Def; // Hide P1-only controls OP_AllControlsMenu[15].status = IT_GRAYEDOUT2; // Chat @@ -8777,10 +8777,8 @@ static void M_DrawControl(void) M_DrawMenuTitle(); M_CentreText(28, - (setupcontrolplayer == 4 ? "\x86""Set controls for ""\x82""Player 4" : - (setupcontrolplayer == 3 ? "\x86""Set controls for ""\x82""Player 3" : - (setupcontrolplayer == 2 ? "\x86""Set controls for ""\x82""Player 2" : - "\x86""Press ""\x82""ENTER""\x86"" to change, ""\x82""BACKSPACE""\x86"" to clear")))); + (setupcontrolplayer > 1 ? va("\x86""Set controls for ""\x82""Player %d", setupcontrolplayer) : + "\x86""Press ""\x82""ENTER""\x86"" to change, ""\x82""BACKSPACE""\x86"" to clear")); if (i) V_DrawCharacter(currentMenu->x - 16, y-(skullAnimCounter/5), @@ -8928,10 +8926,12 @@ static void M_ChangeControl(INT32 choice) M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } -static void M_ResetControls(INT32 choice) +static void M_ResetControlsResponse(INT32 ch) { INT32 i; - (void)choice; + + if (ch != 'y' && ch != KEY_ENTER) + return; // clear all controls for (i = 0; i < num_gamecontrols; i++) @@ -9006,6 +9006,12 @@ static void M_ResetControls(INT32 choice) S_StartSound(NULL, sfx_s224); } +static void M_ResetControls(INT32 choice) +{ + (void)choice; + M_StartMessage(va(M_GetText("Reset Player %d's controls to defaults?\n\n(Press 'Y' to confirm)\n"), setupcontrolplayer), M_ResetControlsResponse, MM_YESNO); +} + // ===== // SOUND // ===== From 9a25d4e988968e5bf97cfc0efac708b860762712 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 03:19:31 -0500 Subject: [PATCH 26/41] This sound doesn't exist yet, but I'm defining it anyway --- src/k_kart.c | 2 +- src/sounds.c | 1 + src/sounds.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 9451a7921..0f41f9cea 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1012,7 +1012,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->kartstuff[k_roulettetype] = 0; // This too if (P_IsLocalPlayer(player)) - S_StartSound(NULL, (mashed ? sfx_itrolm : sfx_itrolf)); + S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); } //} diff --git a/src/sounds.c b/src/sounds.c index 900c88f9c..b6bf7f55c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -793,6 +793,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"itrol8", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, {"itrolf", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end {"itrolm", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end (mashed) + {"itrolk", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end (karma enhanced) {"itrole", true, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Roulette end (Eggman) {"vroom", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Kart Krew opening vroom {"chaooo", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Chao audience cheer diff --git a/src/sounds.h b/src/sounds.h index 1e287a6b8..5ca6be1cb 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -868,6 +868,7 @@ typedef enum sfx_itrol8, sfx_itrolf, sfx_itrolm, + sfx_itrolk, sfx_itrole, sfx_vroom, sfx_chaooo, From 4f0c74e1dcf5d617aec03141e289db6b1551b6fa Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 04:27:31 -0500 Subject: [PATCH 27/41] Remove previous commit's votebuffer, allow an external optional buffer to be passed into G_RandMap I meant to fix the previous method, but I didn't even understand how it knew it was in a vote or not... so I just did it my own way :V (Shouldn't FLUSHMAPBUFFEREARLY be on now...?) --- src/d_netcmd.c | 11 ++++++++--- src/doomstat.h | 1 + src/f_finale.c | 2 +- src/g_game.c | 38 ++++++++++---------------------------- src/g_game.h | 2 +- src/m_menu.c | 2 +- 6 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4a08a1af0..fc545763b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2076,6 +2076,7 @@ void D_SetupVote(void) UINT8 *p = buf; INT32 i; UINT8 secondgt = G_SometimesGetDifferentGametype(); + INT16 votebuffer[3] = {-1,-1,-1}; if (cv_kartencore.value && G_RaceGametype()) WRITEUINT8(p, (gametype|0x80)); @@ -2086,12 +2087,16 @@ void D_SetupVote(void) for (i = 0; i < 5; i++) { + UINT16 m; if (i == 2) // sometimes a different gametype - WRITEUINT16(p, G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true)); + m = G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true, votebuffer); else if (i >= 3) // unknown-random and force-unknown MAP HELL - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, (i-2), (i < 4))); + m = G_RandMap(G_TOLFlag(gametype), prevmap, false, (i-2), (i < 4), votebuffer); else - WRITEUINT16(p, G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, true)); + m = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, true, votebuffer); + if (i < 3) + votebuffer[i] = m; + WRITEUINT16(p, m); } SendNetXCmd(XD_SETUPVOTE, buf, p - buf); diff --git a/src/doomstat.h b/src/doomstat.h index 34456b321..3784145f5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -467,6 +467,7 @@ extern boolean comebackshowninfo; extern tic_t curlap, bestlap; extern INT16 votelevels[5][2]; +extern INT16 votebuffer[5]; extern SINT8 votes[MAXPLAYERS]; extern SINT8 pickedvote; diff --git a/src/f_finale.c b/src/f_finale.c index b84289be6..eb6adae18 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1068,7 +1068,7 @@ void F_TitleScreenTicker(boolean run) return; }*/ - mapname = G_BuildMapName(G_RandMap(TOL_RACE, -2, false, 0, false)+1); + mapname = G_BuildMapName(G_RandMap(TOL_RACE, -2, false, 0, false, NULL)+1); numstaff = 1; while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",mapname,numstaff+1))) != LUMPERROR) diff --git a/src/g_game.c b/src/g_game.c index f9f156a81..04a540b80 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -779,7 +779,7 @@ const char *G_BuildMapName(INT32 map) map = gamemap-1; else map = prevmap; - map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, false, 0, false)+1; + map = G_RandMap(G_TOLFlag(cv_newgametype.value), map, false, 0, false, NULL)+1; } if (map < 100) @@ -3269,8 +3269,7 @@ static INT32 TOLMaps(INT16 tolflags) * \author Graue */ static INT16 *okmaps = NULL; -static INT16 votebuffer[3] = {-1, -1, -1}; -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon) +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer) { INT32 numokmaps = 0; INT16 ix, bufx; @@ -3299,24 +3298,18 @@ tryagain: if (!ignorebuffer) { - if (votebuffer[0] != -1) + if (extbuffer != NULL) { - if (ix == votebuffer[0]) - continue; - - for (bufx = 1; bufx < 3; bufx++) + for (bufx = 0; bufx < (INT16)(sizeof extbuffer); bufx++) { - if (votebuffer[bufx] == -1) // Rest of buffer SHOULD be empty + if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty break; - if (ix == votebuffer[bufx]) + if (ix == extbuffer[bufx]) { isokmap = false; break; } } - - if (!isokmap) - continue; } for (bufx = 0; bufx < (maphell ? 3 : NUMMAPS); bufx++) @@ -3351,18 +3344,18 @@ tryagain: if (randmapbuffer[3] == -1) // Is the buffer basically empty? { ignorebuffer = true; // This will probably only help in situations where there's very few maps, but it's folly not to at least try it - goto tryagain; //return G_RandMap(tolflags, pprevmap, true, maphell, callagainsoon); + goto tryagain; } for (bufx = 3; bufx < NUMMAPS; bufx++) // Let's clear all but the three most recent maps... randmapbuffer[bufx] = -1; - goto tryagain; //return G_RandMap(tolflags, pprevmap, ignorebuffer, maphell, callagainsoon); + goto tryagain; } if (maphell) // Any wiggle room to loosen our restrictions here? { maphell--; - goto tryagain; //return G_RandMap(tolflags, pprevmap, true, maphell-1, callagainsoon); + goto tryagain; } ix = 0; // Sorry, none match. You get MAP01. @@ -3376,17 +3369,6 @@ tryagain: { Z_Free(okmaps); okmaps = NULL; - for (bufx = 0; bufx < 3; bufx++) - votebuffer[bufx] = -1; - } - else if (votebuffer[2] == -1) - { - for (bufx = 0; bufx < 3; bufx++) - if (votebuffer[bufx] == -1) - { - votebuffer[bufx] = ix; - break; - } } return ix; @@ -3548,7 +3530,7 @@ static void G_DoCompleted(void) if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; else if (cv_advancemap.value == 2) // Go to random map. - nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false); + nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL); } // We are committed to this map now. diff --git a/src/g_game.h b/src/g_game.h index 27f961d3b..e29d4bbeb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -255,7 +255,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon); +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 votebuffer[5]); void G_AddMapToBuffer(INT16 map); #endif diff --git a/src/m_menu.c b/src/m_menu.c index 9b1eb62c6..c97929486 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7454,7 +7454,7 @@ static void M_StartServer(INT32 choice) G_StopMetalDemo(); if (!cv_nextmap.value) - CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, false, 0, false)+1); + CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, false, 0, false, NULL)+1); if (cv_maxplayers.value < ssplayers+1) CV_SetValue(&cv_maxplayers, ssplayers+1); From bbf37e1e952e626f4b4004a4916fa3b81d3e36b2 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 04:28:39 -0500 Subject: [PATCH 28/41] Mistakes --- src/doomstat.h | 1 - src/g_game.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 3784145f5..34456b321 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -467,7 +467,6 @@ extern boolean comebackshowninfo; extern tic_t curlap, bestlap; extern INT16 votelevels[5][2]; -extern INT16 votebuffer[5]; extern SINT8 votes[MAXPLAYERS]; extern SINT8 pickedvote; diff --git a/src/g_game.h b/src/g_game.h index e29d4bbeb..6a9014ea3 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -255,7 +255,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics); // Don't split up TOL handling INT16 G_TOLFlag(INT32 pgametype); -INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 votebuffer[5]); +INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer); void G_AddMapToBuffer(INT16 map); #endif From 8aab2277097963ad2232fe569e147f9cdae1a608 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 04:42:14 -0500 Subject: [PATCH 29/41] Accidental removal --- src/g_game.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 04a540b80..c6acb3941 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3310,6 +3310,9 @@ tryagain: break; } } + + if (!isokmap) + continue; } for (bufx = 0; bufx < (maphell ? 3 : NUMMAPS); bufx++) From 5afc783c78e478cc34cbb8e2e29d3d3e62d6fa22 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 05:09:56 -0500 Subject: [PATCH 30/41] Calculate buffer size manually (Yes, I checked; this always outputs "3" for its current usage.) --- src/g_game.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index c6acb3941..9d7ebbb44 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3273,11 +3273,20 @@ INT16 G_RandMap(INT16 tolflags, INT16 pprevmap, boolean ignorebuffer, UINT8 maph { INT32 numokmaps = 0; INT16 ix, bufx; + UINT16 extbufsize = 0; boolean usehellmaps; // Only consider Hell maps in this pick if (!okmaps) okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); + if (extbuffer != NULL) + { + bufx = 0; + while (extbuffer[bufx]) { + extbufsize++; bufx++; + } + } + tryagain: usehellmaps = (maphell == 0 ? false : (maphell == 2 || M_RandomChance(FRACUNIT/100))); // 1% chance of Hell @@ -3298,9 +3307,9 @@ tryagain: if (!ignorebuffer) { - if (extbuffer != NULL) + if (extbufsize > 0) { - for (bufx = 0; bufx < (INT16)(sizeof extbuffer); bufx++) + for (bufx = 0; bufx < extbufsize; bufx++) { if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty break; From 303bcbcdc676d9d5cdc1a29583bfe6b8d70d0a3c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 06:09:26 -0500 Subject: [PATCH 31/41] Flush map buffer early, again Now it's directly in G_AddMapToBuffer --- src/g_game.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 9d7ebbb44..ac34c74d5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3240,7 +3240,6 @@ INT16 G_TOLFlag(INT32 pgametype) return INT16_MAX; } -#ifdef FLUSHMAPBUFFEREARLY static INT32 TOLMaps(INT16 tolflags) { INT32 num = 0; @@ -3251,14 +3250,14 @@ static INT32 TOLMaps(INT16 tolflags) { if (!mapheaderinfo[i]) continue; - + if (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU) // Don't include Map Hell + continue; if ((mapheaderinfo[i]->typeoflevel & tolflags) == tolflags) num++; } return num; } -#endif /** Select a random map with the given typeoflevel flags. * If no map has those flags, this arbitrarily gives you map 1. @@ -3388,10 +3387,21 @@ tryagain: void G_AddMapToBuffer(INT16 map) { - INT16 bufx; + INT16 bufx, refreshnum = (TOLMaps(G_TOLFlag(gametype)) / 2) + 1; + + // Add the map to the buffer. for (bufx = NUMMAPS-1; bufx > 0; bufx--) randmapbuffer[bufx] = randmapbuffer[bufx-1]; randmapbuffer[0] = map; + + // We're getting pretty full, so lets flush this for future usage. + if (randmapbuffer[refreshnum] != -1) + { + // Clear all but the five most recent maps. + for (bufx = 5; bufx < NUMMAPS; bufx++) // bufx < refreshnum? Might not handle everything for gametype switches, though. + randmapbuffer[bufx] = -1; + //CONS_Printf("Random map buffer has been flushed.\n"); + } } // @@ -3529,14 +3539,6 @@ static void G_DoCompleted(void) automapactive = false; -#ifdef FLUSHMAPBUFFEREARLY - if (randmapbuffer[TOLMaps(G_TOLFlag(gametype))-5] != -1) // We're getting pretty full, so! -- no need for this, handled in G_RandMap - { - for (i = 3; i < NUMMAPS; i++) // Let's clear all but the three most recent maps... - randmapbuffer[i] = -1; - } -#endif - if (gametype != GT_COOP) { if (cv_advancemap.value == 0) // Stay on same map. From 55a5d550222e8aa84875d7fb8e4c1a87935c2ad1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 07:18:21 -0500 Subject: [PATCH 32/41] Find bestrank for 7 sec limit enforcement --- src/p_enemy.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index dd68a02c1..2e806bc0b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8359,6 +8359,28 @@ void A_SPBChase(mobj_t *actor) return; } + // Find the player with the best rank + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator || players[i].exiting) + continue; // not in-game + + if (!players[i].mo) + continue; // no mobj + + if (players[i].mo->health <= 0) + continue; // dead + + /*if (players[i].kartstuff[k_respawn]) + continue;*/ // respawning + + if (players[i].kartstuff[k_position] < bestrank) + { + bestrank = players[i].kartstuff[k_position]; + player = &players[i]; + } + } + if (actor->extravalue1 == 1) // MODE: TARGETING { if (actor->tracer && actor->tracer->health) @@ -8379,7 +8401,7 @@ void A_SPBChase(mobj_t *actor) defspeed -= (9*R_PointToDist2(0, 0, actor->tracer->player->cmomx, actor->tracer->player->cmomy))/8; // Be fairer on conveyors // Switch targets if you're no longer 1st for long enough - if (actor->tracer->player->kartstuff[k_position] == 1) + if (actor->tracer->player->kartstuff[k_position] <= bestrank) actor->extravalue2 = 7*TICRATE; else if (actor->extravalue2-- <= 0) actor->extravalue1 = 0; // back to SEEKING @@ -8492,28 +8514,6 @@ void A_SPBChase(mobj_t *actor) { actor->lastlook = -1; // Just make sure this is reset - // Find the player with the best rank - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator || players[i].exiting) - continue; // not in-game - - if (!players[i].mo) - continue; // no mobj - - if (players[i].mo->health <= 0) - continue; // dead - - /*if (players[i].kartstuff[k_respawn]) - continue;*/ // respawning - - if (players[i].kartstuff[k_position] < bestrank) - { - bestrank = players[i].kartstuff[k_position]; - player = &players[i]; - } - } - // No one there? if (player == NULL || !player->mo) { From 1c02dd82138d8d0012c1dfa339ac5d06e90c2e46 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 07:43:05 -0500 Subject: [PATCH 33/41] Slow down animation --- src/info.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/info.c b/src/info.c index c26b83bc2..faa4b1884 100644 --- a/src/info.c +++ b/src/info.c @@ -3388,10 +3388,10 @@ state_t states[NUMSTATES] = {SPR_WBLZ, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIZARDMAN {SPR_WBLN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_LIONMAN - {SPR_FWRK, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK2}, // S_KARMAFIREWORK1 - {SPR_FWRK, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK3}, // S_KARMAFIREWORK2 - {SPR_FWRK, 2|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK4}, // S_KARMAFIREWORK3 - {SPR_FWRK, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4 + {SPR_FWRK, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK2}, // S_KARMAFIREWORK1 + {SPR_FWRK, 1|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK3}, // S_KARMAFIREWORK2 + {SPR_FWRK, 2|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK4}, // S_KARMAFIREWORK3 + {SPR_FWRK, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4 {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL #ifdef SEENAMES From 5533f033517cdddda05d0d9754b69607ecc175f4 Mon Sep 17 00:00:00 2001 From: Sryder Date: Mon, 26 Nov 2018 23:10:24 +0000 Subject: [PATCH 34/41] Revert change to P_SlopeLaunch Don't call slopelaunch just from object z difference if the slope has no physics. --- src/p_mobj.c | 4 +++- src/p_slopes.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 2cb12791f..d19bdd18f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1938,7 +1938,9 @@ void P_XYMovement(mobj_t *mo) FIXED_TO_FLOAT(AngleFixed(newangle)), FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) );*/ - } else if (predictedz-mo->z > abs(slopemom.z/2)) { // Now check if we were supposed to stick to this slope + // Sryder 2018-11-26: Don't launch here if it's a slope without physics, we stick to those like glue anyway + } else if (predictedz-mo->z > abs(slopemom.z/2) + && !(mo->standingslope->flags & SL_NOPHYSICS)) { // Now check if we were supposed to stick to this slope //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); P_SlopeLaunch(mo); } diff --git a/src/p_slopes.c b/src/p_slopes.c index ea85f797f..26b3657f0 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -812,10 +812,10 @@ void P_SlopeLaunch(mobj_t *mo) mo->momy = slopemom.y; mo->momz = slopemom.z; #endif + } //CONS_Printf("Launched off of slope.\n"); mo->standingslope = NULL; - } } // Function to help handle landing on slopes From 99408ae1b6fe88ccff54ef9520dde5be0ae3c804 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 26 Nov 2018 23:34:43 -0500 Subject: [PATCH 35/41] Fix order so the new sound can actually play --- src/k_kart.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index a8fbeea56..b7a17cee0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1006,13 +1006,14 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemamount] = 1; } - player->kartstuff[k_itemblink] = TICRATE; - player->kartstuff[k_itemblinkmode] = ((player->kartstuff[k_roulettetype] == 1) ? 2 : (mashed ? 1 : 0)); - player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number - player->kartstuff[k_roulettetype] = 0; // This too - if (P_IsLocalPlayer(player)) S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); + + player->kartstuff[k_itemblink] = TICRATE; + player->kartstuff[k_itemblinkmode] = ((player->kartstuff[k_roulettetype] == 1) ? 2 : (mashed ? 1 : 0)); + + player->kartstuff[k_itemroulette] = 0; // Since we're done, clear the roulette number + player->kartstuff[k_roulettetype] = 0; // This too } //} From a7a27bc636262320bbceddd8c497f10080a89fdc Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 27 Nov 2018 11:23:28 -0500 Subject: [PATCH 36/41] SEVERELY nerf jointimeout & resynchattempts, too All of these previous defaults are "this is an insane time to reach, by that point you might as well disconnect" --- src/d_clisrv.c | 4 ++-- src/d_netcmd.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 11be98177..ab0e059d2 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -84,7 +84,7 @@ UINT8 playernode[MAXPLAYERS]; // Minimum timeout for sending the savegame // The actual timeout will be longer depending on the savegame length -tic_t jointimeout = (10*TICRATE); +tic_t jointimeout = (3*TICRATE); static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame? static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout? @@ -3010,7 +3010,7 @@ consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}}; -consvar_t cv_resynchattempts = {"resynchattempts", "10", 0, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_resynchattempts = {"resynchattempts", "5", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; consvar_t cv_blamecfail = {"blamecfail", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; // max file size to send to a player (in kilobytes) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9eafc73e1..899790f50 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -425,8 +425,8 @@ consvar_t cv_killingdead = {"killingdead", "Off", CV_NETVAR|CV_NOSHOWHELP, CV_On consvar_t cv_netstat = {"netstat", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // show bandwidth statistics static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; consvar_t cv_nettimeout = {"nettimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; -consvar_t cv_jointimeout = {"jointimeout", "350", CV_CALL|CV_SAVE, jointimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; +//static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; +consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; #ifdef NEWPING consvar_t cv_maxping = {"maxping", "500", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif From 74daafd9eb802cf07da008ef061242dbbddb982c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 27 Nov 2018 12:10:46 -0500 Subject: [PATCH 37/41] Advanced Server Options menu More accessible way of modifying ping limit, timeouts, max file send, etc now that the defaults are stricter --- src/d_clisrv.c | 2 +- src/d_clisrv.h | 1 + src/d_netcmd.c | 3 ++- src/doomstat.h | 5 +++++ src/m_menu.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index ab0e059d2..8c28262d8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -163,7 +163,7 @@ ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL}; -static consvar_t cv_showjoinaddress = {"showjoinaddress", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_showjoinaddress = {"showjoinaddress", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_playbackspeed = {"playbackspeed", "1", 0, playbackspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index a3fcfde05..e767a91e3 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -472,6 +472,7 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; +extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; #define BASEPACKETSIZE ((size_t)&(((doomdata_t *)0)->u)) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 899790f50..1ce919114 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -428,7 +428,8 @@ consvar_t cv_nettimeout = {"nettimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons //static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}}; consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL}; #ifdef NEWPING -consvar_t cv_maxping = {"maxping", "500", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; +consvar_t cv_maxping = {"maxping", "500", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif // Intermission time Tails 04-19-2002 static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}}; diff --git a/src/doomstat.h b/src/doomstat.h index 34456b321..dea7aefd3 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -530,6 +530,11 @@ extern boolean singletics; extern consvar_t cv_timetic; // display high resolution timer extern consvar_t cv_forceskin; // force clients to use the server's skin extern consvar_t cv_downloading; // allow clients to downloading WADs. +extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu +extern consvar_t cv_jointimeout; +#ifdef NEWPING +extern consvar_t cv_maxping; +#endif extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern INT32 serverplayer; extern INT32 adminplayers[MAXPLAYERS]; diff --git a/src/m_menu.c b/src/m_menu.c index c4e0f88b2..eb769aa69 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -321,6 +321,9 @@ static void M_ToggleMIDI(INT32 choice); menu_t /*OP_DataOptionsDef,*/ OP_ScreenshotOptionsDef, OP_EraseDataDef; menu_t OP_HUDOptionsDef, OP_ChatOptionsDef; menu_t OP_GameOptionsDef, OP_ServerOptionsDef; +#ifndef NONET +menu_t OP_AdvServerOptionsDef; +#endif //menu_t OP_NetgameOptionsDef, OP_GametypeOptionsDef; menu_t OP_MonitorToggleDef; static void M_ScreenshotOptions(INT32 choice); @@ -1480,15 +1483,34 @@ static menuitem_t OP_ServerOptionsMenu[] = #ifndef NONET {IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 90}, {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 100}, -#ifdef VANILLAJOINNEXTROUND - {IT_STRING | IT_CVAR, NULL, "Join on Map Change", &cv_joinnextround, 110}, -#endif + {IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 110}, + {IT_STRING | IT_CVAR, NULL, "Pause Permission", &cv_pause, 120}, + {IT_STRING | IT_CVAR, NULL, "Mute All Chat", &cv_mute, 130}, - {IT_STRING | IT_CVAR, NULL, "Allow WAD Downloading", &cv_downloading, 110}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 120}, + {IT_SUBMENU|IT_STRING, NULL, "Advanced Options...", &OP_AdvServerOptionsDef,150}, #endif }; +#ifndef NONET +static menuitem_t OP_AdvServerOptionsMenu[] = +{ + {IT_STRING | IT_CVAR | IT_CV_STRING, + NULL, "Server Browser Address", &cv_masterserver, 10}, + + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 40}, + {IT_STRING | IT_CVAR, NULL, "Ping limit (ms)", &cv_maxping, 50}, + {IT_STRING | IT_CVAR, NULL, "Connection timeout (tics)", &cv_nettimeout, 60}, + {IT_STRING | IT_CVAR, NULL, "Join timeout (tics)", &cv_jointimeout, 70}, + + {IT_STRING | IT_CVAR, NULL, "Max. file transfer send (KB)", &cv_maxsend, 90}, + {IT_STRING | IT_CVAR, NULL, "File transfer packet rate", &cv_downloadspeed, 100}, + + {IT_STRING | IT_CVAR, NULL, "Log join addresses", &cv_showjoinaddress, 120}, + {IT_STRING | IT_CVAR, NULL, "Log resyncs", &cv_blamecfail, 130}, + {IT_STRING | IT_CVAR, NULL, "Log file transfers", &cv_noticedownload, 140}, +}; +#endif + /*static menuitem_t OP_NetgameOptionsMenu[] = { {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 10}, @@ -1973,6 +1995,9 @@ menu_t OP_ChatOptionsDef = DEFAULTMENUSTYLE("M_HUD", OP_ChatOptionsMenu, &OP_HUD menu_t OP_GameOptionsDef = DEFAULTMENUSTYLE("M_GAME", OP_GameOptionsMenu, &OP_MainDef, 30, 30); menu_t OP_ServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 24, 30); +#ifndef NONET +menu_t OP_AdvServerOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_AdvServerOptionsMenu, &OP_ServerOptionsDef, 24, 30); +#endif //menu_t OP_NetgameOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_NetgameOptionsMenu, &OP_ServerOptionsDef, 30, 30); //menu_t OP_GametypeOptionsDef = DEFAULTMENUSTYLE("M_SERVER", OP_GametypeOptionsMenu, &OP_ServerOptionsDef, 30, 30); @@ -2312,7 +2337,19 @@ static void M_ChangeCvar(INT32 choice) CV_Set(cv,s); } else + { +#ifndef NONET + if (cv == &cv_nettimeout || cv == &cv_jointimeout) + choice *= (TICRATE/7); + else if (cv == &cv_maxsend) + choice *= 512; +#ifdef NEWPING + else if (cv == &cv_maxping) + choice *= 50; +#endif +#endif CV_AddValue(cv,choice); + } } static boolean M_ChangeStringCvar(INT32 choice) From 668efe91057bfd1bb8888622fad31910d13c02ae Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 27 Nov 2018 14:28:11 -0500 Subject: [PATCH 38/41] Require 3/5ths of checkpoints instead of 1/2 This broke MKSC in a minor way if you skip a specific item set and then take the big cut... I'll let it go anyway since its an improvement everywhere else. --- src/d_clisrv.c | 2 -- src/d_clisrv.h | 1 - src/d_player.h | 1 - src/g_game.c | 6 ------ src/k_kart.c | 4 ++-- src/lua_playerlib.c | 4 ---- src/p_inter.c | 4 +--- src/p_saveg.c | 2 -- src/p_spec.c | 5 ++--- 9 files changed, 5 insertions(+), 24 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 8c28262d8..7b8c0127d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -619,7 +619,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->starposty = SHORT(players[i].starposty); rsp->starpostz = SHORT(players[i].starpostz); rsp->starpostnum = LONG(players[i].starpostnum); - rsp->starpostcount = LONG(players[i].starpostcount); rsp->starposttime = (tic_t)LONG(players[i].starposttime); rsp->starpostangle = (angle_t)LONG(players[i].starpostangle); @@ -755,7 +754,6 @@ static void resynch_read_player(resynch_pak *rsp) players[i].starposty = SHORT(rsp->starposty); players[i].starpostz = SHORT(rsp->starpostz); players[i].starpostnum = LONG(rsp->starpostnum); - players[i].starpostcount = LONG(rsp->starpostcount); players[i].starposttime = (tic_t)LONG(rsp->starposttime); players[i].starpostangle = (angle_t)LONG(rsp->starpostangle); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e767a91e3..d4090b262 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -251,7 +251,6 @@ typedef struct INT16 starposty; INT16 starpostz; INT32 starpostnum; - INT32 starpostcount; tic_t starposttime; angle_t starpostangle; diff --git a/src/d_player.h b/src/d_player.h index c87437171..2ff781e11 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -515,7 +515,6 @@ typedef struct player_s INT16 starposty; INT16 starpostz; INT32 starpostnum; // The number of the last starpost you hit - INT32 starpostcount; // SRB2kart: how many did you hit? tic_t starposttime; // Your time when you hit the starpost angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way diff --git a/src/g_game.c b/src/g_game.c index 656392a3d..80fc39509 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2266,7 +2266,6 @@ static inline void G_PlayerFinishLevel(INT32 player) p->starposty = 0; p->starpostz = 0; p->starpostnum = 0; - p->starpostcount = 0; // SRB2kart: Increment the "matches played" counter. if (player == consoleplayer) @@ -2318,7 +2317,6 @@ void G_PlayerReborn(INT32 player) INT16 starposty; INT16 starpostz; INT32 starpostnum; - INT32 starpostcount; INT32 starpostangle; fixed_t jumpfactor; INT32 exiting; @@ -2382,7 +2380,6 @@ void G_PlayerReborn(INT32 player) starposty = players[player].starposty; starpostz = players[player].starpostz; starpostnum = players[player].starpostnum; - starpostcount = players[player].starpostcount; starpostangle = players[player].starpostangle; jumpfactor = players[player].jumpfactor; thokitem = players[player].thokitem; @@ -2474,7 +2471,6 @@ void G_PlayerReborn(INT32 player) p->starposty = starposty; p->starpostz = starpostz; p->starpostnum = starpostnum; - p->starpostcount = starpostcount; p->starpostangle = starpostangle; p->jumpfactor = jumpfactor; p->exiting = exiting; @@ -2938,7 +2934,6 @@ void G_DoReborn(INT32 playernum) player->starposty = 0; player->starpostz = 0; player->starpostnum = 0; - player->starpostcount = 0; } if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { @@ -4326,7 +4321,6 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool players[i].playerstate = PST_REBORN; players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; players[i].starpostx = players[i].starposty = players[i].starpostz = 0; - players[i].starpostcount = 0; // srb2kart #if 0 if (netgame || multiplayer) diff --git a/src/k_kart.c b/src/k_kart.c index b7a17cee0..eb7d74932 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7982,10 +7982,10 @@ static void K_drawCheckpointDebugger(void) if (stplyr != &players[displayplayer]) // only for p1 return; - if ((numstarposts/2 + stplyr->starpostnum) >= numstarposts) + if (stplyr->starpostnum >= (numstarposts - (2*numstarposts)/5)) V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Can finish)", stplyr->starpostnum, numstarposts)); else - V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Skip: %d)", stplyr->starpostnum, numstarposts, (numstarposts/2 + stplyr->starpostnum))); + V_DrawString(8, 184, 0, va("Checkpoint: %d / %d (Skip: %d)", stplyr->starpostnum, numstarposts, ((2*numstarposts)/5 + stplyr->starpostnum))); V_DrawString(8, 192, 0, va("Waypoint dist: Prev %d, Next %d", stplyr->kartstuff[k_prevcheck], stplyr->kartstuff[k_nextcheck])); } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1eed10b0f..53f098517 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -246,8 +246,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->starpostz); else if (fastcmp(field,"starpostnum")) lua_pushinteger(L, plr->starpostnum); - else if (fastcmp(field,"starpostcount")) - lua_pushinteger(L, plr->starpostcount); else if (fastcmp(field,"starposttime")) lua_pushinteger(L, plr->starposttime); else if (fastcmp(field,"starpostangle")) @@ -519,8 +517,6 @@ static int player_set(lua_State *L) plr->starpostz = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostnum")) plr->starpostnum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostcount")) - plr->starpostcount = (INT32)luaL_checkinteger(L, 3); else if (fastcmp(field,"starposttime")) plr->starposttime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostangle")) diff --git a/src/p_inter.c b/src/p_inter.c index cabf3aa23..28ce0d961 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1425,8 +1425,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } // // SRB2kart: make sure the player will have enough checkpoints to touch - if (circuitmap - && special->health >= (numstarposts/2 + player->starpostnum)) + if (circuitmap && special->health >= ((2*numstarposts)/5 + player->starpostnum)) { // blatant reuse of a variable that's normally unused in circuit if (!player->tossdelay) @@ -1453,7 +1452,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->starpostz = special->z>>FRACBITS; player->starpostangle = special->angle; player->starpostnum = special->health; - player->starpostcount++; //S_StartSound(toucher, special->info->painsound); return; diff --git a/src/p_saveg.c b/src/p_saveg.c index e702d460f..345d97c02 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -198,7 +198,6 @@ static void P_NetArchivePlayers(void) WRITEINT16(save_p, players[i].starposty); WRITEINT16(save_p, players[i].starpostz); WRITEINT32(save_p, players[i].starpostnum); - WRITEINT32(save_p, players[i].starpostcount); WRITEANGLE(save_p, players[i].starpostangle); WRITEANGLE(save_p, players[i].angle_pos); @@ -382,7 +381,6 @@ static void P_NetUnArchivePlayers(void) players[i].starposty = READINT16(save_p); players[i].starpostz = READINT16(save_p); players[i].starpostnum = READINT32(save_p); - players[i].starpostcount = READINT32(save_p); players[i].starpostangle = READANGLE(save_p); players[i].angle_pos = READANGLE(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 6ac325cd9..935c7d905 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4190,12 +4190,12 @@ DoneSection2: case 10: // Finish Line // SRB2kart - 150117 - if (G_RaceGametype() && (player->starpostcount >= numstarposts/2 || player->exiting)) + if (G_RaceGametype() && (player->starpostnum >= (numstarposts - (2*numstarposts)/5) || player->exiting)) player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0; // if (G_RaceGametype() && !player->exiting) { - if (player->starpostcount >= numstarposts/2) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)") + if (player->starpostnum >= (numstarposts - (2*numstarposts)/5)) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)") { UINT8 nump = 0; @@ -4244,7 +4244,6 @@ DoneSection2: // SRB2kart 200117 player->starpostangle = player->starpostnum = 0; player->starpostx = player->starposty = player->starpostz = 0; - player->starpostcount = 0; //except the time! player->starposttime = player->realtime; From 4e532b7ae50391d1d0c59c0134777ee99f93e6c0 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 27 Nov 2018 19:00:48 -0500 Subject: [PATCH 39/41] I like working on Kart... --- src/d_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 018390144..99f1a409f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -662,7 +662,6 @@ void D_SRB2Loop(void) "===========================================================================\n" " We hope you enjoy this game as\n" " much as we did making it!\n" - " ...wait. =P\n" "===========================================================================\n"); // hack to start on a nice clear console screen. From 261a50fe68de42515d041ac7434853f1fc63b6f7 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 28 Nov 2018 00:45:33 -0500 Subject: [PATCH 40/41] Fix exit music occasionally being wrong on race exit, add K_KartUpdatePosition to Lua --- src/k_kart.c | 2 +- src/k_kart.h | 1 + src/lua_baselib.c | 11 +++++++++++ src/p_user.c | 5 +++-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index eb7d74932..e56e7c96e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4660,7 +4660,7 @@ static void K_KartDrift(player_t *player, boolean onground) // // K_KartUpdatePosition // -static void K_KartUpdatePosition(player_t *player) +void K_KartUpdatePosition(player_t *player) { fixed_t position = 1; fixed_t oldposition = player->kartstuff[k_position]; diff --git a/src/k_kart.h b/src/k_kart.h index 3edbf0bd7..864a8609d 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -49,6 +49,7 @@ player_t *K_FindJawzTarget(mobj_t *actor, player_t *source); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); INT32 K_GetKartDriftSparkValue(player_t *player); +void K_KartUpdatePosition(player_t *player); void K_DropItems(player_t *player); void K_StripItems(player_t *player); void K_StripOther(player_t *player); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1c14093c6..bc41183f7 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2386,6 +2386,16 @@ static int lib_kGetKartDriftSparkValue(lua_State *L) return 1; } +static int lib_kKartUpdatePosition(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + NOHUD + if (!player) + return LUA_ErrInvalid(L, "player_t"); + K_KartUpdatePosition(player); + return 0; +} + static int lib_kDropItems(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2677,6 +2687,7 @@ static luaL_Reg lib[] = { {"K_RepairOrbitChain",lib_kRepairOrbitChain}, {"K_FindJawzTarget",lib_kFindJawzTarget}, {"K_GetKartDriftSparkValue",lib_kGetKartDriftSparkValue}, + {"K_KartUpdatePosition",lib_kKartUpdatePosition}, {"K_DropItems",lib_kDropItems}, {"K_StripItems",lib_kStripItems}, {"K_StripOther",lib_kStripOther}, diff --git a/src/p_user.c b/src/p_user.c index da3df2330..79e0cad74 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1778,6 +1778,9 @@ void P_DoPlayerExit(player_t *player) if (G_RaceGametype()) // If in Race Mode, allow { + player->exiting = raceexittime+2; + K_KartUpdatePosition(player); + if (cv_kartvoices.value) { if (P_IsLocalPlayer(player)) @@ -1798,8 +1801,6 @@ void P_DoPlayerExit(player_t *player) } } - player->exiting = raceexittime+2; - if (cv_inttime.value > 0) P_EndingMusic(player); From 48be0e524665a68082ca6c0add0e7b111d7be33a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 28 Nov 2018 02:31:16 -0500 Subject: [PATCH 41/41] Nerf activation range of Mines, keep explosion radius --- src/info.c | 8 ++++---- src/p_enemy.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/info.c b/src/info.c index faa4b1884..2e661011f 100644 --- a/src/info.c +++ b/src/info.c @@ -15577,7 +15577,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 6*TICRATE, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 288*FRACUNIT, // painchance + 192*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -15604,7 +15604,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 288*FRACUNIT, // painchance + 192*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -15847,7 +15847,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 288*FRACUNIT, // painchance + 192*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -19629,7 +19629,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 288*FRACUNIT, // painchance + 192*FRACUNIT, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate diff --git a/src/p_enemy.c b/src/p_enemy.c index 2e806bc0b..dbf0607d0 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4036,7 +4036,7 @@ void A_MineExplode(mobj_t *actor) INT32 d; INT32 locvar1 = var1; mobjtype_t type; - explodedist = FixedMul(actor->info->painchance, mapheaderinfo[gamemap-1]->mobj_scale); + explodedist = FixedMul((3*actor->info->painchance)/2, mapheaderinfo[gamemap-1]->mobj_scale); #ifdef HAVE_BLUA if (LUA_CallAction("A_MineExplode", actor)) return;