mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-05 09:46:40 +00:00
Rework nextmap to be automatic
- Refactor significantly (now has its own func, `G_GetNextMap`)
- If gametype uses cups, iterate through cups to find the current level, then grab the next valid level
- If not, get the next valid mapheader for your gametype
- SOC `nextmap`/`marathonnext` is not just deprecated but REMOVED
- Hide the NEXTMAP_ constants again, but leave support dummied out for if we have them publically accessible again
- Also get rid of a bunch of OTHER mapheader stuff we're never gonna use
- NiGHTS Grades? NOPE
- Vanilla titlecard patches? NOPE
- Boss music fadeout/replacement? NOPE
- Select Heading? NOPE
- You've been blocked.
- Don't show maps without lumps on the level select list
- this is me being petty, but making it NOTIMEATTACK in SOC instead of TIMEATTACK so we can reconsider the maps with/without them.
This commit is contained in:
parent
b68710faf2
commit
7d990c4f15
15 changed files with 250 additions and 472 deletions
16
src/d_main.c
16
src/d_main.c
|
|
@ -939,14 +939,16 @@ void D_StartTitle(void)
|
|||
|
||||
if (netgame)
|
||||
{
|
||||
if (gametyperules & GTR_CAMPAIGN)
|
||||
{
|
||||
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
||||
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
||||
|
||||
if (server)
|
||||
{
|
||||
COM_BufAddText(va("map %s\n", G_BuildMapName(spstage_start)));
|
||||
}
|
||||
if (server)
|
||||
{
|
||||
INT16 mapnum = G_GetFirstMapOfGametype(gametype)+1;
|
||||
|
||||
if (i > nummapheaders)
|
||||
I_Error("D_StartTitle: No valid map ID found!?");
|
||||
|
||||
COM_BufAddText(va("map %s\n", G_BuildMapName(mapnum)));
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -475,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++)
|
||||
|
|
|
|||
|
|
@ -157,12 +157,9 @@ void clear_levels(void)
|
|||
Z_Free(mapheaderinfo[nummapheaders]->customopts);
|
||||
|
||||
P_DeleteFlickies(nummapheaders);
|
||||
P_DeleteGrades(nummapheaders);
|
||||
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->thumbnailPic);
|
||||
Patch_Free(mapheaderinfo[nummapheaders]->minimapPic);
|
||||
Z_Free(mapheaderinfo[nummapheaders]->nextlevel);
|
||||
Z_Free(mapheaderinfo[nummapheaders]->marathonnext);
|
||||
|
||||
Z_Free(mapheaderinfo[nummapheaders]->lumpname);
|
||||
|
||||
|
|
@ -1155,7 +1152,6 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
{
|
||||
deh_strlcpy(mapheaderinfo[num]->lvlttl, word2,
|
||||
sizeof(mapheaderinfo[num]->lvlttl), va("Level header %d: levelname", num));
|
||||
strlcpy(mapheaderinfo[num]->selectheading, word2, sizeof(mapheaderinfo[num]->selectheading)); // not deh_ so only complains once
|
||||
continue;
|
||||
}
|
||||
// CHEAP HACK: move this over here for lowercase subtitles
|
||||
|
|
@ -1283,14 +1279,6 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
}
|
||||
|
||||
// Strings that can be truncated
|
||||
else if (fastcmp(word, "NEXTLEVEL"))
|
||||
{
|
||||
mapheaderinfo[num]->nextlevel = Z_StrDup(word2);
|
||||
}
|
||||
else if (fastcmp(word, "MARATHONNEXT"))
|
||||
{
|
||||
mapheaderinfo[num]->marathonnext = Z_StrDup(word2);
|
||||
}
|
||||
else if (fastcmp(word, "ZONETITLE"))
|
||||
{
|
||||
deh_strlcpy(mapheaderinfo[num]->zonttl, word2,
|
||||
|
|
@ -1459,12 +1447,12 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
else
|
||||
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]->menuflags &= ~LF2_NOTIMEATTACK;
|
||||
else
|
||||
mapheaderinfo[num]->menuflags |= LF2_NOTIMEATTACK;
|
||||
else
|
||||
mapheaderinfo[num]->menuflags &= ~LF2_NOTIMEATTACK;
|
||||
}
|
||||
else if (fastcmp(word, "VISITNEEDED"))
|
||||
{
|
||||
|
|
@ -4060,19 +4048,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);
|
||||
|
|
|
|||
|
|
@ -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[];
|
||||
|
|
|
|||
|
|
@ -322,12 +322,6 @@ extern struct quake
|
|||
fixed_t radius, intensity;
|
||||
} quake;
|
||||
|
||||
// NiGHTS grades
|
||||
typedef struct
|
||||
{
|
||||
UINT32 grade[6]; // D, C, B, A, S, X (F: failed to reach any of these)
|
||||
} nightsgrades_t;
|
||||
|
||||
// Custom Lua values
|
||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||
typedef struct
|
||||
|
|
@ -355,9 +349,6 @@ typedef struct
|
|||
|
||||
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
|
||||
|
||||
char * nextlevel; ///< Map name of next level.
|
||||
char * marathonnext; ///< See nextlevel, but for Marathon mode.
|
||||
|
||||
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
|
||||
|
||||
char musname[7]; ///< Music track to play. "" for no music.
|
||||
|
|
@ -391,46 +382,22 @@ typedef struct
|
|||
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.)
|
||||
|
||||
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below
|
||||
UINT16 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
||||
|
||||
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.
|
||||
|
||||
// Title card.
|
||||
char ltzzpatch[8]; ///< Zig zag patch.
|
||||
char ltzztext[8]; ///< Zig zag text.
|
||||
char ltactdiamond[8]; ///< Act diamond.
|
||||
|
||||
// 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.
|
||||
|
||||
// NiGHTS stuff.
|
||||
UINT8 numGradedMares; ///< Internal. For grade support.
|
||||
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
|
||||
|
||||
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 stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
|
||||
char muspostbossname[7]; ///< Post-bossdeath music.
|
||||
UINT16 muspostbosstrack; ///< Post-bossdeath track.
|
||||
UINT32 muspostbosspos; ///< Post-bossdeath position
|
||||
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds.
|
||||
|
||||
SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on)
|
||||
|
||||
// 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
|
||||
|
|
@ -606,26 +573,6 @@ typedef struct
|
|||
//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];
|
||||
|
||||
|
|
|
|||
|
|
@ -2416,7 +2416,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();
|
||||
|
|
|
|||
389
src/g_game.c
389
src/g_game.c
|
|
@ -663,7 +663,9 @@ const char *G_BuildMapName(INT32 map)
|
|||
*/
|
||||
INT32 G_MapNumber(const char * name)
|
||||
{
|
||||
#ifdef NEXTMAPINSOC
|
||||
if (strncasecmp("NEXTMAP_", name, 8) != 0)
|
||||
#endif
|
||||
{
|
||||
INT32 map;
|
||||
|
||||
|
|
@ -678,6 +680,7 @@ INT32 G_MapNumber(const char * name)
|
|||
return map;
|
||||
}
|
||||
|
||||
#ifdef NEXTMAPINSOC
|
||||
name += 8;
|
||||
|
||||
if (strcasecmp("EVALUATION", name) == 0)
|
||||
|
|
@ -688,6 +691,7 @@ INT32 G_MapNumber(const char * name)
|
|||
return NEXTMAP_CEREMONY;
|
||||
//if (strcasecmp("TITLE", name) == 0)
|
||||
return NEXTMAP_TITLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Clips the console player's mouse aiming to the current view.
|
||||
|
|
@ -2994,7 +2998,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] =
|
|||
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||
{
|
||||
// Race
|
||||
GTR_CIRCUIT|GTR_BOTS,
|
||||
GTR_CAMPAIGN|GTR_CIRCUIT|GTR_BOTS,
|
||||
// Battle
|
||||
GTR_SPHERES|GTR_BUMPERS|GTR_PAPERITEMS|GTR_KARMA|GTR_ITEMARROWS|GTR_CAPSULES|GTR_BATTLESTARTS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME
|
||||
};
|
||||
|
|
@ -3378,20 +3382,54 @@ UINT32 G_TOLFlag(INT32 pgametype)
|
|||
return gametypetol[pgametype];
|
||||
}
|
||||
|
||||
static INT32 TOLMaps(UINT32 tolflags)
|
||||
INT16 G_GetFirstMapOfGametype(UINT8 pgametype)
|
||||
{
|
||||
INT16 mapnum = nummapheaders;
|
||||
|
||||
if ((gametypedefaultrules[pgametype] & GTR_CAMPAIGN) && kartcupheaders)
|
||||
{
|
||||
mapnum = G_MapNumber(kartcupheaders->levellist[0]);
|
||||
}
|
||||
|
||||
if (mapnum >= nummapheaders)
|
||||
{
|
||||
UINT32 tolflag = G_TOLFlag(pgametype);
|
||||
for (mapnum = 0; mapnum < nummapheaders; mapnum++)
|
||||
{
|
||||
if (!mapheaderinfo[mapnum])
|
||||
continue;
|
||||
if (mapheaderinfo[mapnum]->lumpnum == LUMPERROR)
|
||||
continue;
|
||||
if (!(mapheaderinfo[mapnum]->typeoflevel & tolflag))
|
||||
continue;
|
||||
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mapnum;
|
||||
}
|
||||
|
||||
static INT32 TOLMaps(UINT8 pgametype)
|
||||
{
|
||||
INT32 num = 0;
|
||||
INT32 i;
|
||||
|
||||
// Find all the maps that are ok and and put them in an array.
|
||||
UINT32 tolflag = G_TOLFlag(pgametype);
|
||||
|
||||
// Find all the maps that are ok
|
||||
for (i = 0; i < nummapheaders; i++)
|
||||
{
|
||||
if (!mapheaderinfo[i])
|
||||
continue;
|
||||
if (mapheaderinfo[i]->lumpnum == LUMPERROR)
|
||||
continue;
|
||||
if (!(mapheaderinfo[i]->typeoflevel & tolflag))
|
||||
continue;
|
||||
if (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU) // Don't include Map Hell
|
||||
continue;
|
||||
if ((mapheaderinfo[i]->typeoflevel & tolflags) == tolflags)
|
||||
num++;
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
|
|
@ -3546,7 +3584,7 @@ tryagain:
|
|||
void G_AddMapToBuffer(INT16 map)
|
||||
{
|
||||
INT16 bufx;
|
||||
INT16 refreshnum = (TOLMaps(G_TOLFlag(gametype)))-3;
|
||||
INT16 refreshnum = (TOLMaps(gametype))-3;
|
||||
|
||||
if (refreshnum < 0)
|
||||
refreshnum = 3;
|
||||
|
|
@ -3612,7 +3650,7 @@ static boolean CanSaveLevel(INT32 mapnum)
|
|||
static void G_HandleSaveLevel(void)
|
||||
{
|
||||
// do this before running the intermission or custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c
|
||||
if (nextmap >= 1100-1)
|
||||
if (nextmap >= NEXTMAP_SPECIAL)
|
||||
{
|
||||
if (!gamecomplete)
|
||||
gamecomplete = 2; // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission
|
||||
|
|
@ -3635,6 +3673,167 @@ static void G_HandleSaveLevel(void)
|
|||
G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages
|
||||
}
|
||||
|
||||
static void G_GetNextMap(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
// go to next level
|
||||
// nextmap is 0-based, unlike gamemap
|
||||
if (nextmapoverride != 0)
|
||||
{
|
||||
nextmap = (INT16)(nextmapoverride-1);
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
if (grandprixinfo.roundnum == 0 || grandprixinfo.cup == NULL) // Single session
|
||||
{
|
||||
nextmap = prevmap; // Same map
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map
|
||||
{
|
||||
nextmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proceed to next map
|
||||
const INT32 cupLevelNum = G_MapNumber(grandprixinfo.cup->levellist[grandprixinfo.roundnum]);
|
||||
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||
{
|
||||
nextmap = cupLevelNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextmap = prevmap; // Prevent uninitialised use
|
||||
}
|
||||
|
||||
grandprixinfo.roundnum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bossinfo.boss == true)
|
||||
{
|
||||
nextmap = NEXTMAP_TITLE; // temporary
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 tolflag = G_TOLFlag(gametype);
|
||||
|
||||
if (gametyperules & GTR_CAMPAIGN)
|
||||
{
|
||||
register INT16 cm;
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
UINT8 gettingresult = 0;
|
||||
|
||||
// While this can't produce an infinite loop IN THE ITERATION, it
|
||||
// is technically possible for you to keep cycling inside a lousy
|
||||
// cul-de-sac of the same maps over and over while marathonning
|
||||
// them all, if the same map is present in the cup list multiple
|
||||
// times. There is no good solution. Don't dupe maps between cups!
|
||||
while (cup)
|
||||
{
|
||||
for (i = 0; i < cup->numlevels; i++)
|
||||
{
|
||||
cm = G_MapNumber(cup->levellist[i]);
|
||||
|
||||
// Not valid?
|
||||
if (cm >= nummapheaders
|
||||
|| !mapheaderinfo[cm]
|
||||
|| mapheaderinfo[cm]->lumpnum == LUMPERROR
|
||||
|| !(mapheaderinfo[cm]->typeoflevel & tolflag))
|
||||
continue;
|
||||
|
||||
// Grab the first valid after the map you're on
|
||||
if (gettingresult)
|
||||
{
|
||||
nextmap = cm;
|
||||
gettingresult = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Not the map you're on?
|
||||
if (cm != prevmap)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ok, this is the current map, time to get the next
|
||||
gettingresult = 1;
|
||||
}
|
||||
|
||||
// We have a good nextmap?
|
||||
if (gettingresult == 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Ok, iterate to the next
|
||||
cup = cup->next;
|
||||
}
|
||||
|
||||
// Didn't get a nextmap before reaching the end?
|
||||
if (gettingresult != 2)
|
||||
{
|
||||
if (marathonmode)
|
||||
{
|
||||
nextmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
else
|
||||
{
|
||||
nextmap = NEXTMAP_TITLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i = prevmap;
|
||||
if (++i >= nummapheaders)
|
||||
i = 0;
|
||||
|
||||
while (i != prevmap)
|
||||
{
|
||||
if (!mapheaderinfo[i]
|
||||
|| mapheaderinfo[i]->lumpnum == LUMPERROR
|
||||
|| !(mapheaderinfo[i]->typeoflevel & tolflag)
|
||||
|| (mapheaderinfo[i]->menuflags & LF2_HIDEINMENU))
|
||||
{
|
||||
if (++i >= nummapheaders)
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
nextmap = i;
|
||||
}
|
||||
|
||||
if (!marathonmode)
|
||||
{
|
||||
if (cv_advancemap.value == 0) // Stay on same map.
|
||||
{
|
||||
nextmap = prevmap;
|
||||
}
|
||||
else if (cv_advancemap.value == 2) // Go to random map.
|
||||
{
|
||||
nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, false, NULL);
|
||||
}
|
||||
else if (nextmap >= NEXTMAP_SPECIAL) // Loop back around
|
||||
{
|
||||
nextmap = G_GetFirstMapOfGametype(gametype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We are committed to this map now.
|
||||
// We may as well allocate its header if it doesn't exist
|
||||
// (That is, if it's a real map)
|
||||
if (nextmap < NEXTMAP_SPECIAL && (nextmap >= nummapheaders || !mapheaderinfo[nextmap] || mapheaderinfo[nextmap]->lumpnum == LUMPERROR))
|
||||
I_Error("G_GetNextMap: Internal map ID %d not found (nummapheaders = %d)\n", nextmap, nummapheaders);
|
||||
}
|
||||
|
||||
//
|
||||
// G_DoCompleted
|
||||
//
|
||||
|
|
@ -3696,154 +3895,17 @@ static void G_DoCompleted(void)
|
|||
|
||||
prevmap = (INT16)(gamemap-1);
|
||||
|
||||
if (demo.playback) goto demointermission;
|
||||
|
||||
// go to next level
|
||||
// nextmap is 0-based, unlike gamemap
|
||||
if (nextmapoverride != 0)
|
||||
if (!demo.playback)
|
||||
{
|
||||
nextmap = (INT16)(nextmapoverride-1);
|
||||
G_GetNextMap();
|
||||
|
||||
// Remember last map for when you come out of the special stage.
|
||||
if (!spec)
|
||||
lastmap = nextmap;
|
||||
|
||||
// Set up power level gametype scrambles
|
||||
K_SetPowerLevelScrambles(powertype);
|
||||
}
|
||||
else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext)
|
||||
{
|
||||
const INT32 mNextNum = G_MapNumber(mapheaderinfo[gamemap-1]->marathonnext);
|
||||
|
||||
if (mapheaderinfo[mNextNum])
|
||||
{
|
||||
nextmap = (INT16)mNextNum;
|
||||
}
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
if (grandprixinfo.roundnum == 0 || grandprixinfo.cup == NULL) // Single session
|
||||
{
|
||||
nextmap = prevmap; // Same map
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map
|
||||
{
|
||||
nextmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proceed to next map
|
||||
const INT32 cupLevelNum = G_MapNumber(grandprixinfo.cup->levellist[grandprixinfo.roundnum]);
|
||||
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||
{
|
||||
nextmap = cupLevelNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextmap = prevmap; // Prevent uninitialised use
|
||||
}
|
||||
|
||||
grandprixinfo.roundnum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const INT32 nextNum = G_MapNumber(mapheaderinfo[gamemap-1]->nextlevel);
|
||||
|
||||
if (mapheaderinfo[nextNum])
|
||||
{
|
||||
nextmap = (INT16)nextNum;
|
||||
if (marathonmode && nextmap == spmarathon_start-1)
|
||||
nextmap = NEXTMAP_TITLE; // No infinite loop for you
|
||||
}
|
||||
}
|
||||
|
||||
// Remember last map for when you come out of the special stage.
|
||||
if (!spec)
|
||||
lastmap = nextmap;
|
||||
|
||||
// If nextmap is actually going to get used, make sure it points to
|
||||
// a map of the proper gametype -- skip levels that don't support
|
||||
// the current gametype. (Helps avoid playing boss levels in Race,
|
||||
// for instance).
|
||||
if (K_CanChangeRules())
|
||||
{
|
||||
if (cv_advancemap.value == 0) // Stay on same map.
|
||||
{
|
||||
nextmap = prevmap;
|
||||
}
|
||||
else if (cv_advancemap.value == 2) // Go to random map.
|
||||
{
|
||||
nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, false, NULL);
|
||||
}
|
||||
else if (nextmap < NEXTMAP_SPECIAL)
|
||||
{
|
||||
register INT16 cm = nextmap;
|
||||
UINT32 tolflag = G_TOLFlag(gametype);
|
||||
UINT8* visitedmap;
|
||||
|
||||
visitedmap = Z_Calloc(((nummapheaders+7)/8)*sizeof(UINT8), PU_STATIC, NULL);
|
||||
|
||||
while (!mapheaderinfo[cm] || mapheaderinfo[cm]->lumpnum == LUMPERROR || !(mapheaderinfo[cm]->typeoflevel & tolflag))
|
||||
{
|
||||
visitedmap[cm/8] |= (1<<(cm&7));
|
||||
if (!mapheaderinfo[cm])
|
||||
cm = -1; // guarantee error execution
|
||||
else if (marathonmode && mapheaderinfo[cm]->marathonnext)
|
||||
{
|
||||
cm = G_MapNumber(mapheaderinfo[cm]->marathonnext);
|
||||
}
|
||||
else
|
||||
{
|
||||
cm = G_MapNumber(mapheaderinfo[cm]->nextlevel);
|
||||
}
|
||||
|
||||
if (cm >= nummapheaders) // out of range (either NEXTMAP_SPECIAL or error)
|
||||
{
|
||||
cm = nextmap; //Start the loop again so that the error checking below is executed.
|
||||
|
||||
//Make sure the map actually exists before you try to go to it!
|
||||
if (cm >= nummapheaders || mapheaderinfo[cm]->lumpnum == LUMPERROR)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("Next map given (ID %d) doesn't exist! Reverting to id 0.\n"), cm+1);
|
||||
cm = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (visitedmap[cm/8] & (1<<(cm&7))) // smells familiar
|
||||
{
|
||||
// We got stuck in a loop, came back to the map we started on
|
||||
// without finding one supporting the current gametype.
|
||||
// Thus, print a warning, and just use this map anyways.
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Can't find a compatible map after ID %d; using ID %d anyway\n"), prevmap, cm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Z_Free(visitedmap);
|
||||
nextmap = cm;
|
||||
}
|
||||
// wrap around
|
||||
else if (!(gametyperules & GTR_CAMPAIGN))
|
||||
nextmap = (INT16)(spstage_start-1);
|
||||
|
||||
if (cv_advancemap.value == 0) // Stay on same map.
|
||||
{
|
||||
nextmap = prevmap;
|
||||
}
|
||||
else if (cv_advancemap.value == 2) // Go to random map.
|
||||
{
|
||||
nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// We are committed to this map now.
|
||||
// We may as well allocate its header if it doesn't exist
|
||||
// (That is, if it's a real map)
|
||||
if (nextmap < NEXTMAP_SPECIAL && (nextmap >= nummapheaders || !mapheaderinfo[nextmap] || mapheaderinfo[nextmap]->lumpnum == LUMPERROR))
|
||||
I_Error("G_DoCompleted: Internal map ID %d not found (nummapheaders = %d)\n", nextmap, nummapheaders);
|
||||
|
||||
// Set up power level gametype scrambles
|
||||
K_SetPowerLevelScrambles(powertype);
|
||||
|
||||
demointermission:
|
||||
|
||||
// If the current gametype has no intermission screen set, then don't start it.
|
||||
Y_DetermineIntermissionType();
|
||||
|
|
@ -3866,17 +3928,10 @@ demointermission:
|
|||
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
|
||||
void G_AfterIntermission(void)
|
||||
{
|
||||
if (modeattacking)
|
||||
{
|
||||
M_EndModeAttackRun();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gamecomplete == 2) // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission
|
||||
gamecomplete = 1;
|
||||
|
||||
HU_ClearCEcho();
|
||||
//G_NextLevel();
|
||||
|
||||
if (demo.playback)
|
||||
{
|
||||
|
|
@ -3900,8 +3955,8 @@ void G_AfterIntermission(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((gametyperules & GTR_CAMPAIGN) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1 && (gamecomplete || !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene.
|
||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
||||
if ((gametyperules & GTR_CAMPAIGN) && mapheaderinfo[prevmap]->cutscenenum && !modeattacking && skipstats <= 1 && (gamecomplete || !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene.
|
||||
F_StartCustomCutscene(mapheaderinfo[prevmap]->cutscenenum-1, false, false);
|
||||
else
|
||||
{
|
||||
if (nextmap < NEXTMAP_SPECIAL)
|
||||
|
|
@ -4045,12 +4100,12 @@ void G_EndGame(void)
|
|||
if (demo.recording && (modeattacking || demo.savemode != DSM_NOTSAVING))
|
||||
G_SaveDemo();
|
||||
|
||||
// Only do evaluation and credits in coop games.
|
||||
if (gametyperules & GTR_CAMPAIGN)
|
||||
// Only do evaluation and credits in singleplayer contexts
|
||||
if (!netgame && (gametyperules & GTR_CAMPAIGN))
|
||||
{
|
||||
if (nextmap == NEXTMAP_CEREMONY) // end game with ending
|
||||
if (nextmap == NEXTMAP_CEREMONY) // end game with ceremony
|
||||
{
|
||||
F_StartEnding();
|
||||
D_StartTitle(); //F_StartEnding(); -- temporary
|
||||
return;
|
||||
}
|
||||
if (nextmap == NEXTMAP_CREDITS) // end game with credits
|
||||
|
|
@ -4065,7 +4120,7 @@ void G_EndGame(void)
|
|||
}
|
||||
}
|
||||
|
||||
// 1100 or competitive multiplayer, so go back to title screen.
|
||||
// direct or competitive multiplayer, so go back to title screen.
|
||||
D_StartTitle();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,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);
|
||||
|
|
|
|||
|
|
@ -3178,6 +3178,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;
|
||||
|
|
@ -3186,21 +3188,26 @@ 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)
|
||||
{
|
||||
if (levellist.selectedcup && levellist.selectedcup->numlevels)
|
||||
{
|
||||
|
|
@ -3217,12 +3224,10 @@ boolean M_CanShowLevelInList(INT16 mapnum, UINT8 gt)
|
|||
if (i == levellist.selectedcup->numlevels)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Hmm? Couldn't decide?
|
||||
return false;
|
||||
// Survived our checks.
|
||||
return true;
|
||||
}
|
||||
|
||||
INT16 M_CountLevelsToShowInList(UINT8 gt)
|
||||
|
|
|
|||
|
|
@ -2127,10 +2127,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_pushstring(L, header->nextlevel);
|
||||
else if (fastcmp(field,"marathonnext"))
|
||||
lua_pushstring(L, header->marathonnext);
|
||||
else if (fastcmp(field,"keywords"))
|
||||
lua_pushstring(L, header->keywords);
|
||||
else if (fastcmp(field,"musname"))
|
||||
|
|
@ -2139,20 +2135,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"))
|
||||
|
|
@ -2188,16 +2170,6 @@ 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"))
|
||||
|
|
@ -2212,7 +2184,6 @@ static int mapheaderinfo_get(lua_State *L)
|
|||
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!)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
120
src/p_setup.c
120
src/p_setup.c
|
|
@ -363,19 +363,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
{
|
||||
const INT16 num = (INT16)(i-1);
|
||||
|
||||
Z_Free(mapheaderinfo[num]->nextlevel);
|
||||
mapheaderinfo[num]->nextlevel = NULL;
|
||||
|
||||
Z_Free(mapheaderinfo[num]->marathonnext);
|
||||
mapheaderinfo[num]->marathonnext = NULL;
|
||||
|
||||
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]->startrings = 0;
|
||||
|
|
@ -387,13 +377,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
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");
|
||||
|
|
@ -412,8 +395,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
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;
|
||||
|
|
@ -426,7 +407,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
#else // equivalent to "FlickyList = NONE"
|
||||
P_DeleteFlickies(num);
|
||||
#endif
|
||||
P_DeleteGrades(num);
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
|
|
@ -445,112 +425,12 @@ void P_AllocMapHeader(INT16 i)
|
|||
mapheaderinfo[i]->lumpname = NULL;
|
||||
mapheaderinfo[i]->thumbnailPic = NULL;
|
||||
mapheaderinfo[i]->minimapPic = NULL;
|
||||
mapheaderinfo[i]->nextlevel = NULL;
|
||||
mapheaderinfo[i]->marathonnext = NULL;
|
||||
mapheaderinfo[i]->flickies = NULL;
|
||||
mapheaderinfo[i]->grades = NULL;
|
||||
nummapheaders++;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
for (g = 0; g < 6; ++g)
|
||||
{
|
||||
// Allow "partial" grading systems
|
||||
if (spos != NULL)
|
||||
{
|
||||
mapheaderinfo[i]->grades[mare].grade[g] = atoi(spos);
|
||||
CONS_Debug(DBG_SETUP, "%u ", atoi(spos));
|
||||
// Grab next comma
|
||||
spos = strchr(spos, ',');
|
||||
if (spos)
|
||||
++spos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grade not reachable
|
||||
mapheaderinfo[i]->grades[mare].grade[g] = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
INT32 pgrade = 0;
|
||||
for (i = 0; i < 6; ++i)
|
||||
{
|
||||
if (pscore >= mapheaderinfo[map-1]->grades[mare].grade[i])
|
||||
++pgrade;
|
||||
}
|
||||
return (UINT8)pgrade;
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
||||
//
|
||||
// levelflats
|
||||
//
|
||||
|
|
|
|||
|
|
@ -125,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
|
||||
|
|
|
|||
|
|
@ -4265,14 +4265,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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue