mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into item-bungus
This commit is contained in:
commit
429f61966e
32 changed files with 662 additions and 448 deletions
|
|
@ -301,13 +301,25 @@ target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
|
||||||
# ${SRB2_BLUA_HEADERS}
|
# ${SRB2_BLUA_HEADERS}
|
||||||
#)
|
#)
|
||||||
|
|
||||||
|
## strip debug symbols into separate file when using gcc.
|
||||||
|
## to be consistent with Makefile, don't generate for OS X.
|
||||||
|
if((CMAKE_COMPILER_IS_GNUCC) AND NOT (${CMAKE_SYSTEM} MATCHES Darwin))
|
||||||
|
if((${CMAKE_BUILD_TYPE} MATCHES Debug) OR (${CMAKE_BUILD_TYPE} MATCHES RelWithDebInfo))
|
||||||
|
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
||||||
|
set(OBJCOPY_ONLY_KEEP_DEBUG "--only-keep-debug")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Will make separate debug symbols in *.debug")
|
||||||
|
add_custom_command(TARGET SRB2SDL2 POST_BUILD
|
||||||
|
COMMAND ${OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
|
||||||
|
COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:SRB2SDL2>
|
||||||
|
COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(sdl)
|
add_subdirectory(sdl)
|
||||||
add_subdirectory(objects)
|
add_subdirectory(objects)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM} MATCHES Windows)
|
|
||||||
add_subdirectory(win32)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ${SRB2_SDL2_AVAILABLE})
|
if(NOT ${SRB2_SDL2_AVAILABLE})
|
||||||
message(FATAL_ERROR "There are no targets available to build an SRB2Kart executable. :(")
|
message(FATAL_ERROR "There are no targets available to build an SRB2Kart executable. :(")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -1641,34 +1641,14 @@ void CV_SaveVars(UINT8 **p, boolean in_demo)
|
||||||
// the client will reset all netvars to default before loading
|
// the client will reset all netvars to default before loading
|
||||||
WRITEUINT16(*p, 0x0000);
|
WRITEUINT16(*p, 0x0000);
|
||||||
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
for (cvar = consvar_vars; cvar; cvar = cvar->next)
|
||||||
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (in_demo && cvar->netid == cv_numlaps.netid))
|
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
|
||||||
{
|
{
|
||||||
if (in_demo)
|
if (in_demo)
|
||||||
WRITESTRING(*p, cvar->name);
|
WRITESTRING(*p, cvar->name);
|
||||||
else
|
else
|
||||||
WRITEUINT16(*p, cvar->netid);
|
WRITEUINT16(*p, cvar->netid);
|
||||||
|
|
||||||
// UGLY HACK: Save proper lap count in net replays
|
WRITESTRING(*p, cvar->string);
|
||||||
if (in_demo && cvar->netid == cv_numlaps.netid)
|
|
||||||
{
|
|
||||||
if (cv_basenumlaps.value &&
|
|
||||||
(!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
|
||||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
WRITESTRING(*p, cv_basenumlaps.string);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char buf[9];
|
|
||||||
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
|
|
||||||
WRITESTRING(*p, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WRITESTRING(*p, cvar->string);
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITEUINT8(*p, false);
|
WRITEUINT8(*p, false);
|
||||||
++count;
|
++count;
|
||||||
|
|
|
||||||
|
|
@ -888,7 +888,11 @@ void D_SRB2Loop(void)
|
||||||
if (!singletics)
|
if (!singletics)
|
||||||
{
|
{
|
||||||
INT64 elapsed = (INT64)(finishprecise - enterprecise);
|
INT64 elapsed = (INT64)(finishprecise - enterprecise);
|
||||||
if (elapsed > 0 && (INT64)capbudget > elapsed)
|
|
||||||
|
// in the case of "match refresh rate" + vsync, don't sleep at all
|
||||||
|
const boolean vsync_with_match_refresh = cv_vidwait.value && cv_fpscap.value == 0;
|
||||||
|
|
||||||
|
if (elapsed > 0 && (INT64)capbudget > elapsed && !vsync_with_match_refresh)
|
||||||
{
|
{
|
||||||
I_SleepDuration(capbudget - (finishprecise - enterprecise));
|
I_SleepDuration(capbudget - (finishprecise - enterprecise));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,6 @@ static void Got_DiscordInfo(UINT8 **cp, INT32 playernum);
|
||||||
static void PointLimit_OnChange(void);
|
static void PointLimit_OnChange(void);
|
||||||
static void TimeLimit_OnChange(void);
|
static void TimeLimit_OnChange(void);
|
||||||
static void NumLaps_OnChange(void);
|
static void NumLaps_OnChange(void);
|
||||||
static void BaseNumLaps_OnChange(void);
|
|
||||||
static void Mute_OnChange(void);
|
static void Mute_OnChange(void);
|
||||||
|
|
||||||
static void AutoBalance_OnChange(void);
|
static void AutoBalance_OnChange(void);
|
||||||
|
|
@ -141,7 +140,6 @@ static void Color4_OnChange(void);
|
||||||
static void DummyConsvar_OnChange(void);
|
static void DummyConsvar_OnChange(void);
|
||||||
static void SoundTest_OnChange(void);
|
static void SoundTest_OnChange(void);
|
||||||
|
|
||||||
static void BaseNumLaps_OnChange(void);
|
|
||||||
static void KartFrantic_OnChange(void);
|
static void KartFrantic_OnChange(void);
|
||||||
static void KartSpeed_OnChange(void);
|
static void KartSpeed_OnChange(void);
|
||||||
static void KartEncore_OnChange(void);
|
static void KartEncore_OnChange(void);
|
||||||
|
|
@ -467,10 +465,9 @@ static CV_PossibleValue_t pointlimit_cons_t[] = {{1, "MIN"}, {MAXSCORE, "MAX"},
|
||||||
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_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange);
|
||||||
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "MAX"}, {0, "None"}, {0, NULL}};
|
static CV_PossibleValue_t timelimit_cons_t[] = {{1, "MIN"}, {30, "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_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange);
|
||||||
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
|
||||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange);
|
static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {MAX_LAPS, "MAX"}, {0, "Map default"}, {0, NULL}};
|
||||||
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}};
|
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange);
|
||||||
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange);
|
|
||||||
|
|
||||||
// Point and time limits for every gametype
|
// Point and time limits for every gametype
|
||||||
INT32 pointlimits[NUMGAMETYPES];
|
INT32 pointlimits[NUMGAMETYPES];
|
||||||
|
|
@ -691,7 +688,6 @@ void D_RegisterServerCommands(void)
|
||||||
// misc
|
// misc
|
||||||
CV_RegisterVar(&cv_pointlimit);
|
CV_RegisterVar(&cv_pointlimit);
|
||||||
CV_RegisterVar(&cv_numlaps);
|
CV_RegisterVar(&cv_numlaps);
|
||||||
CV_RegisterVar(&cv_basenumlaps);
|
|
||||||
|
|
||||||
CV_RegisterVar(&cv_autobalance);
|
CV_RegisterVar(&cv_autobalance);
|
||||||
CV_RegisterVar(&cv_teamscramble);
|
CV_RegisterVar(&cv_teamscramble);
|
||||||
|
|
@ -4480,24 +4476,6 @@ static void PointLimit_OnChange(void)
|
||||||
CONS_Printf(M_GetText("Point limit disabled\n"));
|
CONS_Printf(M_GetText("Point limit disabled\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NumLaps_OnChange(void)
|
|
||||||
{
|
|
||||||
if (K_CanChangeRules() == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
|
||||||
&& (cv_numlaps.value > mapheaderinfo[gamemap - 1]->numlaps))
|
|
||||||
{
|
|
||||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just don't be verbose
|
|
||||||
if (gametyperules & GTR_CIRCUIT)
|
|
||||||
CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NetTimeout_OnChange(void)
|
static void NetTimeout_OnChange(void)
|
||||||
{
|
{
|
||||||
connectiontimeout = (tic_t)cv_nettimeout.value;
|
connectiontimeout = (tic_t)cv_nettimeout.value;
|
||||||
|
|
@ -5759,22 +5737,24 @@ static void Command_ShowTime_f(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SRB2Kart: On change messages
|
// SRB2Kart: On change messages
|
||||||
static void BaseNumLaps_OnChange(void)
|
static void NumLaps_OnChange(void)
|
||||||
{
|
{
|
||||||
if (K_CanChangeRules() == true)
|
if (K_CanChangeRules() == false)
|
||||||
{
|
{
|
||||||
const char *str = va("%d", cv_basenumlaps.value);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cv_basenumlaps.value == 0)
|
if (leveltime < starttime)
|
||||||
{
|
{
|
||||||
str = "map defaults";
|
CONS_Printf(M_GetText("Number of laps have been set to %d.\n"), cv_numlaps.value);
|
||||||
}
|
numlaps = (UINT8)cv_numlaps.value;
|
||||||
|
}
|
||||||
CONS_Printf(M_GetText("Number of laps will be changed to %s next round.\n"), str);
|
else
|
||||||
|
{
|
||||||
|
CONS_Printf(M_GetText("Number of laps will be set to %d next round.\n"), cv_numlaps.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void KartFrantic_OnChange(void)
|
static void KartFrantic_OnChange(void)
|
||||||
{
|
{
|
||||||
if (K_CanChangeRules() == false)
|
if (K_CanChangeRules() == false)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ extern consvar_t cv_itemrespawn;
|
||||||
extern consvar_t cv_pointlimit;
|
extern consvar_t cv_pointlimit;
|
||||||
extern consvar_t cv_timelimit;
|
extern consvar_t cv_timelimit;
|
||||||
extern consvar_t cv_numlaps;
|
extern consvar_t cv_numlaps;
|
||||||
extern consvar_t cv_basenumlaps;
|
|
||||||
extern UINT32 timelimitintics;
|
extern UINT32 timelimitintics;
|
||||||
extern consvar_t cv_allowexitlevel;
|
extern consvar_t cv_allowexitlevel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ typedef enum
|
||||||
#define TRICKDELAY (TICRATE/4)
|
#define TRICKDELAY (TICRATE/4)
|
||||||
|
|
||||||
#define TUMBLEBOUNCES 3
|
#define TUMBLEBOUNCES 3
|
||||||
|
#define TUMBLEGRAVITY (4*FRACUNIT)
|
||||||
|
|
||||||
#define BALLHOGINCREMENT (7)
|
#define BALLHOGINCREMENT (7)
|
||||||
|
|
||||||
|
|
@ -541,6 +542,7 @@ typedef struct player_s
|
||||||
INT16 totalring; // Total number of rings obtained for GP
|
INT16 totalring; // Total number of rings obtained for GP
|
||||||
tic_t realtime; // integer replacement for leveltime
|
tic_t realtime; // integer replacement for leveltime
|
||||||
UINT8 laps; // Number of laps (optional)
|
UINT8 laps; // Number of laps (optional)
|
||||||
|
UINT8 latestlap;
|
||||||
INT32 starpostnum; // The number of the last starpost you hit
|
INT32 starpostnum; // The number of the last starpost you hit
|
||||||
|
|
||||||
UINT8 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue
|
UINT8 ctfteam; // 0 == Spectator, 1 == Red, 2 == Blue
|
||||||
|
|
|
||||||
|
|
@ -700,6 +700,7 @@ extern INT16 scramblecount; //for CTF team scramble
|
||||||
extern INT32 cheats;
|
extern INT32 cheats;
|
||||||
|
|
||||||
// SRB2kart
|
// SRB2kart
|
||||||
|
extern UINT8 numlaps;
|
||||||
extern UINT8 gamespeed;
|
extern UINT8 gamespeed;
|
||||||
extern boolean franticitems;
|
extern boolean franticitems;
|
||||||
extern boolean encoremode, prevencoremode;
|
extern boolean encoremode, prevencoremode;
|
||||||
|
|
|
||||||
17
src/g_demo.c
17
src/g_demo.c
|
|
@ -1999,6 +1999,7 @@ void G_BeginRecording(void)
|
||||||
|
|
||||||
WRITEUINT8(demo_p, demoflags);
|
WRITEUINT8(demo_p, demoflags);
|
||||||
WRITEUINT8(demo_p, gametype & 0xFF);
|
WRITEUINT8(demo_p, gametype & 0xFF);
|
||||||
|
WRITEUINT8(demo_p, numlaps);
|
||||||
|
|
||||||
// file list
|
// file list
|
||||||
m = demo_p;/* file count */
|
m = demo_p;/* file count */
|
||||||
|
|
@ -2429,6 +2430,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
p += 16; // map md5
|
p += 16; // map md5
|
||||||
flags = READUINT8(p); // demoflags
|
flags = READUINT8(p); // demoflags
|
||||||
p++; // gametype
|
p++; // gametype
|
||||||
|
p++; // numlaps
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p);
|
||||||
|
|
||||||
aflags = flags & (DF_TIMEATTACK|DF_BREAKTHECAPSULES);
|
aflags = flags & (DF_TIMEATTACK|DF_BREAKTHECAPSULES);
|
||||||
|
|
@ -2486,6 +2488,7 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
p += 16; // mapmd5
|
p += 16; // mapmd5
|
||||||
flags = READUINT8(p);
|
flags = READUINT8(p);
|
||||||
p++; // gametype
|
p++; // gametype
|
||||||
|
p++; // numlaps
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p);
|
||||||
if (!(flags & aflags))
|
if (!(flags & aflags))
|
||||||
{
|
{
|
||||||
|
|
@ -2600,6 +2603,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||||
}
|
}
|
||||||
|
|
||||||
pdemo->gametype = READUINT8(info_p);
|
pdemo->gametype = READUINT8(info_p);
|
||||||
|
pdemo->numlaps = READUINT8(info_p);
|
||||||
|
|
||||||
pdemo->addonstatus = G_CheckDemoExtraFiles(&info_p, true);
|
pdemo->addonstatus = G_CheckDemoExtraFiles(&info_p, true);
|
||||||
info_p += 4; // RNG seed
|
info_p += 4; // RNG seed
|
||||||
|
|
@ -2626,20 +2630,11 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
||||||
if (!stricmp(kartspeed_cons_t[j].strvalue, svalue))
|
if (!stricmp(kartspeed_cons_t[j].strvalue, svalue))
|
||||||
pdemo->kartspeed = kartspeed_cons_t[j].value;
|
pdemo->kartspeed = kartspeed_cons_t[j].value;
|
||||||
}
|
}
|
||||||
else if (netid == cv_basenumlaps.netid && pdemo->gametype == GT_RACE)
|
|
||||||
pdemo->numlaps = atoi(svalue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdemoflags & DF_ENCORE)
|
if (pdemoflags & DF_ENCORE)
|
||||||
pdemo->kartspeed |= DF_ENCORE;
|
pdemo->kartspeed |= DF_ENCORE;
|
||||||
|
|
||||||
/*// Temporary info until this is actually present in replays.
|
|
||||||
(void)extrainfo_p;
|
|
||||||
sprintf(pdemo->winnername, "transrights420");
|
|
||||||
pdemo->winnerskin = 1;
|
|
||||||
pdemo->winnercolor = SKINCOLOR_MOONSET;
|
|
||||||
pdemo->winnertime = 6666;*/
|
|
||||||
|
|
||||||
// Read standings!
|
// Read standings!
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
|
|
@ -2835,6 +2830,7 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
demoflags = READUINT8(demo_p);
|
demoflags = READUINT8(demo_p);
|
||||||
gametype = READUINT8(demo_p);
|
gametype = READUINT8(demo_p);
|
||||||
G_SetGametype(gametype);
|
G_SetGametype(gametype);
|
||||||
|
numlaps = READUINT8(demo_p);
|
||||||
|
|
||||||
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||||
G_SkipDemoExtraFiles(&demo_p);
|
G_SkipDemoExtraFiles(&demo_p);
|
||||||
|
|
@ -3258,6 +3254,7 @@ void G_AddGhost(char *defdemoname)
|
||||||
}
|
}
|
||||||
|
|
||||||
p++; // gametype
|
p++; // gametype
|
||||||
|
p++; // numlaps
|
||||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||||
|
|
||||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
|
|
@ -3475,7 +3472,7 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
||||||
}
|
}
|
||||||
|
|
||||||
p++; // Gametype
|
p++; // Gametype
|
||||||
|
p++; // numlaps
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p);
|
||||||
|
|
||||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
|
|
|
||||||
10
src/g_game.c
10
src/g_game.c
|
|
@ -303,6 +303,7 @@ INT32 cheats; //for multiplayer cheat commands
|
||||||
|
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
// Cvars that we don't want changed mid-game
|
// Cvars that we don't want changed mid-game
|
||||||
|
UINT8 numlaps; // Removed from Cvar hell
|
||||||
UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard
|
UINT8 gamespeed; // Game's current speed (or difficulty, or cc, or etc); 0 for easy, 1 for normal, 2 for hard
|
||||||
boolean encoremode = false; // Encore Mode currently enabled?
|
boolean encoremode = false; // Encore Mode currently enabled?
|
||||||
boolean prevencoremode;
|
boolean prevencoremode;
|
||||||
|
|
@ -2198,6 +2199,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
INT32 khudcardanimation;
|
INT32 khudcardanimation;
|
||||||
INT16 totalring;
|
INT16 totalring;
|
||||||
UINT8 laps;
|
UINT8 laps;
|
||||||
|
UINT8 latestlap;
|
||||||
UINT16 skincolor;
|
UINT16 skincolor;
|
||||||
INT32 skin;
|
INT32 skin;
|
||||||
UINT32 availabilities;
|
UINT32 availabilities;
|
||||||
|
|
@ -2284,6 +2286,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
khudfault = 0;
|
khudfault = 0;
|
||||||
nocontrol = 0;
|
nocontrol = 0;
|
||||||
laps = 0;
|
laps = 0;
|
||||||
|
latestlap = 0;
|
||||||
totalring = 0;
|
totalring = 0;
|
||||||
roundscore = 0;
|
roundscore = 0;
|
||||||
exiting = 0;
|
exiting = 0;
|
||||||
|
|
@ -2324,6 +2327,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
nocontrol = players[player].nocontrol;
|
nocontrol = players[player].nocontrol;
|
||||||
|
|
||||||
laps = players[player].laps;
|
laps = players[player].laps;
|
||||||
|
latestlap = players[player].latestlap;
|
||||||
|
|
||||||
totalring = players[player].totalring;
|
totalring = players[player].totalring;
|
||||||
roundscore = players[player].roundscore;
|
roundscore = players[player].roundscore;
|
||||||
|
|
||||||
|
|
@ -2380,6 +2385,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
p->karthud[khud_cardanimation] = khudcardanimation;
|
p->karthud[khud_cardanimation] = khudcardanimation;
|
||||||
|
|
||||||
p->laps = laps;
|
p->laps = laps;
|
||||||
|
p->latestlap = latestlap;
|
||||||
p->totalring = totalring;
|
p->totalring = totalring;
|
||||||
|
|
||||||
p->bot = bot;
|
p->bot = bot;
|
||||||
|
|
@ -3610,11 +3616,14 @@ static void G_DoCompleted(void)
|
||||||
wipegamestate = GS_NULL;
|
wipegamestate = GS_NULL;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
{
|
{
|
||||||
// SRB2Kart: exitlevel shouldn't get you the points
|
// SRB2Kart: exitlevel shouldn't get you the points
|
||||||
if (!players[i].exiting && !(players[i].pflags & PF_NOCONTEST))
|
if (!players[i].exiting && !(players[i].pflags & PF_NOCONTEST))
|
||||||
{
|
{
|
||||||
|
clientPowerAdd[i] = 0;
|
||||||
|
|
||||||
if (players[i].bot)
|
if (players[i].bot)
|
||||||
{
|
{
|
||||||
K_FakeBotResults(&players[i]);
|
K_FakeBotResults(&players[i]);
|
||||||
|
|
@ -3632,6 +3641,7 @@ static void G_DoCompleted(void)
|
||||||
|
|
||||||
G_PlayerFinishLevel(i); // take away cards and stuff
|
G_PlayerFinishLevel(i); // take away cards and stuff
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// play some generic music if there's no win/cool/lose music going on (for exitlevel commands)
|
// 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))
|
if ((gametyperules & GTR_CIRCUIT) && ((multiplayer && demo.playback) || j == r_splitscreen+1) && (cv_inttime.value > 0))
|
||||||
|
|
|
||||||
|
|
@ -2421,7 +2421,7 @@ static void HU_DrawRankings(void)
|
||||||
if (circuitmap)
|
if (circuitmap)
|
||||||
{
|
{
|
||||||
V_DrawCenteredString(64, 8, 0, "LAP COUNT");
|
V_DrawCenteredString(64, 8, 0, "LAP COUNT");
|
||||||
V_DrawCenteredString(64, 16, hilicol, va("%d", cv_numlaps.value));
|
V_DrawCenteredString(64, 16, hilicol, va("%d", numlaps));
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawCenteredString(256, 8, 0, "GAME SPEED");
|
V_DrawCenteredString(256, 8, 0, "GAME SPEED");
|
||||||
|
|
|
||||||
|
|
@ -675,6 +675,12 @@ static inline BlockItReturn_t PIT_LightningShieldAttack(mobj_t *thing)
|
||||||
return BMIT_ABORT;
|
return BMIT_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thing == NULL || P_MobjWasRemoved(thing))
|
||||||
|
{
|
||||||
|
// Invalid?
|
||||||
|
return BMIT_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
if (thing == lightningSource)
|
if (thing == lightningSource)
|
||||||
{
|
{
|
||||||
// Don't explode yourself!!
|
// Don't explode yourself!!
|
||||||
|
|
|
||||||
14
src/k_hud.c
14
src/k_hud.c
|
|
@ -1716,7 +1716,7 @@ static void K_DrawKartPositionNum(INT32 num)
|
||||||
{
|
{
|
||||||
localpatch = kp_winnernum[(leveltime % (NUMWINFRAMES*3)) / 3];
|
localpatch = kp_winnernum[(leveltime % (NUMWINFRAMES*3)) / 3];
|
||||||
}
|
}
|
||||||
else if (stplyr->laps >= cv_numlaps.value || stplyr->exiting) // Check for the final lap, or won
|
else if (stplyr->laps >= numlaps || stplyr->exiting) // Check for the final lap, or won
|
||||||
{
|
{
|
||||||
boolean useRedNums = K_IsPlayerLosing(stplyr);
|
boolean useRedNums = K_IsPlayerLosing(stplyr);
|
||||||
|
|
||||||
|
|
@ -2347,7 +2347,7 @@ static void K_drawKartLapsAndRings(void)
|
||||||
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitlapflag);
|
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_splitlapflag);
|
||||||
V_DrawScaledPatch(fx+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
|
V_DrawScaledPatch(fx+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
|
||||||
|
|
||||||
if (cv_numlaps.value >= 10)
|
if (numlaps >= 10)
|
||||||
{
|
{
|
||||||
UINT8 ln[2];
|
UINT8 ln[2];
|
||||||
ln[0] = ((stplyr->laps / 10) % 10);
|
ln[0] = ((stplyr->laps / 10) % 10);
|
||||||
|
|
@ -2356,8 +2356,8 @@ static void K_drawKartLapsAndRings(void)
|
||||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||||
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||||
|
|
||||||
ln[0] = ((abs(cv_numlaps.value) / 10) % 10);
|
ln[0] = ((numlaps / 10) % 10);
|
||||||
ln[1] = (abs(cv_numlaps.value) % 10);
|
ln[1] = (numlaps % 10);
|
||||||
|
|
||||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
|
||||||
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
|
||||||
|
|
@ -2365,7 +2365,7 @@ static void K_drawKartLapsAndRings(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->laps) % 10]);
|
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->laps) % 10]);
|
||||||
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(cv_numlaps.value) % 10]);
|
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(numlaps) % 10]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rings
|
// Rings
|
||||||
|
|
@ -2403,7 +2403,7 @@ static void K_drawKartLapsAndRings(void)
|
||||||
{
|
{
|
||||||
// Laps
|
// Laps
|
||||||
V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker);
|
V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker);
|
||||||
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, cv_numlaps.value), cv_numlaps.value));
|
V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, numlaps), numlaps));
|
||||||
|
|
||||||
// Rings
|
// Rings
|
||||||
if (!uselives)
|
if (!uselives)
|
||||||
|
|
@ -4377,7 +4377,7 @@ static void K_drawLapStartAnim(void)
|
||||||
kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL);
|
kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stplyr->laps == (UINT8)(cv_numlaps.value))
|
if (stplyr->laps == (UINT8)(numlaps))
|
||||||
{
|
{
|
||||||
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
|
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
|
||||||
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
|
||||||
|
|
|
||||||
122
src/k_kart.c
122
src/k_kart.c
|
|
@ -357,15 +357,15 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
||||||
/*Invincibility*/ { 0, 0, 0, 0, 3, 4, 6, 9 }, // Invincibility
|
/*Invincibility*/ { 0, 0, 0, 0, 3, 4, 6, 9 }, // Invincibility
|
||||||
/*Banana*/ { 2, 3, 1, 0, 0, 0, 0, 0 }, // Banana
|
/*Banana*/ { 2, 3, 1, 0, 0, 0, 0, 0 }, // Banana
|
||||||
/*Eggman Monitor*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
|
/*Eggman Monitor*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Eggman Monitor
|
||||||
/*Orbinaut*/ { 5, 4, 2, 2, 0, 0, 0, 0 }, // Orbinaut
|
/*Orbinaut*/ { 5, 5, 2, 2, 0, 0, 0, 0 }, // Orbinaut
|
||||||
/*Jawz*/ { 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz
|
/*Jawz*/ { 0, 4, 2, 1, 0, 0, 0, 0 }, // Jawz
|
||||||
/*Mine*/ { 0, 2, 3, 1, 0, 0, 0, 0 }, // Mine
|
/*Mine*/ { 0, 3, 3, 1, 0, 0, 0, 0 }, // Mine
|
||||||
/*Land Mine*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine
|
/*Land Mine*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Land Mine
|
||||||
/*Ballhog*/ { 0, 0, 2, 2, 0, 0, 0, 0 }, // Ballhog
|
/*Ballhog*/ { 0, 0, 2, 2, 0, 0, 0, 0 }, // Ballhog
|
||||||
/*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb
|
/*Self-Propelled Bomb*/ { 0, 0, 0, 0, 0, 2, 4, 0 }, // Self-Propelled Bomb
|
||||||
/*Grow*/ { 0, 0, 0, 1, 2, 3, 0, 0 }, // Grow
|
/*Grow*/ { 0, 0, 0, 1, 2, 3, 0, 0 }, // Grow
|
||||||
/*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink
|
/*Shrink*/ { 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink
|
||||||
/*Lightning Shield*/ { 1, 2, 0, 0, 0, 0, 0, 0 }, // Lightning Shield
|
/*Lightning Shield*/ { 1, 0, 0, 0, 0, 0, 0, 0 }, // Lightning Shield
|
||||||
/*Bubble Shield*/ { 0, 1, 2, 1, 0, 0, 0, 0 }, // Bubble Shield
|
/*Bubble Shield*/ { 0, 1, 2, 1, 0, 0, 0, 0 }, // Bubble Shield
|
||||||
/*Flame Shield*/ { 0, 0, 0, 0, 0, 1, 3, 5 }, // Flame Shield
|
/*Flame Shield*/ { 0, 0, 0, 0, 0, 1, 3, 5 }, // Flame Shield
|
||||||
/*Hyudoro*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Hyudoro
|
/*Hyudoro*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Hyudoro
|
||||||
|
|
@ -373,13 +373,13 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS-1][8] =
|
||||||
/*Super Ring*/ { 2, 1, 1, 0, 0, 0, 0, 0 }, // Super Ring
|
/*Super Ring*/ { 2, 1, 1, 0, 0, 0, 0, 0 }, // Super Ring
|
||||||
/*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
|
/*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
|
||||||
/*Drop Target*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target
|
/*Drop Target*/ { 3, 0, 0, 0, 0, 0, 0, 0 }, // Drop Target
|
||||||
/*Sneaker x2*/ { 0, 0, 2, 2, 1, 0, 0, 0 }, // Sneaker x2
|
/*Sneaker x2*/ { 0, 0, 2, 2, 2, 0, 0, 0 }, // Sneaker x2
|
||||||
/*Sneaker x3*/ { 0, 0, 0, 2, 6,10, 5, 0 }, // Sneaker x3
|
/*Sneaker x3*/ { 0, 0, 0, 1, 6,10, 5, 0 }, // Sneaker x3
|
||||||
/*Banana x3*/ { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3
|
/*Banana x3*/ { 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3
|
||||||
/*Banana x10*/ { 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10
|
/*Banana x10*/ { 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10
|
||||||
/*Orbinaut x3*/ { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3
|
/*Orbinaut x3*/ { 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3
|
||||||
/*Orbinaut x4*/ { 0, 0, 0, 1, 1, 0, 0, 0 }, // Orbinaut x4
|
/*Orbinaut x4*/ { 0, 0, 0, 2, 0, 0, 0, 0 }, // Orbinaut x4
|
||||||
/*Jawz x2*/ { 0, 0, 1, 2, 0, 0, 0, 0 } // Jawz x2
|
/*Jawz x2*/ { 0, 0, 1, 2, 1, 0, 0, 0 } // Jawz x2
|
||||||
};
|
};
|
||||||
|
|
||||||
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
|
static INT32 K_KartItemOddsBattle[NUMKARTRESULTS][2] =
|
||||||
|
|
@ -1704,9 +1704,13 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
|
||||||
UINT8 c;
|
UINT8 c;
|
||||||
|
|
||||||
if (maxdist == 0)
|
if (maxdist == 0)
|
||||||
c = 0;
|
{
|
||||||
|
c = leveltime % CHAOTIXBANDCOLORS;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
c = FixedMul(CHAOTIXBANDCOLORS<<FRACBITS, FixedDiv(curdist-minimumdist, maxdist-minimumdist)) >> FRACBITS;
|
c = FixedMul(CHAOTIXBANDCOLORS<<FRACBITS, FixedDiv(curdist-minimumdist, maxdist-minimumdist)) >> FRACBITS;
|
||||||
|
}
|
||||||
|
|
||||||
stepx = (victim->mo->x - player->mo->x) / CHAOTIXBANDLEN;
|
stepx = (victim->mo->x - player->mo->x) / CHAOTIXBANDLEN;
|
||||||
stepy = (victim->mo->y - player->mo->y) / CHAOTIXBANDLEN;
|
stepy = (victim->mo->y - player->mo->y) / CHAOTIXBANDLEN;
|
||||||
|
|
@ -1725,8 +1729,16 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
|
||||||
curz + (P_RandomRange(24,48)*mapobjectscale),
|
curz + (P_RandomRange(24,48)*mapobjectscale),
|
||||||
MT_SIGNSPARKLE);
|
MT_SIGNSPARKLE);
|
||||||
|
|
||||||
P_SetMobjState(band, S_SIGNSPARK1 + (leveltime % 11));
|
if (maxdist == 0)
|
||||||
P_SetScale(band, (band->destscale = (3*player->mo->scale)/2));
|
{
|
||||||
|
P_SetMobjState(band, S_KSPARK1 + (leveltime % 8));
|
||||||
|
P_SetScale(band, (band->destscale = player->mo->scale));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P_SetMobjState(band, S_SIGNSPARK1 + (leveltime % 11));
|
||||||
|
P_SetScale(band, (band->destscale = (3*player->mo->scale)/2));
|
||||||
|
}
|
||||||
|
|
||||||
band->color = colors[c];
|
band->color = colors[c];
|
||||||
band->colorized = true;
|
band->colorized = true;
|
||||||
|
|
@ -1896,9 +1908,14 @@ static void K_UpdateDraft(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No one to draft off of? Then you can knock that off.
|
// No one to draft off of? Then you can knock that off.
|
||||||
if (player->draftleeway) // Prevent small disruptions from stopping your draft.
|
if (player->draftleeway > 0) // Prevent small disruptions from stopping your draft.
|
||||||
{
|
{
|
||||||
player->draftleeway--;
|
if (P_IsObjectOnGround(player->mo) == true)
|
||||||
|
{
|
||||||
|
// Allow maintaining tether in air setpieces.
|
||||||
|
player->draftleeway--;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->lastdraft >= 0
|
if (player->lastdraft >= 0
|
||||||
&& player->lastdraft < MAXPLAYERS
|
&& player->lastdraft < MAXPLAYERS
|
||||||
&& playeringame[player->lastdraft]
|
&& playeringame[player->lastdraft]
|
||||||
|
|
@ -2979,15 +2996,14 @@ INT16 K_GetSpindashChargeTime(player_t *player)
|
||||||
fixed_t K_GetSpindashChargeSpeed(player_t *player)
|
fixed_t K_GetSpindashChargeSpeed(player_t *player)
|
||||||
{
|
{
|
||||||
// more speed for higher weight & speed
|
// more speed for higher weight & speed
|
||||||
// Tails = +6.25%, Fang = +20.31%, Mighty = +20.31%, Metal = +25%
|
// Tails = +18.75%, Fang = +46.88%, Mighty = +46.88%, Metal = +56.25%
|
||||||
// (can be higher than this value when overcharged)
|
// (can be higher than this value when overcharged)
|
||||||
const fixed_t val = (player->kartspeed + player->kartweight) * (FRACUNIT/32);
|
const fixed_t val = ((player->kartspeed + player->kartweight) + 2) * (FRACUNIT/32);
|
||||||
|
|
||||||
// TODO: gametyperules
|
// TODO: gametyperules
|
||||||
return (gametype == GT_BATTLE) ? (4 * val) : val;
|
return (gametype == GT_BATTLE) ? (4 * val) : val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// sets boostpower, speedboost, accelboost, and handleboost to whatever we need it to be
|
// sets boostpower, speedboost, accelboost, and handleboost to whatever we need it to be
|
||||||
static void K_GetKartBoostPower(player_t *player)
|
static void K_GetKartBoostPower(player_t *player)
|
||||||
{
|
{
|
||||||
|
|
@ -3072,7 +3088,7 @@ static void K_GetKartBoostPower(player_t *player)
|
||||||
|
|
||||||
if (player->startboost) // Startup Boost
|
if (player->startboost) // Startup Boost
|
||||||
{
|
{
|
||||||
ADDBOOST(FRACUNIT/2, 4*FRACUNIT, 0); // + 50% top speed, + 400% acceleration, +0% handling
|
ADDBOOST(FRACUNIT, 4*FRACUNIT, sliptidehandling/2); // + 100% top speed, + 400% acceleration, +25% handling
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->driftboost) // Drift Boost
|
if (player->driftboost) // Drift Boost
|
||||||
|
|
@ -3113,6 +3129,12 @@ static void K_GetKartBoostPower(player_t *player)
|
||||||
draftspeed *= 2;
|
draftspeed *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->itemtype == KITEM_LIGHTNINGSHIELD)
|
||||||
|
{
|
||||||
|
// infinite tether
|
||||||
|
draftspeed *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
speedboost += FixedMul(draftspeed, player->draftpower); // (Drafting suffers no boost stack penalty.)
|
speedboost += FixedMul(draftspeed, player->draftpower); // (Drafting suffers no boost stack penalty.)
|
||||||
numboosts++;
|
numboosts++;
|
||||||
}
|
}
|
||||||
|
|
@ -3616,9 +3638,25 @@ static void K_RemoveGrowShrink(player_t *player)
|
||||||
P_RestoreMusic(player);
|
P_RestoreMusic(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fixed_t K_TumbleZ(mobj_t *mo, fixed_t input)
|
||||||
|
{
|
||||||
|
// Scales base tumble gravity to FRACUNIT
|
||||||
|
const fixed_t baseGravity = FixedMul(DEFAULT_GRAVITY, TUMBLEGRAVITY);
|
||||||
|
|
||||||
|
// Adapt momz w/ gravity
|
||||||
|
fixed_t gravityAdjust = FixedDiv(P_GetMobjGravity(mo), baseGravity);
|
||||||
|
|
||||||
|
if (mo->eflags & MFE_UNDERWATER)
|
||||||
|
{
|
||||||
|
// Reverse doubled falling speed.
|
||||||
|
gravityAdjust /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FixedMul(input, -gravityAdjust);
|
||||||
|
}
|
||||||
|
|
||||||
void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
|
void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
{
|
{
|
||||||
fixed_t gravityadjust;
|
|
||||||
(void)source;
|
(void)source;
|
||||||
|
|
||||||
K_DirectorFollowAttack(player, inflictor, source);
|
K_DirectorFollowAttack(player, inflictor, source);
|
||||||
|
|
@ -3647,16 +3685,7 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
|
|
||||||
S_StartSound(player->mo, sfx_s3k9b);
|
S_StartSound(player->mo, sfx_s3k9b);
|
||||||
|
|
||||||
// adapt momz w/ gravity?
|
player->mo->momz = K_TumbleZ(player->mo, player->tumbleHeight * FRACUNIT);
|
||||||
// as far as kart goes normal gravity is 2 (FRACUNIT*2)
|
|
||||||
|
|
||||||
gravityadjust = P_GetMobjGravity(player->mo)/2; // so we'll halve it for our calculations.
|
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_UNDERWATER)
|
|
||||||
gravityadjust /= 2; // halve "gravity" underwater
|
|
||||||
|
|
||||||
// and then modulate momz like that...
|
|
||||||
player->mo->momz = -gravityadjust * player->tumbleHeight;
|
|
||||||
|
|
||||||
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
P_SetPlayerMobjState(player->mo, S_KART_SPINOUT);
|
||||||
|
|
||||||
|
|
@ -3671,8 +3700,6 @@ static boolean K_LastTumbleBounceCondition(player_t *player)
|
||||||
|
|
||||||
static void K_HandleTumbleBounce(player_t *player)
|
static void K_HandleTumbleBounce(player_t *player)
|
||||||
{
|
{
|
||||||
fixed_t gravityadjust;
|
|
||||||
|
|
||||||
player->tumbleBounces++;
|
player->tumbleBounces++;
|
||||||
player->tumbleHeight = (player->tumbleHeight * ((player->tumbleHeight > 100) ? 3 : 4)) / 5;
|
player->tumbleHeight = (player->tumbleHeight * ((player->tumbleHeight > 100) ? 3 : 4)) / 5;
|
||||||
player->pflags &= ~PF_TUMBLESOUND;
|
player->pflags &= ~PF_TUMBLESOUND;
|
||||||
|
|
@ -3705,7 +3732,7 @@ static void K_HandleTumbleBounce(player_t *player)
|
||||||
|
|
||||||
// A bit of damage hitlag.
|
// A bit of damage hitlag.
|
||||||
// This gives a window for DI!!
|
// This gives a window for DI!!
|
||||||
K_AddHitLag(player->mo, 6, true);
|
K_AddHitLag(player->mo, 3, true);
|
||||||
|
|
||||||
if (P_IsDisplayPlayer(player) && player->tumbleHeight >= 40)
|
if (P_IsDisplayPlayer(player) && player->tumbleHeight >= 40)
|
||||||
P_StartQuake((player->tumbleHeight*3/2)<<FRACBITS, 6); // funny earthquakes for the FEEL
|
P_StartQuake((player->tumbleHeight*3/2)<<FRACBITS, 6); // funny earthquakes for the FEEL
|
||||||
|
|
@ -3715,16 +3742,8 @@ static void K_HandleTumbleBounce(player_t *player)
|
||||||
player->mo->momx = player->mo->momx / 2;
|
player->mo->momx = player->mo->momx / 2;
|
||||||
player->mo->momy = player->mo->momy / 2;
|
player->mo->momy = player->mo->momy / 2;
|
||||||
|
|
||||||
// adapt momz w/ gravity?
|
|
||||||
// as far as kart goes normal gravity is 2 (FRACUNIT*2)
|
|
||||||
|
|
||||||
gravityadjust = P_GetMobjGravity(player->mo)/2; // so we'll halve it for our calculations.
|
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_UNDERWATER)
|
|
||||||
gravityadjust /= 2; // halve "gravity" underwater
|
|
||||||
|
|
||||||
// and then modulate momz like that...
|
// and then modulate momz like that...
|
||||||
player->mo->momz = -gravityadjust * player->tumbleHeight;
|
player->mo->momz = K_TumbleZ(player->mo, player->tumbleHeight * FRACUNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Play a falling sound when you start falling while tumbling and you're nowhere near done bouncing
|
// Play a falling sound when you start falling while tumbling and you're nowhere near done bouncing
|
||||||
|
|
@ -3741,6 +3760,21 @@ static void K_HandleTumbleSound(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void K_TumbleInterrupt(player_t *player)
|
||||||
|
{
|
||||||
|
// If player was tumbling, set variables so that they don't tumble like crazy after they're done respawning
|
||||||
|
if (player->tumbleBounces > 0)
|
||||||
|
{
|
||||||
|
player->tumbleBounces = 0; // MAXBOUNCES-1;
|
||||||
|
player->pflags &= ~PF_TUMBLELASTBOUNCE;
|
||||||
|
//players->tumbleHeight = 20;
|
||||||
|
|
||||||
|
players->mo->rollangle = 0;
|
||||||
|
player->spinouttype = KSPIN_WIPEOUT;
|
||||||
|
player->spinouttimer = player->wipeoutslow = TICRATE+2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
|
void K_ApplyTripWire(player_t *player, tripwirestate_t state)
|
||||||
{
|
{
|
||||||
if (state == TRIP_PASSED)
|
if (state == TRIP_PASSED)
|
||||||
|
|
@ -7243,6 +7277,8 @@ static void K_LookForRings(mobj_t *pmo)
|
||||||
*/
|
*/
|
||||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
|
const boolean onground = P_IsObjectOnGround(player->mo);
|
||||||
|
|
||||||
K_UpdateOffroad(player);
|
K_UpdateOffroad(player);
|
||||||
K_UpdateDraft(player);
|
K_UpdateDraft(player);
|
||||||
K_UpdateEngineSounds(player); // Thanks, VAda!
|
K_UpdateEngineSounds(player); // Thanks, VAda!
|
||||||
|
|
@ -7514,8 +7550,10 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
||||||
if (player->strongdriftboost)
|
if (player->strongdriftboost)
|
||||||
player->strongdriftboost--;
|
player->strongdriftboost--;
|
||||||
|
|
||||||
if (player->startboost)
|
if (player->startboost > 0 && onground == true)
|
||||||
|
{
|
||||||
player->startboost--;
|
player->startboost--;
|
||||||
|
}
|
||||||
|
|
||||||
if (player->spindashboost)
|
if (player->spindashboost)
|
||||||
{
|
{
|
||||||
|
|
@ -8248,7 +8286,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
// distance calculation to work easily
|
// distance calculation to work easily
|
||||||
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
|
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
|
||||||
{
|
{
|
||||||
const UINT8 numfulllapsleft = ((UINT8)cv_numlaps.value - player->laps);
|
const UINT8 numfulllapsleft = ((UINT8)numlaps - player->laps);
|
||||||
|
|
||||||
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ void K_DoPowerClash(player_t *t1, player_t *t2);
|
||||||
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved);
|
void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved);
|
||||||
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type);
|
void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type);
|
||||||
void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||||
|
void K_TumbleInterrupt(player_t *player);
|
||||||
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||||
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
void K_DebtStingPlayer(player_t *player, mobj_t *source);
|
||||||
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
|
void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers);
|
||||||
|
|
|
||||||
426
src/k_pwrlv.c
426
src/k_pwrlv.c
|
|
@ -1,5 +1,12 @@
|
||||||
/// \file k_pwrlv.c
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
/// \brief SRB2Kart Power Levels
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018-2022 by Sally Cochenour
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// \brief Power Level system
|
||||||
|
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
#include "d_netcmd.h"
|
#include "d_netcmd.h"
|
||||||
|
|
@ -19,9 +26,12 @@ UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||||
// This is done so that clients will never be able to hack someone else's score over the server.
|
// This is done so that clients will never be able to hack someone else's score over the server.
|
||||||
UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||||
|
|
||||||
// Which players spec-scummed, and their power level before scumming.
|
// Total calculated power add during the match,
|
||||||
// On race finish, everyone is considered to have "won" against these people.
|
// totalled at the end of the round.
|
||||||
INT16 nospectategrief[MAXPLAYERS];
|
INT16 clientPowerAdd[MAXPLAYERS];
|
||||||
|
|
||||||
|
// Players who spectated mid-race
|
||||||
|
UINT8 spectateGriefed = 0;
|
||||||
|
|
||||||
// Game setting scrambles based on server Power Level
|
// Game setting scrambles based on server Power Level
|
||||||
SINT8 speedscramble = -1;
|
SINT8 speedscramble = -1;
|
||||||
|
|
@ -52,8 +62,14 @@ void K_ClearClientPowerLevels(void)
|
||||||
{
|
{
|
||||||
UINT8 i, j;
|
UINT8 i, j;
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
clientPowerAdd[i] = 0;
|
||||||
|
|
||||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||||
|
{
|
||||||
clientpowerlevels[i][j] = 0;
|
clientpowerlevels[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating
|
// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating
|
||||||
|
|
@ -71,7 +87,7 @@ INT16 K_CalculatePowerLevelInc(INT16 diff)
|
||||||
diff = -MAXDIFF;
|
diff = -MAXDIFF;
|
||||||
#undef MAXDIFF
|
#undef MAXDIFF
|
||||||
|
|
||||||
x = ((diff-2)<<FRACBITS) / PWRLVRECORD_START;
|
x = ((diff-2)<<FRACBITS) / PWRLVRECORD_MEDIAN;
|
||||||
|
|
||||||
for (j = 3; j < 10; j++) // Just skipping to 3 since 0 thru 2 will always just add 0...
|
for (j = 3; j < 10; j++) // Just skipping to 3 since 0 thru 2 will always just add 0...
|
||||||
{
|
{
|
||||||
|
|
@ -98,6 +114,23 @@ INT16 K_CalculatePowerLevelInc(INT16 diff)
|
||||||
return (INT16)(increment >> FRACBITS);
|
return (INT16)(increment >> FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT16 K_PowerLevelPlacementScore(player_t *player)
|
||||||
|
{
|
||||||
|
if ((player->pflags & PF_NOCONTEST) || (player->spectator))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
|
{
|
||||||
|
return MAXPLAYERS - player->position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return player->score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INT16 K_CalculatePowerLevelAvg(void)
|
INT16 K_CalculatePowerLevelAvg(void)
|
||||||
{
|
{
|
||||||
fixed_t avg = 0;
|
fixed_t avg = 0;
|
||||||
|
|
@ -143,7 +176,269 @@ INT16 K_CalculatePowerLevelAvg(void)
|
||||||
return (INT16)(avg >> FRACBITS);
|
return (INT16)(avg >> FRACBITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- K_UpdatePowerLevels could not be moved here due to usage of y_data, unfortunately. --
|
void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
|
||||||
|
{
|
||||||
|
const UINT8 playerNum = player - players;
|
||||||
|
const boolean exitBonus = ((lap > numlaps) || (player->pflags & PF_NOCONTEST));
|
||||||
|
|
||||||
|
SINT8 powerType = K_UsingPowerLevels();
|
||||||
|
|
||||||
|
INT16 yourScore = 0;
|
||||||
|
UINT16 yourPower = 0;
|
||||||
|
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
// Compare every single player against each other for power level increases.
|
||||||
|
// Every player you won against gives you more points, and vice versa.
|
||||||
|
// The amount of points won per match-up depends on the difference between the loser's power and the winner's power.
|
||||||
|
// See K_CalculatePowerLevelInc for more info.
|
||||||
|
|
||||||
|
if (powerType == PWRLV_DISABLED)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playeringame[playerNum] || player->spectator)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("\n========\n");
|
||||||
|
//CONS_Printf("* Power Level change for player %s (LAP %d) *\n", player_names[playerNum], lap);
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
|
||||||
|
yourPower = clientpowerlevels[playerNum][powerType];
|
||||||
|
if (yourPower == 0)
|
||||||
|
{
|
||||||
|
// Guests don't record power level changes.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("%s's PWR.LV: %d\n", player_names[playerNum], yourPower);
|
||||||
|
|
||||||
|
yourScore = K_PowerLevelPlacementScore(player);
|
||||||
|
//CONS_Printf("%s's gametype score: %d\n", player_names[playerNum], yourScore);
|
||||||
|
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
UINT16 theirScore = 0;
|
||||||
|
INT16 theirPower = 0;
|
||||||
|
|
||||||
|
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
||||||
|
INT16 inc = 0; // Total pt increment
|
||||||
|
|
||||||
|
boolean won = false;
|
||||||
|
|
||||||
|
if (i == playerNum) // Same person
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playeringame[i] || players[i].spectator)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("%s VS %s:\n", player_names[playerNum], player_names[i]);
|
||||||
|
|
||||||
|
theirPower = clientpowerlevels[i][powerType];
|
||||||
|
if (theirPower == 0)
|
||||||
|
{
|
||||||
|
// No power level (splitscreen guests, bots)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("%s's PWR.LV: %d\n", player_names[i], theirPower);
|
||||||
|
|
||||||
|
theirScore = K_PowerLevelPlacementScore(&players[i]);
|
||||||
|
//CONS_Printf("%s's gametype score: %d\n", player_names[i], theirScore);
|
||||||
|
|
||||||
|
if (yourScore == theirScore && forfeit == false) // Tie -- neither get any points for this match up.
|
||||||
|
{
|
||||||
|
//CONS_Printf("TIE, no change.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
won = (yourScore > theirScore);
|
||||||
|
|
||||||
|
if (won == true && forfeit == false) // This player won!
|
||||||
|
{
|
||||||
|
diff = theirPower - yourPower;
|
||||||
|
inc += K_CalculatePowerLevelInc(diff);
|
||||||
|
//CONS_Printf("WON! Diff is %d, increment is %d\n", diff, inc);
|
||||||
|
}
|
||||||
|
else // This player lost...
|
||||||
|
{
|
||||||
|
diff = yourPower - theirPower;
|
||||||
|
inc -= K_CalculatePowerLevelInc(diff);
|
||||||
|
//CONS_Printf("LOST... Diff is %d, increment is %d\n", diff, inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitBonus == false)
|
||||||
|
{
|
||||||
|
INT16 prevInc = inc;
|
||||||
|
|
||||||
|
inc /= max(numlaps-1, 1);
|
||||||
|
|
||||||
|
if (inc == 0)
|
||||||
|
{
|
||||||
|
if (prevInc > 0)
|
||||||
|
{
|
||||||
|
inc = 1;
|
||||||
|
}
|
||||||
|
else if (prevInc < 0)
|
||||||
|
{
|
||||||
|
inc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("Reduced (%d / %d = %d) because it's not the end of the race\n", prevInc, numlaps, inc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
|
||||||
|
if (inc == 0)
|
||||||
|
{
|
||||||
|
CONS_Printf("Total Result: No increment, no change.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("Total Result:\n");
|
||||||
|
//CONS_Printf("Increment: %d\n", inc);
|
||||||
|
|
||||||
|
//CONS_Printf("%s current: %d\n", player_names[playerNum], clientPowerAdd[playerNum]);
|
||||||
|
clientPowerAdd[playerNum] += inc;
|
||||||
|
//CONS_Printf("%s final: %d\n", player_names[playerNum], clientPowerAdd[playerNum]);
|
||||||
|
|
||||||
|
//CONS_Printf("%s current: %d\n", player_names[i], clientPowerAdd[i]);
|
||||||
|
clientPowerAdd[i] -= inc;
|
||||||
|
//CONS_Printf("%s final: %d\n", player_names[i], clientPowerAdd[i]);
|
||||||
|
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_UpdatePowerLevelsOnFailure(player_t *player)
|
||||||
|
{
|
||||||
|
// Update upon spectate / quit / NO CONTEST
|
||||||
|
INT16 lapsLeft = 0;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
lapsLeft = (numlaps - player->latestlap) + 1;
|
||||||
|
|
||||||
|
if (lapsLeft <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < lapsLeft; i++)
|
||||||
|
{
|
||||||
|
K_UpdatePowerLevels(player, player->latestlap + (i + 1), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
player->latestlap = numlaps+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc)
|
||||||
|
{
|
||||||
|
INT16 inc = baseInc;
|
||||||
|
UINT8 numPlayers = 0;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
if (yourPower == 0)
|
||||||
|
{
|
||||||
|
// Guests don't record power level changes.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i] || players[i].spectator)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
numPlayers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inc <= 0)
|
||||||
|
{
|
||||||
|
if (player->position == 1)
|
||||||
|
{
|
||||||
|
// Won the whole match?
|
||||||
|
// Get at least one point.
|
||||||
|
inc = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// You trade points in 1v1s,
|
||||||
|
// but is more lenient in bigger lobbies.
|
||||||
|
inc /= max(1, numPlayers-1);
|
||||||
|
|
||||||
|
if (inc == 0)
|
||||||
|
{
|
||||||
|
if (baseInc > 0)
|
||||||
|
{
|
||||||
|
inc = 1;
|
||||||
|
}
|
||||||
|
else if (baseInc < 0)
|
||||||
|
{
|
||||||
|
inc = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yourPower + inc > PWRLVRECORD_MAX)
|
||||||
|
{
|
||||||
|
inc -= ((yourPower + inc) - PWRLVRECORD_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yourPower + inc < PWRLVRECORD_MIN)
|
||||||
|
{
|
||||||
|
inc -= ((yourPower + inc) - PWRLVRECORD_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_CashInPowerLevels(void)
|
||||||
|
{
|
||||||
|
SINT8 powerType = K_UsingPowerLevels();
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
//CONS_Printf("\n========\n");
|
||||||
|
//CONS_Printf("Cashing in power level changes...\n");
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (playeringame[i] == true && powerType != PWRLV_DISABLED)
|
||||||
|
{
|
||||||
|
INT16 inc = K_FinalPowerIncrement(&players[i], clientpowerlevels[i][powerType], clientPowerAdd[i]);
|
||||||
|
clientpowerlevels[i][powerType] += inc;
|
||||||
|
|
||||||
|
//CONS_Printf("%s: %d -> %d (%d)\n", player_names[i], clientpowerlevels[i][powerType] - inc, clientpowerlevels[i][powerType], inc);
|
||||||
|
|
||||||
|
if (!demo.playback && i == consoleplayer && inc != 0)
|
||||||
|
{
|
||||||
|
vspowerlevel[powerType] = clientpowerlevels[i][powerType];
|
||||||
|
|
||||||
|
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_ncitem);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_SaveGameData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clientPowerAdd[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CONS_Printf("========\n");
|
||||||
|
}
|
||||||
|
|
||||||
void K_SetPowerLevelScrambles(SINT8 powertype)
|
void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||||
{
|
{
|
||||||
|
|
@ -227,7 +522,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||||
{
|
{
|
||||||
case 5:
|
case 5:
|
||||||
speed = KARTSPEED_HARD;
|
speed = KARTSPEED_HARD;
|
||||||
encore = true;
|
encore = P_RandomChance(FRACUNIT>>1);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
speed = P_RandomChance((7<<FRACBITS)/10) ? KARTSPEED_HARD : KARTSPEED_NORMAL;
|
speed = P_RandomChance((7<<FRACBITS)/10) ? KARTSPEED_HARD : KARTSPEED_NORMAL;
|
||||||
|
|
@ -238,7 +533,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||||
encore = P_RandomChance(FRACUNIT>>2);
|
encore = P_RandomChance(FRACUNIT>>2);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
speed = 1;
|
speed = KARTSPEED_NORMAL;
|
||||||
encore = P_RandomChance(FRACUNIT>>3);
|
encore = P_RandomChance(FRACUNIT>>3);
|
||||||
break;
|
break;
|
||||||
case 1: default:
|
case 1: default:
|
||||||
|
|
@ -254,7 +549,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Rolled speed: %d\n", speed);
|
CONS_Debug(DBG_GAMELOGIC, "Rolled speed: %d\n", speed);
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Rolled encore: %s\n", (encore ? "true" : "false"));
|
CONS_Debug(DBG_GAMELOGIC, "Rolled encore: %s\n", (encore ? "true" : "false"));
|
||||||
|
|
||||||
if (cv_kartspeed.value == -1)
|
if (cv_kartspeed.value == KARTSPEED_AUTO)
|
||||||
speedscramble = speed;
|
speedscramble = speed;
|
||||||
else
|
else
|
||||||
speedscramble = -1;
|
speedscramble = -1;
|
||||||
|
|
@ -270,88 +565,89 @@ void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
void K_PlayerForfeit(UINT8 playerNum, boolean pointLoss)
|
||||||
{
|
{
|
||||||
UINT8 p = 0;
|
UINT8 p = 0;
|
||||||
INT32 powertype = PWRLV_DISABLED;
|
|
||||||
UINT16 yourpower = PWRLVRECORD_DEF;
|
SINT8 powerType = PWRLV_DISABLED;
|
||||||
UINT16 theirpower = PWRLVRECORD_DEF;
|
UINT16 yourPower = 0;
|
||||||
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
|
||||||
INT16 inc = 0;
|
INT16 inc = 0;
|
||||||
|
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
// power level & spectating is netgames only
|
// power level & spectating is netgames only
|
||||||
if (!netgame)
|
if (!netgame)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// This server isn't using power levels anyway!
|
|
||||||
if (!cv_kartusepwrlv.value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Hey, I just got here!
|
// Hey, I just got here!
|
||||||
if (players[playernum].jointime <= 1)
|
if (players[playerNum].jointime <= 1)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match.
|
// 20 sec into a match counts as a forfeit -- automatic loss against every other player in the match.
|
||||||
if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE))
|
if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spectateGriefed++;
|
||||||
|
|
||||||
|
// This server isn't using power levels, so don't mess with them.
|
||||||
|
if (!cv_kartusepwrlv.value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (playeringame[i] && !players[i].spectator)
|
if ((playeringame[i] && !players[i].spectator)
|
||||||
|
|| (i == playerNum))
|
||||||
|
{
|
||||||
p++;
|
p++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < 2) // no players
|
if (p < 2) // no players
|
||||||
return;
|
|
||||||
|
|
||||||
if ((gametyperules & GTR_CIRCUIT))
|
|
||||||
powertype = PWRLV_RACE;
|
|
||||||
else if ((gametyperules & GTR_BUMPERS))
|
|
||||||
powertype = PWRLV_BATTLE;
|
|
||||||
|
|
||||||
if (powertype == PWRLV_DISABLED) // No power type?!
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes
|
|
||||||
return;
|
|
||||||
yourpower = clientpowerlevels[playernum][powertype];
|
|
||||||
|
|
||||||
// Set up the point compensation.
|
|
||||||
nospectategrief[playernum] = yourpower;
|
|
||||||
|
|
||||||
if (!pointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim!
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
{
|
||||||
if (i == playernum)
|
return;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (clientpowerlevels[i][powertype] == 0) // No power level (splitscreen guests, bots)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
theirpower = clientpowerlevels[i][powertype];
|
|
||||||
|
|
||||||
diff = yourpower - theirpower;
|
|
||||||
inc -= K_CalculatePowerLevelInc(diff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inc == 0) // No change.
|
powerType = K_UsingPowerLevels();
|
||||||
return;
|
|
||||||
|
|
||||||
if (yourpower + inc > PWRLVRECORD_MAX) // I mean... we're subtracting... but y'know how it is :V
|
if (powerType == PWRLV_DISABLED) // No power type?!
|
||||||
inc -= ((yourpower + inc) - PWRLVRECORD_MAX);
|
|
||||||
if (yourpower + inc < PWRLVRECORD_MIN)
|
|
||||||
inc -= ((yourpower + inc) - PWRLVRECORD_MIN);
|
|
||||||
|
|
||||||
clientpowerlevels[playernum][powertype] += inc;
|
|
||||||
|
|
||||||
if (!demo.playback && playernum == consoleplayer)
|
|
||||||
{
|
{
|
||||||
vspowerlevel[powertype] = clientpowerlevels[playernum][powertype];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yourPower = clientpowerlevels[playerNum][powerType];
|
||||||
|
if (yourPower == 0) // splitscreen guests don't record power level changes
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
K_UpdatePowerLevelsOnFailure(&players[playerNum]);
|
||||||
|
inc = K_FinalPowerIncrement(&players[playerNum], yourPower, clientPowerAdd[playerNum]);
|
||||||
|
|
||||||
|
if (inc >= 0)
|
||||||
|
{
|
||||||
|
// Don't record no change or increases.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pointLoss isn't set for stuff like sync-outs,
|
||||||
|
// which shouldn't be so harsh on the victim!
|
||||||
|
if (!demo.playback && pointLoss == true && playerNum == consoleplayer)
|
||||||
|
{
|
||||||
|
vspowerlevel[powerType] = yourPower + inc;
|
||||||
|
|
||||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
if (M_UpdateUnlockablesAndExtraEmblems())
|
||||||
|
{
|
||||||
S_StartSound(NULL, sfx_ncitem);
|
S_StartSound(NULL, sfx_ncitem);
|
||||||
G_SaveGameData(); // save your punishment!
|
}
|
||||||
|
|
||||||
|
G_SaveGameData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,30 @@
|
||||||
|
// DR. ROBOTNIK'S RING RACERS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 2018-2022 by Sally Cochenour
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// \brief Power Level system
|
||||||
|
|
||||||
#ifndef __K_PWRLV__
|
#ifndef __K_PWRLV__
|
||||||
#define __K_PWRLV__
|
#define __K_PWRLV__
|
||||||
|
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
#include "d_player.h"
|
||||||
|
|
||||||
#define PWRLV_DISABLED -1
|
typedef enum
|
||||||
#define PWRLV_RACE 0
|
{
|
||||||
#define PWRLV_BATTLE 1
|
PWRLV_DISABLED = -1,
|
||||||
#define PWRLV_NUMTYPES 2
|
PWRLV_RACE = 0,
|
||||||
|
PWRLV_BATTLE = 1,
|
||||||
|
PWRLV_NUMTYPES = 2,
|
||||||
|
} pwrlv_type_t;
|
||||||
|
|
||||||
#define PWRLVRECORD_START 1000
|
#define PWRLVRECORD_START 1000
|
||||||
#define PWRLVRECORD_DEF 5000
|
#define PWRLVRECORD_MEDIAN 5000
|
||||||
#define PWRLVRECORD_MIN 1
|
#define PWRLVRECORD_MIN 1
|
||||||
#define PWRLVRECORD_MAX 9999
|
#define PWRLVRECORD_MAX 9999
|
||||||
|
|
||||||
|
|
@ -19,13 +33,18 @@ extern SINT8 encorescramble;
|
||||||
|
|
||||||
extern UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
extern UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||||
extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||||
extern INT16 nospectategrief[MAXPLAYERS];
|
extern INT16 clientPowerAdd[MAXPLAYERS];
|
||||||
|
extern UINT8 spectateGriefed;
|
||||||
|
|
||||||
SINT8 K_UsingPowerLevels(void);
|
SINT8 K_UsingPowerLevels(void);
|
||||||
void K_ClearClientPowerLevels(void);
|
void K_ClearClientPowerLevels(void);
|
||||||
INT16 K_CalculatePowerLevelInc(INT16 diff);
|
INT16 K_CalculatePowerLevelInc(INT16 diff);
|
||||||
|
INT16 K_PowerLevelPlacementScore(player_t *player);
|
||||||
INT16 K_CalculatePowerLevelAvg(void);
|
INT16 K_CalculatePowerLevelAvg(void);
|
||||||
//void K_UpdatePowerLevels(void);
|
void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit);
|
||||||
|
void K_UpdatePowerLevelsOnFailure(player_t *player);
|
||||||
|
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 increment);
|
||||||
|
void K_CashInPowerLevels(void);
|
||||||
void K_SetPowerLevelScrambles(SINT8 powertype);
|
void K_SetPowerLevelScrambles(SINT8 powertype);
|
||||||
void K_PlayerForfeit(UINT8 playernum, boolean nopointloss);
|
void K_PlayerForfeit(UINT8 playernum, boolean nopointloss);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,18 +151,8 @@ void K_DoIngameRespawn(player_t *player)
|
||||||
|
|
||||||
player->ringboost = 0;
|
player->ringboost = 0;
|
||||||
player->driftboost = player->strongdriftboost = 0;
|
player->driftboost = player->strongdriftboost = 0;
|
||||||
|
|
||||||
// If player was tumbling, set variables so that they don't tumble like crazy after they're done respawning
|
|
||||||
if (player->tumbleBounces > 0)
|
|
||||||
{
|
|
||||||
player->tumbleBounces = 0; // MAXBOUNCES-1;
|
|
||||||
player->pflags &= ~PF_TUMBLELASTBOUNCE;
|
|
||||||
//players->tumbleHeight = 20;
|
|
||||||
players->mo->rollangle = 0;
|
|
||||||
player->spinouttype = KSPIN_WIPEOUT;
|
|
||||||
player->spinouttimer = player->wipeoutslow = (3*TICRATE/2)+2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
K_TumbleInterrupt(player);
|
||||||
P_ResetPlayer(player);
|
P_ResetPlayer(player);
|
||||||
|
|
||||||
// Set up respawn position if invalid
|
// Set up respawn position if invalid
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,8 @@ static int player_get(lua_State *L)
|
||||||
lua_pushinteger(L, plr->realtime);
|
lua_pushinteger(L, plr->realtime);
|
||||||
else if (fastcmp(field,"laps"))
|
else if (fastcmp(field,"laps"))
|
||||||
lua_pushinteger(L, plr->laps);
|
lua_pushinteger(L, plr->laps);
|
||||||
|
else if (fastcmp(field,"latestlap"))
|
||||||
|
lua_pushinteger(L, plr->latestlap);
|
||||||
else if (fastcmp(field,"ctfteam"))
|
else if (fastcmp(field,"ctfteam"))
|
||||||
lua_pushinteger(L, plr->ctfteam);
|
lua_pushinteger(L, plr->ctfteam);
|
||||||
else if (fastcmp(field,"checkskip"))
|
else if (fastcmp(field,"checkskip"))
|
||||||
|
|
@ -790,6 +792,8 @@ static int player_set(lua_State *L)
|
||||||
plr->realtime = (tic_t)luaL_checkinteger(L, 3);
|
plr->realtime = (tic_t)luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"laps"))
|
else if (fastcmp(field,"laps"))
|
||||||
plr->laps = (UINT8)luaL_checkinteger(L, 3);
|
plr->laps = (UINT8)luaL_checkinteger(L, 3);
|
||||||
|
else if (fastcmp(field,"latestlap"))
|
||||||
|
plr->latestlap = (UINT8)luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"ctfteam"))
|
else if (fastcmp(field,"ctfteam"))
|
||||||
plr->ctfteam = (INT32)luaL_checkinteger(L, 3);
|
plr->ctfteam = (INT32)luaL_checkinteger(L, 3);
|
||||||
else if (fastcmp(field,"checkskip"))
|
else if (fastcmp(field,"checkskip"))
|
||||||
|
|
|
||||||
|
|
@ -391,7 +391,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
||||||
lua_pushinteger(L, mapobjectscale);
|
lua_pushinteger(L, mapobjectscale);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (fastcmp(word,"numlaps")) {
|
} else if (fastcmp(word,"numlaps")) {
|
||||||
lua_pushinteger(L, cv_numlaps.value);
|
lua_pushinteger(L, numlaps);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (fastcmp(word,"racecountdown")) {
|
} else if (fastcmp(word,"racecountdown")) {
|
||||||
lua_pushinteger(L, racecountdown);
|
lua_pushinteger(L, racecountdown);
|
||||||
|
|
|
||||||
10
src/m_menu.c
10
src/m_menu.c
|
|
@ -1478,17 +1478,17 @@ static menuitem_t OP_GameOptionsMenu[] =
|
||||||
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", {.submenu = &OP_MonitorToggleDef}, 10},
|
{IT_STRING | IT_SUBMENU, NULL, "Random Item Toggles...", {.submenu = &OP_MonitorToggleDef}, 10},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Game Speed", {.cvar = &cv_kartspeed}, 30},
|
{IT_STRING | IT_CVAR, NULL, "Game Speed", {.cvar = &cv_kartspeed}, 30},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Frantic Items", {.cvar = &cv_kartfrantic}, 40},
|
{IT_STRING | IT_CVAR, NULL, "Frantic Items", {.cvar = &cv_kartfrantic}, 40},
|
||||||
{IT_SECRET, NULL, "Encore Mode", {.cvar = &cv_kartencore}, 50},
|
{IT_SECRET, NULL, "Encore Mode", {.cvar = &cv_kartencore}, 50},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Number of Laps", {.cvar = &cv_basenumlaps}, 70},
|
{IT_STRING | IT_CVAR, NULL, "Number of Laps", {.cvar = &cv_numlaps}, 70},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", {.cvar = &cv_countdowntime}, 80},
|
{IT_STRING | IT_CVAR, NULL, "Exit Countdown Timer", {.cvar = &cv_countdowntime}, 80},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Time Limit", {.cvar = &cv_timelimit}, 100},
|
{IT_STRING | IT_CVAR, NULL, "Time Limit", {.cvar = &cv_timelimit}, 100},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Starting Bumpers", {.cvar = &cv_kartbumpers}, 110},
|
{IT_STRING | IT_CVAR, NULL, "Starting Bumpers", {.cvar = &cv_kartbumpers}, 110},
|
||||||
{IT_STRING | IT_CVAR, NULL, "Karma Comeback", {.cvar = &cv_kartcomeback}, 120},
|
{IT_STRING | IT_CVAR, NULL, "Karma Comeback", {.cvar = &cv_kartcomeback}, 120},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, NULL, "Track Power Levels", {.cvar = &cv_kartusepwrlv}, 140},
|
{IT_STRING | IT_CVAR, NULL, "Track Power Levels", {.cvar = &cv_kartusepwrlv}, 140},
|
||||||
};
|
};
|
||||||
|
|
||||||
static menuitem_t OP_ServerOptionsMenu[] =
|
static menuitem_t OP_ServerOptionsMenu[] =
|
||||||
|
|
|
||||||
1
src/objects/CMakeLists.txt
Normal file
1
src/objects/CMakeLists.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
target_sourcefile(c)
|
||||||
|
|
@ -14032,21 +14032,21 @@ void A_LightningFollowPlayer(mobj_t *actor)
|
||||||
if (!actor->target)
|
if (!actor->target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (actor->extravalue1) // Make the radius also follow the player somewhat accuratly
|
||||||
{
|
{
|
||||||
if (actor->extravalue1) // Make the radius also follow the player somewhat accuratly
|
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||||
{
|
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
||||||
sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT));
|
P_MoveOrigin(actor, sx, sy, actor->target->z);
|
||||||
sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT));
|
|
||||||
P_MoveOrigin(actor, sx, sy, actor->target->z);
|
|
||||||
}
|
|
||||||
else // else just teleport to player directly
|
|
||||||
P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
|
||||||
|
|
||||||
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
|
|
||||||
actor->momx = actor->target->momx;
|
|
||||||
actor->momy = actor->target->momy;
|
|
||||||
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.
|
|
||||||
}
|
}
|
||||||
|
else // else just teleport to player directly
|
||||||
|
{
|
||||||
|
P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip
|
||||||
|
actor->momx = actor->target->momx;
|
||||||
|
actor->momy = actor->target->momy;
|
||||||
|
actor->momz = actor->target->momz; // Give momentum since we don't teleport to our player literally every frame.
|
||||||
}
|
}
|
||||||
|
|
||||||
// A_FZBoomFlash:
|
// A_FZBoomFlash:
|
||||||
|
|
|
||||||
|
|
@ -792,16 +792,11 @@ boolean P_CheckRacers(void)
|
||||||
boolean eliminatelast = cv_karteliminatelast.value;
|
boolean eliminatelast = cv_karteliminatelast.value;
|
||||||
boolean everyonedone = true;
|
boolean everyonedone = true;
|
||||||
boolean eliminatebots = false;
|
boolean eliminatebots = false;
|
||||||
boolean griefed = false;
|
const boolean griefed = (spectateGriefed > 0);
|
||||||
|
|
||||||
// Check if all the players in the race have finished. If so, end the level.
|
// Check if all the players in the race have finished. If so, end the level.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (nospectategrief[i] != -1) // prevent spectate griefing
|
|
||||||
{
|
|
||||||
griefed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!playeringame[i] || players[i].spectator || players[i].lives <= 0) // Not playing
|
if (!playeringame[i] || players[i].spectator || players[i].lives <= 0) // Not playing
|
||||||
{
|
{
|
||||||
// Y'all aren't even playing
|
// Y'all aren't even playing
|
||||||
|
|
@ -922,7 +917,7 @@ boolean P_CheckRacers(void)
|
||||||
// We're still playing, but no one else is, so we need to reset spectator griefing.
|
// We're still playing, but no one else is, so we need to reset spectator griefing.
|
||||||
if (numplayersingame <= 1)
|
if (numplayersingame <= 1)
|
||||||
{
|
{
|
||||||
memset(nospectategrief, -1, sizeof (nospectategrief));
|
spectateGriefed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turns out we're still having a good time & playing the game, we didn't have to do anything :)
|
// Turns out we're still having a good time & playing the game, we didn't have to do anything :)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@
|
||||||
|
|
||||||
//#define VIEWHEIGHTS "41"
|
//#define VIEWHEIGHTS "41"
|
||||||
|
|
||||||
|
// Maximum laps per map.
|
||||||
|
#define MAX_LAPS 99
|
||||||
|
|
||||||
// Maximum player score.
|
// Maximum player score.
|
||||||
#define MAXSCORE 99999990 // 999999990
|
#define MAXSCORE 99999990 // 999999990
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
||||||
P_SetTarget(&spring->target, object);
|
P_SetTarget(&spring->target, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
K_TumbleInterrupt(object->player);
|
||||||
P_ResetPlayer(object->player);
|
P_ResetPlayer(object->player);
|
||||||
|
|
||||||
object->player->springstars = max(vertispeed, horizspeed) / FRACUNIT / 2;
|
object->player->springstars = max(vertispeed, horizspeed) / FRACUNIT / 2;
|
||||||
|
|
|
||||||
10
src/p_mobj.c
10
src/p_mobj.c
|
|
@ -1130,7 +1130,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
||||||
|
|
||||||
if (mo->player->tumbleBounces > 0)
|
if (mo->player->tumbleBounces > 0)
|
||||||
{
|
{
|
||||||
gravityadd = (5*gravityadd)/2;
|
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -11011,16 +11011,20 @@ void P_RespawnSpecials(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pcount == 1) // No respawn when alone
|
if (pcount == 1) // No respawn when alone
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
else if (pcount > 1)
|
else if (pcount > 1)
|
||||||
{
|
{
|
||||||
time = (120 - ((pcount-2) * 10)) * TICRATE;
|
time = (120 - ((pcount-2) * 20)) * TICRATE;
|
||||||
|
|
||||||
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
|
// If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this.
|
||||||
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
|
// 5 lap courses would have more retreaded ground, while 2 lap courses would have less.
|
||||||
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
|
if ((mapheaderinfo[gamemap-1]->numlaps != 3)
|
||||||
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
|
&& !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE))
|
||||||
|
{
|
||||||
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
|
time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps);
|
||||||
|
}
|
||||||
|
|
||||||
if (time < 10*TICRATE)
|
if (time < 10*TICRATE)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ static void P_NetArchivePlayers(void)
|
||||||
{
|
{
|
||||||
WRITEINT16(save_p, clientpowerlevels[i][j]);
|
WRITEINT16(save_p, clientpowerlevels[i][j]);
|
||||||
}
|
}
|
||||||
|
WRITEINT16(save_p, clientPowerAdd[i]);
|
||||||
|
|
||||||
if (!playeringame[i])
|
if (!playeringame[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -167,6 +168,7 @@ static void P_NetArchivePlayers(void)
|
||||||
WRITEINT16(save_p, players[i].totalring);
|
WRITEINT16(save_p, players[i].totalring);
|
||||||
WRITEUINT32(save_p, players[i].realtime);
|
WRITEUINT32(save_p, players[i].realtime);
|
||||||
WRITEUINT8(save_p, players[i].laps);
|
WRITEUINT8(save_p, players[i].laps);
|
||||||
|
WRITEUINT8(save_p, players[i].latestlap);
|
||||||
WRITEINT32(save_p, players[i].starpostnum);
|
WRITEINT32(save_p, players[i].starpostnum);
|
||||||
|
|
||||||
WRITEUINT8(save_p, players[i].ctfteam);
|
WRITEUINT8(save_p, players[i].ctfteam);
|
||||||
|
|
@ -406,6 +408,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
{
|
{
|
||||||
clientpowerlevels[i][j] = READINT16(save_p);
|
clientpowerlevels[i][j] = READINT16(save_p);
|
||||||
}
|
}
|
||||||
|
clientPowerAdd[i] = READINT16(save_p);
|
||||||
|
|
||||||
// Do NOT memset player struct to 0
|
// Do NOT memset player struct to 0
|
||||||
// other areas may initialize data elsewhere
|
// other areas may initialize data elsewhere
|
||||||
|
|
@ -468,6 +471,7 @@ static void P_NetUnArchivePlayers(void)
|
||||||
players[i].totalring = READINT16(save_p); // Total number of rings obtained for GP
|
players[i].totalring = READINT16(save_p); // Total number of rings obtained for GP
|
||||||
players[i].realtime = READUINT32(save_p); // integer replacement for leveltime
|
players[i].realtime = READUINT32(save_p); // integer replacement for leveltime
|
||||||
players[i].laps = READUINT8(save_p); // Number of laps (optional)
|
players[i].laps = READUINT8(save_p); // Number of laps (optional)
|
||||||
|
players[i].latestlap = READUINT8(save_p);
|
||||||
players[i].starpostnum = READINT32(save_p);
|
players[i].starpostnum = READINT32(save_p);
|
||||||
|
|
||||||
players[i].ctfteam = READUINT8(save_p); // 1 == Red, 2 == Blue
|
players[i].ctfteam = READUINT8(save_p); // 1 == Red, 2 == Blue
|
||||||
|
|
@ -4499,6 +4503,7 @@ static void P_NetArchiveMisc(boolean resending)
|
||||||
WRITEUINT8(save_p, battlecapsules);
|
WRITEUINT8(save_p, battlecapsules);
|
||||||
|
|
||||||
WRITEUINT8(save_p, gamespeed);
|
WRITEUINT8(save_p, gamespeed);
|
||||||
|
WRITEUINT8(save_p, numlaps);
|
||||||
WRITEUINT8(save_p, franticitems);
|
WRITEUINT8(save_p, franticitems);
|
||||||
WRITEUINT8(save_p, comeback);
|
WRITEUINT8(save_p, comeback);
|
||||||
|
|
||||||
|
|
@ -4519,8 +4524,7 @@ static void P_NetArchiveMisc(boolean resending)
|
||||||
WRITEUINT32(save_p, indirectitemcooldown);
|
WRITEUINT32(save_p, indirectitemcooldown);
|
||||||
WRITEUINT32(save_p, mapreset);
|
WRITEUINT32(save_p, mapreset);
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
WRITEUINT8(save_p, spectateGriefed);
|
||||||
WRITEINT16(save_p, nospectategrief[i]);
|
|
||||||
|
|
||||||
WRITEUINT8(save_p, thwompsactive);
|
WRITEUINT8(save_p, thwompsactive);
|
||||||
WRITEUINT8(save_p, lastLowestLap);
|
WRITEUINT8(save_p, lastLowestLap);
|
||||||
|
|
@ -4648,6 +4652,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
||||||
battlecapsules = (boolean)READUINT8(save_p);
|
battlecapsules = (boolean)READUINT8(save_p);
|
||||||
|
|
||||||
gamespeed = READUINT8(save_p);
|
gamespeed = READUINT8(save_p);
|
||||||
|
numlaps = READUINT8(save_p);
|
||||||
franticitems = (boolean)READUINT8(save_p);
|
franticitems = (boolean)READUINT8(save_p);
|
||||||
comeback = (boolean)READUINT8(save_p);
|
comeback = (boolean)READUINT8(save_p);
|
||||||
|
|
||||||
|
|
@ -4668,8 +4673,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
|
||||||
indirectitemcooldown = READUINT32(save_p);
|
indirectitemcooldown = READUINT32(save_p);
|
||||||
mapreset = READUINT32(save_p);
|
mapreset = READUINT32(save_p);
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
spectateGriefed = READUINT8(save_p);
|
||||||
nospectategrief[i] = READINT16(save_p);
|
|
||||||
|
|
||||||
thwompsactive = (boolean)READUINT8(save_p);
|
thwompsactive = (boolean)READUINT8(save_p);
|
||||||
lastLowestLap = READUINT8(save_p);
|
lastLowestLap = READUINT8(save_p);
|
||||||
|
|
|
||||||
|
|
@ -4063,25 +4063,37 @@ static void P_InitPlayers(void)
|
||||||
|
|
||||||
static void P_InitGametype(void)
|
static void P_InitGametype(void)
|
||||||
{
|
{
|
||||||
|
spectateGriefed = 0;
|
||||||
|
K_CashInPowerLevels(); // Pushes power level changes even if intermission was skipped
|
||||||
|
|
||||||
P_InitPlayers();
|
P_InitPlayers();
|
||||||
|
|
||||||
if (modeattacking && !demo.playback)
|
if (modeattacking && !demo.playback)
|
||||||
P_LoadRecordGhosts();
|
P_LoadRecordGhosts();
|
||||||
|
|
||||||
if ((gametyperules & GTR_CIRCUIT) && server)
|
numlaps = 0;
|
||||||
|
if (gametyperules & GTR_CIRCUIT)
|
||||||
{
|
{
|
||||||
if ((netgame || multiplayer) && cv_basenumlaps.value
|
if ((netgame || multiplayer) && cv_numlaps.value
|
||||||
&& (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
&& (!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|
||||||
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value)))
|
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_numlaps.value)))
|
||||||
{
|
{
|
||||||
CV_StealthSetValue(&cv_numlaps, cv_basenumlaps.value);
|
numlaps = cv_numlaps.value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CV_StealthSetValue(&cv_numlaps, mapheaderinfo[gamemap - 1]->numlaps);
|
numlaps = mapheaderinfo[gamemap - 1]->numlaps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wantedcalcdelay = wantedfrequency*2;
|
||||||
|
indirectitemcooldown = 0;
|
||||||
|
mapreset = 0;
|
||||||
|
|
||||||
|
thwompsactive = false;
|
||||||
|
lastLowestLap = 0;
|
||||||
|
spbplace = -1;
|
||||||
|
|
||||||
// Start recording replay in multiplayer with a temp filename
|
// Start recording replay in multiplayer with a temp filename
|
||||||
//@TODO I'd like to fix dedis crashing when recording replays for the future too...
|
//@TODO I'd like to fix dedis crashing when recording replays for the future too...
|
||||||
if (!demo.playback && multiplayer && !dedicated)
|
if (!demo.playback && multiplayer && !dedicated)
|
||||||
|
|
@ -4117,6 +4129,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||||
// Map header should always be in place at this point
|
// Map header should always be in place at this point
|
||||||
INT32 i, ranspecialwipe = 0;
|
INT32 i, ranspecialwipe = 0;
|
||||||
sector_t *ss;
|
sector_t *ss;
|
||||||
|
|
||||||
levelloading = true;
|
levelloading = true;
|
||||||
|
|
||||||
// This is needed. Don't touch.
|
// This is needed. Don't touch.
|
||||||
|
|
@ -4430,17 +4443,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
||||||
K_InitDirector();
|
K_InitDirector();
|
||||||
}
|
}
|
||||||
|
|
||||||
wantedcalcdelay = wantedfrequency*2;
|
|
||||||
indirectitemcooldown = 0;
|
|
||||||
mapreset = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
nospectategrief[i] = -1;
|
|
||||||
|
|
||||||
thwompsactive = false;
|
|
||||||
lastLowestLap = 0;
|
|
||||||
spbplace = -1;
|
|
||||||
|
|
||||||
// clear special respawning que
|
// clear special respawning que
|
||||||
iquehead = iquetail = 0;
|
iquehead = iquetail = 0;
|
||||||
|
|
||||||
|
|
|
||||||
42
src/p_spec.c
42
src/p_spec.c
|
|
@ -1917,14 +1917,6 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
player->karthud[khud_laphand] = 0; // No hands in FREE PLAY
|
||||||
|
|
||||||
player->karthud[khud_lapanimation] = 80;
|
player->karthud[khud_lapanimation] = 80;
|
||||||
|
|
||||||
// save best lap for record attack
|
|
||||||
if (player == &players[consoleplayer])
|
|
||||||
{
|
|
||||||
if (curlap < bestlap || bestlap == 0)
|
|
||||||
bestlap = curlap;
|
|
||||||
curlap = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rainbowstartavailable == true)
|
if (rainbowstartavailable == true)
|
||||||
|
|
@ -1938,18 +1930,18 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
rainbowstartavailable = false;
|
rainbowstartavailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netgame && player->laps >= (UINT8)cv_numlaps.value)
|
if (netgame && player->laps >= numlaps)
|
||||||
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
|
||||||
|
|
||||||
player->starpostnum = 0;
|
player->starpostnum = 0;
|
||||||
|
|
||||||
if (P_IsDisplayPlayer(player))
|
if (P_IsDisplayPlayer(player))
|
||||||
{
|
{
|
||||||
if (player->laps == (UINT8)(cv_numlaps.value)) // final lap
|
if (player->laps == numlaps) // final lap
|
||||||
S_StartSound(NULL, sfx_s3k68);
|
S_StartSound(NULL, sfx_s3k68);
|
||||||
else if ((player->laps > 1) && (player->laps < (UINT8)(cv_numlaps.value))) // non-final lap
|
else if ((player->laps > 1) && (player->laps < numlaps)) // non-final lap
|
||||||
S_StartSound(NULL, sfx_s221);
|
S_StartSound(NULL, sfx_s221);
|
||||||
else if (player->laps > (UINT8)(cv_numlaps.value))
|
else if (player->laps > numlaps)
|
||||||
{
|
{
|
||||||
// finished
|
// finished
|
||||||
S_StartSound(NULL, sfx_s3k6a);
|
S_StartSound(NULL, sfx_s3k6a);
|
||||||
|
|
@ -1958,7 +1950,7 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((player->laps > (UINT8)(cv_numlaps.value)) && (player->position == 1))
|
if ((player->laps > numlaps) && (player->position == 1))
|
||||||
{
|
{
|
||||||
// opponent finished
|
// opponent finished
|
||||||
S_StartSound(NULL, sfx_s253);
|
S_StartSound(NULL, sfx_s253);
|
||||||
|
|
@ -1966,12 +1958,34 @@ static void K_HandleLapIncrement(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// finished race exit setup
|
// finished race exit setup
|
||||||
if (player->laps > (unsigned)cv_numlaps.value)
|
if (player->laps > numlaps)
|
||||||
{
|
{
|
||||||
P_DoPlayerExit(player);
|
P_DoPlayerExit(player);
|
||||||
P_SetupSignExit(player);
|
P_SetupSignExit(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player->laps > player->latestlap)
|
||||||
|
{
|
||||||
|
if (player->laps > 1)
|
||||||
|
{
|
||||||
|
// save best lap for record attack
|
||||||
|
if (modeattacking && player == &players[consoleplayer])
|
||||||
|
{
|
||||||
|
if (curlap < bestlap || bestlap == 0)
|
||||||
|
{
|
||||||
|
bestlap = curlap;
|
||||||
|
}
|
||||||
|
|
||||||
|
curlap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update power levels for this lap.
|
||||||
|
K_UpdatePowerLevels(player, player->laps, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
player->latestlap = player->laps;
|
||||||
|
}
|
||||||
|
|
||||||
thwompsactive = true; // Lap 2 effects
|
thwompsactive = true; // Lap 2 effects
|
||||||
|
|
||||||
lowestLap = P_FindLowestLap();
|
lowestLap = P_FindLowestLap();
|
||||||
|
|
|
||||||
|
|
@ -873,7 +873,7 @@ void P_RestoreMusic(player_t *player)
|
||||||
#if 0
|
#if 0
|
||||||
// Event - Final Lap
|
// Event - Final Lap
|
||||||
// Still works for GME, but disabled for consistency
|
// Still works for GME, but disabled for consistency
|
||||||
if ((gametyperules & GTR_CIRCUIT) && player->laps >= (UINT8)(cv_numlaps.value))
|
if ((gametyperules & GTR_CIRCUIT) && player->laps >= numlaps)
|
||||||
S_SpeedMusic(1.2f);
|
S_SpeedMusic(1.2f);
|
||||||
#endif
|
#endif
|
||||||
if (mapmusresume && cv_resume.value)
|
if (mapmusresume && cv_resume.value)
|
||||||
|
|
@ -3851,6 +3851,7 @@ void P_DoTimeOver(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
player->pflags |= PF_NOCONTEST;
|
player->pflags |= PF_NOCONTEST;
|
||||||
|
K_UpdatePowerLevelsOnFailure(player);
|
||||||
|
|
||||||
if (G_GametypeUsesLives())
|
if (G_GametypeUsesLives())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -79,11 +79,11 @@ if(${SDL2_FOUND})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM} MATCHES Windows)
|
if(${CMAKE_SYSTEM} MATCHES Windows)
|
||||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2win)
|
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2kart)
|
||||||
elseif(${CMAKE_SYSTEM} MATCHES Linux)
|
elseif(${CMAKE_SYSTEM} MATCHES Linux)
|
||||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME lsdlsrb2)
|
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME lsdlsrb2kart)
|
||||||
else()
|
else()
|
||||||
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2)
|
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2kart)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM} MATCHES Darwin)
|
if(${CMAKE_SYSTEM} MATCHES Darwin)
|
||||||
|
|
@ -124,6 +124,14 @@ if(${SDL2_FOUND})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM} MATCHES Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "GNU" AND ${SRB2_SYSTEM_BITS} EQUAL 32)
|
||||||
|
target_link_libraries(SRB2SDL2 PRIVATE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../libs/drmingw/lib/win32/libexchndl.a"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../../libs/drmingw/lib/win32/libmgwhelp.a"
|
||||||
|
)
|
||||||
|
target_include_directories(SRB2SDL2 PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../libs/drmingw/include")
|
||||||
|
endif()
|
||||||
|
|
||||||
#target_link_libraries(SRB2SDL2 PRIVATE SRB2Core)
|
#target_link_libraries(SRB2SDL2 PRIVATE SRB2Core)
|
||||||
|
|
||||||
if(${SRB2_USEASM})
|
if(${SRB2_USEASM})
|
||||||
|
|
@ -168,24 +176,9 @@ if(${SDL2_FOUND})
|
||||||
|
|
||||||
target_compile_definitions(SRB2SDL2 PRIVATE
|
target_compile_definitions(SRB2SDL2 PRIVATE
|
||||||
-DDIRECTFULLSCREEN -DHAVE_SDL
|
-DDIRECTFULLSCREEN -DHAVE_SDL
|
||||||
|
-DHAVE_THREADS
|
||||||
)
|
)
|
||||||
|
|
||||||
## strip debug symbols into separate file when using gcc.
|
|
||||||
## to be consistent with Makefile, don't generate for OS X.
|
|
||||||
if((CMAKE_COMPILER_IS_GNUCC) AND NOT (${CMAKE_SYSTEM} MATCHES Darwin))
|
|
||||||
if((${CMAKE_BUILD_TYPE} MATCHES Debug) OR (${CMAKE_BUILD_TYPE} MATCHES RelWithDebInfo))
|
|
||||||
if(${CMAKE_BUILD_TYPE} MATCHES Debug)
|
|
||||||
set(OBJCOPY_ONLY_KEEP_DEBUG "--only-keep-debug")
|
|
||||||
endif()
|
|
||||||
message(STATUS "Will make separate debug symbols in *.debug")
|
|
||||||
add_custom_command(TARGET SRB2SDL2 POST_BUILD
|
|
||||||
COMMAND ${OBJCOPY} ${OBJCOPY_ONLY_KEEP_DEBUG} $<TARGET_FILE:SRB2SDL2> $<TARGET_FILE:SRB2SDL2>.debug
|
|
||||||
COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:SRB2SDL2>
|
|
||||||
COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE:SRB2SDL2>.debug $<TARGET_FILE:SRB2SDL2>
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#### Installation ####
|
#### Installation ####
|
||||||
if(${CMAKE_SYSTEM} MATCHES Darwin)
|
if(${CMAKE_SYSTEM} MATCHES Darwin)
|
||||||
install(TARGETS SRB2SDL2
|
install(TARGETS SRB2SDL2
|
||||||
|
|
|
||||||
175
src/y_inter.c
175
src/y_inter.c
|
|
@ -214,7 +214,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
{
|
{
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
boolean completed[MAXPLAYERS];
|
boolean completed[MAXPLAYERS];
|
||||||
INT32 numplayersingame = 0, numgriefers = 0;
|
INT32 numplayersingame = 0;
|
||||||
|
|
||||||
// Initialize variables
|
// Initialize variables
|
||||||
if (rankingsmode > 1)
|
if (rankingsmode > 1)
|
||||||
|
|
@ -273,9 +273,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
{
|
{
|
||||||
data.val[i] = UINT32_MAX;
|
data.val[i] = UINT32_MAX;
|
||||||
|
|
||||||
if (nospectategrief[i] != -1)
|
|
||||||
numgriefers++;
|
|
||||||
|
|
||||||
if (!playeringame[i] || players[i].spectator)
|
if (!playeringame[i] || players[i].spectator)
|
||||||
{
|
{
|
||||||
data.increase[i] = INT16_MIN;
|
data.increase[i] = INT16_MIN;
|
||||||
|
|
@ -324,10 +321,10 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
{
|
{
|
||||||
if ((powertype == PWRLV_DISABLED)
|
if ((powertype == PWRLV_DISABLED)
|
||||||
&& !(players[i].pflags & PF_NOCONTEST)
|
&& !(players[i].pflags & PF_NOCONTEST)
|
||||||
&& (data.pos[data.numplayers] < (numplayersingame + numgriefers)))
|
&& (data.pos[data.numplayers] < (numplayersingame + spectateGriefed)))
|
||||||
{
|
{
|
||||||
// Online rank is handled further below in this file.
|
// Online rank is handled further below in this file.
|
||||||
data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + numgriefers);
|
data.increase[i] = K_CalculateGPRankPoints(data.pos[data.numplayers], numplayersingame + spectateGriefed);
|
||||||
players[i].score += data.increase[i];
|
players[i].score += data.increase[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -890,157 +887,6 @@ void Y_Ticker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void K_UpdatePowerLevels(void)
|
|
||||||
{
|
|
||||||
INT32 i, j;
|
|
||||||
INT32 numplayersingame = 0, numgriefers = 0;
|
|
||||||
INT16 increment[MAXPLAYERS];
|
|
||||||
|
|
||||||
// Compare every single player against each other for power level increases.
|
|
||||||
// Every player you won against gives you more points, and vice versa.
|
|
||||||
// The amount of points won per match-up depends on the difference between the loser's power and the winner's power.
|
|
||||||
// See K_CalculatePowerLevelInc for more info.
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
increment[i] = 0;
|
|
||||||
|
|
||||||
if (nospectategrief[i] != -1)
|
|
||||||
numgriefers++;
|
|
||||||
|
|
||||||
if (!playeringame[i] || players[i].spectator)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
numplayersingame++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < numplayersingame; i++)
|
|
||||||
{
|
|
||||||
UINT16 yourpower = PWRLVRECORD_DEF;
|
|
||||||
UINT16 theirpower = PWRLVRECORD_DEF;
|
|
||||||
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
|
||||||
INT16 inc = 0; // Total pt increment
|
|
||||||
UINT8 ipnum = data.num[i];
|
|
||||||
UINT8 jpnum;
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum);
|
|
||||||
|
|
||||||
if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes
|
|
||||||
continue;
|
|
||||||
yourpower = clientpowerlevels[ipnum][powertype];
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower);
|
|
||||||
|
|
||||||
for (j = 0; j < numplayersingame; j++)
|
|
||||||
{
|
|
||||||
boolean won = false;
|
|
||||||
|
|
||||||
jpnum = data.num[j];
|
|
||||||
|
|
||||||
if (i == j || ipnum == jpnum) // Same person
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum);
|
|
||||||
|
|
||||||
if (data.val[i] == data.val[j]) // Tie -- neither get any points for this match up.
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientpowerlevels[jpnum][powertype] == 0) // No power level (splitscreen guests, bots)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
theirpower = clientpowerlevels[jpnum][powertype];
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
|
|
||||||
|
|
||||||
if ((gametyperules & GTR_CIRCUIT))
|
|
||||||
{
|
|
||||||
if (data.val[i] < data.val[j])
|
|
||||||
won = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (data.val[i] > data.val[j])
|
|
||||||
won = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (won) // This player won!
|
|
||||||
{
|
|
||||||
diff = theirpower - yourpower;
|
|
||||||
inc += K_CalculatePowerLevelInc(diff);
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc);
|
|
||||||
}
|
|
||||||
else // This player lost...
|
|
||||||
{
|
|
||||||
diff = yourpower - theirpower;
|
|
||||||
inc -= K_CalculatePowerLevelInc(diff);
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numgriefers != 0) // Automatic win against quitters.
|
|
||||||
{
|
|
||||||
for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++)
|
|
||||||
{
|
|
||||||
if (nospectategrief[jpnum] == -1) // Empty slot
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ipnum == jpnum) // Same person
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum);
|
|
||||||
|
|
||||||
if (nospectategrief[jpnum] == 0) // No power level (splitscreen guests, bots)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
theirpower = nospectategrief[jpnum];
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
|
|
||||||
|
|
||||||
diff = theirpower - yourpower;
|
|
||||||
inc += K_CalculatePowerLevelInc(diff);
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inc == 0)
|
|
||||||
{
|
|
||||||
data.increase[ipnum] = INT16_MIN;
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yourpower + inc > PWRLVRECORD_MAX)
|
|
||||||
inc -= ((yourpower + inc) - PWRLVRECORD_MAX);
|
|
||||||
if (yourpower + inc < PWRLVRECORD_MIN)
|
|
||||||
inc -= ((yourpower + inc) - PWRLVRECORD_MIN);
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc);
|
|
||||||
increment[ipnum] = inc;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n");
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (increment[i] == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
data.increase[i] = increment[i];
|
|
||||||
clientpowerlevels[i][powertype] += data.increase[i];
|
|
||||||
|
|
||||||
if (!demo.playback && i == consoleplayer)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i);
|
|
||||||
vspowerlevel[powertype] = clientpowerlevels[i][powertype];
|
|
||||||
if (M_UpdateUnlockablesAndExtraEmblems())
|
|
||||||
S_StartSound(NULL, sfx_ncitem);
|
|
||||||
G_SaveGameData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Y_DetermineIntermissionType
|
// Y_DetermineIntermissionType
|
||||||
//
|
//
|
||||||
|
|
@ -1121,7 +967,7 @@ void Y_StartIntermission(void)
|
||||||
//if (dedicated) return;
|
//if (dedicated) return;
|
||||||
|
|
||||||
// This should always exist, but just in case...
|
// This should always exist, but just in case...
|
||||||
if(!mapheaderinfo[prevmap])
|
if (!mapheaderinfo[prevmap])
|
||||||
P_AllocMapHeader(prevmap);
|
P_AllocMapHeader(prevmap);
|
||||||
|
|
||||||
switch (intertype)
|
switch (intertype)
|
||||||
|
|
@ -1157,7 +1003,18 @@ void Y_StartIntermission(void)
|
||||||
|
|
||||||
if (powertype != PWRLV_DISABLED)
|
if (powertype != PWRLV_DISABLED)
|
||||||
{
|
{
|
||||||
K_UpdatePowerLevels();
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
// Kind of a hack to do this here,
|
||||||
|
// but couldn't think of a better way.
|
||||||
|
data.increase[i] = K_FinalPowerIncrement(
|
||||||
|
&players[i],
|
||||||
|
clientpowerlevels[i][powertype],
|
||||||
|
clientPowerAdd[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
K_CashInPowerLevels();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (intertype == int_race || intertype == int_battle)
|
//if (intertype == int_race || intertype == int_battle)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue