예제 #1
0
qboolean G_ActivateBehavior (gentity_t *self, int bset )
{
	bState_t	bSID = (bState_t)-1;
	char *bs_name = NULL;

	if ( !self )
	{
		return qfalse;
	}

	bs_name = self->behaviorSet[bset];
	
	if( !(VALIDSTRING( bs_name )) )
	{
		return qfalse;
	}

	if ( self->NPC )
	{
		bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
	}

	if(bSID > -1)
	{
		self->NPC->tempBehavior = BS_DEFAULT;
		self->NPC->behaviorState = bSID;
		if ( bSID == BS_SEARCH || bSID == BS_WANDER )
		{
			//FIXME: Reimplement?
			if( self->waypoint != WAYPOINT_NONE )
			{
				NPC_BSSearchStart( self->waypoint, bSID );
			}
			else
			{
				self->waypoint = NAV::GetNearestNode(self);
				if( self->waypoint != WAYPOINT_NONE )
				{
					NPC_BSSearchStart( self->waypoint, bSID );
				}
			}
		}
	}
	else
	{
		Quake3Game()->DebugPrint( IGameInterface::WL_VERBOSE, "%s attempting to run bSet %s (%s)\n", self->targetname, GetStringForID( BSETTable, bset ), bs_name );
		Quake3Game()->RunScript( self, bs_name );
	}
	return qtrue;
}
예제 #2
0
void WriteLevel(qboolean qbAutosave)
{
	if (!qbAutosave) //-always save the client
	{
		// write out one client - us!
		//
		assert(level.maxclients == 1);	// I'll need to know if this changes, otherwise I'll need to change the way ReadGame works
		gclient_t client = level.clients[0];
		EnumerateFields(savefields_gClient, (byte *)&client, 'GCLI', sizeof(client));	
		WriteLevelLocals();	// level_locals_t level	
	}

	OBJ_SaveObjectiveData();
	FX_Write();

	/////////////
	WriteGEntities(qbAutosave);
	Quake3Game()->VariableSave();
	G_LoadSave_WriteMiscData();

	extern void CG_WriteTheEvilCGHackStuff(void);
	CG_WriteTheEvilCGHackStuff();

	// (Do NOT put any write-code below this line)
	//
	// put out an end-marker so that the load code can check everything was read in...
	//
	static int iDONE = 1234;
	gi.AppendToSaveGame('DONE', &iDONE, sizeof(iDONE));
}
예제 #3
0
void target_counter_use( gentity_t *self, gentity_t *other, gentity_t *activator )
{
	if ( self->count == 0 )
	{
		return;
	}
	
	//gi.Printf("target_counter %s used by %s, entnum %d\n", self->targetname, activator->targetname, activator->s.number );
	self->count--;

	if ( activator )
	{
		Quake3Game()->DebugPrint( IGameInterface::WL_VERBOSE, "target_counter %s used by %s (%d/%d)\n", self->targetname, activator->targetname, (self->max_health-self->count), self->max_health );
	}

	if ( self->count )
	{
		if ( self->target2 )
		{
			//gi.Printf("target_counter %s firing target2 from %s, entnum %d\n", self->targetname, activator->targetname, activator->s.number );
			G_UseTargets2( self, activator, self->target2 );
		}
		return;
	}
	
	G_ActivateBehavior( self,BSET_USE );

	if ( self->spawnflags & 128 )
	{
		self->svFlags |= SVF_INACTIVE;
	}

	self->activator = activator;
	G_UseTargets( self, activator );

	if ( self->count == 0 )
	{
		if ( self->bounceCount == 0 )
		{
			return;
		}
		self->count = self->max_health;
		if ( self->bounceCount > 0 )
		{//-1 means bounce back forever
			self->bounceCount--; 
		}
	}
}
예제 #4
0
void WriteLevel(qboolean qbAutosave)
{
	if (!qbAutosave) //-always save the client
	{
		// write out one client - us!
		//
		assert(level.maxclients == 1);	// I'll need to know if this changes, otherwise I'll need to change the way ReadGame works
		gclient_t client = level.clients[0];
		EnumerateFields(savefields_gClient, &client, INT_ID('G','C','L','I'));
		WriteLevelLocals();	// level_locals_t level
	}

	OBJ_SaveObjectiveData();
	FX_Write();

	/////////////
	WriteGEntities(qbAutosave);
	Quake3Game()->VariableSave();
	G_LoadSave_WriteMiscData();

	extern void CG_WriteTheEvilCGHackStuff(void);
	CG_WriteTheEvilCGHackStuff();

	// (Do NOT put any write-code below this line)
	//
	// put out an end-marker so that the load code can check everything was read in...
	//
	static int iDONE = 1234;

	ojk::SavedGameHelper saved_game(
		::gi.saved_game);

	saved_game.write_chunk<int32_t>(
		INT_ID('D', 'O', 'N', 'E'),
		iDONE);
}
예제 #5
0
/*
=================
ConsoleCommand
// these are added in cg_main, CG_Init so they tab-complete
=================
*/
qboolean	ConsoleCommand( void ) {
	char	*cmd;

	cmd = gi.argv(0);

	if ( Q_stricmp (cmd, "entitylist") == 0 ) 
	{
		Svcmd_EntityList_f();
		return qtrue;
	}

	if (Q_stricmp (cmd, "game_memory") == 0) {
		Svcmd_GameMem_f();
		return qtrue;
	}

//	if (Q_stricmp (cmd, "addbot") == 0) {
//		Svcmd_AddBot_f();
//		return qtrue;
//	}

	if (Q_stricmp (cmd, "nav") == 0) 
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_Nav_f ();
		return qtrue;
	}

	if (Q_stricmp (cmd, "npc") == 0) 
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_NPC_f ();
		return qtrue;
	}

	if (Q_stricmp (cmd, "use") == 0) 
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_Use_f ();
		return qtrue;
	}

	if ( Q_stricmp( cmd, "ICARUS" ) == 0 )	
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}

		Quake3Game()->Svcmd();

		return qtrue;
	}

	if ( Q_stricmp( cmd, "saberColor" ) == 0 )	
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_SaberColor_f();
		return qtrue;
	}

	if ( Q_stricmp( cmd, "saber" ) == 0 )
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_Saber_f();
		return qtrue;
	}

	if ( Q_stricmp( cmd, "saberblade" ) == 0 )
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		Svcmd_SaberBlade_f();
		return qtrue;
	}


	if ( Q_stricmp( cmd, "setForceJump" ) == 0 )	
	{
		Svcmd_ForceJump_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setSaberThrow" ) == 0 )	
	{
		Svcmd_SaberThrow_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceHeal" ) == 0 )	
	{
		Svcmd_ForceHeal_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForcePush" ) == 0 )	
	{
		Svcmd_ForcePush_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForcePull" ) == 0 )	
	{
		Svcmd_ForcePull_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceSpeed" ) == 0 )	
	{
		Svcmd_ForceSpeed_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceGrip" ) == 0 )	
	{
		Svcmd_ForceGrip_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceLightning" ) == 0 )	
	{
		Svcmd_ForceLightning_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setMindTrick" ) == 0 )	
	{
		Svcmd_MindTrick_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setSaberDefense" ) == 0 )	
	{
		Svcmd_SaberDefense_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setSaberOffense" ) == 0 )	
	{
		Svcmd_SaberOffense_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceRage" ) == 0 )	
	{
		Svcmd_ForceSetLevel_f( FP_RAGE );
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceDrain" ) == 0 )	
	{
		Svcmd_ForceSetLevel_f( FP_DRAIN );
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceProtect" ) == 0 )	
	{
		Svcmd_ForceSetLevel_f( FP_PROTECT );
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceAbsorb" ) == 0 )	
	{
		Svcmd_ForceSetLevel_f( FP_ABSORB );
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceSight" ) == 0 )	
	{
		Svcmd_ForceSetLevel_f( FP_SEE );
		return qtrue;
	}
	if ( Q_stricmp( cmd, "setForceAll" ) == 0 )	
	{
		Svcmd_ForceJump_f();
		Svcmd_SaberThrow_f();
		Svcmd_ForceHeal_f();
		Svcmd_ForcePush_f();
		Svcmd_ForcePull_f();
		Svcmd_ForceSpeed_f();
		Svcmd_ForceGrip_f();
		Svcmd_ForceLightning_f();
		Svcmd_MindTrick_f();
		Svcmd_SaberDefense_f();
		Svcmd_SaberOffense_f();
		Svcmd_ForceSetLevel_f( FP_RAGE );
		Svcmd_ForceSetLevel_f( FP_DRAIN );
		Svcmd_ForceSetLevel_f( FP_PROTECT );
		Svcmd_ForceSetLevel_f( FP_ABSORB );
		Svcmd_ForceSetLevel_f( FP_SEE );
		for ( int i = SS_NONE+1; i < SS_NUM_SABER_STYLES; i++ )
		{
			g_entities[0].client->ps.saberStylesKnown |= (1<<i);
		}
		return qtrue;
	}
	if ( Q_stricmp( cmd, "saberAttackCycle" ) == 0 )	
	{
		Svcmd_SaberAttackCycle_f();
		return qtrue;
	}
	if ( Q_stricmp( cmd, "runscript" ) == 0 ) 
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		char *cmd2 = gi.argv(1);

		if ( cmd2 && cmd2[0] )
		{
			char *cmd3 = gi.argv(2);
			if ( cmd3 && cmd3[0] )
			{
				gentity_t *found = NULL;
				if ( (found = G_Find(NULL, FOFS(targetname), cmd2 ) ) != NULL )
				{
					Quake3Game()->RunScript( found, cmd3 );
				}
				else
				{
					//can't find cmd2
					gi.Printf( S_COLOR_RED"runscript: can't find targetname %s\n", cmd2 );
				}
			}
			else
			{
				Quake3Game()->RunScript( &g_entities[0], cmd2 );
			}
		}
		else
		{
			gi.Printf( S_COLOR_RED"usage: runscript <ent targetname> scriptname\n" );
		}
		//FIXME: else warning
		return qtrue;
	}

	if ( Q_stricmp( cmd, "playerteam" ) == 0 ) 
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		char	*cmd2 = gi.argv(1);
		int		n;

		if ( !*cmd2 || !cmd2[0] )
		{
			gi.Printf( S_COLOR_RED"'playerteam' - change player team, requires a team name!\n" );
			gi.Printf( S_COLOR_RED"Valid team names are:\n");
			for ( n = (TEAM_FREE + 1); n < TEAM_NUM_TEAMS; n++ )
			{
				gi.Printf( S_COLOR_RED"%s\n", GetStringForID( TeamTable, n ) );
			}
		}
		else
		{
			team_t	team;

			team = (team_t)GetIDForString( TeamTable, cmd2 );
			if ( team == -1 )
			{
				gi.Printf( S_COLOR_RED"'playerteam' unrecognized team name %s!\n", cmd2 );
				gi.Printf( S_COLOR_RED"Valid team names are:\n");
				for ( n = TEAM_FREE; n < TEAM_NUM_TEAMS; n++ )
				{
					gi.Printf( S_COLOR_RED"%s\n", GetStringForID( TeamTable, n ) );
				}
			}
			else
			{
				g_entities[0].client->playerTeam = team;
				//FIXME: convert Imperial, Malon, Hirogen and Klingon to Scavenger?
			}
		}
		return qtrue;
	}

	if ( Q_stricmp( cmd, "control" ) == 0 )
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		char	*cmd2 = gi.argv(1);
		if ( !*cmd2 || !cmd2[0] )
		{
			if ( !G_ClearViewEntity( &g_entities[0] ) )
			{
				gi.Printf( S_COLOR_RED"control <NPC_targetname>\n", cmd2 );
			}
		}
		else
		{
			Q3_SetViewEntity( 0, cmd2 );
		}
		return qtrue;
	}

	if ( Q_stricmp( cmd, "grab" ) == 0 )
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		char	*cmd2 = gi.argv(1);
		if ( !*cmd2 || !cmd2[0] )
		{
			if ( !G_ReleaseEntity( &g_entities[0] ) )
			{
				gi.Printf( S_COLOR_RED"grab <NPC_targetname>\n", cmd2 );
			}
		}
		else
		{
			G_GrabEntity( &g_entities[0], cmd2 );
		}
		return qtrue;
	}

	if ( Q_stricmp( cmd, "knockdown" ) == 0 )
	{
		if ( !g_cheats->integer ) 
		{
			gi.SendServerCommand( 0, "print \"Cheats are not enabled on this server.\n\"");
			return qfalse;
		}
		G_Knockdown( &g_entities[0], &g_entities[0], vec3_origin, 300, qtrue );
		return qtrue;
	}

	if ( Q_stricmp( cmd, "playerModel" ) == 0 )
	{
		if ( gi.argc() == 1 )
		{
			gi.Printf( S_COLOR_RED"USAGE: playerModel <NPC Name>\n       playerModel <g2model> <skinhead> <skintorso> <skinlower>\n       playerModel player (builds player from customized menu settings)\n" );
			gi.Printf( "playerModel = %s ", va("%s %s %s %s\n", g_char_model->string, g_char_skin_head->string, g_char_skin_torso->string, g_char_skin_legs->string ) );
		}
		else if ( gi.argc() == 2 )
		{
			G_ChangePlayerModel( &g_entities[0], gi.argv(1) );
		}
		else if (  gi.argc() == 5 )
		{
			//instead of setting it directly via a command, we now store it in cvars
			//G_ChangePlayerModel( &g_entities[0], va("%s|%s|%s|%s", gi.argv(1), gi.argv(2), gi.argv(3), gi.argv(4)) );
			gi.cvar_set("g_char_model", gi.argv(1) );
			gi.cvar_set("g_char_skin_head", gi.argv(2) );
			gi.cvar_set("g_char_skin_torso", gi.argv(3) );
			gi.cvar_set("g_char_skin_legs", gi.argv(4) );
			G_InitPlayerFromCvars( &g_entities[0] );
		}
		return qtrue;
	}

	if ( Q_stricmp( cmd, "playerTint" ) == 0 )
	{
		if ( gi.argc() == 4 )
		{
			g_entities[0].client->renderInfo.customRGBA[0] = atoi(gi.argv(1));
			g_entities[0].client->renderInfo.customRGBA[1] = atoi(gi.argv(2));
			g_entities[0].client->renderInfo.customRGBA[2] = atoi(gi.argv(3));
			gi.cvar_set("g_char_color_red", gi.argv(1) );
			gi.cvar_set("g_char_color_green", gi.argv(2) );
			gi.cvar_set("g_char_color_blue", gi.argv(3) );
		}
		else
		{
			gi.Printf( S_COLOR_RED"USAGE: playerTint <red 0 - 255> <green 0 - 255> <blue 0 - 255>\n" );
			gi.Printf( "playerTint = %s\n", va("%d %d %d", g_char_color_red->integer, g_char_color_green->integer, g_char_color_blue->integer ) );
		}
		return qtrue;
	}
	if ( Q_stricmp( cmd, "nexttestaxes" ) == 0 )
	{
		G_NextTestAxes();
	}

	if ( Q_stricmp( cmd, "exitview" ) == 0 )
	{
		Svcmd_ExitView_f();
	}
	
	if (Q_stricmp (cmd, "iknowkungfu") == 0)
	{
		gi.cvar_set( "g_debugMelee", "1" );
		G_SetWeapon( &g_entities[0], WP_MELEE );
		for ( int i = FP_FIRST; i < NUM_FORCE_POWERS; i++ )
		{
			g_entities[0].client->ps.forcePowersKnown |= ( 1 << i );
			if ( i == FP_TELEPATHY )
			{
				g_entities[0].client->ps.forcePowerLevel[i] = FORCE_LEVEL_4;
			}
			else
			{
				g_entities[0].client->ps.forcePowerLevel[i] = FORCE_LEVEL_3;
			}
		}
	}

	return qfalse;
}
예제 #6
0
void scriptrunner_run (gentity_t *self)
{
	/*
	if (self->behaviorSet[BSET_USE])
	{	
		char	newname[MAX_FILENAME_LENGTH];

		sprintf((char *) &newname, "%s/%s", Q3_SCRIPT_DIR, self->behaviorSet[BSET_USE] );

		ICARUS_RunScript( self, newname );
	}
	*/

	if ( self->count != -1 )
	{
		if ( self->count <= 0 )
		{
			self->e_UseFunc = useF_NULL;
			self->behaviorSet[BSET_USE] = NULL;
			return;
		}
		else
		{
			--self->count;
		}
	}

	if (self->behaviorSet[BSET_USE])
	{
		if ( self->spawnflags & 1 )
		{
			if ( !self->activator )
			{
				Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "target_scriptrunner tried to run on invalid entity!\n");
				return;
			}

			if ( self->activator->m_iIcarusID == IIcarusInterface::ICARUS_INVALID )
			{//Need to be initialized through ICARUS
				if ( !self->activator->script_targetname || !self->activator->script_targetname[0] )
				{
					//We don't have a script_targetname, so create a new one
					self->activator->script_targetname = va( "newICARUSEnt%d", numNewICARUSEnts++ );
				}

				if ( Quake3Game()->ValidEntity( self->activator ) )
				{
					Quake3Game()->InitEntity( self->activator );
				}
				else
				{
					Quake3Game()->DebugPrint( IGameInterface::WL_ERROR, "target_scriptrunner tried to run on invalid ICARUS activator!\n");
					return;
				}
			}

			Quake3Game()->DebugPrint( IGameInterface::WL_VERBOSE, "target_scriptrunner running %s on activator %s\n", self->behaviorSet[BSET_USE], self->activator->targetname );

			Quake3Game()->RunScript( self->activator, self->behaviorSet[BSET_USE] );
		}
		else
		{
			if ( self->activator )
			{
				Quake3Game()->DebugPrint( IGameInterface::WL_VERBOSE, "target_scriptrunner %s used by %s\n", self->targetname, self->activator->targetname );
			}
			G_ActivateBehavior( self, BSET_USE );
		}
	}

	if ( self->wait )
	{
		self->nextthink = level.time + self->wait;
	}
}
예제 #7
0
파일: g_utils.cpp 프로젝트: BSzili/OpenJK
/*
=================
G_FreeEntity

Marks the entity as free
=================
*/
void G_FreeEntity( gentity_t *ed ) {
	gi.unlinkentity (ed);		// unlink from world

	// Free the Game Element (the entity) and delete the Icarus ID.
	Quake3Game()->FreeEntity( ed );

	/*if ( ed->neverFree ) {
		return;
	}*/

	if (ed->wayedge!=0)
	{
		NAV::WayEdgesNowClear(ed);
	}


	// remove any ghoul2 models here
	gi.G2API_CleanGhoul2Models(ed->ghoul2);

	if (ed->client && ed->client->NPC_class == CLASS_VEHICLE)
	{
		Vehicle_Remove(ed);

		if ( ed->m_pVehicle )
		{
			gi.Free( ed->m_pVehicle );
		}
		//CVehicleNPC *pVeh = static_cast< CVehicleNPC * >( ed->NPC );
		//delete pVeh;
		//gi.Free((char*)ed->NPC-4);//crazy hack for class vtables
	} 

	//free this stuff now, rather than waiting until the level ends.
	if (ed->NPC)
	{
		gi.Free(ed->NPC);

		if(ed->client->clientInfo.customBasicSoundDir && gi.bIsFromZone(ed->client->clientInfo.customBasicSoundDir, TAG_G_ALLOC)) {
			gi.Free(ed->client->clientInfo.customBasicSoundDir);
		}
		if(ed->client->clientInfo.customCombatSoundDir) {
#ifdef _MSC_VER
			assert(*(unsigned int*)ed->client->clientInfo.customCombatSoundDir != 0xfeeefeee);
#endif
			gi.Free(ed->client->clientInfo.customCombatSoundDir);
		}
		if(ed->client->clientInfo.customExtraSoundDir) {
#ifdef _MSC_VER
			assert(*(unsigned int*)ed->client->clientInfo.customExtraSoundDir != 0xfeeefeee);
#endif
			gi.Free(ed->client->clientInfo.customExtraSoundDir);
		}
		if(ed->client->clientInfo.customJediSoundDir) {
			gi.Free(ed->client->clientInfo.customJediSoundDir);
		}
		if(ed->client->ps.saber[0].name && gi.bIsFromZone(ed->client->ps.saber[0].name, TAG_G_ALLOC) ) {
			gi.Free(ed->client->ps.saber[0].name);
		}
		if(ed->client->ps.saber[0].model && gi.bIsFromZone(ed->client->ps.saber[0].model, TAG_G_ALLOC) ) {
			gi.Free(ed->client->ps.saber[0].model);
		}
		if(ed->client->ps.saber[1].name && gi.bIsFromZone(ed->client->ps.saber[1].name, TAG_G_ALLOC) ) {
			gi.Free(ed->client->ps.saber[1].name);
		}
		if(ed->client->ps.saber[1].model && gi.bIsFromZone(ed->client->ps.saber[1].model, TAG_G_ALLOC) ) {
 			gi.Free(ed->client->ps.saber[1].model);
		}

		gi.Free(ed->client);
	}

	if (ed->soundSet && gi.bIsFromZone(ed->soundSet, TAG_G_ALLOC)) {
		gi.Free(ed->soundSet);
	}
	if (ed->targetname && gi.bIsFromZone(ed->targetname, TAG_G_ALLOC)) {
		gi.Free(ed->targetname);
	}
	if (ed->NPC_targetname && gi.bIsFromZone(ed->NPC_targetname, TAG_G_ALLOC)) {
		gi.Free(ed->NPC_targetname);
	}
	if (ed->NPC_type && gi.bIsFromZone(ed->NPC_type, TAG_G_ALLOC)) {
		gi.Free(ed->NPC_type);
	}
	if (ed->classname && gi.bIsFromZone(ed->classname, TAG_G_ALLOC)) {
		gi.Free(ed->classname );
	}
	if (ed->message && gi.bIsFromZone(ed->message, TAG_G_ALLOC)) {
		gi.Free(ed->message);
	}	
	if (ed->model && gi.bIsFromZone(ed->model, TAG_G_ALLOC)) {
		gi.Free(ed->model);
	}	

//scripting
	if (ed->script_targetname && gi.bIsFromZone(ed->script_targetname, TAG_G_ALLOC)) {
		gi.Free(ed->script_targetname);
	}
	if (ed->cameraGroup && gi.bIsFromZone(ed->cameraGroup, TAG_G_ALLOC)) {
		gi.Free(ed->cameraGroup);
	}
	if (ed->paintarget && gi.bIsFromZone(ed->paintarget, TAG_G_ALLOC)) {
		gi.Free(ed->paintarget);
	}
	if(ed->parms) {
		gi.Free(ed->parms);
	}
	
//Limbs
	if (ed->target && gi.bIsFromZone(ed->target , TAG_G_ALLOC)) {
		gi.Free(ed->target);
	}
	if (ed->target2 && gi.bIsFromZone(ed->target2 , TAG_G_ALLOC)) {
		gi.Free(ed->target2);
	}
	if (ed->target3 && gi.bIsFromZone(ed->target3 , TAG_G_ALLOC)) {
		gi.Free(ed->target3);
	}
	if (ed->target4 && gi.bIsFromZone(ed->target4 , TAG_G_ALLOC)) {
		gi.Free(ed->target4);
	}
	if (ed->opentarget) {
		gi.Free(ed->opentarget);
	}
	if (ed->closetarget) {
		gi.Free(ed->closetarget);
	}
	// Free any associated timers
	TIMER_Clear(ed->s.number);

	memset (ed, 0, sizeof(*ed));
	ed->s.number = ENTITYNUM_NONE;
	ed->classname = "freed";
	ed->freetime = level.time;
	ed->inuse = qfalse;
	ClearInUse(ed);
}
예제 #8
0
static void ReadGEntities(qboolean qbAutosave)
{
	int		iCount;
	
	gi.ReadFromSaveGame('NMED', (void *)&iCount, sizeof(iCount));

	int iPreviousEntRead = -1;
	int i;
	for (i=0; i<iCount; i++)
	{
		int iEntIndex;
		gi.ReadFromSaveGame('EDNM', (void *)&iEntIndex, sizeof(iEntIndex));

		if (iEntIndex >= globals.num_entities)
		{
			globals.num_entities = iEntIndex + 1;
		}

		if (iPreviousEntRead != iEntIndex-1)
		{
			for (int j=iPreviousEntRead+1; j!=iEntIndex; j++)
			{
				if ( g_entities[j].inuse )		// not actually necessary
				{
					G_FreeEntity(&g_entities[j]);
				}
			}
		}
		iPreviousEntRead = iEntIndex;

		// slightly naff syntax here, but makes a few ops clearer later...
		//
		gentity_t  entity;
		gentity_t* pEntOriginal	= &entity;	
		gentity_t* pEnt			= &g_entities[iEntIndex];
		*pEntOriginal = *pEnt;	// struct copy, so we can refer to original
		
		pEntOriginal->ghoul2.kill();
		gi.unlinkentity(pEnt);
		Quake3Game()->FreeEntity( pEnt );
	
		//
		// sneaky:  destroy the ghoul2 object within this struct before binary-loading over the top of it...
		//
		gi.G2API_LoadSaveCodeDestructGhoul2Info(pEnt->ghoul2);
		pEnt->ghoul2.kill();
		EvaluateFields(savefields_gEntity, (byte *)pEnt, (byte *)pEntOriginal, 'GENT', sizeof(*pEnt),qfalse);
		pEnt->ghoul2.kill();

		// now for any fiddly bits...
		//
		if (pEnt->NPC)	// will be qtrue/qfalse
		{
			gNPC_t tempNPC;

			EvaluateFields(savefields_gNPC, (byte *)&tempNPC,(byte *)pEntOriginal->NPC, 'GNPC', sizeof (*pEnt->NPC),qfalse);
			
			// so can we pinch the original's one or do we have to alloc a new one?...
			//
			if (pEntOriginal->NPC)
			{
				// pinch this G_Alloc handle...
				//
				pEnt->NPC = pEntOriginal->NPC;
			}
			else
			{
				// original didn't have one (hmmm...), so make a new one...
				//
				//assert(0);	// I want to know about this, though not in release
				pEnt->NPC = (gNPC_t *) G_Alloc(sizeof(*pEnt->NPC));
			}

			// copy over the one we've just loaded...
			//
			*pEnt->NPC = tempNPC;	// struct copy

			//FIXME: do we need to do these too?
			/*
			if ( pEnt->s.number )
			{//not player
				G_LoadAnimFileSet( *pEnt, *pEnt->NPC_type );
				G_SetSkin( *pEnt, *pEnt->NPC_type, NULL );//  it probably wasn't the default skin, do we need this at all?
			}
			*/
		}

		if (pEnt->client == (gclient_t*) -2)	// one of Mike G's NPC clients?
		{
			gclient_t tempGClient;			

			EvaluateFields(savefields_gClient, (byte *)&tempGClient, (byte *)pEntOriginal->client, 'GCLI', sizeof(*pEnt->client),qtrue);//qfalse);

			// can we pinch the original's client handle or do we have to alloc a new one?...
			//
			if (pEntOriginal->client)
			{
				// pinch this G_Alloc handle...
				//
				pEnt->client = pEntOriginal->client;
			}
			else
			{
				// original didn't have one (hmmm...) so make a new one...
				//				
				pEnt->client = (gclient_t *) G_Alloc(sizeof(*pEnt->client));
			}

			// copy over the one we've just loaded....
			//
			*pEnt->client = tempGClient;	// struct copy

			if ( pEnt->s.number )
			{//not player
				G_ReloadSaberData( pEnt );
			}
		}

		// Some Icarus thing... (probably)
		//
		if (pEnt->parms)	// will be qtrue/qfalse
		{
			parms_t tempParms;
			
			gi.ReadFromSaveGame('PARM', &tempParms, sizeof(tempParms));

			// so can we pinch the original's one or do we have to alloc a new one?...
			//
			if (pEntOriginal->parms)
			{
				// pinch this G_Alloc handle...
				//
				pEnt->parms = pEntOriginal->parms;
			}
			else
			{
				// original didn't have one, so make a new one...
				//				
				pEnt->parms = (parms_t *) G_Alloc(sizeof(*pEnt->parms));
			}

			// copy over the one we've just loaded...
			//
			*pEnt->parms = tempParms;	// struct copy
		}

		if (pEnt->m_pVehicle)	// will be qtrue/qfalse
		{
			Vehicle_t tempVehicle;
			
			EvaluateFields(savefields_gVHIC, (byte *)&tempVehicle,(byte *)pEntOriginal->m_pVehicle, 'VHIC', sizeof (*pEnt->m_pVehicle),qfalse);

			// so can we pinch the original's one or do we have to alloc a new one?...
			//
			if (pEntOriginal->m_pVehicle)
			{
				// pinch this G_Alloc handle...
				//
				pEnt->m_pVehicle = pEntOriginal->m_pVehicle;
			}
			else
			{
				// original didn't have one, so make a new one...
				//				
				pEnt->m_pVehicle = (Vehicle_t *) gi.Malloc( sizeof(Vehicle_t), TAG_G_ALLOC, qfalse );
			}

			// copy over the one we've just loaded...
			//
			*pEnt->m_pVehicle = tempVehicle;	// struct copy
		}

		// the scary ghoul2 stuff...  (fingers crossed)
		//
		{
			char *pGhoul2Data = NULL;
			gi.ReadFromSaveGame('GHL2', 0, 0, (void**)&pGhoul2Data);
			gi.G2API_LoadGhoul2Models(pEnt->ghoul2, pGhoul2Data);	// if it's going to crash anywhere...   <g>
			gi.Free(pGhoul2Data);
		}

//		gi.unlinkentity (pEntOriginal);		
//		ICARUS_FreeEnt( pEntOriginal );
//		*pEntOriginal = *pEnt;	// struct copy				
//		qboolean qbLinked = pEntOriginal->linked;
//		pEntOriginal->linked = qfalse;
//		if (qbLinked)
//		{
//			gi.linkentity (pEntOriginal);		
//		}

		// because the sytem stores sfx_t handles directly instead of the set, we have to reget the set's sfx_t...
		//
		if (pEnt->s.eType == ET_MOVER && pEnt->s.loopSound>0)
		{
			if ( VALIDSTRING( pEnt->soundSet ))
			{
				extern int BMS_MID;	// from g_mover
				pEnt->s.loopSound = CAS_GetBModelSound( pEnt->soundSet, BMS_MID );
				if (pEnt->s.loopSound == -1)
				{
					pEnt->s.loopSound = 0;
				}
			}
		}

		// NPCs and other ents store waypoints that aren't valid after a load
		pEnt->waypoint = 0;

		qboolean qbLinked = pEnt->linked;
		pEnt->linked = qfalse;
		if (qbLinked)
		{
			gi.linkentity (pEnt);		
		}		
	}

	//Read in all the entity timers
	TIMER_Load();//ReadEntityTimers();

	if (!qbAutosave)
	{
		// now zap any g_ents that were inuse when the level was loaded, but are no longer in use in the saved version
		//	that we've just loaded...
		//
		for (i=iPreviousEntRead+1; i<globals.num_entities; i++)
		{
			if ( g_entities[i].inuse )	// not actually necessary
			{
				G_FreeEntity(&g_entities[i]);
			}
		}	

		//Load ICARUS information
		Quake3Game()->ClearEntityList();

		IIcarusInterface::GetIcarus()->Load();

		// check that Icarus has loaded everything it saved out by having a marker chunk after it...
		//
		static int iBlah = 1234;
		gi.ReadFromSaveGame('ICOK', &iBlah, sizeof(iBlah));
	}
	if (!qbAutosave)
	{
		ReadInUseBits();//really shouldn't need to read these bits in at all, just restore them from the ents...
	}
}
예제 #9
0
void ReadLevel(qboolean qbAutosave, qboolean qbLoadTransition)
{
	if ( qbLoadTransition )
	{
		// I STRONGLY SUSPECT THAT THIS WILL JUST ERR_DROP BECAUSE OF THE LOAD SWAPPING OF THE CHUNK-ORDER
		//	BELOW BETWEEN OBJECTIVES AND LEVEL_LOCALS, SO I'M GUESSING THIS IS SOME OLD EF1 JUNK?
		// IN ANY CASE, LET'S MAKE SURE...   // -ste (no idea who wrote the comment stuff below, did it ever work?)
		//
		assert(0);
		//
		//loadtransitions do not need to read the objectives and client data from the level they're going to
		//In a loadtransition, client data is carried over on the server and will be stomped later anyway.
		//The objective info (in client->sess data), however, is read in from G_ReadSessionData which is called before this func,
		//we do NOT want to stomp that session data when doing a load transition
		
		//However, we should still save this info out because these savegames may need to be
		//loaded normally later- perhaps if you die and need to respawn, perhaps as some kind
		//of emergency savegame for resuming, etc.

		//SO: We read it in, but throw it away.
		
		//Read & throw away gclient info
		gclient_t junkClient;
		EvaluateFields(savefields_gClient, (byte *)&junkClient, (byte *)&level.clients[0], 'GCLI', sizeof(*level.clients), qtrue);//qfalse);

		ReadLevelLocals();	// level_locals_t level	

		//Read & throw away objective info
		objectives_t	junkObj[MAX_MISSION_OBJ];
		gi.ReadFromSaveGame('OBJT', (void *) &junkObj, 0);
	}
	else
	{
		if (!qbAutosave )//always load the client unless it's an autosave
		{
			assert(level.maxclients == 1);	// I'll need to know if this changes, otherwise I'll need to change the way things work
		
			gclient_t GClient;
			EvaluateFields(savefields_gClient, (byte *)&GClient, (byte *)&level.clients[0], 'GCLI', sizeof(*level.clients), qtrue);//qfalse);
			level.clients[0] = GClient;	// struct copy
			ReadLevelLocals();	// level_locals_t level	
		}
		
		OBJ_LoadObjectiveData();//loads mission objectives AND tactical info
	}

	FX_Read();

	/////////////

	ReadGEntities(qbAutosave);
	Quake3Game()->VariableLoad();
	G_LoadSave_ReadMiscData();

	extern void CG_ReadTheEvilCGHackStuff(void);
	CG_ReadTheEvilCGHackStuff();

	// (Do NOT put any read-code below this line)
	//
	// check that the whole file content was loaded by specifically requesting an end-marker...
	//
	static int iDONE = 1234;
	gi.ReadFromSaveGame('DONE', &iDONE, sizeof(iDONE));
}