Merge pull request 'Add support for longmapnames' (#22) from longmapnames into ACS2
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/22
This commit is contained in:
commit
dcb3570475
57 changed files with 2249 additions and 2199 deletions
|
|
@ -42,7 +42,7 @@ additional lumps:
|
|||
|
||||
BEHAVIOR = Compiled ACS code.
|
||||
ZNODES = Compiled extended / GL friendly nodes. These are required.
|
||||
PICTURE = A Doom graphic lump, expected to be 160x100. Intended to be a
|
||||
PICTURE = A Doom graphic lump, expected to be 320x240 or 160x100. Intended to be a
|
||||
screenshot of the map itself. This is used by the game for level
|
||||
select menus.
|
||||
MINIMAP = A Doom graphic lump, expected to be 100x100. Intended to be a
|
||||
|
|
|
|||
|
|
@ -3054,7 +3054,7 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor
|
|||
const char *levelName = NULL;
|
||||
size_t levelLen = 0;
|
||||
|
||||
UINT16 nextmap = NUMMAPS;
|
||||
UINT16 nextmap = NEXTMAP_INVALID;
|
||||
|
||||
(void)argC;
|
||||
|
||||
|
|
@ -3075,13 +3075,10 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor
|
|||
{
|
||||
CONS_Alert(CONS_WARNING, "MapWarp level name was not provided.\n");
|
||||
}
|
||||
|
||||
if (levelName[0] == 'M' && levelName[1] == 'A' && levelName[2] == 'P' && levelName[5]=='\0')
|
||||
{
|
||||
levelName = va("MAP%d",M_MapNumber(levelName[3], levelName[4]));
|
||||
}
|
||||
|
||||
if (nextmap >= NUMMAPS)
|
||||
nextmap = G_MapNumber(levelName);
|
||||
|
||||
if (nextmap == NEXTMAP_INVALID)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "MapWarp level %s is not valid or loaded.\n", levelName);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1992,42 +1992,9 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
|
||||
if (var->PossibleValue)
|
||||
{
|
||||
if (var == &cv_nextmap)
|
||||
{
|
||||
// Special case for the nextmap variable, used only directly from the menu
|
||||
INT32 oldvalue = var->value - 1, gt;
|
||||
gt = cv_newgametype.value;
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
do
|
||||
{
|
||||
if(increment > 0) // Going up!
|
||||
{
|
||||
if (++newvalue == NUMMAPS)
|
||||
newvalue = -1;
|
||||
}
|
||||
else // Going down!
|
||||
{
|
||||
if (--newvalue == -2)
|
||||
newvalue = NUMMAPS-1;
|
||||
}
|
||||
|
||||
if (newvalue == oldvalue)
|
||||
break; // don't loop forever if there's none of a certain gametype
|
||||
|
||||
if(!mapheaderinfo[newvalue])
|
||||
continue; // Don't allocate the header. That just makes memory usage skyrocket.
|
||||
|
||||
} while (!M_CanShowLevelInList(newvalue, gt));
|
||||
|
||||
var->value = newvalue + 1;
|
||||
var->func();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
else if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
if (!var->PossibleValue[MAXVAL].strvalue)
|
||||
|
|
|
|||
|
|
@ -909,6 +909,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
UINT8 *p;
|
||||
size_t mirror_length;
|
||||
const char *httpurl = cv_httpsource.string;
|
||||
UINT8 prefgametype = (cv_kartgametypepreference.value == -1)
|
||||
? gametype
|
||||
: cv_kartgametypepreference.value;
|
||||
|
||||
netbuffer->packettype = PT_SERVERINFO;
|
||||
netbuffer->u.serverinfo._255 = 255;
|
||||
|
|
@ -933,7 +936,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
else
|
||||
netbuffer->u.serverinfo.refusereason = 0;
|
||||
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[prefgametype],
|
||||
sizeof netbuffer->u.serverinfo.gametypename);
|
||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
|
|
@ -945,7 +948,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
|
||||
CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string,
|
||||
MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
|
||||
|
||||
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
|
||||
|
||||
|
|
@ -1158,35 +1160,32 @@ static boolean SV_ResendingSavegameToAnyone(void)
|
|||
static void SV_SendSaveGame(INT32 node, boolean resending)
|
||||
{
|
||||
size_t length, compressedlen;
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
UINT8 *compressedsave;
|
||||
UINT8 *buffertosend;
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save.size = NETSAVEGAMESIZE;
|
||||
save.buffer = (UINT8 *)malloc(save.size);
|
||||
if (!save.buffer)
|
||||
if (P_SaveBufferAlloc(&save, NETSAVEGAMESIZE) == false)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Leave room for the uncompressed length.
|
||||
save.p = save.buffer + sizeof(UINT32);
|
||||
save.end = save.buffer + save.size;
|
||||
save.p += sizeof(UINT32);
|
||||
|
||||
P_SaveNetGame(&save, resending);
|
||||
|
||||
length = save.p - save.buffer;
|
||||
if (length > NETSAVEGAMESIZE)
|
||||
{
|
||||
free(save.buffer);
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
// Allocate space for compressed save: one byte fewer than for the
|
||||
// uncompressed data to ensure that the compression is worthwhile.
|
||||
compressedsave = malloc(length - 1);
|
||||
compressedsave = Z_Malloc(length - 1, PU_STATIC, NULL);
|
||||
if (!compressedsave)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
|
|
@ -1197,7 +1196,7 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
if ((compressedlen = lzf_compress(save.buffer + sizeof(UINT32), length - sizeof(UINT32), compressedsave + sizeof(UINT32), length - sizeof(UINT32) - 1)))
|
||||
{
|
||||
// Compressing succeeded; send compressed data
|
||||
free(save.buffer);
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
// State that we're compressed.
|
||||
buffertosend = compressedsave;
|
||||
|
|
@ -1207,14 +1206,14 @@ static void SV_SendSaveGame(INT32 node, boolean resending)
|
|||
else
|
||||
{
|
||||
// Compression failed to make it smaller; send original
|
||||
free(compressedsave);
|
||||
Z_Free(compressedsave);
|
||||
|
||||
// State that we're not compressed
|
||||
buffertosend = save.buffer;
|
||||
WRITEUINT32(save.buffer, 0);
|
||||
}
|
||||
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_RAM, 0);
|
||||
AddRamToSendQueue(node, buffertosend, length, SF_Z_RAM, 0);
|
||||
|
||||
// Remember when we started sending the savegame so we can handle timeouts
|
||||
sendingsavegame[node] = true;
|
||||
|
|
@ -1228,7 +1227,7 @@ static consvar_t cv_dumpconsistency = CVAR_INIT ("dumpconsistency", "Off", CV_SA
|
|||
static void SV_SavedGame(void)
|
||||
{
|
||||
size_t length;
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
char tmpsave[256];
|
||||
|
||||
if (!cv_dumpconsistency.value)
|
||||
|
|
@ -1237,22 +1236,18 @@ static void SV_SavedGame(void)
|
|||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
// first save it in a malloced buffer
|
||||
save.size = NETSAVEGAMESIZE;
|
||||
save.p = save.buffer = (UINT8 *)malloc(save.size);
|
||||
if (!save.p)
|
||||
if (P_SaveBufferAlloc(&save, NETSAVEGAMESIZE) == false)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for savegame\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
save.end = save.buffer + save.size;
|
||||
|
||||
P_SaveNetGame(&save, false);
|
||||
|
||||
length = save.p - save.buffer;
|
||||
if (length > NETSAVEGAMESIZE)
|
||||
{
|
||||
free(save.buffer);
|
||||
P_SaveBufferFree(&save);
|
||||
I_Error("Savegame buffer overrun");
|
||||
}
|
||||
|
||||
|
|
@ -1260,7 +1255,7 @@ static void SV_SavedGame(void)
|
|||
if (!FIL_WriteFile(tmpsave, save.buffer, length))
|
||||
CONS_Printf(M_GetText("Didn't save %s for netgame"), tmpsave);
|
||||
|
||||
free(save.buffer);
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
|
||||
#undef TMPSAVENAME
|
||||
|
|
@ -1270,37 +1265,31 @@ static void SV_SavedGame(void)
|
|||
|
||||
static void CL_LoadReceivedSavegame(boolean reloading)
|
||||
{
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
size_t length, decompressedlen;
|
||||
char tmpsave[256];
|
||||
|
||||
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
|
||||
|
||||
length = FIL_ReadFile(tmpsave, &save.buffer);
|
||||
|
||||
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
|
||||
if (!length)
|
||||
if (P_SaveBufferFromFile(&save, tmpsave) == false)
|
||||
{
|
||||
I_Error("Can't read savegame sent");
|
||||
return;
|
||||
}
|
||||
|
||||
save.p = save.buffer;
|
||||
save.size = length;
|
||||
save.end = save.buffer + save.size;
|
||||
length = save.size;
|
||||
CONS_Printf(M_GetText("Loading savegame length %s\n"), sizeu1(length));
|
||||
|
||||
// Decompress saved game if necessary.
|
||||
decompressedlen = READUINT32(save.p);
|
||||
if(decompressedlen > 0)
|
||||
if (decompressedlen > 0)
|
||||
{
|
||||
UINT8 *decompressedbuffer = Z_Malloc(decompressedlen, PU_STATIC, NULL);
|
||||
|
||||
lzf_decompress(save.p, length - sizeof(UINT32), decompressedbuffer, decompressedlen);
|
||||
Z_Free(save.buffer);
|
||||
|
||||
save.p = save.buffer = decompressedbuffer;
|
||||
save.size = decompressedlen;
|
||||
save.end = save.buffer + decompressedlen;
|
||||
P_SaveBufferFree(&save);
|
||||
P_SaveBufferFromExisting(&save, decompressedbuffer, decompressedlen);
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
|
@ -1332,10 +1321,13 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
}
|
||||
|
||||
// done
|
||||
Z_Free(save.buffer);
|
||||
save.p = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
|
||||
if (unlink(tmpsave) == -1)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
}
|
||||
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
|
||||
|
|
@ -6134,7 +6126,7 @@ void CL_ClearRewinds(void)
|
|||
|
||||
rewind_t *CL_SaveRewindPoint(size_t demopos)
|
||||
{
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
if (rewindhead && rewindhead->leveltime + REWIND_POINT_INTERVAL > leveltime)
|
||||
|
|
@ -6144,10 +6136,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
|
|||
if (!rewind)
|
||||
return NULL;
|
||||
|
||||
save.buffer = save.p = rewind->savebuffer;
|
||||
save.size = NETSAVEGAMESIZE;
|
||||
save.end = save.buffer + save.size;
|
||||
|
||||
P_SaveBufferFromExisting(&save, rewind->savebuffer, NETSAVEGAMESIZE);
|
||||
P_SaveNetGame(&save, false);
|
||||
|
||||
rewind->leveltime = leveltime;
|
||||
|
|
@ -6160,7 +6149,7 @@ rewind_t *CL_SaveRewindPoint(size_t demopos)
|
|||
|
||||
rewind_t *CL_RewindToTime(tic_t time)
|
||||
{
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
while (rewindhead && rewindhead->leveltime > time)
|
||||
|
|
@ -6173,10 +6162,7 @@ rewind_t *CL_RewindToTime(tic_t time)
|
|||
if (!rewindhead)
|
||||
return NULL;
|
||||
|
||||
save.buffer = save.p = rewindhead->savebuffer;
|
||||
save.size = NETSAVEGAMESIZE;
|
||||
save.end = save.buffer + save.size;
|
||||
|
||||
P_SaveBufferFromExisting(&save, rewindhead->savebuffer, NETSAVEGAMESIZE);
|
||||
P_LoadNetGame(&save, false);
|
||||
|
||||
wipegamestate = gamestate; // No fading back in!
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ struct serverinfo_pak
|
|||
tic_t time;
|
||||
tic_t leveltime;
|
||||
char servername[MAXSERVERNAME];
|
||||
char mapname[8];
|
||||
char maptitle[33];
|
||||
unsigned char mapmd5[16];
|
||||
UINT8 actnum;
|
||||
|
|
|
|||
147
src/d_main.cpp
147
src/d_main.cpp
|
|
@ -347,7 +347,7 @@ static bool D_Display(void)
|
|||
if (gamestate != GS_LEVEL && rendermode != render_none)
|
||||
{
|
||||
V_SetPaletteLump("PLAYPAL"); // Reset the palette
|
||||
R_ReInitColormaps(0, LUMPERROR);
|
||||
R_ReInitColormaps(0, NULL, 0, false);
|
||||
}
|
||||
|
||||
F_WipeStartScreen();
|
||||
|
|
@ -986,13 +986,12 @@ void D_StartTitle(void)
|
|||
|
||||
if (server)
|
||||
{
|
||||
char mapname[6];
|
||||
i = G_GetFirstMapOfGametype(gametype)+1;
|
||||
|
||||
strlcpy(mapname, G_BuildMapName(spstage_start), sizeof (mapname));
|
||||
strlwr(mapname);
|
||||
mapname[5] = '\0';
|
||||
if (i > nummapheaders)
|
||||
I_Error("D_StartTitle: No valid map ID found!?");
|
||||
|
||||
COM_BufAddText(va("map %s\n", mapname));
|
||||
COM_BufAddText(va("map %s\n", G_BuildMapName(i)));
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1247,11 +1246,6 @@ D_ConvertVersionNumbers (void)
|
|||
//
|
||||
void D_SRB2Main(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT16 wadnum;
|
||||
lumpinfo_t *lumpinfo;
|
||||
char *name;
|
||||
|
||||
INT32 p;
|
||||
|
||||
INT32 pstartmap = 0;
|
||||
|
|
@ -1512,31 +1506,7 @@ void D_SRB2Main(void)
|
|||
// conversion sometimes needs the palette
|
||||
V_ReloadPalette();
|
||||
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
for (wadnum = 0; wadnum <= mainwads; wadnum++)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5] != '\0')
|
||||
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])
|
||||
{
|
||||
mapheaderinfo[num - 1]->alreadyExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
P_InitMapData(false);
|
||||
|
||||
CON_SetLoadingProgress(LOADED_IWAD);
|
||||
|
||||
|
|
@ -1595,39 +1565,7 @@ void D_SRB2Main(void)
|
|||
//
|
||||
// search for pwad maps
|
||||
//
|
||||
|
||||
//
|
||||
// search for maps... again.
|
||||
//
|
||||
for (wadnum = mainwads+1; wadnum < numwadfiles; wadnum++)
|
||||
{
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5] != '\0')
|
||||
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]->alreadyExists != false)
|
||||
{
|
||||
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||
}
|
||||
|
||||
mapheaderinfo[num - 1]->alreadyExists = true;
|
||||
}
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
P_InitMapData(true);
|
||||
HU_LoadGraphics();
|
||||
}
|
||||
|
||||
|
|
@ -1730,33 +1668,41 @@ void D_SRB2Main(void)
|
|||
{
|
||||
const char *word = M_GetNextParm();
|
||||
|
||||
pstartmap = G_FindMapByNameOrCode(word, 0);
|
||||
|
||||
if (! pstartmap)
|
||||
I_Error("Cannot find a map remotely named '%s'\n", word);
|
||||
if (WADNAMECHECK(word))
|
||||
{
|
||||
if (!(pstartmap = wadnamemap))
|
||||
I_Error("Bad '%s' level warp.\n"
|
||||
#if defined (_WIN32)
|
||||
"Are you using MSDOS 8.3 filenames in Zone Builder?\n"
|
||||
#endif
|
||||
, word);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!M_CheckParm("-server") && !M_CheckParm("-dedicated") && !M_CheckParm("-nograndprix"))
|
||||
{
|
||||
G_SetGameModified(true, true);
|
||||
|
||||
// Start up a "minor" grand prix session
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
|
||||
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
|
||||
grandprixinfo.encore = false;
|
||||
grandprixinfo.masterbots = false;
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.roundnum = 0;
|
||||
grandprixinfo.cup = NULL;
|
||||
grandprixinfo.wonround = false;
|
||||
|
||||
grandprixinfo.initalize = true;
|
||||
}
|
||||
|
||||
autostart = true;
|
||||
if (!(pstartmap = G_FindMapByNameOrCode(word, 0)))
|
||||
I_Error("Cannot find a map remotely named '%s'\n", word);
|
||||
}
|
||||
|
||||
if (!M_CheckParm("-server") && !M_CheckParm("-dedicated") && !M_CheckParm("-nograndprix"))
|
||||
{
|
||||
G_SetGameModified(true, true);
|
||||
|
||||
// Start up a "minor" grand prix session
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
|
||||
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
|
||||
grandprixinfo.encore = false;
|
||||
grandprixinfo.masterbots = false;
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.roundnum = 0;
|
||||
grandprixinfo.cup = NULL;
|
||||
grandprixinfo.wonround = false;
|
||||
|
||||
grandprixinfo.initalize = true;
|
||||
}
|
||||
|
||||
autostart = true;
|
||||
}
|
||||
|
||||
// Set up splitscreen players before joining!
|
||||
|
|
@ -1847,14 +1793,14 @@ void D_SRB2Main(void)
|
|||
// rei/miru: bootmap (Idea: starts the game on a predefined map)
|
||||
if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm()))
|
||||
{
|
||||
pstartmap = bootmap;
|
||||
pstartmap = G_MapNumber(bootmap)+1;
|
||||
|
||||
if (pstartmap < 1 || pstartmap > NUMMAPS)
|
||||
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
|
||||
else
|
||||
if (pstartmap > nummapheaders)
|
||||
{
|
||||
autostart = true;
|
||||
I_Error("Cannot warp to map %s (not found)\n", bootmap);
|
||||
}
|
||||
|
||||
autostart = true;
|
||||
}
|
||||
|
||||
if (autostart || netgame)
|
||||
|
|
@ -1947,14 +1893,11 @@ void D_SRB2Main(void)
|
|||
|
||||
if (server && !M_CheckParm("+map"))
|
||||
{
|
||||
// Prevent warping to nonexistent levels
|
||||
if (W_CheckNumForName(G_BuildMapName(pstartmap)) == LUMPERROR)
|
||||
I_Error("Could not warp to %s (map not found)\n", G_BuildMapName(pstartmap));
|
||||
// Prevent warping to locked levels
|
||||
// ... unless you're in a dedicated server. Yes, technically this means you can view any level by
|
||||
// running a dedicated server and joining it yourself, but that's better than making dedicated server's
|
||||
// lives hell.
|
||||
else if (!dedicated && M_MapLocked(pstartmap))
|
||||
if (!dedicated && M_MapLocked(pstartmap))
|
||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -924,9 +924,9 @@ static void DebugPrintpacket(const char *header)
|
|||
netbuffer->u.servercfg.modifiedgame);
|
||||
break;
|
||||
case PT_SERVERINFO:
|
||||
fprintf(debugfile, " '%s' player %d/%d, map %s, filenum %d, time %u \n",
|
||||
fprintf(debugfile, " '%s' player %d/%d, filenum %d, time %u \n",
|
||||
netbuffer->u.serverinfo.servername, netbuffer->u.serverinfo.numberofplayer,
|
||||
netbuffer->u.serverinfo.maxplayer, netbuffer->u.serverinfo.mapname,
|
||||
netbuffer->u.serverinfo.maxplayer,
|
||||
netbuffer->u.serverinfo.fileneedednum,
|
||||
(UINT32)LONG(netbuffer->u.serverinfo.time));
|
||||
fprintfstringnewline((char *)netbuffer->u.serverinfo.fileneeded,
|
||||
|
|
|
|||
|
|
@ -399,6 +399,8 @@ static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "
|
|||
consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange);
|
||||
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
||||
consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL);
|
||||
static CV_PossibleValue_t kartgametypepreference_cons_t[] = {{-1, "None"}, {GT_RACE, "Race"}, {GT_BATTLE, "Battle"}, {0, NULL}};
|
||||
consvar_t cv_kartgametypepreference = CVAR_INIT ("kartgametypepreference", "None", CV_NETVAR, kartgametypepreference_cons_t, NULL);
|
||||
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Kilometers"}, {2, "Miles"}, {3, "Fracunits"}, {4, "Percentage"}, {0, NULL}};
|
||||
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
|
||||
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
|
||||
|
|
@ -840,6 +842,7 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
CV_RegisterVar(&cv_recordmultiplayerdemos);
|
||||
CV_RegisterVar(&cv_netdemosyncquality);
|
||||
CV_RegisterVar(&cv_netdemosize);
|
||||
|
||||
CV_RegisterVar(&cv_shoutname);
|
||||
CV_RegisterVar(&cv_shoutcolor);
|
||||
|
|
@ -1425,7 +1428,7 @@ UINT8 CanChangeSkin(INT32 playernum)
|
|||
return true;
|
||||
|
||||
// Force skin in effect.
|
||||
if ((cv_forceskin.value != -1) || (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'))
|
||||
if (cv_forceskin.value != -1)
|
||||
return false;
|
||||
|
||||
// Can change skin in intermission and whatnot.
|
||||
|
|
@ -2603,8 +2606,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
|||
if (delay != 2)
|
||||
{
|
||||
UINT8 flags = 0;
|
||||
const char *mapname = G_BuildMapName(mapnum);
|
||||
I_Assert(W_CheckNumForName(mapname) != LUMPERROR);
|
||||
//I_Assert(W_CheckNumForName(mapname) != LUMPERROR);
|
||||
buf_p = buf;
|
||||
if (pencoremode)
|
||||
flags |= 1;
|
||||
|
|
@ -2619,7 +2621,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
|||
// new gametype value
|
||||
WRITEUINT8(buf_p, newgametype);
|
||||
|
||||
WRITESTRINGN(buf_p, mapname, MAX_WADPATH);
|
||||
WRITEINT16(buf_p, mapnum);
|
||||
}
|
||||
|
||||
if (delay == 1)
|
||||
|
|
@ -2650,27 +2652,28 @@ void D_SetupVote(void)
|
|||
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
|
||||
UINT8 *p = buf;
|
||||
INT32 i;
|
||||
UINT8 secondgt = G_SometimesGetDifferentGametype();
|
||||
UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
|
||||
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
|
||||
INT16 votebuffer[4] = {-1,-1,-1,0};
|
||||
|
||||
if ((cv_kartencore.value == 1) && (gametyperules & GTR_CIRCUIT))
|
||||
WRITEUINT8(p, (gametype|0x80));
|
||||
if ((cv_kartencore.value == 1) && (gametypedefaultrules[gt] & GTR_CIRCUIT))
|
||||
WRITEUINT8(p, (gt|VOTEMODIFIER_ENCORE));
|
||||
else
|
||||
WRITEUINT8(p, gametype);
|
||||
WRITEUINT8(p, gt);
|
||||
WRITEUINT8(p, secondgt);
|
||||
secondgt &= ~0x80;
|
||||
secondgt &= ~VOTEMODIFIER_ENCORE;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
UINT16 m;
|
||||
if (i == 2) // sometimes a different gametype
|
||||
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer);
|
||||
else if (i >= 3) // unknown-random and force-unknown MAP HELL
|
||||
m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, (i-2), (i < 4), votebuffer);
|
||||
else if (i >= 3) // unknown-random and formerly force-unknown MAP HELL
|
||||
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, (i-2), (i < 4), votebuffer);
|
||||
else
|
||||
m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, true, votebuffer);
|
||||
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, 0, true, votebuffer);
|
||||
if (i < 3)
|
||||
votebuffer[i] = m; // min() is a dumb workaround for gcc 4.4 array-bounds error
|
||||
votebuffer[i] = m;
|
||||
WRITEUINT16(p, m);
|
||||
}
|
||||
|
||||
|
|
@ -3075,11 +3078,11 @@ static void Command_Map_f(void)
|
|||
*/
|
||||
static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||
{
|
||||
char mapname[MAX_WADPATH+1];
|
||||
UINT8 flags;
|
||||
INT32 resetplayer = 1, lastgametype;
|
||||
UINT8 skipprecutscene, FLS;
|
||||
boolean pencoremode;
|
||||
INT16 mapnumber;
|
||||
|
||||
forceresetplayers = deferencoremode = false;
|
||||
|
||||
|
|
@ -3116,7 +3119,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
FLS = ((flags & (1<<3)) != 0);
|
||||
|
||||
READSTRINGN(*cp, mapname, MAX_WADPATH);
|
||||
mapnumber = READINT16(*cp);
|
||||
|
||||
if (netgame)
|
||||
P_SetRandSeed(READUINT32(*cp));
|
||||
|
|
@ -3124,7 +3127,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
if (!skipprecutscene)
|
||||
{
|
||||
DEBFILE(va("Warping to %s [resetplayer=%d lastgametype=%d gametype=%d cpnd=%d]\n",
|
||||
mapname, resetplayer, lastgametype, gametype, chmappending));
|
||||
G_BuildMapName(mapnumber), resetplayer, lastgametype, gametype, chmappending));
|
||||
CON_LogMessage(M_GetText("Speeding off to level...\n"));
|
||||
}
|
||||
|
||||
|
|
@ -3140,7 +3143,11 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING;
|
||||
demo.savebutton = 0;
|
||||
|
||||
G_InitNew(pencoremode, mapname, resetplayer, skipprecutscene, FLS);
|
||||
// clear this demo before recording a new one
|
||||
if (demo.recording && !modeattacking)
|
||||
G_CheckDemoStatus();
|
||||
|
||||
G_InitNew(pencoremode, mapnumber, resetplayer, skipprecutscene, FLS);
|
||||
if (demo.playback && !demo.timing)
|
||||
precache = true;
|
||||
if (demo.timing)
|
||||
|
|
@ -5380,8 +5387,9 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
INT32 i;
|
||||
UINT8 gt, secondgt;
|
||||
INT16 tempvotelevels[4][2];
|
||||
|
||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||
if (playernum != serverplayer) // admin shouldn't be able to set up vote...
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal vote setup received from %s\n"), player_names[playernum]);
|
||||
if (server)
|
||||
|
|
@ -5392,14 +5400,43 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
gt = (UINT8)READUINT8(*cp);
|
||||
secondgt = (UINT8)READUINT8(*cp);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
// Strip illegal Encore flag.
|
||||
if ((gt & VOTEMODIFIER_ENCORE)
|
||||
&& !(gametypedefaultrules[(gt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
|
||||
{
|
||||
votelevels[i][0] = (UINT16)READUINT16(*cp);
|
||||
votelevels[i][1] = gt;
|
||||
if (!mapheaderinfo[votelevels[i][0]])
|
||||
P_AllocMapHeader(votelevels[i][0]);
|
||||
gt &= ~VOTEMODIFIER_ENCORE;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tempvotelevels[i][0] = (UINT16)READUINT16(*cp);
|
||||
tempvotelevels[i][1] = gt;
|
||||
if (tempvotelevels[i][0] < nummapheaders && mapheaderinfo[tempvotelevels[i][0]])
|
||||
continue;
|
||||
|
||||
if (server)
|
||||
I_Error("Got_SetupVotecmd: Internal map ID %d not found (nummapheaders = %d)", tempvotelevels[i][0], nummapheaders);
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad map ID %d received from %s\n"), tempvotelevels[i][0], player_names[playernum]);
|
||||
return;
|
||||
}
|
||||
|
||||
tempvotelevels[2][1] = secondgt;
|
||||
|
||||
memcpy(votelevels, tempvotelevels, sizeof(votelevels));
|
||||
|
||||
// If third entry has an illelegal Encore flag... (illelegal!?)
|
||||
if ((secondgt & VOTEMODIFIER_ENCORE)
|
||||
&& !(gametypedefaultrules[(secondgt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
|
||||
{
|
||||
secondgt &= ~VOTEMODIFIER_ENCORE;
|
||||
// Apply it to the second entry instead, gametype permitting!
|
||||
if (gametypedefaultrules[gt] & GTR_CIRCUIT)
|
||||
{
|
||||
votelevels[1][1] |= VOTEMODIFIER_ENCORE;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, set third entry's gametype/Encore status.
|
||||
votelevels[2][1] = secondgt;
|
||||
|
||||
G_SetGamestate(GS_VOTING);
|
||||
|
|
@ -5817,7 +5854,7 @@ static void Command_Togglemodified_f(void)
|
|||
|
||||
static void Command_Archivetest_f(void)
|
||||
{
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
UINT32 i, wrote;
|
||||
thinker_t *th;
|
||||
if (gamestate != GS_LEVEL)
|
||||
|
|
@ -5833,9 +5870,11 @@ static void Command_Archivetest_f(void)
|
|||
((mobj_t *)th)->mobjnum = i++;
|
||||
|
||||
// allocate buffer
|
||||
save.size = 1024;
|
||||
save.buffer = save.p = ZZ_Alloc(save.size);
|
||||
save.end = save.buffer + save.size;
|
||||
if (P_SaveBufferAlloc(&save, 1024) == false)
|
||||
{
|
||||
CONS_Printf("Unable to allocate buffer.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// test archive
|
||||
CONS_Printf("LUA_Archive...\n");
|
||||
|
|
@ -5853,10 +5892,12 @@ static void Command_Archivetest_f(void)
|
|||
LUA_UnArchive(&save, true);
|
||||
i = READUINT8(save.p);
|
||||
if (i != 0x7F || wrote != (UINT32)(save.p - save.buffer))
|
||||
{
|
||||
CONS_Printf("Savegame corrupted. (write %u, read %u)\n", wrote, (UINT32)(save.p - save.buffer));
|
||||
}
|
||||
|
||||
// free buffer
|
||||
Z_Free(save.buffer);
|
||||
P_SaveBufferFree(&save);
|
||||
CONS_Printf("Done. No crash.\n");
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ extern consvar_t cv_kartfrantic;
|
|||
extern consvar_t cv_kartcomeback;
|
||||
extern consvar_t cv_kartencore;
|
||||
extern consvar_t cv_kartvoterulechanges;
|
||||
extern consvar_t cv_kartgametypepreference;
|
||||
extern consvar_t cv_kartspeedometer;
|
||||
extern consvar_t cv_kartvoices;
|
||||
extern consvar_t cv_kartbot;
|
||||
|
|
|
|||
|
|
@ -621,18 +621,6 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
|
|||
}
|
||||
return luaL_error(L, "skincolor '%s' could not be found.\n", word);
|
||||
}
|
||||
else if (fastncmp("GRADE_",word,6))
|
||||
{
|
||||
p = word+6;
|
||||
for (i = 0; NIGHTSGRADE_LIST[i]; i++)
|
||||
if (*p == NIGHTSGRADE_LIST[i])
|
||||
{
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MN_",word,3)) {
|
||||
p = word+3;
|
||||
for (i = 0; i < NUMMENUTYPES; i++)
|
||||
|
|
|
|||
491
src/deh_soc.c
491
src/deh_soc.c
|
|
@ -142,28 +142,53 @@ void clear_conditionsets(void)
|
|||
|
||||
void clear_levels(void)
|
||||
{
|
||||
INT16 i;
|
||||
|
||||
// This is potentially dangerous but if we're resetting these headers,
|
||||
// we may as well try to save some memory, right?
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
while (nummapheaders > 0)
|
||||
{
|
||||
if (!mapheaderinfo[i] || i == (tutorialmap-1))
|
||||
nummapheaders--;
|
||||
|
||||
if (!mapheaderinfo[nummapheaders])
|
||||
continue;
|
||||
|
||||
if (strcmp(mapheaderinfo[nummapheaders]->lumpname, tutorialmap) == 0) // Sal: Is this needed...?
|
||||
continue;
|
||||
|
||||
// Custom map header info
|
||||
// (no need to set num to 0, we're freeing the entire header shortly)
|
||||
Z_Free(mapheaderinfo[i]->customopts);
|
||||
Z_Free(mapheaderinfo[nummapheaders]->customopts);
|
||||
|
||||
P_DeleteFlickies(i);
|
||||
P_DeleteGrades(i);
|
||||
P_DeleteFlickies(nummapheaders);
|
||||
|
||||
Z_Free(mapheaderinfo[i]);
|
||||
mapheaderinfo[i] = NULL;
|
||||
Z_Free(mapheaderinfo[nummapheaders]->mainrecord);
|
||||
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->thumbnailPic);
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->minimapPic);
|
||||
|
||||
Z_Free(mapheaderinfo[nummapheaders]->lumpname);
|
||||
|
||||
Z_Free(mapheaderinfo[nummapheaders]);
|
||||
mapheaderinfo[nummapheaders] = NULL;
|
||||
}
|
||||
|
||||
// Realloc the one for the current gamemap as a safeguard
|
||||
P_AllocMapHeader(gamemap-1);
|
||||
// Clear out the cache
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
UINT8 i;
|
||||
|
||||
while (cup)
|
||||
{
|
||||
for (i = 0; i < CUPCACHE_MAX; i++)
|
||||
{
|
||||
cup->cachedlevels[i] = NEXTMAP_INVALID;
|
||||
}
|
||||
cup = cup->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Exit the current gamemap as a safeguard
|
||||
if (Playing())
|
||||
COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed
|
||||
}
|
||||
|
||||
static boolean findFreeSlot(INT32 *num)
|
||||
|
|
@ -1048,27 +1073,44 @@ static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word)
|
|||
{
|
||||
if (fastncmp(word, "ENCORE", 6))
|
||||
{
|
||||
mapheaderinfo[mapnum-1]->use_encore_lighting = true;
|
||||
mapheaderinfo[mapnum]->use_encore_lighting = true;
|
||||
|
||||
return &mapheaderinfo[mapnum-1]->lighting_encore;
|
||||
return &mapheaderinfo[mapnum]->lighting_encore;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &mapheaderinfo[mapnum-1]->lighting;
|
||||
return &mapheaderinfo[mapnum]->lighting;
|
||||
}
|
||||
}
|
||||
|
||||
void readlevelheader(MYFILE *f, INT32 num)
|
||||
void readlevelheader(MYFILE *f, char * name)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
|
||||
char *word;
|
||||
char *word2;
|
||||
//char *word3; // Non-uppercase version of word2
|
||||
|
||||
char *tmp;
|
||||
INT32 i;
|
||||
|
||||
// Reset all previous map header information
|
||||
P_AllocMapHeader((INT16)(num-1));
|
||||
INT32 num = G_MapNumber(name);
|
||||
|
||||
if (num >= nummapheaders)
|
||||
{
|
||||
P_AllocMapHeader((INT16)(num = nummapheaders));
|
||||
}
|
||||
else if (f->wad > mainwads)
|
||||
{
|
||||
// only mark as a major mod if it replaces an already-existing mapheaderinfo
|
||||
G_SetGameModified(multiplayer, true);
|
||||
}
|
||||
|
||||
if (mapheaderinfo[num]->lumpname == NULL)
|
||||
{
|
||||
mapheaderinfo[num]->lumpname = Z_StrDup(name);
|
||||
mapheaderinfo[num]->lumpnamehash = quickncasehash(mapheaderinfo[num]->lumpname, MAXMAPLUMPNAME);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -1106,16 +1148,15 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
|
||||
if (fastcmp(word, "LEVELNAME"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num));
|
||||
strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once
|
||||
deh_strlcpy(mapheaderinfo[num]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num]->lvlttl), va("Level header %d: levelname", num));
|
||||
continue;
|
||||
}
|
||||
// CHEAP HACK: move this over here for lowercase subtitles
|
||||
if (fastcmp(word, "SUBTITLE"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->subttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->subttl), va("Level header %d: subtitle", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->subttl, word2,
|
||||
sizeof(mapheaderinfo[num]->subttl), va("Level header %d: subtitle", num));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1137,19 +1178,19 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
}
|
||||
|
||||
// Sanity limit of 128 params
|
||||
if (mapheaderinfo[num-1]->numCustomOptions == 128)
|
||||
if (mapheaderinfo[num]->numCustomOptions == 128)
|
||||
{
|
||||
deh_warning("Level header %d: too many custom parameters", num);
|
||||
continue;
|
||||
}
|
||||
j = mapheaderinfo[num-1]->numCustomOptions++;
|
||||
j = mapheaderinfo[num]->numCustomOptions++;
|
||||
|
||||
mapheaderinfo[num-1]->customopts =
|
||||
Z_Realloc(mapheaderinfo[num-1]->customopts,
|
||||
sizeof(customoption_t) * mapheaderinfo[num-1]->numCustomOptions, PU_STATIC, NULL);
|
||||
mapheaderinfo[num]->customopts =
|
||||
Z_Realloc(mapheaderinfo[num]->customopts,
|
||||
sizeof(customoption_t) * mapheaderinfo[num]->numCustomOptions, PU_STATIC, NULL);
|
||||
|
||||
// Newly allocated
|
||||
modoption = &mapheaderinfo[num-1]->customopts[j];
|
||||
modoption = &mapheaderinfo[num]->customopts[j];
|
||||
|
||||
strncpy(modoption->option, word, 31);
|
||||
modoption->option[31] = '\0';
|
||||
|
|
@ -1165,33 +1206,33 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
if (fastcmp(word, "FLICKYLIST") || fastcmp(word, "ANIMALLIST"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
P_DeleteFlickies(num-1);
|
||||
P_DeleteFlickies(num);
|
||||
else if (fastcmp(word2, "DEMO"))
|
||||
P_SetDemoFlickies(num-1);
|
||||
P_SetDemoFlickies(num);
|
||||
else if (fastcmp(word2, "ALL"))
|
||||
{
|
||||
mobjtype_t tmpflickies[MAXFLICKIES];
|
||||
|
||||
for (mapheaderinfo[num-1]->numFlickies = 0;
|
||||
((mapheaderinfo[num-1]->numFlickies < MAXFLICKIES) && FLICKYTYPES[mapheaderinfo[num-1]->numFlickies].type);
|
||||
mapheaderinfo[num-1]->numFlickies++)
|
||||
tmpflickies[mapheaderinfo[num-1]->numFlickies] = FLICKYTYPES[mapheaderinfo[num-1]->numFlickies].type;
|
||||
for (mapheaderinfo[num]->numFlickies = 0;
|
||||
((mapheaderinfo[num]->numFlickies < MAXFLICKIES) && FLICKYTYPES[mapheaderinfo[num]->numFlickies].type);
|
||||
mapheaderinfo[num]->numFlickies++)
|
||||
tmpflickies[mapheaderinfo[num]->numFlickies] = FLICKYTYPES[mapheaderinfo[num]->numFlickies].type;
|
||||
|
||||
if (mapheaderinfo[num-1]->numFlickies) // just in case...
|
||||
if (mapheaderinfo[num]->numFlickies) // just in case...
|
||||
{
|
||||
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num-1]->numFlickies;
|
||||
mapheaderinfo[num-1]->flickies = Z_Realloc(mapheaderinfo[num-1]->flickies, newsize, PU_STATIC, NULL);
|
||||
M_Memcpy(mapheaderinfo[num-1]->flickies, tmpflickies, newsize);
|
||||
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num]->numFlickies;
|
||||
mapheaderinfo[num]->flickies = Z_Realloc(mapheaderinfo[num]->flickies, newsize, PU_STATIC, NULL);
|
||||
M_Memcpy(mapheaderinfo[num]->flickies, tmpflickies, newsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mobjtype_t tmpflickies[MAXFLICKIES];
|
||||
mapheaderinfo[num-1]->numFlickies = 0;
|
||||
mapheaderinfo[num]->numFlickies = 0;
|
||||
tmp = strtok(word2,",");
|
||||
// get up to the first MAXFLICKIES flickies
|
||||
do {
|
||||
if (mapheaderinfo[num-1]->numFlickies == MAXFLICKIES) // never going to get above that number
|
||||
if (mapheaderinfo[num]->numFlickies == MAXFLICKIES) // never going to get above that number
|
||||
{
|
||||
deh_warning("Level header %d: too many flickies\n", num);
|
||||
break;
|
||||
|
|
@ -1205,7 +1246,7 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
//deh_warning("Level header %d: unknown flicky mobj type %s\n", num, tmp); -- no need for this line as get_mobjtype complains too
|
||||
continue;
|
||||
}
|
||||
tmpflickies[mapheaderinfo[num-1]->numFlickies] = i;
|
||||
tmpflickies[mapheaderinfo[num]->numFlickies] = i;
|
||||
}
|
||||
else // ...or a quick, limited selection of default flickies!
|
||||
{
|
||||
|
|
@ -1218,17 +1259,17 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
deh_warning("Level header %d: unknown flicky selection %s\n", num, tmp);
|
||||
continue;
|
||||
}
|
||||
tmpflickies[mapheaderinfo[num-1]->numFlickies] = FLICKYTYPES[i].type;
|
||||
tmpflickies[mapheaderinfo[num]->numFlickies] = FLICKYTYPES[i].type;
|
||||
}
|
||||
mapheaderinfo[num-1]->numFlickies++;
|
||||
mapheaderinfo[num]->numFlickies++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
if (mapheaderinfo[num-1]->numFlickies)
|
||||
if (mapheaderinfo[num]->numFlickies)
|
||||
{
|
||||
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num-1]->numFlickies;
|
||||
mapheaderinfo[num-1]->flickies = Z_Realloc(mapheaderinfo[num-1]->flickies, newsize, PU_STATIC, NULL);
|
||||
size_t newsize = sizeof(mobjtype_t) * mapheaderinfo[num]->numFlickies;
|
||||
mapheaderinfo[num]->flickies = Z_Realloc(mapheaderinfo[num]->flickies, newsize, PU_STATIC, NULL);
|
||||
// now we add them to the list!
|
||||
M_Memcpy(mapheaderinfo[num-1]->flickies, tmpflickies, newsize);
|
||||
M_Memcpy(mapheaderinfo[num]->flickies, tmpflickies, newsize);
|
||||
}
|
||||
else
|
||||
deh_warning("Level header %d: no valid flicky types found\n", num);
|
||||
|
|
@ -1238,64 +1279,32 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
// Strings that can be truncated
|
||||
else if (fastcmp(word, "ZONETITLE"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2,
|
||||
sizeof(mapheaderinfo[num-1]->zonttl), va("Level header %d: zonetitle", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->zonttl, word2,
|
||||
sizeof(mapheaderinfo[num]->zonttl), va("Level header %d: zonetitle", num));
|
||||
}
|
||||
else if (fastcmp(word, "SCRIPTNAME"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->scriptname, word2,
|
||||
sizeof(mapheaderinfo[num-1]->scriptname), va("Level header %d: scriptname", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->scriptname, word2,
|
||||
sizeof(mapheaderinfo[num]->scriptname), va("Level header %d: scriptname", num));
|
||||
}
|
||||
else if (fastcmp(word, "RUNSOC"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->runsoc, word2,
|
||||
sizeof(mapheaderinfo[num-1]->runsoc), va("Level header %d: runsoc", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->runsoc, word2,
|
||||
sizeof(mapheaderinfo[num]->runsoc), va("Level header %d: runsoc", num));
|
||||
}
|
||||
else if (fastcmp(word, "ACT"))
|
||||
{
|
||||
/*if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19
|
||||
mapheaderinfo[num-1]->actnum = (UINT8)i;
|
||||
mapheaderinfo[num]->actnum = (UINT8)i;
|
||||
else
|
||||
deh_warning("Level header %d: invalid act number %d", num, i);*/
|
||||
deh_strlcpy(mapheaderinfo[num-1]->actnum, word2,
|
||||
sizeof(mapheaderinfo[num-1]->actnum), va("Level header %d: actnum", num));
|
||||
}
|
||||
else if (fastcmp(word, "NEXTLEVEL"))
|
||||
{
|
||||
if (fastcmp(word2, "TITLE")) i = 1100;
|
||||
else if (fastcmp(word2, "EVALUATION")) i = 1101;
|
||||
else if (fastcmp(word2, "CREDITS")) i = 1102;
|
||||
else if (fastcmp(word2, "ENDING")) i = 1103;
|
||||
else
|
||||
// Support using the actual map name,
|
||||
// i.e., Nextlevel = AB, Nextlevel = FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
mapheaderinfo[num-1]->nextlevel = (INT16)i;
|
||||
}
|
||||
else if (fastcmp(word, "MARATHONNEXT"))
|
||||
{
|
||||
if (fastcmp(word2, "TITLE")) i = 1100;
|
||||
else if (fastcmp(word2, "EVALUATION")) i = 1101;
|
||||
else if (fastcmp(word2, "CREDITS")) i = 1102;
|
||||
else if (fastcmp(word2, "ENDING")) i = 1103;
|
||||
else
|
||||
// Support using the actual map name,
|
||||
// i.e., MarathonNext = AB, MarathonNext = FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
mapheaderinfo[num-1]->marathonnext = (INT16)i;
|
||||
deh_strlcpy(mapheaderinfo[num]->actnum, word2,
|
||||
sizeof(mapheaderinfo[num]->actnum), va("Level header %d: actnum", num));
|
||||
}
|
||||
else if (fastcmp(word, "TYPEOFLEVEL"))
|
||||
{
|
||||
if (i) // it's just a number
|
||||
mapheaderinfo[num-1]->typeoflevel = (UINT32)i;
|
||||
mapheaderinfo[num]->typeoflevel = (UINT32)i;
|
||||
else
|
||||
{
|
||||
UINT32 tol = 0;
|
||||
|
|
@ -1308,20 +1317,20 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
deh_warning("Level header %d: unknown typeoflevel flag %s\n", num, tmp);
|
||||
tol |= TYPEOFLEVEL[i].flag;
|
||||
} while((tmp = strtok(NULL,",")) != NULL);
|
||||
mapheaderinfo[num-1]->typeoflevel = tol;
|
||||
mapheaderinfo[num]->typeoflevel = tol;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "KEYWORDS"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->keywords, word2,
|
||||
sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->keywords, word2,
|
||||
sizeof(mapheaderinfo[num]->keywords), va("Level header %d: keywords", num));
|
||||
}
|
||||
else if (fastcmp(word, "MUSIC"))
|
||||
{
|
||||
if (fastcmp(word2, "NONE"))
|
||||
{
|
||||
mapheaderinfo[num-1]->musname[0][0] = 0; // becomes empty string
|
||||
mapheaderinfo[num-1]->musname_size = 0;
|
||||
mapheaderinfo[num]->musname[0][0] = 0; // becomes empty string
|
||||
mapheaderinfo[num]->musname_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1330,71 +1339,66 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
do {
|
||||
if (j >= MAXMUSNAMES)
|
||||
break;
|
||||
deh_strlcpy(mapheaderinfo[num-1]->musname[j], tmp,
|
||||
sizeof(mapheaderinfo[num-1]->musname[j]), va("Level header %d: music", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->musname[j], tmp,
|
||||
sizeof(mapheaderinfo[num]->musname[j]), va("Level header %d: music", num));
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
if (tmp != NULL)
|
||||
deh_warning("Level header %d: additional music slots past %d discarded", num, MAXMUSNAMES);
|
||||
mapheaderinfo[num-1]->musname_size = j;
|
||||
mapheaderinfo[num]->musname_size = j;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "MUSICSLOT"))
|
||||
deh_warning("Level header %d: MusicSlot parameter is deprecated and will be removed.\nUse \"Music\" instead.", num);
|
||||
else if (fastcmp(word, "MUSICTRACK"))
|
||||
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
|
||||
mapheaderinfo[num]->mustrack = ((UINT16)i - 1);
|
||||
else if (fastcmp(word, "MUSICPOS"))
|
||||
mapheaderinfo[num-1]->muspos = (UINT32)get_number(word2);
|
||||
else if (fastcmp(word, "FORCECHARACTER"))
|
||||
{
|
||||
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
|
||||
strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase
|
||||
}
|
||||
mapheaderinfo[num]->muspos = (UINT32)get_number(word2);
|
||||
else if (fastcmp(word, "WEATHER"))
|
||||
mapheaderinfo[num-1]->weather = get_precip(word2);
|
||||
mapheaderinfo[num]->weather = get_precip(word2);
|
||||
else if (fastcmp(word, "SKYTEXTURE"))
|
||||
deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2,
|
||||
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->skytexture, word2,
|
||||
sizeof(mapheaderinfo[num]->skytexture), va("Level header %d: sky texture", num));
|
||||
else if (fastcmp(word, "SKYNUM"))
|
||||
deh_strlcpy(mapheaderinfo[num-1]->skytexture, va("SKY%s", word2),
|
||||
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->skytexture, va("SKY%s", word2),
|
||||
sizeof(mapheaderinfo[num]->skytexture), va("Level header %d: sky texture", num));
|
||||
else if (fastcmp(word, "PRECUTSCENENUM"))
|
||||
mapheaderinfo[num-1]->precutscenenum = (UINT8)i;
|
||||
mapheaderinfo[num]->precutscenenum = (UINT8)i;
|
||||
else if (fastcmp(word, "CUTSCENENUM"))
|
||||
mapheaderinfo[num-1]->cutscenenum = (UINT8)i;
|
||||
mapheaderinfo[num]->cutscenenum = (UINT8)i;
|
||||
else if (fastcmp(word, "PALETTE"))
|
||||
mapheaderinfo[num-1]->palette = (UINT16)i;
|
||||
mapheaderinfo[num]->palette = (UINT16)i;
|
||||
else if (fastcmp(word, "ENCOREPAL"))
|
||||
mapheaderinfo[num-1]->encorepal = (UINT16)i;
|
||||
mapheaderinfo[num]->encorepal = (UINT16)i;
|
||||
else if (fastcmp(word, "NUMLAPS"))
|
||||
mapheaderinfo[num-1]->numlaps = (UINT8)i;
|
||||
mapheaderinfo[num]->numlaps = (UINT8)i;
|
||||
else if (fastcmp(word, "UNLOCKABLE"))
|
||||
{
|
||||
if (i >= 0 && i <= MAXUNLOCKABLES) // 0 for no unlock required, anything else requires something
|
||||
mapheaderinfo[num-1]->unlockrequired = (SINT8)i - 1;
|
||||
mapheaderinfo[num]->unlockrequired = (SINT8)i - 1;
|
||||
else
|
||||
deh_warning("Level header %d: invalid unlockable number %d", num, i);
|
||||
}
|
||||
else if (fastcmp(word, "LEVELSELECT"))
|
||||
mapheaderinfo[num-1]->levelselect = (UINT8)i;
|
||||
mapheaderinfo[num]->levelselect = (UINT8)i;
|
||||
else if (fastcmp(word, "SKYBOXSCALE"))
|
||||
mapheaderinfo[num-1]->skybox_scalex = mapheaderinfo[num-1]->skybox_scaley = mapheaderinfo[num-1]->skybox_scalez = (INT16)i;
|
||||
mapheaderinfo[num]->skybox_scalex = mapheaderinfo[num]->skybox_scaley = mapheaderinfo[num]->skybox_scalez = (INT16)i;
|
||||
else if (fastcmp(word, "SKYBOXSCALEX"))
|
||||
mapheaderinfo[num-1]->skybox_scalex = (INT16)i;
|
||||
mapheaderinfo[num]->skybox_scalex = (INT16)i;
|
||||
else if (fastcmp(word, "SKYBOXSCALEY"))
|
||||
mapheaderinfo[num-1]->skybox_scaley = (INT16)i;
|
||||
mapheaderinfo[num]->skybox_scaley = (INT16)i;
|
||||
else if (fastcmp(word, "SKYBOXSCALEZ"))
|
||||
mapheaderinfo[num-1]->skybox_scalez = (INT16)i;
|
||||
mapheaderinfo[num]->skybox_scalez = (INT16)i;
|
||||
else if (fastcmp(word, "LEVELFLAGS"))
|
||||
mapheaderinfo[num-1]->levelflags = get_number(word2);
|
||||
mapheaderinfo[num]->levelflags = get_number(word2);
|
||||
else if (fastcmp(word, "MENUFLAGS"))
|
||||
mapheaderinfo[num-1]->menuflags = get_number(word2);
|
||||
mapheaderinfo[num]->menuflags = get_number(word2);
|
||||
// SRB2Kart
|
||||
else if (fastcmp(word, "MOBJSCALE"))
|
||||
mapheaderinfo[num-1]->mobj_scale = get_number(word2);
|
||||
mapheaderinfo[num]->mobj_scale = get_number(word2);
|
||||
else if (fastcmp(word, "DEFAULTWAYPOINTRADIUS"))
|
||||
mapheaderinfo[num-1]->default_waypoint_radius = get_number(word2);
|
||||
mapheaderinfo[num]->default_waypoint_radius = get_number(word2);
|
||||
else if (fastcmp(word, "LIGHTCONTRAST"))
|
||||
{
|
||||
usemaplighting(num, word)->light_contrast = (UINT8)i;
|
||||
|
|
@ -1422,77 +1426,80 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
else if (fastcmp(word, "SCRIPTISFILE"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_SCRIPTISFILE;
|
||||
mapheaderinfo[num]->levelflags |= LF_SCRIPTISFILE;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_SCRIPTISFILE;
|
||||
mapheaderinfo[num]->levelflags &= ~LF_SCRIPTISFILE;
|
||||
}
|
||||
else if (fastcmp(word, "NOZONE"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_NOZONE;
|
||||
mapheaderinfo[num]->levelflags |= LF_NOZONE;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_NOZONE;
|
||||
mapheaderinfo[num]->levelflags &= ~LF_NOZONE;
|
||||
}
|
||||
else if (fastcmp(word, "SECTIONRACE"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_SECTIONRACE;
|
||||
mapheaderinfo[num]->levelflags |= LF_SECTIONRACE;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_SECTIONRACE;
|
||||
mapheaderinfo[num]->levelflags &= ~LF_SECTIONRACE;
|
||||
}
|
||||
else if (fastcmp(word, "SUBTRACTNUM"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->levelflags |= LF_SUBTRACTNUM;
|
||||
mapheaderinfo[num]->levelflags |= LF_SUBTRACTNUM;
|
||||
else
|
||||
mapheaderinfo[num-1]->levelflags &= ~LF_SUBTRACTNUM;
|
||||
mapheaderinfo[num]->levelflags &= ~LF_SUBTRACTNUM;
|
||||
}
|
||||
|
||||
// Individual triggers for menu flags
|
||||
else if (fastcmp(word, "HIDDEN"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_HIDEINMENU;
|
||||
mapheaderinfo[num]->menuflags |= LF2_HIDEINMENU;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_HIDEINMENU;
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_HIDEINMENU;
|
||||
}
|
||||
else if (fastcmp(word, "HIDEINSTATS"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_HIDEINSTATS;
|
||||
mapheaderinfo[num]->menuflags |= LF2_HIDEINSTATS;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_HIDEINSTATS;
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_HIDEINSTATS;
|
||||
}
|
||||
else if (fastcmp(word, "TIMEATTACK") || fastcmp(word, "RECORDATTACK"))
|
||||
else if (fastcmp(word, "NOTIMEATTACK") || fastcmp(word, "NORECORDATTACK"))
|
||||
{ // RECORDATTACK is an accepted alias
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_NOTIMEATTACK;
|
||||
mapheaderinfo[num]->menuflags |= LF2_NOTIMEATTACK;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_NOTIMEATTACK;
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_NOTIMEATTACK;
|
||||
}
|
||||
else if (fastcmp(word, "VISITNEEDED"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_VISITNEEDED;
|
||||
mapheaderinfo[num]->menuflags |= LF2_VISITNEEDED;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_VISITNEEDED;
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_VISITNEEDED;
|
||||
}
|
||||
else if (fastcmp(word, "NOVISITNEEDED"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->menuflags &= ~LF2_VISITNEEDED;
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_VISITNEEDED;
|
||||
else
|
||||
mapheaderinfo[num-1]->menuflags |= LF2_VISITNEEDED;
|
||||
mapheaderinfo[num]->menuflags |= LF2_VISITNEEDED;
|
||||
}
|
||||
else if (fastcmp(word, "GRAVITY"))
|
||||
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||
mapheaderinfo[num]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||
else if (fastcmp(word, "WALLTRANSFER") || fastcmp(word, "WALLRUNNING"))
|
||||
{
|
||||
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||
mapheaderinfo[num-1]->use_walltransfer = true;
|
||||
mapheaderinfo[num]->use_walltransfer = true;
|
||||
else
|
||||
mapheaderinfo[num-1]->use_walltransfer = false;
|
||||
mapheaderinfo[num]->use_walltransfer = false;
|
||||
}
|
||||
// ignored for compatibility
|
||||
else if (fastcmp(word, "NEXTLEVEL") || fastcmp(word, "TIMEATTACK") || fastcmp(word, "RECORDATTACK"))
|
||||
continue;
|
||||
else
|
||||
deh_warning("Level header %d: unknown word '%s'", num, word);
|
||||
}
|
||||
|
|
@ -2555,16 +2562,9 @@ void reademblemdata(MYFILE *f, INT32 num)
|
|||
}
|
||||
else if (fastcmp(word, "TAG"))
|
||||
emblemlocations[num-1].tag = (INT16)value;
|
||||
else if (fastcmp(word, "MAPNUM"))
|
||||
else if (fastcmp(word, "MAPNAME"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
emblemlocations[num-1].level = (INT16)value;
|
||||
emblemlocations[num-1].level = Z_StrDup(word2);
|
||||
}
|
||||
else if (fastcmp(word, "SPRITE"))
|
||||
{
|
||||
|
|
@ -2785,14 +2785,8 @@ void readunlockable(MYFILE *f, INT32 num)
|
|||
}
|
||||
else if (fastcmp(word, "VAR"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
unlockables[num].variable = (INT16)i;
|
||||
// TODO: different field for level name string
|
||||
unlockables[num].variable = (INT16)G_MapNumber(word2);
|
||||
}
|
||||
else
|
||||
deh_warning("Unlockable %d: unknown word '%s'", num+1, word);
|
||||
|
|
@ -2830,7 +2824,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (!params[0])
|
||||
{
|
||||
deh_warning("condition line is empty");
|
||||
deh_warning("condition line is empty for condition ID %d", id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2850,7 +2844,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (x1 < 0 || x1 >= PWRLV_NUMTYPES)
|
||||
{
|
||||
deh_warning("Power level type %d out of range (0 - %d)", x1, PWRLV_NUMTYPES-1);
|
||||
deh_warning("Power level type %d out of range (0 - %d) for condition ID %d", x1, PWRLV_NUMTYPES-1, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2870,16 +2864,11 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
{
|
||||
PARAMCHECK(1);
|
||||
ty = UC_MAPVISITED + offset;
|
||||
re = G_MapNumber(params[1]);
|
||||
|
||||
// Convert to map number if it appears to be one
|
||||
if (params[1][0] >= 'A' && params[1][0] <= 'Z')
|
||||
re = M_MapNumber(params[1][0], params[1][1]);
|
||||
else
|
||||
re = atoi(params[1]);
|
||||
|
||||
if (re < 0 || re >= NUMMAPS)
|
||||
if (re >= nummapheaders)
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
|
||||
deh_warning("Invalid level %s for condition ID %d", params[1], id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2888,16 +2877,11 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
PARAMCHECK(2);
|
||||
ty = UC_MAPTIME;
|
||||
re = atoi(params[2]);
|
||||
x1 = G_MapNumber(params[1]);
|
||||
|
||||
// Convert to map number if it appears to be one
|
||||
if (params[1][0] >= 'A' && params[1][0] <= 'Z')
|
||||
x1 = (INT16)M_MapNumber(params[1][0], params[1][1]);
|
||||
else
|
||||
x1 = (INT16)atoi(params[1]);
|
||||
|
||||
if (x1 < 0 || x1 >= NUMMAPS)
|
||||
if (x1 >= nummapheaders)
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", x1, NUMMAPS);
|
||||
deh_warning("Invalid level %s for condition ID %d", params[1], id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2910,7 +2894,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
// constrained by 32 bits
|
||||
if (re < 0 || re > 31)
|
||||
{
|
||||
deh_warning("Trigger ID %d out of range (0 - 31)", re);
|
||||
deh_warning("Trigger ID %d out of range (0 - 31) for condition ID %d", re, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2928,7 +2912,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (re <= 0 || re > MAXEMBLEMS)
|
||||
{
|
||||
deh_warning("Emblem %d out of range (1 - %d)", re, MAXEMBLEMS);
|
||||
deh_warning("Emblem %d out of range (1 - %d) for condition ID %d", re, MAXEMBLEMS, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2940,7 +2924,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (re <= 0 || re > MAXEXTRAEMBLEMS)
|
||||
{
|
||||
deh_warning("Extra emblem %d out of range (1 - %d)", re, MAXEXTRAEMBLEMS);
|
||||
deh_warning("Extra emblem %d out of range (1 - %d) for condition ID %d", re, MAXEXTRAEMBLEMS, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2952,13 +2936,13 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (re <= 0 || re > MAXCONDITIONSETS)
|
||||
{
|
||||
deh_warning("Condition set %d out of range (1 - %d)", re, MAXCONDITIONSETS);
|
||||
deh_warning("Condition set %d out of range (1 - %d) for condition ID %d", re, MAXCONDITIONSETS, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Invalid condition name %s", params[0]);
|
||||
deh_warning("Invalid condition name %s for condition ID %d", params[0], id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3093,61 +3077,6 @@ void readmaincfg(MYFILE *f)
|
|||
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
}
|
||||
}
|
||||
|
||||
else if (fastcmp(word, "SPSTAGE_START"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
spstage_start = spmarathon_start = (INT16)value;
|
||||
}
|
||||
else if (fastcmp(word, "SPMARATHON_START"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
spmarathon_start = (INT16)value;
|
||||
}
|
||||
else if (fastcmp(word, "SSTAGE_START"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
sstage_start = (INT16)value;
|
||||
sstage_end = (INT16)(sstage_start+7); // 7 special stages total plus one weirdo
|
||||
}
|
||||
else if (fastcmp(word, "SMPSTAGE_START"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
smpstage_start = (INT16)value;
|
||||
smpstage_end = (INT16)(smpstage_start+6); // 7 special stages total
|
||||
}
|
||||
else if (fastcmp(word, "REDTEAM"))
|
||||
{
|
||||
skincolor_redteam = (UINT16)get_number(word2);
|
||||
|
|
@ -3230,16 +3159,7 @@ void readmaincfg(MYFILE *f)
|
|||
}
|
||||
else if (fastcmp(word, "TITLEMAP"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
titlemap = (INT16)value;
|
||||
titlemap = Z_StrDup(word2);
|
||||
titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE"))
|
||||
|
|
@ -3365,30 +3285,12 @@ void readmaincfg(MYFILE *f)
|
|||
}
|
||||
else if (fastcmp(word, "BOOTMAP"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
bootmap = (INT16)value;
|
||||
bootmap = Z_StrDup(word2);
|
||||
//titlechanged = true;
|
||||
}
|
||||
else if (fastcmp(word, "TUTORIALMAP"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
value = M_MapNumber(word2[0], word2[1]);
|
||||
else
|
||||
value = get_number(word2);
|
||||
|
||||
tutorialmap = (INT16)value;
|
||||
tutorialmap = Z_StrDup(word2);
|
||||
}
|
||||
else
|
||||
deh_warning("Maincfg: unknown word '%s'", word);
|
||||
|
|
@ -3600,7 +3502,16 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
|
|||
i = atoi(word2); // used for numerical settings
|
||||
strupr(word2);
|
||||
|
||||
if (fastcmp(word, "ICON"))
|
||||
if (fastcmp(word, "MONITOR"))
|
||||
{
|
||||
if (i > 0 && i < 10)
|
||||
cup->monitor = i;
|
||||
else if (!word2[0] || word2[1] != '\0' || word2[0] == '0')
|
||||
deh_warning("%s Cup: Invalid monitor type \"%s\" (should be 1-9 or A-Z)\n", cup->name, word2);
|
||||
else
|
||||
cup->monitor = (word2[0] - 'A') + 10;
|
||||
}
|
||||
else if (fastcmp(word, "ICON"))
|
||||
{
|
||||
deh_strlcpy(cup->icon, word2,
|
||||
sizeof(cup->icon), va("%s Cup: icon", cup->name));
|
||||
|
|
@ -3611,37 +3522,26 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
|
|||
|
||||
tmp = strtok(word2,",");
|
||||
do {
|
||||
INT32 map = atoi(tmp);
|
||||
|
||||
if (tmp[0] >= 'A' && tmp[0] <= 'Z' && tmp[2] == '\0')
|
||||
map = M_MapNumber(tmp[0], tmp[1]);
|
||||
|
||||
if (!map)
|
||||
break;
|
||||
|
||||
if (cup->numlevels >= MAXLEVELLIST)
|
||||
{
|
||||
deh_warning("%s Cup: reached max levellist (%d)\n", cup->name, MAXLEVELLIST);
|
||||
break;
|
||||
}
|
||||
|
||||
cup->levellist[cup->numlevels] = map - 1;
|
||||
cup->levellist[cup->numlevels] = Z_StrDup(tmp);
|
||||
cup->cachedlevels[cup->numlevels] = NEXTMAP_INVALID;
|
||||
cup->numlevels++;
|
||||
} while((tmp = strtok(NULL,",")) != NULL);
|
||||
}
|
||||
else if (fastcmp(word, "BONUSGAME"))
|
||||
{
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
cup->bonusgame = (INT16)i - 1;
|
||||
cup->levellist[CUPCACHE_BONUS] = Z_StrDup(word2);
|
||||
cup->cachedlevels[CUPCACHE_BONUS] = NEXTMAP_INVALID;
|
||||
}
|
||||
else if (fastcmp(word, "SPECIALSTAGE"))
|
||||
{
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
cup->specialstage = (INT16)i - 1;
|
||||
cup->levellist[CUPCACHE_SPECIAL] = Z_StrDup(word2);
|
||||
cup->cachedlevels[CUPCACHE_SPECIAL] = NEXTMAP_INVALID;
|
||||
}
|
||||
else if (fastcmp(word, "EMERALDNUM"))
|
||||
{
|
||||
|
|
@ -4374,19 +4274,6 @@ static fixed_t find_const(const char **rword)
|
|||
free(word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("GRADE_",word,6))
|
||||
{
|
||||
char *p = word+6;
|
||||
for (i = 0; NIGHTSGRADE_LIST[i]; i++)
|
||||
if (*p == NIGHTSGRADE_LIST[i])
|
||||
{
|
||||
free(word);
|
||||
return i;
|
||||
}
|
||||
const_warning("NiGHTS grade",word);
|
||||
free(word);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; INT_CONST[i].n; i++)
|
||||
if (fastcmp(word,INT_CONST[i].n)) {
|
||||
free(word);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ void readhuditem(MYFILE *f, INT32 num);
|
|||
void readmenu(MYFILE *f, INT32 num);
|
||||
void readtextprompt(MYFILE *f, INT32 num);
|
||||
void readcutscene(MYFILE *f, INT32 num);
|
||||
void readlevelheader(MYFILE *f, INT32 num);
|
||||
void readlevelheader(MYFILE *f, char * name);
|
||||
void readgametype(MYFILE *f, char *gtname);
|
||||
void readsprite2(MYFILE *f, INT32 num);
|
||||
#ifdef HWRENDER
|
||||
|
|
|
|||
|
|
@ -35,17 +35,6 @@ char *FREE_MOBJS[NUMMOBJFREESLOTS];
|
|||
char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
|
||||
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
|
||||
|
||||
const char NIGHTSGRADE_LIST[] = {
|
||||
'F', // GRADE_F
|
||||
'E', // GRADE_E
|
||||
'D', // GRADE_D
|
||||
'C', // GRADE_C
|
||||
'B', // GRADE_B
|
||||
'A', // GRADE_A
|
||||
'S', // GRADE_S
|
||||
'\0'
|
||||
};
|
||||
|
||||
struct flickytypes_s FLICKYTYPES[] = {
|
||||
{"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky)
|
||||
{"RABBIT", MT_FLICKY_02}, // Pocky (1)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ struct int_const_s {
|
|||
lua_Integer v;
|
||||
};
|
||||
|
||||
extern const char NIGHTSGRADE_LIST[];
|
||||
extern struct flickytypes_s FLICKYTYPES[];
|
||||
extern actionpointer_t actionpointers[]; // Array mapping action names to action functions.
|
||||
extern const char *const STATE_LIST[];
|
||||
|
|
|
|||
|
|
@ -368,25 +368,19 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
#endif
|
||||
else if (fastcmp(word, "LEVEL"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
// i.e., Level AB, Level FZ, etc.
|
||||
|
||||
// Convert to map number
|
||||
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||
i = M_MapNumber(word2[0], word2[1]);
|
||||
|
||||
if (i > 0 && i <= NUMMAPS)
|
||||
size_t len = strlen(word2);
|
||||
if (len <= MAXMAPLUMPNAME-1)
|
||||
{
|
||||
if (mapheaderinfo[i])
|
||||
{
|
||||
G_SetGameModified(multiplayer, true); // Only a major mod if editing stuff that isn't your own!
|
||||
}
|
||||
|
||||
readlevelheader(f, i);
|
||||
if (len == 1)
|
||||
readlevelheader(f, va("MAP0%s",word2));
|
||||
else if (len == 2)
|
||||
readlevelheader(f, va("MAP%s",word2));
|
||||
else
|
||||
readlevelheader(f, word2);
|
||||
}
|
||||
else
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS);
|
||||
deh_warning("Map header's lumpname %s is too long (%s characters VS %d max)", word2, sizeu1(len), (MAXMAPLUMPNAME-1));
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
|
|
@ -519,38 +513,51 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
//
|
||||
else if (fastcmp(word, "CUP"))
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
cupheader_t *prev = NULL;
|
||||
|
||||
while (cup)
|
||||
size_t len = strlen(word2);
|
||||
if (len <= MAXCUPNAME-1)
|
||||
{
|
||||
if (fastcmp(cup->name, word2))
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
cupheader_t *prev = NULL;
|
||||
UINT32 hash = quickncasehash(word2, MAXCUPNAME);
|
||||
|
||||
while (cup)
|
||||
{
|
||||
// Only a major mod if editing stuff that isn't your own!
|
||||
G_SetGameModified(multiplayer, true);
|
||||
break;
|
||||
if (hash == cup->namehash && fastcmp(cup->name, word2))
|
||||
{
|
||||
// Only a major mod if editing stuff that isn't your own!
|
||||
G_SetGameModified(multiplayer, true);
|
||||
break;
|
||||
}
|
||||
|
||||
prev = cup;
|
||||
cup = cup->next;
|
||||
}
|
||||
|
||||
prev = cup;
|
||||
cup = cup->next;
|
||||
}
|
||||
// Nothing found, add to the end.
|
||||
if (!cup)
|
||||
{
|
||||
cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL);
|
||||
cup->id = numkartcupheaders;
|
||||
cup->monitor = 1;
|
||||
deh_strlcpy(cup->name, word2,
|
||||
sizeof(cup->name), va("Cup header %s: name", word2));
|
||||
cup->namehash = hash;
|
||||
if (prev != NULL)
|
||||
prev->next = cup;
|
||||
if (kartcupheaders == NULL)
|
||||
kartcupheaders = cup;
|
||||
numkartcupheaders++;
|
||||
CONS_Printf("Added cup %d ('%s')\n", cup->id, cup->name);
|
||||
}
|
||||
|
||||
// Nothing found, add to the end.
|
||||
if (!cup)
|
||||
readcupheader(f, cup);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL);
|
||||
cup->id = numkartcupheaders;
|
||||
deh_strlcpy(cup->name, word2,
|
||||
sizeof(cup->name), va("Cup header %s: name", word2));
|
||||
if (prev != NULL)
|
||||
prev->next = cup;
|
||||
if (kartcupheaders == NULL)
|
||||
kartcupheaders = cup;
|
||||
numkartcupheaders++;
|
||||
CONS_Printf("Added cup %d ('%s')\n", cup->id, cup->name);
|
||||
deh_warning("Cup header's name %s is too long (%s characters VS %d max)", word2, sizeu1(len), (MAXCUPNAME-1));
|
||||
ignorelines(f);
|
||||
}
|
||||
|
||||
readcupheader(f, cup);
|
||||
}
|
||||
else if (fastcmp(word, "WEATHER") || fastcmp(word, "PRECIP") || fastcmp(word, "PRECIPITATION"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -442,7 +442,6 @@ void DRPC_UpdatePresence(void)
|
|||
|
||||
char detailstr[48+1];
|
||||
|
||||
char mapimg[8+1];
|
||||
char mapname[5+21+21+2+1];
|
||||
|
||||
char charimg[4+SKINNAMESIZE+1];
|
||||
|
|
@ -545,14 +544,7 @@ void DRPC_UpdatePresence(void)
|
|||
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) // Map info
|
||||
&& !(demo.playback && demo.title))
|
||||
{
|
||||
if ((gamemap >= 1 && gamemap <= 60) // supported race maps
|
||||
|| (gamemap >= 136 && gamemap <= 164)) // supported battle maps
|
||||
{
|
||||
snprintf(mapimg, 8, "%s", G_BuildMapName(gamemap));
|
||||
strlwr(mapimg);
|
||||
discordPresence.largeImageKey = mapimg; // Map image
|
||||
}
|
||||
else if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||
if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||
{
|
||||
// Hell map, use the method that got you here :P
|
||||
discordPresence.largeImageKey = "miscdice";
|
||||
|
|
|
|||
|
|
@ -289,8 +289,6 @@ struct mapthing_t
|
|||
|
||||
#define ZSHIFT 4
|
||||
|
||||
#define NUMMAPS 1035
|
||||
|
||||
/* slope thing types */
|
||||
enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ extern char liveeventbackup[256];
|
|||
void M_StartupLocale(void);
|
||||
void *M_Memcpy(void* dest, const void* src, size_t n);
|
||||
char *va(const char *format, ...) FUNCPRINTF;
|
||||
char *xva(const char *format, ...) FUNCPRINTF;
|
||||
|
||||
char *M_GetToken(const char *inputString);
|
||||
void M_UnGetToken(void);
|
||||
|
|
@ -386,6 +387,7 @@ typedef enum
|
|||
DBG_SETUP = 0x00000400,
|
||||
DBG_LUA = 0x00000800,
|
||||
DBG_RNG = 0x00001000,
|
||||
DBG_DEMO = 0x00002000,
|
||||
} debugFlags_t;
|
||||
|
||||
struct debugFlagNames_s
|
||||
|
|
|
|||
260
src/doomstat.h
260
src/doomstat.h
|
|
@ -107,6 +107,23 @@ extern preciptype_t precip_freeslot;
|
|||
extern preciptype_t globalweather;
|
||||
extern preciptype_t curWeather;
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
struct recorddata_t
|
||||
{
|
||||
tic_t time; ///< Time in which the level was finished.
|
||||
tic_t lap; ///< Best lap time for this level.
|
||||
//UINT32 score; ///< Score when the level was finished.
|
||||
//UINT16 rings; ///< Rings when the level was finished.
|
||||
};
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED (1)
|
||||
#define MV_BEATEN (1<<1)
|
||||
#define MV_ENCORE (1<<2)
|
||||
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE)
|
||||
#define MV_MP ((MV_MAX+1)<<1)
|
||||
|
||||
// Set if homebrew PWAD stuff has been added.
|
||||
extern boolean modifiedgame;
|
||||
extern boolean majormods;
|
||||
|
|
@ -190,15 +207,11 @@ extern INT32 splitscreen_party[MAXPLAYERS][MAXSPLITSCREENPLAYERS];
|
|||
/* the only local one */
|
||||
extern boolean splitscreen_partied[MAXPLAYERS];
|
||||
|
||||
// Maps of special importance
|
||||
extern INT16 spstage_start, spmarathon_start;
|
||||
extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
|
||||
|
||||
extern INT16 titlemap;
|
||||
extern char * titlemap;
|
||||
extern boolean hidetitlepics;
|
||||
extern INT16 bootmap; //bootmap for loading a map on startup
|
||||
extern char * bootmap; //bootmap for loading a map on startup
|
||||
|
||||
extern INT16 tutorialmap; // map to load for tutorial
|
||||
extern char * tutorialmap; // map to load for tutorial
|
||||
extern boolean tutorialmode; // are we in a tutorial right now?
|
||||
extern INT32 tutorialgcs; // which control scheme is loaded?
|
||||
|
||||
|
|
@ -207,8 +220,6 @@ extern boolean looptitle;
|
|||
// CTF colors.
|
||||
extern UINT16 skincolor_redteam, skincolor_blueteam, skincolor_redring, skincolor_bluering;
|
||||
|
||||
extern tic_t countdowntimer;
|
||||
extern boolean countdowntimeup;
|
||||
extern boolean exitfadestarted;
|
||||
|
||||
struct scene_t
|
||||
|
|
@ -299,8 +310,6 @@ extern textprompt_t *textprompts[MAX_PROMPTS];
|
|||
extern INT16 nextmapoverride;
|
||||
extern UINT8 skipstats;
|
||||
|
||||
extern UINT32 ssspheres; // Total # of spheres in a level
|
||||
|
||||
// Fun extra stuff
|
||||
extern INT16 lastmap; // Last level you were at (returning from special stages).
|
||||
|
||||
|
|
@ -321,12 +330,6 @@ extern struct quake
|
|||
fixed_t radius, intensity;
|
||||
} quake;
|
||||
|
||||
// NiGHTS grades
|
||||
typedef struct
|
||||
{
|
||||
UINT32 grade[6]; // D, C, B, A, S, X (F: failed to reach any of these)
|
||||
} nightsgrades_t;
|
||||
|
||||
// Custom Lua values
|
||||
struct customoption_t
|
||||
{
|
||||
|
|
@ -344,96 +347,115 @@ struct mapheader_lighting_t
|
|||
|
||||
#define MAXMUSNAMES 3 // maximum definable music tracks per level
|
||||
|
||||
// This could support more, but is that a good idea?
|
||||
// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory.
|
||||
#define MAXLEVELLIST 5
|
||||
#define CUPCACHE_BONUS MAXLEVELLIST
|
||||
#define CUPCACHE_SPECIAL MAXLEVELLIST+1
|
||||
#define CUPCACHE_MAX CUPCACHE_SPECIAL+1
|
||||
|
||||
#define MAXCUPNAME 16 // includes \0, for cleaner savedata
|
||||
|
||||
struct cupheader_t
|
||||
{
|
||||
UINT16 id; ///< Cup ID
|
||||
UINT8 monitor; ///< Monitor graphic 1-9 or A-Z
|
||||
|
||||
char name[MAXCUPNAME]; ///< Cup title
|
||||
UINT32 namehash; ///< Cup title hash
|
||||
|
||||
char icon[9]; ///< Name of the icon patch
|
||||
char *levellist[CUPCACHE_MAX]; ///< List of levels that belong to this cup
|
||||
INT16 cachedlevels[CUPCACHE_MAX]; ///< IDs in levellist, bonusgame, and specialstage
|
||||
UINT8 numlevels; ///< Number of levels defined in levellist
|
||||
UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald)
|
||||
SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required.
|
||||
cupheader_t *next; ///< Next cup in linked list
|
||||
};
|
||||
|
||||
extern cupheader_t *kartcupheaders; // Start of cup linked list
|
||||
extern UINT16 numkartcupheaders;
|
||||
|
||||
#define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata
|
||||
|
||||
/** Map header information.
|
||||
*/
|
||||
struct mapheader_t
|
||||
{
|
||||
// The original eight, plus one.
|
||||
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
|
||||
char subttl[33]; ///< Subtitle for level
|
||||
char zonttl[22]; ///< "ZONE" replacement name
|
||||
char actnum[3]; ///< SRB2Kart: Now a 2 character long string.
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
||||
INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI.
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
|
||||
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
|
||||
char skytexture[9]; ///< Sky texture to use.
|
||||
INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.)
|
||||
INT16 skybox_scaley; ///< Skybox Y axis scale.
|
||||
INT16 skybox_scalez; ///< Skybox Z axis scale.
|
||||
// Core game information, not user-modifiable directly
|
||||
char *lumpname; ///< Lump name can be really long
|
||||
UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME)
|
||||
lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap
|
||||
|
||||
// Extra information.
|
||||
char interscreen[8]; ///< 320x200 patch to display at intermission.
|
||||
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)
|
||||
char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191)
|
||||
UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
|
||||
UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
|
||||
INT16 countdown; ///< Countdown until level end?
|
||||
UINT16 palette; ///< PAL lump to use on this map
|
||||
UINT16 encorepal; ///< PAL for encore mode
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
|
||||
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
|
||||
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
|
||||
SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.)
|
||||
void *thumbnailPic; ///< Lump data for the level select thumbnail.
|
||||
void *minimapPic; ///< Lump data for the minimap graphic.
|
||||
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
||||
UINT8 mapvisited; ///< A set of flags that says what we've done in the map.
|
||||
recorddata_t *mainrecord; ///< Stores best time attack data
|
||||
|
||||
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
|
||||
UINT16 startrings; ///< Number of rings players start with.
|
||||
INT32 sstimer; ///< Timer for special stages.
|
||||
UINT32 ssspheres; ///< Sphere requirement in special stages.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
cupheader_t *cup; ///< Cached cup
|
||||
|
||||
// Title card.
|
||||
char ltzzpatch[8]; ///< Zig zag patch.
|
||||
char ltzztext[8]; ///< Zig zag text.
|
||||
char ltactdiamond[8]; ///< Act diamond.
|
||||
// Titlecard information
|
||||
char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
|
||||
char subttl[33]; ///< Subtitle for level
|
||||
char zonttl[22]; ///< "ZONE" replacement name
|
||||
char actnum[3]; ///< SRB2Kart: Now a 2 character long string.
|
||||
|
||||
// Freed animals stuff.
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
// Selection metadata
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
|
||||
// NiGHTS stuff.
|
||||
UINT8 numGradedMares; ///< Internal. For grade support.
|
||||
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
|
||||
SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no.
|
||||
UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in?
|
||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack menus
|
||||
|
||||
// SRB2kart
|
||||
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
|
||||
fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale
|
||||
// Operational metadata
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden.
|
||||
fixed_t gravity; ///< Map-wide gravity.
|
||||
|
||||
mapheader_lighting_t lighting; ///< Wall and sprite lighting
|
||||
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
|
||||
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
|
||||
|
||||
boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not
|
||||
|
||||
// Music stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
// Music information
|
||||
char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music.
|
||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||
UINT32 muspos; ///< Music position to jump to.
|
||||
UINT8 musname_size; ///< Number of music tracks defined
|
||||
|
||||
char muspostbossname[7]; ///< Post-bossdeath music.
|
||||
UINT16 muspostbosstrack; ///< Post-bossdeath track.
|
||||
UINT32 muspostbosspos; ///< Post-bossdeath position
|
||||
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds.
|
||||
// Sky information
|
||||
UINT8 weather; ///< See preciptype_t
|
||||
char skytexture[9]; ///< Sky texture to use.
|
||||
INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.)
|
||||
INT16 skybox_scaley; ///< Skybox Y axis scale.
|
||||
INT16 skybox_scalez; ///< Skybox Z axis scale.
|
||||
|
||||
SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on)
|
||||
// Distance information
|
||||
fixed_t mobj_scale; ///< Defines the size all object calculations are relative to
|
||||
fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale
|
||||
|
||||
// SRB2Kart: Keeps track of if a map lump exists, so we can tell when a map is being replaced.
|
||||
boolean alreadyExists;
|
||||
// Visual information
|
||||
UINT16 palette; ///< PAL lump to use on this map
|
||||
UINT16 encorepal; ///< PAL for encore mode
|
||||
mapheader_lighting_t lighting; ///< Wall and sprite lighting
|
||||
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
|
||||
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
|
||||
|
||||
// Lua stuff.
|
||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
|
||||
// Freed animal information
|
||||
UINT8 numFlickies; ///< Internal. For freed flicky support.
|
||||
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
// Script information
|
||||
char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)
|
||||
char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191)
|
||||
|
||||
// Cutscene information
|
||||
UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
|
||||
UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
|
||||
|
||||
// Lua information
|
||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
// BlanKart
|
||||
boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -448,28 +470,8 @@ struct mapheader_t
|
|||
#define LF2_NOTIMEATTACK (1<<2) ///< Hide this map in Time Attack modes
|
||||
#define LF2_VISITNEEDED (1<<3) ///< Not available in Time Attack modes until you visit the level
|
||||
|
||||
extern mapheader_t* mapheaderinfo[NUMMAPS];
|
||||
|
||||
// This could support more, but is that a good idea?
|
||||
// Keep in mind that it may encourage people making overly long cups just because they "can", and would be a waste of memory.
|
||||
#define MAXLEVELLIST 5
|
||||
|
||||
struct cupheader_t
|
||||
{
|
||||
UINT16 id; ///< Cup ID
|
||||
char name[15]; ///< Cup title (14 chars)
|
||||
char icon[9]; ///< Name of the icon patch
|
||||
INT16 levellist[MAXLEVELLIST]; ///< List of levels that belong to this cup
|
||||
UINT8 numlevels; ///< Number of levels defined in levellist
|
||||
INT16 bonusgame; ///< Map number to use for bonus game
|
||||
INT16 specialstage; ///< Map number to use for special stage
|
||||
UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald)
|
||||
SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required.
|
||||
cupheader_t *next; ///< Next cup in linked list
|
||||
};
|
||||
|
||||
extern cupheader_t *kartcupheaders; // Start of cup linked list
|
||||
extern UINT16 numkartcupheaders;
|
||||
extern mapheader_t** mapheaderinfo;
|
||||
extern INT32 nummapheaders, mapallocsize;
|
||||
|
||||
// Gametypes
|
||||
#define NUMGAMETYPEFREESLOTS 128
|
||||
|
|
@ -577,52 +579,10 @@ extern INT32 luabanks[NUM_LUABANKS];
|
|||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
struct recorddata_t
|
||||
{
|
||||
tic_t time; ///< Time in which the level was finished.
|
||||
tic_t lap; ///< Best lap time for this level.
|
||||
//UINT32 score; ///< Score when the level was finished.
|
||||
//UINT16 rings; ///< Rings when the level was finished.
|
||||
};
|
||||
|
||||
/** Setup for one NiGHTS map.
|
||||
* These are dynamically allocated because I am insane
|
||||
*/
|
||||
#define GRADE_F 0
|
||||
#define GRADE_E 1
|
||||
#define GRADE_D 2
|
||||
#define GRADE_C 3
|
||||
#define GRADE_B 4
|
||||
#define GRADE_A 5
|
||||
#define GRADE_S 6
|
||||
|
||||
/*typedef struct
|
||||
{
|
||||
// 8 mares, 1 overall (0)
|
||||
UINT8 nummares;
|
||||
UINT32 score[9];
|
||||
UINT8 grade[9];
|
||||
tic_t time[9];
|
||||
} nightsdata_t;*/
|
||||
|
||||
//extern nightsdata_t *nightsrecords[NUMMAPS];
|
||||
extern recorddata_t *mainrecords[NUMMAPS];
|
||||
|
||||
// mapvisited is now a set of flags that says what we've done in the map.
|
||||
#define MV_VISITED (1)
|
||||
#define MV_BEATEN (1<<1)
|
||||
#define MV_ENCORE (1<<2)
|
||||
#define MV_MAX (MV_VISITED|MV_BEATEN|MV_ENCORE)
|
||||
#define MV_MP ((MV_MAX+1)<<1)
|
||||
extern UINT8 mapvisited[NUMMAPS];
|
||||
|
||||
extern UINT32 token; ///< Number of tokens collected in a level
|
||||
extern UINT32 tokenlist; ///< List of tokens collected
|
||||
extern boolean gottoken; ///< Did you get a token? Used for end of act
|
||||
extern INT32 tokenbits; ///< Used for setting token bits
|
||||
extern INT32 sstimer; ///< Time allotted in the special stage
|
||||
extern UINT32 bluescore; ///< Blue Team Scores
|
||||
extern UINT32 redscore; ///< Red Team Scores
|
||||
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,8 @@ static void F_CacheTitleScreen(void)
|
|||
|
||||
void F_StartTitleScreen(void)
|
||||
{
|
||||
INT32 titleMapNum;
|
||||
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||
{
|
||||
ttuser_count = 0;
|
||||
|
|
@ -1127,23 +1129,23 @@ void F_StartTitleScreen(void)
|
|||
else
|
||||
wipegamestate = GS_TITLESCREEN;
|
||||
|
||||
if (titlemap)
|
||||
if (titlemap
|
||||
&& ((titleMapNum = G_MapNumber(titlemap)) < nummapheaders)
|
||||
&& mapheaderinfo[titleMapNum]
|
||||
&& mapheaderinfo[titleMapNum]->lumpnum != LUMPERROR)
|
||||
{
|
||||
mapthing_t *startpos;
|
||||
|
||||
gamestate_t prevwipegamestate = wipegamestate;
|
||||
titlemapinaction = TITLEMAP_LOADING;
|
||||
titlemapcameraref = NULL;
|
||||
gamemap = titlemap;
|
||||
gamemap = titleMapNum+1;
|
||||
|
||||
if (!mapheaderinfo[gamemap-1])
|
||||
P_AllocMapHeader(gamemap-1);
|
||||
|
||||
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
|
||||
globalweather = mapheaderinfo[gamemap-1]->weather;
|
||||
maptol = mapheaderinfo[titleMapNum]->typeoflevel;
|
||||
globalweather = mapheaderinfo[titleMapNum]->weather;
|
||||
|
||||
G_DoLoadLevel(true);
|
||||
if (!titlemap)
|
||||
if (!titleMapNum)
|
||||
return;
|
||||
|
||||
players[displayplayers[0]].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater)
|
||||
|
|
@ -1418,20 +1420,17 @@ void F_TitleScreenTicker(boolean run)
|
|||
// is it time?
|
||||
if (!(--demoIdleLeft))
|
||||
{
|
||||
//static boolean use_netreplay = false;
|
||||
|
||||
char dname[9];
|
||||
lumpnum_t l;
|
||||
const char *mapname;
|
||||
char dname[MAXMAPLUMPNAME+1+8+1];
|
||||
UINT16 mapnum;
|
||||
UINT8 numstaff;
|
||||
static boolean use_netreplay = false;
|
||||
|
||||
//@TODO uncomment this when this goes into vanilla
|
||||
/*if ((use_netreplay = !use_netreplay))*/
|
||||
if ((use_netreplay = !use_netreplay))
|
||||
{
|
||||
numstaff = 1;
|
||||
while ((l = W_CheckNumForName(va("TDEMO%03u", numstaff))) != LUMPERROR)
|
||||
lumpnum_t l = LUMPERROR;
|
||||
numstaff = 0;
|
||||
while (numstaff < 99 && (l = W_CheckNumForName(va("TDEMO%03u", numstaff))) != LUMPERROR)
|
||||
numstaff++;
|
||||
numstaff--;
|
||||
|
||||
if (numstaff)
|
||||
{
|
||||
|
|
@ -1444,54 +1443,38 @@ void F_TitleScreenTicker(boolean run)
|
|||
// prevent console spam if failed
|
||||
demoIdleLeft = demoIdleTime;
|
||||
|
||||
if ((l = W_CheckNumForName("MAP01S01")) == LUMPERROR) // gotta have ONE
|
||||
mapnum = G_RandMap(TOL_RACE, -2, 2, 0, false, NULL);
|
||||
if (mapnum == 0) // gotta have ONE
|
||||
{
|
||||
F_StartIntro();
|
||||
return;
|
||||
}
|
||||
|
||||
// Replay intro when done cycling through demos
|
||||
/*
|
||||
if (curDemo == numDemos) -- uuuh... we have a LOT of maps AND a big devteam... probably not gonna see a repeat unless you're super unlucky :V
|
||||
{
|
||||
curDemo = 0;
|
||||
F_StartIntro();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
mapname = G_BuildMapName(G_RandMap(TOL_RACE, -2, 0, 0, false, NULL)+1);
|
||||
|
||||
numstaff = 1;
|
||||
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",mapname,numstaff+1))) != LUMPERROR)
|
||||
numstaff++;
|
||||
|
||||
#if 0 // turns out this isn't how we're gonna organise 'em
|
||||
if (numstaff > 1)
|
||||
{
|
||||
if (laststaff && laststaff <= numstaff) // don't do the same staff member twice in a row, even if they're on different maps
|
||||
{
|
||||
numstaff = M_RandomKey(numstaff-1)+1;
|
||||
if (numstaff >= laststaff)
|
||||
numstaff++;
|
||||
}
|
||||
else
|
||||
numstaff = M_RandomKey(numstaff)+1;
|
||||
}
|
||||
laststaff = numstaff;
|
||||
#else
|
||||
numstaff = M_RandomKey(numstaff)+1;
|
||||
#endif
|
||||
|
||||
// Setup demo name
|
||||
snprintf(dname, 9, "%sS%02u", mapname, numstaff);
|
||||
sprintf(dname, "%s/GHOST_%u", mapheaderinfo[mapnum]->lumpname, numstaff);
|
||||
|
||||
/*if ((l = W_CheckNumForName(dname)) == LUMPERROR) -- we KNOW it exists now
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Demo lump \"%s\" doesn't exist\n"), dname);
|
||||
F_StartIntro();
|
||||
return;
|
||||
}*/
|
||||
// vres GHOST_%u
|
||||
virtres_t *vRes;
|
||||
virtlump_t *vLump;
|
||||
|
||||
vRes = vres_GetMap(mapheaderinfo[mapnum]->lumpnum);
|
||||
vLump = vres_Find(vRes, dname);
|
||||
|
||||
if (vLump == NULL)
|
||||
{
|
||||
|
||||
if (((W_CheckNumForName(va("%sS%02u", mapheaderinfo[mapnum]->lumpname, numstaff)))) != LUMPERROR)
|
||||
sprintf(dname, "%sS%02u", mapheaderinfo[mapnum]->lumpname, numstaff);
|
||||
else
|
||||
{
|
||||
vres_Free(vRes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
vres_Free(vRes);
|
||||
}
|
||||
|
||||
loadreplay:
|
||||
demo.title = demo.fromtitle = true;
|
||||
|
|
@ -1628,7 +1611,7 @@ void F_EndCutScene(void)
|
|||
F_StartGameEvaluation();
|
||||
else if (cutnum == introtoplay-1)
|
||||
D_StartTitle();
|
||||
else if (nextmap < 1100-1)
|
||||
else if (nextmap < NEXTMAP_SPECIAL)
|
||||
G_NextLevel();
|
||||
else
|
||||
G_EndGame();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include <tchar.h>
|
||||
|
||||
#define SUFFIX "*"
|
||||
#define SLASH "\\"
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
|
|
@ -139,7 +138,7 @@ opendir (const CHAR *szPath)
|
|||
/* Allocate enough space to store DIR structure and the complete
|
||||
* directory path given. */
|
||||
nd = (DIR *) malloc (sizeof (DIR) + (strlen(szFullPath) + strlen (SLASH) +
|
||||
strlen(SUFFIX) + 1) * sizeof (CHAR));
|
||||
strlen(PATHSEP) + 1) * sizeof (CHAR));
|
||||
|
||||
if (!nd)
|
||||
{
|
||||
|
|
@ -153,10 +152,9 @@ opendir (const CHAR *szPath)
|
|||
|
||||
/* Add on a slash if the path does not end with one. */
|
||||
if (nd->dd_name[0] != '\0' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
|
||||
nd->dd_name[strlen (nd->dd_name) - 1] != PATHSEP[0])
|
||||
{
|
||||
strcat (nd->dd_name, SLASH);
|
||||
strcat (nd->dd_name, PATHSEP);
|
||||
}
|
||||
|
||||
/* Add on the search pattern */
|
||||
|
|
@ -473,9 +471,9 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (searchpath[searchpathindex[depthleft]-2] != '/')
|
||||
if (searchpath[searchpathindex[depthleft]-2] != PATHSEP[0])
|
||||
{
|
||||
searchpath[searchpathindex[depthleft]-1] = '/';
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -517,8 +515,8 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
|
|||
depthleft++;
|
||||
}
|
||||
|
||||
searchpath[searchpathindex[depthleft]-1]='/';
|
||||
searchpath[searchpathindex[depthleft]]=0;
|
||||
searchpath[searchpathindex[depthleft]-1] = PATHSEP[0];
|
||||
searchpath[searchpathindex[depthleft]] = 0;
|
||||
}
|
||||
else if (!strcasecmp(searchname, dent->d_name))
|
||||
{
|
||||
|
|
|
|||
151
src/g_demo.c
151
src/g_demo.c
|
|
@ -59,12 +59,14 @@ consvar_t cv_recordmultiplayerdemos = CVAR_INIT ("netdemo_record", "Manual Save"
|
|||
static CV_PossibleValue_t netdemosyncquality_cons_t[] = {{1, "MIN"}, {35, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_netdemosyncquality = CVAR_INIT ("netdemo_syncquality", "1", CV_SAVE, netdemosyncquality_cons_t, NULL);
|
||||
|
||||
consvar_t cv_netdemosize = CVAR_INIT ("netdemo_size", "6", CV_SAVE, CV_Natural, NULL);
|
||||
|
||||
boolean nodrawers; // for comparative timing purposes
|
||||
boolean noblit; // for comparative timing purposes
|
||||
tic_t demostarttime; // for comparative timing purposes
|
||||
|
||||
static char demoname[MAX_WADPATH];
|
||||
static savebuffer_t demobuf;
|
||||
static savebuffer_t demobuf = {0};
|
||||
static UINT8 *demotime_p, *demoinfo_p;
|
||||
static UINT8 demoflags;
|
||||
boolean demosynced = true; // console warning message
|
||||
|
|
@ -2000,22 +2002,13 @@ void G_RecordDemo(const char *name)
|
|||
|
||||
strcpy(demoname, name);
|
||||
strcat(demoname, ".lmp");
|
||||
//@TODO make a maxdemosize cvar
|
||||
maxsize = 1024*1024*2;
|
||||
maxsize = 1024 * 1024 * cv_netdemosize.value;
|
||||
|
||||
if (M_CheckParm("-maxdemo") && M_IsNextParm())
|
||||
maxsize = atoi(M_GetNextParm()) * 1024;
|
||||
|
||||
// if (demobuf.buffer)
|
||||
// P_SaveBufferFree(&demobuf);
|
||||
|
||||
demobuf.size = maxsize;
|
||||
demobuf.buffer = (UINT8 *)malloc(maxsize);
|
||||
P_SaveBufferAlloc(&demobuf, maxsize);
|
||||
demobuf.p = NULL;
|
||||
demobuf.end = demobuf.buffer + demobuf.size;
|
||||
|
||||
demo.recording = true;
|
||||
//demo.buffer = &demobuf;
|
||||
demo.buffer = &demobuf;
|
||||
|
||||
/* FIXME: This whole file is in a wretched state. Take a
|
||||
look at G_WriteAllGhostTics and G_WriteDemoTiccmd, they
|
||||
|
|
@ -2039,10 +2032,8 @@ void G_RecordMetal(void)
|
|||
if (M_CheckParm("-maxdemo") && M_IsNextParm())
|
||||
maxsize = atoi(M_GetNextParm()) * 1024;
|
||||
|
||||
demobuf.size = maxsize;
|
||||
demobuf.buffer = (UINT8 *)malloc(maxsize);
|
||||
P_SaveBufferAlloc(&demobuf, maxsize);
|
||||
demobuf.p = NULL;
|
||||
demobuf.end = demobuf.buffer + demobuf.size;
|
||||
|
||||
metalrecording = true;
|
||||
}
|
||||
|
|
@ -2088,7 +2079,7 @@ void G_BeginRecording(void)
|
|||
|
||||
// game data
|
||||
M_Memcpy(demobuf.p, "PLAY", 4); demobuf.p += 4;
|
||||
WRITEINT16(demobuf.p,gamemap);
|
||||
WRITESTRINGN(demobuf.p, mapheaderinfo[gamemap-1]->lumpname, MAXMAPLUMPNAME);
|
||||
M_Memcpy(demobuf.p, mapmd5, 16); demobuf.p += 16;
|
||||
|
||||
WRITEUINT8(demobuf.p, demoflags);
|
||||
|
|
@ -2531,7 +2522,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
p += 16; // demo checksum
|
||||
I_Assert(!memcmp(p, "PLAY", 4));
|
||||
p += 4; // PLAY
|
||||
p += 2; // gamemap
|
||||
SKIPSTRING(p); // gamemap
|
||||
p += 16; // map md5
|
||||
flags = READUINT8(p); // demoflags
|
||||
p++; // gametype
|
||||
|
|
@ -2589,7 +2580,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
Z_Free(buffer);
|
||||
return UINT8_MAX;
|
||||
} p += 4; // "PLAY"
|
||||
p += 2; // gamemap
|
||||
SKIPSTRING(p); // gamemap
|
||||
p += 16; // mapmd5
|
||||
flags = READUINT8(p);
|
||||
p++; // gametype
|
||||
|
|
@ -2635,6 +2626,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
UINT8 *infobuffer, *info_p, *extrainfo_p;
|
||||
UINT8 version, subversion, pdemoflags;
|
||||
UINT16 pdemoversion, count;
|
||||
char mapname[MAXMAPLUMPNAME];
|
||||
|
||||
if (!FIL_ReadFile(pdemo->filepath, &infobuffer))
|
||||
{
|
||||
|
|
@ -2694,7 +2686,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
return;
|
||||
}
|
||||
info_p += 4; // "PLAY"
|
||||
pdemo->map = READINT16(info_p);
|
||||
READSTRINGN(info_p, mapname, sizeof(mapname));
|
||||
pdemo->map = G_MapNumber(mapname);
|
||||
info_p += 16; // mapmd5
|
||||
|
||||
pdemoflags = READUINT8(info_p);
|
||||
|
|
@ -2808,7 +2801,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
{
|
||||
UINT8 i, p;
|
||||
lumpnum_t l;
|
||||
char skin[17],color[MAXCOLORNAME+1],follower[17],*n,*pdemoname;
|
||||
char skin[17],color[MAXCOLORNAME+1],follower[17],mapname[MAXMAPLUMPNAME],*n,*pdemoname;
|
||||
UINT8 version,subversion;
|
||||
UINT32 randseed;
|
||||
char msg[1024];
|
||||
|
|
@ -2848,7 +2841,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
if (FIL_CheckExtension(defdemoname))
|
||||
{
|
||||
//FIL_DefaultExtension(defdemoname, ".lmp");
|
||||
if (!FIL_ReadFile(defdemoname, &demobuf.buffer))
|
||||
if (P_SaveBufferFromFile(&demobuf, defdemoname) == false)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read file '%s'.\n"), defdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
|
|
@ -2856,22 +2849,72 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
demobuf.p = demobuf.buffer;
|
||||
}
|
||||
// load demo resource from WAD
|
||||
else if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
|
||||
else
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
else // it's an internal demo
|
||||
{
|
||||
demobuf.buffer = demobuf.p = W_CacheLumpNum(l, PU_STATIC);
|
||||
if (n == defdemoname)
|
||||
{
|
||||
// Raw lump.
|
||||
if ((l = W_CheckNumForName(defdemoname)) == LUMPERROR)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read lump '%s'.\n"), defdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
Z_Free(pdemoname);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
|
||||
P_SaveBufferFromLump(&demobuf, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
// vres GHOST_%u
|
||||
virtres_t *vRes;
|
||||
virtlump_t *vLump;
|
||||
UINT16 mapnum;
|
||||
size_t step = 0;
|
||||
|
||||
step = 0;
|
||||
while (defdemoname+step < n-1)
|
||||
{
|
||||
mapname[step] = defdemoname[step];
|
||||
step++;
|
||||
}
|
||||
mapname[step] = '\0';
|
||||
|
||||
mapnum = G_MapNumber(mapname);
|
||||
if (mapnum >= nummapheaders || mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read lump '%s (couldn't find map %s)'.\n"), defdemoname, mapname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
Z_Free(pdemoname);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
|
||||
vRes = vres_GetMap(mapheaderinfo[mapnum]->lumpnum);
|
||||
vLump = vres_Find(vRes, pdemoname);
|
||||
|
||||
if (vLump == NULL)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("Failed to read lump '%s (couldn't find lump %s in %s)'.\n"), defdemoname, pdemoname, mapname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
Z_Free(pdemoname);
|
||||
gameaction = ga_nothing;
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
|
||||
P_SaveBufferAlloc(&demobuf, vLump->size);
|
||||
memcpy(demobuf.buffer, vLump->data, vLump->size);
|
||||
|
||||
vres_Free(vRes);
|
||||
}
|
||||
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
||||
skiperrors = true; // SRB2Kart: Don't print warnings for staff ghosts, since they'll inevitably happen when we make bugfixes/changes...
|
||||
skiperrors = true; // RR: Don't print warnings for staff ghosts, since they'll inevitably happen when we make bugfixes/changes...
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -2879,13 +2922,14 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
// read demo header
|
||||
gameaction = ga_nothing;
|
||||
demo.playback = true;
|
||||
demo.buffer = &demobuf;
|
||||
if (memcmp(demobuf.p, DEMOHEADER, 12))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is not a SRB2Kart replay file.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -2905,7 +2949,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -2923,14 +2967,15 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
|
||||
demobuf.p += 4; // "PLAY"
|
||||
gamemap = READINT16(demobuf.p);
|
||||
READSTRINGN(demobuf.p, mapname, sizeof(mapname)); // gamemap
|
||||
gamemap = G_MapNumber(mapname)+1;
|
||||
demobuf.p += 16; // mapmd5
|
||||
|
||||
demoflags = READUINT8(demobuf.p);
|
||||
|
|
@ -2987,7 +3032,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
if (!CON_Ready()) // In the console they'll just see the notice there! No point pulling them out.
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -3024,13 +3069,13 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demobuf.p += 4; // Extrainfo location
|
||||
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->alreadyExists == true))
|
||||
if (!gamemap || (gamemap > nummapheaders) || !mapheaderinfo[gamemap-1] || mapheaderinfo[gamemap-1]->lumpnum == LUMPERROR)
|
||||
{
|
||||
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(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -3049,7 +3094,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -3099,7 +3144,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -3115,7 +3160,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
|
|
@ -3225,7 +3270,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
R_ExecuteSetViewSize();
|
||||
|
||||
P_SetRandSeed(randseed);
|
||||
G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true, false); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||
G_InitNew(demoflags & DF_ENCORE, gamemap, true, true, false); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
@ -3340,7 +3385,7 @@ void G_AddGhost(char *defdemoname)
|
|||
} p += 4; // "PLAY"
|
||||
|
||||
|
||||
p += 2; // gamemap
|
||||
SKIPSTRING(p); // gamemap
|
||||
p += 16; // mapmd5 (possibly check for consistency?)
|
||||
|
||||
flags = READUINT8(p);
|
||||
|
|
@ -3468,7 +3513,7 @@ void G_AddGhost(char *defdemoname)
|
|||
ghosts = gh;
|
||||
|
||||
gh->version = ghostversion;
|
||||
mthing = playerstarts[0];
|
||||
mthing = playerstarts[0] ? playerstarts[0] : deathmatchstarts[0]; // todo not correct but out of scope
|
||||
I_Assert(mthing);
|
||||
{ // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling.
|
||||
fixed_t z,f,c;
|
||||
|
|
@ -3572,7 +3617,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
|||
}
|
||||
|
||||
p += 4; // "PLAY"
|
||||
p += 2; // gamemap
|
||||
SKIPSTRING(p); // gamemap
|
||||
p += 16; // mapmd5 (possibly check for consistency?)
|
||||
|
||||
flags = READUINT8(p);
|
||||
|
|
@ -3650,6 +3695,7 @@ void G_DoPlayMetal(void)
|
|||
thinker_t *th;
|
||||
|
||||
// it's an internal demo
|
||||
// TODO: Use map header to determine lump name
|
||||
if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n"));
|
||||
|
|
@ -3758,7 +3804,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill)
|
|||
WriteDemoChecksum();
|
||||
saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuf.buffer, demobuf.p - demobuf.buffer); // finally output the file.
|
||||
}
|
||||
free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
metalrecording = false;
|
||||
if (saved)
|
||||
I_Error("Saved to %sMS.LMP", G_BuildMapName(gamemap));
|
||||
|
|
@ -3826,8 +3872,7 @@ static void G_StopTimingDemo(void)
|
|||
// called from stopdemo command, map command, and g_checkdemoStatus.
|
||||
void G_StopDemo(void)
|
||||
{
|
||||
Z_Free(demobuf.buffer);
|
||||
demobuf.buffer = NULL;
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.playback = false;
|
||||
if (demo.title)
|
||||
modeattacking = false;
|
||||
|
|
@ -3893,6 +3938,8 @@ boolean G_CheckDemoStatus(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (demo.recording)
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.recording = false;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3966,7 +4013,7 @@ void G_SaveDemo(void)
|
|||
|
||||
if (FIL_WriteFile(demoname, demobuf.buffer, demobuf.p - demobuf.buffer)) // finally output the file.
|
||||
demo.savemode = DSM_SAVED;
|
||||
free(demobuf.buffer);
|
||||
P_SaveBufferFree(&demobuf);
|
||||
demo.recording = false;
|
||||
|
||||
if (!modeattacking)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ extern UINT8 *demo_p;
|
|||
// DEMO playback/recording related stuff.
|
||||
// ======================================
|
||||
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality;
|
||||
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality, cv_netdemosize;
|
||||
|
||||
extern tic_t demostarttime;
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ struct demovars_s {
|
|||
|
||||
boolean freecam;
|
||||
|
||||
const savebuffer_t *buffer; // debug, valid only if recording or playback
|
||||
};
|
||||
|
||||
extern struct demovars_s demo;
|
||||
|
|
|
|||
1036
src/g_game.c
1036
src/g_game.c
File diff suppressed because it is too large
Load diff
24
src/g_game.h
24
src/g_game.h
|
|
@ -27,7 +27,6 @@ extern "C" {
|
|||
extern char gamedatafilename[64];
|
||||
extern char timeattackfolder[64];
|
||||
extern char customversionstring[32];
|
||||
#define GAMEDATASIZE (4*8192)
|
||||
|
||||
extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
|
||||
extern INT32 player_name_changes[MAXPLAYERS];
|
||||
|
|
@ -40,6 +39,19 @@ extern tic_t levelstarttic;
|
|||
|
||||
// for modding?
|
||||
extern INT16 prevmap, nextmap;
|
||||
|
||||
// see also G_MapNumber
|
||||
typedef enum
|
||||
{
|
||||
NEXTMAP_RESERVED = INT16_MAX, // so nextmap+1 doesn't roll over -- remove when gamemap is made 0-indexed
|
||||
NEXTMAP_TITLE = INT16_MAX-1,
|
||||
NEXTMAP_EVALUATION = INT16_MAX-2,
|
||||
NEXTMAP_CREDITS = INT16_MAX-3,
|
||||
NEXTMAP_CEREMONY = INT16_MAX-4,
|
||||
NEXTMAP_INVALID = INT16_MAX-5, // Always last (swap with NEXTMAP_RESERVED when removing that)
|
||||
NEXTMAP_SPECIAL = NEXTMAP_INVALID
|
||||
} nextmapspecial_t;
|
||||
|
||||
extern INT32 gameovertics;
|
||||
extern UINT8 ammoremovaltics;
|
||||
extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
|
||||
|
|
@ -93,8 +105,8 @@ void weaponPrefChange4(void);
|
|||
#define MAXPLMOVE (50)
|
||||
#define SLOWTURNTICS (cv_turnsmooth.value * 3)
|
||||
|
||||
// build an internal map name MAPxx from map number
|
||||
const char *G_BuildMapName(INT32 map);
|
||||
INT32 G_MapNumber(const char *mapname);
|
||||
|
||||
void G_ResetAnglePrediction(player_t *player);
|
||||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer);
|
||||
|
|
@ -136,7 +148,7 @@ extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but sig
|
|||
void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
|
||||
void G_DoReborn(INT32 playernum);
|
||||
void G_PlayerReborn(INT32 player, boolean betweenmaps);
|
||||
void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer,
|
||||
void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer,
|
||||
boolean skipprecutscene, boolean FLS);
|
||||
char *G_BuildMapTitle(INT32 mapnum);
|
||||
|
||||
|
|
@ -173,7 +185,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost);
|
|||
|
||||
// Can be called by the startup code or M_Responder.
|
||||
// A normal game starts at map 1, but a warp test can start elsewhere
|
||||
void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar,
|
||||
void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar,
|
||||
UINT8 ssplayers, boolean FLS);
|
||||
void G_DoLoadLevel(boolean resetplayer);
|
||||
|
||||
|
|
@ -205,7 +217,8 @@ boolean G_IsSpecialStage(INT32 mapnum);
|
|||
boolean G_GametypeUsesLives(void);
|
||||
boolean G_GametypeHasTeams(void);
|
||||
boolean G_GametypeHasSpectators(void);
|
||||
INT16 G_SometimesGetDifferentGametype(void);
|
||||
#define VOTEMODIFIER_ENCORE 0x80
|
||||
INT16 G_SometimesGetDifferentGametype(UINT8 prefgametype);
|
||||
UINT8 G_GetGametypeColor(INT16 gt);
|
||||
void G_BeginLevelExit(void);
|
||||
void G_FinishExitLevel(void);
|
||||
|
|
@ -267,6 +280,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
|
|||
|
||||
// Don't split up TOL handling
|
||||
UINT32 G_TOLFlag(INT32 pgametype);
|
||||
INT16 G_GetFirstMapOfGametype(UINT8 pgametype);
|
||||
|
||||
INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer);
|
||||
void G_AddMapToBuffer(INT16 map);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,9 @@ static char hu_tick;
|
|||
//-------------------------------------------
|
||||
|
||||
patch_t *missingpat;
|
||||
patch_t *blanklvl;
|
||||
patch_t *randomlvl;
|
||||
patch_t *nolvl;
|
||||
|
||||
// song credits
|
||||
static patch_t *songcreditbg;
|
||||
|
|
@ -186,6 +189,10 @@ void HU_LoadGraphics(void)
|
|||
|
||||
Font_Load();
|
||||
|
||||
HU_UpdatePatch(&blanklvl, "BLANKLVL");
|
||||
HU_UpdatePatch(&randomlvl, "RANDOMLV");
|
||||
HU_UpdatePatch(&nolvl, "M_NOLVL");
|
||||
|
||||
HU_UpdatePatch(&songcreditbg, "K_SONGCR");
|
||||
|
||||
// cache ping gfx:
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void K_CheckBumpers(void)
|
|||
winnerscoreadd -= players[i].roundscore;
|
||||
}
|
||||
|
||||
if (bossinfo.boss)
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
if (nobumpers)
|
||||
{
|
||||
|
|
|
|||
11
src/k_hud.c
11
src/k_hud.c
|
|
@ -1454,7 +1454,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
else if ((drawtime/TICRATE) & 1)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
|
||||
|
||||
if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time!
|
||||
if ((modeattacking || (mode == 1)) && !demo.playback) // emblem time!
|
||||
{
|
||||
INT32 workx = TX + 96, worky = TY+18;
|
||||
SINT8 curemb = 0;
|
||||
|
|
@ -3300,7 +3300,6 @@ static void K_drawKartMinimapWaypoint(waypoint_t *wp, INT32 hudx, INT32 hudy, IN
|
|||
|
||||
static void K_drawKartMinimap(void)
|
||||
{
|
||||
INT32 lumpnum;
|
||||
patch_t *AutomapPic, *workingPic;
|
||||
INT32 i = 0;
|
||||
INT32 x, y;
|
||||
|
|
@ -3323,12 +3322,12 @@ static void K_drawKartMinimap(void)
|
|||
if (stplyr != &players[displayplayers[0]])
|
||||
return;
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
|
||||
AutomapPic = mapheaderinfo[gamemap-1]->minimapPic;
|
||||
|
||||
if (lumpnum != -1)
|
||||
AutomapPic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
|
||||
else
|
||||
if (!AutomapPic)
|
||||
{
|
||||
return; // no pic, just get outta here
|
||||
}
|
||||
|
||||
if (r_splitscreen < 2) // 1/2P right aligned
|
||||
{
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_kartcomeback);
|
||||
CV_RegisterVar(&cv_kartencore);
|
||||
CV_RegisterVar(&cv_kartvoterulechanges);
|
||||
CV_RegisterVar(&cv_kartgametypepreference);
|
||||
CV_RegisterVar(&cv_kartspeedometer);
|
||||
CV_RegisterVar(&cv_kartvoices);
|
||||
CV_RegisterVar(&cv_kartbot);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include "k_hud.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "m_menu.h" // Player Setup menu color stuff
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
#include "p_spec.h" // P_StartQuake
|
||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||
|
||||
|
|
@ -390,18 +389,18 @@ static int lib_pGetColorAfter(lua_State *L)
|
|||
// M_MISC
|
||||
//////////////
|
||||
|
||||
static int lib_mMapNumber(lua_State *L)
|
||||
static int lib_gMapNumber(lua_State *L)
|
||||
{
|
||||
const char *arg = luaL_checkstring(L, 1);
|
||||
size_t len = strlen(arg);
|
||||
if (len == 2 || len == 5) {
|
||||
char first = arg[len-2];
|
||||
char second = arg[len-1];
|
||||
lua_pushinteger(L, M_MapNumber(first, second));
|
||||
} else {
|
||||
lua_pushinteger(L, 0);
|
||||
}
|
||||
return 1;
|
||||
INT32 map;
|
||||
|
||||
map = G_MapNumber(arg);
|
||||
|
||||
if (map == INT32_MAX)
|
||||
return 0;
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
// M_RANDOM
|
||||
|
|
@ -3166,12 +3165,12 @@ static int lib_gBuildMapTitle(lua_State *L)
|
|||
{
|
||||
INT32 map = Lcheckmapnumber(L, 1, "G_BuildMapTitle");
|
||||
char *name;
|
||||
if (map < 1 || map > NUMMAPS)
|
||||
if (map < 1 || map > nummapheaders)
|
||||
{
|
||||
return luaL_error(L,
|
||||
"map number %d out of range (1 - %d)",
|
||||
"map ID %d out of range (1 - %d)",
|
||||
map,
|
||||
NUMMAPS
|
||||
nummapheaders
|
||||
);
|
||||
}
|
||||
name = G_BuildMapTitle(map);
|
||||
|
|
@ -3968,9 +3967,6 @@ static luaL_Reg lib[] = {
|
|||
{"M_GetColorAfter",lib_pGetColorAfter},
|
||||
{"M_GetColorBefore",lib_pGetColorBefore},
|
||||
|
||||
// m_misc
|
||||
{"M_MapNumber",lib_mMapNumber},
|
||||
|
||||
// m_random
|
||||
{"P_RandomFixed",lib_pRandomFixed},
|
||||
{"P_RandomByte",lib_pRandomByte},
|
||||
|
|
@ -4173,6 +4169,7 @@ static luaL_Reg lib[] = {
|
|||
// g_game
|
||||
{"G_AddGametype", lib_gAddGametype},
|
||||
{"G_BuildMapName",lib_gBuildMapName},
|
||||
{"G_MapNumber",lib_gMapNumber},
|
||||
{"G_BuildMapTitle",lib_gBuildMapTitle},
|
||||
{"G_FindMap",lib_gFindMap},
|
||||
{"G_FindMapByNameOrCode",lib_gFindMapByNameOrCode},
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "p_local.h" // camera_t
|
||||
#include "screen.h" // screen width/height
|
||||
#include "m_random.h" // m_random
|
||||
#include "m_menu.h" // M_GetMapThumbnail
|
||||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
|
@ -605,7 +606,6 @@ static int libd_drawOnMinimap(lua_State *L)
|
|||
huddrawlist_h list;
|
||||
|
||||
// variables used to replicate k_kart's mmap drawer:
|
||||
INT32 lumpnum;
|
||||
patch_t *AutomapPic;
|
||||
INT32 mx, my;
|
||||
INT32 splitflags, minimaptrans;
|
||||
|
|
@ -691,12 +691,12 @@ static int libd_drawOnMinimap(lua_State *L)
|
|||
if (stplyr != &players[displayplayers[0]])
|
||||
return 0;
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
|
||||
AutomapPic = mapheaderinfo[gamemap-1]->minimapPic;
|
||||
|
||||
if (lumpnum != -1)
|
||||
AutomapPic = W_CachePatchName(va("%sR", G_BuildMapName(gamemap)), PU_HUDGFX);
|
||||
else
|
||||
if (!AutomapPic)
|
||||
{
|
||||
return 0; // no pic, just get outta here
|
||||
}
|
||||
|
||||
mx = MM_X - (AutomapPic->width/2);
|
||||
my = MM_Y - (AutomapPic->height/2);
|
||||
|
|
@ -1091,6 +1091,41 @@ static int libd_getStringColormap(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int libd_getMapThumbnail(lua_State *L)
|
||||
{
|
||||
INT16 mapnum;
|
||||
patch_t *patch = NULL;
|
||||
HUDONLY
|
||||
if (lua_type(L, 1) == LUA_TNUMBER)
|
||||
mapnum = luaL_checkinteger(L, 1) - 1;
|
||||
else
|
||||
mapnum = G_MapNumber(luaL_checkstring(L, 1));
|
||||
|
||||
fixed_t scale = M_GetMapThumbnail(mapnum, &patch);
|
||||
LUA_PushUserdata(L, patch, META_PATCH);
|
||||
lua_pushfixed(L, scale);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int libd_getMapMinimap(lua_State *L)
|
||||
{
|
||||
INT16 mapnum;
|
||||
patch_t *patch = NULL;
|
||||
HUDONLY
|
||||
if (lua_type(L, 1) == LUA_TNUMBER)
|
||||
mapnum = luaL_checkinteger(L, 1) - 1;
|
||||
else
|
||||
mapnum = G_MapNumber(luaL_checkstring(L, 1));
|
||||
|
||||
if (mapnum >= 0 && mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
patch = mapheaderinfo[mapnum]->minimapPic;
|
||||
if (!patch)
|
||||
patch = missingpat;
|
||||
|
||||
LUA_PushUserdata(L, patch, META_PATCH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_width(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
|
|
@ -1258,6 +1293,8 @@ static luaL_Reg lib_draw[] = {
|
|||
{"getSprite2Patch", libd_getSprite2Patch},
|
||||
{"getColormap", libd_getColormap},
|
||||
{"getStringColormap", libd_getStringColormap},
|
||||
{"getMapThumbnail", libd_getMapThumbnail},
|
||||
{"getMapMinimap", libd_getMapMinimap},
|
||||
// drawing
|
||||
{"draw", libd_draw},
|
||||
{"drawScaled", libd_drawScaled},
|
||||
|
|
|
|||
|
|
@ -2516,8 +2516,8 @@ static int lib_getMapheaderinfo(lua_State *L)
|
|||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1)-1;
|
||||
if (i >= NUMMAPS)
|
||||
INT32 i = lua_tointeger(L, 1)-1;
|
||||
if (i < 0 || i >= nummapheaders)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, mapheaderinfo[i], META_MAPHEADER);
|
||||
//CONS_Printf(mapheaderinfo[i]->lvlttl);
|
||||
|
|
@ -2535,7 +2535,7 @@ static int lib_getMapheaderinfo(lua_State *L)
|
|||
|
||||
static int lib_nummapheaders(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMMAPS);
|
||||
lua_pushinteger(L, nummapheaders);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -2547,7 +2547,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
{
|
||||
mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
INT16 i;
|
||||
if (fastcmp(field,"lvlttl"))
|
||||
lua_pushstring(L, header->lvlttl);
|
||||
else if (fastcmp(field,"subttl"))
|
||||
|
|
@ -2558,10 +2557,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushstring(L, header->actnum);
|
||||
else if (fastcmp(field,"typeoflevel"))
|
||||
lua_pushinteger(L, header->typeoflevel);
|
||||
else if (fastcmp(field,"nextlevel"))
|
||||
lua_pushinteger(L, header->nextlevel);
|
||||
else if (fastcmp(field,"marathonnext"))
|
||||
lua_pushinteger(L, header->marathonnext);
|
||||
else if (fastcmp(field,"keywords"))
|
||||
lua_pushstring(L, header->keywords);
|
||||
else if (fastcmp(field,"musname")) // we create a table here because it saves us from a userdata nightmare
|
||||
|
|
@ -2585,22 +2580,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->muspos);
|
||||
else if (fastcmp(field,"musname_size"))
|
||||
lua_pushinteger(L, header->musname_size);
|
||||
else if (fastcmp(field,"musinterfadeout"))
|
||||
lua_pushinteger(L, header->musinterfadeout);
|
||||
else if (fastcmp(field,"musintername"))
|
||||
lua_pushstring(L, header->musintername);
|
||||
else if (fastcmp(field,"muspostbossname"))
|
||||
lua_pushstring(L, header->muspostbossname);
|
||||
else if (fastcmp(field,"muspostbosstrack"))
|
||||
lua_pushinteger(L, header->muspostbosstrack);
|
||||
else if (fastcmp(field,"muspostbosspos"))
|
||||
lua_pushinteger(L, header->muspostbosspos);
|
||||
else if (fastcmp(field,"muspostbossfadein"))
|
||||
lua_pushinteger(L, header->muspostbossfadein);
|
||||
else if (fastcmp(field,"musforcereset"))
|
||||
lua_pushinteger(L, header->musforcereset);
|
||||
else if (fastcmp(field,"forcecharacter"))
|
||||
lua_pushstring(L, header->forcecharacter);
|
||||
else if (fastcmp(field,"weather"))
|
||||
lua_pushinteger(L, header->weather);
|
||||
else if (fastcmp(field,"skytexture"))
|
||||
|
|
@ -2611,12 +2590,7 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->skybox_scaley);
|
||||
else if (fastcmp(field,"skybox_scalez"))
|
||||
lua_pushinteger(L, header->skybox_scalez);
|
||||
else if (fastcmp(field,"interscreen")) {
|
||||
for (i = 0; i < 8; i++)
|
||||
if (!header->interscreen[i])
|
||||
break;
|
||||
lua_pushlstring(L, header->interscreen, i);
|
||||
} else if (fastcmp(field,"runsoc"))
|
||||
else if (fastcmp(field,"runsoc"))
|
||||
lua_pushstring(L, header->runsoc);
|
||||
else if (fastcmp(field,"scriptname"))
|
||||
lua_pushstring(L, header->scriptname);
|
||||
|
|
@ -2624,8 +2598,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->precutscenenum);
|
||||
else if (fastcmp(field,"cutscenenum"))
|
||||
lua_pushinteger(L, header->cutscenenum);
|
||||
else if (fastcmp(field,"countdown"))
|
||||
lua_pushinteger(L, header->countdown);
|
||||
else if (fastcmp(field,"palette"))
|
||||
lua_pushinteger(L, header->palette);
|
||||
else if (fastcmp(field,"numlaps"))
|
||||
|
|
@ -2634,31 +2606,14 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->unlockrequired);
|
||||
else if (fastcmp(field,"levelselect"))
|
||||
lua_pushinteger(L, header->levelselect);
|
||||
else if (fastcmp(field,"bonustype"))
|
||||
lua_pushinteger(L, header->bonustype);
|
||||
else if (fastcmp(field,"ltzzpatch"))
|
||||
lua_pushstring(L, header->ltzzpatch);
|
||||
else if (fastcmp(field,"ltzztext"))
|
||||
lua_pushstring(L, header->ltzztext);
|
||||
else if (fastcmp(field,"ltactdiamond"))
|
||||
lua_pushstring(L, header->ltactdiamond);
|
||||
else if (fastcmp(field,"maxbonuslives"))
|
||||
lua_pushinteger(L, header->maxbonuslives);
|
||||
else if (fastcmp(field,"levelflags"))
|
||||
lua_pushinteger(L, header->levelflags);
|
||||
else if (fastcmp(field,"menuflags"))
|
||||
lua_pushinteger(L, header->menuflags);
|
||||
else if (fastcmp(field,"mobj_scale"))
|
||||
lua_pushfixed(L, header->mobj_scale);
|
||||
else if (fastcmp(field,"startrings"))
|
||||
lua_pushinteger(L, header->startrings);
|
||||
else if (fastcmp(field, "sstimer"))
|
||||
lua_pushinteger(L, header->sstimer);
|
||||
else if (fastcmp(field, "ssspheres"))
|
||||
lua_pushinteger(L, header->ssspheres);
|
||||
else if (fastcmp(field, "gravity"))
|
||||
lua_pushfixed(L, header->gravity);
|
||||
// TODO add support for reading numGradedMares and grades
|
||||
else {
|
||||
// Read custom vars now
|
||||
// (note: don't include the "LUA." in your lua scripts!)
|
||||
|
|
|
|||
|
|
@ -213,35 +213,17 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
lua_pushinteger(L, cv_pointlimit.value);
|
||||
return 1;
|
||||
// begin map vars
|
||||
} else if (fastcmp(word,"spstage_start")) {
|
||||
lua_pushinteger(L, spstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"spmarathon_start")) {
|
||||
lua_pushinteger(L, spmarathon_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sstage_start")) {
|
||||
lua_pushinteger(L, sstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"sstage_end")) {
|
||||
lua_pushinteger(L, sstage_end);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"smpstage_start")) {
|
||||
lua_pushinteger(L, smpstage_start);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"smpstage_end")) {
|
||||
lua_pushinteger(L, smpstage_end);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemap")) {
|
||||
lua_pushinteger(L, titlemap);
|
||||
lua_pushstring(L, titlemap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"titlemapinaction")) {
|
||||
lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF));
|
||||
return 1;
|
||||
} else if (fastcmp(word,"bootmap")) {
|
||||
lua_pushinteger(L, bootmap);
|
||||
lua_pushstring(L, bootmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialmap")) {
|
||||
lua_pushinteger(L, tutorialmap);
|
||||
lua_pushstring(L, tutorialmap);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"tutorialmode")) {
|
||||
lua_pushboolean(L, tutorialmode);
|
||||
|
|
|
|||
|
|
@ -758,6 +758,8 @@ struct debugFlagNames_s const debug_flag_names[] =
|
|||
{"Lua", DBG_LUA},
|
||||
{"RNG", DBG_RNG},
|
||||
{"Randomizer", DBG_RNG}, // alt name
|
||||
{"Demo", DBG_DEMO},
|
||||
{"Replay", DBG_DEMO}, // alt name
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
|
|
|||
177
src/m_cond.c
177
src/m_cond.c
|
|
@ -30,124 +30,7 @@ UINT32 unlocktriggers;
|
|||
conditionset_t conditionSets[MAXCONDITIONSETS];
|
||||
|
||||
// Default Emblem locations
|
||||
emblem_t emblemlocations[MAXEMBLEMS] =
|
||||
{
|
||||
// GOLD DEV MEDALS
|
||||
// These values are directly lifted from the Champion ghost, through the power of hex editing!
|
||||
{ET_TIME, 0, 1, 'A', SKINCOLOR_GOLD, 3021, "", 0}, // Green Hills Zone - 1'26"31
|
||||
{ET_TIME, 0, 2, 'A', SKINCOLOR_GOLD, 4466, "", 0}, // Dark Race - 2'07"60
|
||||
{ET_TIME, 0, 3, 'A', SKINCOLOR_GOLD, 4337, "", 0}, // Northern District Zone - 2'03"91
|
||||
{ET_TIME, 0, 4, 'A', SKINCOLOR_GOLD, 3452, "", 0}, // Darkvile Garden Zone - 1'38"62
|
||||
{ET_TIME, 0, 5, 'A', SKINCOLOR_GOLD, 3525, "", 0}, // Daytona Speedway Zone - 1'40"71
|
||||
{ET_TIME, 0, 6, 'A', SKINCOLOR_GOLD, 4047, "", 0}, // Egg Zeppelin Zone - 1'55"62
|
||||
{ET_TIME, 0, 7, 'A', SKINCOLOR_GOLD, 4041, "", 0}, // Sonic Speedway Zone - 1'55"45
|
||||
{ET_TIME, 0, 8, 'A', SKINCOLOR_GOLD, 3281, "", 0}, // Hill Top Zone - 1'33"74
|
||||
{ET_TIME, 0, 9, 'A', SKINCOLOR_GOLD, 4764, "", 0}, // Misty Maze Zone - 2'16"11
|
||||
{ET_TIME, 0, 10, 'A', SKINCOLOR_GOLD, 4378, "", 0}, // Grand Metropolis - 2'05"08
|
||||
{ET_TIME, 0, 11, 'A', SKINCOLOR_GOLD, 3678, "", 0}, // Sunbeam Paradise Zone - 1'45"08
|
||||
{ET_TIME, 0, 12, 'A', SKINCOLOR_GOLD, 3928, "", 0}, // Diamond Square Zone - 1'52"22
|
||||
{ET_TIME, 0, 13, 'A', SKINCOLOR_GOLD, 3846, "", 0}, // Midnight Meadow Zone - 1'49"88
|
||||
{ET_TIME, 0, 14, 'A', SKINCOLOR_GOLD, 3278, "", 0}, // Twinkle Cart - 1'33"65
|
||||
{ET_TIME, 0, 15, 'A', SKINCOLOR_GOLD, 3591, "", 0}, // Pleasure Castle - 1'42"60
|
||||
{ET_TIME, 0, 16, 'A', SKINCOLOR_GOLD, 5187, "", 0}, // Paradise Hill Zone - 2'28"20
|
||||
{ET_TIME, 0, 17, 'A', SKINCOLOR_GOLD, 4976, "", 0}, // Sub-Zero Peak Zone - 2'22"17
|
||||
{ET_TIME, 0, 18, 'A', SKINCOLOR_GOLD, 3696, "", 0}, // Sapphire Coast Zone - 1'45"60
|
||||
{ET_TIME, 0, 19, 'A', SKINCOLOR_GOLD, 4931, "", 0}, // Sand Valley Zone - 2'20"88
|
||||
{ET_TIME, 0, 20, 'A', SKINCOLOR_GOLD, 4220, "", 0}, // Megablock Castle Zone - 2'00"57
|
||||
{ET_TIME, 0, 21, 'A', SKINCOLOR_GOLD, 4053, "", 0}, // Canyon Rush Zone - 1'55"80
|
||||
{ET_TIME, 0, 22, 'A', SKINCOLOR_GOLD, 3613, "", 0}, // Casino Resort Zone - 1'43"22
|
||||
{ET_TIME, 0, 23, 'A', SKINCOLOR_GOLD, 4385, "", 0}, // Silvercloud Island Zone - 2'05"28
|
||||
{ET_TIME, 0, 24, 'A', SKINCOLOR_GOLD, 5321, "", 0}, // Blue Mountain Zone - 2'32"02
|
||||
{ET_TIME, 0, 25, 'A', SKINCOLOR_GOLD, 4476, "", 0}, // Petroleum Refinery Zone - 2'07"88
|
||||
{ET_TIME, 0, 26, 'A', SKINCOLOR_GOLD, 3295, "", 0}, // Desert Palace Zone - 1'34"14
|
||||
{ET_TIME, 0, 27, 'A', SKINCOLOR_GOLD, 4765, "", 0}, // Aurora Atoll Zone - 2'16"14
|
||||
{ET_TIME, 0, 28, 'A', SKINCOLOR_GOLD, 4670, "", 0}, // Barren Badlands Zone - 2'13"42
|
||||
{ET_TIME, 0, 29, 'A', SKINCOLOR_GOLD, 5888, "", 0}, // Red Barrage Area - 2'48"22
|
||||
{ET_TIME, 0, 30, 'A', SKINCOLOR_GOLD, 4047, "", 0}, // Midnight Channel - 1'55"62
|
||||
{ET_TIME, 0, 31, 'A', SKINCOLOR_GOLD, 4944, "", 0}, // Vanilla Hotel Zone - 2'21"25
|
||||
{ET_TIME, 0, 32, 'A', SKINCOLOR_GOLD, 4638, "", 0}, // Toxic Palace Zone - 2'12"51
|
||||
{ET_TIME, 0, 33, 'A', SKINCOLOR_GOLD, 4036, "", 0}, // Ancient Tomb Zone - 1'55"31
|
||||
{ET_TIME, 0, 34, 'A', SKINCOLOR_GOLD, 3595, "", 0}, // Cloud Cradle Zone K - 1'42"71
|
||||
{ET_TIME, 0, 35, 'A', SKINCOLOR_GOLD, 4705, "", 0}, // Volcanic Valley Zone - 2'14"42
|
||||
{ET_TIME, 0, 36, 'A', SKINCOLOR_GOLD, 3314, "", 0}, // Kodachrome Void Zone - 1'34"68
|
||||
{ET_TIME, 0, 37, 'A', SKINCOLOR_GOLD, 3501, "", 0}, // Boiling Bedrock Zone - 1'40"02
|
||||
{ET_TIME, 0, 38, 'A', SKINCOLOR_GOLD, 4920, "", 0}, // Egg Quarters - 2'20"57
|
||||
{ET_TIME, 0, 39, 'A', SKINCOLOR_GOLD, 4318, "", 0}, // Virtual Highway Zone - 2'03"37
|
||||
{ET_TIME, 0, 40, 'A', SKINCOLOR_GOLD, 3550, "", 0}, // Eggman's Nightclub Zone - 1'41"42
|
||||
{ET_TIME, 0, 41, 'A', SKINCOLOR_GOLD, 2572, "", 0}, // KKR Ganbare Dochu 2 - 1'13"48
|
||||
{ET_TIME, 0, 42, 'A', SKINCOLOR_GOLD, 3091, "", 0}, // CK Chao Circuit 1 - 1'28"31
|
||||
{ET_TIME, 0, 43, 'A', SKINCOLOR_GOLD, 3454, "", 0}, // CK Chao Circuit 2 - 1'38"68
|
||||
{ET_TIME, 0, 44, 'A', SKINCOLOR_GOLD, 2958, "", 0}, // CK Cloud Tops 2 - 1'24"51
|
||||
{ET_TIME, 0, 45, 'A', SKINCOLOR_GOLD, 3693, "", 0}, // CK Regal Raceway - 1'45"51
|
||||
{ET_TIME, 0, 46, 'A', SKINCOLOR_GOLD, 3437, "", 0}, // SD2 Balloon Panic - 1'38"20
|
||||
{ET_TIME, 0, 47, 'A', SKINCOLOR_GOLD, 3238, "", 0}, // SM Dimension Heist - 1'32"51
|
||||
{ET_TIME, 0, 48, 'A', SKINCOLOR_GOLD, 3063, "", 0}, // MKSC Sky Garden - 1'27"51
|
||||
{ET_TIME, 0, 49, 'A', SKINCOLOR_GOLD, 2980, "", 0}, // MKDS Peach Gardens - 1'25"14
|
||||
{ET_TIME, 0, 50, 'A', SKINCOLOR_GOLD, 2914, "", 0}, // MKSC Rainbow Road - 1'23"25
|
||||
{ET_TIME, 0, 51, 'A', SKINCOLOR_GOLD, 3003, "", 0}, // SMK Donut Plains 1 - 1'25"80
|
||||
{ET_TIME, 0, 52, 'A', SKINCOLOR_GOLD, 2930, "", 0}, // SMK Mario Circuit 2 - 1'23"71
|
||||
{ET_TIME, 0, 53, 'A', SKINCOLOR_GOLD, 2389, "", 0}, // SMK Ghost Valley 2 - 1'08"25
|
||||
{ET_TIME, 0, 54, 'A', SKINCOLOR_GOLD, 4292, "", 0}, // SMK Bowser Castle 3 - 2'02"62
|
||||
{ET_TIME, 0, 55, 'A', SKINCOLOR_GOLD, 2346, "", 0}, // SMK Vanilla Lake 2 - 1'07"02
|
||||
|
||||
// SILVER NORMAL MEDALS
|
||||
// The general "guideline" of how good we want a player to be at a map.
|
||||
{ET_TIME, 0, 1, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Green Hills Zone - 1'50"00
|
||||
{ET_TIME, 0, 2, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Dark Race - 2'40"00
|
||||
{ET_TIME, 0, 3, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Northern District Zone - 2'40"00
|
||||
{ET_TIME, 0, 4, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Darkvile Garden Zone - 2'00"00
|
||||
{ET_TIME, 0, 5, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Daytona Speedway Zone - 2'10"00
|
||||
{ET_TIME, 0, 6, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Egg Zeppelin Zone - 2'20"00
|
||||
{ET_TIME, 0, 7, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Sonic Speedway Zone - 2'20"00
|
||||
{ET_TIME, 0, 8, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Hill Top Zone - 1'50"00
|
||||
{ET_TIME, 0, 9, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Misty Maze Zone - 2'50"00
|
||||
{ET_TIME, 0, 10, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Grand Metropolis - 2'20"00
|
||||
{ET_TIME, 0, 11, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Sunbeam Paradise Zone - 2'00"00
|
||||
{ET_TIME, 0, 12, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Diamond Square Zone - 2'10"00
|
||||
{ET_TIME, 0, 13, 'B', SKINCOLOR_GREY, 135*TICRATE, "", 0}, // Midnight Meadow Zone - 2'15"00
|
||||
{ET_TIME, 0, 14, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Twinkle Cart - 2'00"00
|
||||
{ET_TIME, 0, 15, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Pleasure Castle - 2'00"00
|
||||
{ET_TIME, 0, 16, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Paradise Hill Zone - 2'40"00
|
||||
{ET_TIME, 0, 17, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Sub-Zero Peak Zone - 2'50"00
|
||||
{ET_TIME, 0, 18, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Sapphire Coast Zone - 2'10"00
|
||||
{ET_TIME, 0, 19, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Sand Valley Zone - 2'50"00
|
||||
{ET_TIME, 0, 20, 'B', SKINCOLOR_GREY, 145*TICRATE, "", 0}, // Megablock Castle Zone - 2'25"00
|
||||
{ET_TIME, 0, 21, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Canyon Rush Zone - 2'20"00
|
||||
{ET_TIME, 0, 22, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Casino Resort Zone - 2'00"00
|
||||
{ET_TIME, 0, 23, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Silvercloud Island Zone - 2'30"00
|
||||
{ET_TIME, 0, 24, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Blue Mountain Zone - 2'50"00
|
||||
{ET_TIME, 0, 25, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Petroleum Refinery Zone - 2'30"00
|
||||
{ET_TIME, 0, 26, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Desert Palace Zone - 2'00"00
|
||||
{ET_TIME, 0, 27, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Aurora Atoll Zone - 2'40"00
|
||||
{ET_TIME, 0, 28, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Barren Badlands Zone - 2'30"00
|
||||
{ET_TIME, 0, 29, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Red Barrage Area - 2'50"00
|
||||
{ET_TIME, 0, 30, 'B', SKINCOLOR_GREY, 135*TICRATE, "", 0}, // Midnight Channel - 2'15"00
|
||||
{ET_TIME, 0, 31, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Vanilla Hotel Zone - 2'40"00
|
||||
{ET_TIME, 0, 32, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Toxic Palace Zone - 2'40"00
|
||||
{ET_TIME, 0, 33, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Ancient Tomb Zone - 2'30"00
|
||||
{ET_TIME, 0, 34, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Cloud Cradle Zone K - 2'00"00
|
||||
{ET_TIME, 0, 35, 'B', SKINCOLOR_GREY, 165*TICRATE, "", 0}, // Volcanic Valley Zone - 2'45"00
|
||||
{ET_TIME, 0, 36, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Kodachrome Void Zone - 1'50"00
|
||||
{ET_TIME, 0, 37, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Boiling Bedrock Zone - 2'10"00
|
||||
{ET_TIME, 0, 38, 'B', SKINCOLOR_GREY, 165*TICRATE, "", 0}, // Egg Quarters - 2'45"00
|
||||
{ET_TIME, 0, 39, 'B', SKINCOLOR_GREY, 145*TICRATE, "", 0}, // Virtual Highway Zone - 2'25"00
|
||||
{ET_TIME, 0, 40, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Eggman's Nightclub Zone - 2'00"00
|
||||
{ET_TIME, 0, 41, 'B', SKINCOLOR_GREY, 100*TICRATE, "", 0}, // KKR Ganbare Dochu 2 - 1'40"00
|
||||
{ET_TIME, 0, 42, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // CK Chao Circuit 1 - 1'50"00
|
||||
{ET_TIME, 0, 43, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // CK Chao Circuit 2 - 2'00"00
|
||||
{ET_TIME, 0, 44, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // CK Cloud Tops 2 - 1'50"00
|
||||
{ET_TIME, 0, 45, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // CK Regal Raceway - 2'10"00
|
||||
{ET_TIME, 0, 46, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // SD2 Balloon Panic - 1'50"00
|
||||
{ET_TIME, 0, 47, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // SM Dimension Heist - 2'10"00
|
||||
{ET_TIME, 0, 48, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // MKSC Sky Garden - 1'50"00
|
||||
{ET_TIME, 0, 49, 'B', SKINCOLOR_GREY, 105*TICRATE, "", 0}, // MKDS Peach Gardens - 1'45"00
|
||||
{ET_TIME, 0, 50, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // MKSC Rainbow Road - 2'00"00
|
||||
{ET_TIME, 0, 51, 'B', SKINCOLOR_GREY, 100*TICRATE, "", 0}, // SMK Donut Plains 1 - 1'40"00
|
||||
{ET_TIME, 0, 52, 'B', SKINCOLOR_GREY, 105*TICRATE, "", 0}, // SMK Mario Circuit 2 - 1'45"00
|
||||
{ET_TIME, 0, 53, 'B', SKINCOLOR_GREY, 90*TICRATE, "", 0}, // SMK Ghost Valley 2 - 1'30"00
|
||||
{ET_TIME, 0, 54, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // SMK Bowser Castle 3 - 2'30"00
|
||||
{ET_TIME, 0, 55, 'B', SKINCOLOR_GREY, 90*TICRATE, "", 0} // SMK Vanilla Lake 2 - 1'30"00
|
||||
};
|
||||
emblem_t emblemlocations[MAXEMBLEMS] = {0};
|
||||
|
||||
// Default Extra Emblems
|
||||
extraemblem_t extraemblems[MAXEXTRAEMBLEMS] =
|
||||
|
|
@ -177,7 +60,7 @@ unlockable_t unlockables[MAXUNLOCKABLES] =
|
|||
};
|
||||
|
||||
// Number of emblems and extra emblems
|
||||
INT32 numemblems = 110;
|
||||
INT32 numemblems = 0;
|
||||
INT32 numextraemblems = 5;
|
||||
|
||||
// DEFAULT CONDITION SETS FOR SRB2KART:
|
||||
|
|
@ -263,7 +146,10 @@ void M_ClearSecrets(void)
|
|||
{
|
||||
INT32 i;
|
||||
|
||||
memset(mapvisited, 0, sizeof(mapvisited));
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
mapheaderinfo[i]->mapvisited = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXEMBLEMS; ++i)
|
||||
emblemlocations[i].collected = false;
|
||||
|
|
@ -298,11 +184,19 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
case UC_OVERALLTIME: // Requires overall time <= x
|
||||
return (M_GotLowEnoughTime(cn->requirement));
|
||||
case UC_MAPVISITED: // Requires map x to be visited
|
||||
return ((mapvisited[cn->requirement - 1] & MV_VISITED) == MV_VISITED);
|
||||
case UC_MAPBEATEN: // Requires map x to be beaten
|
||||
return ((mapvisited[cn->requirement - 1] & MV_BEATEN) == MV_BEATEN);
|
||||
case UC_MAPENCORE: // Requires map x to be beaten in encore
|
||||
return ((mapvisited[cn->requirement - 1] & MV_ENCORE) == MV_ENCORE);
|
||||
{
|
||||
UINT8 mvtype = MV_VISITED;
|
||||
if (cn->type == UC_MAPBEATEN)
|
||||
mvtype = MV_BEATEN;
|
||||
else if (cn->type == UC_MAPENCORE)
|
||||
mvtype = MV_ENCORE;
|
||||
|
||||
return ((cn->requirement < nummapheaders)
|
||||
&& (mapheaderinfo[cn->requirement])
|
||||
&& ((mapheaderinfo[cn->requirement]->mapvisited & mvtype) == mvtype));
|
||||
}
|
||||
case UC_MAPTIME: // Requires time on map <= x
|
||||
return (G_GetBestTime(cn->extrainfo1) <= (unsigned)cn->requirement);
|
||||
case UC_TRIGGER: // requires map trigger set
|
||||
|
|
@ -467,10 +361,17 @@ UINT8 M_CheckLevelEmblems(void)
|
|||
// Update Score, Time, Rings emblems
|
||||
for (i = 0; i < numemblems; ++i)
|
||||
{
|
||||
INT32 checkLevel;
|
||||
|
||||
if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected)
|
||||
continue;
|
||||
|
||||
levelnum = emblemlocations[i].level;
|
||||
checkLevel = G_MapNumber(emblemlocations[i].level);
|
||||
|
||||
if (checkLevel >= nummapheaders || !mapheaderinfo[checkLevel])
|
||||
continue;
|
||||
|
||||
levelnum = checkLevel;
|
||||
valToReach = emblemlocations[i].var;
|
||||
|
||||
switch (emblemlocations[i].type)
|
||||
|
|
@ -500,17 +401,24 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
|
|||
|
||||
for (i = 0; i < numemblems; ++i)
|
||||
{
|
||||
if (emblemlocations[i].type != ET_MAP || emblemlocations[i].collected)
|
||||
INT32 checkLevel;
|
||||
|
||||
if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected)
|
||||
continue;
|
||||
|
||||
levelnum = emblemlocations[i].level;
|
||||
checkLevel = G_MapNumber(emblemlocations[i].level);
|
||||
|
||||
if (checkLevel >= nummapheaders || !mapheaderinfo[checkLevel])
|
||||
continue;
|
||||
|
||||
levelnum = checkLevel;
|
||||
embtype = emblemlocations[i].var;
|
||||
flags = MV_BEATEN;
|
||||
|
||||
if (embtype & ME_ENCORE)
|
||||
flags |= MV_ENCORE;
|
||||
|
||||
res = ((mapvisited[levelnum - 1] & flags) == flags);
|
||||
res = ((mapheaderinfo[levelnum]->mapvisited & flags) == flags);
|
||||
|
||||
emblemlocations[i].collected = res;
|
||||
if (res)
|
||||
|
|
@ -622,14 +530,14 @@ UINT8 M_GotLowEnoughTime(INT32 tictime)
|
|||
INT32 curtics = 0;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < NUMMAPS; ++i)
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mainrecords[i] || !mainrecords[i]->time)
|
||||
if (!mapheaderinfo[i]->mainrecord || !mapheaderinfo[i]->mainrecord->time)
|
||||
return false;
|
||||
else if ((curtics += mainrecords[i]->time) > tictime)
|
||||
else if ((curtics += mapheaderinfo[i]->mainrecord->time) > tictime)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -648,7 +556,7 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum)
|
|||
static INT32 map = -1;
|
||||
static INT32 i = -1;
|
||||
|
||||
if (mapnum > 0)
|
||||
if (mapnum >= 0)
|
||||
{
|
||||
map = mapnum;
|
||||
i = numemblems;
|
||||
|
|
@ -656,7 +564,12 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum)
|
|||
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (emblemlocations[i].level == map)
|
||||
INT32 checkLevel = G_MapNumber(emblemlocations[i].level);
|
||||
|
||||
if (checkLevel >= nummapheaders || !mapheaderinfo[checkLevel])
|
||||
continue;
|
||||
|
||||
if (checkLevel == map)
|
||||
return &emblemlocations[i];
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ struct emblem_t
|
|||
{
|
||||
UINT8 type; ///< Emblem type
|
||||
INT16 tag; ///< Tag of emblem mapthing
|
||||
INT16 level; ///< Level on which this emblem can be found.
|
||||
char * level; ///< Level on which this emblem can be found.
|
||||
UINT8 sprite; ///< emblem sprite to use, 0 - 25
|
||||
UINT16 color; ///< skincolor to use
|
||||
INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin)
|
||||
|
|
|
|||
227
src/m_menu.c
227
src/m_menu.c
|
|
@ -424,12 +424,14 @@ static void Dummystaff_OnChange(void);
|
|||
consvar_t cv_showfocuslost = CVAR_INIT ("showfocuslost", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
static CV_PossibleValue_t map_cons_t[] = {
|
||||
{0,"MIN"},
|
||||
{NUMMAPS, "MAX"},
|
||||
{-1,"MIN"},
|
||||
{NEXTMAP_SPECIAL, "MAX"}, // TODO: kill nextmap (can't do that i'm afraid!)
|
||||
{0, NULL}
|
||||
};
|
||||
consvar_t cv_nextmap = CVAR_INIT ("nextmap", "1", CV_HIDEN|CV_CALL, map_cons_t, Nextmap_OnChange);
|
||||
|
||||
static INT16 lastnextmap = 1;
|
||||
|
||||
static CV_PossibleValue_t skins_cons_t[MAXSKINS+1] = {{1, DEFAULTSKIN}};
|
||||
consvar_t cv_chooseskin = CVAR_INIT ("chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_cons_t, Nextmap_OnChange);
|
||||
|
||||
|
|
@ -1783,6 +1785,23 @@ INT32 HU_GetHighlightColor(void)
|
|||
return highlightflags;
|
||||
}
|
||||
|
||||
fixed_t M_GetMapThumbnail(INT16 mapnum, patch_t **out)
|
||||
{
|
||||
patch_t *patch = NULL;
|
||||
if (mapnum == -1)
|
||||
patch = randomlvl;
|
||||
else if (mapnum >= 0 && mapnum < nummapheaders && mapheaderinfo[mapnum])
|
||||
patch = mapheaderinfo[mapnum]->thumbnailPic;
|
||||
|
||||
if (!patch)
|
||||
patch = blanklvl;
|
||||
|
||||
*out = patch;
|
||||
|
||||
// check width instead of height because haha big winton
|
||||
return patch->width >= 320 ? FRACUNIT : FRACUNIT*2;
|
||||
}
|
||||
|
||||
// Sky Room
|
||||
menu_t SR_PandoraDef =
|
||||
{
|
||||
|
|
@ -2110,26 +2129,45 @@ static INT32 M_GetFirstLevelInList(void);
|
|||
void Nextmap_OnChange(void)
|
||||
{
|
||||
char *leveltitle;
|
||||
UINT8 active;
|
||||
const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA";
|
||||
|
||||
// welp, we're stuck with nextmap for the time being. so just make the damn thing work
|
||||
if (cv_nextmap.value != lastnextmap)
|
||||
{
|
||||
boolean increment = cv_nextmap.value > lastnextmap;
|
||||
INT16 oldvalue = cv_nextmap.value - 1;
|
||||
INT16 newvalue = oldvalue;
|
||||
INT32 gt = cv_newgametype.value;
|
||||
while (!M_CanShowLevelInList(newvalue, gt))
|
||||
{
|
||||
if (increment) // Going up!
|
||||
{
|
||||
if (++newvalue == nummapheaders)
|
||||
newvalue = -1;
|
||||
}
|
||||
else // Going down!
|
||||
{
|
||||
if (--newvalue == -2)
|
||||
newvalue = nummapheaders-1;
|
||||
}
|
||||
|
||||
if (newvalue == oldvalue)
|
||||
break; // don't loop forever if there's none of a certain gametype
|
||||
}
|
||||
cv_nextmap.value = lastnextmap = newvalue + 1;
|
||||
}
|
||||
|
||||
// Update the string in the consvar.
|
||||
Z_Free(cv_nextmap.zstring);
|
||||
leveltitle = G_BuildMapTitle(cv_nextmap.value);
|
||||
cv_nextmap.string = cv_nextmap.zstring = leveltitle ? leveltitle : Z_StrDup(G_BuildMapName(cv_nextmap.value));
|
||||
|
||||
leveltitle = cv_nextmap.value ? G_BuildMapTitle(cv_nextmap.value) : Z_StrDup("Random");
|
||||
cv_nextmap.string = cv_nextmap.zstring = leveltitle;
|
||||
|
||||
if (currentMenu == &SP_TimeAttackDef)
|
||||
{
|
||||
// see also p_setup.c's P_LoadRecordGhosts
|
||||
const size_t glen = strlen(srb2home)+1+strlen("media")+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
|
||||
char *gpath = malloc(glen);
|
||||
const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA";
|
||||
char *gpath = xva("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
INT32 i;
|
||||
|
||||
if (!gpath)
|
||||
return;
|
||||
|
||||
sprintf(gpath,"%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value));
|
||||
UINT8 active = 0;
|
||||
|
||||
CV_StealthSetValue(&cv_dummystaff, 0);
|
||||
|
||||
|
|
@ -2198,9 +2236,6 @@ void Nextmap_OnChange(void)
|
|||
itemOn = tastart;
|
||||
}
|
||||
|
||||
if (mapheaderinfo[cv_nextmap.value-1] && mapheaderinfo[cv_nextmap.value-1]->forcecharacter[0] != '\0')
|
||||
CV_Set(&cv_chooseskin, mapheaderinfo[cv_nextmap.value-1]->forcecharacter);
|
||||
|
||||
free(gpath);
|
||||
}
|
||||
}
|
||||
|
|
@ -2239,7 +2274,8 @@ static void Dummystaff_OnChange(void)
|
|||
|
||||
dummystaffname[0] = '\0';
|
||||
|
||||
if ((l = W_CheckNumForName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
|
||||
// TODO: Use map header to determine lump name
|
||||
if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
|
||||
{
|
||||
CV_StealthSetValue(&cv_dummystaff, 0);
|
||||
return;
|
||||
|
|
@ -2248,7 +2284,7 @@ static void Dummystaff_OnChange(void)
|
|||
{
|
||||
char *temp = dummystaffname;
|
||||
UINT8 numstaff = 1;
|
||||
while (numstaff < 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value),numstaff+1))) != LUMPERROR)
|
||||
while (numstaff < 99 && (l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(cv_nextmap.value),numstaff+1))) != LUMPERROR)
|
||||
numstaff++;
|
||||
|
||||
if (cv_dummystaff.value < 1)
|
||||
|
|
@ -2256,7 +2292,7 @@ static void Dummystaff_OnChange(void)
|
|||
else if (cv_dummystaff.value > numstaff)
|
||||
CV_StealthSetValue(&cv_dummystaff, 1);
|
||||
|
||||
if ((l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
|
||||
if ((l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(cv_nextmap.value), cv_dummystaff.value))) == LUMPERROR)
|
||||
return; // shouldn't happen but might as well check...
|
||||
|
||||
G_UpdateStaffGhostName(l);
|
||||
|
|
@ -4458,18 +4494,24 @@ static void M_PrepareLevelSelect(void)
|
|||
//
|
||||
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
|
||||
{
|
||||
UINT32 tolflag = G_TOLFlag(gt);
|
||||
|
||||
// Random map!
|
||||
if (mapnum == -1)
|
||||
return (levellistmode == LLM_CREATESERVER);
|
||||
|
||||
// Does the map exist?
|
||||
if (!mapheaderinfo[mapnum])
|
||||
if (mapnum < 0 || mapnum >= nummapheaders || !mapheaderinfo[mapnum])
|
||||
return false;
|
||||
|
||||
// Does the map have a name?
|
||||
if (!mapheaderinfo[mapnum]->lvlttl[0])
|
||||
return false;
|
||||
|
||||
// Does the map have a LUMP?
|
||||
if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
|
||||
return false;
|
||||
|
||||
switch (levellistmode)
|
||||
{
|
||||
case LLM_CREATESERVER:
|
||||
|
|
@ -4480,10 +4522,11 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
|
|||
if (M_MapLocked(mapnum+1))
|
||||
return false; // not unlocked
|
||||
|
||||
if (gt >= 0 && gt < gametypecount && mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt])
|
||||
return true;
|
||||
// Check for TOL
|
||||
if (!(mapheaderinfo[mapnum]->typeoflevel & tolflag))
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
|
||||
/*case LLM_LEVELSELECT:
|
||||
if (mapheaderinfo[mapnum]->levelselect != maplistoption)
|
||||
|
|
@ -4511,7 +4554,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
|
|||
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
|
||||
return false; // map hell
|
||||
|
||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_VISITNEEDED) && !mapvisited[mapnum])
|
||||
if ((mapheaderinfo[mapnum]->menuflags & LF2_VISITNEEDED) && !mapheaderinfo[mapnum]->mapvisited)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -4534,7 +4577,7 @@ static INT32 M_CountLevelsToShowInList(void)
|
|||
{
|
||||
INT32 mapnum, count = 0;
|
||||
|
||||
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
|
||||
for (mapnum = 0; mapnum < nummapheaders; mapnum++)
|
||||
if (M_CanShowLevelInList(mapnum, -1))
|
||||
count++;
|
||||
|
||||
|
|
@ -4545,7 +4588,7 @@ static INT32 M_GetFirstLevelInList(void)
|
|||
{
|
||||
INT32 mapnum;
|
||||
|
||||
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
|
||||
for (mapnum = 0; mapnum < nummapheaders; mapnum++)
|
||||
if (M_CanShowLevelInList(mapnum, -1))
|
||||
return mapnum + 1;
|
||||
|
||||
|
|
@ -5563,7 +5606,6 @@ static void M_HandleReplayHutList(INT32 choice)
|
|||
#define SCALEDVIEWHEIGHT (vid.height/vid.dupy)
|
||||
static void DrawReplayHutReplayInfo(void)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *patch;
|
||||
UINT8 *colormap;
|
||||
INT32 x, y, w, h;
|
||||
|
|
@ -5588,21 +5630,18 @@ static void DrawReplayHutReplayInfo(void)
|
|||
// Draw level stuff
|
||||
x = 15; y = 15;
|
||||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
//CONS_Printf("%d %s\n", demolist[dir_on[menudepthleft]].map, G_BuildMapName(demolist[dir_on[menudepthleft]].map));
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(demolist[dir_on[menudepthleft]].map)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
patch = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
patch = W_CachePatchName("M_NOLVL", PU_CACHE);
|
||||
fixed_t scale = M_GetMapThumbnail(demolist[dir_on[menudepthleft]].map, &patch)/4;
|
||||
if (patch == blanklvl)
|
||||
patch = nolvl;
|
||||
|
||||
if (!(demolist[dir_on[menudepthleft]].kartspeed & DF_ENCORE))
|
||||
V_DrawSmallScaledPatch(x, y, V_SNAPTOTOP, patch);
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOTOP, patch, NULL);
|
||||
else
|
||||
{
|
||||
w = SHORT(patch->width);
|
||||
h = SHORT(patch->height);
|
||||
V_DrawSmallScaledPatch(x+(w>>1), y, V_SNAPTOTOP|V_FLIP, patch);
|
||||
w = FixedMul(SHORT(patch->width), scale);
|
||||
h = FixedMul(SHORT(patch->height), scale);
|
||||
V_DrawFixedPatch((x+(w>>1))<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOTOP|V_FLIP, patch, NULL);
|
||||
|
||||
{
|
||||
static angle_t rubyfloattime = 0;
|
||||
|
|
@ -5614,8 +5653,8 @@ static void DrawReplayHutReplayInfo(void)
|
|||
|
||||
x += 85;
|
||||
|
||||
if (mapheaderinfo[demolist[dir_on[menudepthleft]].map-1])
|
||||
V_DrawString(x, y, V_SNAPTOTOP, G_BuildMapTitle(demolist[dir_on[menudepthleft]].map));
|
||||
if (demolist[dir_on[menudepthleft]].map != NEXTMAP_INVALID)
|
||||
V_DrawString(x, y, V_SNAPTOTOP, G_BuildMapTitle(demolist[dir_on[menudepthleft]].map+1));
|
||||
else
|
||||
V_DrawString(x, y, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded.");
|
||||
|
||||
|
|
@ -6252,15 +6291,10 @@ static boolean M_ExitPandorasBox(void)
|
|||
|
||||
static void M_ChangeLevel(INT32 choice)
|
||||
{
|
||||
char mapname[6];
|
||||
(void)choice;
|
||||
|
||||
strlcpy(mapname, G_BuildMapName(cv_nextmap.value), sizeof (mapname));
|
||||
strlwr(mapname);
|
||||
mapname[5] = '\0';
|
||||
|
||||
INT16 map = cv_nextmap.value ? cv_nextmap.value : G_RandMap(G_TOLFlag(cv_newgametype.value), gamestate == GS_LEVEL ? gamemap-1 : prevmap, 0, 0, false, NULL);
|
||||
M_ClearMenus(true);
|
||||
COM_BufAddText(va("map %s -gametype \"%s\"\n", mapname, cv_newgametype.string));
|
||||
COM_BufAddText(va("map %d -gametype \"%s\"\n", map, cv_newgametype.string));
|
||||
}
|
||||
|
||||
static void M_ConfirmSpectate(INT32 choice)
|
||||
|
|
@ -6618,8 +6652,15 @@ static void M_DrawEmblemHints(void)
|
|||
|
||||
for (i = 0; i < numemblems; i++)
|
||||
{
|
||||
INT32 checkLevel;
|
||||
|
||||
emblem = &emblemlocations[i];
|
||||
if (emblem->level != gamemap || emblem->type != ET_GLOBAL)
|
||||
if (emblem->type != ET_GLOBAL)
|
||||
continue;
|
||||
|
||||
checkLevel = G_MapNumber(emblem->level);
|
||||
|
||||
if (!mapheaderinfo[checkLevel] || gamemap != checkLevel)
|
||||
continue;
|
||||
|
||||
if (emblem->collected)
|
||||
|
|
@ -7544,7 +7585,8 @@ static void M_ChoosePlayer(INT32 choice)
|
|||
|
||||
static INT32 statsLocation;
|
||||
static INT32 statsMax;
|
||||
static INT16 statsMapList[NUMMAPS+1];
|
||||
static INT16 *statsMapList = NULL;
|
||||
static INT16 statsMapListLen;
|
||||
|
||||
static void M_Statistics(INT32 choice)
|
||||
{
|
||||
|
|
@ -7552,9 +7594,13 @@ static void M_Statistics(INT32 choice)
|
|||
|
||||
(void)choice;
|
||||
|
||||
memset(statsMapList, 0, sizeof(statsMapList));
|
||||
if (!statsMapList || nummapheaders != statsMapListLen)
|
||||
{
|
||||
statsMapList = Z_Realloc(statsMapList, nummapheaders * sizeof(*statsMapList), PU_LEVEL, NULL);
|
||||
statsMapListLen = nummapheaders;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i] || mapheaderinfo[i]->lvlttl[0] == '\0')
|
||||
continue;
|
||||
|
|
@ -7696,18 +7742,18 @@ static void M_DrawLevelStats(void)
|
|||
V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[PWRLV_RACE]));
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[PWRLV_BATTLE]));
|
||||
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK))
|
||||
continue;
|
||||
|
||||
if (!mainrecords[i] || mainrecords[i]->time <= 0)
|
||||
if (!mapheaderinfo[i]->mainrecord || mapheaderinfo[i]->mainrecord->time <= 0)
|
||||
{
|
||||
mapsunfinished++;
|
||||
continue;
|
||||
}
|
||||
|
||||
besttime += mainrecords[i]->time;
|
||||
besttime += mapheaderinfo[i]->mainrecord->time;
|
||||
}
|
||||
|
||||
V_DrawString(20, 70, highlightflags, "Combined time records:");
|
||||
|
|
@ -7784,6 +7830,7 @@ static void M_GrandPrixTemp(INT32 choice)
|
|||
static void M_StartGrandPrix(INT32 choice)
|
||||
{
|
||||
cupheader_t *gpcup = kartcupheaders;
|
||||
INT32 levelNum;
|
||||
|
||||
(void)choice;
|
||||
|
||||
|
|
@ -7835,9 +7882,11 @@ static void M_StartGrandPrix(INT32 choice)
|
|||
|
||||
grandprixinfo.initalize = true;
|
||||
|
||||
levelNum = G_MapNumber(grandprixinfo.cup->levellist[0]);
|
||||
|
||||
G_DeferedInitNew(
|
||||
false,
|
||||
G_BuildMapName(grandprixinfo.cup->levellist[0] + 1),
|
||||
levelNum + 1,
|
||||
(UINT8)(cv_chooseskin.value - 1),
|
||||
(UINT8)(cv_splitplayers.value - 1),
|
||||
false
|
||||
|
|
@ -7943,10 +7992,10 @@ void M_DrawTimeAttackMenu(void)
|
|||
{
|
||||
INT32 dupadjust = (vid.width/vid.dupx);
|
||||
tic_t lap = 0, time = 0;
|
||||
if (mainrecords[cv_nextmap.value-1])
|
||||
if (mapheaderinfo[cv_nextmap.value-1]->mainrecord)
|
||||
{
|
||||
lap = mainrecords[cv_nextmap.value-1]->lap;
|
||||
time = mainrecords[cv_nextmap.value-1]->time;
|
||||
lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord->lap;
|
||||
time = mapheaderinfo[cv_nextmap.value-1]->mainrecord->time;
|
||||
}
|
||||
|
||||
V_DrawFill((BASEVIDWIDTH - dupadjust)>>1, 78, dupadjust, 36, 159);
|
||||
|
|
@ -7954,11 +8003,11 @@ void M_DrawTimeAttackMenu(void)
|
|||
if (levellistmode != LLM_ITEMBREAKER)
|
||||
{
|
||||
V_DrawRightAlignedString(149, 80, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(lap, 19, 86, 0, 2);
|
||||
K_drawKartTimestamp(lap, 19, 86, -1, 2);
|
||||
}
|
||||
|
||||
V_DrawRightAlignedString(292, 80, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(time, 162, 86, cv_nextmap.value, 1);
|
||||
K_drawKartTimestamp(time, 162, 86, cv_nextmap.value-1, 1);
|
||||
}
|
||||
/*{
|
||||
char beststr[40];
|
||||
|
|
@ -8134,7 +8183,7 @@ static void M_ChooseTimeAttack(INT32 choice)
|
|||
else
|
||||
G_RecordDemo(nameofdemo);
|
||||
|
||||
G_DeferedInitNew(false, G_BuildMapName(cv_nextmap.value), (UINT8)(cv_chooseskin.value-1), 0, false);
|
||||
G_DeferedInitNew(false, cv_nextmap.value, (UINT8)(cv_chooseskin.value-1), 0, false);
|
||||
}
|
||||
|
||||
static void M_HandleStaffReplay(INT32 choice)
|
||||
|
|
@ -8877,7 +8926,7 @@ static INT32 M_FindFirstMap(INT32 gtype)
|
|||
if (mapheaderinfo[gamemap] && (mapheaderinfo[gamemap]->typeoflevel & gametypetol[gtype]))
|
||||
return gamemap;
|
||||
|
||||
for (i = 0; i < NUMMAPS; i++)
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i])
|
||||
continue;
|
||||
|
|
@ -8942,24 +8991,12 @@ static void M_StartServer(INT32 choice)
|
|||
|
||||
static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *PictureOfLevel;
|
||||
INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1;
|
||||
fixed_t scale = M_GetMapThumbnail(cv_nextmap.value-1, &PictureOfLevel)/4;
|
||||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
if (cv_nextmap.value)
|
||||
{
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
}
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("RANDOMLV", PU_CACHE);
|
||||
|
||||
w = SHORT(PictureOfLevel->width)/2;
|
||||
i = SHORT(PictureOfLevel->height)/2;
|
||||
w = FixedMul(SHORT(PictureOfLevel->width), scale);
|
||||
i = FixedMul(SHORT(PictureOfLevel->height), scale);
|
||||
x = BASEVIDWIDTH/2 - w/2;
|
||||
y = currentMenu->y + 130 + 8 - i;
|
||||
|
||||
|
|
@ -8971,14 +9008,14 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
|||
V_DrawFill(x-1, y-1, w+2, i+2, trans); // variable reuse...
|
||||
|
||||
if ((cv_kartencore.value != 1) || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE)
|
||||
V_DrawSmallScaledPatch(x, y, 0, PictureOfLevel);
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, PictureOfLevel, NULL);
|
||||
else
|
||||
{
|
||||
/*UINT8 *mappingforencore = NULL;
|
||||
if ((lumpnum = W_CheckNumForName(va("%sE", mapname))) != LUMPERROR)
|
||||
mappingforencore = W_CachePatchNum(lumpnum, PU_CACHE);*/
|
||||
|
||||
V_DrawFixedPatch((x+w)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, V_FLIP, PictureOfLevel, 0);
|
||||
V_DrawFixedPatch((x+w)<<FRACBITS, y<<FRACBITS, scale, V_FLIP, PictureOfLevel, NULL);
|
||||
|
||||
{
|
||||
static angle_t rubyfloattime = 0;
|
||||
|
|
@ -9002,7 +9039,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
|||
{
|
||||
i--;
|
||||
if (i == -2)
|
||||
i = NUMMAPS-1;
|
||||
i = nummapheaders-1;
|
||||
|
||||
if (i == oldval)
|
||||
return;
|
||||
|
|
@ -9012,21 +9049,11 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
|||
|
||||
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
|
||||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
if (i+1)
|
||||
{
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(i+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
}
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("RANDOMLV", PU_CACHE);
|
||||
scale = M_GetMapThumbnail(i, &PictureOfLevel)/8;
|
||||
|
||||
x -= horizspac + w/2;
|
||||
|
||||
V_DrawTinyScaledPatch(x, y, trans, PictureOfLevel);
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, trans, PictureOfLevel, NULL);
|
||||
} while (x > horizspac-dupadjust);
|
||||
|
||||
x = (BASEVIDWIDTH + w)/2 + horizspac;
|
||||
|
|
@ -9039,7 +9066,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
|||
do
|
||||
{
|
||||
i++;
|
||||
if (i == NUMMAPS)
|
||||
if (i == nummapheaders)
|
||||
i = -1;
|
||||
|
||||
if (i == oldval)
|
||||
|
|
@ -9050,19 +9077,9 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
|
|||
|
||||
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
|
||||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
if (i+1)
|
||||
{
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(i+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
}
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("RANDOMLV", PU_CACHE);
|
||||
scale = M_GetMapThumbnail(i, &PictureOfLevel)/8;
|
||||
|
||||
V_DrawTinyScaledPatch(x, y, trans, PictureOfLevel);
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, trans, PictureOfLevel, NULL);
|
||||
|
||||
x += horizspac + w/2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -479,6 +479,8 @@ void M_RefreshPauseMenu(void);
|
|||
|
||||
INT32 HU_GetHighlightColor(void);
|
||||
|
||||
fixed_t M_GetMapThumbnail(INT16 mapnum, patch_t **out);
|
||||
|
||||
// Moviemode menu updating
|
||||
void Moviemode_option_Onchange(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -182,32 +182,6 @@ boolean takescreenshot = false; // Take a screenshot this tic
|
|||
|
||||
moviemode_t moviemode = MM_OFF;
|
||||
|
||||
/** Returns the map number for a map identified by the last two characters in
|
||||
* its name.
|
||||
*
|
||||
* \param first The first character after MAP.
|
||||
* \param second The second character after MAP.
|
||||
* \return The map number, or 0 if no map corresponds to these characters.
|
||||
* \sa G_BuildMapName
|
||||
*/
|
||||
INT32 M_MapNumber(char first, char second)
|
||||
{
|
||||
if (isdigit(first))
|
||||
{
|
||||
if (isdigit(second))
|
||||
return ((INT32)first - '0') * 10 + ((INT32)second - '0');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isalpha(first))
|
||||
return 0;
|
||||
if (!isalnum(second))
|
||||
return 0;
|
||||
|
||||
return 100 + ((INT32)tolower(first) - 'a') * 36 + (isdigit(second) ? ((INT32)second - '0') :
|
||||
((INT32)tolower(second) - 'a') + 10);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// FILE INPUT / OUTPUT
|
||||
// ==========================================================================
|
||||
|
|
@ -819,7 +793,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
|
|||
"Unknown";
|
||||
#endif
|
||||
char rendermodetxt[9];
|
||||
char maptext[8];
|
||||
char maptext[MAXMAPLUMPNAME];
|
||||
char lvlttltext[48];
|
||||
char locationtxt[40];
|
||||
char ctrevision[40];
|
||||
|
|
@ -840,7 +814,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
|
|||
}
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
|
||||
snprintf(maptext, MAXMAPLUMPNAME, "%s", G_BuildMapName(gamemap));
|
||||
else
|
||||
snprintf(maptext, 8, "Unknown");
|
||||
|
||||
|
|
@ -1739,6 +1713,32 @@ char *va(const char *format, ...)
|
|||
return string;
|
||||
}
|
||||
|
||||
/** Allocates and returns a string made out of varargs.
|
||||
*
|
||||
* \param format Format string.
|
||||
* \return Pointer to the resulting string.
|
||||
*/
|
||||
char *xva(const char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char *string;
|
||||
|
||||
va_start(argptr, format);
|
||||
int size = vsnprintf(NULL, 0, format, argptr);
|
||||
if (size < 0)
|
||||
I_Error("xva: can't format string");
|
||||
string = static_cast<char *>(malloc((unsigned)size+1));
|
||||
if (!string)
|
||||
I_Error("xva: out of memory");
|
||||
va_end(argptr);
|
||||
|
||||
va_start(argptr, format);
|
||||
vsprintf(string, format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
/** Creates a string in the first argument that is the second argument followed
|
||||
* by the third argument followed by the first argument.
|
||||
* Useful for making filenames with full path. s1 = s2+s3+s1
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ void M_StopMovie(void);
|
|||
// the file where game vars and settings are saved
|
||||
#define CONFIGFILENAME "kartconfig.cfg"
|
||||
|
||||
INT32 M_MapNumber(char first, char second);
|
||||
|
||||
boolean FIL_WriteFile(char const *name, const void *source, size_t length);
|
||||
size_t FIL_ReadFileTag(char const *name, UINT8 **buffer, INT32 tag);
|
||||
#define FIL_ReadFile(n, b) FIL_ReadFileTag(n, b, PU_STATIC)
|
||||
|
|
|
|||
|
|
@ -10512,7 +10512,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
else if (p->bot)
|
||||
{
|
||||
/*
|
||||
if (bonusgame || specialstage)
|
||||
if (bonusgame || specialstage || boss)
|
||||
{
|
||||
// Bots should avoid
|
||||
p->spectator = true;
|
||||
|
|
|
|||
110
src/p_saveg.c
110
src/p_saveg.c
|
|
@ -4852,8 +4852,8 @@ static inline void P_UnArchiveSPGame(savebuffer_t *save, INT16 mapoverride)
|
|||
|
||||
// gamemap changed; we assume that its map header is always valid,
|
||||
// so make it so
|
||||
if(!mapheaderinfo[gamemap-1])
|
||||
P_AllocMapHeader(gamemap-1);
|
||||
if (!gamemap || gamemap > nummapheaders || !mapheaderinfo[gamemap-1])
|
||||
I_Error("P_UnArchiveSPGame: Internal map ID %d not found (nummapheaders = %d)", gamemap-1, nummapheaders);
|
||||
|
||||
//lastmapsaved = gamemap;
|
||||
lastmaploaded = gamemap;
|
||||
|
|
@ -4908,7 +4908,6 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
WRITEUINT8(save->p, mapmusrng);
|
||||
|
||||
WRITEUINT32(save->p, leveltime);
|
||||
WRITEUINT32(save->p, ssspheres);
|
||||
WRITEINT16(save->p, lastmap);
|
||||
WRITEUINT16(save->p, bossdisabled);
|
||||
WRITEUINT8(save->p, ringsdisabled);
|
||||
|
|
@ -4935,7 +4934,6 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
}
|
||||
|
||||
WRITEUINT32(save->p, token);
|
||||
WRITEINT32(save->p, sstimer);
|
||||
WRITEUINT32(save->p, bluescore);
|
||||
WRITEUINT32(save->p, redscore);
|
||||
|
||||
|
|
@ -4968,9 +4966,6 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
|
|||
WRITEFIXED(save->p, gravity);
|
||||
WRITEFIXED(save->p, mapobjectscale);
|
||||
|
||||
WRITEUINT32(save->p, countdowntimer);
|
||||
WRITEUINT8(save->p, countdowntimeup);
|
||||
|
||||
// SRB2kart
|
||||
WRITEINT32(save->p, numgotboxes);
|
||||
WRITEUINT8(save->p, numtargets);
|
||||
|
|
@ -5041,8 +5036,8 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
|||
|
||||
// gamemap changed; we assume that its map header is always valid,
|
||||
// so make it so
|
||||
if(!mapheaderinfo[gamemap-1])
|
||||
P_AllocMapHeader(gamemap-1);
|
||||
if (!gamemap || gamemap > nummapheaders || !mapheaderinfo[gamemap-1])
|
||||
I_Error("P_NetUnArchiveMisc: Internal map ID %d not found (nummapheaders = %d)", gamemap-1, nummapheaders);
|
||||
|
||||
// tell the sound code to reset the music since we're skipping what
|
||||
// normally sets this flag
|
||||
|
|
@ -5078,7 +5073,6 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
|||
|
||||
// get the time
|
||||
leveltime = READUINT32(save->p);
|
||||
ssspheres = READUINT32(save->p);
|
||||
lastmap = READINT16(save->p);
|
||||
bossdisabled = READUINT16(save->p);
|
||||
ringsdisabled = READUINT8(save->p);
|
||||
|
|
@ -5102,7 +5096,6 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
|||
}
|
||||
|
||||
token = READUINT32(save->p);
|
||||
sstimer = READINT32(save->p);
|
||||
bluescore = READUINT32(save->p);
|
||||
redscore = READUINT32(save->p);
|
||||
|
||||
|
|
@ -5135,9 +5128,6 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
|
|||
gravity = READFIXED(save->p);
|
||||
mapobjectscale = READFIXED(save->p);
|
||||
|
||||
countdowntimer = (tic_t)READUINT32(save->p);
|
||||
countdowntimeup = (boolean)READUINT8(save->p);
|
||||
|
||||
// SRB2kart
|
||||
numgotboxes = READINT32(save->p);
|
||||
numtargets = READUINT8(save->p);
|
||||
|
|
@ -5314,7 +5304,7 @@ boolean P_LoadGame(savebuffer_t *save, INT16 mapoverride)
|
|||
return false;
|
||||
|
||||
// Only do this after confirming savegame is ok
|
||||
G_DeferedInitNew(false, G_BuildMapName(gamemap), savedata.skin, 0, true);
|
||||
G_DeferedInitNew(false, gamemap, savedata.skin, 0, true);
|
||||
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
|
||||
|
||||
return true;
|
||||
|
|
@ -5352,3 +5342,93 @@ boolean P_LoadNetGame(savebuffer_t *save, boolean reloading)
|
|||
|
||||
return P_UnArchiveLuabanksAndConsistency(save);
|
||||
}
|
||||
|
||||
boolean P_SaveBufferZAlloc(savebuffer_t *save, size_t alloc_size, INT32 tag, void *user)
|
||||
{
|
||||
I_Assert(save->buffer == NULL);
|
||||
save->buffer = (UINT8 *)Z_Malloc(alloc_size, tag, user);
|
||||
|
||||
if (save->buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
save->size = alloc_size;
|
||||
save->p = save->buffer;
|
||||
save->end = save->buffer + save->size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean P_SaveBufferFromExisting(savebuffer_t *save, UINT8 *existing_buffer, size_t existing_size)
|
||||
{
|
||||
I_Assert(save->buffer == NULL);
|
||||
|
||||
if (existing_buffer == NULL || existing_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
save->buffer = existing_buffer;
|
||||
save->size = existing_size;
|
||||
|
||||
save->p = save->buffer;
|
||||
save->end = save->buffer + save->size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean P_SaveBufferFromLump(savebuffer_t *save, lumpnum_t lump)
|
||||
{
|
||||
I_Assert(save->buffer == NULL);
|
||||
|
||||
if (lump == LUMPERROR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
save->buffer = (UINT8 *)W_CacheLumpNum(lump, PU_STATIC);
|
||||
|
||||
if (save->buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
save->size = W_LumpLength(lump);
|
||||
|
||||
save->p = save->buffer;
|
||||
save->end = save->buffer + save->size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t P_SaveBufferFromFile(savebuffer_t *save, char const *name)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
I_Assert(save->buffer == NULL);
|
||||
len = FIL_ReadFile(name, &save->buffer);
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
save->size = len;
|
||||
|
||||
save->p = save->buffer;
|
||||
save->end = save->buffer + save->size;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void P_SaveBufferInvalidate(savebuffer_t *save)
|
||||
{
|
||||
save->buffer = save->p = save->end = NULL;
|
||||
save->size = 0;
|
||||
}
|
||||
|
||||
void P_SaveBufferFree(savebuffer_t *save)
|
||||
{
|
||||
I_Assert(save->buffer != NULL);
|
||||
Z_Free(save->buffer);
|
||||
P_SaveBufferInvalidate(save);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,13 @@ struct savebuffer_t
|
|||
size_t size;
|
||||
};
|
||||
|
||||
boolean P_SaveBufferZAlloc(savebuffer_t *save, size_t alloc_size, INT32 tag, void *user);
|
||||
#define P_SaveBufferAlloc(a,b) P_SaveBufferZAlloc(a, b, PU_STATIC, NULL)
|
||||
boolean P_SaveBufferFromExisting(savebuffer_t *save, UINT8 *existing_buffer, size_t existing_size);
|
||||
boolean P_SaveBufferFromLump(savebuffer_t *save, lumpnum_t lump);
|
||||
size_t P_SaveBufferFromFile(savebuffer_t *save, char const *name);
|
||||
void P_SaveBufferFree(savebuffer_t *save);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
531
src/p_setup.c
531
src/p_setup.c
|
|
@ -334,11 +334,19 @@ boolean P_IsDegeneratedTubeWaypointSequence(UINT8 sequence)
|
|||
FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
|
||||
{
|
||||
// don't use va() because the calling function probably uses it
|
||||
char mapnum[10];
|
||||
char mapname[MAXMAPLUMPNAME];
|
||||
|
||||
if (gamemap > 0 && gamemap <= nummapheaders && mapheaderinfo[gamemap-1])
|
||||
{
|
||||
sprintf(mapname, "%s", mapheaderinfo[gamemap-1]->lumpname);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(mapname, "ID %d", gamemap-1);
|
||||
}
|
||||
|
||||
sprintf(mapnum, "%hd", gamemap);
|
||||
CON_LogMessage("Map ");
|
||||
CON_LogMessage(mapnum);
|
||||
CON_LogMessage(mapname);
|
||||
CON_LogMessage(" is corrupt: ");
|
||||
CON_LogMessage(msg);
|
||||
CON_LogMessage("\n");
|
||||
|
|
@ -387,40 +395,20 @@ static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
|
|||
* \param i Map number to clear header for.
|
||||
* \sa P_ClearMapHeaderInfo
|
||||
*/
|
||||
static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||
static void P_ClearSingleMapHeaderInfo(INT16 num)
|
||||
{
|
||||
const INT16 num = (INT16)(i-1);
|
||||
boolean exists = (mapheaderinfo[gamemap-1]->alreadyExists == true);
|
||||
|
||||
mapheaderinfo[num]->lvlttl[0] = '\0';
|
||||
mapheaderinfo[num]->selectheading[0] = '\0';
|
||||
mapheaderinfo[num]->subttl[0] = '\0';
|
||||
mapheaderinfo[num]->zonttl[0] = '\0';
|
||||
mapheaderinfo[num]->ltzzpatch[0] = '\0';
|
||||
mapheaderinfo[num]->ltzztext[0] = '\0';
|
||||
mapheaderinfo[num]->ltactdiamond[0] = '\0';
|
||||
mapheaderinfo[num]->actnum[0] = '\0';
|
||||
mapheaderinfo[num]->typeoflevel = 0;
|
||||
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
|
||||
mapheaderinfo[num]->marathonnext = 0;
|
||||
mapheaderinfo[num]->startrings = 0;
|
||||
mapheaderinfo[num]->sstimer = 90;
|
||||
mapheaderinfo[num]->ssspheres = 1;
|
||||
mapheaderinfo[num]->gravity = DEFAULT_GRAVITY;
|
||||
mapheaderinfo[num]->use_walltransfer = false;
|
||||
mapheaderinfo[num]->keywords[0] = '\0';
|
||||
for (i = 0; i < MAXMUSNAMES; i++)
|
||||
for (int i = 0; i < MAXMUSNAMES; i++)
|
||||
mapheaderinfo[num]->musname[i][0] = 0;
|
||||
mapheaderinfo[num]->mustrack = 0;
|
||||
mapheaderinfo[num]->muspos = 0;
|
||||
mapheaderinfo[num]->musinterfadeout = 0;
|
||||
mapheaderinfo[num]->musintername[0] = 0;
|
||||
mapheaderinfo[num]->muspostbossname[0] = 0;
|
||||
mapheaderinfo[num]->muspostbosstrack = 0;
|
||||
mapheaderinfo[num]->muspostbosspos = 0;
|
||||
mapheaderinfo[num]->muspostbossfadein = 0;
|
||||
mapheaderinfo[num]->musforcereset = -1;
|
||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||
mapheaderinfo[num]->musname_size = 0;
|
||||
mapheaderinfo[num]->weather = PRECIP_NONE;
|
||||
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
||||
|
|
@ -428,19 +416,15 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
mapheaderinfo[num]->skybox_scalex = 16;
|
||||
mapheaderinfo[num]->skybox_scaley = 16;
|
||||
mapheaderinfo[num]->skybox_scalez = 16;
|
||||
mapheaderinfo[num]->interscreen[0] = '#';
|
||||
mapheaderinfo[num]->runsoc[0] = '#';
|
||||
mapheaderinfo[num]->scriptname[0] = '#';
|
||||
mapheaderinfo[num]->precutscenenum = 0;
|
||||
mapheaderinfo[num]->cutscenenum = 0;
|
||||
mapheaderinfo[num]->countdown = 0;
|
||||
mapheaderinfo[num]->palette = UINT16_MAX;
|
||||
mapheaderinfo[num]->encorepal = UINT16_MAX;
|
||||
mapheaderinfo[num]->numlaps = NUMLAPS_DEFAULT;
|
||||
mapheaderinfo[num]->unlockrequired = -1;
|
||||
mapheaderinfo[num]->levelselect = 0;
|
||||
mapheaderinfo[num]->bonustype = 0;
|
||||
mapheaderinfo[num]->maxbonuslives = -1;
|
||||
mapheaderinfo[num]->levelflags = 0;
|
||||
mapheaderinfo[num]->menuflags = 0;
|
||||
mapheaderinfo[num]->mobj_scale = FRACUNIT;
|
||||
|
|
@ -453,10 +437,10 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
#else // equivalent to "FlickyList = NONE"
|
||||
P_DeleteFlickies(num);
|
||||
#endif
|
||||
P_DeleteGrades(num);
|
||||
|
||||
// see p_setup.c - prevents replacing maps in addons with different versions
|
||||
mapheaderinfo[num]->alreadyExists = exists;
|
||||
mapheaderinfo[num]->mapvisited = 0;
|
||||
Z_Free(mapheaderinfo[num]->mainrecord);
|
||||
mapheaderinfo[num]->mainrecord = NULL;
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
|
|
@ -468,110 +452,53 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
*/
|
||||
void P_AllocMapHeader(INT16 i)
|
||||
{
|
||||
if (!mapheaderinfo[i])
|
||||
if (i > nummapheaders)
|
||||
I_Error("P_AllocMapHeader: Called on %d, should be %d", i, nummapheaders);
|
||||
|
||||
if (i >= NEXTMAP_SPECIAL)
|
||||
{
|
||||
mapheaderinfo[i] = Z_Malloc(sizeof(mapheader_t), PU_STATIC, NULL);
|
||||
mapheaderinfo[i]->flickies = NULL;
|
||||
mapheaderinfo[i]->grades = NULL;
|
||||
}
|
||||
P_ClearSingleMapHeaderInfo(i + 1);
|
||||
}
|
||||
|
||||
/** NiGHTS Grades are a special structure,
|
||||
* we initialize them here.
|
||||
*
|
||||
* \param i Index of header to allocate grades for
|
||||
* \param mare The mare we're adding grades for
|
||||
* \param grades the string from DeHackEd, we work with it ourselves
|
||||
*/
|
||||
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext)
|
||||
{
|
||||
INT32 g;
|
||||
char *spos = gtext;
|
||||
|
||||
CONS_Debug(DBG_SETUP, "Map %d Mare %d: ", i+1, (UINT16)mare+1);
|
||||
|
||||
if (mapheaderinfo[i]->numGradedMares < mare+1)
|
||||
{
|
||||
mapheaderinfo[i]->numGradedMares = mare+1;
|
||||
mapheaderinfo[i]->grades = Z_Realloc(mapheaderinfo[i]->grades, sizeof(nightsgrades_t) * mapheaderinfo[i]->numGradedMares, PU_STATIC, NULL);
|
||||
I_Error("P_AllocMapHeader: Too many maps!");
|
||||
}
|
||||
|
||||
for (g = 0; g < 6; ++g)
|
||||
if (i >= mapallocsize)
|
||||
{
|
||||
// Allow "partial" grading systems
|
||||
if (spos != NULL)
|
||||
if (!mapallocsize)
|
||||
{
|
||||
mapheaderinfo[i]->grades[mare].grade[g] = atoi(spos);
|
||||
CONS_Debug(DBG_SETUP, "%u ", atoi(spos));
|
||||
// Grab next comma
|
||||
spos = strchr(spos, ',');
|
||||
if (spos)
|
||||
++spos;
|
||||
mapallocsize = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grade not reachable
|
||||
mapheaderinfo[i]->grades[mare].grade[g] = UINT32_MAX;
|
||||
mapallocsize *= 2;
|
||||
}
|
||||
|
||||
mapheaderinfo = Z_ReallocAlign(
|
||||
(void*) mapheaderinfo,
|
||||
sizeof(mapheader_t*) * mapallocsize,
|
||||
PU_STATIC,
|
||||
NULL,
|
||||
sizeof(mapheader_t*) * 8
|
||||
);
|
||||
|
||||
if (!mapheaderinfo)
|
||||
I_Error("P_AllocMapHeader: Not enough memory to realloc mapheaderinfo (size %d)", mapallocsize);
|
||||
}
|
||||
|
||||
CONS_Debug(DBG_SETUP, "\n");
|
||||
}
|
||||
|
||||
/** And this removes the grades safely.
|
||||
*
|
||||
* \param i The header to remove grades from
|
||||
*/
|
||||
void P_DeleteGrades(INT16 i)
|
||||
{
|
||||
if (mapheaderinfo[i]->grades)
|
||||
Z_Free(mapheaderinfo[i]->grades);
|
||||
|
||||
mapheaderinfo[i]->grades = NULL;
|
||||
mapheaderinfo[i]->numGradedMares = 0;
|
||||
}
|
||||
|
||||
/** And this fetches the grades
|
||||
*
|
||||
* \param pscore The player's score.
|
||||
* \param map The game map.
|
||||
* \param mare The mare to test.
|
||||
*/
|
||||
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// Determining the grade
|
||||
if (mapheaderinfo[map-1] && mapheaderinfo[map-1]->grades && mapheaderinfo[map-1]->numGradedMares >= mare + 1)
|
||||
if (!mapheaderinfo[i])
|
||||
{
|
||||
INT32 pgrade = 0;
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
if (pscore >= mapheaderinfo[map-1]->grades[mare].grade[i])
|
||||
++pgrade;
|
||||
}
|
||||
return (UINT8)pgrade;
|
||||
mapheaderinfo[i] = Z_Malloc(sizeof(mapheader_t), PU_STATIC, NULL);
|
||||
if (!mapheaderinfo[i])
|
||||
I_Error("P_AllocMapHeader: Not enough memory to allocate new mapheader (ID %d)", i);
|
||||
|
||||
mapheaderinfo[i]->lumpnum = LUMPERROR;
|
||||
mapheaderinfo[i]->lumpname = NULL;
|
||||
mapheaderinfo[i]->thumbnailPic = NULL;
|
||||
mapheaderinfo[i]->minimapPic = NULL;
|
||||
mapheaderinfo[i]->cup = NULL;
|
||||
mapheaderinfo[i]->mainrecord = NULL;
|
||||
mapheaderinfo[i]->flickies = NULL;
|
||||
nummapheaders++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT8 P_HasGrades(INT16 map, UINT8 mare)
|
||||
{
|
||||
// Determining the grade
|
||||
// Mare 0 is treated as overall and is true if ANY grades exist
|
||||
if (mapheaderinfo[map-1] && mapheaderinfo[map-1]->grades
|
||||
&& (mare == 0 || mapheaderinfo[map-1]->numGradedMares >= mare))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade)
|
||||
{
|
||||
// Get the score for the grade... if it exists
|
||||
if (grade == GRADE_F || grade > GRADE_S || !P_HasGrades(map, mare)) return 0;
|
||||
|
||||
return mapheaderinfo[map-1]->grades[mare].grade[grade-1];
|
||||
P_ClearSingleMapHeaderInfo(i);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -808,65 +735,6 @@ void P_ReloadRings(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SCANTHINGS
|
||||
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
|
||||
{
|
||||
size_t i, n;
|
||||
UINT8 *data, *datastart;
|
||||
UINT16 type, maprings;
|
||||
INT16 tol;
|
||||
UINT32 flags;
|
||||
|
||||
tol = mapheaderinfo[mapnum-1]->typeoflevel;
|
||||
flags = mapheaderinfo[mapnum-1]->levelflags;
|
||||
|
||||
n = W_LumpLengthPwad(wadnum, lumpnum) / (5 * sizeof (INT16));
|
||||
//CONS_Printf("%u map things found!\n", n);
|
||||
|
||||
maprings = 0;
|
||||
data = datastart = W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
data += 3 * sizeof (INT16); // skip x y position, angle
|
||||
type = READUINT16(data) & 4095;
|
||||
data += sizeof (INT16); // skip options
|
||||
|
||||
if (mt->type == mobjinfo[MT_RANDOMITEM].doomednum)
|
||||
{
|
||||
nummapboxes++;
|
||||
}
|
||||
else if (mt->type == mobjinfo[MT_RING].doomednum)
|
||||
{
|
||||
maprings++;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 603: // 10 diagonal rings
|
||||
maprings += 10;
|
||||
break;
|
||||
case 600: // 5 vertical rings
|
||||
case 601: // 5 vertical rings
|
||||
case 602: // 5 diagonal rings
|
||||
maprings += 5;
|
||||
break;
|
||||
case 604: // 8 circle rings
|
||||
maprings += 8;
|
||||
break;
|
||||
case 605: // 16 circle rings
|
||||
maprings += 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Z_Free(datastart);
|
||||
|
||||
if (maprings)
|
||||
CONS_Printf("%s has %u rings\n", G_BuildMapName(mapnum), maprings);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmp_loopends(const void *a, const void *b)
|
||||
{
|
||||
const mapthing_t
|
||||
|
|
@ -968,20 +836,15 @@ void P_WriteThings(void)
|
|||
{
|
||||
size_t i, length;
|
||||
mapthing_t *mt;
|
||||
savebuffer_t save;
|
||||
savebuffer_t save = {0};
|
||||
INT16 temp;
|
||||
|
||||
save.size = nummapthings * sizeof (mapthing_t);
|
||||
save.p = save.buffer = (UINT8 *)malloc(nummapthings * sizeof (mapthing_t));
|
||||
|
||||
if (!save.p)
|
||||
if (P_SaveBufferAlloc(&save, nummapthings * sizeof (mapthing_t)) == false)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("No more free memory for thing writing!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
save.end = save.buffer + save.size;
|
||||
|
||||
mt = mapthings;
|
||||
for (i = 0; i < nummapthings; i++, mt++)
|
||||
{
|
||||
|
|
@ -2389,7 +2252,7 @@ typedef struct
|
|||
static FILE *P_OpenTextmap(const char *mode, const char *error)
|
||||
{
|
||||
FILE *f;
|
||||
char *filepath = va(pandf, srb2home, "TEXTMAP");
|
||||
char *filepath = va("%s" PATHSEP "TEXTMAP.%s.txt", srb2home, mapheaderinfo[gamemap-1]->lumpname);
|
||||
|
||||
f = fopen(filepath, mode);
|
||||
if (!f)
|
||||
|
|
@ -7879,19 +7742,9 @@ static void P_InitLevelSettings(boolean reloadinggamestate)
|
|||
// emerald hunt
|
||||
hunt1 = hunt2 = hunt3 = NULL;
|
||||
|
||||
// map time limit
|
||||
if (mapheaderinfo[gamemap-1]->countdown)
|
||||
{
|
||||
countdowntimer = mapheaderinfo[gamemap-1]->countdown * TICRATE;
|
||||
}
|
||||
else
|
||||
countdowntimer = 0;
|
||||
countdowntimeup = false;
|
||||
|
||||
// circuit, race and competition stuff
|
||||
circuitmap = false;
|
||||
numstarposts = 0;
|
||||
ssspheres = 0;
|
||||
numbosswaypoints = 0;
|
||||
if (!reloadinggamestate)
|
||||
timeinmap = 0;
|
||||
|
|
@ -8047,43 +7900,6 @@ static void P_RunLevelScript(const char *scriptname)
|
|||
COM_BufExecute(); // Run it!
|
||||
}
|
||||
|
||||
static void P_ForceCharacter(const char *forcecharskin)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
char skincmd[33];
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
const char *num = "";
|
||||
|
||||
if (i > 0)
|
||||
num = va("%d", i+1);
|
||||
|
||||
sprintf(skincmd, "skin%s %s\n", num, forcecharskin);
|
||||
CV_Set(&cv_skin[i], forcecharskin);
|
||||
}
|
||||
|
||||
COM_BufAddText(skincmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
SetPlayerSkin(g_localplayers[i], forcecharskin);
|
||||
|
||||
// normal player colors in single player
|
||||
if ((unsigned)cv_playercolor[i].value != skins[players[g_localplayers[i]].skin].prefcolor && !modeattacking)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[i], skins[players[g_localplayers[i]].skin].prefcolor);
|
||||
players[g_localplayers[i]].skincolor = skins[players[g_localplayers[i]].skin].prefcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void P_ResetSpawnpoints(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
|
@ -8112,7 +7928,7 @@ static void P_LoadRecordGhosts(void)
|
|||
INT32 i;
|
||||
const char *gamemode = (modeattacking & ATTACKING_ITEMBREAK) ? "IB" : "RA";
|
||||
|
||||
gpath = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)));
|
||||
gpath = xva("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
|
||||
|
||||
// Best Time ghost
|
||||
if (cv_ghost_besttime.value)
|
||||
|
|
@ -8165,14 +7981,15 @@ static void P_LoadRecordGhosts(void)
|
|||
{
|
||||
lumpnum_t l;
|
||||
UINT8 j = 1;
|
||||
while (j <= 99 && (l = W_CheckNumForName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
|
||||
// TODO: Use map header to determine lump name
|
||||
while (j <= 99 && (l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
|
||||
{
|
||||
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(gpath);
|
||||
free(gpath);
|
||||
}
|
||||
|
||||
static void P_SetupCamera(UINT8 pnum, camera_t *cam)
|
||||
|
|
@ -8307,7 +8124,7 @@ static void P_InitGametype(void)
|
|||
#else
|
||||
strcpy(ver, VERSIONSTRING);
|
||||
#endif
|
||||
sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s"PATHSEP"%d-%s",
|
||||
snprintf(buf, sizeof buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s"PATHSEP"%d-%s",
|
||||
srb2home, ver, (int) (time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
parts = M_PathParts(buf);
|
||||
|
|
@ -8329,6 +8146,8 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
// Map header should always be in place at this point
|
||||
INT32 i, ranspecialwipe = 0;
|
||||
sector_t *ss;
|
||||
virtlump_t *encoreLump = NULL;
|
||||
lumpnum_t oldEncore = LUMPERROR;
|
||||
|
||||
levelloading = true;
|
||||
|
||||
|
|
@ -8366,9 +8185,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
for (i = 0; i <= r_splitscreen; i++)
|
||||
postimgtype[i] = postimg_none;
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0')
|
||||
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
|
||||
|
||||
// Initial height of PointOfView
|
||||
// will be set by player think.
|
||||
players[consoleplayer].viewz = 1;
|
||||
|
|
@ -8540,15 +8356,46 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
}
|
||||
|
||||
// internal game map
|
||||
maplumpname = G_BuildMapName(gamemap);
|
||||
lastloadedmaplumpnum = W_CheckNumForMap(maplumpname);
|
||||
maplumpname = mapheaderinfo[gamemap-1]->lumpname;
|
||||
lastloadedmaplumpnum = mapheaderinfo[gamemap-1]->lumpnum;
|
||||
if (lastloadedmaplumpnum == LUMPERROR)
|
||||
I_Error("Map %s not found.\n", maplumpname);
|
||||
|
||||
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
|
||||
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette,
|
||||
W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T'))));
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
if (encoremode)
|
||||
{
|
||||
encoreLump = vres_Find(curmapvirt, "ENCORE");
|
||||
if (!encoreLump)
|
||||
oldEncore = W_CheckNumForName(va("%sE", maplumpname));
|
||||
}
|
||||
else
|
||||
{
|
||||
encoreLump = vres_Find(curmapvirt, "TWEAKMAP");
|
||||
if (!encoreLump)
|
||||
oldEncore = W_CheckNumForName(va("%sT", maplumpname));
|
||||
}
|
||||
}
|
||||
|
||||
if (encoreLump)
|
||||
{
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, encoreLump->data, encoreLump->size, false);
|
||||
}
|
||||
else if (oldEncore != LUMPERROR)
|
||||
{
|
||||
// mildly annoying, but whatever
|
||||
size_t size = W_LumpLength(oldEncore);
|
||||
void *data = malloc(size);
|
||||
W_ReadLump(oldEncore, data);
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, data, size, wadfiles[WADFILENUM(oldEncore)]->compatmode);
|
||||
free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, NULL, 0, false);
|
||||
}
|
||||
CON_SetupBackColormap();
|
||||
|
||||
// SRB2 determines the sky texture to be used depending on the map header.
|
||||
|
|
@ -8662,9 +8509,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
R_PrecacheLevel();
|
||||
|
||||
if (!(netgame || multiplayer || demo.playback) && !majormods)
|
||||
mapvisited[gamemap-1] |= MV_VISITED;
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_VISITED;
|
||||
else if (!demo.playback)
|
||||
mapvisited[gamemap-1] |= MV_MP; // you want to record that you've been there this session, but not permanently
|
||||
mapheaderinfo[gamemap-1]->mapvisited |= MV_MP; // you want to record that you've been there this session, but not permanently
|
||||
|
||||
G_AddMapToBuffer(gamemap-1);
|
||||
|
||||
|
|
@ -8901,6 +8748,143 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
|
|||
return lumpinfo;
|
||||
}
|
||||
|
||||
lumpnum_t wadnamelump = LUMPERROR;
|
||||
INT16 wadnamemap = 0; // gamemap based
|
||||
|
||||
// Initialising map data...
|
||||
UINT8 P_InitMapData(boolean existingmapheaders)
|
||||
{
|
||||
UINT8 ret = 0;
|
||||
INT32 i;
|
||||
lumpnum_t maplump;
|
||||
virtres_t *virtmap;
|
||||
virtlump_t *minimap, *thumbnailPic;
|
||||
patch_t *oldPic;
|
||||
char *name;
|
||||
|
||||
for (i = 0; i < nummapheaders; ++i)
|
||||
{
|
||||
name = mapheaderinfo[i]->lumpname;
|
||||
maplump = W_CheckNumForMap(name);
|
||||
|
||||
// Doesn't exist?
|
||||
if (maplump == INT16_MAX)
|
||||
{
|
||||
#ifndef DEVELOP
|
||||
if (!existingmapheaders)
|
||||
{
|
||||
I_Error("P_InitMapData: Base map %s has a header but no level\n", name);
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// Always check for cup cache reassociations.
|
||||
// (The core assumption is that cups < headers.)
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
INT32 j;
|
||||
|
||||
mapheaderinfo[i]->cup = NULL;
|
||||
|
||||
while (cup)
|
||||
{
|
||||
for (j = 0; j < CUPCACHE_MAX; j++)
|
||||
{
|
||||
// Already discovered?
|
||||
if (cup->cachedlevels[j] != NEXTMAP_INVALID)
|
||||
continue;
|
||||
|
||||
if (!cup->levellist[j] || strcasecmp(cup->levellist[j], name) != 0)
|
||||
continue;
|
||||
|
||||
// Only panic about back-reference for non-bonus material.
|
||||
if (j < MAXLEVELLIST)
|
||||
{
|
||||
if (mapheaderinfo[i]->cup)
|
||||
I_Error("P_InitMapData: Map %s cannot appear in cups multiple times! (First in %s, now in %s)", name, mapheaderinfo[i]->cup->name, cup->name);
|
||||
mapheaderinfo[i]->cup = cup;
|
||||
}
|
||||
|
||||
cup->cachedlevels[j] = i;
|
||||
}
|
||||
cup = cup->next;
|
||||
}
|
||||
}
|
||||
|
||||
// No change?
|
||||
if (mapheaderinfo[i]->lumpnum == maplump)
|
||||
continue;
|
||||
|
||||
// Okay, it does...
|
||||
{
|
||||
ret |= MAPRET_ADDED;
|
||||
|
||||
if (existingmapheaders)
|
||||
{
|
||||
CONS_Printf("%s\n", name);
|
||||
|
||||
if (mapheaderinfo[i]->lumpnum != LUMPERROR)
|
||||
{
|
||||
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||
|
||||
//If you replaced the map you're on, end the level when done.
|
||||
if (i == gamemap - 1)
|
||||
ret |= MAPRET_CURRENTREPLACED;
|
||||
}
|
||||
}
|
||||
|
||||
mapheaderinfo[i]->lumpnum = maplump;
|
||||
if (maplump == wadnamelump)
|
||||
wadnamemap = i+1;
|
||||
|
||||
// Get map thumbnail and minimap
|
||||
virtmap = vres_GetMap(mapheaderinfo[i]->lumpnum);
|
||||
thumbnailPic = vres_Find(virtmap, "PICTURE");
|
||||
minimap = vres_Find(virtmap, "MINIMAP");
|
||||
|
||||
// Clear out existing graphics...
|
||||
if (mapheaderinfo[i]->thumbnailPic)
|
||||
{
|
||||
Patch_Free(mapheaderinfo[i]->thumbnailPic);
|
||||
}
|
||||
|
||||
if (mapheaderinfo[i]->minimapPic)
|
||||
{
|
||||
Patch_Free(mapheaderinfo[i]->minimapPic);
|
||||
}
|
||||
|
||||
// Now apply the new ones!
|
||||
if (thumbnailPic)
|
||||
{
|
||||
mapheaderinfo[i]->thumbnailPic = vres_GetPatch(thumbnailPic, PU_STATIC);
|
||||
}
|
||||
// okay... try finding them the old-fashioned way
|
||||
else
|
||||
{
|
||||
oldPic = W_CachePatchName(va("%sP", name), PU_STATIC);
|
||||
if (oldPic != missingpat)
|
||||
mapheaderinfo[i]->thumbnailPic = oldPic;
|
||||
}
|
||||
|
||||
if (minimap)
|
||||
{
|
||||
mapheaderinfo[i]->minimapPic = vres_GetPatch(minimap, PU_STATIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
oldPic = W_CachePatchName(va("%sR", name), PU_STATIC);
|
||||
if (oldPic != missingpat)
|
||||
mapheaderinfo[i]->minimapPic = oldPic;
|
||||
}
|
||||
|
||||
vres_Free(virtmap);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Add a wadfile to the active wad files,
|
||||
// replace sounds, musics, patches, textures, sprites and maps
|
||||
|
|
@ -8926,7 +8910,6 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
|
|||
UINT16 numlumps, wadnum;
|
||||
char *name;
|
||||
lumpinfo_t *lumpinfo;
|
||||
boolean mapsadded = false;
|
||||
|
||||
// Vars to help us with the position start and amount of each resource type.
|
||||
// Useful for PK3s since they use folders.
|
||||
|
|
@ -9082,41 +9065,6 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
|
|||
//
|
||||
R_LoadSpriteInfoLumps(wadnum, numlumps);
|
||||
|
||||
//
|
||||
// search for maps
|
||||
//
|
||||
lumpinfo = wadfiles[wadnum]->lumpinfo;
|
||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
||||
{
|
||||
name = lumpinfo->name;
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
|
||||
{
|
||||
INT16 num;
|
||||
if (name[5]!='\0')
|
||||
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]->alreadyExists != false)
|
||||
{
|
||||
G_SetGameModified(multiplayer, true); // oops, double-defined - no record attack privileges for you
|
||||
}
|
||||
mapheaderinfo[num - 1]->alreadyExists = true;
|
||||
}
|
||||
|
||||
if (num == gamemap)
|
||||
partadd_replacescurrentmap = true;
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
mapsadded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
refreshdirmenu &= ~REFRESHDIR_GAMEDATA; // Under usual circumstances we'd wait for REFRESHDIR_ flags to disappear the next frame, but this one's a bit too dangerous for that...
|
||||
partadd_stage = 0;
|
||||
return wadnum;
|
||||
|
|
@ -9180,9 +9128,16 @@ boolean P_MultiSetupWadFiles(boolean fullsetup)
|
|||
|
||||
if (partadd_stage == 2)
|
||||
{
|
||||
if (partadd_replacescurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer))
|
||||
UINT8 mapsadded = P_InitMapData(true);
|
||||
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
if ((mapsadded & MAPRET_CURRENTREPLACED)
|
||||
&& (gamestate == GS_LEVEL)
|
||||
&& (netgame || multiplayer))
|
||||
{
|
||||
CONS_Printf(M_GetText("Current map %d replaced, ending the level to ensure consistency.\n"), gamemap);
|
||||
CONS_Printf(M_GetText("Current map %s replaced by added file, ending the level to ensure consistency.\n"), mapheaderinfo[gamemap-1]->lumpname);
|
||||
if (server)
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,9 +103,6 @@ extern size_t nummapthings;
|
|||
extern mapthing_t *mapthings;
|
||||
|
||||
void P_SetupLevelSky(const char *skytexname, boolean global);
|
||||
#ifdef SCANTHINGS
|
||||
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
|
||||
#endif
|
||||
void P_RespawnThings(void);
|
||||
boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate);
|
||||
void P_PostLoadLevel(void);
|
||||
|
|
@ -114,6 +111,13 @@ void HWR_LoadLevel(void);
|
|||
#endif
|
||||
boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat);
|
||||
|
||||
#define MAPRET_ADDED (1)
|
||||
#define MAPRET_CURRENTREPLACED (1<<1)
|
||||
UINT8 P_InitMapData(boolean existingmapheaders);
|
||||
extern lumpnum_t wadnamelump;
|
||||
extern INT16 wadnamemap;
|
||||
#define WADNAMECHECK(name) (!strncmp(name, "WADNAME", 7))
|
||||
|
||||
// WARNING: The following functions should be grouped as follows:
|
||||
// any amount of PartialAdds followed by MultiSetups until returned true,
|
||||
// as soon as possible.
|
||||
|
|
@ -150,11 +154,6 @@ void P_DeleteFlickies(INT16 i);
|
|||
|
||||
// Needed for NiGHTS
|
||||
void P_ReloadRings(void);
|
||||
void P_DeleteGrades(INT16 i);
|
||||
void P_AddGradesForMare(INT16 i, UINT8 mare, char *gtext);
|
||||
UINT8 P_GetGrade(UINT32 pscore, INT16 map, UINT8 mare);
|
||||
UINT8 P_HasGrades(INT16 map, UINT8 mare);
|
||||
UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -6714,10 +6714,6 @@ void P_InitSpecials(void)
|
|||
maplighting.directional = lighting->use_light_angle;
|
||||
maplighting.angle = lighting->light_angle;
|
||||
|
||||
// Defaults in case levels don't have them set.
|
||||
sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6;
|
||||
ssspheres = mapheaderinfo[gamemap-1]->ssspheres;
|
||||
|
||||
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
|
||||
|
||||
// Set weather
|
||||
|
|
@ -6868,11 +6864,6 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
// Process Section 2
|
||||
switch(GETSECSPECIAL(sector->special, 2))
|
||||
{
|
||||
case 10: // Time for special stage
|
||||
sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish
|
||||
ssspheres = sector->ceilingheight>>FRACBITS; // Ring count for special stage
|
||||
break;
|
||||
|
||||
case 11: // Custom global gravity!
|
||||
if (udmf)
|
||||
break;
|
||||
|
|
|
|||
24
src/p_user.c
24
src/p_user.c
|
|
@ -303,11 +303,15 @@ boolean P_PlayerMoving(INT32 pnum)
|
|||
//
|
||||
UINT8 P_GetNextEmerald(void)
|
||||
{
|
||||
if (gamemap >= sstage_start && gamemap <= sstage_end)
|
||||
return (UINT8)(gamemap - sstage_start);
|
||||
if (gamemap >= smpstage_start || gamemap <= smpstage_end)
|
||||
return (UINT8)(gamemap - smpstage_start);
|
||||
return 0;
|
||||
INT16 mapnum = gamemap-1;
|
||||
|
||||
if (mapnum > nummapheaders || !mapheaderinfo[mapnum])
|
||||
return 0;
|
||||
|
||||
if (!mapheaderinfo[mapnum]->cup || mapheaderinfo[mapnum]->cup->cachedlevels[CUPCACHE_SPECIAL] != mapnum)
|
||||
return 0;
|
||||
|
||||
return mapheaderinfo[mapnum]->cup->emeraldnum;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2098,9 +2102,6 @@ void P_MovePlayer(player_t *player)
|
|||
|
||||
fixed_t runspd;
|
||||
|
||||
if (countdowntimeup)
|
||||
return;
|
||||
|
||||
cmd = &player->cmd;
|
||||
runspd = 14*player->mo->scale; //srb2kart
|
||||
|
||||
|
|
@ -4293,14 +4294,7 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
if (!player->spectator)
|
||||
P_PlayerInSpecialSector(player);
|
||||
else if (
|
||||
#else
|
||||
if (player->spectator &&
|
||||
#endif
|
||||
(gametyperules & GTR_LIVES))
|
||||
{
|
||||
/*P_ConsiderAllGone()*/;
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ void R_InitColormaps(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
|
||||
void R_ReInitColormaps(UINT16 num, void *newencoremap, size_t encoremapsize, boolean compat)
|
||||
{
|
||||
char colormap[9] = "COLORMAP";
|
||||
lumpnum_t lump;
|
||||
|
|
@ -325,18 +325,17 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
|
|||
}
|
||||
|
||||
// Encore mode.
|
||||
if (newencoremap != LUMPERROR)
|
||||
if (newencoremap)
|
||||
{
|
||||
lighttable_t *colormap_p, *colormap_p2;
|
||||
size_t p, i;
|
||||
|
||||
encoremap = Z_MallocAlign(256 + 10, PU_LEVEL, NULL, 8);
|
||||
W_ReadLump(newencoremap, encoremap);
|
||||
M_Memcpy(encoremap, newencoremap, encoremapsize);
|
||||
colormap_p = colormap_p2 = colormaps;
|
||||
colormap_p += COLORMAP_REMAPOFFSET;
|
||||
|
||||
remap = wadfiles[WADFILENUM(newencoremap)]->compatmode;
|
||||
if (remap)
|
||||
if (compat)
|
||||
{
|
||||
UINT8 *copy = malloc(256);
|
||||
memcpy(copy, encoremap, 256);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ extern size_t flatmemory, spritememory, texturememory;
|
|||
//#define COLORMAPREVERSELIST
|
||||
|
||||
void R_InitColormaps(void);
|
||||
void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap);
|
||||
void R_ReInitColormaps(UINT16 num, void *newencoremap, size_t encoremapsize, boolean compat);
|
||||
void R_ClearColormaps(void);
|
||||
extracolormap_t *R_CreateDefaultColormap(boolean lighttable);
|
||||
extracolormap_t *R_GetDefaultColormap(void);
|
||||
|
|
|
|||
|
|
@ -913,6 +913,9 @@ struct patch_t
|
|||
};
|
||||
|
||||
extern patch_t *missingpat;
|
||||
extern patch_t *blanklvl;
|
||||
extern patch_t *randomlvl;
|
||||
extern patch_t *nolvl;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(1)
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static void Patch_FreeData(patch_t *patch)
|
|||
|
||||
void Patch_Free(patch_t *patch)
|
||||
{
|
||||
if (patch == missingpat)
|
||||
if (!patch || patch == missingpat)
|
||||
return;
|
||||
Patch_FreeData(patch);
|
||||
Z_Free(patch);
|
||||
|
|
|
|||
|
|
@ -198,12 +198,6 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum))
|
||||
{
|
||||
// Being forced to play as this character by the level
|
||||
return true;
|
||||
}
|
||||
|
||||
if (netgame && (cv_forceskin.value == skinnum))
|
||||
{
|
||||
// Being forced to play as this character by the server
|
||||
|
|
|
|||
|
|
@ -442,6 +442,31 @@ static void ST_drawRenderDebug(INT32 *height)
|
|||
ST_pushDebugString(height, va("Skybox Portals: %4s", sizeu1(i->skybox_portals)));
|
||||
}
|
||||
|
||||
static void ST_drawDemoDebug(INT32 *height)
|
||||
{
|
||||
if (!demo.recording && !demo.playback)
|
||||
return;
|
||||
|
||||
size_t needle = demo.buffer->p - demo.buffer->buffer;
|
||||
size_t size = demo.buffer->size;
|
||||
double percent = (double)needle / size * 100.0;
|
||||
double avg = (double)needle / leveltime;
|
||||
|
||||
ST_pushDebugString(height, va("%s/%s bytes", sizeu1(needle), sizeu2(size)));
|
||||
ST_pushDebugString(height, va(
|
||||
"%.2f/%.2f MB %5.2f%%",
|
||||
needle / (1024.0 * 1024.0),
|
||||
size / (1024.0 * 1024.0),
|
||||
percent
|
||||
));
|
||||
ST_pushDebugString(height, va(
|
||||
"%.2f KB/s (ETA %.2f minutes)",
|
||||
avg * TICRATE / 1024.0,
|
||||
(size - needle) / (avg * TICRATE * 60.0)
|
||||
));
|
||||
ST_pushDebugString(height, va("Demo (%s)", demo.recording ? "recording" : "playback"));
|
||||
}
|
||||
|
||||
static void ST_drawDebugInfo(void)
|
||||
{
|
||||
INT32 height = 192;
|
||||
|
|
@ -512,6 +537,11 @@ static void ST_drawDebugInfo(void)
|
|||
ST_drawRenderDebug(&height);
|
||||
}
|
||||
|
||||
if (cht_debug & DBG_DEMO)
|
||||
{
|
||||
ST_drawDemoDebug(&height);
|
||||
}
|
||||
|
||||
if (cht_debug & DBG_MEMORY)
|
||||
V_DrawRightAlignedString(320, height, V_MONOSPACE, va("Heap used: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10)));
|
||||
}
|
||||
|
|
|
|||
369
src/w_wad.c
369
src/w_wad.c
|
|
@ -64,11 +64,7 @@
|
|||
#include "i_system.h"
|
||||
#include "md5.h"
|
||||
#include "lua_script.h"
|
||||
#ifdef SCANTHINGS
|
||||
#include "p_setup.h" // P_ScanThings
|
||||
#endif
|
||||
#include "m_misc.h" // M_MapNumber
|
||||
#include "g_game.h" // G_SetGameModified
|
||||
#include "g_game.h" // G_MapNumber
|
||||
|
||||
#include "k_terrain.h"
|
||||
|
||||
|
|
@ -94,10 +90,12 @@ typedef struct
|
|||
|
||||
// Must be a power of two
|
||||
#define LUMPNUMCACHESIZE 64
|
||||
#define LUMPNUMCACHENAME 32
|
||||
|
||||
typedef struct lumpnum_cache_s
|
||||
{
|
||||
char lumpname[32];
|
||||
UINT32 lumphash;
|
||||
lumpnum_t lumpnum;
|
||||
} lumpnum_cache_t;
|
||||
|
||||
|
|
@ -307,22 +305,6 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
|
|||
DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SCANTHINGS
|
||||
// Scan maps for emblems 'n shit
|
||||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo;
|
||||
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
|
||||
{
|
||||
const char *name = lump_p->name;
|
||||
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P' && name[5]=='\0')
|
||||
{
|
||||
INT16 mapnum = (INT16)M_MapNumber(name[3], name[4]);
|
||||
P_ScanThings(mapnum, wadnum, lump + ML_THINGS);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline boolean CheckCompatFilename(const char *filename)
|
||||
|
|
@ -545,19 +527,76 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
|
|||
}
|
||||
else
|
||||
lump_p->compression = CM_NOCOMPRESSION;
|
||||
|
||||
memset(lump_p->name, 0x00, 9);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
// Allocate the lump's long name.
|
||||
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->longname, fileinfo->name, 8);
|
||||
lump_p->longname[8] = '\0';
|
||||
if (WADNAMECHECK(fileinfo->name))
|
||||
{
|
||||
size_t namelen;
|
||||
const char *trimname, *dotpos;
|
||||
|
||||
// Allocate the lump's full name.
|
||||
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->fullname, fileinfo->name, 8);
|
||||
lump_p->fullname[8] = '\0';
|
||||
trimname = strrchr(filename, PATHSEP[0]);
|
||||
#if defined (_WIN32)
|
||||
// For Zone Builder support, work around temporary filenames.
|
||||
// They're annoyingly randomised, BUT they follow \Temp\8\8.3...
|
||||
// AND they're always guaranteed to follow the map file, which
|
||||
// should already have a WADNAME in it for us to piggyback off.
|
||||
// EXAMPLE: // \Temp\gj3l7w7n\4f926789.wad
|
||||
|
||||
if (trimname != 0
|
||||
&& wadnamelump != LUMPERROR
|
||||
&& strlen(trimname+1) == 8+1+3)
|
||||
{
|
||||
const char *temp = trimname-1;
|
||||
while (temp >= filename+5 && *temp != PATHSEP[0])
|
||||
temp--;
|
||||
|
||||
if (((trimname-1) - temp) == 8
|
||||
&& temp >= filename+5
|
||||
&& !strncmp(temp-5, PATHSEP"Temp", 5))
|
||||
{
|
||||
filename = wadfiles[
|
||||
((wadnamelump & ~UINT16_MAX) >> 16)
|
||||
]->filename;
|
||||
trimname = strrchr(filename, PATHSEP[0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Strip away file address
|
||||
if (trimname != 0)
|
||||
trimname++;
|
||||
else
|
||||
trimname = filename; // Care taken for root files.
|
||||
|
||||
// First stop, not last, to permit RR_GREENHILLS.beta3.wad
|
||||
if ((dotpos = strchr(trimname, '.')) != 0)
|
||||
namelen = (dotpos + 1 - trimname);
|
||||
else
|
||||
namelen = strlen(trimname);
|
||||
|
||||
// Allocate the lump's long and full name (save on memory).
|
||||
lump_p->longname = lump_p->fullname = Z_Calloc(namelen * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->longname, trimname, namelen);
|
||||
lump_p->longname[namelen-1] = '\0';
|
||||
|
||||
CONS_Debug(DBG_SETUP, "WADNAME handling:\n -- path %s\n -- interpreted lumpname %s\n", filename, lump_p->longname);
|
||||
|
||||
// Grab the hash from the first part
|
||||
lump_p->hash = quickncasehash(lump_p->longname, 8);
|
||||
|
||||
wadnamelump = i | (numwadfiles << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set up true hash
|
||||
lump_p->hash = quickncasehash(lump_p->name, 8);
|
||||
|
||||
// Allocate the lump's long and full name (save on memory).
|
||||
lump_p->longname = lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
|
||||
strncpy(lump_p->longname, fileinfo->name, 8);
|
||||
lump_p->longname[8] = '\0';
|
||||
}
|
||||
}
|
||||
free(fileinfov);
|
||||
*nlmp = numlumps;
|
||||
|
|
@ -1094,6 +1133,63 @@ UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump)
|
|||
return INT16_MAX;
|
||||
}
|
||||
|
||||
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
|
||||
UINT16 W_CheckNumForMapPwad(const char *name, UINT32 hash, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
UINT16 i, end;
|
||||
|
||||
if (wadfiles[wad]->type == RET_WAD)
|
||||
{
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++)
|
||||
{
|
||||
// Not the hash?
|
||||
if ((wadfiles[wad]->lumpinfo + i)->hash != hash)
|
||||
continue;
|
||||
|
||||
// Not the name? (always use longname, even in wads, to accomodate WADNAME)
|
||||
if (strcasecmp(name, (wadfiles[wad]->lumpinfo + i)->longname))
|
||||
continue;
|
||||
|
||||
// Not a header?
|
||||
if (W_LumpLength(i | (wad << 16)) > 0)
|
||||
continue;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else if (wadfiles[wad]->type == RET_PK3)
|
||||
{
|
||||
i = W_CheckNumForFolderStartPK3("maps/", wad, startlump);
|
||||
|
||||
if (i != INT16_MAX)
|
||||
{
|
||||
end = W_CheckNumForFolderEndPK3("maps/", wad, i);
|
||||
|
||||
// Now look for the specified map.
|
||||
for (; i < end; i++)
|
||||
{
|
||||
// Not the hash?
|
||||
if ((wadfiles[wad]->lumpinfo + i)->hash != hash)
|
||||
continue;
|
||||
|
||||
// Not the name?
|
||||
if (strcasecmp(name, (wadfiles[wad]->lumpinfo + i)->longname))
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
// Not a .wad?
|
||||
if (!W_IsLumpWad(i | (wad << 16)))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
//
|
||||
// Same as the original, but checks in one pwad only.
|
||||
// wadid is a wad number
|
||||
|
|
@ -1141,12 +1237,14 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
UINT16 i;
|
||||
static char uname[256 + 1];
|
||||
UINT32 hash;
|
||||
|
||||
if (!TestValidLump(wad,0))
|
||||
return INT16_MAX;
|
||||
|
||||
strlcpy(uname, name, sizeof uname);
|
||||
strupr(uname);
|
||||
hash = quickncasehash(uname, 8); // Not a mistake, legacy system for short lumpnames
|
||||
|
||||
//
|
||||
// scan forward
|
||||
|
|
@ -1157,8 +1255,14 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
|
|||
{
|
||||
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
|
||||
if (!strcmp(lump_p->longname, uname))
|
||||
return i;
|
||||
{
|
||||
if (lump_p->hash != hash)
|
||||
continue;
|
||||
if (strcmp(lump_p->longname, uname))
|
||||
continue;
|
||||
return i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// not found.
|
||||
|
|
@ -1234,6 +1338,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
lumpnum_t W_CheckNumForName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash = name ? quickncasehash(name, 8) : 0;
|
||||
lumpnum_t check = INT16_MAX;
|
||||
|
||||
if (name == NULL)
|
||||
|
|
@ -1247,6 +1352,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||
{
|
||||
if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8]
|
||||
&& lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumphash == hash
|
||||
&& strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
|
||||
{
|
||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||
|
|
@ -1284,6 +1390,7 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
lumpnum_t W_CheckNumForLongName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 hash = name ? quickncasehash(name, 8) : 0;
|
||||
lumpnum_t check = INT16_MAX;
|
||||
|
||||
if (name == NULL)
|
||||
|
|
@ -1321,6 +1428,7 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
||||
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
|
||||
lumpnumcache[lumpnumcacheindex].lumphash = hash;
|
||||
}
|
||||
|
||||
return (i << 16) + check;
|
||||
|
|
@ -1329,45 +1437,52 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
|
||||
// Look for valid map data through all added files in descendant order.
|
||||
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
|
||||
// TODO: Make it search through cache first, maybe...?
|
||||
lumpnum_t W_CheckNumForMap(const char *name)
|
||||
{
|
||||
UINT32 hash = quickncasehash(name, 8);
|
||||
UINT16 lumpNum, end;
|
||||
UINT32 i;
|
||||
lumpinfo_t *p;
|
||||
for (i = numwadfiles - 1; i < numwadfiles; i--)
|
||||
lumpnum_t check = INT16_MAX;
|
||||
UINT32 uhash, hash = quickncasehash(name, LUMPNUMCACHENAME);
|
||||
INT32 i;
|
||||
|
||||
// Check the lumpnumcache first. Loop backwards so that we check
|
||||
// most recent entries first
|
||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||
{
|
||||
if (wadfiles[i]->type == RET_WAD)
|
||||
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumphash == hash
|
||||
&& strcasecmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||
{
|
||||
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
|
||||
{
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strncmp(name, p->name, 8))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
else if (wadfiles[i]->type == RET_PK3)
|
||||
{
|
||||
lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0);
|
||||
if (lumpNum != INT16_MAX)
|
||||
end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum);
|
||||
else
|
||||
continue;
|
||||
// Now look for the specified map.
|
||||
for (; lumpNum < end; lumpNum++)
|
||||
{
|
||||
p = wadfiles[i]->lumpinfo + lumpNum;
|
||||
if (p->hash == hash && !strnicmp(name, p->name, 8))
|
||||
{
|
||||
const char *extension = strrchr(p->fullname, '.');
|
||||
if (!(extension && stricmp(extension, ".wad")))
|
||||
return (i<<16) + lumpNum;
|
||||
}
|
||||
}
|
||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||
}
|
||||
}
|
||||
return LUMPERROR;
|
||||
|
||||
uhash = quickncasehash(name, 8); // Not a mistake, legacy system for short lumpnames
|
||||
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
check = W_CheckNumForMapPwad(name, uhash, (UINT16)i, 0);
|
||||
|
||||
if (check != INT16_MAX)
|
||||
break; // found it
|
||||
}
|
||||
|
||||
if (check == INT16_MAX)
|
||||
{
|
||||
return LUMPERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(name) < LUMPNUMCACHENAME)
|
||||
{
|
||||
// Update the cache.
|
||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', LUMPNUMCACHENAME);
|
||||
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, LUMPNUMCACHENAME);
|
||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
|
||||
lumpnumcache[lumpnumcacheindex].lumphash = hash;
|
||||
}
|
||||
|
||||
return (i << 16) + check;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1893,6 +2008,28 @@ void *W_CacheLumpName(const char *name, INT32 tag)
|
|||
// Cache a patch into heap memory, convert the patch format as necessary
|
||||
//
|
||||
|
||||
static void *MakePatch(void *lumpdata, size_t size, INT32 tag, void *cache, boolean remap)
|
||||
{
|
||||
void *ptr, *dest;
|
||||
size_t len = size;
|
||||
|
||||
ptr = lumpdata;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
|
||||
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
|
||||
#endif
|
||||
|
||||
if (remap)
|
||||
R_DoPaletteRemapPatch(ptr, len);
|
||||
|
||||
dest = Z_Calloc(sizeof(patch_t), tag, cache);
|
||||
|
||||
Patch_Create(ptr, len, dest);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
||||
{
|
||||
lumpcache_t *lumpcache = NULL;
|
||||
|
|
@ -1905,25 +2042,13 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
|
|||
if (!lumpcache[lump])
|
||||
{
|
||||
size_t len = W_LumpLengthPwad(wad, lump);
|
||||
void *ptr, *dest, *lumpdata = Z_Malloc(len, PU_STATIC, NULL);
|
||||
void *lumpdata = Z_Malloc(len, PU_STATIC, NULL);
|
||||
|
||||
// read the lump in full
|
||||
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
|
||||
ptr = lumpdata;
|
||||
|
||||
#ifndef NO_PNG_LUMPS
|
||||
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
|
||||
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
|
||||
#endif
|
||||
|
||||
// we already know this is a patch, do palette remapping here
|
||||
if (wadfiles[wad]->compatmode)
|
||||
R_DoPaletteRemapPatch(ptr, len);
|
||||
|
||||
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
|
||||
Patch_Create(ptr, len, dest);
|
||||
|
||||
Z_Free(ptr);
|
||||
MakePatch(lumpdata, len, tag, &lumpcache[lump], wadfiles[wad]->compatmode);
|
||||
Z_Free(lumpdata);
|
||||
}
|
||||
else
|
||||
Z_ChangeTag(lumpcache[lump], tag);
|
||||
|
|
@ -2395,28 +2520,48 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
|
||||
if (W_IsLumpWad(lumpnum))
|
||||
{
|
||||
UINT32 realentry;
|
||||
size_t *vsizecache;
|
||||
|
||||
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
|
||||
UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL);
|
||||
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
|
||||
numlumps = ((wadinfo_t *)wadData)->numlumps;
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
|
||||
// Build the lumps.
|
||||
for (i = 0; i < numlumps; i++)
|
||||
i = ((wadinfo_t *)wadData)->numlumps;
|
||||
vsizecache = Z_Malloc(sizeof(size_t)*i, PU_LEVEL, NULL);
|
||||
|
||||
for (realentry = 0; realentry < i; realentry++)
|
||||
{
|
||||
vlumps[i].size = (size_t)(((filelump_t *)(fileinfo + i))->size);
|
||||
// Play it safe with the name in this case.
|
||||
memcpy(vlumps[i].name, (fileinfo + i)->name, 8);
|
||||
vlumps[i].name[8] = '\0';
|
||||
vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that.
|
||||
memcpy(vlumps[i].data, wadData + (fileinfo + i)->filepos, vlumps[i].size);
|
||||
vsizecache[realentry] = (size_t)(((filelump_t *)(fileinfo + realentry))->size);
|
||||
|
||||
if (!vsizecache[realentry])
|
||||
continue;
|
||||
|
||||
numlumps++;
|
||||
}
|
||||
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
|
||||
// Build the lumps, skipping over empty entries.
|
||||
for (i = 0, realentry = 0; i < numlumps; realentry++)
|
||||
{
|
||||
if (vsizecache[realentry] == 0)
|
||||
continue;
|
||||
vlumps[i].size = vsizecache[realentry];
|
||||
// Play it safe with the name in this case.
|
||||
memcpy(vlumps[i].name, (fileinfo + realentry)->name, 8);
|
||||
vlumps[i].name[8] = '\0';
|
||||
vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that.
|
||||
memcpy(vlumps[i].data, wadData + (fileinfo + realentry)->filepos, vlumps[i].size);
|
||||
i++;
|
||||
}
|
||||
|
||||
Z_Free(vsizecache);
|
||||
Z_Free(wadData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Count number of lumps until the end of resource OR up until next "MAPXX" lump.
|
||||
// Count number of lumps until the end of resource OR up until next 0-length lump.
|
||||
lumpnum_t lumppos = lumpnum + 1;
|
||||
lumpnum_t lastlump = wadfiles[WADFILENUM(lumpnum)]->numlumps;
|
||||
// or the end of directory, for PK3 files
|
||||
|
|
@ -2430,8 +2575,12 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
free(dirname);
|
||||
}
|
||||
for (i = LUMPNUM(lumppos); i < lastlump; i++, lumppos++, numlumps++)
|
||||
if (memcmp(W_CheckNameForNum(lumppos), "MAP", 3) == 0)
|
||||
break;
|
||||
{
|
||||
if (W_LumpLength(lumppos) > 0)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
numlumps++;
|
||||
|
||||
vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL);
|
||||
|
|
@ -2463,7 +2612,12 @@ void vres_Free(virtres_t* vres)
|
|||
}
|
||||
|
||||
while (vres->numlumps--)
|
||||
Z_Free(vres->vlumps[vres->numlumps].data);
|
||||
{
|
||||
if (vres->vlumps[vres->numlumps].data)
|
||||
{
|
||||
Z_Free(vres->vlumps[vres->numlumps].data);
|
||||
}
|
||||
}
|
||||
Z_Free(vres->vlumps);
|
||||
Z_Free(vres);
|
||||
}
|
||||
|
|
@ -2494,3 +2648,30 @@ virtlump_t* vres_Find(const virtres_t* vres, const char* name)
|
|||
return &vres->vlumps[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** \brief Gets patch from given virtual lump
|
||||
*
|
||||
* \param Virtual lump
|
||||
* \return Patch data
|
||||
*
|
||||
*/
|
||||
void *vres_GetPatch(virtlump_t *vlump, INT32 tag)
|
||||
{
|
||||
patch_t *patch;
|
||||
|
||||
if (!vlump)
|
||||
return NULL;
|
||||
|
||||
patch = MakePatch(vlump->data, vlump->size, tag, NULL, false);
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Software-only compile cache the data without conversion
|
||||
if (rendermode == render_soft || rendermode == render_none)
|
||||
#endif
|
||||
return (void *)patch;
|
||||
|
||||
#ifdef HWRENDER
|
||||
Patch_CreateGL(patch);
|
||||
return (void *)patch;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ struct virtres_t {
|
|||
virtres_t* vres_GetMap(lumpnum_t);
|
||||
void vres_Free(virtres_t*);
|
||||
virtlump_t* vres_Find(const virtres_t*, const char*);
|
||||
void* vres_GetPatch(virtlump_t *vlump, INT32);
|
||||
|
||||
// =========================================================================
|
||||
// DYNAMIC WAD LOADING
|
||||
|
|
@ -163,6 +164,7 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum);
|
|||
|
||||
UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump); // checks only in one pwad
|
||||
|
||||
UINT16 W_CheckNumForMapPwad(const char *name, UINT32 hash, UINT16 wad, UINT16 startlump);
|
||||
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
|
||||
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump);
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ typedef struct
|
|||
char str[62];
|
||||
UINT8 gtc;
|
||||
const char *gts;
|
||||
patch_t *pic;
|
||||
boolean encore;
|
||||
} y_votelvlinfo;
|
||||
|
||||
|
|
@ -175,7 +174,6 @@ static patch_t *cursor1 = NULL;
|
|||
static patch_t *cursor2 = NULL;
|
||||
static patch_t *cursor3 = NULL;
|
||||
static patch_t *cursor4 = NULL;
|
||||
static patch_t *randomlvl = NULL;
|
||||
static patch_t *rubyicon = NULL;
|
||||
|
||||
static void Y_UnloadVoteData(void);
|
||||
|
|
@ -1036,8 +1034,8 @@ void Y_StartIntermission(void)
|
|||
//if (dedicated) return;
|
||||
|
||||
// This should always exist, but just in case...
|
||||
if (!mapheaderinfo[prevmap])
|
||||
P_AllocMapHeader(prevmap);
|
||||
if (prevmap >= nummapheaders || !mapheaderinfo[prevmap])
|
||||
I_Error("Y_StartIntermission: Internal map ID %d not found (nummapheaders = %d)", prevmap, nummapheaders);
|
||||
|
||||
switch (intertype)
|
||||
{
|
||||
|
|
@ -1189,6 +1187,9 @@ void Y_VoteDrawer(void)
|
|||
INT32 i, x, y = 0, height = 0;
|
||||
UINT8 selected[4];
|
||||
fixed_t rubyheight = 0;
|
||||
fixed_t scale;
|
||||
patch_t *pic;
|
||||
INT16 mapnum;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
|
@ -1257,19 +1258,19 @@ void Y_VoteDrawer(void)
|
|||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
const char *str;
|
||||
patch_t *pic;
|
||||
UINT8 j, color;
|
||||
|
||||
if (i == 3)
|
||||
{
|
||||
str = "RANDOM";
|
||||
pic = randomlvl;
|
||||
mapnum = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = levelinfo[i].str;
|
||||
pic = levelinfo[i].pic;
|
||||
mapnum = votelevels[i][0];
|
||||
}
|
||||
scale = M_GetMapThumbnail(mapnum, &pic)/4;
|
||||
|
||||
if (selected[i])
|
||||
{
|
||||
|
|
@ -1333,10 +1334,10 @@ void Y_VoteDrawer(void)
|
|||
}
|
||||
|
||||
if (!levelinfo[i].encore)
|
||||
V_DrawSmallScaledPatch(BASEVIDWIDTH-100, y, V_SNAPTORIGHT, pic);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-100)<<FRACBITS, y<<FRACBITS, scale, V_SNAPTORIGHT, pic, NULL);
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, scale, V_FLIP|V_SNAPTORIGHT, pic, NULL);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, ((y+25)<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTORIGHT, rubyicon, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1356,11 +1357,12 @@ void Y_VoteDrawer(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
scale /= 2;
|
||||
if (!levelinfo[i].encore)
|
||||
V_DrawTinyScaledPatch(BASEVIDWIDTH-60, y, V_SNAPTORIGHT, pic);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-60)<<FRACBITS, y<<FRACBITS, scale, V_SNAPTORIGHT, pic, NULL);
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, FRACUNIT/4, V_FLIP|V_SNAPTORIGHT, pic, 0);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-20)<<FRACBITS, y<<FRACBITS, scale, V_FLIP|V_SNAPTORIGHT, pic, NULL);
|
||||
V_DrawFixedPatch((BASEVIDWIDTH-40)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTORIGHT, rubyicon, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1385,12 +1387,12 @@ void Y_VoteDrawer(void)
|
|||
|
||||
if ((playeringame[i] && !players[i].spectator) && votes[i] != -1)
|
||||
{
|
||||
patch_t *pic;
|
||||
|
||||
if (votes[i] >= 3 && (i != pickedvote || voteendtic == -1))
|
||||
pic = randomlvl;
|
||||
mapnum = -1; // randomlvl
|
||||
else
|
||||
pic = levelinfo[votes[i]].pic;
|
||||
mapnum = votelevels[votes[i]][0];
|
||||
|
||||
scale = M_GetMapThumbnail(mapnum, &pic)/8;
|
||||
|
||||
if (!timer && i == voteclient.ranim)
|
||||
{
|
||||
|
|
@ -1402,10 +1404,10 @@ void Y_VoteDrawer(void)
|
|||
}
|
||||
|
||||
if (!levelinfo[votes[i]].encore)
|
||||
V_DrawTinyScaledPatch(x, y, V_SNAPTOLEFT, pic);
|
||||
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOLEFT, pic, NULL);
|
||||
else
|
||||
{
|
||||
V_DrawFixedPatch((x+40)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/4, V_SNAPTOLEFT|V_FLIP, pic, 0);
|
||||
V_DrawFixedPatch((x+FixedMul(pic->width, scale))<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOLEFT|V_FLIP, pic, NULL);
|
||||
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, rubyicon, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1719,6 +1721,7 @@ void Y_VoteTicker(void)
|
|||
void Y_StartVote(void)
|
||||
{
|
||||
INT32 i = 0;
|
||||
boolean battlemode = ((votelevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); // todo gametyperules
|
||||
|
||||
votetic = -1;
|
||||
|
||||
|
|
@ -1729,14 +1732,13 @@ void Y_StartVote(void)
|
|||
|
||||
Y_AnimatedVoteScreenCheck();
|
||||
|
||||
widebgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
|
||||
bgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
|
||||
widebgpatch = W_CachePatchName((battlemode ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
|
||||
bgpatch = W_CachePatchName((battlemode ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
|
||||
cursor = W_CachePatchName("M_CURSOR", PU_STATIC);
|
||||
cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC);
|
||||
cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC);
|
||||
cursor3 = W_CachePatchName("P3CURSOR", PU_STATIC);
|
||||
cursor4 = W_CachePatchName("P4CURSOR", PU_STATIC);
|
||||
randomlvl = W_CachePatchName("RANDOMLV", PU_STATIC);
|
||||
rubyicon = W_CachePatchName("RUBYICON", PU_STATIC);
|
||||
|
||||
timer = cv_votetime.value*TICRATE;
|
||||
|
|
@ -1761,11 +1763,9 @@ void Y_StartVote(void)
|
|||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
|
||||
// set up the encore
|
||||
levelinfo[i].encore = (votelevels[i][1] & 0x80);
|
||||
votelevels[i][1] &= ~0x80;
|
||||
levelinfo[i].encore = (votelevels[i][1] & VOTEMODIFIER_ENCORE);
|
||||
votelevels[i][1] &= ~VOTEMODIFIER_ENCORE;
|
||||
|
||||
// set up the levelstring
|
||||
if (mapheaderinfo[votelevels[i][0]]->levelflags & LF_NOZONE || !mapheaderinfo[votelevels[i][0]]->zonttl[0])
|
||||
|
|
@ -1803,13 +1803,6 @@ void Y_StartVote(void)
|
|||
levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue;
|
||||
else
|
||||
levelinfo[i].gts = NULL;
|
||||
|
||||
// set up the pic
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_STATIC);
|
||||
else
|
||||
levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_STATIC);
|
||||
}
|
||||
|
||||
voteclient.loaded = true;
|
||||
|
|
@ -1833,8 +1826,6 @@ void Y_EndVote(void)
|
|||
//
|
||||
static void Y_UnloadVoteData(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
voteclient.loaded = false;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
|
|
@ -1847,30 +1838,7 @@ static void Y_UnloadVoteData(void)
|
|||
UNLOAD(cursor2);
|
||||
UNLOAD(cursor3);
|
||||
UNLOAD(cursor4);
|
||||
UNLOAD(randomlvl);
|
||||
UNLOAD(rubyicon);
|
||||
|
||||
// to prevent double frees...
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
// I went to all the trouble of doing this,
|
||||
// but literally nowhere else frees level pics.
|
||||
#if 0
|
||||
UINT8 j;
|
||||
|
||||
if (!levelinfo[i].pic)
|
||||
continue;
|
||||
|
||||
for (j = i+1; j < 4; j++)
|
||||
{
|
||||
if (levelinfo[j].pic == levelinfo[i].pic)
|
||||
levelinfo[j].pic = NULL;
|
||||
}
|
||||
UNLOAD(levelinfo[i].pic);
|
||||
#else
|
||||
CLEANUP(levelinfo[i].pic);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
20
src/z_zone.c
20
src/z_zone.c
|
|
@ -47,7 +47,6 @@
|
|||
#ifdef HAVE_VALGRIND
|
||||
#include "valgrind.h"
|
||||
static boolean Z_calloc = false;
|
||||
#include "memcheck.h"
|
||||
#endif
|
||||
|
||||
#define ZONEID 0xa441d13d
|
||||
|
|
@ -151,7 +150,7 @@ void Z_Free2(void *ptr, const char *file, INT32 line)
|
|||
if (block->user != NULL)
|
||||
*block->user = NULL;
|
||||
|
||||
#ifdef VALGRIND_DESTROY_MEMPOOL
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_DESTROY_MEMPOOL(block);
|
||||
#endif
|
||||
block->prev->next = block->next;
|
||||
|
|
@ -217,10 +216,6 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
|
|||
ptr = MEMORY(block);
|
||||
I_Assert((intptr_t)ptr % alignof (max_align_t) == 0);
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
Z_calloc = false;
|
||||
#endif
|
||||
|
||||
block->next = head.next;
|
||||
block->prev = &head;
|
||||
head.next = block;
|
||||
|
|
@ -233,8 +228,9 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
|
|||
block->size = sizeof (memblock_t) + size;
|
||||
block->realsize = size;
|
||||
|
||||
#ifdef VALGRIND_CREATE_MEMPOOL
|
||||
#ifdef HAVE_VALGRIND
|
||||
VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc);
|
||||
Z_calloc = false;
|
||||
#endif
|
||||
|
||||
block->id = ZONEID;
|
||||
|
|
@ -266,7 +262,7 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
|
|||
*/
|
||||
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line)
|
||||
{
|
||||
#ifdef VALGRIND_MEMPOOL_ALLOC
|
||||
#ifdef HAVE_VALGRIND
|
||||
Z_calloc = true;
|
||||
#endif
|
||||
return memset(Z_Malloc2 (size, tag, user, alignbits, file, line), 0, size);
|
||||
|
|
@ -435,13 +431,12 @@ void Z_CheckHeap(INT32 i)
|
|||
CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n",
|
||||
blocknumon, block->ownerfile, block->ownerline);
|
||||
#endif
|
||||
#ifdef VALGRIND_MEMPOOL_EXISTS
|
||||
if (!VALGRIND_MEMPOOL_EXISTS(block))
|
||||
#ifdef HAVE_VALGRIND
|
||||
if (RUNNING_ON_VALGRIND && !VALGRIND_MEMPOOL_EXISTS(block))
|
||||
{
|
||||
I_Error("Z_CheckHeap %d: block %u"
|
||||
"(owned by %s:%d)"
|
||||
" should not exist", i, blocknumon,
|
||||
" should not exist", i, blocknumon,
|
||||
block->ownerfile, block->ownerline
|
||||
);
|
||||
}
|
||||
|
|
@ -470,9 +465,6 @@ void Z_CheckHeap(INT32 i)
|
|||
block->ownerfile, block->ownerline
|
||||
);
|
||||
}
|
||||
#ifdef VALGRIND_MAKE_MEM_DEFINED
|
||||
VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr);
|
||||
#endif
|
||||
if (block->id != ZONEID)
|
||||
{
|
||||
I_Error("Z_CheckHeap %d: block %u"
|
||||
|
|
|
|||
Loading…
Reference in a new issue