wait now correctly waits until the start of the next input frame (thus ensuring that -attack is delayed for long enough).
implemented hud_teaminfo_show ezhud element. _LOTS_ of hacks. ezhud needs updated engine. fix issue with overly friendly prints. handle svc_setinfo more gracefully, for the next time OMC makes a bug. allow glsl to embed default values for float cvars, in case they're not already set. this can save some docs... removed prints about "wad" "foo\", fixing a crash concerning just which print function to call. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4925 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
ad9b98f73c
commit
365c11181c
17 changed files with 326 additions and 89 deletions
|
@ -1714,6 +1714,8 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
}
|
||||
|
||||
IN_Move (NULL, 0, frametime);
|
||||
|
||||
Cbuf_Waited(); //its okay to stop waiting now
|
||||
return; // sendcmds come from the demo
|
||||
}
|
||||
|
||||
|
@ -1803,6 +1805,8 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
{
|
||||
CL_BaseMove (&independantphysics[plnum], plnum, (msecstouse - independantphysics[plnum].msec), wantfps);
|
||||
CL_FinishMove(&independantphysics[plnum], msecstouse, plnum);
|
||||
|
||||
Cbuf_Waited(); //its okay to stop waiting now
|
||||
}
|
||||
|
||||
// if we are spectator, try autocam
|
||||
|
|
|
@ -4663,19 +4663,22 @@ void CL_ParseSetInfo (void)
|
|||
char value[MAX_QWMSGLEN];
|
||||
|
||||
slot = MSG_ReadByte ();
|
||||
if (slot >= MAX_CLIENTS)
|
||||
Host_EndGame ("CL_ParseServerMessage: svc_setinfo > MAX_SCOREBOARD");
|
||||
|
||||
player = &cl.players[slot];
|
||||
|
||||
Q_strncpyz (key, MSG_ReadString(), sizeof(key));
|
||||
Q_strncpyz (value, MSG_ReadString(), sizeof(value));
|
||||
|
||||
Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value);
|
||||
if (slot >= MAX_CLIENTS)
|
||||
Con_Printf("INVALID SETINFO %i: %s=%s\n", slot, key, value);
|
||||
else
|
||||
{
|
||||
player = &cl.players[slot];
|
||||
|
||||
Info_SetValueForStarKey (player->userinfo, key, value, sizeof(player->userinfo));
|
||||
Con_DPrintf("SETINFO %s: %s=%s\n", player->name, key, value);
|
||||
|
||||
CL_ProcessUserInfo (slot, player);
|
||||
Info_SetValueForStarKey (player->userinfo, key, value, sizeof(player->userinfo));
|
||||
|
||||
CL_ProcessUserInfo (slot, player);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5691,6 +5694,32 @@ void CL_ParsePrint(char *msg, int level)
|
|||
}
|
||||
|
||||
|
||||
void CL_ParseTeamInfo(void)
|
||||
{
|
||||
unsigned int pidx = atoi(Cmd_Argv(1));
|
||||
vec3_t org =
|
||||
{
|
||||
atof(Cmd_Argv(2)),
|
||||
atof(Cmd_Argv(3)),
|
||||
atof(Cmd_Argv(4))
|
||||
};
|
||||
float health = atof(Cmd_Argv(5));
|
||||
float armour = atof(Cmd_Argv(6));
|
||||
unsigned int items = strtoul(Cmd_Argv(7), NULL, 0);
|
||||
char *nick = Cmd_Argv(8);
|
||||
|
||||
if (pidx < cl.allocated_client_slots)
|
||||
{
|
||||
player_info_t *pl = &cl.players[pidx];
|
||||
pl->tinfo.time = cl.time+5;
|
||||
pl->tinfo.health = health;
|
||||
pl->tinfo.armour = armour;
|
||||
pl->tinfo.items = items;
|
||||
VectorCopy(org, pl->tinfo.org);
|
||||
Q_strncpyz(pl->tinfo.nick, nick, sizeof(pl->tinfo.nick));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char stufftext[4096];
|
||||
void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from network segregation.
|
||||
|
@ -5781,7 +5810,8 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
|
|||
else if (!strncmp(stufftext, "//tinfo ", 8))
|
||||
{
|
||||
Cmd_TokenizeString(stufftext+2, false, false);
|
||||
Plug_Command_f();
|
||||
CL_ParseTeamInfo();
|
||||
Plug_Command_f(); //FIXME: deprecate this call
|
||||
}
|
||||
else if (!strncmp(stufftext, "//sn ", 5))
|
||||
{
|
||||
|
|
|
@ -695,6 +695,95 @@ static qintptr_t VARGS Plug_GetLocationName(void *offset, quintptr_t mask, const
|
|||
return VM_LONG(arg[1]);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int client;
|
||||
unsigned int items;
|
||||
float armor;
|
||||
float health;
|
||||
vec3_t org;
|
||||
char nick[16];
|
||||
} teamplayerinfo_t;
|
||||
static qintptr_t VARGS Plug_GetTeamInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
teamplayerinfo_t *players = VM_POINTER(arg[0]);
|
||||
size_t maxplayers = VM_LONG(arg[1]);
|
||||
qboolean showenemies = VM_LONG(arg[2]);
|
||||
qboolean showself = VM_LONG(arg[3]);
|
||||
int count = 0;
|
||||
int i;
|
||||
int self;
|
||||
lerpents_t *le;
|
||||
player_info_t *pl;
|
||||
|
||||
if (VM_OOB(arg[0], maxplayers*sizeof(*players)))
|
||||
return 0;
|
||||
maxplayers = min(maxplayers, cl.allocated_client_slots);
|
||||
|
||||
Cvar_Get("ti", "1", CVAR_USERINFO, "Hacks because ktx sucks. Must be 1 in order to receive team information in ktx.");
|
||||
|
||||
self = cl.playerview[0].playernum;
|
||||
if (cl.playerview[0].cam_state != CAM_FREECAM)
|
||||
self = cl.playerview[0].cam_spec_track;
|
||||
|
||||
for (i = 0; i < cl.allocated_client_slots && maxplayers > 0; i++)
|
||||
{
|
||||
if (!*cl.players[i].name) //empty slot
|
||||
continue;
|
||||
if (cl.players[i].spectator) //shoo!
|
||||
continue;
|
||||
if (i == self && !showself)
|
||||
continue;
|
||||
if (!showenemies && strcmp(cl.players[i].team, cl.players[self].team))
|
||||
continue;
|
||||
players->client = i;
|
||||
|
||||
pl = &cl.players[i];
|
||||
if (pl->tinfo.time > cl.time)
|
||||
{ //mod is explicitly telling us this junk
|
||||
players->items = pl->tinfo.items;
|
||||
players->health = pl->tinfo.health;
|
||||
players->armor = pl->tinfo.armour;
|
||||
VectorCopy(pl->tinfo.org, players->org);
|
||||
Q_strncpyz(players->nick, pl->tinfo.nick, sizeof(players->nick));
|
||||
}
|
||||
else if (i == self)
|
||||
{ //oh hey look, its me.
|
||||
players->items = cl.playerview[0].stats[STAT_ITEMS];
|
||||
players->armor = cl.playerview[0].statsf[STAT_ARMOR];
|
||||
players->health = cl.playerview[0].statsf[STAT_HEALTH];
|
||||
Q_strncpyz(players->nick, "", sizeof(players->nick));
|
||||
}
|
||||
else
|
||||
{ //scrape it from the mvd (assuming there is one...
|
||||
players->items = cl.players[i].stats[STAT_ITEMS];
|
||||
players->armor = cl.players[i].statsf[STAT_ARMOR];
|
||||
players->health = cl.players[i].statsf[STAT_HEALTH];
|
||||
Q_strncpyz(players->nick, "", sizeof(players->nick));
|
||||
|
||||
VectorClear(players->org);
|
||||
}
|
||||
|
||||
//scrape origin from interpolation, if its more valid.
|
||||
if (i+1 < cl.maxlerpents && cl.lerpentssequence && cl.lerpents[i+1].sequence == cl.lerpentssequence)
|
||||
{
|
||||
le = &cl.lerpents[i+1];
|
||||
VectorCopy(le->origin, players->org);
|
||||
}
|
||||
else if (cl.lerpentssequence && cl.lerpplayers[i].sequence == cl.lerpentssequence)
|
||||
{
|
||||
le = &cl.lerpplayers[i];
|
||||
VectorCopy(le->origin, players->org);
|
||||
}
|
||||
|
||||
players++;
|
||||
maxplayers--;
|
||||
count++;
|
||||
}
|
||||
|
||||
return VM_LONG(count);
|
||||
}
|
||||
|
||||
static qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
|
@ -1058,6 +1147,7 @@ void Plug_Client_Init(void)
|
|||
Plug_RegisterBuiltin("LocalSound", Plug_LocalSound, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("SCR_CenterPrint", Plug_SCR_CenterPrint, PLUG_BIF_NEEDSRENDERER);
|
||||
|
||||
Plug_RegisterBuiltin("GetTeamInfo", Plug_GetTeamInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("GetLocationName", Plug_GetLocationName, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("GetPlayerInfo", Plug_GetPlayerInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("LocalPlayerNumber", Plug_LocalPlayerNumber, PLUG_BIF_NEEDSRENDERER);
|
||||
|
|
|
@ -164,6 +164,16 @@ typedef struct player_info_s
|
|||
int ping;
|
||||
qbyte pl;
|
||||
|
||||
struct
|
||||
{
|
||||
float time; //invalid if too old.
|
||||
int health;
|
||||
int armour;
|
||||
unsigned int items;
|
||||
vec3_t org;
|
||||
char nick[8]; //kinda short, yes.
|
||||
} tinfo;
|
||||
|
||||
qboolean ignored;
|
||||
qboolean vignored;
|
||||
|
||||
|
|
|
@ -153,6 +153,12 @@ struct {
|
|||
} cmd_text[RESTRICT_MAX+3+MAX_SPLITS]; //max is local.
|
||||
//RESTRICT_MAX+1 is the from sever buffer (max+2 is for second player...)
|
||||
|
||||
void Cbuf_Waited(void)
|
||||
{
|
||||
//input packet was sent to server, its okay to continue executing stuff like -attack now
|
||||
cmd_text[RESTRICT_LOCAL].waitattime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Wait_f
|
||||
|
@ -424,6 +430,15 @@ void Cbuf_Execute (void)
|
|||
{
|
||||
int level;
|
||||
|
||||
#ifndef SERVERONLY
|
||||
if (cmd_text[RESTRICT_LOCAL].waitattime && cls.state == ca_active)
|
||||
{
|
||||
//keep binds blocked until after the next input frame was sent to the server (at which point it will be cleared
|
||||
//this ensures that wait and +attack etc works synchronously, as though your client never even supported network independance! yay... I guess.
|
||||
cmd_text[RESTRICT_LOCAL].waitattime = realtime;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (level = 0; level < sizeof(cmd_text)/sizeof(cmd_text[0]); level++)
|
||||
if (cmd_text[level].buf.cursize)
|
||||
Cbuf_ExecuteLevel(level);
|
||||
|
|
|
@ -34,6 +34,7 @@ The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute ();
|
|||
|
||||
*/
|
||||
|
||||
void Cbuf_Waited(void);
|
||||
|
||||
void Cbuf_Init (void);
|
||||
// allocates an initial text buffer that will grow as needed
|
||||
|
|
|
@ -924,11 +924,6 @@ void Cvar_ForceCheatVars(qboolean semicheats, qboolean absolutecheats)
|
|||
if (!(var->flags & (CVAR_CHEAT|CVAR_SEMICHEAT)))
|
||||
continue;
|
||||
|
||||
if (var->flags & CVAR_RULESETLATCH)
|
||||
{
|
||||
Con_Printf("Hello\n");
|
||||
}
|
||||
|
||||
latch = var->latched_string;
|
||||
var->latched_string = NULL;
|
||||
if (!latch)
|
||||
|
|
|
@ -1283,6 +1283,7 @@
|
|||
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;SERVERONLY;MULTITHREAD"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
SmallerTypeCheck="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
FloatingPointModel="2"
|
||||
|
|
|
@ -1031,9 +1031,22 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
{
|
||||
cvar_t *var;
|
||||
char namebuf[64];
|
||||
char valuebuf[64];
|
||||
memcpy(namebuf, script, end - script);
|
||||
namebuf[end - script] = 0;
|
||||
var = Cvar_Get(namebuf, "0", CVAR_SHADERSYSTEM, "GLSL Variables");
|
||||
while (*end == ' ' || *end == '\t')
|
||||
end++;
|
||||
if (*end == '=')
|
||||
{
|
||||
script = ++end;
|
||||
while (*end && *end != '\n' && *end != '\r' && end < script+sizeof(namebuf)-1)
|
||||
end++;
|
||||
memcpy(valuebuf, script, end - script);
|
||||
valuebuf[end - script] = 0;
|
||||
}
|
||||
else
|
||||
strcpy(valuebuf, "0");
|
||||
var = Cvar_Get(namebuf, valuebuf, CVAR_SHADERSYSTEM, "GLSL Variables");
|
||||
if (var)
|
||||
permutationdefines[nummodifiers++] = Z_StrDup(va("#define %s %g\n", namebuf, var->value));
|
||||
}
|
||||
|
|
|
@ -2294,6 +2294,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
|||
/*set cvar unirforms*/
|
||||
for (i = 0; cvarnames[i]; i++)
|
||||
{
|
||||
char *tmpval;
|
||||
if (prog->numparams == SHADER_PROGPARMS_MAX)
|
||||
{
|
||||
Con_Printf("Too many cvar paramters for program\n");
|
||||
|
@ -2302,7 +2303,14 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
|||
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
|
||||
tmpname[p] = cvarnames[i][p];
|
||||
tmpname[p] = 0;
|
||||
cvar = Cvar_Get(tmpname, "0", CVAR_SHADERSYSTEM, "glsl cvars");
|
||||
tmpval = strchr(tmpname, '=');
|
||||
if (tmpval)
|
||||
*tmpval++ = 0;
|
||||
else
|
||||
tmpval = "0";
|
||||
while(p > 0 && (tmpname[p-1] == ' ' || tmpname[p-1] == '\t'))
|
||||
tmpname[--p] = 0;
|
||||
cvar = Cvar_Get(tmpname, tmpval, CVAR_SHADERSYSTEM, "glsl cvars");
|
||||
if (!cvar)
|
||||
continue;
|
||||
cvar->flags |= CVAR_SHADERSYSTEM;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <ctype.h>
|
||||
//#include <sys/time.h>
|
||||
|
||||
#undef progfuncs
|
||||
|
||||
#define PATHSEPERATOR '/'
|
||||
|
||||
#ifndef QCC
|
||||
|
@ -131,8 +133,8 @@ void QC_strlcat(char *dest, const char *src, size_t destsize)
|
|||
dest += curlen;
|
||||
while(*src && ++curlen < destsize)
|
||||
*dest++ = *src++;
|
||||
if (*src)
|
||||
printf("QC_strlcpy: truncation\n");
|
||||
// if (*src)
|
||||
// printf("QC_strlcpy: truncation\n");
|
||||
*dest = 0;
|
||||
}
|
||||
void QC_strlcpy(char *dest, const char *src, size_t destsize)
|
||||
|
@ -142,8 +144,8 @@ void QC_strlcpy(char *dest, const char *src, size_t destsize)
|
|||
return; //err
|
||||
while(*src && ++curlen < destsize)
|
||||
*dest++ = *src++;
|
||||
if (*src)
|
||||
printf("QC_strlcpy: truncation\n");
|
||||
// if (*src)
|
||||
// printf("QC_strlcpy: truncation\n");
|
||||
*dest = 0;
|
||||
}
|
||||
void QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize)
|
||||
|
@ -153,8 +155,8 @@ void QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize)
|
|||
return; //err
|
||||
for(; *src && srclen > 0 && ++curlen < destsize; srclen--)
|
||||
*dest++ = *src++;
|
||||
if (srclen)
|
||||
printf("QC_strlcpy: truncation\n");
|
||||
// if (srclen)
|
||||
// printf("QC_strlcpy: truncation\n");
|
||||
*dest = 0;
|
||||
}
|
||||
|
||||
|
@ -312,7 +314,7 @@ skipwhite:
|
|||
}
|
||||
else if (c=='\0')
|
||||
{
|
||||
printf("ERROR: Unterminated string\n");
|
||||
// printf("ERROR: Unterminated string\n");
|
||||
qcc_token[len] = 0;
|
||||
return (char*)data;
|
||||
}
|
||||
|
@ -324,7 +326,7 @@ skipwhite:
|
|||
//so \r\n terminates the string if the last char was an escaped quote, but not otherwise.
|
||||
if (len > 0 && qcc_token[len-1] == '\"')
|
||||
{
|
||||
printf("ERROR: new line in string\n");
|
||||
// printf("ERROR: new line in string\n");
|
||||
qcc_token[len] = 0;
|
||||
return (char*)data;
|
||||
}
|
||||
|
@ -519,6 +521,7 @@ For abnormal program terminations
|
|||
*/
|
||||
void VARGS QCC_Error (int errortype, const char *error, ...)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
extern int numsourcefiles;
|
||||
va_list argptr;
|
||||
char msg[2048];
|
||||
|
@ -877,6 +880,7 @@ int SafeSeek(int hand, int ofs, int mode)
|
|||
}
|
||||
pbool SafeClose(int hand)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
pbool ret;
|
||||
ret = externs->WriteFile(qccfile[hand].name, qccfile[hand].buff, qccfile[hand].maxofs);
|
||||
// if (qccfile[hand].buffismalloc)
|
||||
|
@ -1163,6 +1167,7 @@ char *QCC_SanitizeCharSet(char *mem, unsigned int *len, pbool *freeresult, int *
|
|||
|
||||
long QCC_LoadFile (char *filename, void **bufferptr)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
char *mem;
|
||||
int check;
|
||||
int flen;
|
||||
|
@ -1221,6 +1226,7 @@ long QCC_LoadFile (char *filename, void **bufferptr)
|
|||
}
|
||||
void QCC_AddFile (char *filename)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
char *mem;
|
||||
int len;
|
||||
len = externs->FileSize(filename);
|
||||
|
@ -1241,6 +1247,7 @@ void QCC_AddFile (char *filename)
|
|||
}
|
||||
void *FS_ReadToMem(char *filename, void *mem, int *len)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
if (!mem)
|
||||
{
|
||||
*len = externs->FileSize(filename);
|
||||
|
@ -1251,6 +1258,7 @@ void *FS_ReadToMem(char *filename, void *mem, int *len)
|
|||
|
||||
void FS_CloseFromMem(void *mem)
|
||||
{
|
||||
progfuncs_t *progfuncs = qccprogfuncs;
|
||||
externs->memfree(mem);
|
||||
}
|
||||
|
||||
|
|
|
@ -6512,15 +6512,15 @@ static void QCBUILTIN PF_clientcommand (pubprogfuncs_t *prinst, struct globalvar
|
|||
{
|
||||
client_t *oldhostclient = host_client;
|
||||
edict_t *oldsvplayer = sv_player;
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
//find client for this entity
|
||||
i = NUM_FOR_EDICT(prinst, G_EDICT(prinst, OFS_PARM0)) - 1;
|
||||
if (i < 0 || i >= sv.allocated_client_slots)
|
||||
i = NUM_FOR_EDICT(prinst, G_EDICT(prinst, OFS_PARM0));
|
||||
if (i <= 0 || i > sv.allocated_client_slots)
|
||||
PR_BIError(prinst, "PF_clientcommand: entity is not a client");
|
||||
else
|
||||
{
|
||||
host_client = &svs.clients[i];
|
||||
host_client = &svs.clients[i-1];
|
||||
sv_player = host_client->edict;
|
||||
if (host_client->state == cs_connected || host_client->state == cs_spawned)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,12 @@ void Draw_TextBox (int x, int y, int width, int lines)
|
|||
{
|
||||
}
|
||||
|
||||
char *TP_LocationName (vec3_t location)
|
||||
{
|
||||
static char locname[256];
|
||||
pGetLocationName(location, locname, sizeof(locname));
|
||||
return locname;
|
||||
}
|
||||
|
||||
|
||||
void Draw_SPic(float x, float y, mpic_t *pic, float scale)
|
||||
|
@ -224,9 +230,35 @@ int Sbar_BottomColor(player_info_t *pi)
|
|||
{
|
||||
return Sbar_ColorForMap(pi->bottomcolour);
|
||||
}
|
||||
int dehex(char nib)
|
||||
{
|
||||
if (nib >= '0' && nib <= '9')
|
||||
return nib - '0';
|
||||
if (nib >= 'a' && nib <= 'f')
|
||||
return nib - 'a' + 10;
|
||||
if (nib >= 'A' && nib <= 'F')
|
||||
return nib - 'A' + 10;
|
||||
return 0;
|
||||
}
|
||||
char *TP_ParseFunChars(char *str, qbool chat)
|
||||
{
|
||||
return str;
|
||||
static char resultbuf[1024];
|
||||
char *out = resultbuf, *end = resultbuf+sizeof(resultbuf)-1;
|
||||
|
||||
while (out < end)
|
||||
{
|
||||
if (str[0] == '$' && str[1] == 'x' && str[2] && str[3])
|
||||
{
|
||||
*out++ = (dehex(str[2]) << 4) | dehex(str[3]);
|
||||
str+=4;
|
||||
}
|
||||
else if (*str)
|
||||
*out++ = *str++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
*out = 0;
|
||||
return resultbuf;
|
||||
}
|
||||
char *TP_ItemName(unsigned int itbit)
|
||||
{
|
||||
|
@ -633,6 +665,7 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
CHECKBUILTIN(Cvar_GetNVFDG);
|
||||
if (BUILTINISVALID(Cvar_GetNVFDG) &&
|
||||
BUILTINISVALID(Draw_ImageSize) &&
|
||||
BUILTINISVALID(GetTeamInfo) &&
|
||||
Plug_Export("SbarBase", EZHud_Draw) &&
|
||||
Plug_Export("MenuEvent", EZHud_MenuEvent) &&
|
||||
Plug_Export("Tick", EZHud_Tick) &&
|
||||
|
|
|
@ -5265,19 +5265,15 @@ static void SCR_HUD_DrawTeamHoldInfo(hud_t *hud)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAXX
|
||||
static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxname, int maxloc, qbool width_only, hud_t *hud);
|
||||
#endif
|
||||
static int SCR_HudDrawTeamInfoPlayer(teamplayerinfo_t *ti_cl, int x, int y, int maxname, int maxloc, qbool width_only, hud_t *hud);
|
||||
|
||||
#ifdef HAXX
|
||||
#define FONTWIDTH 8
|
||||
static void SCR_HUD_DrawTeamInfo(hud_t *hud)
|
||||
{
|
||||
int x, y, _y, width, height;
|
||||
int i, j, k, slots[MAX_CLIENTS], slots_num, maxname, maxloc;
|
||||
int i, j, k, slots_num, maxname, maxloc;
|
||||
char tmp[1024], *nick;
|
||||
|
||||
// Used for hud_teaminfo, data is collected in screen.c / scr_teaminfo
|
||||
extern ti_player_t ti_clients[MAX_CLIENTS];
|
||||
teamplayerinfo_t ti_clients[MAX_CLIENTS];
|
||||
|
||||
extern qbool hud_editor;
|
||||
|
||||
|
@ -5302,45 +5298,29 @@ static void SCR_HUD_DrawTeamInfo(hud_t *hud)
|
|||
}
|
||||
|
||||
// Don't update hud item unless first view is beeing displayed
|
||||
if ( CURRVIEW != 1 && CURRVIEW != 0)
|
||||
return;
|
||||
// if ( CURRVIEW != 1 && CURRVIEW != 0)
|
||||
// return;
|
||||
|
||||
if (cls.mvdplayback)
|
||||
Update_TeamInfo();
|
||||
slots_num = pGetTeamInfo(ti_clients, countof(ti_clients), hud_teaminfo_show_enemies->ival, hud_teaminfo_show_self->ival);
|
||||
|
||||
// fill data we require to draw teaminfo
|
||||
for ( maxloc = maxname = slots_num = i = 0; i < MAX_CLIENTS; i++ ) {
|
||||
if ( !cl.players[i].name[0] || cl.players[i].spectator
|
||||
|| !ti_clients[i].time || ti_clients[i].time + 5 < cl.time
|
||||
)
|
||||
continue;
|
||||
|
||||
// do not show enemy players unless it's MVD and user wishes to show them
|
||||
if (VX_TrackerIsEnemy( i ) && (!cls.mvdplayback || !hud_teaminfo_show_enemies->integer))
|
||||
continue;
|
||||
|
||||
// do not show tracked player to spectator
|
||||
if ((cl.spectator && Cam_TrackNum() == i) && hud_teaminfo_show_self->integer == 0)
|
||||
continue;
|
||||
|
||||
for ( maxloc = maxname = i = 0; i < slots_num; i++ ) {
|
||||
// dynamically guess max length of name/location
|
||||
nick = (ti_clients[i].nick[0] ? ti_clients[i].nick : cl.players[i].name); // we use nick or name
|
||||
maxname = max(maxname, strlen(TP_ParseFunChars(nick, false)));
|
||||
|
||||
strlcpy(tmp, TP_LocationName(ti_clients[i].org), sizeof(tmp));
|
||||
maxloc = max(maxloc, strlen(TP_ParseFunChars(tmp, false)));
|
||||
|
||||
slots[slots_num++] = i;
|
||||
}
|
||||
|
||||
// well, better use fixed loc length
|
||||
maxloc = bound(0, hud_teaminfo_loc_width->integer, 100);
|
||||
maxloc = bound(0, hud_teaminfo_loc_width->ival, 100);
|
||||
// limit name length
|
||||
maxname = bound(0, maxname, hud_teaminfo_name_width->integer);
|
||||
maxname = bound(0, maxname, hud_teaminfo_name_width->ival);
|
||||
|
||||
// this does't draw anything, just calculate width
|
||||
width = FONTWIDTH * hud_teaminfo_scale->value * SCR_HudDrawTeamInfoPlayer(&ti_clients[0], 0, 0, maxname, maxloc, true, hud);
|
||||
height = FONTWIDTH * hud_teaminfo_scale->value * (hud_teaminfo_show_enemies->integer?slots_num+n_teams:slots_num);
|
||||
height = FONTWIDTH * hud_teaminfo_scale->value * (hud_teaminfo_show_enemies->ival?slots_num+n_teams:slots_num);
|
||||
|
||||
if (hud_editor)
|
||||
HUD_PrepareDraw(hud, width , FONTWIDTH, &x, &y);
|
||||
|
@ -5359,7 +5339,7 @@ static void SCR_HUD_DrawTeamInfo(hud_t *hud)
|
|||
|
||||
// If multiple teams are displayed then sort the display and print team header on overlay
|
||||
k=0;
|
||||
if (hud_teaminfo_show_enemies->integer)
|
||||
if (hud_teaminfo_show_enemies->ival)
|
||||
{
|
||||
while (sorted_teams[k].name)
|
||||
{
|
||||
|
@ -5369,10 +5349,10 @@ static void SCR_HUD_DrawTeamInfo(hud_t *hud)
|
|||
_y += FONTWIDTH * hud_teaminfo_scale->value;
|
||||
for ( j = 0; j < slots_num; j++ )
|
||||
{
|
||||
i = slots[j];
|
||||
i = ti_clients[j].client;
|
||||
if (!strcmp(cl.players[i].team,sorted_teams[k].name))
|
||||
{
|
||||
SCR_HudDrawTeamInfoPlayer(&ti_clients[i], x, _y, maxname, maxloc, false, hud);
|
||||
SCR_HudDrawTeamInfoPlayer(&ti_clients[j], x, _y, maxname, maxloc, false, hud);
|
||||
_y += FONTWIDTH * hud_teaminfo_scale->value;
|
||||
}
|
||||
}
|
||||
|
@ -5382,22 +5362,61 @@ static void SCR_HUD_DrawTeamInfo(hud_t *hud)
|
|||
else
|
||||
{
|
||||
for ( j = 0; j < slots_num; j++ ) {
|
||||
i = slots[j];
|
||||
SCR_HudDrawTeamInfoPlayer(&ti_clients[i], x, _y, maxname, maxloc, false, hud);
|
||||
SCR_HudDrawTeamInfoPlayer(&ti_clients[j], x, _y, maxname, maxloc, false, hud);
|
||||
_y += FONTWIDTH * hud_teaminfo_scale->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
qbool Has_Both_RL_and_LG (int flags) { return (flags & IT_ROCKET_LAUNCHER) && (flags & IT_LIGHTNING); }
|
||||
#ifdef HAXX
|
||||
static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxname, int maxloc, qbool width_only, hud_t *hud)
|
||||
#define FONTWIDTH 8
|
||||
void str_align_right (char *target, size_t size, const char *source, size_t length)
|
||||
{
|
||||
if (length > size - 1)
|
||||
length = size - 1;
|
||||
|
||||
if (strlen(source) >= length) {
|
||||
strlcpy(target, source, size);
|
||||
target[length] = 0;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length - strlen(source); i++) {
|
||||
target[i] = ' ';
|
||||
}
|
||||
|
||||
strlcpy(target + i, source, size - i);
|
||||
}
|
||||
}
|
||||
int Player_GetTrackId(int uid)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
unsigned int BestWeaponFromStatItems(unsigned int items)
|
||||
{
|
||||
int i;
|
||||
for (i = 1<<7; i; i>>=1)
|
||||
{
|
||||
if (items & i)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
mpic_t * SCR_GetWeaponIconByFlag (int flag)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0, j = 1; i < 7; i++, j*=2)
|
||||
{
|
||||
if (flag == j)
|
||||
return sb_weapons[0][i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static int SCR_HudDrawTeamInfoPlayer(teamplayerinfo_t *ti_cl, int x, int y, int maxname, int maxloc, qbool width_only, hud_t *hud)
|
||||
{
|
||||
extern mpic_t * SCR_GetWeaponIconByFlag (int flag);
|
||||
extern cvar_t tp_name_rlg;
|
||||
|
||||
char *s, *loc, tmp[1024], tmp2[MAX_MACRO_STRING], *aclr;
|
||||
char *s, *loc, tmp[1024], tmp2[1024], *aclr;
|
||||
int x_in = x; // save x
|
||||
int i;
|
||||
mpic_t *pic;
|
||||
|
@ -5442,11 +5461,11 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
break;
|
||||
case 'w': // draw "best" weapon icon/name
|
||||
|
||||
switch (HUD_FindVar(hud, "weapon_style")->integer) {
|
||||
switch (HUD_FindVar(hud, "weapon_style")->ival) {
|
||||
case 1:
|
||||
if(!width_only) {
|
||||
if (Has_Both_RL_and_LG(ti_cl->items)) {
|
||||
char *weap_str = tp_name_rlg.string;
|
||||
char *weap_str = pCvar_GetNVFDG("tp_name_rlg", "rlg", 0, NULL, NULL)->string;
|
||||
char weap_white_stripped[32];
|
||||
Util_SkipChars(weap_str, "{}", weap_white_stripped, 32);
|
||||
Draw_ColoredString (x, y, weap_white_stripped, false);
|
||||
|
@ -5475,7 +5494,7 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
case 'H': // draw health, padding with space on right side
|
||||
|
||||
if(!width_only) {
|
||||
snprintf(tmp, sizeof(tmp), (s[0] == 'h' ? "%s%3d" : "%s%-3d"), (ti_cl->health < HUD_FindVar(hud, "low_health")->integer ? "&cf00" : ""), ti_cl->health);
|
||||
snprintf(tmp, sizeof(tmp), (s[0] == 'h' ? "%s%3d" : "%s%-3d"), (ti_cl->health < HUD_FindVar(hud, "low_health")->ival ? "&cf00" : ""), (int)ti_cl->health);
|
||||
Draw_SString (x, y, tmp, scale);
|
||||
}
|
||||
x += 3 * FONTWIDTH * scale;
|
||||
|
@ -5489,7 +5508,7 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
//
|
||||
// different styles of armor
|
||||
//
|
||||
switch (HUD_FindVar(hud,"armor_style")->integer) {
|
||||
switch (HUD_FindVar(hud,"armor_style")->ival) {
|
||||
case 1: // image prefixed armor value
|
||||
if(!width_only) {
|
||||
if (ti_cl->items & IT_ARMOR3)
|
||||
|
@ -5546,7 +5565,7 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
}
|
||||
|
||||
if(!width_only) { // value drawed no matter which style
|
||||
snprintf(tmp, sizeof(tmp), (s[0] == 'a' ? "%s%3d" : "%s%-3d"), aclr, ti_cl->armor);
|
||||
snprintf(tmp, sizeof(tmp), (s[0] == 'a' ? "%s%3d" : "%s%-3d"), aclr, (int)ti_cl->armor);
|
||||
Draw_SString (x, y, tmp, scale);
|
||||
}
|
||||
x += 3 * FONTWIDTH * scale;
|
||||
|
@ -5566,7 +5585,7 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
|
||||
break;
|
||||
case 'p': // draw powerups
|
||||
switch (HUD_FindVar(hud, "powerup_style")->integer) {
|
||||
switch (HUD_FindVar(hud, "powerup_style")->ival) {
|
||||
case 1: // quad/pent/ring image
|
||||
if(!width_only) {
|
||||
if (ti_cl->items & IT_QUAD)
|
||||
|
@ -5658,7 +5677,6 @@ static int SCR_HudDrawTeamInfoPlayer(ti_player_t *ti_cl, int x, int y, int maxna
|
|||
|
||||
return (x - x_in) / (FONTWIDTH * scale); // return width
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAXX
|
||||
void SCR_HUD_DrawItemsClock(hud_t *hud)
|
||||
|
@ -8046,7 +8064,6 @@ void CommonDraw_Init(void)
|
|||
"maxname", "16",
|
||||
NULL);
|
||||
|
||||
#ifdef HAXX
|
||||
HUD_Register("teaminfo", NULL, "Show information about your team in short form.",
|
||||
0, ca_active, 0, SCR_HUD_DrawTeamInfo,
|
||||
"0", "", "right", "center", "0", "0", "0.2", "20 20 20", NULL,
|
||||
|
@ -8062,7 +8079,6 @@ void CommonDraw_Init(void)
|
|||
"scale","1",
|
||||
"powerup_style","1",
|
||||
NULL);
|
||||
#endif
|
||||
|
||||
HUD_Register("mp3_title", NULL, "Shows current mp3 playing.",
|
||||
HUD_PLUSMINUS, ca_disconnected, 0, SCR_HUD_DrawMP3_Title,
|
||||
|
|
|
@ -155,6 +155,10 @@ BUILTIN(void, SetUserInfo, (const char *key, const char *value));
|
|||
BUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,clients,maxclients,showenemies,showself
|
||||
BUILTINR(int, GetTeamInfo, (teamplayerinfo_t *clients, unsigned int maxclients, int showenemies, int showself));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,soundname
|
||||
BUILTIN(void, LocalSound, (const char *soundname));
|
||||
#undef ARGNAMES
|
||||
|
@ -423,6 +427,7 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(Menu_Control);
|
||||
CHECKBUILTIN(Key_GetKeyCode);
|
||||
CHECKBUILTIN(GetLocationName);
|
||||
CHECKBUILTIN(GetTeamInfo);
|
||||
CHECKBUILTIN(GetNetworkInfo);
|
||||
|
||||
//drawing routines
|
||||
|
|
|
@ -233,7 +233,17 @@ EBUILTIN(int, GetLocalPlayerNumbers, (int firstseat, int numseats, int *playernu
|
|||
EBUILTIN(void, GetServerInfo, (char *info, int infolen));
|
||||
EBUILTIN(void, SetUserInfo, (const char *key, const char *value));
|
||||
EBUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
EBUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int client;
|
||||
unsigned int items;
|
||||
float armor;
|
||||
float health;
|
||||
vec3_t org;
|
||||
char nick[16];
|
||||
} teamplayerinfo_t;
|
||||
EBUILTIN(int, GetTeamInfo, (teamplayerinfo_t *clients, unsigned int maxclients, int showenemies, int showself));
|
||||
|
||||
typedef struct {
|
||||
int seats;
|
||||
|
|
|
@ -15,6 +15,7 @@ int Q_vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs)
|
|||
int tokens=0;
|
||||
char *string;
|
||||
char tempbuffer[64];
|
||||
char sign;
|
||||
unsigned int _uint;
|
||||
int _int;
|
||||
float _float;
|
||||
|
@ -176,25 +177,22 @@ Con_Printf("%i bytes left\n", maxlen);
|
|||
}
|
||||
if (_int < 0)
|
||||
{
|
||||
if (maxlen-- == 0)
|
||||
{*buffer++='\0';return tokens;}
|
||||
*buffer++ = '-';
|
||||
sign = '-';
|
||||
_int *= -1;
|
||||
}
|
||||
else if (plus)
|
||||
{
|
||||
if (maxlen-- == 0)
|
||||
{*buffer++='\0';return tokens;}
|
||||
*buffer++ = '+';
|
||||
}
|
||||
sign = '+';
|
||||
else
|
||||
sign = 0;
|
||||
i = sizeof(tempbuffer)-2;
|
||||
tempbuffer[sizeof(tempbuffer)-1] = '\0';
|
||||
while(_int)
|
||||
{
|
||||
tempbuffer[i] = _int%10 + '0';
|
||||
tempbuffer[i--] = _int%10 + '0';
|
||||
_int/=10;
|
||||
i--;
|
||||
}
|
||||
if (sign)
|
||||
tempbuffer[i--] = sign;
|
||||
string = tempbuffer+i+1;
|
||||
|
||||
if (!*string)
|
||||
|
|
Loading…
Reference in a new issue