mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-25 20:01:04 +00:00
Merge branch 'majormods' into 'next'
Allow playing in Record Attack with minor add-ons See merge request KartKrew/Kart-Public!31
This commit is contained in:
commit
cf06f108ed
22 changed files with 239 additions and 414 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
81
src/g_game.c
81
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
61
src/m_menu.c
61
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)
|
||||
|
|
235
src/p_map.c
235
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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
19
src/p_spec.c
19
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;)
|
||||
|
|
68
src/p_user.c
68
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);
|
||||
|
|
|
@ -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)<<FRACBITS;
|
||||
GETSPEED(normalspeed)
|
||||
//GETSPEED(normalspeed)
|
||||
GETSPEED(runspeed)
|
||||
GETSPEED(mindash)
|
||||
GETSPEED(maxdash)
|
||||
GETSPEED(actionspd)
|
||||
//GETSPEED(mindash)
|
||||
//GETSPEED(maxdash)
|
||||
//GETSPEED(actionspd)
|
||||
#undef GETSPEED
|
||||
|
||||
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue