Merge pull request 'Cherries™️ Part 2' (#175) from cherries into blankart-dev
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/175
This commit is contained in:
commit
65cea70c05
35 changed files with 1038 additions and 588 deletions
|
|
@ -143,6 +143,7 @@ k_director.c
|
|||
k_follower.c
|
||||
k_mapuser.c
|
||||
k_stats.c
|
||||
k_specialstage.c
|
||||
h_timers.cpp
|
||||
stun.c
|
||||
lonesha256.c
|
||||
|
|
|
|||
|
|
@ -90,6 +90,15 @@ CV_PossibleValue_t kartspeed_cons_t[] = {
|
|||
{KARTSPEED_EXPERT, "Expert"},
|
||||
{0, NULL}
|
||||
};
|
||||
CV_PossibleValue_t gpdifficulty_cons_t[] = {
|
||||
{KARTSPEED_EASY, "Easy"},
|
||||
{KARTSPEED_NORMAL, "Normal"},
|
||||
{KARTSPEED_HARD, "Hard"},
|
||||
{KARTSPEED_EXPERT, "Expert"},
|
||||
{KARTGP_MASTER, "Master"},
|
||||
{KARTGP_NIGHTMARE, "Nightmare"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
consvar_t cv_resetnetvars = CVAR_INIT ("resetnetvars", "Off", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
|
|
@ -2102,6 +2111,15 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
|
|||
return;
|
||||
}
|
||||
|
||||
if (var == &cv_kartspeed && !M_SecretUnlocked(SECRET_HARDSPEED))
|
||||
{
|
||||
if (!stricmp(value, "Hard") || !stricmp(value, "Expert") || atoi(value) >= KARTSPEED_HARD)
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't unlocked this yet!\n"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (var == &cv_forceskin)
|
||||
{
|
||||
INT32 skin = R_SkinAvailable(value);
|
||||
|
|
@ -2307,9 +2325,14 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
if (var->PossibleValue[max].value == var->value)
|
||||
currentindice = max;
|
||||
|
||||
if ((var == &cv_kartspeed || var == &cv_kartbattlespeed) && !M_SecretUnlocked(SECRET_HARDSPEED))
|
||||
if (var->PossibleValue == kartspeed_cons_t || var->PossibleValue == gpdifficulty_cons_t)
|
||||
{
|
||||
max = (M_SecretUnlocked(SECRET_HARDSPEED) ? 5 : 3);
|
||||
if (!M_SecretUnlocked(SECRET_HARDSPEED))
|
||||
{
|
||||
max = KARTSPEED_NORMAL+1;
|
||||
if (var->PossibleValue == kartspeed_cons_t)
|
||||
max++; // Accommodate KARTSPEED_AUTO
|
||||
}
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
if (currentindice == -1)
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ extern CV_PossibleValue_t CV_Natural[];
|
|||
#define KARTSPEED_EXPERT 3
|
||||
#define KARTGP_MASTER 4 // Not a speed setting, gives hard speed with maxed out bots
|
||||
#define KARTGP_NIGHTMARE 5 // Not a speed setting, gives expert speed with maxed out bots
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[];
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[], gpdifficulty_cons_t[];
|
||||
// Invincibility types.
|
||||
#define KARTINVIN_LEGACY 0
|
||||
#define KARTINVIN_ALTERN 1
|
||||
|
|
|
|||
|
|
@ -4119,30 +4119,22 @@ void SV_StopServer(void)
|
|||
}
|
||||
|
||||
// called at singleplayer start and stopdemo
|
||||
void SV_StartSinglePlayerServer(void)
|
||||
void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame)
|
||||
{
|
||||
INT32 lastgametype = gametype;
|
||||
server = true;
|
||||
netgame = false;
|
||||
multiplayer = false;
|
||||
multiplayer = (modeattacking == ATTACKING_NONE) && !grandprixinfo.gp; // G: no multiplayer in GP!
|
||||
|
||||
if ((modeattacking == ATTACKING_ITEMBREAK) || (bossinfo.boss == true))
|
||||
{
|
||||
G_SetGametype(GT_BATTLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SetGametype(GT_RACE);
|
||||
}
|
||||
netgame = false; // so setting timelimit works... (XD_NETVAR doesn't play nice with SV_StopServer)
|
||||
|
||||
G_SetGametype(dogametype);
|
||||
if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype);
|
||||
|
||||
netgame = donetgame;
|
||||
|
||||
// no more tic the game with this settings!
|
||||
SV_StopServer();
|
||||
|
||||
if (splitscreen)
|
||||
multiplayer = true;
|
||||
}
|
||||
|
||||
static void SV_SendRefuse(INT32 node, const char *reason)
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ typedef enum
|
|||
void NetKeepAlive(void);
|
||||
void NetUpdate(void);
|
||||
|
||||
void SV_StartSinglePlayerServer(void);
|
||||
void SV_StartSinglePlayerServer(INT32 dogametype, boolean donetgame);
|
||||
boolean SV_SpawnServer(void);
|
||||
void SV_StopServer(void);
|
||||
void SV_ResetServer(void);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "m_random.h" // P_ClearRandom
|
||||
#include "acs/interface.h"
|
||||
#include "k_specialstage.h"
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
|
@ -1188,6 +1189,9 @@ void D_StartTitle(void)
|
|||
// Reset boss info
|
||||
K_ResetBossInfo();
|
||||
|
||||
// Reset Special Stage
|
||||
K_ResetSpecialStage();
|
||||
|
||||
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
|
||||
maptol = 0;
|
||||
|
||||
|
|
@ -2027,34 +2031,20 @@ void D_SRB2Main(void)
|
|||
INT16 newskill = -1;
|
||||
const char *sskill = M_GetNextParm();
|
||||
|
||||
const char *masterstr = "Master";
|
||||
const char *nightmarestr = "NIGHTMARE";
|
||||
|
||||
if (!strcasecmp(masterstr, sskill))
|
||||
for (j = 0; gpdifficulty_cons_t[j].strvalue; j++)
|
||||
{
|
||||
newskill = KARTGP_MASTER;
|
||||
}
|
||||
else if (!strcasecmp(nightmarestr, sskill))
|
||||
{
|
||||
newskill = KARTGP_NIGHTMARE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; kartspeed_cons_t[j].strvalue; j++)
|
||||
if (!strcasecmp(gpdifficulty_cons_t[j].strvalue, sskill))
|
||||
{
|
||||
if (!strcasecmp(kartspeed_cons_t[j].strvalue, sskill))
|
||||
{
|
||||
newskill = (INT16)kartspeed_cons_t[j].value;
|
||||
break;
|
||||
}
|
||||
newskill = (INT16)gpdifficulty_cons_t[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kartspeed_cons_t[j].strvalue) // reached end of the list with no match
|
||||
{
|
||||
j = atoi(sskill); // assume they gave us a skill number, which is okay too
|
||||
if (j >= KARTSPEED_EASY && j <= KARTGP_NIGHTMARE)
|
||||
newskill = (INT16)j;
|
||||
}
|
||||
if (!gpdifficulty_cons_t[j].strvalue) // reached end of the list with no match
|
||||
{
|
||||
j = atoi(sskill); // assume they gave us a skill number, which is okay too
|
||||
if (j >= KARTSPEED_EASY && j <= KARTGP_NIGHTMARE)
|
||||
newskill = (INT16)j;
|
||||
}
|
||||
|
||||
if (grandprixinfo.gp == true)
|
||||
|
|
|
|||
239
src/d_netcmd.c
239
src/d_netcmd.c
|
|
@ -67,6 +67,7 @@
|
|||
#include "deh_tables.h"
|
||||
#include "m_perfstats.h"
|
||||
#include "g_party.h"
|
||||
#include "k_specialstage.h"
|
||||
|
||||
#define CV_RESTRICT CV_NETVAR
|
||||
|
||||
|
|
@ -632,6 +633,7 @@ consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", 0, C
|
|||
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", 0, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebugcolorize = CVAR_INIT ("kartdebugcolorize", "Off", 0, CV_OnOff, NULL);
|
||||
consvar_t cv_kartdebugdirector = CVAR_INIT ("kartdebugdirector", "Off", 0, CV_OnOff, NULL);
|
||||
consvar_t cv_gptest = CVAR_INIT ("gptest", "Off", CV_CHEAT|CV_NETVAR, CV_OnOff, NULL);
|
||||
|
||||
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_votetime = CVAR_INIT ("votetime", "20", CV_NETVAR, votetime_cons_t, NULL);
|
||||
|
|
@ -657,9 +659,9 @@ consvar_t cv_overtime = CVAR_INIT ("overtime", "Yes", CV_NETVAR|CV_CHEAT, CV_Yes
|
|||
consvar_t cv_rollingdemos = CVAR_INIT ("rollingdemos", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
|
||||
consvar_t cv_pointlimit = CVAR_INIT ("pointlimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
|
||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {99999, "MAX"}, {0, "None"}, {0, NULL}};
|
||||
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
|
||||
consvar_t cv_timelimit = CVAR_INIT ("timelimit", "None", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
|
||||
|
||||
static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {MAX_LAPS, "MAX"}, {-1, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange);
|
||||
|
|
@ -2889,6 +2891,10 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
|||
{
|
||||
pencoremode = bossinfo.encore;
|
||||
}
|
||||
else if (specialStage.active == true)
|
||||
{
|
||||
pencoremode = specialStage.encore;
|
||||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
pencoremode = grandprixinfo.encore;
|
||||
|
|
@ -3280,6 +3286,7 @@ static void Command_Map_f(void)
|
|||
if (newgametype == GT_BATTLE)
|
||||
{
|
||||
grandprixinfo.gp = false;
|
||||
specialStage.active = false;
|
||||
K_ResetBossInfo();
|
||||
|
||||
if (mapheaderinfo[newmapnum-1] &&
|
||||
|
|
@ -3289,76 +3296,76 @@ static void Command_Map_f(void)
|
|||
bossinfo.encore = newencoremode;
|
||||
}
|
||||
}
|
||||
else // default GP
|
||||
else
|
||||
{
|
||||
grandprixinfo.gamespeed = (cv_kartspeed.value == KARTSPEED_AUTO ? KARTSPEED_NORMAL : cv_kartspeed.value);
|
||||
grandprixinfo.masterbots = false;
|
||||
|
||||
if (option_skill)
|
||||
if (mapheaderinfo[newmapnum-1] &&
|
||||
mapheaderinfo[newmapnum-1]->typeoflevel & TOL_SPECIAL) // Special Stage
|
||||
{
|
||||
const char *masterstr = "Master";
|
||||
const char *nightmarestr = "NIGHTMARE";
|
||||
const char *skillname = COM_Argv(option_skill + 1);
|
||||
INT32 newskill = -1;
|
||||
INT32 j;
|
||||
grandprixinfo.gp = false;
|
||||
bossinfo.boss = false;
|
||||
|
||||
if (!strcasecmp(masterstr, skillname))
|
||||
specialStage.active = true;
|
||||
specialStage.encore = newencoremode;
|
||||
}
|
||||
else // default GP
|
||||
{
|
||||
grandprixinfo.gamespeed = (cv_kartspeed.value == KARTSPEED_AUTO ? KARTSPEED_NORMAL : cv_kartspeed.value);
|
||||
grandprixinfo.masterbots = false;
|
||||
|
||||
if (option_skill)
|
||||
{
|
||||
newskill = KARTGP_MASTER;
|
||||
}
|
||||
else if (!strcasecmp(nightmarestr, skillname))
|
||||
{
|
||||
newskill = KARTGP_NIGHTMARE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; kartspeed_cons_t[j].strvalue; j++)
|
||||
const char *skillname = COM_Argv(option_skill + 1);
|
||||
INT32 newskill = -1;
|
||||
INT32 j;
|
||||
|
||||
for (j = 0; gpdifficulty_cons_t[j].strvalue; j++)
|
||||
{
|
||||
if (!strcasecmp(kartspeed_cons_t[j].strvalue, skillname))
|
||||
if (!strcasecmp(gpdifficulty_cons_t[j].strvalue, skillname))
|
||||
{
|
||||
newskill = (INT16)kartspeed_cons_t[j].value;
|
||||
newskill = (INT16)gpdifficulty_cons_t[j].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!kartspeed_cons_t[j].strvalue) // reached end of the list with no match
|
||||
if (!gpdifficulty_cons_t[j].strvalue) // reached end of the list with no match
|
||||
{
|
||||
INT32 num = atoi(COM_Argv(option_skill + 1)); // assume they gave us a skill number, which is okay too
|
||||
if (num >= KARTSPEED_EASY && num <= KARTGP_NIGHTMARE)
|
||||
newskill = (INT16)num;
|
||||
}
|
||||
|
||||
if (newskill != -1)
|
||||
{
|
||||
if (newskill == KARTGP_MASTER)
|
||||
{
|
||||
grandprixinfo.gamespeed = KARTSPEED_HARD;
|
||||
grandprixinfo.masterbots = true;
|
||||
}
|
||||
else if (newskill == KARTGP_NIGHTMARE)
|
||||
{
|
||||
grandprixinfo.gamespeed = KARTSPEED_EXPERT;
|
||||
grandprixinfo.masterbots = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandprixinfo.gamespeed = newskill;
|
||||
grandprixinfo.masterbots = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newskill != -1)
|
||||
{
|
||||
if (newskill == KARTGP_MASTER)
|
||||
{
|
||||
grandprixinfo.gamespeed = KARTSPEED_HARD;
|
||||
grandprixinfo.masterbots = true;
|
||||
}
|
||||
else if (newskill == KARTGP_NIGHTMARE)
|
||||
{
|
||||
grandprixinfo.gamespeed = KARTSPEED_EXPERT;
|
||||
grandprixinfo.masterbots = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandprixinfo.gamespeed = newskill;
|
||||
grandprixinfo.masterbots = false;
|
||||
}
|
||||
}
|
||||
grandprixinfo.encore = newencoremode;
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.roundnum = 0;
|
||||
grandprixinfo.cup = NULL;
|
||||
grandprixinfo.wonround = false;
|
||||
|
||||
bossinfo.boss = false;
|
||||
specialStage.active = false;
|
||||
|
||||
grandprixinfo.initalize = true;
|
||||
}
|
||||
|
||||
grandprixinfo.encore = newencoremode;
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.roundnum = 0;
|
||||
grandprixinfo.cup = NULL;
|
||||
grandprixinfo.wonround = false;
|
||||
|
||||
bossinfo.boss = false;
|
||||
|
||||
grandprixinfo.initalize = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4504,7 +4511,7 @@ void Schedule_Run(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
// Don't engage in automation while in a restricted context.
|
||||
return;
|
||||
|
|
@ -4640,7 +4647,7 @@ void Automate_Run(automateEvents_t type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
// Don't engage in automation while in a restricted context.
|
||||
return;
|
||||
|
|
@ -5428,7 +5435,12 @@ void ItemFinder_OnChange(void)
|
|||
*/
|
||||
static void PointLimit_OnChange(void)
|
||||
{
|
||||
// Don't allow pointlimit in Single Player/Co-Op/Race!
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't allow pointlimit in non-pointlimited gametypes!
|
||||
if (server && Playing() && !(gametyperules & GTR_POINTLIMIT))
|
||||
{
|
||||
if (cv_pointlimit.value)
|
||||
|
|
@ -5443,7 +5455,7 @@ static void PointLimit_OnChange(void)
|
|||
cv_pointlimit.value,
|
||||
cv_pointlimit.value > 1 ? "s" : "");
|
||||
}
|
||||
else if (netgame || multiplayer)
|
||||
else
|
||||
CONS_Printf(M_GetText("Point limit disabled\n"));
|
||||
}
|
||||
|
||||
|
|
@ -5478,26 +5490,40 @@ UINT32 secretextratime = 0;
|
|||
*/
|
||||
static void TimeLimit_OnChange(void)
|
||||
{
|
||||
// Don't allow timelimit in Single Player/Co-Op/Race!
|
||||
if (server && Playing() && cv_timelimit.value != 0 && (bossinfo.boss || !(gametyperules & GTR_TIMELIMIT)))
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
CV_SetValue(&cv_timelimit, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cv_timelimit.value != 0)
|
||||
if (gamestate == GS_LEVEL && leveltime < starttime)
|
||||
{
|
||||
CONS_Printf(M_GetText("Rounds will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003
|
||||
timelimitintics = cv_timelimit.value * (60*TICRATE);
|
||||
if (cv_timelimit.value)
|
||||
{
|
||||
CONS_Printf(M_GetText("Time limit has been set to %d minute%s.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Time limit has been disabled.\n"));
|
||||
}
|
||||
|
||||
// Note the deliberate absence of any code preventing
|
||||
// pointlimit and timelimit from being set simultaneously.
|
||||
// Some people might like to use them together. It works.
|
||||
}
|
||||
timelimitintics = cv_timelimit.value * (60*TICRATE);
|
||||
extratimeintics = secretextratime = 0;
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
DRPC_UpdatePresence();
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cv_timelimit.value)
|
||||
{
|
||||
CONS_Printf(M_GetText("Time limit will be %d minute%s next round.\n"), cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s");
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Printf(M_GetText("Time limit will be disabled next round.\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adjusts certain settings to match a changed gametype.
|
||||
|
|
@ -5523,7 +5549,7 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
}
|
||||
// Only do the following as the server, not as remote admin.
|
||||
// There will always be a server, and this only needs to be done once.
|
||||
if (server && (multiplayer || netgame))
|
||||
if (server && multiplayer)
|
||||
{
|
||||
if (!cv_timelimit.changed) // user hasn't changed limits
|
||||
{
|
||||
|
|
@ -5534,27 +5560,6 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
CV_SetValue(&cv_pointlimit, pointlimits[gametype]);
|
||||
}
|
||||
}
|
||||
/* -- no longer useful
|
||||
else if (!multiplayer && !netgame)
|
||||
{
|
||||
G_SetGametype(GT_RACE);
|
||||
}
|
||||
*/
|
||||
|
||||
// reset timelimit and pointlimit in race/coop, prevent stupid cheats
|
||||
if (server)
|
||||
{
|
||||
if (!(gametyperules & GTR_TIMELIMIT))
|
||||
{
|
||||
if (cv_timelimit.value)
|
||||
CV_SetValue(&cv_timelimit, 0);
|
||||
}
|
||||
if (!(gametyperules & GTR_POINTLIMIT))
|
||||
{
|
||||
if (cv_pointlimit.value)
|
||||
CV_SetValue(&cv_pointlimit, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// don't retain teams in other modes or between changes from ctf to team match.
|
||||
// also, stop any and all forms of team scrambling that might otherwise take place.
|
||||
|
|
@ -7313,6 +7318,11 @@ static void Command_ShowTime_f(void)
|
|||
// SRB2Kart: On change messages
|
||||
static void NumLaps_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (gamestate == GS_LEVEL)
|
||||
{
|
||||
numlaps = K_RaceLapCount(gamemap - 1);
|
||||
|
|
@ -7341,12 +7351,12 @@ static void NumLaps_OnChange(void)
|
|||
|
||||
static void KartFrantic_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (leveltime < starttime)
|
||||
if (gamestate == GS_LEVEL && leveltime < starttime)
|
||||
{
|
||||
CONS_Printf(M_GetText("Frantic items has been set to %s.\n"), cv_kartfrantic.value ? M_GetText("on") : M_GetText("off"));
|
||||
franticitems = (boolean)cv_kartfrantic.value;
|
||||
|
|
@ -7359,19 +7369,12 @@ static void KartFrantic_OnChange(void)
|
|||
|
||||
static void KartSpeed_OnChange(void)
|
||||
{
|
||||
if (!M_SecretUnlocked(SECRET_HARDSPEED) && (cv_kartspeed.value == KARTSPEED_HARD || cv_kartspeed.value == KARTSPEED_EXPERT))
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (leveltime < starttime && cv_kartspeed.value != KARTSPEED_AUTO)
|
||||
if (gamestate == GS_LEVEL && leveltime < starttime && cv_kartspeed.value != KARTSPEED_AUTO)
|
||||
{
|
||||
CONS_Printf(M_GetText("Race speed has been changed to \"%s\".\n"), cv_kartspeed.string);
|
||||
gamespeed = (UINT8)cv_kartspeed.value;
|
||||
|
|
@ -7391,7 +7394,7 @@ static void KartBattleSpeed_OnChange(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7409,7 +7412,7 @@ static void KartBattleSpeed_OnChange(void)
|
|||
|
||||
static void KartEncore_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7419,7 +7422,7 @@ static void KartEncore_OnChange(void)
|
|||
|
||||
static void KartComeback_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7442,7 +7445,7 @@ static void KartEliminateLast_OnChange(void)
|
|||
|
||||
static void KartRings_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7459,7 +7462,7 @@ static void KartRings_OnChange(void)
|
|||
|
||||
static void KartPurpleDrift_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7492,7 +7495,7 @@ static void KartPurpleDrift_OnChange(void)
|
|||
|
||||
static void KartStacking_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7525,7 +7528,7 @@ static void KartStacking_OnChange(void)
|
|||
|
||||
static void KartChaining_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7558,7 +7561,7 @@ static void KartChaining_OnChange(void)
|
|||
|
||||
static void KartSlipdash_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7591,7 +7594,7 @@ static void KartSlipdash_OnChange(void)
|
|||
|
||||
static void KartSlopeBoost_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7624,7 +7627,7 @@ static void KartSlopeBoost_OnChange(void)
|
|||
|
||||
static void KartDrafting_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7657,7 +7660,7 @@ static void KartDrafting_OnChange(void)
|
|||
|
||||
static void KartAirDrop_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7690,7 +7693,7 @@ static void KartAirDrop_OnChange(void)
|
|||
|
||||
static void KartItemLitter_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7723,7 +7726,7 @@ static void KartItemLitter_OnChange(void)
|
|||
|
||||
static void KartAntiBump_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7747,7 +7750,7 @@ static void KartAntiBump_OnChange(void)
|
|||
|
||||
static void KartItemBreaker_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7769,7 +7772,7 @@ static void KartItemBreaker_OnChange(void)
|
|||
|
||||
static void KartInvinType_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -7787,7 +7790,7 @@ static void KartInvinType_OnChange(void)
|
|||
|
||||
static void KartBumpSpark_OnChange(void)
|
||||
{
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(false) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugdistribution,
|
|||
extern consvar_t cv_kartdebugshrink;
|
||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize, cv_kartdebugdirector;
|
||||
extern consvar_t cv_kartdebugwaypoints, cv_kartdebuglap, cv_kartdebugbot, cv_kartdebugcluster, cv_kartdebugrings;
|
||||
extern consvar_t cv_gptest;
|
||||
|
||||
extern consvar_t cv_itemfinder;
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,9 @@ typedef enum
|
|||
khud_lapanimation, // Used to show the lap start wing logo animation
|
||||
khud_laphand, // Lap hand gfx to use; 0 = none, 1 = :ok_hand:, 2 = :thumbs_up:, 3 = :thumps_down:
|
||||
|
||||
// Big text
|
||||
khud_finish, // Set when completing a round
|
||||
|
||||
// Camera
|
||||
khud_boostcam, // Camera push forward on boost
|
||||
khud_destboostcam, // Ditto
|
||||
|
|
|
|||
|
|
@ -3632,7 +3632,15 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
|
|||
}
|
||||
else if (fastcmp(word, "LEVELLIST"))
|
||||
{
|
||||
cup->numlevels = 0;
|
||||
while (cup->numlevels > 0)
|
||||
{
|
||||
cup->numlevels--;
|
||||
Z_Free(cup->levellist[cup->numlevels]);
|
||||
cup->levellist[cup->numlevels] = NULL;
|
||||
if (cup->cachedlevels[cup->numlevels] == NEXTMAP_INVALID)
|
||||
continue;
|
||||
mapheaderinfo[cup->cachedlevels[cup->numlevels]]->cup = NULL;
|
||||
}
|
||||
|
||||
tmp = strtok(word2,",");
|
||||
do {
|
||||
|
|
@ -3649,11 +3657,13 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
|
|||
}
|
||||
else if (fastcmp(word, "BONUSGAME"))
|
||||
{
|
||||
Z_Free(cup->levellist[CUPCACHE_BONUS]);
|
||||
cup->levellist[CUPCACHE_BONUS] = Z_StrDup(word2);
|
||||
cup->cachedlevels[CUPCACHE_BONUS] = NEXTMAP_INVALID;
|
||||
}
|
||||
else if (fastcmp(word, "SPECIALSTAGE"))
|
||||
{
|
||||
Z_Free(cup->levellist[CUPCACHE_SPECIAL]);
|
||||
cup->levellist[CUPCACHE_SPECIAL] = Z_StrDup(word2);
|
||||
cup->cachedlevels[CUPCACHE_SPECIAL] = NEXTMAP_INVALID;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -533,6 +533,11 @@ extern int compuncommitted;
|
|||
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
|
||||
//#define PAPER_COLLISIONCORRECTION
|
||||
|
||||
#ifdef DEVELOP
|
||||
// Easily make it so that overtime works offline
|
||||
#define TESTOVERTIMEINFREEPLAY
|
||||
#endif
|
||||
|
||||
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
|
||||
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
|
||||
/// on the bright side it fixes some weird issues with translucent walls
|
||||
|
|
|
|||
|
|
@ -530,6 +530,7 @@ enum TypeOfLevel
|
|||
TOL_RACE = 0x0001, ///< Race
|
||||
TOL_BATTLE = 0x0002, ///< Battle
|
||||
TOL_BOSS = 0x0004, ///< Boss (variant of battle, but forbidden)
|
||||
TOL_SPECIAL = 0x0008, ///< Special Stage (variant of race, but forbidden)
|
||||
|
||||
// Compat
|
||||
TOL_COMPAT1 = 0x0008, ///< For compat. Handles all the unused kart v1 types.
|
||||
|
|
|
|||
|
|
@ -1876,10 +1876,8 @@ void F_EndCutScene(void)
|
|||
F_StartGameEvaluation();
|
||||
else if (cutnum == introtoplay-1)
|
||||
D_StartTitle();
|
||||
else if (nextmap < NEXTMAP_SPECIAL)
|
||||
G_NextLevel();
|
||||
else
|
||||
G_EndGame();
|
||||
G_NextLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
236
src/g_game.c
236
src/g_game.c
|
|
@ -59,6 +59,7 @@
|
|||
#include "k_color.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "k_bot.h"
|
||||
#include "k_odds.h"
|
||||
#include "doomstat.h"
|
||||
|
|
@ -2709,6 +2710,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
INT32 nextcheck; // Distace to Next Legacy Checkpoint
|
||||
|
||||
INT32 exiting;
|
||||
INT32 khudfinish;
|
||||
INT32 khudcardanimation;
|
||||
INT16 totalring;
|
||||
UINT8 laps;
|
||||
|
|
@ -2825,6 +2827,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
latestlap = 0;
|
||||
roundscore = 0;
|
||||
exiting = 0;
|
||||
khudfinish = 0;
|
||||
khudcardanimation = 0;
|
||||
starpostx =0;
|
||||
starposty = 0;
|
||||
|
|
@ -2835,7 +2838,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
starposttime = 0;
|
||||
prevcheck = 0;
|
||||
nextcheck = 0;
|
||||
xtralife = 0;
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
|
|
@ -2883,7 +2885,16 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
roundscore = players[player].roundscore;
|
||||
|
||||
exiting = players[player].exiting;
|
||||
khudcardanimation = (exiting > 0) ? players[player].karthud[khud_cardanimation] : 0;
|
||||
if (exiting > 0)
|
||||
{
|
||||
khudfinish = players[player].karthud[khud_finish];
|
||||
khudcardanimation = players[player].karthud[khud_cardanimation];
|
||||
}
|
||||
else
|
||||
{
|
||||
khudfinish = 0;
|
||||
khudcardanimation = 0;
|
||||
}
|
||||
|
||||
starpostx = players[player].starpostx;
|
||||
starposty = players[player].starposty;
|
||||
|
|
@ -2961,6 +2972,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->nextcheck = nextcheck;
|
||||
|
||||
p->exiting = exiting;
|
||||
p->karthud[khud_finish] = khudfinish;
|
||||
p->karthud[khud_cardanimation] = khudcardanimation;
|
||||
|
||||
p->laps = laps;
|
||||
|
|
@ -3798,6 +3810,7 @@ tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = {
|
|||
{"RACE",TOL_RACE},
|
||||
{"BATTLE",TOL_BATTLE},
|
||||
{"BOSS",TOL_BOSS},
|
||||
{"SPECIAL",TOL_SPECIAL},
|
||||
{"TV",TOL_TV},
|
||||
|
||||
// Compat stuff
|
||||
|
|
@ -4324,7 +4337,7 @@ static void G_UpdateVisited(void)
|
|||
return;
|
||||
|
||||
// Update visitation flags
|
||||
maprecord_t *record = G_AllocateMapRecord(G_BuildMapName(gamemap));
|
||||
maprecord_t *record = G_AllocateMapRecord(G_BuildMapName(prevmap+1));
|
||||
record->visited |= MV_BEATEN;
|
||||
if (encoremode == true)
|
||||
record->visited |= MV_ENCORE;
|
||||
|
|
@ -4372,6 +4385,7 @@ static void G_HandleSaveLevel(void)
|
|||
|
||||
static INT16 G_GetNextMap(boolean advancemap)
|
||||
{
|
||||
boolean spec = G_IsSpecialStage(prevmap+1);
|
||||
INT32 i;
|
||||
INT16 newmap, curmap = gamestate == GS_LEVEL ? gamemap-1 : prevmap;
|
||||
|
||||
|
|
@ -4383,20 +4397,104 @@ static INT16 G_GetNextMap(boolean advancemap)
|
|||
}
|
||||
else if (grandprixinfo.gp == true)
|
||||
{
|
||||
if (grandprixinfo.roundnum == 0 || grandprixinfo.cup == NULL) // Single session
|
||||
// G: oh dear, this whole GP block has loads of side effects...
|
||||
// for now, just repeat the same map for "map +"
|
||||
// you're not supposed to use that in GP anyways
|
||||
if (!advancemap || // ...right?
|
||||
grandprixinfo.roundnum == 0 || grandprixinfo.cup == NULL) // Single session
|
||||
{
|
||||
newmap = curmap; // Same map
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map
|
||||
INT32 lastgametype = gametype;
|
||||
|
||||
// If we're in a GP event, don't immediately follow it up with another.
|
||||
// I also suspect this will not work with online GP so I'm gonna prevent it right now.
|
||||
// The server might have to communicate eventmode (alongside other GP data) in XD_MAP later.
|
||||
if (netgame || grandprixinfo.eventmode != GPEVENT_NONE)
|
||||
{
|
||||
grandprixinfo.eventmode = GPEVENT_NONE;
|
||||
|
||||
G_SetGametype(GT_RACE);
|
||||
if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype);
|
||||
|
||||
specialStage.active = false;
|
||||
bossinfo.boss = false;
|
||||
}
|
||||
// Special stage
|
||||
else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
|
||||
{
|
||||
INT16 totaltotalring = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
if (players[i].bot)
|
||||
continue;
|
||||
totaltotalring += players[i].totalring;
|
||||
}
|
||||
|
||||
if (totaltotalring >= 50)
|
||||
{
|
||||
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_SPECIAL];
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
|
||||
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_SPECIAL|TOL_BOSS|TOL_BATTLE))
|
||||
{
|
||||
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
||||
newmap = cupLevelNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (grandprixinfo.roundnum == (grandprixinfo.cup->numlevels+1)/2) // 3 for a 5-map cup
|
||||
{
|
||||
// todo any other condition?
|
||||
{
|
||||
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS];
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
|
||||
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE))
|
||||
{
|
||||
grandprixinfo.eventmode = GPEVENT_BONUS;
|
||||
newmap = cupLevelNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grandprixinfo.eventmode != GPEVENT_NONE)
|
||||
{
|
||||
// nextmap is set above
|
||||
const INT32 newtol = mapheaderinfo[newmap]->typeoflevel;
|
||||
|
||||
if (newtol & TOL_SPECIAL)
|
||||
{
|
||||
specialStage.active = true;
|
||||
specialStage.encore = grandprixinfo.encore;
|
||||
}
|
||||
else //(if newtol & (TOL_BATTLE|TOL_BOSS)) -- safe to assume??
|
||||
{
|
||||
G_SetGametype(GT_BATTLE);
|
||||
if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype);
|
||||
if (newtol & TOL_BOSS)
|
||||
{
|
||||
K_ResetBossInfo();
|
||||
bossinfo.boss = true;
|
||||
bossinfo.encore = grandprixinfo.encore;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map
|
||||
{
|
||||
newmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proceed to next map
|
||||
const INT32 cupLevelNum =grandprixinfo.cup->cachedlevels[grandprixinfo.roundnum];
|
||||
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[grandprixinfo.roundnum];
|
||||
|
||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||
{
|
||||
|
|
@ -4478,14 +4576,7 @@ static INT16 G_GetNextMap(boolean advancemap)
|
|||
// Didn't get a nextmap before reaching the end?
|
||||
if (gettingresult != 2)
|
||||
{
|
||||
if (marathonmode)
|
||||
{
|
||||
newmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
else
|
||||
{
|
||||
newmap = NEXTMAP_TITLE;
|
||||
}
|
||||
newmap = NEXTMAP_CEREMONY; // ceremonymap
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -4513,19 +4604,39 @@ static INT16 G_GetNextMap(boolean advancemap)
|
|||
newmap = cm;
|
||||
}
|
||||
|
||||
if (advancemap && !marathonmode)
|
||||
if (advancemap && K_CanChangeRules(true))
|
||||
{
|
||||
if (cv_advancemap.value == 0) // Stay on same map.
|
||||
switch (cv_advancemap.value)
|
||||
{
|
||||
newmap = curmap;
|
||||
}
|
||||
else if (cv_advancemap.value == 2) // Go to random map.
|
||||
{
|
||||
newmap = G_RandMap(G_TOLFlag(gametype), curmap, 0, 0, NULL);
|
||||
}
|
||||
else if (nextmap >= NEXTMAP_SPECIAL) // Loop back around
|
||||
{
|
||||
newmap = G_GetFirstMapOfGametype(gametype);
|
||||
case 0: // Stay on same map.
|
||||
newmap = curmap;
|
||||
break;
|
||||
case 3: // Voting screen.
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (players[i].spectator)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (i != MAXPLAYERS)
|
||||
{
|
||||
newmap = NEXTMAP_VOTING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case 2: // Go to random map.
|
||||
newmap = G_RandMap(G_TOLFlag(gametype), curmap, 0, 0, NULL);
|
||||
break;
|
||||
default:
|
||||
if (newmap >= NEXTMAP_SPECIAL) // Loop back around
|
||||
{
|
||||
newmap = G_GetFirstMapOfGametype(gametype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4534,6 +4645,9 @@ static INT16 G_GetNextMap(boolean advancemap)
|
|||
if (newmap == NEXTMAP_INVALID || (newmap < NEXTMAP_SPECIAL && (newmap >= nummapheaders || !mapheaderinfo[newmap] || mapheaderinfo[newmap]->lumpnum == LUMPERROR)))
|
||||
I_Error("G_GetNextMap: Internal map ID %d not found (nummapheaders = %d)\n", newmap, nummapheaders);
|
||||
|
||||
if (!spec)
|
||||
lastmap = newmap;
|
||||
|
||||
return newmap;
|
||||
}
|
||||
|
||||
|
|
@ -4543,8 +4657,6 @@ static INT16 G_GetNextMap(boolean advancemap)
|
|||
static void G_DoCompleted(void)
|
||||
{
|
||||
INT32 i, j = 0;
|
||||
boolean spec = G_IsSpecialStage(gamemap);
|
||||
SINT8 powertype = K_UsingPowerLevels();
|
||||
|
||||
if (modeattacking && pausedelay)
|
||||
pausedelay = 0;
|
||||
|
|
@ -4587,8 +4699,9 @@ static void G_DoCompleted(void)
|
|||
}
|
||||
}
|
||||
|
||||
// See Y_StartIntermission timer handling
|
||||
if ((gametyperules & GTR_CIRCUIT) && ((multiplayer && demo.playback) || j == r_splitscreen+1) && (!K_CanChangeRules(false) || cv_inttime.value > 0))
|
||||
// play some generic music if there's no win/cool/lose music going on (for exitlevel commands)
|
||||
if ((gametyperules & GTR_CIRCUIT) && ((multiplayer && demo.playback) || j == r_splitscreen+1) && (cv_inttime.value > 0))
|
||||
{
|
||||
S_ChangeMusicInternal("racent", true);
|
||||
S_ShowMusicCredit(-30*FRACUNIT, 5*TICRATE, V_SNAPTOTOP);
|
||||
|
|
@ -4603,14 +4716,8 @@ static void G_DoCompleted(void)
|
|||
|
||||
if (!demo.playback)
|
||||
{
|
||||
nextmap = G_GetNextMap(true);
|
||||
|
||||
// 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);
|
||||
K_SetPowerLevelScrambles(K_UsingPowerLevels());
|
||||
}
|
||||
|
||||
// If the current gametype has no intermission screen set, then don't start it.
|
||||
|
|
@ -4621,7 +4728,6 @@ static void G_DoCompleted(void)
|
|||
|| (intertype == int_none))
|
||||
{
|
||||
G_UpdateVisited();
|
||||
G_HandleSaveLevel();
|
||||
G_AfterIntermission();
|
||||
}
|
||||
else
|
||||
|
|
@ -4629,7 +4735,6 @@ static void G_DoCompleted(void)
|
|||
G_SetGamestate(GS_INTERMISSION);
|
||||
Y_StartIntermission();
|
||||
G_UpdateVisited();
|
||||
G_HandleSaveLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4663,14 +4768,17 @@ void G_AfterIntermission(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (gamestate != GS_VOTING)
|
||||
{
|
||||
nextmap = G_GetNextMap(true);
|
||||
G_HandleSaveLevel();
|
||||
}
|
||||
|
||||
if (grandprixinfo.gp == true && 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)
|
||||
G_NextLevel();
|
||||
else
|
||||
G_EndGame();
|
||||
G_NextLevel();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4682,25 +4790,15 @@ void G_AfterIntermission(void)
|
|||
//
|
||||
void G_NextLevel(void)
|
||||
{
|
||||
if (gamestate != GS_VOTING)
|
||||
if (nextmap >= NEXTMAP_SPECIAL)
|
||||
{
|
||||
if ((cv_advancemap.value == 3) && grandprixinfo.gp == false && bossinfo.boss == false && !modeattacking && !skipstats && (multiplayer || netgame))
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
{
|
||||
gameaction = ga_startvote;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forceresetplayers = false;
|
||||
deferencoremode = (cv_kartencore.value == 1);
|
||||
G_EndGame();
|
||||
return;
|
||||
}
|
||||
|
||||
forceresetplayers = false;
|
||||
deferencoremode = (cv_kartencore.value == 1);
|
||||
|
||||
gameaction = ga_worlddone;
|
||||
}
|
||||
|
||||
|
|
@ -4727,7 +4825,11 @@ static void G_DoWorldDone(void)
|
|||
static void G_DoStartVote(void)
|
||||
{
|
||||
if (server)
|
||||
{
|
||||
if (gamestate == GS_VOTING)
|
||||
I_Error("G_DoStartVote: NEXTMAP_VOTING causes recursive vote!");
|
||||
D_SetupVote();
|
||||
}
|
||||
gameaction = ga_nothing;
|
||||
}
|
||||
|
||||
|
|
@ -4805,8 +4907,12 @@ static void G_DoContinued(void)
|
|||
// when something new is added.
|
||||
void G_EndGame(void)
|
||||
{
|
||||
if (demo.recording && (modeattacking || demo.savemode != DSM_NOTSAVING))
|
||||
G_SaveDemo();
|
||||
// Handle voting
|
||||
if (nextmap == NEXTMAP_VOTING)
|
||||
{
|
||||
gameaction = ga_startvote;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only do evaluation and credits in singleplayer contexts
|
||||
if (!netgame && grandprixinfo.gp == true)
|
||||
|
|
@ -5492,6 +5598,7 @@ cleanup:
|
|||
void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ssplayers, boolean FLS)
|
||||
{
|
||||
UINT16 color = SKINCOLOR_NONE;
|
||||
INT32 dogametype;
|
||||
|
||||
paused = false;
|
||||
|
||||
|
|
@ -5502,8 +5609,17 @@ void G_DeferedInitNew(boolean pencoremode, INT32 map, INT32 pickedchar, UINT8 ss
|
|||
|
||||
G_ResetRandMapBuffer();
|
||||
|
||||
if ((modeattacking == ATTACKING_ITEMBREAK) || (bossinfo.boss == true))
|
||||
{
|
||||
dogametype = GT_BATTLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dogametype = GT_RACE;
|
||||
}
|
||||
|
||||
// this leave the actual game if needed
|
||||
SV_StartSinglePlayerServer();
|
||||
SV_StartSinglePlayerServer(dogametype, false);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ typedef enum
|
|||
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_VOTING = INT16_MAX-5,
|
||||
NEXTMAP_INVALID = INT16_MAX-6, // Always last
|
||||
NEXTMAP_SPECIAL = NEXTMAP_INVALID
|
||||
} nextmapspecial_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -2510,7 +2510,7 @@ static void HU_DrawRankings(void)
|
|||
|
||||
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
|
||||
{
|
||||
if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0)
|
||||
if ((gametyperules & GTR_TIMELIMIT) && timelimitintics > 0)
|
||||
{
|
||||
UINT32 timeval = (timelimitintics + starttime + 1 - leveltime);
|
||||
if (timeval > timelimitintics+1)
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ void K_CheckBumpers(void)
|
|||
winnerscoreadd -= players[i].roundscore;
|
||||
}
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(true) == false)
|
||||
{
|
||||
if (nobumpers)
|
||||
{
|
||||
|
|
@ -274,7 +274,8 @@ void K_CheckBumpers(void)
|
|||
if (!itembreaker && cv_kartitembreaker.value)
|
||||
{
|
||||
// Reset map to turn on battle capsules
|
||||
D_MapChange(gamemap, gametype, encoremode, true, 0, false, false);
|
||||
if (server)
|
||||
D_MapChange(gamemap, gametype, encoremode, true, 0, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -486,22 +487,13 @@ void K_SpawnPlayerBattleBumpers(player_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
void K_BattleInit(UINT8 numPlayers)
|
||||
void K_BattleInit(boolean singleplayercontext)
|
||||
{
|
||||
if ((gametyperules & GTR_ITEMBREAKER) && !itembreaker && !bossinfo.boss)
|
||||
if ((gametyperules & GTR_ITEMBREAKER) && singleplayercontext && !itembreaker && !bossinfo.boss)
|
||||
{
|
||||
if (modeattacking != ATTACKING_ITEMBREAK)
|
||||
{
|
||||
if (!cv_kartitembreaker.value)
|
||||
goto afteritembreaker;
|
||||
|
||||
if (numPlayers > 1)
|
||||
goto afteritembreaker;
|
||||
}
|
||||
|
||||
itembreaker = true;
|
||||
if (!(K_CanChangeRules(true) && !cv_kartitembreaker.value))
|
||||
itembreaker = true;
|
||||
}
|
||||
afteritembreaker:
|
||||
|
||||
if (gametyperules & GTR_BUMPERS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ void K_CheckBumpers(void);
|
|||
UINT8 K_NumEmeralds(player_t *player);
|
||||
void K_RunPaperItemSpawners(void);
|
||||
void K_SpawnPlayerBattleBumpers(player_t *p);
|
||||
void K_BattleInit(UINT8 numPlayers);
|
||||
void K_BattleInit(boolean singleplayercontext);
|
||||
void K_RespawnBattleBoxes(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ void K_UpdateMatchRaceBots(void)
|
|||
{
|
||||
difficulty = 0;
|
||||
}
|
||||
else if (K_CanChangeRules() == false)
|
||||
else if (K_CanChangeRules(true) == false)
|
||||
{
|
||||
difficulty = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
#include "k_specialstage.h"
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
#include "g_game.h"
|
||||
|
|
@ -737,18 +738,12 @@ void K_PlayerLoseLife(player_t *player)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_CanChangeRules(void)
|
||||
boolean K_CanChangeRules(boolean allowdemos)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_CanChangeRules(void)
|
||||
boolean K_CanChangeRules(boolean allowdemos)
|
||||
{
|
||||
if (demo.playback)
|
||||
{
|
||||
// We've already got our important settings!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (grandprixinfo.gp == true && grandprixinfo.roundnum > 0)
|
||||
{
|
||||
// Don't cheat the rules of the GP!
|
||||
|
|
@ -761,11 +756,29 @@ boolean K_CanChangeRules(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (modeattacking == true)
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
// Don't cheat special stages!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (marathonmode)
|
||||
{
|
||||
// Don't cheat the endurance challenge!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (modeattacking != ATTACKING_NONE)
|
||||
{
|
||||
// Don't cheat the rules of Time Trials!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!allowdemos && demo.playback)
|
||||
{
|
||||
// We've already got our important settings!
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,19 +171,19 @@ void K_PlayerLoseLife(player_t *player);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_CanChangeRules(void);
|
||||
boolean K_CanChangeRules(boolean allowdemos);
|
||||
|
||||
Returns whenver or not the server is allowed
|
||||
to change the game rules.
|
||||
|
||||
Input Arguments:-
|
||||
None
|
||||
allowdemos - permits this behavior during demo playback
|
||||
|
||||
Return:-
|
||||
true if can change important gameplay rules, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_CanChangeRules(void);
|
||||
boolean K_CanChangeRules(boolean allowdemos);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
255
src/k_hud.c
255
src/k_hud.c
|
|
@ -1628,37 +1628,38 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
// TIME_Y = 6; // 6
|
||||
|
||||
tic_t worktime;
|
||||
boolean dontdraw = false;
|
||||
boolean overtime = false;
|
||||
UINT8 *textcolor = 0;
|
||||
fixed_t jitter = 0;
|
||||
boolean overtime = false, fastjitter = false, countdown = false;
|
||||
UINT8 *textcolor = NULL;
|
||||
|
||||
INT32 splitflags = 0;
|
||||
if (!mode)
|
||||
{
|
||||
splitflags = V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_SPLITSCREEN;
|
||||
|
||||
#ifndef TESTOVERTIMEINFREEPLAY
|
||||
if (itembreaker) // capsules override any time limit settings
|
||||
;
|
||||
else
|
||||
#endif
|
||||
if (bossinfo.boss == true)
|
||||
;
|
||||
else if (timelimitintics > 0 && (gametyperules & GTR_TIMELIMIT)) // TODO
|
||||
{
|
||||
if (drawtime >= (timelimitintics - 5*TICRATE) && ((drawtime*4)/TICRATE) % 2 == 0)
|
||||
{
|
||||
dontdraw = true;
|
||||
}
|
||||
|
||||
if (timelimitintics > 0)
|
||||
{
|
||||
if (drawtime >= timelimitintics)
|
||||
{
|
||||
overtime = true;
|
||||
// drawtime = 0;
|
||||
jitter = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawtime = timelimitintics - drawtime;
|
||||
countdown = true;
|
||||
if (secretextratime)
|
||||
;
|
||||
else if (extratimeintics)
|
||||
{
|
||||
jitter = 2;
|
||||
fastjitter = true;
|
||||
}
|
||||
else if (drawtime <= 5*TICRATE)
|
||||
{
|
||||
jitter = ((drawtime <= 3*TICRATE) && (((drawtime-1) % TICRATE) >= TICRATE-2))
|
||||
? 3 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1675,10 +1676,26 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
|
||||
worktime = drawtime/(60*TICRATE);
|
||||
|
||||
if (drawtime != UINT32_MAX && worktime >= 100)
|
||||
{
|
||||
jitter = 1;
|
||||
fastjitter = true;
|
||||
worktime = 99;
|
||||
drawtime = (100*(60*TICRATE))-1;
|
||||
}
|
||||
|
||||
if (fastjitter)
|
||||
{
|
||||
jitter *= R_GetTimeFrac(RTF_LEVEL) * (leveltime & 1 ? 1 : -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (drawtime & 2) jitter = -jitter;
|
||||
jitter *= !!(drawtime & 1) != countdown ? FRACUNIT - R_GetTimeFrac(RTF_LEVEL) : R_GetTimeFrac(RTF_LEVEL);
|
||||
}
|
||||
|
||||
if (mode && drawtime == UINT32_MAX)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("--'--\"--"));
|
||||
else if (dontdraw) // overtime flash
|
||||
;
|
||||
else if (overtime)
|
||||
{
|
||||
if (((drawtime*2)/TICRATE) % 2 == 0)
|
||||
|
|
@ -1690,66 +1707,47 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
|
|||
textcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_ORANGE, GTC_CACHE);
|
||||
}
|
||||
|
||||
V_DrawStringScaledEx(
|
||||
(TIME_X + 33) << FRACBITS,
|
||||
(TIME_Y + 3) << FRACBITS,
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
splitflags,
|
||||
textcolor,
|
||||
KART_FONT,
|
||||
va("OVERTIME!")
|
||||
);
|
||||
}
|
||||
else if (worktime < 100) // 99:99:99 only
|
||||
{
|
||||
// zero minute
|
||||
if (worktime < 10)
|
||||
const char *overtimestr = "OVERTIME";
|
||||
for (UINT8 i = 0; i < strlen(overtimestr); i++)
|
||||
{
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("0"));
|
||||
// minutes time 0 __ __
|
||||
V_DrawKartString(TX+12, TY+3, splitflags, va("%d", worktime));
|
||||
V_DrawStringScaledEx(
|
||||
(TIME_X + 33 + 12*i + (i == 6 ? -4 : i == 7 ? -1 : 0)) << FRACBITS,
|
||||
((TIME_Y + 3) << FRACBITS) + (i & 1 ? jitter : -jitter),
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
FRACUNIT,
|
||||
splitflags,
|
||||
textcolor,
|
||||
KART_FONT,
|
||||
va("%c", overtimestr[i])
|
||||
);
|
||||
}
|
||||
// minutes time 0 __ __
|
||||
else
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
else
|
||||
{
|
||||
// minutes time 00 __ __
|
||||
V_DrawKartStringAtFixed(TX<<FRACBITS, ((TY+3)<<FRACBITS)+jitter, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartStringAtFixed((TX+12)<<FRACBITS, ((TY+3)<<FRACBITS)-jitter, splitflags, va("%d", worktime%10));
|
||||
|
||||
// apostrophe location _'__ __
|
||||
V_DrawKartString(TX+24, TY+3, splitflags, va("'"));
|
||||
|
||||
worktime = (drawtime/TICRATE % 60);
|
||||
|
||||
// zero second _ 0_ __
|
||||
if (worktime < 10)
|
||||
{
|
||||
V_DrawKartString(TX+36, TY+3, splitflags, va("0"));
|
||||
// seconds time _ _0 __
|
||||
V_DrawKartString(TX+48, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
// zero second _ 00 __
|
||||
else
|
||||
V_DrawKartString(TX+36, TY+3, splitflags, va("%d", worktime));
|
||||
// seconds time _ 00 __
|
||||
V_DrawKartStringAtFixed((TX+36)<<FRACBITS, ((TY+3)<<FRACBITS)+jitter, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartStringAtFixed((TX+48)<<FRACBITS, ((TY+3)<<FRACBITS)-jitter, splitflags, va("%d", worktime%10));
|
||||
|
||||
// quotation mark location _ __"__
|
||||
V_DrawKartString(TX+60, TY+3, splitflags, va("\""));
|
||||
|
||||
worktime = G_TicsToCentiseconds(drawtime);
|
||||
|
||||
// zero tick _ __ 0_
|
||||
if (worktime < 10)
|
||||
{
|
||||
V_DrawKartString(TX+72, TY+3, splitflags, va("0"));
|
||||
// tics _ __ _0
|
||||
V_DrawKartString(TX+84, TY+3, splitflags, va("%d", worktime));
|
||||
}
|
||||
// zero tick _ __ 00
|
||||
else
|
||||
V_DrawKartString(TX+72, TY+3, splitflags, va("%d", worktime));
|
||||
// tics _ __ 00
|
||||
V_DrawKartStringAtFixed((TX+72)<<FRACBITS, ((TY+3)<<FRACBITS)+jitter, splitflags, va("%d", worktime/10));
|
||||
V_DrawKartStringAtFixed((TX+84)<<FRACBITS, ((TY+3)<<FRACBITS)-jitter, splitflags, va("%d", worktime%10));
|
||||
}
|
||||
else if ((drawtime/TICRATE) & 1)
|
||||
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
|
||||
|
||||
if ((modeattacking || (mode == 1)) && G_EmblemsEnabled()) // emblem time!
|
||||
{
|
||||
|
|
@ -4290,7 +4288,7 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
mobj = players[i].mo;
|
||||
|
||||
if (players[i].mo->health <= 0 && players[i].pflags & PF_NOCONTEST)
|
||||
if (mobj->health <= 0 && (players[i].pflags & PF_NOCONTEST))
|
||||
{
|
||||
workingPic = kp_nocontestminimap;
|
||||
|
||||
|
|
@ -4308,10 +4306,13 @@ static void K_drawKartMinimap(void)
|
|||
iconoffsets.y = heighthalf - workingPic->topoffset - adjusty;
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
|
||||
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
mobj = mobj->tracer;
|
||||
}
|
||||
else
|
||||
{
|
||||
skin = ((skin_t*)players[i].mo->skin)-skins;
|
||||
skin = ((skin_t*)mobj->skin)-skins;
|
||||
|
||||
workingPic = faceprefix[skin][FACE_MINIMAP];
|
||||
|
||||
|
|
@ -4343,7 +4344,7 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
colorizeplayer = players[i].mo->colorized;
|
||||
colorizeplayer = mobj->colorized;
|
||||
|
||||
if ((players[i].invincibilitytimer) && ((K_InvincibilityGradient(players[i].invincibilitytimer) > (FRACUNIT/2)) || (K_GetKartInvinType() == KARTINVIN_LEGACY)))
|
||||
{
|
||||
|
|
@ -4352,10 +4353,10 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
usecolor = players[i].mo->color;
|
||||
usecolor = mobj->color;
|
||||
}
|
||||
|
||||
if (players[i].mo->color)
|
||||
if (usecolor)
|
||||
{
|
||||
if (colorizeplayer)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, usecolor, GTC_CACHE);
|
||||
|
|
@ -4524,7 +4525,7 @@ static void K_drawKartMinimap(void)
|
|||
|
||||
mobj = players[localplayers[i]].mo;
|
||||
|
||||
if (players[localplayers[i]].mo->health <= 0 && players[localplayers[i]].pflags & PF_NOCONTEST)
|
||||
if (mobj->health <= 0 && (players[localplayers[i]].pflags & PF_NOCONTEST))
|
||||
{
|
||||
workingPic = kp_nocontestminimap;
|
||||
|
||||
|
|
@ -4544,10 +4545,13 @@ static void K_drawKartMinimap(void)
|
|||
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
|
||||
|
||||
nocontest = true;
|
||||
|
||||
if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer))
|
||||
mobj = mobj->tracer;
|
||||
}
|
||||
else
|
||||
{
|
||||
skin = ((skin_t*)players[localplayers[i]].mo->skin)-skins;
|
||||
skin = ((skin_t*)mobj->skin)-skins;
|
||||
|
||||
workingPic = faceprefix[skin][FACE_MINIMAP];
|
||||
|
||||
|
|
@ -4578,7 +4582,7 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
colorizeplayer = players[localplayers[i]].mo->colorized;
|
||||
colorizeplayer = mobj->colorized;
|
||||
|
||||
if ((players[localplayers[i]].invincibilitytimer) &&
|
||||
((K_InvincibilityGradient(players[localplayers[i]].invincibilitytimer) >
|
||||
|
|
@ -4589,10 +4593,10 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
usecolor = players[localplayers[i]].mo->color;
|
||||
usecolor = mobj->color;
|
||||
}
|
||||
|
||||
if (players[localplayers[i]].mo->color)
|
||||
if (usecolor)
|
||||
{
|
||||
if (colorizeplayer)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, usecolor, GTC_CACHE);
|
||||
|
|
@ -4701,6 +4705,56 @@ static void K_drawKartMinimap(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void K_drawKartFinish(void)
|
||||
{
|
||||
INT32 timer, minsplitstationary, pnum = 0, splitflags = V_SPLITSCREEN;
|
||||
patch_t **kptodraw;
|
||||
|
||||
{
|
||||
timer = stplyr->karthud[khud_finish];
|
||||
kptodraw = kp_racefinish;
|
||||
minsplitstationary = 2;
|
||||
}
|
||||
|
||||
if (!timer || timer > 2*TICRATE)
|
||||
return;
|
||||
|
||||
if ((timer % (2*5)) / 5) // blink
|
||||
pnum = 1;
|
||||
|
||||
if (r_splitscreen > 0)
|
||||
pnum += (r_splitscreen > 1) ? 2 : 4;
|
||||
|
||||
if (r_splitscreen >= minsplitstationary) // 3/4p, stationary FIN
|
||||
{
|
||||
V_DrawScaledPatch(STCD_X - (SHORT(kptodraw[pnum]->width)/2), STCD_Y - (SHORT(kptodraw[pnum]->height)/2), splitflags, kptodraw[pnum]);
|
||||
return;
|
||||
}
|
||||
|
||||
//else -- 1/2p, scrolling FINISH
|
||||
{
|
||||
INT32 x, xval, ox, interpx, pwidth;
|
||||
|
||||
x = ((vid.width<<FRACBITS)/vid.dupx);
|
||||
xval = (SHORT(kptodraw[pnum]->width)<<FRACBITS);
|
||||
|
||||
pwidth = max(xval, x);
|
||||
|
||||
x = ((TICRATE - timer) * pwidth) / TICRATE;
|
||||
ox = ((TICRATE - (timer - 1)) * pwidth) / TICRATE;
|
||||
|
||||
interpx = R_InterpolateFixed(ox, x);
|
||||
|
||||
if (r_splitscreen && stplyrnum == 1)
|
||||
interpx = -interpx;
|
||||
|
||||
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (pwidth / 2),
|
||||
(STCD_Y<<FRACBITS) - (SHORT(kptodraw[pnum]->height)<<(FRACBITS-1)),
|
||||
FRACUNIT,
|
||||
splitflags, kptodraw[pnum], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawKartStartCountdown(void)
|
||||
{
|
||||
INT32 pnum = 0;
|
||||
|
|
@ -4745,51 +4799,6 @@ static void K_drawKartStartCountdown(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void K_drawKartFinish(void)
|
||||
{
|
||||
INT32 pnum = 0, splitflags = V_SPLITSCREEN;
|
||||
|
||||
if (!stplyr->karthud[khud_cardanimation] || stplyr->karthud[khud_cardanimation] >= 2*TICRATE)
|
||||
return;
|
||||
|
||||
if ((stplyr->karthud[khud_cardanimation] % (2*5)) / 5) // blink
|
||||
pnum = 1;
|
||||
|
||||
if (r_splitscreen > 1) // 3/4p, stationary FIN
|
||||
{
|
||||
pnum += 2;
|
||||
V_DrawScaledPatch(STCD_X - (kp_racefinish[pnum]->width/2), STCD_Y - (kp_racefinish[pnum]->height/2), splitflags, kp_racefinish[pnum]);
|
||||
return;
|
||||
}
|
||||
|
||||
//else -- 1/2p, scrolling FINISH
|
||||
{
|
||||
INT32 x, xval, ox, interpx, pwidth;
|
||||
|
||||
if (r_splitscreen) // wide splitscreen
|
||||
pnum += 4;
|
||||
|
||||
x = ((vid.width<<FRACBITS)/vid.dupx);
|
||||
xval = (kp_racefinish[pnum]->width)<<FRACBITS;
|
||||
|
||||
pwidth = max(xval, x);
|
||||
|
||||
x = ((TICRATE - stplyr->karthud[khud_cardanimation]) * pwidth) / TICRATE;
|
||||
ox = ((TICRATE - (stplyr->karthud[khud_cardanimation] - 1)) * pwidth) / TICRATE;
|
||||
|
||||
|
||||
interpx = R_InterpolateFixed(ox, x);
|
||||
|
||||
if (r_splitscreen && stplyrnum == 1)
|
||||
interpx = -interpx;
|
||||
|
||||
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (pwidth / 2),
|
||||
(STCD_Y<<FRACBITS) - (kp_racefinish[pnum]->height<<(FRACBITS-1)),
|
||||
FRACUNIT,
|
||||
splitflags, kp_racefinish[pnum], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void K_drawBattleFullscreen(void)
|
||||
{
|
||||
INT32 cardanim = stplyr->karthud[khud_cardanimation] << FRACBITS;
|
||||
|
|
@ -4850,7 +4859,7 @@ static void K_drawBattleFullscreen(void)
|
|||
{
|
||||
if (stplyrnum == 0)
|
||||
V_DrawFadeScreen(0xFF00, 16);
|
||||
if (stplyr->exiting < 6*TICRATE && !stplyr->spectator)
|
||||
if (stplyr->exiting <= 6*TICRATE && !stplyr->spectator)
|
||||
{
|
||||
patch_t *p = kp_battlecool;
|
||||
|
||||
|
|
@ -4861,8 +4870,8 @@ static void K_drawBattleFullscreen(void)
|
|||
|
||||
V_DrawFixedPatch(x<<FRACBITS, y, scale, splitflags, p, NULL);
|
||||
}
|
||||
else
|
||||
K_drawKartFinish();
|
||||
|
||||
K_drawKartFinish();
|
||||
}
|
||||
else if (stplyr->bumper <= 0 && stplyr->karmadelay && comeback && !stplyr->spectator && drawcomebacktimer)
|
||||
{
|
||||
|
|
|
|||
75
src/k_kart.c
75
src/k_kart.c
|
|
@ -65,6 +65,7 @@
|
|||
#include "k_grandprix.h"
|
||||
#include "k_cluster.hpp"
|
||||
#include "k_odds.h"
|
||||
#include "k_specialstage.h"
|
||||
|
||||
#include "h_timers.h"
|
||||
#include "blan/b_soc.h"
|
||||
|
|
@ -100,26 +101,34 @@ vector3_t clusterpoint, clusterdtf;
|
|||
void K_TimerInit(void)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT8 numPlayers = 0;//, numspec = 0;
|
||||
UINT8 numPlayers = 0;
|
||||
boolean domodeattack = ((modeattacking != ATTACKING_NONE)
|
||||
|| (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE));
|
||||
|
||||
starttime = introtime = 0;
|
||||
|
||||
if (!bossinfo.boss)
|
||||
if (specialStage.active == true)
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
K_InitSpecialStage();
|
||||
}
|
||||
else if (bossinfo.boss == false)
|
||||
{
|
||||
if (!domodeattack)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
continue;
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
numPlayers++;
|
||||
}
|
||||
|
||||
if (players[i].spectator == true)
|
||||
if (numPlayers < 2)
|
||||
{
|
||||
//numspec++;
|
||||
continue;
|
||||
domodeattack = true;
|
||||
}
|
||||
|
||||
numPlayers++;
|
||||
}
|
||||
|
||||
introtime = (108) + 5; // 108 for rotation, + 5 for white fade
|
||||
|
|
@ -131,15 +140,14 @@ void K_TimerInit(void)
|
|||
}
|
||||
}
|
||||
|
||||
// NOW you can try to setup Item Breaker, if there's not enough players for a match
|
||||
K_BattleInit(numPlayers);
|
||||
timelimitintics = extratimeintics = secretextratime = 0; // G: restore K_TimerReset?
|
||||
K_BattleInit(domodeattack);
|
||||
|
||||
timelimitintics = extratimeintics = secretextratime = 0;
|
||||
if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss)
|
||||
if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss && !modeattacking)
|
||||
{
|
||||
if (!K_CanChangeRules())
|
||||
if (!K_CanChangeRules(true))
|
||||
{
|
||||
if (grandprixinfo.gp)
|
||||
if (itembreaker)
|
||||
{
|
||||
timelimitintics = (20*TICRATE);
|
||||
}
|
||||
|
|
@ -414,6 +422,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_saltyhop);
|
||||
|
||||
CV_RegisterVar(&cv_naturalcamera);
|
||||
CV_RegisterVar(&cv_gptest);
|
||||
}
|
||||
|
||||
//}
|
||||
|
|
@ -6310,9 +6319,8 @@ void K_KartPlayerHUDUpdate(player_t *player)
|
|||
if (player->karthud[khud_tauntvoices])
|
||||
player->karthud[khud_tauntvoices]--;
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
if (gametyperules & GTR_RINGS)
|
||||
{
|
||||
|
||||
if ((K_RingsActive() == true))
|
||||
{
|
||||
if (player->pflags & PF_RINGLOCK)
|
||||
|
|
@ -6322,16 +6330,20 @@ void K_KartPlayerHUDUpdate(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->exiting)
|
||||
{
|
||||
if (player->karthud[khud_finish] <= 2*TICRATE)
|
||||
player->karthud[khud_finish]++;
|
||||
}
|
||||
else
|
||||
player->karthud[khud_finish] = 0;
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && (player->exiting || player->karmadelay))
|
||||
{
|
||||
if (player->exiting)
|
||||
{
|
||||
if (player->exiting < 6*TICRATE)
|
||||
player->karthud[khud_cardanimation] += ((164-player->karthud[khud_cardanimation])/8)+1;
|
||||
else if (player->exiting == 6*TICRATE)
|
||||
player->karthud[khud_cardanimation] = 0;
|
||||
else if (player->karthud[khud_cardanimation] < 2*TICRATE)
|
||||
player->karthud[khud_cardanimation]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6346,11 +6358,6 @@ void K_KartPlayerHUDUpdate(player_t *player)
|
|||
if (player->karthud[khud_cardanimation] < 0)
|
||||
player->karthud[khud_cardanimation] = 0;
|
||||
}
|
||||
else if ((gametyperules & GTR_CIRCUIT) && player->exiting)
|
||||
{
|
||||
if (player->karthud[khud_cardanimation] < 2*TICRATE)
|
||||
player->karthud[khud_cardanimation]++;
|
||||
}
|
||||
else
|
||||
player->karthud[khud_cardanimation] = 0;
|
||||
|
||||
|
|
@ -6599,7 +6606,15 @@ UINT8 K_RaceLapCount(INT16 mapNum)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (cv_numlaps.value == -1 || modeattacking != ATTACKING_NONE)
|
||||
if ((grandprixinfo.gp == true)
|
||||
&& (grandprixinfo.eventmode == GPEVENT_NONE)
|
||||
&& cv_gptest.value)
|
||||
{
|
||||
// For testing
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (cv_numlaps.value == -1 || K_CanChangeRules(true) == false)
|
||||
{
|
||||
// Use map default
|
||||
return mapheaderinfo[mapNum]->numlaps;
|
||||
|
|
@ -7330,8 +7345,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
|
||||
K_UpdateTripwire(player);
|
||||
|
||||
K_KartPlayerHUDUpdate(player);
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->waterskip = 0;
|
||||
|
||||
|
|
@ -11396,7 +11409,7 @@ boolean K_NotFreePlay(void)
|
|||
UINT8 i;
|
||||
UINT8 nump = 0;
|
||||
|
||||
if (K_CanChangeRules() == false)
|
||||
if (K_CanChangeRules(true) == false)
|
||||
{
|
||||
// Rounds with direction are never FREE PLAY.
|
||||
return true;
|
||||
|
|
|
|||
32
src/k_odds.c
32
src/k_odds.c
|
|
@ -152,6 +152,38 @@ static UINT8 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
|
|||
{ 5, 1 } // Jawz x2
|
||||
};
|
||||
|
||||
static UINT8 K_KartItemOddsSpecial[NUMKARTRESULTS-1][4] =
|
||||
{
|
||||
//M N O P
|
||||
{ 1, 1, 0, 0 }, // Sneaker
|
||||
{ 0, 0, 0, 0 }, // Rocket Sneaker
|
||||
{ 0, 0, 0, 0 }, // Invincibility
|
||||
{ 0, 0, 0, 0 }, // Banana
|
||||
{ 0, 0, 0, 0 }, // Eggman Monitor
|
||||
{ 1, 1, 0, 0 }, // Orbinaut
|
||||
{ 1, 1, 0, 0 }, // Jawz
|
||||
{ 0, 0, 0, 0 }, // Mine
|
||||
{ 0, 0, 0, 0 }, // Ballhog
|
||||
{ 0, 0, 0, 1 }, // Self-Propelled Bomb
|
||||
{ 0, 0, 0, 0 }, // Grow
|
||||
{ 0, 0, 0, 0 }, // Shrink
|
||||
{ 0, 0, 0, 0 }, // Thunder Shield
|
||||
{ 0, 0, 0, 0 }, // Hyudoro
|
||||
{ 0, 0, 0, 0 }, // Pogo Spring
|
||||
{ 0, 0, 0, 0 }, // Kitchen Sink
|
||||
{ 0, 0, 0, 0 }, // Super Ring
|
||||
{ 0, 0, 0, 0 }, // Land Mine
|
||||
{ 0, 0, 0, 0 }, // Bubble Shield
|
||||
{ 0, 0, 0, 0 }, // Flame Shield
|
||||
{ 0, 1, 1, 0 }, // Sneaker x2
|
||||
{ 0, 0, 1, 1 }, // Sneaker x3
|
||||
{ 0, 0, 0, 0 }, // Banana x3
|
||||
{ 0, 0, 0, 0 }, // Banana x10
|
||||
{ 0, 1, 1, 0 }, // Orbinaut x3
|
||||
{ 0, 0, 1, 1 }, // Orbinaut x4
|
||||
{ 0, 0, 1, 1 } // Jawz x2
|
||||
};
|
||||
|
||||
// Cooldown time table; contains both base (index 0) and current (index 1)
|
||||
// times. Base times are in seconds, current times are in tics.
|
||||
tic_t ItemBGone[NUMKARTRESULTS][2] =
|
||||
|
|
|
|||
139
src/k_specialstage.c
Normal file
139
src/k_specialstage.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_specialstage.c
|
||||
/// \brief Special Stage game logic
|
||||
|
||||
#include "k_specialstage.h"
|
||||
#include "doomdef.h"
|
||||
#include "d_player.h"
|
||||
#include "g_game.h"
|
||||
#include "p_local.h"
|
||||
#include "k_kart.h"
|
||||
#include "s_sound.h"
|
||||
#include "st_stuff.h"
|
||||
#include "z_zone.h"
|
||||
#include "k_waypoint.h"
|
||||
|
||||
struct specialStage specialStage;
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_ResetSpecialStage(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_ResetSpecialStage(void)
|
||||
{
|
||||
memset(&specialStage, 0, sizeof(struct specialStage));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_InitSpecialStage(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_InitSpecialStage(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
specialStage.beamDist = UINT32_MAX; // TODO: make proper value
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
|
||||
if (playeringame[i] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player = &players[i];
|
||||
if (player->spectator == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Rolling start? lol
|
||||
P_InstaThrust(player->mo, player->mo->angle, K_GetKartSpeed(player, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_MoveExitBeam(void)
|
||||
|
||||
Updates the exit beam.
|
||||
--------------------------------------------------*/
|
||||
static void K_MoveExitBeam(void)
|
||||
{
|
||||
UINT32 moveDist = 0;
|
||||
INT32 i;
|
||||
|
||||
if (leveltime <= 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
moveDist = (8 * mapobjectscale) / FRACUNIT;
|
||||
|
||||
if (specialStage.beamDist <= moveDist)
|
||||
{
|
||||
specialStage.beamDist = 0;
|
||||
|
||||
// TODO: Fail Special Stage
|
||||
}
|
||||
else
|
||||
{
|
||||
specialStage.beamDist -= moveDist;
|
||||
}
|
||||
|
||||
// Find players who are now outside of the level.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
|
||||
if (playeringame[i] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player = &players[i];
|
||||
|
||||
if (player->spectator == true
|
||||
|| player->exiting > 0
|
||||
|| (player->pflags & PF_NOCONTEST))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->distancetofinish > specialStage.beamDist)
|
||||
{
|
||||
P_DoTimeOver(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_TickSpecialStage(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_TickSpecialStage(void)
|
||||
{
|
||||
if (specialStage.active == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
K_MoveExitBeam();
|
||||
}
|
||||
62
src/k_specialstage.h
Normal file
62
src/k_specialstage.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2022 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2022 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_specialstage.h
|
||||
/// \brief Special Stage game logic
|
||||
|
||||
#ifndef __K_SPECIALSTAGE__
|
||||
#define __K_SPECIALSTAGE__
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct specialStage
|
||||
{
|
||||
boolean active; ///< If true, then we are in a special stage
|
||||
boolean encore; ///< Copy of encore, just to make sure you can't cheat it with cvars
|
||||
|
||||
UINT32 beamDist; ///< Where the exit beam is.
|
||||
mobj_t *capsule; ///< The Chaos Emerald capsule.
|
||||
} specialStage;
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_ResetSpecialStage(void);
|
||||
|
||||
Resets Special Stage information to a clean slate.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_ResetSpecialStage(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_InitSpecialStage(void);
|
||||
|
||||
Initializes Special Stage data on map load.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_InitSpecialStage(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_TickSpecialStage(void);
|
||||
|
||||
Updates Special Stage data each frame.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_TickSpecialStage(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -221,7 +221,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
|||
lua_pushinteger(L, redscore);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"timelimit")) {
|
||||
lua_pushinteger(L, cv_timelimit.value);
|
||||
lua_pushinteger(L, timelimitintics);
|
||||
return 1;
|
||||
} else if (fastcmp(word,"pointlimit")) {
|
||||
lua_pushinteger(L, cv_pointlimit.value);
|
||||
|
|
|
|||
|
|
@ -464,10 +464,9 @@ static CV_PossibleValue_t dummybumpspark_cons_t[] = {{BUMPSPARK_NONE, "Off"},
|
|||
{0, NULL}};
|
||||
consvar_t cv_dummyattackingbumpspark = CVAR_INIT ("dummyattackingbumpspark", "Off", CV_HIDEN|CV_CALL|CV_NOINIT, dummybumpspark_cons_t, Nextmap_OnChange);
|
||||
|
||||
static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{KARTSPEED_EASY, "Easy"}, {KARTSPEED_NORMAL, "Normal"}, {KARTSPEED_HARD, "Hard"}, {KARTSPEED_EXPERT, "Expert"}, {KARTGP_MASTER, "Master"}, {KARTGP_NIGHTMARE, "Nightmare"}, {0, NULL}};
|
||||
static CV_PossibleValue_t dummygpcup_cons_t[50] = {{1, "TEMP"}}; // A REALLY BIG NUMBER, SINCE THIS IS TEMP UNTIL NEW MENUS
|
||||
|
||||
consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HIDEN, dummygpdifficulty_cons_t, NULL);
|
||||
consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HIDEN, gpdifficulty_cons_t, NULL);
|
||||
consvar_t cv_dummygpencore = CVAR_INIT ("dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL);
|
||||
consvar_t cv_dummygpcup = CVAR_INIT ("dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL);
|
||||
|
||||
|
|
@ -6551,8 +6550,7 @@ INT32 MR_StartServer(INT32 choice)
|
|||
if (menustack[0] == MN_MP_SPLITSCREEN) // offline server
|
||||
{
|
||||
paused = false;
|
||||
SV_StartSinglePlayerServer();
|
||||
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
|
||||
SV_StartSinglePlayerServer(cv_newgametype.value, false);
|
||||
D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3335,9 +3335,12 @@ void A_AttractChase(void *thing)
|
|||
// Set attraction flag
|
||||
actor->cusval = 1;
|
||||
|
||||
if ((actor->tracer->player->itemtype == KITEM_THUNDERSHIELD
|
||||
if (
|
||||
actor->tracer->player && actor->tracer->health
|
||||
&& ((gametyperules & GTR_BUMPERS)
|
||||
|| (actor->tracer->player->itemtype == KITEM_THUNDERSHIELD
|
||||
&& RINGTOTAL(actor->tracer->player) < actor->tracer->player->ringmax
|
||||
&& !(actor->tracer->player->pflags & PF_RINGLOCK))
|
||||
&& !(actor->tracer->player->pflags & PF_RINGLOCK)))
|
||||
//&& P_CheckSight(actor, actor->tracer)
|
||||
)
|
||||
{
|
||||
|
|
|
|||
124
src/p_inter.c
124
src/p_inter.c
|
|
@ -991,14 +991,9 @@ void P_TouchStarPost(mobj_t *post, player_t *player, boolean snaptopost)
|
|||
player->starpostnum = post->health;
|
||||
}
|
||||
|
||||
// Easily make it so that overtime works offline
|
||||
#define TESTOVERTIMEINFREEPLAY
|
||||
|
||||
/** Checks if the level timer is over the timelimit and the round should end,
|
||||
* unless you are in overtime. In which case leveltime may stretch out beyond
|
||||
* timelimitintics and overtime's status will be checked here each tick.
|
||||
* Verify that the value of ::cv_timelimit is greater than zero before
|
||||
* calling this function.
|
||||
*
|
||||
* \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials
|
||||
*/
|
||||
|
|
@ -1006,25 +1001,73 @@ void P_CheckTimeLimit(void)
|
|||
{
|
||||
INT32 i, k;
|
||||
|
||||
if (!cv_timelimit.value)
|
||||
if (exitcountdown)
|
||||
return;
|
||||
|
||||
if (!(multiplayer || netgame))
|
||||
if (!timelimitintics)
|
||||
return;
|
||||
|
||||
if (!(gametyperules & GTR_TIMELIMIT))
|
||||
if (leveltime < starttime)
|
||||
{
|
||||
if (secretextratime)
|
||||
secretextratime--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (itembreaker)
|
||||
return;
|
||||
INT32 timeleft = timelimitintics + starttime - leveltime;
|
||||
if (timeleft > 0)
|
||||
{
|
||||
if (secretextratime)
|
||||
{
|
||||
secretextratime--;
|
||||
timelimitintics++;
|
||||
}
|
||||
else if (extratimeintics)
|
||||
{
|
||||
timelimitintics++;
|
||||
if (leveltime & 1)
|
||||
;
|
||||
else
|
||||
{
|
||||
if (extratimeintics > 20)
|
||||
{
|
||||
extratimeintics -= 20;
|
||||
timelimitintics += 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
timelimitintics += extratimeintics;
|
||||
extratimeintics = 0;
|
||||
}
|
||||
S_StartSound(NULL, sfx_ptally);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timelimitintics > 60*TICRATE && !itembreaker)
|
||||
{
|
||||
if (timeleft == 60*TICRATE)
|
||||
S_StartSound(NULL, sfx_cdfm67); // guys it's a bell it's just like splatoon guys
|
||||
if (timeleft == 59*TICRATE)
|
||||
S_StartSound(NULL, sfx_bhurry); // hurry up :))))
|
||||
}
|
||||
|
||||
if (leveltime < (timelimitintics + starttime))
|
||||
// last five second countdown
|
||||
if (timeleft % TICRATE == 0)
|
||||
{
|
||||
if (timeleft <= 5*TICRATE)
|
||||
S_StartSound(NULL, sfx_kc35); // 5, 4
|
||||
if (timeleft <= 3*TICRATE)
|
||||
S_StartSound(NULL, sfx_kc3d); // 3, 2, 1
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (gameaction == ga_completed)
|
||||
return;
|
||||
|
||||
if (cv_overtime.value)
|
||||
if (!itembreaker && !grandprixinfo.gp && cv_overtime.value)
|
||||
{
|
||||
INT32 playerarray[MAXPLAYERS];
|
||||
INT32 tempplayer = 0;
|
||||
|
|
@ -1043,7 +1086,7 @@ void P_CheckTimeLimit(void)
|
|||
#ifdef TESTOVERTIMEINFREEPLAY
|
||||
if (timelimitintics > 0 && (gametyperules & GTR_TIMELIMIT) && startedInFreePlay)
|
||||
{
|
||||
return;
|
||||
goto overtimesound;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1085,23 +1128,33 @@ void P_CheckTimeLimit(void)
|
|||
|
||||
//End the round if the top players aren't tied.
|
||||
if (players[playerarray[0]].roundscore == players[playerarray[1]].roundscore)
|
||||
return;
|
||||
goto overtimesound;
|
||||
}
|
||||
else
|
||||
{
|
||||
//In team match and CTF, determining a tie is much simpler. =P
|
||||
if (redscore == bluescore)
|
||||
return;
|
||||
goto overtimesound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
P_DoAllPlayersExit(0, false);
|
||||
return;
|
||||
|
||||
overtimesound:
|
||||
if (timeleft == 0)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k50); // overtime warning
|
||||
S_StartSound(NULL, sfx_s3k9d);
|
||||
}
|
||||
if (timeleft == -2*TICRATE)
|
||||
S_StartSoundAtVolume(NULL, sfx_s3k50, 128);
|
||||
if (timeleft == -4*TICRATE)
|
||||
S_StartSoundAtVolume(NULL, sfx_s3k50, 96);
|
||||
}
|
||||
|
||||
/** Checks if a player's score is over the pointlimit and the round should end.
|
||||
* Verify that the value of ::cv_pointlimit is greater than zero before
|
||||
* calling this function.
|
||||
*
|
||||
* \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials
|
||||
*/
|
||||
|
|
@ -1112,7 +1165,7 @@ void P_CheckPointLimit(void)
|
|||
if (exitcountdown)
|
||||
return;
|
||||
|
||||
if (!K_CanChangeRules())
|
||||
if (!K_CanChangeRules(true))
|
||||
return;
|
||||
|
||||
if (!cv_pointlimit.value)
|
||||
|
|
@ -1158,7 +1211,7 @@ boolean P_CheckRacers(void)
|
|||
{
|
||||
const boolean griefed = (spectateGriefed > 0);
|
||||
|
||||
boolean eliminateLast = (!K_CanChangeRules() && !demo.playback) || (cv_karteliminatelast.value != 0); // temp hack until this is ported properly
|
||||
boolean eliminateLast = (!K_CanChangeRules(true) || (cv_karteliminatelast.value != 0));
|
||||
boolean allHumansDone = true;
|
||||
//boolean allBotsDone = true;
|
||||
|
||||
|
|
@ -1277,7 +1330,7 @@ boolean P_CheckRacers(void)
|
|||
{
|
||||
tic_t countdown = 30*TICRATE; // 30 seconds left to finish, get going!
|
||||
|
||||
if (K_CanChangeRules() == true)
|
||||
if (K_CanChangeRules(true) == true)
|
||||
{
|
||||
// Custom timer
|
||||
countdown = cv_countdowntime.value * TICRATE;
|
||||
|
|
@ -1412,15 +1465,39 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
|
||||
if (itembreaker)
|
||||
{
|
||||
// G: uncommented this for funsies
|
||||
mobj_t * ring;
|
||||
angle_t dir = 0;
|
||||
if (inflictor)
|
||||
dir = R_PointToAngle2(inflictor->x, inflictor->y, target->x, target->y);
|
||||
else
|
||||
dir = R_PointToAngle2(source->x, source->y, target->x, target->y);
|
||||
for (UINT8 i = 0; i < 2; i++)
|
||||
{
|
||||
dir += (ANGLE_MAX/3);
|
||||
ring = P_SpawnMobj(target->x, target->y, target->z, MT_RING);
|
||||
ring->angle = dir;
|
||||
P_InstaThrust(ring, dir, 16*ring->scale);
|
||||
ring->momz = 8 * target->scale * P_MobjFlip(target);
|
||||
P_SetTarget(&ring->tracer, source);
|
||||
source->player->pickuprings++;
|
||||
}
|
||||
|
||||
target->flags2 |= MF2_BOSSFLEE;
|
||||
target->flags2 |= MF2_DONTRESPAWN;
|
||||
K_SpawnBattlePoints(source->player, NULL, 1);
|
||||
|
||||
// All targets busted!
|
||||
if (++numtargets >= nummapboxes)
|
||||
{
|
||||
P_DoAllPlayersExit(0, true);
|
||||
P_DoAllPlayersExit(0, (grandprixinfo.gp == true));
|
||||
}
|
||||
else if (timelimitintics)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s221);
|
||||
extratimeintics += 10*TICRATE;
|
||||
secretextratime = TICRATE/2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (cv_itemrespawn.value && modeattacking == ATTACKING_NONE && !itembreaker)
|
||||
|
|
@ -1591,6 +1668,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
|||
kart->old_y = target->old_y;
|
||||
kart->old_z = target->old_z;
|
||||
|
||||
if (target->player->pflags & PF_NOCONTEST)
|
||||
P_SetTarget(&target->tracer, kart);
|
||||
|
||||
if (damagetype != DMG_TIMEOVER)
|
||||
{
|
||||
kart->angle = flingangle + ANGLE_180;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@
|
|||
#include "doomstat.h" // MAXMUSNAMES
|
||||
#include "k_mapuser.h"
|
||||
#include "p_deepcopy.h"
|
||||
#include "k_specialstage.h"
|
||||
|
||||
#include "blan/b_soc.h"
|
||||
|
||||
|
|
|
|||
46
src/p_tick.c
46
src/p_tick.c
|
|
@ -42,6 +42,7 @@
|
|||
#include "acs/interface.h"
|
||||
#include "k_bot.h" // K_BotTicker
|
||||
#include "k_odds.h" // ItemBGone
|
||||
#include "k_specialstage.h"
|
||||
|
||||
#ifdef PARANOIA
|
||||
#include "deh_tables.h" // MOBJTYPE_LIST
|
||||
|
|
@ -752,6 +753,7 @@ void P_Ticker(boolean run)
|
|||
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
|
||||
{
|
||||
P_PlayerThink(&players[i]);
|
||||
K_KartPlayerHUDUpdate(&players[i]);
|
||||
|
||||
if (!players[i].spectator)
|
||||
p++;
|
||||
|
|
@ -838,48 +840,6 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
}
|
||||
|
||||
if (timelimitintics > 0)
|
||||
{
|
||||
// last minute
|
||||
if (timelimitintics > 60*TICRATE && leveltime == timelimitintics - 60*TICRATE + starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_cdfm67); // guys it's a bell it's just like splatoon guys
|
||||
}
|
||||
if (timelimitintics > 60*TICRATE && leveltime == timelimitintics - 59*TICRATE + starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_bhurry); // hurry up :))))
|
||||
}
|
||||
|
||||
// overtime
|
||||
if (gameaction != ga_completed && leveltime == timelimitintics + 1 + starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k50); // overtime warning
|
||||
S_StartSound(NULL, sfx_s3k9d);
|
||||
}
|
||||
if (gameaction != ga_completed && leveltime == timelimitintics + 2*TICRATE + starttime)
|
||||
{
|
||||
S_StartSoundAtVolume(NULL, sfx_s3k50, 128);
|
||||
}
|
||||
if (gameaction != ga_completed && leveltime == timelimitintics + 4*TICRATE + starttime)
|
||||
{
|
||||
S_StartSoundAtVolume(NULL, sfx_s3k50, 96);
|
||||
}
|
||||
|
||||
// last five second countdown
|
||||
if (leveltime == timelimitintics - 5 * TICRATE + starttime ||
|
||||
leveltime == timelimitintics - 4 * TICRATE + starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_kc35); // 5, 4
|
||||
}
|
||||
if (leveltime == timelimitintics - TICRATE + starttime ||
|
||||
leveltime == timelimitintics - 2 * TICRATE + starttime ||
|
||||
leveltime == timelimitintics - 3 * TICRATE + starttime)
|
||||
{
|
||||
S_StartSound(NULL, sfx_kc35);
|
||||
S_StartSound(NULL, sfx_kc3d); // 3, 2, 1
|
||||
}
|
||||
}
|
||||
|
||||
// Change timing of start music based on gametyperules
|
||||
{
|
||||
tic_t startingtime = (gametyperules & GTR_NOCOUNTDOWN) ? introtime : starttime;
|
||||
|
|
@ -961,6 +921,8 @@ void P_Ticker(boolean run)
|
|||
|
||||
K_BossInfoTicker();
|
||||
|
||||
K_TickSpecialStage();
|
||||
|
||||
if (gametyperules & GTR_WANTED)
|
||||
{
|
||||
if (wantedcalcdelay && --wantedcalcdelay <= 0)
|
||||
|
|
|
|||
173
src/p_user.c
173
src/p_user.c
|
|
@ -1311,7 +1311,8 @@ void P_DoPlayerExit(player_t *player, pflags_t flags)
|
|||
S_StartSound(player->mo, playerskin->soundsid[S_sfx[sfx_id].skinsound]);
|
||||
}
|
||||
|
||||
if (!K_CanChangeRules() || cv_inttime.value > 0)
|
||||
// See Y_StartIntermission timer handling
|
||||
if (!K_CanChangeRules(false) || cv_inttime.value > 0)
|
||||
P_EndingMusic(player);
|
||||
|
||||
if (P_CheckRacers())
|
||||
|
|
@ -3854,8 +3855,6 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
player->old_drawangle = player->drawangle;
|
||||
|
||||
player->pflags &= ~PF_HITFINISHLINE;
|
||||
|
||||
if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj))
|
||||
{
|
||||
P_SetTarget(&player->awayviewmobj, NULL); // remove awayviewmobj asap if invalid
|
||||
|
|
@ -4039,29 +4038,6 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
// check water content, set stuff in mobj
|
||||
P_MobjCheckWater(player->mo);
|
||||
|
||||
#ifndef SECTORSPECIALSAFTERTHINK
|
||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||
player->onconveyor = 0;
|
||||
// check special sectors : damage & secrets
|
||||
|
||||
if (!player->spectator)
|
||||
P_PlayerInSpecialSector(player);
|
||||
#endif
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
if (player->spectator)
|
||||
player->mo->renderflags |= RF_GHOSTLY;
|
||||
else
|
||||
player->mo->renderflags &= ~RF_GHOSTLYMASK;
|
||||
P_DeathThink(player);
|
||||
LUA_HookPlayer(player, HOOK(PlayerThink));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure spectators always have a score and ring count of 0.
|
||||
if (player->spectator)
|
||||
{
|
||||
|
|
@ -4162,8 +4138,91 @@ void P_PlayerThink(player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->flashing)
|
||||
|
||||
if (cmd->flags & TICCMD_TYPING)
|
||||
{
|
||||
/*
|
||||
typing_duration is slow to start and slow to stop.
|
||||
|
||||
typing_timer counts down a grace period before the player is not
|
||||
actually considered typing anymore.
|
||||
*/
|
||||
if (cmd->flags & TICCMD_KEYSTROKE)
|
||||
{
|
||||
/* speed up if we are typing quickly! */
|
||||
if (player->typing_duration > 0 && player->typing_timer > 12)
|
||||
{
|
||||
if (player->typing_duration < 16)
|
||||
{
|
||||
player->typing_duration = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* slows down a tiny bit as it approaches the next dot */
|
||||
const UINT8 step = (((player->typing_duration + 15) & ~15) -
|
||||
player->typing_duration) / 2;
|
||||
player->typing_duration += max(step, 4);
|
||||
}
|
||||
}
|
||||
|
||||
player->typing_timer = 15;
|
||||
}
|
||||
else if (player->typing_timer > 0)
|
||||
{
|
||||
player->typing_timer--;
|
||||
}
|
||||
|
||||
/* if we are in the grace period (including currently typing) */
|
||||
if (player->typing_timer + player->typing_duration > 0)
|
||||
{
|
||||
/* always end the cycle on two dots */
|
||||
if (player->typing_timer == 0 &&
|
||||
(player->typing_duration < 16 || player->typing_duration == 40))
|
||||
{
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
else if (player->typing_duration < 63)
|
||||
{
|
||||
player->typing_duration++;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_duration = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_timer = 0;
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
|
||||
player->pflags &= ~PF_HITFINISHLINE;
|
||||
|
||||
// check water content, set stuff in mobj
|
||||
P_MobjCheckWater(player->mo);
|
||||
|
||||
#ifndef SECTORSPECIALSAFTERTHINK
|
||||
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
|
||||
player->onconveyor = 0;
|
||||
// check special sectors : damage & secrets
|
||||
|
||||
if (!player->spectator)
|
||||
P_PlayerInSpecialSector(player);
|
||||
#endif
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
{
|
||||
if (player->spectator)
|
||||
player->mo->renderflags |= RF_GHOSTLY;
|
||||
else
|
||||
player->mo->renderflags &= ~RF_GHOSTLYMASK;
|
||||
P_DeathThink(player);
|
||||
LUA_HookPlayer(player, HOOK(PlayerThink));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((netgame || multiplayer) && player->spectator && !player->bot && cmd->buttons & BT_ATTACK && !player->flashing)
|
||||
{
|
||||
player->pflags ^= PF_WANTSTOJOIN;
|
||||
player->flashing = TICRATE/2 + 1;
|
||||
|
|
@ -4280,64 +4339,6 @@ void P_PlayerThink(player_t *player)
|
|||
player->mo->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
|
||||
if (cmd->flags & TICCMD_TYPING)
|
||||
{
|
||||
/*
|
||||
typing_duration is slow to start and slow to stop.
|
||||
|
||||
typing_timer counts down a grace period before the player is not
|
||||
actually considered typing anymore.
|
||||
*/
|
||||
if (cmd->flags & TICCMD_KEYSTROKE)
|
||||
{
|
||||
/* speed up if we are typing quickly! */
|
||||
if (player->typing_duration > 0 && player->typing_timer > 12)
|
||||
{
|
||||
if (player->typing_duration < 16)
|
||||
{
|
||||
player->typing_duration = 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* slows down a tiny bit as it approaches the next dot */
|
||||
const UINT8 step = (((player->typing_duration + 15) & ~15) -
|
||||
player->typing_duration) / 2;
|
||||
player->typing_duration += max(step, 4);
|
||||
}
|
||||
}
|
||||
|
||||
player->typing_timer = 15;
|
||||
}
|
||||
else if (player->typing_timer > 0)
|
||||
{
|
||||
player->typing_timer--;
|
||||
}
|
||||
|
||||
/* if we are in the grace period (including currently typing) */
|
||||
if (player->typing_timer + player->typing_duration > 0)
|
||||
{
|
||||
/* always end the cycle on two dots */
|
||||
if (player->typing_timer == 0 &&
|
||||
(player->typing_duration < 16 || player->typing_duration == 40))
|
||||
{
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
else if (player->typing_duration < 63)
|
||||
{
|
||||
player->typing_duration++;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_duration = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->typing_timer = 0;
|
||||
player->typing_duration = 0;
|
||||
}
|
||||
|
||||
K_KartPlayerThink(player, cmd); // SRB2kart
|
||||
|
||||
DoABarrelRoll(player);
|
||||
|
|
|
|||
|
|
@ -305,6 +305,8 @@ char * V_ScaledWordWrap(
|
|||
V__DrawDupxString (x,y,FRACUNIT,option,HU_FONT,string)
|
||||
#define V_DrawKartString( x,y,option,string ) \
|
||||
V__DrawDupxString (x,y,FRACUNIT,option,KART_FONT,string)
|
||||
#define V_DrawKartStringAtFixed( x,y,option,string ) \
|
||||
V__DrawOneScaleString (x,y,FRACUNIT,option,KART_FONT,string)
|
||||
void V_DrawCenteredString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
void V_DrawRightAlignedString(INT32 x, INT32 y, INT32 option, const char *string);
|
||||
|
||||
|
|
|
|||
|
|
@ -769,18 +769,8 @@ void Y_Ticker(void)
|
|||
P_DoTeamscrambling();
|
||||
}*/
|
||||
|
||||
// multiplayer uses timer (based on cv_inttime)
|
||||
if (timer)
|
||||
{
|
||||
if (!--timer)
|
||||
{
|
||||
Y_EndIntermission();
|
||||
G_AfterIntermission();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// single player is hardcoded to go away after awhile
|
||||
else if (intertic == endtic)
|
||||
if ((timer && !--timer)
|
||||
|| (intertic == endtic))
|
||||
{
|
||||
Y_EndIntermission();
|
||||
G_AfterIntermission();
|
||||
|
|
@ -869,8 +859,8 @@ void Y_Ticker(void)
|
|||
S_StartSound(NULL, (kaching ? sfx_chchng : sfx_ptally));
|
||||
Y_CalculateMatchData(2, Y_CompareRank);
|
||||
}
|
||||
else
|
||||
endtic = intertic + 3*TICRATE; // 3 second pause after end of tally
|
||||
/*else -- This is how to define an endtic, but we currently use timer for both SP and MP.
|
||||
endtic = intertic + 3*TICRATE;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -934,23 +924,32 @@ void Y_StartIntermission(void)
|
|||
powertype = K_UsingPowerLevels();
|
||||
|
||||
// determine the tic the intermission ends
|
||||
if (!multiplayer || demo.playback)
|
||||
// Technically cv_inttime is saved to demos... but this permits having extremely long timers for post-netgame chatting without stranding you on the intermission in netreplays.
|
||||
if (!K_CanChangeRules(false))
|
||||
{
|
||||
timer = ((nump >= 2) ? 10 : 5)*TICRATE;
|
||||
timer = 10*TICRATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer = cv_inttime.value*TICRATE;
|
||||
|
||||
if (!timer)
|
||||
timer = 1; // prevent a weird bug
|
||||
}
|
||||
|
||||
// determine the tic everybody's scores/PWR starts getting sorted
|
||||
sorttic = -1;
|
||||
if (multiplayer || nump >= 2)
|
||||
if (!timer)
|
||||
{
|
||||
sorttic = max((timer/2) - 2*TICRATE, 2*TICRATE); // 8 second pause after match results
|
||||
// Prevent a weird bug
|
||||
timer = 1;
|
||||
}
|
||||
else if (nump < 2 && !netgame)
|
||||
{
|
||||
// No PWR/global score, skip it
|
||||
timer /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Minimum two seconds for match results, then two second slideover approx halfway through
|
||||
sorttic = max((timer/2) - 2*TICRATE, 2*TICRATE);
|
||||
}
|
||||
|
||||
if (intermissiontypes[gametype] != int_none)
|
||||
|
|
@ -971,7 +970,7 @@ void Y_StartIntermission(void)
|
|||
case int_battle:
|
||||
case int_battletime:
|
||||
{
|
||||
if (cv_inttime.value > 0)
|
||||
if (timer > 1)
|
||||
{
|
||||
S_ChangeMusicInternal("racent", true); // loop it
|
||||
S_ShowMusicCredit(-30*FRACUNIT, 5*TICRATE, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue