Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sv_game.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 // sv_game.c -- interface to the game dll
00023 
00024 #include "server.h"
00025 
00026 #include "../game/botlib.h"
00027 
00028 botlib_export_t *botlib_export;
00029 
00030 void SV_GameError( const char *string ) {
00031     Com_Error( ERR_DROP, "%s", string );
00032 }
00033 
00034 void SV_GamePrint( const char *string ) {
00035     Com_Printf( "%s", string );
00036 }
00037 
00038 // these functions must be used instead of pointer arithmetic, because
00039 // the game allocates gentities with private information after the server shared part
00040 int SV_NumForGentity( sharedEntity_t *ent ) {
00041     int     num;
00042 
00043     num = ( (byte *)ent - (byte *)sv.gentities ) / sv.gentitySize;
00044 
00045     return num;
00046 }
00047 
00048 sharedEntity_t *SV_GentityNum( int num ) {
00049     sharedEntity_t *ent;
00050 
00051     ent = (sharedEntity_t *)((byte *)sv.gentities + sv.gentitySize*(num));
00052 
00053     return ent;
00054 }
00055 
00056 playerState_t *SV_GameClientNum( int num ) {
00057     playerState_t   *ps;
00058 
00059     ps = (playerState_t *)((byte *)sv.gameClients + sv.gameClientSize*(num));
00060 
00061     return ps;
00062 }
00063 
00064 svEntity_t  *SV_SvEntityForGentity( sharedEntity_t *gEnt ) {
00065     if ( !gEnt || gEnt->s.number < 0 || gEnt->s.number >= MAX_GENTITIES ) {
00066         Com_Error( ERR_DROP, "SV_SvEntityForGentity: bad gEnt" );
00067     }
00068     return &sv.svEntities[ gEnt->s.number ];
00069 }
00070 
00071 sharedEntity_t *SV_GEntityForSvEntity( svEntity_t *svEnt ) {
00072     int     num;
00073 
00074     num = svEnt - sv.svEntities;
00075     return SV_GentityNum( num );
00076 }
00077 
00078 /*
00079 ===============
00080 SV_GameSendServerCommand
00081 
00082 Sends a command string to a client
00083 ===============
00084 */
00085 void SV_GameSendServerCommand( int clientNum, const char *text ) {
00086     if ( clientNum == -1 ) {
00087         SV_SendServerCommand( NULL, "%s", text );
00088     } else {
00089         if ( clientNum < 0 || clientNum >= sv_maxclients->integer ) {
00090             return;
00091         }
00092         SV_SendServerCommand( svs.clients + clientNum, "%s", text );    
00093     }
00094 }
00095 
00096 
00097 /*
00098 ===============
00099 SV_GameDropClient
00100 
00101 Disconnects the client with a message
00102 ===============
00103 */
00104 void SV_GameDropClient( int clientNum, const char *reason ) {
00105     if ( clientNum < 0 || clientNum >= sv_maxclients->integer ) {
00106         return;
00107     }
00108     SV_DropClient( svs.clients + clientNum, reason );   
00109 }
00110 
00111 
00112 /*
00113 =================
00114 SV_SetBrushModel
00115 
00116 sets mins and maxs for inline bmodels
00117 =================
00118 */
00119 void SV_SetBrushModel( sharedEntity_t *ent, const char *name ) {
00120     clipHandle_t    h;
00121     vec3_t          mins, maxs;
00122 
00123     if (!name) {
00124         Com_Error( ERR_DROP, "SV_SetBrushModel: NULL" );
00125     }
00126 
00127     if (name[0] != '*') {
00128         Com_Error( ERR_DROP, "SV_SetBrushModel: %s isn't a brush model", name );
00129     }
00130 
00131 
00132     ent->s.modelindex = atoi( name + 1 );
00133 
00134     h = CM_InlineModel( ent->s.modelindex );
00135     CM_ModelBounds( h, mins, maxs );
00136     VectorCopy (mins, ent->r.mins);
00137     VectorCopy (maxs, ent->r.maxs);
00138     ent->r.bmodel = qtrue;
00139 
00140     ent->r.contents = -1;       // we don't know exactly what is in the brushes
00141 
00142     SV_LinkEntity( ent );       // FIXME: remove
00143 }
00144 
00145 
00146 
00147 /*
00148 =================
00149 SV_inPVS
00150 
00151 Also checks portalareas so that doors block sight
00152 =================
00153 */
00154 qboolean SV_inPVS (const vec3_t p1, const vec3_t p2)
00155 {
00156     int     leafnum;
00157     int     cluster;
00158     int     area1, area2;
00159     byte    *mask;
00160 
00161     leafnum = CM_PointLeafnum (p1);
00162     cluster = CM_LeafCluster (leafnum);
00163     area1 = CM_LeafArea (leafnum);
00164     mask = CM_ClusterPVS (cluster);
00165 
00166     leafnum = CM_PointLeafnum (p2);
00167     cluster = CM_LeafCluster (leafnum);
00168     area2 = CM_LeafArea (leafnum);
00169     if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
00170         return qfalse;
00171     if (!CM_AreasConnected (area1, area2))
00172         return qfalse;      // a door blocks sight
00173     return qtrue;
00174 }
00175 
00176 
00177 /*
00178 =================
00179 SV_inPVSIgnorePortals
00180 
00181 Does NOT check portalareas
00182 =================
00183 */
00184 qboolean SV_inPVSIgnorePortals( const vec3_t p1, const vec3_t p2)
00185 {
00186     int     leafnum;
00187     int     cluster;
00188     int     area1, area2;
00189     byte    *mask;
00190 
00191     leafnum = CM_PointLeafnum (p1);
00192     cluster = CM_LeafCluster (leafnum);
00193     area1 = CM_LeafArea (leafnum);
00194     mask = CM_ClusterPVS (cluster);
00195 
00196     leafnum = CM_PointLeafnum (p2);
00197     cluster = CM_LeafCluster (leafnum);
00198     area2 = CM_LeafArea (leafnum);
00199 
00200     if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
00201         return qfalse;
00202 
00203     return qtrue;
00204 }
00205 
00206 
00207 /*
00208 ========================
00209 SV_AdjustAreaPortalState
00210 ========================
00211 */
00212 void SV_AdjustAreaPortalState( sharedEntity_t *ent, qboolean open ) {
00213     svEntity_t  *svEnt;
00214 
00215     svEnt = SV_SvEntityForGentity( ent );
00216     if ( svEnt->areanum2 == -1 ) {
00217         return;
00218     }
00219     CM_AdjustAreaPortalState( svEnt->areanum, svEnt->areanum2, open );
00220 }
00221 
00222 
00223 /*
00224 ==================
00225 SV_GameAreaEntities
00226 ==================
00227 */
00228 qboolean    SV_EntityContact( vec3_t mins, vec3_t maxs, const sharedEntity_t *gEnt, int capsule ) {
00229     const float *origin, *angles;
00230     clipHandle_t    ch;
00231     trace_t         trace;
00232 
00233     // check for exact collision
00234     origin = gEnt->r.currentOrigin;
00235     angles = gEnt->r.currentAngles;
00236 
00237     ch = SV_ClipHandleForEntity( gEnt );
00238     CM_TransformedBoxTrace ( &trace, vec3_origin, vec3_origin, mins, maxs,
00239         ch, -1, origin, angles, capsule );
00240 
00241     return trace.startsolid;
00242 }
00243 
00244 
00245 /*
00246 ===============
00247 SV_GetServerinfo
00248 
00249 ===============
00250 */
00251 void SV_GetServerinfo( char *buffer, int bufferSize ) {
00252     if ( bufferSize < 1 ) {
00253         Com_Error( ERR_DROP, "SV_GetServerinfo: bufferSize == %i", bufferSize );
00254     }
00255     Q_strncpyz( buffer, Cvar_InfoString( CVAR_SERVERINFO ), bufferSize );
00256 }
00257 
00258 /*
00259 ===============
00260 SV_LocateGameData
00261 
00262 ===============
00263 */
00264 void SV_LocateGameData( sharedEntity_t *gEnts, int numGEntities, int sizeofGEntity_t,
00265                        playerState_t *clients, int sizeofGameClient ) {
00266     sv.gentities = gEnts;
00267     sv.gentitySize = sizeofGEntity_t;
00268     sv.num_entities = numGEntities;
00269 
00270     sv.gameClients = clients;
00271     sv.gameClientSize = sizeofGameClient;
00272 }
00273 
00274 
00275 /*
00276 ===============
00277 SV_GetUsercmd
00278 
00279 ===============
00280 */
00281 void SV_GetUsercmd( int clientNum, usercmd_t *cmd ) {
00282     if ( clientNum < 0 || clientNum >= sv_maxclients->integer ) {
00283         Com_Error( ERR_DROP, "SV_GetUsercmd: bad clientNum:%i", clientNum );
00284     }
00285     *cmd = svs.clients[clientNum].lastUsercmd;
00286 }
00287 
00288 //==============================================
00289 
00290 static int  FloatAsInt( float f ) {
00291     union
00292     {
00293         int i;
00294         float f;
00295     } temp;
00296     
00297     temp.f = f;
00298     return temp.i;
00299 }
00300 
00301 /*
00302 ====================
00303 SV_GameSystemCalls
00304 
00305 The module is making a system call
00306 ====================
00307 */
00308 //rcg010207 - see my comments in VM_DllSyscall(), in qcommon/vm.c ...
00309 #if ((defined __linux__) && (defined __powerpc__))
00310 #define VMA(x) ((void *) args[x])
00311 #else
00312 #define VMA(x) VM_ArgPtr(args[x])
00313 #endif
00314 
00315 #define VMF(x)  ((float *)args)[x]
00316 
00317 int SV_GameSystemCalls( int *args ) {
00318     switch( args[0] ) {
00319     case G_PRINT:
00320         Com_Printf( "%s", VMA(1) );
00321         return 0;
00322     case G_ERROR:
00323         Com_Error( ERR_DROP, "%s", VMA(1) );
00324         return 0;
00325     case G_MILLISECONDS:
00326         return Sys_Milliseconds();
00327     case G_CVAR_REGISTER:
00328         Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] ); 
00329         return 0;
00330     case G_CVAR_UPDATE:
00331         Cvar_Update( VMA(1) );
00332         return 0;
00333     case G_CVAR_SET:
00334         Cvar_Set( (const char *)VMA(1), (const char *)VMA(2) );
00335         return 0;
00336     case G_CVAR_VARIABLE_INTEGER_VALUE:
00337         return Cvar_VariableIntegerValue( (const char *)VMA(1) );
00338     case G_CVAR_VARIABLE_STRING_BUFFER:
00339         Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
00340         return 0;
00341     case G_ARGC:
00342         return Cmd_Argc();
00343     case G_ARGV:
00344         Cmd_ArgvBuffer( args[1], VMA(2), args[3] );
00345         return 0;
00346     case G_SEND_CONSOLE_COMMAND:
00347         Cbuf_ExecuteText( args[1], VMA(2) );
00348         return 0;
00349 
00350     case G_FS_FOPEN_FILE:
00351         return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
00352     case G_FS_READ:
00353         FS_Read2( VMA(1), args[2], args[3] );
00354         return 0;
00355     case G_FS_WRITE:
00356         FS_Write( VMA(1), args[2], args[3] );
00357         return 0;
00358     case G_FS_FCLOSE_FILE:
00359         FS_FCloseFile( args[1] );
00360         return 0;
00361     case G_FS_GETFILELIST:
00362         return FS_GetFileList( VMA(1), VMA(2), VMA(3), args[4] );
00363     case G_FS_SEEK:
00364         return FS_Seek( args[1], args[2], args[3] );
00365 
00366     case G_LOCATE_GAME_DATA:
00367         SV_LocateGameData( VMA(1), args[2], args[3], VMA(4), args[5] );
00368         return 0;
00369     case G_DROP_CLIENT:
00370         SV_GameDropClient( args[1], VMA(2) );
00371         return 0;
00372     case G_SEND_SERVER_COMMAND:
00373         SV_GameSendServerCommand( args[1], VMA(2) );
00374         return 0;
00375     case G_LINKENTITY:
00376         SV_LinkEntity( VMA(1) );
00377         return 0;
00378     case G_UNLINKENTITY:
00379         SV_UnlinkEntity( VMA(1) );
00380         return 0;
00381     case G_ENTITIES_IN_BOX:
00382         return SV_AreaEntities( VMA(1), VMA(2), VMA(3), args[4] );
00383     case G_ENTITY_CONTACT:
00384         return SV_EntityContact( VMA(1), VMA(2), VMA(3), /*int capsule*/ qfalse );
00385     case G_ENTITY_CONTACTCAPSULE:
00386         return SV_EntityContact( VMA(1), VMA(2), VMA(3), /*int capsule*/ qtrue );
00387     case G_TRACE:
00388         SV_Trace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse );
00389         return 0;
00390     case G_TRACECAPSULE:
00391         SV_Trace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue );
00392         return 0;
00393     case G_POINT_CONTENTS:
00394         return SV_PointContents( VMA(1), args[2] );
00395     case G_SET_BRUSH_MODEL:
00396         SV_SetBrushModel( VMA(1), VMA(2) );
00397         return 0;
00398     case G_IN_PVS:
00399         return SV_inPVS( VMA(1), VMA(2) );
00400     case G_IN_PVS_IGNORE_PORTALS:
00401         return SV_inPVSIgnorePortals( VMA(1), VMA(2) );
00402 
00403     case G_SET_CONFIGSTRING:
00404         SV_SetConfigstring( args[1], VMA(2) );
00405         return 0;
00406     case G_GET_CONFIGSTRING:
00407         SV_GetConfigstring( args[1], VMA(2), args[3] );
00408         return 0;
00409     case G_SET_USERINFO:
00410         SV_SetUserinfo( args[1], VMA(2) );
00411         return 0;
00412     case G_GET_USERINFO:
00413         SV_GetUserinfo( args[1], VMA(2), args[3] );
00414         return 0;
00415     case G_GET_SERVERINFO:
00416         SV_GetServerinfo( VMA(1), args[2] );
00417         return 0;
00418     case G_ADJUST_AREA_PORTAL_STATE:
00419         SV_AdjustAreaPortalState( VMA(1), args[2] );
00420         return 0;
00421     case G_AREAS_CONNECTED:
00422         return CM_AreasConnected( args[1], args[2] );
00423 
00424     case G_BOT_ALLOCATE_CLIENT:
00425         return SV_BotAllocateClient();
00426     case G_BOT_FREE_CLIENT:
00427         SV_BotFreeClient( args[1] );
00428         return 0;
00429 
00430     case G_GET_USERCMD:
00431         SV_GetUsercmd( args[1], VMA(2) );
00432         return 0;
00433     case G_GET_ENTITY_TOKEN:
00434         {
00435             const char  *s;
00436 
00437             s = COM_Parse( &sv.entityParsePoint );
00438             Q_strncpyz( VMA(1), s, args[2] );
00439             if ( !sv.entityParsePoint && !s[0] ) {
00440                 return qfalse;
00441             } else {
00442                 return qtrue;
00443             }
00444         }
00445 
00446     case G_DEBUG_POLYGON_CREATE:
00447         return BotImport_DebugPolygonCreate( args[1], args[2], VMA(3) );
00448     case G_DEBUG_POLYGON_DELETE:
00449         BotImport_DebugPolygonDelete( args[1] );
00450         return 0;
00451     case G_REAL_TIME:
00452         return Com_RealTime( VMA(1) );
00453     case G_SNAPVECTOR:
00454         Sys_SnapVector( VMA(1) );
00455         return 0;
00456 
00457         //====================================
00458 
00459     case BOTLIB_SETUP:
00460         return SV_BotLibSetup();
00461     case BOTLIB_SHUTDOWN:
00462         return SV_BotLibShutdown();
00463     case BOTLIB_LIBVAR_SET:
00464         return botlib_export->BotLibVarSet( VMA(1), VMA(2) );
00465     case BOTLIB_LIBVAR_GET:
00466         return botlib_export->BotLibVarGet( VMA(1), VMA(2), args[3] );
00467 
00468     case BOTLIB_PC_ADD_GLOBAL_DEFINE:
00469         return botlib_export->PC_AddGlobalDefine( VMA(1) );
00470     case BOTLIB_PC_LOAD_SOURCE:
00471         return botlib_export->PC_LoadSourceHandle( VMA(1) );
00472     case BOTLIB_PC_FREE_SOURCE:
00473         return botlib_export->PC_FreeSourceHandle( args[1] );
00474     case BOTLIB_PC_READ_TOKEN:
00475         return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
00476     case BOTLIB_PC_SOURCE_FILE_AND_LINE:
00477         return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );
00478 
00479     case BOTLIB_START_FRAME:
00480         return botlib_export->BotLibStartFrame( VMF(1) );
00481     case BOTLIB_LOAD_MAP:
00482         return botlib_export->BotLibLoadMap( VMA(1) );
00483     case BOTLIB_UPDATENTITY:
00484         return botlib_export->BotLibUpdateEntity( args[1], VMA(2) );
00485     case BOTLIB_TEST:
00486         return botlib_export->Test( args[1], VMA(2), VMA(3), VMA(4) );
00487 
00488     case BOTLIB_GET_SNAPSHOT_ENTITY:
00489         return SV_BotGetSnapshotEntity( args[1], args[2] );
00490     case BOTLIB_GET_CONSOLE_MESSAGE:
00491         return SV_BotGetConsoleMessage( args[1], VMA(2), args[3] );
00492     case BOTLIB_USER_COMMAND:
00493         SV_ClientThink( &svs.clients[args[1]], VMA(2) );
00494         return 0;
00495 
00496     case BOTLIB_AAS_BBOX_AREAS:
00497         return botlib_export->aas.AAS_BBoxAreas( VMA(1), VMA(2), VMA(3), args[4] );
00498     case BOTLIB_AAS_AREA_INFO:
00499         return botlib_export->aas.AAS_AreaInfo( args[1], VMA(2) );
00500     case BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL:
00501         return botlib_export->aas.AAS_AlternativeRouteGoals( VMA(1), args[2], VMA(3), args[4], args[5], VMA(6), args[7], args[8] );
00502     case BOTLIB_AAS_ENTITY_INFO:
00503         botlib_export->aas.AAS_EntityInfo( args[1], VMA(2) );
00504         return 0;
00505 
00506     case BOTLIB_AAS_INITIALIZED:
00507         return botlib_export->aas.AAS_Initialized();
00508     case BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX:
00509         botlib_export->aas.AAS_PresenceTypeBoundingBox( args[1], VMA(2), VMA(3) );
00510         return 0;
00511     case BOTLIB_AAS_TIME:
00512         return FloatAsInt( botlib_export->aas.AAS_Time() );
00513 
00514     case BOTLIB_AAS_POINT_AREA_NUM:
00515         return botlib_export->aas.AAS_PointAreaNum( VMA(1) );
00516     case BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX:
00517         return botlib_export->aas.AAS_PointReachabilityAreaIndex( VMA(1) );
00518     case BOTLIB_AAS_TRACE_AREAS:
00519         return botlib_export->aas.AAS_TraceAreas( VMA(1), VMA(2), VMA(3), VMA(4), args[5] );
00520 
00521     case BOTLIB_AAS_POINT_CONTENTS:
00522         return botlib_export->aas.AAS_PointContents( VMA(1) );
00523     case BOTLIB_AAS_NEXT_BSP_ENTITY:
00524         return botlib_export->aas.AAS_NextBSPEntity( args[1] );
00525     case BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY:
00526         return botlib_export->aas.AAS_ValueForBSPEpairKey( args[1], VMA(2), VMA(3), args[4] );
00527     case BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY:
00528         return botlib_export->aas.AAS_VectorForBSPEpairKey( args[1], VMA(2), VMA(3) );
00529     case BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY:
00530         return botlib_export->aas.AAS_FloatForBSPEpairKey( args[1], VMA(2), VMA(3) );
00531     case BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY:
00532         return botlib_export->aas.AAS_IntForBSPEpairKey( args[1], VMA(2), VMA(3) );
00533 
00534     case BOTLIB_AAS_AREA_REACHABILITY:
00535         return botlib_export->aas.AAS_AreaReachability( args[1] );
00536 
00537     case BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA:
00538         return botlib_export->aas.AAS_AreaTravelTimeToGoalArea( args[1], VMA(2), args[3], args[4] );
00539     case BOTLIB_AAS_ENABLE_ROUTING_AREA:
00540         return botlib_export->aas.AAS_EnableRoutingArea( args[1], args[2] );
00541     case BOTLIB_AAS_PREDICT_ROUTE:
00542         return botlib_export->aas.AAS_PredictRoute( VMA(1), args[2], VMA(3), args[4], args[5], args[6], args[7], args[8], args[9], args[10], args[11] );
00543 
00544     case BOTLIB_AAS_SWIMMING:
00545         return botlib_export->aas.AAS_Swimming( VMA(1) );
00546     case BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT:
00547         return botlib_export->aas.AAS_PredictClientMovement( VMA(1), args[2], VMA(3), args[4], args[5],
00548             VMA(6), VMA(7), args[8], args[9], VMF(10), args[11], args[12], args[13] );
00549 
00550     case BOTLIB_EA_SAY:
00551         botlib_export->ea.EA_Say( args[1], VMA(2) );
00552         return 0;
00553     case BOTLIB_EA_SAY_TEAM:
00554         botlib_export->ea.EA_SayTeam( args[1], VMA(2) );
00555         return 0;
00556     case BOTLIB_EA_COMMAND:
00557         botlib_export->ea.EA_Command( args[1], VMA(2) );
00558         return 0;
00559 
00560     case BOTLIB_EA_ACTION:
00561         botlib_export->ea.EA_Action( args[1], args[2] );
00562         break;
00563     case BOTLIB_EA_GESTURE:
00564         botlib_export->ea.EA_Gesture( args[1] );
00565         return 0;
00566     case BOTLIB_EA_TALK:
00567         botlib_export->ea.EA_Talk( args[1] );
00568         return 0;
00569     case BOTLIB_EA_ATTACK:
00570         botlib_export->ea.EA_Attack( args[1] );
00571         return 0;
00572     case BOTLIB_EA_USE:
00573         botlib_export->ea.EA_Use( args[1] );
00574         return 0;
00575     case BOTLIB_EA_RESPAWN:
00576         botlib_export->ea.EA_Respawn( args[1] );
00577         return 0;
00578     case BOTLIB_EA_CROUCH:
00579         botlib_export->ea.EA_Crouch( args[1] );
00580         return 0;
00581     case BOTLIB_EA_MOVE_UP:
00582         botlib_export->ea.EA_MoveUp( args[1] );
00583         return 0;
00584     case BOTLIB_EA_MOVE_DOWN:
00585         botlib_export->ea.EA_MoveDown( args[1] );
00586         return 0;
00587     case BOTLIB_EA_MOVE_FORWARD:
00588         botlib_export->ea.EA_MoveForward( args[1] );
00589         return 0;
00590     case BOTLIB_EA_MOVE_BACK:
00591         botlib_export->ea.EA_MoveBack( args[1] );
00592         return 0;
00593     case BOTLIB_EA_MOVE_LEFT:
00594         botlib_export->ea.EA_MoveLeft( args[1] );
00595         return 0;
00596     case BOTLIB_EA_MOVE_RIGHT:
00597         botlib_export->ea.EA_MoveRight( args[1] );
00598         return 0;
00599 
00600     case BOTLIB_EA_SELECT_WEAPON:
00601         botlib_export->ea.EA_SelectWeapon( args[1], args[2] );
00602         return 0;
00603     case BOTLIB_EA_JUMP:
00604         botlib_export->ea.EA_Jump( args[1] );
00605         return 0;
00606     case BOTLIB_EA_DELAYED_JUMP:
00607         botlib_export->ea.EA_DelayedJump( args[1] );
00608         return 0;
00609     case BOTLIB_EA_MOVE:
00610         botlib_export->ea.EA_Move( args[1], VMA(2), VMF(3) );
00611         return 0;
00612     case BOTLIB_EA_VIEW:
00613         botlib_export->ea.EA_View( args[1], VMA(2) );
00614         return 0;
00615 
00616     case BOTLIB_EA_END_REGULAR:
00617         botlib_export->ea.EA_EndRegular( args[1], VMF(2) );
00618         return 0;
00619     case BOTLIB_EA_GET_INPUT:
00620         botlib_export->ea.EA_GetInput( args[1], VMF(2), VMA(3) );
00621         return 0;
00622     case BOTLIB_EA_RESET_INPUT:
00623         botlib_export->ea.EA_ResetInput( args[1] );
00624         return 0;
00625 
00626     case BOTLIB_AI_LOAD_CHARACTER:
00627         return botlib_export->ai.BotLoadCharacter( VMA(1), VMF(2) );
00628     case BOTLIB_AI_FREE_CHARACTER:
00629         botlib_export->ai.BotFreeCharacter( args[1] );
00630         return 0;
00631     case BOTLIB_AI_CHARACTERISTIC_FLOAT:
00632         return FloatAsInt( botlib_export->ai.Characteristic_Float( args[1], args[2] ) );
00633     case BOTLIB_AI_CHARACTERISTIC_BFLOAT:
00634         return FloatAsInt( botlib_export->ai.Characteristic_BFloat( args[1], args[2], VMF(3), VMF(4) ) );
00635     case BOTLIB_AI_CHARACTERISTIC_INTEGER:
00636         return botlib_export->ai.Characteristic_Integer( args[1], args[2] );
00637     case BOTLIB_AI_CHARACTERISTIC_BINTEGER:
00638         return botlib_export->ai.Characteristic_BInteger( args[1], args[2], args[3], args[4] );
00639     case BOTLIB_AI_CHARACTERISTIC_STRING:
00640         botlib_export->ai.Characteristic_String( args[1], args[2], VMA(3), args[4] );
00641         return 0;
00642 
00643     case BOTLIB_AI_ALLOC_CHAT_STATE:
00644         return botlib_export->ai.BotAllocChatState();
00645     case BOTLIB_AI_FREE_CHAT_STATE:
00646         botlib_export->ai.BotFreeChatState( args[1] );
00647         return 0;
00648     case BOTLIB_AI_QUEUE_CONSOLE_MESSAGE:
00649         botlib_export->ai.BotQueueConsoleMessage( args[1], args[2], VMA(3) );
00650         return 0;
00651     case BOTLIB_AI_REMOVE_CONSOLE_MESSAGE:
00652         botlib_export->ai.BotRemoveConsoleMessage( args[1], args[2] );
00653         return 0;
00654     case BOTLIB_AI_NEXT_CONSOLE_MESSAGE:
00655         return botlib_export->ai.BotNextConsoleMessage( args[1], VMA(2) );
00656     case BOTLIB_AI_NUM_CONSOLE_MESSAGE:
00657         return botlib_export->ai.BotNumConsoleMessages( args[1] );
00658     case BOTLIB_AI_INITIAL_CHAT:
00659         botlib_export->ai.BotInitialChat( args[1], VMA(2), args[3], VMA(4), VMA(5), VMA(6), VMA(7), VMA(8), VMA(9), VMA(10), VMA(11) );
00660         return 0;
00661     case BOTLIB_AI_NUM_INITIAL_CHATS:
00662         return botlib_export->ai.BotNumInitialChats( args[1], VMA(2) );
00663     case BOTLIB_AI_REPLY_CHAT:
00664         return botlib_export->ai.BotReplyChat( args[1], VMA(2), args[3], args[4], VMA(5), VMA(6), VMA(7), VMA(8), VMA(9), VMA(10), VMA(11), VMA(12) );
00665     case BOTLIB_AI_CHAT_LENGTH:
00666         return botlib_export->ai.BotChatLength( args[1] );
00667     case BOTLIB_AI_ENTER_CHAT:
00668         botlib_export->ai.BotEnterChat( args[1], args[2], args[3] );
00669         return 0;
00670     case BOTLIB_AI_GET_CHAT_MESSAGE:
00671         botlib_export->ai.BotGetChatMessage( args[1], VMA(2), args[3] );
00672         return 0;
00673     case BOTLIB_AI_STRING_CONTAINS:
00674         return botlib_export->ai.StringContains( VMA(1), VMA(2), args[3] );
00675     case BOTLIB_AI_FIND_MATCH:
00676         return botlib_export->ai.BotFindMatch( VMA(1), VMA(2), args[3] );
00677     case BOTLIB_AI_MATCH_VARIABLE:
00678         botlib_export->ai.BotMatchVariable( VMA(1), args[2], VMA(3), args[4] );
00679         return 0;
00680     case BOTLIB_AI_UNIFY_WHITE_SPACES:
00681         botlib_export->ai.UnifyWhiteSpaces( VMA(1) );
00682         return 0;
00683     case BOTLIB_AI_REPLACE_SYNONYMS:
00684         botlib_export->ai.BotReplaceSynonyms( VMA(1), args[2] );
00685         return 0;
00686     case BOTLIB_AI_LOAD_CHAT_FILE:
00687         return botlib_export->ai.BotLoadChatFile( args[1], VMA(2), VMA(3) );
00688     case BOTLIB_AI_SET_CHAT_GENDER:
00689         botlib_export->ai.BotSetChatGender( args[1], args[2] );
00690         return 0;
00691     case BOTLIB_AI_SET_CHAT_NAME:
00692         botlib_export->ai.BotSetChatName( args[1], VMA(2), args[3] );
00693         return 0;
00694 
00695     case BOTLIB_AI_RESET_GOAL_STATE:
00696         botlib_export->ai.BotResetGoalState( args[1] );
00697         return 0;
00698     case BOTLIB_AI_RESET_AVOID_GOALS:
00699         botlib_export->ai.BotResetAvoidGoals( args[1] );
00700         return 0;
00701     case BOTLIB_AI_REMOVE_FROM_AVOID_GOALS:
00702         botlib_export->ai.BotRemoveFromAvoidGoals( args[1], args[2] );
00703         return 0;
00704     case BOTLIB_AI_PUSH_GOAL:
00705         botlib_export->ai.BotPushGoal( args[1], VMA(2) );
00706         return 0;
00707     case BOTLIB_AI_POP_GOAL:
00708         botlib_export->ai.BotPopGoal( args[1] );
00709         return 0;
00710     case BOTLIB_AI_EMPTY_GOAL_STACK:
00711         botlib_export->ai.BotEmptyGoalStack( args[1] );
00712         return 0;
00713     case BOTLIB_AI_DUMP_AVOID_GOALS:
00714         botlib_export->ai.BotDumpAvoidGoals( args[1] );
00715         return 0;
00716     case BOTLIB_AI_DUMP_GOAL_STACK:
00717         botlib_export->ai.BotDumpGoalStack( args[1] );
00718         return 0;
00719     case BOTLIB_AI_GOAL_NAME:
00720         botlib_export->ai.BotGoalName( args[1], VMA(2), args[3] );
00721         return 0;
00722     case BOTLIB_AI_GET_TOP_GOAL:
00723         return botlib_export->ai.BotGetTopGoal( args[1], VMA(2) );
00724     case BOTLIB_AI_GET_SECOND_GOAL:
00725         return botlib_export->ai.BotGetSecondGoal( args[1], VMA(2) );
00726     case BOTLIB_AI_CHOOSE_LTG_ITEM:
00727         return botlib_export->ai.BotChooseLTGItem( args[1], VMA(2), VMA(3), args[4] );
00728     case BOTLIB_AI_CHOOSE_NBG_ITEM:
00729         return botlib_export->ai.BotChooseNBGItem( args[1], VMA(2), VMA(3), args[4], VMA(5), VMF(6) );
00730     case BOTLIB_AI_TOUCHING_GOAL:
00731         return botlib_export->ai.BotTouchingGoal( VMA(1), VMA(2) );
00732     case BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE:
00733         return botlib_export->ai.BotItemGoalInVisButNotVisible( args[1], VMA(2), VMA(3), VMA(4) );
00734     case BOTLIB_AI_GET_LEVEL_ITEM_GOAL:
00735         return botlib_export->ai.BotGetLevelItemGoal( args[1], VMA(2), VMA(3) );
00736     case BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL:
00737         return botlib_export->ai.BotGetNextCampSpotGoal( args[1], VMA(2) );
00738     case BOTLIB_AI_GET_MAP_LOCATION_GOAL:
00739         return botlib_export->ai.BotGetMapLocationGoal( VMA(1), VMA(2) );
00740     case BOTLIB_AI_AVOID_GOAL_TIME:
00741         return FloatAsInt( botlib_export->ai.BotAvoidGoalTime( args[1], args[2] ) );
00742     case BOTLIB_AI_SET_AVOID_GOAL_TIME:
00743         botlib_export->ai.BotSetAvoidGoalTime( args[1], args[2], VMF(3));
00744         return 0;
00745     case BOTLIB_AI_INIT_LEVEL_ITEMS:
00746         botlib_export->ai.BotInitLevelItems();
00747         return 0;
00748     case BOTLIB_AI_UPDATE_ENTITY_ITEMS:
00749         botlib_export->ai.BotUpdateEntityItems();
00750         return 0;
00751     case BOTLIB_AI_LOAD_ITEM_WEIGHTS:
00752         return botlib_export->ai.BotLoadItemWeights( args[1], VMA(2) );
00753     case BOTLIB_AI_FREE_ITEM_WEIGHTS:
00754         botlib_export->ai.BotFreeItemWeights( args[1] );
00755         return 0;
00756     case BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC:
00757         botlib_export->ai.BotInterbreedGoalFuzzyLogic( args[1], args[2], args[3] );
00758         return 0;
00759     case BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC:
00760         botlib_export->ai.BotSaveGoalFuzzyLogic( args[1], VMA(2) );
00761         return 0;
00762     case BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC:
00763         botlib_export->ai.BotMutateGoalFuzzyLogic( args[1], VMF(2) );
00764         return 0;
00765     case BOTLIB_AI_ALLOC_GOAL_STATE:
00766         return botlib_export->ai.BotAllocGoalState( args[1] );
00767     case BOTLIB_AI_FREE_GOAL_STATE:
00768         botlib_export->ai.BotFreeGoalState( args[1] );
00769         return 0;
00770 
00771     case BOTLIB_AI_RESET_MOVE_STATE:
00772         botlib_export->ai.BotResetMoveState( args[1] );
00773         return 0;
00774     case BOTLIB_AI_ADD_AVOID_SPOT:
00775         botlib_export->ai.BotAddAvoidSpot( args[1], VMA(2), VMF(3), args[4] );
00776         return 0;
00777     case BOTLIB_AI_MOVE_TO_GOAL:
00778         botlib_export->ai.BotMoveToGoal( VMA(1), args[2], VMA(3), args[4] );
00779         return 0;
00780     case BOTLIB_AI_MOVE_IN_DIRECTION:
00781         return botlib_export->ai.BotMoveInDirection( args[1], VMA(2), VMF(3), args[4] );
00782     case BOTLIB_AI_RESET_AVOID_REACH:
00783         botlib_export->ai.BotResetAvoidReach( args[1] );
00784         return 0;
00785     case BOTLIB_AI_RESET_LAST_AVOID_REACH:
00786         botlib_export->ai.BotResetLastAvoidReach( args[1] );
00787         return 0;
00788     case BOTLIB_AI_REACHABILITY_AREA:
00789         return botlib_export->ai.BotReachabilityArea( VMA(1), args[2] );
00790     case BOTLIB_AI_MOVEMENT_VIEW_TARGET:
00791         return botlib_export->ai.BotMovementViewTarget( args[1], VMA(2), args[3], VMF(4), VMA(5) );
00792     case BOTLIB_AI_PREDICT_VISIBLE_POSITION:
00793         return botlib_export->ai.BotPredictVisiblePosition( VMA(1), args[2], VMA(3), args[4], VMA(5) );
00794     case BOTLIB_AI_ALLOC_MOVE_STATE:
00795         return botlib_export->ai.BotAllocMoveState();
00796     case BOTLIB_AI_FREE_MOVE_STATE:
00797         botlib_export->ai.BotFreeMoveState( args[1] );
00798         return 0;
00799     case BOTLIB_AI_INIT_MOVE_STATE:
00800         botlib_export->ai.BotInitMoveState( args[1], VMA(2) );
00801         return 0;
00802 
00803     case BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON:
00804         return botlib_export->ai.BotChooseBestFightWeapon( args[1], VMA(2) );
00805     case BOTLIB_AI_GET_WEAPON_INFO:
00806         botlib_export->ai.BotGetWeaponInfo( args[1], args[2], VMA(3) );
00807         return 0;
00808     case BOTLIB_AI_LOAD_WEAPON_WEIGHTS:
00809         return botlib_export->ai.BotLoadWeaponWeights( args[1], VMA(2) );
00810     case BOTLIB_AI_ALLOC_WEAPON_STATE:
00811         return botlib_export->ai.BotAllocWeaponState();
00812     case BOTLIB_AI_FREE_WEAPON_STATE:
00813         botlib_export->ai.BotFreeWeaponState( args[1] );
00814         return 0;
00815     case BOTLIB_AI_RESET_WEAPON_STATE:
00816         botlib_export->ai.BotResetWeaponState( args[1] );
00817         return 0;
00818 
00819     case BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION:
00820         return botlib_export->ai.GeneticParentsAndChildSelection(args[1], VMA(2), VMA(3), VMA(4), VMA(5));
00821 
00822     case TRAP_MEMSET:
00823         Com_Memset( VMA(1), args[2], args[3] );
00824         return 0;
00825 
00826     case TRAP_MEMCPY:
00827         Com_Memcpy( VMA(1), VMA(2), args[3] );
00828         return 0;
00829 
00830     case TRAP_STRNCPY:
00831         return (int)strncpy( VMA(1), VMA(2), args[3] );
00832 
00833     case TRAP_SIN:
00834         return FloatAsInt( sin( VMF(1) ) );
00835 
00836     case TRAP_COS:
00837         return FloatAsInt( cos( VMF(1) ) );
00838 
00839     case TRAP_ATAN2:
00840         return FloatAsInt( atan2( VMF(1), VMF(2) ) );
00841 
00842     case TRAP_SQRT:
00843         return FloatAsInt( sqrt( VMF(1) ) );
00844 
00845     case TRAP_MATRIXMULTIPLY:
00846         MatrixMultiply( VMA(1), VMA(2), VMA(3) );
00847         return 0;
00848 
00849     case TRAP_ANGLEVECTORS:
00850         AngleVectors( VMA(1), VMA(2), VMA(3), VMA(4) );
00851         return 0;
00852 
00853     case TRAP_PERPENDICULARVECTOR:
00854         PerpendicularVector( VMA(1), VMA(2) );
00855         return 0;
00856 
00857     case TRAP_FLOOR:
00858         return FloatAsInt( floor( VMF(1) ) );
00859 
00860     case TRAP_CEIL:
00861         return FloatAsInt( ceil( VMF(1) ) );
00862 
00863 
00864     default:
00865         Com_Error( ERR_DROP, "Bad game system trap: %i", args[0] );
00866     }
00867     return -1;
00868 }
00869 
00870 /*
00871 ===============
00872 SV_ShutdownGameProgs
00873 
00874 Called every time a map changes
00875 ===============
00876 */
00877 void SV_ShutdownGameProgs( void ) {
00878     if ( !gvm ) {
00879         return;
00880     }
00881     VM_Call( gvm, GAME_SHUTDOWN, qfalse );
00882     VM_Free( gvm );
00883     gvm = NULL;
00884 }
00885 
00886 /*
00887 ==================
00888 SV_InitGameVM
00889 
00890 Called for both a full init and a restart
00891 ==================
00892 */
00893 static void SV_InitGameVM( qboolean restart ) {
00894     int     i;
00895 
00896     // start the entity parsing at the beginning
00897     sv.entityParsePoint = CM_EntityString();
00898 
00899     // clear all gentity pointers that might still be set from
00900     // a previous level
00901     // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=522
00902     //   now done before GAME_INIT call
00903     for ( i = 0 ; i < sv_maxclients->integer ; i++ ) {
00904         svs.clients[i].gentity = NULL;
00905     }
00906     
00907     // use the current msec count for a random seed
00908     // init for this gamestate
00909     VM_Call( gvm, GAME_INIT, svs.time, Com_Milliseconds(), restart );
00910 }
00911 
00912 
00913 
00914 /*
00915 ===================
00916 SV_RestartGameProgs
00917 
00918 Called on a map_restart, but not on a normal map change
00919 ===================
00920 */
00921 void SV_RestartGameProgs( void ) {
00922     if ( !gvm ) {
00923         return;
00924     }
00925     VM_Call( gvm, GAME_SHUTDOWN, qtrue );
00926 
00927     // do a restart instead of a free
00928     gvm = VM_Restart( gvm );
00929     if ( !gvm ) { // bk001212 - as done below
00930         Com_Error( ERR_FATAL, "VM_Restart on game failed" );
00931     }
00932 
00933     SV_InitGameVM( qtrue );
00934 }
00935 
00936 
00937 /*
00938 ===============
00939 SV_InitGameProgs
00940 
00941 Called on a normal map change, not on a map_restart
00942 ===============
00943 */
00944 void SV_InitGameProgs( void ) {
00945     cvar_t  *var;
00946     //FIXME these are temp while I make bots run in vm
00947     extern int  bot_enable;
00948 
00949     var = Cvar_Get( "bot_enable", "1", CVAR_LATCH );
00950     if ( var ) {
00951         bot_enable = var->integer;
00952     }
00953     else {
00954         bot_enable = 0;
00955     }
00956 
00957     // load the dll or bytecode
00958     gvm = VM_Create( "qagame", SV_GameSystemCalls, Cvar_VariableValue( "vm_game" ) );
00959     if ( !gvm ) {
00960         Com_Error( ERR_FATAL, "VM_Create on game failed" );
00961     }
00962 
00963     SV_InitGameVM( qfalse );
00964 }
00965 
00966 
00967 /*
00968 ====================
00969 SV_GameCommand
00970 
00971 See if the current console command is claimed by the game
00972 ====================
00973 */
00974 qboolean SV_GameCommand( void ) {
00975     if ( sv.state != SS_GAME ) {
00976         return qfalse;
00977     }
00978 
00979     return VM_Call( gvm, GAME_CONSOLE_COMMAND );
00980 }
00981 

Generated on Thu Aug 25 12:37:56 2005 for Quake III Arena by  doxygen 1.3.9.1