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)/y_inter.o \
|
||||||
$(OBJDIR)/st_stuff.o \
|
$(OBJDIR)/st_stuff.o \
|
||||||
$(OBJDIR)/k_kart.o \
|
$(OBJDIR)/k_kart.o \
|
||||||
|
$(OBJDIR)/k_pwrlv.o \
|
||||||
$(OBJDIR)/m_aatree.o \
|
$(OBJDIR)/m_aatree.o \
|
||||||
$(OBJDIR)/m_anigif.o \
|
$(OBJDIR)/m_anigif.o \
|
||||||
$(OBJDIR)/m_argv.o \
|
$(OBJDIR)/m_argv.o \
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,12 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
||||||
|
|
||||||
//SRB2kart
|
//SRB2kart
|
||||||
CV_PossibleValue_t kartspeed_cons_t[] = {
|
CV_PossibleValue_t kartspeed_cons_t[] = {
|
||||||
{0, "Easy"}, {1, "Normal"}, {2, "Hard"},
|
{-1, "Auto"},
|
||||||
{0, NULL}};
|
{0, "Easy"},
|
||||||
|
{1, "Normal"},
|
||||||
|
{2, "Hard"},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
// Filter consvars by EXECVERSION
|
// Filter consvars by EXECVERSION
|
||||||
// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
|
// 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;
|
newvalue = var->value + 1;
|
||||||
if (newvalue > maxspeed)
|
if (newvalue > maxspeed)
|
||||||
newvalue = 0;
|
newvalue = -1;
|
||||||
var->value = newvalue;
|
var->value = newvalue;
|
||||||
var->string = var->PossibleValue[var->value].strvalue;
|
var->string = var->PossibleValue[var->value].strvalue;
|
||||||
var->func();
|
var->func();
|
||||||
|
|
@ -1743,7 +1747,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
|
||||||
else if (increment < 0) // Going down!
|
else if (increment < 0) // Going down!
|
||||||
{
|
{
|
||||||
newvalue = var->value - 1;
|
newvalue = var->value - 1;
|
||||||
if (newvalue < 0)
|
if (newvalue < -1)
|
||||||
newvalue = maxspeed;
|
newvalue = maxspeed;
|
||||||
var->value = newvalue;
|
var->value = newvalue;
|
||||||
var->string = var->PossibleValue[var->value].strvalue;
|
var->string = var->PossibleValue[var->value].strvalue;
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
// cl loading screen
|
// 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.cheatsenabled = CV_CheatsEnabled();
|
||||||
|
|
||||||
netbuffer->u.serverinfo.kartvars = (UINT8) (
|
netbuffer->u.serverinfo.kartvars = (UINT8) (
|
||||||
(cv_kartspeed.value & SV_SPEEDMASK) |
|
(gamespeed & SV_SPEEDMASK) |
|
||||||
(dedicated ? SV_DEDICATED : 0) |
|
(dedicated ? SV_DEDICATED : 0) |
|
||||||
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
|
(D_IsJoinPasswordOn() ? SV_PASSWORD : 0)
|
||||||
);
|
);
|
||||||
|
|
@ -1420,6 +1421,11 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
|
|
||||||
p = PutFileNeeded(0);
|
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));
|
HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1494,7 +1500,7 @@ static void SV_SendPlayerInfo(INT32 node)
|
||||||
*/
|
*/
|
||||||
static boolean SV_SendServerConfig(INT32 node)
|
static boolean SV_SendServerConfig(INT32 node)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i, j;
|
||||||
UINT8 *p, *op;
|
UINT8 *p, *op;
|
||||||
boolean waspacketsent;
|
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.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor));
|
||||||
|
|
||||||
memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers));
|
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++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[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])
|
if (!playeringame[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2306,6 +2315,7 @@ static void CL_ConnectToServer(boolean viams)
|
||||||
wipegamestate = GS_WAITINGPLAYERS;
|
wipegamestate = GS_WAITINGPLAYERS;
|
||||||
|
|
||||||
ClearAdminPlayers();
|
ClearAdminPlayers();
|
||||||
|
K_ClearClientPowerLevels();
|
||||||
pnumnodes = 1;
|
pnumnodes = 1;
|
||||||
oldtic = I_GetTime() - 1;
|
oldtic = I_GetTime() - 1;
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
|
|
@ -3156,6 +3166,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
break;
|
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])
|
if (playernode[pnum] == playernode[consoleplayer])
|
||||||
{
|
{
|
||||||
#ifdef DUMPCONSISTENCY
|
#ifdef DUMPCONSISTENCY
|
||||||
|
|
@ -3324,6 +3349,7 @@ void SV_ResetServer(void)
|
||||||
playernode[i] = UINT8_MAX;
|
playernode[i] = UINT8_MAX;
|
||||||
sprintf(player_names[i], "Player %d", i + 1);
|
sprintf(player_names[i], "Player %d", i + 1);
|
||||||
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
adminplayers[i] = -1; // Populate the entire adminplayers array with -1.
|
||||||
|
K_ClearClientPowerLevels();
|
||||||
}
|
}
|
||||||
|
|
||||||
mynode = 0;
|
mynode = 0;
|
||||||
|
|
@ -3399,6 +3425,7 @@ void D_QuitNetGame(void)
|
||||||
|
|
||||||
D_CloseConnection();
|
D_CloseConnection();
|
||||||
ClearAdminPlayers();
|
ClearAdminPlayers();
|
||||||
|
K_ClearClientPowerLevels();
|
||||||
|
|
||||||
DEBFILE("===========================================================================\n"
|
DEBFILE("===========================================================================\n"
|
||||||
" Log finish\n"
|
" Log finish\n"
|
||||||
|
|
@ -3445,11 +3472,12 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = READUINT8(*p);
|
node = (UINT8)READUINT8(*p);
|
||||||
newplayernum = READUINT8(*p);
|
newplayernum = (UINT8)READUINT8(*p);
|
||||||
splitscreenplayer = newplayernum/MAXPLAYERS;
|
splitscreenplayer = (UINT8)READUINT8(*p);
|
||||||
newplayernum %= MAXPLAYERS;
|
|
||||||
|
|
||||||
|
CONS_Debug(DBG_NETPLAY, "addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer);
|
||||||
|
|
||||||
// Clear player before joining, lest some things get set incorrectly
|
// Clear player before joining, lest some things get set incorrectly
|
||||||
CL_ClearPlayer(newplayernum);
|
CL_ClearPlayer(newplayernum);
|
||||||
|
|
||||||
|
|
@ -3466,7 +3494,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
if (splitscreenplayer)
|
if (splitscreenplayer)
|
||||||
{
|
{
|
||||||
displayplayers[splitscreenplayer] = newplayernum;
|
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)
|
if (splitscreenplayer == 1 && botingame)
|
||||||
players[newplayernum].bot = 1;
|
players[newplayernum].bot = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -3477,6 +3505,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
displayplayers[i] = newplayernum;
|
displayplayers[i] = newplayernum;
|
||||||
DEBFILE("spawning me\n");
|
DEBFILE("spawning me\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
D_SendPlayerConfig();
|
D_SendPlayerConfig();
|
||||||
addedtogame = true;
|
addedtogame = true;
|
||||||
}
|
}
|
||||||
|
|
@ -3532,7 +3561,6 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
|
||||||
static boolean SV_AddWaitingPlayers(void)
|
static boolean SV_AddWaitingPlayers(void)
|
||||||
{
|
{
|
||||||
INT32 node, n, newplayer = false;
|
INT32 node, n, newplayer = false;
|
||||||
XBOXSTATIC UINT8 buf[2];
|
|
||||||
UINT8 newplayernum = 0;
|
UINT8 newplayernum = 0;
|
||||||
|
|
||||||
// What is the reason for this? Why can't newplayernum always be 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
|
// splitscreen can allow 2+ players in one node
|
||||||
for (; nodewaiting[node] > 0; nodewaiting[node]--)
|
for (; nodewaiting[node] > 0; nodewaiting[node]--)
|
||||||
{
|
{
|
||||||
|
UINT8 buf[3];
|
||||||
|
UINT8 *buf_p = buf;
|
||||||
|
|
||||||
newplayer = true;
|
newplayer = true;
|
||||||
|
|
||||||
// search for a free playernum
|
// search for a free playernum
|
||||||
|
|
@ -3552,8 +3583,10 @@ static boolean SV_AddWaitingPlayers(void)
|
||||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||||
{
|
{
|
||||||
for (n = 0; n < MAXNETNODES; n++)
|
for (n = 0; n < MAXNETNODES; n++)
|
||||||
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum
|
if (nodetoplayer[n] == newplayernum
|
||||||
|| nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum)
|
|| nodetoplayer2[n] == newplayernum
|
||||||
|
|| nodetoplayer3[n] == newplayernum
|
||||||
|
|| nodetoplayer4[n] == newplayernum)
|
||||||
break;
|
break;
|
||||||
if (n == MAXNETNODES)
|
if (n == MAXNETNODES)
|
||||||
break;
|
break;
|
||||||
|
|
@ -3565,28 +3598,23 @@ static boolean SV_AddWaitingPlayers(void)
|
||||||
|
|
||||||
playernode[newplayernum] = (UINT8)node;
|
playernode[newplayernum] = (UINT8)node;
|
||||||
|
|
||||||
buf[0] = (UINT8)node;
|
WRITEUINT8(buf_p, (UINT8)node);
|
||||||
buf[1] = newplayernum;
|
WRITEUINT8(buf_p, newplayernum);
|
||||||
|
|
||||||
if (playerpernode[node] < 1)
|
if (playerpernode[node] < 1)
|
||||||
nodetoplayer[node] = newplayernum;
|
nodetoplayer[node] = newplayernum;
|
||||||
else if (playerpernode[node] < 2)
|
else if (playerpernode[node] < 2)
|
||||||
{
|
|
||||||
nodetoplayer2[node] = newplayernum;
|
nodetoplayer2[node] = newplayernum;
|
||||||
buf[1] += MAXPLAYERS;
|
|
||||||
}
|
|
||||||
else if (playerpernode[node] < 3)
|
else if (playerpernode[node] < 3)
|
||||||
{
|
|
||||||
nodetoplayer3[node] = newplayernum;
|
nodetoplayer3[node] = newplayernum;
|
||||||
buf[1] += MAXPLAYERS*2;
|
else if (playerpernode[node] < 4)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nodetoplayer4[node] = newplayernum;
|
nodetoplayer4[node] = newplayernum;
|
||||||
buf[1] += MAXPLAYERS*3;
|
|
||||||
}
|
WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num
|
||||||
|
|
||||||
playerpernode[node]++;
|
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));
|
DEBFILE(va("Server added player %d node %d\n", newplayernum, node));
|
||||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
// 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
|
case PT_SERVERCFG: // Positive response of client join request
|
||||||
{
|
{
|
||||||
INT32 j;
|
INT32 j, k;
|
||||||
UINT8 *scp;
|
UINT8 *scp;
|
||||||
|
|
||||||
if (server && serverrunning && node != servernode)
|
if (server && serverrunning && node != servernode)
|
||||||
|
|
@ -4104,7 +4132,11 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
||||||
I_Error("Bad gametype in cliserv!");
|
I_Error("Bad gametype in cliserv!");
|
||||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||||
for (j = 0; j < MAXPLAYERS; j++)
|
for (j = 0; j < MAXPLAYERS; j++)
|
||||||
|
{
|
||||||
adminplayers[j] = netbuffer->u.servercfg.adminplayers[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);
|
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "d_netcmd.h"
|
#include "d_netcmd.h"
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
#include "k_pwrlv.h" // PWRLV_NUMTYPES
|
||||||
|
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
|
|
@ -325,6 +326,7 @@ typedef struct
|
||||||
UINT8 gametype;
|
UINT8 gametype;
|
||||||
UINT8 modifiedgame;
|
UINT8 modifiedgame;
|
||||||
SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed
|
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.
|
char server_context[8]; // Unique context id, generated at server startup.
|
||||||
|
|
||||||
|
|
@ -387,6 +389,10 @@ typedef struct
|
||||||
UINT8 actnum;
|
UINT8 actnum;
|
||||||
UINT8 iszone;
|
UINT8 iszone;
|
||||||
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
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;
|
} ATTRPACK serverinfo_pak;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
||||||
|
|
@ -1558,7 +1558,7 @@ void D_SRB2Main(void)
|
||||||
else if (!dedicated && M_MapLocked(pstartmap))
|
else if (!dedicated && M_MapLocked(pstartmap))
|
||||||
I_Error("You need to unlock this level before you can warp to it!\n");
|
I_Error("You need to unlock this level before you can warp to it!\n");
|
||||||
else
|
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"))
|
else if (M_CheckParm("-skipintro"))
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@
|
||||||
#include "m_cond.h"
|
#include "m_cond.h"
|
||||||
#include "m_anigif.h"
|
#include "m_anigif.h"
|
||||||
#include "k_kart.h" // SRB2kart
|
#include "k_kart.h" // SRB2kart
|
||||||
|
#include "k_pwrlv.h"
|
||||||
#include "y_inter.h"
|
#include "y_inter.h"
|
||||||
|
|
||||||
#ifdef NETGAME_DEVMODE
|
#ifdef NETGAME_DEVMODE
|
||||||
|
|
@ -61,6 +62,7 @@
|
||||||
|
|
||||||
static void Got_NameAndColor(UINT8 **cp, INT32 playernum);
|
static void Got_NameAndColor(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_WeaponPref(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_Mapcmd(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum);
|
static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum);
|
||||||
static void Got_SetupVotecmd(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};
|
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}};
|
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_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}};
|
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_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_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_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}};
|
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};
|
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}};
|
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_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}};
|
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};
|
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}};
|
static CV_PossibleValue_t kartdebugamount_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
|
||||||
|
|
@ -500,6 +505,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
|
||||||
"MODIFYVOTE",
|
"MODIFYVOTE",
|
||||||
"PICKVOTE",
|
"PICKVOTE",
|
||||||
"REMOVEPLAYER",
|
"REMOVEPLAYER",
|
||||||
|
"POWERLEVEL",
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
"LUACMD",
|
"LUACMD",
|
||||||
"LUAVAR"
|
"LUAVAR"
|
||||||
|
|
@ -531,6 +537,7 @@ void D_RegisterServerCommands(void)
|
||||||
|
|
||||||
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
|
||||||
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
|
||||||
|
RegisterNetXCmd(XD_POWERLEVEL, Got_PowerLevel);
|
||||||
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
|
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
|
||||||
RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd);
|
RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd);
|
||||||
RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd);
|
RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd);
|
||||||
|
|
@ -1924,6 +1931,17 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum)
|
||||||
players[playernum].pflags |= PF_ANALOGMODE;
|
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)
|
void D_SendPlayerConfig(void)
|
||||||
{
|
{
|
||||||
SendNameAndColor();
|
SendNameAndColor();
|
||||||
|
|
@ -1940,6 +1958,31 @@ void D_SendPlayerConfig(void)
|
||||||
SendWeaponPref3();
|
SendWeaponPref3();
|
||||||
if (splitscreen > 2)
|
if (splitscreen > 2)
|
||||||
SendWeaponPref4();
|
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!
|
// Only works for displayplayer, sorry!
|
||||||
|
|
@ -2352,7 +2395,7 @@ void D_SetupVote(void)
|
||||||
UINT8 secondgt = G_SometimesGetDifferentGametype();
|
UINT8 secondgt = G_SometimesGetDifferentGametype();
|
||||||
INT16 votebuffer[3] = {-1,-1,-1};
|
INT16 votebuffer[3] = {-1,-1,-1};
|
||||||
|
|
||||||
if (cv_kartencore.value && G_RaceGametype())
|
if ((cv_kartencore.value == 1) && G_RaceGametype())
|
||||||
WRITEUINT8(p, (gametype|0x80));
|
WRITEUINT8(p, (gametype|0x80));
|
||||||
else
|
else
|
||||||
WRITEUINT8(p, gametype);
|
WRITEUINT8(p, gametype);
|
||||||
|
|
@ -2523,7 +2566,7 @@ static void Command_Map_f(void)
|
||||||
// new encoremode value
|
// new encoremode value
|
||||||
// use cvar by default
|
// use cvar by default
|
||||||
|
|
||||||
newencoremode = (boolean)cv_kartencore.value;
|
newencoremode = (cv_kartencore.value == 1);
|
||||||
|
|
||||||
if (COM_CheckParm("-encore"))
|
if (COM_CheckParm("-encore"))
|
||||||
{
|
{
|
||||||
|
|
@ -3650,6 +3693,9 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
||||||
if (K_IsPlayerWanted(&players[playernum]))
|
if (K_IsPlayerWanted(&players[playernum]))
|
||||||
K_CalculateBattleWanted();
|
K_CalculateBattleWanted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
K_PlayerForfeit(playernum, true);
|
||||||
|
|
||||||
players[playernum].health = 1;
|
players[playernum].health = 1;
|
||||||
if (players[playernum].mo)
|
if (players[playernum].mo)
|
||||||
players[playernum].mo->health = 1;
|
players[playernum].mo->health = 1;
|
||||||
|
|
@ -5739,7 +5785,7 @@ static void KartSpeed_OnChange(void)
|
||||||
if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2)
|
if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
|
||||||
CV_StealthSetValue(&cv_kartspeed, 1);
|
CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5759,10 +5805,10 @@ static void KartEncore_OnChange(void)
|
||||||
{
|
{
|
||||||
if (G_RaceGametype())
|
if (G_RaceGametype())
|
||||||
{
|
{
|
||||||
if ((boolean)cv_kartencore.value != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/)
|
if ((cv_kartencore.value == 1) != 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"));
|
CONS_Printf(M_GetText("Encore Mode will be set to %s next round.\n"), cv_kartencore.string);
|
||||||
else
|
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_kartvoterulechanges;
|
||||||
extern consvar_t cv_kartspeedometer;
|
extern consvar_t cv_kartspeedometer;
|
||||||
extern consvar_t cv_kartvoices;
|
extern consvar_t cv_kartvoices;
|
||||||
|
|
||||||
extern consvar_t cv_karteliminatelast;
|
extern consvar_t cv_karteliminatelast;
|
||||||
|
extern consvar_t cv_kartusepwrlv;
|
||||||
|
|
||||||
extern consvar_t cv_votetime;
|
extern consvar_t cv_votetime;
|
||||||
|
|
||||||
|
|
@ -178,9 +178,10 @@ typedef enum
|
||||||
XD_MODIFYVOTE, // 23
|
XD_MODIFYVOTE, // 23
|
||||||
XD_PICKVOTE, // 24
|
XD_PICKVOTE, // 24
|
||||||
XD_REMOVEPLAYER,// 25
|
XD_REMOVEPLAYER,// 25
|
||||||
|
XD_POWERLEVEL, // 26
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
XD_LUACMD, // 26
|
XD_LUACMD, // 27
|
||||||
XD_LUAVAR, // 27
|
XD_LUAVAR, // 28
|
||||||
#endif
|
#endif
|
||||||
MAXNETXCMD
|
MAXNETXCMD
|
||||||
} netxcmd_t;
|
} netxcmd_t;
|
||||||
|
|
|
||||||
|
|
@ -2663,6 +2663,19 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
||||||
ty = UC_PLAYTIME + offset;
|
ty = UC_PLAYTIME + offset;
|
||||||
re = atoi(params[1]);
|
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")
|
else if ((offset=0) || fastcmp(params[0], "GAMECLEAR")
|
||||||
|| (++offset && fastcmp(params[0], "ALLEMERALDS")))
|
|| (++offset && fastcmp(params[0], "ALLEMERALDS")))
|
||||||
//|| (++offset && fastcmp(params[0], "ULTIMATECLEAR")))
|
//|| (++offset && fastcmp(params[0], "ULTIMATECLEAR")))
|
||||||
|
|
@ -2715,7 +2728,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
|
||||||
|
|
||||||
if (x1 < 0 || x1 >= NUMMAPS)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@
|
||||||
#include "../z_zone.h"
|
#include "../z_zone.h"
|
||||||
#include "../g_input.h"
|
#include "../g_input.h"
|
||||||
|
|
||||||
|
#include "../k_pwrlv.h"
|
||||||
|
|
||||||
#include "../console.h"
|
#include "../console.h"
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
|
|
@ -618,6 +620,11 @@ void I_Quit (void)
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
D_SaveBan(); // save the ban list
|
D_SaveBan(); // save the ban list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Make sure you lose points for ALT-F4
|
||||||
|
if (Playing())
|
||||||
|
K_PlayerForfeit(consoleplayer, true);
|
||||||
|
|
||||||
G_SaveGameData(); // Tails 12-08-2002
|
G_SaveGameData(); // Tails 12-08-2002
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,6 @@ extern FILE *logstream;
|
||||||
// AND appveyor.yml, for the build bots!
|
// AND appveyor.yml, for the build bots!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Maintain compatibility with 1.0.x record attack replays?
|
|
||||||
//#define DEMO_COMPAT_100
|
|
||||||
|
|
||||||
// Does this version require an added patch file?
|
// Does this version require an added patch file?
|
||||||
// Comment or uncomment this as necessary.
|
// Comment or uncomment this as necessary.
|
||||||
#define USE_PATCH_FILE
|
#define USE_PATCH_FILE
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,6 @@ extern tic_t wantedcalcdelay;
|
||||||
extern tic_t indirectitemcooldown;
|
extern tic_t indirectitemcooldown;
|
||||||
extern tic_t hyubgone;
|
extern tic_t hyubgone;
|
||||||
extern tic_t mapreset;
|
extern tic_t mapreset;
|
||||||
extern UINT8 nospectategrief;
|
|
||||||
extern boolean thwompsactive;
|
extern boolean thwompsactive;
|
||||||
extern SINT8 spbplace;
|
extern SINT8 spbplace;
|
||||||
|
|
||||||
|
|
|
||||||
447
src/g_game.c
447
src/g_game.c
|
|
@ -48,6 +48,7 @@
|
||||||
#include "m_cond.h" // condition sets
|
#include "m_cond.h" // condition sets
|
||||||
#include "md5.h" // demo checksums
|
#include "md5.h" // demo checksums
|
||||||
#include "k_kart.h" // SRB2kart
|
#include "k_kart.h" // SRB2kart
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
gameaction_t gameaction;
|
gameaction_t gameaction;
|
||||||
gamestate_t gamestate = GS_NULL;
|
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 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 hyubgone; // Cooldown before hyudoro is allowed to be rerolled
|
||||||
tic_t mapreset; // Map reset delay when enough players have joined an empty game
|
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
|
boolean thwompsactive; // Thwomps activate on lap 2
|
||||||
SINT8 spbplace; // SPB exists, give the person behind better items
|
SINT8 spbplace; // SPB exists, give the person behind better items
|
||||||
|
|
||||||
|
|
@ -2346,7 +2346,7 @@ void G_Ticker(boolean run)
|
||||||
|
|
||||||
G_DoReborn(consoleplayer);*/
|
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++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
|
@ -2378,21 +2378,7 @@ void G_Ticker(boolean run)
|
||||||
|
|
||||||
if (playeringame[i])
|
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);
|
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
|
||||||
|
|
||||||
// Use the leveltime sent in the player's ticcmd to determine control lag
|
// 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
|
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;
|
continue;
|
||||||
if (j == i)
|
if (j == i)
|
||||||
continue;
|
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
|
if (num > 1) // found dupes
|
||||||
|
|
@ -3065,8 +3060,21 @@ mapthing_t *G_FindRaceStart(INT32 playernum)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (players[i].score > players[playernum].score || i < playernum)
|
if (i < playernum)
|
||||||
pos++;
|
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)
|
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;
|
return gametype;
|
||||||
|
|
||||||
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
|
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
|
||||||
|
|
@ -3405,25 +3414,33 @@ INT16 G_SometimesGetDifferentGametype(void)
|
||||||
randmapbuffer[NUMMAPS]--;
|
randmapbuffer[NUMMAPS]--;
|
||||||
if (encorepossible)
|
if (encorepossible)
|
||||||
{
|
{
|
||||||
switch (cv_kartvoterulechanges.value)
|
if (encorescramble != -1)
|
||||||
|
encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case 3: // always
|
switch (cv_kartvoterulechanges.value)
|
||||||
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
{
|
||||||
break;
|
case 3: // always
|
||||||
case 2: // frequent
|
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
|
||||||
encorepossible = M_RandomChance(FRACUNIT>>1);
|
break;
|
||||||
break;
|
case 2: // frequent
|
||||||
case 1: // sometimes
|
encorepossible = M_RandomChance(FRACUNIT>>1);
|
||||||
default:
|
break;
|
||||||
encorepossible = M_RandomChance(FRACUNIT>>2);
|
case 1: // sometimes
|
||||||
break;
|
default:
|
||||||
|
encorepossible = M_RandomChance(FRACUNIT>>2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (encorepossible != (boolean)cv_kartencore.value)
|
if (encorepossible != (cv_kartencore.value == 1))
|
||||||
return (gametype|0x80);
|
return (gametype|0x80);
|
||||||
}
|
}
|
||||||
return gametype;
|
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?
|
switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
|
||||||
{
|
{
|
||||||
case 3: // always
|
case 3: // always
|
||||||
|
|
@ -3893,7 +3910,7 @@ void G_NextLevel(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
forceresetplayers = false;
|
forceresetplayers = false;
|
||||||
deferencoremode = (boolean)cv_kartencore.value;
|
deferencoremode = (cv_kartencore.value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gameaction = ga_worlddone;
|
gameaction = ga_worlddone;
|
||||||
|
|
@ -4056,9 +4073,13 @@ void G_LoadGameData(void)
|
||||||
// to new gamedata
|
// to new gamedata
|
||||||
G_ClearRecords(); // main and nights records
|
G_ClearRecords(); // main and nights records
|
||||||
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
M_ClearSecrets(); // emblems, unlocks, maps visited, etc
|
||||||
|
|
||||||
totalplaytime = 0; // total play time (separate from all)
|
totalplaytime = 0; // total play time (separate from all)
|
||||||
matchesplayed = 0; // SRB2Kart: matches played & finished
|
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"))
|
if (M_CheckParm("-nodata"))
|
||||||
return; // Don't load.
|
return; // Don't load.
|
||||||
|
|
||||||
|
|
@ -4089,6 +4110,9 @@ void G_LoadGameData(void)
|
||||||
totalplaytime = READUINT32(save_p);
|
totalplaytime = READUINT32(save_p);
|
||||||
matchesplayed = READUINT32(save_p);
|
matchesplayed = READUINT32(save_p);
|
||||||
|
|
||||||
|
for (i = 0; i < PWRLV_NUMTYPES; i++)
|
||||||
|
vspowerlevel[i] = READUINT16(save_p);
|
||||||
|
|
||||||
modded = READUINT8(save_p);
|
modded = READUINT8(save_p);
|
||||||
|
|
||||||
// Aha! Someone's been screwing with the save file!
|
// 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, totalplaytime);
|
||||||
WRITEUINT32(save_p, matchesplayed);
|
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
|
btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded
|
||||||
WRITEUINT8(save_p, btemp);
|
WRITEUINT8(save_p, btemp);
|
||||||
|
|
||||||
|
|
@ -4746,7 +4773,7 @@ char *G_BuildMapTitle(INT32 mapnum)
|
||||||
// DEMO RECORDING
|
// DEMO RECORDING
|
||||||
//
|
//
|
||||||
|
|
||||||
#define DEMOVERSION 0x0002
|
#define DEMOVERSION 0x0003
|
||||||
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
|
||||||
|
|
||||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
#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_ENCORE 0x40
|
||||||
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
|
#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
|
#define DEMO_SPECTATOR 0x40
|
||||||
|
|
||||||
// For demos
|
// For demos
|
||||||
|
|
@ -4904,7 +4925,6 @@ void G_ReadDemoExtraData(void)
|
||||||
kartspeed = READUINT8(demo_p);
|
kartspeed = READUINT8(demo_p);
|
||||||
kartweight = READUINT8(demo_p);
|
kartweight = READUINT8(demo_p);
|
||||||
|
|
||||||
|
|
||||||
if (stricmp(skins[players[p].skin].name, name) != 0)
|
if (stricmp(skins[players[p].skin].name, name) != 0)
|
||||||
FindClosestSkinForStats(p, kartspeed, kartweight);
|
FindClosestSkinForStats(p, kartspeed, kartweight);
|
||||||
|
|
||||||
|
|
@ -5622,16 +5642,9 @@ void G_ConsGhostTic(INT32 playernum)
|
||||||
else
|
else
|
||||||
ghostext[playernum].desyncframes = 0;
|
ghostext[playernum].desyncframes = 0;
|
||||||
|
|
||||||
if (
|
if (players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem
|
||||||
#ifdef DEMO_COMPAT_100
|
|| players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount
|
||||||
demo.version != 0x0001 &&
|
|| players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers)
|
||||||
#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 (demosynced)
|
if (demosynced)
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n"));
|
||||||
|
|
@ -5659,10 +5672,6 @@ void G_GhostTicker(void)
|
||||||
// Skip normal demo data.
|
// Skip normal demo data.
|
||||||
UINT8 ziptic = READUINT8(g->p);
|
UINT8 ziptic = READUINT8(g->p);
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (g->version != 0x0001)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
while (ziptic != DW_END) // Get rid of extradata stuff
|
while (ziptic != DW_END) // Get rid of extradata stuff
|
||||||
{
|
{
|
||||||
if (ziptic == 0) // Only support player 0 info for now
|
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
|
ziptic = READUINT8(g->p); // Back to actual ziptic stuff
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ziptic & ZT_FWD)
|
if (ziptic & ZT_FWD)
|
||||||
g->p++;
|
g->p++;
|
||||||
|
|
@ -5708,18 +5714,12 @@ void G_GhostTicker(void)
|
||||||
// Grab ghost data.
|
// Grab ghost data.
|
||||||
ziptic = READUINT8(g->p);
|
ziptic = READUINT8(g->p);
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (g->version != 0x0001)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
if (ziptic == 0xFF)
|
if (ziptic == 0xFF)
|
||||||
goto skippedghosttic; // Didn't write ghost info this frame
|
goto skippedghosttic; // Didn't write ghost info this frame
|
||||||
else if (ziptic != 0)
|
else if (ziptic != 0)
|
||||||
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||||
ziptic = READUINT8(g->p);
|
ziptic = READUINT8(g->p);
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (ziptic & GZT_XYZ)
|
if (ziptic & GZT_XYZ)
|
||||||
{
|
{
|
||||||
g->oldmo.x = READFIXED(g->p);
|
g->oldmo.x = READFIXED(g->p);
|
||||||
|
|
@ -5860,15 +5860,8 @@ void G_GhostTicker(void)
|
||||||
g->p += 12; // kartitem, kartamount, kartbumpers
|
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.
|
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
|
I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
skippedghosttic:
|
skippedghosttic:
|
||||||
// Tick ghost colors (Super and Mario Invincibility flashing)
|
// Tick ghost colors (Super and Mario Invincibility flashing)
|
||||||
|
|
@ -6378,20 +6371,15 @@ void G_BeginRecording(void)
|
||||||
|
|
||||||
switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
{
|
{
|
||||||
case ATTACKING_NONE: // 0
|
case ATTACKING_NONE: // 0
|
||||||
break;
|
break;
|
||||||
case ATTACKING_RECORD: // 1
|
case ATTACKING_RECORD: // 1
|
||||||
demotime_p = demo_p;
|
demotime_p = demo_p;
|
||||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
WRITEUINT32(demo_p,UINT32_MAX); // time
|
||||||
WRITEUINT32(demo_p,UINT32_MAX); // lap
|
WRITEUINT32(demo_p,UINT32_MAX); // lap
|
||||||
break;
|
break;
|
||||||
/*case ATTACKING_NIGHTS: // 2
|
default: // 3
|
||||||
demotime_p = demo_p;
|
break;
|
||||||
WRITEUINT32(demo_p,UINT32_MAX); // time
|
|
||||||
WRITEUINT32(demo_p,0); // score
|
|
||||||
break;*/
|
|
||||||
default: // 3
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITEUINT32(demo_p,P_GetInitSeed());
|
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
|
// Score, since Kart uses this to determine where you start on the map
|
||||||
WRITEUINT32(demo_p, player->score);
|
WRITEUINT32(demo_p, player->score);
|
||||||
|
|
||||||
|
// Power Levels
|
||||||
|
WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE]);
|
||||||
|
|
||||||
// Kart speed and weight
|
// Kart speed and weight
|
||||||
WRITEUINT8(demo_p, skins[player->skin].kartspeed);
|
WRITEUINT8(demo_p, skins[player->skin].kartspeed);
|
||||||
WRITEUINT8(demo_p, skins[player->skin].kartweight);
|
WRITEUINT8(demo_p, skins[player->skin].kartweight);
|
||||||
|
|
@ -6529,18 +6520,13 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap)
|
||||||
{
|
{
|
||||||
if (!demo.recording || !demotime_p)
|
if (!demo.recording || !demotime_p)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (demoflags & DF_RECORDATTACK)
|
if (demoflags & DF_RECORDATTACK)
|
||||||
{
|
{
|
||||||
WRITEUINT32(demotime_p, ptime);
|
WRITEUINT32(demotime_p, ptime);
|
||||||
WRITEUINT32(demotime_p, plap);
|
WRITEUINT32(demotime_p, plap);
|
||||||
demotime_p = NULL;
|
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)
|
static void G_LoadDemoExtraFiles(UINT8 **pp)
|
||||||
|
|
@ -6783,13 +6769,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname)
|
||||||
case DEMOVERSION: // latest always supported
|
case DEMOVERSION: // latest always supported
|
||||||
p += 64; // full demo title
|
p += 64; // full demo title
|
||||||
break;
|
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.
|
// too old, cannot support.
|
||||||
default:
|
default:
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname);
|
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;
|
info_p += 64;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
case 0x0001:
|
|
||||||
pdemo->type = MD_OUTDATED;
|
|
||||||
sprintf(pdemo->title, "Legacy Replay");
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
// too old, cannot support.
|
// too old, cannot support.
|
||||||
default:
|
default:
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath);
|
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);
|
Z_Free(infobuffer);
|
||||||
return;
|
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);
|
pdemo->gametype = READUINT8(info_p);
|
||||||
|
|
||||||
|
|
@ -7131,10 +7094,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
demo_p += 64;
|
demo_p += 64;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
case 0x0001:
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
// too old, cannot support.
|
// too old, cannot support.
|
||||||
default:
|
default:
|
||||||
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
|
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
|
demo_p += 16; // mapmd5
|
||||||
|
|
||||||
demoflags = READUINT8(demo_p);
|
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);
|
gametype = 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.
|
||||||
|
|
@ -7238,9 +7179,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT;
|
||||||
multiplayer = !!(demoflags & DF_MULTIPLAYER);
|
multiplayer = !!(demoflags & DF_MULTIPLAYER);
|
||||||
|
|
@ -7268,109 +7206,20 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
// Random seed
|
// Random seed
|
||||||
randseed = READUINT32(demo_p);
|
randseed = READUINT32(demo_p);
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (demo.version != 0x0001)
|
|
||||||
#endif
|
|
||||||
demo_p += 4; // Extrainfo location
|
demo_p += 4; // Extrainfo location
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
// ...*map* not loaded?
|
||||||
if (demo.version == 0x0001)
|
if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK))
|
||||||
{
|
{
|
||||||
// Player name
|
snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname);
|
||||||
M_Memcpy(player_names[0],demo_p,16);
|
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||||
demo_p += 16;
|
M_StartMessage(msg, NULL, MM_NOTHING);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z_Free(pdemoname);
|
Z_Free(pdemoname);
|
||||||
|
Z_Free(demobuffer);
|
||||||
memset(&oldcmd,0,sizeof(oldcmd));
|
demo.playback = false;
|
||||||
memset(&oldghost,0,sizeof(oldghost));
|
demo.title = false;
|
||||||
memset(&ghostext,0,sizeof(ghostext));
|
return;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// net var data
|
// net var data
|
||||||
CV_LoadNetVars(&demo_p);
|
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
|
// Score, since Kart uses this to determine where you start on the map
|
||||||
players[p].score = READUINT32(demo_p);
|
players[p].score = READUINT32(demo_p);
|
||||||
|
|
||||||
|
// Power Levels
|
||||||
|
clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE] = READUINT16(demo_p);
|
||||||
|
|
||||||
// Kart stats, temporarily
|
// Kart stats, temporarily
|
||||||
kartspeed[p] = READUINT8(demo_p);
|
kartspeed[p] = READUINT8(demo_p);
|
||||||
kartweight[p] = READUINT8(demo_p);
|
kartweight[p] = READUINT8(demo_p);
|
||||||
|
|
@ -7509,10 +7361,6 @@ void G_DoPlayDemo(char *defdemoname)
|
||||||
|
|
||||||
R_ExecuteSetViewSize();
|
R_ExecuteSetViewSize();
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
post_compat:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
P_SetRandSeed(randseed);
|
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.
|
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
|
case DEMOVERSION: // latest always supported
|
||||||
p += 64; // title
|
p += 64; // title
|
||||||
break;
|
break;
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
case 0x0001:
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
// too old, cannot support.
|
// too old, cannot support.
|
||||||
default:
|
default:
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname);
|
||||||
|
|
@ -7647,15 +7491,9 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
p++; // gametype
|
||||||
if (ghostversion != 0x0001)
|
G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts.
|
||||||
#endif
|
|
||||||
p++; // gametype
|
|
||||||
|
|
||||||
#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)
|
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
{
|
{
|
||||||
case ATTACKING_NONE: // 0
|
case ATTACKING_NONE: // 0
|
||||||
|
|
@ -7671,41 +7509,6 @@ void G_AddGhost(char *defdemoname)
|
||||||
}
|
}
|
||||||
|
|
||||||
p += 4; // random seed
|
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
|
p += 4; // Extra data location reference
|
||||||
|
|
||||||
// net var data
|
// net var data
|
||||||
|
|
@ -7725,10 +7528,6 @@ void G_AddGhost(char *defdemoname)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (ghostversion != 0x0001)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
if (READUINT8(p) != 0)
|
if (READUINT8(p) != 0)
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname);
|
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 += 16;
|
||||||
|
|
||||||
p += 4; // score
|
p += 4; // score
|
||||||
|
p += 2; // powerlevel
|
||||||
|
|
||||||
kartspeed = READUINT8(p);
|
kartspeed = READUINT8(p);
|
||||||
kartweight = READUINT8(p);
|
kartweight = READUINT8(p);
|
||||||
|
|
@ -7761,9 +7561,6 @@ void G_AddGhost(char *defdemoname)
|
||||||
Z_Free(buffer);
|
Z_Free(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < numskins; i++)
|
for (i = 0; i < numskins; i++)
|
||||||
if (!stricmp(skins[i].name,skin))
|
if (!stricmp(skins[i].name,skin))
|
||||||
|
|
@ -7863,18 +7660,13 @@ void G_UpdateStaffGhostName(lumpnum_t l)
|
||||||
ghostversion = READUINT16(p);
|
ghostversion = READUINT16(p);
|
||||||
switch(ghostversion)
|
switch(ghostversion)
|
||||||
{
|
{
|
||||||
case DEMOVERSION: // latest always supported
|
case DEMOVERSION: // latest always supported
|
||||||
p += 64; // full demo title
|
p += 64; // full demo title
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
// too old, cannot support.
|
||||||
case 0x0001:
|
default:
|
||||||
break;
|
goto fail;
|
||||||
#endif
|
|
||||||
|
|
||||||
// too old, cannot support.
|
|
||||||
default:
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p += 16; // demo checksum
|
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
|
goto fail; // we don't NEED to do it here, but whatever
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (ghostversion != 0x0001)
|
|
||||||
#endif
|
|
||||||
p++; // Gametype
|
p++; // Gametype
|
||||||
|
|
||||||
#ifdef DEMO_COMPAT_100
|
|
||||||
if (ghostversion != 0x0001)
|
|
||||||
#endif
|
|
||||||
G_SkipDemoExtraFiles(&p);
|
G_SkipDemoExtraFiles(&p);
|
||||||
|
|
||||||
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT)
|
||||||
{
|
{
|
||||||
case ATTACKING_NONE: // 0
|
case ATTACKING_NONE: // 0
|
||||||
break;
|
break;
|
||||||
case ATTACKING_RECORD: // 1
|
case ATTACKING_RECORD: // 1
|
||||||
p += 8; // demo time, lap
|
p += 8; // demo time, lap
|
||||||
break;
|
break;
|
||||||
/*case ATTACKING_NIGHTS: // 2
|
default: // 3
|
||||||
p += 8; // demo time left, score
|
break;
|
||||||
break;*/
|
|
||||||
default: // 3
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p += 4; // random seed
|
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
|
p += 4; // Extrainfo location marker
|
||||||
|
|
||||||
// Ehhhh don't need ghostversion here (?) so I'll reuse the var here
|
// 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
|
case DEMOVERSION: // latest always supported
|
||||||
break;
|
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.
|
// too old, cannot support.
|
||||||
default:
|
default:
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n"));
|
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, 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.
|
// When you play, you quickly see your score because your name is displayed in white.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
/// \brief SRB2kart general.
|
/// \brief SRB2kart general.
|
||||||
/// All of the SRB2kart-unique stuff.
|
/// All of the SRB2kart-unique stuff.
|
||||||
|
|
||||||
|
#include "k_kart.h"
|
||||||
|
#include "k_pwrlv.h"
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
|
@ -18,7 +20,6 @@
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "m_cond.h"
|
#include "m_cond.h"
|
||||||
#include "k_kart.h"
|
|
||||||
#include "f_finale.h"
|
#include "f_finale.h"
|
||||||
#include "lua_hud.h" // For Lua hud checks
|
#include "lua_hud.h" // For Lua hud checks
|
||||||
#include "lua_hook.h" // For MobjDamage and ShouldDamage
|
#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
|
// 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
|
// indirectitemcooldown is timer before anyone's allowed another Shrink/SPB
|
||||||
// mapreset is set when enough players fill an empty server
|
// 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
|
//{ SRB2kart Color Code
|
||||||
|
|
||||||
|
|
@ -580,6 +579,7 @@ void K_RegisterKartStuff(void)
|
||||||
CV_RegisterVar(&cv_kartspeedometer);
|
CV_RegisterVar(&cv_kartspeedometer);
|
||||||
CV_RegisterVar(&cv_kartvoices);
|
CV_RegisterVar(&cv_kartvoices);
|
||||||
CV_RegisterVar(&cv_karteliminatelast);
|
CV_RegisterVar(&cv_karteliminatelast);
|
||||||
|
CV_RegisterVar(&cv_kartusepwrlv);
|
||||||
CV_RegisterVar(&cv_votetime);
|
CV_RegisterVar(&cv_votetime);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_kartdebugitem);
|
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_things.h" // numskins
|
||||||
//#include "r_draw.h" // R_GetColorByName
|
//#include "r_draw.h" // R_GetColorByName
|
||||||
#include "k_kart.h" // K_GetKartColorByName
|
#include "k_kart.h" // K_GetKartColorByName
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
// Map triggers for linedef executors
|
// Map triggers for linedef executors
|
||||||
// 32 triggers, one bit each
|
// 32 triggers, one bit each
|
||||||
|
|
@ -289,6 +290,8 @@ UINT8 M_CheckCondition(condition_t *cn)
|
||||||
return (totalplaytime >= (unsigned)cn->requirement);
|
return (totalplaytime >= (unsigned)cn->requirement);
|
||||||
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
case UC_MATCHESPLAYED: // Requires any level completed >= x times
|
||||||
return (matchesplayed >= (unsigned)cn->requirement);
|
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
|
case UC_GAMECLEAR: // Requires game beaten >= x times
|
||||||
return (timesBeaten >= (unsigned)cn->requirement);
|
return (timesBeaten >= (unsigned)cn->requirement);
|
||||||
case UC_ALLEMERALDS: // Requires game beaten with all 7 emeralds >= x times
|
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_PLAYTIME, // PLAYTIME [tics]
|
||||||
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played]
|
||||||
UC_GAMECLEAR, // GAMECLEAR <x times>
|
UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle]
|
||||||
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
UC_GAMECLEAR, // GAMECLEAR <x times>
|
||||||
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
UC_ALLEMERALDS, // ALLEMERALDS <x times>
|
||||||
//UC_OVERALLSCORE, // OVERALLSCORE [score to beat]
|
//UC_ULTIMATECLEAR, // ULTIMATECLEAR <x times>
|
||||||
UC_OVERALLTIME, // OVERALLTIME [time to beat, tics]
|
//UC_OVERALLSCORE, // OVERALLSCORE [score to beat]
|
||||||
//UC_OVERALLRINGS, // OVERALLRINGS [rings to beat]
|
UC_OVERALLTIME, // OVERALLTIME [time to beat, tics]
|
||||||
UC_MAPVISITED, // MAPVISITED [map number]
|
//UC_OVERALLRINGS, // OVERALLRINGS [rings to beat]
|
||||||
UC_MAPBEATEN, // MAPBEATEN [map number]
|
UC_MAPVISITED, // MAPVISITED [map number]
|
||||||
UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number]
|
UC_MAPBEATEN, // MAPBEATEN [map number]
|
||||||
//UC_MAPULTIMATE, // MAPULTIMATE [map number]
|
UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number]
|
||||||
//UC_MAPPERFECT, // MAPPERFECT [map number]
|
//UC_MAPULTIMATE, // MAPULTIMATE [map number]
|
||||||
//UC_MAPSCORE, // MAPSCORE [map number] [score to beat]
|
//UC_MAPPERFECT, // MAPPERFECT [map number]
|
||||||
UC_MAPTIME, // MAPTIME [map number] [time to beat, tics]
|
//UC_MAPSCORE, // MAPSCORE [map number] [score to beat]
|
||||||
//UC_MAPRINGS, // MAPRINGS [map number] [rings to beat]
|
UC_MAPTIME, // MAPTIME [map number] [time to beat, tics]
|
||||||
//UC_NIGHTSSCORE, // NIGHTSSCORE [map number] <mare, omit or "0" for overall> [score to beat]
|
//UC_MAPRINGS, // MAPRINGS [map number] [rings to beat]
|
||||||
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
//UC_NIGHTSSCORE, // NIGHTSSCORE [map number] <mare, omit or "0" for overall> [score to beat]
|
||||||
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [grade]
|
//UC_NIGHTSTIME, // NIGHTSTIME [map number] <mare, omit "0" overall> [time to beat, tics]
|
||||||
UC_TRIGGER, // TRIGGER [trigger number]
|
//UC_NIGHTSGRADE, // NIGHTSGRADE [map number] <mare, omit "0" overall> [grade]
|
||||||
UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems]
|
UC_TRIGGER, // TRIGGER [trigger number]
|
||||||
UC_EMBLEM, // EMBLEM [emblem number]
|
UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems]
|
||||||
UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number]
|
UC_EMBLEM, // EMBLEM [emblem number]
|
||||||
UC_CONDITIONSET, // CONDITIONSET [condition set number]
|
UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number]
|
||||||
|
UC_CONDITIONSET, // CONDITIONSET [condition set number]
|
||||||
} conditiontype_t;
|
} conditiontype_t;
|
||||||
|
|
||||||
// Condition Set information
|
// Condition Set information
|
||||||
|
|
|
||||||
|
|
@ -3558,8 +3558,6 @@ void A_BubbleCheck(mobj_t *actor)
|
||||||
//
|
//
|
||||||
void A_AttractChase(mobj_t *actor)
|
void A_AttractChase(mobj_t *actor)
|
||||||
{
|
{
|
||||||
fixed_t z;
|
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
if (LUA_CallAction("A_AttractChase", actor))
|
if (LUA_CallAction("A_AttractChase", actor))
|
||||||
return;
|
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));
|
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));
|
//P_SetScale(actor, (actor->destscale = actor->target->scale));
|
||||||
z = actor->target->z;
|
actor->z = actor->target->z;
|
||||||
if (( actor->eflags & MFE_VERTICALFLIP ))
|
K_MatchGenericExtraFlags(actor, actor->target);
|
||||||
z -= actor->height + offz;
|
P_TeleportMove(actor, actor->target->x, actor->target->y,
|
||||||
else
|
actor->z +
|
||||||
z += actor->target->height + offz;
|
( actor->target->height + offz )* P_MobjFlip(actor));
|
||||||
P_TeleportMove(actor, actor->target->x, actor->target->y, z);
|
|
||||||
actor->extravalue1++;
|
actor->extravalue1++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3635,15 +3632,12 @@ void A_AttractChase(mobj_t *actor)
|
||||||
fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1);
|
fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1);
|
||||||
|
|
||||||
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
|
P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1)));
|
||||||
z = actor->target->z;
|
actor->z = actor->target->z;
|
||||||
if (( actor->eflags & MFE_VERTICALFLIP ))
|
K_MatchGenericExtraFlags(actor, actor->target);
|
||||||
z += actor->target->height - actor->height - 24 * actor->target->scale;
|
|
||||||
else
|
|
||||||
z += 24 * actor->target->scale;
|
|
||||||
P_TeleportMove(actor,
|
P_TeleportMove(actor,
|
||||||
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
|
actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)),
|
||||||
actor->target->y + FixedMul(dist, FINESINE(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->angle += ANG30;
|
||||||
actor->extravalue1++;
|
actor->extravalue1++;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "v_video.h" // video flags for CEchos
|
#include "v_video.h" // video flags for CEchos
|
||||||
#include "k_kart.h" // SRB2kart
|
#include "k_kart.h" // SRB2kart
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
// CTF player names
|
// CTF player names
|
||||||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
#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.
|
// Checks whether or not to end a race netgame.
|
||||||
boolean P_CheckRacers(void)
|
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.
|
// 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++)
|
||||||
|
|
@ -2064,57 +2066,53 @@ boolean P_CheckRacers(void)
|
||||||
return true;
|
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;
|
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
|
P_DoTimeOver(&players[i]);
|
||||||
for (j = i+1; j < MAXPLAYERS; j++)
|
countdown = countdown2 = 0;
|
||||||
{
|
return true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!countdown) // Check to see if the winners have finished, to set countdown.
|
if (!countdown) // Check to see if the winners have finished, to set countdown.
|
||||||
{
|
{
|
||||||
UINT8 numingame = 0, numexiting = 0;
|
|
||||||
UINT8 winningpos = 1;
|
UINT8 winningpos = 1;
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
winningpos = max(1, numplayersingame/2);
|
||||||
{
|
if (numplayersingame % 2) // any remainder?
|
||||||
if (!playeringame[i] || players[i].spectator)
|
|
||||||
continue;
|
|
||||||
numingame++;
|
|
||||||
if (players[i].exiting)
|
|
||||||
numexiting++;
|
|
||||||
}
|
|
||||||
|
|
||||||
winningpos = max(1, numingame/2);
|
|
||||||
if (numingame % 2) // any remainder?
|
|
||||||
winningpos++;
|
winningpos++;
|
||||||
|
|
||||||
if (numexiting >= winningpos)
|
if (numexiting >= winningpos)
|
||||||
countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going!
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
17
src/p_mobj.c
17
src/p_mobj.c
|
|
@ -8744,18 +8744,13 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mobj->z = mobj->target->z;
|
||||||
|
|
||||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||||
{
|
|
||||||
fixed_t z;
|
P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||||
z = mobj->target->z;
|
mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT),
|
||||||
if (( mobj->eflags & MFE_VERTICALFLIP ))
|
mobj->z + mobj->target->height * P_MobjFlip(mobj));
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MT_TIREGREASE:
|
case MT_TIREGREASE:
|
||||||
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player
|
if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,9 @@
|
||||||
#include "p_slopes.h"
|
#include "p_slopes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// SRB2Kart
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
savedata_t savedata;
|
savedata_t savedata;
|
||||||
UINT8 *save_p;
|
UINT8 *save_p;
|
||||||
|
|
||||||
|
|
@ -3302,7 +3305,10 @@ static void P_NetArchiveMisc(void)
|
||||||
WRITEUINT32(save_p, indirectitemcooldown);
|
WRITEUINT32(save_p, indirectitemcooldown);
|
||||||
WRITEUINT32(save_p, hyubgone);
|
WRITEUINT32(save_p, hyubgone);
|
||||||
WRITEUINT32(save_p, mapreset);
|
WRITEUINT32(save_p, mapreset);
|
||||||
WRITEUINT8(save_p, nospectategrief);
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
WRITEINT16(save_p, nospectategrief[i]);
|
||||||
|
|
||||||
WRITEUINT8(save_p, thwompsactive);
|
WRITEUINT8(save_p, thwompsactive);
|
||||||
WRITESINT8(save_p, spbplace);
|
WRITESINT8(save_p, spbplace);
|
||||||
|
|
||||||
|
|
@ -3419,7 +3425,10 @@ static inline boolean P_NetUnArchiveMisc(void)
|
||||||
indirectitemcooldown = READUINT32(save_p);
|
indirectitemcooldown = READUINT32(save_p);
|
||||||
hyubgone = READUINT32(save_p);
|
hyubgone = READUINT32(save_p);
|
||||||
mapreset = 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);
|
thwompsactive = (boolean)READUINT8(save_p);
|
||||||
spbplace = READSINT8(save_p);
|
spbplace = READSINT8(save_p);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@
|
||||||
|
|
||||||
// SRB2Kart
|
// SRB2Kart
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
|
#include "k_pwrlv.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Map MD5, calculated on level load.
|
// Map MD5, calculated on level load.
|
||||||
|
|
@ -2396,7 +2397,12 @@ static void P_LevelInitStuff(void)
|
||||||
if (G_BattleGametype())
|
if (G_BattleGametype())
|
||||||
gamespeed = 0;
|
gamespeed = 0;
|
||||||
else
|
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;
|
franticitems = (boolean)cv_kartfrantic.value;
|
||||||
comeback = (boolean)cv_kartcomeback.value;
|
comeback = (boolean)cv_kartcomeback.value;
|
||||||
}
|
}
|
||||||
|
|
@ -2405,6 +2411,7 @@ static void P_LevelInitStuff(void)
|
||||||
battlewanted[i] = -1;
|
battlewanted[i] = -1;
|
||||||
|
|
||||||
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
memset(&battleovertime, 0, sizeof(struct battleovertime));
|
||||||
|
speedscramble = encorescramble = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -3290,7 +3297,10 @@ boolean P_SetupLevel(boolean skipprecip)
|
||||||
indirectitemcooldown = 0;
|
indirectitemcooldown = 0;
|
||||||
hyubgone = 0;
|
hyubgone = 0;
|
||||||
mapreset = 0;
|
mapreset = 0;
|
||||||
nospectategrief = 0;
|
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
nospectategrief[i] = -1;
|
||||||
|
|
||||||
thwompsactive = false;
|
thwompsactive = false;
|
||||||
spbplace = -1;
|
spbplace = -1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3637,10 +3637,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
||||||
break;
|
break;
|
||||||
case 9: // Ring Drainer (Floor Touch)
|
case 9: // Ring Drainer (Floor Touch)
|
||||||
case 10: // Ring Drainer (No 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->kartstuff[k_rings]--;
|
||||||
player->health--;
|
|
||||||
S_StartSound(player->mo, sfx_itemup);
|
S_StartSound(player->mo, sfx_itemup);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4309,10 +4308,6 @@ DoneSection2:
|
||||||
// Play the starpost sound for 'consistency'
|
// Play the starpost sound for 'consistency'
|
||||||
// S_StartSound(player->mo, sfx_strpst);
|
// 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
|
thwompsactive = true; // Lap 2 effects
|
||||||
}
|
}
|
||||||
else if (player->starpostnum)
|
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)
|
if (demo.playback)
|
||||||
{
|
{
|
||||||
|
G_ReadDemoExtraData();
|
||||||
#ifdef DEMO_COMPAT_100
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (demo.version == 0x0001)
|
if (playeringame[i])
|
||||||
{
|
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; 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.
|
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();
|
G_ConsAllGhostTics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8140,8 +8140,6 @@ void P_PlayerThink(player_t *player)
|
||||||
|
|
||||||
cmd = &player->cmd;
|
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
|
// SRB2kart
|
||||||
// Save the dir the player is holding
|
// Save the dir the player is holding
|
||||||
// to allow items to be thrown forward or backward.
|
// to allow items to be thrown forward or backward.
|
||||||
|
|
@ -8151,7 +8149,6 @@ void P_PlayerThink(player_t *player)
|
||||||
player->kartstuff[k_throwdir] = -1;
|
player->kartstuff[k_throwdir] = -1;
|
||||||
else
|
else
|
||||||
player->kartstuff[k_throwdir] = 0;
|
player->kartstuff[k_throwdir] = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Add some extra randomization.
|
// Add some extra randomization.
|
||||||
if (cmd->forwardmove)
|
if (cmd->forwardmove)
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ static char returnWadPath[256];
|
||||||
#include "../d_net.h"
|
#include "../d_net.h"
|
||||||
#include "../g_game.h"
|
#include "../g_game.h"
|
||||||
#include "../filesrch.h"
|
#include "../filesrch.h"
|
||||||
|
#include "../k_pwrlv.h"
|
||||||
#include "endtxt.h"
|
#include "endtxt.h"
|
||||||
#include "sdlmain.h"
|
#include "sdlmain.h"
|
||||||
|
|
||||||
|
|
@ -3056,6 +3057,11 @@ void I_Quit(void)
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
D_SaveBan(); // save the ban list
|
D_SaveBan(); // save the ban list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Make sure you lose points for ALT-F4
|
||||||
|
if (Playing())
|
||||||
|
K_PlayerForfeit(consoleplayer, true);
|
||||||
|
|
||||||
G_SaveGameData(false); // Tails 12-08-2002
|
G_SaveGameData(false); // Tails 12-08-2002
|
||||||
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
||||||
// but sometimes we forget and use 'F10'.. so save here too.
|
// but sometimes we forget and use 'F10'.. so save here too.
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,7 @@ static char returnWadPath[256];
|
||||||
#include "../d_net.h"
|
#include "../d_net.h"
|
||||||
#include "../g_game.h"
|
#include "../g_game.h"
|
||||||
#include "../filesrch.h"
|
#include "../filesrch.h"
|
||||||
|
#include "../k_pwrlv.h"
|
||||||
#include "endtxt.h"
|
#include "endtxt.h"
|
||||||
#include "sdlmain.h"
|
#include "sdlmain.h"
|
||||||
|
|
||||||
|
|
@ -2977,6 +2978,11 @@ void I_Quit(void)
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
D_SaveBan(); // save the ban list
|
D_SaveBan(); // save the ban list
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Make sure you lose points for ALT-F4
|
||||||
|
if (Playing())
|
||||||
|
K_PlayerForfeit(consoleplayer, true);
|
||||||
|
|
||||||
G_SaveGameData(); // Tails 12-08-2002
|
G_SaveGameData(); // Tails 12-08-2002
|
||||||
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
//added:16-02-98: when recording a demo, should exit using 'q' key,
|
||||||
// but sometimes we forget and use 'F10'.. so save here too.
|
// 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 "m_random.h" // M_RandomKey
|
||||||
#include "g_input.h" // PLAYER1INPUTDOWN
|
#include "g_input.h" // PLAYER1INPUTDOWN
|
||||||
#include "k_kart.h" // colortranslations
|
#include "k_kart.h" // colortranslations
|
||||||
|
#include "k_pwrlv.h"
|
||||||
#include "lua_hook.h" // IntermissionThinker hook
|
#include "lua_hook.h" // IntermissionThinker hook
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
|
|
@ -89,7 +90,7 @@ typedef union
|
||||||
INT32 numplayers; // Number of players being displayed
|
INT32 numplayers; // Number of players being displayed
|
||||||
char levelstring[64]; // holds levelnames up to 64 characters
|
char levelstring[64]; // holds levelnames up to 64 characters
|
||||||
// SRB2kart
|
// 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
|
UINT8 jitter[MAXPLAYERS]; // wiggle
|
||||||
UINT32 val[MAXPLAYERS]; // Gametype-specific value
|
UINT32 val[MAXPLAYERS]; // Gametype-specific value
|
||||||
UINT8 pos[MAXPLAYERS]; // player positions. used for ties
|
UINT8 pos[MAXPLAYERS]; // player positions. used for ties
|
||||||
|
|
@ -109,6 +110,7 @@ static boolean usetile;
|
||||||
boolean usebuffer = false;
|
boolean usebuffer = false;
|
||||||
static boolean useinterpic;
|
static boolean useinterpic;
|
||||||
static INT32 timer;
|
static INT32 timer;
|
||||||
|
static INT32 powertype = PWRLV_DISABLED;
|
||||||
|
|
||||||
static INT32 intertic;
|
static INT32 intertic;
|
||||||
static INT32 endtic = -1;
|
static INT32 endtic = -1;
|
||||||
|
|
@ -192,11 +194,13 @@ static void Y_CompareBattle(INT32 i)
|
||||||
|
|
||||||
static void Y_CompareRank(INT32 i)
|
static void Y_CompareRank(INT32 i)
|
||||||
{
|
{
|
||||||
UINT8 increase = ((data.match.increase[i] == UINT8_MAX) ? 0 : data.match.increase[i]);
|
INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]);
|
||||||
if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (players[i].score - increase) > data.match.val[data.match.numplayers]))
|
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;
|
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;
|
data.match.num[data.match.numplayers] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +208,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;
|
INT32 numplayersingame = 0, numgriefers = 0;
|
||||||
|
|
||||||
// Initialize variables
|
// Initialize variables
|
||||||
if (rankingsmode > 1)
|
if (rankingsmode > 1)
|
||||||
|
|
@ -256,14 +260,17 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
{
|
{
|
||||||
data.match.val[i] = UINT32_MAX;
|
data.match.val[i] = UINT32_MAX;
|
||||||
|
|
||||||
|
if (nospectategrief[i] != -1)
|
||||||
|
numgriefers++;
|
||||||
|
|
||||||
if (!playeringame[i] || players[i].spectator)
|
if (!playeringame[i] || players[i].spectator)
|
||||||
{
|
{
|
||||||
data.match.increase[i] = UINT8_MAX;
|
data.match.increase[i] = INT16_MIN;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rankingsmode)
|
if (!rankingsmode)
|
||||||
data.match.increase[i] = UINT8_MAX;
|
data.match.increase[i] = INT16_MIN;
|
||||||
|
|
||||||
numplayersingame++;
|
numplayersingame++;
|
||||||
}
|
}
|
||||||
|
|
@ -275,8 +282,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
|
|
||||||
for (j = 0; j < numplayersingame; j++)
|
for (j = 0; j < numplayersingame; j++)
|
||||||
{
|
{
|
||||||
INT32 nump = ((G_RaceGametype() && nospectategrief > 0) ? nospectategrief : numplayersingame);
|
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator || completed[i])
|
if (!playeringame[i] || players[i].spectator || completed[i])
|
||||||
|
|
@ -298,9 +303,10 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
|
||||||
else
|
else
|
||||||
data.match.pos[data.match.numplayers] = data.match.numplayers+1;
|
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];
|
players[i].score += data.match.increase[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,7 +435,7 @@ void Y_IntermissionDrawer(void)
|
||||||
const char *timeheader;
|
const char *timeheader;
|
||||||
|
|
||||||
if (data.match.rankingsmode)
|
if (data.match.rankingsmode)
|
||||||
timeheader = "RANK";
|
timeheader = "PWR.LV";
|
||||||
else
|
else
|
||||||
timeheader = (intertype == int_race ? "TIME" : "SCORE");
|
timeheader = (intertype == int_race ? "TIME" : "SCORE");
|
||||||
|
|
||||||
|
|
@ -491,21 +497,23 @@ void Y_IntermissionDrawer(void)
|
||||||
|
|
||||||
if (data.match.rankingsmode)
|
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)
|
if (data.match.increase[data.match.num[i]] != INT16_MIN)
|
||||||
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]]);
|
||||||
snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]);
|
|
||||||
|
|
||||||
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
V_DrawRightAlignedThinString(x+135+gutter, y-1, V_6WIDTHSPACE, strtime);
|
V_DrawRightAlignedThinString(x+133+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
else
|
else
|
||||||
V_DrawRightAlignedString(x+120+gutter, y, 0, strtime);
|
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)
|
if (data.match.numplayers > NUMFORNEWCOLUMN)
|
||||||
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
V_DrawRightAlignedThinString(x+152+gutter, y-1, V_6WIDTHSPACE, strtime);
|
||||||
else
|
else
|
||||||
|
|
@ -589,9 +597,14 @@ dotimer:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make it obvious that scrambling is happening 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 && (intertic/TICRATE % 2 == 0))
|
//{
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));
|
/*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
|
if (data.match.num[q] == MAXPLAYERS
|
||||||
|| !data.match.increase[data.match.num[q]]
|
|| !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;
|
continue;
|
||||||
|
|
||||||
r++;
|
r++;
|
||||||
data.match.jitter[data.match.num[q]] = 1;
|
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)
|
if (r)
|
||||||
|
|
@ -780,6 +826,153 @@ static void Y_UpdateRecordReplays(void)
|
||||||
//CV_AddValue(&cv_nextmap, -1);
|
//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
|
// Y_StartIntermission
|
||||||
//
|
//
|
||||||
|
|
@ -794,6 +987,19 @@ void Y_StartIntermission(void)
|
||||||
I_Error("endtic is dirty");
|
I_Error("endtic is dirty");
|
||||||
#endif
|
#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)
|
if (!multiplayer)
|
||||||
{
|
{
|
||||||
timer = 0;
|
timer = 0;
|
||||||
|
|
@ -870,6 +1076,8 @@ void Y_StartIntermission(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (powertype != -1)
|
||||||
|
K_UpdatePowerLevels();
|
||||||
|
|
||||||
bgpatch = W_CachePatchName("MENUBG", PU_STATIC);
|
bgpatch = W_CachePatchName("MENUBG", PU_STATIC);
|
||||||
widebgpatch = W_CachePatchName("WEIRDRES", PU_STATIC);
|
widebgpatch = W_CachePatchName("WEIRDRES", PU_STATIC);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue