diff --git a/src/d_main.c b/src/d_main.c index 29a91686..5cf95f4b 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1162,7 +1162,7 @@ void D_SRB2Main(void) if (s) // Check for NULL? { if (!W_VerifyNMUSlumps(s)) - G_SetGameModified(true); + G_SetGameModified(true, false); D_AddFile(s); } } @@ -1189,7 +1189,7 @@ void D_SRB2Main(void) else { if (!M_CheckParm("-server")) - G_SetGameModified(true); + G_SetGameModified(true, true); autostart = true; } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d8c81f65..6df7718e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2209,10 +2209,12 @@ static void Command_Map_f(void) return; } - if (!(netgame || multiplayer) && (!modifiedgame || savemoddata)) + if (!(netgame || multiplayer) && !majormods) { if (COM_CheckParm("-force")) - G_SetGameModified(false); + { + G_SetGameModified(false, true); + } else { CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); @@ -3791,7 +3793,7 @@ static void Command_RunSOC(void) if (!P_RunSOC(fn)) CONS_Printf(M_GetText("Could not find SOC.\n")); else - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, false); return; } @@ -3845,7 +3847,7 @@ static void Got_RunSOCcmd(UINT8 **cp, INT32 playernum) } P_RunSOC(filename); - G_SetGameModified(true); + G_SetGameModified(true, false); } /** Adds a pwad at runtime. @@ -3882,7 +3884,7 @@ static void Command_Addfile(void) CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; } - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, false); } // Add file on your client directly if it is trivial, or you aren't in a netgame. @@ -4128,7 +4130,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum) return; } - G_SetGameModified(true); + G_SetGameModified(true, false); } static void Command_ListWADS_f(void) @@ -4485,7 +4487,7 @@ static void Ringslinger_OnChange(void) } if (cv_ringslinger.value) // Only if it's been turned on - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } static void Gravity_OnChange(void) @@ -4506,7 +4508,7 @@ static void Gravity_OnChange(void) #endif if (!CV_IsSetToDefault(&cv_gravity)) - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); gravity = cv_gravity.value; } @@ -4902,7 +4904,7 @@ static void Fishcake_OnChange(void) // so don't make modifiedgame always on! if (cv_debug) { - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } else if (cv_debug != cv_fishcake.value) @@ -4918,12 +4920,14 @@ static void Fishcake_OnChange(void) */ static void Command_Isgamemodified_f(void) { - if (savemoddata) - CONS_Printf(M_GetText("modifiedgame is true, but you can save medal and record data in this mod.\n")); + if (majormods) + CONS_Printf("The game has been modified with major add-ons, so you cannot play Record Attack.\n"); + else if (savemoddata) + CONS_Printf("The game has been modified with an add-on with its own save data, so you can play Record Attack and earn medals.\n"); else if (modifiedgame) - CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n")); + CONS_Printf("The game has been modified with only minor add-ons. You can play Record Attack, earn medals and unlock extras.\n"); else - CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n")); + CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n"); } static void Command_Cheats_f(void) diff --git a/src/d_netfil.c b/src/d_netfil.c index c7cfdbc1..99a05840 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -426,7 +426,7 @@ void CL_LoadServerFiles(void) else if (fileneeded[i].status == FS_FOUND) { P_AddWadFile(fileneeded[i].filename); - G_SetGameModified(true); + G_SetGameModified(true, false); fileneeded[i].status = FS_OPEN; } else if (fileneeded[i].status == FS_MD5SUMBAD) diff --git a/src/dehacked.c b/src/dehacked.c index b9e29bc4..0ad67ff0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -21,6 +21,7 @@ #include "w_wad.h" #include "m_menu.h" #include "m_misc.h" +#include "filesrch.h" // for refreshdirmenu #include "f_finale.h" #include "dehacked.h" #include "st_stuff.h" @@ -79,8 +80,6 @@ static powertype_t get_power(const char *word); boolean deh_loaded = false; static int dbg_line; -static boolean gamedataadded = false; - #ifdef DELFILE typedef struct undehacked_s { @@ -602,6 +601,14 @@ done: Z_Free(s); } +static int freeslotusage[2][2] = {{0, 0}, {0, 0}}; // [S_, MT_][max, previous .wad's max] + +void DEH_UpdateMaxFreeslots(void) +{ + freeslotusage[0][1] = freeslotusage[0][0]; + freeslotusage[1][1] = freeslotusage[1][0]; +} + // TODO: Figure out how to do undolines for this.... // TODO: Warnings for running out of freeslots static void readfreeslots(MYFILE *f) @@ -664,6 +671,7 @@ static void readfreeslots(MYFILE *f) if (!FREE_STATES[i]) { FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_STATES[i],word); + freeslotusage[0][0]++; break; } } @@ -673,6 +681,7 @@ static void readfreeslots(MYFILE *f) if (!FREE_MOBJS[i]) { FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_MOBJS[i],word); + freeslotusage[1][0]++; break; } } @@ -3139,6 +3148,7 @@ static void readmaincfg(MYFILE *f) strlcpy(gamedatafilename, word2, sizeof (gamedatafilename)); strlwr(gamedatafilename); savemoddata = true; + majormods = false; // Also save a time attack folder filenamelen = strlen(gamedatafilename)-4; // Strip off the extension @@ -3151,7 +3161,7 @@ static void readmaincfg(MYFILE *f) // can't use sprintf since there is %u in savegamename strcatbf(savegamename, srb2home, PATHSEP); - gamedataadded = true; + refreshdirmenu |= REFRESHDIR_GAMEDATA; } else if (fastcmp(word, "RESETDATA")) { @@ -3382,8 +3392,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) for (i = 0; i < NUMSFX; i++) savesfxnames[i] = S_sfx[i].name; - gamedataadded = false; - // it doesn't test the version of SRB2 and version of dehacked file dbg_line = -1; // start at -1 so the first line is 0. while (!myfeof(f)) @@ -3417,10 +3425,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) if (fastcmp(word, "FREESLOT")) { readfreeslots(f); + // This is not a major mod. continue; } else if (fastcmp(word, "MAINCFG")) { + G_SetGameModified(multiplayer, true); readmaincfg(f); DEH_WriteUndoline(word, "", UNDO_HEADER); continue; @@ -3429,6 +3439,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) { readwipes(f); DEH_WriteUndoline(word, "", UNDO_HEADER); + // This is not a major mod. continue; } word2 = strtok(NULL, " "); @@ -3449,6 +3460,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. continue; } if (word2) @@ -3462,19 +3474,25 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) // Read texture from spec file. readtexture(f, word2); DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. } else if (fastcmp(word, "PATCH")) { // Read patch from spec file. readpatch(f, word2, wad); DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. } else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_mobjtype(word2); // find a thing by name if (i < NUMMOBJTYPES && i >= 0) + { + if (i < (MT_FIRSTFREESLOT+freeslotusage[1][1])) + G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED readthing(f, i); + } else { deh_warning("Thing %d out of range (0 - %d)", i, NUMMOBJTYPES-1); @@ -3485,6 +3503,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) /* else if (fastcmp(word, "ANIMTEX")) { readAnimTex(f, i); + // This is not a major mod. }*/ else if (fastcmp(word, "LIGHT")) { @@ -3498,6 +3517,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. #endif } else if (fastcmp(word, "SPRITE")) @@ -3513,6 +3533,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. #endif } else if (fastcmp(word, "LEVEL")) @@ -3525,7 +3546,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) i = M_MapNumber(word2[0], word2[1]); if (i > 0 && i <= NUMMAPS) + { + if (mapheaderinfo[i]) + G_SetGameModified(multiplayer, true); // only mark as a major mod if it replaces an already-existing mapheaderinfo readlevelheader(f, i); + } else { deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS); @@ -3543,13 +3568,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + //G_SetGameModified(multiplayer, true); -- might have to reconsider in a future update } else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE")) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_state(word2); // find a state by name if (i < NUMSTATES && i >= 0) + { + if (i < (S_FIRSTFREESLOT+freeslotusage[0][1])) + G_SetGameModified(multiplayer, true); // affecting something earlier than the first freeslot allocated in this .wad? DENIED readframe(f, i); + } else { deh_warning("Frame %d out of range (0 - %d)", i, NUMSTATES-1); @@ -3578,6 +3608,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) } else deh_warning("pointer (Frame %d) : missing ')'", i); + G_SetGameModified(multiplayer, true); }*/ else if (fastcmp(word, "SOUND")) { @@ -3591,6 +3622,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. } /* else if (fastcmp(word, "SPRITE")) { @@ -3611,6 +3643,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) } else deh_warning("Sprite %d doesn't exist",i); + // This is not a major mod. }*/ else if (fastcmp(word, "HUDITEM")) { @@ -3624,10 +3657,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) ignorelines(f); } DEH_WriteUndoline(word, word2, UNDO_HEADER); + // This is not a major mod. } else if (fastcmp(word, "EMBLEM")) { - if (!gamedataadded) + if (!(refreshdirmenu & REFRESHDIR_GAMEDATA)) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3647,7 +3681,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) } else if (fastcmp(word, "EXTRAEMBLEM")) { - if (!gamedataadded) + if (!(refreshdirmenu & REFRESHDIR_GAMEDATA)) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3667,7 +3701,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) } else if (fastcmp(word, "UNLOCKABLE")) { - if (!gamedataadded) + if (!(refreshdirmenu & REFRESHDIR_GAMEDATA)) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3683,7 +3717,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) } else if (fastcmp(word, "CONDITIONSET")) { - if (!gamedataadded) + if (!(refreshdirmenu & REFRESHDIR_GAMEDATA)) { deh_warning("You must define a custom gamedata to use \"%s\"", word); ignorelines(f); @@ -3718,7 +3752,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) { boolean clearall = (fastcmp(word2, "ALL")); - if (!gamedataadded) + if (!(refreshdirmenu & REFRESHDIR_GAMEDATA)) { deh_warning("You must define a custom gamedata to use \"%s\"", word); continue; @@ -3755,8 +3789,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_warning("No word in this line: %s", s); } // end while - if (gamedataadded) - G_LoadGameData(); + /*if (gamedataadded) -- REFRESHDIR_GAMEDATA murdered this + G_LoadGameData();*/ dbg_line = -1; if (deh_num_warning) @@ -9356,6 +9390,7 @@ static inline int lib_freeslot(lua_State *L) CONS_Printf("State S_%s allocated.\n",word); FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_STATES[i],word); + freeslotusage[0][0]++; lua_pushinteger(L, i); r++; break; @@ -9371,6 +9406,7 @@ static inline int lib_freeslot(lua_State *L) CONS_Printf("MobjType MT_%s allocated.\n",word); FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL); strcpy(FREE_MOBJS[i],word); + freeslotusage[1][0]++; lua_pushinteger(L, i); r++; break; @@ -9740,6 +9776,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"modifiedgame")) { lua_pushboolean(L, modifiedgame && !savemoddata); return 1; + } else if (fastcmp(word,"majormods")) { + lua_pushboolean(L, majormods); + return 1; } else if (fastcmp(word,"menuactive")) { lua_pushboolean(L, menuactive); return 1; diff --git a/src/dehacked.h b/src/dehacked.h index 683fe7d9..0d6cc902 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -37,6 +37,8 @@ void DEH_UnloadDehackedWad(UINT16 wad); void DEH_LoadDehackedLump(lumpnum_t lumpnum); void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump); +void DEH_UpdateMaxFreeslots(void); + void DEH_Check(void); fixed_t get_number(const char *word); diff --git a/src/doomstat.h b/src/doomstat.h index 6d710e28..9ae2726d 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -54,6 +54,7 @@ extern boolean gamecomplete; // Set if homebrew PWAD stuff has been added. extern boolean modifiedgame; +extern boolean majormods; extern UINT16 mainwads; extern boolean savemoddata; // This mod saves time/emblem data. extern boolean disableSpeedAdjust; // Don't alter the duration of player states if true @@ -280,6 +281,8 @@ typedef struct #define LF2_NIGHTSATTACK 8 ///< Show this map in NiGHTS mode menu #define LF2_NOVISITNEEDED 16 ///< Available in time attack/nights mode without visiting the level +#define LF2_EXISTSHACK 128 ///< Map lump exists; as noted, a single-bit hack that can be freely movable to other variables without concern. + // Save override #define SAVE_NEVER -1 #define SAVE_DEFAULT 0 diff --git a/src/filesrch.h b/src/filesrch.h index 4186271b..01a52848 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -88,7 +88,8 @@ typedef enum REFRESHDIR_WARNING = 4, REFRESHDIR_ERROR = 8, REFRESHDIR_NOTLOADED = 16, - REFRESHDIR_MAX = 32 + REFRESHDIR_MAX = 32, + REFRESHDIR_GAMEDATA = 64 } refreshdir_enum; void closefilemenu(boolean validsize); diff --git a/src/g_game.c b/src/g_game.c index ee004b64..5014e781 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -16,6 +16,7 @@ #include "d_main.h" #include "d_player.h" #include "f_finale.h" +#include "filesrch.h" // for refreshdirmenu #include "p_setup.h" #include "p_saveg.h" #include "i_system.h" @@ -86,7 +87,8 @@ INT16 lastmapsaved = 0; // Last map we auto-saved at boolean gamecomplete = false; UINT16 mainwads = 0; -boolean modifiedgame; // Set if homebrew PWAD stuff has been added. +boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added. +boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added. boolean savemoddata = false; UINT8 paused; UINT8 modeattacking = ATTACKING_NONE; @@ -752,16 +754,21 @@ void G_SetNightsRecords(void) }*/ // for consistency among messages: this modifies the game and removes savemoddata. -void G_SetGameModified(boolean silent) +void G_SetGameModified(boolean silent, boolean major) { - if (modifiedgame && !savemoddata) + if ((majormods && modifiedgame) || !mainwads || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty? return; modifiedgame = true; - savemoddata = false; + + if (!major) + return; + + //savemoddata = false; -- there is literally no reason to do this anymore. + majormods = true; if (!silent) - CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n")); + CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\n")); // If in record attack recording, cancel it. if (modeattacking) @@ -3942,7 +3949,6 @@ void G_LoadGameData(void) // Saves the main data file, which stores information such as emblems found, etc. void G_SaveGameData(boolean force) { - const boolean wasmodified = modifiedgame; size_t length; INT32 i, j; UINT8 btemp; @@ -3959,9 +3965,7 @@ void G_SaveGameData(boolean force) return; } - if (force) // SRB2Kart: for enabling unlocks online, even if the game is modified - modifiedgame = savemoddata; // L-let's just sort of... hack around the cheat protection, because I'm too worried about just removing it @@; - else if (modifiedgame && !savemoddata) + if (majormods && !force) { free(savebuffer); save_p = savebuffer = NULL; @@ -3974,7 +3978,7 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); - btemp = (UINT8)(savemoddata || modifiedgame); + btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded WRITEUINT8(save_p, btemp); // TODO put another cipher on these things? meh, I don't care... @@ -4060,9 +4064,6 @@ void G_SaveGameData(boolean force) FIL_WriteFile(va(pandf, srb2home, gamedatafilename), savebuffer, length); free(savebuffer); save_p = savebuffer = NULL; - - if (force) // Eeeek, I'm sorry for my sins! - modifiedgame = wasmodified; } #define VERSIONSIZE 16 @@ -5921,6 +5922,32 @@ void G_DoPlayDemo(char *defdemoname) return; } + // Skin not loaded? + if (!SetPlayerSkin(0, skin)) + { + snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + + // ...*map* not loaded? + if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK)) + { + snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demoplayback = false; + titledemo = false; + return; + } + Z_Free(pdemoname); memset(&oldcmd,0,sizeof(oldcmd)); @@ -5952,9 +5979,6 @@ void G_DoPlayDemo(char *defdemoname) P_SetRandSeed(randseed); G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. - // Set skin - SetPlayerSkin(0, skin); - // Set color for (i = 0; i < MAXSKINCOLORS; i++) if (!stricmp(KartColor_Names[i],color)) // SRB2kart @@ -6004,6 +6028,7 @@ void G_AddGhost(char *defdemoname) UINT8 *buffer,*p; mapthing_t *mthing; UINT16 count, ghostversion; + skin_t *ghskin = &skins[0]; name[16] = '\0'; skin[16] = '\0'; @@ -6149,6 +6174,21 @@ void G_AddGhost(char *defdemoname) return; } + for (i = 0; i < numskins; i++) + if (!stricmp(skins[i].name,skin)) + { + ghskin = &skins[i]; + break; + } + + if (i == numskins) + { + CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid character.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + gh = Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL); gh->next = ghosts; gh->buffer = buffer; @@ -6194,14 +6234,7 @@ void G_AddGhost(char *defdemoname) gh->oldmo.z = gh->mo->z; // Set skin - gh->mo->skin = &skins[0]; - for (i = 0; i < numskins; i++) - if (!stricmp(skins[i].name,skin)) - { - gh->mo->skin = &skins[i]; - break; - } - gh->oldmo.skin = gh->mo->skin; + gh->mo->skin = gh->oldmo.skin = ghskin; // Set color gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor; diff --git a/src/g_game.h b/src/g_game.h index 6d11a4a0..fc7a4a4f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -226,7 +226,7 @@ boolean G_GetRetryFlag(void); void G_LoadGameData(void); void G_LoadGameSettings(void); -void G_SetGameModified(boolean silent); +void G_SetGameModified(boolean silent, boolean major); void G_SetGamestate(gamestate_t newstate); diff --git a/src/lua_script.c b/src/lua_script.c index 34a26052..1f87d33e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -212,6 +212,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump) LUA_LoadFile(&f, name); // actually load file! + // Okay, we've modified the game beyond the point of no return. + G_SetGameModified(multiplayer, true); + free(name); Z_Free(f.data); } diff --git a/src/m_cheat.c b/src/m_cheat.c index 38d8cc7a..2fc2e85c 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -121,7 +121,7 @@ static UINT8 cheatf_devmode(void) S_StartSound(0, sfx_itemup); // Just unlock all the things and turn on -debug and console devmode. - G_SetGameModified(false); + G_SetGameModified(false, false); // might need to revist the latter later for (i = 0; i < MAXUNLOCKABLES; i++) unlockables[i].unlocked = true; devparm = true; @@ -295,7 +295,7 @@ void Command_CheatNoClip_f(void) plyr->pflags ^= PF_NOCLIP; CONS_Printf(M_GetText("No Clipping %s\n"), plyr->pflags & PF_NOCLIP ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } void Command_CheatGod_f(void) @@ -310,7 +310,7 @@ void Command_CheatGod_f(void) plyr->pflags ^= PF_GODMODE; CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } void Command_CheatNoTarget_f(void) @@ -325,7 +325,7 @@ void Command_CheatNoTarget_f(void) plyr->pflags ^= PF_INVIS; CONS_Printf(M_GetText("SEP Field %s\n"), plyr->pflags & PF_INVIS ? M_GetText("On") : M_GetText("Off")); - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } void Command_Scale_f(void) @@ -727,7 +727,7 @@ void Command_Devmode_f(void) return; } - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } /*void Command_Setrings_f(void) @@ -1267,7 +1267,7 @@ void Command_ObjectPlace_f(void) REQUIRE_SINGLEPLAYER; REQUIRE_NOULTIMATE; - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); // Entering objectplace? if (!objectplacing) diff --git a/src/m_cond.c b/src/m_cond.c index 35eccd1c..b777e7d2 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -385,8 +385,7 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force) char cechoText[992] = ""; UINT8 cechoLines = 0; - if (modifiedgame && !savemoddata - && !force) // SRB2Kart: for enabling unlocks online in modified servers + if (majormods && !force) // SRB2Kart: for enabling unlocks online in modified servers return false; M_CheckUnlockConditions(); diff --git a/src/m_menu.c b/src/m_menu.c index f0831a17..ee94ab3c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -274,14 +274,13 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; #ifndef NONET static void M_StartServerMenu(INT32 choice); static void M_ConnectMenu(INT32 choice); -#endif -static void M_StartOfflineServerMenu(INT32 choice); -static void M_StartServer(INT32 choice); -#ifndef NONET +static void M_ConnectMenuModChecks(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); #endif +static void M_StartOfflineServerMenu(INT32 choice); +static void M_StartServer(INT32 choice); static void M_SetupMultiPlayer(INT32 choice); static void M_SetupMultiPlayer2(INT32 choice); static void M_SetupMultiPlayer3(INT32 choice); @@ -935,11 +934,11 @@ static menuitem_t MP_MainMenu[] = {IT_HEADER, NULL, "Join a game", NULL, 132-24}, #ifndef NONET - {IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenu, 142-24}, + {IT_STRING|IT_CALL, NULL, "Internet server browser...",M_ConnectMenuModChecks, 142-24}, {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24}, #else - {IT_GRAYEDOUT, NULL, "Internet server browser...",M_ConnectMenu, 142-24}, - {IT_GRAYEDOUT, NULL, "Specify IPv4 address:", M_HandleConnectIP, 150-24}, + {IT_GRAYEDOUT, NULL, "Internet server browser...",NULL, 142-24}, + {IT_GRAYEDOUT, NULL, "Specify IPv4 address:", NULL, 150-24}, #endif //{IT_HEADER, NULL, "Player setup", NULL, 80}, //{IT_STRING|IT_CALL, NULL, "Name, character, color...", M_SetupMultiPlayer, 90}, @@ -2739,10 +2738,10 @@ boolean M_Responder(event_t *ev) || (currentMenu->menuitems[itemOn].status & IT_TYPE)==IT_SUBMENU) && (currentMenu->menuitems[itemOn].status & IT_CALLTYPE)) { - if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && modifiedgame && !savemoddata) + if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods) { S_StartSound(NULL, sfx_menu1); - M_StartMessage(M_GetText("This cannot be done with add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); + M_StartMessage(M_GetText("This cannot be done with complex add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); return true; } } @@ -4527,9 +4526,14 @@ static char *M_AddonsHeaderPath(void) #define CLEARNAME Z_Free(refreshdirname);\ refreshdirname = NULL +static boolean prevmajormods = false; + static void M_AddonsClearName(INT32 choice) { - CLEARNAME; + if (!majormods || prevmajormods) + { + CLEARNAME; + } M_StopMessage(choice); } @@ -4539,10 +4543,17 @@ static boolean M_AddonsRefresh(void) if ((refreshdirmenu & REFRESHDIR_NORMAL) && !preparefilemenu(true)) { UNEXIST; + if (refreshdirname) + { + CLEARNAME; + } return true; } - if (refreshdirmenu & REFRESHDIR_ADDFILE) + if (!majormods && prevmajormods) + prevmajormods = false; + + if ((refreshdirmenu & REFRESHDIR_ADDFILE) || (majormods && !prevmajormods)) { char *message = NULL; @@ -4550,7 +4561,7 @@ static boolean M_AddonsRefresh(void) { S_StartSound(NULL, sfx_s26d); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nif you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); else message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); } @@ -4559,6 +4570,12 @@ static boolean M_AddonsRefresh(void) S_StartSound(NULL, sfx_s224); message = va("%c%s\x80\nA file was loaded with %s.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname, ((refreshdirmenu & REFRESHDIR_ERROR) ? "errors" : "warnings")); } + else if (majormods && !prevmajormods) + { + S_StartSound(NULL, sfx_s221); + message = va("%c%s\x80\nGameplay has now been modified.\nif you wish to play record attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + prevmajormods = majormods; + } if (message) { @@ -4709,7 +4726,7 @@ static void M_DrawAddons(void) V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]); x = BASEVIDWIDTH - x - 16; - V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); + V_DrawSmallScaledPatch(x, y + 4, ((!majormods) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]); if (modifiedgame) V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]); @@ -5106,7 +5123,7 @@ static void M_GetAllEmeralds(INT32 choice) emeralds = ((EMERALD7)*2)-1; M_StartMessage(M_GetText("You now have all 7 emeralds.\nUse them wisely.\nWith great power comes great ring drain.\n"),NULL,MM_NOTHING); - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } static void M_DestroyRobotsResponse(INT32 ch) @@ -5117,7 +5134,7 @@ static void M_DestroyRobotsResponse(INT32 ch) // Destroy all robots P_DestroyRobots(); - G_SetGameModified(multiplayer); + G_SetGameModified(multiplayer, true); } static void M_DestroyRobots(INT32 choice) @@ -7384,6 +7401,20 @@ static void M_ConnectMenu(INT32 choice) M_Refresh(0); } +static void M_ConnectMenuModChecks(INT32 choice) +{ + (void)choice; + // okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work + + if (modifiedgame) + { + M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); + return; + } + + M_ConnectMenu(-1); +} + static UINT32 roomIds[NUM_LIST_ROOMS]; static void M_RoomMenu(INT32 choice) diff --git a/src/p_map.c b/src/p_map.c index c307e572..051a1e6f 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3231,129 +3231,6 @@ isblocking: return false; // stop } -// -// P_IsClimbingValid -// -// Unlike P_DoClimbing, don't use when up against a one-sided linedef. -// -static boolean P_IsClimbingValid(player_t *player, angle_t angle) -{ - fixed_t platx, platy; - subsector_t *glidesector; - fixed_t floorz, ceilingz; - - platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); - - glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); - -#ifdef ESLOPE - floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; - ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; -#else - floorz = glidesector->sector->floorheight; - ceilingz = glidesector->sector->ceilingheight; -#endif - - if (glidesector->sector != player->mo->subsector->sector) - { - boolean floorclimb = false; - fixed_t topheight, bottomheight; - - if (glidesector->sector->ffloors) - { - ffloor_t *rover; - for (rover = glidesector->sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); -#endif - - floorclimb = true; - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) - { - floorclimb = true; - } - if (topheight < player->mo->z) // Waaaay below the ledge. - { - floorclimb = false; - } - if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - else - { - if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) - { - floorclimb = true; - } - if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. - { - floorclimb = false; - } - if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) - { - floorclimb = false; - } - } - - if (floorclimb) - break; - } - } - - if (player->mo->eflags & MFE_VERTICALFLIP) - { - if ((floorz <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) - floorclimb = true; - - if ((floorz > player->mo->z) - && glidesector->sector->floorpic == skyflatnum) - return false; - - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) - || (player->mo->z + player->mo->height <= floorz)) - floorclimb = true; - } - else - { - if ((ceilingz >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= ceilingz)) - floorclimb = true; - - if ((ceilingz < player->mo->z+player->mo->height) - && glidesector->sector->ceilingpic == skyflatnum) - return false; - - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz) - || (player->mo->z >= ceilingz)) - floorclimb = true; - } - - if (!floorclimb) - return false; - - return true; - } - - return false; -} - // // PTR_SlideTraverse // @@ -3407,117 +3284,7 @@ isblocking: P_ProcessSpecialSector(slidemo->player, slidemo->subsector->sector, li->polyobj->lines[0]->backsector); } - if (slidemo->player && (slidemo->player->pflags & PF_GLIDING || slidemo->player->climbing) - && slidemo->player->charability == CA_GLIDEANDCLIMB) - { - line_t *checkline = li; - sector_t *checksector; - ffloor_t *rover; - fixed_t topheight, bottomheight; - boolean fofline = false; - INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - if (!side && li->backsector) - checksector = li->backsector; - else - checksector = li->frontsector; - - if (checksector->ffloors) - { - for (rover = checksector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) - continue; - - topheight = *rover->topheight; - bottomheight = *rover->bottomheight; - -#ifdef ESLOPE - if (*rover->t_slope) - topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); - if (*rover->b_slope) - bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); -#endif - - if (topheight < slidemo->z) - continue; - - if (bottomheight > slidemo->z + slidemo->height) - continue; - - // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? - if (rover->master->flags & ML_TFERLINE) - { - size_t linenum = li-checksector->lines[0]; - checkline = rover->master->frontsector->lines[0] + linenum; - fofline = true; - } - - break; - } - } - - // see about climbing on the wall - if (!(checkline->flags & ML_NOCLIMB)) - { - boolean canclimb; - angle_t climbangle, climbline; - INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); - - climbangle = climbline = R_PointToAngle2(li->v1->x, li->v1->y, li->v2->x, li->v2->y); - - if (whichside) // on second side? - climbline += ANGLE_180; - - climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - - canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true); - - if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) - || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) - && canclimb) - { - slidemo->angle = climbangle; - if (!demoplayback || P_AnalogMove(slidemo->player)) - { - if (slidemo->player == &players[consoleplayer]) - localangle = slidemo->angle; - else if (slidemo->player == &players[secondarydisplayplayer]) - localangle2 = slidemo->angle; - else if (slidemo->player == &players[thirddisplayplayer]) - localangle3 = slidemo->angle; - else if (slidemo->player == &players[fourthdisplayplayer]) - localangle4 = slidemo->angle; - } - - if (!slidemo->player->climbing) - { - S_StartSound(slidemo->player->mo, sfx_s3k4a); - slidemo->player->climbing = 5; - } - - slidemo->player->pflags &= ~(PF_GLIDING|PF_SPINNING|PF_JUMPED|PF_THOKKED); - slidemo->player->glidetime = 0; - slidemo->player->secondjump = 0; - - if (slidemo->player->climbing > 1) - slidemo->momz = slidemo->momx = slidemo->momy = 0; - - if (fofline) - whichside = 0; - - if (!whichside) - { - slidemo->player->lastsidehit = checkline->sidenum[whichside]; - slidemo->player->lastlinehit = (INT16)(checkline - lines); - } - - P_Thrust(slidemo, slidemo->angle, FixedMul(5*FRACUNIT, slidemo->scale)); - } - } - } - - if (in->frac < bestslidefrac && (!slidemo->player || !slidemo->player->climbing)) + if (in->frac < bestslidefrac) { secondslidefrac = bestslidefrac; secondslideline = bestslideline; diff --git a/src/p_mobj.c b/src/p_mobj.c index f71ff209..d380b97a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3233,8 +3233,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) #endif *rover->topheight; - if (!(player->pflags & PF_NIGHTSMODE) && !player->homing - && (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height) + if (((player->charflags & SF_RUNONWATER) && player->mo->ceilingz-topheight >= player->mo->height) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) && abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) diff --git a/src/p_setup.c b/src/p_setup.c index 49b22184..912791cf 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -234,7 +234,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); mapheaderinfo[num]->levelflags = 0; DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); - mapheaderinfo[num]->menuflags = 0; + mapheaderinfo[num]->menuflags = (mainwads ? 0 : LF2_EXISTSHACK); // see p_setup.c - prevents replacing maps in addons with easier versions // TODO grades support for delfile (pfft yeah right) P_DeleteGrades(num); // SRB2Kart @@ -1120,7 +1120,7 @@ static inline void P_SpawnEmblems(void) static void P_SpawnSecretItems(boolean loademblems) { // Now let's spawn those funky emblem things! Tails 12-08-2002 - if (netgame || multiplayer || (modifiedgame && !savemoddata)) // No cheating!! + if (netgame || multiplayer || majormods) // No cheating!! return; if (loademblems) @@ -3272,7 +3272,7 @@ boolean P_SetupLevel(boolean skipprecip) nextmapoverride = 0; skipstats = false; - if (!(netgame || multiplayer) && (!modifiedgame || savemoddata)) + if (!(netgame || multiplayer) && !majormods) mapvisited[gamemap-1] |= MV_VISITED; levelloading = false; @@ -3455,6 +3455,14 @@ boolean P_AddWadFile(const char *wadfilename) continue; num = (INT16)M_MapNumber(name[3], name[4]); + // we want to record whether this map exists. if it doesn't have a header, we can assume it's not relephant + if (num <= NUMMAPS && mapheaderinfo[num-1]) + { + if (mapheaderinfo[num-1]->menuflags & LF2_EXISTSHACK) + G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you + mapheaderinfo[num-1]->menuflags |= LF2_EXISTSHACK; + } + //If you replaced the map you're on, end the level when done. if (num == gamemap) replacedcurrentmap = true; @@ -3481,6 +3489,8 @@ boolean P_AddWadFile(const char *wadfilename) SendNetXCmd(XD_EXITLEVEL, NULL, 0); } + refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_GAMEDATA to disappear the next frame, but it's a bit too dangerous for that... + return true; } diff --git a/src/p_spec.c b/src/p_spec.c index ca4967ce..24f56c43 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1758,12 +1758,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller switch (specialtype) { - case 305: // continuous + /*case 305: // continuous case 306: // each time case 307: // once if (!(actor && actor->player && actor->player->charability == dist/10)) return false; - break; + break;*/ case 309: // continuous case 310: // each time // Only red team members can activate this. @@ -3864,14 +3864,6 @@ DoneSection2: P_InstaThrust(player->mo, player->mo->angle, linespeed); - /*if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH)) // SRB2kart - { - if (!(player->pflags & PF_SPINNING)) - player->pflags |= PF_SPINNING; - - //P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); - }*/ - player->kartstuff[k_dashpadcooldown] = TICRATE/3; player->kartstuff[k_drift] = 0; player->kartstuff[k_driftcharge] = 0; @@ -5781,7 +5773,7 @@ void P_SpawnSpecials(INT32 fromnetsave) lines[i].special = 0; continue; } - /*else -- commented out because irrelevant to kart + /*else -- commented out because irrelevant to kart. keeping here because we can use these flags for something else now { if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) || (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) @@ -7997,12 +7989,13 @@ static void P_SearchForDisableLinedefs(void) } else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY) continue; // Net-only never triggers in single player - else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) + // commented out because irrelevant to kart. keeping here because we can use these flags for something else now + /*else if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) continue; else if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) continue; else if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)) - continue; + continue;*/ // Disable any linedef specials with our tag. for (j = -1; (j = P_FindLineFromLineTag(&lines[i], j)) >= 0;) diff --git a/src/p_user.c b/src/p_user.c index d7423d80..ce411d2d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7323,74 +7323,6 @@ static void P_MovePlayer(player_t *player) if (CheckForBustableBlocks) P_CheckBustableBlocks(player); - // Special handling for - // gliding in 2D mode - if ((twodlevel || player->mo->flags2 & MF2_TWOD) && player->pflags & PF_GLIDING && player->charability == CA_GLIDEANDCLIMB - && !(player->mo->flags & MF_NOCLIP)) - { - msecnode_t *node; // only place it's being used in P_MovePlayer now - fixed_t oldx; - fixed_t oldy; - fixed_t floorz, ceilingz; - - oldx = player->mo->x; - oldy = player->mo->y; - - P_UnsetThingPosition(player->mo); - player->mo->x += player->mo->momx; - player->mo->y += player->mo->momy; - P_SetThingPosition(player->mo); - - for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (!node->m_sector) - break; - - if (node->m_sector->ffloors) - { - ffloor_t *rover; - fixed_t topheight, bottomheight; - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) - continue; - - topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); - if (topheight > player->mo->z && bottomheight < player->mo->z) - { - P_ResetPlayer(player); - S_StartSound(player->mo, sfx_s3k4a); - player->climbing = 5; - player->mo->momx = player->mo->momy = player->mo->momz = 0; - break; - } - } - } - - floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); - ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL); - - if (player->mo->z+player->mo->height > ceilingz - && node->m_sector->ceilingpic == skyflatnum) - continue; - - if (floorz > player->mo->z || ceilingz < player->mo->z) - { - P_ResetPlayer(player); - S_StartSound(player->mo, sfx_s3k4a); - player->climbing = 5; - player->mo->momx = player->mo->momy = player->mo->momz = 0; - break; - } - } - P_UnsetThingPosition(player->mo); - player->mo->x = oldx; - player->mo->y = oldy; - P_SetThingPosition(player->mo); - } - // Check for a BOUNCY sector! if (CheckForBouncySector) P_CheckBouncySectors(player); diff --git a/src/r_things.c b/src/r_things.c index d6234d4b..135ae6a2 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2635,7 +2635,7 @@ INT32 R_SkinAvailable(const char *name) } // network code calls this when a 'skin change' is received -void SetPlayerSkin(INT32 playernum, const char *skinname) +boolean SetPlayerSkin(INT32 playernum, const char *skinname) { INT32 i; player_t *player = &players[playernum]; @@ -2646,7 +2646,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) if (stricmp(skins[i].name, skinname) == 0) { SetPlayerSkinByNum(playernum, i); - return; + return true; } } @@ -2656,6 +2656,7 @@ void SetPlayerSkin(INT32 playernum, const char *skinname) CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname); SetPlayerSkinByNum(playernum, 0); + return false; } // Same as SetPlayerSkin, but uses the skin #. @@ -2894,27 +2895,27 @@ void R_AddSkins(UINT16 wadnum) #define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value); // character type identification FULLPROCESS(flags) - FULLPROCESS(ability) - FULLPROCESS(ability2) + //FULLPROCESS(ability) + //FULLPROCESS(ability2) - FULLPROCESS(thokitem) - FULLPROCESS(spinitem) - FULLPROCESS(revitem) + //FULLPROCESS(thokitem) + //FULLPROCESS(spinitem) + //FULLPROCESS(revitem) #undef FULLPROCESS #define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<field = atoi(value); +/*#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); GETINT(thrustfactor) GETINT(accelstart) GETINT(acceleration) -#undef GETINT +#undef GETINT*/ #define GETKARTSTAT(field) \ else if (!stricmp(stoken, #field)) \ @@ -2933,8 +2934,8 @@ void R_AddSkins(UINT16 wadnum) else if (!stricmp(stoken, "prefcolor")) skin->prefcolor = K_GetKartColorByName(value); - else if (!stricmp(stoken, "jumpfactor")) - skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); + //else if (!stricmp(stoken, "jumpfactor")) + //skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); else if (!stricmp(stoken, "highresscale")) skin->highresscale = FLOAT_TO_FIXED(atof(value)); else @@ -3044,6 +3045,9 @@ next_token: HWR_AddPlayerMD2(numskins); #endif + if (skin->flags & SF_RUNONWATER) // this is literally the only way a skin can be a major mod... this might be a bit heavy handed + G_SetGameModified(multiplayer, true); + numskins++; } return; diff --git a/src/r_things.h b/src/r_things.h index 53784415..01d8fc07 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -194,7 +194,7 @@ typedef struct drawnode_s extern INT32 numskins; extern skin_t skins[MAXSKINS]; -void SetPlayerSkin(INT32 playernum,const char *skinname); +boolean SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 INT32 R_SkinAvailable(const char *name); void R_AddSkins(UINT16 wadnum); diff --git a/src/w_wad.c b/src/w_wad.c index 63bee97d..efa09ce4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -34,6 +34,7 @@ #include "z_zone.h" #include "fastcmp.h" +#include "g_game.h" // G_LoadGameData #include "filesrch.h" #include "i_video.h" // rendermode @@ -799,6 +800,10 @@ UINT16 W_InitFile(const char *filename) break; } + if (refreshdirmenu & REFRESHDIR_GAMEDATA) + G_LoadGameData(); + DEH_UpdateMaxFreeslots(); + W_InvalidateLumpnumCache(); return wadfile->numlumps; } diff --git a/src/y_inter.c b/src/y_inter.c index a8b1f740..6fe71bdc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -782,7 +782,7 @@ void Y_StartIntermission(void) } case int_race: // (time-only race) { - if ((!modifiedgame || savemoddata) && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen + if (!majormods && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen { // Update visitation flags mapvisited[gamemap-1] |= MV_BEATEN;