Merge branch 'conclusions' into 'master'

Conclusions

See merge request KartKrew/Kart!1300
This commit is contained in:
Oni 2023-06-28 00:51:45 +00:00
commit 93e3b2aca0
28 changed files with 531 additions and 848 deletions

View file

@ -464,22 +464,12 @@ static void D_Display(void)
}
break;
case GS_ENDING:
F_EndingDrawer();
HU_Erase();
HU_Drawer();
break;
case GS_CUTSCENE:
F_CutsceneDrawer();
HU_Erase();
HU_Drawer();
break;
case GS_GAMEEND:
F_GameEndDrawer();
break;
case GS_EVALUATION:
F_GameEvaluationDrawer();
HU_Erase();
@ -980,7 +970,6 @@ void D_ClearState(void)
SplitScreen_OnChange();
cht_debug = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
// In case someone exits out at the same time they start a time attack run,

View file

@ -6300,7 +6300,6 @@ void Command_ExitGame_f(void)
SplitScreen_OnChange();
cht_debug = 0;
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
if (dirmenu)

View file

@ -2583,6 +2583,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
}
}
else if ((offset=0) || fastcmp(params[0], "ADDON")
|| (++offset && fastcmp(params[0], "CREDITS"))
|| (++offset && fastcmp(params[0], "REPLAY"))
|| (++offset && fastcmp(params[0], "CRASH")))
{
@ -3120,13 +3121,13 @@ void readmaincfg(MYFILE *f, boolean mainfile)
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "USEBLACKROCK"))
else if (fastcmp(word, "USESEAL"))
{
useBlackRock = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
useSeal = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "LOOPTITLE"))
{
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
looptitle = (value != 0 || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
else if (fastcmp(word, "TITLEMAP"))
@ -3137,7 +3138,7 @@ void readmaincfg(MYFILE *f, boolean mainfile)
}
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE"))
{
hidetitlepics = (boolean)(value || word2[0] == 'T' || word2[0] == 'Y');
hidetitlepics = (boolean)(value != 0 || word2[0] == 'T' || word2[0] == 'Y');
titlechanged = true;
}
else if (fastcmp(word, "TITLEPICSMODE"))
@ -3365,14 +3366,6 @@ void readwipes(MYFILE *f)
else if (fastcmp(pword, "FINAL"))
wipeoffset = wipe_evaluation_final;
}
else if (fastncmp(word, "GAMEEND_", 8))
{
pword = word + 8;
if (fastcmp(pword, "TOBLACK"))
wipeoffset = wipe_gameend_toblack;
else if (fastcmp(pword, "FINAL"))
wipeoffset = wipe_gameend_final;
}
else if (fastncmp(word, "CEREMONY_", 9))
{
pword = word + 9;
@ -3438,6 +3431,15 @@ static void invalidateacrosscups(UINT16 map)
mapheaderinfo[map]->cup = NULL;
}
static char *MapNameOrRemoval(char *name)
{
if (name[0] == '\0'
|| (name[0] == '/' && name[1] == '\0'))
return NULL;
return Z_StrDup(name);
}
void readcupheader(MYFILE *f, cupheader_t *cup)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -3539,8 +3541,12 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
break;
}
cup->levellist[CUPCACHE_BONUS + cup->numbonus] = Z_StrDup(tmp);
cup->levellist[CUPCACHE_BONUS + cup->numbonus] = MapNameOrRemoval(tmp);
cup->cachedlevels[CUPCACHE_BONUS + cup->numbonus] = NEXTMAP_INVALID;
if (cup->levellist[CUPCACHE_BONUS + cup->numbonus] == NULL)
break;
cup->numbonus++;
} while((tmp = strtok(NULL,",")) != NULL);
}
@ -3548,9 +3554,16 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
{
invalidateacrosscups(cup->cachedlevels[CUPCACHE_SPECIAL]);
Z_Free(cup->levellist[CUPCACHE_SPECIAL]);
cup->levellist[CUPCACHE_SPECIAL] = Z_StrDup(word2);
cup->levellist[CUPCACHE_SPECIAL] = MapNameOrRemoval(word2);
cup->cachedlevels[CUPCACHE_SPECIAL] = NEXTMAP_INVALID;
}
else if (fastcmp(word, "ALTPODIUM"))
{
invalidateacrosscups(cup->cachedlevels[CUPCACHE_PODIUM]);
Z_Free(cup->levellist[CUPCACHE_PODIUM]);
cup->levellist[CUPCACHE_PODIUM] = MapNameOrRemoval(word2);
cup->cachedlevels[CUPCACHE_PODIUM] = NEXTMAP_INVALID;
}
else if (fastcmp(word, "EMERALDNUM"))
{
if (i >= 0 && i <= 14)
@ -3558,6 +3571,10 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
else
deh_warning("%s Cup: invalid emerald number %d", cup->name, i);
}
else if (fastcmp(word, "PLAYCREDITS"))
{
cup->playcredits = (i != 0 || word2[0] == 'T' || word2[0] == 'Y');
}
else
deh_warning("%s Cup: unknown word '%s'", cup->name, word);
}

View file

@ -6851,9 +6851,7 @@ struct int_const_s const INT_CONST[] = {
{"GS_MENU",GS_MENU},
{"GS_CREDITS",GS_CREDITS},
{"GS_EVALUATION",GS_EVALUATION},
{"GS_GAMEEND",GS_GAMEEND},
{"GS_INTRO",GS_INTRO},
{"GS_ENDING",GS_ENDING},
{"GS_CUTSCENE",GS_CUTSCENE},
{"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER},
{"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS},

View file

@ -383,7 +383,8 @@ struct customoption_t
#define CUPCACHE_BONUS MAXLEVELLIST
#define MAXBONUSLIST 2
#define CUPCACHE_SPECIAL (CUPCACHE_BONUS+MAXBONUSLIST)
#define CUPCACHE_MAX (CUPCACHE_SPECIAL+1)
#define CUPCACHE_PODIUM (CUPCACHE_SPECIAL+1)
#define CUPCACHE_MAX (CUPCACHE_PODIUM+1)
#define MAXCUPNAME 16 // includes \0, for cleaner savedata
@ -401,6 +402,9 @@ struct cupheader_t
UINT8 numlevels; ///< Number of levels defined in levellist
UINT8 numbonus; ///< Number of bonus stages defined
UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald)
boolean playcredits; ///< Play the credits?
cupwindata_t windata[4]; ///< Data for cup visitation
cupheader_t *next; ///< Next cup in linked list
};
@ -687,8 +691,6 @@ typedef enum
EMERALD_ALL = EMERALD_ALLCHAOS|EMERALD_ALLSUPER
} emeraldflags_t;
extern UINT16 emeralds;
#define ALLCHAOSEMERALDS(v) ((v & EMERALD_ALLCHAOS) == EMERALD_ALLCHAOS)
#define ALLSUPEREMERALDS(v) ((v & EMERALD_ALLSUPER) == EMERALD_ALLSUPER)
#define ALLEMERALDS(v) ((v & EMERALD_ALL) == EMERALD_ALL)
@ -744,7 +746,7 @@ extern INT32 flameseg;
extern UINT8 introtoplay;
extern UINT8 creditscutscene;
extern UINT8 useBlackRock;
extern UINT8 useSeal;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,6 @@ boolean F_CutsceneResponder(event_t *ev);
boolean F_CreditResponder(event_t *ev);
// Called by main loop.
void F_GameEndTicker(void);
void F_IntroTicker(void);
void F_TitleScreenTicker(boolean run);
void F_CutsceneTicker(void);
@ -41,7 +40,6 @@ void F_TitleDemoTicker(void);
void F_TextPromptTicker(void);
// Called by main loop.
void F_GameEndDrawer(void);
void F_IntroDrawer(void);
void F_TitleScreenDrawer(void);
void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname);
@ -54,9 +52,6 @@ void F_GameEvaluationDrawer(void);
void F_StartGameEvaluation(void);
void F_GameEvaluationTicker(void);
void F_EndingTicker(void);
void F_EndingDrawer(void);
void F_CreditTicker(void);
void F_CreditDrawer(void);
@ -173,10 +168,8 @@ enum
wipe_menu_toblack,
wipe_credits_toblack,
wipe_evaluation_toblack,
wipe_gameend_toblack,
wipe_ceremony_toblack,
wipe_intro_toblack,
wipe_ending_toblack,
wipe_cutscene_toblack,
// Specialized wipes
@ -192,10 +185,8 @@ enum
wipe_menu_final,
wipe_credits_final,
wipe_evaluation_final,
wipe_gameend_final,
wipe_ceremony_final,
wipe_intro_final,
wipe_ending_final,
wipe_cutscene_final,
// custom intermissions

View file

@ -63,10 +63,8 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
1, // wipe_menu_toblack
99, // wipe_credits_toblack
0, // wipe_evaluation_toblack
0, // wipe_gameend_toblack
0, // wipe_ceremony_toblack
UINT8_MAX, // wipe_intro_toblack (hardcoded)
99, // wipe_ending_toblack (hardcoded)
99, // wipe_cutscene_toblack (hardcoded)
72, // wipe_encore_toinvert
@ -80,10 +78,8 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
1, // wipe_menu_final
99, // wipe_credits_final
0, // wipe_evaluation_final
0, // wipe_gameend_final
0, // wipe_ceremony_final
99, // wipe_intro_final (hardcoded)
99, // wipe_ending_final (hardcoded)
99 // wipe_cutscene_final (hardcoded)
};
@ -98,10 +94,8 @@ static boolean g_wipedef_toblack[NUMWIPEDEFS] = {
true, // wipe_menu_toblack
true, // wipe_credits_toblack
true, // wipe_evaluation_toblack
true, // wipe_gameend_toblack
true, // wipe_ceremony_toblack
true, // wipe_intro_toblack (hardcoded)
true, // wipe_ending_toblack (hardcoded)
true, // wipe_cutscene_toblack (hardcoded)
false, // wipe_encore_toinvert
@ -115,10 +109,8 @@ static boolean g_wipedef_toblack[NUMWIPEDEFS] = {
true, // wipe_menu_final
true, // wipe_credits_final
true, // wipe_evaluation_final
true, // wipe_gameend_final
true, // wipe_ceremony_final
true, // wipe_intro_final (hardcoded)
true, // wipe_ending_final (hardcoded)
true // wipe_cutscene_final (hardcoded)
};
@ -133,10 +125,8 @@ static boolean g_wipedef_toinvert[NUMWIPEDEFS] = {
false, // wipe_menu_toblack
false, // wipe_credits_toblack
false, // wipe_evaluation_toblack
false, // wipe_gameend_toblack
false, // wipe_ceremony_toblack
false, // wipe_intro_toblack (hardcoded)
false, // wipe_ending_toblack (hardcoded)
false, // wipe_cutscene_toblack (hardcoded)
true, // wipe_encore_toinvert
@ -150,10 +140,8 @@ static boolean g_wipedef_toinvert[NUMWIPEDEFS] = {
false, // wipe_menu_final
false, // wipe_credits_final
false, // wipe_evaluation_final
false, // wipe_gameend_final
false, // wipe_ceremony_final
false, // wipe_intro_final (hardcoded)
false, // wipe_ending_final (hardcoded)
false // wipe_cutscene_final (hardcoded)
};
@ -168,10 +156,8 @@ static boolean g_wipedef_towhite[NUMWIPEDEFS] = {
false, // wipe_menu_toblack
false, // wipe_credits_toblack
false, // wipe_evaluation_toblack
false, // wipe_gameend_toblack
false, // wipe_ceremony_toblack
false, // wipe_intro_toblack (hardcoded)
false, // wipe_ending_toblack (hardcoded)
false, // wipe_cutscene_toblack (hardcoded)
false, // wipe_encore_toinvert
@ -185,10 +171,8 @@ static boolean g_wipedef_towhite[NUMWIPEDEFS] = {
false, // wipe_menu_final
false, // wipe_credits_final
false, // wipe_evaluation_final
false, // wipe_gameend_final
false, // wipe_ceremony_final
false, // wipe_intro_final (hardcoded)
false, // wipe_ending_final (hardcoded)
false // wipe_cutscene_final (hardcoded)
};
@ -203,10 +187,8 @@ static boolean g_wipedef_crossfade[NUMWIPEDEFS] = {
false, // wipe_menu_toblack
false, // wipe_credits_toblack
false, // wipe_evaluation_toblack
false, // wipe_gameend_toblack
false, // wipe_ceremony_toblack
false, // wipe_intro_toblack (hardcoded)
false, // wipe_ending_toblack (hardcoded)
false, // wipe_cutscene_toblack (hardcoded)
false, // wipe_encore_toinvert
@ -220,10 +202,8 @@ static boolean g_wipedef_crossfade[NUMWIPEDEFS] = {
true, // wipe_menu_final
true, // wipe_credits_final
true, // wipe_evaluation_final
true, // wipe_gameend_final
true, // wipe_ceremony_final
true, // wipe_intro_final (hardcoded)
true, // wipe_ending_final (hardcoded)
true // wipe_cutscene_final (hardcoded)
};

View file

@ -140,8 +140,6 @@ boolean usedCheats = false; // Set when a "cheats on" is ever used.
UINT8 paused;
UINT8 modeattacking = ATTACKING_NONE;
boolean imcontinuing = false;
boolean runemeraldmanager = false;
UINT16 emeraldspawndelay = 60*TICRATE;
// menu demo things
UINT8 numDemos = 0;
@ -205,7 +203,6 @@ static boolean retryingmodeattack = false;
UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
UINT16 emeralds;
INT32 luabanks[NUM_LUABANKS];
// Temporary holding place for nights data for the current map
@ -264,7 +261,7 @@ UINT8 maxXtraLife = 2; // Max extra lives from rings
UINT8 introtoplay;
UINT8 creditscutscene;
UINT8 useBlackRock = 1;
UINT8 useSeal = 1;
// Emerald locations
mobj_t *hunt1;
@ -1785,7 +1782,7 @@ boolean G_Responder(event_t *ev)
return true;
}
}
else if (gamestate == GS_CREDITS || gamestate == GS_ENDING) // todo: keep ending here?
else if (gamestate == GS_CREDITS)
{
if (HU_Responder(ev))
{
@ -1813,7 +1810,17 @@ boolean G_Responder(event_t *ev)
if (K_CeremonyResponder(ev))
{
nextmap = NEXTMAP_TITLE;
if (grandprixinfo.gp == true
&& grandprixinfo.cup != NULL
&& grandprixinfo.cup->playcredits == true)
{
nextmap = NEXTMAP_CREDITS;
}
else
{
nextmap = NEXTMAP_TITLE;
}
G_EndGame();
return true;
}
@ -1822,11 +1829,6 @@ boolean G_Responder(event_t *ev)
{
return true;
}
// Demo End
else if (gamestate == GS_GAMEEND)
{
return true;
}
else if (gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_EVALUATION)
{
if (HU_Responder(ev))
@ -2322,23 +2324,12 @@ void G_Ticker(boolean run)
F_IntroTicker();
break;
case GS_ENDING:
if (run)
F_EndingTicker();
HU_Ticker();
break;
case GS_CUTSCENE:
if (run)
F_CutsceneTicker();
HU_Ticker();
break;
case GS_GAMEEND:
if (run)
F_GameEndTicker();
break;
case GS_EVALUATION:
if (run)
F_GameEvaluationTicker();
@ -3387,10 +3378,6 @@ void G_ExitLevel(void)
// Don't save demos immediately here! Let standings write first
}
else if (gamestate == GS_ENDING)
{
F_StartCredits();
}
else if (gamestate == GS_CREDITS)
{
F_StartGameEvaluation();
@ -4664,6 +4651,8 @@ void G_EndGame(void)
// Only do evaluation and credits in singleplayer contexts
if (!netgame && grandprixinfo.gp == true)
{
G_HandleSaveLevel(true);
if (nextmap == NEXTMAP_CEREMONY) // end game with ceremony
{
if (K_StartCeremony() == true)
@ -4736,7 +4725,15 @@ void G_LoadGameSettings(void)
}
#define GD_VERSIONCHECK 0xBA5ED123 // Change every major version, as usual
#define GD_VERSIONMINOR 3 // Change every format update
#define GD_VERSIONMINOR 4 // Change every format update
typedef enum
{
GDEVER_ADDON = 1,
GDEVER_CREDITS = 1<<1,
GDEVER_REPLAY = 1<<2,
GDEVER_SPECIAL = 1<<3,
} gdeverdone_t;
static const char *G_GameDataFolder(void)
{
@ -4860,9 +4857,21 @@ void G_LoadGameData(void)
gamedata->chaokeys = READUINT16(save.p);
gamedata->everloadedaddon = (boolean)READUINT8(save.p);
gamedata->eversavedreplay = (boolean)READUINT8(save.p);
gamedata->everseenspecial = (boolean)READUINT8(save.p);
if (versionMinor >= 4)
{
UINT32 everflags = READUINT32(save.p);
gamedata->everloadedaddon = !!(everflags & GDEVER_ADDON);
gamedata->everfinishedcredits = !!(everflags & GDEVER_CREDITS);
gamedata->eversavedreplay = !!(everflags & GDEVER_REPLAY);
gamedata->everseenspecial = !!(everflags & GDEVER_SPECIAL);
}
else
{
gamedata->everloadedaddon = (boolean)READUINT8(save.p);
gamedata->eversavedreplay = (boolean)READUINT8(save.p);
gamedata->everseenspecial = (boolean)READUINT8(save.p);
}
}
else
{
@ -5289,7 +5298,7 @@ void G_SaveGameData(void)
4+4+
(4*GDGT_MAX)+
4+1+2+2+
1+1+1+
4+
4+
(MAXEMBLEMS+(MAXUNLOCKABLES*2)+MAXCONDITIONSETS)+
4+2);
@ -5426,11 +5435,22 @@ void G_SaveGameData(void)
WRITEUINT16(save.p, gamedata->keyspending); // 2
WRITEUINT16(save.p, gamedata->chaokeys); // 2
WRITEUINT8(save.p, gamedata->everloadedaddon); // 1
WRITEUINT8(save.p, gamedata->eversavedreplay); // 1
WRITEUINT8(save.p, gamedata->everseenspecial); // 1
{
UINT32 everflags = 0;
WRITEUINT32(save.p, quickncasehash(timeattackfolder, 64));
if (gamedata->everloadedaddon)
everflags |= GDEVER_ADDON;
if (gamedata->everfinishedcredits)
everflags |= GDEVER_CREDITS;
if (gamedata->eversavedreplay)
everflags |= GDEVER_REPLAY;
if (gamedata->everseenspecial)
everflags |= GDEVER_SPECIAL;
WRITEUINT32(save.p, everflags); // 4
}
WRITEUINT32(save.p, quickncasehash(timeattackfolder, 64)); // 4
// To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < MAXEMBLEMS;) // MAXEMBLEMS * 1;

View file

@ -35,12 +35,10 @@ typedef enum
GS_CREDITS, // credit sequence
GS_EVALUATION, // Evaluation at the end of a game.
GS_GAMEEND, // game end sequence - "did you get all those chaos emeralds?"
GS_CEREMONY, // RR: Podium sequence
// Hardcoded fades or other fading methods
GS_INTRO, // introduction
GS_ENDING, // currently shared between bad and good endings
GS_CUTSCENE, // custom cutscene
// Not fadable

View file

@ -8134,8 +8134,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate
sfx_s3k9c, // deathsound
0, // speed
72*FRACUNIT, // radius
72*FRACUNIT, // height
80*FRACUNIT, // radius
80*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage

View file

@ -5440,7 +5440,7 @@ void K_drawKartHUD(void)
{
if (gametyperules & GTR_CIRCUIT)
{
if (numlaps > 1)
if (numlaps != 1)
{
K_drawKartLaps();
gametypeinfoshown = true;

View file

@ -1055,6 +1055,7 @@ typedef enum
extras_eggtv,
extras_stereo,
extras_password,
extras_credits,
} extras_e;
void M_InitExtras(INT32 choice); // init for the struct

View file

@ -209,7 +209,6 @@ static boolean M_GamestateCanOpenMenu(void)
{
case GS_INTRO:
case GS_CUTSCENE:
case GS_GAMEEND:
case GS_CREDITS:
case GS_EVALUATION:
case GS_CEREMONY:

View file

@ -235,16 +235,25 @@ void K_UpdatePodiumWaypoints(player_t *const player)
--------------------------------------------------*/
boolean K_StartCeremony(void)
{
INT32 podiumMapNum = nummapheaders;
INT32 i;
if (grandprixinfo.gp == false)
{
return false;
}
if (podiummap
&& ((podiumMapNum = G_MapNumber(podiummap)) < nummapheaders)
INT32 i;
INT32 podiumMapNum = NEXTMAP_INVALID;
if (grandprixinfo.cup != NULL
&& grandprixinfo.cup->cachedlevels[CUPCACHE_PODIUM] != NEXTMAP_INVALID)
{
podiumMapNum = grandprixinfo.cup->cachedlevels[CUPCACHE_PODIUM];
}
else if (podiummap)
{
podiumMapNum = G_MapNumber(podiummap);
}
if (podiumMapNum < nummapheaders
&& mapheaderinfo[podiumMapNum]
&& mapheaderinfo[podiumMapNum]->lumpnum != LUMPERROR)
{

View file

@ -394,8 +394,6 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
skincolor_redring = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "skincolor_bluering"))
skincolor_bluering = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "emeralds"))
emeralds = (UINT16)luaL_checkinteger(L, 2);
else if (fastcmp(word, "gravity"))
gravity = (fixed_t)luaL_checkinteger(L, 2);
else if (fastcmp(word, "stoppedclock"))

View file

@ -469,29 +469,6 @@ void Command_Savecheckpoint_f(void)
}
}
// Like M_GetAllEmeralds() but for console devmode junkies.
/*
void Command_Getallemeralds_f(void)
{
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER;
emeralds = EMERALD_ALL;
CONS_Printf(M_GetText("You now have all 7 emeralds.\n"));
}
void Command_Resetemeralds_f(void)
{
REQUIRE_CHEATS;
REQUIRE_SINGLEPLAYER;
emeralds = 0;
CONS_Printf(M_GetText("Emeralds reset to zero.\n"));
}
*/
//
// Devmode
//

View file

@ -610,6 +610,7 @@ void M_ClearStats(void)
gamedata->timesBeaten = 0;
gamedata->everloadedaddon = false;
gamedata->everfinishedcredits = false;
gamedata->eversavedreplay = false;
gamedata->everseenspecial = false;
gamedata->evercrashed = false;
@ -738,6 +739,43 @@ boolean M_NotFreePlay(player_t *player)
return false;
}
UINT16 M_CheckCupEmeralds(UINT8 difficulty)
{
if (difficulty == 0)
return 0;
if (difficulty >= KARTGP_MAX)
difficulty = KARTGP_MASTER;
cupheader_t *cup;
UINT16 ret = 0, seen = 0;
for (cup = kartcupheaders; cup; cup = cup->next)
{
// Does it not *have* an emerald?
if (cup->emeraldnum == 0 || cup->emeraldnum > 14)
continue;
UINT16 emerald = 1<<(cup->emeraldnum-1);
// Only count the first reference.
if (seen & emerald)
continue;
// We've seen it, prevent future repetitions.
seen |= emerald;
// Did you actually get it?
if (cup->windata[difficulty].got_emerald == false)
continue;
// Wa hoo !
ret |= emerald;
}
return ret;
}
// See also M_GetConditionString
boolean M_CheckCondition(condition_t *cn, player_t *player)
{
@ -791,30 +829,12 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
case UC_ALLSUPER:
case UC_ALLEMERALDS:
{
cupheader_t *cup;
UINT16 ret = 0;
UINT8 i;
if (gamestate == GS_LEVEL)
return false; // this one could be laggy with many cups available
for (cup = kartcupheaders; cup; cup = cup->next)
{
if (cup->emeraldnum == 0)
continue;
i = cn->requirement;
for (i = cn->requirement; i < KARTGP_MAX; i++)
{
if (cup->windata[i].got_emerald == true)
break;
}
if (i == KARTGP_MAX)
continue;
ret |= 1<<(cup->emeraldnum-1);
}
ret = M_CheckCupEmeralds(cn->requirement);
if (cn->type == UC_ALLCHAOS)
return ALLCHAOSEMERALDS(ret);
@ -835,6 +855,8 @@ boolean M_CheckCondition(condition_t *cn, player_t *player)
case UC_ADDON:
return ((gamedata->everloadedaddon == true)
&& M_SecretUnlocked(SECRET_ADDONS, true));
case UC_CREDITS:
return (gamedata->everfinishedcredits == true);
case UC_REPLAY:
return (gamedata->eversavedreplay == true);
case UC_CRASH:
@ -1289,6 +1311,8 @@ static const char *M_GetConditionString(condition_t *cn)
if (!M_SecretUnlocked(SECRET_ADDONS, true))
return NULL;
return "load a custom addon into \"Dr. Robotnik's Ring Racers\"";
case UC_CREDITS:
return "watch the developer credits all the way from start to finish";
case UC_REPLAY:
return "save a replay after finishing a round";
case UC_CRASH:

View file

@ -52,6 +52,7 @@ typedef enum
UC_CONDITIONSET, // CONDITIONSET [condition set number]
UC_ADDON, // Ever loaded a custom file?
UC_CREDITS, // Finish watching the credits
UC_REPLAY, // Save a replay
UC_CRASH, // Hee ho !
@ -287,6 +288,7 @@ struct gamedata_t
// SPECIFIC SPECIAL EVENTS
boolean everloadedaddon;
boolean everfinishedcredits;
boolean eversavedreplay;
boolean everseenspecial;
boolean evercrashed;
@ -340,6 +342,7 @@ void M_ClearSecrets(void);
void M_ClearStats(void);
boolean M_NotFreePlay(player_t *player);
UINT16 M_CheckCupEmeralds(UINT8 difficulty);
// Updating conditions and unlockables
boolean M_ConditionInterpret(const char *password);

View file

@ -5,6 +5,15 @@
#include "../m_cond.h"
#include "../m_cheat.h"
#include "../s_sound.h"
#include "../f_finale.h"
static void M_Credits(INT32 choice)
{
(void)choice;
restoreMenu = currentMenu;
M_ClearMenus(true);
F_StartCredits();
}
menuitem_t EXTRAS_Main[] =
{
@ -32,6 +41,9 @@ menuitem_t EXTRAS_Main[] =
{IT_STRING | IT_CVAR | IT_CV_STRING, "Password", "If you don't know any passwords, come back later!",
NULL, {.cvar = &cv_dummyextraspassword}, 0, 0},
{IT_STRING | IT_CALL, "Credits", "It's important to know who makes the video games you play.",
NULL, {.routine = M_Credits}, 0, 0},
};
// the extras menu essentially reuses the options menu stuff

View file

@ -485,7 +485,6 @@ void M_StartTimeAttack(INT32 choice)
// Still need to reset devmode
cht_debug = 0;
emeralds = 0;
if (demo.playback)
G_StopDemo();

View file

@ -155,7 +155,8 @@ static void M_StartCup(UINT8 entry)
NULL, MM_NOTHING, NULL, NULL
);
G_HandleSaveLevel(true);
if (FIL_FileExists(gpbackup))
remove(gpbackup);
return;
}

View file

@ -266,7 +266,7 @@ boolean M_LevelListFromGametype(INT16 gt)
G_GetBackupCupData(
cupgrid.grandprix == true
|| cv_splitplayers.value <= 1
&& cv_splitplayers.value <= 1
);
templevelsearch.cup = kartcupheaders;

View file

@ -566,8 +566,6 @@ extern INT32 modulothing;
#define MAXHUNTEMERALDS 64
extern mapthing_t *huntemeralds[MAXHUNTEMERALDS];
extern INT32 numhuntemeralds;
extern boolean runemeraldmanager;
extern UINT16 emeraldspawndelay;
extern INT32 numstarposts;
extern UINT16 bossdisabled;
extern boolean stoppedclock;

View file

@ -5662,7 +5662,6 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITESINT8(save->p, g_pickedVote);
WRITEUINT16(save->p, emeralds);
{
UINT8 globools = 0;
if (stagefailed)
@ -5836,7 +5835,6 @@ static boolean P_NetUnArchiveMisc(savebuffer_t *save, boolean reloading)
g_pickedVote = READSINT8(save->p);
emeralds = READUINT16(save->p);
{
UINT8 globools = READUINT8(save->p);
stagefailed = !!(globools & 1);

View file

@ -7351,10 +7351,6 @@ static void P_InitLevelSettings(void)
K_TimerReset();
// special stage tokens, emeralds, and ring total
runemeraldmanager = false;
emeraldspawndelay = 60*TICRATE;
nummaprings = 0;
nummapboxes = numgotboxes = 0;
maptargets = numtargets = 0;
@ -8362,7 +8358,7 @@ void P_PostLoadLevel(void)
P_RunCachedActions();
G_HandleSaveLevel(gamestate == GS_CEREMONY);
G_HandleSaveLevel(false);
if (marathonmode & MA_INGAME)
{

View file

@ -4647,11 +4647,12 @@ void P_SetupSignExit(player_t *player, boolean tie)
thinker_t *think;
INT32 numfound = 0;
angle_t bestAngle = K_MomentumAngle(player->mo) + ANGLE_180;
if (player->position != 1)
if (player->position != 1
|| (gametyperules & GTR_SPECIALSTART))
return;
angle_t bestAngle = K_MomentumAngle(player->mo) + ANGLE_180;
for (; node; node = node->m_thinglist_next)
{
thing = node->m_thing;

View file

@ -342,7 +342,6 @@ void P_GiveEmerald(boolean spawnObj)
UINT8 em = P_GetNextEmerald();
S_StartSound(NULL, sfx_cgot); // Got the emerald!
emeralds |= (1 << em);
stagefailed = false;
if (spawnObj)
@ -714,12 +713,50 @@ void P_PlayVictorySound(mobj_t *source)
void P_EndingMusic(void)
{
const char *jingle = NULL;
boolean nointer = false;
UINT8 bestPos = UINT8_MAX;
player_t *bestPlayer = NULL;
SINT8 i;
// See G_DoCompleted and Y_DetermineIntermissionType
boolean nointer = ((modeattacking && (players[consoleplayer].pflags & PF_NOCONTEST))
|| (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE));
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i]
|| players[i].spectator)
continue;
// Battle powerstone win
if ((gametyperules & GTR_POWERSTONES)
&& ALLCHAOSEMERALDS(players[i].emeralds))
break;
// Special round?
if (((gametyperules & GTR_SPECIALSTART)
|| (grandprixinfo.gp == true
&& grandprixinfo.eventmode == GPEVENT_SPECIAL)
) == false)
continue;
// Any player has completed well?
if (!players[i].exiting
|| players[i].bot
|| K_IsPlayerLosing(&players[i]))
continue;
// Special win
break;
}
// Event - Emerald Finish
if (i != MAXPLAYERS)
{
jingle = "EMRLD";
goto skippingposition;
}
// Event - Level Finish
// Check for if this is valid or not
for (i = 0; i <= r_splitscreen; i++)
@ -756,10 +793,6 @@ void P_EndingMusic(void)
}
}
// See G_DoCompleted and Y_DetermineIntermissionType
nointer = ((modeattacking && (players[consoleplayer].pflags & PF_NOCONTEST))
|| (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE));
if (bestPlayer == NULL)
{
// No jingle for you
@ -798,6 +831,8 @@ void P_EndingMusic(void)
}
}
skippingposition:
if (nointer == true)
{
// Do not set "racent" in G_Ticker