diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d3503971..7b8c0127 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? @@ -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}; @@ -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); @@ -1304,7 +1302,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(); @@ -3010,7 +3008,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) @@ -3343,6 +3341,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 +3528,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 +3540,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 +4561,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_clisrv.h b/src/d_clisrv.h index a3fcfde0..d4090b26 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; @@ -472,6 +471,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_main.c b/src/d_main.c index 01839014..99f1a409 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. diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8427b673..e5d2f0cb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -425,10 +425,11 @@ 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}; +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}}; @@ -1206,7 +1207,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) @@ -2076,6 +2077,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 +2088,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, 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, true, 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, 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/d_player.h b/src/d_player.h index a5907646..2ff781e1 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; //} @@ -511,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/dehacked.c b/src/dehacked.c index cfa08b45..4380772a 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 @@ -8270,6 +8278,9 @@ static const char *const KARTSTUFF_LIST[] = { "COMEBACKMODE", "WANTED", "YOUGOTEM", + + "ITEMBLINK", + "ITEMBLINKMODE" }; static const char *const HUDITEMS_LIST[] = { @@ -9770,6 +9781,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"thwompsactive")) { lua_pushboolean(L, thwompsactive); return 1; + } else if (fastcmp(word,"spbplace")) { + lua_pushinteger(L, spbplace); + return 1; } return 0; diff --git a/src/doomstat.h b/src/doomstat.h index 34456b32..f87e3048 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 SINT8 spbplace; extern boolean legitimateexit; extern boolean comebackshowninfo; @@ -530,6 +531,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/f_finale.c b/src/f_finale.c index ea89b2b7..eb6adae1 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, 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 e9309b80..80fc3950 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 +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? @@ -779,7 +780,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, NULL)+1; } if (map < 100) @@ -2265,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) @@ -2317,7 +2317,6 @@ void G_PlayerReborn(INT32 player) INT16 starposty; INT16 starpostz; INT32 starpostnum; - INT32 starpostcount; INT32 starpostangle; fixed_t jumpfactor; INT32 exiting; @@ -2381,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; @@ -2473,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; @@ -2937,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)) { @@ -3138,8 +3134,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) @@ -3167,6 +3162,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 @@ -3240,7 +3237,6 @@ INT16 G_TOLFlag(INT32 pgametype) return INT16_MAX; } -#ifdef FLUSHMAPBUFFEREARLY static INT32 TOLMaps(INT16 tolflags) { INT32 num = 0; @@ -3251,14 +3247,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. @@ -3269,15 +3265,24 @@ 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, INT16 *extbuffer) { 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,6 +3303,23 @@ tryagain: if (!ignorebuffer) { + if (extbufsize > 0) + { + for (bufx = 0; bufx < extbufsize; bufx++) + { + if (extbuffer[bufx] == -1) // Rest of buffer SHOULD be empty + break; + if (ix == extbuffer[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 @@ -3308,12 +3330,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) @@ -3330,20 +3352,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, dontadd, true, maphell, callagainsoon); + goto 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, dontadd, ignorebuffer, maphell, callagainsoon); + goto tryagain; } 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; } ix = 0; // Sorry, none match. You get MAP01. @@ -3351,15 +3371,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) { @@ -3370,6 +3382,25 @@ tryagain: return ix; } +void G_AddMapToBuffer(INT16 map) +{ + 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"); + } +} + // // G_DoCompleted // @@ -3505,22 +3536,12 @@ 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; - if (cv_kartvoterulechanges.value == 1) // sometimes - randmapbuffer[NUMMAPS] = 0; - } -#endif - if (gametype != GT_COOP) { 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, NULL); } // We are committed to this map now. @@ -4300,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/g_game.h b/src/g_game.h index 621da3f8..6a9014ea 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, INT16 *extbuffer); +void G_AddMapToBuffer(INT16 map); #endif diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 2d346878..ece627d3 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 68915e97..894a4a8c 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 c545cb80..2856cada 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 ce543158..5f2cd032 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/info.c b/src/info.c index fa241ad7..2e661011 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, 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 {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -15571,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 @@ -15598,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 @@ -15841,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 @@ -17282,7 +17288,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 +17315,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 +17369,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 @@ -19623,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 @@ -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<kartstuff[k_itemtype] = KITEM_JAWZ; player->kartstuff[k_itemamount] = 2; break; - case KITEM_SPB: // Indirect items - case KITEM_SHRINK: - indirectitemcooldown = 30*TICRATE; + case KITEM_SPB: + case KITEM_SHRINK: // Indirect items + indirectitemcooldown = 20*TICRATE; /* FALLTHRU */ default: if (getitem <= 0 || getitem >= NUMKARTRESULTS) // Sad (Fallback) @@ -649,7 +657,8 @@ 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! @@ -761,7 +770,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed) //{ 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; @@ -841,13 +850,15 @@ 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 = (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]; @@ -949,6 +960,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)) @@ -960,6 +973,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)) @@ -972,7 +987,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); + 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++) \ @@ -992,11 +1007,14 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemamount] = 1; } + 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 - - if (P_IsLocalPlayer(player)) - S_StartSound(NULL, sfx_itrolf); } //} @@ -1843,9 +1861,8 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) pt->color = source->skincolor; } -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem, mobj_t *inflictor) +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem) { - (void)inflictor; // in case some weirdo doesn't want Lua. // PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too. #ifdef HAVE_BLUA boolean force = false; // Used to check if Lua ShouldSpin should get us damaged reguardless of flashtics or heck knows what. @@ -1857,6 +1874,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem else if (shouldForce == 2) return; #else + (void)inflictor; // in case some weirdo doesn't want Lua. static const boolean force = false; #endif @@ -1965,8 +1983,6 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) { - (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' - // PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too. #ifdef HAVE_BLUA boolean force = false; // Used to check if Lua ShouldSquish should get us damaged reguardless of flashtics or heck knows what. @@ -1978,6 +1994,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) else if (shouldForce == 2) return; #else + (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' static const boolean force = false; #endif @@ -2055,6 +2072,14 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) 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; @@ -3098,7 +3123,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++; @@ -3229,44 +3255,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, NULL); - - // 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]))); } @@ -3274,11 +3273,13 @@ 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); } } } + void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { const fixed_t vscale = mapheaderinfo[gamemap-1]->mobj_scale + (mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); @@ -4031,6 +4032,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<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 @@ -4298,43 +4342,14 @@ 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])) + // This doesn't go in HUD update because it has potential gameplay ramifications + if (player->kartstuff[k_itemblink] && player->kartstuff[k_itemblink]-- <= 0) { - 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; - } + player->kartstuff[k_itemblinkmode] = 0; + player->kartstuff[k_itemblink] = 0; + } - 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]--; @@ -4710,7 +4725,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]; @@ -5319,7 +5334,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) { @@ -6299,29 +6314,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 @@ -6377,41 +6447,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 @@ -6421,7 +6547,7 @@ static void K_drawKartItem(void) } } else - V_DrawScaledPatch(ITEM_X, ITEM_Y, V_HUDTRANS|splitflags, localpatch); + V_DrawFixedPatch(ITEM_X<kartstuff[k_position] == spbplace+1)); for (i = 1; i < NUMKARTRESULTS; i++) { @@ -7921,10 +8047,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/k_kart.h b/src/k_kart.h index d191af97..fed490db 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -24,11 +24,12 @@ 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); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem, mobj_t *inflictor); +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem); void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_StealBumper(player_t *player, player_t *victim, boolean force); @@ -48,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 97eb5cf1..79de02a5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2190,16 +2190,16 @@ static int lib_kSpinPlayer(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = NULL; INT32 type = (INT32)luaL_optinteger(L, 3, 0); - boolean trapitem = lua_optboolean(L, 4); mobj_t *inflictor = NULL; + boolean trapitem = lua_optboolean(L, 5); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - if (!lua_isnone(L, 5) && lua_isuserdata(L, 5)) - inflictor = *((mobj_t **)luaL_checkudata(L, 5, META_MOBJ)); - K_SpinPlayer(player, source, type, trapitem, inflictor); + if (!lua_isnone(L, 4) && lua_isuserdata(L, 4)) + inflictor = *((mobj_t **)luaL_checkudata(L, 4, META_MOBJ)); + K_SpinPlayer(player, source, type, inflictor, trapitem); return 0; } @@ -2392,6 +2392,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)); @@ -2683,6 +2693,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/lua_hudlib.c b/src/lua_hudlib.c index f042e8f5..6efab0f8 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -515,8 +515,8 @@ static int libd_getColormap(lua_State *L) else if (lua_type(L, 1) == LUA_TNUMBER) // skin number { skinnum = (INT32)luaL_checkinteger(L, 1); - if (skinnum < TC_ALLWHITE || skinnum >= 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/lua_playerlib.c b/src/lua_playerlib.c index 1eed10b0..53f09851 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/m_cheat.c b/src/m_cheat.c index e57a85ae..3992147c 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); } diff --git a/src/m_cond.c b/src/m_cond.c index 5a9d4f2a..9c56124e 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) diff --git a/src/m_menu.c b/src/m_menu.c index 8e49b215..b3c1cdd0 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); @@ -1097,8 +1100,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}, @@ -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) @@ -7454,7 +7491,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, NULL)+1); if (cv_maxplayers.value < ssplayers+1) CV_SetValue(&cv_maxplayers, ssplayers+1); @@ -8600,7 +8637,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 +8669,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 +8701,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 +8733,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 +8814,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 +8963,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 +9043,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 // ===== diff --git a/src/p_enemy.c b/src/p_enemy.c index a78957b0..dbf0607d 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; @@ -8354,10 +8354,33 @@ 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; } + // 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) @@ -8369,11 +8392,21 @@ 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] <= bestrank) + 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 @@ -8458,41 +8491,28 @@ void A_SPBChase(mobj_t *actor) else if (actor->extravalue1 == 2) // MODE: WAIT... { actor->momx = actor->momy = actor->momz = 0; // Stoooop - 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 { - // 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]; - } - } + actor->lastlook = -1; // Just make sure this is reset // No one there? if (player == NULL || !player->mo) @@ -8509,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); @@ -8560,6 +8582,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; } } diff --git a/src/p_inter.c b/src/p_inter.c index 717e8139..9c66df17 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -497,9 +497,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } else if (special->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]++; @@ -590,7 +599,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_RemoveMobj(special); } else - K_SpinPlayer(player, NULL, 0, false, special); + K_SpinPlayer(player, NULL, 0, special, false); return; /*case MT_EERIEFOG: special->frame &= ~FF_TRANS80; @@ -1416,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) @@ -1444,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; @@ -2003,19 +2010,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 +2040,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; } @@ -3293,7 +3309,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da || inflictor->type == MT_SMK_THWOMP || inflictor->player)) { player->kartstuff[k_sneakertimer] = 0; - K_SpinPlayer(player, source, 1, false, inflictor); + K_SpinPlayer(player, source, 1, inflictor, false); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); @@ -3305,7 +3321,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - K_SpinPlayer(player, source, 0, false, inflictor); + K_SpinPlayer(player, source, 0, inflictor, false); } return true; } diff --git a/src/p_map.c b/src/p_map.c index 6d8579df..e3ce18c9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -882,7 +882,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(thing->player, tmthing->target, tmthing); else - K_SpinPlayer(thing->player, tmthing->target, 0, false, tmthing); + K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, false); } return true; // This doesn't collide with anything, but we want it to effect the player anyway. @@ -915,7 +915,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PLAYER) { // Player Damage - K_SpinPlayer(thing->player, tmthing->target, 0, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD), tmthing); + K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD)); // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -1061,7 +1061,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // Player Damage - K_SpinPlayer(tmthing->player, thing->target, 0, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD), tmthing); + K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD)); // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -1091,7 +1091,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(tmthing->player, thing->target, thing); else - K_SpinPlayer(tmthing->player, thing->target, 0, false, tmthing); + K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, false); return true; } @@ -1543,7 +1543,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { K_StealBumper(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0, false, tmthing); + K_SpinPlayer(thing->player, tmthing, 0, tmthing, false); } } else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) @@ -1552,7 +1552,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { K_StealBumper(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0, false, thing); + K_SpinPlayer(tmthing->player, thing, 0, thing, false); } } else @@ -1563,12 +1563,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer])) { K_StealBumper(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0, false, tmthing); + K_SpinPlayer(tmthing->player, thing, 0, tmthing, false); } else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer])) { K_StealBumper(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0, false, thing); + K_SpinPlayer(thing->player, tmthing, 0, thing, false); } } @@ -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; diff --git a/src/p_mobj.c b/src/p_mobj.c index 2cb12791..521070f5 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; } @@ -1938,7 +1941,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); } @@ -2523,7 +2528,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; @@ -6832,6 +6837,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); @@ -8154,7 +8171,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; @@ -8599,7 +8616,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); @@ -8623,20 +8642,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) @@ -9081,6 +9086,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); @@ -10378,6 +10399,9 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->type == MT_SHADOW) P_RemoveShadow(mobj); + if (mobj->type == MT_SPB) + spbplace = -1; + mobj->health = 0; // Just because // unlink from sector and block lists diff --git a/src/p_saveg.c b/src/p_saveg.c index 1b4314b8..345d97c0 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); @@ -3287,6 +3285,7 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, mapreset); WRITEUINT8(save_p, nospectategrief); WRITEUINT8(save_p, thwompsactive); + WRITESINT8(save_p, spbplace); // Is it paused? if (paused) @@ -3393,6 +3392,7 @@ static inline boolean P_NetUnArchiveMisc(void) mapreset = READUINT32(save_p); nospectategrief = READUINT8(save_p); thwompsactive = (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 68cdc797..f6169a35 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; + spbplace = -1; // clear special respawning que iquehead = iquetail = 0; @@ -3113,6 +3114,8 @@ boolean P_SetupLevel(boolean skipprecip) #endif } + G_AddMapToBuffer(gamemap-1); + return true; } diff --git a/src/p_slopes.c b/src/p_slopes.c index 9513cac0..26b3657f 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 diff --git a/src/p_spec.c b/src/p_spec.c index 27345fe5..b72a6145 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4033,7 +4033,7 @@ DoneSection2: case 7: // SRB2kart 190117 - Oil Slick (deprecated) if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { - K_SpinPlayer(player, NULL, 0, false, NULL); + K_SpinPlayer(player, NULL, 0, NULL, false); } break; @@ -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; diff --git a/src/p_user.c b/src/p_user.c index 296f3b0c..488b8e7c 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); @@ -7758,13 +7759,16 @@ 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. + { + spbplace = -1; indirectitemcooldown = 0; + } if (mo == inflictor) // Don't nuke yourself, dummy! continue; if (mo->type == MT_PLAYER) // Players wipe out in Kart - K_SpinPlayer(mo->player, source, 0, false, inflictor); + K_SpinPlayer(mo->player, source, 0, inflictor, false); //} else P_DamageMobj(mo, inflictor, source, 1000); @@ -7946,6 +7950,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 +7990,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 +9107,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; diff --git a/src/r_draw.c b/src/r_draw.c index 60927434..560f3063 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 0ff19bc7..c43d1579 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/s_sound.c b/src/s_sound.c index 422a00a1..2c88b78e 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1199,7 +1199,7 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t approx_dist <<= FRACBITS; - return approx_dist; + return FixedDiv(approx_dist, mapheaderinfo[gamemap-1]->mobj_scale); // approx_dist } // diff --git a/src/sounds.c b/src/sounds.c index 5531e7a3..b6bf7f55 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -792,6 +792,8 @@ 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) + {"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 e93a17a4..5ca6be1c 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -867,6 +867,8 @@ typedef enum sfx_itrol7, sfx_itrol8, sfx_itrolf, + sfx_itrolm, + sfx_itrolk, sfx_itrole, sfx_vroom, sfx_chaooo,