mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'master' into new-menus
This commit is contained in:
commit
d306df81c8
29 changed files with 943 additions and 544 deletions
|
|
@ -493,6 +493,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/y_inter.o \
|
||||
$(OBJDIR)/st_stuff.o \
|
||||
$(OBJDIR)/k_kart.o \
|
||||
$(OBJDIR)/k_pwrlv.o \
|
||||
$(OBJDIR)/m_aatree.o \
|
||||
$(OBJDIR)/m_anigif.o \
|
||||
$(OBJDIR)/m_argv.o \
|
||||
|
|
|
|||
|
|
@ -70,8 +70,12 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
|||
|
||||
//SRB2kart
|
||||
CV_PossibleValue_t kartspeed_cons_t[] = {
|
||||
{0, "Easy"}, {1, "Normal"}, {2, "Hard"},
|
||||
{0, NULL}};
|
||||
{-1, "Auto"},
|
||||
{0, "Easy"},
|
||||
{1, "Normal"},
|
||||
{2, "Hard"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
// Filter consvars by EXECVERSION
|
||||
// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
|
||||
|
|
@ -1734,7 +1738,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
{
|
||||
newvalue = var->value + 1;
|
||||
if (newvalue > maxspeed)
|
||||
newvalue = 0;
|
||||
newvalue = -1;
|
||||
var->value = newvalue;
|
||||
var->string = var->PossibleValue[var->value].strvalue;
|
||||
var->func();
|
||||
|
|
@ -1743,7 +1747,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
|||
else if (increment < 0) // Going down!
|
||||
{
|
||||
newvalue = var->value - 1;
|
||||
if (newvalue < 0)
|
||||
if (newvalue < -1)
|
||||
newvalue = maxspeed;
|
||||
var->value = newvalue;
|
||||
var->string = var->PossibleValue[var->value].strvalue;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "lua_script.h"
|
||||
#include "lua_hook.h"
|
||||
#include "k_kart.h"
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
#ifdef CLIENT_LOADINGSCREEN
|
||||
// cl loading screen
|
||||
|
|
@ -1350,7 +1351,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
|
||||
netbuffer->u.serverinfo.kartvars = (UINT8) (
|
||||
(cv_kartspeed.value & SV_SPEEDMASK) |
|
||||
(gamespeed & SV_SPEEDMASK) |
|
||||
(dedicated ? SV_DEDICATED : 0) |
|
||||
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
|
||||
);
|
||||
|
|
@ -1420,6 +1421,11 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
|
||||
p = PutFileNeeded(0);
|
||||
|
||||
if (cv_kartusepwrlv.value)
|
||||
netbuffer->u.serverinfo.avgpwrlv = K_CalculatePowerLevelAvg();
|
||||
else
|
||||
netbuffer->u.serverinfo.avgpwrlv = -1;
|
||||
|
||||
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||
}
|
||||
|
||||
|
|
@ -1494,7 +1500,7 @@ static void SV_SendPlayerInfo(INT32 node)
|
|||
*/
|
||||
static boolean SV_SendServerConfig(INT32 node)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 i, j;
|
||||
UINT8 *p, *op;
|
||||
boolean waspacketsent;
|
||||
|
||||
|
|
@ -1517,10 +1523,13 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
|
||||
|
||||
memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers));
|
||||
memset(netbuffer->u.servercfg.powerlevels, 0, sizeof(netbuffer->u.servercfg.powerlevels));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i];
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j];
|
||||
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
|
@ -2306,6 +2315,7 @@ static void CL_ConnectToServer(boolean viams)
|
|||
wipegamestate = GS_WAITINGPLAYERS;
|
||||
|
||||
ClearAdminPlayers();
|
||||
K_ClearClientPowerLevels();
|
||||
pnumnodes = 1;
|
||||
oldtic = I_GetTime() - 1;
|
||||
#ifndef NONET
|
||||
|
|
@ -3156,6 +3166,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
break;
|
||||
}
|
||||
|
||||
// SRB2Kart: kicks count as forfeit
|
||||
switch (kickreason)
|
||||
{
|
||||
case KR_KICK:
|
||||
case KR_BAN:
|
||||
case KR_LEAVE:
|
||||
// Intentional removals should be hit with a true forfeit.
|
||||
K_PlayerForfeit(pnum, true);
|
||||
break;
|
||||
default:
|
||||
// Otherwise, give remaining players the point compensation, but doesn't penalize who left.
|
||||
K_PlayerForfeit(pnum, false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (playernode[pnum] == playernode[consoleplayer])
|
||||
{
|
||||
#ifdef DUMPCONSISTENCY
|
||||
|
|
@ -3324,6 +3349,7 @@ void SV_ResetServer(void)
|
|||
playernode[i] = UINT8_MAX;
|
||||
sprintf(player_names[i], "Player %d", i + 1);
|
||||
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||
K_ClearClientPowerLevels();
|
||||
}
|
||||
|
||||
mynode = 0;
|
||||
|
|
@ -3399,6 +3425,7 @@ void D_QuitNetGame(void)
|
|||
|
||||
D_CloseConnection();
|
||||
ClearAdminPlayers();
|
||||
K_ClearClientPowerLevels();
|
||||
|
||||
DEBFILE("===========================================================================\n"
|
||||
" Log finish\n"
|
||||
|
|
@ -3445,11 +3472,12 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
return;
|
||||
}
|
||||
|
||||
node = READUINT8(*p);
|
||||
newplayernum = READUINT8(*p);
|
||||
splitscreenplayer = newplayernum/MAXPLAYERS;
|
||||
newplayernum %= MAXPLAYERS;
|
||||
node = (UINT8)READUINT8(*p);
|
||||
newplayernum = (UINT8)READUINT8(*p);
|
||||
splitscreenplayer = (UINT8)READUINT8(*p);
|
||||
|
||||
CONS_Debug(DBG_NETPLAY, "addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer);
|
||||
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
CL_ClearPlayer(newplayernum);
|
||||
|
||||
|
|
@ -3466,7 +3494,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
if (splitscreenplayer)
|
||||
{
|
||||
displayplayers[splitscreenplayer] = newplayernum;
|
||||
DEBFILE(va("spawning one of my sister number %d\n", splitscreenplayer));
|
||||
DEBFILE(va("spawning sister # %d\n", splitscreenplayer));
|
||||
if (splitscreenplayer == 1 && botingame)
|
||||
players[newplayernum].bot = 1;
|
||||
}
|
||||
|
|
@ -3477,6 +3505,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
|||
displayplayers[i] = newplayernum;
|
||||
DEBFILE("spawning me\n");
|
||||
}
|
||||
|
||||
D_SendPlayerConfig();
|
||||
addedtogame = true;
|
||||
}
|
||||
|
|
@ -3532,7 +3561,6 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
|
|||
static boolean SV_AddWaitingPlayers(void)
|
||||
{
|
||||
INT32 node, n, newplayer = false;
|
||||
XBOXSTATIC UINT8 buf[2];
|
||||
UINT8 newplayernum = 0;
|
||||
|
||||
// What is the reason for this? Why can't newplayernum always be 0?
|
||||
|
|
@ -3545,6 +3573,9 @@ static boolean SV_AddWaitingPlayers(void)
|
|||
// splitscreen can allow 2+ players in one node
|
||||
for (; nodewaiting[node] > 0; nodewaiting[node]--)
|
||||
{
|
||||
UINT8 buf[3];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
newplayer = true;
|
||||
|
||||
// search for a free playernum
|
||||
|
|
@ -3552,8 +3583,10 @@ static boolean SV_AddWaitingPlayers(void)
|
|||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum
|
||||
|| nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum)
|
||||
if (nodetoplayer[n] == newplayernum
|
||||
|| nodetoplayer2[n] == newplayernum
|
||||
|| nodetoplayer3[n] == newplayernum
|
||||
|| nodetoplayer4[n] == newplayernum)
|
||||
break;
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
|
|
@ -3565,28 +3598,23 @@ static boolean SV_AddWaitingPlayers(void)
|
|||
|
||||
playernode[newplayernum] = (UINT8)node;
|
||||
|
||||
buf[0] = (UINT8)node;
|
||||
buf[1] = newplayernum;
|
||||
WRITEUINT8(buf_p, (UINT8)node);
|
||||
WRITEUINT8(buf_p, newplayernum);
|
||||
|
||||
if (playerpernode[node] < 1)
|
||||
nodetoplayer[node] = newplayernum;
|
||||
else if (playerpernode[node] < 2)
|
||||
{
|
||||
nodetoplayer2[node] = newplayernum;
|
||||
buf[1] += MAXPLAYERS;
|
||||
}
|
||||
else if (playerpernode[node] < 3)
|
||||
{
|
||||
nodetoplayer3[node] = newplayernum;
|
||||
buf[1] += MAXPLAYERS*2;
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (playerpernode[node] < 4)
|
||||
nodetoplayer4[node] = newplayernum;
|
||||
buf[1] += MAXPLAYERS*3;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num
|
||||
|
||||
playerpernode[node]++;
|
||||
|
||||
SendNetXCmd(XD_ADDPLAYER, &buf, 2);
|
||||
SendNetXCmd(XD_ADDPLAYER, buf, buf_p - buf);
|
||||
|
||||
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
|
|
@ -4081,7 +4109,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
|
||||
case PT_SERVERCFG: // Positive response of client join request
|
||||
{
|
||||
INT32 j;
|
||||
INT32 j, k;
|
||||
UINT8 *scp;
|
||||
|
||||
if (server && serverrunning && node != servernode)
|
||||
|
|
@ -4104,7 +4132,11 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
I_Error("Bad gametype in cliserv!");
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
adminplayers[j] = netbuffer->u.servercfg.adminplayers[j];
|
||||
for (k = 0; k < PWRLV_NUMTYPES; k++)
|
||||
clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k];
|
||||
}
|
||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "d_netcmd.h"
|
||||
#include "tables.h"
|
||||
#include "d_player.h"
|
||||
#include "k_pwrlv.h" // PWRLV_NUMTYPES
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
|
|
@ -325,6 +326,7 @@ typedef struct
|
|||
UINT8 gametype;
|
||||
UINT8 modifiedgame;
|
||||
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
|
||||
UINT16 powerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; // SRB2kart: player power levels
|
||||
|
||||
char server_context[8]; // Unique context id, generated at server startup.
|
||||
|
||||
|
|
@ -387,6 +389,10 @@ typedef struct
|
|||
UINT8 actnum;
|
||||
UINT8 iszone;
|
||||
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||
// Anything beyond this point won't be read by the normal SRB2 Master Server display.
|
||||
// The MS uses a simple unpack, so the size of the packet above shouldn't be changed, either.
|
||||
// As long as those two conditions are met, we can add as much information as we want to the end.
|
||||
INT16 avgpwrlv; // Kart avg power level
|
||||
} ATTRPACK serverinfo_pak;
|
||||
|
||||
typedef struct
|
||||
|
|
|
|||
|
|
@ -1558,7 +1558,7 @@ void D_SRB2Main(void)
|
|||
else if (!dedicated && M_MapLocked(pstartmap))
|
||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
||||
else
|
||||
D_MapChange(pstartmap, gametype, (boolean)cv_kartencore.value, true, 0, false, false);
|
||||
D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false);
|
||||
}
|
||||
}
|
||||
else if (M_CheckParm("-skipintro"))
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "m_cond.h"
|
||||
#include "m_anigif.h"
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_pwrlv.h"
|
||||
#include "y_inter.h"
|
||||
|
||||
#ifdef NETGAME_DEVMODE
|
||||
|
|
@ -61,6 +62,7 @@
|
|||
|
||||
static void Got_NameAndColor(UINT8 **cp, INT32 playernum);
|
||||
static void Got_WeaponPref(UINT8 **cp, INT32 playernum);
|
||||
static void Got_PowerLevel(UINT8 **cp, INT32 playernum);
|
||||
static void Got_Mapcmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum);
|
||||
|
|
@ -358,12 +360,13 @@ consvar_t cv_kartminimap = {"kartminimap", "4", CV_SAVE, kartminimap_cons_t, NUL
|
|||
consvar_t cv_kartcheck = {"kartcheck", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0, NULL}};
|
||||
consvar_t cv_kartinvinsfx = {"kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartspeed = {"kartspeed", "Normal", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartspeed = {"kartspeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "On"}, {0, NULL}};
|
||||
consvar_t cv_kartencore = {"kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
|
||||
consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}};
|
||||
|
|
@ -373,6 +376,8 @@ consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t,
|
|||
|
||||
consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}};
|
||||
consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||
|
|
@ -500,6 +505,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
|||
"MODIFYVOTE",
|
||||
"PICKVOTE",
|
||||
"REMOVEPLAYER",
|
||||
"POWERLEVEL",
|
||||
#ifdef HAVE_BLUA
|
||||
"LUACMD",
|
||||
"LUAVAR"
|
||||
|
|
@ -531,6 +537,7 @@ void D_RegisterServerCommands(void)
|
|||
|
||||
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
||||
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
||||
RegisterNetXCmd(XD_POWERLEVEL, Got_PowerLevel);
|
||||
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
|
||||
RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd);
|
||||
RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd);
|
||||
|
|
@ -1924,6 +1931,17 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
|||
players[playernum].pflags |= PF_ANALOGMODE;
|
||||
}
|
||||
|
||||
static void Got_PowerLevel(UINT8 **cp,INT32 playernum)
|
||||
{
|
||||
UINT16 race = (UINT16)READUINT16(*cp);
|
||||
UINT16 battle = (UINT16)READUINT16(*cp);
|
||||
|
||||
clientpowerlevels[playernum][PWRLV_RACE] = min(PWRLVRECORD_MAX, race);
|
||||
clientpowerlevels[playernum][PWRLV_BATTLE] = min(PWRLVRECORD_MAX, battle);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "set player %d to power %d\n", playernum, race);
|
||||
}
|
||||
|
||||
void D_SendPlayerConfig(void)
|
||||
{
|
||||
SendNameAndColor();
|
||||
|
|
@ -1940,6 +1958,31 @@ void D_SendPlayerConfig(void)
|
|||
SendWeaponPref3();
|
||||
if (splitscreen > 2)
|
||||
SendWeaponPref4();
|
||||
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT16(buf_p, vspowerlevel[PWRLV_RACE]);
|
||||
WRITEUINT16(buf_p, vspowerlevel[PWRLV_BATTLE]);
|
||||
|
||||
SendNetXCmd(XD_POWERLEVEL, buf, 4);
|
||||
}
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT16(buf_p, 0);
|
||||
WRITEUINT16(buf_p, 0);
|
||||
|
||||
SendNetXCmd2(XD_POWERLEVEL, buf, 4);
|
||||
if (splitscreen > 1)
|
||||
SendNetXCmd3(XD_POWERLEVEL, buf, 4);
|
||||
if (splitscreen > 2)
|
||||
SendNetXCmd4(XD_POWERLEVEL, buf, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Only works for displayplayer, sorry!
|
||||
|
|
@ -2352,7 +2395,7 @@ void D_SetupVote(void)
|
|||
UINT8 secondgt = G_SometimesGetDifferentGametype();
|
||||
INT16 votebuffer[3] = {-1,-1,-1};
|
||||
|
||||
if (cv_kartencore.value && G_RaceGametype())
|
||||
if ((cv_kartencore.value == 1) && G_RaceGametype())
|
||||
WRITEUINT8(p, (gametype|0x80));
|
||||
else
|
||||
WRITEUINT8(p, gametype);
|
||||
|
|
@ -2523,7 +2566,7 @@ static void Command_Map_f(void)
|
|||
// new encoremode value
|
||||
// use cvar by default
|
||||
|
||||
newencoremode = (boolean)cv_kartencore.value;
|
||||
newencoremode = (cv_kartencore.value == 1);
|
||||
|
||||
if (COM_CheckParm("-encore"))
|
||||
{
|
||||
|
|
@ -3650,6 +3693,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
if (K_IsPlayerWanted(&players[playernum]))
|
||||
K_CalculateBattleWanted();
|
||||
}
|
||||
|
||||
K_PlayerForfeit(playernum, true);
|
||||
|
||||
players[playernum].health = 1;
|
||||
if (players[playernum].mo)
|
||||
players[playernum].mo->health = 1;
|
||||
|
|
@ -5739,7 +5785,7 @@ static void KartSpeed_OnChange(void)
|
|||
if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||
CV_StealthSetValue(&cv_kartspeed, 1);
|
||||
CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -5759,10 +5805,10 @@ static void KartEncore_OnChange(void)
|
|||
{
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
if ((boolean)cv_kartencore.value != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/)
|
||||
CONS_Printf(M_GetText("Encore Mode will be turned %s next round.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off"));
|
||||
if ((cv_kartencore.value == 1) != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/)
|
||||
CONS_Printf(M_GetText("Encore Mode will be set to %s next round.\n"), cv_kartencore.string);
|
||||
else
|
||||
CONS_Printf(M_GetText("Encore Mode has been turned %s.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off"));
|
||||
CONS_Printf(M_GetText("Encore Mode has been set to %s.\n"), cv_kartencore.string);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,8 +120,8 @@ extern consvar_t cv_kartencore;
|
|||
extern consvar_t cv_kartvoterulechanges;
|
||||
extern consvar_t cv_kartspeedometer;
|
||||
extern consvar_t cv_kartvoices;
|
||||
|
||||
extern consvar_t cv_karteliminatelast;
|
||||
extern consvar_t cv_kartusepwrlv;
|
||||
|
||||
extern consvar_t cv_votetime;
|
||||
|
||||
|
|
@ -178,9 +178,10 @@ typedef enum
|
|||
XD_MODIFYVOTE, // 23
|
||||
XD_PICKVOTE, // 24
|
||||
XD_REMOVEPLAYER,// 25
|
||||
XD_POWERLEVEL, // 26
|
||||
#ifdef HAVE_BLUA
|
||||
XD_LUACMD, // 26
|
||||
XD_LUAVAR, // 27
|
||||
XD_LUACMD, // 27
|
||||
XD_LUAVAR, // 28
|
||||
#endif
|
||||
MAXNETXCMD
|
||||
} netxcmd_t;
|
||||
|
|
|
|||
|
|
@ -2663,6 +2663,19 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
ty = UC_PLAYTIME + offset;
|
||||
re = atoi(params[1]);
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "POWERLEVEL"))
|
||||
{
|
||||
PARAMCHECK(2);
|
||||
ty = UC_POWERLEVEL;
|
||||
re = atoi(params[1]);
|
||||
x1 = atoi(params[2]);
|
||||
|
||||
if (x1 < 0 || x1 >= PWRLV_NUMTYPES)
|
||||
{
|
||||
deh_warning("Power level type %d out of range (0 - %d)", x1, PWRLV_NUMTYPES-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "GAMECLEAR")
|
||||
|| (++offset && fastcmp(params[0], "ALLEMERALDS")))
|
||||
//|| (++offset && fastcmp(params[0], "ULTIMATECLEAR")))
|
||||
|
|
@ -2715,7 +2728,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
|||
|
||||
if (x1 < 0 || x1 >= NUMMAPS)
|
||||
{
|
||||
deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS);
|
||||
deh_warning("Level number %d out of range (1 - %d)", x1, NUMMAPS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@
|
|||
#include "../z_zone.h"
|
||||
#include "../g_input.h"
|
||||
|
||||
#include "../k_pwrlv.h"
|
||||
|
||||
#include "../console.h"
|
||||
|
||||
#ifdef __GNUG__
|
||||
|
|
@ -618,6 +620,11 @@ void I_Quit (void)
|
|||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
|
||||
// Make sure you lose points for ALT-F4
|
||||
if (Playing())
|
||||
K_PlayerForfeit(consoleplayer, true);
|
||||
|
||||
G_SaveGameData(); // Tails 12-08-2002
|
||||
if (demorecording)
|
||||
G_CheckDemoStatus();
|
||||
|
|
|
|||
|
|
@ -158,9 +158,6 @@ extern FILE *logstream;
|
|||
// AND appveyor.yml, for the build bots!
|
||||
#endif
|
||||
|
||||
// Maintain compatibility with 1.0.x record attack replays?
|
||||
//#define DEMO_COMPAT_100
|
||||
|
||||
// Does this version require an added patch file?
|
||||
// Comment or uncomment this as necessary.
|
||||
#define USE_PATCH_FILE
|
||||
|
|
|
|||
|
|
@ -496,7 +496,6 @@ extern tic_t wantedcalcdelay;
|
|||
extern tic_t indirectitemcooldown;
|
||||
extern tic_t hyubgone;
|
||||
extern tic_t mapreset;
|
||||
extern UINT8 nospectategrief;
|
||||
extern boolean thwompsactive;
|
||||
extern SINT8 spbplace;
|
||||
|
||||
|
|
|
|||
447
src/g_game.c
447
src/g_game.c
|
|
@ -48,6 +48,7 @@
|
|||
#include "m_cond.h" // condition sets
|
||||
#include "md5.h" // demo checksums
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
gameaction_t gameaction;
|
||||
gamestate_t gamestate = GS_NULL;
|
||||
|
|
@ -274,7 +275,6 @@ tic_t wantedcalcdelay; // Time before it recalculates WANTED
|
|||
tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded
|
||||
tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled
|
||||
tic_t mapreset; // Map reset delay when enough players have joined an empty game
|
||||
UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing
|
||||
boolean thwompsactive; // Thwomps activate on lap 2
|
||||
SINT8 spbplace; // SPB exists, give the person behind better items
|
||||
|
||||
|
|
@ -2346,7 +2346,7 @@ void G_Ticker(boolean run)
|
|||
|
||||
G_DoReborn(consoleplayer);*/
|
||||
|
||||
D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false);
|
||||
D_MapChange(gamemap, gametype, (cv_kartencore.value == 1), true, 1, false, false);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -2378,21 +2378,7 @@ void G_Ticker(boolean run)
|
|||
|
||||
if (playeringame[i])
|
||||
{
|
||||
//@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat...
|
||||
// Remove for 1.1!
|
||||
|
||||
// SRB2kart
|
||||
// Save the dir the player is holding
|
||||
// to allow items to be thrown forward or backward.
|
||||
if (cmd->buttons & BT_FORWARD)
|
||||
players[i].kartstuff[k_throwdir] = 1;
|
||||
else if (cmd->buttons & BT_BACKWARD)
|
||||
players[i].kartstuff[k_throwdir] = -1;
|
||||
else
|
||||
players[i].kartstuff[k_throwdir] = 0;
|
||||
|
||||
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
|
||||
|
||||
// Use the leveltime sent in the player's ticcmd to determine control lag
|
||||
cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
|
||||
}
|
||||
|
|
@ -3056,8 +3042,17 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
continue;
|
||||
if (j == i)
|
||||
continue;
|
||||
if (players[j].score == players[i].score)
|
||||
num++;
|
||||
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE])
|
||||
num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[j].score == players[i].score)
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num > 1) // found dupes
|
||||
|
|
@ -3065,8 +3060,21 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (players[i].score > players[playernum].score || i < playernum)
|
||||
if (i < playernum)
|
||||
pos++;
|
||||
else
|
||||
{
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE])
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].score > players[playernum].score)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3395,9 +3403,10 @@ boolean G_BattleGametype(void)
|
|||
//
|
||||
INT16 G_SometimesGetDifferentGametype(void)
|
||||
{
|
||||
boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE) && G_RaceGametype());
|
||||
boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1) && G_RaceGametype());
|
||||
|
||||
if (!cv_kartvoterulechanges.value) // never
|
||||
if (!cv_kartvoterulechanges.value // never
|
||||
&& encorescramble != 1) // destroying the code for this one instance
|
||||
return gametype;
|
||||
|
||||
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
|
||||
|
|
@ -3405,25 +3414,33 @@ INT16 G_SometimesGetDifferentGametype(void)
|
|||
randmapbuffer[NUMMAPS]--;
|
||||
if (encorepossible)
|
||||
{
|
||||
switch (cv_kartvoterulechanges.value)
|
||||
if (encorescramble != -1)
|
||||
encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission
|
||||
else
|
||||
{
|
||||
case 3: // always
|
||||
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
||||
break;
|
||||
case 2: // frequent
|
||||
encorepossible = M_RandomChance(FRACUNIT>>1);
|
||||
break;
|
||||
case 1: // sometimes
|
||||
default:
|
||||
encorepossible = M_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
switch (cv_kartvoterulechanges.value)
|
||||
{
|
||||
case 3: // always
|
||||
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
||||
break;
|
||||
case 2: // frequent
|
||||
encorepossible = M_RandomChance(FRACUNIT>>1);
|
||||
break;
|
||||
case 1: // sometimes
|
||||
default:
|
||||
encorepossible = M_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (encorepossible != (boolean)cv_kartencore.value)
|
||||
if (encorepossible != (cv_kartencore.value == 1))
|
||||
return (gametype|0x80);
|
||||
}
|
||||
return gametype;
|
||||
}
|
||||
|
||||
if (!cv_kartvoterulechanges.value) // never (again)
|
||||
return gametype;
|
||||
|
||||
switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
|
||||
{
|
||||
case 3: // always
|
||||
|
|
@ -3893,7 +3910,7 @@ void G_NextLevel(void)
|
|||
}
|
||||
|
||||
forceresetplayers = false;
|
||||
deferencoremode = (boolean)cv_kartencore.value;
|
||||
deferencoremode = (cv_kartencore.value == 1);
|
||||
}
|
||||
|
||||
gameaction = ga_worlddone;
|
||||
|
|
@ -4056,9 +4073,13 @@ void G_LoadGameData(void)
|
|||
// to new gamedata
|
||||
G_ClearRecords(); // main and nights records
|
||||
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
||||
|
||||
totalplaytime = 0; // total play time (separate from all)
|
||||
matchesplayed = 0; // SRB2Kart: matches played & finished
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++) // SRB2Kart: online rank system
|
||||
vspowerlevel[i] = PWRLVRECORD_START;
|
||||
|
||||
if (M_CheckParm("-nodata"))
|
||||
return; // Don't load.
|
||||
|
||||
|
|
@ -4089,6 +4110,9 @@ void G_LoadGameData(void)
|
|||
totalplaytime = READUINT32(save_p);
|
||||
matchesplayed = READUINT32(save_p);
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
vspowerlevel[i] = READUINT16(save_p);
|
||||
|
||||
modded = READUINT8(save_p);
|
||||
|
||||
// Aha! Someone's been screwing with the save file!
|
||||
|
|
@ -4234,6 +4258,9 @@ void G_SaveGameData(boolean force)
|
|||
WRITEUINT32(save_p, totalplaytime);
|
||||
WRITEUINT32(save_p, matchesplayed);
|
||||
|
||||
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
WRITEUINT16(save_p, vspowerlevel[i]);
|
||||
|
||||
btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded
|
||||
WRITEUINT8(save_p, btemp);
|
||||
|
||||
|
|
@ -4746,7 +4773,7 @@ char *G_BuildMapTitle(INT32 mapnum)
|
|||
// DEMO RECORDING
|
||||
//
|
||||
|
||||
#define DEMOVERSION 0x0002
|
||||
#define DEMOVERSION 0x0003
|
||||
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
||||
|
||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||
|
|
@ -4757,12 +4784,6 @@ char *G_BuildMapTitle(INT32 mapnum)
|
|||
#define DF_ENCORE 0x40
|
||||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
#define DF_FILELIST 0x08 // This demo contains an extra files list
|
||||
#define DF_GAMETYPEMASK 0x30
|
||||
#define DF_GAMESHIFT 4
|
||||
#endif
|
||||
|
||||
#define DEMO_SPECTATOR 0x40
|
||||
|
||||
// For demos
|
||||
|
|
@ -4904,7 +4925,6 @@ void G_ReadDemoExtraData(void)
|
|||
kartspeed = READUINT8(demo_p);
|
||||
kartweight = READUINT8(demo_p);
|
||||
|
||||
|
||||
if (stricmp(skins[players[p].skin].name, name) != 0)
|
||||
FindClosestSkinForStats(p, kartspeed, kartweight);
|
||||
|
||||
|
|
@ -5622,16 +5642,9 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
else
|
||||
ghostext[playernum].desyncframes = 0;
|
||||
|
||||
if (
|
||||
#ifdef DEMO_COMPAT_100
|
||||
demo.version != 0x0001 &&
|
||||
#endif
|
||||
(
|
||||
players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem ||
|
||||
players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount ||
|
||||
players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers
|
||||
)
|
||||
)
|
||||
if (players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem
|
||||
|| players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount
|
||||
|| players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers)
|
||||
{
|
||||
if (demosynced)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||
|
|
@ -5659,10 +5672,6 @@ void G_GhostTicker(void)
|
|||
// Skip normal demo data.
|
||||
UINT8 ziptic = READUINT8(g->p);
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (g->version != 0x0001)
|
||||
{
|
||||
#endif
|
||||
while (ziptic != DW_END) // Get rid of extradata stuff
|
||||
{
|
||||
if (ziptic == 0) // Only support player 0 info for now
|
||||
|
|
@ -5686,9 +5695,6 @@ void G_GhostTicker(void)
|
|||
}
|
||||
|
||||
ziptic = READUINT8(g->p); // Back to actual ziptic stuff
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ziptic & ZT_FWD)
|
||||
g->p++;
|
||||
|
|
@ -5708,18 +5714,12 @@ void G_GhostTicker(void)
|
|||
// Grab ghost data.
|
||||
ziptic = READUINT8(g->p);
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (g->version != 0x0001)
|
||||
{
|
||||
#endif
|
||||
if (ziptic == 0xFF)
|
||||
goto skippedghosttic; // Didn't write ghost info this frame
|
||||
else if (ziptic != 0)
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
ziptic = READUINT8(g->p);
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ziptic & GZT_XYZ)
|
||||
{
|
||||
g->oldmo.x = READFIXED(g->p);
|
||||
|
|
@ -5860,15 +5860,8 @@ void G_GhostTicker(void)
|
|||
g->p += 12; // kartitem, kartamount, kartbumpers
|
||||
}
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (g->version != 0x0001)
|
||||
{
|
||||
#endif
|
||||
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
skippedghosttic:
|
||||
// Tick ghost colors (Super and Mario Invincibility flashing)
|
||||
|
|
@ -6378,20 +6371,15 @@ void G_BeginRecording(void)
|
|||
|
||||
switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
{
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // lap
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,0); // score
|
||||
break;*/
|
||||
default: // 3
|
||||
break;
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
demotime_p = demo_p;
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||
WRITEUINT32(demo_p,UINT32_MAX); // lap
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
|
||||
WRITEUINT32(demo_p,P_GetInitSeed());
|
||||
|
|
@ -6431,6 +6419,9 @@ void G_BeginRecording(void)
|
|||
// Score, since Kart uses this to determine where you start on the map
|
||||
WRITEUINT32(demo_p, player->score);
|
||||
|
||||
// Power Levels
|
||||
WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE]);
|
||||
|
||||
// Kart speed and weight
|
||||
WRITEUINT8(demo_p, skins[player->skin].kartspeed);
|
||||
WRITEUINT8(demo_p, skins[player->skin].kartweight);
|
||||
|
|
@ -6529,18 +6520,13 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap)
|
|||
{
|
||||
if (!demo.recording || !demotime_p)
|
||||
return;
|
||||
|
||||
if (demoflags & DF_RECORDATTACK)
|
||||
{
|
||||
WRITEUINT32(demotime_p, ptime);
|
||||
WRITEUINT32(demotime_p, plap);
|
||||
demotime_p = NULL;
|
||||
}
|
||||
/*else if (demoflags & DF_NIGHTSATTACK)
|
||||
{
|
||||
WRITEUINT32(demotime_p, ptime);
|
||||
WRITEUINT32(demotime_p, pscore);
|
||||
demotime_p = NULL;
|
||||
}*/
|
||||
}
|
||||
|
||||
static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||
|
|
@ -6783,13 +6769,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
|||
case DEMOVERSION: // latest always supported
|
||||
p += 64; // full demo title
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
// Old replays gotta go :]
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' outdated version. It will be overwritten. Nyeheheh.\n"), oldname);
|
||||
Z_Free(buffer);
|
||||
return UINT8_MAX;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
|
||||
|
|
@ -6881,12 +6860,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
info_p += 64;
|
||||
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
pdemo->type = MD_OUTDATED;
|
||||
sprintf(pdemo->title, "Legacy Replay");
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
||||
|
|
@ -6921,16 +6894,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo)
|
|||
Z_Free(infobuffer);
|
||||
return;
|
||||
}
|
||||
#ifdef DEMO_COMPAT_100
|
||||
else if (pdemoversion == 0x0001)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath);
|
||||
pdemo->type = MD_INVALID;
|
||||
sprintf(pdemo->title, "INVALID REPLAY");
|
||||
Z_Free(infobuffer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
pdemo->gametype = READUINT8(info_p);
|
||||
|
||||
|
|
@ -7131,10 +7094,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_p += 64;
|
||||
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
||||
|
|
@ -7163,24 +7122,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
demo_p += 16; // mapmd5
|
||||
|
||||
demoflags = READUINT8(demo_p);
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version == 0x0001)
|
||||
{
|
||||
if (demoflags & DF_MULTIPLAYER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
gametype = READUINT8(demo_p);
|
||||
|
||||
if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running.
|
||||
|
|
@ -7238,9 +7179,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
||||
multiplayer = !!(demoflags & DF_MULTIPLAYER);
|
||||
|
|
@ -7268,109 +7206,20 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
// Random seed
|
||||
randseed = READUINT32(demo_p);
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version != 0x0001)
|
||||
#endif
|
||||
demo_p += 4; // Extrainfo location
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version == 0x0001)
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||
{
|
||||
// Player name
|
||||
M_Memcpy(player_names[0],demo_p,16);
|
||||
demo_p += 16;
|
||||
|
||||
// Skin
|
||||
M_Memcpy(skin,demo_p,16);
|
||||
demo_p += 16;
|
||||
|
||||
// Color
|
||||
M_Memcpy(color,demo_p,16);
|
||||
demo_p += 16;
|
||||
|
||||
demo_p += 5; // Backwards compat - some stats
|
||||
// SRB2kart
|
||||
kartspeed[0] = READUINT8(demo_p);
|
||||
kartweight[0] = READUINT8(demo_p);
|
||||
//
|
||||
demo_p += 9; // Backwards compat - more stats
|
||||
|
||||
// Skin not loaded?
|
||||
if (!SetPlayerSkin(0, skin))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// ...*map* not loaded?
|
||||
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set color
|
||||
for (i = 0; i < MAXSKINCOLORS; i++)
|
||||
if (!stricmp(KartColor_Names[i],color)) // SRB2kart
|
||||
{
|
||||
players[0].skincolor = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// net var data
|
||||
CV_LoadNetVars(&demo_p);
|
||||
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demo_p == DEMOMARKER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||
Z_Free(pdemoname);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n"));
|
||||
|
||||
// console warning messages
|
||||
#if defined(SKIPERRORS) && !defined(DEVELOP)
|
||||
demosynced = (!skiperrors);
|
||||
#else
|
||||
demosynced = true;
|
||||
#endif
|
||||
|
||||
// didn't start recording right away.
|
||||
demo.deferstart = false;
|
||||
|
||||
consoleplayer = 0;
|
||||
memset(displayplayers, 0, sizeof(displayplayers));
|
||||
memset(playeringame, 0, sizeof(playeringame));
|
||||
playeringame[0] = true;
|
||||
|
||||
goto post_compat;
|
||||
Z_Free(demobuffer);
|
||||
demo.playback = false;
|
||||
demo.title = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// net var data
|
||||
CV_LoadNetVars(&demo_p);
|
||||
|
|
@ -7485,6 +7334,9 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
// Score, since Kart uses this to determine where you start on the map
|
||||
players[p].score = READUINT32(demo_p);
|
||||
|
||||
// Power Levels
|
||||
clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE] = READUINT16(demo_p);
|
||||
|
||||
// Kart stats, temporarily
|
||||
kartspeed[p] = READUINT8(demo_p);
|
||||
kartweight[p] = READUINT8(demo_p);
|
||||
|
|
@ -7509,10 +7361,6 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
|
||||
R_ExecuteSetViewSize();
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
post_compat:
|
||||
#endif
|
||||
|
||||
P_SetRandSeed(randseed);
|
||||
G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||
|
||||
|
|
@ -7603,10 +7451,6 @@ void G_AddGhost(char *defdemoname)
|
|||
case DEMOVERSION: // latest always supported
|
||||
p += 64; // title
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
break;
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
||||
|
|
@ -7647,15 +7491,9 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion != 0x0001)
|
||||
#endif
|
||||
p++; // gametype
|
||||
p++; // gametype
|
||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion != 0x0001)
|
||||
#endif
|
||||
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
{
|
||||
case ATTACKING_NONE: // 0
|
||||
|
|
@ -7671,41 +7509,6 @@ void G_AddGhost(char *defdemoname)
|
|||
}
|
||||
|
||||
p += 4; // random seed
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name (TODO: Display this somehow if it doesn't match cv_playername!)
|
||||
M_Memcpy(name, p,16);
|
||||
p += 16;
|
||||
|
||||
// Skin
|
||||
M_Memcpy(skin, p,16);
|
||||
p += 16;
|
||||
|
||||
// Color
|
||||
M_Memcpy(color, p,16);
|
||||
p += 16;
|
||||
|
||||
// Ghosts do not have a player structure to put this in.
|
||||
p++; // charability
|
||||
p++; // charability2
|
||||
p++; // actionspd
|
||||
p++; // mindash
|
||||
p++; // maxdash
|
||||
// SRB2kart
|
||||
p++; // kartspeed
|
||||
p++; // kartweight
|
||||
//
|
||||
p++; // normalspeed
|
||||
p++; // runspeed
|
||||
p++; // thrustfactor
|
||||
p++; // accelstart
|
||||
p++; // acceleration
|
||||
p += 4; // jumpfactor
|
||||
}
|
||||
else
|
||||
#endif
|
||||
p += 4; // Extra data location reference
|
||||
|
||||
// net var data
|
||||
|
|
@ -7725,10 +7528,6 @@ void G_AddGhost(char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion != 0x0001)
|
||||
{
|
||||
#endif
|
||||
if (READUINT8(p) != 0)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
||||
|
|
@ -7750,6 +7549,7 @@ void G_AddGhost(char *defdemoname)
|
|||
p += 16;
|
||||
|
||||
p += 4; // score
|
||||
p += 2; // powerlevel
|
||||
|
||||
kartspeed = READUINT8(p);
|
||||
kartweight = READUINT8(p);
|
||||
|
|
@ -7761,9 +7561,6 @@ void G_AddGhost(char *defdemoname)
|
|||
Z_Free(buffer);
|
||||
return;
|
||||
}
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
if (!stricmp(skins[i].name,skin))
|
||||
|
|
@ -7863,18 +7660,13 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
|||
ghostversion = READUINT16(p);
|
||||
switch(ghostversion)
|
||||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
p += 64; // full demo title
|
||||
break;
|
||||
case DEMOVERSION: // latest always supported
|
||||
p += 64; // full demo title
|
||||
break;
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
break;
|
||||
#endif
|
||||
|
||||
// too old, cannot support.
|
||||
default:
|
||||
goto fail;
|
||||
// too old, cannot support.
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
p += 16; // demo checksum
|
||||
|
|
@ -7894,43 +7686,22 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
|||
goto fail; // we don't NEED to do it here, but whatever
|
||||
}
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion != 0x0001)
|
||||
#endif
|
||||
p++; // Gametype
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion != 0x0001)
|
||||
#endif
|
||||
G_SkipDemoExtraFiles(&p);
|
||||
|
||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||
{
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
p += 8; // demo time, lap
|
||||
break;
|
||||
/*case ATTACKING_NIGHTS: // 2
|
||||
p += 8; // demo time left, score
|
||||
break;*/
|
||||
default: // 3
|
||||
break;
|
||||
case ATTACKING_NONE: // 0
|
||||
break;
|
||||
case ATTACKING_RECORD: // 1
|
||||
p += 8; // demo time, lap
|
||||
break;
|
||||
default: // 3
|
||||
break;
|
||||
}
|
||||
|
||||
p += 4; // random seed
|
||||
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (ghostversion == 0x0001)
|
||||
{
|
||||
// Player name
|
||||
M_Memcpy(dummystaffname, p,16);
|
||||
dummystaffname[16] = '\0';
|
||||
goto fail; // Not really a failure but whatever
|
||||
}
|
||||
#endif
|
||||
|
||||
p += 4; // Extrainfo location marker
|
||||
|
||||
// Ehhhh don't need ghostversion here (?) so I'll reuse the var here
|
||||
|
|
@ -8015,10 +7786,6 @@ void G_DoPlayMetal(void)
|
|||
{
|
||||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
#ifdef DEMO_COMPAT_100
|
||||
case 0x0001:
|
||||
I_Error("You need to implement demo compat here, doofus! %s:%d", __FILE__, __LINE__);
|
||||
#endif
|
||||
// too old, cannot support.
|
||||
default:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
|
||||
|
|
|
|||
|
|
@ -3049,7 +3049,7 @@ static void HU_DrawRankings(void)
|
|||
}
|
||||
|
||||
V_DrawCenteredString(256, 8, 0, "GAME SPEED");
|
||||
V_DrawCenteredString(256, 16, hilicol, cv_kartspeed.string);
|
||||
V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].strvalue);
|
||||
}
|
||||
|
||||
// When you play, you quickly see your score because your name is displayed in white.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
/// \brief SRB2kart general.
|
||||
/// All of the SRB2kart-unique stuff.
|
||||
|
||||
#include "k_kart.h"
|
||||
#include "k_pwrlv.h"
|
||||
#include "doomdef.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_game.h"
|
||||
|
|
@ -18,7 +20,6 @@
|
|||
#include "z_zone.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_cond.h"
|
||||
#include "k_kart.h"
|
||||
#include "f_finale.h"
|
||||
#include "lua_hud.h" // For Lua hud checks
|
||||
#include "lua_hook.h" // For MobjDamage and ShouldDamage
|
||||
|
|
@ -31,8 +32,6 @@
|
|||
// battlewanted is an array of the WANTED player nums, -1 for no player in that slot
|
||||
// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB
|
||||
// mapreset is set when enough players fill an empty server
|
||||
// nospectategrief is the players in-game needed to eliminate the person in last
|
||||
|
||||
|
||||
//{ SRB2kart Color Code
|
||||
|
||||
|
|
@ -580,6 +579,7 @@ void K_RegisterKartStuff(void)
|
|||
CV_RegisterVar(&cv_kartspeedometer);
|
||||
CV_RegisterVar(&cv_kartvoices);
|
||||
CV_RegisterVar(&cv_karteliminatelast);
|
||||
CV_RegisterVar(&cv_kartusepwrlv);
|
||||
CV_RegisterVar(&cv_votetime);
|
||||
|
||||
CV_RegisterVar(&cv_kartdebugitem);
|
||||
|
|
|
|||
301
src/k_pwrlv.c
Normal file
301
src/k_pwrlv.c
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/// \file k_pwrlv.c
|
||||
/// \brief SRB2Kart Power Levels
|
||||
|
||||
#include "k_pwrlv.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "g_game.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
|
||||
#include "p_tick.h" // leveltime
|
||||
|
||||
// Online rankings for the main gametypes.
|
||||
// This array is saved to the gamedata.
|
||||
UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||
|
||||
// Client-sided calculations done for Power Levels.
|
||||
// This is done so that clients will never be able to hack someone else's score over the server.
|
||||
UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||
|
||||
// Which players spec-scummed, and their power level before scumming.
|
||||
// On race finish, everyone is considered to have "won" against these people.
|
||||
INT16 nospectategrief[MAXPLAYERS];
|
||||
|
||||
// Game setting scrambles based on server Power Level
|
||||
SINT8 speedscramble = -1;
|
||||
SINT8 encorescramble = -1;
|
||||
|
||||
void K_ClearClientPowerLevels(void)
|
||||
{
|
||||
UINT8 i, j;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
for (j = 0; j < PWRLV_NUMTYPES; j++)
|
||||
clientpowerlevels[i][j] = 0;
|
||||
}
|
||||
|
||||
// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating
|
||||
INT16 K_CalculatePowerLevelInc(INT16 diff)
|
||||
{
|
||||
INT16 control[10] = {0,0,0,1,8,50,125,125,125,125};
|
||||
fixed_t increment = 0;
|
||||
fixed_t x;
|
||||
UINT8 j;
|
||||
|
||||
#define MAXDIFF (PWRLVRECORD_MAX - 1)
|
||||
if (diff > MAXDIFF)
|
||||
diff = MAXDIFF;
|
||||
if (diff < -MAXDIFF)
|
||||
diff = -MAXDIFF;
|
||||
#undef MAXDIFF
|
||||
|
||||
x = ((diff-2)<<FRACBITS) / PWRLVRECORD_DEF;
|
||||
|
||||
for (j = 3; j < 10; j++) // Just skipping to 3 since 0 thru 2 will always just add 0...
|
||||
{
|
||||
fixed_t f = abs(x - ((j-4)<<FRACBITS));
|
||||
fixed_t add;
|
||||
|
||||
if (f >= (2<<FRACBITS))
|
||||
{
|
||||
continue; //add = 0;
|
||||
}
|
||||
else if (f >= (1<<FRACBITS))
|
||||
{
|
||||
fixed_t f2 = (2<<FRACBITS) - f;
|
||||
add = FixedMul(FixedMul(f2, f2), f2) / 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
add = ((3*FixedMul(FixedMul(f, f), f)) - (6*FixedMul(f, f)) + (4<<FRACBITS)) / 6;
|
||||
}
|
||||
|
||||
increment += (add * control[j]);
|
||||
}
|
||||
|
||||
return (INT16)(increment >> FRACBITS);
|
||||
}
|
||||
|
||||
INT16 K_CalculatePowerLevelAvg(void)
|
||||
{
|
||||
fixed_t avg = 0;
|
||||
UINT8 div = 0;
|
||||
SINT8 t = PWRLV_DISABLED;
|
||||
UINT8 i;
|
||||
|
||||
if (!netgame || !cv_kartusepwrlv.value)
|
||||
return 0; // No average.
|
||||
|
||||
if (G_RaceGametype())
|
||||
t = PWRLV_RACE;
|
||||
else if (G_BattleGametype())
|
||||
t = PWRLV_BATTLE;
|
||||
|
||||
if (t == PWRLV_DISABLED)
|
||||
return 0; // Hmm?!
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator
|
||||
|| clientpowerlevels[i][t] == 0) // splitscreen player
|
||||
continue;
|
||||
|
||||
avg += clientpowerlevels[i][t];
|
||||
div++;
|
||||
}
|
||||
|
||||
if (!div)
|
||||
return 0; // No average.
|
||||
|
||||
avg /= div;
|
||||
|
||||
return (INT16)(avg >> FRACBITS);
|
||||
}
|
||||
|
||||
// -- K_UpdatePowerLevels could not be moved here due to usage of y_data, unfortunately. --
|
||||
|
||||
void K_SetPowerLevelScrambles(SINT8 powertype)
|
||||
{
|
||||
switch (powertype)
|
||||
{
|
||||
case PWRLV_RACE:
|
||||
if (cv_kartspeed.value == -1 || cv_kartencore.value == -1)
|
||||
{
|
||||
UINT8 speed = atoi(cv_kartspeed.defaultvalue);
|
||||
boolean encore = false;
|
||||
INT16 avg = 0, min = 0;
|
||||
UINT8 i, t = 0;
|
||||
|
||||
avg = K_CalculatePowerLevelAvg();
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (min == 0 || clientpowerlevels[i][0] < min)
|
||||
min = clientpowerlevels[i][0];
|
||||
}
|
||||
|
||||
if (min >= 7800)
|
||||
{
|
||||
if (avg >= 8200)
|
||||
t = 5;
|
||||
else
|
||||
t = 4;
|
||||
}
|
||||
else if (min >= 6800)
|
||||
{
|
||||
if (avg >= 7200)
|
||||
t = 4;
|
||||
else
|
||||
t = 3;
|
||||
}
|
||||
else if (min >= 5800)
|
||||
{
|
||||
if (avg >= 6200)
|
||||
t = 3;
|
||||
else
|
||||
t = 2;
|
||||
}
|
||||
else if (min >= 3800)
|
||||
{
|
||||
if (avg >= 4200)
|
||||
t = 2;
|
||||
else
|
||||
t = 1;
|
||||
}
|
||||
else if (min >= 1800)
|
||||
{
|
||||
if (avg >= 2200)
|
||||
t = 1;
|
||||
else
|
||||
t = 0;
|
||||
}
|
||||
else
|
||||
t = 0;
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case 5:
|
||||
speed = 2;
|
||||
encore = true;
|
||||
break;
|
||||
case 4:
|
||||
speed = M_RandomChance((7<<FRACBITS)/10) ? 2 : 1;
|
||||
encore = M_RandomChance(FRACUNIT>>1);
|
||||
break;
|
||||
case 3:
|
||||
speed = M_RandomChance((3<<FRACBITS)/10) ? 2 : 1;
|
||||
encore = M_RandomChance(FRACUNIT>>2);
|
||||
break;
|
||||
case 2:
|
||||
speed = 1;
|
||||
encore = M_RandomChance(FRACUNIT>>3);
|
||||
break;
|
||||
case 1: default:
|
||||
speed = 1;
|
||||
encore = false;
|
||||
break;
|
||||
case 0:
|
||||
speed = M_RandomChance((3<<FRACBITS)/10) ? 0 : 1;
|
||||
encore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cv_kartspeed.value == -1)
|
||||
speedscramble = speed;
|
||||
else
|
||||
speedscramble = -1;
|
||||
|
||||
if (cv_kartencore.value == -1)
|
||||
encorescramble = (encore ? 1 : 0);
|
||||
else
|
||||
encorescramble = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
|
||||
{
|
||||
UINT8 p = 0;
|
||||
INT32 powertype = PWRLV_DISABLED;
|
||||
UINT16 yourpower = PWRLVRECORD_DEF;
|
||||
UINT16 theirpower = PWRLVRECORD_DEF;
|
||||
INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV
|
||||
INT16 inc = 0;
|
||||
UINT8 i;
|
||||
|
||||
// power level & spectating is netgames only
|
||||
if (!netgame)
|
||||
return;
|
||||
|
||||
// This server isn't using power levels anyway!
|
||||
if (!cv_kartusepwrlv.value)
|
||||
return;
|
||||
|
||||
// Hey, I just got here!
|
||||
if (players[playernum].jointime <= 1)
|
||||
return;
|
||||
|
||||
// 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match.
|
||||
if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE))
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i] && !players[i].spectator)
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p < 2) // no players
|
||||
return;
|
||||
|
||||
if (G_RaceGametype())
|
||||
powertype = PWRLV_RACE;
|
||||
else if (G_BattleGametype())
|
||||
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)
|
||||
continue;
|
||||
|
||||
theirpower = PWRLVRECORD_DEF;
|
||||
if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests)
|
||||
theirpower = clientpowerlevels[i][powertype];
|
||||
|
||||
diff = yourpower - theirpower;
|
||||
inc -= K_CalculatePowerLevelInc(diff);
|
||||
}
|
||||
|
||||
if (inc == 0) // No change.
|
||||
return;
|
||||
|
||||
if (yourpower + inc > PWRLVRECORD_MAX) // I mean... we're subtracting... but y'know how it is :V
|
||||
inc -= ((yourpower + inc) - PWRLVRECORD_MAX);
|
||||
if (yourpower + inc < PWRLVRECORD_MIN)
|
||||
inc -= ((yourpower + inc) - PWRLVRECORD_MIN);
|
||||
|
||||
clientpowerlevels[playernum][powertype] += inc;
|
||||
|
||||
if (playernum == consoleplayer)
|
||||
{
|
||||
vspowerlevel[powertype] = clientpowerlevels[playernum][powertype];
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData(true); // save your punishment!
|
||||
}
|
||||
}
|
||||
31
src/k_pwrlv.h
Normal file
31
src/k_pwrlv.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __K_PWRLV__
|
||||
#define __K_PWRLV__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
|
||||
#define PWRLV_DISABLED -1
|
||||
#define PWRLV_RACE 0
|
||||
#define PWRLV_BATTLE 1
|
||||
#define PWRLV_NUMTYPES 2
|
||||
|
||||
#define PWRLVRECORD_START 1000 // 5000?
|
||||
#define PWRLVRECORD_DEF 5000
|
||||
#define PWRLVRECORD_MIN 1
|
||||
#define PWRLVRECORD_MAX 9999
|
||||
|
||||
extern SINT8 speedscramble;
|
||||
extern SINT8 encorescramble;
|
||||
|
||||
extern UINT16 vspowerlevel[PWRLV_NUMTYPES];
|
||||
extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES];
|
||||
extern INT16 nospectategrief[MAXPLAYERS];
|
||||
|
||||
void K_ClearClientPowerLevels(void);
|
||||
INT16 K_CalculatePowerLevelInc(INT16 diff);
|
||||
INT16 K_CalculatePowerLevelAvg(void);
|
||||
//void K_UpdatePowerLevels(void);
|
||||
void K_SetPowerLevelScrambles(SINT8 powertype);
|
||||
void K_PlayerForfeit(UINT8 playernum, boolean nopointloss);
|
||||
|
||||
#endif
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "r_things.h" // numskins
|
||||
//#include "r_draw.h" // R_GetColorByName
|
||||
#include "k_kart.h" // K_GetKartColorByName
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
// Map triggers for linedef executors
|
||||
// 32 triggers, one bit each
|
||||
|
|
@ -289,6 +290,8 @@ UINT8 M_CheckCondition(condition_t *cn)
|
|||
return (totalplaytime >= (unsigned)cn->requirement);
|
||||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
||||
return (matchesplayed >= (unsigned)cn->requirement);
|
||||
case UC_POWERLEVEL: // Requires power level >= x on a certain gametype
|
||||
return (vspowerlevel[cn->extrainfo1] >= (unsigned)cn->requirement);
|
||||
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||
return (timesBeaten >= (unsigned)cn->requirement);
|
||||
case UC_ALLEMERALDS: // Requires game beaten with all 7 emeralds >= x times
|
||||
|
|
|
|||
45
src/m_cond.h
45
src/m_cond.h
|
|
@ -22,28 +22,29 @@ typedef enum
|
|||
{
|
||||
UC_PLAYTIME, // PLAYTIME [tics]
|
||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
||||
//UC_OVERALLSCORE, // OVERALLSCORE [score to beat]
|
||||
UC_OVERALLTIME, // OVERALLTIME [time to beat, tics]
|
||||
//UC_OVERALLRINGS, // OVERALLRINGS [rings to beat]
|
||||
UC_MAPVISITED, // MAPVISITED [map number]
|
||||
UC_MAPBEATEN, // MAPBEATEN [map number]
|
||||
UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number]
|
||||
//UC_MAPULTIMATE, // MAPULTIMATE [map number]
|
||||
//UC_MAPPERFECT, // MAPPERFECT [map number]
|
||||
//UC_MAPSCORE, // MAPSCORE [map number] [score to beat]
|
||||
UC_MAPTIME, // MAPTIME [map number] [time to beat, tics]
|
||||
//UC_MAPRINGS, // MAPRINGS [map number] [rings to beat]
|
||||
//UC_NIGHTSSCORE, // NIGHTSSCORE [map number] <mare, omit or "0" for overall> [score to beat]
|
||||
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
||||
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [grade]
|
||||
UC_TRIGGER, // TRIGGER [trigger number]
|
||||
UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems]
|
||||
UC_EMBLEM, // EMBLEM [emblem number]
|
||||
UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number]
|
||||
UC_CONDITIONSET, // CONDITIONSET [condition set number]
|
||||
UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle]
|
||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
||||
//UC_OVERALLSCORE, // OVERALLSCORE [score to beat]
|
||||
UC_OVERALLTIME, // OVERALLTIME [time to beat, tics]
|
||||
//UC_OVERALLRINGS, // OVERALLRINGS [rings to beat]
|
||||
UC_MAPVISITED, // MAPVISITED [map number]
|
||||
UC_MAPBEATEN, // MAPBEATEN [map number]
|
||||
UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number]
|
||||
//UC_MAPULTIMATE, // MAPULTIMATE [map number]
|
||||
//UC_MAPPERFECT, // MAPPERFECT [map number]
|
||||
//UC_MAPSCORE, // MAPSCORE [map number] [score to beat]
|
||||
UC_MAPTIME, // MAPTIME [map number] [time to beat, tics]
|
||||
//UC_MAPRINGS, // MAPRINGS [map number] [rings to beat]
|
||||
//UC_NIGHTSSCORE, // NIGHTSSCORE [map number] <mare, omit or "0" for overall> [score to beat]
|
||||
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
||||
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [grade]
|
||||
UC_TRIGGER, // TRIGGER [trigger number]
|
||||
UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems]
|
||||
UC_EMBLEM, // EMBLEM [emblem number]
|
||||
UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number]
|
||||
UC_CONDITIONSET, // CONDITIONSET [condition set number]
|
||||
} conditiontype_t;
|
||||
|
||||
// Condition Set information
|
||||
|
|
|
|||
|
|
@ -3558,8 +3558,6 @@ void A_BubbleCheck(mobj_t *actor)
|
|||
//
|
||||
void A_AttractChase(mobj_t *actor)
|
||||
{
|
||||
fixed_t z;
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_AttractChase", actor))
|
||||
return;
|
||||
|
|
@ -3603,12 +3601,11 @@ void A_AttractChase(mobj_t *actor)
|
|||
{
|
||||
fixed_t offz = FixedMul(80*actor->target->scale, FINESINE(FixedAngle((90 - (9 * abs(10 - actor->extravalue1))) << FRACBITS) >> ANGLETOFINESHIFT));
|
||||
//P_SetScale(actor, (actor->destscale = actor->target->scale));
|
||||
z = actor->target->z;
|
||||
if (( actor->eflags & MFE_VERTICALFLIP ))
|
||||
z -= actor->height + offz;
|
||||
else
|
||||
z += actor->target->height + offz;
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y, z);
|
||||
actor->z = actor->target->z;
|
||||
K_MatchGenericExtraFlags(actor, actor->target);
|
||||
P_TeleportMove(actor, actor->target->x, actor->target->y,
|
||||
actor->z +
|
||||
( actor->target->height + offz )* P_MobjFlip(actor));
|
||||
actor->extravalue1++;
|
||||
}
|
||||
}
|
||||
|
|
@ -3635,15 +3632,12 @@ void A_AttractChase(mobj_t *actor)
|
|||
fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1);
|
||||
|
||||
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
|
||||
z = actor->target->z;
|
||||
if (( actor->eflags & MFE_VERTICALFLIP ))
|
||||
z += actor->target->height - actor->height - 24 * actor->target->scale;
|
||||
else
|
||||
z += 24 * actor->target->scale;
|
||||
actor->z = actor->target->z;
|
||||
K_MatchGenericExtraFlags(actor, actor->target);
|
||||
P_TeleportMove(actor,
|
||||
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||
z);
|
||||
actor->z + actor->target->scale * 24 * P_MobjFlip(actor));
|
||||
|
||||
actor->angle += ANG30;
|
||||
actor->extravalue1++;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "m_misc.h"
|
||||
#include "v_video.h" // video flags for CEchos
|
||||
#include "k_kart.h" // SRB2kart
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
// CTF player names
|
||||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
||||
|
|
@ -2047,7 +2048,8 @@ void P_CheckPointLimit(void)
|
|||
// Checks whether or not to end a race netgame.
|
||||
boolean P_CheckRacers(void)
|
||||
{
|
||||
INT32 i, j, numplayersingame = 0;
|
||||
INT32 i, j, numplayersingame = 0, numexiting = 0;
|
||||
boolean griefed = false;
|
||||
|
||||
// Check if all the players in the race have finished. If so, end the level.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -2064,57 +2066,53 @@ boolean P_CheckRacers(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (cv_karteliminatelast.value)
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
if (nospectategrief[j] != -1) // prevent spectate griefing
|
||||
griefed = true;
|
||||
if (!playeringame[j] || players[j].spectator)
|
||||
continue;
|
||||
numplayersingame++;
|
||||
if (players[j].exiting)
|
||||
numexiting++;
|
||||
}
|
||||
|
||||
if (cv_karteliminatelast.value && numplayersingame > 1 && !griefed)
|
||||
{
|
||||
// check if we just got unlucky and there was only one guy who was a problem
|
||||
for (j = i+1; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (!playeringame[j] || players[j].spectator)
|
||||
if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives)
|
||||
continue;
|
||||
numplayersingame++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (numplayersingame > 1 && nospectategrief > 0 && numplayersingame >= nospectategrief) // prevent spectate griefing
|
||||
if (j == MAXPLAYERS) // finish anyways, force a time over
|
||||
{
|
||||
// check if we just got unlucky and there was only one guy who was a problem
|
||||
for (j = i+1; j < MAXPLAYERS; j++)
|
||||
{
|
||||
if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == MAXPLAYERS) // finish anyways, force a time over
|
||||
{
|
||||
P_DoTimeOver(&players[i]);
|
||||
countdown = countdown2 = 0;
|
||||
return true;
|
||||
}
|
||||
P_DoTimeOver(&players[i]);
|
||||
countdown = countdown2 = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!countdown) // Check to see if the winners have finished, to set countdown.
|
||||
{
|
||||
UINT8 numingame = 0, numexiting = 0;
|
||||
UINT8 winningpos = 1;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
numingame++;
|
||||
if (players[i].exiting)
|
||||
numexiting++;
|
||||
}
|
||||
|
||||
winningpos = max(1, numingame/2);
|
||||
if (numingame % 2) // any remainder?
|
||||
winningpos = max(1, numplayersingame/2);
|
||||
if (numplayersingame % 2) // any remainder?
|
||||
winningpos++;
|
||||
|
||||
if (numexiting >= winningpos)
|
||||
countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going!
|
||||
}
|
||||
|
||||
if (numplayersingame < 2) // reset nospectategrief in free play
|
||||
{
|
||||
for (j = 0; j < MAXPLAYERS; j++)
|
||||
nospectategrief[j] = -1;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
17
src/p_mobj.c
17
src/p_mobj.c
|
|
@ -8744,18 +8744,13 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
mobj->z = mobj->target->z;
|
||||
|
||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||
{
|
||||
fixed_t z;
|
||||
z = mobj->target->z;
|
||||
if (( mobj->eflags & MFE_VERTICALFLIP ))
|
||||
z -= mobj->height;
|
||||
else
|
||||
z += mobj->target->height;
|
||||
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
z);
|
||||
}
|
||||
|
||||
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||
mobj->z + mobj->target->height * P_MobjFlip(mobj));
|
||||
break;
|
||||
case MT_TIREGREASE:
|
||||
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@
|
|||
#include "p_slopes.h"
|
||||
#endif
|
||||
|
||||
// SRB2Kart
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
savedata_t savedata;
|
||||
UINT8 *save_p;
|
||||
|
||||
|
|
@ -3302,7 +3305,10 @@ static void P_NetArchiveMisc(void)
|
|||
WRITEUINT32(save_p, indirectitemcooldown);
|
||||
WRITEUINT32(save_p, hyubgone);
|
||||
WRITEUINT32(save_p, mapreset);
|
||||
WRITEUINT8(save_p, nospectategrief);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
WRITEINT16(save_p, nospectategrief[i]);
|
||||
|
||||
WRITEUINT8(save_p, thwompsactive);
|
||||
WRITESINT8(save_p, spbplace);
|
||||
|
||||
|
|
@ -3419,7 +3425,10 @@ static inline boolean P_NetUnArchiveMisc(void)
|
|||
indirectitemcooldown = READUINT32(save_p);
|
||||
hyubgone = READUINT32(save_p);
|
||||
mapreset = READUINT32(save_p);
|
||||
nospectategrief = READUINT8(save_p);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
nospectategrief[i] = READINT16(save_p);
|
||||
|
||||
thwompsactive = (boolean)READUINT8(save_p);
|
||||
spbplace = READSINT8(save_p);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
|
||||
// SRB2Kart
|
||||
#include "k_kart.h"
|
||||
#include "k_pwrlv.h"
|
||||
|
||||
//
|
||||
// Map MD5, calculated on level load.
|
||||
|
|
@ -2396,7 +2397,12 @@ static void P_LevelInitStuff(void)
|
|||
if (G_BattleGametype())
|
||||
gamespeed = 0;
|
||||
else
|
||||
gamespeed = (UINT8)cv_kartspeed.value;
|
||||
{
|
||||
if (cv_kartspeed.value == -1)
|
||||
gamespeed = ((speedscramble == -1) ? atoi(cv_kartspeed.defaultvalue) : (UINT8)speedscramble);
|
||||
else
|
||||
gamespeed = (UINT8)cv_kartspeed.value;
|
||||
}
|
||||
franticitems = (boolean)cv_kartfrantic.value;
|
||||
comeback = (boolean)cv_kartcomeback.value;
|
||||
}
|
||||
|
|
@ -2405,6 +2411,7 @@ static void P_LevelInitStuff(void)
|
|||
battlewanted[i] = -1;
|
||||
|
||||
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
||||
speedscramble = encorescramble = -1;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3290,7 +3297,10 @@ boolean P_SetupLevel(boolean skipprecip)
|
|||
indirectitemcooldown = 0;
|
||||
hyubgone = 0;
|
||||
mapreset = 0;
|
||||
nospectategrief = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
nospectategrief[i] = -1;
|
||||
|
||||
thwompsactive = false;
|
||||
spbplace = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -3637,10 +3637,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
break;
|
||||
case 9: // Ring Drainer (Floor Touch)
|
||||
case 10: // Ring Drainer (No Floor Touch)
|
||||
if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1)
|
||||
if (leveltime % (TICRATE/2) == 0 && player->kartstuff[k_rings] > 0)
|
||||
{
|
||||
player->mo->health--;
|
||||
player->health--;
|
||||
player->kartstuff[k_rings]--;
|
||||
S_StartSound(player->mo, sfx_itemup);
|
||||
}
|
||||
break;
|
||||
|
|
@ -4309,10 +4308,6 @@ DoneSection2:
|
|||
// Play the starpost sound for 'consistency'
|
||||
// S_StartSound(player->mo, sfx_strpst);
|
||||
|
||||
// Figure out how many are playing on the last lap, to prevent spectate griefing
|
||||
if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1))
|
||||
nospectategrief = nump;
|
||||
|
||||
thwompsactive = true; // Lap 2 effects
|
||||
}
|
||||
else if (player->starpostnum)
|
||||
|
|
|
|||
36
src/p_tick.c
36
src/p_tick.c
|
|
@ -617,33 +617,10 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
if (demo.playback)
|
||||
{
|
||||
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version == 0x0001)
|
||||
{
|
||||
G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
G_ReadDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
{
|
||||
//@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now...
|
||||
// Remove for 1.1!
|
||||
if (players[i].cmd.buttons & BT_FORWARD)
|
||||
players[i].kartstuff[k_throwdir] = 1;
|
||||
else if (players[i].cmd.buttons & BT_BACKWARD)
|
||||
players[i].kartstuff[k_throwdir] = -1;
|
||||
else
|
||||
players[i].kartstuff[k_throwdir] = 0;
|
||||
|
||||
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
#ifdef DEMO_COMPAT_100
|
||||
}
|
||||
#endif
|
||||
G_ReadDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
|
@ -761,11 +738,6 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
else if (demo.playback) // Use Ghost data for consistency checks.
|
||||
{
|
||||
#ifdef DEMO_COMPAT_100
|
||||
if (demo.version == 0x0001)
|
||||
G_ConsGhostTic(0);
|
||||
else
|
||||
#endif
|
||||
G_ConsAllGhostTics();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8140,8 +8140,6 @@ void P_PlayerThink(player_t *player)
|
|||
|
||||
cmd = &player->cmd;
|
||||
|
||||
//@TODO This fixes a one-tic latency on direction handling, AND makes behavior consistent while paused, but is not BC with 1.0.4. Do this for 1.1!
|
||||
#if 0
|
||||
// SRB2kart
|
||||
// Save the dir the player is holding
|
||||
// to allow items to be thrown forward or backward.
|
||||
|
|
@ -8151,7 +8149,6 @@ void P_PlayerThink(player_t *player)
|
|||
player->kartstuff[k_throwdir] = -1;
|
||||
else
|
||||
player->kartstuff[k_throwdir] = 0;
|
||||
#endif
|
||||
|
||||
// Add some extra randomization.
|
||||
if (cmd->forwardmove)
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ static char returnWadPath[256];
|
|||
#include "../d_net.h"
|
||||
#include "../g_game.h"
|
||||
#include "../filesrch.h"
|
||||
#include "../k_pwrlv.h"
|
||||
#include "endtxt.h"
|
||||
#include "sdlmain.h"
|
||||
|
||||
|
|
@ -3056,6 +3057,11 @@ void I_Quit(void)
|
|||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
|
||||
// Make sure you lose points for ALT-F4
|
||||
if (Playing())
|
||||
K_PlayerForfeit(consoleplayer, true);
|
||||
|
||||
G_SaveGameData(false); // Tails 12-08-2002
|
||||
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
||||
// but sometimes we forget and use 'F10'.. so save here too.
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ static char returnWadPath[256];
|
|||
#include "../d_net.h"
|
||||
#include "../g_game.h"
|
||||
#include "../filesrch.h"
|
||||
#include "../k_pwrlv.h"
|
||||
#include "endtxt.h"
|
||||
#include "sdlmain.h"
|
||||
|
||||
|
|
@ -2977,6 +2978,11 @@ void I_Quit(void)
|
|||
#ifndef NONET
|
||||
D_SaveBan(); // save the ban list
|
||||
#endif
|
||||
|
||||
// Make sure you lose points for ALT-F4
|
||||
if (Playing())
|
||||
K_PlayerForfeit(consoleplayer, true);
|
||||
|
||||
G_SaveGameData(); // Tails 12-08-2002
|
||||
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
||||
// but sometimes we forget and use 'F10'.. so save here too.
|
||||
|
|
|
|||
266
src/y_inter.c
266
src/y_inter.c
|
|
@ -39,6 +39,7 @@
|
|||
#include "m_random.h" // M_RandomKey
|
||||
#include "g_input.h" // PLAYER1INPUTDOWN
|
||||
#include "k_kart.h" // colortranslations
|
||||
#include "k_pwrlv.h"
|
||||
#include "lua_hook.h" // IntermissionThinker hook
|
||||
|
||||
#ifdef HWRENDER
|
||||
|
|
@ -89,7 +90,7 @@ typedef union
|
|||
INT32 numplayers; // Number of players being displayed
|
||||
char levelstring[64]; // holds levelnames up to 64 characters
|
||||
// SRB2kart
|
||||
UINT8 increase[MAXPLAYERS]; // how much did the score increase by?
|
||||
INT16 increase[MAXPLAYERS]; // how much did the score increase by?
|
||||
UINT8 jitter[MAXPLAYERS]; // wiggle
|
||||
UINT32 val[MAXPLAYERS]; // Gametype-specific value
|
||||
UINT8 pos[MAXPLAYERS]; // player positions. used for ties
|
||||
|
|
@ -109,6 +110,7 @@ static boolean usetile;
|
|||
boolean usebuffer = false;
|
||||
static boolean useinterpic;
|
||||
static INT32 timer;
|
||||
static INT32 powertype = PWRLV_DISABLED;
|
||||
|
||||
static INT32 intertic;
|
||||
static INT32 endtic = -1;
|
||||
|
|
@ -192,11 +194,13 @@ static void Y_CompareBattle(INT32 i)
|
|||
|
||||
static void Y_CompareRank(INT32 i)
|
||||
{
|
||||
UINT8 increase = ((data.match.increase[i] == UINT8_MAX) ? 0 : data.match.increase[i]);
|
||||
if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (players[i].score - increase) > data.match.val[data.match.numplayers]))
|
||||
INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]);
|
||||
UINT32 score = (powertype != -1 ? clientpowerlevels[i][powertype] : players[i].score);
|
||||
|
||||
if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (score - increase) > data.match.val[data.match.numplayers]))
|
||||
return;
|
||||
|
||||
data.match.val[data.match.numplayers] = (players[i].score - increase);
|
||||
data.match.val[data.match.numplayers] = (score - increase);
|
||||
data.match.num[data.match.numplayers] = i;
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +208,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
{
|
||||
INT32 i, j;
|
||||
boolean completed[MAXPLAYERS];
|
||||
INT32 numplayersingame = 0;
|
||||
INT32 numplayersingame = 0, numgriefers = 0;
|
||||
|
||||
// Initialize variables
|
||||
if (rankingsmode > 1)
|
||||
|
|
@ -256,14 +260,17 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
{
|
||||
data.match.val[i] = UINT32_MAX;
|
||||
|
||||
if (nospectategrief[i] != -1)
|
||||
numgriefers++;
|
||||
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
data.match.increase[i] = UINT8_MAX;
|
||||
data.match.increase[i] = INT16_MIN;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rankingsmode)
|
||||
data.match.increase[i] = UINT8_MAX;
|
||||
data.match.increase[i] = INT16_MIN;
|
||||
|
||||
numplayersingame++;
|
||||
}
|
||||
|
|
@ -275,8 +282,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
|
||||
for (j = 0; j < numplayersingame; j++)
|
||||
{
|
||||
INT32 nump = ((G_RaceGametype() && nospectategrief > 0) ? nospectategrief : numplayersingame);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator || completed[i])
|
||||
|
|
@ -298,9 +303,10 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
|||
else
|
||||
data.match.pos[data.match.numplayers] = data.match.numplayers+1;
|
||||
|
||||
if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < nump))
|
||||
if ((!rankingsmode && powertype == -1) // Single player rankings (grand prix). Online rank is handled below.
|
||||
&& !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < (numplayersingame + numgriefers)))
|
||||
{
|
||||
data.match.increase[i] = nump - data.match.pos[data.match.numplayers];
|
||||
data.match.increase[i] = (numplayersingame + numgriefers) - data.match.pos[data.match.numplayers];
|
||||
players[i].score += data.match.increase[i];
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +435,7 @@ void Y_IntermissionDrawer(void)
|
|||
const char *timeheader;
|
||||
|
||||
if (data.match.rankingsmode)
|
||||
timeheader = "RANK";
|
||||
timeheader = "PWR.LV";
|
||||
else
|
||||
timeheader = (intertype == int_race ? "TIME" : "SCORE");
|
||||
|
||||
|
|
@ -491,21 +497,23 @@ void Y_IntermissionDrawer(void)
|
|||
|
||||
if (data.match.rankingsmode)
|
||||
{
|
||||
if (data.match.increase[data.match.num[i]] != UINT8_MAX)
|
||||
if (!clientpowerlevels[data.match.num[i]][powertype]) // No power level (splitscreen guests)
|
||||
STRBUFCPY(strtime, "----");
|
||||
else
|
||||
{
|
||||
if (data.match.increase[data.match.num[i]] > 9)
|
||||
snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]);
|
||||
else
|
||||
snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]);
|
||||
if (data.match.increase[data.match.num[i]] != INT16_MIN)
|
||||
{
|
||||
snprintf(strtime, sizeof strtime, "(%d)", data.match.increase[data.match.num[i]]);
|
||||
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+133+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
V_DrawRightAlignedString(x+118+gutter, y, 0, strtime);
|
||||
}
|
||||
|
||||
snprintf(strtime, sizeof strtime, "%d", data.match.val[i]);
|
||||
}
|
||||
|
||||
snprintf(strtime, sizeof strtime, "%d", data.match.val[i]);
|
||||
|
||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
|
|
@ -589,9 +597,14 @@ dotimer:
|
|||
break;
|
||||
}
|
||||
|
||||
// Make it obvious that scrambling is happening next round.
|
||||
if (cv_scrambleonchange.value && cv_teamscramble.value && (intertic/TICRATE % 2 == 0))
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));
|
||||
//if ((intertic/TICRATE) & 1) // Make it obvious that scrambling is happening next round. (OR NOT, I GUESS)
|
||||
//{
|
||||
/*if (cv_scrambleonchange.value && cv_teamscramble.value)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/
|
||||
if (speedscramble != -1 && speedscramble != gamespeed)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM,
|
||||
va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue));
|
||||
//}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -674,13 +687,46 @@ void Y_Ticker(void)
|
|||
{
|
||||
if (data.match.num[q] == MAXPLAYERS
|
||||
|| !data.match.increase[data.match.num[q]]
|
||||
|| data.match.increase[data.match.num[q]] == UINT8_MAX)
|
||||
|| data.match.increase[data.match.num[q]] == INT16_MIN)
|
||||
continue;
|
||||
|
||||
r++;
|
||||
data.match.jitter[data.match.num[q]] = 1;
|
||||
if (--data.match.increase[data.match.num[q]])
|
||||
kaching = false;
|
||||
|
||||
if (powertype != -1)
|
||||
{
|
||||
// Power Levels
|
||||
if (abs(data.match.increase[data.match.num[q]]) < 10)
|
||||
{
|
||||
// Not a lot of point increase left, just set to 0 instantly
|
||||
data.match.increase[data.match.num[q]] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SINT8 remove = 0; // default (should not happen)
|
||||
|
||||
if (data.match.increase[data.match.num[q]] < 0)
|
||||
remove = -10;
|
||||
else if (data.match.increase[data.match.num[q]] > 0)
|
||||
remove = 10;
|
||||
|
||||
// Remove 10 points at a time
|
||||
data.match.increase[data.match.num[q]] -= remove;
|
||||
|
||||
// Still not zero, no kaching yet
|
||||
if (data.match.increase[data.match.num[q]] != 0)
|
||||
kaching = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Basic bitch points
|
||||
if (data.match.increase[data.match.num[q]])
|
||||
{
|
||||
if (--data.match.increase[data.match.num[q]])
|
||||
kaching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r)
|
||||
|
|
@ -780,6 +826,153 @@ static void Y_UpdateRecordReplays(void)
|
|||
//CV_AddValue(&cv_nextmap, -1);
|
||||
}
|
||||
|
||||
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.match.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.match.num[j];
|
||||
|
||||
if (i == j || ipnum == jpnum) // Same person
|
||||
continue;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum);
|
||||
|
||||
if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up.
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
theirpower = PWRLVRECORD_DEF;
|
||||
if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests)
|
||||
theirpower = clientpowerlevels[jpnum][powertype];
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
|
||||
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
if (data.match.val[i] < data.match.val[j])
|
||||
won = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.match.val[i] > data.match.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);
|
||||
|
||||
theirpower = PWRLVRECORD_DEF;
|
||||
if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests)
|
||||
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.match.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.match.increase[i] = increment[i];
|
||||
clientpowerlevels[i][powertype] += data.match.increase[i];
|
||||
|
||||
if (i == consoleplayer)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i);
|
||||
vspowerlevel[powertype] = clientpowerlevels[i][powertype];
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(true))
|
||||
S_StartSound(NULL, sfx_ncitem);
|
||||
G_SaveGameData(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Y_StartIntermission
|
||||
//
|
||||
|
|
@ -794,6 +987,19 @@ void Y_StartIntermission(void)
|
|||
I_Error("endtic is dirty");
|
||||
#endif
|
||||
|
||||
// set player Power Level type
|
||||
powertype = PWRLV_DISABLED;
|
||||
|
||||
if (netgame && cv_kartusepwrlv.value)
|
||||
{
|
||||
if (G_RaceGametype())
|
||||
powertype = PWRLV_RACE;
|
||||
else if (G_BattleGametype())
|
||||
powertype = PWRLV_BATTLE;
|
||||
}
|
||||
|
||||
K_SetPowerLevelScrambles(powertype);
|
||||
|
||||
if (!multiplayer)
|
||||
{
|
||||
timer = 0;
|
||||
|
|
@ -870,6 +1076,8 @@ void Y_StartIntermission(void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (powertype != -1)
|
||||
K_UpdatePowerLevels();
|
||||
|
||||
bgpatch = W_CachePatchName("MENUBG", PU_STATIC);
|
||||
widebgpatch = W_CachePatchName("WEIRDRES", PU_STATIC);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue