mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-28 14:41:57 +00:00
Added cl_autodemo cvar to automatically record games. 1 records multiview demos where possible, -1 strictly records singleview demos.
Enclosed mvd recording in ifdefs, so it can be disabled at compile-time for any mods that don't want to have to deal with it. Removed the recorded players thing. Allow csqc to use EF_FULLBRIGHT. Fix cl_pure to attempt to actually download missing packages. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5303 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
bf30886163
commit
5b7a426afe
48 changed files with 1331 additions and 795 deletions
|
@ -919,7 +919,7 @@ ifdef windir
|
||||||
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
||||||
SV_LDFLAGS=`$(SDLCONFIG) --static-libs`
|
SV_LDFLAGS=`$(SDLCONFIG) --static-libs`
|
||||||
else
|
else
|
||||||
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(SDLCONFIG) --static-libs`
|
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --static-libs`
|
||||||
VK_LDFLAGS=$(VKLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --static-libs`
|
VK_LDFLAGS=$(VKLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --static-libs`
|
||||||
M_LDFLAGS=$(MLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --static-libs`
|
M_LDFLAGS=$(MLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --static-libs`
|
||||||
SV_LDFLAGS=`$(SDLCONFIG) --static-libs`
|
SV_LDFLAGS=`$(SDLCONFIG) --static-libs`
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ void CL_Stop_f (void)
|
||||||
{
|
{
|
||||||
if (!cls.demorecording)
|
if (!cls.demorecording)
|
||||||
{
|
{
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||||
SV_MVDStop_f();
|
SV_MVDStop_f();
|
||||||
#else
|
#else
|
||||||
Con_Printf ("Not recording a demo.\n");
|
Con_Printf ("Not recording a demo.\n");
|
||||||
|
@ -1135,8 +1135,10 @@ void CL_WriteSetDemoMessage (void)
|
||||||
record a single player game.
|
record a single player game.
|
||||||
*/
|
*/
|
||||||
#ifndef CLIENTONLY
|
#ifndef CLIENTONLY
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
mvddest_t *SV_MVD_InitRecordFile (char *name);
|
mvddest_t *SV_MVD_InitRecordFile (char *name);
|
||||||
qboolean SV_MVD_Record (mvddest_t *dest);
|
qboolean SV_MVD_Record (mvddest_t *dest);
|
||||||
|
#endif
|
||||||
void CL_RecordMap_f (void)
|
void CL_RecordMap_f (void)
|
||||||
{
|
{
|
||||||
char demoname[MAX_QPATH];
|
char demoname[MAX_QPATH];
|
||||||
|
@ -1154,9 +1156,22 @@ void CL_RecordMap_f (void)
|
||||||
|
|
||||||
SV_SpawnServer (mapname, NULL, false, false);
|
SV_SpawnServer (mapname, NULL, false, false);
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
COM_DefaultExtension(demoname, ".mvd", sizeof(demoname));
|
COM_DefaultExtension(demoname, ".mvd", sizeof(demoname));
|
||||||
|
#else
|
||||||
|
COM_DefaultExtension(demoname, ".dem", sizeof(demoname));
|
||||||
|
#endif
|
||||||
COM_FileExtension(demoname, demoext, sizeof(demoext));
|
COM_FileExtension(demoname, demoext, sizeof(demoext));
|
||||||
|
|
||||||
|
#if defined(AVAIL_GZDEC) && !defined(CLIENTONLY)
|
||||||
|
{
|
||||||
|
extern cvar_t sv_demoAutoCompress;
|
||||||
|
if (sv_demoAutoCompress.ival)
|
||||||
|
Q_strncatz(demoname, ".gz", sizeof(demoname));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (!strcmp(demoext, "mvd"))
|
if (!strcmp(demoext, "mvd"))
|
||||||
{
|
{
|
||||||
if (!SV_MVD_Record (SV_MVD_InitRecordFile(demoname)))
|
if (!SV_MVD_Record (SV_MVD_InitRecordFile(demoname)))
|
||||||
|
@ -1165,6 +1180,7 @@ void CL_RecordMap_f (void)
|
||||||
// Cbuf_AddText(va("mvdrecord %s\n", COM_QuotedString(demoname, buf, sizeof(buf))), RESTRICT_LOCAL);
|
// Cbuf_AddText(va("mvdrecord %s\n", COM_QuotedString(demoname, buf, sizeof(buf))), RESTRICT_LOCAL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cls.demooutfile = FS_OpenVFS (demoname, "wb", FS_GAME);
|
cls.demooutfile = FS_OpenVFS (demoname, "wb", FS_GAME);
|
||||||
if (!cls.demooutfile)
|
if (!cls.demooutfile)
|
||||||
|
@ -1172,6 +1188,11 @@ void CL_RecordMap_f (void)
|
||||||
CL_Disconnect_f();
|
CL_Disconnect_f();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef AVAIL_GZDEC
|
||||||
|
if (!Q_strcasecmp(".gz", COM_GetFileExtension(demoname, NULL)))
|
||||||
|
cls.demooutfile = FS_GZ_WriteFilter(cls.demooutfile, true, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
if (!strcmp(demoext, "dem"))
|
if (!strcmp(demoext, "dem"))
|
||||||
{
|
{
|
||||||
|
@ -1197,10 +1218,10 @@ static void CLQW_RecordServerData(sizebuf_t *buf, int *seq)
|
||||||
// send the serverdata
|
// send the serverdata
|
||||||
MSG_WriteByte (buf, svc_serverdata);
|
MSG_WriteByte (buf, svc_serverdata);
|
||||||
#ifdef PROTOCOL_VERSION_FTE
|
#ifdef PROTOCOL_VERSION_FTE
|
||||||
if (cls.fteprotocolextensions) //maintain demo compatability
|
if (cls.fteprotocolextensions&~PEXT1_HIDEPROTOCOLS) //maintain demo compatability
|
||||||
{
|
{
|
||||||
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
||||||
MSG_WriteLong (buf, cls.fteprotocolextensions);
|
MSG_WriteLong (buf, cls.fteprotocolextensions&~PEXT1_HIDEPROTOCOLS);
|
||||||
}
|
}
|
||||||
if (cls.fteprotocolextensions2) //maintain demo compatability
|
if (cls.fteprotocolextensions2) //maintain demo compatability
|
||||||
{
|
{
|
||||||
|
@ -1308,6 +1329,7 @@ void CLNQ_WriteServerData(sizebuf_t *buf) //for demo recording
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *val;
|
const char *val;
|
||||||
|
|
||||||
|
//This is for compat with DP.
|
||||||
val = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs");
|
val = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogs");
|
||||||
if (*val)
|
if (*val)
|
||||||
{
|
{
|
||||||
|
@ -1328,10 +1350,10 @@ void CLNQ_WriteServerData(sizebuf_t *buf) //for demo recording
|
||||||
}
|
}
|
||||||
|
|
||||||
MSG_WriteByte(buf, svc_serverdata);
|
MSG_WriteByte(buf, svc_serverdata);
|
||||||
if (cls.fteprotocolextensions)
|
if (cls.fteprotocolextensions&~PEXT1_HIDEPROTOCOLS)
|
||||||
{
|
{
|
||||||
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
MSG_WriteLong (buf, PROTOCOL_VERSION_FTE);
|
||||||
MSG_WriteLong (buf, cls.fteprotocolextensions);
|
MSG_WriteLong (buf, cls.fteprotocolextensions&~PEXT1_HIDEPROTOCOLS);
|
||||||
}
|
}
|
||||||
if (cls.fteprotocolextensions2)
|
if (cls.fteprotocolextensions2)
|
||||||
{
|
{
|
||||||
|
@ -1365,6 +1387,8 @@ void CLNQ_WriteServerData(sizebuf_t *buf) //for demo recording
|
||||||
if (protmain == PROTOCOL_VERSION_RMQ)
|
if (protmain == PROTOCOL_VERSION_RMQ)
|
||||||
MSG_WriteLong (buf, protfl);
|
MSG_WriteLong (buf, protfl);
|
||||||
|
|
||||||
|
if (cls.fteprotocolextensions2 & PEXT2_PREDINFO)
|
||||||
|
MSG_WriteString(buf, FS_GetGamedir(true));
|
||||||
MSG_WriteByte (buf, cl.allocated_client_slots);
|
MSG_WriteByte (buf, cl.allocated_client_slots);
|
||||||
MSG_WriteByte (buf, cl.deathmatch?GAME_DEATHMATCH:GAME_COOP);
|
MSG_WriteByte (buf, cl.deathmatch?GAME_DEATHMATCH:GAME_COOP);
|
||||||
MSG_WriteString (buf, cl.levelname);
|
MSG_WriteString (buf, cl.levelname);
|
||||||
|
@ -1586,6 +1610,123 @@ static int CL_Record_Lightstyles(sizebuf_t *buf, int seq)
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send current status of all other players
|
||||||
|
static int CL_RecordInitialPlayers(sizebuf_t *buf, int seq, qboolean isnq)
|
||||||
|
{
|
||||||
|
char info[MAX_LOCALINFO_STRING];
|
||||||
|
player_info_t *player;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < cl.allocated_client_slots; i++)
|
||||||
|
{
|
||||||
|
player = cl.players + i;
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
|
||||||
|
if (player->frags != 0)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_updatefrags);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteShort(buf, player->frags);
|
||||||
|
}
|
||||||
|
if (isnq)
|
||||||
|
{
|
||||||
|
if (!*player->name)
|
||||||
|
continue;
|
||||||
|
MSG_WriteByte (buf, svc_updatename);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteString (buf, player->name);
|
||||||
|
|
||||||
|
MSG_WriteByte (buf, svc_updatecolors);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteByte (buf, player->rtopcolor*16+player->rbottomcolor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (player->ping != 0)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_updateping);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteShort (buf, player->ping);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->pl != 0)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_updatepl);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteByte (buf, player->pl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->userinfo.numkeys)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svc_updateentertime);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteFloat (buf, realtime - player->realentertime); //seconds since
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->userinfo.numkeys)
|
||||||
|
{
|
||||||
|
InfoBuf_ToString(&player->userinfo, info, min(buf->maxsize-buf->cursize-6, sizeof(info)), basicuserinfos, NULL, NULL, NULL, NULL);
|
||||||
|
MSG_WriteByte (buf, svc_updateuserinfo);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteLong (buf, player->userid);
|
||||||
|
MSG_WriteString (buf, info);
|
||||||
|
|
||||||
|
//spam svc_setinfo for all the infos that didn't fit.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
static int CL_RecordInitialStats(sizebuf_t *buf, int seq, qboolean isnq)
|
||||||
|
{
|
||||||
|
int seat, i;
|
||||||
|
for (seat = 0; seat < cl.splitclients; seat++)
|
||||||
|
{
|
||||||
|
//higher stats should be 0 and thus not be sent, if not valid.
|
||||||
|
for (i = 0; i < MAX_CL_STATS; i++)
|
||||||
|
{
|
||||||
|
if (cl.playerview[seat].stats[i] || cl.playerview[seat].statsf[i])
|
||||||
|
{
|
||||||
|
double fs = cl.playerview[seat].statsf[i];
|
||||||
|
double is = cl.playerview[seat].stats[i];
|
||||||
|
if (seat)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfte_choosesplitclient);
|
||||||
|
MSG_WriteByte (buf, seat);
|
||||||
|
}
|
||||||
|
if ((int)fs == is)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, isnq?svcnq_updatestatlong:svcqw_updatestatlong);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteLong (buf, is);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfte_updatestatfloat);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteLong (buf, fs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cl.playerview[seat].statsstr[i])
|
||||||
|
{
|
||||||
|
if (seat)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (buf, svcfte_choosesplitclient);
|
||||||
|
MSG_WriteByte (buf, seat);
|
||||||
|
}
|
||||||
|
MSG_WriteByte (buf, svcfte_updatestatstring);
|
||||||
|
MSG_WriteByte (buf, i);
|
||||||
|
MSG_WriteString (buf, cl.playerview[seat].statsstr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->cursize > buf->maxsize/2)
|
||||||
|
CL_WriteRecordDemoMessage (buf, seq++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
const char *Get_Q2ConfigString(int i);
|
const char *Get_Q2ConfigString(int i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1601,9 +1742,8 @@ void CL_Record_f (void)
|
||||||
char name[MAX_OSPATH];
|
char name[MAX_OSPATH];
|
||||||
sizebuf_t buf;
|
sizebuf_t buf;
|
||||||
char buf_data[MAX_OVERALLMSGLEN];
|
char buf_data[MAX_OVERALLMSGLEN];
|
||||||
int n, i, seat;
|
int n, i;
|
||||||
char *s, *p, *fname;
|
char *s, *p, *fname;
|
||||||
player_info_t *player;
|
|
||||||
extern char gamedirfile[];
|
extern char gamedirfile[];
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
const char *defaultext;
|
const char *defaultext;
|
||||||
|
@ -1653,7 +1793,7 @@ void CL_Record_f (void)
|
||||||
// They did.
|
// They did.
|
||||||
if ( s != NULL ) {
|
if ( s != NULL ) {
|
||||||
if (!Q_strcasecmp(s, defaultext))
|
if (!Q_strcasecmp(s, defaultext))
|
||||||
*s = 0; //hack away that extension that they added.
|
*s = 0; //hack away that extension that they added, so that we don't get dupes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1707,7 +1847,12 @@ void CL_Record_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the filename doesn't contain illegal characters
|
// Make sure the filename doesn't contain illegal characters
|
||||||
for (p=fname ; *p ; p++)
|
p=fname;
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
|
if (*sv_demoDir.string && !strncmp(p, sv_demoDir.string, strlen(sv_demoDir.string)) && p[strlen(sv_demoDir.string)] == '/')
|
||||||
|
p += strlen(sv_demoDir.string)+1; //allow a demos/ prefix (primarily because of autodemos)
|
||||||
|
#endif
|
||||||
|
for ( ; *p ; p++)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
*p &= 0x7F; // strip high bit
|
*p &= 0x7F; // strip high bit
|
||||||
|
@ -1716,10 +1861,18 @@ void CL_Record_f (void)
|
||||||
|| c=='<' || c=='>' || c=='"' || c=='.')
|
|| c=='<' || c=='>' || c=='"' || c=='.')
|
||||||
*p = '_';
|
*p = '_';
|
||||||
}
|
}
|
||||||
Q_strncpyz(name, fname, sizeof(name)-8);
|
Q_strncpyz(name, fname, sizeof(name)-4-strlen(defaultext));
|
||||||
|
|
||||||
|
#if defined(AVAIL_GZDEC) && !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||||
|
{
|
||||||
|
extern cvar_t sv_demoAutoCompress;
|
||||||
|
if (sv_demoAutoCompress.ival == 1 || !*sv_demoAutoCompress.string)
|
||||||
|
defaultext = va("%s.gz", defaultext);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//make a unique name (unless the user specified it).
|
//make a unique name (unless the user specified it).
|
||||||
strcat (name, defaultext); //we have the space
|
Q_strncatz(name, defaultext, sizeof(name));
|
||||||
if (c != 2)
|
if (c != 2)
|
||||||
{
|
{
|
||||||
vfsfile_t *f;
|
vfsfile_t *f;
|
||||||
|
@ -1728,7 +1881,7 @@ void CL_Record_f (void)
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
//remove the extension again
|
//remove the extension again
|
||||||
Q_strncpyz(name, fname, sizeof(name)-8);
|
Q_strncpyz(name, fname, sizeof(name)-4-strlen(defaultext));
|
||||||
p = name + strlen(name);
|
p = name + strlen(name);
|
||||||
strcat(p, "_XX");
|
strcat(p, "_XX");
|
||||||
strcat(p, defaultext);
|
strcat(p, defaultext);
|
||||||
|
@ -1737,8 +1890,8 @@ void CL_Record_f (void)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
VFS_CLOSE (f);
|
VFS_CLOSE (f);
|
||||||
p[0] = i%100 + '0';
|
p[0] = ((i/10)%10) + '0';
|
||||||
p[1] = i%10 + '0';
|
p[1] = (i%10) + '0';
|
||||||
f = FS_OpenVFS (name, "rb", FS_GAME);
|
f = FS_OpenVFS (name, "rb", FS_GAME);
|
||||||
i++;
|
i++;
|
||||||
} while (f && i < 100);
|
} while (f && i < 100);
|
||||||
|
@ -1748,12 +1901,18 @@ void CL_Record_f (void)
|
||||||
//
|
//
|
||||||
// open the demo file
|
// open the demo file
|
||||||
//
|
//
|
||||||
cls.demooutfile = FS_OpenVFS (name, "wb", FS_GAME);
|
cls.demooutfile = FS_OpenVFS (name, "wb", FS_GAMEONLY);
|
||||||
if (!cls.demooutfile)
|
if (!cls.demooutfile)
|
||||||
{
|
{
|
||||||
Con_Printf ("ERROR: couldn't open.\n");
|
Con_Printf ("ERROR: couldn't open.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AVAIL_GZDEC
|
||||||
|
if (!Q_strcasecmp(".gz", COM_GetFileExtension(name, NULL)))
|
||||||
|
cls.demooutfile = FS_GZ_WriteFilter(cls.demooutfile, true, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
cls.demohadkeyframe = false;
|
cls.demohadkeyframe = false;
|
||||||
|
|
||||||
Con_Printf ("recording to %s.\n", name);
|
Con_Printf ("recording to %s.\n", name);
|
||||||
|
@ -1903,100 +2062,9 @@ void CL_Record_f (void)
|
||||||
|
|
||||||
if (buf.cursize)
|
if (buf.cursize)
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
|
seq = CL_RecordInitialPlayers(&buf, seq, false);
|
||||||
// send current status of all other players
|
|
||||||
|
|
||||||
for (i = 0; i < cl.allocated_client_slots; i++)
|
|
||||||
{
|
|
||||||
player = cl.players + i;
|
|
||||||
|
|
||||||
if (player->frags != 0)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_updatefrags);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteShort (&buf, player->frags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->ping != 0)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_updateping);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteShort (&buf, player->ping);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->pl != 0)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_updatepl);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteByte (&buf, player->pl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->userinfo.numkeys)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svc_updateentertime);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteFloat (&buf, realtime - player->realentertime); //seconds since
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->userinfo.numkeys)
|
|
||||||
{
|
|
||||||
char info[MAX_LOCALINFO_STRING];
|
|
||||||
InfoBuf_ToString(&player->userinfo, info, sizeof(info), basicuserinfos, NULL, NULL, NULL, NULL);
|
|
||||||
MSG_WriteByte (&buf, svc_updateuserinfo);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteLong (&buf, player->userid);
|
|
||||||
MSG_WriteString (&buf, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
}
|
|
||||||
|
|
||||||
seq = CL_Record_Lightstyles(&buf, seq);
|
seq = CL_Record_Lightstyles(&buf, seq);
|
||||||
|
seq = CL_RecordInitialStats(&buf, seq, false);
|
||||||
for (seat = 0; seat < cl.splitclients; seat++)
|
|
||||||
{
|
|
||||||
//higher stats should be 0 and thus not be sent, if not valid.
|
|
||||||
for (i = 0; i < MAX_CL_STATS; i++)
|
|
||||||
{
|
|
||||||
if (cl.playerview[seat].stats[i] || cl.playerview[seat].statsf[i])
|
|
||||||
{
|
|
||||||
double fs = cl.playerview[seat].statsf[i];
|
|
||||||
double is = cl.playerview[seat].stats[i];
|
|
||||||
if (seat)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svcfte_choosesplitclient);
|
|
||||||
MSG_WriteByte (&buf, seat);
|
|
||||||
}
|
|
||||||
if ((int)fs == is)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svcqw_updatestatlong);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteLong (&buf, is);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svcfte_updatestatfloat);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteLong (&buf, fs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cl.playerview[seat].statsstr[i])
|
|
||||||
{
|
|
||||||
if (seat)
|
|
||||||
{
|
|
||||||
MSG_WriteByte (&buf, svcfte_choosesplitclient);
|
|
||||||
MSG_WriteByte (&buf, seat);
|
|
||||||
}
|
|
||||||
MSG_WriteByte (&buf, svcfte_updatestatstring);
|
|
||||||
MSG_WriteByte (&buf, i);
|
|
||||||
MSG_WriteString (&buf, cl.playerview[seat].statsstr[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf.cursize > buf.maxsize/2)
|
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the client to check and download skins
|
// get the client to check and download skins
|
||||||
// when that is completed, a begin command will be issued
|
// when that is completed, a begin command will be issued
|
||||||
|
@ -2075,9 +2143,9 @@ void CL_Record_f (void)
|
||||||
MSG_WriteByte (&buf, svcnq_signonnum);
|
MSG_WriteByte (&buf, svcnq_signonnum);
|
||||||
MSG_WriteByte (&buf, 2);
|
MSG_WriteByte (&buf, 2);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
//fixme: clients
|
seq = CL_RecordInitialPlayers(&buf, seq, true);
|
||||||
seq = CL_Record_Lightstyles(&buf, seq);
|
seq = CL_Record_Lightstyles(&buf, seq);
|
||||||
//fixme: stats
|
seq = CL_RecordInitialStats(&buf, seq, true);
|
||||||
MSG_WriteByte (&buf, svcnq_signonnum);
|
MSG_WriteByte (&buf, svcnq_signonnum);
|
||||||
MSG_WriteByte (&buf, 3);
|
MSG_WriteByte (&buf, 3);
|
||||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||||
|
@ -2089,6 +2157,10 @@ void CL_Record_f (void)
|
||||||
CL_Stop_f();
|
CL_Stop_f();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||||
|
if (cl.numackframes < sizeof(cl.ackframes)/sizeof(cl.ackframes[0]))
|
||||||
|
cl.ackframes[cl.numackframes++] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QDECL CompleteDemoList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
static int QDECL CompleteDemoList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||||
|
@ -2102,7 +2174,11 @@ void CL_DemoList_c(int argn, const char *partial, struct xcommandargcompletioncb
|
||||||
if (argn == 1)
|
if (argn == 1)
|
||||||
{
|
{
|
||||||
COM_EnumerateFiles(va("%s*.qwd", partial), CompleteDemoList, ctx);
|
COM_EnumerateFiles(va("%s*.qwd", partial), CompleteDemoList, ctx);
|
||||||
|
COM_EnumerateFiles(va("%s*.qwd.gz", partial), CompleteDemoList, ctx);
|
||||||
|
#ifdef NQPROT
|
||||||
COM_EnumerateFiles(va("%s*.dem", partial), CompleteDemoList, ctx);
|
COM_EnumerateFiles(va("%s*.dem", partial), CompleteDemoList, ctx);
|
||||||
|
COM_EnumerateFiles(va("%s*.dem.gz", partial), CompleteDemoList, ctx);
|
||||||
|
#endif
|
||||||
COM_EnumerateFiles(va("%s*.mvd", partial), CompleteDemoList, ctx);
|
COM_EnumerateFiles(va("%s*.mvd", partial), CompleteDemoList, ctx);
|
||||||
COM_EnumerateFiles(va("%s*.mvd.gz", partial), CompleteDemoList, ctx);
|
COM_EnumerateFiles(va("%s*.mvd.gz", partial), CompleteDemoList, ctx);
|
||||||
|
|
||||||
|
@ -2181,6 +2257,11 @@ void CL_ReRecord_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AVAIL_GZDEC
|
||||||
|
if (!Q_strcasecmp(".gz", COM_GetFileExtension(name, NULL)))
|
||||||
|
cls.demooutfile = FS_GZ_WriteFilter(cls.demooutfile, true, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
Con_Printf ("recording to %s.\n", name);
|
Con_Printf ("recording to %s.\n", name);
|
||||||
|
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
|
@ -2497,7 +2578,7 @@ void CL_PlayDemo(char *demoname, qboolean usesystempath)
|
||||||
Q_strncpyz (cls.lastdemoname, demoname, sizeof(cls.lastdemoname));
|
Q_strncpyz (cls.lastdemoname, demoname, sizeof(cls.lastdemoname));
|
||||||
|
|
||||||
#ifdef AVAIL_GZDEC
|
#ifdef AVAIL_GZDEC
|
||||||
if (strlen(name) >= 3 && !Q_strcasecmp(name + strlen(name) - 3, ".gz"))
|
if (!strcmp(COM_GetFileExtension(name,NULL), ".gz"))
|
||||||
f = FS_DecompressGZip(f, NULL);
|
f = FS_DecompressGZip(f, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4002,6 +4002,7 @@ void CL_LinkPacketEntities (void)
|
||||||
modelflags = model->flags;
|
modelflags = model->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (cl.model_precache_vwep[0] && state->modelindex2 < MAX_VWEP_MODELS)
|
if (cl.model_precache_vwep[0] && state->modelindex2 < MAX_VWEP_MODELS)
|
||||||
{
|
{
|
||||||
if (state->modelindex == cl_playerindex && cl.model_precache_vwep[0]->loadstate == MLS_LOADED &&
|
if (state->modelindex == cl_playerindex && cl.model_precache_vwep[0]->loadstate == MLS_LOADED &&
|
||||||
|
@ -4013,7 +4014,9 @@ void CL_LinkPacketEntities (void)
|
||||||
else
|
else
|
||||||
model2 = NULL;
|
model2 = NULL;
|
||||||
}
|
}
|
||||||
else if (state->modelindex2 && state->modelindex2 < MAX_PRECACHE_MODELS)
|
else
|
||||||
|
#endif
|
||||||
|
if (state->modelindex2 && state->modelindex2 < MAX_PRECACHE_MODELS)
|
||||||
model2 = cl.model_precache[state->modelindex2];
|
model2 = cl.model_precache[state->modelindex2];
|
||||||
else
|
else
|
||||||
model2 = NULL;
|
model2 = NULL;
|
||||||
|
@ -4972,7 +4975,9 @@ void CL_LinkPlayers (void)
|
||||||
static int flickertime;
|
static int flickertime;
|
||||||
static int flicker;
|
static int flicker;
|
||||||
float predictmsmult = 1000*cl_predict_players_frac.value;
|
float predictmsmult = 1000*cl_predict_players_frac.value;
|
||||||
|
#ifndef NOLEGACY
|
||||||
int modelindex2;
|
int modelindex2;
|
||||||
|
#endif
|
||||||
extern cvar_t cl_demospeed;
|
extern cvar_t cl_demospeed;
|
||||||
int displayseq;
|
int displayseq;
|
||||||
|
|
||||||
|
@ -5023,15 +5028,19 @@ void CL_LinkPlayers (void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//the extra modelindex check is to stop lame mods from using vweps with rings
|
//the extra modelindex check is to stop lame mods from using vweps with rings
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (state->command.impulse && cl.model_precache_vwep[0] && cl.model_precache_vwep[0]->type != mod_dummy && state->modelindex == cl_playerindex)
|
if (state->command.impulse && cl.model_precache_vwep[0] && cl.model_precache_vwep[0]->type != mod_dummy && state->modelindex == cl_playerindex)
|
||||||
{
|
{
|
||||||
model = cl.model_precache_vwep[0];
|
model = cl.model_precache_vwep[0];
|
||||||
modelindex2 = state->command.impulse;
|
modelindex2 = state->command.impulse;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
model = cl.model_precache[state->modelindex];
|
model = cl.model_precache[state->modelindex];
|
||||||
|
#ifndef NOLEGACY
|
||||||
modelindex2 = 0;
|
modelindex2 = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// spawn light flashes, even ones coming from invisible objects
|
// spawn light flashes, even ones coming from invisible objects
|
||||||
|
@ -5221,8 +5230,10 @@ void CL_LinkPlayers (void)
|
||||||
CL_AddFlagModels (ent, 0);
|
CL_AddFlagModels (ent, 0);
|
||||||
else if (state->effects & QWEF_FLAG2)
|
else if (state->effects & QWEF_FLAG2)
|
||||||
CL_AddFlagModels (ent, 1);
|
CL_AddFlagModels (ent, 1);
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (modelindex2)
|
if (modelindex2)
|
||||||
CL_AddVWeapModel (ent, cl.model_precache_vwep[modelindex2]);
|
CL_AddVWeapModel (ent, cl.model_precache_vwep[modelindex2]);
|
||||||
|
#endif
|
||||||
|
|
||||||
CLQ1_AddShadow(ent);
|
CLQ1_AddShadow(ent);
|
||||||
CLQ1_AddPowerupShell(ent, false, state->effects);
|
CLQ1_AddPowerupShell(ent, false, state->effects);
|
||||||
|
|
|
@ -390,6 +390,17 @@ void CL_MakeActive(char *gamename)
|
||||||
SCR_EndLoadingPlaque();
|
SCR_EndLoadingPlaque();
|
||||||
CL_UpdateWindowTitle();
|
CL_UpdateWindowTitle();
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
|
if (sv_demoAutoRecord.ival && !sv.mvdrecording && !cls.demorecording && !cls.demoplayback && MVD_CheckSpace(false))
|
||||||
|
{ //don't auto-record if we're already recording... or playing a different demo.
|
||||||
|
extern cvar_t sv_demoAutoPrefix;
|
||||||
|
char timestamp[64];
|
||||||
|
time_t tm = time(NULL);
|
||||||
|
strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", localtime(&tm));
|
||||||
|
Cbuf_AddText(va("record %s%s%s%s_%s\n", sv_demoDir.string, *sv_demoDir.string?"/":"", sv_demoAutoPrefix.string, host_mapname.string, timestamp), RESTRICT_LOCAL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TP_ExecTrigger("f_begin", true);
|
TP_ExecTrigger("f_begin", true);
|
||||||
if (cls.demoplayback)
|
if (cls.demoplayback)
|
||||||
TP_ExecTrigger("f_spawndemo", true);
|
TP_ExecTrigger("f_spawndemo", true);
|
||||||
|
@ -1445,8 +1456,7 @@ void CL_Rcon_f (void)
|
||||||
{
|
{
|
||||||
char cryptpass[1024], crypttime[64];
|
char cryptpass[1024], crypttime[64];
|
||||||
const char *hex = "0123456789ABCDEF"; //must be upper-case for compat with mvdsv.
|
const char *hex = "0123456789ABCDEF"; //must be upper-case for compat with mvdsv.
|
||||||
time_t clienttime;
|
time_t clienttime = time(NULL);
|
||||||
time(&clienttime);
|
|
||||||
size_t digestsize;
|
size_t digestsize;
|
||||||
unsigned char digest[64];
|
unsigned char digest[64];
|
||||||
const unsigned char **tokens = alloca(sizeof(*tokens)*(4+Cmd_Argc()*2));
|
const unsigned char **tokens = alloca(sizeof(*tokens)*(4+Cmd_Argc()*2));
|
||||||
|
|
|
@ -829,6 +829,7 @@ void CL_DownloadFinished(qdownload_t *dl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef NOLEGACY
|
||||||
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(cl.model_name_vwep[i], filename))
|
if (!strcmp(cl.model_name_vwep[i], filename))
|
||||||
|
@ -837,6 +838,7 @@ void CL_DownloadFinished(qdownload_t *dl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
S_ResetFailedLoad(); //okay, so this can still get a little spammy in bad places...
|
S_ResetFailedLoad(); //okay, so this can still get a little spammy in bad places...
|
||||||
|
|
||||||
|
@ -1163,6 +1165,7 @@ static void Model_CheckDownloads (void)
|
||||||
CL_CheckModelResources(s);
|
CL_CheckModelResources(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
||||||
{
|
{
|
||||||
s = cl.model_name_vwep[i];
|
s = cl.model_name_vwep[i];
|
||||||
|
@ -1176,6 +1179,7 @@ static void Model_CheckDownloads (void)
|
||||||
CL_CheckOrEnqueDownloadFile(s, s, 0);
|
CL_CheckOrEnqueDownloadFile(s, s, 0);
|
||||||
CL_CheckModelResources(s);
|
CL_CheckModelResources(s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CL_LoadModels(int stage, qboolean dontactuallyload)
|
static int CL_LoadModels(int stage, qboolean dontactuallyload)
|
||||||
|
@ -1300,6 +1304,7 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload)
|
||||||
endstage();
|
endstage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef NOLEGACY
|
||||||
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
for (i = 0; i < MAX_VWEP_MODELS; i++)
|
||||||
{
|
{
|
||||||
if (!cl.model_name_vwep[i][0])
|
if (!cl.model_name_vwep[i][0])
|
||||||
|
@ -1317,6 +1322,7 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload)
|
||||||
endstage();
|
endstage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1609,6 +1615,7 @@ void CL_RequestNextDownload (void)
|
||||||
|
|
||||||
if (!cl.contentstage)
|
if (!cl.contentstage)
|
||||||
{
|
{
|
||||||
|
int pure;
|
||||||
stage = 0;
|
stage = 0;
|
||||||
stage = CL_LoadModels(stage, true);
|
stage = CL_LoadModels(stage, true);
|
||||||
stage = CL_LoadSounds(stage, true);
|
stage = CL_LoadSounds(stage, true);
|
||||||
|
@ -1616,8 +1623,12 @@ void CL_RequestNextDownload (void)
|
||||||
cl.contentstage = 0;
|
cl.contentstage = 0;
|
||||||
|
|
||||||
//might be safer to do it later, but kinder to do it before wasting time.
|
//might be safer to do it later, but kinder to do it before wasting time.
|
||||||
if (!FS_PureOkay())
|
pure = FS_PureOkay();
|
||||||
{
|
if (pure < 0 || (pure==0 && (cls.download || cl.downloadlist)))
|
||||||
|
return; //we're downloading something and may still be able to satisfy it.
|
||||||
|
if (pure == 0 && !cls.demoplayback)
|
||||||
|
{ //failure!
|
||||||
|
Con_Printf(CON_ERROR"You are missing pure packages, and they could not be autodownloaded.\nYou may need to purchase an update.\n");
|
||||||
#ifdef HAVE_MEDIA_ENCODER
|
#ifdef HAVE_MEDIA_ENCODER
|
||||||
if (cls.demoplayback && Media_Capturing())
|
if (cls.demoplayback && Media_Capturing())
|
||||||
{
|
{
|
||||||
|
@ -4108,8 +4119,10 @@ static void CL_ParseModellist (qboolean lots)
|
||||||
cl_spikeindex = nummodels;
|
cl_spikeindex = nummodels;
|
||||||
if (!strcmp(cl.model_name[nummodels],"progs/player.mdl"))
|
if (!strcmp(cl.model_name[nummodels],"progs/player.mdl"))
|
||||||
cl_playerindex = nummodels;
|
cl_playerindex = nummodels;
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (*cl.model_name_vwep[0] && !strcmp(cl.model_name[nummodels],cl.model_name_vwep[0]) && cl_playerindex == -1)
|
if (*cl.model_name_vwep[0] && !strcmp(cl.model_name[nummodels],cl.model_name_vwep[0]) && cl_playerindex == -1)
|
||||||
cl_playerindex = nummodels;
|
cl_playerindex = nummodels;
|
||||||
|
#endif
|
||||||
if (!strcmp(cl.model_name[nummodels],"progs/h_player.mdl"))
|
if (!strcmp(cl.model_name[nummodels],"progs/h_player.mdl"))
|
||||||
cl_h_playerindex = nummodels;
|
cl_h_playerindex = nummodels;
|
||||||
if (!strcmp(cl.model_name[nummodels],"progs/flag.mdl"))
|
if (!strcmp(cl.model_name[nummodels],"progs/flag.mdl"))
|
||||||
|
@ -6303,6 +6316,7 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
|
||||||
cl.serverpakschanged = true;
|
cl.serverpakschanged = true;
|
||||||
CL_CheckServerPacks();
|
CL_CheckServerPacks();
|
||||||
}
|
}
|
||||||
|
#ifndef NOLEGACY
|
||||||
else if (!strncmp(stufftext, "//vwep ", 7)) //list of vwep model indexes, because using the normal model precaches wasn't cool enough
|
else if (!strncmp(stufftext, "//vwep ", 7)) //list of vwep model indexes, because using the normal model precaches wasn't cool enough
|
||||||
{ //(from zquake/ezquake)
|
{ //(from zquake/ezquake)
|
||||||
int i;
|
int i;
|
||||||
|
@ -6323,6 +6337,7 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (cls.demoplayback && !strncmp(stufftext, "playdemo ", 9))
|
else if (cls.demoplayback && !strncmp(stufftext, "playdemo ", 9))
|
||||||
{ //some demos (like speed-demos-archive's marathon runs) chain multiple demos with playdemo commands
|
{ //some demos (like speed-demos-archive's marathon runs) chain multiple demos with playdemo commands
|
||||||
//these should still chain properly even when the demo is in some archive(like .dz) or subdir
|
//these should still chain properly even when the demo is in some archive(like .dz) or subdir
|
||||||
|
|
|
@ -1077,22 +1077,33 @@ void CL_ParseTEnt (void)
|
||||||
case TENQ_BEAM:
|
case TENQ_BEAM:
|
||||||
type = TEQW_BEAM;
|
type = TEQW_BEAM;
|
||||||
break;
|
break;
|
||||||
case TENQ_EXPLOSION_SPRITE:
|
case TENQ_QWEXPLOSION:
|
||||||
type = TE_EXPLOSION;
|
type = TEQW_QWEXPLOSION;
|
||||||
break;
|
break;
|
||||||
case TE_EXPLOSION:
|
case TENQ_NQEXPLOSION:
|
||||||
type = TEQW_EXPLOSION_NOSPRITE;
|
type = TEQW_NQEXPLOSION;
|
||||||
break;
|
break;
|
||||||
case TE_GUNSHOT:
|
case TENQ_NQGUNSHOT:
|
||||||
type = TE_GUNSHOT_NQCOMPAT;
|
type = TEQW_NQGUNSHOT;
|
||||||
break;
|
break;
|
||||||
case TE_GUNSHOT_NQCOMPAT:
|
case TENQ_QWGUNSHOT:
|
||||||
type = TE_GUNSHOT;
|
type = TEQW_QWGUNSHOT;
|
||||||
break;
|
break;
|
||||||
|
case TENQ_RAILTRAIL:
|
||||||
|
type = TEQW_RAILTRAIL;
|
||||||
|
break;
|
||||||
|
case TENQ_NEHLIGHTNING4:
|
||||||
|
type = TEQW_NEHLIGHTNING4;
|
||||||
|
break;
|
||||||
|
// case TENQ_NEHSMOKE:
|
||||||
|
// type = TEQW_NEHSMOKE;
|
||||||
|
// break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//else QW values
|
||||||
|
|
||||||
//right, nq vs qw doesn't matter now, supposedly.
|
//right, nq vs qw doesn't matter now, supposedly.
|
||||||
|
|
||||||
|
@ -1103,15 +1114,14 @@ void CL_ParseTEnt (void)
|
||||||
"tarexplosion", "lightning1", "lightning2", "wizspike",
|
"tarexplosion", "lightning1", "lightning2", "wizspike",
|
||||||
"knightspike", "lightning3", "lavasplash", "teleport",
|
"knightspike", "lightning3", "lavasplash", "teleport",
|
||||||
"blood", "lightningblood", "bullet", "superbullet", //bullets deprecated
|
"blood", "lightningblood", "bullet", "superbullet", //bullets deprecated
|
||||||
"railtrail", "beam", "explosion2", "nqexplosion",
|
"neh_explosion3", "railtrail/neh_lightning4", "beam", "explosion2",
|
||||||
"nqgunshot", "?", "?", "?",
|
"nqexplosion", "nqgunshot", "?", "?",
|
||||||
#ifdef HEXEN2
|
#ifdef HEXEN2
|
||||||
"h2lightsml", "h2chain", "h2sunstf1", "h2sunstf2",
|
"h2lightsml", "h2chain", "h2sunstf1", "h2sunstf2",
|
||||||
"h2light", "h2cb", "h2ic", "h2gaze",
|
"h2light", "h2cb", "h2ic", "h2gaze",
|
||||||
"h2famine", "h2partexp"
|
"h2famine", "h2partexp"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type < countof(te_names))
|
if (type < countof(te_names))
|
||||||
Con_Printf(" te_%s\n", te_names[type]);
|
Con_Printf(" te_%s\n", te_names[type]);
|
||||||
else
|
else
|
||||||
|
@ -1274,7 +1284,7 @@ void CL_ParseTEnt (void)
|
||||||
S_StartSound (0, 0, cl_sfx_ric3, pos, NULL, 1, 1, 0, 0, 0);
|
S_StartSound (0, 0, cl_sfx_ric3, pos, NULL, 1, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TE_SUPERBULLET:
|
case TEQW_SUPERBULLET:
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
pos[1] = MSG_ReadCoord ();
|
pos[1] = MSG_ReadCoord ();
|
||||||
pos[2] = MSG_ReadCoord ();
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
@ -1342,8 +1352,8 @@ void CL_ParseTEnt (void)
|
||||||
ex->endalpha = ex->startalpha; //don't fade out
|
ex->endalpha = ex->startalpha; //don't fade out
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TEQW_EXPLOSION_NOSPRITE: //nq-style, no sprite
|
case TEQW_NQEXPLOSION: //nq-style, no sprite
|
||||||
case TE_EXPLOSION: //qw-style, with (optional) sprite
|
case TEQW_QWEXPLOSION: //qw-style, with (optional) sprite
|
||||||
// particles
|
// particles
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
pos[1] = MSG_ReadCoord ();
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
@ -1375,7 +1385,7 @@ void CL_ParseTEnt (void)
|
||||||
S_StartSound (0, 0, cl_sfx_r_exp3, pos, NULL, 1, 1, 0, 0, 0);
|
S_StartSound (0, 0, cl_sfx_r_exp3, pos, NULL, 1, 1, 0, 0, 0);
|
||||||
|
|
||||||
// sprite
|
// sprite
|
||||||
if (type == TE_EXPLOSION && cl_expsprite.ival) // temp hopefully
|
if (type == TEQW_QWEXPLOSION && cl_expsprite.ival) // temp hopefully
|
||||||
{
|
{
|
||||||
explosion_t *ex = CL_AllocExplosion (pos);
|
explosion_t *ex = CL_AllocExplosion (pos);
|
||||||
ex->start = cl.time;
|
ex->start = cl.time;
|
||||||
|
@ -1411,6 +1421,7 @@ void CL_ParseTEnt (void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TE_EXPLOSION3_NEH:
|
||||||
case TEDP_EXPLOSIONRGB:
|
case TEDP_EXPLOSIONRGB:
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
pos[1] = MSG_ReadCoord ();
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
@ -1420,6 +1431,18 @@ void CL_ParseTEnt (void)
|
||||||
|
|
||||||
if (cl_legacystains.ival) Surf_AddStain(pos, -1, -1, -1, 100);
|
if (cl_legacystains.ival) Surf_AddStain(pos, -1, -1, -1, 100);
|
||||||
|
|
||||||
|
if (type == TEDP_EXPLOSIONRGB)
|
||||||
|
{
|
||||||
|
pos2[0] = MSG_ReadByte()/255.0;
|
||||||
|
pos2[1] = MSG_ReadByte()/255.0;
|
||||||
|
pos2[2] = MSG_ReadByte()/255.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //TE_EXPLOSION3_NEH
|
||||||
|
pos2[0] = MSG_ReadCoord();
|
||||||
|
pos2[1] = MSG_ReadCoord();
|
||||||
|
pos2[2] = MSG_ReadCoord();
|
||||||
|
}
|
||||||
|
|
||||||
// light
|
// light
|
||||||
if (r_explosionlight.value)
|
if (r_explosionlight.value)
|
||||||
|
@ -1430,9 +1453,9 @@ void CL_ParseTEnt (void)
|
||||||
dl->die = cl.time + 0.5;
|
dl->die = cl.time + 0.5;
|
||||||
dl->decay = 300;
|
dl->decay = 300;
|
||||||
|
|
||||||
dl->color[0] = 0.4f*MSG_ReadByte()/255.0f;
|
dl->color[0] = 0.4f*pos2[0];
|
||||||
dl->color[1] = 0.4f*MSG_ReadByte()/255.0f;
|
dl->color[1] = 0.4f*pos2[1];
|
||||||
dl->color[2] = 0.4f*MSG_ReadByte()/255.0f;
|
dl->color[2] = 0.4f*pos2[2];
|
||||||
dl->channelfade[0] = 0;
|
dl->channelfade[0] = 0;
|
||||||
dl->channelfade[1] = 0;
|
dl->channelfade[1] = 0;
|
||||||
dl->channelfade[2] = 0;
|
dl->channelfade[2] = 0;
|
||||||
|
@ -1490,6 +1513,11 @@ void CL_ParseTEnt (void)
|
||||||
case TE_LIGHTNING3: // lightning bolts
|
case TE_LIGHTNING3: // lightning bolts
|
||||||
CL_ParseBeam (BT_Q1LIGHTNING3);
|
CL_ParseBeam (BT_Q1LIGHTNING3);
|
||||||
break;
|
break;
|
||||||
|
case TEQW_NEHLIGHTNING4:
|
||||||
|
Con_DPrintf("TEQW_NEHLIGHTNING4 not implemented\n");
|
||||||
|
MSG_ReadString();
|
||||||
|
CL_ParseBeam (BT_Q1LIGHTNING2);
|
||||||
|
break;
|
||||||
|
|
||||||
case TE_LAVASPLASH:
|
case TE_LAVASPLASH:
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
|
@ -1518,9 +1546,9 @@ void CL_ParseTEnt (void)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_GUNSHOT: // bullet hitting wall
|
case TEQW_QWGUNSHOT: // bullet hitting wall
|
||||||
case TE_GUNSHOT_NQCOMPAT:
|
case TEQW_NQGUNSHOT:
|
||||||
if (type == TE_GUNSHOT_NQCOMPAT)
|
if (type == TEQW_NQGUNSHOT)
|
||||||
cnt = 1;
|
cnt = 1;
|
||||||
else
|
else
|
||||||
cnt = MSG_ReadByte ();
|
cnt = MSG_ReadByte ();
|
||||||
|
@ -1535,7 +1563,7 @@ void CL_ParseTEnt (void)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TEQW_BLOOD: // bullets hitting body
|
case TEQW_QWBLOOD: // bullets hitting body
|
||||||
cnt = MSG_ReadByte ();
|
cnt = MSG_ReadByte ();
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
pos[1] = MSG_ReadCoord ();
|
pos[1] = MSG_ReadCoord ();
|
||||||
|
@ -1565,7 +1593,7 @@ void CL_ParseTEnt (void)
|
||||||
CL_ParseBeam (BT_Q1BEAM);
|
CL_ParseBeam (BT_Q1BEAM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TE_RAILTRAIL:
|
case TEQW_RAILTRAIL:
|
||||||
pos[0] = MSG_ReadCoord ();
|
pos[0] = MSG_ReadCoord ();
|
||||||
pos[1] = MSG_ReadCoord ();
|
pos[1] = MSG_ReadCoord ();
|
||||||
pos[2] = MSG_ReadCoord ();
|
pos[2] = MSG_ReadCoord ();
|
||||||
|
@ -1836,6 +1864,11 @@ void CL_ParseTEnt (void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// case TEQW_NEHRAILTRAIL:
|
||||||
|
// case TEQW_NEHEXPLOSION3:
|
||||||
|
// case TEQW_NEHLIGHTNING4:
|
||||||
|
// case TEQW_NEHSMOKE:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Host_EndGame ("CL_ParseTEnt: bad type - %i", type);
|
Host_EndGame ("CL_ParseTEnt: bad type - %i", type);
|
||||||
}
|
}
|
||||||
|
@ -2438,7 +2471,7 @@ void CL_SmokeAndFlash(vec3_t origin)
|
||||||
ex = CL_AllocExplosion (origin);
|
ex = CL_AllocExplosion (origin);
|
||||||
VectorClear(ex->angles);
|
VectorClear(ex->angles);
|
||||||
// ex->type = ex_flash;
|
// ex->type = ex_flash;
|
||||||
ex->flags = Q2RF_FULLBRIGHT;
|
ex->flags = RF_FULLBRIGHT;
|
||||||
ex->numframes = 2;
|
ex->numframes = 2;
|
||||||
ex->start = cl.time;
|
ex->start = cl.time;
|
||||||
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_flash].modelname, MLV_WARN);
|
ex->model = Mod_ForName (q2tentmodels[q2cl_mod_flash].modelname, MLV_WARN);
|
||||||
|
@ -2648,7 +2681,7 @@ void CLQ2_ParseTEnt (void)
|
||||||
case CRTE_BLASTER_MUZZLEFLASH:
|
case CRTE_BLASTER_MUZZLEFLASH:
|
||||||
MSG_ReadPos (pos);
|
MSG_ReadPos (pos);
|
||||||
ex = CL_AllocExplosion (pos);
|
ex = CL_AllocExplosion (pos);
|
||||||
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
|
ex->flags = RF_FULLBRIGHT|RF_NOSHADOW;
|
||||||
ex->start = cl.q2frame.servertime - 100;
|
ex->start = cl.q2frame.servertime - 100;
|
||||||
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0.1*5, 0*5);
|
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0.1*5, 0*5);
|
||||||
P_RunParticleEffectTypeString(pos, NULL, 1, "te_muzzleflash");
|
P_RunParticleEffectTypeString(pos, NULL, 1, "te_muzzleflash");
|
||||||
|
@ -2656,7 +2689,7 @@ void CLQ2_ParseTEnt (void)
|
||||||
case CRTE_BLUE_MUZZLEFLASH:
|
case CRTE_BLUE_MUZZLEFLASH:
|
||||||
MSG_ReadPos (pos);
|
MSG_ReadPos (pos);
|
||||||
ex = CL_AllocExplosion (pos);
|
ex = CL_AllocExplosion (pos);
|
||||||
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
|
ex->flags = RF_FULLBRIGHT|RF_NOSHADOW;
|
||||||
ex->start = cl.q2frame.servertime - 100;
|
ex->start = cl.q2frame.servertime - 100;
|
||||||
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0.1*5, 0*5);
|
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0.1*5, 0*5);
|
||||||
P_RunParticleEffectTypeString(pos, NULL, 1, "te_blue_muzzleflash");
|
P_RunParticleEffectTypeString(pos, NULL, 1, "te_blue_muzzleflash");
|
||||||
|
@ -2664,7 +2697,7 @@ void CLQ2_ParseTEnt (void)
|
||||||
case CRTE_SMART_MUZZLEFLASH:
|
case CRTE_SMART_MUZZLEFLASH:
|
||||||
MSG_ReadPos (pos);
|
MSG_ReadPos (pos);
|
||||||
ex = CL_AllocExplosion (pos);
|
ex = CL_AllocExplosion (pos);
|
||||||
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
|
ex->flags = RF_FULLBRIGHT|RF_NOSHADOW;
|
||||||
ex->start = cl.q2frame.servertime - 100;
|
ex->start = cl.q2frame.servertime - 100;
|
||||||
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0*5, 0.2*5);
|
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0*5, 0.2*5);
|
||||||
P_RunParticleEffectTypeString(pos, NULL, 1, "te_smart_muzzleflash");
|
P_RunParticleEffectTypeString(pos, NULL, 1, "te_smart_muzzleflash");
|
||||||
|
@ -2675,7 +2708,7 @@ void CLQ2_ParseTEnt (void)
|
||||||
MSG_ReadPos (pos);
|
MSG_ReadPos (pos);
|
||||||
ex = CL_AllocExplosion (pos);
|
ex = CL_AllocExplosion (pos);
|
||||||
VectorCopy (pos, ex->origin);
|
VectorCopy (pos, ex->origin);
|
||||||
ex->flags = Q2RF_FULLBRIGHT|RF_NOSHADOW;
|
ex->flags = RF_FULLBRIGHT|RF_NOSHADOW;
|
||||||
ex->start = cl.q2frame.servertime - 100;
|
ex->start = cl.q2frame.servertime - 100;
|
||||||
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0*5, 0.2*5);
|
CL_NewDlight(0, pos, 350, 0.5, 0.2*5, 0*5, 0.2*5);
|
||||||
P_RunParticleEffectTypeString(pos, NULL, 1, "te_deathfield");
|
P_RunParticleEffectTypeString(pos, NULL, 1, "te_deathfield");
|
||||||
|
|
|
@ -844,10 +844,17 @@ typedef struct
|
||||||
//
|
//
|
||||||
// information that is static for the entire time connected to a server
|
// information that is static for the entire time connected to a server
|
||||||
//
|
//
|
||||||
|
#ifndef NOLEGACY
|
||||||
char model_name_vwep[MAX_VWEP_MODELS][MAX_QPATH];
|
char model_name_vwep[MAX_VWEP_MODELS][MAX_QPATH];
|
||||||
|
struct model_s *model_precache_vwep[MAX_VWEP_MODELS];
|
||||||
|
#endif
|
||||||
char model_name[MAX_PRECACHE_MODELS][MAX_QPATH];
|
char model_name[MAX_PRECACHE_MODELS][MAX_QPATH];
|
||||||
|
struct model_s *model_precache[MAX_PRECACHE_MODELS];
|
||||||
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
|
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
|
||||||
|
struct sfx_s *sound_precache[MAX_PRECACHE_SOUNDS];
|
||||||
char *particle_ssname[MAX_SSPARTICLESPRE];
|
char *particle_ssname[MAX_SSPARTICLESPRE];
|
||||||
|
int particle_ssprecache[MAX_SSPARTICLESPRE]; //these are actually 1-based, so 0 can be used to lazy-init them. I cheat.
|
||||||
|
|
||||||
#ifdef Q2CLIENT
|
#ifdef Q2CLIENT
|
||||||
char *configstring_general[Q2MAX_CLIENTS|Q2MAX_GENERAL];
|
char *configstring_general[Q2MAX_CLIENTS|Q2MAX_GENERAL];
|
||||||
char *image_name[Q2MAX_IMAGES];
|
char *image_name[Q2MAX_IMAGES];
|
||||||
|
@ -855,11 +862,6 @@ typedef struct
|
||||||
short inventory[MAX_SPLITS][Q2MAX_ITEMS];
|
short inventory[MAX_SPLITS][Q2MAX_ITEMS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct model_s *model_precache_vwep[MAX_VWEP_MODELS];
|
|
||||||
struct model_s *model_precache[MAX_PRECACHE_MODELS];
|
|
||||||
struct sfx_s *sound_precache[MAX_PRECACHE_SOUNDS];
|
|
||||||
int particle_ssprecache[MAX_SSPARTICLESPRE]; //these are actually 1-based, so 0 can be used to lazy-init them. I cheat.
|
|
||||||
|
|
||||||
char model_csqcname[MAX_CSMODELS][MAX_QPATH];
|
char model_csqcname[MAX_CSMODELS][MAX_QPATH];
|
||||||
struct model_s *model_csqcprecache[MAX_CSMODELS];
|
struct model_s *model_csqcprecache[MAX_CSMODELS];
|
||||||
char *particle_csname[MAX_CSPARTICLESPRE];
|
char *particle_csname[MAX_CSPARTICLESPRE];
|
||||||
|
|
|
@ -2615,6 +2615,7 @@ void Con_DrawConsole (int lines, qboolean noback)
|
||||||
{
|
{
|
||||||
char *tiptext = NULL;
|
char *tiptext = NULL;
|
||||||
shader_t *shader = NULL;
|
shader_t *shader = NULL;
|
||||||
|
model_t *model = NULL;
|
||||||
char *mouseover;
|
char *mouseover;
|
||||||
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
|
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
|
||||||
{
|
{
|
||||||
|
@ -2662,13 +2663,20 @@ void Con_DrawConsole (int lines, qboolean noback)
|
||||||
shader->height = 240;
|
shader->height = 240;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
key = Info_ValueForKey(info, "modelviewer");
|
||||||
|
if (*key)
|
||||||
|
{
|
||||||
|
model = Mod_ForName(key, MLV_WARN);
|
||||||
|
if (model->loadstate != MLS_LOADED)
|
||||||
|
model = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tiptext = Info_ValueForKey(info, "tip");
|
tiptext = Info_ValueForKey(info, "tip");
|
||||||
}
|
}
|
||||||
Z_Free(mouseover);
|
Z_Free(mouseover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tiptext && *tiptext) || shader)
|
if ((tiptext && *tiptext) || shader || model)
|
||||||
{
|
{
|
||||||
//FIXME: draw a proper background.
|
//FIXME: draw a proper background.
|
||||||
//FIXME: support line breaks.
|
//FIXME: support line breaks.
|
||||||
|
@ -2683,7 +2691,12 @@ void Con_DrawConsole (int lines, qboolean noback)
|
||||||
lines = Font_LineBreaks(buffer, COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false), (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
|
lines = Font_LineBreaks(buffer, COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false), (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
|
||||||
th = (Font_CharHeight()*lines * vid.height) / vid.pixelheight;
|
th = (Font_CharHeight()*lines * vid.height) / vid.pixelheight;
|
||||||
|
|
||||||
if (shader)
|
if (model)
|
||||||
|
{
|
||||||
|
iw = 128;
|
||||||
|
ih = 128;
|
||||||
|
}
|
||||||
|
else if (shader)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
if (R_GetShaderSizes(shader, &w, &h, false) >= 0)
|
if (R_GetShaderSizes(shader, &w, &h, false) >= 0)
|
||||||
|
@ -2726,6 +2739,94 @@ void Con_DrawConsole (int lines, qboolean noback)
|
||||||
}
|
}
|
||||||
Font_EndString(font_console);
|
Font_EndString(font_console);
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
|
playerview_t pv;
|
||||||
|
entity_t ent;
|
||||||
|
vec3_t fwd, rgt, up;
|
||||||
|
vec3_t lightpos = {0, 1, 0};
|
||||||
|
|
||||||
|
if (R2D_Flush)
|
||||||
|
R2D_Flush();
|
||||||
|
|
||||||
|
memset(&pv, 0, sizeof(pv));
|
||||||
|
|
||||||
|
CL_DecayLights ();
|
||||||
|
CL_ClearEntityLists();
|
||||||
|
V_ClearRefdef(&pv);
|
||||||
|
r_refdef.drawsbar = false;
|
||||||
|
V_CalcRefdef(&pv);
|
||||||
|
|
||||||
|
r_refdef.grect.width = iw;
|
||||||
|
r_refdef.grect.height = ih;
|
||||||
|
r_refdef.grect.x = x-8-iw;
|
||||||
|
r_refdef.grect.y = y+((th>ih)?(th-ih)/2:0);
|
||||||
|
r_refdef.time = realtime;
|
||||||
|
|
||||||
|
r_refdef.flags = RDF_NOWORLDMODEL;
|
||||||
|
|
||||||
|
r_refdef.afov = 60;
|
||||||
|
r_refdef.fov_x = 0;
|
||||||
|
r_refdef.fov_y = 0;
|
||||||
|
r_refdef.dirty |= RDFD_FOV;
|
||||||
|
|
||||||
|
VectorClear(r_refdef.viewangles);
|
||||||
|
r_refdef.viewangles[0] = 20;
|
||||||
|
r_refdef.viewangles[1] = realtime * 90;
|
||||||
|
AngleVectors(r_refdef.viewangles, fwd, rgt, up);
|
||||||
|
VectorScale(fwd, -64, r_refdef.vieworg);
|
||||||
|
|
||||||
|
memset(&ent, 0, sizeof(ent));
|
||||||
|
ent.scale = 1;
|
||||||
|
// ent.angles[1] = realtime*45;//mods->yaw;
|
||||||
|
// ent.angles[0] = realtime*23.4;//mods->pitch;
|
||||||
|
|
||||||
|
ent.angles[0]*=r_meshpitch.value;
|
||||||
|
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
|
||||||
|
ent.angles[0]*=r_meshpitch.value;
|
||||||
|
VectorInverse(ent.axis[1]);
|
||||||
|
|
||||||
|
ent.model = model;
|
||||||
|
if (!ent.model)
|
||||||
|
return; //panic!
|
||||||
|
ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
|
||||||
|
Vector4Set(ent.shaderRGBAf, 1, 1, 1, 1);
|
||||||
|
/*if (strstr(model->name, "player"))
|
||||||
|
{
|
||||||
|
ent.bottomcolour = genhsv(realtime*0.1 + 0, 1, 1);
|
||||||
|
ent.topcolour = genhsv(realtime*0.1 + 0.5, 1, 1);
|
||||||
|
}
|
||||||
|
else*/
|
||||||
|
{
|
||||||
|
ent.topcolour = TOP_DEFAULT;
|
||||||
|
ent.bottomcolour = BOTTOM_DEFAULT;
|
||||||
|
}
|
||||||
|
// ent.fatness = sin(realtime)*5;
|
||||||
|
ent.playerindex = -1;
|
||||||
|
ent.skinnum = 0;
|
||||||
|
ent.shaderTime = 0;//realtime;
|
||||||
|
ent.framestate.g[FS_REG].lerpweight[0] = 1;
|
||||||
|
// ent.framestate.g[FS_REG].frame[0] = animationnum;
|
||||||
|
ent.framestate.g[FS_REG].frametime[0] = ent.framestate.g[FS_REG].frametime[1] = realtime;
|
||||||
|
ent.framestate.g[FS_REG].endbone = 0x7fffffff;
|
||||||
|
// ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
|
||||||
|
|
||||||
|
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
|
||||||
|
ent.light_range[0] = ent.light_range[1] = ent.light_range[2] = 0.33;
|
||||||
|
|
||||||
|
V_ApplyRefdef();
|
||||||
|
|
||||||
|
VectorNormalize(lightpos);
|
||||||
|
ent.light_dir[0] = DotProduct(lightpos, ent.axis[0]);
|
||||||
|
ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]);
|
||||||
|
ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]);
|
||||||
|
|
||||||
|
ent.light_known = 2;
|
||||||
|
|
||||||
|
V_AddEntity(&ent);
|
||||||
|
|
||||||
|
R_RenderView();
|
||||||
|
}
|
||||||
if (shader)
|
if (shader)
|
||||||
{
|
{
|
||||||
if (th > ih)
|
if (th > ih)
|
||||||
|
|
|
@ -229,6 +229,50 @@ void M_Menu_Options_f (void)
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||||
|
extern cvar_t sv_demoAutoRecord;
|
||||||
|
static const char *autorecordopts[] = {
|
||||||
|
"Off",
|
||||||
|
"Singleview",
|
||||||
|
"Multiview",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static const char *autorecordvals[] = {
|
||||||
|
"0",
|
||||||
|
"-1",
|
||||||
|
"1",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
extern cvar_t cl_loopbackprotocol;
|
||||||
|
static const char *lprotopts[] = {
|
||||||
|
"Vanilla QW",
|
||||||
|
"FTE QW (recommended)",
|
||||||
|
#ifdef NQPROT
|
||||||
|
"FTE NQ",
|
||||||
|
"666",
|
||||||
|
"BJP3",
|
||||||
|
// "DP6",
|
||||||
|
// "DP7",
|
||||||
|
"Automatic (FTE NQ/QW)",
|
||||||
|
"Vanilla NQ",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
static const char *lprotvals[] = {
|
||||||
|
"qwid",
|
||||||
|
"qw",
|
||||||
|
#ifdef NQPROT
|
||||||
|
"nq",
|
||||||
|
"fitz",
|
||||||
|
"bjp3",
|
||||||
|
// "dp6",
|
||||||
|
// "dp7",
|
||||||
|
"auto",
|
||||||
|
"nqid",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
menubulk_t bulk[] = {
|
menubulk_t bulk[] = {
|
||||||
MB_CONSOLECMD("Customize controls", "menu_keys\n", "Modify keyboard and mouse inputs."),
|
MB_CONSOLECMD("Customize controls", "menu_keys\n", "Modify keyboard and mouse inputs."),
|
||||||
|
@ -250,6 +294,10 @@ void M_Menu_Options_f (void)
|
||||||
MB_CHECKBOXCVAR("Windowed Mouse", _windowed_mouse, 0),
|
MB_CHECKBOXCVAR("Windowed Mouse", _windowed_mouse, 0),
|
||||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||||
MB_COMBOCVAR("Auto Save", sv_autosave, autosaveopts, autosavevals, NULL),
|
MB_COMBOCVAR("Auto Save", sv_autosave, autosaveopts, autosavevals, NULL),
|
||||||
|
#endif
|
||||||
|
#if !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||||
|
MB_COMBOCVAR("Auto Record", sv_demoAutoRecord, autorecordopts, autorecordvals, NULL),
|
||||||
|
MB_COMBOCVAR("Force Protocol", cl_loopbackprotocol, lprotopts, lprotvals, "Some protocols may impose additional limitations/breakages, and are listed only for potential demo-recording compat."),
|
||||||
#endif
|
#endif
|
||||||
MB_SPACING(4),
|
MB_SPACING(4),
|
||||||
// removed hud options (cl_sbar, cl_hudswap, old-style chat, old-style msg)
|
// removed hud options (cl_sbar, cl_hudswap, old-style chat, old-style msg)
|
||||||
|
@ -904,7 +952,7 @@ const char *presetexec[] =
|
||||||
"r_bloom 1;"
|
"r_bloom 1;"
|
||||||
"r_deluxemapping 0;" //won't be seen anyway
|
"r_deluxemapping 0;" //won't be seen anyway
|
||||||
"r_particledesc \"high tsshaft\";"
|
"r_particledesc \"high tsshaft\";"
|
||||||
"r_waterstyle 3;"
|
// "r_waterstyle 3;" //too expensive.
|
||||||
"r_glsl_offsetmapping 1;"
|
"r_glsl_offsetmapping 1;"
|
||||||
"r_shadow_realtime_world 1;"
|
"r_shadow_realtime_world 1;"
|
||||||
"gl_texture_anisotropic_filtering 16;"
|
"gl_texture_anisotropic_filtering 16;"
|
||||||
|
|
|
@ -1009,6 +1009,31 @@ void M_Demo_Reselect(demomenu_t *info, const char *name)
|
||||||
|
|
||||||
void M_Menu_Demos_f (void)
|
void M_Menu_Demos_f (void)
|
||||||
{
|
{
|
||||||
|
char *demoexts[] = {
|
||||||
|
".mvd", ".mvd.gz",
|
||||||
|
".qwz", ".qwz.gz",
|
||||||
|
#ifdef NQPROT
|
||||||
|
".dem", ".dem.gz",
|
||||||
|
#endif
|
||||||
|
#ifdef Q2CLIENT
|
||||||
|
".dm2", ".dm2.gz"
|
||||||
|
#endif
|
||||||
|
//there are also qizmo demos (.qwz) out there...
|
||||||
|
//we don't support them, but if we were to ask quizmo to decode them for us, we could do.
|
||||||
|
};
|
||||||
|
char *archiveexts[] = {
|
||||||
|
#ifdef PACKAGE_PK3
|
||||||
|
".zip", ".pk3", ".pk4",
|
||||||
|
#endif
|
||||||
|
#ifdef PACKAGE_Q1PAK
|
||||||
|
".pak",
|
||||||
|
#endif
|
||||||
|
#ifdef PACKAGE_DZIP
|
||||||
|
".dz",
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
size_t u;
|
||||||
demomenu_t *info;
|
demomenu_t *info;
|
||||||
menu_t *menu;
|
menu_t *menu;
|
||||||
static demoloc_t mediareenterloc = {FS_GAME, "demos/"};
|
static demoloc_t mediareenterloc = {FS_GAME, "demos/"};
|
||||||
|
@ -1038,36 +1063,20 @@ void M_Menu_Demos_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
info->numext = 0;
|
info->numext = 0;
|
||||||
|
for (u = 0; u < countof(demoexts); u++)
|
||||||
|
{
|
||||||
info->command[info->numext] = "closemenu;playdemo";
|
info->command[info->numext] = "closemenu;playdemo";
|
||||||
info->ext[info->numext++] = ".qwd";
|
info->ext[info->numext++] = demoexts[u];
|
||||||
info->command[info->numext] = "closemenu;playdemo";
|
}
|
||||||
info->ext[info->numext++] = ".dem";
|
|
||||||
info->command[info->numext] = "closemenu;playdemo";
|
|
||||||
info->ext[info->numext++] = ".dm2";
|
|
||||||
info->command[info->numext] = "closemenu;playdemo";
|
|
||||||
info->ext[info->numext++] = ".mvd";
|
|
||||||
info->command[info->numext] = "closemenu;playdemo";
|
|
||||||
info->ext[info->numext++] = ".mvd.gz";
|
|
||||||
//there are also qizmo demos (.qwz) out there...
|
|
||||||
//we don't support them, but if we were to ask quizmo to decode them for us, we could do.
|
|
||||||
|
|
||||||
//and some archive formats... for the luls
|
//and some archive formats... for the luls
|
||||||
#ifdef PACKAGE_PK3
|
for (u = 0; u < countof(archiveexts); u++)
|
||||||
|
{
|
||||||
|
if (archiveexts[u])
|
||||||
|
continue;
|
||||||
info->command[info->numext] = NULL;
|
info->command[info->numext] = NULL;
|
||||||
info->ext[info->numext++] = ".zip";
|
info->ext[info->numext++] = archiveexts[u];
|
||||||
info->command[info->numext] = NULL;
|
}
|
||||||
info->ext[info->numext++] = ".pk3";
|
|
||||||
info->command[info->numext] = NULL;
|
|
||||||
info->ext[info->numext++] = ".pk4";
|
|
||||||
#endif
|
|
||||||
#ifdef PACKAGE_Q1PAK
|
|
||||||
info->command[info->numext] = NULL;
|
|
||||||
info->ext[info->numext++] = ".pak";
|
|
||||||
#endif
|
|
||||||
#ifdef PACKAGE_DZIP
|
|
||||||
info->command[info->numext] = NULL;
|
|
||||||
info->ext[info->numext++] = ".dz";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MC_AddWhiteText(menu, 24, 170, 8, "Choose a Demo", false);
|
MC_AddWhiteText(menu, 24, 170, 8, "Choose a Demo", false);
|
||||||
MC_AddWhiteText(menu, 16, 170, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false);
|
MC_AddWhiteText(menu, 16, 170, 24, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f", false);
|
||||||
|
|
|
@ -369,6 +369,16 @@ typedef struct texnums_s {
|
||||||
texid_t fullbright;
|
texid_t fullbright;
|
||||||
texid_t reflectcube;
|
texid_t reflectcube;
|
||||||
texid_t reflectmask;
|
texid_t reflectmask;
|
||||||
|
|
||||||
|
//the material's pushconstants. vulkan guarentees only 128 bytes. so 8 vec4s. note that lmscales should want 4 of them...
|
||||||
|
/*struct
|
||||||
|
{
|
||||||
|
vec4_t basefactors;
|
||||||
|
vec4_t specfactors;
|
||||||
|
vec4_t fullbrightfactors;
|
||||||
|
|
||||||
|
//FIXME: envmap index, lightmap index, etc.
|
||||||
|
} factors;*/
|
||||||
} texnums_t;
|
} texnums_t;
|
||||||
|
|
||||||
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
|
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
|
||||||
|
|
|
@ -1636,7 +1636,7 @@ parsefluid:
|
||||||
else if (!Q_strncasecmp(e, "transparent", 11))
|
else if (!Q_strncasecmp(e, "transparent", 11))
|
||||||
mod->rflags |= RF_TRANSLUCENT; //force blend
|
mod->rflags |= RF_TRANSLUCENT; //force blend
|
||||||
else if (!Q_strncasecmp(e, "fullbright", 10))
|
else if (!Q_strncasecmp(e, "fullbright", 10))
|
||||||
mod->rflags |= Q2RF_FULLBRIGHT; //fullbright, woo
|
mod->rflags |= RF_FULLBRIGHT; //fullbright, woo
|
||||||
else if (!Q_strncasecmp(e, "shadow", 6))
|
else if (!Q_strncasecmp(e, "shadow", 6))
|
||||||
mod->rflags &= ~RF_NOSHADOW; //clear noshadow
|
mod->rflags &= ~RF_NOSHADOW; //clear noshadow
|
||||||
else if (!Q_strncasecmp(e, "noshadow", 8))
|
else if (!Q_strncasecmp(e, "noshadow", 8))
|
||||||
|
@ -2378,7 +2378,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
|
||||||
Q_strncatz(outstr, " additive", outstrlen);
|
Q_strncatz(outstr, " additive", outstrlen);
|
||||||
if (ptype->models[i].rflags&RF_TRANSLUCENT)
|
if (ptype->models[i].rflags&RF_TRANSLUCENT)
|
||||||
Q_strncatz(outstr, " transparent", outstrlen);
|
Q_strncatz(outstr, " transparent", outstrlen);
|
||||||
if (ptype->models[i].rflags&Q2RF_FULLBRIGHT)
|
if (ptype->models[i].rflags&RF_FULLBRIGHT)
|
||||||
Q_strncatz(outstr, " fullbright", outstrlen);
|
Q_strncatz(outstr, " fullbright", outstrlen);
|
||||||
if (ptype->models[i].rflags&RF_NOSHADOW)
|
if (ptype->models[i].rflags&RF_NOSHADOW)
|
||||||
Q_strncatz(outstr, " noshadow", outstrlen);
|
Q_strncatz(outstr, " noshadow", outstrlen);
|
||||||
|
|
|
@ -876,6 +876,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
|
||||||
}
|
}
|
||||||
|
|
||||||
effects = in->v->effects;
|
effects = in->v->effects;
|
||||||
|
if (effects & EF_FULLBRIGHT)
|
||||||
|
out->flags |= RF_FULLBRIGHT;
|
||||||
if (effects & NQEF_ADDITIVE)
|
if (effects & NQEF_ADDITIVE)
|
||||||
out->flags |= RF_ADDITIVE;
|
out->flags |= RF_ADDITIVE;
|
||||||
if (effects & EF_NOSHADOW)
|
if (effects & EF_NOSHADOW)
|
||||||
|
@ -7022,7 +7024,7 @@ void *PDECL CSQC_PRLoadFile (const char *path, unsigned char *(PDECL *buf_get)(v
|
||||||
//also kinda irrelevant with sv_pure.
|
//also kinda irrelevant with sv_pure.
|
||||||
#ifndef FTE_TARGET_WEB
|
#ifndef FTE_TARGET_WEB
|
||||||
if (file
|
if (file
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||||
&& !sv_demo_write_csqc.ival
|
&& !sv_demo_write_csqc.ival
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
|
|
|
@ -464,7 +464,7 @@ cvar_t gl_screenangle = CVAR("gl_screenangle", "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VKQUAKE
|
#ifdef VKQUAKE
|
||||||
cvar_t vk_stagingbuffers = CVARD ("vk_stagingbuffers", "", "Configures which dynamic buffers are copied into gpu memory for rendering, instead of reading from shared memory. Empty for default settings.\nAccepted chars are u, e, v, 0.");
|
cvar_t vk_stagingbuffers = CVARFD ("vk_stagingbuffers", "", CVAR_RENDERERLATCH, "Configures which dynamic buffers are copied into gpu memory for rendering, instead of reading from shared memory. Empty for default settings.\nAccepted chars are u, e, v, 0.");
|
||||||
cvar_t vk_submissionthread = CVARD ("vk_submissionthread", "", "Execute submits+presents on a thread dedicated to executing them. This may be a significant speedup on certain drivers.");
|
cvar_t vk_submissionthread = CVARD ("vk_submissionthread", "", "Execute submits+presents on a thread dedicated to executing them. This may be a significant speedup on certain drivers.");
|
||||||
cvar_t vk_debug = CVARFD("vk_debug", "0", CVAR_VIDEOLATCH, "Register a debug handler to display driver/layer messages. 2 enables the standard validation layers.");
|
cvar_t vk_debug = CVARFD("vk_debug", "0", CVAR_VIDEOLATCH, "Register a debug handler to display driver/layer messages. 2 enables the standard validation layers.");
|
||||||
cvar_t vk_dualqueue = CVARFD("vk_dualqueue", "", CVAR_VIDEOLATCH, "Attempt to use a separate queue for presentation. Blank for default.");
|
cvar_t vk_dualqueue = CVARFD("vk_dualqueue", "", CVAR_VIDEOLATCH, "Attempt to use a separate queue for presentation. Blank for default.");
|
||||||
|
@ -1731,6 +1731,7 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
|
||||||
cl.model_precache[i] = Mod_FindName (Mod_FixName(cl.model_name[i], cl.model_name[1]));
|
cl.model_precache[i] = Mod_FindName (Mod_FixName(cl.model_name[i], cl.model_name[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
for (i=0; i < MAX_VWEP_MODELS; i++)
|
for (i=0; i < MAX_VWEP_MODELS; i++)
|
||||||
{
|
{
|
||||||
if (*cl.model_name_vwep[i])
|
if (*cl.model_name_vwep[i])
|
||||||
|
@ -1738,6 +1739,7 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
|
||||||
else
|
else
|
||||||
cl.model_precache_vwep[i] = NULL;
|
cl.model_precache_vwep[i] = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CSQC_DAT
|
#ifdef CSQC_DAT
|
||||||
for (i=1 ; i<MAX_CSMODELS ; i++)
|
for (i=1 ; i<MAX_CSMODELS ; i++)
|
||||||
|
@ -1815,7 +1817,7 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
||||||
|
|
||||||
void R_ReloadRenderer_f (void)
|
void R_ReloadRenderer_f (void)
|
||||||
{
|
{
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && (defined(Q2BSPS) || defined(Q3BSPS))
|
||||||
void *portalblob = NULL;
|
void *portalblob = NULL;
|
||||||
size_t portalsize = 0;
|
size_t portalsize = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1824,7 +1826,7 @@ void R_ReloadRenderer_f (void)
|
||||||
if (qrenderer == QR_NONE || qrenderer == QR_HEADLESS)
|
if (qrenderer == QR_NONE || qrenderer == QR_HEADLESS)
|
||||||
return; //don't bother reloading the renderer if its not actually rendering anything anyway.
|
return; //don't bother reloading the renderer if its not actually rendering anything anyway.
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && (defined(Q2BSPS) || defined(Q3BSPS))
|
||||||
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
|
@ -1841,7 +1843,7 @@ void R_ReloadRenderer_f (void)
|
||||||
R_ApplyRenderer_Load(NULL);
|
R_ApplyRenderer_Load(NULL);
|
||||||
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
Cvar_ApplyCallbacks(CVAR_RENDERERCALLBACK);
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && (defined(Q2BSPS) || defined(Q3BSPS))
|
||||||
if (portalblob)
|
if (portalblob)
|
||||||
{
|
{
|
||||||
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
|
@ -2076,7 +2078,7 @@ void R_RestartRenderer (rendererstate_t *newr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && (defined(Q2BSPS) || defined(Q3BSPS))
|
||||||
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.state == ss_active && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
{
|
{
|
||||||
void *t;
|
void *t;
|
||||||
|
@ -2160,7 +2162,7 @@ void R_RestartRenderer (rendererstate_t *newr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CLIENTONLY
|
#if !defined(CLIENTONLY) && (defined(Q2BSPS) || defined(Q3BSPS))
|
||||||
if (portalblob)
|
if (portalblob)
|
||||||
{
|
{
|
||||||
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
if (sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
|
|
|
@ -972,9 +972,6 @@ static qboolean OpenAL_InitLibrary(void)
|
||||||
firefoxstaticsounds = !!strstr(emscripten_run_script_string("navigator.userAgent"), "Firefox");
|
firefoxstaticsounds = !!strstr(emscripten_run_script_string("navigator.userAgent"), "Firefox");
|
||||||
if (firefoxstaticsounds)
|
if (firefoxstaticsounds)
|
||||||
Con_DPrintf("Firefox detected - disabling static sounds to avoid SORRY, I CAN'T HEAR YOU\n");
|
Con_DPrintf("Firefox detected - disabling static sounds to avoid SORRY, I CAN'T HEAR YOU\n");
|
||||||
#else
|
|
||||||
if (COM_CheckParm("-noopenal"))
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENAL_STATIC
|
#ifdef OPENAL_STATIC
|
||||||
|
@ -1019,6 +1016,9 @@ static qboolean OpenAL_InitLibrary(void)
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (COM_CheckParm("-noopenal"))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!openallib_tried)
|
if (!openallib_tried)
|
||||||
{
|
{
|
||||||
openallib_tried = true;
|
openallib_tried = true;
|
||||||
|
|
|
@ -3117,6 +3117,15 @@ static const char *If_Token_Term(const char *func, const char **end)
|
||||||
level++;
|
level++;
|
||||||
s2++;
|
s2++;
|
||||||
}
|
}
|
||||||
|
if (!level)
|
||||||
|
{
|
||||||
|
char *t = malloc(s2-s+1);
|
||||||
|
memcpy(t, s, s2-s);
|
||||||
|
t[s2-s-((s2==s)?0:1)] = 0;
|
||||||
|
func = If_Token(t, end, IF_PRI_MAX);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
else
|
||||||
func = If_Token(s, end, IF_PRI_MAX);
|
func = If_Token(s, end, IF_PRI_MAX);
|
||||||
*end = s2;
|
*end = s2;
|
||||||
s = *end;
|
s = *end;
|
||||||
|
|
|
@ -612,7 +612,7 @@ void FS_UnloadPackFiles(void);
|
||||||
void FS_ReloadPackFiles(void);
|
void FS_ReloadPackFiles(void);
|
||||||
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
|
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
|
||||||
void FS_PureMode(int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed); //implies an fs_restart. ref package names are optional, for q3 where pure names don't contain usable paths
|
void FS_PureMode(int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed); //implies an fs_restart. ref package names are optional, for q3 where pure names don't contain usable paths
|
||||||
qboolean FS_PureOkay(void);
|
int FS_PureOkay(void);
|
||||||
|
|
||||||
//recursively tries to open files until it can get a zip.
|
//recursively tries to open files until it can get a zip.
|
||||||
vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name);
|
vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name);
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||||
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||||
#define SAVEDGAMES //Can save the game.
|
#define SAVEDGAMES //Can save the game.
|
||||||
|
#define MVD_RECORDING //server can record MVDs.
|
||||||
|
|
||||||
// Networking options
|
// Networking options
|
||||||
#define NQPROT //act as an nq client/server, with nq gamecode.
|
#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||||
|
|
|
@ -114,6 +114,7 @@
|
||||||
////#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
////#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||||
////#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
////#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||||
//#define SAVEDGAMES //Can save the game.
|
//#define SAVEDGAMES //Can save the game.
|
||||||
|
//#define MVD_RECORDING //server can record MVDs.
|
||||||
|
|
||||||
// Networking options
|
// Networking options
|
||||||
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||||
|
|
|
@ -111,6 +111,7 @@
|
||||||
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||||
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||||
#define SAVEDGAMES //Can save the game.
|
#define SAVEDGAMES //Can save the game.
|
||||||
|
#define MVD_RECORDING //server can record MVDs.
|
||||||
|
|
||||||
// Networking options
|
// Networking options
|
||||||
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
#undef PSKMODELS
|
#undef PSKMODELS
|
||||||
|
|
||||||
// What do we NOT want to use
|
// What do we NOT want to use
|
||||||
|
#undef MVD_RECORDING //server can record MVDs.
|
||||||
#undef D3D9QUAKE
|
#undef D3D9QUAKE
|
||||||
#undef D3D11QUAKE
|
#undef D3D11QUAKE
|
||||||
#undef D3D8QUAKE
|
#undef D3D8QUAKE
|
||||||
|
|
|
@ -3528,7 +3528,8 @@ void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean FS_PureOkay(void)
|
#ifndef SERVERONLY
|
||||||
|
int FS_PureOkay(void)
|
||||||
{
|
{
|
||||||
//returns true if all pure packages that we're meant to need could load.
|
//returns true if all pure packages that we're meant to need could load.
|
||||||
//if they couldn't then they won't override things, or the game will just be completely screwed due to having absolutely no game data
|
//if they couldn't then they won't override things, or the game will just be completely screwed due to having absolutely no game data
|
||||||
|
@ -3591,7 +3592,10 @@ qboolean FS_PureOkay(void)
|
||||||
continue;
|
continue;
|
||||||
else //if (!sp)
|
else //if (!sp)
|
||||||
{
|
{
|
||||||
Con_Printf("Pure package %s:%i missing\n", pname, crc);
|
if (!CL_CheckDLFile(va("package/%s", pname)))
|
||||||
|
if (CL_CheckOrEnqueDownloadFile(va("package/%s", pname), va("%s.%i", pname, crc), DLLF_NONGAME))
|
||||||
|
return -1;
|
||||||
|
Con_Printf(CON_ERROR"Pure package %s:%i missing.\n", pname, crc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3600,6 +3604,7 @@ qboolean FS_PureOkay(void)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum)
|
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum)
|
||||||
{ //this is for q3 compatibility.
|
{ //this is for q3 compatibility.
|
||||||
|
|
|
@ -3307,7 +3307,9 @@ typedef struct ftenet_tcpconnect_stream_s {
|
||||||
{
|
{
|
||||||
qboolean connection_close;
|
qboolean connection_close;
|
||||||
} httpstate;
|
} httpstate;
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
qtvpendingstate_t qtvstate;
|
qtvpendingstate_t qtvstate;
|
||||||
|
#endif
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char resource[32];
|
char resource[32];
|
||||||
|
@ -3475,8 +3477,8 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
char adr[256];
|
char adr[256];
|
||||||
int i;
|
int i;
|
||||||
const char *filetype = NULL;
|
const char *filetype = NULL;
|
||||||
char *resp = NULL; //response headers (no length/gap)
|
const char *resp = NULL; //response headers (no length/gap)
|
||||||
char *body = NULL; //response body
|
const char *body = NULL; //response body
|
||||||
int method;
|
int method;
|
||||||
if (!strcmp(arg[WCATTR_METHOD], "GET"))
|
if (!strcmp(arg[WCATTR_METHOD], "GET"))
|
||||||
method = 0;
|
method = 0;
|
||||||
|
@ -3489,15 +3491,14 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
body = NULL;
|
body = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: demonum/
|
|
||||||
|
|
||||||
st->dlfile = NULL;
|
st->dlfile = NULL;
|
||||||
if (!resp && *arg[WCATTR_URL] == '/')
|
if (!resp && *arg[WCATTR_URL] == '/')
|
||||||
{ //'can't use SV_LocateDownload, as that assumes an active client.
|
{ //'can't use SV_LocateDownload, as that assumes an active client.
|
||||||
char *name = arg[WCATTR_URL]+1;
|
const char *name = arg[WCATTR_URL]+1;
|
||||||
char *extraheaders = "";
|
char *extraheaders = "";
|
||||||
time_t modificationtime = 0;
|
time_t modificationtime = 0;
|
||||||
char *query = strchr(arg[WCATTR_URL]+1, '?');
|
char *query = strchr(arg[WCATTR_URL]+1, '?');
|
||||||
|
func_t func = 0;
|
||||||
if (query)
|
if (query)
|
||||||
*query++ = 0;
|
*query++ = 0;
|
||||||
|
|
||||||
|
@ -3506,33 +3507,35 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
if (!*name)
|
if (!*name)
|
||||||
name = "index.html";
|
name = "index.html";
|
||||||
|
|
||||||
|
if (sv.state && svs.gametype == GT_PROGS && svprogfuncs)
|
||||||
|
func = svprogfuncs->FindFunction(svprogfuncs, "HTTP_GeneratePage", PR_ANY);
|
||||||
|
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
void *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||||
|
((string_t *)pr_globals)[OFS_PARM0] = svprogfuncs->TempString(svprogfuncs, query?va("%s?%s", name, query):name);
|
||||||
|
((string_t *)pr_globals)[OFS_PARM1] = svprogfuncs->TempString(svprogfuncs, arg[WCATTR_METHOD]);
|
||||||
|
((string_t *)pr_globals)[OFS_PARM2] = 0; //we don't support any postdata at this time.
|
||||||
|
((string_t *)pr_globals)[OFS_PARM3] = 0; //we don't support any request headers at this time.
|
||||||
|
((string_t *)pr_globals)[OFS_PARM4] = 0; //we don't have any default response headers yet.
|
||||||
|
((string_t *)pr_globals)[OFS_PARM5] = 0;
|
||||||
|
((string_t *)pr_globals)[OFS_PARM6] = 0;
|
||||||
|
((string_t *)pr_globals)[OFS_PARM7] = 0;
|
||||||
|
svprogfuncs->ExecuteProgram(svprogfuncs, func);
|
||||||
|
|
||||||
|
if (((string_t *)pr_globals)[OFS_RETURN])
|
||||||
|
{ //note that "" is not null
|
||||||
|
body = svprogfuncs->StringToNative(svprogfuncs, ((string_t *)pr_globals)[OFS_RETURN]);
|
||||||
|
resp = svprogfuncs->StringToNative(svprogfuncs, ((string_t *)pr_globals)[OFS_PARM4]);
|
||||||
|
resp = va("%s%s", *body?"HTTP/1.1 200 Ok\r\n":"HTTP/1.1 404 File Not Found\r\n", resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME: provide some resource->filename mapping that allows various misc files.
|
//FIXME: provide some resource->filename mapping that allows various misc files.
|
||||||
|
|
||||||
/*if (!strcmp(name, "live.html"))
|
if (body)
|
||||||
{
|
|
||||||
resp = "HTTP/1.1 200 Ok\r\n"
|
|
||||||
"Content-Type: text/html\r\n";
|
|
||||||
body =
|
|
||||||
"<!DOCTYPE HTML>"
|
|
||||||
"<html>"
|
|
||||||
"<style>"
|
|
||||||
"html, body { height: 100%%; width: 100%%; margin: 0; padding: 0;}"
|
|
||||||
"div { height: 100%%; width: 100%%; }"
|
|
||||||
"</style>"
|
|
||||||
"<div>"
|
|
||||||
"<object name=\"ieplug\" type=\"application/x-fteplugin\" classid=\"clsid:7d676c9f-fb84-40b6-b3ff-e10831557eeb\" width=\"100%%\" height=\"100%%\">"
|
|
||||||
"<param name=\"game\" value=\"q1\">"
|
|
||||||
"<object name=\"npplug\" type=\"application/x-fteplugin\" width=\"100%%\" height=\"100%%\">"
|
|
||||||
"<param name=\"game\" value=\"q1\">"
|
|
||||||
"Please install a plugin first.<br/>"
|
|
||||||
"</object>"
|
|
||||||
"</object>"
|
|
||||||
"</div>"
|
|
||||||
"</html>"
|
|
||||||
;
|
;
|
||||||
}
|
else if (!strcmp(name, "index.html"))
|
||||||
else */
|
|
||||||
if (!strcmp(name, "index.html"))
|
|
||||||
{
|
{
|
||||||
resp = "HTTP/1.1 200 Ok\r\n"
|
resp = "HTTP/1.1 200 Ok\r\n"
|
||||||
"Content-Type: text/html\r\n";
|
"Content-Type: text/html\r\n";
|
||||||
|
@ -3636,6 +3639,7 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
"Content-Type: application/x-ftemanifest\r\n";
|
"Content-Type: application/x-ftemanifest\r\n";
|
||||||
body = NULL;
|
body = NULL;
|
||||||
}*/
|
}*/
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
else if (!Q_strncasecmp(name, "demolist", 8))
|
else if (!Q_strncasecmp(name, "demolist", 8))
|
||||||
{
|
{
|
||||||
filetype = "text/html";
|
filetype = "text/html";
|
||||||
|
@ -3656,6 +3660,7 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
body = NULL;
|
body = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (!SV_AllowDownload(name))
|
else if (!SV_AllowDownload(name))
|
||||||
{
|
{
|
||||||
Con_Printf("Denied download of %s to %s\n", arg[WCATTR_URL], NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
Con_Printf("Denied download of %s to %s\n", arg[WCATTR_URL], NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||||
|
@ -3680,9 +3685,10 @@ qboolean FTENET_TCPConnect_HTTPResponse(ftenet_tcpconnect_stream_t *st, httparg_
|
||||||
{
|
{
|
||||||
flocation_t gzloc;
|
flocation_t gzloc;
|
||||||
flocation_t rawloc;
|
flocation_t rawloc;
|
||||||
extern cvar_t sv_demoDir;
|
#ifdef MVD_RECORDING
|
||||||
if (!Q_strncasecmp(name, "demos/", 6))
|
if (!Q_strncasecmp(name, "demos/", 6))
|
||||||
name = va("%s/%s", sv_demoDir.string, name+6);
|
name = va("%s/%s", sv_demoDir.string, name+6);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (FS_FLocateFile(name, FSLF_IFFOUND, &rawloc))
|
if (FS_FLocateFile(name, FSLF_IFFOUND, &rawloc))
|
||||||
{
|
{
|
||||||
|
@ -4484,6 +4490,7 @@ closesvstream:
|
||||||
|
|
||||||
if (headerscomplete)
|
if (headerscomplete)
|
||||||
{
|
{
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
//for QTV connections, we just need the method and a blank line. our qtv parser will parse the actual headers.
|
//for QTV connections, we just need the method and a blank line. our qtv parser will parse the actual headers.
|
||||||
if (!Q_strncasecmp(st->inbuffer, "QTV", 3))
|
if (!Q_strncasecmp(st->inbuffer, "QTV", 3))
|
||||||
{
|
{
|
||||||
|
@ -4503,6 +4510,7 @@ closesvstream:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
net_message.cursize = 0;
|
net_message.cursize = 0;
|
||||||
if (!FTENET_TCP_ParseHTTPRequest(con, st))
|
if (!FTENET_TCP_ParseHTTPRequest(con, st))
|
||||||
|
|
|
@ -2929,9 +2929,18 @@ void QCBUILTIN PF_edict_for_num(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
||||||
unsigned int num = G_FLOAT(OFS_PARM0);
|
unsigned int num = G_FLOAT(OFS_PARM0);
|
||||||
if (num >= w->num_edicts)
|
if (num >= w->num_edicts)
|
||||||
RETURN_EDICT(prinst, w->edicts);
|
RETURN_EDICT(prinst, w->edicts);
|
||||||
|
G_INT(OFS_RETURN) = num;
|
||||||
|
/*
|
||||||
ent = (edict_t*)EDICT_NUM_PB(prinst, num);
|
ent = (edict_t*)EDICT_NUM_PB(prinst, num);
|
||||||
RETURN_EDICT(prinst, ent);
|
if (!ent)
|
||||||
|
{
|
||||||
|
ent = ED_AllocIntoTable(progfuncs, num, false, prinst.fields_size);
|
||||||
|
ent->ereftype = ER_FREE;
|
||||||
|
if (externs->entspawn)
|
||||||
|
externs->entspawn((struct edict_s *) ent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_EDICT(prinst, ent);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -38,12 +38,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define PEXT_ENTITYDBL2 0x00004000 //max of 1024 ents instead of 512
|
#define PEXT_ENTITYDBL2 0x00004000 //max of 1024 ents instead of 512
|
||||||
#define PEXT_FLOATCOORDS 0x00008000 //supports floating point origins.
|
#define PEXT_FLOATCOORDS 0x00008000 //supports floating point origins.
|
||||||
//#define PEXT_VWEAP 0x00010000 //cause an extra qbyte to be sent, and an extra list of models for vweaps.
|
//#define PEXT_VWEAP 0x00010000 //cause an extra qbyte to be sent, and an extra list of models for vweaps.
|
||||||
#ifdef Q2BSPS
|
#define PEXT_Q2BSP_ 0x00020000
|
||||||
#define PEXT_Q2BSP 0x00020000
|
#define PEXT_Q3BSP_ 0x00040000
|
||||||
#endif
|
|
||||||
#ifdef Q3BSPS
|
|
||||||
#define PEXT_Q3BSP 0x00040000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PEXT_COLOURMOD 0x00080000 //this replaces an older value which would rarly have caried any actual data.
|
#define PEXT_COLOURMOD 0x00080000 //this replaces an older value which would rarly have caried any actual data.
|
||||||
|
|
||||||
|
@ -66,6 +62,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define PEXT_BIGUSERINFOS 0xffffffff
|
#define PEXT_BIGUSERINFOS 0xffffffff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q2BSPS
|
||||||
|
#define PEXT_Q2BSP PEXT_Q2BSP_
|
||||||
|
#endif
|
||||||
|
#ifdef Q3BSPS
|
||||||
|
#define PEXT_Q3BSP PEXT_Q3BSP_
|
||||||
|
#endif
|
||||||
|
#define PEXT1_HIDEPROTOCOLS (PEXT_Q3BSP_|PEXT_Q2BSP_|PEXT_HLBSP) //These are hints for the server, and not useful to the client (they can figure stuff out themselves)
|
||||||
|
|
||||||
#define PEXT2_PRYDONCURSOR 0x00000001
|
#define PEXT2_PRYDONCURSOR 0x00000001
|
||||||
#define PEXT2_VOICECHAT 0x00000002
|
#define PEXT2_VOICECHAT 0x00000002
|
||||||
#define PEXT2_SETANGLEDELTA 0x00000004
|
#define PEXT2_SETANGLEDELTA 0x00000004
|
||||||
|
@ -916,8 +920,10 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
TE_SPIKE = 0,
|
TE_SPIKE = 0,
|
||||||
TE_SUPERSPIKE = 1,
|
TE_SUPERSPIKE = 1,
|
||||||
TE_GUNSHOT = 2, //qw has count byte, nq does not
|
TEQW_QWGUNSHOT = 2, //qw has count byte, nq does not
|
||||||
TE_EXPLOSION = 3, //remapped to TEQW_EXPLOSIONNOSPRITE for nq.
|
TENQ_NQGUNSHOT = 2, //nq has no count byte
|
||||||
|
TEQW_QWEXPLOSION = 3, //remapped to TEQW_EXPLOSIONNOSPRITE for nq.
|
||||||
|
TENQ_NQEXPLOSION = 3, //remapped to TEQW_EXPLOSIONNOSPRITE for nq.
|
||||||
TE_TAREXPLOSION = 4,
|
TE_TAREXPLOSION = 4,
|
||||||
TE_LIGHTNING1 = 5,
|
TE_LIGHTNING1 = 5,
|
||||||
TE_LIGHTNING2 = 6,
|
TE_LIGHTNING2 = 6,
|
||||||
|
@ -927,25 +933,27 @@ enum {
|
||||||
TE_LAVASPLASH = 10,
|
TE_LAVASPLASH = 10,
|
||||||
TE_TELEPORT = 11,
|
TE_TELEPORT = 11,
|
||||||
|
|
||||||
TEQW_BLOOD = 12, //implemented as a particle() in nq
|
TEQW_QWBLOOD = 12, //implemented as a particle() in nq
|
||||||
TENQ_EXPLOSION2 = 12, //remapped to TEQW_EXPLOSION2 for qw
|
TENQ_EXPLOSION2 = 12, //remapped to TEQW_EXPLOSION2 for qw
|
||||||
TEQW_LIGHTNINGBLOOD = 13, //implemented as a particle() in nq
|
TEQW_LIGHTNINGBLOOD = 13, //implemented as a particle() in nq
|
||||||
TENQ_BEAM = 13, //remapped to TEQW_BEAM for qw
|
TENQ_BEAM = 13, //remapped to TEQW_BEAM for qw
|
||||||
|
|
||||||
#ifdef PEXT_TE_BULLET
|
#ifdef PEXT_TE_BULLET
|
||||||
TE_BULLET = 14,
|
TE_BULLET = 14,
|
||||||
TE_SUPERBULLET = 15,
|
TEQW_SUPERBULLET = 15,
|
||||||
#endif
|
#endif
|
||||||
TENEH_RAILTRAIL = 15, //gah [vector] origin [coord] red [coord] green [coord] blue
|
TENQ_RAILTRAIL = 15, //gah [vector] origin [coord] red [coord] green [coord] blue
|
||||||
TENEH_EXPLOSION3 = 16, //gah [vector] origin [coord] red [coord] green [coord] blue
|
TE_EXPLOSION3_NEH = 16, //gah [vector] origin [coord] red [coord] green [coord] blue
|
||||||
TE_RAILTRAIL = 17, //use the builtin, luke.
|
TEQW_RAILTRAIL = 17, //use the builtin, luke.
|
||||||
TENEH_LIGHTNING4 = 17, //gah [string] model [entity] entity [vector] start [vector] end
|
TENQ_NEHLIGHTNING4 = 17, //gah [string] model [entity] entity [vector] start [vector] end
|
||||||
|
TEQW_NEHLIGHTNING4 = 1000, //give a real value if its ever properly implemented
|
||||||
TEQW_BEAM = 18, //use the builtin, luke.
|
TEQW_BEAM = 18, //use the builtin, luke.
|
||||||
TENEH_SMOKE = 18, //gah [vector] origin [byte] palette
|
TENQ_NEHSMOKE = 18, //gah [vector] origin [byte] palette
|
||||||
TEQW_EXPLOSION2 = 19, //use the builtin, luke.
|
TEQW_EXPLOSION2 = 19, //use the builtin, luke.
|
||||||
TEQW_EXPLOSION_NOSPRITE = 20, //nq-style explosion over qw
|
TEQW_NQEXPLOSION = 20, //nq-style explosion over qw
|
||||||
TENQ_EXPLOSION_SPRITE = 20, //qw-style explosion over nq
|
TENQ_QWEXPLOSION = 20, //qw-style explosion over nq
|
||||||
TE_GUNSHOT_NQCOMPAT = 21, //nq has count byte, qw does not
|
TEQW_NQGUNSHOT = 21, //nq has count byte, qw does not
|
||||||
|
TENQ_QWGUNSHOT = 21, //nq has count byte, qw does not
|
||||||
|
|
||||||
// hexen 2
|
// hexen 2
|
||||||
TEH2_STREAM_LIGHTNING_SMALL = 24,
|
TEH2_STREAM_LIGHTNING_SMALL = 24,
|
||||||
|
@ -959,7 +967,7 @@ enum {
|
||||||
TEH2_STREAM_FAMINE = 32,
|
TEH2_STREAM_FAMINE = 32,
|
||||||
TEH2_PARTICLEEXPLOSION = 33,
|
TEH2_PARTICLEEXPLOSION = 33,
|
||||||
|
|
||||||
TEDP_BLOOD = 50,
|
TEDP_BLOOD = 50, // [coord*3] origin [byte*3] vel [byte] count
|
||||||
TEDP_SPARK = 51,
|
TEDP_SPARK = 51,
|
||||||
TEDP_BLOODSHOWER = 52,
|
TEDP_BLOODSHOWER = 52,
|
||||||
TEDP_EXPLOSIONRGB = 53,
|
TEDP_EXPLOSIONRGB = 53,
|
||||||
|
@ -1298,7 +1306,7 @@ typedef struct q1usercmd_s
|
||||||
#define Q2RF_MINLIGHT (1u<<0) //ni always have some light (viewmodel)
|
#define Q2RF_MINLIGHT (1u<<0) //ni always have some light (viewmodel)
|
||||||
#define RF_EXTERNALMODEL (1u<<1) //i don't draw through eyes, only mirrors
|
#define RF_EXTERNALMODEL (1u<<1) //i don't draw through eyes, only mirrors
|
||||||
#define RF_WEAPONMODEL (1u<<2) //i only draw through eyes
|
#define RF_WEAPONMODEL (1u<<2) //i only draw through eyes
|
||||||
#define Q2RF_FULLBRIGHT (1u<<3) //i always draw full intensity
|
#define RF_FULLBRIGHT (1u<<3) //i always draw full intensity
|
||||||
#define RF_DEPTHHACK (1u<<4) //i for view weapon Z crunching
|
#define RF_DEPTHHACK (1u<<4) //i for view weapon Z crunching
|
||||||
#define RF_TRANSLUCENT (1u<<5) //forces shader sort order and BEF_FORCETRANSPARENT
|
#define RF_TRANSLUCENT (1u<<5) //forces shader sort order and BEF_FORCETRANSPARENT
|
||||||
#define Q2RF_FRAMELERP (1u<<6) //q2only
|
#define Q2RF_FRAMELERP (1u<<6) //q2only
|
||||||
|
|
|
@ -676,7 +676,11 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
||||||
if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS)
|
if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS)
|
||||||
{
|
{
|
||||||
//heads don't get skinned, only players (and weaponless players), they do still get recoloured.
|
//heads don't get skinned, only players (and weaponless players), they do still get recoloured.
|
||||||
if (model==cl.model_precache[cl_playerindex] || model==cl.model_precache_vwep[0])
|
if (model==cl.model_precache[cl_playerindex]
|
||||||
|
#ifndef NOLEGACY
|
||||||
|
|| model==cl.model_precache_vwep[0]
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (!cl.players[e->playerindex].qwskin)
|
if (!cl.players[e->playerindex].qwskin)
|
||||||
Skin_Find(&cl.players[e->playerindex]);
|
Skin_Find(&cl.players[e->playerindex]);
|
||||||
|
@ -1333,15 +1337,17 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
|
||||||
e->light_known = 2;
|
e->light_known = 2;
|
||||||
return e->light_known-1;
|
return e->light_known-1;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
#ifdef HEXEN2
|
#ifdef HEXEN2
|
||||||
if ((e->drawflags & MLS_MASK) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT))
|
(e->drawflags & MLS_MASK) == MLS_FULLBRIGHT ||
|
||||||
|
#endif
|
||||||
|
(e->flags & RF_FULLBRIGHT))
|
||||||
{
|
{
|
||||||
e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1;
|
e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1;
|
||||||
e->light_range[0] = e->light_range[1] = e->light_range[2] = 0;
|
e->light_range[0] = e->light_range[1] = e->light_range[2] = 0;
|
||||||
e->light_known = 2;
|
e->light_known = 2;
|
||||||
return e->light_known-1;
|
return e->light_known-1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival && (clmodel->engineflags & MDLF_EZQUAKEFBCHEAT) && cls.protocol == CP_QUAKEWORLD && cl.deathmatch)
|
if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival && (clmodel->engineflags & MDLF_EZQUAKEFBCHEAT) && cls.protocol == CP_QUAKEWORLD && cl.deathmatch)
|
||||||
{
|
{
|
||||||
e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1;
|
e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1;
|
||||||
|
|
|
@ -7306,8 +7306,8 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
||||||
struct brushface_s faces[countof(planes)];
|
struct brushface_s faces[countof(planes)];
|
||||||
|
|
||||||
//patch info
|
//patch info
|
||||||
brushtex_t *patch_tex;
|
brushtex_t *patch_tex=NULL;
|
||||||
int patch_w, patch_h;
|
int patch_w=0, patch_h=0;
|
||||||
vec5_t patch_v[64][64];
|
vec5_t patch_v[64][64];
|
||||||
|
|
||||||
#ifdef RUNTIMELIGHTING
|
#ifdef RUNTIMELIGHTING
|
||||||
|
@ -7344,7 +7344,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
||||||
brush.patch = NULL;
|
brush.patch = NULL;
|
||||||
Terr_Brush_Insert(submod, subhm, &brush);
|
Terr_Brush_Insert(submod, subhm, &brush);
|
||||||
}
|
}
|
||||||
else
|
else if (patch_tex)
|
||||||
Terr_Patch_Insert(submod, subhm, patch_tex, patch_w, patch_h, patch_v[0], countof(patch_v[0]));
|
Terr_Patch_Insert(submod, subhm, patch_tex, patch_w, patch_h, patch_v[0], countof(patch_v[0]));
|
||||||
subhm->brushesedited = oe;
|
subhm->brushesedited = oe;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2505,6 +2505,10 @@ static shaderkey_t shaderkeys[] =
|
||||||
{"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
{"progblendfunc", Shader_ProgBlendFunc, "fte"}, //specifies the blend mode (actually just overrides the first subpasses' blendmode.
|
||||||
{"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
{"progmap", Shader_ProgMap, "fte"}, //avoids needing extra subpasses (actually just inserts an extra pass).
|
||||||
|
|
||||||
|
{"basefactor", NULL, "fte"}, //material scalers for glsl
|
||||||
|
{"specularfactor", NULL, "fte"}, //material scalers for glsl
|
||||||
|
{"fullbrightfactor", NULL, "fte"}, //material scalers for glsl
|
||||||
|
|
||||||
//dp compat
|
//dp compat
|
||||||
{"reflectcube", Shader_ReflectCube, "dp"},
|
{"reflectcube", Shader_ReflectCube, "dp"},
|
||||||
{"camera", Shader_DP_Camera, "dp"},
|
{"camera", Shader_DP_Camera, "dp"},
|
||||||
|
@ -5847,11 +5851,10 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
|
||||||
if (!builtin && r_lightmap.ival)
|
if (!builtin && r_lightmap.ival)
|
||||||
builtin = (
|
builtin = (
|
||||||
"{\n"
|
"{\n"
|
||||||
"fte_program drawflat_wall\n"
|
"fte_program drawflat_wall#LM\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"map $lightmap\n"
|
"map $lightmap\n"
|
||||||
"tcgen lightmap\n"
|
"tcgen lightmap\n"
|
||||||
"rgbgen srgb 255 255 255\n"
|
|
||||||
"}\n"
|
"}\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
|
@ -7990,7 +7990,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"uniform vec4 e_lmscale;\n"
|
"uniform vec4 e_lmscale;\n"
|
||||||
"void main ()\n"
|
"void main ()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
"#ifdef LM\n"
|
||||||
|
"col = vec4(1.0);\n"
|
||||||
|
"#else\n"
|
||||||
"col = vec4(e_lmscale.rgb * ((v_normal.z < 0.73)?r_wallcolor:r_floorcolor), e_lmscale.a);\n"
|
"col = vec4(e_lmscale.rgb * ((v_normal.z < 0.73)?r_wallcolor:r_floorcolor), e_lmscale.a);\n"
|
||||||
|
"#endif\n"
|
||||||
"lm = v_lmcoord;\n"
|
"lm = v_lmcoord;\n"
|
||||||
"gl_Position = ftetransform();\n"
|
"gl_Position = ftetransform();\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
@ -9805,6 +9809,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
{QR_OPENGL, 110, "postproc_ascii",
|
{QR_OPENGL, 110, "postproc_ascii",
|
||||||
"!!cvardf r_glsl_ascii_mono=0\n"
|
"!!cvardf r_glsl_ascii_mono=0\n"
|
||||||
"!!samps 1\n"
|
"!!samps 1\n"
|
||||||
|
|
||||||
//derived from https://www.shadertoy.com/view/lssGDj
|
//derived from https://www.shadertoy.com/view/lssGDj
|
||||||
|
|
||||||
"#include \"sys/defs.h\"\n"
|
"#include \"sys/defs.h\"\n"
|
||||||
|
@ -9838,7 +9843,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
|
|
||||||
"float gray = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;\n"
|
"float gray = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;\n"
|
||||||
|
|
||||||
"if (r_glsl_ascii_mono != 0)\n"
|
"if (r_glsl_ascii_mono != 0.0)\n"
|
||||||
"gray = gray = pow(gray, 0.7); //quake is just too dark otherwise.\n"
|
"gray = gray = pow(gray, 0.7); //quake is just too dark otherwise.\n"
|
||||||
"else\n"
|
"else\n"
|
||||||
"gray = gray = pow(gray, 0.45); //col*char is FAR too dark otherwise, and much of the colour will come from the col term anyway.\n"
|
"gray = gray = pow(gray, 0.45); //col*char is FAR too dark otherwise, and much of the colour will come from the col term anyway.\n"
|
||||||
|
@ -9854,7 +9859,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"if (gray > 0.8) n = 11512810.0; // #\n"
|
"if (gray > 0.8) n = 11512810.0; // #\n"
|
||||||
|
|
||||||
"vec2 p = mod(uv/4.0, 2.0) - vec2(1.0);\n"
|
"vec2 p = mod(uv/4.0, 2.0) - vec2(1.0);\n"
|
||||||
"if (r_glsl_ascii_mono != 0)\n"
|
"if (r_glsl_ascii_mono != 0.0)\n"
|
||||||
"col = vec3(character(n, p));\n"
|
"col = vec3(character(n, p));\n"
|
||||||
"else\n"
|
"else\n"
|
||||||
"col = col*character(n, p); //note that this is kinda cheating.\n"
|
"col = col*character(n, p); //note that this is kinda cheating.\n"
|
||||||
|
|
|
@ -724,7 +724,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
||||||
nl = strchr(msg, '\n');
|
nl = strchr(msg, '\n');
|
||||||
if (nl)
|
if (nl)
|
||||||
*nl = '\0';
|
*nl = '\0';
|
||||||
Con_Printf("HTTP: %s %s (%s)\n", buffer, COM_TrimString(msg, trimmed, sizeof(trimmed)), Location);
|
Con_Printf("%s: %s %s (%s)\n", dl->url, buffer, COM_TrimString(msg, trimmed, sizeof(trimmed)), Location);
|
||||||
if (!*Location)
|
if (!*Location)
|
||||||
Con_Printf("Server redirected to null location\n");
|
Con_Printf("Server redirected to null location\n");
|
||||||
else
|
else
|
||||||
|
@ -763,7 +763,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
||||||
if (nl>msg&&nl[-1] == '\r')
|
if (nl>msg&&nl[-1] == '\r')
|
||||||
nl--;
|
nl--;
|
||||||
*nl = '\0';
|
*nl = '\0';
|
||||||
Con_Printf("HTTP: %s%s\n", buffer, msg);
|
Con_Printf("%s: %s%s\n", dl->url, buffer, msg);
|
||||||
return false; //something went wrong.
|
return false; //something went wrong.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "qcc.h"
|
#include "qcc.h"
|
||||||
|
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
void QCC_Canonicalize(char *fullname, size_t fullnamesize, const char *newfile, const char *base);
|
void QCC_Canonicalize(char *fullname, size_t fullnamesize, const char *newfile, const char *base);
|
||||||
|
|
||||||
|
@ -1635,3 +1636,4 @@ void Packager_ParseFile(struct pkgctx_s *ctx, char *scriptname)
|
||||||
void Packager_Destroy(struct pkgctx_s *ctx)
|
void Packager_Destroy(struct pkgctx_s *ctx)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1247,12 +1247,11 @@ pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, const cha
|
||||||
pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs, int fldtype, char *s)
|
pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs, int fldtype, char *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char string[128];
|
|
||||||
fdef_t *def;
|
fdef_t *def;
|
||||||
char *v, *w;
|
|
||||||
string_t st;
|
string_t st;
|
||||||
mfunction_t *func;
|
mfunction_t *func;
|
||||||
int type = fldtype & ~DEF_SAVEGLOBAL;
|
int type = fldtype & ~DEF_SAVEGLOBAL;
|
||||||
|
double d;
|
||||||
qcptr += fldofs*sizeof(int);
|
qcptr += fldofs*sizeof(int);
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -1267,37 +1266,40 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_float:
|
case ev_float:
|
||||||
*(float *)(progfuncs->funcs.stringtable + qcptr) = (float)atof (s);
|
while(*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
d = strtod(s, &s);
|
||||||
|
while(*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
*(float *)(progfuncs->funcs.stringtable + qcptr) = d;
|
||||||
|
if (*s)
|
||||||
|
return false; //some kind of junk in there.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ev_entity: //ent references are simple ints for us.
|
||||||
case ev_integer:
|
case ev_integer:
|
||||||
*(int *)(progfuncs->funcs.stringtable + qcptr) = atoi (s);
|
while(*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
i = strtol(s, &s, 0);
|
||||||
|
while(*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
*(int *)(progfuncs->funcs.stringtable + qcptr) = i;
|
||||||
|
if (*s)
|
||||||
|
return false; //some kind of junk in there.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_vector:
|
case ev_vector:
|
||||||
strcpy (string, s);
|
|
||||||
v = string;
|
|
||||||
w = string;
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
{
|
{
|
||||||
while (*v && *v != ' ')
|
while(*s == ' ' || *s == '\t')
|
||||||
v++;
|
s++;
|
||||||
if (!*v)
|
d = strtod(s, &s);
|
||||||
{
|
((float *)(progfuncs->funcs.stringtable + qcptr))[i] = d;
|
||||||
((float *)(progfuncs->funcs.stringtable + qcptr))[i] = (float)atof (w);
|
|
||||||
w = v;
|
|
||||||
}
|
}
|
||||||
else
|
while(*s == ' ' || *s == '\t')
|
||||||
{
|
s++;
|
||||||
*v = 0;
|
if (*s)
|
||||||
((float *)(progfuncs->funcs.stringtable + qcptr))[i] = (float)atof (w);
|
return false; //some kind of junk in there.
|
||||||
w = v = v+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ev_entity:
|
|
||||||
*(int *)(progfuncs->funcs.stringtable + qcptr) = atoi (s);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_field:
|
case ev_field:
|
||||||
|
@ -1311,7 +1313,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ev_function:
|
case ev_function:
|
||||||
if (s[1]==':'&&s[2]=='\0')
|
if (s[0] && s[1]==':'&&s[2]=='\0') //this isn't right...
|
||||||
{
|
{
|
||||||
*(func_t *)(progfuncs->funcs.stringtable + qcptr) = 0;
|
*(func_t *)(progfuncs->funcs.stringtable + qcptr) = 0;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1326,7 +1328,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, size_t qcptr, unsigned int fldofs,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1341,7 +1343,7 @@ Used for initial level load and for savegames.
|
||||||
====================
|
====================
|
||||||
*/
|
*/
|
||||||
#if 1
|
#if 1
|
||||||
const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edictrun_t *ent)
|
static const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edictrun_t *ent, pbool *out_maphack)
|
||||||
{
|
{
|
||||||
fdef_t *key;
|
fdef_t *key;
|
||||||
pbool init;
|
pbool init;
|
||||||
|
@ -1432,8 +1434,19 @@ const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edictrun_t
|
||||||
}
|
}
|
||||||
|
|
||||||
cont:
|
cont:
|
||||||
|
switch(key->type)
|
||||||
|
{
|
||||||
|
case ev_function:
|
||||||
|
case ev_field:
|
||||||
|
case ev_entity:
|
||||||
|
case ev_pointer:
|
||||||
|
*out_maphack = true; //one of these types of fields means evil maphacks are at play.
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!ED_ParseEpair (progfuncs, (char*)ent->fields - progfuncs->funcs.stringtable, key->ofs, key->type, qcc_token))
|
if (!ED_ParseEpair (progfuncs, (char*)ent->fields - progfuncs->funcs.stringtable, key->ofs, key->type, qcc_token))
|
||||||
{
|
{
|
||||||
|
if (externs->badfield && externs->badfield(&progfuncs->funcs, (struct edict_s*)ent, keyname, qcc_token))
|
||||||
|
continue;
|
||||||
continue;
|
continue;
|
||||||
// Sys_Error ("ED_ParseEdict: parse error on entities");
|
// Sys_Error ("ED_ParseEdict: parse error on entities");
|
||||||
}
|
}
|
||||||
|
@ -1911,6 +1924,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD
|
||||||
int crc = 1;
|
int crc = 1;
|
||||||
int entsize = 0;
|
int entsize = 0;
|
||||||
int numents = 0;
|
int numents = 0;
|
||||||
|
pbool maphacks = false;
|
||||||
|
|
||||||
pbool resethunk=0;
|
pbool resethunk=0;
|
||||||
pbool isloadgame;
|
pbool isloadgame;
|
||||||
|
@ -2021,7 +2035,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD
|
||||||
ed->ereftype = ER_ENTITY;
|
ed->ereftype = ER_ENTITY;
|
||||||
if (externs->entspawn)
|
if (externs->entspawn)
|
||||||
externs->entspawn((struct edict_s *) ed, true);
|
externs->entspawn((struct edict_s *) ed, true);
|
||||||
file = ED_ParseEdict(progfuncs, file, ed);
|
file = ED_ParseEdict(progfuncs, file, ed, &maphacks);
|
||||||
|
|
||||||
if (entspawned)
|
if (entspawned)
|
||||||
entspawned(ppf, (struct edict_s *)ed, ctx, datastart, file);
|
entspawned(ppf, (struct edict_s *)ed, ctx, datastart, file);
|
||||||
|
@ -2262,7 +2276,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD
|
||||||
externs->entspawn((struct edict_s *) ed, true);
|
externs->entspawn((struct edict_s *) ed, true);
|
||||||
|
|
||||||
ed->ereftype = ER_ENTITY;
|
ed->ereftype = ER_ENTITY;
|
||||||
file = ED_ParseEdict (progfuncs, file, ed);
|
file = ED_ParseEdict (progfuncs, file, ed, &maphacks);
|
||||||
}
|
}
|
||||||
sv_num_edicts = ++numents;
|
sv_num_edicts = ++numents;
|
||||||
continue;
|
continue;
|
||||||
|
@ -2292,7 +2306,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, void *ctx, void (PD
|
||||||
ed->ereftype = ER_ENTITY;
|
ed->ereftype = ER_ENTITY;
|
||||||
if (externs->entspawn)
|
if (externs->entspawn)
|
||||||
externs->entspawn((struct edict_s *) ed, true);
|
externs->entspawn((struct edict_s *) ed, true);
|
||||||
file = ED_ParseEdict(progfuncs, file, ed);
|
file = ED_ParseEdict(progfuncs, file, ed, &maphacks);
|
||||||
|
|
||||||
if (entspawned)
|
if (entspawned)
|
||||||
entspawned(ppf, (struct edict_s *)ed, ctx, datastart, file);
|
entspawned(ppf, (struct edict_s *)ed, ctx, datastart, file);
|
||||||
|
@ -2409,6 +2423,7 @@ struct edict_s *PDECL PR_RestoreEnt (pubprogfuncs_t *ppf, const char *buf, size_
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
edictrun_t *ent;
|
edictrun_t *ent;
|
||||||
const char *start = buf;
|
const char *start = buf;
|
||||||
|
pbool maphacks = false; //don't really care.
|
||||||
|
|
||||||
buf = QCC_COM_Parse(buf); //read the key
|
buf = QCC_COM_Parse(buf); //read the key
|
||||||
if (!buf || !*qcc_token)
|
if (!buf || !*qcc_token)
|
||||||
|
@ -2425,7 +2440,7 @@ struct edict_s *PDECL PR_RestoreEnt (pubprogfuncs_t *ppf, const char *buf, size_
|
||||||
if (ent->ereftype == ER_FREE && externs->entspawn)
|
if (ent->ereftype == ER_FREE && externs->entspawn)
|
||||||
externs->entspawn((struct edict_s *) ent, false);
|
externs->entspawn((struct edict_s *) ent, false);
|
||||||
|
|
||||||
buf = ED_ParseEdict(progfuncs, buf, ent);
|
buf = ED_ParseEdict(progfuncs, buf, ent, &maphacks);
|
||||||
|
|
||||||
*size = buf - start;
|
*size = buf - start;
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,6 @@ char *PDECL ED_NewString (pubprogfuncs_t *ppf, const char *string, int minlength
|
||||||
|
|
||||||
void PDECL ED_Print (pubprogfuncs_t *progfuncs, struct edict_s *ed);
|
void PDECL ED_Print (pubprogfuncs_t *progfuncs, struct edict_s *ed);
|
||||||
//void ED_Write (FILE *f, edictrun_t *ed);
|
//void ED_Write (FILE *f, edictrun_t *ed);
|
||||||
const char *ED_ParseEdict (progfuncs_t *progfuncs, const char *data, edictrun_t *ent);
|
|
||||||
|
|
||||||
//void ED_WriteGlobals (FILE *f);
|
//void ED_WriteGlobals (FILE *f);
|
||||||
void ED_ParseGlobals (char *data);
|
void ED_ParseGlobals (char *data);
|
||||||
|
|
|
@ -600,7 +600,7 @@ extern qboolean ssqc_deprecated_warned;
|
||||||
#define svcdp_showlmp 35 // [string] slotname [string] lmpfilename [short] x [short] y
|
#define svcdp_showlmp 35 // [string] slotname [string] lmpfilename [short] x [short] y
|
||||||
#define svcdp_hidelmp 36 // [string] slotname
|
#define svcdp_hidelmp 36 // [string] slotname
|
||||||
|
|
||||||
#define TE_RAILTRAIL_NEH 15 // [vector] origin [coord] red [coord] green [coord] blue (fixme: ignored)
|
//#define TE_RAILTRAIL_NEH 15 // [vector] origin [coord] red [coord] green [coord] blue (fixme: ignored)
|
||||||
#define TE_EXPLOSION3_NEH 16 // [vector] origin [coord] red [coord] green [coord] blue (fixme: ignored)
|
#define TE_EXPLOSION3_NEH 16 // [vector] origin [coord] red [coord] green [coord] blue (fixme: ignored)
|
||||||
#define TE_LIGHTNING4_NEH 17 // [string] model [entity] entity [vector] start [vector] end
|
#define TE_LIGHTNING4_NEH 17 // [string] model [entity] entity [vector] start [vector] end
|
||||||
#define TE_SMOKE_NEH 18
|
#define TE_SMOKE_NEH 18
|
||||||
|
@ -861,7 +861,7 @@ void NPP_NQFlush(void)
|
||||||
buffer[0] = svcfte_cgamepacket;
|
buffer[0] = svcfte_cgamepacket;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TE_EXPLOSION:
|
case TENQ_NQEXPLOSION:
|
||||||
if (writedest == &sv.datagram)
|
if (writedest == &sv.datagram)
|
||||||
{ //for old clients, use a te_explosion.
|
{ //for old clients, use a te_explosion.
|
||||||
//for clients that support it, use a TEQW_EXPLOSIONNOSPRITE
|
//for clients that support it, use a TEQW_EXPLOSIONNOSPRITE
|
||||||
|
@ -880,7 +880,7 @@ void NPP_NQFlush(void)
|
||||||
|
|
||||||
requireextension = PEXT_TE_BULLET;
|
requireextension = PEXT_TE_BULLET;
|
||||||
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, 0, requireextension);
|
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, 0, requireextension);
|
||||||
buffer[1] = TEQW_EXPLOSION_NOSPRITE;
|
buffer[1] = TEQW_NQEXPLOSION;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TENQ_BEAM:
|
case TENQ_BEAM:
|
||||||
|
@ -901,7 +901,7 @@ void NPP_NQFlush(void)
|
||||||
memcpy(&cd, &buffer[2+destprim->coordsize*2], destprim->coordsize);
|
memcpy(&cd, &buffer[2+destprim->coordsize*2], destprim->coordsize);
|
||||||
org[2] = MSG_FromCoord(cd, destprim->coordsize);
|
org[2] = MSG_FromCoord(cd, destprim->coordsize);
|
||||||
|
|
||||||
buffer[1] = TE_EXPLOSION; //use a generic crappy explosion
|
buffer[1] = TEQW_QWEXPLOSION; //use a generic crappy explosion
|
||||||
SZ_Write(&sv.multicast, buffer, bufferlen-2); //trim the two trailing colour bytes
|
SZ_Write(&sv.multicast, buffer, bufferlen-2); //trim the two trailing colour bytes
|
||||||
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, 0, requireextension);
|
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, 0, requireextension);
|
||||||
}
|
}
|
||||||
|
@ -1240,7 +1240,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
||||||
multicasttype=MULTICAST_PHS;
|
multicasttype=MULTICAST_PHS;
|
||||||
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
|
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
|
||||||
break;
|
break;
|
||||||
case TE_GUNSHOT:
|
case TENQ_NQGUNSHOT:
|
||||||
multicastpos=3;
|
multicastpos=3;
|
||||||
multicasttype=MULTICAST_PVS;
|
multicasttype=MULTICAST_PVS;
|
||||||
//we need to emit annother qbyte here. QuakeWorld has a number of particles.
|
//we need to emit annother qbyte here. QuakeWorld has a number of particles.
|
||||||
|
@ -1249,7 +1249,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
||||||
data = 1;
|
data = 1;
|
||||||
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
|
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
|
||||||
break;
|
break;
|
||||||
case TE_EXPLOSION:
|
case TENQ_NQEXPLOSION:
|
||||||
case TE_SPIKE:
|
case TE_SPIKE:
|
||||||
case TE_SUPERSPIKE:
|
case TE_SUPERSPIKE:
|
||||||
multicastpos=2;
|
multicastpos=2;
|
||||||
|
@ -1279,12 +1279,12 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
||||||
multicasttype=MULTICAST_PHS;
|
multicasttype=MULTICAST_PHS;
|
||||||
break;
|
break;
|
||||||
case TE_EXPLOSIONSMALL2:
|
case TE_EXPLOSIONSMALL2:
|
||||||
data = TE_EXPLOSION;
|
data = TEQW_QWEXPLOSION;
|
||||||
protocollen = sizeof(qbyte)*2 + destprim->coordsize*3;
|
protocollen = sizeof(qbyte)*2 + destprim->coordsize*3;
|
||||||
multicastpos=2;
|
multicastpos=2;
|
||||||
multicasttype=MULTICAST_PHS;
|
multicasttype=MULTICAST_PHS;
|
||||||
break;
|
break;
|
||||||
case TE_RAILTRAIL:
|
case TEQW_RAILTRAIL:
|
||||||
protocollen = destprim->coordsize*6+sizeof(qbyte)*1;
|
protocollen = destprim->coordsize*6+sizeof(qbyte)*1;
|
||||||
multicastpos=2;
|
multicastpos=2;
|
||||||
multicasttype=MULTICAST_PHS;
|
multicasttype=MULTICAST_PHS;
|
||||||
|
@ -1904,7 +1904,7 @@ void NPP_QWFlush(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TEQW_LIGHTNINGBLOOD:
|
case TEQW_LIGHTNINGBLOOD:
|
||||||
case TEQW_BLOOD: //needs to be converted to a particle
|
case TEQW_QWBLOOD: //needs to be converted to an svc_particle
|
||||||
{
|
{
|
||||||
vec3_t org;
|
vec3_t org;
|
||||||
qbyte count;
|
qbyte count;
|
||||||
|
@ -1957,7 +1957,7 @@ void NPP_QWFlush(void)
|
||||||
NPP_AddData(&colour, sizeof(qbyte));
|
NPP_AddData(&colour, sizeof(qbyte));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TE_GUNSHOT: //needs byte 3 removed
|
case TEQW_QWGUNSHOT: //needs byte 3 removed
|
||||||
if (bufferlen >= 3)
|
if (bufferlen >= 3)
|
||||||
{
|
{
|
||||||
memmove(buffer+2, buffer+3, bufferlen-3);
|
memmove(buffer+2, buffer+3, bufferlen-3);
|
||||||
|
@ -2184,14 +2184,14 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
||||||
multicasttype=MULTICAST_PHS;
|
multicasttype=MULTICAST_PHS;
|
||||||
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
|
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
|
||||||
break;
|
break;
|
||||||
case TEQW_BLOOD: //needs to be converted to a particle
|
case TEQW_QWBLOOD: //needs to be converted to a particle
|
||||||
case TE_GUNSHOT: //needs qbyte 2 removed
|
case TEQW_QWGUNSHOT: //needs qbyte 2 removed
|
||||||
multicastpos=3;
|
multicastpos=3;
|
||||||
multicasttype=MULTICAST_PVS;
|
multicasttype=MULTICAST_PVS;
|
||||||
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
|
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
|
||||||
break;
|
break;
|
||||||
case TEQW_LIGHTNINGBLOOD:
|
case TEQW_LIGHTNINGBLOOD:
|
||||||
case TE_EXPLOSION:
|
case TEQW_QWEXPLOSION:
|
||||||
case TE_SPIKE:
|
case TE_SPIKE:
|
||||||
case TE_SUPERSPIKE:
|
case TE_SUPERSPIKE:
|
||||||
multicastpos=2;
|
multicastpos=2;
|
||||||
|
@ -2207,7 +2207,7 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
||||||
multicasttype=MULTICAST_PVS;
|
multicasttype=MULTICAST_PVS;
|
||||||
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
|
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
|
||||||
break;
|
break;
|
||||||
case TE_RAILTRAIL:
|
case TEQW_RAILTRAIL:
|
||||||
multicastpos=1;
|
multicastpos=1;
|
||||||
multicasttype=MULTICAST_PVS;
|
multicasttype=MULTICAST_PVS;
|
||||||
protocollen = destprim->coordsize*3+sizeof(qbyte)*1;
|
protocollen = destprim->coordsize*3+sizeof(qbyte)*1;
|
||||||
|
|
|
@ -3226,7 +3226,7 @@ void QCBUILTIN PF_particle (pubprogfuncs_t *prinst, globalvars_t *pr_globals) //
|
||||||
if (color == 73)
|
if (color == 73)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||||
MSG_WriteByte (&sv.multicast, TEQW_BLOOD);
|
MSG_WriteByte (&sv.multicast, TEQW_QWBLOOD);
|
||||||
MSG_WriteByte (&sv.multicast, count<10?1:(count+10)/20);
|
MSG_WriteByte (&sv.multicast, count<10?1:(count+10)/20);
|
||||||
MSG_WriteCoord (&sv.multicast, org[0]);
|
MSG_WriteCoord (&sv.multicast, org[0]);
|
||||||
MSG_WriteCoord (&sv.multicast, org[1]);
|
MSG_WriteCoord (&sv.multicast, org[1]);
|
||||||
|
@ -3292,7 +3292,7 @@ static void QCBUILTIN PF_te_blooddp (pubprogfuncs_t *prinst, globalvars_t *pr_gl
|
||||||
|
|
||||||
(void)dir; //FIXME: sould be sending TEDP_BLOOD
|
(void)dir; //FIXME: sould be sending TEDP_BLOOD
|
||||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||||
MSG_WriteByte (&sv.multicast, TEQW_BLOOD);
|
MSG_WriteByte (&sv.multicast, TEQW_QWBLOOD);
|
||||||
MSG_WriteByte (&sv.multicast, count<10?1:(count+10)/20);
|
MSG_WriteByte (&sv.multicast, count<10?1:(count+10)/20);
|
||||||
MSG_WriteCoord (&sv.multicast, org[0]);
|
MSG_WriteCoord (&sv.multicast, org[0]);
|
||||||
MSG_WriteCoord (&sv.multicast, org[1]);
|
MSG_WriteCoord (&sv.multicast, org[1]);
|
||||||
|
@ -3878,6 +3878,7 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
||||||
else
|
else
|
||||||
SV_StuffcmdToClient(cl, str);
|
SV_StuffcmdToClient(cl, str);
|
||||||
}
|
}
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (!(flags & STUFFCMD_IGNOREINDEMO))
|
if (!(flags & STUFFCMD_IGNOREINDEMO))
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
|
@ -3885,6 +3886,7 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
||||||
MSG_WriteByte (msg, svc_stufftext);
|
MSG_WriteByte (msg, svc_stufftext);
|
||||||
MSG_WriteString (msg, str);
|
MSG_WriteString (msg, str);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3948,6 +3950,7 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
||||||
SV_StuffcmdToClient(cl, str);
|
SV_StuffcmdToClient(cl, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (!(flags & STUFFCMD_IGNOREINDEMO))
|
if (!(flags & STUFFCMD_IGNOREINDEMO))
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
|
@ -3955,6 +3958,7 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
||||||
MSG_WriteByte (msg, svc_stufftext);
|
MSG_WriteByte (msg, svc_stufftext);
|
||||||
MSG_WriteString (msg, str);
|
MSG_WriteString (msg, str);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//this seems a little dangerous. v_cshift could leave a spectator's machine unusable if they switch players at unfortunate times.
|
//this seems a little dangerous. v_cshift could leave a spectator's machine unusable if they switch players at unfortunate times.
|
||||||
if (!(flags & STUFFCMD_DEMOONLY))
|
if (!(flags & STUFFCMD_DEMOONLY))
|
||||||
|
@ -4444,6 +4448,7 @@ static void QCBUILTIN PF_getmodelindex (pubprogfuncs_t *prinst, struct globalvar
|
||||||
|
|
||||||
G_FLOAT(OFS_RETURN) = PF_precache_model_Internal(prinst, s, queryonly);
|
G_FLOAT(OFS_RETURN) = PF_precache_model_Internal(prinst, s, queryonly);
|
||||||
}
|
}
|
||||||
|
#ifndef NOLEGACY
|
||||||
void QCBUILTIN PF_precache_vwep_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
void QCBUILTIN PF_precache_vwep_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -4480,6 +4485,7 @@ void QCBUILTIN PF_precache_vwep_model (pubprogfuncs_t *prinst, struct globalvars
|
||||||
G_FLOAT(OFS_RETURN) = 0;
|
G_FLOAT(OFS_RETURN) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// warning: ‘PF_svcoredump’ defined but not used
|
// warning: ‘PF_svcoredump’ defined but not used
|
||||||
/*
|
/*
|
||||||
|
@ -4620,6 +4626,7 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
if (style < MAX_STANDARDLIGHTSTYLES || *val)
|
if (style < MAX_STANDARDLIGHTSTYLES || *val)
|
||||||
|
@ -4645,6 +4652,7 @@ void QCBUILTIN PF_applylightstyle(int style, const char *val, vec3_t rgb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5572,9 +5580,12 @@ static void QCBUILTIN PF_qtBroadcast_WriteEntity (pubprogfuncs_t *prinst, struct
|
||||||
//======================================================
|
//======================================================
|
||||||
|
|
||||||
//copes with any qw point entities.
|
//copes with any qw point entities.
|
||||||
void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is available for some tent types.
|
void SV_point_tempentity (vec3_t o, int qwtype, int count) //count (usually 1) is available for some tent types.
|
||||||
{
|
{
|
||||||
int split=0;
|
int split=0;
|
||||||
|
#ifdef NQPROT
|
||||||
|
int nqtype = qwtype;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SERVER_DEMO_PLAYBACK
|
#ifdef SERVER_DEMO_PLAYBACK
|
||||||
if (sv.demofile)
|
if (sv.demofile)
|
||||||
|
@ -5586,49 +5597,63 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
||||||
#endif
|
#endif
|
||||||
switch(type)
|
switch(qwtype)
|
||||||
{
|
{
|
||||||
case TE_BULLET:
|
case TE_BULLET:
|
||||||
MSG_WriteByte (&sv.multicast, TE_SPIKE);
|
MSG_WriteByte (&sv.multicast, TE_SPIKE);
|
||||||
|
qwtype = TE_BULLET;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, TE_SPIKE);
|
MSG_WriteByte (&sv.nqmulticast, TE_SPIKE);
|
||||||
|
nqtype = TE_BULLET;
|
||||||
#endif
|
#endif
|
||||||
type = TE_BULLET;
|
|
||||||
split = PEXT_TE_BULLET;
|
split = PEXT_TE_BULLET;
|
||||||
break;
|
break;
|
||||||
case TE_SUPERBULLET:
|
case TEQW_SUPERBULLET:
|
||||||
MSG_WriteByte (&sv.multicast, TE_SUPERSPIKE);
|
MSG_WriteByte (&sv.multicast, TE_SUPERSPIKE);
|
||||||
|
qwtype = TEQW_SUPERBULLET;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, TE_SUPERSPIKE);
|
MSG_WriteByte (&sv.nqmulticast, TE_SUPERSPIKE);
|
||||||
|
nqtype = TE_SUPERSPIKE;
|
||||||
#endif
|
#endif
|
||||||
type = TE_SUPERBULLET;
|
|
||||||
split = PEXT_TE_BULLET;
|
split = PEXT_TE_BULLET;
|
||||||
break;
|
break;
|
||||||
case TEQW_BLOOD:
|
case TEQW_QWBLOOD:
|
||||||
case TE_GUNSHOT:
|
case TEQW_QWGUNSHOT:
|
||||||
MSG_WriteByte (&sv.multicast, type);
|
MSG_WriteByte (&sv.multicast, qwtype);
|
||||||
MSG_WriteByte (&sv.multicast, count);
|
MSG_WriteByte (&sv.multicast, count);
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, type); //nq doesn't have a count.
|
MSG_WriteByte (&sv.nqmulticast, nqtype); //nq doesn't have a count.
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case TEQW_EXPLOSION_NOSPRITE:
|
case TEQW_QWEXPLOSION:
|
||||||
MSG_WriteByte (&sv.multicast, TE_EXPLOSION);
|
MSG_WriteByte (&sv.multicast, TEQW_QWEXPLOSION);
|
||||||
|
qwtype = -1;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, TE_EXPLOSION);
|
MSG_WriteByte (&sv.nqmulticast, TENQ_NQEXPLOSION);
|
||||||
|
nqtype = TENQ_QWEXPLOSION;
|
||||||
|
#endif
|
||||||
|
split = PEXT_TE_BULLET;
|
||||||
|
break;
|
||||||
|
case TEQW_NQEXPLOSION:
|
||||||
|
MSG_WriteByte (&sv.multicast, TEQW_QWEXPLOSION);
|
||||||
|
qwtype = TEQW_NQEXPLOSION;
|
||||||
|
#ifdef NQPROT
|
||||||
|
MSG_WriteByte (&sv.nqmulticast, TENQ_NQEXPLOSION);
|
||||||
|
nqtype = -1;
|
||||||
#endif
|
#endif
|
||||||
type = TEQW_EXPLOSION_NOSPRITE;
|
|
||||||
split = PEXT_TE_BULLET;
|
split = PEXT_TE_BULLET;
|
||||||
break;
|
break;
|
||||||
case TE_LIGHTNING1:
|
case TE_LIGHTNING1:
|
||||||
case TE_LIGHTNING2:
|
case TE_LIGHTNING2:
|
||||||
case TE_LIGHTNING3:
|
case TE_LIGHTNING3:
|
||||||
SV_Error("SV_point_tempentity - type is a beam\n");
|
SV_Error("SV_point_tempentity - type is a beam\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
MSG_WriteByte (&sv.multicast, type);
|
MSG_WriteByte (&sv.multicast, qwtype);
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
MSG_WriteByte (&sv.nqmulticast, type);
|
MSG_WriteByte (&sv.nqmulticast, nqtype);
|
||||||
#endif
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
MSG_WriteCoord (&sv.multicast, o[0]);
|
MSG_WriteCoord (&sv.multicast, o[0]);
|
||||||
MSG_WriteCoord (&sv.multicast, o[1]);
|
MSG_WriteCoord (&sv.multicast, o[1]);
|
||||||
|
@ -5638,7 +5663,7 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is
|
||||||
MSG_WriteCoord (&sv.nqmulticast, o[1]);
|
MSG_WriteCoord (&sv.nqmulticast, o[1]);
|
||||||
MSG_WriteCoord (&sv.nqmulticast, o[2]);
|
MSG_WriteCoord (&sv.nqmulticast, o[2]);
|
||||||
#endif
|
#endif
|
||||||
if (type == TEQW_BLOOD || type == TEQW_LIGHTNINGBLOOD)
|
if (qwtype == TEQW_QWBLOOD || qwtype == TEQW_LIGHTNINGBLOOD)
|
||||||
{
|
{
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
sv.nqmulticast.cursize = 0; //don't send a te_blood or lightningblood to an nq client - they'll die horribly.
|
sv.nqmulticast.cursize = 0; //don't send a te_blood or lightningblood to an nq client - they'll die horribly.
|
||||||
|
@ -5653,7 +5678,7 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is
|
||||||
MSG_WriteChar (&sv.nqmulticast, 0);
|
MSG_WriteChar (&sv.nqmulticast, 0);
|
||||||
MSG_WriteChar (&sv.nqmulticast, 0);
|
MSG_WriteChar (&sv.nqmulticast, 0);
|
||||||
MSG_WriteByte (&sv.nqmulticast, count*20);
|
MSG_WriteByte (&sv.nqmulticast, count*20);
|
||||||
if (type == TEQW_BLOOD)
|
if (qwtype == TEQW_QWBLOOD)
|
||||||
MSG_WriteByte (&sv.nqmulticast, 73);
|
MSG_WriteByte (&sv.nqmulticast, 73);
|
||||||
else
|
else
|
||||||
MSG_WriteByte (&sv.nqmulticast, 225);
|
MSG_WriteByte (&sv.nqmulticast, 225);
|
||||||
|
@ -5665,13 +5690,29 @@ void SV_point_tempentity (vec3_t o, int type, int count) //count (usually 1) is
|
||||||
if (!split) //don't bother sending again.
|
if (!split) //don't bother sending again.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//this is for cool people (not nq users)
|
//this is for people with an extension to do that effect properly
|
||||||
|
if (qwtype >= 0)
|
||||||
|
{
|
||||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||||
MSG_WriteByte (&sv.multicast, type);
|
MSG_WriteByte (&sv.multicast, qwtype);
|
||||||
|
if (qwtype == TEQW_QWBLOOD || qwtype == TEQW_QWGUNSHOT)
|
||||||
|
MSG_WriteByte (&sv.multicast, count);
|
||||||
MSG_WriteCoord (&sv.multicast, o[0]);
|
MSG_WriteCoord (&sv.multicast, o[0]);
|
||||||
MSG_WriteCoord (&sv.multicast, o[1]);
|
MSG_WriteCoord (&sv.multicast, o[1]);
|
||||||
MSG_WriteCoord (&sv.multicast, o[2]);
|
MSG_WriteCoord (&sv.multicast, o[2]);
|
||||||
|
}
|
||||||
|
#ifdef NQPROT
|
||||||
|
if (nqtype >= 0)
|
||||||
|
{
|
||||||
|
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
||||||
|
MSG_WriteByte (&sv.nqmulticast, nqtype);
|
||||||
|
if (/*nqtype == TENQ_QWBLOOD ||*/ nqtype == TEQW_NQGUNSHOT)
|
||||||
|
MSG_WriteByte (&sv.multicast, count);
|
||||||
|
MSG_WriteCoord (&sv.nqmulticast, o[0]);
|
||||||
|
MSG_WriteCoord (&sv.nqmulticast, o[1]);
|
||||||
|
MSG_WriteCoord (&sv.nqmulticast, o[2]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
SV_MulticastProtExt (o, MULTICAST_PHS, pr_global_struct->dimension_send, 0, split);
|
SV_MulticastProtExt (o, MULTICAST_PHS, pr_global_struct->dimension_send, 0, split);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6947,6 +6988,7 @@ static void QCBUILTIN PF_readcmd (pubprogfuncs_t *prinst, struct globalvars_s *p
|
||||||
SV_BeginRedirect(old, oldl);
|
SV_BeginRedirect(old, oldl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
PF_forcedemoframe
|
PF_forcedemoframe
|
||||||
|
@ -6963,7 +7005,7 @@ static void QCBUILTIN PF_forcedemoframe (pubprogfuncs_t *prinst, struct globalva
|
||||||
// if (G_FLOAT(OFS_PARM0) == 1)
|
// if (G_FLOAT(OFS_PARM0) == 1)
|
||||||
// SV_SendDemoMessage();
|
// SV_SendDemoMessage();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -8667,10 +8709,15 @@ static void QCBUILTIN PF_te_gunshot(pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
if (svprogfuncs->callargc >= 2)
|
if (svprogfuncs->callargc >= 2)
|
||||||
|
{
|
||||||
count = G_FLOAT(OFS_PARM1);
|
count = G_FLOAT(OFS_PARM1);
|
||||||
|
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_QWGUNSHOT, count);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
count = 1;
|
count = 1;
|
||||||
SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_GUNSHOT, count);
|
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_NQGUNSHOT, count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//DP_TE_QUADEFFECTS1
|
//DP_TE_QUADEFFECTS1
|
||||||
static void QCBUILTIN PF_te_gunshotquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_te_gunshotquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
@ -8710,7 +8757,7 @@ static void QCBUILTIN PF_te_bloodqw(pubprogfuncs_t *prinst, struct globalvars_s
|
||||||
count = G_FLOAT(OFS_PARM1);
|
count = G_FLOAT(OFS_PARM1);
|
||||||
else
|
else
|
||||||
count = 1;
|
count = 1;
|
||||||
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_BLOOD, count);
|
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_QWBLOOD, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
//DP_TE_STANDARDEFFECTBUILTINS
|
//DP_TE_STANDARDEFFECTBUILTINS
|
||||||
|
@ -8729,10 +8776,10 @@ static void QCBUILTIN PF_te_superspikequad(pubprogfuncs_t *prinst, struct global
|
||||||
//void(vector org) te_explosion = #421;
|
//void(vector org) te_explosion = #421;
|
||||||
static void QCBUILTIN PF_te_explosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_te_explosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
if (progstype != PROG_QW)
|
if (progstype == PROG_QW)
|
||||||
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_EXPLOSION_NOSPRITE, 1);
|
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_QWEXPLOSION, 1);
|
||||||
else
|
else
|
||||||
SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_EXPLOSION, 1);
|
SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_NQEXPLOSION, 1);
|
||||||
}
|
}
|
||||||
//DP_TE_QUADEFFECTS1
|
//DP_TE_QUADEFFECTS1
|
||||||
static void QCBUILTIN PF_te_explosionquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_te_explosionquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
@ -8789,7 +8836,7 @@ static void QCBUILTIN PF_te_explosion2(pubprogfuncs_t *prinst, struct globalvars
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||||
MSG_WriteByte (&sv.multicast, old?TE_EXPLOSION:TEQW_EXPLOSION2);
|
MSG_WriteByte (&sv.multicast, old?TEQW_QWEXPLOSION:TEQW_EXPLOSION2);
|
||||||
MSG_WriteCoord (&sv.multicast, org[0]);
|
MSG_WriteCoord (&sv.multicast, org[0]);
|
||||||
MSG_WriteCoord (&sv.multicast, org[1]);
|
MSG_WriteCoord (&sv.multicast, org[1]);
|
||||||
MSG_WriteCoord (&sv.multicast, org[2]);
|
MSG_WriteCoord (&sv.multicast, org[2]);
|
||||||
|
@ -8799,6 +8846,8 @@ static void QCBUILTIN PF_te_explosion2(pubprogfuncs_t *prinst, struct globalvars
|
||||||
MSG_WriteByte (&sv.multicast, length);
|
MSG_WriteByte (&sv.multicast, length);
|
||||||
}
|
}
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
|
if (!old)
|
||||||
|
{
|
||||||
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
||||||
MSG_WriteByte (&sv.nqmulticast, TENQ_EXPLOSION2);
|
MSG_WriteByte (&sv.nqmulticast, TENQ_EXPLOSION2);
|
||||||
MSG_WriteCoord (&sv.nqmulticast, org[0]);
|
MSG_WriteCoord (&sv.nqmulticast, org[0]);
|
||||||
|
@ -8806,6 +8855,7 @@ static void QCBUILTIN PF_te_explosion2(pubprogfuncs_t *prinst, struct globalvars
|
||||||
MSG_WriteCoord (&sv.nqmulticast, org[2]);
|
MSG_WriteCoord (&sv.nqmulticast, org[2]);
|
||||||
MSG_WriteByte (&sv.nqmulticast, start);
|
MSG_WriteByte (&sv.nqmulticast, start);
|
||||||
MSG_WriteByte (&sv.nqmulticast, length);
|
MSG_WriteByte (&sv.nqmulticast, length);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (old)
|
if (old)
|
||||||
|
@ -10335,7 +10385,9 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 99, D("void(string dst, string src, float count)",NULL), true},
|
{"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 99, D("void(string dst, string src, float count)",NULL), true},
|
||||||
{"logtext", PF_logtext, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true},
|
{"logtext", PF_logtext, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true},
|
||||||
{"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true},
|
{"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true},
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
{"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true},
|
{"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true},
|
||||||
|
#endif
|
||||||
//end of mvdsv
|
//end of mvdsv
|
||||||
#endif
|
#endif
|
||||||
{"redirectcmd", PF_redirectcmd, 0, 0, 0, 101, D("void(entity to, string str)","Executes a single console command, and sends the text generated by it to the specified player. The command will be executed at the end of the frame once QC is no longer running - you may wish to pre/postfix it with 'echo'.")},
|
{"redirectcmd", PF_redirectcmd, 0, 0, 0, 101, D("void(entity to, string str)","Executes a single console command, and sends the text generated by it to the specified player. The command will be executed at the end of the frame once QC is no longer running - you may wish to pre/postfix it with 'echo'.")},
|
||||||
|
@ -10996,7 +11048,9 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"setpause", PF_setpause, 0, 0, 0, 531, D("void(float pause)", "Sets whether the server should or should not be paused. This does not affect auto-paused things like when the console is down.")},
|
{"setpause", PF_setpause, 0, 0, 0, 531, D("void(float pause)", "Sets whether the server should or should not be paused. This does not affect auto-paused things like when the console is down.")},
|
||||||
//end dp extras
|
//end dp extras
|
||||||
//begin mvdsv extras
|
//begin mvdsv extras
|
||||||
|
#ifndef NOLEGACY
|
||||||
{"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"},
|
{"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"},
|
||||||
|
#endif
|
||||||
//end mvdsv extras
|
//end mvdsv extras
|
||||||
//restart dp extras
|
//restart dp extras
|
||||||
{"log", PF_Logarithm, 0, 0, 0, 532, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")},
|
{"log", PF_Logarithm, 0, 0, 0, 532, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")},
|
||||||
|
@ -11621,16 +11675,16 @@ void PR_DumpPlatform_f(void)
|
||||||
{"input_buttons", "float", CS},
|
{"input_buttons", "float", CS},
|
||||||
{"input_impulse", "float", CS},
|
{"input_impulse", "float", CS},
|
||||||
{"msg_entity", "entity", QW|NQ},
|
{"msg_entity", "entity", QW|NQ},
|
||||||
{"main", "void()", QW|NQ},
|
{"main", "void()", QW|NQ, D("This function is never called, and is effectively dead code.")},
|
||||||
{"StartFrame", "void()", QW|NQ},
|
{"StartFrame", "void()", QW|NQ, D("Called at the start of each new physics frame. Player entities may think out of sequence so try not to depend upon explicit ordering too much.")},
|
||||||
{"PlayerPreThink", "void()", QW|NQ},
|
{"PlayerPreThink", "void()", QW|NQ, D("With Prediction(QW compat/FTE default): Called before the player's input commands are processed.\nNo Prediction(NQ compat): Called AFTER the player's movement intents have already been processed (ie: velocity will have already changed according to input_*, but before the actual position change.")},
|
||||||
{"PlayerPostThink", "void()", QW|NQ},
|
{"PlayerPostThink", "void()", QW|NQ, D("Called after the player's input commands are processed.")},
|
||||||
{"ClientKill", "void()", QW|NQ},
|
{"ClientKill", "void()", QW|NQ, D("Called in response to 'cmd kill' (or just 'kill').")},
|
||||||
{"ClientConnect", "void()", QW|NQ},
|
{"ClientConnect", "void(optional float csqcactive)", QW|NQ, D("Called after the connecting client has finished loading and is ready to receive active entities. Note that this is NOT the first place that a client might be referred to.")},
|
||||||
{"PutClientInServer", "void()", QW|NQ},
|
{"PutClientInServer", "void()", QW|NQ, D("Enginewise, this is only ever called immediately after ClientConnect and is thus a little redundant. Modwise, this is also called for respawning a player etc.")},
|
||||||
{"ClientDisconnect", "void()", QW|NQ},
|
{"ClientDisconnect", "void()", QW|NQ, D("Called once a client disconnects or times out. Not guarenteed to be called on map changes.")},
|
||||||
{"SetNewParms", "void()", QW|NQ},
|
{"SetNewParms", "void()", QW|NQ, D("Called without context when a new client initially connects (before ClientConnect is even called). This function is expected to only set the parm* globals so that they can be decoded properly later. You should not rely on 'self' being set.")},
|
||||||
{"SetChangeParms", "void()", QW|NQ},
|
{"SetChangeParms", "void()", QW|NQ, D("Called for each client on map changes. Should copy various entity fields to the parm* globals.")},
|
||||||
{"end_sys_globals", "void", QW|NQ|CS|MENU},
|
{"end_sys_globals", "void", QW|NQ|CS|MENU},
|
||||||
|
|
||||||
|
|
||||||
|
@ -11826,7 +11880,7 @@ void PR_DumpPlatform_f(void)
|
||||||
|
|
||||||
{"GameCommand", "void(string cmdtext)", CS|MENU},
|
{"GameCommand", "void(string cmdtext)", CS|MENU},
|
||||||
{"Cef_GeneratePage", "string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders)", QW|NQ|CS|MENU, "Provides an entrypoint to generate pages for the CEF plugin from within QC. Headers are \n-separated key/value pairs (use tokenizebyseparator)."},
|
{"Cef_GeneratePage", "string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders)", QW|NQ|CS|MENU, "Provides an entrypoint to generate pages for the CEF plugin from within QC. Headers are \n-separated key/value pairs (use tokenizebyseparator)."},
|
||||||
// {"HTTP_GeneratePage", "string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders)", QW|NQ, "Provides an entrypoint to generate pages for pages requested over http (sv_listen_tcp+net_enable_http). Headers are \n-separated key/value pairs (use tokenizebyseparator)."},
|
{"HTTP_GeneratePage", "string(string uri, string method, string postdata, __in string requestheaders, __inout string responseheaders)", QW|NQ, "Provides an entrypoint to generate pages for pages requested over http (sv_port_tcp+net_enable_http). Headers are \r\n-separated key/value pairs (use tokenizebyseparator). Return __NULL__ to let the engine handle it, an empty string for a 404, and any other text for a regular 200 response."},
|
||||||
|
|
||||||
{"init", "void(float prevprogs)", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget)."},
|
{"init", "void(float prevprogs)", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget)."},
|
||||||
{"initents", "void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules."},
|
{"initents", "void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules."},
|
||||||
|
|
|
@ -2836,7 +2836,7 @@ cont:
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QDECL Lua_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, void *ctx, void (PDECL *callback) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend))
|
static int QDECL Lua_LoadEnts(pubprogfuncs_t *pf, const char *mapstring, void *ctx, void (PDECL *callback) (pubprogfuncs_t *progfuncs, struct edict_s *ed, void *ctx, const char *entstart, const char *entend), pbool (PDECL *unhandledcallback)(pubprogfuncs_t *,void *,const char **))
|
||||||
{
|
{
|
||||||
lua_State *L = lua.ctx;
|
lua_State *L = lua.ctx;
|
||||||
struct edict_s *ed = NULL;
|
struct edict_s *ed = NULL;
|
||||||
|
|
|
@ -77,9 +77,7 @@ void SV_SavegameComment (char *text, size_t textsize)
|
||||||
text[textsize-1] = '\0';
|
text[textsize-1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QUAKETC
|
pbool SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char **ptr)
|
||||||
|
|
||||||
pbool SV_Legacy_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char **ptr)
|
|
||||||
{
|
{
|
||||||
char token[8192];
|
char token[8192];
|
||||||
com_tokentype_t tt;
|
com_tokentype_t tt;
|
||||||
|
@ -164,6 +162,8 @@ pbool SV_Legacy_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QUAKETC
|
||||||
|
|
||||||
//expects the version to have already been parsed
|
//expects the version to have already been parsed
|
||||||
static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
||||||
{
|
{
|
||||||
|
@ -409,7 +409,7 @@ static qboolean SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
||||||
strcpy(file, "loadgame");
|
strcpy(file, "loadgame");
|
||||||
clnum=VFS_READ(f, file+8, filelen);
|
clnum=VFS_READ(f, file+8, filelen);
|
||||||
file[filelen+8]='\0';
|
file[filelen+8]='\0';
|
||||||
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_Legacy_ExtendedSaveData);
|
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_ExtendedSaveData);
|
||||||
BZ_Free(file);
|
BZ_Free(file);
|
||||||
|
|
||||||
PR_LoadGlabalStruct(false);
|
PR_LoadGlabalStruct(false);
|
||||||
|
@ -947,7 +947,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
|
||||||
memset(file, 0, filelen+1);
|
memset(file, 0, filelen+1);
|
||||||
VFS_READ(f, file, filelen);
|
VFS_READ(f, file, filelen);
|
||||||
file[filelen]='\0';
|
file[filelen]='\0';
|
||||||
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_Legacy_ExtendedSaveData);
|
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, NULL, NULL, SV_ExtendedSaveData);
|
||||||
BZ_Free(file);
|
BZ_Free(file);
|
||||||
|
|
||||||
progstype = pt;
|
progstype = pt;
|
||||||
|
@ -1302,9 +1302,11 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame)
|
||||||
for (i=1 ; i<MAX_SSPARTICLESPRE ; i++)
|
for (i=1 ; i<MAX_SSPARTICLESPRE ; i++)
|
||||||
if (sv.strings.particle_precache[i] && *sv.strings.particle_precache[i])
|
if (sv.strings.particle_precache[i] && *sv.strings.particle_precache[i])
|
||||||
VFS_PRINTF (f, "particle %i %s\n", i, COM_QuotedString(sv.strings.particle_precache[i], buf, sizeof(buf), false));
|
VFS_PRINTF (f, "particle %i %s\n", i, COM_QuotedString(sv.strings.particle_precache[i], buf, sizeof(buf), false));
|
||||||
|
#ifndef NOLEGACY
|
||||||
for (i = 0; i < sizeof(sv.strings.vw_model_precache)/sizeof(sv.strings.vw_model_precache[0]); i++)
|
for (i = 0; i < sizeof(sv.strings.vw_model_precache)/sizeof(sv.strings.vw_model_precache[0]); i++)
|
||||||
if (sv.strings.vw_model_precache[i])
|
if (sv.strings.vw_model_precache[i])
|
||||||
VFS_PRINTF (f, "vwep %i %s\n", i, COM_QuotedString(sv.strings.vw_model_precache[i], buf, sizeof(buf), false));
|
VFS_PRINTF (f, "vwep %i %s\n", i, COM_QuotedString(sv.strings.vw_model_precache[i], buf, sizeof(buf), false));
|
||||||
|
#endif
|
||||||
|
|
||||||
PR_Common_SaveGame(f, svprogfuncs, version >= CACHEGAME_VERSION_BINARY);
|
PR_Common_SaveGame(f, svprogfuncs, version >= CACHEGAME_VERSION_BINARY);
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ typedef struct
|
||||||
qboolean mapchangelocked;
|
qboolean mapchangelocked;
|
||||||
|
|
||||||
#ifdef SAVEDGAMES
|
#ifdef SAVEDGAMES
|
||||||
|
char loadgame_on_restart[MAX_QPATH]; //saved game to load on map_restart
|
||||||
double autosave_time;
|
double autosave_time;
|
||||||
#endif
|
#endif
|
||||||
double time;
|
double time;
|
||||||
|
@ -140,8 +141,6 @@ typedef struct
|
||||||
char mapname[256]; // text description of the map
|
char mapname[256]; // text description of the map
|
||||||
char modelname[MAX_QPATH]; // maps/<name>.bsp, for model_precache[0]
|
char modelname[MAX_QPATH]; // maps/<name>.bsp, for model_precache[0]
|
||||||
|
|
||||||
char loadgame_on_restart[MAX_QPATH]; //saved game to load on map_restart
|
|
||||||
|
|
||||||
world_t world;
|
world_t world;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -153,7 +152,9 @@ typedef struct
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
struct {
|
struct {
|
||||||
|
#ifndef NOLEGACY
|
||||||
const char *vw_model_precache[32];
|
const char *vw_model_precache[32];
|
||||||
|
#endif
|
||||||
const char *model_precache[MAX_PRECACHE_MODELS]; // NULL terminated
|
const char *model_precache[MAX_PRECACHE_MODELS]; // NULL terminated
|
||||||
const char *particle_precache[MAX_SSPARTICLESPRE]; // NULL terminated
|
const char *particle_precache[MAX_SSPARTICLESPRE]; // NULL terminated
|
||||||
const char *sound_precache[MAX_PRECACHE_SOUNDS]; // NULL terminated
|
const char *sound_precache[MAX_PRECACHE_SOUNDS]; // NULL terminated
|
||||||
|
@ -164,8 +165,10 @@ typedef struct
|
||||||
qboolean stringsalloced; //if true, we need to free the string pointers safely rather than just memsetting them to 0
|
qboolean stringsalloced; //if true, we need to free the string pointers safely rather than just memsetting them to 0
|
||||||
vec3_t lightstylecolours[MAX_LIGHTSTYLES];
|
vec3_t lightstylecolours[MAX_LIGHTSTYLES];
|
||||||
|
|
||||||
|
#ifdef HEXEN2
|
||||||
char h2miditrack[MAX_QPATH];
|
char h2miditrack[MAX_QPATH];
|
||||||
qbyte h2cdtrack;
|
qbyte h2cdtrack;
|
||||||
|
#endif
|
||||||
|
|
||||||
int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up)
|
int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up)
|
||||||
int spawned_client_slots; //number of PLAYER slots which are active (ie: putclientinserver was called)
|
int spawned_client_slots; //number of PLAYER slots which are active (ie: putclientinserver was called)
|
||||||
|
@ -223,8 +226,6 @@ typedef struct
|
||||||
int signon_buffer_size[MAX_SIGNON_BUFFERS];
|
int signon_buffer_size[MAX_SIGNON_BUFFERS];
|
||||||
qbyte signon_buffers[MAX_SIGNON_BUFFERS][MAX_DATAGRAM];
|
qbyte signon_buffers[MAX_SIGNON_BUFFERS][MAX_DATAGRAM];
|
||||||
|
|
||||||
qboolean msgfromdemo;
|
|
||||||
|
|
||||||
qboolean gamedirchanged;
|
qboolean gamedirchanged;
|
||||||
|
|
||||||
qboolean haveitems2; //use items2 field instead of serverflags for the high bits of STAT_ITEMS
|
qboolean haveitems2; //use items2 field instead of serverflags for the high bits of STAT_ITEMS
|
||||||
|
@ -232,11 +233,12 @@ typedef struct
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
qboolean mvdrecording;
|
qboolean mvdrecording;
|
||||||
|
#endif
|
||||||
|
|
||||||
//====================================================
|
//====================================================
|
||||||
//this lot is for serverside playback of demos
|
//this lot is for serverside playback of mvds. Use QTV instead.
|
||||||
#ifdef SERVER_DEMO_PLAYBACK
|
#ifdef SERVER_DEMO_PLAYBACK
|
||||||
qboolean mvdplayback;
|
qboolean mvdplayback;
|
||||||
float realtime;
|
float realtime;
|
||||||
|
@ -408,9 +410,13 @@ enum
|
||||||
PRESPAWN_INVALID=0,
|
PRESPAWN_INVALID=0,
|
||||||
PRESPAWN_PROTOCOLSWITCH, //nq drops unreliables until reliables are acked. this gives us a chance to drop any clc_move packets with formats from the previous map
|
PRESPAWN_PROTOCOLSWITCH, //nq drops unreliables until reliables are acked. this gives us a chance to drop any clc_move packets with formats from the previous map
|
||||||
PRESPAWN_SERVERINFO,
|
PRESPAWN_SERVERINFO,
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
PRESPAWN_CSPROGS, //demos contain a copy of the csprogs.
|
PRESPAWN_CSPROGS, //demos contain a copy of the csprogs.
|
||||||
|
#endif
|
||||||
PRESPAWN_SOUNDLIST, //nq skips these
|
PRESPAWN_SOUNDLIST, //nq skips these
|
||||||
|
#ifndef NOLEGACY
|
||||||
PRESPAWN_VWEPMODELLIST, //qw ugly extension.
|
PRESPAWN_VWEPMODELLIST, //qw ugly extension.
|
||||||
|
#endif
|
||||||
PRESPAWN_MODELLIST,
|
PRESPAWN_MODELLIST,
|
||||||
PRESPAWN_MAPCHECK, //wait for old prespawn command
|
PRESPAWN_MAPCHECK, //wait for old prespawn command
|
||||||
PRESPAWN_PARTICLES,
|
PRESPAWN_PARTICLES,
|
||||||
|
@ -676,8 +682,6 @@ typedef struct client_s
|
||||||
|
|
||||||
int trustlevel;
|
int trustlevel;
|
||||||
|
|
||||||
qboolean wasrecorded; //this client shouldn't get any net messages sent to them
|
|
||||||
|
|
||||||
vec3_t specorigin; //mvds need to use a different origin from the one QC has.
|
vec3_t specorigin; //mvds need to use a different origin from the one QC has.
|
||||||
vec3_t specvelocity;
|
vec3_t specvelocity;
|
||||||
|
|
||||||
|
@ -737,7 +741,7 @@ typedef struct client_s
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
//mvd stuff
|
//mvd stuff
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
#define MSG_BUF_SIZE 8192
|
#define MSG_BUF_SIZE 8192
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -768,13 +772,13 @@ typedef struct {
|
||||||
int to;
|
int to;
|
||||||
int size;
|
int size;
|
||||||
qbyte data[1]; //gcc doesn't allow [] (?)
|
qbyte data[1]; //gcc doesn't allow [] (?)
|
||||||
} header_t;
|
} mvd_header_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
sizebuf_t sb;
|
sizebuf_t sb;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
header_t *h;
|
mvd_header_t *h;
|
||||||
} demobuf_t;
|
} demobuf_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -821,7 +825,7 @@ typedef struct
|
||||||
|
|
||||||
struct mvddest_s *dest;
|
struct mvddest_s *dest;
|
||||||
} demo_t;
|
} demo_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
@ -935,10 +939,6 @@ typedef struct
|
||||||
|
|
||||||
struct netprim_s netprim;
|
struct netprim_s netprim;
|
||||||
|
|
||||||
qboolean demoplayback;
|
|
||||||
qboolean demorecording;
|
|
||||||
qboolean msgfromdemo;
|
|
||||||
|
|
||||||
int language; //the server operators language
|
int language; //the server operators language
|
||||||
laggedpacket_t *free_lagged_packet;
|
laggedpacket_t *free_lagged_packet;
|
||||||
packet_entities_t entstatebuffer; /*just a temp buffer*/
|
packet_entities_t entstatebuffer; /*just a temp buffer*/
|
||||||
|
@ -1479,7 +1479,7 @@ void SV_ChatThink(client_t *client);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
/*
|
/*
|
||||||
//
|
//
|
||||||
// sv_mvd.c
|
// sv_mvd.c
|
||||||
|
@ -1551,12 +1551,16 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest);
|
||||||
|
|
||||||
extern demo_t demo; // server demo struct
|
extern demo_t demo; // server demo struct
|
||||||
|
|
||||||
|
extern cvar_t sv_demoDir;
|
||||||
|
extern cvar_t sv_demoAutoRecord;
|
||||||
extern cvar_t sv_demofps;
|
extern cvar_t sv_demofps;
|
||||||
extern cvar_t sv_demoPings;
|
extern cvar_t sv_demoPings;
|
||||||
extern cvar_t sv_demoUseCache;
|
extern cvar_t sv_demoUseCache;
|
||||||
extern cvar_t sv_demoMaxSize;
|
extern cvar_t sv_demoMaxSize;
|
||||||
extern cvar_t sv_demoMaxDirSize;
|
extern cvar_t sv_demoMaxDirSize;
|
||||||
|
|
||||||
|
qboolean MVD_CheckSpace(qboolean broadcastwarnings);
|
||||||
|
void SV_MVD_AutoRecord (void);
|
||||||
char *SV_Demo_CurrentOutput(void);
|
char *SV_Demo_CurrentOutput(void);
|
||||||
void SV_Demo_PrintOutputs(void);
|
void SV_Demo_PrintOutputs(void);
|
||||||
void SV_MVDInit(void);
|
void SV_MVDInit(void);
|
||||||
|
@ -1575,6 +1579,7 @@ typedef struct
|
||||||
char challenge[32];
|
char challenge[32];
|
||||||
} qtvpendingstate_t;
|
} qtvpendingstate_t;
|
||||||
int SV_MVD_GotQTVRequest(vfsfile_t *clientstream, char *headerstart, char *headerend, qtvpendingstate_t *p);
|
int SV_MVD_GotQTVRequest(vfsfile_t *clientstream, char *headerstart, char *headerend, qtvpendingstate_t *p);
|
||||||
|
#endif
|
||||||
|
|
||||||
// savegame.c
|
// savegame.c
|
||||||
void SV_Savegame_f (void);
|
void SV_Savegame_f (void);
|
||||||
|
|
|
@ -692,8 +692,10 @@ void SV_Map_f (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_MVDStop_f();
|
SV_MVDStop_f();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
if (!isDedicated) //otherwise, info used on map loading isn't present
|
if (!isDedicated) //otherwise, info used on map loading isn't present
|
||||||
|
@ -1999,7 +2001,9 @@ static void SV_Status_f (void)
|
||||||
Con_Printf("gamedir : %s\n", FS_GetGamedir(true));
|
Con_Printf("gamedir : %s\n", FS_GetGamedir(true));
|
||||||
if (sv.csqcdebug)
|
if (sv.csqcdebug)
|
||||||
Con_Printf("csqc debug : true\n");
|
Con_Printf("csqc debug : true\n");
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_Demo_PrintOutputs();
|
SV_Demo_PrintOutputs();
|
||||||
|
#endif
|
||||||
NET_PrintConnectionsStatus(svs.sockets);
|
NET_PrintConnectionsStatus(svs.sockets);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2187,6 +2191,7 @@ void SV_ConSay_f(void)
|
||||||
SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text);
|
SV_ClientPrintf(client, PRINT_CHAT, "%s\n", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg;
|
sizebuf_t *msg;
|
||||||
|
@ -2198,6 +2203,7 @@ void SV_ConSay_f(void)
|
||||||
MSG_WriteChar(msg, '\n');
|
MSG_WriteChar(msg, '\n');
|
||||||
MSG_WriteChar(msg, 0);
|
MSG_WriteChar(msg, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SV_ConSayOne_f (void)
|
static void SV_ConSayOne_f (void)
|
||||||
|
@ -2927,6 +2933,7 @@ void SV_PrecacheList_f(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
char *group = Cmd_Argv(1);
|
char *group = Cmd_Argv(1);
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (!*group || !strncmp(group, "vwep", 4))
|
if (!*group || !strncmp(group, "vwep", 4))
|
||||||
{
|
{
|
||||||
for (i = 0; i < sizeof(sv.strings.vw_model_precache)/sizeof(sv.strings.vw_model_precache[0]); i++)
|
for (i = 0; i < sizeof(sv.strings.vw_model_precache)/sizeof(sv.strings.vw_model_precache[0]); i++)
|
||||||
|
@ -2935,6 +2942,7 @@ void SV_PrecacheList_f(void)
|
||||||
Con_Printf("vwep %u: %s\n", i, sv.strings.vw_model_precache[i]);
|
Con_Printf("vwep %u: %s\n", i, sv.strings.vw_model_precache[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (!*group || !strncmp(group, "model", 5))
|
if (!*group || !strncmp(group, "model", 5))
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAX_PRECACHE_MODELS; i++)
|
for (i = 0; i < MAX_PRECACHE_MODELS; i++)
|
||||||
|
|
|
@ -6,176 +6,6 @@
|
||||||
void NPP_MVDWriteByte(qbyte data, client_t *to, int broadcast);
|
void NPP_MVDWriteByte(qbyte data, client_t *to, int broadcast);
|
||||||
|
|
||||||
void SV_New_f (void);
|
void SV_New_f (void);
|
||||||
/*
|
|
||||||
float svdemotime;
|
|
||||||
FILE *svdemofile;
|
|
||||||
|
|
||||||
void SV_WriteDemoMessage (sizebuf_t *msg)
|
|
||||||
{
|
|
||||||
short len;
|
|
||||||
float time;
|
|
||||||
if (!svs.demorecording)
|
|
||||||
return;
|
|
||||||
time = LittleFloat(sv.time);
|
|
||||||
fwrite(&time, 1, sizeof(time), svdemofile);
|
|
||||||
len = LittleShort((short)msg->cursize);
|
|
||||||
fwrite(&len, 1, sizeof(len), svdemofile);
|
|
||||||
fwrite(msg->data, 1, msg->cursize, svdemofile);
|
|
||||||
}
|
|
||||||
|
|
||||||
qboolean SV_GetDemoMessage (void)
|
|
||||||
{
|
|
||||||
short len;
|
|
||||||
float time;
|
|
||||||
if (sv.time < svdemotime)
|
|
||||||
{
|
|
||||||
sv.msgfromdemo = false;
|
|
||||||
return NET_GetPacket(NS_SERVER);
|
|
||||||
}
|
|
||||||
sv.msgfromdemo = true;
|
|
||||||
|
|
||||||
fread(&len, 1, sizeof(len), svdemofile);
|
|
||||||
net_message.cursize = LittleShort(len);
|
|
||||||
fread(net_message.data, 1, net_message.cursize, svdemofile);
|
|
||||||
|
|
||||||
sv.time = svdemotime;
|
|
||||||
|
|
||||||
if (!fread(&time, 1, sizeof(time), svdemofile))
|
|
||||||
{
|
|
||||||
svs.demoplayback = false;
|
|
||||||
fclose(svdemofile);
|
|
||||||
}
|
|
||||||
svdemotime = LittleFloat(time);
|
|
||||||
|
|
||||||
net_from.ip[0] = 0;
|
|
||||||
net_from.ip[1] = 0;
|
|
||||||
net_from.ip[2] = 0;
|
|
||||||
net_from.ip[3] = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
qboolean SV_GetPacket (void)
|
|
||||||
{
|
|
||||||
if (svs.demoplayback)
|
|
||||||
return SV_GetDemoMessage ();
|
|
||||||
|
|
||||||
if (!NET_GetPacket (NS_SERVER))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SV_WriteDemoMessage (&net_message);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_RecordDemo_f (void)
|
|
||||||
{
|
|
||||||
client_t *c;
|
|
||||||
int clnum;
|
|
||||||
int i;
|
|
||||||
char *name;
|
|
||||||
char *mapname;
|
|
||||||
name = Cmd_Argv(1);
|
|
||||||
mapname = Cmd_Argv(2);
|
|
||||||
|
|
||||||
svdemofile = fopen(name, "wb");
|
|
||||||
if (!svdemofile)
|
|
||||||
{
|
|
||||||
Con_Printf("Failed to open output file\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(mapname, 1, sizeof(char)*(strlen(mapname)+1), svdemofile);
|
|
||||||
|
|
||||||
|
|
||||||
for (clnum = 0; clnum < svs.allocated_client_slots; clnum++) //clear the server so the clients reconnect and send nice fresh messages.
|
|
||||||
{
|
|
||||||
c = &svs.clients[clnum];
|
|
||||||
if (c->state < cs_connected)
|
|
||||||
continue;
|
|
||||||
ClientReliableWrite_Begin (c, svc_stufftext, 2+strlen("reconnect\n"));
|
|
||||||
ClientReliableWrite_String (c, "disconnect;wait;reconnect\n");
|
|
||||||
c->drop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SV_SendMessagesToAll ();
|
|
||||||
|
|
||||||
svs.demorecording = true;
|
|
||||||
|
|
||||||
i = predictablerandgetseed();
|
|
||||||
fwrite(&i, 1, sizeof(i), svdemofile);
|
|
||||||
|
|
||||||
SV_SpawnServer(mapname, NULL, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SV_LoadClientDemo (void);
|
|
||||||
void SV_PlayDemo_f(void)
|
|
||||||
{
|
|
||||||
client_t *c;
|
|
||||||
int clnum;
|
|
||||||
int i;
|
|
||||||
char *name;
|
|
||||||
float time;
|
|
||||||
char mapname[64];
|
|
||||||
|
|
||||||
name = Cmd_Argv(1);
|
|
||||||
|
|
||||||
if (svdemofile)
|
|
||||||
fclose(svdemofile);
|
|
||||||
svs.demoplayback=false;
|
|
||||||
svs.demorecording=false;
|
|
||||||
|
|
||||||
COM_FOpenFile(name, &svdemofile);
|
|
||||||
|
|
||||||
if (!svdemofile)
|
|
||||||
{
|
|
||||||
Con_Printf("Failed to open input file\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifndef SERVERONLY
|
|
||||||
CL_Disconnect();
|
|
||||||
#endif
|
|
||||||
i = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
fread(mapname+i, 1, sizeof(char), svdemofile);
|
|
||||||
i++;
|
|
||||||
} while (mapname[i-1]);
|
|
||||||
|
|
||||||
svs.demoplayback = true;
|
|
||||||
|
|
||||||
for (clnum = 0; clnum < svs.allocated_client_slots; clnum++) //clear the server so new clients don't conflict.
|
|
||||||
{
|
|
||||||
c = &svs.clients[clnum];
|
|
||||||
if (c->state < cs_connected)
|
|
||||||
continue;
|
|
||||||
ClientReliableWrite_Begin (c, svc_stufftext, 2+strlen("reconnect\n"));
|
|
||||||
ClientReliableWrite_String (c, "reconnect\n");
|
|
||||||
c->drop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SV_SendMessagesToAll ();
|
|
||||||
|
|
||||||
fread(&i, 1, sizeof(i), svdemofile);
|
|
||||||
predictablesrand(i);
|
|
||||||
|
|
||||||
|
|
||||||
fread(&time, 1, sizeof(time), svdemofile);
|
|
||||||
svdemotime = LittleFloat(time);
|
|
||||||
|
|
||||||
SV_SpawnServer(mapname, NULL, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
qboolean SV_GetPacket (void)
|
qboolean SV_GetPacket (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2363,6 +2363,7 @@ qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
void SV_WritePlayersToMVD (client_t *client, client_frame_t *frame, sizebuf_t *msg)
|
void SV_WritePlayersToMVD (client_t *client, client_frame_t *frame, sizebuf_t *msg)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
@ -2449,6 +2450,7 @@ void SV_WritePlayersToMVD (client_t *client, client_frame_t *frame, sizebuf_t *m
|
||||||
dcl->flags |= DF_GIB;
|
dcl->flags |= DF_GIB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
|
@ -4034,9 +4036,11 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
||||||
// send over the players in the PVS
|
// send over the players in the PVS
|
||||||
if (svs.gametype != GT_HALFLIFE)
|
if (svs.gametype != GT_HALFLIFE)
|
||||||
{
|
{
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (client == &demo.recorder)
|
if (client == &demo.recorder)
|
||||||
SV_WritePlayersToMVD(client, frame, msg);
|
SV_WritePlayersToMVD(client, frame, msg);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
SV_WritePlayersToClient (client, frame, clent, cameras, msg);
|
SV_WritePlayersToClient (client, frame, clent, cameras, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -605,8 +605,10 @@ void SV_UnspawnServer (void) //terminate the running server.
|
||||||
Con_TPrintf("Server ended\n");
|
Con_TPrintf("Server ended\n");
|
||||||
SV_FinalMessage("Server unspawned\n");
|
SV_FinalMessage("Server unspawned\n");
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_MVDStop (MVD_CLOSE_STOPPED, false);
|
SV_MVDStop (MVD_CLOSE_STOPPED, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < sv.allocated_client_slots; i++)
|
for (i = 0; i < sv.allocated_client_slots; i++)
|
||||||
{
|
{
|
||||||
|
@ -1725,8 +1727,9 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
||||||
|
|
||||||
FS_ReferenceControl(0, 0);
|
FS_ReferenceControl(0, 0);
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_MVD_SendInitialGamestate(NULL);
|
SV_MVD_SendInitialGamestate(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
SSV_UpdateAddresses();
|
SSV_UpdateAddresses();
|
||||||
|
|
||||||
|
|
|
@ -221,8 +221,10 @@ void SV_Shutdown (void)
|
||||||
|
|
||||||
SV_UnspawnServer();
|
SV_UnspawnServer();
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_MVDStop (MVD_CLOSE_STOPPED, false);
|
SV_MVDStop (MVD_CLOSE_STOPPED, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (svs.entstatebuffer.entities)
|
if (svs.entstatebuffer.entities)
|
||||||
{
|
{
|
||||||
|
@ -722,7 +724,9 @@ void SV_DropClient (client_t *drop)
|
||||||
{
|
{
|
||||||
// send notification to all remaining clients
|
// send notification to all remaining clients
|
||||||
SV_FullClientUpdate (drop, NULL);
|
SV_FullClientUpdate (drop, NULL);
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_MVD_FullClientUpdate(NULL, drop);
|
SV_MVD_FullClientUpdate(NULL, drop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drop->controlled)
|
if (drop->controlled)
|
||||||
|
@ -968,8 +972,10 @@ void SV_FullClientUpdate (client_t *client, client_t *to)
|
||||||
{
|
{
|
||||||
SV_FullClientUpdate(client, &svs.clients[i]);
|
SV_FullClientUpdate(client, &svs.clients[i]);
|
||||||
}
|
}
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_FullClientUpdate(client, &demo.recorder);
|
SV_FullClientUpdate(client, &demo.recorder);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2549,7 +2555,7 @@ client_t *SVC_DirectConnect(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sv.msgfromdemo || net_from.type == NA_LOOPBACK) //normal rules don't apply
|
if (net_from.type == NA_LOOPBACK) //normal rules don't apply
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2737,9 +2743,6 @@ client_t *SVC_DirectConnect(void)
|
||||||
newcl->protocol = protocol;
|
newcl->protocol = protocol;
|
||||||
Q_strncpyz(newcl->guid, guid, sizeof(newcl->guid));
|
Q_strncpyz(newcl->guid, guid, sizeof(newcl->guid));
|
||||||
|
|
||||||
if (sv.msgfromdemo)
|
|
||||||
newcl->wasrecorded = true;
|
|
||||||
|
|
||||||
// Con_TPrintf("%s:%s:connect\n", sv.name, NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
// Con_TPrintf("%s:%s:connect\n", sv.name, NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
|
|
||||||
// if there is already a slot for this ip, drop it
|
// if there is already a slot for this ip, drop it
|
||||||
|
@ -3127,12 +3130,6 @@ client_t *SVC_DirectConnect(void)
|
||||||
newcl->lockedtill = 0;
|
newcl->lockedtill = 0;
|
||||||
|
|
||||||
#ifdef SVRANKING
|
#ifdef SVRANKING
|
||||||
if (svs.demorecording || (svs.demoplayback && newcl->wasrecorded)) //disable rankings. Could cock things up.
|
|
||||||
{
|
|
||||||
SV_GetNewSpawnParms(newcl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//rankid is figured out in extract from user info
|
//rankid is figured out in extract from user info
|
||||||
if (!newcl->rankid) //failed to get a userid
|
if (!newcl->rankid) //failed to get a userid
|
||||||
{
|
{
|
||||||
|
@ -3210,7 +3207,6 @@ client_t *SVC_DirectConnect(void)
|
||||||
}
|
}
|
||||||
//else loaded players already have their initial parms set
|
//else loaded players already have their initial parms set
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
// call the progs to get default spawn parms for the new client
|
// call the progs to get default spawn parms for the new client
|
||||||
if (!preserveparms)
|
if (!preserveparms)
|
||||||
|
@ -3220,8 +3216,6 @@ client_t *SVC_DirectConnect(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (!newcl->wasrecorded)
|
|
||||||
{
|
|
||||||
SV_AcceptMessage (newcl);
|
SV_AcceptMessage (newcl);
|
||||||
|
|
||||||
newcl->state = cs_free;
|
newcl->state = cs_free;
|
||||||
|
@ -3244,20 +3238,6 @@ client_t *SVC_DirectConnect(void)
|
||||||
// Con_DPrintf ("Client %s connected\n", newcl->name);
|
// Con_DPrintf ("Client %s connected\n", newcl->name);
|
||||||
}
|
}
|
||||||
newcl->state = cs_connected;
|
newcl->state = cs_connected;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (newcl->spectator)
|
|
||||||
{
|
|
||||||
SV_BroadcastTPrintf(PRINT_LOW, "recorded spectator %s connected\n", newcl->name);
|
|
||||||
// Con_Printf ("Recorded spectator %s connected\n", newcl->name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SV_BroadcastTPrintf(PRINT_LOW, "recorded client %s connected\n", newcl->name);
|
|
||||||
// Con_DPrintf ("Recorded client %s connected\n", newcl->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newcl->sendinfo = true;
|
newcl->sendinfo = true;
|
||||||
|
|
||||||
if (redirect)
|
if (redirect)
|
||||||
|
@ -3361,7 +3341,7 @@ int Rcon_Validate (void)
|
||||||
|
|
||||||
const size_t digestsize = 20;
|
const size_t digestsize = 20;
|
||||||
size_t i, k;
|
size_t i, k;
|
||||||
unsigned char digest[digestsize];
|
unsigned char digest[512];
|
||||||
const unsigned char **tokens = alloca(sizeof(*tokens)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
const unsigned char **tokens = alloca(sizeof(*tokens)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
||||||
size_t *toksizes = alloca(sizeof(*toksizes)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
size_t *toksizes = alloca(sizeof(*toksizes)*(Cmd_Argc()*2+5)); //overallocation in case argc is 0.
|
||||||
if (strlen(pass) > digestsize*2)
|
if (strlen(pass) > digestsize*2)
|
||||||
|
@ -4778,11 +4758,13 @@ static void SV_PauseChanged(void)
|
||||||
ClientReliableWrite_Byte (cl, sv.paused!=0);
|
ClientReliableWrite_Byte (cl, sv.paused!=0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
ClientReliableWrite_Begin (&demo.recorder, svc_setpause, 2);
|
ClientReliableWrite_Begin (&demo.recorder, svc_setpause, 2);
|
||||||
ClientReliableWrite_Byte (&demo.recorder, sv.paused!=0);
|
ClientReliableWrite_Byte (&demo.recorder, sv.paused!=0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5046,10 +5028,9 @@ float SV_Frame (void)
|
||||||
// send messages back to the clients that had packets read this frame
|
// send messages back to the clients that had packets read this frame
|
||||||
SV_SendClientMessages ();
|
SV_SendClientMessages ();
|
||||||
|
|
||||||
// demo_start = Sys_DoubleTime ();
|
#ifdef MVD_RECORDING
|
||||||
SV_SendMVDMessage();
|
SV_SendMVDMessage();
|
||||||
// demo_end = Sys_DoubleTime ();
|
#endif
|
||||||
// svs.stats.demo += demo_end - demo_start;
|
|
||||||
|
|
||||||
// send a heartbeat to the master if needed
|
// send a heartbeat to the master if needed
|
||||||
SV_Master_Heartbeat ();
|
SV_Master_Heartbeat ();
|
||||||
|
@ -5097,8 +5078,10 @@ static void SV_InfoChanged(void *context, const char *key)
|
||||||
if (context != &svs.info && *key == '_')
|
if (context != &svs.info && *key == '_')
|
||||||
return; //these keys are considered private to originating client/server, and are not broadcast to anyone else
|
return; //these keys are considered private to originating client/server, and are not broadcast to anyone else
|
||||||
|
|
||||||
if (svs.demorecording)
|
#ifdef MVD_RECORDING
|
||||||
|
if (sv.mvdrecording)
|
||||||
InfoSync_Add(&demo.recorder.infosync, context, key); //make sure it gets written into mvds too.
|
InfoSync_Add(&demo.recorder.infosync, context, key); //make sure it gets written into mvds too.
|
||||||
|
#endif
|
||||||
for (i = 0; i < svs.allocated_client_slots; i++)
|
for (i = 0; i < svs.allocated_client_slots; i++)
|
||||||
{
|
{
|
||||||
if (svs.clients[i].state >= cs_connected)
|
if (svs.clients[i].state >= cs_connected)
|
||||||
|
@ -5289,7 +5272,9 @@ void SV_InitLocal (void)
|
||||||
Cmd_AddCommandAD ("load", SV_Loadgame_f, SV_Savegame_c, "Loads an existing saved game.");
|
Cmd_AddCommandAD ("load", SV_Loadgame_f, SV_Savegame_c, "Loads an existing saved game.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_MVDInit();
|
SV_MVDInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
svs.info.ChangeCB = SV_InfoChanged;
|
svs.info.ChangeCB = SV_InfoChanged;
|
||||||
svs.info.ChangeCTX = &svs.info;
|
svs.info.ChangeCTX = &svs.info;
|
||||||
|
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
#ifndef CLIENTONLY
|
#ifndef CLIENTONLY
|
||||||
|
|
||||||
#include "winquake.h"
|
#include "winquake.h"
|
||||||
|
@ -26,16 +27,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#include "netinc.h"
|
#include "netinc.h"
|
||||||
|
|
||||||
|
|
||||||
void SV_MVDStop_f (void);
|
void SV_MVDStop_f (void);
|
||||||
|
|
||||||
#define demo_size_padding 0x1000
|
#define demo_size_padding 0x1000
|
||||||
|
|
||||||
static void QDECL SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue);
|
static void QDECL SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue);
|
||||||
|
|
||||||
|
cvar_t sv_demoAutoRecord = CVARAD("sv_demoAutoRecord", "0", "cl_autodemo", "If set, automatically record demos.\n-1: record on client connection.\n1+: record once there's this many active players on the server.");
|
||||||
cvar_t sv_demoUseCache = CVARD("sv_demoUseCache", "", "If set, demo data will be flushed only periodically");
|
cvar_t sv_demoUseCache = CVARD("sv_demoUseCache", "", "If set, demo data will be flushed only periodically");
|
||||||
cvar_t sv_demoCacheSize = CVAR("sv_demoCacheSize", "0x80000"); //half a meg
|
cvar_t sv_demoCacheSize = CVAR("sv_demoCacheSize", "0x80000"); //half a meg
|
||||||
cvar_t sv_demoMaxDirSize = CVARD("sv_demoMaxDirSize", "102400", "Maximum allowed serverside storage for mvds. set to blank to remove the limit. New demos cannot be recorded once this reaches 0."); //so ktpro autorecords.
|
cvar_t sv_demoMaxDirSize = CVARD("sv_demoMaxDirSize", "100mb", "Maximum allowed serverside storage space for mvds. set to blank to remove the limit. New demos cannot be recorded once this size is reached."); //so ktpro autorecords.
|
||||||
|
cvar_t sv_demoMaxDirCount = CVARD("sv_demoMaxDirCount", "500", "Maximum allowed serverside mvds to record. Set to 0 to remove the limit. New demos cannot be recorded once this many demos have already been recorded."); //so ktpro autorecords.
|
||||||
|
cvar_t sv_demoMaxDirAge = CVARD("sv_demoMaxDirAge", "0", "Maximum allowed age for demos, any older demos will be deleted when sv_demoClearOld is set (this doesn't prevent recording new demos).");
|
||||||
|
cvar_t sv_demoClearOld = CVARD("sv_demoClearOld", "0", "Automatically delete demos to keep the demos count reasonable.");
|
||||||
cvar_t sv_demoDir = CVARC("sv_demoDir", "demos", SV_DemoDir_Callback);
|
cvar_t sv_demoDir = CVARC("sv_demoDir", "demos", SV_DemoDir_Callback);
|
||||||
cvar_t sv_demofps = CVAR("sv_demofps", "30");
|
cvar_t sv_demofps = CVAR("sv_demofps", "30");
|
||||||
cvar_t sv_demoPings = CVARD("sv_demoPings", "10", "Interval between ping updates in mvds");
|
cvar_t sv_demoPings = CVARD("sv_demoPings", "10", "Interval between ping updates in mvds");
|
||||||
|
@ -49,6 +53,7 @@ cvar_t qtv_password = CVAR( "qtv_password", "");
|
||||||
cvar_t qtv_maxstreams = CVARAFD( "qtv_maxstreams", "0",
|
cvar_t qtv_maxstreams = CVARAFD( "qtv_maxstreams", "0",
|
||||||
"mvd_maxstreams", 0, "This is the maximum number of QTV clients/proxies that may be directly connected to the server. If empty then there is no limit. 0 disallows any streaming.");
|
"mvd_maxstreams", 0, "This is the maximum number of QTV clients/proxies that may be directly connected to the server. If empty then there is no limit. 0 disallows any streaming.");
|
||||||
|
|
||||||
|
cvar_t sv_demoAutoPrefix = CVAR("sv_demoAutoPrefix", "auto_");
|
||||||
cvar_t sv_demoPrefix = CVAR("sv_demoPrefix", "");
|
cvar_t sv_demoPrefix = CVAR("sv_demoPrefix", "");
|
||||||
cvar_t sv_demoSuffix = CVAR("sv_demoSuffix", "");
|
cvar_t sv_demoSuffix = CVAR("sv_demoSuffix", "");
|
||||||
cvar_t sv_demotxt = CVAR("sv_demotxt", "1");
|
cvar_t sv_demotxt = CVAR("sv_demotxt", "1");
|
||||||
|
@ -656,20 +661,20 @@ void DemoWriteQTVTimePad(int msecs) //broadcast to all proxies
|
||||||
// returns the file size
|
// returns the file size
|
||||||
// return -1 if file is not present
|
// return -1 if file is not present
|
||||||
// the file should be in BINARY mode for stupid OSs that care
|
// the file should be in BINARY mode for stupid OSs that care
|
||||||
#define MAX_DIRFILES 1000
|
|
||||||
#define MAX_MVD_NAME 64
|
#define MAX_MVD_NAME 64
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char name[MAX_MVD_NAME];
|
char name[MAX_MVD_NAME];
|
||||||
int size;
|
qofs_t size;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
|
searchpathfuncs_t *path;
|
||||||
} file_t;
|
} file_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
file_t *files;
|
file_t *files;
|
||||||
int size;
|
qofs_t size;
|
||||||
int numfiles;
|
int numfiles;
|
||||||
int numdirs;
|
int numdirs;
|
||||||
|
|
||||||
|
@ -690,11 +695,19 @@ static int QDECL Sys_listdirFound(const char *fname, qofs_t fsize, time_t mtime,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (dir->numfiles == dir->maxfiles)
|
if (dir->numfiles == dir->maxfiles)
|
||||||
return true;
|
{
|
||||||
|
int nc = dir->numfiles + 256;
|
||||||
|
file_t *n = realloc(dir->files, nc*sizeof(*dir->files));
|
||||||
|
if (!n)
|
||||||
|
return false;
|
||||||
|
dir->files = n;
|
||||||
|
dir->maxfiles = nc;
|
||||||
|
}
|
||||||
f = &dir->files[dir->numfiles++];
|
f = &dir->files[dir->numfiles++];
|
||||||
Q_strncpyz(f->name, fname, sizeof(f->name));
|
Q_strncpyz(f->name, fname, sizeof(f->name));
|
||||||
f->size = fsize;
|
f->size = fsize;
|
||||||
f->mtime = mtime;
|
f->mtime = mtime;
|
||||||
|
f->path = spath;
|
||||||
dir->size += fsize;
|
dir->size += fsize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -712,22 +725,29 @@ static int QDECL Sys_listdir_Sort(const void *va, const void *vb)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dir_t *Sys_listdir (char *path, char *ext, qboolean usesorting)
|
static dir_t *Sys_listdemos (char *path, int ispublic, qboolean usesorting)
|
||||||
{
|
{
|
||||||
|
const char *exts[] = {
|
||||||
|
".mvd", ".mvd.gz",
|
||||||
|
".qwz", ".qwz.gz",
|
||||||
|
#ifdef NQPROT
|
||||||
|
".dem", ".dem.gz",
|
||||||
|
#endif
|
||||||
|
#if defined(Q2SERVER) || defined(Q2CLIENT)
|
||||||
|
".dm2", ".dm2.gz"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
char searchterm[MAX_QPATH];
|
char searchterm[MAX_QPATH];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
unsigned int maxfiles = MAX_DIRFILES;
|
dir_t *dir = malloc(sizeof(*dir));
|
||||||
dir_t *dir = malloc(sizeof(*dir) + sizeof(*dir->files)*maxfiles);
|
|
||||||
memset(dir, 0, sizeof(*dir));
|
memset(dir, 0, sizeof(*dir));
|
||||||
dir->files = (file_t*)(dir+1);
|
dir->files = NULL;
|
||||||
dir->maxfiles = maxfiles;
|
dir->maxfiles = 0;
|
||||||
|
|
||||||
Q_strncpyz(searchterm, va("%s/*%s", path, ext), sizeof(searchterm));
|
for (i = 0; i < (ispublic?2:countof(exts)); i++)
|
||||||
COM_EnumerateFiles(searchterm, Sys_listdirFound, dir);
|
|
||||||
|
|
||||||
if (!strcmp(ext, ".mvd"))
|
|
||||||
{
|
{
|
||||||
Q_strncpyz(searchterm, va("%s/*%s.gz", path, ext), sizeof(searchterm));
|
Q_strncpyz(searchterm, va("%s/*%s", path, exts[i]), sizeof(searchterm));
|
||||||
COM_EnumerateFiles(searchterm, Sys_listdirFound, dir);
|
COM_EnumerateFiles(searchterm, Sys_listdirFound, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,6 +758,8 @@ static dir_t *Sys_listdir (char *path, char *ext, qboolean usesorting)
|
||||||
}
|
}
|
||||||
static void Sys_freedir(dir_t *dir)
|
static void Sys_freedir(dir_t *dir)
|
||||||
{
|
{
|
||||||
|
if (dir)
|
||||||
|
free(dir->files);
|
||||||
free(dir);
|
free(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,6 +1197,9 @@ void MVD_Init (void)
|
||||||
Cvar_Register (&sv_demoCacheSize, MVDVARGROUP);
|
Cvar_Register (&sv_demoCacheSize, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoMaxSize, MVDVARGROUP);
|
Cvar_Register (&sv_demoMaxSize, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoMaxDirSize, MVDVARGROUP);
|
Cvar_Register (&sv_demoMaxDirSize, MVDVARGROUP);
|
||||||
|
Cvar_Register (&sv_demoMaxDirCount, MVDVARGROUP);
|
||||||
|
Cvar_Register (&sv_demoMaxDirAge, MVDVARGROUP);
|
||||||
|
Cvar_Register (&sv_demoClearOld, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoDir, MVDVARGROUP);
|
Cvar_Register (&sv_demoDir, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoPrefix, MVDVARGROUP);
|
Cvar_Register (&sv_demoPrefix, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoSuffix, MVDVARGROUP);
|
Cvar_Register (&sv_demoSuffix, MVDVARGROUP);
|
||||||
|
@ -1182,6 +1207,8 @@ void MVD_Init (void)
|
||||||
Cvar_Register (&sv_demoExtraNames, MVDVARGROUP);
|
Cvar_Register (&sv_demoExtraNames, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoExtensions, MVDVARGROUP);
|
Cvar_Register (&sv_demoExtensions, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demoAutoCompress,MVDVARGROUP);
|
Cvar_Register (&sv_demoAutoCompress,MVDVARGROUP);
|
||||||
|
Cvar_Register (&sv_demoAutoRecord, MVDVARGROUP);
|
||||||
|
Cvar_Register (&sv_demoAutoPrefix, MVDVARGROUP);
|
||||||
Cvar_Register (&sv_demo_write_csqc,MVDVARGROUP);
|
Cvar_Register (&sv_demo_write_csqc,MVDVARGROUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,6 +1288,7 @@ mvddest_t *SV_FindRecordFile(char *match, mvddest_t ***link_out)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
SV_InitRecord
|
SV_InitRecord
|
||||||
|
@ -1269,12 +1297,10 @@ SV_InitRecord
|
||||||
|
|
||||||
mvddest_t *SV_MVD_InitRecordFile (char *name)
|
mvddest_t *SV_MVD_InitRecordFile (char *name)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s, *txtname;
|
||||||
mvddest_t *dst;
|
mvddest_t *dst;
|
||||||
vfsfile_t *file;
|
vfsfile_t *file;
|
||||||
|
|
||||||
char path[MAX_OSPATH];
|
|
||||||
|
|
||||||
if (strlen(name) >= countof(dst->filename))
|
if (strlen(name) >= countof(dst->filename))
|
||||||
{
|
{
|
||||||
Con_Printf ("ERROR: couldn't open \"%s\". Too long.\n", name);
|
Con_Printf ("ERROR: couldn't open \"%s\". Too long.\n", name);
|
||||||
|
@ -1289,7 +1315,7 @@ mvddest_t *SV_MVD_InitRecordFile (char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AVAIL_GZDEC
|
#ifdef AVAIL_GZDEC
|
||||||
if (!Q_strcasecmp("gz", COM_FileExtension(name, path, sizeof(path))))
|
if (!Q_strcasecmp(".gz", COM_GetFileExtension(name, NULL)))
|
||||||
file = FS_GZ_WriteFilter(file, true, true);
|
file = FS_GZ_WriteFilter(file, true, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1344,7 +1370,8 @@ mvddest_t *SV_MVD_InitRecordFile (char *name)
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "memory", name);
|
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "memory", name);
|
||||||
break;
|
break;
|
||||||
case DEST_THREADEDFILE:
|
case DEST_THREADEDFILE:
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "worker thread", name);
|
//SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "worker thread", name);
|
||||||
|
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording:\n%s\n", name);
|
||||||
break;
|
break;
|
||||||
case DEST_FILE:
|
case DEST_FILE:
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "disk", name);
|
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "disk", name);
|
||||||
|
@ -1352,14 +1379,21 @@ mvddest_t *SV_MVD_InitRecordFile (char *name)
|
||||||
}
|
}
|
||||||
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), SV_Demo_CurrentOutput());
|
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), SV_Demo_CurrentOutput());
|
||||||
|
|
||||||
Q_strncpyz(path, name, MAX_OSPATH);
|
txtname = SV_MVDName2Txt(name);
|
||||||
Q_strncpyz(path + strlen(path) - 3, "txt", MAX_OSPATH - strlen(path) + 3);
|
|
||||||
|
|
||||||
if (sv_demotxt.value)
|
if (sv_demotxt.value)
|
||||||
{
|
{
|
||||||
vfsfile_t *f;
|
vfsfile_t *f;
|
||||||
|
|
||||||
f = FS_OpenVFS (path, "wt", FS_GAMEONLY);
|
if (sv_demotxt.value == 2)
|
||||||
|
{
|
||||||
|
//this is a special mode for mods that want to write it instead (done via the sv_demoinfoadd command).
|
||||||
|
f = FS_OpenVFS (txtname, "wt", FS_GAMEONLY);
|
||||||
|
if (f)
|
||||||
|
VFS_CLOSE(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = FS_OpenVFS (txtname, "wt", FS_GAMEONLY);
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
{
|
{
|
||||||
char buf[2000];
|
char buf[2000];
|
||||||
|
@ -1373,10 +1407,11 @@ mvddest_t *SV_MVD_InitRecordFile (char *name)
|
||||||
VFS_CLOSE(f);
|
VFS_CLOSE(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FS_Remove(path, FS_GAMEONLY);
|
FS_Remove(txtname, FS_GAMEONLY);
|
||||||
FS_FlushFSHashRemoved(path);
|
FS_FlushFSHashRemoved(txtname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
|
@ -1607,13 +1642,8 @@ qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pointless extensions that are redundant with mvds
|
//pointless extensions that are redundant with mvds
|
||||||
demo.recorder.fteprotocolextensions &= ~PEXT_ACCURATETIMINGS | PEXT_HLBSP | PEXT_CHUNKEDDOWNLOADS;
|
demo.recorder.fteprotocolextensions &= ~PEXT_ACCURATETIMINGS | PEXT_CHUNKEDDOWNLOADS;
|
||||||
#ifdef PEXT_Q2BSP
|
demo.recorder.fteprotocolextensions &= ~PEXT1_HIDEPROTOCOLS;
|
||||||
demo.recorder.fteprotocolextensions &= ~PEXT_Q2BSP;
|
|
||||||
#endif
|
|
||||||
#ifdef PEXT_Q3BSP
|
|
||||||
demo.recorder.fteprotocolextensions &= ~PEXT_Q3BSP;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
||||||
|
@ -1917,6 +1947,86 @@ char *SV_CleanName (unsigned char *name)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//figure out the actual size limit. this is somewhat approximate anyway.
|
||||||
|
qofs_t MVD_DemoMaxDirSize(void)
|
||||||
|
{
|
||||||
|
char *e;
|
||||||
|
double maxdirsize = strtod(sv_demoMaxDirSize.string, &e);
|
||||||
|
if (*e == ' ' || *e == '\t')
|
||||||
|
e++;
|
||||||
|
//that will be trailed by g[b], m[b], k[b], or b
|
||||||
|
if (*e == 'b' || *e == 'B')
|
||||||
|
return maxdirsize;
|
||||||
|
else if (*e == 'k' || *e == 'K')
|
||||||
|
return maxdirsize * 1024;
|
||||||
|
else if (*e == 'm' || *e == 'M')
|
||||||
|
return maxdirsize * 1024*1024;
|
||||||
|
else if (*e == 'g' || *e == 'G')
|
||||||
|
return maxdirsize * 1024*1024*1024;
|
||||||
|
else
|
||||||
|
return maxdirsize * 1024; //assume kb.
|
||||||
|
}
|
||||||
|
//returns if there's enough disk space to record another demo.
|
||||||
|
qboolean MVD_CheckSpace(qboolean broadcastwarnings)
|
||||||
|
{
|
||||||
|
dir_t *dir;
|
||||||
|
|
||||||
|
qofs_t maxdirsize = MVD_DemoMaxDirSize();
|
||||||
|
if (maxdirsize > 0 || sv_demoMaxDirCount.ival > 0 || sv_demoMaxDirAge.ival > 0)
|
||||||
|
{
|
||||||
|
dir = Sys_listdemos(sv_demoDir.string, false, SORT_BY_DATE);
|
||||||
|
if (sv_demoClearOld.ival && *sv_demoDir.string)
|
||||||
|
{
|
||||||
|
time_t removebeforetime = time(NULL) - sv_demoMaxDirAge.value*60*60*24;
|
||||||
|
while (dir->numfiles && (
|
||||||
|
(maxdirsize>0 && dir->size > maxdirsize) ||
|
||||||
|
(sv_demoMaxDirCount.ival>0 && dir->numfiles >= sv_demoMaxDirCount.ival) ||
|
||||||
|
(sv_demoMaxDirAge.ival && dir->files[dir->numfiles-1].mtime && dir->files[dir->numfiles-1].mtime - removebeforetime < 0)))
|
||||||
|
{
|
||||||
|
file_t *f = &dir->files[dir->numfiles-1]; //this is the file we want to kill.
|
||||||
|
if (!f->path || !f->path->RemoveFile)
|
||||||
|
{ //erm, can't remove it...
|
||||||
|
dir->size -= f->size;
|
||||||
|
dir->numfiles--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (f->path->RemoveFile(f->path, f->name))
|
||||||
|
{ //okay, looks like we managed to kill it.
|
||||||
|
Con_Printf(CON_WARNING"Removed demo \"%s\"\n", f->name);
|
||||||
|
dir->size -= f->size;
|
||||||
|
dir->numfiles--;
|
||||||
|
|
||||||
|
//Try to take the .txt too.
|
||||||
|
f->path->RemoveFile(f->path, SV_MVDName2Txt(f->name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir->numfiles && sv_demoMaxDirCount.ival>0 && dir->numfiles >= sv_demoMaxDirCount.ival)
|
||||||
|
{
|
||||||
|
if (broadcastwarnings)
|
||||||
|
SV_BroadcastPrintf(PRINT_MEDIUM, CON_WARNING"insufficient directory space, increase server's sv_demoMaxDirCount\n");
|
||||||
|
else
|
||||||
|
Con_Printf(CON_WARNING"insufficient demo space, increase sv_demoMaxDirCount\n");
|
||||||
|
Sys_freedir(dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dir->numfiles && maxdirsize>0 && dir->size > maxdirsize)
|
||||||
|
{
|
||||||
|
if (broadcastwarnings)
|
||||||
|
SV_BroadcastPrintf(PRINT_MEDIUM, CON_WARNING"insufficient directory space, increase server's sv_demoMaxDirSize\n");
|
||||||
|
else
|
||||||
|
Con_Printf(CON_WARNING"insufficient demo space, increase sv_demoMaxDirSize\n");
|
||||||
|
Sys_freedir(dir);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_freedir(dir);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
SV_Record_f
|
SV_Record_f
|
||||||
|
@ -1929,7 +2039,6 @@ void SV_MVD_Record_f (void)
|
||||||
int c;
|
int c;
|
||||||
char name[MAX_OSPATH+MAX_MVD_NAME];
|
char name[MAX_OSPATH+MAX_MVD_NAME];
|
||||||
char newname[MAX_MVD_NAME];
|
char newname[MAX_MVD_NAME];
|
||||||
dir_t *dir;
|
|
||||||
|
|
||||||
c = Cmd_Argc();
|
c = Cmd_Argc();
|
||||||
if (c != 2)
|
if (c != 2)
|
||||||
|
@ -1943,15 +2052,8 @@ void SV_MVD_Record_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".*", SORT_NO);
|
if (!MVD_CheckSpace(Cmd_FromGamecode()))
|
||||||
if (sv_demoMaxDirSize.value && dir->size > sv_demoMaxDirSize.value*1024)
|
|
||||||
{
|
|
||||||
Con_Printf("insufficient directory space, increase sv_demoMaxDirSize\n");
|
|
||||||
Sys_freedir(dir);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Sys_freedir(dir);
|
|
||||||
dir = NULL;
|
|
||||||
|
|
||||||
Q_strncpyz(newname, va("%s%s", sv_demoPrefix.string, SV_CleanName(Cmd_Argv(1))),
|
Q_strncpyz(newname, va("%s%s", sv_demoPrefix.string, SV_CleanName(Cmd_Argv(1))),
|
||||||
sizeof(newname) - strlen(sv_demoSuffix.string) - 5);
|
sizeof(newname) - strlen(sv_demoSuffix.string) - 5);
|
||||||
|
@ -1975,6 +2077,49 @@ void SV_MVD_Record_f (void)
|
||||||
SV_MVD_Record (SV_MVD_InitRecordFile(name));
|
SV_MVD_Record (SV_MVD_InitRecordFile(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//called when a connecting player becomes active.
|
||||||
|
void SV_MVD_AutoRecord (void)
|
||||||
|
{
|
||||||
|
//not enabled (for the server) anyway.
|
||||||
|
if (sv_demoAutoRecord.ival <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//don't record multiple...
|
||||||
|
if (sv.mvdrecording)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//only do it if we're underneath our quotas.
|
||||||
|
if (!MVD_CheckSpace(true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (sv_demoAutoRecord.ival > 0)
|
||||||
|
{
|
||||||
|
int playercount = 0, i;
|
||||||
|
for (i = 0; i < svs.allocated_client_slots; i++)
|
||||||
|
{
|
||||||
|
if (svs.clients[i].state >= cs_spawned)
|
||||||
|
playercount++;
|
||||||
|
}
|
||||||
|
if (playercount >= sv_demoAutoRecord.ival)
|
||||||
|
{ //okay, we've reached our player count, its time to start recording now.
|
||||||
|
char name[MAX_OSPATH];
|
||||||
|
char timestamp[64];
|
||||||
|
time_t tm = time(NULL);
|
||||||
|
strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", localtime(&tm));
|
||||||
|
Q_snprintfz(name, sizeof(name), "%s/%s%s_%s", sv_demoDir.string, sv_demoAutoPrefix.string, svs.name, timestamp);
|
||||||
|
#ifdef AVAIL_GZDEC
|
||||||
|
if (sv_demoAutoCompress.ival == 1 || !*sv_demoAutoCompress.string) //default is to gzip.
|
||||||
|
Q_strncatz(name, ".mvd.gz", sizeof(name));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
Q_strncatz(name, ".mvd", sizeof(name));
|
||||||
|
FS_CreatePath (name, FS_GAMEONLY);
|
||||||
|
|
||||||
|
SV_MVD_Record (SV_MVD_InitRecordFile(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SV_MVD_QTVReverse_f (void)
|
void SV_MVD_QTVReverse_f (void)
|
||||||
{
|
{
|
||||||
#if 1//ndef HAVE_TCP
|
#if 1//ndef HAVE_TCP
|
||||||
|
@ -2170,7 +2315,6 @@ int Dem_CountTeamPlayers (char *t)
|
||||||
void SV_MVDEasyRecord_f (void)
|
void SV_MVDEasyRecord_f (void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
dir_t *dir;
|
|
||||||
char name[1024];
|
char name[1024];
|
||||||
char name2[MAX_OSPATH*7]; // scream
|
char name2[MAX_OSPATH*7]; // scream
|
||||||
//char name2[MAX_OSPATH*2];
|
//char name2[MAX_OSPATH*2];
|
||||||
|
@ -2190,14 +2334,8 @@ void SV_MVDEasyRecord_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".*", SORT_NO);
|
if (!MVD_CheckSpace(Cmd_FromGamecode()))
|
||||||
if (sv_demoMaxDirSize.value && dir->size > sv_demoMaxDirSize.value*1024)
|
|
||||||
{
|
|
||||||
Con_Printf("insufficient directory space, increase sv_demoMaxDirSize\n");
|
|
||||||
Sys_freedir(dir);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Sys_freedir(dir);
|
|
||||||
|
|
||||||
if (c == 2)
|
if (c == 2)
|
||||||
{
|
{
|
||||||
|
@ -2286,9 +2424,10 @@ void SV_MVDList_f (void)
|
||||||
file_t *list;
|
file_t *list;
|
||||||
float f;
|
float f;
|
||||||
int i,j,show;
|
int i,j,show;
|
||||||
|
qofs_t maxdirsize = MVD_DemoMaxDirSize();
|
||||||
|
|
||||||
Con_Printf("content of %s/*.mvd\n", sv_demoDir.string);
|
Con_Printf("content of %s/*.mvd\n", sv_demoDir.string);
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".mvd", SORT_BY_DATE);
|
dir = Sys_listdemos(sv_demoDir.string, true, SORT_BY_DATE);
|
||||||
list = dir->files;
|
list = dir->files;
|
||||||
if (!list->name[0])
|
if (!list->name[0])
|
||||||
{
|
{
|
||||||
|
@ -2307,10 +2446,10 @@ void SV_MVDList_f (void)
|
||||||
for (d = demo.dest; d; d = d->nextdest)
|
for (d = demo.dest; d; d = d->nextdest)
|
||||||
{
|
{
|
||||||
if (d->desttype != DEST_STREAM && !strcmp(list->name, d->simplename))
|
if (d->desttype != DEST_STREAM && !strcmp(list->name, d->simplename))
|
||||||
Con_Printf("*%d: ^[^7%s\\demo\\%s/%s^] %dk\n", i, list->name, sv_demoDir.string, list->name, d->totalsize/1024);
|
Con_Printf("*%d: ^[^7%s\\demo\\%s/%s^] %uk\n", i, list->name, sv_demoDir.string, list->name, (unsigned int)(d->totalsize/1024));
|
||||||
}
|
}
|
||||||
if (!d)
|
if (!d)
|
||||||
Con_Printf("%d: ^[^7%s\\demo\\%s/%s^] %dk\n", i, list->name, sv_demoDir.string, list->name, list->size/1024);
|
Con_Printf("%d: ^[^7%s\\demo\\%s/%s^] %uk\n", i, list->name, sv_demoDir.string, list->name, (unsigned int)(list->size/1024));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2318,9 +2457,9 @@ void SV_MVDList_f (void)
|
||||||
dir->size += d->totalsize;
|
dir->size += d->totalsize;
|
||||||
|
|
||||||
Con_Printf("\ndirectory size: %.1fMB\n",(float)dir->size/(1024*1024));
|
Con_Printf("\ndirectory size: %.1fMB\n",(float)dir->size/(1024*1024));
|
||||||
if (sv_demoMaxDirSize.value)
|
if (maxdirsize)
|
||||||
{
|
{
|
||||||
f = (sv_demoMaxDirSize.value*1024 - dir->size)/(1024*1024);
|
f = (maxdirsize - dir->size)/(1024*1024);
|
||||||
if ( f < 0)
|
if ( f < 0)
|
||||||
f = 0;
|
f = 0;
|
||||||
Con_Printf("space available: %.1fMB\n", f);
|
Con_Printf("space available: %.1fMB\n", f);
|
||||||
|
@ -2337,9 +2476,10 @@ void SV_UserCmdMVDList_f (void)
|
||||||
file_t *list;
|
file_t *list;
|
||||||
float f;
|
float f;
|
||||||
int i,j,show;
|
int i,j,show;
|
||||||
|
qofs_t maxdirsize = MVD_DemoMaxDirSize();
|
||||||
|
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "available demos:\n");
|
SV_ClientPrintf(host_client, PRINT_HIGH, "available demos:\n");
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".mvd", SORT_BY_DATE);
|
dir = Sys_listdemos(sv_demoDir.string, true, SORT_BY_DATE);
|
||||||
list = dir->files;
|
list = dir->files;
|
||||||
if (!list->name[0])
|
if (!list->name[0])
|
||||||
{
|
{
|
||||||
|
@ -2363,23 +2503,26 @@ void SV_UserCmdMVDList_f (void)
|
||||||
if (!d)
|
if (!d)
|
||||||
{
|
{
|
||||||
if (host_client->fteprotocolextensions2 & PEXT_CSQC) //its a hack to use csqc this way, but oh well, but other clients don't want the gibberish.
|
if (host_client->fteprotocolextensions2 & PEXT_CSQC) //its a hack to use csqc this way, but oh well, but other clients don't want the gibberish.
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%d: ^[%s\\type\\/download demos/%s^] %dk\n", i, list->name, list->name, list->size/1024);
|
SV_ClientPrintf(host_client, PRINT_HIGH, "%d: ^[%s\\type\\/download demos/%s^] %dk\n", i, list->name, list->name, (unsigned int)(list->size/1024));
|
||||||
else
|
else
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "%d: %s %dk\n", i, list->name, list->size/1024);
|
SV_ClientPrintf(host_client, PRINT_HIGH, "%d: %s %dk\n", i, list->name, (unsigned int)(list->size/1024));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host_client->num_backbuf == MAX_BACK_BUFFERS)
|
if (host_client->num_backbuf >= MAX_BACK_BUFFERS/2)
|
||||||
|
{
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "*MORE*\n");
|
SV_ClientPrintf(host_client, PRINT_HIGH, "*MORE*\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (d = demo.dest; d; d = d->nextdest)
|
for (d = demo.dest; d; d = d->nextdest)
|
||||||
dir->size += d->totalsize;
|
dir->size += d->totalsize;
|
||||||
|
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "\ndirectory size: %.1fMB\n",(float)dir->size/(1024*1024));
|
SV_ClientPrintf(host_client, PRINT_HIGH, "\ndirectory size: %.1fMB\n",(float)dir->size/(1024*1024));
|
||||||
if (sv_demoMaxDirSize.value)
|
if (maxdirsize)
|
||||||
{
|
{
|
||||||
f = (sv_demoMaxDirSize.value*1024 - dir->size)/(1024*1024);
|
f = (maxdirsize - dir->size)/(1024*1024);
|
||||||
if ( f < 0)
|
if ( f < 0)
|
||||||
f = 0;
|
f = 0;
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "space available: %.1fMB\n", f);
|
SV_ClientPrintf(host_client, PRINT_HIGH, "space available: %.1fMB\n", f);
|
||||||
|
@ -2395,6 +2538,7 @@ void SV_UserCmdMVDList_HTML (vfsfile_t *pipe)
|
||||||
file_t *list;
|
file_t *list;
|
||||||
float f;
|
float f;
|
||||||
int i;
|
int i;
|
||||||
|
qofs_t maxdirsize = MVD_DemoMaxDirSize();
|
||||||
|
|
||||||
VFS_PRINTF(pipe,
|
VFS_PRINTF(pipe,
|
||||||
"<html>"
|
"<html>"
|
||||||
|
@ -2418,7 +2562,7 @@ void SV_UserCmdMVDList_HTML (vfsfile_t *pipe)
|
||||||
, fs_manifest->formalname, hostname.string);
|
, fs_manifest->formalname, hostname.string);
|
||||||
|
|
||||||
VFS_PRINTF(pipe, "available demos:<br/>\n");
|
VFS_PRINTF(pipe, "available demos:<br/>\n");
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".mvd", SORT_BY_DATE);
|
dir = Sys_listdemos(sv_demoDir.string, true, SORT_BY_DATE);
|
||||||
list = dir->files;
|
list = dir->files;
|
||||||
if (!list->name[0])
|
if (!list->name[0])
|
||||||
{
|
{
|
||||||
|
@ -2436,7 +2580,7 @@ void SV_UserCmdMVDList_HTML (vfsfile_t *pipe)
|
||||||
{
|
{
|
||||||
char datetime[64];
|
char datetime[64];
|
||||||
strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", localtime(&list->mtime));
|
strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", localtime(&list->mtime));
|
||||||
VFS_PRINTF(pipe, "%d: <a href='/demos/%s'>%s</a> %dk <a href='javascript:void(0)' onclick='playdemo(\"%s\")'>play</a> %s<br/>\n", i, list->name, list->name, list->size/1024, list->name, datetime);
|
VFS_PRINTF(pipe, "%d: <a href='/demos/%s'>%s</a> %uk <a href='javascript:void(0)' onclick='playdemo(\"%s\")'>play</a> %s<br/>\n", i, list->name, list->name, (unsigned int)(list->size/1024), list->name, datetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2444,9 +2588,9 @@ void SV_UserCmdMVDList_HTML (vfsfile_t *pipe)
|
||||||
dir->size += d->totalsize;
|
dir->size += d->totalsize;
|
||||||
|
|
||||||
VFS_PRINTF(pipe, "<br/>\ndirectory size: %.1fMB<br/>\n",(float)dir->size/(1024*1024));
|
VFS_PRINTF(pipe, "<br/>\ndirectory size: %.1fMB<br/>\n",(float)dir->size/(1024*1024));
|
||||||
if (sv_demoMaxDirSize.value)
|
if (maxdirsize)
|
||||||
{
|
{
|
||||||
f = (sv_demoMaxDirSize.value*1024 - dir->size)/(1024*1024);
|
f = (maxdirsize - dir->size)/(1024*1024);
|
||||||
if ( f < 0)
|
if ( f < 0)
|
||||||
f = 0;
|
f = 0;
|
||||||
VFS_PRINTF(pipe, "space available: %.1fMB<br/>\n", f);
|
VFS_PRINTF(pipe, "space available: %.1fMB<br/>\n", f);
|
||||||
|
@ -2479,7 +2623,7 @@ char *SV_MVDNum(char *buffer, int bufferlen, int num) //lame number->name lookup
|
||||||
file_t *list;
|
file_t *list;
|
||||||
dir_t *dir;
|
dir_t *dir;
|
||||||
|
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".mvd", SORT_BY_DATE);
|
dir = Sys_listdemos(sv_demoDir.string, true, SORT_BY_DATE);
|
||||||
list = dir->files;
|
list = dir->files;
|
||||||
|
|
||||||
if (num < 0)
|
if (num < 0)
|
||||||
|
@ -2501,16 +2645,23 @@ char *SV_MVDNum(char *buffer, int bufferlen, int num) //lame number->name lookup
|
||||||
char *SV_MVDName2Txt(char *name)
|
char *SV_MVDName2Txt(char *name)
|
||||||
{
|
{
|
||||||
char s[MAX_OSPATH];
|
char s[MAX_OSPATH];
|
||||||
|
const char *ext;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Q_strncpyz(s, name, MAX_OSPATH);
|
Q_strncpyz(s, name, MAX_OSPATH);
|
||||||
|
|
||||||
if (strstr(s, ".mvd.gz") != NULL)
|
ext = COM_GetFileExtension(s, NULL);
|
||||||
Q_strncpyz(s + strlen(s) - 6, "txt", MAX_OSPATH - strlen(s) + 6);
|
if (!Q_strcasecmp(ext, ".gz"))
|
||||||
else
|
ext = COM_GetFileExtension(s, ext);
|
||||||
Q_strncpyz(s + strlen(s) - 3, "txt", MAX_OSPATH - strlen(s) + 3);
|
else if (!Q_strcasecmp(ext, ".xz"))
|
||||||
|
ext = COM_GetFileExtension(s, ext);
|
||||||
|
if (!ext || !*ext) //if there's no extension on there, then make sure we're pointing to the end of the string.
|
||||||
|
ext = s+strlen(s);
|
||||||
|
if (ext > s+sizeof(s)+4) //make sure we don't overflow the buffer by truncating the base/path, ensuring that we don't write some other type of file.
|
||||||
|
ext = s+sizeof(s)+4; //should probably make this an error case and abort instead.
|
||||||
|
strcpy((char*)ext, ".txt");
|
||||||
|
|
||||||
return va("%s", s);
|
return va("%s", s);
|
||||||
}
|
}
|
||||||
|
@ -2529,7 +2680,7 @@ void SV_MVDRemove_f (void)
|
||||||
|
|
||||||
if (Cmd_Argc() != 2)
|
if (Cmd_Argc() != 2)
|
||||||
{
|
{
|
||||||
Con_Printf("rmdemo <demoname> - removes the demo\nrmdemo *<token> - removes demo with <token> in the name\nrmdemo * - removes all demos\n");
|
Con_Printf("%s <demoname> - removes the demo\nrmdemo *<token> - removes demo with <token> in the name\nrmdemo * - removes all demos\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2542,7 +2693,7 @@ void SV_MVDRemove_f (void)
|
||||||
// remove all demos with specified token
|
// remove all demos with specified token
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
||||||
dir = Sys_listdir(sv_demoDir.string, ".mvd", SORT_BY_DATE);
|
dir = Sys_listdemos(sv_demoDir.string, true, SORT_BY_DATE);
|
||||||
list = dir->files;
|
list = dir->files;
|
||||||
for (i = 0;i < dir->numfiles; list++)
|
for (i = 0;i < dir->numfiles; list++)
|
||||||
{
|
{
|
||||||
|
@ -2605,14 +2756,14 @@ void SV_MVDRemoveNum_f (void)
|
||||||
|
|
||||||
if (Cmd_Argc() != 2)
|
if (Cmd_Argc() != 2)
|
||||||
{
|
{
|
||||||
Con_Printf("rmdemonum <#>\n");
|
Con_Printf("%s <#>\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = Cmd_Argv(1);
|
val = Cmd_Argv(1);
|
||||||
if ((num = atoi(val)) == 0 && val[0] != '0')
|
if ((num = atoi(val)) == 0 && val[0] != '0')
|
||||||
{
|
{
|
||||||
Con_Printf("rmdemonum <#>\n");
|
Con_Printf("%s <#>\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2644,12 +2795,13 @@ void SV_MVDInfoAdd_f (void)
|
||||||
char *name, *args, path[MAX_OSPATH];
|
char *name, *args, path[MAX_OSPATH];
|
||||||
vfsfile_t *f;
|
vfsfile_t *f;
|
||||||
|
|
||||||
|
//** is a special hack for ktx
|
||||||
if (Cmd_Argc() < 3) {
|
if (Cmd_Argc() < 3) {
|
||||||
Con_Printf("usage:MVDInfoAdd <demonum> <info string>\n<demonum> = * for currently recorded demo\n");
|
Con_Printf("%s <demonum> <info string>\n<demonum> = * for currently recorded demo\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(Cmd_Argv(1), "*"))
|
if (!strcmp(Cmd_Argv(1), "*") || !strcmp(Cmd_Argv(1), "**"))
|
||||||
{
|
{
|
||||||
mvddest_t *active = SV_FindRecordFile(NULL, NULL);
|
mvddest_t *active = SV_FindRecordFile(NULL, NULL);
|
||||||
if (!active)
|
if (!active)
|
||||||
|
@ -2673,12 +2825,26 @@ void SV_MVDInfoAdd_f (void)
|
||||||
snprintf(path, MAX_OSPATH, "%s/%s", sv_demoDir.string, name);
|
snprintf(path, MAX_OSPATH, "%s/%s", sv_demoDir.string, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((f = FS_OpenVFS(path, "a+t", FS_GAMEONLY)) == NULL)
|
if ((f = FS_OpenVFS(path, "ab", FS_GAMEONLY)) == NULL)
|
||||||
{
|
{
|
||||||
Con_Printf("failed to open the file\n");
|
Con_Printf("%s: failed to open \"%s\"\n", Cmd_Argv(0), path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(Cmd_Argv(1), "**"))
|
||||||
|
{
|
||||||
|
size_t fsize;
|
||||||
|
args = FS_LoadMallocFile(Cmd_Argv(2), &fsize);
|
||||||
|
if (args)
|
||||||
|
{
|
||||||
|
VFS_WRITE(f, args, fsize);
|
||||||
|
FS_FreeFile(args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con_Printf("%s: failed to open input file\n", Cmd_Argv(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// skip demonum
|
// skip demonum
|
||||||
args = Cmd_Args();
|
args = Cmd_Args();
|
||||||
while (*args > 32) args++;
|
while (*args > 32) args++;
|
||||||
|
@ -2686,6 +2852,7 @@ void SV_MVDInfoAdd_f (void)
|
||||||
|
|
||||||
VFS_WRITE(f, args, strlen(args));
|
VFS_WRITE(f, args, strlen(args));
|
||||||
VFS_WRITE(f, "\n", 1);
|
VFS_WRITE(f, "\n", 1);
|
||||||
|
}
|
||||||
VFS_FLUSH(f);
|
VFS_FLUSH(f);
|
||||||
VFS_CLOSE(f);
|
VFS_CLOSE(f);
|
||||||
}
|
}
|
||||||
|
@ -2697,7 +2864,7 @@ void SV_MVDInfoRemove_f (void)
|
||||||
|
|
||||||
if (Cmd_Argc() < 2)
|
if (Cmd_Argc() < 2)
|
||||||
{
|
{
|
||||||
Con_Printf("usage:demoInfoRemove <demonum>\n<demonum> = * for currently recorded demo\n");
|
Con_Printf("%s <demonum>\n<demonum> = * for currently recorded demo\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2744,7 +2911,7 @@ void SV_MVDInfo_f (void)
|
||||||
|
|
||||||
if (Cmd_Argc() < 2)
|
if (Cmd_Argc() < 2)
|
||||||
{
|
{
|
||||||
Con_Printf("usage:demoinfo <demonum>\n<demonum> = * for currently recorded demo\n");
|
Con_Printf("%s <demonum>\n<demonum> = * for currently recorded demo\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2806,14 +2973,14 @@ void SV_MVDPlayNum_f(void)
|
||||||
|
|
||||||
if (Cmd_Argc() != 2)
|
if (Cmd_Argc() != 2)
|
||||||
{
|
{
|
||||||
Con_Printf("mvdplaynum <#>\n");
|
Con_Printf("%s <#>\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = Cmd_Argv(1);
|
val = Cmd_Argv(1);
|
||||||
if ((num = atoi(val)) == 0 && val[0] != '0')
|
if ((num = atoi(val)) == 0 && val[0] != '0')
|
||||||
{
|
{
|
||||||
Con_Printf("mvdplaynum <#>\n");
|
Con_Printf("%s <#>\n", Cmd_Argv(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2872,3 +3039,4 @@ void SV_MVDInit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -501,6 +501,7 @@ void VARGS SV_ClientPrintf (client_t *cl, int level, const char *fmt, ...)
|
||||||
if(strlen(string) >= sizeof(string))
|
if(strlen(string) >= sizeof(string))
|
||||||
Sys_Error("SV_ClientPrintf: Buffer stomped\n");
|
Sys_Error("SV_ClientPrintf: Buffer stomped\n");
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||||
|
@ -508,6 +509,7 @@ void VARGS SV_ClientPrintf (client_t *cl, int level, const char *fmt, ...)
|
||||||
MSG_WriteByte (msg, level);
|
MSG_WriteByte (msg, level);
|
||||||
MSG_WriteString (msg, string);
|
MSG_WriteString (msg, string);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cl->controller)
|
if (cl->controller)
|
||||||
SV_PrintToClient(cl->controller, level, string);
|
SV_PrintToClient(cl->controller, level, string);
|
||||||
|
@ -531,6 +533,7 @@ void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t stringnum, .
|
||||||
if(strlen(string) >= sizeof(string))
|
if(strlen(string) >= sizeof(string))
|
||||||
Sys_Error("SV_ClientTPrintf: Buffer stomped\n");
|
Sys_Error("SV_ClientTPrintf: Buffer stomped\n");
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||||
|
@ -538,6 +541,7 @@ void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t stringnum, .
|
||||||
MSG_WriteByte (msg, level);
|
MSG_WriteByte (msg, level);
|
||||||
MSG_WriteString (msg, string);
|
MSG_WriteString (msg, string);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SV_PrintToClient(cl, level, string);
|
SV_PrintToClient(cl, level, string);
|
||||||
}
|
}
|
||||||
|
@ -585,6 +589,7 @@ void VARGS SV_BroadcastPrintf (int level, const char *fmt, ...)
|
||||||
SV_PrintToClient(cl, level, string);
|
SV_PrintToClient(cl, level, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
||||||
|
@ -592,6 +597,7 @@ void VARGS SV_BroadcastPrintf (int level, const char *fmt, ...)
|
||||||
MSG_WriteByte (msg, level);
|
MSG_WriteByte (msg, level);
|
||||||
MSG_WriteString (msg, string);
|
MSG_WriteString (msg, string);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1136,6 +1142,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording && ((demo.recorder.fteprotocolextensions & with) == with) && !(demo.recorder.fteprotocolextensions & without))
|
if (sv.mvdrecording && ((demo.recorder.fteprotocolextensions & with) == with) && !(demo.recorder.fteprotocolextensions & without))
|
||||||
{
|
{
|
||||||
sizebuf_t *msg;
|
sizebuf_t *msg;
|
||||||
|
@ -1184,6 +1191,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
}
|
}
|
||||||
SZ_Write(msg, sv.multicast.data, sv.multicast.cursize);
|
SZ_Write(msg, sv.multicast.data, sv.multicast.cursize);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
SZ_Clear (&sv.nqmulticast);
|
SZ_Clear (&sv.nqmulticast);
|
||||||
|
@ -1336,6 +1344,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
callback(client, &client->datagram, ctx);
|
callback(client, &client->datagram, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg;
|
sizebuf_t *msg;
|
||||||
|
@ -1388,6 +1397,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca
|
||||||
}
|
}
|
||||||
callback(&demo.recorder, msg, ctx);
|
callback(&demo.recorder, msg, ctx);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//version does all the work now
|
//version does all the work now
|
||||||
|
@ -1803,12 +1813,14 @@ void SV_WriteCenterPrint(client_t *cl, char *s)
|
||||||
}
|
}
|
||||||
ClientReliableWrite_String (cl, s);
|
ClientReliableWrite_String (cl, s);
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
||||||
MSG_WriteByte (msg, svc_centerprint);
|
MSG_WriteByte (msg, svc_centerprint);
|
||||||
MSG_WriteString (msg, s);
|
MSG_WriteString (msg, s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2928,8 +2940,10 @@ void SV_FlushBroadcasts (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_MVD_WriteReliables(true);
|
SV_MVD_WriteReliables(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
SZ_Clear (&sv.reliable_datagram);
|
SZ_Clear (&sv.reliable_datagram);
|
||||||
SZ_Clear (&sv.datagram);
|
SZ_Clear (&sv.datagram);
|
||||||
|
@ -3126,6 +3140,7 @@ void SV_UpdateToReliableMessages (void)
|
||||||
ClientReliableWrite_Short(client, host_client->edict->v->frags);
|
ClientReliableWrite_Short(client, host_client->edict->v->frags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
||||||
|
@ -3133,6 +3148,7 @@ void SV_UpdateToReliableMessages (void)
|
||||||
MSG_WriteByte(msg, i);
|
MSG_WriteByte(msg, i);
|
||||||
MSG_WriteShort(msg, host_client->edict->v->frags);
|
MSG_WriteShort(msg, host_client->edict->v->frags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
host_client->old_frags = host_client->edict->v->frags;
|
host_client->old_frags = host_client->edict->v->frags;
|
||||||
}
|
}
|
||||||
|
@ -3194,6 +3210,7 @@ void SV_UpdateToReliableMessages (void)
|
||||||
ClientReliableWrite_Short(client, curfrags);
|
ClientReliableWrite_Short(client, curfrags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
||||||
|
@ -3201,6 +3218,7 @@ void SV_UpdateToReliableMessages (void)
|
||||||
MSG_WriteByte(msg, i);
|
MSG_WriteByte(msg, i);
|
||||||
MSG_WriteShort(msg, curfrags);
|
MSG_WriteShort(msg, curfrags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
host_client->old_frags = curfrags;
|
host_client->old_frags = curfrags;
|
||||||
}
|
}
|
||||||
|
@ -3384,6 +3402,7 @@ void SV_BroadcastUserinfoChange(client_t *about, qboolean isbasic, const char *k
|
||||||
SV_SendUserinfoChange(client, about, isbasic, key, newval);
|
SV_SendUserinfoChange(client, about, isbasic, key, newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording && (isbasic || (demo.recorder.fteprotocolextensions & PEXT_BIGUSERINFOS)))
|
if (sv.mvdrecording && (isbasic || (demo.recorder.fteprotocolextensions & PEXT_BIGUSERINFOS)))
|
||||||
{
|
{
|
||||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(newval)+4);
|
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(newval)+4);
|
||||||
|
@ -3392,6 +3411,7 @@ void SV_BroadcastUserinfoChange(client_t *about, qboolean isbasic, const char *k
|
||||||
MSG_WriteString (msg, key);
|
MSG_WriteString (msg, key);
|
||||||
MSG_WriteString (msg, newval);
|
MSG_WriteString (msg, newval);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3470,13 +3490,6 @@ void SV_SendClientMessages (void)
|
||||||
SV_ChatThink(c);
|
SV_ChatThink(c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (c->wasrecorded)
|
|
||||||
{
|
|
||||||
c->netchan.message.cursize = 0;
|
|
||||||
c->datagram.cursize = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NEWSPEEDCHEATPROT
|
#ifdef NEWSPEEDCHEATPROT
|
||||||
//allow the client more time for client movement.
|
//allow the client more time for client movement.
|
||||||
//if they're running too slowly, FORCE them to run
|
//if they're running too slowly, FORCE them to run
|
||||||
|
@ -3665,8 +3678,10 @@ void SV_SendClientMessages (void)
|
||||||
}
|
}
|
||||||
c->lastoutgoingphysicstime = sv.world.physicstime;
|
c->lastoutgoingphysicstime = sv.world.physicstime;
|
||||||
}
|
}
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
SV_ProcessSendFlags(&demo.recorder);
|
SV_ProcessSendFlags(&demo.recorder);
|
||||||
|
#endif
|
||||||
SV_CleanupEnts();
|
SV_CleanupEnts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3674,6 +3689,7 @@ void SV_SendClientMessages (void)
|
||||||
//#pragma optimize( "", on )
|
//#pragma optimize( "", on )
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time);
|
void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time);
|
||||||
|
|
||||||
void DemoWriteQTVTimePad(int msecs);
|
void DemoWriteQTVTimePad(int msecs);
|
||||||
|
@ -3871,7 +3887,7 @@ void SV_SendMVDMessage(void)
|
||||||
|
|
||||||
// MVDSetMsgBuf(demo.dbuf,&demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf);
|
// MVDSetMsgBuf(demo.dbuf,&demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1050,12 +1050,22 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
else if (client->prespawn_idx == 4)
|
else if (client->prespawn_idx == 4)
|
||||||
{
|
{
|
||||||
int track = 0;
|
int track = 0;
|
||||||
|
const char *noise = "";
|
||||||
|
|
||||||
if (progstype == PROG_H2)
|
if (progstype == PROG_H2)
|
||||||
|
{
|
||||||
track = sv.h2cdtrack; //hexen2 has a special hack
|
track = sv.h2cdtrack; //hexen2 has a special hack
|
||||||
|
}
|
||||||
else if (svprogfuncs)
|
else if (svprogfuncs)
|
||||||
|
{
|
||||||
track = ((edict_t*)sv.world.edicts)->v->sounds;
|
track = ((edict_t*)sv.world.edicts)->v->sounds;
|
||||||
|
noise = PR_GetString(svprogfuncs, ((edict_t*)sv.world.edicts)->v->noise);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track == -1 && *noise)
|
||||||
|
SV_StuffcmdToClient(client, va("cd loop \"%s\"\n", noise));
|
||||||
|
else
|
||||||
|
{
|
||||||
ClientReliableWrite_Begin(client, svc_cdtrack, 2);
|
ClientReliableWrite_Begin(client, svc_cdtrack, 2);
|
||||||
ClientReliableWrite_Byte (client, track);
|
ClientReliableWrite_Byte (client, track);
|
||||||
if (ISNQCLIENT(client))
|
if (ISNQCLIENT(client))
|
||||||
|
@ -1064,6 +1074,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
if (!track && *sv.h2miditrack)
|
if (!track && *sv.h2miditrack)
|
||||||
SV_StuffcmdToClient(client, va("music \"%s\"\n", sv.h2miditrack));
|
SV_StuffcmdToClient(client, va("music \"%s\"\n", sv.h2miditrack));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (client->prespawn_idx == 5)
|
else if (client->prespawn_idx == 5)
|
||||||
{
|
{
|
||||||
ClientReliableWrite_Begin(client, svc_setpause, 2);
|
ClientReliableWrite_Begin(client, svc_setpause, 2);
|
||||||
|
@ -1080,6 +1091,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (client->prespawn_stage == PRESPAWN_CSPROGS)
|
if (client->prespawn_stage == PRESPAWN_CSPROGS)
|
||||||
{
|
{
|
||||||
extern cvar_t sv_demo_write_csqc;
|
extern cvar_t sv_demo_write_csqc;
|
||||||
|
@ -1144,6 +1156,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
client->prespawn_stage++;
|
client->prespawn_stage++;
|
||||||
client->prespawn_idx = 0;
|
client->prespawn_idx = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (client->prespawn_stage == PRESPAWN_SOUNDLIST)
|
if (client->prespawn_stage == PRESPAWN_SOUNDLIST)
|
||||||
{
|
{
|
||||||
|
@ -1218,6 +1231,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (client->prespawn_stage == PRESPAWN_VWEPMODELLIST)
|
if (client->prespawn_stage == PRESPAWN_VWEPMODELLIST)
|
||||||
{
|
{
|
||||||
//no indicies. the protocol can't cope with them.
|
//no indicies. the protocol can't cope with them.
|
||||||
|
@ -1257,6 +1271,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
}
|
}
|
||||||
client->prespawn_stage++;
|
client->prespawn_stage++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (client->prespawn_stage == PRESPAWN_MODELLIST)
|
if (client->prespawn_stage == PRESPAWN_MODELLIST)
|
||||||
{
|
{
|
||||||
|
@ -1702,7 +1717,7 @@ void SVQW_PreSpawn_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo)
|
if ( atoi(Cmd_Argv(1)) != svs.spawncount)
|
||||||
{
|
{
|
||||||
Con_Printf ("SV_PreSpawn_f from different level\n");
|
Con_Printf ("SV_PreSpawn_f from different level\n");
|
||||||
//FIXME: we shouldn't need the following line.
|
//FIXME: we shouldn't need the following line.
|
||||||
|
@ -1769,7 +1784,7 @@ void SVQW_Spawn_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo)
|
if ( atoi(Cmd_Argv(1)) != svs.spawncount)
|
||||||
{
|
{
|
||||||
Con_Printf ("SV_Spawn_f from different level\n");
|
Con_Printf ("SV_Spawn_f from different level\n");
|
||||||
SV_New_f ();
|
SV_New_f ();
|
||||||
|
@ -1785,7 +1800,9 @@ void SVQW_Spawn_f (void)
|
||||||
// normally this could overflow, but no need to check due to backbuf
|
// normally this could overflow, but no need to check due to backbuf
|
||||||
for (i=0, client = svs.clients ; i<svs.allocated_client_slots ; i++, client++)
|
for (i=0, client = svs.clients ; i<svs.allocated_client_slots ; i++, client++)
|
||||||
SV_FullClientUpdate(client, host_client);
|
SV_FullClientUpdate(client, host_client);
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_MVD_FullClientUpdate(NULL, host_client);
|
SV_MVD_FullClientUpdate(NULL, host_client);
|
||||||
|
#endif
|
||||||
|
|
||||||
// send all current light styles
|
// send all current light styles
|
||||||
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
||||||
|
@ -2020,10 +2037,16 @@ void SV_Begin_Core(client_t *split)
|
||||||
SV_SpawnParmsToQC(split);
|
SV_SpawnParmsToQC(split);
|
||||||
|
|
||||||
// call the spawn function
|
// call the spawn function
|
||||||
|
{
|
||||||
|
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
|
||||||
pr_global_struct->time = sv.world.physicstime;
|
pr_global_struct->time = sv.world.physicstime;
|
||||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
|
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
|
||||||
|
|
||||||
|
if (pr_globals)
|
||||||
|
G_FLOAT(OFS_PARM0) = split->csqcactive; //this arg is part of EXT_CSQC_1, but doesn't have to be supported by the mod
|
||||||
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
|
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sv.spawned_observer_slots++;
|
sv.spawned_observer_slots++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2156,7 +2179,7 @@ void SV_Begin_f (void)
|
||||||
split->state = cs_spawned;
|
split->state = cs_spawned;
|
||||||
|
|
||||||
// handle the case of a level changing while a client was connecting
|
// handle the case of a level changing while a client was connecting
|
||||||
if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo)
|
if ( atoi(Cmd_Argv(1)) != svs.spawncount)
|
||||||
{
|
{
|
||||||
Con_Printf ("SV_Begin_f from different level\n");
|
Con_Printf ("SV_Begin_f from different level\n");
|
||||||
SV_New_f ();
|
SV_New_f ();
|
||||||
|
@ -2216,6 +2239,10 @@ void SV_Begin_f (void)
|
||||||
MSG_WriteAngle (&host_client->netchan.message, host_client->edict->v->angles[1] );
|
MSG_WriteAngle (&host_client->netchan.message, host_client->edict->v->angles[1] );
|
||||||
MSG_WriteAngle (&host_client->netchan.message, 0 );
|
MSG_WriteAngle (&host_client->netchan.message, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
|
SV_MVD_AutoRecord();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -2708,6 +2735,7 @@ void SV_VoiceReadPacket(void)
|
||||||
ring->receiver[j>>3] |= 1<<(j&3);
|
ring->receiver[j>>3] |= 1<<(j&3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording && sv_voip_record.ival && !(sv_voip_record.ival == 2 && !host_client->spectator))
|
if (sv.mvdrecording && sv_voip_record.ival && !(sv_voip_record.ival == 2 && !host_client->spectator))
|
||||||
{
|
{
|
||||||
sizebuf_t *msg;
|
sizebuf_t *msg;
|
||||||
|
@ -2733,6 +2761,7 @@ void SV_VoiceReadPacket(void)
|
||||||
MSG_WriteShort(msg, ring->datalen);
|
MSG_WriteShort(msg, ring->datalen);
|
||||||
SZ_Write(msg, ring->data, ring->datalen);
|
SZ_Write(msg, ring->data, ring->datalen);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void SV_VoiceInitClient(client_t *client)
|
void SV_VoiceInitClient(client_t *client)
|
||||||
{
|
{
|
||||||
|
@ -3041,7 +3070,6 @@ qboolean SV_AllowDownload (const char *name)
|
||||||
static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
|
static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
|
||||||
{
|
{
|
||||||
extern cvar_t allow_download_anymap, allow_download_pakcontents;
|
extern cvar_t allow_download_anymap, allow_download_pakcontents;
|
||||||
extern cvar_t sv_demoDir;
|
|
||||||
qboolean protectedpak;
|
qboolean protectedpak;
|
||||||
qboolean found;
|
qboolean found;
|
||||||
static char tmpname[MAX_QPATH];
|
static char tmpname[MAX_QPATH];
|
||||||
|
@ -3049,6 +3077,7 @@ static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacem
|
||||||
if (replacementname)
|
if (replacementname)
|
||||||
*replacementname = NULL;
|
*replacementname = NULL;
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
//mvdsv demo downloading support demonum/ -> demos/XXXX (sets up the client paths)
|
//mvdsv demo downloading support demonum/ -> demos/XXXX (sets up the client paths)
|
||||||
if (!Q_strncasecmp(name, "demonum/", 8))
|
if (!Q_strncasecmp(name, "demonum/", 8))
|
||||||
{
|
{
|
||||||
|
@ -3066,6 +3095,7 @@ static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacem
|
||||||
return DLERR_REDIRECTFILE;
|
return DLERR_REDIRECTFILE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!SV_AllowDownload(name))
|
if (!SV_AllowDownload(name))
|
||||||
{
|
{
|
||||||
|
@ -3073,12 +3103,14 @@ static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacem
|
||||||
return DLERR_PERMISSIONS; //not permitted (even if it exists).
|
return DLERR_PERMISSIONS; //not permitted (even if it exists).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
//mvdsv demo downloading support. demos/ -> demodir (sets up the server paths)
|
//mvdsv demo downloading support. demos/ -> demodir (sets up the server paths)
|
||||||
if (!Q_strncasecmp(name, "demos/", 6))
|
if (!Q_strncasecmp(name, "demos/", 6))
|
||||||
{
|
{
|
||||||
Q_snprintfz(tmpname, sizeof(tmpname), "%s/%s", sv_demoDir.string, name+6);
|
Q_snprintfz(tmpname, sizeof(tmpname), "%s/%s", sv_demoDir.string, name+6);
|
||||||
name = tmpname;
|
name = tmpname;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!Q_strncasecmp(name, "package/", 8))
|
if (!Q_strncasecmp(name, "package/", 8))
|
||||||
{
|
{
|
||||||
|
@ -3241,6 +3273,7 @@ void SV_DownloadSize_f(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
void SV_DemoDownload_f(void)
|
void SV_DemoDownload_f(void)
|
||||||
{
|
{
|
||||||
int arg;
|
int arg;
|
||||||
|
@ -3298,6 +3331,7 @@ void SV_DemoDownload_f(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
|
@ -3309,7 +3343,6 @@ void SV_BeginDownload_f(void)
|
||||||
char *name = Cmd_Argv(1);
|
char *name = Cmd_Argv(1);
|
||||||
char *redirection = NULL;
|
char *redirection = NULL;
|
||||||
extern cvar_t allow_download_anymap, allow_download_pakcontents;
|
extern cvar_t allow_download_anymap, allow_download_pakcontents;
|
||||||
extern cvar_t sv_demoDir;
|
|
||||||
flocation_t loc;
|
flocation_t loc;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -3682,13 +3715,14 @@ void SV_Say (qboolean team)
|
||||||
char t1[32], *t2;
|
char t1[32], *t2;
|
||||||
int cls = 0;
|
int cls = 0;
|
||||||
float floodtime;
|
float floodtime;
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
sizebuf_t *msg;
|
sizebuf_t *msg;
|
||||||
|
qboolean mvdrecording;
|
||||||
|
#endif
|
||||||
|
|
||||||
qboolean sent[MAX_CLIENTS]; //so we don't send to the same splitscreen connection twice. (it's ugly)
|
qboolean sent[MAX_CLIENTS]; //so we don't send to the same splitscreen connection twice. (it's ugly)
|
||||||
int cln;
|
int cln;
|
||||||
|
|
||||||
qboolean mvdrecording;
|
|
||||||
|
|
||||||
char *s, *s2;
|
char *s, *s2;
|
||||||
|
|
||||||
if (Cmd_Argc () < 2)
|
if (Cmd_Argc () < 2)
|
||||||
|
@ -3780,8 +3814,10 @@ void SV_Say (qboolean team)
|
||||||
if (!(host_client->penalties & BAN_MUTE))
|
if (!(host_client->penalties & BAN_MUTE))
|
||||||
Sys_Printf ("%s", text);
|
Sys_Printf ("%s", text);
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
mvdrecording = sv.mvdrecording;
|
mvdrecording = sv.mvdrecording;
|
||||||
sv.mvdrecording = false; //so that the SV_ClientPrintf doesn't send to all players.
|
sv.mvdrecording = false; //so that the SV_ClientPrintf doesn't send to all players.
|
||||||
|
#endif
|
||||||
for (j = 0, client = svs.clients; j < svs.allocated_client_slots; j++, client++)
|
for (j = 0, client = svs.clients; j < svs.allocated_client_slots; j++, client++)
|
||||||
{
|
{
|
||||||
if (client->state != cs_spawned && client->state != cs_connected)
|
if (client->state != cs_spawned && client->state != cs_connected)
|
||||||
|
@ -3828,6 +3864,7 @@ void SV_Say (qboolean team)
|
||||||
|
|
||||||
SV_ClientPrintf(client, PRINT_CHAT, "%s", text);
|
SV_ClientPrintf(client, PRINT_CHAT, "%s", text);
|
||||||
}
|
}
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
sv.mvdrecording = mvdrecording;
|
sv.mvdrecording = mvdrecording;
|
||||||
|
|
||||||
if (!sv.mvdrecording || !cls)
|
if (!sv.mvdrecording || !cls)
|
||||||
|
@ -3842,6 +3879,7 @@ void SV_Say (qboolean team)
|
||||||
MSG_WriteByte (msg, svc_print);
|
MSG_WriteByte (msg, svc_print);
|
||||||
MSG_WriteByte (msg, PRINT_CHAT);
|
MSG_WriteByte (msg, PRINT_CHAT);
|
||||||
MSG_WriteString (msg, text);
|
MSG_WriteString (msg, text);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4029,7 +4067,7 @@ void SV_Pause_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host_client->spectator && !svs.demoplayback)
|
if (host_client->spectator)
|
||||||
{
|
{
|
||||||
SV_ClientTPrintf (host_client, PRINT_HIGH, "Spectators may not pause the game\n");
|
SV_ClientTPrintf (host_client, PRINT_HIGH, "Spectators may not pause the game\n");
|
||||||
return;
|
return;
|
||||||
|
@ -5476,7 +5514,9 @@ static void SVNQ_Spawn_f (void)
|
||||||
// normally this could overflow, but no need to check due to backbuf
|
// normally this could overflow, but no need to check due to backbuf
|
||||||
for (i=0, client = svs.clients; i<sv.allocated_client_slots ; i++, client++)
|
for (i=0, client = svs.clients; i<sv.allocated_client_slots ; i++, client++)
|
||||||
SV_FullClientUpdate(client, host_client);
|
SV_FullClientUpdate(client, host_client);
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
SV_MVD_FullClientUpdate(NULL, host_client);
|
SV_MVD_FullClientUpdate(NULL, host_client);
|
||||||
|
#endif
|
||||||
|
|
||||||
// send all current light styles
|
// send all current light styles
|
||||||
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
|
||||||
|
@ -5958,11 +5998,13 @@ ucmd_t ucmds[] =
|
||||||
{"setinfo", SV_SetInfo_f},
|
{"setinfo", SV_SetInfo_f},
|
||||||
{"serverinfo", SV_ShowServerinfo_f},
|
{"serverinfo", SV_ShowServerinfo_f},
|
||||||
|
|
||||||
|
#ifdef MVD_RECORDING
|
||||||
/*demo/download commands*/
|
/*demo/download commands*/
|
||||||
{"demolist", SV_UserCmdMVDList_f},
|
{"demolist", SV_UserCmdMVDList_f},
|
||||||
{"dlist", SV_UserCmdMVDList_f}, //apparently people are too lazy to type.
|
{"dlist", SV_UserCmdMVDList_f}, //apparently people are too lazy to type.
|
||||||
{"demoinfo", SV_MVDInfo_f},
|
{"demoinfo", SV_MVDInfo_f},
|
||||||
{"dl", SV_DemoDownload_f},
|
{"dl", SV_DemoDownload_f},
|
||||||
|
#endif
|
||||||
|
|
||||||
{"stopdownload", SV_StopDownload_f},
|
{"stopdownload", SV_StopDownload_f},
|
||||||
{"dlsize", SV_DownloadSize_f},
|
{"dlsize", SV_DownloadSize_f},
|
||||||
|
@ -6098,8 +6140,8 @@ ucmd_t nqucmds[] =
|
||||||
/*various misc extensions*/
|
/*various misc extensions*/
|
||||||
{"protocols", SVNQ_Protocols_f, true},
|
{"protocols", SVNQ_Protocols_f, true},
|
||||||
{"pext", SV_Pext_f, true},
|
{"pext", SV_Pext_f, true},
|
||||||
{"enablecsqc", SV_EnableClientsCSQC},
|
{"enablecsqc", SV_EnableClientsCSQC, 2},
|
||||||
{"disablecsqc", SV_DisableClientsCSQC},
|
{"disablecsqc", SV_DisableClientsCSQC, 2},
|
||||||
{"challengeconnect", NULL},
|
{"challengeconnect", NULL},
|
||||||
|
|
||||||
/*spectating, this should be fun...*/
|
/*spectating, this should be fun...*/
|
||||||
|
@ -6184,6 +6226,7 @@ void SV_ExecuteUserCommand (const char *s, qboolean fromQC)
|
||||||
{
|
{
|
||||||
if (u->func)
|
if (u->func)
|
||||||
u->func();
|
u->func();
|
||||||
|
if (host_client->spawned)
|
||||||
PR_KrimzonParseCommand(s);
|
PR_KrimzonParseCommand(s);
|
||||||
}
|
}
|
||||||
host_client = oldhost;
|
host_client = oldhost;
|
||||||
|
@ -7491,6 +7534,7 @@ void SV_ReadQCRequest(void)
|
||||||
int i;
|
int i;
|
||||||
globalvars_t *pr_globals;
|
globalvars_t *pr_globals;
|
||||||
client_t *cl = host_client;
|
client_t *cl = host_client;
|
||||||
|
edict_t *ed;
|
||||||
|
|
||||||
if (!svprogfuncs)
|
if (!svprogfuncs)
|
||||||
{
|
{
|
||||||
|
@ -7550,7 +7594,14 @@ void SV_ReadQCRequest(void)
|
||||||
e = MSGSV_ReadEntity(host_client);
|
e = MSGSV_ReadEntity(host_client);
|
||||||
if (e < 0 || e >= sv.world.num_edicts)
|
if (e < 0 || e >= sv.world.num_edicts)
|
||||||
e = 0;
|
e = 0;
|
||||||
G_INT(OFS_PARM0+i*3) = EDICT_TO_PROG(svprogfuncs, EDICT_NUM_PB(svprogfuncs, e));
|
ed = EDICT_NUM_PB(svprogfuncs, e);
|
||||||
|
if (!ed)
|
||||||
|
{
|
||||||
|
ed = sv.world.edicts;
|
||||||
|
Con_Printf("client %s sent invalid entity\n", fromclient->name);
|
||||||
|
host_client->drop = true;
|
||||||
|
}
|
||||||
|
G_INT(OFS_PARM0+i*3) = EDICT_TO_PROG(svprogfuncs, ed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -7564,6 +7615,7 @@ done:
|
||||||
else
|
else
|
||||||
fname = va("CSEv_%s", rname);
|
fname = va("CSEv_%s", rname);
|
||||||
f = PR_FindFunction(svprogfuncs, fname, PR_ANY);
|
f = PR_FindFunction(svprogfuncs, fname, PR_ANY);
|
||||||
|
#ifndef NOLEGACY
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
if (i)
|
if (i)
|
||||||
|
@ -7572,7 +7624,10 @@ done:
|
||||||
rname = va("Cmd_%s", rname);
|
rname = va("Cmd_%s", rname);
|
||||||
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
||||||
}
|
}
|
||||||
if (!cl)
|
#endif
|
||||||
|
if (host_client->drop)
|
||||||
|
;
|
||||||
|
else if (!cl)
|
||||||
; //bad seat! not going to warn as they might have been removed recently
|
; //bad seat! not going to warn as they might have been removed recently
|
||||||
else if (f)
|
else if (f)
|
||||||
{
|
{
|
||||||
|
@ -7905,6 +7960,8 @@ void SV_ExecuteClientMessage (client_t *cl)
|
||||||
#endif
|
#endif
|
||||||
case clcdp_ackframe:
|
case clcdp_ackframe:
|
||||||
cl->delta_sequence = MSG_ReadLong();
|
cl->delta_sequence = MSG_ReadLong();
|
||||||
|
if (cl->delta_sequence == -1 && cl->pendingdeltabits)
|
||||||
|
cl->pendingdeltabits[0] = UF_REMOVE;
|
||||||
SV_AckEntityFrame(cl, cl->delta_sequence);
|
SV_AckEntityFrame(cl, cl->delta_sequence);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,11 @@ varying vec2 lm;
|
||||||
uniform vec4 e_lmscale;
|
uniform vec4 e_lmscale;
|
||||||
void main ()
|
void main ()
|
||||||
{
|
{
|
||||||
|
#ifdef LM
|
||||||
|
col = vec4(1.0);
|
||||||
|
#else
|
||||||
col = vec4(e_lmscale.rgb * ((v_normal.z < 0.73)?r_wallcolor:r_floorcolor), e_lmscale.a);
|
col = vec4(e_lmscale.rgb * ((v_normal.z < 0.73)?r_wallcolor:r_floorcolor), e_lmscale.a);
|
||||||
|
#endif
|
||||||
lm = v_lmcoord;
|
lm = v_lmcoord;
|
||||||
gl_Position = ftetransform();
|
gl_Position = ftetransform();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3597,8 +3597,11 @@ static void BE_DrawMeshChain_Internal(void)
|
||||||
|
|
||||||
vkCmdBindVertexBuffers(vk.rendertarg->cbuf, 0, VK_BUFF_MAX, vertexbuffers, vertexoffsets);
|
vkCmdBindVertexBuffers(vk.rendertarg->cbuf, 0, VK_BUFF_MAX, vertexbuffers, vertexoffsets);
|
||||||
if (BE_SetupMeshProgram(altshader->prog, altshader->passes, altshader->flags, idxcount))
|
if (BE_SetupMeshProgram(altshader->prog, altshader->passes, altshader->flags, idxcount))
|
||||||
|
{
|
||||||
|
// vkCmdPushConstants(vk.rendertarg->cbuf, altshader->prog->layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(shaderstate.curtexnums->factors), shaderstate.curtexnums->factors);
|
||||||
vkCmdDrawIndexed(vk.rendertarg->cbuf, idxcount, 1, idxfirst, 0, 0);
|
vkCmdDrawIndexed(vk.rendertarg->cbuf, idxcount, 1, idxfirst, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (1)
|
else if (1)
|
||||||
{
|
{
|
||||||
shaderpass_t *p;
|
shaderpass_t *p;
|
||||||
|
|
Loading…
Reference in a new issue