Q2 now runs properly.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@902 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
300734ae71
commit
74f9fa8581
10 changed files with 185 additions and 156 deletions
|
@ -62,7 +62,7 @@ Q2SOLID_BSP // bsp clip, touch on edge
|
|||
|
||||
|
||||
#define MAXTOUCH 32
|
||||
typedef struct
|
||||
typedef struct q2pmove_s
|
||||
{
|
||||
// state (in / out)
|
||||
q2pmove_state_t s;
|
||||
|
@ -85,10 +85,12 @@ typedef struct
|
|||
int waterlevel;
|
||||
|
||||
// callbacks to test the world
|
||||
q2trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
|
||||
int (*pointcontents) (vec3_t point);
|
||||
q2trace_t (VARGS *trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
|
||||
int (VARGS *pointcontents) (vec3_t point);
|
||||
} q2pmove_t;
|
||||
|
||||
void VARGS Q2_Pmove (q2pmove_t *pmove);
|
||||
|
||||
//===============================================================
|
||||
|
||||
// link_t is only used for entity area links now
|
||||
|
@ -173,6 +175,7 @@ struct q2edict_s
|
|||
//
|
||||
// functions provided by the main engine
|
||||
//
|
||||
//yes, these are all VARGS, for the calling convention rather than actually being varargs.
|
||||
typedef struct
|
||||
{
|
||||
// special messages
|
||||
|
@ -180,73 +183,73 @@ typedef struct
|
|||
void (VARGS *dprintf) (char *fmt, ...);
|
||||
void (VARGS *cprintf) (q2edict_t *ent, int printlevel, char *fmt, ...);
|
||||
void (VARGS *centerprintf) (q2edict_t *ent, char *fmt, ...);
|
||||
void (*sound) (q2edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
|
||||
void (*positioned_sound) (vec3_t origin, q2edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
|
||||
void (VARGS *sound) (q2edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
|
||||
void (VARGS *positioned_sound) (vec3_t origin, q2edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
|
||||
|
||||
// config strings hold all the index strings, the lightstyles,
|
||||
// and misc data like the sky definition and cdtrack.
|
||||
// All of the current configstrings are sent to clients when
|
||||
// they connect, and changes are sent to all connected clients.
|
||||
void (*configstring) (int num, char *string);
|
||||
void (VARGS *configstring) (int num, char *string);
|
||||
|
||||
void (VARGS *error) (char *fmt, ...);
|
||||
|
||||
// the *index functions create configstrings and some internal server state
|
||||
int (*modelindex) (char *name);
|
||||
int (*soundindex) (char *name);
|
||||
int (*imageindex) (char *name);
|
||||
int (VARGS *modelindex) (char *name);
|
||||
int (VARGS *soundindex) (char *name);
|
||||
int (VARGS *imageindex) (char *name);
|
||||
|
||||
void (*setmodel) (q2edict_t *ent, char *name);
|
||||
void (VARGS *setmodel) (q2edict_t *ent, char *name);
|
||||
|
||||
// collision detection
|
||||
q2trace_t (*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passent, int contentmask);
|
||||
int (*pointcontents) (vec3_t point);
|
||||
qboolean (*inPVS) (vec3_t p1, vec3_t p2);
|
||||
qboolean (*inPHS) (vec3_t p1, vec3_t p2);
|
||||
void (*SetAreaPortalState) (int portalnum, qboolean open);
|
||||
qboolean (*AreasConnected) (int area1, int area2);
|
||||
q2trace_t (VARGS *trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passent, int contentmask);
|
||||
int (VARGS *pointcontents) (vec3_t point);
|
||||
qboolean (VARGS *inPVS) (vec3_t p1, vec3_t p2);
|
||||
qboolean (VARGS *inPHS) (vec3_t p1, vec3_t p2);
|
||||
void (VARGS *SetAreaPortalState) (int portalnum, qboolean open);
|
||||
qboolean (VARGS *AreasConnected) (int area1, int area2);
|
||||
|
||||
// an entity will never be sent to a client or used for collision
|
||||
// if it is not passed to linkentity. If the size, position, or
|
||||
// solidity changes, it must be relinked.
|
||||
void (*linkentity) (q2edict_t *ent);
|
||||
void (*unlinkentity) (q2edict_t *ent); // call before removing an interactive edict
|
||||
int (*BoxEdicts) (vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype);
|
||||
void (*Pmove) (q2pmove_t *pmove); // player movement code common with client prediction
|
||||
void (VARGS *linkentity) (q2edict_t *ent);
|
||||
void (VARGS *unlinkentity) (q2edict_t *ent); // call before removing an interactive edict
|
||||
int (VARGS *BoxEdicts) (vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype);
|
||||
void (VARGS *Pmove) (q2pmove_t *pmove); // player movement code common with client prediction
|
||||
|
||||
// network messaging
|
||||
void (*multicast) (vec3_t origin, multicast_t to);
|
||||
void (*unicast) (q2edict_t *ent, qboolean reliable);
|
||||
void (*WriteChar) (int c);
|
||||
void (*WriteByte) (int c);
|
||||
void (*WriteShort) (int c);
|
||||
void (*WriteLong) (int c);
|
||||
void (*WriteFloat) (float f);
|
||||
void (*WriteString) (char *s);
|
||||
void (*WritePosition) (vec3_t pos); // some fractional bits
|
||||
void (*WriteDir) (vec3_t pos); // single byte encoded, very coarse
|
||||
void (*WriteAngle) (float f);
|
||||
void (VARGS *multicast) (vec3_t origin, multicast_t to);
|
||||
void (VARGS *unicast) (q2edict_t *ent, qboolean reliable);
|
||||
void (VARGS *WriteChar) (int c);
|
||||
void (VARGS *WriteByte) (int c);
|
||||
void (VARGS *WriteShort) (int c);
|
||||
void (VARGS *WriteLong) (int c);
|
||||
void (VARGS *WriteFloat) (float f);
|
||||
void (VARGS *WriteString) (char *s);
|
||||
void (VARGS *WritePosition) (vec3_t pos); // some fractional bits
|
||||
void (VARGS *WriteDir) (vec3_t pos); // single byte encoded, very coarse
|
||||
void (VARGS *WriteAngle) (float f);
|
||||
|
||||
// managed memory allocation
|
||||
void *(*TagMalloc) (int size, int tag);
|
||||
void (*TagFree) (void *block);
|
||||
void (*FreeTags) (int tag);
|
||||
void *(VARGS *TagMalloc) (int size, int tag);
|
||||
void (VARGS *TagFree) (void *block);
|
||||
void (VARGS *FreeTags) (int tag);
|
||||
|
||||
// console variable interaction
|
||||
cvar_t *(*cvar) (char *var_name, char *value, int flags);
|
||||
cvar_t *(*cvar_set) (char *var_name, char *value);
|
||||
cvar_t *(*cvar_forceset) (char *var_name, char *value);
|
||||
cvar_t *(VARGS *cvar) (char *var_name, char *value, int flags);
|
||||
cvar_t *(VARGS *cvar_set) (char *var_name, char *value);
|
||||
cvar_t *(VARGS *cvar_forceset) (char *var_name, char *value);
|
||||
|
||||
// ClientCommand and ServerCommand parameter access
|
||||
int (*argc) (void);
|
||||
char *(*argv) (int n);
|
||||
char *(*args) (void); // concatenation of all argv >= 1
|
||||
int (VARGS *argc) (void);
|
||||
char *(VARGS *argv) (int n);
|
||||
char *(VARGS *args) (void); // concatenation of all argv >= 1
|
||||
|
||||
// add commands to the server console as if they were typed in
|
||||
// for map changing, etc
|
||||
void (*AddCommandString) (char *text);
|
||||
void (VARGS *AddCommandString) (char *text);
|
||||
|
||||
void (*DebugGraph) (float value, int color);
|
||||
void (VARGS *DebugGraph) (float value, int color);
|
||||
} game_import_t;
|
||||
|
||||
//
|
||||
|
@ -259,38 +262,38 @@ typedef struct
|
|||
// the init function will only be called when a game starts,
|
||||
// not each time a level is loaded. Persistant data for clients
|
||||
// and the server can be allocated in init
|
||||
void (*Init) (void);
|
||||
void (*Shutdown) (void);
|
||||
void (VARGS *Init) (void);
|
||||
void (VARGS *Shutdown) (void);
|
||||
|
||||
// each new level entered will cause a call to SpawnEntities
|
||||
void (*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
|
||||
void (VARGS *SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
|
||||
|
||||
// Read/Write Game is for storing persistant cross level information
|
||||
// about the world state and the clients.
|
||||
// WriteGame is called every time a level is exited.
|
||||
// ReadGame is called on a loadgame.
|
||||
void (*WriteGame) (char *filename, qboolean autosave);
|
||||
void (*ReadGame) (char *filename);
|
||||
void (VARGS *WriteGame) (char *filename, qboolean autosave);
|
||||
void (VARGS *ReadGame) (char *filename);
|
||||
|
||||
// ReadLevel is called after the default map information has been
|
||||
// loaded with SpawnEntities
|
||||
void (*WriteLevel) (char *filename);
|
||||
void (*ReadLevel) (char *filename);
|
||||
void (VARGS *WriteLevel) (char *filename);
|
||||
void (VARGS *ReadLevel) (char *filename);
|
||||
|
||||
qboolean (*ClientConnect) (q2edict_t *ent, char *userinfo);
|
||||
void (*ClientBegin) (q2edict_t *ent);
|
||||
void (*ClientUserinfoChanged) (q2edict_t *ent, char *userinfo);
|
||||
void (*ClientDisconnect) (q2edict_t *ent);
|
||||
void (*ClientCommand) (q2edict_t *ent);
|
||||
void (*ClientThink) (q2edict_t *ent, q2usercmd_t *cmd);
|
||||
qboolean (VARGS *ClientConnect) (q2edict_t *ent, char *userinfo);
|
||||
void (VARGS *ClientBegin) (q2edict_t *ent);
|
||||
void (VARGS *ClientUserinfoChanged) (q2edict_t *ent, char *userinfo);
|
||||
void (VARGS *ClientDisconnect) (q2edict_t *ent);
|
||||
void (VARGS *ClientCommand) (q2edict_t *ent);
|
||||
void (VARGS *ClientThink) (q2edict_t *ent, q2usercmd_t *cmd);
|
||||
|
||||
void (*RunFrame) (void);
|
||||
void (VARGS *RunFrame) (void);
|
||||
|
||||
// ServerCommand will be called when an "sv <command>" command is issued on the
|
||||
// server console.
|
||||
// The game can issue gi.argc() / gi.argv() commands to get the rest
|
||||
// of the parameters
|
||||
void (*ServerCommand) (void);
|
||||
void (VARGS *ServerCommand) (void);
|
||||
|
||||
//
|
||||
// global variables shared between game and server
|
||||
|
|
|
@ -30,7 +30,12 @@ void SV_SavegameComment (char *text)
|
|||
i = SAVEGAME_COMMENT_LENGTH;
|
||||
memcpy (text, mapname, i);
|
||||
}
|
||||
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
|
||||
if (ge) //q2
|
||||
{
|
||||
sprintf (kills,"");
|
||||
}
|
||||
else
|
||||
sprintf (kills,"kills:%3i/%3i", (int)pr_global_struct->killed_monsters, (int)pr_global_struct->total_monsters);
|
||||
memcpy (text+22, kills, strlen(kills));
|
||||
// convert space to _ to make stdio happy
|
||||
for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
|
||||
|
@ -466,6 +471,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
|
|||
|
||||
int filelen, filepos;
|
||||
char *file;
|
||||
gametype_e gametype;
|
||||
|
||||
levelcache_t *cache;
|
||||
|
||||
|
@ -480,17 +486,25 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
|
|||
if (!cache)
|
||||
return false; //not visited yet. Ignore the existing caches as fakes.
|
||||
|
||||
gametype = cache->gametype;
|
||||
|
||||
sprintf (name, "%s/saves/%s", com_gamedir, level);
|
||||
COM_DefaultExtension (name, ".lvc");
|
||||
|
||||
// Con_TPrintf (STL_LOADGAMEFROM, name);
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (ge)
|
||||
if (gametype == GT_QUAKE2)
|
||||
{
|
||||
SV_SpawnServer (level, startspot, false, false);
|
||||
|
||||
SV_ClearWorld();
|
||||
if (!ge)
|
||||
{
|
||||
Con_Printf("Incorrect gamecode type.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ge->ReadLevel(name);
|
||||
|
||||
for (i=0 ; i<100 ; i++) //run for 10 secs to iron out a few bugs.
|
||||
|
@ -540,6 +554,11 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
|
|||
fscanf (f, "%f\n",&time);
|
||||
|
||||
SV_SpawnServer (mapname, startspot, false, false);
|
||||
if (svs.gametype != gametype)
|
||||
{
|
||||
Con_Printf("Incorrect gamecode type. Cannot load game.\n");
|
||||
return false;
|
||||
}
|
||||
if (sv.state != ss_active)
|
||||
{
|
||||
fclose (f);
|
||||
|
@ -670,6 +689,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
|
|||
cache->mapname = (char *)(cache+1);
|
||||
strcpy(cache->mapname, sv.name);
|
||||
|
||||
cache->gametype = svs.gametype;
|
||||
cache->next = svs.levcache;
|
||||
svs.levcache = cache;
|
||||
}
|
||||
|
@ -682,7 +702,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
|
|||
Con_TPrintf (STL_SAVEGAMETO, name);
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (!svprogfuncs)
|
||||
if (ge)
|
||||
{
|
||||
char path[256];
|
||||
strcpy(path, name);
|
||||
|
@ -805,7 +825,7 @@ void SV_Savegame_f (void)
|
|||
return;
|
||||
}
|
||||
SV_SavegameComment(comment);
|
||||
fprintf (f, "%d\n", FTESAVEGAME_VERSION);
|
||||
fprintf (f, "%d\n", FTESAVEGAME_VERSION+svs.gametype);
|
||||
fprintf (f, "%s\n", comment);
|
||||
|
||||
fprintf(f, "%i\n", sv.allocated_client_slots);
|
||||
|
@ -914,6 +934,7 @@ void SV_Loadgame_f (void)
|
|||
int clnum;
|
||||
int slots;
|
||||
client_t *cl;
|
||||
gametype_e gametype;
|
||||
|
||||
int len, buflen=0;
|
||||
char *buffer=NULL;
|
||||
|
@ -933,25 +954,30 @@ void SV_Loadgame_f (void)
|
|||
|
||||
fgets(str, sizeof(str)-1, f);
|
||||
version = atoi(str);
|
||||
if (version != FTESAVEGAME_VERSION)
|
||||
if (version < FTESAVEGAME_VERSION || version >= FTESAVEGAME_VERSION+GT_MAX)
|
||||
{
|
||||
fclose (f);
|
||||
Con_TPrintf (STL_BADSAVEVERSION, version, FTESAVEGAME_VERSION);
|
||||
return;
|
||||
}
|
||||
gametype = version - FTESAVEGAME_VERSION;
|
||||
fgets(str, sizeof(str)-1, f);
|
||||
#ifndef SERVERONLY
|
||||
if (!cls.state)
|
||||
#endif
|
||||
Con_TPrintf (STL_LOADGAMEFROM, filename);
|
||||
|
||||
|
||||
for (clnum = 0; clnum < MAX_CLIENTS; clnum++) //clear the server for the level change.
|
||||
{
|
||||
cl = &svs.clients[clnum];
|
||||
if (cl->state <= cs_zombie)
|
||||
continue;
|
||||
|
||||
MSG_WriteByte (&cl->netchan.message, svc_stufftext);
|
||||
if (cl->isq2client)
|
||||
MSG_WriteByte (&cl->netchan.message, svcq2_stufftext);
|
||||
else
|
||||
MSG_WriteByte (&cl->netchan.message, svc_stufftext);
|
||||
MSG_WriteString (&cl->netchan.message, "echo Loading Game;disconnect;wait;wait;reconnect\n"); //kindly ask the client to come again.
|
||||
cl->istobeloaded = false;
|
||||
}
|
||||
|
@ -1039,8 +1065,6 @@ void SV_Loadgame_f (void)
|
|||
Cmd_ExecuteString(str, RESTRICT_RCON);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SV_FlushLevelCache();
|
||||
|
||||
fgets(str, sizeof(str)-1, f);
|
||||
|
@ -1063,9 +1087,10 @@ void SV_Loadgame_f (void)
|
|||
if (!*str)
|
||||
continue;
|
||||
|
||||
cache = Z_Malloc(sizeof(levelcache_t)+strlen(sv.name)+1);
|
||||
cache = Z_Malloc(sizeof(levelcache_t)+strlen(str)+1);
|
||||
cache->mapname = (char *)(cache+1);
|
||||
strcpy(cache->mapname, str);
|
||||
cache->gametype = gametype;
|
||||
|
||||
cache->next = svs.levcache;
|
||||
|
||||
|
@ -1073,7 +1098,6 @@ void SV_Loadgame_f (void)
|
|||
|
||||
|
||||
|
||||
|
||||
sprintf (filename, "%s/saves/%s/%s.lvc", com_gamedir, savename, cache->mapname);
|
||||
fi = fopen(filename, "rb");
|
||||
if (!fi)
|
||||
|
@ -1116,9 +1140,7 @@ void SV_Loadgame_f (void)
|
|||
|
||||
fclose(f);
|
||||
|
||||
|
||||
SV_LoadLevelCache(str, "", true);
|
||||
|
||||
sv.allocated_client_slots = slots;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -642,17 +642,19 @@ typedef struct bannedips_s {
|
|||
netadr_t adr;
|
||||
} bannedips_t;
|
||||
|
||||
typedef struct levelcache_s {
|
||||
struct levelcache_s *next;
|
||||
char *mapname;
|
||||
} levelcache_t;
|
||||
|
||||
typedef enum {
|
||||
GT_PROGS, //q1, qw, h2 are similar enough that we consider it only one game mode. (We don't support the h2 protocol)
|
||||
GT_QUAKE2, //q2 servers run from a q2 game dll
|
||||
GT_QUAKE3 //q3 servers run off the q3 qvm api
|
||||
GT_QUAKE3, //q3 servers run off the q3 qvm api
|
||||
GT_MAX
|
||||
} gametype_e;
|
||||
|
||||
typedef struct levelcache_s {
|
||||
struct levelcache_s *next;
|
||||
char *mapname;
|
||||
gametype_e gametype;
|
||||
} levelcache_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gametype_e gametype;
|
||||
|
@ -891,7 +893,7 @@ void SV_FilterImpulseInit(void);
|
|||
|
||||
//svq2_game.c
|
||||
qboolean SVQ2_InitGameProgs(void);
|
||||
void SVQ2_ShutdownGameProgs (void);
|
||||
void VARGS SVQ2_ShutdownGameProgs (void);
|
||||
|
||||
//svq2_ents.c
|
||||
void SV_BuildClientFrame (client_t *client);
|
||||
|
@ -923,7 +925,7 @@ void SV_ClearQCStats(void);
|
|||
|
||||
void SV_SendClientMessages (void);
|
||||
|
||||
void SV_Multicast (vec3_t origin, multicast_t to);
|
||||
void VARGS SV_Multicast (vec3_t origin, multicast_t to);
|
||||
#define FULLDIMENSIONMASK 0xffffffff
|
||||
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without);
|
||||
|
||||
|
@ -1136,7 +1138,10 @@ int SV_RateForClient(client_t *cl);
|
|||
void SVVC_Frame (qboolean enabled);
|
||||
void SV_CalcPHS (void);
|
||||
#ifdef Q2SERVER
|
||||
void SVQ2_LinkEdict(q2edict_t *ent);
|
||||
void VARGS SVQ2_LinkEdict(q2edict_t *ent);
|
||||
void VARGS SVQ2_UnlinkEdict(q2edict_t *ent);
|
||||
int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
|
||||
int maxcount, int areatype);
|
||||
#endif
|
||||
|
||||
void SV_GetConsoleCommands (void);
|
||||
|
|
|
@ -440,6 +440,7 @@ void SV_Map_f (void)
|
|||
Con_TPrintf (STL_MAPCOMMANDUSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy (level, Cmd_Argv(1));
|
||||
startspot = ((Cmd_Argc() == 2)?NULL:Cmd_Argv(2));
|
||||
|
||||
|
@ -510,7 +511,24 @@ void SV_Map_f (void)
|
|||
SV_SaveSpawnparms (issamelevel);
|
||||
|
||||
if (startspot && !issamelevel && !newunit)
|
||||
SV_SaveLevelCache(false);
|
||||
{
|
||||
if (ge)
|
||||
{
|
||||
qboolean savedinuse[MAX_CLIENTS];
|
||||
for (i=0 ; i<sv.allocated_client_slots; i++)
|
||||
{
|
||||
savedinuse[i] = svs.clients[i].q2edict->inuse;
|
||||
svs.clients[i].q2edict->inuse = false;
|
||||
}
|
||||
SV_SaveLevelCache(false);
|
||||
for (i=0 ; i<sv.allocated_client_slots; i++)
|
||||
{
|
||||
svs.clients[i].q2edict->inuse = savedinuse[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
SV_SaveLevelCache(false);
|
||||
}
|
||||
|
||||
for (i=0 ; i<MAX_CLIENTS ; i++) //we need to drop all q2 clients. We don't mix q1w with q2.
|
||||
{
|
||||
|
|
|
@ -445,7 +445,9 @@ void SV_UnspawnServer (void) //terminate the running server.
|
|||
if (svs.clients[i].state)
|
||||
SV_DropClient(svs.clients+i);
|
||||
}
|
||||
|
||||
#ifdef Q2SERVER
|
||||
SVQ2_ShutdownGameProgs();
|
||||
#endif
|
||||
sv.worldmodel = NULL;
|
||||
sv.state = ss_dead;
|
||||
*sv.name = '\0';
|
||||
|
|
|
@ -292,7 +292,8 @@ void SV_DropClient (client_t *drop)
|
|||
return;
|
||||
}
|
||||
// add the disconnect
|
||||
MSG_WriteByte (&drop->netchan.message, drop->isq2client?svcq2_disconnect:svc_disconnect);
|
||||
if (drop->state != cs_zombie)
|
||||
MSG_WriteByte (&drop->netchan.message, drop->isq2client?svcq2_disconnect:svc_disconnect);
|
||||
|
||||
#ifdef SVRANKING
|
||||
if (drop->state == cs_spawned)
|
||||
|
@ -2701,6 +2702,8 @@ void SV_Impulse_f (void)
|
|||
Con_Printf("No empty player slots\n");
|
||||
return;
|
||||
}
|
||||
if (!svprogfuncs)
|
||||
return;
|
||||
|
||||
pr_global_struct->time = sv.time;
|
||||
|
||||
|
|
|
@ -666,7 +666,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
|||
}
|
||||
|
||||
//version does all the work now
|
||||
void SV_Multicast (vec3_t origin, multicast_t to)
|
||||
void VARGS SV_Multicast (vec3_t origin, multicast_t to)
|
||||
{
|
||||
SV_MulticastProtExt(origin, to, FULLDIMENSIONMASK, 0, 0);
|
||||
}
|
||||
|
|
|
@ -1195,7 +1195,14 @@ void SV_Begin_f (void)
|
|||
|
||||
for (split = host_client; split; split = split->controlled)
|
||||
{
|
||||
if (split->istobeloaded)
|
||||
#ifdef Q2SERVER
|
||||
if (ge)
|
||||
{
|
||||
ge->ClientBegin(split->q2edict);
|
||||
split->istobeloaded = false;
|
||||
}
|
||||
#endif
|
||||
else if (split->istobeloaded)
|
||||
{
|
||||
sendangles = true;
|
||||
split->istobeloaded = false;
|
||||
|
@ -1276,12 +1283,6 @@ void SV_Begin_f (void)
|
|||
host_client = oh;
|
||||
}
|
||||
}
|
||||
#ifdef Q2SERVER
|
||||
else
|
||||
{
|
||||
ge->ClientBegin(split->q2edict);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3705,15 +3706,6 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
|||
qboolean jumpable;
|
||||
extern cvar_t sv_gravity;
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (!svprogfuncs)
|
||||
{
|
||||
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)ucmd);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// DMW copied this KK hack copied from QuakeForge anti-cheat
|
||||
// (also extra inside parm on all SV_RunCmds that follow)
|
||||
|
@ -4381,6 +4373,12 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
|
|||
int seq_hash;
|
||||
int lastframe;
|
||||
|
||||
if (!ge)
|
||||
{
|
||||
Con_Printf("Q2 client without Q2 server\n");
|
||||
SV_DropClient(cl);
|
||||
}
|
||||
|
||||
// calc ping time
|
||||
frame = &cl->q2frames[cl->netchan.incoming_acknowledged & Q2UPDATE_MASK];
|
||||
|
||||
|
@ -4479,36 +4477,22 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
|
|||
|
||||
if (!sv.paused)
|
||||
{
|
||||
/*if (sv_nomsec.value)
|
||||
{
|
||||
cmd = newcmd;
|
||||
SV_ClientThink ();
|
||||
|
||||
cl->lastcmd = newcmd;
|
||||
cl->lastcmd.buttons = 0; // avoid multiple fires on lag
|
||||
break;
|
||||
}*/
|
||||
SV_PreRunCmd();
|
||||
|
||||
if (net_drop < 20)
|
||||
{
|
||||
while (net_drop > 2)
|
||||
{
|
||||
SV_RunCmd (&cl->lastcmd, false);
|
||||
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&cl->lastcmd);
|
||||
net_drop--;
|
||||
}
|
||||
if (net_drop > 1)
|
||||
SV_RunCmd (&oldest, false);
|
||||
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&oldest);
|
||||
if (net_drop > 0)
|
||||
SV_RunCmd (&oldcmd, false);
|
||||
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&oldcmd);
|
||||
}
|
||||
SV_RunCmd (&newcmd, false);
|
||||
|
||||
SV_PostRunCmd();
|
||||
ge->ClientThink (host_client->q2edict, (q2usercmd_t*)&newcmd);
|
||||
}
|
||||
|
||||
cl->lastcmd = newcmd;
|
||||
cl->lastcmd.buttons = 0; // avoid multiple fires on lag
|
||||
break;
|
||||
|
||||
case clcq2_userinfo:
|
||||
|
|
|
@ -10,11 +10,6 @@ qboolean SVQ2_InitGameProgs(void)
|
|||
#else
|
||||
game_export_t *ge;
|
||||
|
||||
int SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
|
||||
int maxcount, int areatype);
|
||||
|
||||
void SVQ2_LinkEdict(q2edict_t *ent);
|
||||
void SVQ2_UnlinkEdict(q2edict_t *ent);
|
||||
trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict);
|
||||
|
||||
|
||||
|
@ -31,7 +26,7 @@ PF_Unicast
|
|||
Sends the contents of the mutlicast buffer to a single client
|
||||
===============
|
||||
*/
|
||||
static void PFQ2_Unicast (q2edict_t *ent, qboolean reliable)
|
||||
static void VARGS PFQ2_Unicast (q2edict_t *ent, qboolean reliable)
|
||||
{
|
||||
int p;
|
||||
client_t *client;
|
||||
|
@ -172,7 +167,7 @@ PF_Configstring
|
|||
|
||||
===============
|
||||
*/
|
||||
static void PFQ2_Configstring (int i, char *val)
|
||||
static void VARGS PFQ2_Configstring (int i, char *val)
|
||||
{
|
||||
int j;
|
||||
if (i < 0 || i >= Q2MAX_CONFIGSTRINGS)
|
||||
|
@ -278,17 +273,17 @@ static int SVQ2_FindIndex (char *name, int start, int max, char *strings, int st
|
|||
}
|
||||
|
||||
|
||||
static int SVQ2_ModelIndex (char *name)
|
||||
static int VARGS SVQ2_ModelIndex (char *name)
|
||||
{
|
||||
return SVQ2_FindIndex (name, Q2CS_MODELS, Q2MAX_MODELS, sv.model_precache[1], sizeof(sv.model_precache[0]), true);
|
||||
}
|
||||
|
||||
static int SVQ2_SoundIndex (char *name)
|
||||
static int VARGS SVQ2_SoundIndex (char *name)
|
||||
{
|
||||
return SVQ2_FindIndex (name, Q2CS_SOUNDS, Q2MAX_SOUNDS, sv.sound_precache[1], sizeof(sv.sound_precache[0]), true);
|
||||
}
|
||||
|
||||
static int SVQ2_ImageIndex (char *name)
|
||||
static int VARGS SVQ2_ImageIndex (char *name)
|
||||
{
|
||||
return SVQ2_FindIndex (name, Q2CS_IMAGES, Q2MAX_IMAGES, sv.image_precache[1], sizeof(sv.image_precache[0]), true);
|
||||
}
|
||||
|
@ -300,7 +295,7 @@ PF_setmodel
|
|||
Also sets mins and maxs for inline bmodels
|
||||
=================
|
||||
*/
|
||||
static void PFQ2_setmodel (q2edict_t *ent, char *name)
|
||||
static void VARGS PFQ2_setmodel (q2edict_t *ent, char *name)
|
||||
{
|
||||
int i;
|
||||
model_t *mod;
|
||||
|
@ -335,18 +330,18 @@ static qboolean CMQ2_Q1BSP_SetAreaPortalState (int portalnum, qboolean open)
|
|||
return true;
|
||||
}*/
|
||||
|
||||
static void PFQ2_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
|
||||
static void PFQ2_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
|
||||
static void PFQ2_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
|
||||
static void PFQ2_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
|
||||
static void PFQ2_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
|
||||
static void PFQ2_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
|
||||
static void PFQ2_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
|
||||
static void PFQ2_WritePos (vec3_t pos) { MSG_WriteCoord (&sv.multicast, pos[0]);
|
||||
static void VARGS PFQ2_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
|
||||
static void VARGS PFQ2_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
|
||||
static void VARGS PFQ2_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
|
||||
static void VARGS PFQ2_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
|
||||
static void VARGS PFQ2_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
|
||||
static void VARGS PFQ2_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
|
||||
static void VARGS PFQ2_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
|
||||
static void VARGS PFQ2_WritePos (vec3_t pos) { MSG_WriteCoord (&sv.multicast, pos[0]);
|
||||
MSG_WriteCoord (&sv.multicast, pos[1]);
|
||||
MSG_WriteCoord (&sv.multicast, pos[2]);
|
||||
}
|
||||
static void PFQ2_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
|
||||
static void VARGS PFQ2_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -355,7 +350,7 @@ PF_inPVS
|
|||
Also checks portalareas so that doors block sight
|
||||
=================
|
||||
*/
|
||||
static qboolean PFQ2_inPVS (vec3_t p1, vec3_t p2)
|
||||
static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2)
|
||||
{
|
||||
int leafnum;
|
||||
int cluster;
|
||||
|
@ -385,7 +380,7 @@ PF_inPHS
|
|||
Also checks portalareas so that doors block sound
|
||||
=================
|
||||
*/
|
||||
static qboolean PFQ2_inPHS (vec3_t p1, vec3_t p2)
|
||||
static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
|
||||
{
|
||||
int leafnum;
|
||||
int cluster;
|
||||
|
@ -429,7 +424,7 @@ static qboolean PFQ2_inPHS (vec3_t p1, vec3_t p2)
|
|||
#define Q2CHAN_BODY 4*/
|
||||
#define Q2CHAN_RELIABLE 16
|
||||
|
||||
void SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
|
||||
void VARGS SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
|
||||
int soundindex, float volume,
|
||||
float attenuation, float timeofs)
|
||||
{
|
||||
|
@ -540,7 +535,7 @@ void SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
|
|||
}
|
||||
}
|
||||
|
||||
static void PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, float volume,
|
||||
static void VARGS PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, float volume,
|
||||
float attenuation, float timeofs)
|
||||
{
|
||||
if (!entity)
|
||||
|
@ -548,7 +543,7 @@ static void PFQ2_StartSound (q2edict_t *entity, int channel, int sound_num, floa
|
|||
SVQ2_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs);
|
||||
}
|
||||
|
||||
static q2trace_t SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passedict, int contentmask)
|
||||
static q2trace_t VARGS SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, q2edict_t *passedict, int contentmask)
|
||||
{
|
||||
q2trace_t ret;
|
||||
trace_t tr;
|
||||
|
@ -562,19 +557,19 @@ static q2trace_t SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int SVQ2_PointContents (vec3_t p)
|
||||
static int VARGS SVQ2_PointContents (vec3_t p)
|
||||
{
|
||||
q2trace_t tr = SVQ2_Trace(p, NULL, NULL, p, NULL, ~0);
|
||||
return tr.contents;
|
||||
// return CM_PointContents(p, 0);
|
||||
}
|
||||
|
||||
static cvar_t *Q2Cvar_Get (char *var_name, char *value, int flags)
|
||||
static cvar_t *VARGS Q2Cvar_Get (char *var_name, char *value, int flags)
|
||||
{
|
||||
return Cvar_Get(var_name, value, flags, "Quake2 game variables");
|
||||
}
|
||||
|
||||
cvar_t *Q2Cvar_Set (char *var_name, char *value)
|
||||
cvar_t *VARGS Q2Cvar_Set (char *var_name, char *value)
|
||||
{
|
||||
cvar_t *var = Cvar_FindVar(var_name);
|
||||
if (!var)
|
||||
|
@ -584,7 +579,7 @@ cvar_t *Q2Cvar_Set (char *var_name, char *value)
|
|||
}
|
||||
return Cvar_Set(var, value);
|
||||
}
|
||||
cvar_t *Q2Cvar_ForceSet (char *var_name, char *value)
|
||||
cvar_t *VARGS Q2Cvar_ForceSet (char *var_name, char *value)
|
||||
{
|
||||
cvar_t *var = Cvar_FindVar(var_name);
|
||||
if (!var)
|
||||
|
@ -605,7 +600,7 @@ Called when either the entire server is being killed, or
|
|||
it is changing to a different game directory.
|
||||
===============
|
||||
*/
|
||||
void SVQ2_ShutdownGameProgs (void)
|
||||
void VARGS SVQ2_ShutdownGameProgs (void)
|
||||
{
|
||||
if (!ge)
|
||||
return;
|
||||
|
@ -614,7 +609,7 @@ void SVQ2_ShutdownGameProgs (void)
|
|||
ge = NULL;
|
||||
}
|
||||
|
||||
static void AddCommandString(char *command)
|
||||
static void VARGS AddCommandString(char *command)
|
||||
{
|
||||
Cbuf_AddText(command, RESTRICT_LOCAL);
|
||||
}
|
||||
|
@ -627,15 +622,12 @@ Init the game subsystem for a new map
|
|||
===============
|
||||
*/
|
||||
|
||||
void Q2SCR_DebugGraph(float value, int color)
|
||||
void VARGS Q2SCR_DebugGraph(float value, int color)
|
||||
{return;}
|
||||
|
||||
void Q2_Pmove (q2pmove_t *pmove);
|
||||
|
||||
qboolean SVQ2_InitGameProgs(void)
|
||||
{
|
||||
static game_import_t import;
|
||||
|
||||
volatile static game_import_t import; //volatile because msvc sucks
|
||||
if (COM_CheckParm("-noq2dll"))
|
||||
{
|
||||
SVQ2_ShutdownGameProgs();
|
||||
|
@ -725,7 +717,7 @@ qboolean SVQ2_InitGameProgs(void)
|
|||
*/
|
||||
}
|
||||
|
||||
ge = (game_export_t *)Sys_GetGameAPI (&import);
|
||||
ge = (game_export_t *)Sys_GetGameAPI ((game_import_t*)&import);
|
||||
|
||||
if (!ge)
|
||||
return false;
|
||||
|
|
|
@ -644,7 +644,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
|
|||
|
||||
|
||||
#ifdef Q2SERVER
|
||||
void SVQ2_UnlinkEdict(q2edict_t *ent)
|
||||
void VARGS SVQ2_UnlinkEdict(q2edict_t *ent)
|
||||
{
|
||||
if (!ent->area.prev)
|
||||
return; // not linked in anywhere
|
||||
|
@ -652,7 +652,7 @@ void SVQ2_UnlinkEdict(q2edict_t *ent)
|
|||
ent->area.prev = ent->area.next = NULL;
|
||||
}
|
||||
|
||||
void SVQ2_LinkEdict(q2edict_t *ent)
|
||||
void VARGS SVQ2_LinkEdict(q2edict_t *ent)
|
||||
{
|
||||
areanode_t *node;
|
||||
int leafs[MAX_TOTAL_ENT_LEAFS];
|
||||
|
@ -1353,7 +1353,7 @@ void SVQ2_AreaEdicts_r (areanode_t *node)
|
|||
SVQ2_AreaEdicts_r ( node->children[1] );
|
||||
}
|
||||
|
||||
int SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
|
||||
int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list,
|
||||
int maxcount, int areatype)
|
||||
{
|
||||
area_mins = mins;
|
||||
|
|
Loading…
Reference in a new issue