mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-20 19:02:23 +00:00
Räume sv_game.c auf
This commit is contained in:
parent
ca69a68868
commit
c49f21c9d0
1 changed files with 268 additions and 249 deletions
|
@ -1,339 +1,353 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// sv_game.c -- interface to the game dll
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Interface between the server and the game module.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "header/server.h"
|
||||
|
||||
game_export_t *ge;
|
||||
|
||||
game_export_t *ge;
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_Unicast
|
||||
|
||||
Sends the contents of the mutlicast buffer to a single client
|
||||
===============
|
||||
*/
|
||||
void PF_Unicast (edict_t *ent, qboolean reliable)
|
||||
* Sends the contents of the mutlicast buffer to a single client
|
||||
*/
|
||||
void
|
||||
PF_Unicast ( edict_t *ent, qboolean reliable )
|
||||
{
|
||||
int p;
|
||||
client_t *client;
|
||||
int p;
|
||||
client_t *client;
|
||||
|
||||
if (!ent)
|
||||
if ( !ent )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p = NUM_FOR_EDICT(ent);
|
||||
if (p < 1 || p > maxclients->value)
|
||||
p = NUM_FOR_EDICT( ent );
|
||||
|
||||
if ( ( p < 1 ) || ( p > maxclients->value ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client = svs.clients + (p-1);
|
||||
client = svs.clients + ( p - 1 );
|
||||
|
||||
if (reliable)
|
||||
SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize);
|
||||
if ( reliable )
|
||||
{
|
||||
SZ_Write( &client->netchan.message, sv.multicast.data, sv.multicast.cursize );
|
||||
}
|
||||
else
|
||||
SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize);
|
||||
{
|
||||
SZ_Write( &client->datagram, sv.multicast.data, sv.multicast.cursize );
|
||||
}
|
||||
|
||||
SZ_Clear (&sv.multicast);
|
||||
SZ_Clear( &sv.multicast );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_dprintf
|
||||
|
||||
Debug print to server console
|
||||
===============
|
||||
*/
|
||||
void PF_dprintf (char *fmt, ...)
|
||||
* Debug print to server console
|
||||
*/
|
||||
void
|
||||
PF_dprintf ( char *fmt, ... )
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (msg, fmt, argptr);
|
||||
va_end (argptr);
|
||||
char msg [ 1024 ];
|
||||
va_list argptr;
|
||||
|
||||
Com_Printf ("%s", msg);
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( msg, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
Com_Printf( "%s", msg );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_cprintf
|
||||
|
||||
Print to a single client
|
||||
===============
|
||||
*/
|
||||
void PF_cprintf (edict_t *ent, int level, char *fmt, ...)
|
||||
* Print to a single client
|
||||
*/
|
||||
void
|
||||
PF_cprintf ( edict_t *ent, int level, char *fmt, ... )
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
int n;
|
||||
char msg [ 1024 ];
|
||||
va_list argptr;
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
if (ent)
|
||||
|
||||
if ( ent )
|
||||
{
|
||||
n = NUM_FOR_EDICT(ent);
|
||||
if (n < 1 || n > maxclients->value)
|
||||
Com_Error (ERR_DROP, "cprintf to a non-client");
|
||||
n = NUM_FOR_EDICT( ent );
|
||||
|
||||
if ( ( n < 1 ) || ( n > maxclients->value ) )
|
||||
{
|
||||
Com_Error( ERR_DROP, "cprintf to a non-client" );
|
||||
}
|
||||
}
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (msg, fmt, argptr);
|
||||
va_end (argptr);
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( msg, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
if (ent)
|
||||
SV_ClientPrintf (svs.clients+(n-1), level, "%s", msg);
|
||||
if ( ent )
|
||||
{
|
||||
SV_ClientPrintf( svs.clients + ( n - 1 ), level, "%s", msg );
|
||||
}
|
||||
else
|
||||
Com_Printf ("%s", msg);
|
||||
{
|
||||
Com_Printf( "%s", msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_centerprintf
|
||||
|
||||
centerprint to a single client
|
||||
===============
|
||||
*/
|
||||
void PF_centerprintf (edict_t *ent, char *fmt, ...)
|
||||
* centerprint to a single client
|
||||
*/
|
||||
void
|
||||
PF_centerprintf ( edict_t *ent, char *fmt, ... )
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
int n;
|
||||
|
||||
n = NUM_FOR_EDICT(ent);
|
||||
if (n < 1 || n > maxclients->value)
|
||||
return; // Com_Error (ERR_DROP, "centerprintf to a non-client");
|
||||
char msg [ 1024 ];
|
||||
va_list argptr;
|
||||
int n;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (msg, fmt, argptr);
|
||||
va_end (argptr);
|
||||
n = NUM_FOR_EDICT( ent );
|
||||
|
||||
MSG_WriteByte (&sv.multicast,svc_centerprint);
|
||||
MSG_WriteString (&sv.multicast,msg);
|
||||
PF_Unicast (ent, true);
|
||||
if ( ( n < 1 ) || ( n > maxclients->value ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( msg, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
MSG_WriteByte( &sv.multicast, svc_centerprint );
|
||||
MSG_WriteString( &sv.multicast, msg );
|
||||
PF_Unicast( ent, true );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_error
|
||||
|
||||
Abort the server with a game error
|
||||
===============
|
||||
*/
|
||||
void PF_error (char *fmt, ...)
|
||||
* Abort the server with a game error
|
||||
*/
|
||||
void
|
||||
PF_error ( char *fmt, ... )
|
||||
{
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsprintf (msg, fmt, argptr);
|
||||
va_end (argptr);
|
||||
char msg [ 1024 ];
|
||||
va_list argptr;
|
||||
|
||||
Com_Error (ERR_DROP, "Game Error: %s", msg);
|
||||
va_start( argptr, fmt );
|
||||
vsprintf( msg, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
Com_Error( ERR_DROP, "Game Error: %s", msg );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_setmodel
|
||||
|
||||
Also sets mins and maxs for inline bmodels
|
||||
=================
|
||||
*/
|
||||
void PF_setmodel (edict_t *ent, char *name)
|
||||
* Also sets mins and maxs for inline bmodels
|
||||
*/
|
||||
void
|
||||
PF_setmodel ( edict_t *ent, char *name )
|
||||
{
|
||||
int i;
|
||||
cmodel_t *mod;
|
||||
int i;
|
||||
cmodel_t *mod;
|
||||
|
||||
if (!name)
|
||||
Com_Error (ERR_DROP, "PF_setmodel: NULL");
|
||||
if ( !name )
|
||||
{
|
||||
Com_Error( ERR_DROP, "PF_setmodel: NULL" );
|
||||
}
|
||||
|
||||
i = SV_ModelIndex( name );
|
||||
|
||||
i = SV_ModelIndex (name);
|
||||
|
||||
ent->s.modelindex = i;
|
||||
|
||||
// if it is an inline model, get the size information for it
|
||||
if (name[0] == '*')
|
||||
/* if it is an inline model, get the size information for it */
|
||||
if ( name [ 0 ] == '*' )
|
||||
{
|
||||
mod = CM_InlineModel (name);
|
||||
VectorCopy (mod->mins, ent->mins);
|
||||
VectorCopy (mod->maxs, ent->maxs);
|
||||
SV_LinkEdict (ent);
|
||||
mod = CM_InlineModel( name );
|
||||
VectorCopy( mod->mins, ent->mins );
|
||||
VectorCopy( mod->maxs, ent->maxs );
|
||||
SV_LinkEdict( ent );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_Configstring
|
||||
|
||||
===============
|
||||
*/
|
||||
void PF_Configstring (int index, char *val)
|
||||
void
|
||||
PF_Configstring ( int index, char *val )
|
||||
{
|
||||
if (index < 0 || index >= MAX_CONFIGSTRINGS)
|
||||
Com_Error (ERR_DROP, "configstring: bad index %i\n", index);
|
||||
if ( ( index < 0 ) || ( index >= MAX_CONFIGSTRINGS ) )
|
||||
{
|
||||
Com_Error( ERR_DROP, "configstring: bad index %i\n", index );
|
||||
}
|
||||
|
||||
if (!val)
|
||||
if ( !val )
|
||||
{
|
||||
val = "";
|
||||
}
|
||||
|
||||
// change the string in sv
|
||||
strcpy (sv.configstrings[index], val);
|
||||
/* change the string in sv */
|
||||
strcpy( sv.configstrings [ index ], val );
|
||||
|
||||
|
||||
if (sv.state != ss_loading)
|
||||
{ // send the update to everyone
|
||||
SZ_Clear (&sv.multicast);
|
||||
MSG_WriteChar (&sv.multicast, svc_configstring);
|
||||
MSG_WriteShort (&sv.multicast, index);
|
||||
MSG_WriteString (&sv.multicast, val);
|
||||
if ( sv.state != ss_loading )
|
||||
{
|
||||
/* send the update to everyone */
|
||||
SZ_Clear( &sv.multicast );
|
||||
MSG_WriteChar( &sv.multicast, svc_configstring );
|
||||
MSG_WriteShort( &sv.multicast, index );
|
||||
MSG_WriteString( &sv.multicast, val );
|
||||
|
||||
SV_Multicast (vec3_origin, MULTICAST_ALL_R);
|
||||
SV_Multicast( vec3_origin, MULTICAST_ALL_R );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PF_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);}
|
||||
void PF_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);}
|
||||
void PF_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);}
|
||||
void PF_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);}
|
||||
void PF_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);}
|
||||
void PF_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);}
|
||||
void PF_WritePos (vec3_t pos) {MSG_WritePos (&sv.multicast, pos);}
|
||||
void PF_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);}
|
||||
void PF_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);}
|
||||
|
||||
void
|
||||
PF_WriteChar ( int c ) { MSG_WriteChar( &sv.multicast, c ); }
|
||||
void
|
||||
PF_WriteByte ( int c ) { MSG_WriteByte( &sv.multicast, c ); }
|
||||
void
|
||||
PF_WriteShort ( int c ) { MSG_WriteShort( &sv.multicast, c ); }
|
||||
void
|
||||
PF_WriteLong ( int c ) { MSG_WriteLong( &sv.multicast, c ); }
|
||||
void
|
||||
PF_WriteFloat ( float f ) { MSG_WriteFloat( &sv.multicast, f ); }
|
||||
void
|
||||
PF_WriteString ( char *s ) { MSG_WriteString( &sv.multicast, s ); }
|
||||
void
|
||||
PF_WritePos ( vec3_t pos ) { MSG_WritePos( &sv.multicast, pos ); }
|
||||
void
|
||||
PF_WriteDir ( vec3_t dir ) { MSG_WriteDir( &sv.multicast, dir ); }
|
||||
void
|
||||
PF_WriteAngle ( float f ) { MSG_WriteAngle( &sv.multicast, f ); }
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_inPVS
|
||||
|
||||
Also checks portalareas so that doors block sight
|
||||
=================
|
||||
*/
|
||||
qboolean PF_inPVS (vec3_t p1, vec3_t p2)
|
||||
* Also checks portalareas so that doors block sight
|
||||
*/
|
||||
qboolean
|
||||
PF_inPVS ( vec3_t p1, vec3_t p2 )
|
||||
{
|
||||
int leafnum;
|
||||
int cluster;
|
||||
int area1, area2;
|
||||
byte *mask;
|
||||
int leafnum;
|
||||
int cluster;
|
||||
int area1, area2;
|
||||
byte *mask;
|
||||
|
||||
leafnum = CM_PointLeafnum (p1);
|
||||
cluster = CM_LeafCluster (leafnum);
|
||||
area1 = CM_LeafArea (leafnum);
|
||||
mask = CM_ClusterPVS (cluster);
|
||||
leafnum = CM_PointLeafnum( p1 );
|
||||
cluster = CM_LeafCluster( leafnum );
|
||||
area1 = CM_LeafArea( leafnum );
|
||||
mask = CM_ClusterPVS( cluster );
|
||||
|
||||
leafnum = CM_PointLeafnum (p2);
|
||||
cluster = CM_LeafCluster (leafnum);
|
||||
area2 = CM_LeafArea (leafnum);
|
||||
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
|
||||
return false;
|
||||
if (!CM_AreasConnected (area1, area2))
|
||||
return false; // a door blocks sight
|
||||
return true;
|
||||
leafnum = CM_PointLeafnum( p2 );
|
||||
cluster = CM_LeafCluster( leafnum );
|
||||
area2 = CM_LeafArea( leafnum );
|
||||
|
||||
if ( mask && ( !( mask [ cluster >> 3 ] & ( 1 << ( cluster & 7 ) ) ) ) )
|
||||
{
|
||||
return ( false );
|
||||
}
|
||||
|
||||
if ( !CM_AreasConnected( area1, area2 ) )
|
||||
{
|
||||
return ( false ); /* a door blocks sight */
|
||||
}
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
PF_inPHS
|
||||
|
||||
Also checks portalareas so that doors block sound
|
||||
=================
|
||||
*/
|
||||
qboolean PF_inPHS (vec3_t p1, vec3_t p2)
|
||||
* Also checks portalareas so that doors block sound
|
||||
*/
|
||||
qboolean
|
||||
PF_inPHS ( vec3_t p1, vec3_t p2 )
|
||||
{
|
||||
int leafnum;
|
||||
int cluster;
|
||||
int area1, area2;
|
||||
byte *mask;
|
||||
int leafnum;
|
||||
int cluster;
|
||||
int area1, area2;
|
||||
byte *mask;
|
||||
|
||||
leafnum = CM_PointLeafnum (p1);
|
||||
cluster = CM_LeafCluster (leafnum);
|
||||
area1 = CM_LeafArea (leafnum);
|
||||
mask = CM_ClusterPHS (cluster);
|
||||
leafnum = CM_PointLeafnum( p1 );
|
||||
cluster = CM_LeafCluster( leafnum );
|
||||
area1 = CM_LeafArea( leafnum );
|
||||
mask = CM_ClusterPHS( cluster );
|
||||
|
||||
leafnum = CM_PointLeafnum (p2);
|
||||
cluster = CM_LeafCluster (leafnum);
|
||||
area2 = CM_LeafArea (leafnum);
|
||||
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
|
||||
return false; // more than one bounce away
|
||||
if (!CM_AreasConnected (area1, area2))
|
||||
return false; // a door blocks hearing
|
||||
leafnum = CM_PointLeafnum( p2 );
|
||||
cluster = CM_LeafCluster( leafnum );
|
||||
area2 = CM_LeafArea( leafnum );
|
||||
|
||||
return true;
|
||||
if ( mask && ( !( mask [ cluster >> 3 ] & ( 1 << ( cluster & 7 ) ) ) ) )
|
||||
{
|
||||
return ( false ); /* more than one bounce away */
|
||||
}
|
||||
|
||||
if ( !CM_AreasConnected( area1, area2 ) )
|
||||
{
|
||||
return ( false ); /* a door blocks hearing */
|
||||
}
|
||||
|
||||
return ( true );
|
||||
}
|
||||
|
||||
void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume,
|
||||
float attenuation, float timeofs)
|
||||
void
|
||||
PF_StartSound ( edict_t *entity, int channel, int sound_num, float volume, float attenuation, float timeofs )
|
||||
{
|
||||
if (!entity)
|
||||
if ( !entity )
|
||||
{
|
||||
return;
|
||||
SV_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs);
|
||||
}
|
||||
|
||||
SV_StartSound( NULL, entity, channel, sound_num, volume, attenuation, timeofs );
|
||||
}
|
||||
|
||||
//==============================================
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_ShutdownGameProgs
|
||||
|
||||
Called when either the entire server is being killed, or
|
||||
it is changing to a different game directory.
|
||||
===============
|
||||
*/
|
||||
void SV_ShutdownGameProgs (void)
|
||||
* Called when either the entire server is being killed, or
|
||||
* it is changing to a different game directory.
|
||||
*/
|
||||
void
|
||||
SV_ShutdownGameProgs ( void )
|
||||
{
|
||||
if (!ge)
|
||||
if ( !ge )
|
||||
{
|
||||
return;
|
||||
ge->Shutdown ();
|
||||
Sys_UnloadGame ();
|
||||
}
|
||||
|
||||
ge->Shutdown();
|
||||
Sys_UnloadGame();
|
||||
ge = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_InitGameProgs
|
||||
|
||||
Init the game subsystem for a new map
|
||||
===============
|
||||
*/
|
||||
* Init the game subsystem for a new map
|
||||
*/
|
||||
#ifndef DEDICATED_ONLY
|
||||
void SCR_DebugGraph (float value, int color);
|
||||
void SCR_DebugGraph ( float value, int color );
|
||||
|
||||
#endif
|
||||
|
||||
void SV_InitGameProgs (void)
|
||||
void
|
||||
SV_InitGameProgs ( void )
|
||||
{
|
||||
game_import_t import;
|
||||
game_import_t import;
|
||||
|
||||
// unload anything we have now
|
||||
if (ge)
|
||||
SV_ShutdownGameProgs ();
|
||||
/* unload anything we have now */
|
||||
if ( ge )
|
||||
{
|
||||
SV_ShutdownGameProgs();
|
||||
}
|
||||
|
||||
Com_Printf( "-------- game initialization -------\n" );
|
||||
|
||||
// load a new game dll
|
||||
/* load a new game dll */
|
||||
import.multicast = SV_Multicast;
|
||||
import.unicast = PF_Unicast;
|
||||
import.bprintf = SV_BroadcastPrintf;
|
||||
|
@ -386,20 +400,25 @@ void SV_InitGameProgs (void)
|
|||
#ifndef DEDICATED_ONLY
|
||||
import.DebugGraph = SCR_DebugGraph;
|
||||
#endif
|
||||
|
||||
|
||||
import.SetAreaPortalState = CM_SetAreaPortalState;
|
||||
import.AreasConnected = CM_AreasConnected;
|
||||
|
||||
ge = (game_export_t *)Sys_GetGameAPI (&import);
|
||||
ge = (game_export_t *) Sys_GetGameAPI( &import );
|
||||
|
||||
if (!ge)
|
||||
Com_Error (ERR_DROP, "failed to load game DLL");
|
||||
if (ge->apiversion != GAME_API_VERSION)
|
||||
Com_Error (ERR_DROP, "game is version %i, not %i", ge->apiversion,
|
||||
GAME_API_VERSION);
|
||||
if ( !ge )
|
||||
{
|
||||
Com_Error( ERR_DROP, "failed to load game DLL" );
|
||||
}
|
||||
|
||||
ge->Init ();
|
||||
if ( ge->apiversion != GAME_API_VERSION )
|
||||
{
|
||||
Com_Error( ERR_DROP, "game is version %i, not %i", ge->apiversion,
|
||||
GAME_API_VERSION );
|
||||
}
|
||||
|
||||
Com_Printf("------------------------------------\n\n");
|
||||
ge->Init();
|
||||
|
||||
Com_Printf( "------------------------------------\n\n" );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue