예제 #1
0
/*
=================
ShutdownGame
=================
*/
void ShutdownGame( void ) {
	gi.Printf ("==== ShutdownGame ====\n");

	gi.Printf ("... ICARUS_Shutdown\n");
	ICARUS_Shutdown ();	//Shut ICARUS down

	gi.Printf ("... Reference Tags Cleared\n");
	TAG_Init();	//Clear the reference tags

	gi.Printf ("... Navigation Data Cleared\n");
	NAV_Shutdown();

	// write all the client session data so we can get it back
	G_WriteSessionData();

/*
Ghoul2 Insert Start
*/
	gi.Printf ("... Ghoul2 Models Shutdown\n");
	for (int i=0; i<MAX_GENTITIES; i++)
	{
		gi.G2API_CleanGhoul2Models(g_entities[i].ghoul2);
	}
/*
Ghoul2 Insert End
*/
}
예제 #2
0
void NAV_CheckCalcPaths( void )
{	
	if ( navCalcPathTime && navCalcPathTime < level.time )
	{//first time we've ever loaded this map...
		//clear all the failed edges
		navigator.ClearAllFailedEdges();

		//Calculate all paths
		NAV_CalculatePaths( level.mapname, giMapChecksum );
		
		navigator.CalculatePaths();

#ifndef FINAL_BUILD
		if ( fatalErrors )
		{
			gi.Printf( S_COLOR_RED"Not saving .nav file due to fatal nav errors\n" );
		}
		else 
#endif
		if ( navigator.Save( level.mapname, giMapChecksum ) == qfalse )
		{
			gi.Printf("Unable to save navigations data for map \"%s\" (checksum:%d)\n", level.mapname, giMapChecksum );
		}
		navCalcPathTime = 0;
	}
}
예제 #3
0
extern "C" __declspec( dllexport ) int __cdecl vmMain ( int command, int arg1, int arg2 /*, ..., arg10); (?) no more than 2 seems to ever be used. */ )
{
	assert( g_realVmMain );
	int retVal = g_realVmMain( command, arg1, arg2 );
	if( command == 1 && g_inShutdown )
	{
		g_inShutdown = qfalse;

		g_realDllEntry = 0;
		g_realGetGameAPI = 0;
		g_realShutdown = 0;
		g_realVmMain = 0;

		if( g_modShutdown )
		{
			g_imports.Printf( "^5Calling mod_jagamex86.dll's Shutdown()\n" );
			g_modShutdown();
		}
		if( g_modJagamex86 )
		{
			g_imports.Printf( "^5Unloading mod_jagamex86.dll\n" );
			FreeLibrary( g_modJagamex86 );
		}

		g_imports.Printf( "^5Unloading original_jagamex86.dll\n" );

		g_exports = 0;
		assert( FreeLibrary( g_originalJagamex86 ) );
		g_originalJagamex86 = 0;
	}
	return retVal;
}
예제 #4
0
template< typename FncPtr > bool FindProcAddress( char* procName, char* dllName, FncPtr& out_func )
{
	if( !( out_func = (FncPtr) GetProcAddress( g_modJagamex86, procName ) ) )
	{
		g_imports.Printf( "^5Warning: No %s in %s! Ignoring it.\n", procName, dllName );
		return false;
	}
	return true;
}
예제 #5
0
void Com_Printf( const char *msg, ... ) {
	va_list		argptr;
	char		text[1024];

	va_start (argptr, msg);
	vsprintf (text, msg, argptr);
	va_end (argptr);

	gi.Printf ("%s", text);
}
예제 #6
0
/*
================
G_FindTeams

Chain together all entities with a matching team field.
Entity teams are used for item groups and multi-entity mover groups.

All but the first will have the FL_TEAMSLAVE flag set and teammaster field set
All but the last will have the teamchain field set to the next one
================
*/
void G_FindTeams( void ) {
	gentity_t	*e, *e2;
	int		i, j;
	int		c, c2;

	c = 0;
	c2 = 0;
//	for ( i=1, e=g_entities,i ; i < globals.num_entities ; i++,e++ )
	for ( i=1 ; i < globals.num_entities ; i++ )
	{
//		if (!e->inuse)
//			continue;
		if(!PInUse(i))
			continue;
		e=&g_entities[i];

		if (!e->team)
			continue;
		if (e->flags & FL_TEAMSLAVE)
			continue;
		e->teammaster = e;
		c++;
		c2++;
//		for (j=i+1, e2=e+1 ; j < globals.num_entities ; j++,e2++)
		for (j=i+1; j < globals.num_entities ; j++)
		{
//			if (!e2->inuse)
//				continue;
			if(!PInUse(j))
				continue;
			
			e2=&g_entities[j];
			if (!e2->team)
				continue;
			if (e2->flags & FL_TEAMSLAVE)
				continue;
			if (!strcmp(e->team, e2->team))
			{
				c2++;
				e2->teamchain = e->teamchain;
				e->teamchain = e2;
				e2->teammaster = e;
				e2->flags |= FL_TEAMSLAVE;

				// make sure that targets only point at the master
				if ( e2->targetname ) {
					e->targetname = e2->targetname;
					e2->targetname = NULL;
				}
			}
		}
	}

	gi.Printf ("%i teams with %i entities\n", c, c2);
}
예제 #7
0
void InitGame(  const char *mapname, const char *spawntarget, int checkSum, const char *entities, int levelTime, int randomSeed, int globalTime, SavedGameJustLoaded_e eSavedGameJustLoaded, qboolean qbLoadTransition )
{
	int		i;

	giMapChecksum = checkSum;
	g_eSavedGameJustLoaded = eSavedGameJustLoaded;
	g_qbLoadTransition = qbLoadTransition;

	gi.Printf ("------- Game Initialization -------\n");
	gi.Printf ("gamename: %s\n", GAMEVERSION);
	gi.Printf ("gamedate: %s\n", __DATE__);

	srand( randomSeed );

	G_InitCvars();

	G_InitMemory();

	// set some level globals
	memset( &level, 0, sizeof( level ) );
	level.time = levelTime;
	level.globalTime = globalTime;
	Q_strncpyz( level.mapname, mapname, sizeof(level.mapname) );
	if ( spawntarget != NULL && spawntarget[0] )
	{
		Q_strncpyz( level.spawntarget, spawntarget, sizeof(level.spawntarget) );
	}
	else
	{
		level.spawntarget[0] = 0;
	}


	G_InitWorldSession();

	// initialize all entities for this game
	memset( g_entities, 0, MAX_GENTITIES * sizeof(g_entities[0]) );
	globals.gentities = g_entities;
	ClearAllInUse();
	// initialize all clients for this game
	level.maxclients = 1;
	level.clients = (struct gclient_s *) G_Alloc( level.maxclients * sizeof(level.clients[0]) );

	// set client fields on player
	g_entities[0].client = level.clients;

	// always leave room for the max number of clients,
	// even if they aren't all used, so numbers inside that
	// range are NEVER anything but clients
	globals.num_entities = MAX_CLIENTS;

	//Set up NPC init data
	NPC_InitGame();
	
	TIMER_Clear();

	//
	//ICARUS INIT START

	gi.Printf("------ ICARUS Initialization ------\n");
	gi.Printf("ICARUS version : %1.2f\n", ICARUS_VERSION);

	Interface_Init( &interface_export );
	ICARUS_Init();

	gi.Printf ("-----------------------------------\n");

	//ICARUS INIT END
	//

	IT_LoadItemParms ();

	ClearRegisteredItems();

	//FIXME: if this is from a loadgame, it needs to be sure to write this out whenever you do a savegame since the edges and routes are dynamic...
	navCalculatePaths	= ( navigator.Load( mapname, checkSum ) == qfalse );

	// parse the key/value pairs and spawn gentities
	G_SpawnEntitiesFromString( entities );

	// general initialization
	G_FindTeams();

//	SaveRegisteredItems();

	gi.Printf ("-----------------------------------\n");

	//randomize the rand functions
	byte num_calls = (byte)timeGetTime();

	for(i = 0; i < (int)num_calls; i++)
	{
		rand();
	}

	if ( navCalculatePaths )
	{//not loaded - need to calc paths
		navCalcPathTime = level.time + START_TIME_NAV_CALC;//make sure all ents are in and linked
	}
	else
	{//loaded
		//FIXME: if this is from a loadgame, it needs to be sure to write this 
		//out whenever you do a savegame since the edges and routes are dynamic...
		//OR: always do a navigator.CheckBlockedEdges() on map startup after nav-load/calc-paths
		navigator.pathsCalculated = qtrue;//just to be safe?  Does this get saved out?  No... assumed
		//need to do this, because combatpoint waypoints aren't saved out...?
		CP_FindCombatPointWaypoints();
		navCalcPathTime = 0;

		if ( g_eSavedGameJustLoaded == eNO )
		{//clear all the failed edges unless we just loaded the game (which would include failed edges)
			navigator.ClearAllFailedEdges();
		}
	}

	player = &g_entities[0];

	//Init dynamic music
	level.dmState = DM_EXPLORE;
	level.dmDebounceTime = 0;
	level.dmBeatTime = 0;

	level.curAlertID = 1;//0 is default for lastAlertEvent, so...
	eventClearTime = 0;
}
예제 #8
0
void G_RunFrame( int levelTime ) {
	int			i;
	gentity_t	*ent;
	int			msec;
	int			ents_inuse=0; // someone's gonna be pissed I put this here...
#if	AI_TIMERS
	AITime = 0;
	navTime = 0;
#endif//	AI_TIMERS
	
	level.framenum++;
	level.previousTime = level.time;
	level.time = levelTime;
	msec = level.time - level.previousTime;
	
	NAV_CheckCalcPaths();
	//ResetTeamCounters();
	
	AI_UpdateGroups();

	if ( d_altRoutes->integer )
	{
		navigator.CheckAllFailedEdges();
	}
	navigator.ClearCheckedNodes();

	//remember last waypoint, clear current one
//	for ( i = 0, ent = &g_entities[0]; i < globals.num_entities ; i++, ent++) 
	for ( i = 0; i < globals.num_entities ; i++) 
	{
//		if ( !ent->inuse )
//			continue;

		if(!PInUse(i))
			continue;
		
		ent = &g_entities[i];
	
		if ( ent->waypoint != WAYPOINT_NONE 
			&& ent->noWaypointTime < level.time )
		{
			ent->lastWaypoint = ent->waypoint;
			ent->waypoint = WAYPOINT_NONE;
		}
		if ( d_altRoutes->integer )
		{
			navigator.CheckFailedNodes( ent );
		}
	}

	//Look to clear out old events
	ClearPlayerAlertEvents();

	//Run the frame for all entities
//	for ( i = 0, ent = &g_entities[0]; i < globals.num_entities ; i++, ent++)
	for ( i = 0; i < globals.num_entities ; i++) 
	{
//		if ( !ent->inuse )
//			continue;

		if(!PInUse(i))
			continue;
		ents_inuse++;
		ent = &g_entities[i];

		// clear events that are too old
		if ( level.time - ent->eventTime > EVENT_VALID_MSEC ) {
			if ( ent->s.event ) {
				ent->s.event = 0;	// &= EV_EVENT_BITS;
				if ( ent->client ) {
					ent->client->ps.externalEvent = 0;
				}
			}
			if ( ent->freeAfterEvent ) {
				// tempEntities or dropped items completely go away after their event
				G_FreeEntity( ent );
				continue;
			} else if ( ent->unlinkAfterEvent ) {
				// items that will respawn will hide themselves after their pickup event
				ent->unlinkAfterEvent = qfalse;
				gi.unlinkentity( ent );
			}
		}

		// temporary entities don't think
		if ( ent->freeAfterEvent )
			continue;

		G_CheckTasksCompleted(ent);

		G_Roff( ent );

		if( !ent->client )
		{
			if ( !(ent->svFlags & SVF_SELF_ANIMATING) )
			{//FIXME: make sure this is done only for models with frames?
				//Or just flag as animating?
				if ( ent->s.eFlags & EF_ANIM_ONCE )
				{
					ent->s.frame++;
				}
				else if ( !(ent->s.eFlags & EF_ANIM_ALLFAST) )
				{
					G_Animate( ent );
				}
			}
		}
		G_CheckSpecialPersistentEvents( ent );

		if ( ent->s.eType == ET_MISSILE ) 
		{
			G_RunMissile( ent );
			continue;
		}

		if ( ent->s.eType == ET_ITEM ) 
		{
			G_RunItem( ent );
			continue;
		}

		if ( ent->s.eType == ET_MOVER ) 
		{
			if ( ent->model && Q_stricmp( "models/test/mikeg/tie_fighter.md3", ent->model ) == 0 )
			{
				TieFighterThink( ent );
			}
			G_RunMover( ent );
			continue;
		}

		//The player
		if ( i == 0 ) 
		{
			// decay batteries if the goggles are active
			if ( cg.zoomMode == 1 && ent->client->ps.batteryCharge > 0 )
			{
				ent->client->ps.batteryCharge--;
			}
			else if ( cg.zoomMode == 3 && ent->client->ps.batteryCharge > 0 )
			{
				ent->client->ps.batteryCharge -= 2;

				if ( ent->client->ps.batteryCharge < 0 )
				{
					ent->client->ps.batteryCharge = 0;
				}
			}

			G_CheckEndLevelTimers( ent );
			//Recalculate the nearest waypoint for the coming NPC updates
			NAV_FindPlayerWaypoint();

			if( ent->taskManager && !stop_icarus )
			{
				ent->taskManager->Update();
			}
			//dead
			if ( ent->health <= 0 )
			{
				if ( ent->client->ps.groundEntityNum != ENTITYNUM_NONE )
				{//on the ground
					pitch_roll_for_slope( ent, NULL );
				}
			}

			continue;	// players are ucmd driven
		}

		G_RunThink( ent );	// be aware that ent may be free after returning from here, at least one func frees them
		ClearNPCGlobals();			//	but these 2 funcs are ok
		//UpdateTeamCounters( ent );	//	   to call anyway on a freed ent.
	}

	// perform final fixups on the player
	ent = &g_entities[0];
	if ( ent->inuse ) 
	{
		ClientEndFrame( ent );
	}
	if( g_numEntities->integer )
	{
		gi.Printf( S_COLOR_WHITE"Number of Entities in use : %d\n", ents_inuse );
	}
	//DEBUG STUFF
	NAV_ShowDebugInfo();
	NPC_ShowDebugInfo();

	G_DynamicMusicUpdate();

#if	AI_TIMERS
	AITime -= navTime;
	if ( AITime > 20 )
	{
		gi.Printf( S_COLOR_RED"ERROR: total AI time: %d\n", AITime );
	}
	else if ( AITime > 10 )
	{
		gi.Printf( S_COLOR_YELLOW"WARNING: total AI time: %d\n", AITime );
	}
	else if ( AITime > 2 )
	{
		gi.Printf( S_COLOR_GREEN"total AI time: %d\n", AITime );
	}
	if ( navTime > 20 )
	{
		gi.Printf( S_COLOR_RED"ERROR: total nav time: %d\n", navTime );
	}
	else if ( navTime > 10 )
	{
		gi.Printf( S_COLOR_YELLOW"WARNING: total nav time: %d\n", navTime );
	}
	else if ( navTime > 2 )
	{
		gi.Printf( S_COLOR_GREEN"total nav time: %d\n", navTime );
	}
#endif//	AI_TIMERS

#ifndef FINAL_BUILD
	if ( delayedShutDown != 0 && delayedShutDown < level.time )
	{
		G_Error( "Game Errors. Scroll up the console to read them.\n" );
	}
#endif

#ifdef _DEBUG
	if(!(level.framenum&0xff))
	{
		ValidateInUseBits();
	}
#endif
}
예제 #9
0
/**
	@brief First function called when the DLL is loaded: Server API?
**/
extern "C" __declspec( dllexport ) game_export_t* __cdecl GetGameAPI( game_import_t* imports )
{
	// static global variables are guaranteed to be 0, I heard. Let's assert that.
	assert( !g_exports );
	assert( !g_originalJagamex86 );
	assert( !g_modJagamex86 );
	assert( !g_inShutdown );
	assert( !g_realDllEntry );
	assert( !g_realGetGameAPI );
	assert( !g_originalJagamex86 );
	assert( !g_realShutdown );
	assert( !g_realVmMain );
	assert( !g_modShutdown );

	imports->Printf( "^5Loading original_jagamex86.dll\n" );
	g_inShutdown = qfalse;

	g_originalJagamex86 = LoadLibrary( "original_jagamex86.dll" );
	if( !g_originalJagamex86 )
	{
		// imports->Error would be a bad idea because that'd jmp out of the cleanup code for failed dll loading, causing "Sys_GetGameAPI without Sys_UnloadingGame"
		imports->Printf( "^1Error: Could not load original_jagamex86.dll!\n" );
		return 0;
	}

	// Get the original functions
	if( ! (g_realGetGameAPI = (GetGameAPI_t) GetProcAddress( g_originalJagamex86, "GetGameAPI" ) ) )
	{
		imports->Printf( "^1Error: No GetGameAPI in original_jagamex86.dll!\n" );
		return 0;
	}
	if( ! (g_realDllEntry = (dllEntry_t) GetProcAddress( g_originalJagamex86, "dllEntry" ) ) )
	{
		imports->Printf( "^1Error: No dllEntry in original_jagamex86.dll!\n" );
		return 0;
	}
	if( ! (g_realVmMain = (vmMain_t) GetProcAddress( g_originalJagamex86, "vmMain" ) ) )
	{
		imports->Printf( "^1Error: No vmMain in original_jagamex86.dll!\n" );
		return 0;
	}

	// save the imports for later usage
	g_imports = *imports;

	// Get the active mod
	char fs_game[ 256 + 1 ]; // variables can be up to 256 chars - not sure about trailing \0, so + 1
	g_imports.Cvar_VariableStringBuffer( "fs_game", fs_game, sizeof( fs_game ) / sizeof( char ) );
	if( *fs_game == '\0' )
	{
		fs_game[0] = 'b';
		fs_game[1] = 'a';
		fs_game[2] = 's';
		fs_game[3] = 'e';
		fs_game[4] = '\0';
	}
	g_imports.Printf( "fs_game = %s\n", fs_game );

	if( strcmp( fs_game, "base" ) )
	{
		char dllName[ MAX_QPATH + 19 ]; // "/mod_jagamex86.dll\0" is 19 chars.
		sprintf_s( dllName, 256 + 19, "%s/mod_jagamex86.dll", fs_game );
		g_modJagamex86 = LoadLibrary( dllName );
		if( g_modJagamex86 )
		{
			g_imports.Printf( "^5Found %s - looking for functions.\n", dllName );
			GetGameAPI_t modGetGameAPI;
			vmMain_t modVmMain;
			dllEntry_t modDllEntry;
			SetOriginalFunctions_t modSetOriginalFunctions;

			if( !FindProcAddress( "GetGameAPI", dllName, modGetGameAPI ) ||
				!FindProcAddress( "vmMain", dllName, modVmMain ) ||
				!FindProcAddress( "dllEntry", dllName, modDllEntry ) ||
				!FindProcAddress( "SetOriginalFunctions", dllName, modSetOriginalFunctions ) )
			{
				FreeLibrary( g_modJagamex86 );
				g_modJagamex86 = 0;
			}
			else
			{
				FindProcAddress( "Shutdown", dllName, g_modShutdown ); // optional - not bad if it fails.
				modSetOriginalFunctions( g_realGetGameAPI, g_realDllEntry, g_realVmMain );
				g_realGetGameAPI = modGetGameAPI;
				g_realDllEntry = modDllEntry;
				g_realVmMain = modVmMain;
			}
		}
		else
		{
			g_imports.Printf( "^5No %s available - forwarding to original_jagamex86.dll.\n", dllName );
		}
	}

	// call the "real" GetGameAPI
	g_exports = g_realGetGameAPI( &g_imports );
	if( !g_exports )
	{
		// if that failed, clean up and pass on failure
		g_realGetGameAPI = 0;
		g_realDllEntry = 0;
		g_realVmMain = 0;
		assert( FreeLibrary( g_originalJagamex86 ) );
		g_originalJagamex86 = 0;
		return 0;
	}
	// Change Shutdown to our own wrapper which prepares for library freeing
	g_realShutdown = g_exports->Shutdown;
	g_exports->Shutdown = ShutdownWrapper;

	g_imports.Printf( "^5Successfully loaded original_jagamex86.dll\n" );
	return g_exports;
}