First steps at implementing a mechanism that allows you to load non-cheaty good-faith mods such as custom characters with no Lua scripting, and play record attack with them. Features a few bad hacks and a few more areas of improvement; I'll try to iron them out before they hit `next` or `master`.

This commit is contained in:
toaster 2019-01-15 19:01:55 +00:00
parent f53594cf81
commit 081872aa85
13 changed files with 91 additions and 25 deletions

View File

@ -1253,6 +1253,7 @@ void D_SRB2Main(void)
#endif //ifndef DEVELOP
mainwadstally = packetsizetally;
majormods = false;
cht_Init();

View File

@ -2214,10 +2214,13 @@ static void Command_Map_f(void)
return;
}
if (!(netgame || multiplayer) && (!modifiedgame || savemoddata))
if (!(netgame || multiplayer) && (!majormods || savemoddata))
{
if (COM_CheckParm("-force"))
{
G_SetGameModified(false);
majormods = true;
}
else
{
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
@ -4915,7 +4918,7 @@ 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"));
else if (modifiedgame)
else if (/*modifiedgame*/ majormods)
CONS_Printf(M_GetText("modifiedgame is true, extras will not be unlocked\n"));
else
CONS_Printf(M_GetText("modifiedgame is false, you can unlock extras\n"));

View File

@ -3417,18 +3417,21 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
if (fastcmp(word, "FREESLOT"))
{
readfreeslots(f);
majormods = true;
continue;
}
else if (fastcmp(word, "MAINCFG"))
{
readmaincfg(f);
DEH_WriteUndoline(word, "", UNDO_HEADER);
majormods = true;
continue;
}
else if (fastcmp(word, "WIPES"))
{
readwipes(f);
DEH_WriteUndoline(word, "", UNDO_HEADER);
//majormods = true;
continue;
}
word2 = strtok(NULL, " ");
@ -3449,6 +3452,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
continue;
}
if (word2)
@ -3462,12 +3466,14 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
// Read texture from spec file.
readtexture(f, word2);
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
}
else if (fastcmp(word, "PATCH"))
{
// Read patch from spec file.
readpatch(f, word2, wad);
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
}
else if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
{
@ -3481,10 +3487,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
/* else if (fastcmp(word, "ANIMTEX"))
{
readAnimTex(f, i);
//majormods = true;
}*/
else if (fastcmp(word, "LIGHT"))
{
@ -3498,6 +3506,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
#endif
}
else if (fastcmp(word, "SPRITE"))
@ -3513,6 +3522,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
#endif
}
else if (fastcmp(word, "LEVEL"))
@ -3525,7 +3535,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
i = M_MapNumber(word2[0], word2[1]);
if (i > 0 && i <= NUMMAPS)
{
if (mapheaderinfo[i])
majormods = 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,6 +3557,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true; -- might have to reconsider in a future update
}
else if (fastcmp(word, "FRAME") || fastcmp(word, "STATE"))
{
@ -3556,6 +3571,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
// <Callum> Added translations to this just in case its re-enabled
/* else if (fastcmp(word, "POINTER"))
@ -3578,6 +3594,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
}
else
deh_warning("pointer (Frame %d) : missing ')'", i);
majormods = true;
}*/
else if (fastcmp(word, "SOUND"))
{
@ -3591,6 +3608,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true; -- ...this won't bite me in the ass later, will it?
}
/* else if (fastcmp(word, "SPRITE"))
{
@ -3611,6 +3629,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
}
else
deh_warning("Sprite %d doesn't exist",i);
//majormods = true;
}*/
else if (fastcmp(word, "HUDITEM"))
{
@ -3624,6 +3643,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
//majormods = true;
}
else if (fastcmp(word, "EMBLEM"))
{
@ -3644,6 +3664,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
else if (fastcmp(word, "EXTRAEMBLEM"))
{
@ -3664,6 +3685,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
else if (fastcmp(word, "UNLOCKABLE"))
{
@ -3680,6 +3702,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
else if (fastcmp(word, "CONDITIONSET"))
{
@ -3697,6 +3720,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
}
// no undo support for this insanity yet
//DEH_WriteUndoline(word, word2, UNDO_HEADER);
majormods = true;
}
else if (fastcmp(word, "SRB2KART"))
{
@ -3743,6 +3767,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
if (clearall || fastcmp(word2, "LEVELS"))
clear_levels();
majormods = true;
}
else
deh_warning("Unknown word: %s", word);
@ -9737,7 +9763,7 @@ static inline int lib_getenum(lua_State *L)
lua_pushboolean(L, devparm);
return 1;
} else if (fastcmp(word,"modifiedgame")) {
lua_pushboolean(L, modifiedgame && !savemoddata);
lua_pushboolean(L, /*modifiedgame*/ majormods && !savemoddata);
return 1;
} else if (fastcmp(word,"menuactive")) {
lua_pushboolean(L, menuactive);

View File

@ -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

View File

@ -86,7 +86,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;
@ -5918,6 +5919,19 @@ 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 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));
@ -5949,9 +5963,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
@ -6146,6 +6157,22 @@ void G_AddGhost(char *defdemoname)
return;
}
gh->oldmo->skin = &skins[0];
for (i = 0; i < numskins; i++)
if (!stricmp(skins[i].name,skin))
{
gh->oldmo->skin = &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;
@ -6191,14 +6218,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;
// Set color
gh->mo->color = ((skin_t*)gh->mo->skin)->prefcolor;

View File

@ -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.
majormods = true;
free(name);
Z_Free(f.data);
}

View File

@ -1268,6 +1268,7 @@ void Command_ObjectPlace_f(void)
REQUIRE_NOULTIMATE;
G_SetGameModified(multiplayer);
majormods = true;
// Entering objectplace?
if (!objectplacing)

View File

@ -385,7 +385,7 @@ UINT8 M_UpdateUnlockablesAndExtraEmblems(boolean force)
char cechoText[992] = "";
UINT8 cechoLines = 0;
if (modifiedgame && !savemoddata
if (/*modifiedgame*/ majormods && !savemoddata
&& !force) // SRB2Kart: for enabling unlocks online in modified servers
return false;

View File

@ -2773,10 +2773,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) && /*modifiedgame*/ majormods && !savemoddata)
{
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;
}
}

View File

@ -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 || (/*modifiedgame*/ majormods && !savemoddata)) // 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) && (/*!modifiedgame*/ !majormods || savemoddata))
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)
majormods = 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;

View File

@ -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 #.

View File

@ -194,7 +194,7 @@ typedef struct drawnode_s
extern INT32 numskins;
extern skin_t skins[MAXSKINS + 1];
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);

View File

@ -786,7 +786,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 ((/*!modifiedgame*/ !majormods || savemoddata) && !multiplayer && !demoplayback) // remove this once we have a proper time attack screen
{
// Update visitation flags
mapvisited[gamemap-1] |= MV_BEATEN;