/* =========================================================================== Copyright (C) 1999 - 2005, Id Software, Inc. Copyright (C) 2000 - 2013, Raven Software, Inc. Copyright (C) 2001 - 2013, Activision, Inc. Copyright (C) 2013 - 2015, OpenJK contributors This file is part of the OpenJK source code. OpenJK is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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, see . =========================================================================== */ // sv_game.c -- interface to the game dll #include "server.h" #include "botlib/botlib.h" #include "qcommon/stringed_ingame.h" #include "qcommon/RoffSystem.h" #include "ghoul2/ghoul2_shared.h" #include "qcommon/cm_public.h" #include "icarus/GameInterface.h" #include "qcommon/timing.h" #include "NPCNav/navigator.h" #include "sv_gameapi.h" // these functions must be used instead of pointer arithmetic, because // the game allocates gentities with private information after the server shared part int SV_NumForGentity( sharedEntity_t *ent ) { int num; num = ( (byte *)ent - (byte *)sv.gentities ) / sv.gentitySize; return num; } sharedEntity_t *SV_GentityNum( int num ) { sharedEntity_t *ent; ent = (sharedEntity_t *)((byte *)sv.gentities + sv.gentitySize*(num)); return ent; } playerState_t *SV_GameClientNum( int num ) { playerState_t *ps; ps = (playerState_t *)((byte *)sv.gameClients + sv.gameClientSize*(num)); return ps; } svEntity_t *SV_SvEntityForGentity( sharedEntity_t *gEnt ) { if ( !gEnt || gEnt->s.number < 0 || gEnt->s.number >= MAX_GENTITIES ) { Com_Error( ERR_DROP, "SV_SvEntityForGentity: bad gEnt" ); } return &sv.svEntities[ gEnt->s.number ]; } sharedEntity_t *SV_GEntityForSvEntity( svEntity_t *svEnt ) { int num; num = svEnt - sv.svEntities; return SV_GentityNum( num ); } /* ================= SV_inPVS Also checks portalareas so that doors block sight ================= */ qboolean SV_inPVS (const vec3_t p1, const vec3_t p2) { 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 (p2); cluster = CM_LeafCluster (leafnum); area2 = CM_LeafArea (leafnum); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return qfalse; if (!CM_AreasConnected (area1, area2)) return qfalse; // a door blocks sight return qtrue; } //============================================== /* =============== SV_ShutdownGameProgs Called every time a map changes =============== */ void SV_ShutdownGameProgs( void ) { if ( !svs.gameStarted ) { return; } SV_UnbindGame(); } /* =============== SV_InitGameProgs Called on a normal map change, not on a map_restart =============== */ void SV_InitGameProgs( void ) { //FIXME these are temp while I make bots run in vm extern int bot_enable; cvar_t *var = Cvar_Get( "bot_enable", "1", CVAR_LATCH ); bot_enable = var ? var->integer : 0; svs.gameStarted = qtrue; SV_BindGame(); SV_InitGame( qfalse ); } /* ==================== SV_GameCommand See if the current console command is claimed by the game ==================== */ qboolean SV_GameCommand( void ) { if ( sv.state != SS_GAME ) { return qfalse; } return GVM_ConsoleCommand(); }