⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_main.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include <setjmp.h>
#include "g_local.h"
#include "g_utils.h"
#include "Entity.h"
#include "vector.h"
#include "scriptmaster.h"
#include "navigate.h"
#include "viewthing.h"
#include "console.h"
#include "player.h"
#include "surface.h"
#include "gravpath.h"
#include "deadbody.h"

Vector vec_origin = "0 0 0";
Vector vec_zero = "0 0 0";

qboolean          LoadingSavegame = false;
qboolean          LoadingServer = false;
game_locals_t		game;
level_locals_t		level;
game_import_t		gi;
game_export_t		globals;

edict_t				*g_edicts = NULL;
edict_t				active_edicts;
edict_t				free_edicts;

netconsole_t      *g_consoles;
netconbuffer_t    *g_conbuffers;
netsurface_t      *g_surfaces;

cvar_t	*developer;
cvar_t	*deathmatch;
cvar_t	*coop;
cvar_t	*dmflags;
cvar_t	*skill;
cvar_t	*fraglimit;
cvar_t	*timelimit;
cvar_t	*password;

cvar_t	*filterban;

cvar_t	*flood_msgs;
cvar_t	*flood_persecond;
cvar_t	*flood_waitdelay;

cvar_t	*maxclients;
cvar_t	*maxentities;
cvar_t   *maxconsoles;
cvar_t   *maxsurfaces;
cvar_t	*g_select_empty;
cvar_t	*g_unlimited_ammo;
cvar_t	*nomonsters;
cvar_t	*dm_respawn;
cvar_t   *dialog;
cvar_t	*precache;
cvar_t   *g_showmem;
cvar_t   *g_timeents;

cvar_t	*sv_maxvelocity;
cvar_t	*sv_gravity;

cvar_t	*dedicated;

cvar_t	*sv_rollspeed;
cvar_t	*sv_rollangle;
cvar_t	*gun_x;
cvar_t	*gun_y;
cvar_t	*gun_z;

cvar_t	*run_pitch;
cvar_t	*run_roll;
cvar_t	*bob_up;
cvar_t	*bob_pitch;
cvar_t	*bob_roll;

cvar_t	*sv_cheats;
cvar_t	*sv_showbboxes;
cvar_t	*sv_showentnums;
cvar_t   *sv_rocketspeed;
cvar_t   *sv_rocketrate;

cvar_t	*sv_stopspeed;
cvar_t	*sv_friction;
cvar_t	*sv_waterfriction;
cvar_t	*sv_waterspeed;

cvar_t   *sv_maxbulletholes;
cvar_t   *sv_maxbloodsplats;
cvar_t   *sv_gore;
cvar_t   *sv_gibs;
cvar_t   *sv_showdamage;
cvar_t   *sv_showdamagelocation;
cvar_t	*sv_traceinfo;
cvar_t	*sv_drawtrace;
cvar_t   *sv_maplist;
cvar_t   *sv_footsteps;
cvar_t   *sv_fatrockets;

cvar_t	*csys_posx;
cvar_t	*csys_posy;
cvar_t	*csys_posz;
cvar_t	*csys_x;
cvar_t	*csys_y;
cvar_t	*csys_z;
cvar_t	*csys_draw;

cvar_t   *parentmode;

int		sv_numtraces;

usercmd_t *current_ucmd;

void     G_AllocDebugLines( void );
void		G_ClientDrawBoundingBoxes( void );
void		( *ServerError )( const char *fmt, ... );
char		G_ErrorMessage[ 1024 ];
jmp_buf	G_AbortGame;

/*
===============
G_Error

Abort the server with a game error
===============
*/
void G_Error
	(
	const char *fmt,
	...
	)

	{
	va_list	argptr;
	
	va_start( argptr, fmt );
	vsprintf( G_ErrorMessage, fmt, argptr );
	va_end( argptr );

   assert( 0 );

	longjmp( G_AbortGame, -1 );
	}

/*
===============
G_ExitWithError

Calls the server's error function with the last error that occurred.
Should only be called after a setjmp( G_AbortGame ) call
===============
*/
void G_ExitWithError
	(
	void
	)
	
	{
	ServerError( G_ErrorMessage );
	}

/*
=================
G_ShutdownGame

Frees up any resources
=================
*/
void G_ShutdownGame
	(
	void
	)

	{
	gi.dprintf ("==== ShutdownGame ====\n");

	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

   G_LevelShutdown();

   gi.FreeTags (TAG_GAME);
	}

/*
============
G_InitGame

This will be called when the dll is first loaded, which
only happens when a new game is begun
============
*/
void G_InitGame
   (
   void
   )

	{
	gi.dprintf ("==== InitGame ====\n");

	// Install our own error handler, since we can't
	// call the EXE's handler from within a C++ class
	ServerError = gi.error;
	gi.error = G_Error;

	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

	// initialize the game variables
	gameVars.ClearList();

	gun_x = gi.cvar ("gun_x", "0", 0);
	gun_y = gi.cvar ("gun_y", "0", 0);
	gun_z = gi.cvar ("gun_z", "0", 0);

	developer			= gi.cvar( "developer", "0", 0 );
	precache 			= gi.cvar( "sv_precache", "1", 0 );

	//FIXME: sv_ prefix is wrong for these
	sv_rollspeed		    = gi.cvar ("sv_rollspeed", "200", 0);
	sv_rollangle		    = gi.cvar ("sv_rollangle", "2", 0);
	sv_maxvelocity		    = gi.cvar ("sv_maxvelocity", "2000", 0);
	sv_gravity			    = gi.cvar ("sv_gravity", "800", 0);
   sv_maxbulletholes     = gi.cvar ("sv_maxbulletholes", "32", 0);
   sv_maxbloodsplats     = gi.cvar ("sv_maxbloodspats", "5", 0);
   sv_gore               = gi.cvar ("sv_gore", "1", 0);
   sv_gibs               = gi.cvar ("sv_gibs", "1", 0);
   sv_showdamage         = gi.cvar ("sv_showdetaildamage", "0", 0);
   sv_showdamagelocation = gi.cvar ("sv_showdamagelocation", "0", 0);

	// noset vars
	dedicated			= gi.cvar ("dedicated", "0", CVAR_NOSET);

	// latched vars
	sv_cheats			= gi.cvar ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
	deathmatch			= gi.cvar ("deathmatch", "0", CVAR_SERVERINFO|CVAR_LATCH);
   coop					= gi.cvar ("coop", "0", CVAR_SERVERINFO|CVAR_LATCH);
	skill					= gi.cvar ("skill", "1", CVAR_SERVERINFO|CVAR_LATCH);
#ifdef SIN
	maxclients			= gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH | CVAR_ARCHIVE );
#else
	maxclients			= gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
#endif
	maxentities			= gi.cvar ("maxentities", "1024", CVAR_LATCH);
   maxconsoles       = gi.cvar ("maxconsoles", "32", CVAR_LATCH);
   maxsurfaces       = gi.cvar ("maxsurfaces", "1024", CVAR_LATCH);

	// flood control
	flood_msgs        = gi.cvar ("flood_msgs", "4", 0);
	flood_persecond   = gi.cvar ("flood_persecond", "4", 0);
	flood_waitdelay   = gi.cvar ("flood_waitdelay", "10", 0);

   // change anytime vars
	password          = gi.cvar ("password", "", CVAR_USERINFO);
	filterban         = gi.cvar ("filterban", "1", 0);
#ifdef SIN_ARCADE
	dmflags				= gi.cvar ("dmflags", "0", CVAR_SERVERINFO|CVAR_ARCHIVE);
	fraglimit			= gi.cvar ("fraglimit", "0", CVAR_SERVERINFO|CVAR_ARCHIVE);
	timelimit			= gi.cvar ("timelimit", "0", CVAR_SERVERINFO|CVAR_ARCHIVE);
#else
	dmflags				= gi.cvar ("dmflags", "0", CVAR_SERVERINFO);
	fraglimit			= gi.cvar ("fraglimit", "0", CVAR_SERVERINFO);
	timelimit			= gi.cvar ("timelimit", "0", CVAR_SERVERINFO);
#endif
	g_select_empty		= gi.cvar ("g_select_empty", "0", CVAR_ARCHIVE);
	g_unlimited_ammo	= gi.cvar ("g_unlimited_ammo", "0", CVAR_SERVERINFO);
   g_showmem         = gi.cvar ("g_showmem", "0", 0 );
   g_timeents        = gi.cvar ("g_timeents", "0", 0 );
	dm_respawn			= gi.cvar ("dm_respawn", "2", CVAR_SERVERINFO);
	nomonsters			= gi.cvar ("nomonsters", "0", CVAR_SERVERINFO);
   dialog   			= gi.cvar ("dialog", "2", CVAR_SERVERINFO | CVAR_ARCHIVE );

	run_pitch			= gi.cvar ("run_pitch", "0.002", 0);
	run_roll				= gi.cvar ("run_roll", "0.005", 0);
	bob_up				= gi.cvar ("bob_up", "0.005", 0);
	bob_pitch			= gi.cvar ("bob_pitch", "0.002", 0);
	bob_roll				= gi.cvar ("bob_roll", "0.002", 0);

	bob_roll				= gi.cvar ("bob_roll", "0.002", 0);

	csys_posx			= gi.cvar ("csys_posx",	"0", 0);
	csys_posy			= gi.cvar ("csys_posy",	"0", 0);
	csys_posz			= gi.cvar ("csys_posz",	"0", 0);
	csys_x				= gi.cvar ("csys_x",		"0", 0);
	csys_y				= gi.cvar ("csys_y",		"0", 0);
	csys_z				= gi.cvar ("csys_z",		"0", 0);
	csys_draw			= gi.cvar ("csys_draw", "0", 0);

	sv_traceinfo		= gi.cvar ("sv_traceinfo", "0", 0);
	sv_drawtrace		= gi.cvar ("sv_drawtrace", "0", 0);
		
   // debug stuff
	sv_showbboxes		= gi.cvar ("sv_showbboxes", "0", 0);
	sv_showentnums		= gi.cvar ("sv_showentnums", "0", 0);
   sv_rocketspeed    = gi.cvar ("sv_rocketspeed", "300", 0);
   sv_rocketrate     = gi.cvar ("sv_rocketrate", "1.2", 0);

	sv_friction			= gi.cvar ("sv_friction", "4", CVAR_SERVERINFO);
	sv_stopspeed		= gi.cvar ("sv_stopspeed", "100", CVAR_SERVERINFO);
	sv_waterfriction	= gi.cvar ("sv_waterfriction", "1", CVAR_SERVERINFO);
	sv_waterspeed		= gi.cvar ("sv_waterspeed", "400", CVAR_SERVERINFO);
   sv_maplist        = gi.cvar ("sv_maplist", "", CVAR_SERVERINFO|CVAR_ARCHIVE);
   sv_footsteps      = gi.cvar ("sv_footsteps", "1", CVAR_SERVERINFO|CVAR_ARCHIVE);

   if ( deathmatch->value )
      {
      sv_fatrockets = gi.cvar ("sv_fatrockets", "1", CVAR_SERVERINFO);
      }
   else
      {
      sv_fatrockets = gi.cvar ("sv_fatrockets", "1", CVAR_SERVERINFO);
      }

   parentmode        = gi.cvar ("parentmode", "0", CVAR_USERINFO|CVAR_SERVERINFO|CVAR_ARCHIVE);

	G_InitEvents();
	sv_numtraces = 0;

	game.maxentities = maxentities->value;
	if (maxclients->value * 8 > game.maxentities)
		{
		game.maxentities = maxclients->value * 8;
		}
	game.maxclients = maxclients->value;
   game.maxconsoles = maxconsoles->value;
   game.maxsurfaces = maxsurfaces->value;
   G_AllocGameData();
   }

void G_AllocGameData
   (
   void 
   )

   {
   int i;

	gi.FreeTags( TAG_GAME );

   // Initialize debug lines
	G_AllocDebugLines();

	// initialize all entities for this game
	g_edicts =  ( edict_t * )gi.TagMalloc (game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
	globals.edicts = g_edicts;
	globals.max_edicts = game.maxentities;

	// Add all the edicts to the free list
	LL_Reset( &free_edicts, next, prev );
	LL_Reset( &active_edicts, next, prev );
	for( i = 0; i < game.maxentities; i++ )
		{
		LL_Add( &free_edicts, &g_edicts[ i ], next, prev );
		}

	// initialize all clients for this game
	game.clients = ( gclient_t * )gi.TagMalloc (game.maxclients * sizeof(game.clients[0]), TAG_GAME);
	memset( game.clients, 0, game.maxclients * sizeof( game.clients[ 0 ] ) );
	for (i=0 ; i<game.maxclients ; i++)
		{
     	// set client fields on player ents
		g_edicts[ i + 1 ].client = game.clients + i;

		G_InitClientPersistant (&game.clients[i]);
		G_InitClientResp (&game.clients[i]);
		}
	globals.num_edicts = game.maxclients+1;

   // initialize all the consoles
   g_consoles = (netconsole_t *)gi.TagMalloc (game.maxconsoles * sizeof(g_consoles[0]), TAG_GAME);
   globals.consoles = g_consoles;
   globals.max_consoles = game.maxconsoles;
   globals.num_consoles = 0;
   g_conbuffers = (netconbuffer_t *)gi.TagMalloc (game.maxconsoles * sizeof(g_conbuffers[0]), TAG_GAME);
   globals.conbuffers = g_conbuffers;

   // initialize the surfaces
   g_surfaces = (netsurface_t *)gi.TagMalloc (game.maxsurfaces * sizeof(g_surfaces[0]), TAG_GAME);
   globals.surfaces = g_surfaces;
   globals.max_surfaces = game.maxsurfaces;
   globals.num_surfaces = 0;
   }

void ReadGame
   (
   const char *name
   )

	{
   str mapname;
   str spawnpoint;
	Archiver arc;
   int version;
   int savegame_version;

   LoadingServer = true;

   // Get rid of anything left over from the last level
   G_LevelShutdown();

	arc.Read( name );

   arc.ReadInteger( &version );
   if ( version < GAME_API_VERSION )
      {
      gi.error( "Savegame from an older version (%d) of Sin.\n", version );
      }
   else if ( version > GAME_API_VERSION )
      {
      gi.error( "Savegame from version %d of Sin.\n", version );
      }

   arc.ReadInteger( &savegame_version );
   if ( savegame_version < SAVEGAME_VERSION )
      {
      gi.error( "Savegame from an older version (%d) of Sin.\n", version );
      }
   else if ( savegame_version > SAVEGAME_VERSION )
      {
      gi.error( "Savegame from version %d of Sin.\n", version );
      }

   // Read the map name (needed by G_MapInit)
   arc.ReadString( &mapname );

   // Set up for a new map
   G_MapInit( mapname.c_str() );

   arc.ReadObject( &PersistantData );
   arc.ReadObject( &game );
	arc.ReadObject( &gameVars );

   arc.Close();
   }

void G_ReadGame
   (
   const char *name
   )

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

   ReadGame( name );
   }

/*
============
WriteGame

This will be called whenever the game goes to a new level,
and when the user explicitly saves the game.

Game information include cross level data, like multi level
triggers, help computer info, and all client states.

A single player death will automatically restore from the
last save position.
============
*/

void WriteGame
   (
   const char *name,
   qboolean autosave
   )

	{
   Archiver arc;

   game.autosaved = autosave;

   arc.Create( name );

   arc.WriteInteger( GAME_API_VERSION );
   arc.WriteInteger( SAVEGAME_VERSION );

   arc.WriteString( level.mapname );

   arc.WriteObject( &PersistantData );
   arc.WriteObject( &game );
   arc.WriteObject( &gameVars );

	arc.Close();

   game.autosaved = false;
   }

void G_WriteGame
   (
   const char *name,
   qboolean autosave
   )

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

   WriteGame( name, autosave );
   }

/*
==============
G_WriteClient
==============
*/
void G_WriteClient
   (
   Archiver &arc,
   gclient_t *client
   )

   {
   arc.WriteRaw( client, sizeof( gclient_t ) );
   }

/*
==============
G_ReadClient
==============
*/
void G_ReadClient
   (
   Archiver &arc,
   gclient_t *client
   )

   {
   arc.ReadRaw( client, sizeof( gclient_t ) );
   }

/*
==================
G_SaveClientData

Some information that should be persistant, like health, 
is stored in the Entity structure, so it needs to be mirrored 
out to the client structure before all the edicts are wiped.
==================
*/
void G_SaveClientData
   (
   void
   )

   {
	int		i;
	edict_t	*ent;

   PersistantData.Reset();

   if ( deathmatch->value )
      {
      return;
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -