void TIMER_Save( void ) { int j; gentity_t *ent; ojk::SavedGameHelper saved_game( ::gi.saved_game); for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ ) { int numTimers = TIMER_GetCount(j); if ( !ent->inuse && numTimers) { // Com_Printf( "WARNING: ent with timers not inuse\n" ); assert(numTimers); TIMER_Clear( j ); numTimers = 0; } //Write out the timer information saved_game.write_chunk<int32_t>( INT_ID('T', 'I', 'M', 'E'), numTimers); gtimer_t *p = g_timers[j]; assert ((numTimers && p) || (!numTimers && !p)); while(p) { const char *timerID = p->id.c_str(); const int length = strlen(timerID) + 1; const int time = p->time - level.time; //convert this back to delta so we can use SET after loading assert( length < 1024 );//This will cause problems when loading the timer if longer //Write out the string size and data saved_game.write_chunk<int32_t>( INT_ID('T', 'S', 'L', 'N'), length); saved_game.write_chunk( INT_ID('T', 'S', 'N', 'M'), timerID, length); //Write out the timer data saved_game.write_chunk<int32_t>( INT_ID('T', 'D', 'T', 'A'), time); p = p->next; } } }
void TIMER_Save( void ) { int j; gentity_t *ent; for ( j = 0, ent = &g_entities[0]; j < MAX_GENTITIES; j++, ent++ ) { unsigned char numTimers = TIMER_GetCount(j); if ( !ent->inuse && numTimers) { // Com_Printf( "WARNING: ent with timers not inuse\n" ); assert(numTimers); TIMER_Clear( j ); numTimers = 0; } //Write out the timer information gi.AppendToSaveGame(INT_ID('T','I','M','E'), (void *)&numTimers, sizeof(numTimers)); gtimer_t *p = g_timers[j]; assert ((numTimers && p) || (!numTimers && !p)); while(p) { const char *timerID = p->id.c_str(); const int length = strlen(timerID) + 1; const int time = p->time - level.time; //convert this back to delta so we can use SET after loading assert( length < 1024 );//This will cause problems when loading the timer if longer //Write out the id string gi.AppendToSaveGame(INT_ID('T','M','I','D'), (void *) timerID, length); //Write out the timer data gi.AppendToSaveGame(INT_ID('T','D','T','A'), (void *) &time, sizeof( time ) ); p = p->next; } } }
void TIMER_Clear( gentity_t *ent ) { if ( ent ) TIMER_Clear( ent->s.number ); }
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; }
/* ================= 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); }