void CLevel::ClearAllObjects () { u32 CLObjNum = Level().Objects.o_count(); bool ParentFound = true; while (ParentFound) { ParentFound = false; for (u32 i=0; i<CLObjNum; i++) { CObject* pObj = Level().Objects.o_get_by_iterator(i); if (!pObj->H_Parent()) continue; //----------------------------------------------------------- NET_Packet GEN; GEN.w_begin (M_EVENT); //--------------------------------------------- GEN.w_u32 (Level().timeServer()); GEN.w_u16 (GE_OWNERSHIP_REJECT); GEN.w_u16 (pObj->H_Parent()->ID()); GEN.w_u16 (u16(pObj->ID())); game_events->insert (GEN); if (g_bDebugEvents) ProcessGameEvents(); //------------------------------------------------------------- ParentFound = true; //------------------------------------------------------------- #ifdef DEBUG Msg ("Rejection of %s[%d] from %s[%d]", *(pObj->cNameSect()), pObj->ID(), *(pObj->H_Parent()->cNameSect()), pObj->H_Parent()->ID()); #endif }; ProcessGameEvents(); }; CLObjNum = Level().Objects.o_count(); for (u32 i=0; i<CLObjNum; i++) { CObject* pObj = Level().Objects.o_get_by_iterator(i); R_ASSERT(pObj->H_Parent()==NULL); //----------------------------------------------------------- NET_Packet GEN; GEN.w_begin (M_EVENT); //--------------------------------------------- GEN.w_u32 (Level().timeServer()); GEN.w_u16 (GE_DESTROY); GEN.w_u16 (u16(pObj->ID())); game_events->insert (GEN); if (g_bDebugEvents) ProcessGameEvents(); //------------------------------------------------------------- ParentFound = true; //------------------------------------------------------------- #ifdef DEBUG Msg ("Destruction of %s[%d]", *(pObj->cNameSect()), pObj->ID()); #endif }; ProcessGameEvents(); };
void CLevel::OnFrame () { #ifdef DEBUG_MEMORY_MANAGER debug_memory_guard __guard__; #endif // DEBUG_MEMORY_MANAGER #ifdef DEBUG DBG_RenderUpdate( ); #endif // #ifdef DEBUG Fvector temp_vector; m_feel_deny.feel_touch_update (temp_vector, 0.f); if (GameID()!=eGameIDSingle) psDeviceFlags.set(rsDisableObjectsAsCrows,true); else psDeviceFlags.set(rsDisableObjectsAsCrows,false); // commit events from bullet manager from prev-frame Device.Statistic->TEST0.Begin (); BulletManager().CommitEvents (); Device.Statistic->TEST0.End (); // Client receive if (net_isDisconnected()) { if (OnClient() && GameID() != eGameIDSingle) { #ifdef DEBUG Msg("* I'm disconnected, so clear all objects..."); #endif // #ifdef DEBUG ClearAllObjects(); } Engine.Event.Defer ("kernel:disconnect"); return; } else { Device.Statistic->netClient1.Begin(); ClientReceive (); Device.Statistic->netClient1.End (); } ProcessGameEvents (); if (m_bNeed_CrPr) make_NetCorrectionPrediction(); if(!g_dedicated_server ) { if (g_mt_config.test(mtMap)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(m_map_manager,&CMapManager::Update)); else MapManager().Update (); if( IsGameTypeSingle() && Device.dwPrecacheFrame==0 ) { if (g_mt_config.test(mtMap)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(m_game_task_manager,&CGameTaskManager::UpdateTasks)); else GameTaskManager().UpdateTasks(); } } // Inherited update inherited::OnFrame (); // Draw client/server stats if ( !g_dedicated_server && psDeviceFlags.test(rsStatistic)) { CGameFont* F = HUD().Font().pFontDI; if (!psNET_direct_connect) { if ( IsServer() ) { const IServerStatistic* S = Server->GetStatistic(); F->SetHeightI (0.015f); F->OutSetI (0.0f,0.5f); F->SetColor (D3DCOLOR_XRGB(0,255,0)); F->OutNext ("IN: %4d/%4d (%2.1f%%)", S->bytes_in_real, S->bytes_in, 100.f*float(S->bytes_in_real)/float(S->bytes_in)); F->OutNext ("OUT: %4d/%4d (%2.1f%%)", S->bytes_out_real, S->bytes_out, 100.f*float(S->bytes_out_real)/float(S->bytes_out)); F->OutNext ("client_2_sever ping: %d", net_Statistic.getPing()); F->OutNext ("SPS/Sended : %4d/%4d", S->dwBytesPerSec, S->dwBytesSended); F->OutNext ("sv_urate/cl_urate : %4d/%4d", psNET_ServerUpdate, psNET_ClientUpdate); F->SetColor (D3DCOLOR_XRGB(255,255,255)); struct net_stats_functor { xrServer* m_server; CGameFont* F; void operator()(IClient* C) { m_server->UpdateClientStatistic(C); F->OutNext("%10s: P(%d), BPS(%2.1fK), MRR(%2d), MSR(%2d), Retried(%2d), Blocked(%2d)", //Server->game->get_option_s(*C->Name,"name",*C->Name), C->name.c_str(), C->stats.getPing(), float(C->stats.getBPS()),// /1024, C->stats.getMPS_Receive (), C->stats.getMPS_Send (), C->stats.getRetriedCount(), C->stats.dwTimesBlocked ); } }; net_stats_functor tmp_functor; tmp_functor.m_server = Server; tmp_functor.F = F; Server->ForEachClientDo(tmp_functor); } if (IsClient()) { IPureClient::UpdateStatistic(); F->SetHeightI(0.015f); F->OutSetI (0.0f,0.5f); F->SetColor (D3DCOLOR_XRGB(0,255,0)); F->OutNext ("client_2_sever ping: %d", net_Statistic.getPing()); F->OutNext ("sv_urate/cl_urate : %4d/%4d", psNET_ServerUpdate, psNET_ClientUpdate); F->SetColor (D3DCOLOR_XRGB(255,255,255)); F->OutNext("P(%d), BPS(%2.1fK), MRR(%2d), MSR(%2d), Retried(%2d), Blocked(%2d), Sended(%2d), SPS(%2d)", //Server->game->get_option_s(C->Name,"name",C->Name), // C->Name, net_Statistic.getPing(), float(net_Statistic.getBPS()),// /1024, net_Statistic.getMPS_Receive (), net_Statistic.getMPS_Send (), net_Statistic.getRetriedCount(), net_Statistic.dwTimesBlocked, net_Statistic.dwBytesSended, net_Statistic.dwBytesPerSec ); #ifdef DEBUG if (!pStatGraphR) { pStatGraphR = new CStatGraph(); pStatGraphR->SetRect(50, 700, 300, 68, 0xff000000, 0xff000000); //m_stat_graph->SetGrid(0, 0.0f, 10, 1.0f, 0xff808080, 0xffffffff); pStatGraphR->SetMinMax(0.0f, 65536.0f, 1000); pStatGraphR->SetStyle(CStatGraph::stBarLine); pStatGraphR->AppendSubGraph(CStatGraph::stBarLine); } pStatGraphR->AppendItem(float(net_Statistic.getBPS()), 0xff00ff00, 0); F->OutSet(20.f, 700.f); F->OutNext("64 KBS"); #endif } } } else { #ifdef DEBUG if (pStatGraphR) xr_delete(pStatGraphR); #endif } // g_pGamePersistent->Environment().SetGameTime (GetGameDayTimeSec(),GetGameTimeFactor()); g_pGamePersistent->Environment().SetGameTime (GetEnvironmentGameDayTimeSec(),game->GetEnvironmentGameTimeFactor()); //Device.Statistic->cripting.Begin (); if (!g_dedicated_server) ai().script_engine().script_process (ScriptEngine::eScriptProcessorLevel)->update(); //Device.Statistic->Scripting.End (); m_ph_commander->update (); m_ph_commander_scripts->update (); // autosave_manager().update (); //просчитать полет пуль Device.Statistic->TEST0.Begin (); BulletManager().CommitRenderSet (); Device.Statistic->TEST0.End (); // update static sounds if(!g_dedicated_server) { if (g_mt_config.test(mtLevelSounds)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(m_level_sound_manager,&CLevelSoundManager::Update)); else m_level_sound_manager->Update (); } // deffer LUA-GC-STEP if (!g_dedicated_server) { if (g_mt_config.test(mtLUA_GC)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(this,&CLevel::script_gc)); else script_gc () ; } //----------------------------------------------------- if (pStatGraphR) { static float fRPC_Mult = 10.0f; static float fRPS_Mult = 1.0f; pStatGraphR->AppendItem(float(m_dwRPC)*fRPC_Mult, 0xffff0000, 1); pStatGraphR->AppendItem(float(m_dwRPS)*fRPS_Mult, 0xff00ff00, 0); }; }
void CLevel::remove_objects () { if (!IsGameTypeSingle()) Msg("CLevel::remove_objects - Start"); BOOL b_stored = psDeviceFlags.test(rsDisableObjectsAsCrows); Game().reset_ui (); if (OnServer()) { VERIFY (Server); Server->SLS_Clear (); } snd_Events.clear (); for (int i=0; i<6; ++i) { psNET_Flags.set (NETFLAG_MINIMIZEUPDATES,FALSE); // ugly hack for checks that update is twice on frame // we need it since we do updates for checking network messages ++(Device.dwFrame); psDeviceFlags.set (rsDisableObjectsAsCrows,TRUE); ClientReceive (); ProcessGameEvents (); Objects.Update (true); Sleep (100); } if (OnClient()) ClearAllObjects (); BulletManager().Clear (); ph_commander().clear (); ph_commander_scripts().clear(); if(!g_dedicated_server) space_restriction_manager().clear (); psDeviceFlags.set (rsDisableObjectsAsCrows, b_stored); g_b_ClearGameCaptions = true; if (!g_dedicated_server) ai().script_engine().collect_all_garbage (); stalker_animation_data_storage().clear (); VERIFY (Render); Render->models_Clear (FALSE); Render->clear_static_wallmarks (); #ifdef DEBUG if(!g_dedicated_server) if (!client_spawn_manager().registry().empty()) client_spawn_manager().dump (); #endif // DEBUG if(!g_dedicated_server) { VERIFY (client_spawn_manager().registry().empty()); client_spawn_manager().clear (); } for (int i=0; i<6; i++) { ++(Device.dwFrame); Objects.Update(true); } g_pGamePersistent->destroy_particles (false); //. xr_delete (m_seniority_hierarchy_holder); //. m_seniority_hierarchy_holder = xr_new<CSeniorityHierarchyHolder>(); if (!IsGameTypeSingle()) Msg("CLevel::remove_objects - End"); }
void CLevel::ClientReceive() { Demo_StartFrame(); Demo_Update(); m_dwRPC = 0; m_dwRPS = 0; for (NET_Packet* P = net_msg_Retreive(); P; P=net_msg_Retreive()) { //----------------------------------------------------- m_dwRPC++; m_dwRPS += P->B.count; //----------------------------------------------------- u16 m_type; u16 ID; P->r_begin (m_type); switch (m_type) { case M_MAP_SYNC: { shared_str map_name; P->r_stringZ(map_name); shared_str _name = net_Hosts.size() ? net_Hosts.front().dpSessionName:""; if(_name.size() && _name!=map_name && OnClient()) { Msg("!!! map sync failed. current is[%s] server is[%s]",m_name.c_str(), map_name.c_str()); Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",m_caServerOptions.size() ? size_t( xr_strdup(*m_caServerOptions)) : 0, m_caClientOptions.size() ? size_t(xr_strdup(*m_caClientOptions)) : 0); } }break; case M_SPAWN: { if (!m_bGameConfigStarted || !bReady) { Msg ("Unconventional M_SPAWN received : cgf[%s] | bReady[%s]", (m_bGameConfigStarted) ? "true" : "false", (bReady) ? "true" : "false"); break; } /*/ cl_Process_Spawn(*P); /*/ game_events->insert (*P); if (g_bDebugEvents) ProcessGameEvents(); //*/ } break; case M_EVENT: game_events->insert (*P); if (g_bDebugEvents) ProcessGameEvents(); break; case M_EVENT_PACK: NET_Packet tmpP; while (!P->r_eof()) { tmpP.B.count = P->r_u8(); P->r(&tmpP.B.data, tmpP.B.count); tmpP.timeReceive = P->timeReceive; game_events->insert (tmpP); if (g_bDebugEvents) ProcessGameEvents(); }; break; case M_UPDATE: { game->net_import_update (*P); //------------------------------------------- if (OnServer()) break; //------------------------------------------- }; // ни в коем случае нельзя здесь ставить break, т.к. в случае если все объекты не влазят в пакет M_UPDATE, // они досылаются через M_UPDATE_OBJECTS case M_UPDATE_OBJECTS: { Objects.net_Import (P); if (OnClient()) UpdateDeltaUpd(timeServer()); IClientStatistic pStat = Level().GetStatistic(); u32 dTime = 0; if ((Level().timeServer() + pStat.getPing()) < P->timeReceive) { dTime = pStat.getPing(); } else dTime = Level().timeServer() - P->timeReceive + pStat.getPing(); u32 NumSteps = ph_world->CalcNumSteps(dTime); SetNumCrSteps(NumSteps); }break; // case M_UPDATE_OBJECTS: // { // Objects.net_Import (P); // }break; //----------- for E3 ----------------------------- case M_CL_UPDATE: { if (OnClient()) break; P->r_u16 (ID); u32 Ping = P->r_u32(); CGameObject* O = smart_cast<CGameObject*>(Objects.net_Find (ID)); if (0 == O) break; O->net_Import(*P); //--------------------------------------------------- UpdateDeltaUpd(timeServer()); if (pObjects4CrPr.empty() && pActors4CrPr.empty()) break; if (O->CLS_ID != CLSID_OBJECT_ACTOR) break; u32 dTime = 0; if ((Level().timeServer() + Ping) < P->timeReceive) { #ifdef DEBUG // Msg("! TimeServer[%d] < TimeReceive[%d]", Level().timeServer(), P->timeReceive); #endif dTime = Ping; } else dTime = Level().timeServer() - P->timeReceive + Ping; u32 NumSteps = ph_world->CalcNumSteps(dTime); SetNumCrSteps(NumSteps); O->CrPr_SetActivationStep(u32(ph_world->m_steps_num) - NumSteps); AddActor_To_Actors4CrPr(O); }break; case M_MOVE_PLAYERS: { u8 Count = P->r_u8(); for (u8 i=0; i<Count; i++) { u16 ID = P->r_u16(); Fvector NewPos, NewDir; P->r_vec3(NewPos); P->r_vec3(NewDir); CActor* OActor = smart_cast<CActor*>(Objects.net_Find (ID)); if (0 == OActor) break; OActor->MoveActor(NewPos, NewDir); }; NET_Packet PRespond; PRespond.w_begin(M_MOVE_PLAYERS_RESPOND); Send(PRespond, net_flags(TRUE, TRUE)); }break; //------------------------------------------------ case M_CL_INPUT: { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_ImportInput(*P); }break; //--------------------------------------------------- case M_SV_CONFIG_NEW_CLIENT: InitializeClientGame(*P); break; case M_SV_CONFIG_GAME: game->net_import_state (*P); break; case M_SV_CONFIG_FINISHED: game_configured = TRUE; Msg("- Game configuring : Finished "); break; case M_MIGRATE_DEACTIVATE: // TO: Changing server, just deactivate { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_MigrateInactive (*P); if (bDebug) Log("! MIGRATE_DEACTIVATE",*O->cName()); } break; case M_MIGRATE_ACTIVATE: // TO: Changing server, full state { P->r_u16 (ID); CObject* O = Objects.net_Find (ID); if (0 == O) break; O->net_MigrateActive (*P); if (bDebug) Log("! MIGRATE_ACTIVATE",*O->cName()); } break; case M_CHAT: { char buffer[256]; P->r_stringZ(buffer); Msg ("- %s",buffer); } break; case M_GAMEMESSAGE: { if (!game) break; Game().OnGameMessage(*P); }break; case M_RELOAD_GAME: case M_LOAD_GAME: case M_CHANGE_LEVEL: { if(m_type==M_LOAD_GAME) { string256 saved_name; P->r_stringZ (saved_name); if(xr_strlen(saved_name) && ai().get_alife()) { CSavedGameWrapper wrapper(saved_name); if (wrapper.level_id() == ai().level_graph().level_id()) { Engine.Event.Defer ("Game:QuickLoad", size_t(xr_strdup(saved_name)), 0); break; } } } Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",size_t(xr_strdup(*m_caServerOptions)),size_t(xr_strdup(*m_caClientOptions))); }break; case M_SAVE_GAME: { ClientSave (); }break; case M_GAMESPY_CDKEY_VALIDATION_CHALLENGE: { OnGameSpyChallenge(P); }break; case M_AUTH_CHALLENGE: { OnBuildVersionChallenge(); }break; case M_CLIENT_CONNECT_RESULT: { OnConnectResult(P); }break; case M_CHAT_MESSAGE: { if (!game) break; Game().OnChatMessage(P); }break; case M_CLIENT_WARN: { if (!game) break; Game().OnWarnMessage(P); }break; case M_REMOTE_CONTROL_AUTH: case M_REMOTE_CONTROL_CMD: { Game().OnRadminMessage(m_type, P); }break; case M_CHANGE_LEVEL_GAME: { Msg("- M_CHANGE_LEVEL_GAME Received"); if (OnClient()) { Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",m_caServerOptions.size() ? size_t( xr_strdup(*m_caServerOptions)) : 0,m_caClientOptions.size() ? size_t(xr_strdup(*m_caClientOptions)) : 0); } else { const char* m_SO = m_caServerOptions.c_str(); // const char* m_CO = m_caClientOptions.c_str(); m_SO = strchr(m_SO, '/'); if (m_SO) m_SO++; m_SO = strchr(m_SO, '/'); string128 LevelName = ""; string128 GameType = ""; P->r_stringZ(LevelName); P->r_stringZ(GameType); string4096 NewServerOptions = ""; sprintf_s(NewServerOptions, "%s/%s", LevelName, GameType); if (m_SO) strcat(NewServerOptions, m_SO); m_caServerOptions = NewServerOptions; Engine.Event.Defer ("KERNEL:disconnect"); Engine.Event.Defer ("KERNEL:start",size_t(xr_strdup(*m_caServerOptions)),size_t(xr_strdup(*m_caClientOptions))); }; }break; case M_CHANGE_SELF_NAME: { net_OnChangeSelfName(P); }break; case M_BULLET_CHECK_RESPOND: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->On_Check_Respond(P); }break; case M_STATISTIC_UPDATE: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->OnUpdateRequest(P); }break; case M_STATISTIC_UPDATE_RESPOND: { if (!game) break; if (GameID() != GAME_SINGLE) Game().m_WeaponUsageStatistic->OnUpdateRespond(P); }break; case M_BATTLEYE: { #ifdef BATTLEYE battleye_system.ReadPacketClient( P ); #endif // BATTLEYE }break; } net_msg_Release(); } // if (!g_bDebugEvents) ProcessGameSpawns(); }
void CLevel::OnFrame () { #ifdef DEBUG_MEMORY_MANAGER debug_memory_guard __guard__; #endif // DEBUG_MEMORY_MANAGER m_feel_deny.update (); if (GameID()!=GAME_SINGLE) psDeviceFlags.set(rsDisableObjectsAsCrows,true); else psDeviceFlags.set(rsDisableObjectsAsCrows,false); // commit events from bullet manager from prev-frame Device.Statistic->TEST0.Begin (); BulletManager().CommitEvents (); Device.Statistic->TEST0.End (); // Client receive if (net_isDisconnected()) { if (OnClient() && GameID() != GAME_SINGLE) ClearAllObjects(); Engine.Event.Defer ("kernel:disconnect"); return; } else { Device.Statistic->netClient1.Begin(); ClientReceive (); Device.Statistic->netClient1.End (); } ProcessGameEvents (); if (m_bNeed_CrPr) make_NetCorrectionPrediction(); if(!g_dedicated_server) MapManager().Update (); // Inherited update inherited::OnFrame (); // Draw client/server stats if ( !g_dedicated_server && psDeviceFlags.test(rsStatistic)) { CGameFont* F = HUD().Font().pFontDI; if (!psNET_direct_connect) { if ( IsServer() ) { const IServerStatistic* S = Server->GetStatistic(); F->SetHeightI (0.015f); F->OutSetI (0.0f,0.5f); F->SetColor (D3DCOLOR_XRGB(0,255,0)); F->OutNext ("IN: %4d/%4d (%2.1f%%)", S->bytes_in_real, S->bytes_in, 100.f*float(S->bytes_in_real)/float(S->bytes_in)); F->OutNext ("OUT: %4d/%4d (%2.1f%%)", S->bytes_out_real, S->bytes_out, 100.f*float(S->bytes_out_real)/float(S->bytes_out)); F->OutNext ("client_2_sever ping: %d", net_Statistic.getPing()); F->OutNext ("SPS/Sended : %4d/%4d", S->dwBytesPerSec, S->dwBytesSended); F->OutNext ("sv_urate/cl_urate : %4d/%4d", psNET_ServerUpdate, psNET_ClientUpdate); F->SetColor (D3DCOLOR_XRGB(255,255,255)); for (u32 I=0; I<Server->client_Count(); ++I) { IClient* C = Server->client_Get(I); Server->UpdateClientStatistic(C); F->OutNext("P(%d), BPS(%2.1fK), MRR(%2d), MSR(%2d), Retried(%2d), Blocked(%2d)", //Server->game->get_option_s(*C->Name,"name",*C->Name), // C->Name, C->stats.getPing(), float(C->stats.getBPS()),// /1024, C->stats.getMPS_Receive (), C->stats.getMPS_Send (), C->stats.getRetriedCount(), C->stats.dwTimesBlocked ); } } if (IsClient()) { IPureClient::UpdateStatistic(); F->SetHeightI(0.015f); F->OutSetI (0.0f,0.5f); F->SetColor (D3DCOLOR_XRGB(0,255,0)); F->OutNext ("client_2_sever ping: %d", net_Statistic.getPing()); F->OutNext ("sv_urate/cl_urate : %4d/%4d", psNET_ServerUpdate, psNET_ClientUpdate); F->SetColor (D3DCOLOR_XRGB(255,255,255)); F->OutNext("P(%d), BPS(%2.1fK), MRR(%2d), MSR(%2d), Retried(%2d), Blocked(%2d), Sended(%2d), SPS(%2d)", //Server->game->get_option_s(C->Name,"name",C->Name), // C->Name, net_Statistic.getPing(), float(net_Statistic.getBPS()),// /1024, net_Statistic.getMPS_Receive (), net_Statistic.getMPS_Send (), net_Statistic.getRetriedCount(), net_Statistic.dwTimesBlocked, net_Statistic.dwBytesSended, net_Statistic.dwBytesPerSec ); } } } // g_pGamePersistent->Environment().SetGameTime (GetGameDayTimeSec(),GetGameTimeFactor()); g_pGamePersistent->Environment().SetGameTime (GetEnvironmentGameDayTimeSec(),GetGameTimeFactor()); //Device.Statistic->cripting.Begin (); if (!g_dedicated_server) ai().script_engine().script_process (ScriptEngine::eScriptProcessorLevel)->update(); //Device.Statistic->Scripting.End (); m_ph_commander->update (); m_ph_commander_scripts->update (); // autosave_manager().update (); //просчитать полет пуль Device.Statistic->TEST0.Begin (); BulletManager().CommitRenderSet (); Device.Statistic->TEST0.End (); // update static sounds if(!g_dedicated_server) { if (g_mt_config.test(mtLevelSounds)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(m_level_sound_manager,&CLevelSoundManager::Update)); else m_level_sound_manager->Update (); } // deffer LUA-GC-STEP if (!g_dedicated_server) { if (g_mt_config.test(mtLUA_GC)) Device.seqParallel.push_back (fastdelegate::FastDelegate0<>(this,&CLevel::script_gc)); else script_gc () ; } //----------------------------------------------------- if (pStatGraphR) { static float fRPC_Mult = 10.0f; static float fRPS_Mult = 1.0f; pStatGraphR->AppendItem(float(m_dwRPC)*fRPC_Mult, 0xffff0000, 1); pStatGraphR->AppendItem(float(m_dwRPS)*fRPS_Mult, 0xff00ff00, 0); }; }