mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-27 12:31:54 +00:00
Merge branch 'master' into projectile-sanity
This commit is contained in:
commit
928d9116da
53 changed files with 2103 additions and 3439 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -2085,42 +2085,6 @@ 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;
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
#define MINVAL 0
|
||||
#define MAXVAL 1
|
||||
if (var->PossibleValue[MINVAL].strvalue && !strcmp(var->PossibleValue[MINVAL].strvalue, "MIN"))
|
||||
|
|
|
|||
|
|
@ -933,7 +933,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -279,7 +279,6 @@ typedef struct
|
|||
tic_t time;
|
||||
tic_t leveltime;
|
||||
char servername[MAXSERVERNAME];
|
||||
char mapname[8];
|
||||
char maptitle[33];
|
||||
unsigned char mapmd5[16];
|
||||
UINT8 actnum;
|
||||
|
|
|
|||
105
src/d_main.c
105
src/d_main.c
|
|
@ -353,7 +353,7 @@ static void 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);
|
||||
}
|
||||
|
||||
F_WipeStartScreen();
|
||||
|
|
@ -939,20 +939,16 @@ void D_StartTitle(void)
|
|||
|
||||
if (netgame)
|
||||
{
|
||||
if (gametyperules & GTR_CAMPAIGN)
|
||||
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
||||
|
||||
if (server)
|
||||
{
|
||||
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
||||
i = G_GetFirstMapOfGametype(gametype)+1;
|
||||
|
||||
if (server)
|
||||
{
|
||||
char mapname[6];
|
||||
if (i > nummapheaders)
|
||||
I_Error("D_StartTitle: No valid map ID found!?");
|
||||
|
||||
strlcpy(mapname, G_BuildMapName(spstage_start), sizeof (mapname));
|
||||
strlwr(mapname);
|
||||
mapname[5] = '\0';
|
||||
|
||||
COM_BufAddText(va("map %s\n", mapname));
|
||||
}
|
||||
COM_BufAddText(va("map %s\n", G_BuildMapName(i)));
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1196,13 +1192,10 @@ D_ConvertVersionNumbers (void)
|
|||
//
|
||||
void D_SRB2Main(void)
|
||||
{
|
||||
INT32 i;
|
||||
UINT16 wadnum;
|
||||
lumpinfo_t *lumpinfo;
|
||||
char *name;
|
||||
|
||||
INT32 p;
|
||||
|
||||
INT32 numbasemapheaders;
|
||||
|
||||
INT32 pstartmap = 1;
|
||||
boolean autostart = false;
|
||||
|
||||
|
|
@ -1445,31 +1438,16 @@ void D_SRB2Main(void)
|
|||
|
||||
#endif //ifndef DEVELOP
|
||||
|
||||
//
|
||||
// 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;
|
||||
// Do it before P_InitMapData because PNG patch
|
||||
// conversion sometimes needs the palette
|
||||
V_ReloadPalette();
|
||||
|
||||
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]);
|
||||
//
|
||||
// search for mainwad maps
|
||||
//
|
||||
P_InitMapData(0);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numbasemapheaders = nummapheaders;
|
||||
|
||||
CON_SetLoadingProgress(LOADED_IWAD);
|
||||
|
||||
|
|
@ -1478,37 +1456,9 @@ void D_SRB2Main(void)
|
|||
D_CleanFile(startuppwads);
|
||||
|
||||
//
|
||||
// search for maps... again.
|
||||
// search for pwad maps
|
||||
//
|
||||
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(numbasemapheaders);
|
||||
|
||||
CON_SetLoadingProgress(LOADED_PWAD);
|
||||
|
||||
|
|
@ -1765,14 +1715,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;
|
||||
}
|
||||
|
||||
// Has to be done before anything else so skin, color, etc in command buffer has an affect.
|
||||
|
|
@ -1869,14 +1819,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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -911,9 +911,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,
|
||||
|
|
|
|||
|
|
@ -1394,7 +1394,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.
|
||||
|
|
@ -2510,8 +2510,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(G_BuildMapName(mapnum)) != LUMPERROR);
|
||||
buf_p = buf;
|
||||
if (pencoremode)
|
||||
flags |= 1;
|
||||
|
|
@ -2526,7 +2525,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)
|
||||
|
|
@ -2969,11 +2968,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;
|
||||
|
||||
|
|
@ -3010,7 +3009,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));
|
||||
|
|
@ -3018,7 +3017,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"));
|
||||
}
|
||||
|
||||
|
|
@ -3034,7 +3033,7 @@ 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);
|
||||
G_InitNew(pencoremode, mapnumber, resetplayer, skipprecutscene, FLS);
|
||||
if (demo.playback && !demo.timing)
|
||||
precache = true;
|
||||
if (demo.timing)
|
||||
|
|
@ -5255,8 +5254,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)
|
||||
|
|
@ -5276,10 +5276,15 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
votelevels[i][0] = (UINT16)READUINT16(*cp);
|
||||
votelevels[i][1] = gt;
|
||||
if (!mapheaderinfo[votelevels[i][0]])
|
||||
P_AllocMapHeader(votelevels[i][0]);
|
||||
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;
|
||||
}
|
||||
|
||||
// If third entry has an illelegal Encore flag... (illelegal!?)
|
||||
|
|
@ -5290,12 +5295,14 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
// Apply it to the second entry instead, gametype permitting!
|
||||
if (gametypedefaultrules[gt] & GTR_CIRCUIT)
|
||||
{
|
||||
votelevels[1][1] |= VOTEMODIFIER_ENCORE;
|
||||
tempvotelevels[1][1] |= VOTEMODIFIER_ENCORE;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, set third entry's gametype/Encore status.
|
||||
votelevels[2][1] = secondgt;
|
||||
tempvotelevels[2][1] = secondgt;
|
||||
|
||||
memcpy(votelevels, tempvotelevels, sizeof(votelevels));
|
||||
|
||||
G_SetGamestate(GS_VOTING);
|
||||
Y_StartVote();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "dehacked.h"
|
||||
#include "deh_lua.h"
|
||||
#include "deh_tables.h"
|
||||
#include "deh_soc.h" // freeslotusage
|
||||
|
||||
// freeslot takes a name (string only!)
|
||||
// and allocates it to the appropriate free slot.
|
||||
|
|
@ -474,18 +475,6 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
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])
|
||||
{
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("PRECIP_",word,7)) {
|
||||
p = word+7;
|
||||
for (i = 0; i < MAXPRECIP; i++)
|
||||
|
|
|
|||
451
src/deh_soc.c
451
src/deh_soc.c
|
|
@ -140,28 +140,50 @@ 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;
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// TODO: Figure out how to do undolines for this....
|
||||
|
|
@ -838,17 +860,33 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
|
|
@ -886,16 +924,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;
|
||||
}
|
||||
|
||||
|
|
@ -917,19 +954,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';
|
||||
|
|
@ -945,33 +982,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;
|
||||
|
|
@ -985,7 +1022,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!
|
||||
{
|
||||
|
|
@ -998,17 +1035,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);
|
||||
|
|
@ -1018,62 +1055,30 @@ 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 <= 99) // 0 for no act number
|
||||
mapheaderinfo[num-1]->actnum = (UINT8)i;
|
||||
mapheaderinfo[num]->actnum = (UINT8)i;
|
||||
else
|
||||
deh_warning("Level header %d: invalid act number %d", num, i);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
|
@ -1086,152 +1091,147 @@ 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; // becomes empty string
|
||||
mapheaderinfo[num]->musname[0] = 0; // becomes empty string
|
||||
else
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num-1]->musname, word2,
|
||||
sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num));
|
||||
deh_strlcpy(mapheaderinfo[num]->musname, word2,
|
||||
sizeof(mapheaderinfo[num]->musname), va("Level header %d: music", num));
|
||||
}
|
||||
}
|
||||
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, "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, "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"))
|
||||
{
|
||||
mapheaderinfo[num-1]->light_contrast = (UINT8)i;
|
||||
mapheaderinfo[num]->light_contrast = (UINT8)i;
|
||||
}
|
||||
else if (fastcmp(word, "LIGHTANGLE"))
|
||||
{
|
||||
if (fastcmp(word2, "EVEN"))
|
||||
{
|
||||
mapheaderinfo[num-1]->use_light_angle = false;
|
||||
mapheaderinfo[num-1]->light_angle = 0;
|
||||
mapheaderinfo[num]->use_light_angle = false;
|
||||
mapheaderinfo[num]->light_angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapheaderinfo[num-1]->use_light_angle = true;
|
||||
mapheaderinfo[num-1]->light_angle = FixedAngle(FloatToFixed(atof(word2)));
|
||||
mapheaderinfo[num]->use_light_angle = true;
|
||||
mapheaderinfo[num]->light_angle = FixedAngle(FloatToFixed(atof(word2)));
|
||||
}
|
||||
}
|
||||
// Individual triggers for level flags, for ease of use (and 2.0 compatibility)
|
||||
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, "GRAVITY"))
|
||||
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||
mapheaderinfo[num]->gravity = FLOAT_TO_FIXED(atof(word2));
|
||||
else
|
||||
deh_warning("Level header %d: unknown word '%s'", num, word);
|
||||
}
|
||||
|
|
@ -2103,16 +2103,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"))
|
||||
{
|
||||
|
|
@ -2333,13 +2326,7 @@ 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]);
|
||||
|
||||
// TODO: different field for level name string
|
||||
unlockables[num].variable = (INT16)i;
|
||||
}
|
||||
else
|
||||
|
|
@ -2378,7 +2365,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;
|
||||
}
|
||||
|
||||
|
|
@ -2398,7 +2385,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2418,16 +2405,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2436,16 +2418,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2458,7 +2435,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2476,7 +2453,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2488,7 +2465,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2500,13 +2477,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;
|
||||
}
|
||||
|
||||
|
|
@ -2641,61 +2618,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);
|
||||
|
|
@ -2778,16 +2700,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"))
|
||||
|
|
@ -2915,30 +2828,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);
|
||||
|
|
@ -3161,37 +3056,24 @@ 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else if (fastcmp(word, "EMERALDNUM"))
|
||||
{
|
||||
|
|
@ -3902,19 +3784,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);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,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
|
||||
|
|
|
|||
|
|
@ -32,17 +32,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)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,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[];
|
||||
|
|
|
|||
|
|
@ -358,25 +358,14 @@ 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -405,7 +405,9 @@ void DRPC_UpdatePresence(void)
|
|||
{
|
||||
char detailstr[48+1];
|
||||
|
||||
#ifdef USEMAPIMG
|
||||
char mapimg[8+1];
|
||||
#endif
|
||||
char mapname[5+21+21+2+1];
|
||||
|
||||
char charimg[4+SKINNAMESIZE+1];
|
||||
|
|
@ -508,14 +510,18 @@ void DRPC_UpdatePresence(void)
|
|||
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) // Map info
|
||||
&& !(demo.playback && demo.title))
|
||||
{
|
||||
#ifdef USEMAPIMG
|
||||
if ((gamemap >= 1 && gamemap <= 60) // supported race maps
|
||||
|| (gamemap >= 136 && gamemap <= 164)) // supported battle maps
|
||||
{
|
||||
snprintf(mapimg, 8, "%s", G_BuildMapName(gamemap));
|
||||
//FIXME
|
||||
//snprintf(mapimg, 8, "%s", G_BuildMapName(gamemap));
|
||||
strlwr(mapimg);
|
||||
discordPresence.largeImageKey = mapimg; // Map image
|
||||
}
|
||||
else if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||
else
|
||||
#endif
|
||||
if (mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU)
|
||||
{
|
||||
// Hell map, use the method that got you here :P
|
||||
discordPresence.largeImageKey = "miscdice";
|
||||
|
|
|
|||
|
|
@ -218,8 +218,6 @@ typedef struct
|
|||
|
||||
#define ZSHIFT 4
|
||||
|
||||
#define NUMMAPS 1035
|
||||
|
||||
/* slope thing types */
|
||||
enum
|
||||
{
|
||||
|
|
|
|||
259
src/doomstat.h
259
src/doomstat.h
|
|
@ -25,6 +25,9 @@
|
|||
// We need the player data structure as well.
|
||||
#include "d_player.h"
|
||||
|
||||
// For lumpnum_t.
|
||||
#include "w_wad.h"
|
||||
|
||||
// =============================
|
||||
// Selected map etc.
|
||||
// =============================
|
||||
|
|
@ -102,6 +105,23 @@ extern preciptype_t precip_freeslot;
|
|||
extern preciptype_t globalweather;
|
||||
extern preciptype_t curWeather;
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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.
|
||||
} recorddata_t;
|
||||
|
||||
// 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;
|
||||
|
|
@ -185,15 +205,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 boolean looptitle;
|
||||
|
|
@ -201,8 +217,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;
|
||||
|
||||
typedef struct
|
||||
|
|
@ -293,8 +307,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).
|
||||
extern mobj_t *redflag, *blueflag; // Pointers to physical flags
|
||||
|
|
@ -319,106 +331,113 @@ 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
|
||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||
typedef struct
|
||||
{
|
||||
char option[32]; // 31 usable characters
|
||||
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf.
|
||||
} customoption_t;
|
||||
|
||||
// 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
|
||||
|
||||
typedef struct cupheader_s
|
||||
{
|
||||
UINT16 id; ///< Cup ID
|
||||
char name[15]; ///< Cup title (14 chars)
|
||||
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.
|
||||
struct cupheader_s *next; ///< Next cup in linked list
|
||||
} cupheader_t;
|
||||
|
||||
extern cupheader_t *kartcupheaders; // Start of cup linked list
|
||||
extern UINT16 numkartcupheaders;
|
||||
|
||||
#define MAXMAPLUMPNAME 64 // includes \0, for cleaner savedata
|
||||
|
||||
/** Map header information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
// 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
|
||||
UINT8 actnum; ///< Act number or 0 for none.
|
||||
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 musname[7]; ///< Music track to play. "" 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.
|
||||
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
|
||||
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.
|
||||
void *encoreLump; ///< Lump data for the Encore Mode remap.
|
||||
void *tweakLump; ///< Lump data for the palette tweak remap.
|
||||
|
||||
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
|
||||
UINT8 actnum; ///< Act number or 0 for none.
|
||||
|
||||
// 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?
|
||||
UINT16 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.
|
||||
|
||||
UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting.
|
||||
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
|
||||
angle_t light_angle; ///< Angle of directional wall lighting.
|
||||
// Music information
|
||||
char musname[7]; ///< Music track to play. "" 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.
|
||||
|
||||
// Music stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
// 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.
|
||||
|
||||
char muspostbossname[7]; ///< Post-bossdeath music.
|
||||
UINT16 muspostbosstrack; ///< Post-bossdeath track.
|
||||
UINT32 muspostbosspos; ///< Post-bossdeath position
|
||||
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds.
|
||||
// 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
|
||||
|
||||
SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on)
|
||||
// Visual information
|
||||
UINT16 palette; ///< PAL lump to use on this map
|
||||
UINT16 encorepal; ///< PAL for encore mode
|
||||
UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting.
|
||||
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
|
||||
angle_t light_angle; ///< Angle of directional wall lighting.
|
||||
|
||||
// SRB2Kart: Keeps track of if a map lump exists, so we can tell when a map is being replaced.
|
||||
boolean alreadyExists;
|
||||
// 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.
|
||||
|
||||
// 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.
|
||||
// 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.
|
||||
} mapheader_t;
|
||||
|
||||
// level flags
|
||||
|
|
@ -432,28 +451,8 @@ typedef struct
|
|||
#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
|
||||
|
||||
typedef struct cupheader_s
|
||||
{
|
||||
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.
|
||||
struct cupheader_s *next; ///< Next cup in linked list
|
||||
} cupheader_t;
|
||||
|
||||
extern cupheader_t *kartcupheaders; // Start of cup linked list
|
||||
extern UINT16 numkartcupheaders;
|
||||
extern mapheader_t** mapheaderinfo;
|
||||
extern INT32 nummapheaders, mapallocsize;
|
||||
|
||||
// Gametypes
|
||||
#define NUMGAMETYPEFREESLOTS 128
|
||||
|
|
@ -575,52 +574,10 @@ extern INT32 luabanks[NUM_LUABANKS];
|
|||
|
||||
extern INT32 nummaprings; //keep track of spawned rings/coins
|
||||
|
||||
/** Time attack information, currently a very small structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
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.
|
||||
} recorddata_t;
|
||||
|
||||
/** 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
|
||||
|
||||
|
|
|
|||
|
|
@ -1837,6 +1837,7 @@ static void F_CacheTitleScreen(void)
|
|||
|
||||
void F_StartTitleScreen(void)
|
||||
{
|
||||
INT32 titleMapNum;
|
||||
setup_numplayers = 0;
|
||||
|
||||
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
|
||||
|
|
@ -1848,20 +1849,20 @@ 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)
|
||||
|
|
@ -2196,12 +2197,14 @@ void F_TitleScreenTicker(boolean run)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef STAFFGHOSTS
|
||||
// is it time?
|
||||
if (!(--demoIdleLeft))
|
||||
{
|
||||
//static boolean use_netreplay = false;
|
||||
|
||||
char dname[9];
|
||||
char *dname2 = dname;
|
||||
lumpnum_t l;
|
||||
const char *mapname;
|
||||
UINT8 numstaff;
|
||||
|
|
@ -2231,41 +2234,16 @@ void F_TitleScreenTicker(boolean run)
|
|||
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)
|
||||
while (numstaff < 99 && (l = W_CheckNumForLongName(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);
|
||||
dname2 = Z_StrDup(va("%sS%02u", mapname, numstaff));
|
||||
|
||||
/*if ((l = W_CheckNumForName(dname)) == LUMPERROR) -- we KNOW it exists now
|
||||
{
|
||||
|
|
@ -2278,8 +2256,14 @@ loadreplay:
|
|||
demo.title = demo.fromtitle = true;
|
||||
demo.ignorefiles = true;
|
||||
demo.loadfiles = false;
|
||||
G_DoPlayDemo(dname);
|
||||
G_DoPlayDemo(dname2);
|
||||
|
||||
if (dname2 != dname)
|
||||
{
|
||||
Z_Free(dname2);
|
||||
}
|
||||
}
|
||||
#endif //#ifdef STAFFGHOSTS
|
||||
}
|
||||
|
||||
void F_TitleDemoTicker(void)
|
||||
|
|
@ -2409,7 +2393,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();
|
||||
|
|
|
|||
22
src/g_demo.c
22
src/g_demo.c
|
|
@ -1994,7 +1994,7 @@ void G_BeginRecording(void)
|
|||
|
||||
// game data
|
||||
M_Memcpy(demo_p, "PLAY", 4); demo_p += 4;
|
||||
WRITEINT16(demo_p,gamemap);
|
||||
WRITESTRINGN(demo_p, mapheaderinfo[gamemap-1]->lumpname, MAXMAPLUMPNAME);
|
||||
M_Memcpy(demo_p, mapmd5, 16); demo_p += 16;
|
||||
|
||||
WRITEUINT8(demo_p, demoflags);
|
||||
|
|
@ -2426,7 +2426,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
|
||||
|
|
@ -2484,7 +2484,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
|
||||
|
|
@ -2703,7 +2703,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];
|
||||
|
|
@ -2824,7 +2824,8 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
demo_p += 4; // "PLAY"
|
||||
gamemap = READINT16(demo_p);
|
||||
READSTRINGN(demo_p, mapname, sizeof(mapname)); // gamemap
|
||||
gamemap = G_MapNumber(mapname)+1;
|
||||
demo_p += 16; // mapmd5
|
||||
|
||||
demoflags = READUINT8(demo_p);
|
||||
|
|
@ -2918,7 +2919,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_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);
|
||||
|
|
@ -3118,7 +3119,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++)
|
||||
{
|
||||
|
|
@ -3233,7 +3234,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);
|
||||
|
|
@ -3358,7 +3359,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;
|
||||
|
|
@ -3462,7 +3463,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);
|
||||
|
|
@ -3540,6 +3541,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"));
|
||||
|
|
|
|||
861
src/g_game.c
861
src/g_game.c
File diff suppressed because it is too large
Load diff
21
src/g_game.h
21
src/g_game.h
|
|
@ -23,7 +23,6 @@
|
|||
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];
|
||||
|
|
@ -36,6 +35,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)
|
||||
|
|
@ -81,8 +93,8 @@ extern consvar_t cv_resume;
|
|||
#define MAXPLMOVE (50)
|
||||
#define SLOWTURNTICS (6)
|
||||
|
||||
// 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);
|
||||
|
|
@ -112,7 +124,7 @@ boolean G_PlayerInputDown(UINT8 p, INT32 gc, UINT8 menuPlayers);
|
|||
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);
|
||||
|
||||
|
|
@ -150,7 +162,7 @@ void G_SpawnPlayer(INT32 playernum);
|
|||
|
||||
// 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);
|
||||
|
||||
|
|
@ -244,6 +256,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,7 @@ static char hu_tick;
|
|||
//-------------------------------------------
|
||||
|
||||
patch_t *missingpat;
|
||||
patch_t *blanklvl;
|
||||
|
||||
// song credits
|
||||
static patch_t *songcreditbg;
|
||||
|
|
@ -186,6 +187,8 @@ void HU_LoadGraphics(void)
|
|||
|
||||
Font_Load();
|
||||
|
||||
HU_UpdatePatch(&blanklvl, "BLANKLVL");
|
||||
|
||||
HU_UpdatePatch(&songcreditbg, "K_SONGCR");
|
||||
|
||||
// cache ping gfx:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "r_sky.h" // skyflatnum
|
||||
#include "k_grandprix.h" // K_CanChangeRules
|
||||
|
||||
// Battle overtime info
|
||||
struct battleovertime battleovertime;
|
||||
|
|
@ -126,7 +127,7 @@ void K_CheckBumpers(void)
|
|||
winnerscoreadd -= players[i].roundscore;
|
||||
}
|
||||
|
||||
if (bossinfo.boss)
|
||||
if (K_CanChangeRules() == false)
|
||||
{
|
||||
if (nobumpers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3320,7 +3320,6 @@ static void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32
|
|||
|
||||
static void K_drawKartMinimap(void)
|
||||
{
|
||||
INT32 lumpnum;
|
||||
patch_t *AutomapPic;
|
||||
INT32 i = 0;
|
||||
INT32 x, y;
|
||||
|
|
@ -3344,12 +3343,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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -218,6 +218,15 @@ extern menu_t PLAY_LevelSelectDef;
|
|||
extern menuitem_t PLAY_TimeAttack[];
|
||||
extern menu_t PLAY_TimeAttackDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ta_replay = 0,
|
||||
ta_guest,
|
||||
ta_ghosts,
|
||||
ta_spacer,
|
||||
ta_start,
|
||||
} ta_e;
|
||||
|
||||
extern menuitem_t PLAY_TAReplay[];
|
||||
extern menu_t PLAY_TAReplayDef;
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ menu_t PLAY_LevelSelectDef = {
|
|||
NULL
|
||||
};
|
||||
|
||||
// see ta_e
|
||||
menuitem_t PLAY_TimeAttack[] =
|
||||
{
|
||||
{IT_STRING | IT_SUBMENU, "Replay...", NULL, NULL, {.submenu = &PLAY_TAReplayDef}, 0, 0},
|
||||
|
|
|
|||
|
|
@ -1846,14 +1846,16 @@ static void M_DrawCupPreview(INT16 y, cupheader_t *cup)
|
|||
i = (cupgrid.previewanim / 82) % cup->numlevels;
|
||||
while (x < BASEVIDWIDTH + pad)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *PictureOfLevel;
|
||||
INT32 cupLevelNum = cup->cachedlevels[i];
|
||||
patch_t *PictureOfLevel = NULL;
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cup->levellist[i]+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||
{
|
||||
PictureOfLevel = mapheaderinfo[cupLevelNum]->thumbnailPic;
|
||||
}
|
||||
|
||||
if (!PictureOfLevel)
|
||||
PictureOfLevel = blanklvl;
|
||||
|
||||
V_DrawSmallScaledPatch(x + 1, y+2, 0, PictureOfLevel);
|
||||
i = (i+1) % cup->numlevels;
|
||||
|
|
@ -2073,18 +2075,19 @@ static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
|
|||
|
||||
static void M_DrawLevelSelectBlock(INT16 x, INT16 y, INT16 map, boolean redblink, boolean greyscale)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *PictureOfLevel;
|
||||
patch_t *PictureOfLevel = NULL;
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
if (greyscale)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GREY, GTC_MENUCACHE);
|
||||
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(map+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE);
|
||||
if (mapheaderinfo[map])
|
||||
{
|
||||
PictureOfLevel = mapheaderinfo[map]->thumbnailPic;
|
||||
}
|
||||
|
||||
if (!PictureOfLevel)
|
||||
PictureOfLevel = blanklvl;
|
||||
|
||||
if (redblink)
|
||||
V_DrawScaledPatch(3+x, y, 0, W_CachePatchName("LVLSEL2", PU_CACHE));
|
||||
|
|
@ -2114,10 +2117,10 @@ void M_DrawLevelSelect(void)
|
|||
{
|
||||
INT16 lvlx = t, lvly = y;
|
||||
|
||||
while (!M_CanShowLevelInList(map, levellist.newgametype) && map < NUMMAPS)
|
||||
while (!M_CanShowLevelInList(map, levellist.newgametype) && map < nummapheaders)
|
||||
map++;
|
||||
|
||||
if (map >= NUMMAPS)
|
||||
if (map >= nummapheaders)
|
||||
break;
|
||||
|
||||
if (i == levellist.cursor && tatransition)
|
||||
|
|
@ -2146,7 +2149,7 @@ void M_DrawTimeAttack(void)
|
|||
INT16 rightedge = 149+t+155;
|
||||
INT16 opty = 140;
|
||||
INT32 w;
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *minimap = NULL;
|
||||
UINT8 i;
|
||||
consvar_t *cv;
|
||||
|
||||
|
|
@ -2156,17 +2159,34 @@ void M_DrawTimeAttack(void)
|
|||
|
||||
V_DrawScaledPatch(149+t, 70, 0, W_CachePatchName("BESTTIME", PU_CACHE));
|
||||
|
||||
if (currentMenu == &PLAY_TimeAttackDef)
|
||||
if (currentMenu == &PLAY_TimeAttackDef && mapheaderinfo[map])
|
||||
{
|
||||
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(map+1)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
V_DrawScaledPatch(24-t, 82, 0, W_CachePatchNum(lumpnum, PU_CACHE));
|
||||
tic_t timerec = 0;
|
||||
tic_t laprec = 0;
|
||||
UINT32 timeheight = 82;
|
||||
|
||||
V_DrawRightAlignedString(rightedge-12, 82, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(0, 162+t, 88, 0, 2);
|
||||
if ((minimap = mapheaderinfo[map]->minimapPic))
|
||||
V_DrawScaledPatch(24-t, 82, 0, minimap);
|
||||
|
||||
V_DrawRightAlignedString(rightedge-12, 112, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(0, 162+t, 118, map, 1);
|
||||
if (mapheaderinfo[map]->mainrecord)
|
||||
{
|
||||
timerec = mapheaderinfo[map]->mainrecord->time;
|
||||
laprec = mapheaderinfo[map]->mainrecord->lap;
|
||||
}
|
||||
|
||||
if (levellist.newgametype != GT_BATTLE)
|
||||
{
|
||||
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST LAP:");
|
||||
K_drawKartTimestamp(laprec, 162+t, timeheight+6, 0, 2);
|
||||
timeheight += 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeheight += 15;
|
||||
}
|
||||
|
||||
V_DrawRightAlignedString(rightedge-12, timeheight, highlightflags, "BEST TIME:");
|
||||
K_drawKartTimestamp(timerec, 162+t, timeheight+6, map, 1);
|
||||
}
|
||||
else
|
||||
opty = 80;
|
||||
|
|
@ -3789,8 +3809,7 @@ void M_DrawPlaybackMenu(void)
|
|||
#define SCALEDVIEWHEIGHT (vid.height/vid.dupy)
|
||||
void M_DrawReplayHutReplayInfo(void)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *patch;
|
||||
patch_t *patch = NULL;
|
||||
UINT8 *colormap;
|
||||
INT32 x, y, w, h;
|
||||
|
||||
|
|
@ -3816,11 +3835,19 @@ void M_DrawReplayHutReplayInfo(void)
|
|||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
//CONS_Printf("%d %s\n", extrasmenu.demolist[dir_on[menudepthleft]].map, G_BuildMapName(extrasmenu.demolist[dir_on[menudepthleft]].map));
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(extrasmenu.demolist[dir_on[menudepthleft]].map)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
patch = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
|
||||
if (mapheaderinfo[extrasmenu.demolist[dir_on[menudepthleft]].map])
|
||||
{
|
||||
patch = mapheaderinfo[extrasmenu.demolist[dir_on[menudepthleft]].map]->thumbnailPic;
|
||||
if (!patch)
|
||||
{
|
||||
patch = blanklvl;
|
||||
}
|
||||
}
|
||||
else if (!patch)
|
||||
{
|
||||
patch = W_CachePatchName("M_NOLVL", PU_CACHE);
|
||||
}
|
||||
|
||||
if (!(extrasmenu.demolist[dir_on[menudepthleft]].kartspeed & DF_ENCORE))
|
||||
V_DrawSmallScaledPatch(x, y, V_SNAPTOTOP, patch);
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ static void Dummymenuplayer_OnChange(void)
|
|||
|
||||
static void Dummystaff_OnChange(void)
|
||||
{
|
||||
#if 0
|
||||
#ifdef STAFFGHOSTS
|
||||
lumpnum_t l;
|
||||
|
||||
dummystaffname[0] = '\0';
|
||||
|
|
@ -281,7 +281,7 @@ static void Dummystaff_OnChange(void)
|
|||
|
||||
sprintf(temp, " - %d", cv_dummystaff.value);
|
||||
}
|
||||
#endif
|
||||
#endif //#ifdef STAFFGHOSTS
|
||||
}
|
||||
|
||||
void Screenshot_option_Onchange(void)
|
||||
|
|
@ -3182,6 +3182,8 @@ void M_SetupDifficultySelect(INT32 choice)
|
|||
//
|
||||
boolean M_CanShowLevelInList(INT16 mapnum, UINT8 gt)
|
||||
{
|
||||
UINT32 tolflag = G_TOLFlag(gt);
|
||||
|
||||
// Does the map exist?
|
||||
if (!mapheaderinfo[mapnum])
|
||||
return false;
|
||||
|
|
@ -3190,48 +3192,40 @@ boolean M_CanShowLevelInList(INT16 mapnum, UINT8 gt)
|
|||
if (!mapheaderinfo[mapnum]->lvlttl[0])
|
||||
return false;
|
||||
|
||||
// Does the map have a LUMP?
|
||||
if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
|
||||
return false;
|
||||
|
||||
if (M_MapLocked(mapnum+1))
|
||||
return false; // not unlocked
|
||||
|
||||
// Check for TOL
|
||||
if (!(mapheaderinfo[mapnum]->typeoflevel & tolflag))
|
||||
return false;
|
||||
|
||||
// Should the map be hidden?
|
||||
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU /*&& mapnum+1 != gamemap*/)
|
||||
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
|
||||
return false;
|
||||
|
||||
// I don't know why, but some may have exceptions.
|
||||
if (levellist.timeattack && (mapheaderinfo[mapnum]->menuflags & LF2_NOTIMEATTACK))
|
||||
return false;
|
||||
|
||||
if (gt == GT_BATTLE && (mapheaderinfo[mapnum]->typeoflevel & TOL_BATTLE))
|
||||
return true;
|
||||
|
||||
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
|
||||
if (gametypedefaultrules[gt] & GTR_CAMPAIGN && levellist.selectedcup)
|
||||
{
|
||||
if (levellist.selectedcup && levellist.selectedcup->numlevels)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < levellist.selectedcup->numlevels; i++)
|
||||
{
|
||||
if (mapnum == levellist.selectedcup->levellist[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == levellist.selectedcup->numlevels)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (mapheaderinfo[mapnum]->cup != levellist.selectedcup)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hmm? Couldn't decide?
|
||||
return false;
|
||||
// Survived our checks.
|
||||
return true;
|
||||
}
|
||||
|
||||
INT16 M_CountLevelsToShowInList(UINT8 gt)
|
||||
{
|
||||
INT16 mapnum, count = 0;
|
||||
|
||||
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
|
||||
for (mapnum = 0; mapnum < nummapheaders; mapnum++)
|
||||
if (M_CanShowLevelInList(mapnum, gt))
|
||||
count++;
|
||||
|
||||
|
|
@ -3242,7 +3236,7 @@ INT16 M_GetFirstLevelInList(UINT8 gt)
|
|||
{
|
||||
INT16 mapnum;
|
||||
|
||||
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
|
||||
for (mapnum = 0; mapnum < nummapheaders; mapnum++)
|
||||
if (M_CanShowLevelInList(mapnum, gt))
|
||||
return mapnum;
|
||||
|
||||
|
|
@ -3410,7 +3404,9 @@ void M_CupSelectHandler(INT32 choice)
|
|||
{
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
if ((!newcup) || (newcup && newcup->unlockrequired != -1 && !unlockables[newcup->unlockrequired].unlocked))
|
||||
if ((!newcup)
|
||||
|| (newcup && newcup->unlockrequired != -1 && !unlockables[newcup->unlockrequired].unlocked)
|
||||
|| (newcup->cachedlevels[0] == NEXTMAP_INVALID))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kb2);
|
||||
return;
|
||||
|
|
@ -3418,7 +3414,7 @@ void M_CupSelectHandler(INT32 choice)
|
|||
|
||||
if (cupgrid.grandprix == true)
|
||||
{
|
||||
|
||||
INT32 levelNum;
|
||||
UINT8 ssplayers = cv_splitplayers.value-1;
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
|
@ -3462,8 +3458,10 @@ void M_CupSelectHandler(INT32 choice)
|
|||
netgame = levellist.netgame; // ^ ditto.
|
||||
}
|
||||
|
||||
levelNum = grandprixinfo.cup->cachedlevels[0];
|
||||
|
||||
D_MapChange(
|
||||
grandprixinfo.cup->levellist[0] + 1,
|
||||
levelNum + 1,
|
||||
GT_RACE,
|
||||
grandprixinfo.encore,
|
||||
true,
|
||||
|
|
@ -3549,16 +3547,16 @@ void M_LevelSelectHandler(INT32 choice)
|
|||
{
|
||||
map++;
|
||||
|
||||
while (!M_CanShowLevelInList(map, levellist.newgametype) && map < NUMMAPS)
|
||||
while (!M_CanShowLevelInList(map, levellist.newgametype) && map < nummapheaders)
|
||||
map++;
|
||||
|
||||
if (map >= NUMMAPS)
|
||||
if (map >= nummapheaders)
|
||||
break;
|
||||
|
||||
add--;
|
||||
}
|
||||
|
||||
if (map >= NUMMAPS)
|
||||
if (map >= nummapheaders)
|
||||
{
|
||||
// This shouldn't happen
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "k_hud.h"
|
||||
#include "d_netcmd.h" // IsPlayerAdmin
|
||||
#include "k_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
|
||||
|
||||
|
|
@ -378,23 +377,6 @@ static int lib_pGetEffectiveFollowerColor(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// M_MISC
|
||||
//////////////
|
||||
|
||||
static int lib_mMapNumber(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;
|
||||
}
|
||||
|
||||
// M_RANDOM
|
||||
//////////////
|
||||
|
||||
|
|
@ -2499,9 +2481,8 @@ static int lib_sStopSoundByID(lua_State *L)
|
|||
|
||||
static int lib_sChangeMusic(lua_State *L)
|
||||
{
|
||||
UINT32 position, prefadems, fadeinms;
|
||||
|
||||
const char *music_name = luaL_checkstring(L, 1);
|
||||
UINT32 position, prefadems, fadeinms;
|
||||
boolean looping = (boolean)lua_opttrueboolean(L, 2);
|
||||
player_t *player = NULL;
|
||||
UINT16 music_flags = 0;
|
||||
|
|
@ -3065,12 +3046,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);
|
||||
|
|
@ -3838,9 +3819,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},
|
||||
|
|
|
|||
|
|
@ -574,6 +574,7 @@ static int libd_drawStretched(lua_State *L)
|
|||
}
|
||||
|
||||
// KART: draw patch on minimap from x, y coordinates on the map
|
||||
// Sal: Let's please just merge the relevant info into the actual function, and have Lua call that...
|
||||
static int libd_drawOnMinimap(lua_State *L)
|
||||
{
|
||||
fixed_t x, y, scale; // coordinates of the object
|
||||
|
|
@ -583,7 +584,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;
|
||||
|
|
@ -669,12 +669,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);
|
||||
|
|
|
|||
|
|
@ -2085,8 +2085,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);
|
||||
|
|
@ -2104,7 +2104,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;
|
||||
}
|
||||
|
||||
|
|
@ -2116,7 +2116,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"))
|
||||
|
|
@ -2127,10 +2126,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(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"))
|
||||
|
|
@ -2139,22 +2134,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
lua_pushinteger(L, header->mustrack);
|
||||
else if (fastcmp(field,"muspos"))
|
||||
lua_pushinteger(L, header->muspos);
|
||||
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"))
|
||||
|
|
@ -2165,12 +2144,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);
|
||||
|
|
@ -2178,8 +2152,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"))
|
||||
|
|
@ -2188,31 +2160,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!)
|
||||
|
|
|
|||
|
|
@ -211,35 +211,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);
|
||||
|
|
|
|||
57
src/m_cond.c
57
src/m_cond.c
|
|
@ -81,7 +81,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;
|
||||
|
|
@ -129,11 +132,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
|
||||
|
|
@ -298,10 +309,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)
|
||||
|
|
@ -331,17 +349,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)
|
||||
|
|
@ -407,7 +432,8 @@ UINT8 M_MapLocked(INT32 mapnum)
|
|||
if (1)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!mapnum || mapnum > nummapheaders)
|
||||
return false;
|
||||
if (!mapheaderinfo[mapnum-1] || mapheaderinfo[mapnum-1]->unlockrequired < 0)
|
||||
return false;
|
||||
if (!unlockables[mapheaderinfo[mapnum-1]->unlockrequired].unlocked)
|
||||
|
|
@ -458,14 +484,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;
|
||||
|
|
@ -492,7 +518,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;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ typedef struct
|
|||
{
|
||||
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)
|
||||
|
|
|
|||
28
src/m_misc.c
28
src/m_misc.c
|
|
@ -226,32 +226,6 @@ void M_AddToJoinedIPs(char *address, char *servname)
|
|||
strcpy(joinedIPlist[0][1], servname);
|
||||
}
|
||||
|
||||
/** 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
|
||||
// ==========================================================================
|
||||
|
|
@ -956,9 +930,11 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
|
|||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (gamestate == GS_LEVEL)
|
||||
snprintf(maptext, 8, "%s", G_BuildMapName(gamemap));
|
||||
else
|
||||
#endif
|
||||
snprintf(maptext, 8, "Unknown");
|
||||
|
||||
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@ void M_AddToJoinedIPs(char *address, char *servname);
|
|||
void M_SaveJoinedIPs(void);
|
||||
void M_LoadJoinedIPs(void);
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -3460,28 +3460,6 @@ void A_BossDeath(mobj_t *mo)
|
|||
EV_DoElevator(&junk, elevateUp, false);
|
||||
Tag_FSet(&junk.tags, LE_CAPSULE2);
|
||||
EV_DoElevator(&junk, elevateHighest, false);
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->muspostbossname[0] &&
|
||||
S_MusicExists(mapheaderinfo[gamemap-1]->muspostbossname))
|
||||
{
|
||||
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
|
||||
// So just park ourselves in the mapmus variables.
|
||||
// But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES).
|
||||
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7);
|
||||
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
|
||||
{
|
||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
|
||||
mapmusname[6] = 0;
|
||||
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
|
||||
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
|
||||
}
|
||||
|
||||
// don't change if we're in another tune
|
||||
// but in case we're in jingle, use our parked mapmus variables so the correct track restores
|
||||
if (!changed)
|
||||
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, (1*MUSICRATE)+(MUSICRATE/2),
|
||||
mapheaderinfo[gamemap-1]->muspostbossfadein);
|
||||
}
|
||||
}
|
||||
|
||||
bossjustdie:
|
||||
|
|
|
|||
|
|
@ -11069,7 +11069,7 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
else if (p->bot)
|
||||
{
|
||||
/*
|
||||
if (bonusgame || specialstage)
|
||||
if (bonusgame || specialstage || boss)
|
||||
{
|
||||
// Bots should avoid
|
||||
p->spectator = true;
|
||||
|
|
|
|||
|
|
@ -4427,8 +4427,8 @@ static inline void P_UnArchiveSPGame(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;
|
||||
|
|
@ -4482,7 +4482,6 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
WRITEUINT8(save_p, encoremode);
|
||||
|
||||
WRITEUINT32(save_p, leveltime);
|
||||
WRITEUINT32(save_p, ssspheres);
|
||||
WRITEINT16(save_p, lastmap);
|
||||
WRITEUINT16(save_p, bossdisabled);
|
||||
|
||||
|
|
@ -4508,7 +4507,6 @@ static void P_NetArchiveMisc(boolean resending)
|
|||
}
|
||||
|
||||
WRITEUINT32(save_p, token);
|
||||
WRITEINT32(save_p, sstimer);
|
||||
WRITEUINT32(save_p, bluescore);
|
||||
WRITEUINT32(save_p, redscore);
|
||||
|
||||
|
|
@ -4537,9 +4535,6 @@ static void P_NetArchiveMisc(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);
|
||||
|
|
@ -4614,8 +4609,8 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
|
||||
// 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
|
||||
|
|
@ -4649,7 +4644,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
|
||||
// get the time
|
||||
leveltime = READUINT32(save_p);
|
||||
ssspheres = READUINT32(save_p);
|
||||
lastmap = READINT16(save_p);
|
||||
bossdisabled = READUINT16(save_p);
|
||||
|
||||
|
|
@ -4672,7 +4666,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
}
|
||||
|
||||
token = READUINT32(save_p);
|
||||
sstimer = READINT32(save_p);
|
||||
bluescore = READUINT32(save_p);
|
||||
redscore = READUINT32(save_p);
|
||||
|
||||
|
|
@ -4701,9 +4694,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
|||
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);
|
||||
|
|
@ -4880,7 +4870,7 @@ boolean P_LoadGame(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;
|
||||
|
|
|
|||
496
src/p_setup.c
496
src/p_setup.c
|
|
@ -134,6 +134,8 @@ boolean stoppedclock;
|
|||
boolean levelloading;
|
||||
UINT8 levelfadecol;
|
||||
|
||||
virtres_t *curmapvirt;
|
||||
|
||||
// BLOCKMAP
|
||||
// Created from axis aligned bounding box
|
||||
// of the map, a rectangular array of
|
||||
|
|
@ -312,11 +314,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];
|
||||
|
||||
sprintf(mapnum, "%hd", gamemap);
|
||||
if (gamemap > 0 && gamemap <= nummapheaders && mapheaderinfo[gamemap-1])
|
||||
{
|
||||
sprintf(mapname, "%s", mapheaderinfo[gamemap-1]->lumpname);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(mapname, "ID %d", gamemap-1);
|
||||
}
|
||||
|
||||
CON_LogMessage("Map ");
|
||||
CON_LogMessage(mapnum);
|
||||
CON_LogMessage(mapname);
|
||||
CON_LogMessage(" is corrupt: ");
|
||||
CON_LogMessage(msg);
|
||||
CON_LogMessage("\n");
|
||||
|
|
@ -357,59 +367,34 @@ void P_DeleteFlickies(INT16 i)
|
|||
* \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;
|
||||
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]->keywords[0] = '\0';
|
||||
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
|
||||
sprintf(mapheaderinfo[num]->musname, "%.5sM", G_BuildMapName(num+1));
|
||||
mapheaderinfo[num]->musname[6] = 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]->weather = PRECIP_NONE;
|
||||
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
||||
mapheaderinfo[num]->skytexture[4] = 0;
|
||||
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;
|
||||
|
|
@ -422,10 +407,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;
|
||||
|
|
@ -437,110 +422,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);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -736,69 +664,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_BATTLECAPSULE].doomednum)
|
||||
{
|
||||
maptargets++;
|
||||
}
|
||||
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 void P_SpawnMapThings(boolean spawnemblems)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -847,6 +712,7 @@ static void P_SpawnMapThings(boolean spawnemblems)
|
|||
// Experimental groovy write function!
|
||||
void P_WriteThings(void)
|
||||
{
|
||||
const char * filename;
|
||||
size_t i, length;
|
||||
mapthing_t *mt;
|
||||
UINT8 *savebuffer, *savebuf_p;
|
||||
|
|
@ -875,11 +741,13 @@ void P_WriteThings(void)
|
|||
|
||||
length = savebuf_p - savebuffer;
|
||||
|
||||
FIL_WriteFile(va("newthings%d.lmp", gamemap), savebuffer, length);
|
||||
filename = va("newthings-%s.lmp", G_BuildMapName(gamemap));
|
||||
|
||||
FIL_WriteFile(filename, savebuffer, length);
|
||||
free(savebuffer);
|
||||
savebuf_p = NULL;
|
||||
|
||||
CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap);
|
||||
CONS_Printf(M_GetText("%s saved.\n"), filename);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3560,15 +3428,14 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest)
|
|||
|
||||
static boolean P_LoadMapFromFile(void)
|
||||
{
|
||||
virtres_t *virt = vres_GetMap(lastloadedmaplumpnum);
|
||||
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
|
||||
virtlump_t *textmap = vres_Find(curmapvirt, "TEXTMAP");
|
||||
size_t i;
|
||||
udmf = textmap != NULL;
|
||||
|
||||
if (!P_LoadMapData(virt))
|
||||
if (!P_LoadMapData(curmapvirt))
|
||||
return false;
|
||||
P_LoadMapBSP(virt);
|
||||
P_LoadMapLUT(virt);
|
||||
P_LoadMapBSP(curmapvirt);
|
||||
P_LoadMapLUT(curmapvirt);
|
||||
|
||||
P_LinkMapData();
|
||||
|
||||
|
|
@ -3593,9 +3460,9 @@ static boolean P_LoadMapFromFile(void)
|
|||
if (sectors[i].tags.count)
|
||||
spawnsectors[i].tags.tags = memcpy(Z_Malloc(sectors[i].tags.count*sizeof(mtag_t), PU_LEVEL, NULL), sectors[i].tags.tags, sectors[i].tags.count*sizeof(mtag_t));
|
||||
|
||||
P_MakeMapMD5(virt, &mapmd5);
|
||||
P_MakeMapMD5(curmapvirt, &mapmd5);
|
||||
|
||||
vres_Free(virt);
|
||||
vres_Free(curmapvirt);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3659,15 +3526,6 @@ static void P_InitLevelSettings(void)
|
|||
// 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;
|
||||
|
||||
// clear ctf pointers
|
||||
redflag = blueflag = NULL;
|
||||
rflagpoint = bflagpoint = NULL;
|
||||
|
|
@ -3675,7 +3533,7 @@ static void P_InitLevelSettings(void)
|
|||
// circuit, race and competition stuff
|
||||
circuitmap = false;
|
||||
numstarposts = 0;
|
||||
ssspheres = timeinmap = 0;
|
||||
timeinmap = 0;
|
||||
|
||||
// special stage
|
||||
stagefailed = true; // assume failed unless proven otherwise - P_GiveEmerald or emerald touchspecial
|
||||
|
|
@ -3819,43 +3677,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;
|
||||
|
|
@ -3939,17 +3760,20 @@ static void P_LoadRecordGhosts(void)
|
|||
if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath)))
|
||||
G_AddGhost(va("%s-guest.lmp", gpath));
|
||||
|
||||
#ifdef STAFFGHOSTS
|
||||
// Staff Attack ghosts
|
||||
if (cv_ghost_staff.value)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
#endif //#ifdef STAFFGHOSTS
|
||||
|
||||
free(gpath);
|
||||
}
|
||||
|
|
@ -4096,6 +3920,7 @@ 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;
|
||||
|
||||
levelloading = true;
|
||||
|
||||
|
|
@ -4133,9 +3958,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;
|
||||
|
|
@ -4317,13 +4139,33 @@ 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);
|
||||
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette,
|
||||
W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T'))));
|
||||
curmapvirt = vres_GetMap(lastloadedmaplumpnum);
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
if (encoremode)
|
||||
{
|
||||
encoreLump = vres_Find(curmapvirt, "ENCORE");
|
||||
}
|
||||
else
|
||||
{
|
||||
encoreLump = vres_Find(curmapvirt, "TWEAKMAP");
|
||||
}
|
||||
}
|
||||
|
||||
if (encoreLump)
|
||||
{
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, encoreLump->data, encoreLump->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, NULL, 0);
|
||||
}
|
||||
CON_SetupBackColormap();
|
||||
|
||||
// SRB2 determines the sky texture to be used depending on the map header.
|
||||
|
|
@ -4424,9 +4266,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
skipstats = 0;
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -4613,6 +4455,118 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
|
|||
return lumpinfo;
|
||||
}
|
||||
|
||||
// Initialising map data (and catching replacements)...
|
||||
UINT8 P_InitMapData(INT32 numexistingmapheaders)
|
||||
{
|
||||
UINT8 ret = 0;
|
||||
INT32 i;
|
||||
lumpnum_t maplump;
|
||||
virtres_t *virtmap;
|
||||
virtlump_t *minimap, *thumbnailPic;
|
||||
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 (!numexistingmapheaders)
|
||||
{
|
||||
I_Error("P_InitMapData: Base map %s has a header but no level\n", name);
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
// No change?
|
||||
if (mapheaderinfo[i]->lumpnum == maplump)
|
||||
continue;
|
||||
|
||||
// Okay, it does...
|
||||
{
|
||||
ret |= MAPRET_ADDED;
|
||||
CONS_Printf("%s\n", name);
|
||||
|
||||
if (numexistingmapheaders && 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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
if (minimap)
|
||||
{
|
||||
mapheaderinfo[i]->minimapPic = vres_GetPatch(minimap, PU_STATIC);
|
||||
}
|
||||
|
||||
vres_Free(virtmap);
|
||||
|
||||
// Now associate it with a cup cache.
|
||||
// (The core assumption is that cups < headers.)
|
||||
if (i >= numexistingmapheaders)
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
INT32 j;
|
||||
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 || j == CUPCACHE_SPECIAL)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT16 p_adding_file = INT16_MAX;
|
||||
|
||||
//
|
||||
|
|
@ -4622,13 +4576,13 @@ UINT16 p_adding_file = INT16_MAX;
|
|||
boolean P_AddWadFile(const char *wadfilename)
|
||||
{
|
||||
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
INT32 numexistingmapheaders = nummapheaders;
|
||||
UINT16 numlumps, wadnum;
|
||||
char *name;
|
||||
lumpinfo_t *lumpinfo;
|
||||
|
||||
//boolean texturechange = false; ///\todo Useless; broken when back-frontporting PK3 changes?
|
||||
boolean mapsadded = false;
|
||||
boolean replacedcurrentmap = false;
|
||||
UINT8 mapsadded = 0;
|
||||
|
||||
// Vars to help us with the position start and amount of each resource type.
|
||||
// Useful for PK3s since they use folders.
|
||||
|
|
@ -4778,36 +4732,8 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
//
|
||||
// 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]);
|
||||
mapsadded = P_InitMapData(numexistingmapheaders);
|
||||
|
||||
// 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 you replaced the map you're on, end the level when done.
|
||||
if (num == gamemap)
|
||||
replacedcurrentmap = true;
|
||||
|
||||
CONS_Printf("%s\n", name);
|
||||
mapsadded = true;
|
||||
}
|
||||
}
|
||||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
|
|
@ -4825,7 +4751,7 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
if (cursaveslot > 0)
|
||||
cursaveslot = 0;
|
||||
|
||||
if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer))
|
||||
if ((mapsadded & MAPRET_CURRENTREPLACED) && gamestate == GS_LEVEL && (netgame || multiplayer))
|
||||
{
|
||||
CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap);
|
||||
if (server)
|
||||
|
|
|
|||
|
|
@ -99,15 +99,17 @@ extern mapthing_t *mapthings;
|
|||
extern UINT16 p_adding_file;
|
||||
|
||||
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);
|
||||
#ifdef HWRENDER
|
||||
void HWR_LoadLevel(void);
|
||||
#endif
|
||||
boolean P_AddWadFile(const char *wadfilename);
|
||||
|
||||
#define MAPRET_ADDED (1)
|
||||
#define MAPRET_CURRENTREPLACED (1<<1)
|
||||
UINT8 P_InitMapData(INT32 numexistingmapheaders);
|
||||
|
||||
boolean P_RunSOC(const char *socfilename);
|
||||
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);
|
||||
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num);
|
||||
|
|
@ -123,10 +125,5 @@ 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);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
13
src/p_spec.c
13
src/p_spec.c
|
|
@ -2522,6 +2522,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
break;
|
||||
|
||||
case 415: // Run a script
|
||||
// FIXME: cursed
|
||||
CONS_Alert(CONS_WARNING, "Linedef special 415 is currently broken! Fix it later, BYE.\n");
|
||||
#if 0
|
||||
if (cv_runscripts.value)
|
||||
{
|
||||
INT32 scrnum;
|
||||
|
|
@ -2556,6 +2559,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
else
|
||||
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 416: // Spawn adjustable fire flicker
|
||||
|
|
@ -5927,10 +5931,6 @@ void P_InitSpecials(void)
|
|||
maplighting.directional = mapheaderinfo[gamemap-1]->use_light_angle;
|
||||
maplighting.angle = mapheaderinfo[gamemap-1]->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
|
||||
|
|
@ -6022,11 +6022,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!
|
||||
gravity = sector->floorheight/1000;
|
||||
break;
|
||||
|
|
|
|||
24
src/p_user.c
24
src/p_user.c
|
|
@ -300,11 +300,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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -2144,9 +2148,6 @@ void P_MovePlayer(player_t *player)
|
|||
|
||||
fixed_t runspd;
|
||||
|
||||
if (countdowntimeup)
|
||||
return;
|
||||
|
||||
cmd = &player->cmd;
|
||||
runspd = 14*player->mo->scale; //srb2kart
|
||||
|
||||
|
|
@ -4288,14 +4289,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ void R_InitColormaps(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
|
||||
void R_ReInitColormaps(UINT16 num, void *newencoremap, size_t encoremapsize)
|
||||
{
|
||||
char colormap[9] = "COLORMAP";
|
||||
lumpnum_t lump;
|
||||
|
|
@ -309,13 +309,13 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
|
|||
W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U);
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
void R_ClearColormaps(void);
|
||||
extracolormap_t *R_CreateDefaultColormap(boolean lighttable);
|
||||
extracolormap_t *R_GetDefaultColormap(void);
|
||||
|
|
|
|||
|
|
@ -698,6 +698,7 @@ typedef struct
|
|||
} patch_t;
|
||||
|
||||
extern patch_t *missingpat;
|
||||
extern patch_t *blanklvl;
|
||||
|
||||
#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);
|
||||
|
|
|
|||
|
|
@ -191,12 +191,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
|
||||
|
|
|
|||
|
|
@ -386,7 +386,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
|
|||
if (channels[cnum].sfxinfo == &S_sfx[sfx_id] && channels[cnum].origin == origin)
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +406,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
|
|||
if (channels[cnum].sfxinfo == &S_sfx[sfxnum])
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -763,7 +761,6 @@ void S_StopSound(void *origin)
|
|||
if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2394,6 +2391,7 @@ void S_StartEx(boolean reset)
|
|||
music_stack_fadein = JINGLEPOSTFADE;
|
||||
}
|
||||
|
||||
// TODO: fix this function, needs better support for map names
|
||||
static void Command_Tunes_f(void)
|
||||
{
|
||||
const char *tunearg;
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ const char *GetPalette(void)
|
|||
return "PLAYPAL";
|
||||
}
|
||||
|
||||
static void LoadMapPalette(void)
|
||||
void V_ReloadPalette(void)
|
||||
{
|
||||
LoadPalette(GetPalette());
|
||||
}
|
||||
|
|
@ -416,7 +416,7 @@ static void LoadMapPalette(void)
|
|||
void V_SetPalette(INT32 palettenum)
|
||||
{
|
||||
if (!pLocalPalette)
|
||||
LoadMapPalette();
|
||||
V_ReloadPalette();
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
|
|
@ -449,7 +449,7 @@ void V_SetPaletteLump(const char *pal)
|
|||
static void CV_palette_OnChange(void)
|
||||
{
|
||||
// reload palette
|
||||
LoadMapPalette();
|
||||
V_ReloadPalette();
|
||||
V_SetPalette(0);
|
||||
}
|
||||
|
||||
|
|
@ -2980,8 +2980,6 @@ void V_Init(void)
|
|||
UINT8 *base = vid.buffer;
|
||||
const INT32 screensize = vid.rowbytes * vid.height;
|
||||
|
||||
LoadMapPalette();
|
||||
|
||||
for (i = 0; i < NUMSCREENS; i++)
|
||||
screens[i] = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors);
|
|||
UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
|
||||
UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
|
||||
|
||||
// Loads the correct palette into memory
|
||||
void V_ReloadPalette(void);
|
||||
|
||||
// Set the current RGB palette lookup to use for palettized graphics
|
||||
void V_SetPalette(INT32 palettenum);
|
||||
|
||||
|
|
|
|||
299
src/w_wad.c
299
src/w_wad.c
|
|
@ -64,10 +64,6 @@
|
|||
#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 "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];
|
||||
char lumpname[LUMPNUMCACHENAME];
|
||||
UINT32 lumphash;
|
||||
lumpnum_t lumpnum;
|
||||
} lumpnum_cache_t;
|
||||
|
||||
|
|
@ -273,22 +271,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
|
||||
}
|
||||
|
||||
/** Compute MD5 message digest for bytes read from STREAM of this filname.
|
||||
|
|
@ -975,6 +957,53 @@ 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, UINT16 wad, UINT16 startlump)
|
||||
{
|
||||
UINT16 i, end;
|
||||
|
||||
if (wadfiles[wad]->type == RET_WAD)
|
||||
{
|
||||
for (i = startlump; i < wadfiles[wad]->numlumps; i++)
|
||||
{
|
||||
// Not the name?
|
||||
if (strcasecmp(name, (wadfiles[wad]->lumpinfo + i)->name))
|
||||
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 name?
|
||||
if (strcasecmp(name, (wadfiles[wad]->lumpinfo + i)->longname))
|
||||
continue;
|
||||
|
||||
// Not a .wad?
|
||||
if (!W_IsLumpWad(i | (wad << 16)))
|
||||
continue;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return INT16_MAX;
|
||||
}
|
||||
|
||||
//
|
||||
// Same as the original, but checks in one pwad only.
|
||||
// wadid is a wad number
|
||||
|
|
@ -1114,8 +1143,12 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
|
|||
//
|
||||
lumpnum_t W_CheckNumForName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
lumpnum_t check = INT16_MAX;
|
||||
UINT32 hash = quickncasehash(name, 8);
|
||||
INT32 i;
|
||||
|
||||
if (name == NULL)
|
||||
return LUMPERROR;
|
||||
|
||||
if (!*name) // some doofus gave us an empty string?
|
||||
return LUMPERROR;
|
||||
|
|
@ -1125,6 +1158,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);
|
||||
|
|
@ -1140,14 +1174,18 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
break; //found it
|
||||
}
|
||||
|
||||
if (check == INT16_MAX) return LUMPERROR;
|
||||
if (check == INT16_MAX)
|
||||
{
|
||||
return LUMPERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update the cache.
|
||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', LUMPNUMCACHENAME);
|
||||
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
|
||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
|
||||
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
|
||||
lumpnumcache[lumpnumcacheindex].lumphash = hash;
|
||||
|
||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||
}
|
||||
|
|
@ -1161,8 +1199,12 @@ lumpnum_t W_CheckNumForName(const char *name)
|
|||
//
|
||||
lumpnum_t W_CheckNumForLongName(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
lumpnum_t check = INT16_MAX;
|
||||
UINT32 hash = quickncasehash(name, LUMPNUMCACHENAME);
|
||||
INT32 i;
|
||||
|
||||
if (name == NULL)
|
||||
return LUMPERROR;
|
||||
|
||||
if (!*name) // some doofus gave us an empty string?
|
||||
return LUMPERROR;
|
||||
|
|
@ -1171,7 +1213,8 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
// most recent entries first
|
||||
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
|
||||
{
|
||||
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||
if (lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumphash == hash
|
||||
&& strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
|
||||
{
|
||||
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
|
||||
return lumpnumcache[lumpnumcacheindex].lumpnum;
|
||||
|
|
@ -1186,16 +1229,20 @@ lumpnum_t W_CheckNumForLongName(const char *name)
|
|||
break; //found it
|
||||
}
|
||||
|
||||
if (check == INT16_MAX) return LUMPERROR;
|
||||
if (check == INT16_MAX)
|
||||
{
|
||||
return LUMPERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(name) < 32)
|
||||
if (strlen(name) < LUMPNUMCACHENAME)
|
||||
{
|
||||
// Update the cache.
|
||||
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
|
||||
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
|
||||
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
|
||||
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;
|
||||
|
|
@ -1204,45 +1251,50 @@ 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 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;
|
||||
|
||||
for (i = numwadfiles - 1; i >= 0; i--)
|
||||
{
|
||||
check = W_CheckNumForMapPwad(name, (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;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1714,6 +1766,27 @@ 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)
|
||||
{
|
||||
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
|
||||
|
||||
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;
|
||||
|
|
@ -1726,21 +1799,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
|
||||
|
||||
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
|
||||
Patch_Create(ptr, len, dest);
|
||||
|
||||
Z_Free(ptr);
|
||||
MakePatch(lumpdata, len, tag, &lumpcache[lump]);
|
||||
Z_Free(lumpdata);
|
||||
}
|
||||
else
|
||||
Z_ChangeTag(lumpcache[lump], tag);
|
||||
|
|
@ -2206,32 +2271,56 @@ 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;
|
||||
for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; 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);
|
||||
|
|
@ -2257,7 +2346,12 @@ virtres_t* vres_GetMap(lumpnum_t lumpnum)
|
|||
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);
|
||||
}
|
||||
|
|
@ -2288,3 +2382,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);
|
||||
|
||||
#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 @@ typedef struct {
|
|||
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 tag);
|
||||
|
||||
// =========================================================================
|
||||
// DYNAMIC WAD LOADING
|
||||
|
|
@ -154,6 +155,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, 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ typedef struct
|
|||
char str[62];
|
||||
UINT8 gtc;
|
||||
const char *gts;
|
||||
patch_t *pic;
|
||||
boolean encore;
|
||||
} y_votelvlinfo;
|
||||
|
||||
|
|
@ -834,8 +833,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)
|
||||
{
|
||||
|
|
@ -1011,7 +1010,18 @@ void Y_VoteDrawer(void)
|
|||
else
|
||||
{
|
||||
str = levelinfo[i].str;
|
||||
pic = levelinfo[i].pic;
|
||||
|
||||
pic = NULL;
|
||||
|
||||
if (mapheaderinfo[votelevels[i][0]])
|
||||
{
|
||||
pic = mapheaderinfo[votelevels[i][0]]->thumbnailPic;
|
||||
}
|
||||
|
||||
if (!pic)
|
||||
{
|
||||
pic = blanklvl;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected[i])
|
||||
|
|
@ -1131,9 +1141,23 @@ void Y_VoteDrawer(void)
|
|||
patch_t *pic;
|
||||
|
||||
if (votes[i] >= 3 && (i != pickedvote || voteendtic == -1))
|
||||
{
|
||||
pic = randomlvl;
|
||||
}
|
||||
else
|
||||
pic = levelinfo[votes[i]].pic;
|
||||
{
|
||||
pic = NULL;
|
||||
|
||||
if (mapheaderinfo[votelevels[votes[i]][0]])
|
||||
{
|
||||
pic = mapheaderinfo[votelevels[votes[i]][0]]->thumbnailPic;
|
||||
}
|
||||
|
||||
if (!pic)
|
||||
{
|
||||
pic = blanklvl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!timer && i == voteclient.ranim)
|
||||
{
|
||||
|
|
@ -1492,8 +1516,6 @@ void Y_StartVote(void)
|
|||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
|
||||
// set up the encore
|
||||
levelinfo[i].encore = (votelevels[i][1] & VOTEMODIFIER_ENCORE);
|
||||
votelevels[i][1] &= ~VOTEMODIFIER_ENCORE;
|
||||
|
|
@ -1534,13 +1556,6 @@ void Y_StartVote(void)
|
|||
levelinfo[i].gts = Gametype_Names[votelevels[i][1]];
|
||||
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;
|
||||
|
|
@ -1561,8 +1576,6 @@ void Y_EndVote(void)
|
|||
//
|
||||
static void Y_UnloadVoteData(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
voteclient.loaded = false;
|
||||
|
||||
if (rendermode != render_soft)
|
||||
|
|
@ -1577,28 +1590,6 @@ static void Y_UnloadVoteData(void)
|
|||
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
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue