Merge pull request 'New Multiplayer Tab Ranking' (#85) from neotabranking into blankart-dev
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/85
This commit is contained in:
commit
390160aa4e
15 changed files with 659 additions and 127 deletions
|
|
@ -160,7 +160,10 @@ static tic_t neededtic;
|
|||
SINT8 servernode = 0; // the number of the server node
|
||||
SINT8 joinnode = 0; // used for CL_VIEWSERVER
|
||||
|
||||
char connectedservername[MAXSERVERNAME+1];
|
||||
char connectedservername[MAXSERVERNAME];
|
||||
char connectedservercontact[MAXSERVERCONTACT];
|
||||
char connectedserverdescription[MAXSERVERDESCRIPTION];
|
||||
|
||||
/// \brief do we accept new players?
|
||||
/// \todo WORK!
|
||||
boolean acceptnewnode = true;
|
||||
|
|
@ -867,7 +870,7 @@ static boolean CL_SendJoin(void)
|
|||
return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak));
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
CopyCaretColors (char *p, const char *s, int n)
|
||||
{
|
||||
char *t;
|
||||
|
|
@ -1140,6 +1143,10 @@ static boolean SV_SendServerConfig(INT32 node)
|
|||
|
||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||
|
||||
strncpy(netbuffer->u.servercfg.server_name, cv_servername.string, MAXSERVERNAME);
|
||||
strncpy(netbuffer->u.servercfg.server_contact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||
strncpy(netbuffer->u.servercfg.server_description, connectedserverdescription, MAXSERVERDESCRIPTION);
|
||||
|
||||
{
|
||||
const size_t len = sizeof (serverconfig_pak);
|
||||
|
||||
|
|
@ -3545,14 +3552,19 @@ void SV_ResetServer(void)
|
|||
// clear server_context
|
||||
memset(server_context, '-', 8);
|
||||
|
||||
memset(connectedservername, 0, MAXSERVERNAME);
|
||||
memset(connectedservercontact, 0, MAXSERVERCONTACT);
|
||||
memset(connectedserverdescription, 0, MAXSERVERDESCRIPTION);
|
||||
|
||||
CV_RevertNetVars();
|
||||
|
||||
DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n");
|
||||
}
|
||||
|
||||
static inline void SV_GenContext(void)
|
||||
static void SV_GenContext(void)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
// generate server_context, as exactly 8 bytes of randomly mixed A-Z and a-z
|
||||
// (hopefully M_Random is initialized!! if not this will be awfully silly!)
|
||||
for (i = 0; i < 8; i++)
|
||||
|
|
@ -3563,6 +3575,10 @@ static inline void SV_GenContext(void)
|
|||
else // lowercase
|
||||
server_context[i] = 'a'+(a-26);
|
||||
}
|
||||
|
||||
CopyCaretColors(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
CopyCaretColors(connectedservercontact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||
strncpy(connectedserverdescription, DEFAULTDESCSTRING, MAXSERVERDESCRIPTION);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -4365,6 +4381,40 @@ static void PT_LoginAuth(SINT8 node, INT32 netconsole)
|
|||
CONS_Printf(M_GetText("Password from %s failed.\n"), player_names[netconsole]);
|
||||
}
|
||||
|
||||
void ServerInfoUpdateSend(void)
|
||||
{
|
||||
UINT32 n;
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
for (n = 1; n < MAXNETNODES; n++)
|
||||
{
|
||||
// Do Shit
|
||||
if (nodeingame[n])
|
||||
{
|
||||
CopyCaretColors(netbuffer->u.serverinfoupdate.servername, cv_servername.string, MAXSERVERNAME);
|
||||
CopyCaretColors(netbuffer->u.serverinfoupdate.servercontact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||
strncpy(netbuffer->u.serverinfoupdate.serverdescription, connectedserverdescription, MAXSERVERDESCRIPTION);
|
||||
|
||||
netbuffer->packettype = PT_SERVERINFOUPDATE;
|
||||
HSendPacket(n, true, 0, sizeof(netbuffer->u.serverinfoupdate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PT_ServerInfoUpdate(SINT8 node)
|
||||
{
|
||||
doomdata_t *netbuffer = DOOMCOM_DATA(doomcom);
|
||||
|
||||
if (node != servernode)
|
||||
return;
|
||||
|
||||
if ((size_t)doomcom->datalength < sizeof(netbuffer->u.serverinfoupdate))/* ignore partial sends */
|
||||
return;
|
||||
|
||||
strncpy(connectedservername, netbuffer->u.serverinfoupdate.servername, MAXSERVERNAME);
|
||||
strncpy(connectedservercontact, netbuffer->u.serverinfoupdate.servercontact, MAXSERVERCONTACT);
|
||||
strncpy(connectedserverdescription, netbuffer->u.serverinfoupdate.serverdescription, MAXSERVERDESCRIPTION);
|
||||
}
|
||||
|
||||
/** Called when a PT_NODETIMEOUT packet is received
|
||||
*
|
||||
|
|
@ -4593,7 +4643,12 @@ static void HandlePacketFromAwayNode(SINT8 node)
|
|||
G_SetGametype(netbuffer->u.servercfg.gametype);
|
||||
|
||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||
|
||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||
|
||||
strncpy(connectedservername, netbuffer->u.servercfg.server_name, MAXSERVERNAME);
|
||||
strncpy(connectedservercontact, netbuffer->u.servercfg.server_contact, MAXSERVERCONTACT);
|
||||
strncpy(connectedserverdescription, netbuffer->u.servercfg.server_description, MAXSERVERDESCRIPTION);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
|
|
@ -5136,6 +5191,9 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
case PT_LOGINCHALLENGE:
|
||||
PT_LoginChallenge(node);
|
||||
break;
|
||||
case PT_SERVERINFOUPDATE:
|
||||
PT_ServerInfoUpdate(node);
|
||||
break;
|
||||
case PT_WILLRESENDGAMESTATE:
|
||||
PT_WillResendGamestate();
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,15 @@ applications may follow different packet versions.
|
|||
// one that defines the actual packets to
|
||||
// be transmitted.
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXSERVERCONTACT 320
|
||||
#define MAXSERVERDESCRIPTION 320
|
||||
#define MAXSERVERDESCRIPTIONLINE 40
|
||||
#define DEFAULTDESCSTRING "Welcome to my SRB2Kart server!\n"
|
||||
|
||||
// Sends over info via packets to client players.
|
||||
void ServerInfoUpdateSend(void);
|
||||
|
||||
// Networking and tick handling related.
|
||||
#define BACKUPTICS 512 // more than enough for most timeouts....
|
||||
#define CLIENTBACKUPTICS 32
|
||||
|
|
@ -121,6 +130,8 @@ typedef enum
|
|||
PT_LOGINAUTH, // Challenge response from the client.
|
||||
|
||||
PT_PING, // Packet sent to tell clients the other client's latency to server.
|
||||
|
||||
PT_SERVERINFOUPDATE, // Update server info for clients.
|
||||
NUMPACKETTYPE
|
||||
} packettype_t;
|
||||
|
||||
|
|
@ -211,6 +222,10 @@ struct serverconfig_pak
|
|||
UINT8 maxplayer;
|
||||
boolean allownewplayer;
|
||||
boolean discordinvites;
|
||||
|
||||
char server_name[MAXSERVERNAME];
|
||||
char server_contact[MAXSERVERCONTACT];
|
||||
char server_description[MAXSERVERDESCRIPTION];
|
||||
} ATTRPACK;
|
||||
|
||||
struct filetx_pak
|
||||
|
|
@ -259,7 +274,6 @@ struct clientconfig_pak
|
|||
#define SV_DEDICATED 0x40 // server is dedicated
|
||||
#define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
|
||||
|
||||
#define MAXSERVERNAME 32
|
||||
#define MAXFILENEEDED 915
|
||||
#define MAX_MIRROR_LENGTH 256
|
||||
// This packet is too large
|
||||
|
|
@ -296,6 +310,13 @@ struct serverinfo_pak
|
|||
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
|
||||
} ATTRPACK;
|
||||
|
||||
struct serverinfoupdate_pak
|
||||
{
|
||||
char servername[MAXSERVERNAME];
|
||||
char servercontact[MAXSERVERCONTACT];
|
||||
char serverdescription[MAXSERVERDESCRIPTION];
|
||||
};
|
||||
|
||||
struct serverrefuse_pak
|
||||
{
|
||||
char reason[255];
|
||||
|
|
@ -365,28 +386,29 @@ struct doomdata_t
|
|||
UINT8 reserved; // Padding
|
||||
union
|
||||
{
|
||||
clientcmd_pak clientpak; // 147 bytes
|
||||
client2cmd_pak client2pak; // 206 bytes
|
||||
client3cmd_pak client3pak; // 264 bytes(?)
|
||||
client4cmd_pak client4pak; // 324 bytes(?)
|
||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
||||
serverconfig_pak servercfg; // 773 bytes
|
||||
UINT8 textcmd[MAXTEXTCMD+2]; // 66049 bytes (wut??? 64k??? More like 258 bytes...)
|
||||
char filetxpak[sizeof (filetx_pak)];// 139 bytes
|
||||
clientcmd_pak clientpak;
|
||||
client2cmd_pak client2pak;
|
||||
client3cmd_pak client3pak;
|
||||
client4cmd_pak client4pak;
|
||||
servertics_pak serverpak;
|
||||
serverconfig_pak servercfg;
|
||||
UINT8 textcmd[MAXTEXTCMD+2];
|
||||
char filetxpak[sizeof (filetx_pak)];
|
||||
char fileack[sizeof (fileack_pak)];
|
||||
UINT8 filereceived;
|
||||
clientconfig_pak clientcfg; // 136 bytes
|
||||
clientconfig_pak clientcfg;
|
||||
char salt[9];
|
||||
UINT8 sha256sum[32];
|
||||
serverinfo_pak serverinfo; // 1024 bytes
|
||||
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
|
||||
askinfo_pak askinfo; // 61 bytes
|
||||
msaskinfo_pak msaskinfo; // 22 bytes
|
||||
plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];// 576 bytes(?)
|
||||
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
|
||||
INT32 filesneedednum; // 4 bytes
|
||||
filesneededconfig_pak filesneededcfg; // ??? bytes
|
||||
netinfo_pak netinfo; // Don't believe their lies
|
||||
serverinfo_pak serverinfo;
|
||||
serverrefuse_pak serverrefuse;
|
||||
serverinfoupdate_pak serverinfoupdate;
|
||||
askinfo_pak askinfo;
|
||||
msaskinfo_pak msaskinfo;
|
||||
plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];
|
||||
plrconfig playerconfig[MAXPLAYERS];
|
||||
INT32 filesneedednum;
|
||||
filesneededconfig_pak filesneededcfg;
|
||||
netinfo_pak netinfo;
|
||||
} u; // This is needed to pack diff packet types data together
|
||||
} ATTRPACK;
|
||||
|
||||
|
|
@ -452,7 +474,9 @@ extern boolean dedicated; // For dedicated server
|
|||
extern UINT16 software_MAXPACKETLENGTH;
|
||||
extern boolean acceptnewnode;
|
||||
extern SINT8 servernode;
|
||||
extern char connectedservername[MAXSERVERNAME+1];
|
||||
extern char connectedservername[MAXSERVERNAME];
|
||||
extern char connectedservercontact[MAXSERVERCONTACT];
|
||||
extern char connectedserverdescription[MAXSERVERDESCRIPTION];
|
||||
|
||||
void Command_Ping_f(void);
|
||||
extern tic_t connectiontimeout;
|
||||
|
|
@ -548,6 +572,8 @@ void CL_UpdateServerList(void);
|
|||
// Is there a game running
|
||||
boolean Playing(void);
|
||||
|
||||
void CopyCaretColors (char *p, const char *s, int n);
|
||||
|
||||
// Broadcasts special packets to other players
|
||||
// to notify of game exit
|
||||
void D_QuitNetGame(void);
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
// SRB2Kart
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
#include "k_hud.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_random.h" // P_ClearRandom
|
||||
#include "acs/interface.h"
|
||||
|
|
@ -1213,6 +1214,10 @@ void D_StartTitle(void)
|
|||
// Reset GP
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
|
||||
// Reset Server mods
|
||||
numcustomservermods = 0;
|
||||
memset(customservermods, 0, sizeof(customservermods));
|
||||
|
||||
// Reset boss info
|
||||
K_ResetBossInfo();
|
||||
|
||||
|
|
@ -1969,8 +1974,6 @@ void D_SRB2Main(void)
|
|||
|
||||
COM_BufExecute(); // ensure the command buffer gets executed before the map starts (+skin)
|
||||
|
||||
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
|
||||
if (M_CheckParm("-gametype") && M_IsNextParm())
|
||||
{
|
||||
// from Command_Map_f
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#include "k_pwrlv.h"
|
||||
#include "y_inter.h"
|
||||
#include "k_color.h"
|
||||
#include "k_hud.h"
|
||||
#include "k_grandprix.h"
|
||||
#include "k_boss.h"
|
||||
#include "k_follower.h"
|
||||
|
|
@ -102,6 +103,8 @@ static void Got_ScheduleTaskcmd(UINT8 **cp, INT32 playernum);
|
|||
static void Got_ScheduleClearcmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_Automatecmd(UINT8 **cp, INT32 playernum);
|
||||
static void Got_Cheat(UINT8 **cp, INT32 playernum);
|
||||
static void Command_ScoreboardAdd(void);
|
||||
static void Command_ScoreboardClear(void);
|
||||
|
||||
static void PointLimit_OnChange(void);
|
||||
static void TimeLimit_OnChange(void);
|
||||
|
|
@ -817,6 +820,8 @@ void D_RegisterServerCommands(void)
|
|||
RegisterNetXCmd(XD_AUTOMATE, Got_Automatecmd);
|
||||
|
||||
RegisterNetXCmd(XD_CHEAT, Got_Cheat);
|
||||
COM_AddCommand("scoreboard_addline", Command_ScoreboardAdd);
|
||||
COM_AddCommand("scoreboard_clear", Command_ScoreboardClear);
|
||||
|
||||
// Remote Administration
|
||||
COM_AddCommand("password", Command_Changepassword_f);
|
||||
|
|
@ -3666,6 +3671,83 @@ static void Got_Clearscores(UINT8 **cp, INT32 playernum)
|
|||
CONS_Printf(M_GetText("Scores have been reset by the server.\n"));
|
||||
}
|
||||
|
||||
static void Command_ScoreboardAdd(void)
|
||||
{
|
||||
if (!server)
|
||||
{
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("addscoreboard <text>: Add text to the scoreboard\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
size_t i, j = COM_Argc();
|
||||
char message[MAXSERVERDESCRIPTIONLINE+1];
|
||||
char *finalstring;
|
||||
INT32 strlensize = 0;
|
||||
INT32 serverdesclen = 0;
|
||||
|
||||
// Steal from the motd code so you don't have to put the string in quotes.
|
||||
strlcpy(message, COM_Argv(1), sizeof message);
|
||||
for (i = 2; i < j; i++)
|
||||
{
|
||||
strlcat(message, " ", sizeof message);
|
||||
strlcat(message, COM_Argv(i), sizeof message);
|
||||
}
|
||||
|
||||
strlensize = strlen(message);
|
||||
message[strlensize+1] = '\0';
|
||||
message[MAXSERVERDESCRIPTIONLINE] = '\0';
|
||||
|
||||
finalstring = Z_Calloc(MAXSERVERDESCRIPTIONLINE*sizeof(char), PU_STATIC, NULL);
|
||||
|
||||
CopyCaretColors(finalstring, message, MAXSERVERDESCRIPTIONLINE);
|
||||
|
||||
strlensize = strlen(finalstring);
|
||||
serverdesclen = strlen(connectedserverdescription);
|
||||
|
||||
if ((strlensize+1) > MAXSERVERDESCRIPTIONLINE)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Scoreboard line is too long to add.\n"));
|
||||
Z_Free(finalstring);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((serverdesclen + strlensize) > MAXSERVERDESCRIPTION)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Scoreboard text is full so no more text can be added.\n"));
|
||||
Z_Free(finalstring);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncat(connectedserverdescription, va("%s\n", finalstring), MAXSERVERDESCRIPTIONLINE);
|
||||
CONS_Printf(M_GetText("Scoreboard text line has been added.\n"));
|
||||
}
|
||||
|
||||
ServerInfoUpdateSend();
|
||||
Z_Free(finalstring);
|
||||
}
|
||||
}
|
||||
|
||||
static void Command_ScoreboardClear(void)
|
||||
{
|
||||
if (!server)
|
||||
{
|
||||
CONS_Printf(M_GetText("Only the server can use this.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&connectedserverdescription, 0, sizeof(connectedserverdescription));
|
||||
ServerInfoUpdateSend();
|
||||
CONS_Printf(M_GetText("Scoreboard text have been reset by the server.\n"));
|
||||
}
|
||||
|
||||
// Team changing functions
|
||||
static void HandleTeamChangeCommand(UINT8 localplayer)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "k_bot.h" // bot constants (for lua)
|
||||
#include "g_input.h" // Game controls (for lua)
|
||||
#include "k_kart.h" // awardscaledrings_t
|
||||
#include "k_hud.h" // scoreboardmod_e
|
||||
#include "k_waypoint.h" // waypoint values (for lua)
|
||||
|
||||
#include "deh_tables.h"
|
||||
|
|
@ -1636,5 +1637,10 @@ struct int_const_s const INT_CONST[] = {
|
|||
// k_waypoint.h values
|
||||
{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},
|
||||
|
||||
// scoreboardmod
|
||||
{"SCOREBOARDMOD_NOTUSED", SCOREBOARDMOD_NOTUSED},
|
||||
{"SCOREBOARDMOD_INACTIVE", SCOREBOARDMOD_INACTIVE},
|
||||
{"SCOREBOARDMOD_ACTIVE", SCOREBOARDMOD_ACTIVE},
|
||||
|
||||
{NULL,0}
|
||||
};
|
||||
|
|
|
|||
29
src/g_demo.c
29
src/g_demo.c
|
|
@ -112,7 +112,7 @@ demoghost *ghosts = NULL;
|
|||
// DEMO RECORDING
|
||||
//
|
||||
|
||||
#define DEMOVERSION 0x0009
|
||||
#define DEMOVERSION 0x000A
|
||||
#define DEMOHEADER "\xF0" "BlanReplay" "\x0F"
|
||||
|
||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||
|
|
@ -244,6 +244,9 @@ typedef struct
|
|||
UINT32 raflags;
|
||||
UINT8 gametype;
|
||||
UINT8 numlaps;
|
||||
char servername[MAXSERVERNAME];
|
||||
char servercontact[MAXSERVERCONTACT];
|
||||
char serverdescription[MAXSERVERDESCRIPTION];
|
||||
|
||||
UINT8 numfiles;
|
||||
demofile_t *files;
|
||||
|
|
@ -653,6 +656,7 @@ static headerstatus_e G_ReadDemoHeader(UINT8 *dp, demoheader_t *header)
|
|||
UINT8 attack;
|
||||
boolean kart = false, oldkart = false;
|
||||
boolean raflag = true;
|
||||
boolean serverinfo = true;
|
||||
|
||||
// these may not be present in old demo formats, so initialize them
|
||||
// also initialize them so the header can be free'd without issues
|
||||
|
|
@ -662,6 +666,9 @@ static headerstatus_e G_ReadDemoHeader(UINT8 *dp, demoheader_t *header)
|
|||
header->mapmusrng = 0;
|
||||
header->numlaps = 0;
|
||||
header->raflags = 0;
|
||||
memset(header->servername, 0, MAXSERVERNAME);
|
||||
memset(header->servercontact, 0, MAXSERVERCONTACT);
|
||||
memset(header->serverdescription, 0, MAXSERVERDESCRIPTION);
|
||||
header->empty = false;
|
||||
|
||||
dp += 12;
|
||||
|
|
@ -676,6 +683,10 @@ static headerstatus_e G_ReadDemoHeader(UINT8 *dp, demoheader_t *header)
|
|||
case DEMOVERSION: // latest always supported
|
||||
break;
|
||||
|
||||
case 0x0009:
|
||||
serverinfo = false;
|
||||
break;
|
||||
|
||||
default: // too old, cannot support.
|
||||
return HEADER_BADVERSION;
|
||||
}
|
||||
|
|
@ -683,6 +694,7 @@ static headerstatus_e G_ReadDemoHeader(UINT8 *dp, demoheader_t *header)
|
|||
else if (!memcmp(startdp, "\xF0" "KartReplay" "\x0F", 12))
|
||||
{
|
||||
raflag = false;
|
||||
serverinfo = false;
|
||||
switch (header->demoversion)
|
||||
{
|
||||
case 0x0001: // SRB2Kart 1.0.x (only staff ghosts supported)
|
||||
|
|
@ -736,6 +748,13 @@ static headerstatus_e G_ReadDemoHeader(UINT8 *dp, demoheader_t *header)
|
|||
header->raflags = READUINT32(dp);
|
||||
}
|
||||
|
||||
if (serverinfo)
|
||||
{
|
||||
READSTRINGN(dp, header->servername, MAXSERVERNAME);
|
||||
READSTRINGN(dp, header->servercontact, MAXSERVERCONTACT);
|
||||
READSTRINGN(dp, header->serverdescription, MAXSERVERDESCRIPTION);
|
||||
}
|
||||
|
||||
if (oldkart)
|
||||
{
|
||||
if (header->demoflags & DF_MULTIPLAYER)
|
||||
|
|
@ -2755,6 +2774,9 @@ void G_BeginRecording(void)
|
|||
|
||||
WRITEUINT8(demobuf.p, demoflags);
|
||||
WRITEUINT32(demobuf.p, raflags);
|
||||
WRITESTRINGN(demobuf.p, connectedservername, MAXSERVERNAME);
|
||||
WRITESTRINGN(demobuf.p, connectedservercontact, MAXSERVERCONTACT);
|
||||
WRITESTRINGN(demobuf.p, connectedserverdescription, MAXSERVERDESCRIPTION);
|
||||
WRITEUINT8(demobuf.p, gametype & 0xFF);
|
||||
WRITEUINT8(demobuf.p, numlaps);
|
||||
|
||||
|
|
@ -3765,6 +3787,11 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
P_SetRandSeed(header.randseed);
|
||||
G_InitNew(demoflags & DF_ENCORE, gamemap, true, true, false); // Doesn't matter whether you reset or not here, given changes to resetplayer.
|
||||
|
||||
// Setup server name, contact and description.
|
||||
strncpy(connectedservername, header.servername, MAXSERVERNAME);
|
||||
strncpy(connectedservercontact, header.servercontact, MAXSERVERCONTACT);
|
||||
strncpy(connectedserverdescription, header.serverdescription, MAXSERVERDESCRIPTION);
|
||||
|
||||
for (pnum = 0; pnum < header.numplayers; pnum++)
|
||||
{
|
||||
// oldghost init doesn't work here, players aren't immediately spawned anymore
|
||||
|
|
|
|||
139
src/hu_stuff.c
139
src/hu_stuff.c
|
|
@ -2253,13 +2253,13 @@ void HU_Erase(void)
|
|||
static int
|
||||
Ping_gfx_num (int lag)
|
||||
{
|
||||
if (lag <= 2)
|
||||
if (lag < 2)
|
||||
return 0;
|
||||
else if (lag <= 4)
|
||||
else if (lag < 4)
|
||||
return 1;
|
||||
else if (lag <= 7)
|
||||
else if (lag < 7)
|
||||
return 2;
|
||||
else if (lag <= 10)
|
||||
else if (lag < 10)
|
||||
return 3;
|
||||
else
|
||||
return 4;
|
||||
|
|
@ -2268,46 +2268,54 @@ Ping_gfx_num (int lag)
|
|||
static int
|
||||
Ping_gfx_color (int lag)
|
||||
{
|
||||
if (lag <= 2)
|
||||
if (lag < 2)
|
||||
return SKINCOLOR_JAWZ;
|
||||
else if (lag <= 4)
|
||||
else if (lag < 4)
|
||||
return SKINCOLOR_MINT;
|
||||
else if (lag <= 7)
|
||||
else if (lag < 7)
|
||||
return SKINCOLOR_GOLD;
|
||||
else if (lag <= 10)
|
||||
else if (lag < 10)
|
||||
return SKINCOLOR_RASPBERRY;
|
||||
else
|
||||
return SKINCOLOR_MAGENTA;
|
||||
}
|
||||
|
||||
static int
|
||||
PL_gfx_color (int pl)
|
||||
PL_gfx_color (int pl, boolean mode)
|
||||
{
|
||||
if (pl <= 2)
|
||||
return 72;
|
||||
else if (pl <= 4)
|
||||
return 54;
|
||||
else if (pl <= 6)
|
||||
return 35;
|
||||
if (mode)
|
||||
{
|
||||
if (pl < 2)
|
||||
return SKINCOLOR_GOLD;
|
||||
else if (pl < 4)
|
||||
return SKINCOLOR_ORANGE;
|
||||
else if (pl < 6)
|
||||
return SKINCOLOR_CRIMSON;
|
||||
else
|
||||
return SKINCOLOR_MAGENTA;
|
||||
}
|
||||
else
|
||||
return 181;
|
||||
{
|
||||
if (pl < 2)
|
||||
return 72;
|
||||
else if (pl < 4)
|
||||
return 54;
|
||||
else if (pl < 6)
|
||||
return 35;
|
||||
else
|
||||
return 181;
|
||||
}
|
||||
}
|
||||
|
||||
static const UINT8 *
|
||||
Ping_gfx_colormap (UINT32 ping, boolean gentleman)
|
||||
Ping_gfx_colormap (UINT32 ping, UINT32 lag)
|
||||
{
|
||||
const UINT8 *colormap = NULL;
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(ping), GTC_CACHE);
|
||||
const UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, Ping_gfx_color(lag), GTC_CACHE);
|
||||
|
||||
if (servermaxping && ping > servermaxping && hu_tick < 4)
|
||||
{
|
||||
// flash ping red if too high
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
|
||||
}
|
||||
else if (gentleman)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PASTEL, GTC_CACHE);
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE);
|
||||
}
|
||||
|
||||
return colormap;
|
||||
|
|
@ -2327,34 +2335,42 @@ Ping_conversion (UINT32 lag)
|
|||
//
|
||||
// HU_drawPing
|
||||
//
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, UINT32 mindelay, UINT32 pl, INT32 flags)
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, UINT32 mindelay, UINT32 pl, INT32 flags, boolean icon)
|
||||
{
|
||||
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
|
||||
INT32 gfxnum; // gfx to draw
|
||||
UINT32 lag = max(ping, mindelay);
|
||||
UINT8 *colormap = NULL;
|
||||
|
||||
gfxnum = Ping_gfx_num(ping);
|
||||
|
||||
if (pl)
|
||||
{
|
||||
V_DrawFill(
|
||||
-pinggfx[gfxnum]->leftoffset + x + 2 - 1,
|
||||
-pinggfx[gfxnum]->topoffset + y - 1,
|
||||
pinggfx[gfxnum]->width + 2,
|
||||
pinggfx[gfxnum]->height + 2,
|
||||
PL_gfx_color(pl) | flags
|
||||
);
|
||||
if (icon)
|
||||
{
|
||||
V_DrawFill(
|
||||
-pinggfx[gfxnum]->leftoffset + x + 2 - 1,
|
||||
-pinggfx[gfxnum]->topoffset + y - 1,
|
||||
pinggfx[gfxnum]->width + 2,
|
||||
pinggfx[gfxnum]->height + 2,
|
||||
PL_gfx_color(pl, false) | flags
|
||||
);
|
||||
}
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, PL_gfx_color(pl, true), GTC_CACHE);
|
||||
}
|
||||
|
||||
if (measureid == 1)
|
||||
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+11, flags, pingmeasure[measureid]);
|
||||
V_DrawMappedPatch(x+11 - pingmeasure[measureid]->width, y+11, flags, pingmeasure[measureid], colormap);
|
||||
|
||||
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
|
||||
if (icon)
|
||||
{
|
||||
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
|
||||
}
|
||||
|
||||
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+11, flags, Ping_conversion(lag), Ping_gfx_colormap(ping, ping <= lag));
|
||||
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+11, flags, Ping_conversion(lag), Ping_gfx_colormap(ping, lag));
|
||||
|
||||
if (measureid == 0)
|
||||
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+11, flags, pingmeasure[measureid]);
|
||||
V_DrawMappedPatch(x+1 - pingmeasure[measureid]->width, y+11, flags, pingmeasure[measureid], colormap);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2472,11 +2488,26 @@ static void HU_DrawRankings(void)
|
|||
hilicol = V_YELLOWMAP;
|
||||
}
|
||||
|
||||
// draw the current gametype in the lower right
|
||||
if (modeattacking)
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "Record Attack");
|
||||
if (!demo.playback)
|
||||
{
|
||||
// draw the current map in the lower left
|
||||
char *maptitle = G_BuildMapTitle(gamemap);
|
||||
|
||||
if (maptitle)
|
||||
{
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, maptitle);
|
||||
Z_Free(maptitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "UNKNOWN");
|
||||
}
|
||||
}
|
||||
else
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
|
||||
{
|
||||
// draw the current gametype in the lower left
|
||||
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, (modeattacking) ? "Record Attack" : gametype_cons_t[gametype].strvalue);
|
||||
}
|
||||
|
||||
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
|
||||
{
|
||||
|
|
@ -2532,7 +2563,7 @@ static void HU_DrawRankings(void)
|
|||
{
|
||||
tab[i].num = -1;
|
||||
tab[i].name = NULL;
|
||||
tab[i].count = INT32_MAX;
|
||||
tab[i].string[0] = '\0';
|
||||
|
||||
if (!playeringame[i] || players[i].spectator || !players[i].mo)
|
||||
continue;
|
||||
|
|
@ -2563,13 +2594,19 @@ static void HU_DrawRankings(void)
|
|||
|
||||
if ((gametyperules & GTR_CIRCUIT))
|
||||
{
|
||||
if (circuitmap)
|
||||
tab[scorelines].count = players[i].laps;
|
||||
if (!players[i].exiting)
|
||||
sprintf(tab[scorelines].string, "Lap %d", players[i].laps);
|
||||
else
|
||||
tab[scorelines].count = players[i].realtime;
|
||||
{
|
||||
INT32 min = G_TicsToMinutes(players[i].realtime, true);
|
||||
INT32 sec = G_TicsToSeconds(players[i].realtime);
|
||||
INT32 cen = G_TicsToCentiseconds(players[i].realtime);
|
||||
|
||||
sprintf(tab[scorelines].string, "%i'%02i\"%02i", min, sec, cen);
|
||||
}
|
||||
}
|
||||
else
|
||||
tab[scorelines].count = players[i].roundscore;
|
||||
sprintf(tab[scorelines].string, "%d", players[i].roundscore);
|
||||
|
||||
scorelines++;
|
||||
|
||||
|
|
@ -2579,7 +2616,15 @@ static void HU_DrawRankings(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
K_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, whiteplayer, hilicol);
|
||||
if (cv_newtabranking.value)
|
||||
{
|
||||
INT32 xoffset = K_DrawNeoTabRankings(0, 33, tab, scorelines, whiteplayer, hilicol, true);
|
||||
K_DrawServerDescrption(xoffset+10, 33);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_DrawTabRankings(((scorelines > 8) ? 32 : 40), 33, tab, scorelines, whiteplayer, hilicol);
|
||||
}
|
||||
|
||||
// draw spectators in a ticker across the bottom
|
||||
if (netgame && G_GametypeHasSpectators())
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ extern char english_shiftxform[];
|
|||
|
||||
struct playersort_t
|
||||
{
|
||||
UINT32 count;
|
||||
char string[48];
|
||||
INT32 num;
|
||||
const char *name;
|
||||
};
|
||||
|
|
@ -133,7 +133,7 @@ void HU_Drawer(void);
|
|||
char HU_dequeueChatChar(void);
|
||||
void HU_Erase(void);
|
||||
void HU_clearChatChars(void);
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, UINT32 mindelay, UINT32 pl, INT32 flags);
|
||||
void HU_drawPing(INT32 x, INT32 y, UINT32 ping, UINT32 mindelay, UINT32 pl, INT32 flags, boolean icon);
|
||||
void HU_drawMiniPing (INT32 x, INT32 y, UINT32 ping, UINT32 lag, INT32 flags);
|
||||
|
||||
INT32 HU_CreateTeamScoresTbl(playersort_t *tab, UINT32 dmtotals[]);
|
||||
|
|
|
|||
315
src/k_hud.c
315
src/k_hud.c
|
|
@ -100,6 +100,8 @@ consvar_t cv_driftgaugeoffset = CVAR_INIT ("kartdriftgaugeoffset", "-10", CV_SAV
|
|||
static CV_PossibleValue_t HudColor_cons_t[MAXSKINCOLORS+1];
|
||||
consvar_t cv_colorizedhudcolor = CVAR_INIT ("colorizedhudcolor", "Skin Color", CV_SAVE, HudColor_cons_t, NULL);
|
||||
|
||||
consvar_t cv_newtabranking = CVAR_INIT ("newtabranking", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
//{ Patch Definitions
|
||||
static patch_t *kp_nodraw;
|
||||
|
||||
|
|
@ -254,6 +256,7 @@ void K_RegisterKartHUDStuff(void)
|
|||
CV_RegisterVar(&cv_smoothposition);
|
||||
CV_RegisterVar(&cv_driftgauge);
|
||||
CV_RegisterVar(&cv_driftgaugeoffset);
|
||||
CV_RegisterVar(&cv_newtabranking);
|
||||
}
|
||||
|
||||
void K_LoadKartHUDGraphics(void)
|
||||
|
|
@ -2109,18 +2112,248 @@ static void K_drawBossHealthBar(void)
|
|||
}
|
||||
|
||||
//
|
||||
// HU_DrawTabRankings -- moved here to take advantage of kart stuff!
|
||||
// K_DrawNeoTabRankings -- A new way to view ingame info!
|
||||
// returns starting x of right offset for drawing your own info in there!
|
||||
//
|
||||
INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol, boolean split)
|
||||
{
|
||||
INT32 i, rightoffset = split ? 160 - 6: BASEVIDWIDTH - 6;
|
||||
const UINT8 *colormap = NULL;
|
||||
UINT16 hightlightcolor = 0;
|
||||
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
|
||||
INT32 basey = y, basex = x, y2, x2;
|
||||
|
||||
scorelines--;
|
||||
|
||||
x += 4;
|
||||
y += 9*scorelines;
|
||||
|
||||
V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
|
||||
|
||||
if (split)
|
||||
{
|
||||
V_DrawFill(x + rightoffset + 6, 26, 1, 162, 0); // Draw a vertical line because it looks nice!
|
||||
}
|
||||
|
||||
for (i = scorelines; i >= 0; i--)
|
||||
{
|
||||
INT32 pos = CLAMP(players[tab[i].num].position, 0 , MAXPLAYERS);
|
||||
char playername[MAXPLAYERNAME+1];
|
||||
|
||||
if (players[tab[i].num].spectator || !players[tab[i].num].mo)
|
||||
continue; //ignore them.
|
||||
|
||||
if (netgame) // don't draw ping offline
|
||||
{
|
||||
if (players[tab[i].num].bot)
|
||||
{
|
||||
V_DrawThinString(x - 18 + 25, y, 0, "CPU");
|
||||
}
|
||||
else if (tab[i].num != serverplayer || !server_lagless)
|
||||
{
|
||||
INT32 xoff = cv_pingmeasurement.value == 1 ? 33 : 26;
|
||||
|
||||
HU_drawPing(x - 18 + xoff , y-10, playerpingtable[tab[i].num], playerdelaytable[tab[i].num], playerpacketlosstable[tab[i].num], 0, false);
|
||||
}
|
||||
else if (tab[i].num == serverplayer)
|
||||
{
|
||||
V_DrawThinString(x - 18 + 25, y, 0, "SRV");
|
||||
}
|
||||
}
|
||||
|
||||
STRBUFCPY(playername, tab[i].name);
|
||||
|
||||
if (players[tab[i].num].mo->color)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
if (players[tab[i].num].mo->colorized)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
else
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
|
||||
hightlightcolor = skincolors[players[tab[i].num].mo->color].chatcolor;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(x-5, y+1, 0, kp_facenum[pos]);
|
||||
|
||||
x2 = netgame ? x + (BASEVIDWIDTH/20) : x;
|
||||
y2 = y;
|
||||
|
||||
V_DrawThinString(x2 + 20, y2, ((tab[i].num == whiteplayer) ? hightlightcolor : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, playername);
|
||||
|
||||
V_DrawFixedPatch((x2+11)*FRACUNIT, (y+1)*FRACUNIT, FRACUNIT/2, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
|
||||
|
||||
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
|
||||
{
|
||||
INT32 bumperx = x+19;
|
||||
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
|
||||
for (j = 1; j < players[tab[i].num].bumper; j++)
|
||||
{
|
||||
bumperx += 5;
|
||||
V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (tab[i].num == whiteplayer)
|
||||
V_DrawFixedPatch((x2+11)*FRACUNIT, (y+1)*FRACUNIT, FRACUNIT/2, 0, kp_facehighlight[(leveltime / 4) % 8], NULL);
|
||||
|
||||
if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumper <= 0)
|
||||
V_DrawScaledPatch(x2-4, y-7, 0, kp_ranknobumpers);
|
||||
|
||||
if (tab[i].string[0] != '\0')
|
||||
V_DrawRightAlignedThinString(x+rightoffset+2, y, V_6WIDTHSPACE, tab[i].string);
|
||||
|
||||
y -= 9;
|
||||
}
|
||||
return x+rightoffset;
|
||||
}
|
||||
|
||||
servermods_t customservermods[MAXSERVERMODS];
|
||||
UINT8 numcustomservermods = 0;
|
||||
|
||||
// Adds a new mod to the scoreboard display.
|
||||
void K_AddNewScoreboardMod(const char *name, const consvar_t *cvar, SINT8 active)
|
||||
{
|
||||
UINT32 hashcompare = HASH32(name, MAXSERVERMODNAME);
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXSERVERMODS; i++)
|
||||
{
|
||||
if (customservermods[i].hash == hashcompare)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Scoreboard mod '%s' has already been added to the scoreboard.\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (numcustomservermods+1 == MAXSERVERMODS)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Maximum Amount of scoreboard mods has been reached.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(customservermods[numcustomservermods].modname, name, MAXSERVERMODNAME);
|
||||
customservermods[numcustomservermods].hash = hashcompare;
|
||||
customservermods[numcustomservermods].cvar = cvar;
|
||||
customservermods[numcustomservermods].active = CLAMP(active, SCOREBOARDMOD_NOTUSED, SCOREBOARDMOD_ACTIVE);
|
||||
customservermods[numcustomservermods].valid = true;
|
||||
numcustomservermods++;
|
||||
}
|
||||
|
||||
// Change the status of static scoreboard displays.
|
||||
void K_SetScoreboardModStatus(const char *name, SINT8 active)
|
||||
{
|
||||
UINT32 hashcompare = HASH32(name, MAXSERVERMODNAME);
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXSERVERMODS; i++)
|
||||
{
|
||||
if (customservermods[i].hash == hashcompare)
|
||||
{
|
||||
customservermods[i].active = CLAMP(active, SCOREBOARDMOD_NOTUSED, SCOREBOARDMOD_ACTIVE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CONS_Alert(CONS_WARNING, "Server mod '%s' does not exist so status cannot be changed.\n", name);
|
||||
}
|
||||
|
||||
#define BASEMODS 11
|
||||
void K_DrawServerMods(INT32 x, INT32 y)
|
||||
{
|
||||
UINT8 i, j;
|
||||
INT32 xoff = 0, yoff = 10;
|
||||
UINT8 numdrawn = 0;
|
||||
|
||||
servermods_t basemods[BASEMODS] =
|
||||
{
|
||||
{"Rings", 0, NULL, K_RingsActive() > 0, true},
|
||||
{"4-Tier Drifts", 0, NULL, K_PurpleDriftActive() > 0, true},
|
||||
{"Slipdash", 0, NULL, K_SlipdashActive() > 0, true},
|
||||
{"Stacking", 0, NULL, K_StackingActive() > 0, true},
|
||||
{"Chaining", 0, NULL, K_ChainingActive() > 0, true},
|
||||
{"Chain Offroad", 0, &cv_kartchainingoffroad, -1, true},
|
||||
{"Slope Boost", 0, NULL, K_PurpleDriftActive() > 0, true},
|
||||
{"Drafting", 0, NULL, K_PurpleDriftActive() > 0, true},
|
||||
{"Bump Spark", 0, &cv_kartbumpspark, -1, true},
|
||||
{"Bump Spring", 0, &cv_kartbumpspring, -1, true},
|
||||
{"Alt. Invin.", 0, NULL, K_GetKartInvinType() == KARTINVIN_ALTERN, true}
|
||||
};
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
UINT8 modcount = j == 0 ? BASEMODS : numcustomservermods;
|
||||
servermods_t *modslist = j == 0 ? basemods : customservermods;
|
||||
|
||||
// Draw the the modlist.
|
||||
for (i = 0; i < modcount; i++)
|
||||
{
|
||||
boolean drawdis = false;
|
||||
|
||||
if (modslist[i].valid)
|
||||
{
|
||||
if (modslist[i].cvar && modslist[i].cvar->value)
|
||||
{
|
||||
drawdis = true;
|
||||
}
|
||||
else if (modslist[i].active == SCOREBOARDMOD_ACTIVE)
|
||||
{
|
||||
drawdis = true;
|
||||
}
|
||||
|
||||
if (drawdis && modslist[i].modname[0] != '\0')
|
||||
{
|
||||
V_DrawSmallString(x+xoff, y+yoff, V_6WIDTHSPACE|V_ALLOWLOWERCASE, modslist[i].modname);
|
||||
numdrawn++;
|
||||
|
||||
if ((numdrawn % 2) == 0)
|
||||
{
|
||||
xoff -= 50;
|
||||
yoff += 5;
|
||||
}
|
||||
else if ((numdrawn % 1) == 0)
|
||||
{
|
||||
xoff += 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numdrawn > 0)
|
||||
V_DrawThinString(x, y, V_6WIDTHSPACE|V_ALLOWLOWERCASE|V_GRAYMAP, "Gameplay / Balance Changes:");
|
||||
|
||||
}
|
||||
#undef BASEMODS
|
||||
|
||||
void K_DrawServerDescrption(INT32 x, INT32 y)
|
||||
{
|
||||
UINT8 i, newlinecount = 0;
|
||||
if (connectedservername[0] != '\0')
|
||||
V_DrawThinString(x, y, V_6WIDTHSPACE|V_ALLOWLOWERCASE, connectedservername);
|
||||
|
||||
V_DrawSmallString(x, y+10, V_6WIDTHSPACE|V_ALLOWLOWERCASE|V_GRAYMAP, va("Contact: %s", (connectedservercontact[0] != '\0') ? connectedservercontact : ""));
|
||||
|
||||
if (connectedserverdescription[0] != '\0')
|
||||
{
|
||||
V_DrawSmallString(x, y+20, V_6WIDTHSPACE|V_ALLOWLOWERCASE, connectedserverdescription);
|
||||
|
||||
for (i = 0; connectedserverdescription[i]; i++)
|
||||
newlinecount += (connectedserverdescription[i] == '\n');
|
||||
}
|
||||
|
||||
K_DrawServerMods(x, y + 25 + newlinecount*6);
|
||||
}
|
||||
|
||||
// The old school one....
|
||||
void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol)
|
||||
{
|
||||
INT32 i, rightoffset = 240;
|
||||
const UINT8 *colormap;
|
||||
UINT8 *colormap = NULL;
|
||||
UINT16 hightlightcolor = 0;
|
||||
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
|
||||
int basey = y, basex = x, y2;
|
||||
|
||||
//this function is designed for 9 or less score lines only
|
||||
//I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up
|
||||
|
||||
V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
|
||||
|
||||
scorelines--;
|
||||
|
|
@ -2139,7 +2372,7 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
|
||||
for (i = scorelines; i >= 0; i--)
|
||||
{
|
||||
char strtime[MAXPLAYERNAME+1];
|
||||
char playername[MAXPLAYERNAME+1];
|
||||
|
||||
if (players[tab[i].num].spectator || !players[tab[i].num].mo)
|
||||
continue; //ignore them.
|
||||
|
|
@ -2152,19 +2385,18 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
}
|
||||
else if (tab[i].num != serverplayer || !server_lagless)
|
||||
{
|
||||
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], playerdelaytable[tab[i].num], playerpacketlosstable[tab[i].num], 0);
|
||||
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], playerdelaytable[tab[i].num], playerpacketlosstable[tab[i].num], 0, true);
|
||||
}
|
||||
else if (tab[i].num == serverplayer)
|
||||
{
|
||||
V_DrawString(x + ((i < 8) ? -25 : rightoffset + 3), y-2, V_SNAPTOLEFT, "SRV");
|
||||
}
|
||||
}
|
||||
|
||||
STRBUFCPY(strtime, tab[i].name);
|
||||
STRBUFCPY(playername, tab[i].name);
|
||||
|
||||
y2 = y;
|
||||
|
||||
if (scorelines >= 8)
|
||||
V_DrawThinString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime);
|
||||
else
|
||||
V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime);
|
||||
|
||||
if (players[tab[i].num].mo->color)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
|
|
@ -2173,19 +2405,27 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
else
|
||||
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
|
||||
|
||||
V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
|
||||
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
|
||||
{
|
||||
INT32 bumperx = x+19;
|
||||
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
|
||||
for (j = 1; j < players[tab[i].num].bumper; j++)
|
||||
{
|
||||
bumperx += 5;
|
||||
V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap);
|
||||
}
|
||||
}*/
|
||||
hightlightcolor = skincolors[players[tab[i].num].mo->color].chatcolor;
|
||||
}
|
||||
|
||||
if (scorelines >= 8)
|
||||
V_DrawThinString(x + 20, y2, ((tab[i].num == whiteplayer) ? hightlightcolor : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, playername);
|
||||
else
|
||||
V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hightlightcolor : 0)|V_ALLOWLOWERCASE, playername);
|
||||
|
||||
V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
|
||||
|
||||
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
|
||||
{
|
||||
INT32 bumperx = x+19;
|
||||
V_DrawMappedPatch(bumperx-2, y-4, 0, kp_tinybumper[0], colormap);
|
||||
for (j = 1; j < players[tab[i].num].bumper; j++)
|
||||
{
|
||||
bumperx += 5;
|
||||
V_DrawMappedPatch(bumperx, y-4, 0, kp_tinybumper[1], colormap);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (tab[i].num == whiteplayer)
|
||||
V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]);
|
||||
|
||||
|
|
@ -2200,31 +2440,8 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
|
|||
V_DrawScaledPatch(x-5, y+6, 0, kp_facenum[pos]);
|
||||
}
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
{
|
||||
#define timestring(time) va("%i'%02i\"%02i", G_TicsToMinutes(time, true), G_TicsToSeconds(time), G_TicsToCentiseconds(time))
|
||||
if (scorelines >= 8)
|
||||
{
|
||||
if (players[tab[i].num].exiting)
|
||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, hilicol|V_6WIDTHSPACE, timestring(players[tab[i].num].realtime));
|
||||
else if (players[tab[i].num].pflags & PF_NOCONTEST)
|
||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, "NO CONTEST.");
|
||||
else if (circuitmap)
|
||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, va("Lap %d", tab[i].count));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[tab[i].num].exiting)
|
||||
V_DrawRightAlignedString(x+rightoffset, y, hilicol, timestring(players[tab[i].num].realtime));
|
||||
else if (players[tab[i].num].pflags & PF_NOCONTEST)
|
||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, 0, "NO CONTEST.");
|
||||
else if (circuitmap)
|
||||
V_DrawRightAlignedString(x+rightoffset, y, 0, va("Lap %d", tab[i].count));
|
||||
}
|
||||
#undef timestring
|
||||
}
|
||||
else
|
||||
V_DrawRightAlignedString(x+rightoffset, y, 0, va("%u", tab[i].count));
|
||||
if (tab[i].string[0] != '\0')
|
||||
V_DrawRightAlignedThinString(x+rightoffset, y-1, V_6WIDTHSPACE, tab[i].string);
|
||||
|
||||
y -= 18;
|
||||
if (i == 8)
|
||||
|
|
|
|||
30
src/k_hud.h
30
src/k_hud.h
|
|
@ -62,6 +62,8 @@ extern consvar_t cv_colorizeditembox;
|
|||
extern consvar_t cv_darkitembox;
|
||||
extern consvar_t cv_colorizedhudcolor;
|
||||
|
||||
extern consvar_t cv_newtabranking;
|
||||
|
||||
struct trackingResult_t
|
||||
{
|
||||
fixed_t x, y;
|
||||
|
|
@ -97,7 +99,35 @@ void K_LoadKartHUDGraphics(void);
|
|||
void K_drawKartHUD(void);
|
||||
void K_drawKartFreePlay(void);
|
||||
void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UINT8 mode);
|
||||
INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol, boolean split);
|
||||
void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol);
|
||||
|
||||
#define MAXSERVERMODS 255
|
||||
#define MAXSERVERMODNAME 13
|
||||
|
||||
struct servermods_t
|
||||
{
|
||||
char modname[MAXSERVERMODNAME];
|
||||
UINT32 hash;
|
||||
const consvar_t *cvar;
|
||||
SINT8 active; // -1 is N/A (example: if using cvar activation), 0 is off, 1 is on.
|
||||
boolean valid;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCOREBOARDMOD_NOTUSED = -1,
|
||||
SCOREBOARDMOD_INACTIVE,
|
||||
SCOREBOARDMOD_ACTIVE,
|
||||
} scoreboardmod_e;
|
||||
|
||||
extern servermods_t customservermods[MAXSERVERMODS];
|
||||
extern UINT8 numcustomservermods;
|
||||
void K_AddNewScoreboardMod(const char *name, const consvar_t *cvar, SINT8 active);
|
||||
void K_SetScoreboardModStatus(const char *name, SINT8 active);
|
||||
|
||||
void K_DrawServerDescrption(INT32 x, INT32 y);
|
||||
|
||||
void K_DrawDriftGauge(void);
|
||||
void K_ResetAfterImageValues(void);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -4349,6 +4349,29 @@ static int lib_kAwardScaledPlayerRings(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kAddNewScoreboardMod(lua_State *L)
|
||||
{
|
||||
const char *modname = luaL_checkstring(L, 1);
|
||||
const char *cvarname = lua_isnil(L, 2) ? NULL : luaL_checkstring(L, 2);
|
||||
const consvar_t *cvar = lua_isnil(L, 2) ? NULL : CV_FindVar(cvarname);
|
||||
SINT8 active = SCOREBOARDMOD_NOTUSED;
|
||||
|
||||
if (!cvarname || !cvar)
|
||||
active = SCOREBOARDMOD_ACTIVE;
|
||||
|
||||
K_AddNewScoreboardMod(modname, cvar, active);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kSetScoreboardModStatus(lua_State *L)
|
||||
{
|
||||
const char *modname = luaL_checkstring(L, 1);
|
||||
SINT8 active = CLAMP(luaL_checkinteger(L, 2), SCOREBOARDMOD_NOTUSED, SCOREBOARDMOD_ACTIVE);
|
||||
|
||||
K_SetScoreboardModStatus(modname, active);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kPlayerUsesBotMovement(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
|
|
@ -5257,6 +5280,10 @@ static luaL_Reg lib[] = {
|
|||
{"K_AwardPlayerRings", lib_kAwardPlayerRings},
|
||||
{"K_AwardScaledPlayerRings", lib_kAwardScaledPlayerRings},
|
||||
|
||||
// k_hud
|
||||
{"K_AddNewScoreboardMod", lib_kAddNewScoreboardMod},
|
||||
{"K_SetScoreboardModStatus", lib_kSetScoreboardModStatus},
|
||||
|
||||
// k_waypoint
|
||||
{"K_NextRespawnWaypointIndex", lib_kNextRespawnWaypointIndex},
|
||||
{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
|
||||
|
|
|
|||
|
|
@ -6429,8 +6429,6 @@ INT32 MR_StartServer(INT32 choice)
|
|||
|
||||
multiplayer = true;
|
||||
|
||||
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
|
||||
// Still need to reset devmode
|
||||
cht_debug = 0;
|
||||
|
||||
|
|
|
|||
11
src/mserv.c
11
src/mserv.c
|
|
@ -22,6 +22,8 @@
|
|||
#include "mserv.h"
|
||||
#include "m_menu.h"
|
||||
#include "z_zone.h"
|
||||
#include "byteptr.h"
|
||||
#include "i_net.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
|
|
@ -503,6 +505,15 @@ Update_parameters (void)
|
|||
UpdateServer();
|
||||
}
|
||||
#endif/*MASTERSERVER*/
|
||||
|
||||
// Lets update Clients on this info.
|
||||
if (Playing() && server)
|
||||
{
|
||||
CopyCaretColors(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
CopyCaretColors(connectedservercontact, cv_server_contact.string, MAXSERVERCONTACT);
|
||||
|
||||
ServerInfoUpdateSend();
|
||||
}
|
||||
}
|
||||
|
||||
static void MasterServer_OnChange(void)
|
||||
|
|
|
|||
|
|
@ -603,7 +603,7 @@ void SCR_DisplayLocalPing(void)
|
|||
if (( cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping) )) // only show 2 (warning) if our ping is at a bad level
|
||||
{
|
||||
INT32 dispy = cv_ticrate.value ? 160 : 181;
|
||||
HU_drawPing(307, dispy, ping, mindelay, pl, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS);
|
||||
HU_drawPing(307, dispy, ping, mindelay, pl, V_SNAPTORIGHT | V_SNAPTOBOTTOM, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ TYPEDEF (fileack_pak);
|
|||
TYPEDEF (clientconfig_pak);
|
||||
TYPEDEF (serverinfo_pak);
|
||||
TYPEDEF (serverrefuse_pak);
|
||||
TYPEDEF (serverinfoupdate_pak);
|
||||
TYPEDEF (askinfo_pak);
|
||||
TYPEDEF (msaskinfo_pak);
|
||||
TYPEDEF (plrinfo);
|
||||
|
|
@ -176,6 +177,7 @@ TYPEDEF (followercategory_t);
|
|||
|
||||
// k_hud.h
|
||||
TYPEDEF (trackingResult_t);
|
||||
TYPEDEF (servermods_t);
|
||||
|
||||
// k_menu.h
|
||||
TYPEDEF (menucolor_t);
|
||||
|
|
|
|||
Loading…
Reference in a new issue