mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
"Special Mode" (Sealed Stars) and "Versus Mode" (bosses) are now gametypes
* The existing structs are now exclusively for handling extra data.
* `specialStage` has been renamed to `specialstageinfo`, to reflect that it is not the sole arbiter.
* `specialstageinfo.valid` and `bossinfo.valid` are what must be checked before grabbing data from either struct.
* These are turned on when the gametype extra data is successfully initialised, not on map start.
* `K_InitBossHealthBar(...)` for `bossinfo.valid`
* `K_InitSpecialStage(void)` for `specialstageinfo.valid`
* `K_CanChangeRules(...)` no longer checks these
* No longer uses duplicate encore information.
* The map command (and -warp) now guesses gametype using a general `G_GuessGametypeByTOL(UINT32)` function
* Grabs the first gametype with an overlap between the requested TOL and the gametype's TOL.
* The cool Versus-specific intro is now checked via `K_CheckBossIntro()`.
This commit is contained in:
parent
d29e43f80d
commit
17dd15b998
29 changed files with 257 additions and 238 deletions
|
|
@ -54,7 +54,6 @@
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
#include "k_bot.h"
|
#include "k_bot.h"
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "s_sound.h" // sfx_syfail
|
#include "s_sound.h" // sfx_syfail
|
||||||
#include "m_cond.h" // netUnlocked
|
#include "m_cond.h" // netUnlocked
|
||||||
|
|
|
||||||
28
src/d_main.c
28
src/d_main.c
|
|
@ -72,7 +72,6 @@
|
||||||
|
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "m_random.h" // P_ClearRandom
|
#include "m_random.h" // P_ClearRandom
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
|
|
@ -969,12 +968,6 @@ void D_StartTitle(void)
|
||||||
// Reset GP
|
// Reset GP
|
||||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||||
|
|
||||||
// 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
|
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
|
||||||
maptol = 0;
|
maptol = 0;
|
||||||
|
|
||||||
|
|
@ -1204,13 +1197,14 @@ D_ConvertVersionNumbers (void)
|
||||||
//
|
//
|
||||||
void D_SRB2Main(void)
|
void D_SRB2Main(void)
|
||||||
{
|
{
|
||||||
INT32 i, p;
|
INT32 i, j, p;
|
||||||
#ifdef DEVELOP
|
#ifdef DEVELOP
|
||||||
INT32 pstartmap = 1; // default to first loaded map (Test Run)
|
INT32 pstartmap = 1; // default to first loaded map (Test Run)
|
||||||
#else
|
#else
|
||||||
INT32 pstartmap = 0; // default to random map (0 is not a valid map number)
|
INT32 pstartmap = 0; // default to random map (0 is not a valid map number)
|
||||||
#endif
|
#endif
|
||||||
boolean autostart = false;
|
boolean autostart = false;
|
||||||
|
INT32 newgametype = -1;
|
||||||
|
|
||||||
/* break the version string into version numbers, for netplay */
|
/* break the version string into version numbers, for netplay */
|
||||||
D_ConvertVersionNumbers();
|
D_ConvertVersionNumbers();
|
||||||
|
|
@ -1788,8 +1782,6 @@ void D_SRB2Main(void)
|
||||||
if (M_CheckParm("-gametype") && M_IsNextParm())
|
if (M_CheckParm("-gametype") && M_IsNextParm())
|
||||||
{
|
{
|
||||||
// from Command_Map_f
|
// from Command_Map_f
|
||||||
INT32 j;
|
|
||||||
INT16 newgametype = -1;
|
|
||||||
const char *sgametype = M_GetNextParm();
|
const char *sgametype = M_GetNextParm();
|
||||||
|
|
||||||
newgametype = G_GetGametypeByName(sgametype);
|
newgametype = G_GetGametypeByName(sgametype);
|
||||||
|
|
@ -1811,7 +1803,6 @@ void D_SRB2Main(void)
|
||||||
|
|
||||||
if (M_CheckParm("-skill") && M_IsNextParm())
|
if (M_CheckParm("-skill") && M_IsNextParm())
|
||||||
{
|
{
|
||||||
INT32 j;
|
|
||||||
INT16 newskill = -1;
|
INT16 newskill = -1;
|
||||||
const char *sskill = M_GetNextParm();
|
const char *sskill = M_GetNextParm();
|
||||||
|
|
||||||
|
|
@ -1864,11 +1855,20 @@ void D_SRB2Main(void)
|
||||||
|
|
||||||
if (grandprixinfo.gp == true && mapheaderinfo[pstartmap-1])
|
if (grandprixinfo.gp == true && mapheaderinfo[pstartmap-1])
|
||||||
{
|
{
|
||||||
if (mapheaderinfo[pstartmap-1]->typeoflevel & TOL_SPECIAL)
|
if (newgametype == -1)
|
||||||
{
|
{
|
||||||
specialStage.active = true;
|
newgametype = G_GuessGametypeByTOL(mapheaderinfo[pstartmap-1]->typeoflevel);
|
||||||
specialStage.encore = grandprixinfo.encore;
|
if (newgametype != -1)
|
||||||
|
{
|
||||||
|
j = gametype;
|
||||||
|
G_SetGametype(newgametype);
|
||||||
|
D_GameTypeChanged(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gametyperules & (GTR_BOSS|GTR_CATCHER))
|
||||||
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
||||||
|
else if (gametype != GT_RACE)
|
||||||
|
grandprixinfo.eventmode = GPEVENT_BONUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_SetUsedCheats();
|
G_SetUsedCheats();
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@
|
||||||
#include "k_color.h"
|
#include "k_color.h"
|
||||||
#include "k_respawn.h"
|
#include "k_respawn.h"
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_follower.h"
|
#include "k_follower.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "deh_tables.h"
|
#include "deh_tables.h"
|
||||||
|
|
@ -2525,15 +2524,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
||||||
FLS = false;
|
FLS = false;
|
||||||
|
|
||||||
// Too lazy to change the input value for every instance of this function.......
|
// Too lazy to change the input value for every instance of this function.......
|
||||||
if (bossinfo.boss == true)
|
if (grandprixinfo.gp == true)
|
||||||
{
|
|
||||||
pencoremode = bossinfo.encore;
|
|
||||||
}
|
|
||||||
else if (specialStage.active == true)
|
|
||||||
{
|
|
||||||
pencoremode = specialStage.encore;
|
|
||||||
}
|
|
||||||
else if (grandprixinfo.gp == true)
|
|
||||||
{
|
{
|
||||||
pencoremode = grandprixinfo.encore;
|
pencoremode = grandprixinfo.encore;
|
||||||
}
|
}
|
||||||
|
|
@ -2843,7 +2834,15 @@ static void Command_Map_f(void)
|
||||||
if (mapheaderinfo[newmapnum-1])
|
if (mapheaderinfo[newmapnum-1])
|
||||||
{
|
{
|
||||||
// Let's just guess so we don't have to specify the gametype EVERY time...
|
// Let's just guess so we don't have to specify the gametype EVERY time...
|
||||||
newgametype = (mapheaderinfo[newmapnum-1]->typeoflevel & (TOL_BATTLE|TOL_BOSS)) ? GT_BATTLE : GT_RACE;
|
newgametype = G_GuessGametypeByTOL(mapheaderinfo[newmapnum-1]->typeoflevel);
|
||||||
|
|
||||||
|
if (newgametype == -1)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support any known gametype!\n"), realmapname, G_BuildMapName(newmapnum));
|
||||||
|
Z_Free(realmapname);
|
||||||
|
Z_Free(mapname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2855,6 +2854,8 @@ static void Command_Map_f(void)
|
||||||
if (!M_SecretUnlocked(SECRET_ENCORE, false) && newencoremode == true && !usingcheats)
|
if (!M_SecretUnlocked(SECRET_ENCORE, false) && newencoremode == true && !usingcheats)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("You haven't unlocked Encore Mode yet!\n"));
|
CONS_Alert(CONS_NOTICE, M_GetText("You haven't unlocked Encore Mode yet!\n"));
|
||||||
|
Z_Free(realmapname);
|
||||||
|
Z_Free(mapname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2875,7 +2876,7 @@ static void Command_Map_f(void)
|
||||||
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
|
mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), (gametype_cons_t[newgametype].strvalue));
|
CONS_Alert(CONS_WARNING, M_GetText("%s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), gametypes[newgametype]->name);
|
||||||
Z_Free(realmapname);
|
Z_Free(realmapname);
|
||||||
Z_Free(mapname);
|
Z_Free(mapname);
|
||||||
return;
|
return;
|
||||||
|
|
@ -2940,35 +2941,18 @@ static void Command_Map_f(void)
|
||||||
|
|
||||||
grandprixinfo.eventmode = GPEVENT_NONE;
|
grandprixinfo.eventmode = GPEVENT_NONE;
|
||||||
|
|
||||||
if (newgametype == GT_BATTLE)
|
if (gametypes[newgametype]->rules & (GTR_BOSS|GTR_CATCHER))
|
||||||
{
|
{
|
||||||
grandprixinfo.eventmode = GPEVENT_BONUS;
|
|
||||||
|
|
||||||
if (mapheaderinfo[newmapnum-1] &&
|
|
||||||
mapheaderinfo[newmapnum-1]->typeoflevel & TOL_BOSS)
|
|
||||||
{
|
|
||||||
bossinfo.boss = true;
|
|
||||||
bossinfo.encore = newencoremode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bossinfo.boss = false;
|
|
||||||
K_ResetBossInfo();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mapheaderinfo[newmapnum-1] &&
|
|
||||||
mapheaderinfo[newmapnum-1]->typeoflevel & TOL_SPECIAL) // Special Stage
|
|
||||||
{
|
|
||||||
specialStage.active = true;
|
|
||||||
specialStage.encore = newencoremode;
|
|
||||||
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
||||||
}
|
}
|
||||||
else
|
else if (newgametype != GT_RACE)
|
||||||
{
|
{
|
||||||
specialStage.active = false;
|
grandprixinfo.eventmode = GPEVENT_BONUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Playing())
|
||||||
|
{
|
||||||
|
multiplayer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3022,7 +3006,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
else if (gametype != lastgametype)
|
else if (gametype != lastgametype)
|
||||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||||
|
|
||||||
if (!(gametyperules & GTR_ENCORE) && !bossinfo.boss)
|
if (!(gametyperules & GTR_ENCORE))
|
||||||
pencoremode = false;
|
pencoremode = false;
|
||||||
|
|
||||||
skipprecutscene = ((flags & (1<<2)) != 0);
|
skipprecutscene = ((flags & (1<<2)) != 0);
|
||||||
|
|
@ -5737,11 +5721,11 @@ void Command_Retry_f(void)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
|
||||||
}
|
}
|
||||||
else if (grandprixinfo.gp == false && bossinfo.boss == false)
|
else if (grandprixinfo.gp == false)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("This only works in singleplayer games.\n"));
|
CONS_Printf(M_GetText("This only works in singleplayer games.\n"));
|
||||||
}
|
}
|
||||||
else if (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE)
|
else if (grandprixinfo.eventmode == GPEVENT_BONUS)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("You can't retry right now!\n"));
|
CONS_Printf(M_GetText("You can't retry right now!\n"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,8 @@ enum GameType
|
||||||
{
|
{
|
||||||
GT_RACE = 0,
|
GT_RACE = 0,
|
||||||
GT_BATTLE,
|
GT_BATTLE,
|
||||||
|
GT_SPECIAL,
|
||||||
|
GT_VERSUS,
|
||||||
|
|
||||||
GT_FIRSTFREESLOT,
|
GT_FIRSTFREESLOT,
|
||||||
GT_LASTFREESLOT = 127, // Previously (GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1) - it would be necessary to rewrite VOTEMODIFIER_ENCORE to go higher than this.
|
GT_LASTFREESLOT = 127, // Previously (GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1) - it would be necessary to rewrite VOTEMODIFIER_ENCORE to go higher than this.
|
||||||
|
|
@ -509,12 +511,16 @@ enum GameTypeRules
|
||||||
GTR_TEAMSTARTS = 1<<16, // Use team-based start positions
|
GTR_TEAMSTARTS = 1<<16, // Use team-based start positions
|
||||||
|
|
||||||
// To be rearranged later
|
// To be rearranged later
|
||||||
GTR_NOCUPSELECT = 1<<20, // Your maps are not selected via cup. ...mutually exclusive with GTR_CAMPAIGN.
|
GTR_CATCHER = 1<<17, // UFO Catcher (only works with GTR_CIRCUIT)
|
||||||
|
GTR_BOSS = 1<<18, // Boss intro and spawning
|
||||||
|
|
||||||
|
GTR_NOCUPSELECT = 1<<20, // Your maps are not selected via cup.
|
||||||
GTR_CLOSERPLAYERS = 1<<21, // Buffs spindash and draft power to bring everyone together, nerfs invincibility and grow to prevent excessive combos
|
GTR_CLOSERPLAYERS = 1<<21, // Buffs spindash and draft power to bring everyone together, nerfs invincibility and grow to prevent excessive combos
|
||||||
GTR_ENCORE = 1<<22, // Alternate Encore mirroring, scripting, and texture remapping
|
GTR_ENCORE = 1<<22, // Alternate Encore mirroring, scripting, and texture remapping
|
||||||
|
|
||||||
// free: to and including 1<<31
|
// free: to and including 1<<31
|
||||||
};
|
};
|
||||||
|
// Remember to update GAMETYPERULE_LIST in deh_soc.c
|
||||||
|
|
||||||
// TODO: replace every instance
|
// TODO: replace every instance
|
||||||
#define gametyperules (gametypes[gametype]->rules)
|
#define gametyperules (gametypes[gametype]->rules)
|
||||||
|
|
@ -531,6 +537,7 @@ enum TypeOfLevel
|
||||||
// Modifiers
|
// Modifiers
|
||||||
TOL_TV = 0x0100 ///< Midnight Channel specific: draw TV like overlay on HUD
|
TOL_TV = 0x0100 ///< Midnight Channel specific: draw TV like overlay on HUD
|
||||||
};
|
};
|
||||||
|
// Make sure to update TYPEOFLEVEL too
|
||||||
|
|
||||||
#define MAXTOL (1<<31)
|
#define MAXTOL (1<<31)
|
||||||
#define NUMBASETOLNAMES (5)
|
#define NUMBASETOLNAMES (5)
|
||||||
|
|
|
||||||
108
src/g_game.c
108
src/g_game.c
|
|
@ -1425,9 +1425,9 @@ void G_StartTitleCard(void)
|
||||||
// play the sound
|
// play the sound
|
||||||
{
|
{
|
||||||
sfxenum_t kstart = sfx_kstart;
|
sfxenum_t kstart = sfx_kstart;
|
||||||
if (bossinfo.boss)
|
if (K_CheckBossIntro() == true)
|
||||||
kstart = sfx_ssa021;
|
kstart = sfx_ssa021;
|
||||||
else if (encoremode)
|
else if (encoremode == true)
|
||||||
kstart = sfx_ruby2;
|
kstart = sfx_ruby2;
|
||||||
S_StartSound(NULL, kstart);
|
S_StartSound(NULL, kstart);
|
||||||
}
|
}
|
||||||
|
|
@ -2790,22 +2790,9 @@ mapthing_t *G_FindMapStart(INT32 playernum)
|
||||||
if (!playeringame[playernum])
|
if (!playeringame[playernum])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// -- Spectators --
|
// -- Time Attack --
|
||||||
// Order in platform gametypes: Race->DM->CTF
|
|
||||||
// And, with deathmatch starts: DM->CTF->Race
|
|
||||||
if (players[playernum].spectator)
|
|
||||||
{
|
|
||||||
// In platform gametypes, spawn in Co-op starts first
|
|
||||||
// Overriden by GTR_BATTLESTARTS.
|
|
||||||
if (gametyperules & GTR_BATTLESTARTS && bossinfo.boss == false)
|
|
||||||
spawnpoint = G_FindBattleStartOrFallback(playernum);
|
|
||||||
else
|
|
||||||
spawnpoint = G_FindRaceStartOrFallback(playernum);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Grand Prix / Time Attack --
|
|
||||||
// Order: Race->DM->CTF
|
// Order: Race->DM->CTF
|
||||||
else if (grandprixinfo.gp || modeattacking)
|
if (K_TimeAttackRules() == true)
|
||||||
spawnpoint = G_FindRaceStartOrFallback(playernum);
|
spawnpoint = G_FindRaceStartOrFallback(playernum);
|
||||||
|
|
||||||
// -- CTF --
|
// -- CTF --
|
||||||
|
|
@ -2911,7 +2898,7 @@ void G_ExitLevel(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
boolean youlost = false;
|
boolean youlost = false;
|
||||||
if (bossinfo.boss == true)
|
if (gametyperules & GTR_BOSS)
|
||||||
{
|
{
|
||||||
youlost = true;
|
youlost = true;
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
|
@ -3021,12 +3008,35 @@ static gametype_t defaultgametypes[] =
|
||||||
0,
|
0,
|
||||||
2,
|
2,
|
||||||
},
|
},
|
||||||
|
// GT_SPECIAL
|
||||||
|
{
|
||||||
|
"Special",
|
||||||
|
"GT_SPECIAL",
|
||||||
|
GTR_CATCHER|GTR_CIRCUIT,
|
||||||
|
TOL_SPECIAL,
|
||||||
|
int_race,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
|
||||||
|
// GT_VERSUS
|
||||||
|
{
|
||||||
|
"Versus",
|
||||||
|
"GT_VERSUS",
|
||||||
|
GTR_BOSS|GTR_SPHERES|GTR_BUMPERS|GTR_POINTLIMIT|GTR_CLOSERPLAYERS|GTR_NOCUPSELECT|GTR_ENCORE,
|
||||||
|
TOL_BOSS,
|
||||||
|
int_battle,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
gametype_t *gametypes[MAXGAMETYPES+1] =
|
gametype_t *gametypes[MAXGAMETYPES+1] =
|
||||||
{
|
{
|
||||||
&defaultgametypes[GT_RACE],
|
&defaultgametypes[GT_RACE],
|
||||||
&defaultgametypes[GT_BATTLE],
|
&defaultgametypes[GT_BATTLE],
|
||||||
|
&defaultgametypes[GT_SPECIAL],
|
||||||
|
&defaultgametypes[GT_VERSUS],
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -3048,6 +3058,25 @@ INT32 G_GetGametypeByName(const char *gametypestr)
|
||||||
return -1; // unknown gametype
|
return -1; // unknown gametype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// G_GuessGametypeByTOL
|
||||||
|
//
|
||||||
|
// Returns the first valid number for the given typeoflevel, or -1 if not valid.
|
||||||
|
//
|
||||||
|
INT32 G_GuessGametypeByTOL(UINT32 tol)
|
||||||
|
{
|
||||||
|
INT32 i = 0;
|
||||||
|
|
||||||
|
while (gametypes[i] != NULL)
|
||||||
|
{
|
||||||
|
if (tol & gametypes[i]->tol)
|
||||||
|
return i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; // unknown gametype
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_SetGametype
|
// G_SetGametype
|
||||||
//
|
//
|
||||||
|
|
@ -3651,7 +3680,7 @@ static void G_GetNextMap(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INT32 lastgametype = gametype;
|
INT32 lastgametype = gametype, newgametype = GT_RACE;
|
||||||
// 5 levels, 2 bonus stages: after rounds 2 and 4 (but flexible enough to accomodate other solutions)
|
// 5 levels, 2 bonus stages: after rounds 2 and 4 (but flexible enough to accomodate other solutions)
|
||||||
UINT8 bonusmodulo = (grandprixinfo.cup->numlevels+1)/(grandprixinfo.cup->numbonus+1);
|
UINT8 bonusmodulo = (grandprixinfo.cup->numlevels+1)/(grandprixinfo.cup->numbonus+1);
|
||||||
UINT8 bonusindex = (grandprixinfo.roundnum / bonusmodulo) - 1;
|
UINT8 bonusindex = (grandprixinfo.roundnum / bonusmodulo) - 1;
|
||||||
|
|
@ -3668,9 +3697,6 @@ static void G_GetNextMap(void)
|
||||||
G_SetGametype(GT_RACE);
|
G_SetGametype(GT_RACE);
|
||||||
if (gametype != lastgametype)
|
if (gametype != lastgametype)
|
||||||
D_GameTypeChanged(lastgametype);
|
D_GameTypeChanged(lastgametype);
|
||||||
|
|
||||||
specialStage.active = false;
|
|
||||||
bossinfo.boss = false;
|
|
||||||
}
|
}
|
||||||
// Special stage
|
// Special stage
|
||||||
else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
|
else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
|
||||||
|
|
@ -3691,11 +3717,11 @@ static void G_GetNextMap(void)
|
||||||
if (totaltotalring >= 50)
|
if (totaltotalring >= 50)
|
||||||
{
|
{
|
||||||
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_SPECIAL];
|
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_SPECIAL];
|
||||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
|
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||||
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_SPECIAL|TOL_BOSS|TOL_BATTLE))
|
|
||||||
{
|
{
|
||||||
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
grandprixinfo.eventmode = GPEVENT_SPECIAL;
|
||||||
nextmap = cupLevelNum;
|
nextmap = cupLevelNum;
|
||||||
|
newgametype = G_GuessGametypeByTOL(mapheaderinfo[cupLevelNum]->typeoflevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3706,37 +3732,27 @@ static void G_GetNextMap(void)
|
||||||
// todo any other condition?
|
// todo any other condition?
|
||||||
{
|
{
|
||||||
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS + bonusindex];
|
const INT32 cupLevelNum = grandprixinfo.cup->cachedlevels[CUPCACHE_BONUS + bonusindex];
|
||||||
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum]
|
if (cupLevelNum < nummapheaders && mapheaderinfo[cupLevelNum])
|
||||||
&& mapheaderinfo[cupLevelNum]->typeoflevel & (TOL_BOSS|TOL_BATTLE))
|
|
||||||
{
|
{
|
||||||
grandprixinfo.eventmode = GPEVENT_BONUS;
|
grandprixinfo.eventmode = GPEVENT_BONUS;
|
||||||
nextmap = cupLevelNum;
|
nextmap = cupLevelNum;
|
||||||
|
newgametype = G_GuessGametypeByTOL(mapheaderinfo[cupLevelNum]->typeoflevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newgametype == -1)
|
||||||
|
{
|
||||||
|
// Don't permit invalid changes.
|
||||||
|
grandprixinfo.eventmode = GPEVENT_NONE;
|
||||||
|
newgametype = gametype;
|
||||||
|
}
|
||||||
|
|
||||||
if (grandprixinfo.eventmode != GPEVENT_NONE)
|
if (grandprixinfo.eventmode != GPEVENT_NONE)
|
||||||
{
|
{
|
||||||
// nextmap is set above
|
G_SetGametype(newgametype);
|
||||||
const INT32 newtol = mapheaderinfo[nextmap]->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)
|
if (gametype != lastgametype)
|
||||||
D_GameTypeChanged(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
|
else if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels) // On final map
|
||||||
{
|
{
|
||||||
|
|
@ -3760,10 +3776,6 @@ static void G_GetNextMap(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bossinfo.boss == true)
|
|
||||||
{
|
|
||||||
nextmap = NEXTMAP_TITLE; // temporary
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT32 tolflag = G_TOLFlag(gametype);
|
UINT32 tolflag = G_TOLFlag(gametype);
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,8 @@ char *G_PrepareGametypeConstant(const char *newgtconst);
|
||||||
void G_UpdateGametypeSelections(void);
|
void G_UpdateGametypeSelections(void);
|
||||||
void G_AddTOL(UINT32 newtol, const char *tolname);
|
void G_AddTOL(UINT32 newtol, const char *tolname);
|
||||||
INT32 G_GetGametypeByName(const char *gametypestr);
|
INT32 G_GetGametypeByName(const char *gametypestr);
|
||||||
|
INT32 G_GuessGametypeByTOL(UINT32 tol);
|
||||||
|
|
||||||
boolean G_IsSpecialStage(INT32 mapnum);
|
boolean G_IsSpecialStage(INT32 mapnum);
|
||||||
boolean G_GametypeUsesLives(void);
|
boolean G_GametypeUsesLives(void);
|
||||||
boolean G_GametypeHasTeams(void);
|
boolean G_GametypeHasTeams(void);
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
#include "s_sound.h" // song credits
|
#include "s_sound.h" // song credits
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_color.h"
|
#include "k_color.h"
|
||||||
#include "k_hud.h"
|
#include "k_hud.h"
|
||||||
#include "r_fps.h"
|
#include "r_fps.h"
|
||||||
|
|
@ -2409,7 +2408,7 @@ static void HU_DrawRankings(void)
|
||||||
else if (gametype >= 0 && gametype < numgametypes)
|
else if (gametype >= 0 && gametype < numgametypes)
|
||||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametypes[gametype]->name);
|
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametypes[gametype]->name);
|
||||||
|
|
||||||
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
|
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)))
|
||||||
{
|
{
|
||||||
if ((gametyperules & GTR_TIMELIMIT) && timelimitintics > 0)
|
if ((gametyperules & GTR_TIMELIMIT) && timelimitintics > 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
/// \brief SRB2Kart Battle Mode specific code
|
/// \brief SRB2Kart Battle Mode specific code
|
||||||
|
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdata.h"
|
#include "doomdata.h"
|
||||||
|
|
@ -357,7 +356,7 @@ void K_RunPaperItemSpawners(void)
|
||||||
UINT8 pcount = 0;
|
UINT8 pcount = 0;
|
||||||
INT16 i;
|
INT16 i;
|
||||||
|
|
||||||
if (battlecapsules || bossinfo.boss)
|
if (battlecapsules)
|
||||||
{
|
{
|
||||||
// Gametype uses paper items, but this specific expression doesn't
|
// Gametype uses paper items, but this specific expression doesn't
|
||||||
return;
|
return;
|
||||||
|
|
@ -794,7 +793,7 @@ void K_BattleInit(boolean singleplayercontext)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if ((gametyperules & GTR_CAPSULES) && singleplayercontext && !battlecapsules && !bossinfo.boss)
|
if ((gametyperules & GTR_CAPSULES) && singleplayercontext && !battlecapsules)
|
||||||
{
|
{
|
||||||
mapthing_t *mt = mapthings;
|
mapthing_t *mt = mapthings;
|
||||||
for (i = 0; i < nummapthings; i++, mt++)
|
for (i = 0; i < nummapthings; i++, mt++)
|
||||||
|
|
|
||||||
37
src/k_boss.c
37
src/k_boss.c
|
|
@ -23,7 +23,7 @@
|
||||||
struct bossinfo bossinfo;
|
struct bossinfo bossinfo;
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_ClearBossInfo(void)
|
void K_ResetBossInfo(void)
|
||||||
|
|
||||||
See header file for description.
|
See header file for description.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
|
|
@ -32,6 +32,8 @@ void K_ResetBossInfo(void)
|
||||||
Z_Free(bossinfo.enemyname);
|
Z_Free(bossinfo.enemyname);
|
||||||
Z_Free(bossinfo.subtitle);
|
Z_Free(bossinfo.subtitle);
|
||||||
memset(&bossinfo, 0, sizeof(struct bossinfo));
|
memset(&bossinfo, 0, sizeof(struct bossinfo));
|
||||||
|
bossinfo.barlen = BOSSHEALTHBARLEN;
|
||||||
|
bossinfo.titlesound = sfx_typri1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
|
|
@ -43,7 +45,7 @@ void K_BossInfoTicker(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
if (bossinfo.boss == false)
|
if (bossinfo.valid == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update healthbar data. (only if the hud is visible)
|
// Update healthbar data. (only if the hud is visible)
|
||||||
|
|
@ -108,6 +110,18 @@ void K_BossInfoTicker(void)
|
||||||
|
|
||||||
void K_InitBossHealthBar(const char *enemyname, const char *subtitle, sfxenum_t titlesound, fixed_t pinchmagnitude, UINT8 divisions)
|
void K_InitBossHealthBar(const char *enemyname, const char *subtitle, sfxenum_t titlesound, fixed_t pinchmagnitude, UINT8 divisions)
|
||||||
{
|
{
|
||||||
|
if (!(gametyperules & GTR_BOSS))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bossinfo.valid = true;
|
||||||
|
|
||||||
|
if (!leveltime)
|
||||||
|
{
|
||||||
|
bossinfo.coolintro = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (enemyname && enemyname[0])
|
if (enemyname && enemyname[0])
|
||||||
{
|
{
|
||||||
Z_Free(bossinfo.enemyname);
|
Z_Free(bossinfo.enemyname);
|
||||||
|
|
@ -158,6 +172,9 @@ void K_InitBossHealthBar(const char *enemyname, const char *subtitle, sfxenum_t
|
||||||
|
|
||||||
void K_UpdateBossHealthBar(fixed_t magnitude, tic_t jitterlen)
|
void K_UpdateBossHealthBar(fixed_t magnitude, tic_t jitterlen)
|
||||||
{
|
{
|
||||||
|
if (bossinfo.valid == false)
|
||||||
|
return;
|
||||||
|
|
||||||
if (magnitude > FRACUNIT)
|
if (magnitude > FRACUNIT)
|
||||||
magnitude = FRACUNIT;
|
magnitude = FRACUNIT;
|
||||||
else if (magnitude < 0)
|
else if (magnitude < 0)
|
||||||
|
|
@ -177,6 +194,9 @@ void K_DeclareWeakspot(mobj_t *spot, spottype_t spottype, UINT16 color, boolean
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
|
if (bossinfo.valid == false)
|
||||||
|
return;
|
||||||
|
|
||||||
// First check whether the spot is already in the list and simply redeclaring weakness (for example, a vulnerable moment in the pattern).
|
// First check whether the spot is already in the list and simply redeclaring weakness (for example, a vulnerable moment in the pattern).
|
||||||
for (i = 0; i < NUMWEAKSPOTS; i++)
|
for (i = 0; i < NUMWEAKSPOTS; i++)
|
||||||
if (bossinfo.weakspots[i].spot == spot)
|
if (bossinfo.weakspots[i].spot == spot)
|
||||||
|
|
@ -206,3 +226,16 @@ void K_DeclareWeakspot(mobj_t *spot, spottype_t spottype, UINT16 color, boolean
|
||||||
bossinfo.doweakspotsound = spottype;
|
bossinfo.doweakspotsound = spottype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
boolean K_CheckBossIntro(void);
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
boolean K_CheckBossIntro(void)
|
||||||
|
{
|
||||||
|
if (bossinfo.valid == false)
|
||||||
|
return false;
|
||||||
|
return bossinfo.coolintro;
|
||||||
|
}
|
||||||
|
|
|
||||||
17
src/k_boss.h
17
src/k_boss.h
|
|
@ -39,7 +39,8 @@ struct weakspot_t
|
||||||
|
|
||||||
extern struct bossinfo
|
extern struct bossinfo
|
||||||
{
|
{
|
||||||
boolean boss; ///< If true, then we are fighting a boss
|
boolean valid; ///< If true, then data in this struct is valid
|
||||||
|
|
||||||
UINT8 healthbar; ///< Actual health bar fill amount
|
UINT8 healthbar; ///< Actual health bar fill amount
|
||||||
UINT8 visualbar; ///< Tracks above, but with delay
|
UINT8 visualbar; ///< Tracks above, but with delay
|
||||||
fixed_t visualdiv; ///< How far apart health bar divisions should appear
|
fixed_t visualdiv; ///< How far apart health bar divisions should appear
|
||||||
|
|
@ -48,7 +49,7 @@ extern struct bossinfo
|
||||||
UINT8 barlen; ///< The length of the bar (only reduced when a boss is deceased)
|
UINT8 barlen; ///< The length of the bar (only reduced when a boss is deceased)
|
||||||
char *enemyname; ///< The name next to the bar
|
char *enemyname; ///< The name next to the bar
|
||||||
weakspot_t weakspots[NUMWEAKSPOTS]; ///< Array of weak spots (for minimap/object tracking)
|
weakspot_t weakspots[NUMWEAKSPOTS]; ///< Array of weak spots (for minimap/object tracking)
|
||||||
boolean encore; ///< Copy of encore, just to make sure you can't cheat it with cvars
|
boolean coolintro; ///< Determines whether the map start(s/ed) with a boss-specific intro.
|
||||||
spottype_t doweakspotsound; ///< If nonzero, at least one weakspot was declared this tic
|
spottype_t doweakspotsound; ///< If nonzero, at least one weakspot was declared this tic
|
||||||
tic_t titleshow; ///< Show this many letters on the titlecard
|
tic_t titleshow; ///< Show this many letters on the titlecard
|
||||||
sfxenum_t titlesound; ///< Sound to play when title typing
|
sfxenum_t titlesound; ///< Sound to play when title typing
|
||||||
|
|
@ -112,4 +113,16 @@ void K_UpdateBossHealthBar(fixed_t magnitude, tic_t jitterlen);
|
||||||
|
|
||||||
void K_DeclareWeakspot(mobj_t *spot, spottype_t spottype, UINT16 color, boolean minimap);
|
void K_DeclareWeakspot(mobj_t *spot, spottype_t spottype, UINT16 color, boolean minimap);
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
boolean K_CheckBossIntro(void);
|
||||||
|
|
||||||
|
Checks whether the Versus-specific intro is playing for this map start.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
true if cool intro in action,
|
||||||
|
otherwise false.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
|
||||||
|
boolean K_CheckBossIntro(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "r_things.h" // numskins
|
#include "r_things.h" // numskins
|
||||||
#include "k_race.h" // finishBeamLine
|
#include "k_race.h" // finishBeamLine
|
||||||
#include "k_boss.h"
|
|
||||||
#include "m_perfstats.h"
|
#include "m_perfstats.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -168,7 +167,7 @@ void K_UpdateMatchRaceBots(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (difficulty == 0 || !(gametyperules & GTR_BOTS) || bossinfo.boss == true)
|
if (difficulty == 0 || !(gametyperules & GTR_BOTS))
|
||||||
{
|
{
|
||||||
wantedbots = 0;
|
wantedbots = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
/// \brief Grand Prix mode game logic & bot behaviors
|
/// \brief Grand Prix mode game logic & bot behaviors
|
||||||
|
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
|
@ -529,7 +528,7 @@ void K_RetireBots(void)
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
if (grandprixinfo.gp == true
|
if (grandprixinfo.gp == true
|
||||||
&& ((grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
|
&& ((grandprixinfo.cup != NULL && grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
|
||||||
|| grandprixinfo.eventmode != GPEVENT_NONE))
|
|| grandprixinfo.eventmode != GPEVENT_NONE))
|
||||||
{
|
{
|
||||||
// No replacement.
|
// No replacement.
|
||||||
|
|
@ -703,24 +702,12 @@ void K_PlayerLoseLife(player_t *player)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
boolean K_CanChangeRules(boolean allowdemos)
|
boolean K_CanChangeRules(boolean allowdemos)
|
||||||
{
|
{
|
||||||
if (grandprixinfo.gp == true && grandprixinfo.roundnum > 0)
|
if (grandprixinfo.gp == true /*&& grandprixinfo.roundnum > 0*/)
|
||||||
{
|
{
|
||||||
// Don't cheat the rules of the GP!
|
// Don't cheat the rules of the GP!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bossinfo.boss == true)
|
|
||||||
{
|
|
||||||
// Don't cheat the boss!
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (specialStage.active == true)
|
|
||||||
{
|
|
||||||
// Don't cheat special stages!
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marathonmode)
|
if (marathonmode)
|
||||||
{
|
{
|
||||||
// Don't cheat the endurance challenge!
|
// Don't cheat the endurance challenge!
|
||||||
|
|
|
||||||
14
src/k_hud.c
14
src/k_hud.c
|
|
@ -3360,7 +3360,7 @@ static void K_drawKartNameTags(void)
|
||||||
c.z = viewz;
|
c.z = viewz;
|
||||||
|
|
||||||
// Maybe shouldn't be handling this here... but the camera info is too good.
|
// Maybe shouldn't be handling this here... but the camera info is too good.
|
||||||
if (bossinfo.boss)
|
if (bossinfo.valid == true)
|
||||||
{
|
{
|
||||||
weakspotdraw_t weakspotdraw[NUMWEAKSPOTS];
|
weakspotdraw_t weakspotdraw[NUMWEAKSPOTS];
|
||||||
UINT8 numdraw = 0;
|
UINT8 numdraw = 0;
|
||||||
|
|
@ -3923,7 +3923,7 @@ static void K_drawKartMinimap(void)
|
||||||
|
|
||||||
// Target reticule
|
// Target reticule
|
||||||
if (((gametyperules & GTR_CIRCUIT) && players[i].position == spbplace)
|
if (((gametyperules & GTR_CIRCUIT) && players[i].position == spbplace)
|
||||||
|| ((gametyperules & GTR_POINTLIMIT) && K_IsPlayerWanted(&players[i])))
|
|| ((gametyperules & (GTR_BOSS|GTR_POINTLIMIT)) == GTR_POINTLIMIT && K_IsPlayerWanted(&players[i])))
|
||||||
{
|
{
|
||||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||||
}
|
}
|
||||||
|
|
@ -3981,7 +3981,7 @@ static void K_drawKartMinimap(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...but first, any boss targets.
|
// ...but first, any boss targets.
|
||||||
if (bossinfo.boss)
|
if (bossinfo.valid == true)
|
||||||
{
|
{
|
||||||
for (i = 0; i < NUMWEAKSPOTS; i++)
|
for (i = 0; i < NUMWEAKSPOTS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -4050,7 +4050,7 @@ static void K_drawKartMinimap(void)
|
||||||
|
|
||||||
// Target reticule
|
// Target reticule
|
||||||
if (((gametyperules & GTR_CIRCUIT) && players[localplayers[i]].position == spbplace)
|
if (((gametyperules & GTR_CIRCUIT) && players[localplayers[i]].position == spbplace)
|
||||||
|| ((gametyperules & GTR_POINTLIMIT) && K_IsPlayerWanted(&players[localplayers[i]])))
|
|| ((gametyperules & (GTR_BOSS|GTR_POINTLIMIT)) == GTR_POINTLIMIT && K_IsPlayerWanted(&players[localplayers[i]])))
|
||||||
{
|
{
|
||||||
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic);
|
||||||
}
|
}
|
||||||
|
|
@ -4838,7 +4838,7 @@ void K_drawKartFreePlay(void)
|
||||||
if (!LUA_HudEnabled(hud_freeplay))
|
if (!LUA_HudEnabled(hud_freeplay))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (modeattacking || grandprixinfo.gp || bossinfo.boss || stplyr->spectator)
|
if (modeattacking || grandprixinfo.gp || bossinfo.valid || stplyr->spectator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lt_exitticker < TICRATE/2)
|
if (lt_exitticker < TICRATE/2)
|
||||||
|
|
@ -5098,7 +5098,7 @@ void K_drawKartHUD(void)
|
||||||
{
|
{
|
||||||
if (LUA_HudEnabled(hud_position))
|
if (LUA_HudEnabled(hud_position))
|
||||||
{
|
{
|
||||||
if (bossinfo.boss)
|
if (bossinfo.valid)
|
||||||
{
|
{
|
||||||
K_drawBossHealthBar();
|
K_drawBossHealthBar();
|
||||||
}
|
}
|
||||||
|
|
@ -5140,7 +5140,7 @@ void K_drawKartHUD(void)
|
||||||
K_drawBlueSphereMeter();
|
K_drawBlueSphereMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modeattacking && !bossinfo.boss)
|
if (modeattacking && !bossinfo.valid)
|
||||||
{
|
{
|
||||||
// Draw the input UI
|
// Draw the input UI
|
||||||
if (LUA_HudEnabled(hud_position))
|
if (LUA_HudEnabled(hud_position))
|
||||||
|
|
|
||||||
34
src/k_kart.c
34
src/k_kart.c
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
#include "k_color.h"
|
#include "k_color.h"
|
||||||
#include "k_respawn.h"
|
#include "k_respawn.h"
|
||||||
|
|
@ -41,6 +40,7 @@
|
||||||
#include "k_follower.h"
|
#include "k_follower.h"
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
|
#include "k_boss.h"
|
||||||
#include "k_specialstage.h"
|
#include "k_specialstage.h"
|
||||||
#include "k_roulette.h"
|
#include "k_roulette.h"
|
||||||
|
|
||||||
|
|
@ -109,11 +109,13 @@ void K_TimerInit(void)
|
||||||
boolean domodeattack = ((modeattacking != ATTACKING_NONE)
|
boolean domodeattack = ((modeattacking != ATTACKING_NONE)
|
||||||
|| (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE));
|
|| (grandprixinfo.gp == true && grandprixinfo.eventmode != GPEVENT_NONE));
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if ((gametyperules & (GTR_CATCHER|GTR_CIRCUIT)) == (GTR_CATCHER|GTR_CIRCUIT))
|
||||||
{
|
{
|
||||||
K_InitSpecialStage();
|
K_InitSpecialStage();
|
||||||
}
|
}
|
||||||
else if (bossinfo.boss == false)
|
else if (K_CheckBossIntro() == true)
|
||||||
|
;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!domodeattack)
|
if (!domodeattack)
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +154,7 @@ void K_TimerInit(void)
|
||||||
|
|
||||||
K_BattleInit(domodeattack);
|
K_BattleInit(domodeattack);
|
||||||
|
|
||||||
if ((gametyperules & GTR_TIMELIMIT) && !bossinfo.boss && !modeattacking)
|
if ((gametyperules & GTR_TIMELIMIT) && !modeattacking)
|
||||||
{
|
{
|
||||||
if (!K_CanChangeRules(true))
|
if (!K_CanChangeRules(true))
|
||||||
{
|
{
|
||||||
|
|
@ -343,7 +345,7 @@ boolean K_IsPlayerLosing(player_t *player)
|
||||||
if (battlecapsules && numtargets == 0)
|
if (battlecapsules && numtargets == 0)
|
||||||
return true; // Didn't even TRY?
|
return true; // Didn't even TRY?
|
||||||
|
|
||||||
if (battlecapsules || bossinfo.boss)
|
if (battlecapsules || (gametyperules & GTR_BOSS))
|
||||||
return (player->bumpers <= 0); // anything short of DNF is COOL
|
return (player->bumpers <= 0); // anything short of DNF is COOL
|
||||||
|
|
||||||
if (player->position == 1)
|
if (player->position == 1)
|
||||||
|
|
@ -513,7 +515,7 @@ boolean K_TimeAttackRules(void)
|
||||||
UINT8 playing = 0;
|
UINT8 playing = 0;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if ((gametyperules & (GTR_CATCHER|GTR_CIRCUIT)) == (GTR_CATCHER|GTR_CIRCUIT))
|
||||||
{
|
{
|
||||||
// Kind of a hack -- Special Stages
|
// Kind of a hack -- Special Stages
|
||||||
// are expected to be 1-player, so
|
// are expected to be 1-player, so
|
||||||
|
|
@ -1301,8 +1303,8 @@ static boolean K_TryDraft(player_t *player, mobj_t *dest, fixed_t minDist, fixed
|
||||||
*/
|
*/
|
||||||
static void K_UpdateDraft(player_t *player)
|
static void K_UpdateDraft(player_t *player)
|
||||||
{
|
{
|
||||||
const boolean addUfo = ((specialStage.active == true)
|
const boolean addUfo = ((specialstageinfo.valid == true)
|
||||||
&& (specialStage.ufo != NULL && P_MobjWasRemoved(specialStage.ufo) == false));
|
&& (specialstageinfo.ufo != NULL && P_MobjWasRemoved(specialstageinfo.ufo) == false));
|
||||||
|
|
||||||
fixed_t topspd = K_GetKartSpeed(player, false, false);
|
fixed_t topspd = K_GetKartSpeed(player, false, false);
|
||||||
fixed_t draftdistance;
|
fixed_t draftdistance;
|
||||||
|
|
@ -1345,7 +1347,7 @@ static void K_UpdateDraft(player_t *player)
|
||||||
if (addUfo == true)
|
if (addUfo == true)
|
||||||
{
|
{
|
||||||
// Tether off of the UFO!
|
// Tether off of the UFO!
|
||||||
if (K_TryDraft(player, specialStage.ufo, minDist, draftdistance, leniency) == true)
|
if (K_TryDraft(player, specialstageinfo.ufo, minDist, draftdistance, leniency) == true)
|
||||||
{
|
{
|
||||||
return; // Finished doing our draft.
|
return; // Finished doing our draft.
|
||||||
}
|
}
|
||||||
|
|
@ -1402,8 +1404,8 @@ static void K_UpdateDraft(player_t *player)
|
||||||
else if (addUfo == true)
|
else if (addUfo == true)
|
||||||
{
|
{
|
||||||
// kind of a hack to not have to mess with how lastdraft works
|
// kind of a hack to not have to mess with how lastdraft works
|
||||||
fixed_t dist = P_AproxDistance(P_AproxDistance(specialStage.ufo->x - player->mo->x, specialStage.ufo->y - player->mo->y), specialStage.ufo->z - player->mo->z);
|
fixed_t dist = P_AproxDistance(P_AproxDistance(specialstageinfo.ufo->x - player->mo->x, specialstageinfo.ufo->y - player->mo->y), specialstageinfo.ufo->z - player->mo->z);
|
||||||
K_DrawDraftCombiring(player, specialStage.ufo, dist, draftdistance, true);
|
K_DrawDraftCombiring(player, specialstageinfo.ufo, dist, draftdistance, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Remove draft speed boost.
|
else // Remove draft speed boost.
|
||||||
|
|
@ -4128,7 +4130,7 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers)
|
||||||
|
|
||||||
player->karmadelay = comebacktime;
|
player->karmadelay = comebacktime;
|
||||||
|
|
||||||
if (bossinfo.boss)
|
if (gametyperules & GTR_BOSS)
|
||||||
{
|
{
|
||||||
P_DoTimeOver(player);
|
P_DoTimeOver(player);
|
||||||
}
|
}
|
||||||
|
|
@ -6789,10 +6791,10 @@ mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range)
|
||||||
mobj_t *wtarg = NULL;
|
mobj_t *wtarg = NULL;
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
// Always target the UFO.
|
// Always target the UFO.
|
||||||
return specialStage.ufo;
|
return specialstageinfo.ufo;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
|
@ -8028,10 +8030,10 @@ void K_KartPlayerAfterThink(player_t *player)
|
||||||
|
|
||||||
mobj_t *ret = NULL;
|
mobj_t *ret = NULL;
|
||||||
|
|
||||||
if (specialStage.active == true && lastTargID == MAXPLAYERS)
|
if (specialstageinfo.valid == true && lastTargID == MAXPLAYERS)
|
||||||
{
|
{
|
||||||
// Aiming at the UFO.
|
// Aiming at the UFO.
|
||||||
lastTarg = specialStage.ufo;
|
lastTarg = specialstageinfo.ufo;
|
||||||
}
|
}
|
||||||
else if ((lastTargID >= 0 && lastTargID <= MAXPLAYERS)
|
else if ((lastTargID >= 0 && lastTargID <= MAXPLAYERS)
|
||||||
&& playeringame[lastTargID] == true)
|
&& playeringame[lastTargID] == true)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
|
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
|
||||||
#include "p_tick.h" // leveltime
|
#include "p_tick.h" // leveltime
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_profiles.h"
|
#include "k_profiles.h"
|
||||||
|
|
||||||
// Client-sided calculations done for Power Levels.
|
// Client-sided calculations done for Power Levels.
|
||||||
|
|
@ -38,7 +37,7 @@ SINT8 K_UsingPowerLevels(void)
|
||||||
{
|
{
|
||||||
SINT8 pt = PWRLV_DISABLED;
|
SINT8 pt = PWRLV_DISABLED;
|
||||||
|
|
||||||
if (!cv_kartusepwrlv.value || !(netgame || (demo.playback && demo.netgame)) || grandprixinfo.gp == true || bossinfo.boss == true)
|
if (!cv_kartusepwrlv.value || !(netgame || (demo.playback && demo.netgame)) || grandprixinfo.gp == true)
|
||||||
{
|
{
|
||||||
return PWRLV_DISABLED;
|
return PWRLV_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ static UINT32 K_GetItemRouletteDistance(const player_t *player, UINT8 numPlayers
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
UINT32 ufoDis = K_GetSpecialUFODistance();
|
UINT32 ufoDis = K_GetSpecialUFODistance();
|
||||||
|
|
||||||
|
|
@ -506,7 +506,7 @@ INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette,
|
||||||
I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table
|
I_Assert(pos < 2); // DO NOT allow positions past the bounds of the table
|
||||||
newOdds = K_KartItemOddsBattle[item-1][pos];
|
newOdds = K_KartItemOddsBattle[item-1][pos];
|
||||||
}
|
}
|
||||||
else if (specialStage.active == true)
|
else if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
I_Assert(pos < 4); // Ditto
|
I_Assert(pos < 4); // Ditto
|
||||||
newOdds = K_KartItemOddsSpecial[item-1][pos];
|
newOdds = K_KartItemOddsSpecial[item-1][pos];
|
||||||
|
|
@ -573,7 +573,7 @@ INT32 K_KartGetItemOdds(const player_t *player, itemroulette_t *const roulette,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specialStage.active == false)
|
if (specialstageinfo.valid == false)
|
||||||
{
|
{
|
||||||
if (roulette->firstDist < ENDDIST*2 // No SPB when 1st is almost done
|
if (roulette->firstDist < ENDDIST*2 // No SPB when 1st is almost done
|
||||||
|| position == 1) // No SPB for 1st ever
|
|| position == 1) // No SPB for 1st ever
|
||||||
|
|
@ -705,7 +705,7 @@ static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulett
|
||||||
oddsValid[i] = false;
|
oddsValid[i] = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (specialStage.active == true && i > 3)
|
else if (specialstageinfo.valid == true && i > 3)
|
||||||
{
|
{
|
||||||
oddsValid[i] = false;
|
oddsValid[i] = false;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -734,7 +734,7 @@ static UINT8 K_FindUseodds(const player_t *player, itemroulette_t *const roulett
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (specialStage.active == true) // Special Stages
|
if (specialstageinfo.valid == true) // Special Stages
|
||||||
{
|
{
|
||||||
SETUPDISTTABLE(0,2);
|
SETUPDISTTABLE(0,2);
|
||||||
SETUPDISTTABLE(1,2);
|
SETUPDISTTABLE(1,2);
|
||||||
|
|
@ -808,7 +808,7 @@ static boolean K_ForcedSPB(const player_t *player, itemroulette_t *const roulett
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -904,7 +904,7 @@ static void K_InitRoulette(itemroulette_t *const roulette)
|
||||||
roulette->exiting++;
|
roulette->exiting++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
UINT32 dis = K_UndoMapScaling(players[i].distancetofinish);
|
UINT32 dis = K_UndoMapScaling(players[i].distancetofinish);
|
||||||
if (dis < roulette->secondDist)
|
if (dis < roulette->secondDist)
|
||||||
|
|
@ -926,7 +926,7 @@ static void K_InitRoulette(itemroulette_t *const roulette)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
roulette->firstDist = K_UndoMapScaling(K_GetSpecialUFODistance());
|
roulette->firstDist = K_UndoMapScaling(K_GetSpecialUFODistance());
|
||||||
}
|
}
|
||||||
|
|
@ -1114,7 +1114,7 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet
|
||||||
|
|
||||||
// SPECIAL CASE No. 2:
|
// SPECIAL CASE No. 2:
|
||||||
// Use a special, pre-determined item reel for Time Attack / Free Play
|
// Use a special, pre-determined item reel for Time Attack / Free Play
|
||||||
if (bossinfo.boss == true)
|
if (gametyperules & GTR_BOSS)
|
||||||
{
|
{
|
||||||
for (i = 0; K_KartItemReelBoss[i] != KITEM_NONE; i++)
|
for (i = 0; K_KartItemReelBoss[i] != KITEM_NONE; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#include "k_waypoint.h"
|
#include "k_waypoint.h"
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
|
|
||||||
struct specialStage specialStage;
|
struct specialstageinfo specialstageinfo;
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_ResetSpecialStage(void)
|
void K_ResetSpecialStage(void)
|
||||||
|
|
@ -31,7 +31,8 @@ struct specialStage specialStage;
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
void K_ResetSpecialStage(void)
|
void K_ResetSpecialStage(void)
|
||||||
{
|
{
|
||||||
memset(&specialStage, 0, sizeof(struct specialStage));
|
memset(&specialstageinfo, 0, sizeof(struct specialstageinfo));
|
||||||
|
specialstageinfo.beamDist = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
|
|
@ -43,8 +44,15 @@ void K_InitSpecialStage(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
specialStage.beamDist = UINT32_MAX; // TODO: make proper value
|
if ((gametyperules & (GTR_CATCHER|GTR_CIRCUIT)) != (GTR_CATCHER|GTR_CIRCUIT))
|
||||||
P_SetTarget(&specialStage.ufo, Obj_CreateSpecialUFO());
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
specialstageinfo.valid = true;
|
||||||
|
|
||||||
|
specialstageinfo.beamDist = UINT32_MAX; // TODO: make proper value
|
||||||
|
P_SetTarget(&specialstageinfo.ufo, Obj_CreateSpecialUFO());
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -88,15 +96,15 @@ static void K_MoveExitBeam(void)
|
||||||
|
|
||||||
moveDist = (8 * mapobjectscale) / FRACUNIT;
|
moveDist = (8 * mapobjectscale) / FRACUNIT;
|
||||||
|
|
||||||
if (specialStage.beamDist <= moveDist)
|
if (specialstageinfo.beamDist <= moveDist)
|
||||||
{
|
{
|
||||||
specialStage.beamDist = 0;
|
specialstageinfo.beamDist = 0;
|
||||||
|
|
||||||
// TODO: Fail Special Stage
|
// TODO: Fail Special Stage
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
specialStage.beamDist -= moveDist;
|
specialstageinfo.beamDist -= moveDist;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find players who are now outside of the level.
|
// Find players who are now outside of the level.
|
||||||
|
|
@ -118,7 +126,7 @@ static void K_MoveExitBeam(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->distancetofinish > specialStage.beamDist)
|
if (player->distancetofinish > specialstageinfo.beamDist)
|
||||||
{
|
{
|
||||||
P_DoTimeOver(player);
|
P_DoTimeOver(player);
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +140,7 @@ static void K_MoveExitBeam(void)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
void K_TickSpecialStage(void)
|
void K_TickSpecialStage(void)
|
||||||
{
|
{
|
||||||
if (specialStage.active == false)
|
if (specialstageinfo.valid == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,13 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
|
||||||
extern struct specialStage
|
extern struct specialstageinfo
|
||||||
{
|
{
|
||||||
boolean active; ///< If true, then we are in a special stage
|
boolean valid; ///< If true, then data in this struct is valid
|
||||||
boolean encore; ///< Copy of encore, just to make sure you can't cheat it with cvars
|
|
||||||
|
|
||||||
UINT32 beamDist; ///< Where the exit beam is.
|
UINT32 beamDist; ///< Where the exit beam is.
|
||||||
mobj_t *ufo; ///< The Chaos Emerald capsule.
|
mobj_t *ufo; ///< The Chaos Emerald capsule.
|
||||||
} specialStage;
|
} specialstageinfo;
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_ResetSpecialStage(void);
|
void K_ResetSpecialStage(void);
|
||||||
|
|
|
||||||
|
|
@ -549,7 +549,7 @@ static void SPBSeek(mobj_t *spb, mobj_t *bestMobj)
|
||||||
|
|
||||||
SetSPBSpeed(spb, xySpeed, zSpeed);
|
SetSPBSpeed(spb, xySpeed, zSpeed);
|
||||||
|
|
||||||
if (specialStage.active == false)
|
if (specialstageinfo.valid == false)
|
||||||
{
|
{
|
||||||
// see if a player is near us, if they are, try to hit them by slightly thrusting towards them, otherwise, bleh!
|
// see if a player is near us, if they are, try to hit them by slightly thrusting towards them, otherwise, bleh!
|
||||||
steerDist = 1536 * mapobjectscale;
|
steerDist = 1536 * mapobjectscale;
|
||||||
|
|
@ -874,12 +874,12 @@ void Obj_SPBThink(mobj_t *spb)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
if (specialStage.ufo != NULL && P_MobjWasRemoved(specialStage.ufo) == false)
|
if (specialstageinfo.ufo != NULL && P_MobjWasRemoved(specialstageinfo.ufo) == false)
|
||||||
{
|
{
|
||||||
bestRank = 1;
|
bestRank = 1;
|
||||||
bestMobj = specialStage.ufo;
|
bestMobj = specialstageinfo.ufo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,9 +239,9 @@ static void UFOUpdateAngle(mobj_t *ufo)
|
||||||
|
|
||||||
waypoint_t *K_GetSpecialUFOWaypoint(mobj_t *ufo)
|
waypoint_t *K_GetSpecialUFOWaypoint(mobj_t *ufo)
|
||||||
{
|
{
|
||||||
if ((ufo == NULL) && (specialStage.active == true))
|
if ((ufo == NULL) && (specialstageinfo.valid == true))
|
||||||
{
|
{
|
||||||
ufo = specialStage.ufo;
|
ufo = specialstageinfo.ufo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ufo != NULL && P_MobjWasRemoved(ufo) == false
|
if (ufo != NULL && P_MobjWasRemoved(ufo) == false
|
||||||
|
|
@ -820,11 +820,11 @@ mobj_t *Obj_CreateSpecialUFO(void)
|
||||||
|
|
||||||
UINT32 K_GetSpecialUFODistance(void)
|
UINT32 K_GetSpecialUFODistance(void)
|
||||||
{
|
{
|
||||||
if (specialStage.active == true)
|
if (specialstageinfo.valid == true)
|
||||||
{
|
{
|
||||||
if (specialStage.ufo != NULL && P_MobjWasRemoved(specialStage.ufo) == false)
|
if (specialstageinfo.ufo != NULL && P_MobjWasRemoved(specialstageinfo.ufo) == false)
|
||||||
{
|
{
|
||||||
return (UINT32)ufo_distancetofinish(specialStage.ufo);
|
return (UINT32)ufo_distancetofinish(specialstageinfo.ufo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
#include "k_grandprix.h"
|
#include "k_grandprix.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_respawn.h"
|
#include "k_respawn.h"
|
||||||
#include "p_spec.h"
|
#include "p_spec.h"
|
||||||
#include "k_objects.h"
|
#include "k_objects.h"
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_boss.h"
|
|
||||||
#include "k_color.h"
|
#include "k_color.h"
|
||||||
#include "k_respawn.h"
|
#include "k_respawn.h"
|
||||||
#include "k_bot.h"
|
#include "k_bot.h"
|
||||||
|
|
@ -9366,7 +9365,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
||||||
{
|
{
|
||||||
if (gametyperules & GTR_PAPERITEMS)
|
if (gametyperules & GTR_PAPERITEMS)
|
||||||
{
|
{
|
||||||
if (battlecapsules == true || bossinfo.boss == true)
|
if (battlecapsules == true)
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
@ -12075,7 +12074,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
||||||
|
|
||||||
// No bosses outside of a combat situation.
|
// No bosses outside of a combat situation.
|
||||||
// (just in case we want boss arenas to do double duty as battle maps)
|
// (just in case we want boss arenas to do double duty as battle maps)
|
||||||
if (!bossinfo.boss && (mobjinfo[i].flags & MF_BOSS))
|
if (!(gametyperules & GTR_BOSS) && (mobjinfo[i].flags & MF_BOSS))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -12096,7 +12095,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
|
||||||
if ((i == MT_RING) && (gametyperules & GTR_SPHERES))
|
if ((i == MT_RING) && (gametyperules & GTR_SPHERES))
|
||||||
return MT_BLUESPHERE;
|
return MT_BLUESPHERE;
|
||||||
|
|
||||||
if ((i == MT_RANDOMITEM) && (gametyperules & (GTR_PAPERITEMS|GTR_CIRCUIT)) == (GTR_PAPERITEMS|GTR_CIRCUIT) && !bossinfo.boss)
|
if ((i == MT_RANDOMITEM) && (gametyperules & (GTR_PAPERITEMS|GTR_CIRCUIT)) == (GTR_PAPERITEMS|GTR_CIRCUIT))
|
||||||
return MT_PAPERITEMSPOT;
|
return MT_PAPERITEMSPOT;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
||||||
|
|
@ -6844,7 +6844,7 @@ static void P_InitLevelSettings(void)
|
||||||
if (playeringame[i] && !players[i].spectator)
|
if (playeringame[i] && !players[i].spectator)
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
if (grandprixinfo.gp == false && bossinfo.boss == false)
|
if (grandprixinfo.gp == false)
|
||||||
players[i].lives = 3;
|
players[i].lives = 3;
|
||||||
|
|
||||||
G_PlayerReborn(i, true);
|
G_PlayerReborn(i, true);
|
||||||
|
|
@ -6854,38 +6854,27 @@ static void P_InitLevelSettings(void)
|
||||||
racecountdown = exitcountdown = exitfadestarted = 0;
|
racecountdown = exitcountdown = exitfadestarted = 0;
|
||||||
curlap = bestlap = 0; // SRB2Kart
|
curlap = bestlap = 0; // SRB2Kart
|
||||||
|
|
||||||
// SRB2Kart: map load variables
|
// Gamespeed and frantic items
|
||||||
|
gamespeed = KARTSPEED_EASY;
|
||||||
|
franticitems = false;
|
||||||
|
|
||||||
if (grandprixinfo.gp == true)
|
if (grandprixinfo.gp == true)
|
||||||
{
|
{
|
||||||
if (!(gametyperules & GTR_CIRCUIT))
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
{
|
|
||||||
gamespeed = KARTSPEED_EASY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
gamespeed = grandprixinfo.gamespeed;
|
gamespeed = grandprixinfo.gamespeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
franticitems = false;
|
|
||||||
}
|
|
||||||
else if (bossinfo.boss)
|
|
||||||
{
|
|
||||||
gamespeed = KARTSPEED_EASY;
|
|
||||||
franticitems = false;
|
|
||||||
}
|
}
|
||||||
else if (modeattacking)
|
else if (modeattacking)
|
||||||
{
|
{
|
||||||
if (!(gametyperules & GTR_CIRCUIT))
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
gamespeed = KARTSPEED_EASY;
|
{
|
||||||
else
|
|
||||||
gamespeed = KARTSPEED_HARD;
|
gamespeed = KARTSPEED_HARD;
|
||||||
franticitems = false;
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(gametyperules & GTR_CIRCUIT))
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
gamespeed = KARTSPEED_EASY;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (cv_kartspeed.value == KARTSPEED_AUTO)
|
if (cv_kartspeed.value == KARTSPEED_AUTO)
|
||||||
gamespeed = ((speedscramble == -1) ? KARTSPEED_NORMAL : (UINT8)speedscramble);
|
gamespeed = ((speedscramble == -1) ? KARTSPEED_NORMAL : (UINT8)speedscramble);
|
||||||
|
|
@ -6900,6 +6889,9 @@ static void P_InitLevelSettings(void)
|
||||||
|
|
||||||
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
||||||
speedscramble = encorescramble = -1;
|
speedscramble = encorescramble = -1;
|
||||||
|
|
||||||
|
K_ResetSpecialStage();
|
||||||
|
K_ResetBossInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -7611,19 +7603,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||||
K_UpdateMatchRaceBots();
|
K_UpdateMatchRaceBots();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bossinfo.boss)
|
|
||||||
{
|
|
||||||
// Reset some pesky boss state that can't be handled elsewhere.
|
|
||||||
bossinfo.barlen = BOSSHEALTHBARLEN;
|
|
||||||
bossinfo.visualbar = 0;
|
|
||||||
Z_Free(bossinfo.enemyname);
|
|
||||||
Z_Free(bossinfo.subtitle);
|
|
||||||
bossinfo.enemyname = bossinfo.subtitle = NULL;
|
|
||||||
bossinfo.titleshow = 0;
|
|
||||||
bossinfo.titlesound = sfx_typri1;
|
|
||||||
memset(&(bossinfo.weakspots), 0, sizeof(weakspot_t)*NUMWEAKSPOTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fromnetsave) // uglier hack
|
if (!fromnetsave) // uglier hack
|
||||||
{ // to make a newly loaded level start on the second frame.
|
{ // to make a newly loaded level start on the second frame.
|
||||||
INT32 buf = gametic % BACKUPTICS;
|
INT32 buf = gametic % BACKUPTICS;
|
||||||
|
|
|
||||||
|
|
@ -646,7 +646,7 @@ void P_Ticker(boolean run)
|
||||||
P_PlayerAfterThink(&players[i]);
|
P_PlayerAfterThink(&players[i]);
|
||||||
|
|
||||||
// Bosses have a punchy start, so no position.
|
// Bosses have a punchy start, so no position.
|
||||||
if (bossinfo.boss == true)
|
if (K_CheckBossIntro() == true)
|
||||||
{
|
{
|
||||||
if (leveltime == 3)
|
if (leveltime == 3)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -828,7 +828,8 @@ void P_RestoreMusic(player_t *player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Event - Level Start
|
// Event - Level Start
|
||||||
if (bossinfo.boss == false && (leveltime < (starttime + (TICRATE/2)))) // see also where time overs are handled
|
if ((K_CheckBossIntro() == false)
|
||||||
|
&& (leveltime < (starttime + (TICRATE/2)))) // see also where time overs are handled
|
||||||
return;
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -3612,7 +3613,7 @@ void P_DoTimeOver(player_t *player)
|
||||||
legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p
|
legitimateexit = true; // SRB2kart: losing a race is still seeing it through to the end :p
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netgame && !player->bot && !bossinfo.boss)
|
if (netgame && !player->bot && !(gametyperules & GTR_BOSS))
|
||||||
{
|
{
|
||||||
CON_LogMessage(va(M_GetText("%s ran out of time.\n"), player_names[player-players]));
|
CON_LogMessage(va(M_GetText("%s ran out of time.\n"), player_names[player-players]));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@
|
||||||
#include "m_misc.h" // for tunes command
|
#include "m_misc.h" // for tunes command
|
||||||
#include "m_cond.h" // for conditionsets
|
#include "m_cond.h" // for conditionsets
|
||||||
#include "lua_hook.h" // MusicChange hook
|
#include "lua_hook.h" // MusicChange hook
|
||||||
#include "k_boss.h" // bossinfo
|
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
|
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
|
|
|
||||||
|
|
@ -597,7 +597,7 @@ void ST_runTitleCard(void)
|
||||||
|
|
||||||
// SRB2KART
|
// SRB2KART
|
||||||
// side Zig-Zag positions...
|
// side Zig-Zag positions...
|
||||||
if (bossinfo.boss == true)
|
if (K_CheckBossIntro() == true)
|
||||||
{
|
{
|
||||||
// Handle name info...
|
// Handle name info...
|
||||||
if (bossinfo.enemyname)
|
if (bossinfo.enemyname)
|
||||||
|
|
@ -792,7 +792,7 @@ void ST_drawTitleCard(void)
|
||||||
if (lt_ticker < TTANIMSTART)
|
if (lt_ticker < TTANIMSTART)
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
|
||||||
|
|
||||||
if (bossinfo.boss == true)
|
if (K_CheckBossIntro() == true)
|
||||||
{
|
{
|
||||||
// WARNING!
|
// WARNING!
|
||||||
// https://twitter.com/matthewseiji/status/1485003284196716544
|
// https://twitter.com/matthewseiji/status/1485003284196716544
|
||||||
|
|
|
||||||
|
|
@ -589,7 +589,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
|
||||||
{
|
{
|
||||||
const tic_t length = TICRATE/4;
|
const tic_t length = TICRATE/4;
|
||||||
tic_t timer = lt_exitticker;
|
tic_t timer = lt_exitticker;
|
||||||
if (bossinfo.boss == true)
|
if (K_CheckBossIntro() == true)
|
||||||
{
|
{
|
||||||
if (leveltime <= 3)
|
if (leveltime <= 3)
|
||||||
timer = 0;
|
timer = 0;
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// set up the levelstring
|
// set up the levelstring
|
||||||
if (bossinfo.boss == true && bossinfo.enemyname)
|
if (bossinfo.valid == true && bossinfo.enemyname)
|
||||||
{
|
{
|
||||||
snprintf(data.levelstring,
|
snprintf(data.levelstring,
|
||||||
sizeof data.levelstring,
|
sizeof data.levelstring,
|
||||||
|
|
@ -574,7 +574,7 @@ skiptallydrawer:
|
||||||
if (!LUA_HudEnabled(hud_intermissionmessages))
|
if (!LUA_HudEnabled(hud_intermissionmessages))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (timer && grandprixinfo.gp == false && bossinfo.boss == false && !modeattacking)
|
if (timer && grandprixinfo.gp == false && !modeattacking)
|
||||||
{
|
{
|
||||||
char *string;
|
char *string;
|
||||||
INT32 tickdown = (timer+1)/TICRATE;
|
INT32 tickdown = (timer+1)/TICRATE;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue