Q3 server works a bit better now.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1265 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
02ba159623
commit
a81732a8e0
1 changed files with 129 additions and 50 deletions
|
@ -31,6 +31,8 @@ q3entityState_t *q3_baselines;
|
|||
#define SENTITY_FOR_GENTITY(ge) (SENTITY_FOR_NUM(NUM_FOR_GENTITY(ge)))
|
||||
#define GENTITY_FOR_SENTITY(se) (GENTITY_FOR_NUM(NUM_FOR_SENTITY(se)))
|
||||
|
||||
static qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
|
||||
|
||||
void SVQ3_CreateBaseline(void);
|
||||
|
||||
char *mapentspointer;
|
||||
|
@ -285,8 +287,7 @@ int SVQ3_EntitiesInBoxNode(areanode_t *node, vec3_t mins, vec3_t maxs, int *list
|
|||
q3serverEntity_t *sent;
|
||||
q3sharedEntity_t *gent;
|
||||
|
||||
int linkcount = 0, ln;
|
||||
float d1, d2;
|
||||
int linkcount = 0;
|
||||
|
||||
//work out who they are first.
|
||||
for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next)
|
||||
|
@ -329,9 +330,10 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
|
|||
int contactlist[128];
|
||||
trace_t tr;
|
||||
vec3_t mmins, mmaxs;
|
||||
int i, contactcount;
|
||||
q3entityShared_t *es;
|
||||
int i;
|
||||
q3sharedEntity_t *es;
|
||||
model_t *mod;
|
||||
int ourowner;
|
||||
|
||||
if (!mins)
|
||||
mins = vec3_origin;
|
||||
|
@ -365,17 +367,48 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
|
|||
}
|
||||
}
|
||||
|
||||
if ( entnum != ENTITYNUM_WORLD )
|
||||
{
|
||||
ourowner = GENTITY_FOR_NUM(entnum)->r.ownerNum;
|
||||
if (ourowner == ENTITYNUM_WORLD)
|
||||
ourowner = -1;
|
||||
}
|
||||
else
|
||||
ourowner = -1;
|
||||
|
||||
|
||||
for (i = SVQ3_EntitiesInBox(mmins, mmaxs, contactlist, sizeof(contactlist)/sizeof(contactlist[0]))-1; i >= 0; i--)
|
||||
{
|
||||
if (contactlist[i] == entnum)
|
||||
continue; //don't collide with self.
|
||||
|
||||
es = GENTITY_FOR_NUM(contactlist[i]);
|
||||
if (es->bmodel)
|
||||
mod = Mod_ForName(va("*%i", es->s.modelindex), true);
|
||||
if (!(es->r.contents & contentmask))
|
||||
continue;
|
||||
|
||||
if (entnum != ENTITYNUM_WORLD)
|
||||
{
|
||||
// if (contactlist[i] == entnum)
|
||||
// continue; // don't clip against the pass entity
|
||||
// if (es->r.ownerNum == entnum)
|
||||
// continue; // don't clip against own missiles
|
||||
// if (es->r.ownerNum == ourowner)
|
||||
// continue; // don't clip against other missiles from our owner
|
||||
}
|
||||
|
||||
if (es->r.bmodel)
|
||||
{
|
||||
mod = Mod_ForName(va("*%i", es->s.modelindex), false);
|
||||
if (mod->needload)
|
||||
continue;
|
||||
tr = CM_TransformedBoxTrace(mod, start, end, mins, maxs, 0xffffffff, es->r.currentOrigin, vec3_origin);
|
||||
}
|
||||
else
|
||||
mod = CM_TempBoxModel(es->mins, es->maxs);
|
||||
tr = CM_TransformedBoxTrace(mod, start, mins, mmins, mmaxs, contentmask, es->currentOrigin, es->currentAngles);
|
||||
{
|
||||
mod = CM_TempBoxModel(es->r.mins, es->r.maxs);
|
||||
tr = CM_TransformedBoxTrace(mod, start, end, mins, maxs, 0xffffffff, es->r.currentOrigin, es->r.currentAngles);
|
||||
// mod->funcs.Trace(mod, 0, 0, start, end, mins, maxs, &tr);
|
||||
}
|
||||
if (tr.fraction < result->fraction)
|
||||
{
|
||||
result->allsolid = tr.allsolid;
|
||||
|
@ -384,7 +417,7 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
|
|||
result->entityNum = contactlist[i];
|
||||
result->fraction = tr.fraction;
|
||||
result->plane = tr.plane;
|
||||
result->startsolid = tr.startsolid;
|
||||
result->startsolid |= tr.startsolid;
|
||||
// if (tr.surface)
|
||||
// result->surfaceFlags = tr.surface->flags;
|
||||
// else
|
||||
|
@ -393,20 +426,24 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
|
|||
}
|
||||
}
|
||||
|
||||
int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3entityShared_t *ent)
|
||||
int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent)
|
||||
{
|
||||
/* model_t *mod;
|
||||
vec3_t org;
|
||||
model_t *mod;
|
||||
trace_t tr;
|
||||
|
||||
VectorSubtract(maxs, mins, org);
|
||||
VectorMA(mins, 0.5, org, org);
|
||||
if (!ent->s.modelindex || ent->r.bmodel)
|
||||
mod = CM_TempBoxModel(ent->r.mins, ent->r.maxs);
|
||||
else
|
||||
mod = Mod_ForName(va("*%i", ent->s.modelindex), false);
|
||||
mod->funcs.Trace(mod, 0, 0, org, org, mins, maxs, &tr);
|
||||
|
||||
if (tr.startsolid)*/
|
||||
if (mod->needload || !mod->funcs.Trace)
|
||||
return false;
|
||||
|
||||
mod->funcs.Trace(mod, 0, 0, vec3_origin, vec3_origin, mins, maxs, &tr);
|
||||
|
||||
if (tr.startsolid)
|
||||
return true;
|
||||
// return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SVQ3_SetBrushModel(q3sharedEntity_t *ent, char *modelname)
|
||||
|
@ -473,7 +510,7 @@ void SVQ3_SendServerCommand(client_t *cl, char *str)
|
|||
}
|
||||
|
||||
cl->num_server_commands++;
|
||||
Q_strncpyz(cl->server_commands[cl->num_server_commands], str, sizeof(cl->server_commands[0]));
|
||||
Q_strncpyz(cl->server_commands[cl->num_server_commands & TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
|
||||
}
|
||||
|
||||
void SVQ3_SetConfigString(int num, char *string)
|
||||
|
@ -581,6 +618,48 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
|
|||
Q_strncpyz(VM_POINTER(arg[1]), Cmd_Argv(VM_LONG(arg[0])), VM_LONG(arg[2]));
|
||||
break;
|
||||
|
||||
|
||||
case G_FS_FOPEN_FILE: //fopen
|
||||
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
|
||||
break; //out of bounds.
|
||||
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
|
||||
break;
|
||||
|
||||
case G_FS_READ: //fread
|
||||
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
|
||||
break; //out of bounds.
|
||||
|
||||
VMUI_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
|
||||
break;
|
||||
case G_FS_WRITE: //fwrite
|
||||
break;
|
||||
case G_FS_FCLOSE_FILE: //fclose
|
||||
VMUI_fclose(VM_LONG(arg[0]), 0);
|
||||
break;
|
||||
|
||||
/* case G_FS_GETFILELIST: //fs listing
|
||||
if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset)
|
||||
break; //out of bounds.
|
||||
{
|
||||
vmsearch_t vms;
|
||||
vms.initialbuffer = vms.buffer = VM_POINTER(arg[2]);
|
||||
vms.skip = strlen(VM_POINTER(arg[0]))+1;
|
||||
vms.bufferleft = arg[3];
|
||||
vms.found=0;
|
||||
if (*(char *)VM_POINTER(arg[0]) == '$')
|
||||
{
|
||||
extern char com_basedir[];
|
||||
vms.skip=0;
|
||||
Sys_EnumerateFiles(com_basedir, "*", VMEnumMods, &vms);
|
||||
}
|
||||
else if (*(char *)VM_POINTER(arg[1]) == '.' || *(char *)VM_POINTER(arg[1]) == '/')
|
||||
COM_EnumerateFiles(va("%s/*%s", VM_POINTER(arg[0]), VM_POINTER(arg[1])), VMEnum, &vms);
|
||||
else
|
||||
COM_EnumerateFiles(va("%s/*.%s", VM_POINTER(arg[0]), VM_POINTER(arg[1])), VMEnum, &vms);
|
||||
VM_LONG(ret) = vms.found;
|
||||
}
|
||||
break;*/
|
||||
|
||||
case G_LOCATE_GAME_DATA: // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, 15
|
||||
// playerState_t *clients, int sizeofGameClient );
|
||||
|
||||
|
@ -597,6 +676,8 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
|
|||
break;
|
||||
|
||||
case G_SEND_SERVER_COMMAND: // ( int clientNum, const char *fmt, ... ); 17
|
||||
|
||||
Con_DPrintf("Game dispatching %s\n", VM_POINTER(arg[1]));
|
||||
if (VM_LONG(arg[0]) == -1)
|
||||
{ //broadcast
|
||||
SVQ3_SendServerCommand(NULL, VM_POINTER(arg[1]));
|
||||
|
@ -653,7 +734,7 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
|
|||
return SVQ3_EntitiesInBox(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
|
||||
break;
|
||||
case G_POINT_CONTENTS:
|
||||
return sv.worldmodel->funcs.PointContents(sv.worldmodel, VM_POINTER(arg[0]));
|
||||
return CM_PointContents(sv.worldmodel, VM_POINTER(arg[0]));
|
||||
break;
|
||||
case G_SET_BRUSH_MODEL: //ent, name
|
||||
VALIDATEPOINTER(arg[0], sizeof(q3sharedEntity_t));
|
||||
|
@ -667,7 +748,7 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
|
|||
mapentspointer = COM_ParseOut(mapentspointer, VM_POINTER(arg[0]), arg[1]);
|
||||
return !!mapentspointer;
|
||||
|
||||
case G_REAL_TIME: // 42
|
||||
case G_REAL_TIME: // 41
|
||||
Con_Printf("builtin %i is not implemented\n", fn);
|
||||
return 0;
|
||||
case G_SNAPVECTOR:
|
||||
|
@ -767,20 +848,13 @@ void SVQ3_ShutdownGame(void)
|
|||
|
||||
qboolean SVQ3_InitGame(void)
|
||||
{
|
||||
int i;
|
||||
char buffer[8192];
|
||||
|
||||
if (sv.worldmodel->fromgame == fg_quake)
|
||||
return false; //always fail on q1bsp
|
||||
|
||||
//clear out the configstrings
|
||||
for (i = 0; i < MAX_CONFIGSTRINGS; i++)
|
||||
{
|
||||
if (svq3_configstrings[i])
|
||||
{
|
||||
Z_Free(svq3_configstrings[i]);
|
||||
svq3_configstrings[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SVQ3_ShutdownGame();
|
||||
|
||||
q3gamevm = VM_Create(NULL, "vm/qagame", Q3G_SystemCalls, Q3G_SystemCallsEx);
|
||||
|
||||
|
@ -791,9 +865,12 @@ qboolean SVQ3_InitGame(void)
|
|||
|
||||
q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES);
|
||||
|
||||
svq3_configstrings[0] = Z_Malloc(strlen(svs.info)+1 + 9+strlen(sv.name)+16);
|
||||
strcpy(svq3_configstrings[0], svs.info);
|
||||
Info_SetValueForKey(svq3_configstrings[0], "mapname", sv.name, MAX_SERVERINFO_STRING);
|
||||
strcpy(buffer, svs.info);
|
||||
Info_SetValueForKey(buffer, "map", "", sizeof(buffer));
|
||||
Info_SetValueForKey(buffer, "maxclients", "", sizeof(buffer));
|
||||
Info_SetValueForKey(buffer, "mapname", sv.name, sizeof(buffer));
|
||||
Info_SetValueForKey(buffer, "sv_maxclients", "32", sizeof(buffer));
|
||||
SVQ3_SetConfigString(0, buffer);
|
||||
|
||||
svq3_configstrings[1] = Z_Malloc(32);
|
||||
Info_SetValueForKey(svq3_configstrings[1], "sv_serverid", va("%i", svs.spawncount), MAX_SERVERINFO_STRING);
|
||||
|
@ -814,7 +891,7 @@ qboolean SVQ3_InitGame(void)
|
|||
|
||||
void SVQ3_RunFrame(void)
|
||||
{
|
||||
VM_Call(q3gamevm, GAME_RUN_FRAME, sv.framenum*100);
|
||||
VM_Call(q3gamevm, GAME_RUN_FRAME, (int)(sv.time*1000));
|
||||
}
|
||||
|
||||
void SVQ3_ClientCommand(client_t *cl)
|
||||
|
@ -952,6 +1029,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
|
|||
// not fully in game yet
|
||||
delta = 0;
|
||||
oldsnap = NULL;
|
||||
return;
|
||||
}
|
||||
else if(client->delta_sequence < 0)
|
||||
{
|
||||
|
@ -988,7 +1066,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
|
|||
|
||||
// write snapshot header
|
||||
MSG_WriteBits(msg, svcq3_snapshot, 8);
|
||||
MSG_WriteBits(msg, sv.framenum*100, 32);
|
||||
MSG_WriteBits(msg, (int)(sv.time*1000), 32);
|
||||
MSG_WriteBits(msg, delta, 8); // what we are delta'ing from
|
||||
|
||||
// write snapFlags
|
||||
|
@ -1004,7 +1082,6 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
|
|||
|
||||
// delta encode the entities
|
||||
SVQ3_EmitPacketEntities(client, oldsnap, snap, msg);
|
||||
// MSG_WriteBits( msg, ENTITYNUM_NONE, GENTITYNUM_BITS );
|
||||
|
||||
// while( msg.cursize < sv_padPackets->integer ) { // FIXME?
|
||||
// for( i=0 ; i<sv_padPackets->integer ; i++ )
|
||||
|
@ -1164,7 +1241,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
|
|||
org[2] += ps->viewheight;
|
||||
|
||||
clientarea = CM_PointLeafnum(sv.worldmodel, org);
|
||||
bitvector = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org), clientarea);
|
||||
bitvector = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org), NULL);
|
||||
clientarea = CM_LeafArea(sv.worldmodel, clientarea);
|
||||
/*
|
||||
if( client->areanum != clientarea ) {
|
||||
|
@ -1260,12 +1337,12 @@ void SVQ3_BuildClientSnapshot( client_t *client )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
for (i = 0; i < snap->areabytes;i++)
|
||||
{ //fix areabits, q2->q3 style..
|
||||
snap->areabits[i]^=255;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1524,7 +1601,6 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
|
|||
from = &nullcmd;
|
||||
for(i=0, to=commands; i<cmdCount; i++, to++)
|
||||
{
|
||||
memcpy(to, from, sizeof(*to));
|
||||
MSG_Q3_ReadDeltaUsercmd(key, from, to);
|
||||
from = to;
|
||||
}
|
||||
|
@ -1541,8 +1617,8 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
|
|||
// run G_ClientThink() on each usercmd
|
||||
for(i=0,to=commands; i<cmdCount; i++, to++)
|
||||
{
|
||||
if(to->servertime <= client->lastcmd.servertime )
|
||||
continue;
|
||||
// if(to->servertime <= client->lastcmd.servertime )
|
||||
// continue;
|
||||
|
||||
memcpy( &client->lastcmd, to, sizeof(client->lastcmd));
|
||||
SVQ3_ClientThink(client);
|
||||
|
@ -1554,15 +1630,19 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
|
|||
|
||||
}
|
||||
|
||||
void SVQ3_UpdateUserinfo_f(void)
|
||||
void SVQ3_UpdateUserinfo_f(client_t *cl)
|
||||
{
|
||||
Q_strncpyz( host_client->userinfo, Cmd_Argv(1), sizeof(host_client->userinfo) );
|
||||
Q_strncpyz( cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo) );
|
||||
|
||||
SV_ExtractFromUserinfo (host_client);
|
||||
SV_ExtractFromUserinfo (cl);
|
||||
|
||||
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, host_client-svs.clients);
|
||||
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, cl-svs.clients);
|
||||
}
|
||||
|
||||
void SVQ3_Drop_f(client_t *cl)
|
||||
{
|
||||
SV_DropClient(cl);
|
||||
}
|
||||
|
||||
typedef struct ucmd_s {
|
||||
char *name;
|
||||
|
@ -1571,7 +1651,7 @@ typedef struct ucmd_s {
|
|||
|
||||
static const ucmd_t ucmds[] = {
|
||||
{ "userinfo", SVQ3_UpdateUserinfo_f},
|
||||
{ "disconnect", NULL},//SV_Disconnect_f },
|
||||
{ "disconnect", SVQ3_Drop_f},//SV_Disconnect_f },
|
||||
|
||||
// TODO
|
||||
{ "cp", NULL },
|
||||
|
@ -1640,7 +1720,7 @@ void SVQ3_ParseClientCommand(client_t *client)
|
|||
void SVQ3_ParseClientMessage(client_t *client)
|
||||
{
|
||||
int serverid; //sorta like the level number.
|
||||
int c, last;
|
||||
int c;
|
||||
|
||||
host_client = client;
|
||||
|
||||
|
@ -1697,7 +1777,6 @@ void SVQ3_ParseClientMessage(client_t *client)
|
|||
return;
|
||||
}
|
||||
|
||||
last = c;
|
||||
c = MSG_ReadBits(8);
|
||||
if (c == clcq3_eom)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue