diff --git a/src/d_main.cpp b/src/d_main.cpp index 45ab05fd4..7e16f6c59 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -81,7 +81,7 @@ #include // Put hashes here to get them out of header hell. -#define ASSET_HASH_MAIN_PK3 "91b06902a9fbb1871f0217c756910e22" +#define ASSET_HASH_MAIN_PK3 "68bb249e7d8cbbbeca01a7d0542ea9d3" #define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7" #define ASSET_HASH_GFX_KART "06f86ee16136eb8a7043b15001797034" #define ASSET_HASH_TEXTURES_KART "abb53d56aba47c3a8cb0f764da1c8b80" diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c139e9485..9c5689f03 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -151,6 +151,7 @@ static void KartEncore_OnChange(void); static void KartComeback_OnChange(void); static void KartEliminateLast_OnChange(void); static void KartRings_OnChange(void); +static void KartPurpleDrift_OnChange(void); static void KartStacking_OnChange(void); static void KartChaining_OnChange(void); static void KartSlipdash_OnChange(void); @@ -494,7 +495,7 @@ consvar_t cv_kartwalltransfer = CVAR_INIT ("BG_forcewalltransfer", "Off", CV_NET consvar_t cv_kartusepwrlv = CVAR_INIT ("kartusepwrlv", "Yes", CV_NETVAR, CV_YesNo, NULL); -consvar_t cv_kartpurpledrift = CVAR_INIT ("kartpurpledrift", "No", CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_kartpurpledrift = CVAR_INIT ("kartpurpledrift", "No", CV_NETVAR, CV_YesNo, KartPurpleDrift_OnChange); consvar_t cv_kartbumpspark = CVAR_INIT ("kartbumpspark", "No", CV_NETVAR, CV_YesNo, NULL); @@ -7059,6 +7060,39 @@ static void KartRings_OnChange(void) } } +static void KartPurpleDrift_OnChange(void) +{ + if (K_CanChangeRules() == false) + { + return; + } + + if (!purpledriftactive && cv_kartpurpledrift.value) + { + if (leveltime < starttime) + { + purpledriftactive = true; + CONS_Printf(M_GetText("4-tier drifting has been turned \"On\".\n")); + } + else + { + CONS_Printf(M_GetText("4-tier drifting will be turned \"On\" Next Round.\n")); + } + } + else if (purpledriftactive && !cv_kartpurpledrift.value) + { + if (leveltime < starttime) + { + purpledriftactive = false; + CONS_Printf(M_GetText("4-tier drifting has been turned \"Off\".\n")); + } + else + { + CONS_Printf(M_GetText("4-tier drifting will be turned \"Off\" next round.\n")); + } + } +} + static void KartStacking_OnChange(void) { if (K_CanChangeRules() == false) @@ -7066,7 +7100,7 @@ static void KartStacking_OnChange(void) return; } - if (!stackingactive && cv_kartstacking.value) + if (!K_StackingActive() && cv_kartstacking.value) { if (leveltime < starttime) { @@ -7078,7 +7112,7 @@ static void KartStacking_OnChange(void) CONS_Printf(M_GetText("Boost Stacking will be turned \"On\" next round.\n")); } } - else if (stackingactive && !cv_kartstacking.value) + else if (K_StackingActive() && !cv_kartstacking.value) { if (leveltime < starttime) { @@ -7099,7 +7133,7 @@ static void KartChaining_OnChange(void) return; } - if (!chainingactive && cv_kartchaining.value) + if (!K_ChainingActive() && cv_kartchaining.value) { if (leveltime < starttime) { @@ -7111,7 +7145,7 @@ static void KartChaining_OnChange(void) CONS_Printf(M_GetText("Boost Chaining will be turned \"On\" Next Round.\n")); } } - else if (chainingactive && !cv_kartstacking.value) + else if (K_ChainingActive() && !cv_kartstacking.value) { if (leveltime < starttime) { @@ -7132,7 +7166,7 @@ static void KartSlipdash_OnChange(void) return; } - if (!slipdashactive && cv_kartslipdash.value) + if (!K_SlipdashActive() && cv_kartslipdash.value) { if (leveltime < starttime) { @@ -7144,7 +7178,7 @@ static void KartSlipdash_OnChange(void) CONS_Printf(M_GetText("Slipdashing will be turned \"On\" Next Round.\n")); } } - else if (slipdashactive && !cv_kartslipdash.value) + else if (K_SlipdashActive() && !cv_kartslipdash.value) { if (leveltime < starttime) { diff --git a/src/info/menus.h b/src/info/menus.h index 77f87d715..e223c1dca 100644 --- a/src/info/menus.h +++ b/src/info/menus.h @@ -7,6 +7,7 @@ _(PLAYBACK) _(SP_MAIN) _(SP_GRANDPRIX) _(SP_TIMEATTACK) +_(SP_MODS) _(SP_GUESTREPLAY) _(SP_REPLAY) _(SP_GHOST) diff --git a/src/k_hud.c b/src/k_hud.c index f5693c400..d7141c0f2 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2658,20 +2658,9 @@ static void K_DrawRivalTagForPlayer(fixed_t x, fixed_t y) static const char *K_StringTypingDot(player_t *p) { - if (p->typing_duration > 47) - { - return "..."; - } - else if (p->typing_duration > 31) - { - return ".."; - } - else if (p->typing_duration > 15) - { - return "."; - } - else - return ""; + const char *dots = "..."; + + return dots + CLAMP(3 - p->typing_duration/16, 0, 3); } static void K_DrawTypingNotifier(fixed_t x, fixed_t y, player_t *p) diff --git a/src/k_kart.c b/src/k_kart.c index af9511b8f..614f625dc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -10732,6 +10732,17 @@ boolean K_RingsActive(void) return true; } +boolean K_PurpleDriftActive(void) +{ + if (purpledriftactive) + { + // Purpledrift is enabled! + return true; + } + + return false; +} + boolean K_StackingActive(void) { if (stackingactive) diff --git a/src/k_kart.h b/src/k_kart.h index d79d0456b..e2a5d685b 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -234,6 +234,7 @@ void K_UnsetItemOut(player_t *player); boolean K_SafeRespawnPosition(mobj_t * mo); boolean K_RingsActive(void); +boolean K_PurpleDriftActive(void); boolean K_StackingActive(void); boolean K_ChainingActive(void); boolean K_SlipdashActive(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c620190b7..7d1abb725 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -3985,6 +3985,13 @@ static int lib_kRingsActive(lua_State *L) return 1; } +// Checks if Purple Drift is active. +static int lib_kPurpleDriftActive(lua_State *L) +{ + lua_pushboolean(L, K_PurpleDriftActive()); + return 1; +} + // Checks if Stacking is active. static int lib_kStackingActive(lua_State *L) { @@ -4365,6 +4372,7 @@ static luaL_Reg lib[] = { {"K_GetCollideAngle",lib_kGetCollideAngle}, {"K_RingsActive",lib_kRingsActive}, + {"K_PurpleDriftActive",lib_kPurpleDriftActive}, {"K_StackingActive",lib_kStackingActive}, {"K_ChainingActive",lib_kChainingActive}, {"K_SlipdashActive",lib_kSlipdashActive}, diff --git a/src/m_menu.c b/src/m_menu.c index bcbf33255..6945f66e4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -355,6 +355,12 @@ consvar_t cv_dummyrings = CVAR_INIT ("dummyrings", "0", CV_HIDEN, ringlimit_cons consvar_t cv_dummylives = CVAR_INIT ("dummylives", "0", CV_HIDEN, liveslimit_cons_t, NULL); static consvar_t cv_dummystaff = CVAR_INIT ("dummystaff", "0", CV_HIDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange); +consvar_t cv_dummyattackingrings = CVAR_INIT ("dummyattackingrings", "Off", CV_NOSHOWHELP|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange); +consvar_t cv_dummyattackingstacking = CVAR_INIT ("dummyattackingstacking", "Off", CV_NOSHOWHELP|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange); +consvar_t cv_dummyattackingchaining = CVAR_INIT ("dummyattackingchaining", "Off", CV_NOSHOWHELP|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange); +consvar_t cv_dummyattackingslipdash = CVAR_INIT ("dummyattackingslipdash", "Off", CV_NOSHOWHELP|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange); +consvar_t cv_dummyattackingpurpledrift = CVAR_INIT ("dummyattackingpurpledrift", "Off", CV_NOSHOWHELP|CV_CALL|CV_NOINIT, CV_OnOff, Nextmap_OnChange); + static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {3, "Master"}, {0, NULL}}; static CV_PossibleValue_t dummygpcup_cons_t[50] = {{1, "TEMP"}}; // A REALLY BIG NUMBER, SINCE THIS IS TEMP UNTIL NEW MENUS @@ -487,6 +493,41 @@ void M_OpenGLOptionsMenu(INT32 choice) static INT32 M_FindFirstMap(INT32 gtype); static INT32 M_GetFirstLevelInList(void); +#define ADD(cv, str) \ +if (cv.value) \ +{ \ + len += 3; \ + new_str = Z_Realloc(new_str, len, PU_STATIC, NULL); \ + strcat(new_str, str); \ +} + +char *M_AppendGametypeAndModName(void) +{ + UINT8 len = 3; + char *new_str; + + new_str = Z_Malloc(4, PU_STATIC, NULL); + + if ((!Playing() && (levellistmode == LLM_ITEMBREAKER)) || (modeattacking & ATTACKING_ITEMBREAK)) + { + strcpy(new_str, "IB-"); + } + else + { + strcpy(new_str, "RA-"); + } + + ADD(cv_dummyattackingrings, "RN-") + ADD(cv_dummyattackingstacking, "ST-") + ADD(cv_dummyattackingchaining, "CH-") + ADD(cv_dummyattackingslipdash, "SD-") + ADD(cv_dummyattackingpurpledrift, "PD-") + + new_str[len-1] = '\0'; + + return new_str; +} + // Nextmap. Used for Time Attack. void Nextmap_OnChange(void) { @@ -523,10 +564,10 @@ void Nextmap_OnChange(void) leveltitle = cv_nextmap.value ? G_BuildMapTitle(cv_nextmap.value) : Z_StrDup("Random"); cv_nextmap.string = cv_nextmap.zstring = leveltitle; - if (menustack[0] == MN_SP_TIMEATTACK) + if (menustack[0] == MN_SP_TIMEATTACK || menustack[0] == MN_SP_MODS) { // see also p_setup.c's P_LoadRecordGhosts - const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; + char *gamemode = M_AppendGametypeAndModName(); char *gpath = xva("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); UINT8 active = 0; @@ -600,6 +641,7 @@ void Nextmap_OnChange(void) } free(gpath); + Z_Free(gamemode); } } @@ -1807,6 +1849,12 @@ void M_Init(void) CV_RegisterVar(&cv_dummylives); CV_RegisterVar(&cv_dummystaff); + CV_RegisterVar(&cv_dummyattackingrings); + CV_RegisterVar(&cv_dummyattackingstacking); + CV_RegisterVar(&cv_dummyattackingchaining); + CV_RegisterVar(&cv_dummyattackingslipdash); + CV_RegisterVar(&cv_dummyattackingpurpledrift); + CV_RegisterVar(&cv_dummygpdifficulty); CV_RegisterVar(&cv_dummygpencore); CV_RegisterVar(&cv_dummygpcup); @@ -5723,6 +5771,7 @@ void M_QuitTimeAttackMenu(INT32 choice) void M_ChooseTimeAttack(INT32 choice) { char *gpath; + char *gamemode = M_AppendGametypeAndModName(); char nameofdemo[256]; (void)choice; emeralds = 0; @@ -5736,7 +5785,9 @@ void M_ChooseTimeAttack(INT32 choice) strcat(gpath, PATHSEP); strcat(gpath, G_BuildMapName(cv_nextmap.value)); - snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-%s-last", gpath, cv_skin[0].string, (modeattacking & ATTACKING_ITEMBREAK) ? "IB" : "RA"); + snprintf(nameofdemo, sizeof nameofdemo, "%s-%s-%s-last", gpath, cv_skin[0].string, gamemode); + + Z_Free(gamemode); if (!cv_autorecord.value) remove(va("%s"PATHSEP"%s.lmp", srb2home, nameofdemo)); @@ -5791,7 +5842,7 @@ void M_HandleStaffReplay(INT32 choice) void M_ReplayTimeAttack(INT32 choice) { const char *which; - const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; + const char *gamemode = M_AppendGametypeAndModName(); M_ClearMenus(true); demo.loadfiles = false; demo.ignorefiles = true; // Just assume that record attack replays have the files needed @@ -5817,7 +5868,7 @@ void M_ReplayTimeAttack(INT32 choice) static void M_EraseGuest(INT32 choice) { - const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; + const char *gamemode = M_AppendGametypeAndModName(); const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode); (void)choice; if (FIL_FileExists(rguest)) @@ -5830,7 +5881,7 @@ static void M_EraseGuest(INT32 choice) static void M_OverwriteGuest(const char *which) { - const char *gamemode = (levellistmode == LLM_ITEMBREAKER) ? "IB" : "RA"; + const char *gamemode = M_AppendGametypeAndModName(); char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), gamemode)); UINT8 *buf; size_t len; diff --git a/src/m_menu.h b/src/m_menu.h index e73f6f47b..c545e4ea9 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -465,6 +465,8 @@ extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; extern consvar_t cv_dummygpdifficulty, cv_dummygpencore, cv_dummygpcup; extern consvar_t cv_dummyrings, cv_dummylives; extern consvar_t cv_dummymenuplayer, cv_dummyteam, cv_dummyspectate, cv_dummyscramble; +extern consvar_t cv_dummyattackingrings, cv_dummyattackingstacking, cv_dummyattackingchaining; +extern consvar_t cv_dummyattackingslipdash, cv_dummyattackingpurpledrift; extern CV_PossibleValue_t gametype_cons_t[]; extern char dummystaffname[22]; @@ -487,6 +489,9 @@ void M_CheatActivationResponder(INT32 ch); void M_ModeAttackRetry(INT32 choice); +// File name appender for RA gametype+mod reading. +char *M_AppendGametypeAndModName(void); + // Level select updating void Nextmap_OnChange(void); diff --git a/src/p_mobj.h b/src/p_mobj.h index ae887a9f0..4345002dd 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -581,6 +581,7 @@ extern boolean ringsactive; extern boolean stackingactive; extern boolean chainingactive; extern boolean slipdashactive; +extern boolean purpledriftactive; extern UINT16 bossdisabled; extern boolean stoppedclock; diff --git a/src/p_saveg.c b/src/p_saveg.c index 35d75090f..a10c4ed5a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -5096,6 +5096,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending) WRITEUINT8(save->p, stackingactive); WRITEUINT8(save->p, chainingactive); WRITEUINT8(save->p, slipdashactive); + WRITEUINT8(save->p, purpledriftactive); for (i = 0; i < 4; i++) { @@ -5268,6 +5269,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool stackingactive = READUINT8(save->p); chainingactive = READUINT8(save->p); slipdashactive = READUINT8(save->p); + purpledriftactive = READUINT8(save->p); for (i = 0; i < 4; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index a419d28c2..06ec7b5fd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -142,10 +142,11 @@ line_t *spawnlines; side_t *spawnsides; INT32 numstarposts; INT32 numbosswaypoints; -boolean ringsactive = false; -boolean stackingactive = false; -boolean chainingactive = false; -boolean slipdashactive = false; +boolean ringsactive; +boolean stackingactive; +boolean chainingactive; +boolean slipdashactive; +boolean purpledriftactive; UINT16 bossdisabled; boolean stoppedclock; boolean levelloading; @@ -7866,10 +7867,14 @@ static void P_InitLevelSettings(boolean reloadinggamestate) stackingactive = false; chainingactive = false; slipdashactive = false; + purpledriftactive = false; if (cv_kartrings.value) ringsactive = true; + if (cv_kartslipdash.value) + purpledriftactive = true; + if (cv_kartstacking.value) stackingactive = true; @@ -7952,6 +7957,11 @@ static void P_InitLevelSettings(boolean reloadinggamestate) gamespeed = KARTSPEED_HARD; franticitems = false; comeback = false; + ringsactive = cv_dummyattackingrings.value; + purpledriftactive = cv_dummyattackingpurpledrift.value; + stackingactive = cv_dummyattackingstacking.value; + chainingactive = cv_dummyattackingchaining.value; + slipdashactive = cv_dummyattackingslipdash.value; } else { @@ -8068,7 +8078,7 @@ static void P_LoadRecordGhosts(void) // see also m_menu.c's Nextmap_OnChange char *gpath; INT32 i; - const char *gamemode = (modeattacking & ATTACKING_ITEMBREAK) ? "IB" : "RA"; + char *gamemode = M_AppendGametypeAndModName(); gpath = xva("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap)); @@ -8132,6 +8142,7 @@ static void P_LoadRecordGhosts(void) } free(gpath); + Z_Free(gamemode); } static void P_SetupCamera(UINT8 pnum, camera_t *cam)