mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 22:51:57 +00:00
Added bugs relating to scr_scoreboard_* cvars, broken indepphysics, and generally screwed up
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2547 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
3ca64edd06
commit
5fc1d3fdea
8 changed files with 484 additions and 141 deletions
|
@ -1016,6 +1016,10 @@ unsigned long _stdcall CL_IndepPhysicsThread(void *param)
|
|||
spare = CL_FilterTime((time - lasttime)*1000, cl_netfps.value);
|
||||
if (spare)
|
||||
{
|
||||
//don't let them bank too much and get sudden bursts
|
||||
if (spare > 15)
|
||||
spare = 15;
|
||||
|
||||
time -= spare/1000.0f;
|
||||
EnterCriticalSection(&indepcriticialsection);
|
||||
if (cls.state)
|
||||
|
@ -1073,6 +1077,99 @@ void CL_UseIndepPhysics(qboolean allow)
|
|||
runningindepphys = false;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_mutex_t indepcriticalsection;
|
||||
pthread_t indepphysicsthread;
|
||||
|
||||
void CL_AllowIndependantSendCmd(qboolean allow)
|
||||
{
|
||||
if (!runningindepphys)
|
||||
return;
|
||||
|
||||
if (allowindepphys != allow && runningindepphys)
|
||||
{
|
||||
if (allow)
|
||||
pthread_mutex_unlock(&indepcriticalsection);
|
||||
else
|
||||
pthread_mutex_lock(&indepcriticalsection);
|
||||
allowindepphys = allow;
|
||||
}
|
||||
}
|
||||
|
||||
void *CL_IndepPhysicsThread(void *param)
|
||||
{
|
||||
int sleeptime;
|
||||
double fps;
|
||||
double time, lasttime;
|
||||
double spare;
|
||||
lasttime = Sys_DoubleTime();
|
||||
while(runningindepphys)
|
||||
{
|
||||
time = Sys_DoubleTime();
|
||||
spare = CL_FilterTime((time - lasttime)*1000, cl_netfps.value);
|
||||
if (spare)
|
||||
{
|
||||
//don't let them bank too much and get sudden bursts
|
||||
if (spare > 15)
|
||||
spare = 15;
|
||||
|
||||
time -= spare/1000.0f;
|
||||
pthread_mutex_lock(&indepcriticalsection);
|
||||
if (cls.state)
|
||||
CL_SendCmd(time - lasttime);
|
||||
lasttime = time;
|
||||
pthread_mutex_unlock(&indepcriticalsection);
|
||||
}
|
||||
|
||||
fps = cl_netfps.value;
|
||||
if (fps < 4)
|
||||
fps = 4;
|
||||
while (fps < 100)
|
||||
fps*=2;
|
||||
|
||||
sleeptime = (1000*1000)/fps;
|
||||
|
||||
if (sleeptime)
|
||||
usleep(sleeptime);
|
||||
else
|
||||
usleep(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CL_UseIndepPhysics(qboolean allow)
|
||||
{
|
||||
if (runningindepphys == allow)
|
||||
return;
|
||||
|
||||
if (allow)
|
||||
{ //enable it
|
||||
pthread_mutex_init(&indepcriticalsection, NULL);
|
||||
runningindepphys = true;
|
||||
|
||||
pthread_create(&indepphysicsthread, NULL, CL_IndepPhysicsThread, NULL);
|
||||
allowindepphys = 1;
|
||||
|
||||
//now this would be awesome, but would require root permissions... which is plain wrong!
|
||||
//however, lack of this line means its really duel-core only.
|
||||
//pthread_setschedparam(indepthread, SCHED_*, ?);
|
||||
//is there anything to weight the thread up a bit against the main thread? (considering that most of the time we'll be idling)
|
||||
}
|
||||
else
|
||||
{
|
||||
//shut it down.
|
||||
runningindepphys = false; //tell thread to exit gracefully
|
||||
|
||||
pthread_mutex_lock(&indepcriticalsection);
|
||||
pthread_join(indepphysicsthread, 0);
|
||||
pthread_mutex_unlock(&indepcriticalsection);
|
||||
pthread_mutex_destroy(&indepcriticalsection);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void CL_AllowIndependantSendCmd(qboolean allow)
|
||||
{
|
||||
|
|
|
@ -2390,8 +2390,8 @@ void CLQ2_ParseClientinfo(int i, char *s)
|
|||
Info_SetValueForKey(player->userinfo, "name", name, MAX_INFO_STRING);
|
||||
|
||||
cl.players[i].userid = i;
|
||||
cl.players[i].bottomcolor = 1;
|
||||
cl.players[i].topcolor = 1;
|
||||
cl.players[i].rbottomcolor = 1;
|
||||
cl.players[i].rtopcolor = 1;
|
||||
CL_ProcessUserInfo (i, player);
|
||||
}
|
||||
|
||||
|
@ -2915,12 +2915,8 @@ CL_NewTranslation
|
|||
*/
|
||||
void CL_NewTranslation (int slot)
|
||||
{
|
||||
#ifdef SWQUAKE
|
||||
//int i, j; //unreferenced
|
||||
int top, bottom;
|
||||
//qbyte *dest, *source; //unreferenced
|
||||
int local;
|
||||
#endif
|
||||
|
||||
char *s;
|
||||
player_info_t *player;
|
||||
|
@ -2936,58 +2932,56 @@ void CL_NewTranslation (int slot)
|
|||
player->skin = NULL;
|
||||
|
||||
|
||||
#ifdef RGLQUAKE
|
||||
if (qrenderer == QR_OPENGL)
|
||||
{ //gl doesn't need to do anything except prevent the sys_error below.
|
||||
return;
|
||||
|
||||
top = player->rtopcolor;
|
||||
bottom = player->rbottomcolor;
|
||||
if (cl.splitclients < 2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
|
||||
{
|
||||
if (cl.teamplay && cl.spectator)
|
||||
{
|
||||
local = Cam_TrackNum(0);
|
||||
if (local < 0)
|
||||
local = cl.playernum[0];
|
||||
}
|
||||
else
|
||||
local = cl.playernum[0];
|
||||
if (cl.teamplay && !strcmp(player->team, cl.players[local].team))
|
||||
{
|
||||
if (cl_teamtopcolor>=0)
|
||||
top = cl_teamtopcolor;
|
||||
if (cl_teambottomcolor>=0)
|
||||
bottom = cl_teambottomcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cl_enemytopcolor>=0)
|
||||
top = cl_enemytopcolor;
|
||||
if (cl_enemybottomcolor>=0)
|
||||
bottom = cl_enemybottomcolor;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (top > 13 || top < 0)
|
||||
top = 13;
|
||||
if (bottom > 13 || bottom < 0)
|
||||
bottom = 13;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
top = player->topcolor;
|
||||
bottom = player->bottomcolor;
|
||||
if (!cl.splitclients && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
|
||||
if (player->ttopcolor != top || player->tbottomcolor != bottom || !player->skin)
|
||||
{
|
||||
if (cl.teamplay && cl.spectator)
|
||||
{
|
||||
local = Cam_TrackNum(0);
|
||||
if (local < 0)
|
||||
local = cl.playernum[0];
|
||||
}
|
||||
else
|
||||
local = cl.playernum[0];
|
||||
if (cl.teamplay && !strcmp(player->team, cl.players[local].team))
|
||||
{
|
||||
if (cl_teamtopcolor>=0)
|
||||
top = cl_teamtopcolor;
|
||||
if (cl_teambottomcolor>=0)
|
||||
bottom = cl_teambottomcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cl_enemytopcolor>=0)
|
||||
top = cl_enemytopcolor;
|
||||
if (cl_enemybottomcolor>=0)
|
||||
bottom = cl_enemybottomcolor;
|
||||
}
|
||||
}
|
||||
|
||||
if (top > 13 || top < 0)
|
||||
top = 13;
|
||||
if (bottom > 13 || bottom < 0)
|
||||
bottom = 13;
|
||||
|
||||
if (player->_topcolor != top ||
|
||||
player->_bottomcolor != bottom || !player->skin) {
|
||||
player->_topcolor = top;
|
||||
player->_bottomcolor = bottom;
|
||||
player->ttopcolor = top;
|
||||
player->tbottomcolor = bottom;
|
||||
D_DereferenceRemap(player->palremap);
|
||||
player->palremap = D_GetPaletteRemap(255, 255, 255, false, true, top, bottom);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//other renderers still need the team stuff set, but that's all
|
||||
player->ttopcolor = top;
|
||||
player->tbottomcolor = bottom;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2999,8 +2993,8 @@ void CL_ProcessUserInfo (int slot, player_info_t *player)
|
|||
{
|
||||
Q_strncpyz (player->name, Info_ValueForKey (player->userinfo, "name"), sizeof(player->name));
|
||||
Q_strncpyz (player->team, Info_ValueForKey (player->userinfo, "team"), sizeof(player->team));
|
||||
player->topcolor = atoi(Info_ValueForKey (player->userinfo, "topcolor"));
|
||||
player->bottomcolor = atoi(Info_ValueForKey (player->userinfo, "bottomcolor"));
|
||||
player->rtopcolor = atoi(Info_ValueForKey (player->userinfo, "topcolor"));
|
||||
player->rbottomcolor = atoi(Info_ValueForKey (player->userinfo, "bottomcolor"));
|
||||
if (atoi(Info_ValueForKey (player->userinfo, "*spectator")))
|
||||
player->spectator = true;
|
||||
else
|
||||
|
@ -3590,7 +3584,7 @@ int CL_PlayerColor(player_info_t *plr, int *name_ormask)
|
|||
if (cl.teamfortress) //override based on team
|
||||
{
|
||||
// TODO: needs some work
|
||||
switch (plr->bottomcolor)
|
||||
switch (plr->rbottomcolor)
|
||||
{ //translate q1 skin colours to console colours
|
||||
case 10:
|
||||
case 1:
|
||||
|
@ -4986,8 +4980,8 @@ void CLNQ_ParseServerMessage (void)
|
|||
break;
|
||||
//FIXME:!!!!
|
||||
|
||||
cl.players[i].topcolor = a&0x0f;
|
||||
cl.players[i].bottomcolor = (a&0xf0)>>4;
|
||||
cl.players[i].rtopcolor = a&0x0f;
|
||||
cl.players[i].rbottomcolor = (a&0xf0)>>4;
|
||||
|
||||
if (cls.state == ca_active)
|
||||
Skin_Find (&cl.players[i]);
|
||||
|
|
|
@ -382,13 +382,13 @@ int VARGS Plug_GetPlayerInfo(void *offset, unsigned int mask, const long *arg)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
out->bottomcolour = cl.players[i].bottomcolor;
|
||||
out->bottomcolour = cl.players[i].rbottomcolor;
|
||||
out->topcolour = cl.players[i].rtopcolor;
|
||||
out->frags = cl.players[i].frags;
|
||||
Q_strncpyz(out->name, cl.players[i].name, PLUGMAX_SCOREBOARDNAME);
|
||||
out->ping = cl.players[i].ping;
|
||||
out->pl = cl.players[i].pl;
|
||||
out->starttime = cl.players[i].entertime;
|
||||
out->topcolour = cl.players[i].topcolor;
|
||||
out->userid = cl.players[i].userid;
|
||||
out->spectator = cl.players[i].spectator;
|
||||
Q_strncpyz(out->userinfo, cl.players[i].userinfo, sizeof(out->userinfo));
|
||||
|
|
|
@ -1439,13 +1439,13 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
vci->bottomcolour = cl.players[i].bottomcolor;
|
||||
vci->bottomcolour = cl.players[i].rbottomcolor;
|
||||
vci->frags = cl.players[i].frags;
|
||||
Q_strncpyz(vci->name, cl.players[i].name, UIMAX_SCOREBOARDNAME);
|
||||
vci->ping = cl.players[i].ping;
|
||||
vci->pl = cl.players[i].pl;
|
||||
vci->starttime = cl.players[i].entertime;
|
||||
vci->topcolour = cl.players[i].topcolor;
|
||||
vci->topcolour = cl.players[i].rtopcolor;
|
||||
vci->userid = cl.players[i].userid;
|
||||
Q_strncpyz(vci->userinfo, cl.players[i].userinfo, sizeof(vci->userinfo));
|
||||
}
|
||||
|
|
|
@ -144,11 +144,11 @@ typedef struct player_info_s
|
|||
qboolean ignored;
|
||||
|
||||
// skin information
|
||||
int topcolor;
|
||||
int bottomcolor;
|
||||
int rtopcolor; //real, according to their userinfo
|
||||
int rbottomcolor;
|
||||
|
||||
int _topcolor;
|
||||
int _bottomcolor;
|
||||
int ttopcolor; //team, according to colour forcing
|
||||
int tbottomcolor;
|
||||
|
||||
#ifdef SWQUAKE
|
||||
struct palremap_s *palremap;
|
||||
|
|
|
@ -17,6 +17,7 @@ cvar_t r_dodgypcxfiles = SCVAR("r_dodgypcxfiles", "0"); //Quake 2's PCX loading
|
|||
//and some Q2 mods include PCX files
|
||||
//that only work with this assumption
|
||||
|
||||
#define GLOBAL(x) x
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
@ -874,6 +875,8 @@ term_source (j_decompress_ptr cinfo)
|
|||
}
|
||||
|
||||
|
||||
#define GLOBAL(x) x
|
||||
|
||||
GLOBAL(void)
|
||||
jpeg_mem_src (j_decompress_ptr cinfo, qbyte * infile, int maxlen)
|
||||
{
|
||||
|
|
|
@ -23,6 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
extern cvar_t hud_tracking_show;
|
||||
|
||||
cvar_t scr_scoreboard_drawtitle = SCVAR("scr_scoreboard_drawtitle", "1");
|
||||
cvar_t scr_scoreboard_showfrags = SCVAR("scr_scoreboard_showfrags", "0");
|
||||
cvar_t scr_scoreboard_titleseperator = SCVAR("scr_scoreboard_titleseperator", "1");
|
||||
cvar_t scr_scoreboard_forcecolors = SCVAR("scr_scoreboard_forcecolors", "0"); //damn americans
|
||||
|
||||
//===========================================
|
||||
//rogue changed and added defines
|
||||
|
||||
|
@ -108,6 +113,31 @@ void Sbar_TeamOverlay (void);
|
|||
void Sbar_MiniDeathmatchOverlay (void);
|
||||
void Sbar_ChatModeOverlay(void);
|
||||
|
||||
int Sbar_PlayerNum(void)
|
||||
{
|
||||
int num;
|
||||
num = cl.spectator?Cam_TrackNum(0):-1;
|
||||
if (num < 0)
|
||||
num = cl.playernum;
|
||||
return num;
|
||||
}
|
||||
|
||||
int Sbar_TopColour(player_info_t *p)
|
||||
{
|
||||
if (scr_scoreboard_forcecolors.value)
|
||||
return p->ttopcolor;
|
||||
else
|
||||
return p->rtopcolor;
|
||||
}
|
||||
|
||||
int Sbar_BottomColour(player_info_t *p)
|
||||
{
|
||||
if (scr_scoreboard_forcecolors.value)
|
||||
return p->tbottomcolor;
|
||||
else
|
||||
return p->rbottomcolor;
|
||||
}
|
||||
|
||||
void Draw_FunString(int x, int y, unsigned char *str)
|
||||
{
|
||||
int ext = CON_WHITEMASK;
|
||||
|
@ -954,6 +984,11 @@ void Sbar_Start (void) //if one of these fails, skip the entire status bar.
|
|||
|
||||
void Sbar_Init (void)
|
||||
{
|
||||
Cvar_Register(&scr_scoreboard_drawtitle, "Scoreboard settings");
|
||||
Cvar_Register(&scr_scoreboard_showfrags, "Scoreboard settings");
|
||||
Cvar_Register(&scr_scoreboard_titleseperator, "Scoreboard settings");
|
||||
Cvar_Register(&scr_scoreboard_forcecolors, "Scoreboard settings");
|
||||
|
||||
Cmd_AddCommand ("+showscores", Sbar_ShowScores);
|
||||
Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
|
||||
|
||||
|
@ -1115,8 +1150,6 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
//ZOID: this should be MAX_CLIENTS, not MAX_SCOREBOARD!!
|
||||
//int fragsort[MAX_SCOREBOARD];
|
||||
int fragsort[MAX_CLIENTS];
|
||||
int scoreboardlines;
|
||||
typedef struct {
|
||||
|
@ -1124,6 +1157,8 @@ typedef struct {
|
|||
int frags;
|
||||
int players;
|
||||
int plow, phigh, ptotal;
|
||||
int topcolour, bottomcolour;
|
||||
qboolean ownteam;
|
||||
} team_t;
|
||||
team_t teams[MAX_CLIENTS];
|
||||
int teamsort[MAX_CLIENTS];
|
||||
|
@ -1167,6 +1202,7 @@ void Sbar_SortTeams (void)
|
|||
int i, j, k;
|
||||
player_info_t *s;
|
||||
char t[16+1];
|
||||
int ownnum;
|
||||
|
||||
// request new ping times every two second
|
||||
scoreboardteams = 0;
|
||||
|
@ -1179,36 +1215,49 @@ void Sbar_SortTeams (void)
|
|||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
teams[i].plow = 999;
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
ownnum = Sbar_PlayerNum();
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
s = &cl.players[i];
|
||||
if (!s->name[0])
|
||||
continue;
|
||||
if (s->spectator)
|
||||
if (!s->name[0] || s->spectator)
|
||||
continue;
|
||||
|
||||
// find his team in the list
|
||||
t[16] = 0;
|
||||
Q_strncpyz(t, s->team, sizeof(t));
|
||||
if (!t[0])
|
||||
continue; // not on team
|
||||
for (j = 0; j < scoreboardteams; j++)
|
||||
if (!strcmp(teams[j].team, t)) {
|
||||
teams[j].frags += s->frags;
|
||||
teams[j].players++;
|
||||
goto addpinginfo;
|
||||
if (!strcmp(teams[j].team, t))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (j == scoreboardteams) { // must add him
|
||||
j = scoreboardteams++;
|
||||
strcpy(teams[j].team, t);
|
||||
teams[j].frags = s->frags;
|
||||
teams[j].players = 1;
|
||||
addpinginfo:
|
||||
if (teams[j].plow > s->ping)
|
||||
teams[j].plow = s->ping;
|
||||
if (teams[j].phigh < s->ping)
|
||||
teams[j].phigh = s->ping;
|
||||
teams[j].ptotal += s->ping;
|
||||
|
||||
/*if (cl.teamfortress)
|
||||
{
|
||||
teams[j].topcolour = teams[j].bottomcolour = TF_TeamToColour(t);
|
||||
}
|
||||
else*/ if (j == scoreboardteams || i == ownnum)
|
||||
{
|
||||
teams[j].topcolour = Sbar_TopColour(s);
|
||||
teams[j].bottomcolour = Sbar_BottomColour(s);
|
||||
}
|
||||
|
||||
if (j == scoreboardteams)
|
||||
{ // create a team for this player
|
||||
scoreboardteams++;
|
||||
strcpy(teams[j].team, t);
|
||||
}
|
||||
|
||||
teams[j].frags += s->frags;
|
||||
teams[j].players++;
|
||||
|
||||
if (teams[j].plow > s->ping)
|
||||
teams[j].plow = s->ping;
|
||||
if (teams[j].phigh < s->ping)
|
||||
teams[j].phigh = s->ping;
|
||||
teams[j].ptotal += s->ping;
|
||||
|
||||
}
|
||||
|
||||
// sort
|
||||
|
@ -1218,7 +1267,8 @@ addpinginfo:
|
|||
// good 'ol bubble sort
|
||||
for (i = 0; i < scoreboardteams - 1; i++)
|
||||
for (j = i + 1; j < scoreboardteams; j++)
|
||||
if (teams[teamsort[i]].frags < teams[teamsort[j]].frags) {
|
||||
if (teams[teamsort[i]].frags < teams[teamsort[j]].frags)
|
||||
{
|
||||
k = teamsort[i];
|
||||
teamsort[i] = teamsort[j];
|
||||
teamsort[j] = k;
|
||||
|
@ -1468,11 +1518,14 @@ void Sbar_DrawFrags (void)
|
|||
int i, k, l;
|
||||
int top, bottom;
|
||||
int x, y, f;
|
||||
int ownnum;
|
||||
char num[12];
|
||||
player_info_t *s;
|
||||
|
||||
Sbar_SortFrags (false);
|
||||
|
||||
ownnum = Sbar_PlayerNum();
|
||||
|
||||
// draw the text
|
||||
l = scoreboardlines <= 4 ? scoreboardlines : 4;
|
||||
|
||||
|
@ -1490,8 +1543,8 @@ void Sbar_DrawFrags (void)
|
|||
continue;
|
||||
|
||||
// draw background
|
||||
top = s->topcolor;
|
||||
bottom = s->bottomcolor;
|
||||
top = Sbar_TopColour(s);
|
||||
bottom = Sbar_BottomColour(s);
|
||||
top = (top < 0) ? 0 : ((top > 13) ? 13 : top);
|
||||
bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom);
|
||||
|
||||
|
@ -1511,7 +1564,7 @@ void Sbar_DrawFrags (void)
|
|||
Sbar_DrawCharacter ( (x+2)*8 , -24, num[1]);
|
||||
Sbar_DrawCharacter ( (x+3)*8 , -24, num[2]);
|
||||
|
||||
if (k == cl.playernum[0])
|
||||
if (k == ownnum)
|
||||
{
|
||||
Sbar_DrawCharacter (x*8+2, -24, 16);
|
||||
Sbar_DrawCharacter ( (x+4)*8-4, -24, 17);
|
||||
|
@ -1942,11 +1995,16 @@ void Sbar_TeamOverlay (void)
|
|||
scr_copyeverything = 1;
|
||||
scr_fullupdate = 0;
|
||||
|
||||
pic = Draw_SafeCachePic ("gfx/ranking.lmp");
|
||||
if (pic)
|
||||
Draw_Pic ((vid.width-pic->width)/2, 0, pic);
|
||||
y = 0;
|
||||
|
||||
if (scr_scoreboard_drawtitle.value)
|
||||
{
|
||||
pic = Draw_SafeCachePic ("gfx/ranking.lmp");
|
||||
if (pic)
|
||||
Draw_Pic ((vid.width-pic->width)/2, 0, pic);
|
||||
y += 24;
|
||||
}
|
||||
|
||||
y = 24;
|
||||
x = (vid.width - 320)/2 + 36;
|
||||
Draw_String(x, y, "low/avg/high team total players");
|
||||
y += 8;
|
||||
|
@ -2012,6 +2070,83 @@ Sbar_DeathmatchOverlay
|
|||
ping time frags name
|
||||
==================
|
||||
*/
|
||||
|
||||
//for reference:
|
||||
//define COLUMN(title, width, code)
|
||||
|
||||
#define COLUMN_PING COLUMN(ping, 4*8, \
|
||||
{ \
|
||||
int p = s->ping; \
|
||||
if (p < 0 || p > 999) p = 999; \
|
||||
sprintf(num, "%4i", p); \
|
||||
Draw_FunString(x, y, num); \
|
||||
})
|
||||
|
||||
#define COLUMN_PL COLUMN(pl, 2*8, \
|
||||
{ \
|
||||
int p = s->pl; \
|
||||
sprintf(num, "%3i", p); \
|
||||
Draw_FunString(x, y, num); \
|
||||
})
|
||||
#define COLUMN_TIME COLUMN(time, 4*8, \
|
||||
{ \
|
||||
if (cl.intermission) \
|
||||
total = cl.completed_time - s->entertime; \
|
||||
else \
|
||||
total = cl.servertime - s->entertime; \
|
||||
minutes = (int)total/60; \
|
||||
sprintf (num, "%4i", minutes); \
|
||||
Draw_String ( x , y, num); \
|
||||
})
|
||||
#define COLUMN_FRAGS COLUMN(frags, 5*8, \
|
||||
{ \
|
||||
top = Sbar_TopColour(s); \
|
||||
bottom = Sbar_BottomColour(s); \
|
||||
top = Sbar_ColorForMap (top); \
|
||||
bottom = Sbar_ColorForMap (bottom); \
|
||||
\
|
||||
if (largegame) \
|
||||
Draw_Fill ( x, y+1, 40, 3, top); \
|
||||
else \
|
||||
Draw_Fill ( x, y, 40, 4, top); \
|
||||
Draw_Fill ( x, y+4, 40, 4, bottom); \
|
||||
\
|
||||
f = s->frags; \
|
||||
sprintf (num, "%3i",f); \
|
||||
\
|
||||
Draw_Character ( x+8 , y, num[0]); \
|
||||
Draw_Character ( x+16 , y, num[1]); \
|
||||
Draw_Character ( x+24 , y, num[2]); \
|
||||
\
|
||||
if ((cl.spectator && k == spec_track[0]) || \
|
||||
(!cl.spectator && k == cl.playernum[0])) \
|
||||
{ \
|
||||
Draw_Character ( x, y, 16); \
|
||||
Draw_Character ( x + 32, y, 17); \
|
||||
} \
|
||||
})
|
||||
#define COLUMN_TEAMNAME COLUMN(team, 4*8, {Draw_FunStringLen(x, y, s->team, 4);})
|
||||
#define COLUMN_NAME COLUMN(name, 16*8, {Draw_FunString(x, y, s->name);})
|
||||
#define COLUMN_KILLS COLUMN(kils, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetKills(k)));})
|
||||
#define COLUMN_TKILLS COLUMN(tkil, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetTKills(k)));})
|
||||
#define COLUMN_DEATHS COLUMN(dths, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetDeaths(k)));})
|
||||
#define COLUMN_TOUCHES COLUMN(tchs, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetTouches(k)));})
|
||||
#define COLUMN_CAPS COLUMN(caps, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetCaptures(k)));})
|
||||
|
||||
|
||||
|
||||
//columns are listed here in display order
|
||||
#define ALLCOLUMNS COLUMN_PING COLUMN_PL COLUMN_TIME COLUMN_FRAGS COLUMN_TEAMNAME COLUMN_NAME COLUMN_KILLS COLUMN_TKILLS COLUMN_DEATHS COLUMN_TOUCHES COLUMN_CAPS
|
||||
|
||||
enum
|
||||
{
|
||||
#define COLUMN(title, width, code) COLUMN##title,
|
||||
ALLCOLUMNS
|
||||
#undef COLUMN
|
||||
COLUMN_MAX
|
||||
};
|
||||
|
||||
#define ADDCOLUMN(id) showcolumns |= (1<<id)
|
||||
void Sbar_DeathmatchOverlay (int start)
|
||||
{
|
||||
mpic_t *pic;
|
||||
|
@ -2024,6 +2159,8 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
int minutes;
|
||||
int p;
|
||||
int skip = 10;
|
||||
int showcolumns;
|
||||
int startx;
|
||||
|
||||
if (largegame)
|
||||
skip = 8;
|
||||
|
@ -2038,11 +2175,18 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
scr_copyeverything = 1;
|
||||
scr_fullupdate = 0;
|
||||
|
||||
if (!start)
|
||||
if (start)
|
||||
y = start;
|
||||
else
|
||||
{
|
||||
pic = Draw_SafeCachePic ("gfx/ranking.lmp");
|
||||
if (pic)
|
||||
Draw_Pic ((vid.width - 320)/2 + 160-pic->width/2, 0, pic);
|
||||
y = 0;
|
||||
if (scr_scoreboard_drawtitle.value)
|
||||
{
|
||||
pic = Draw_SafeCachePic ("gfx/ranking.lmp");
|
||||
if (pic)
|
||||
Draw_Pic ((vid.width - 320)/2 + 160-pic->width/2, 0, pic);
|
||||
y += 24;
|
||||
}
|
||||
}
|
||||
|
||||
// scores
|
||||
|
@ -2055,6 +2199,78 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
y = start;
|
||||
else
|
||||
y = 24;
|
||||
|
||||
showcolumns = 0;
|
||||
|
||||
//we use startx here as the total width
|
||||
startx = 0;
|
||||
|
||||
#define COLUMN(title, cwidth, code) if (startx+(cwidth)+8 <= vid.width) {showcolumns |= (1<<COLUMN##title); startx += cwidth+8;}
|
||||
//columns are listed here in priority order (if the screen is too narrow, later ones will be hidden)
|
||||
COLUMN_NAME
|
||||
COLUMN_PING
|
||||
COLUMN_PL
|
||||
COLUMN_TIME
|
||||
COLUMN_FRAGS
|
||||
if (cl.teamplay)
|
||||
{
|
||||
COLUMN_TEAMNAME
|
||||
}
|
||||
if (cl.teamplay && Stats_HaveFlags())
|
||||
{
|
||||
COLUMN_CAPS
|
||||
}
|
||||
if (scr_scoreboard_showfrags.value && Stats_HaveKills())
|
||||
{
|
||||
COLUMN_KILLS
|
||||
COLUMN_DEATHS
|
||||
if (cl.teamplay)
|
||||
{
|
||||
COLUMN_TKILLS
|
||||
}
|
||||
}
|
||||
if (cl.teamplay && Stats_HaveFlags())
|
||||
{
|
||||
COLUMN_TOUCHES
|
||||
}
|
||||
#undef COLUMN
|
||||
|
||||
startx = (vid.width-startx)/2;
|
||||
|
||||
x = startx;
|
||||
#define COLUMN(title, width, code) if (showcolumns & (1<<COLUMN##title)) {Draw_FunString(x, y, #title); x += width+8;}
|
||||
ALLCOLUMNS
|
||||
#undef COLUMN
|
||||
y += 8;
|
||||
|
||||
if (scr_scoreboard_titleseperator.value)
|
||||
{
|
||||
x = startx;
|
||||
#define COLUMN(title, width, code) if (showcolumns & (1<<COLUMN##title)) {Draw_String(x, y, "\x1d"); for (i = 8; i < width-8; i+= 8) Draw_String(x+i, y, "\x1e"); Draw_String(x+i, y, "\x1f"); x += width+8;}
|
||||
ALLCOLUMNS
|
||||
#undef COLUMN
|
||||
y += 8;
|
||||
}
|
||||
|
||||
y -= skip;
|
||||
for (i = 0; i < scoreboardlines; i++)
|
||||
{
|
||||
k = fragsort[i];
|
||||
s = &cl.players[k];
|
||||
if (!s->name[0])
|
||||
continue;
|
||||
|
||||
y += skip;
|
||||
if (y > vid.height-10)
|
||||
break;
|
||||
|
||||
x = startx;
|
||||
#define COLUMN(title, width, code) if (showcolumns & (1<<COLUMN##title)) {code x += width+8;}
|
||||
ALLCOLUMNS
|
||||
#undef COLUMN
|
||||
}
|
||||
|
||||
/*
|
||||
if (cl.teamplay)
|
||||
{
|
||||
if (scr_chatmode)
|
||||
|
@ -2165,7 +2381,7 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
|
||||
y += skip;
|
||||
}
|
||||
|
||||
*/
|
||||
Draw_Character(0,0,' ' | CON_WHITEMASK);
|
||||
|
||||
if (y >= vid.height-10) // we ran over the screen size, squish
|
||||
|
@ -2228,8 +2444,8 @@ void Sbar_ChatModeOverlay(void)
|
|||
continue;
|
||||
|
||||
// draw background
|
||||
top = s->topcolor;
|
||||
bottom = s->bottomcolor;
|
||||
top = Sbar_TopColour(s);
|
||||
bottom = Sbar_BottomColour(s);
|
||||
top = Sbar_ColorForMap (top);
|
||||
bottom = Sbar_ColorForMap (bottom);
|
||||
|
||||
|
@ -2338,8 +2554,8 @@ void Sbar_MiniDeathmatchOverlay (void)
|
|||
continue;
|
||||
|
||||
// draw ping
|
||||
top = s->topcolor;
|
||||
bottom = s->bottomcolor;
|
||||
top = Sbar_TopColour(s);
|
||||
bottom = Sbar_BottomColour(s);
|
||||
top = Sbar_ColorForMap (top);
|
||||
bottom = Sbar_ColorForMap (bottom);
|
||||
|
||||
|
|
|
@ -2445,19 +2445,19 @@ void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_
|
|||
|
||||
eyes = state->modelindex && cl.model_precache[state->modelindex] && !strcmp(cl.model_precache[state->modelindex]->name, "progs/eyes.mdl");
|
||||
|
||||
if (state->effects & (EF_BLUE | EF_RED) || eyes)
|
||||
if (state->effects & (EF_BLUE | EF_RED) || eyes)
|
||||
{
|
||||
vars.enemy_powerups = 0;
|
||||
vars.enemy_powerups_time = realtime;
|
||||
vars.enemy_powerups = 0;
|
||||
vars.enemy_powerups_time = realtime;
|
||||
|
||||
if (state->effects & EF_BLUE)
|
||||
vars.enemy_powerups |= TP_QUAD;
|
||||
if (state->effects & EF_RED)
|
||||
vars.enemy_powerups |= TP_PENT;
|
||||
if (eyes)
|
||||
vars.enemy_powerups |= TP_RING;
|
||||
}
|
||||
}
|
||||
if (state->effects & EF_BLUE)
|
||||
vars.enemy_powerups |= TP_QUAD;
|
||||
if (state->effects & EF_RED)
|
||||
vars.enemy_powerups |= TP_PENT;
|
||||
if (eyes)
|
||||
vars.enemy_powerups |= TP_RING;
|
||||
}
|
||||
}
|
||||
if (!cl.spectator && !cl.teamfortress && info - cl.players == cl.playernum[SP])
|
||||
{
|
||||
if ((state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && !(oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2)))
|
||||
|
@ -2505,9 +2505,11 @@ more:
|
|||
if (FindNearestItem (it_weapons, &item)) {
|
||||
ExecTookTrigger (item->cvar->string, item->itemflag, org);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// we don't know what entity caused the sound, try to guess...
|
||||
if (vars.stat_framecounts[STAT_ITEMS] == cls.framecount) {
|
||||
if (vars.stat_framecounts[STAT_ITEMS] == cls.framecount)
|
||||
{
|
||||
if (vars.items & ~vars.olditems & IT_LIGHTNING)
|
||||
ExecTookTrigger (tp_name_lg.string, it_lg, cl.simorg[SP]);
|
||||
else if (vars.items & ~vars.olditems & IT_ROCKET_LAUNCHER)
|
||||
|
@ -2526,7 +2528,8 @@ more:
|
|||
}
|
||||
|
||||
// armor
|
||||
if (!strcmp(s, "items/armor1.wav")) {
|
||||
if (!strcmp(s, "items/armor1.wav"))
|
||||
{
|
||||
item_t *item;
|
||||
qbool armor_updated;
|
||||
int armortype;
|
||||
|
@ -2552,7 +2555,8 @@ more:
|
|||
}
|
||||
}
|
||||
|
||||
static qboolean TP_IsItemVisible(item_vis_t *visitem) {
|
||||
static qboolean TP_IsItemVisible(item_vis_t *visitem)
|
||||
{
|
||||
vec3_t end, v;
|
||||
trace_t trace;
|
||||
|
||||
|
@ -2602,7 +2606,8 @@ static qboolean TP_IsItemVisible(item_vis_t *visitem) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static float TP_RankPoint(item_vis_t *visitem) {
|
||||
static float TP_RankPoint(item_vis_t *visitem)
|
||||
{
|
||||
vec3_t v2, v3;
|
||||
float miss;
|
||||
|
||||
|
@ -2620,41 +2625,50 @@ static float TP_RankPoint(item_vis_t *visitem) {
|
|||
return (visitem->dist < 3000.0 / 8.0) ? miss * (visitem->dist * 8.0 * 0.0002f + 0.3f) : miss;
|
||||
}
|
||||
|
||||
static char *Utils_TF_ColorToTeam_Failsafe(int color) {
|
||||
static char *Utils_TF_ColorToTeam_Failsafe(int color)
|
||||
{
|
||||
int i, j, teamcounts[8], numteamsseen = 0, best = -1;
|
||||
char *teams[MAX_CLIENTS];
|
||||
|
||||
memset(teams, 0, sizeof(teams));
|
||||
memset(teamcounts, 0, sizeof(teamcounts));
|
||||
|
||||
for (i = 0; i < MAX_CLIENTS; i++) {
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if (!cl.players[i].name[0] || cl.players[i].spectator)
|
||||
continue;
|
||||
if (cl.players[i].bottomcolor != color)
|
||||
if (cl.players[i].rbottomcolor != color)
|
||||
continue;
|
||||
for (j = 0; j < numteamsseen; j++) {
|
||||
for (j = 0; j < numteamsseen; j++)
|
||||
{
|
||||
if (!strcmp(cl.players[i].team, teams[j]))
|
||||
break;
|
||||
}
|
||||
if (j == numteamsseen) {
|
||||
if (j == numteamsseen)
|
||||
{
|
||||
teams[numteamsseen] = cl.players[i].team;
|
||||
teamcounts[numteamsseen] = 1;
|
||||
numteamsseen++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
teamcounts[j]++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < numteamsseen; i++) {
|
||||
for (i = 0; i < numteamsseen; i++)
|
||||
{
|
||||
if (best == -1 || teamcounts[i] > teamcounts[best])
|
||||
best = i;
|
||||
}
|
||||
return (best == -1) ? "" : teams[best];
|
||||
}
|
||||
|
||||
char *Utils_TF_ColorToTeam(int color) {
|
||||
char *Utils_TF_ColorToTeam(int color)
|
||||
{
|
||||
char *s;
|
||||
|
||||
switch (color) {
|
||||
switch (color)
|
||||
{
|
||||
case 13:
|
||||
if (*(s = Info_ValueForKey(cl.serverinfo, "team1")) || *(s = Info_ValueForKey(cl.serverinfo, "t1")))
|
||||
return s;
|
||||
|
@ -2678,7 +2692,8 @@ char *Utils_TF_ColorToTeam(int color) {
|
|||
}
|
||||
|
||||
|
||||
static void TP_FindPoint (void) {
|
||||
static void TP_FindPoint (void)
|
||||
{
|
||||
packet_entities_t *pak;
|
||||
entity_state_t *ent;
|
||||
int i, j, pointflags_dmm;
|
||||
|
@ -2703,7 +2718,8 @@ static void TP_FindPoint (void) {
|
|||
visitem.vieworg[2] += 22 + (v_viewheight.value ? bound (-7, v_viewheight.value, 4) : 0);
|
||||
|
||||
pointflags_dmm = pointflags;
|
||||
if (!cl.teamfortress && cl.deathmatch >= 1 && cl.deathmatch <= 4) {
|
||||
if (!cl.teamfortress && cl.deathmatch >= 1 && cl.deathmatch <= 4)
|
||||
{
|
||||
if (cl.deathmatch == 4)
|
||||
pointflags_dmm &= ~it_ammo;
|
||||
if (cl.deathmatch != 1)
|
||||
|
@ -2711,13 +2727,16 @@ static void TP_FindPoint (void) {
|
|||
}
|
||||
|
||||
pak = &cl.frames[cl.validsequence & UPDATE_MASK].packet_entities;
|
||||
for (i = 0,ent = pak->entities; i < pak->num_entities; i++, ent++) {
|
||||
for (i = 0,ent = pak->entities; i < pak->num_entities; i++, ent++)
|
||||
{
|
||||
item = model2item[ent->modelindex];
|
||||
if (!item || !(item->itemflag & pointflags_dmm))
|
||||
continue;
|
||||
// special check for armors
|
||||
if (item->itemflag == (it_ra|it_ya|it_ga)) {
|
||||
switch (ent->skinnum) {
|
||||
if (item->itemflag == (it_ra|it_ya|it_ga))
|
||||
{
|
||||
switch (ent->skinnum)
|
||||
{
|
||||
case 0: if (!(pointflags_dmm & it_ga)) continue;
|
||||
case 1: if (!(pointflags_dmm & it_ya)) continue;
|
||||
default: if (!(pointflags_dmm & it_ra)) continue;
|
||||
|
@ -2733,7 +2752,8 @@ static void TP_FindPoint (void) {
|
|||
continue;
|
||||
|
||||
// check if we can actually see the object
|
||||
if ((rank < best || best < 0) && TP_IsItemVisible(&visitem)) {
|
||||
if ((rank < best || best < 0) && TP_IsItemVisible(&visitem))
|
||||
{
|
||||
best = rank;
|
||||
bestent = ent;
|
||||
bestitem = item;
|
||||
|
@ -2742,7 +2762,8 @@ static void TP_FindPoint (void) {
|
|||
|
||||
state = cl.frames[cl.parsecount & UPDATE_MASK].playerstate;
|
||||
info = cl.players;
|
||||
for (j = 0; j < MAX_CLIENTS; j++, info++, state++) {
|
||||
for (j = 0; j < MAX_CLIENTS; j++, info++, state++)
|
||||
{
|
||||
if (state->messagenum != cl.parsecount || j == cl.playernum[0] || info->spectator)
|
||||
continue;
|
||||
|
||||
|
@ -2762,7 +2783,8 @@ static void TP_FindPoint (void) {
|
|||
continue;
|
||||
|
||||
// check if we can actually see the object
|
||||
if ((rank < best || best < 0) && TP_IsItemVisible(&visitem)) {
|
||||
if ((rank < best || best < 0) && TP_IsItemVisible(&visitem))
|
||||
{
|
||||
qboolean teammate, eyes = false;
|
||||
|
||||
eyes = state->modelindex && cl.model_precache[state->modelindex] && !strcmp(cl.model_precache[state->modelindex]->name, "progs/eyes.mdl");
|
||||
|
@ -2781,13 +2803,15 @@ static void TP_FindPoint (void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (best >= 0 && bestinfo) {
|
||||
if (best >= 0 && bestinfo)
|
||||
{
|
||||
qboolean teammate, eyes;
|
||||
char *name, buf[256] = {0};
|
||||
|
||||
eyes = beststate->modelindex && cl.model_precache[beststate->modelindex] && !strcmp(cl.model_precache[beststate->modelindex]->name, "progs/eyes.mdl");
|
||||
if (cl.teamfortress) {
|
||||
teammate = !strcmp(Utils_TF_ColorToTeam(bestinfo->bottomcolor), TP_PlayerTeam());
|
||||
if (cl.teamfortress)
|
||||
{
|
||||
teammate = !strcmp(Utils_TF_ColorToTeam(bestinfo->rbottomcolor), TP_PlayerTeam());
|
||||
|
||||
if (eyes)
|
||||
name = tp_name_eyes.string; //duck on 2night2
|
||||
|
@ -2800,7 +2824,9 @@ static void TP_FindPoint (void) {
|
|||
|
||||
if (!eyes)
|
||||
name = va("%s%s%s", name, name[0] ? " " : "", Skin_To_TFSkin(Info_ValueForKey(bestinfo->userinfo, "skin")));
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
teammate = !!(cl.teamplay && !strcmp(bestinfo->team, TP_PlayerTeam()));
|
||||
|
||||
if (eyes)
|
||||
|
@ -2819,17 +2845,23 @@ static void TP_FindPoint (void) {
|
|||
Q_strncpyz (vars.pointloc, TP_LocationName (beststate->origin), sizeof(vars.pointloc));
|
||||
|
||||
vars.pointtype = (teammate && !eyes) ? POINT_TYPE_TEAMMATE : POINT_TYPE_ENEMY;
|
||||
} else if (best >= 0) {
|
||||
}
|
||||
else if (best >= 0)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!bestitem->cvar) {
|
||||
if (!bestitem->cvar)
|
||||
{
|
||||
// armors are special
|
||||
switch (bestent->skinnum) {
|
||||
switch (bestent->skinnum)
|
||||
{
|
||||
case 0: p = tp_name_ga.string; break;
|
||||
case 1: p = tp_name_ya.string; break;
|
||||
default: p = tp_name_ra.string;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
p = bestitem->cvar->string;
|
||||
}
|
||||
|
||||
|
@ -2837,7 +2869,8 @@ static void TP_FindPoint (void) {
|
|||
Q_strncpyz (vars.pointname, p, sizeof(vars.pointname));
|
||||
Q_strncpyz (vars.pointloc, TP_LocationName (bestent->origin), sizeof(vars.pointloc));
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
nothing:
|
||||
Q_strncpyz (vars.pointname, tp_name_nothing.string, sizeof(vars.pointname));
|
||||
vars.pointloc[0] = 0;
|
||||
|
|
Loading…
Reference in a new issue