diff options
Diffstat (limited to '')
-rw-r--r-- | src/World.cpp | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/src/World.cpp b/src/World.cpp index c08b44f77..46488d58b 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -233,21 +233,19 @@ cWorld::cTickThread::cTickThread(cWorld & a_World) : void cWorld::cTickThread::Execute(void) { auto LastTime = std::chrono::steady_clock::now(); - static const auto msPerTick = std::chrono::milliseconds(50); - auto TickTime = std::chrono::steady_clock::duration(50); + auto TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(cTickTime(1)); while (!m_ShouldTerminate) { auto NowTime = std::chrono::steady_clock::now(); - auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(NowTime - LastTime).count(); - auto LastTickMsec = std::chrono::duration_cast<std::chrono::duration<int>>(TickTime).count(); - m_World.Tick(static_cast<float>(msec), LastTickMsec); - TickTime = std::chrono::steady_clock::now() - NowTime; + auto WaitTime = std::chrono::duration_cast<std::chrono::milliseconds>(NowTime - LastTime); + m_World.Tick(WaitTime, TickTime); + TickTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - NowTime); - if (TickTime < msPerTick) + if (TickTime < cTickTime(1)) { - // Stretch tick time until it's at least msPerTick - std::this_thread::sleep_for(msPerTick - TickTime); + // Stretch tick time until it's at least 1 tick + std::this_thread::sleep_for(cTickTime(1) - TickTime); } LastTime = NowTime; @@ -274,8 +272,6 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin m_Dimension(a_Dimension), m_IsSpawnExplicitlySet(false), m_IsDaylightCycleEnabled(true), - m_WorldAgeSecs(0), - m_TimeOfDaySecs(0), m_WorldAge(0), m_TimeOfDay(0), m_LastTimeUpdate(0), @@ -618,7 +614,7 @@ void cWorld::Start(void) InitialiseGeneratorDefaults(IniFile); InitialiseAndLoadMobSpawningValues(IniFile); - SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", m_TimeOfDay)); + SetTimeOfDay(IniFile.GetValueSetI("General", "TimeInTicks", GetTimeOfDay())); m_ChunkMap = make_unique<cChunkMap>(this); @@ -645,10 +641,10 @@ void cWorld::Start(void) m_TickThread.Start(); // Init of the spawn monster time (as they are supposed to have different spawn rate) - m_LastSpawnMonster.insert(std::map<cMonster::eFamily, Int64>::value_type(cMonster::mfHostile, 0)); - m_LastSpawnMonster.insert(std::map<cMonster::eFamily, Int64>::value_type(cMonster::mfPassive, 0)); - m_LastSpawnMonster.insert(std::map<cMonster::eFamily, Int64>::value_type(cMonster::mfAmbient, 0)); - m_LastSpawnMonster.insert(std::map<cMonster::eFamily, Int64>::value_type(cMonster::mfWater, 0)); + m_LastSpawnMonster.insert(std::map<cMonster::eFamily, cTickTimeLong>::value_type(cMonster::mfHostile, cTickTimeLong(0))); + m_LastSpawnMonster.insert(std::map<cMonster::eFamily, cTickTimeLong>::value_type(cMonster::mfPassive, cTickTimeLong(0))); + m_LastSpawnMonster.insert(std::map<cMonster::eFamily, cTickTimeLong>::value_type(cMonster::mfAmbient, cTickTimeLong(0))); + m_LastSpawnMonster.insert(std::map<cMonster::eFamily, cTickTimeLong>::value_type(cMonster::mfWater, cTickTimeLong(0))); m_MapManager.LoadMapData(); @@ -839,7 +835,7 @@ void cWorld::Stop(void) IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes); IniFile.SetValueB("General", "IsDaylightCycleEnabled", m_IsDaylightCycleEnabled); IniFile.SetValueI("General", "Weather", (int)m_Weather); - IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay); + IniFile.SetValueI("General", "TimeInTicks", GetTimeOfDay()); IniFile.WriteFile(m_IniFileName); m_TickThread.Stop(); @@ -853,7 +849,7 @@ void cWorld::Stop(void) -void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) +void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) { // Call the plugins cPluginManager::Get()->CallHookWorldTick(*this, a_Dt, a_LastTickDurationMSec); @@ -869,30 +865,27 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) SetChunkData(**itr); } // for itr - SetChunkDataQueue[] - m_WorldAgeSecs += (double)a_Dt / 1000.0; - m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); + m_WorldAge += a_Dt; if (m_IsDaylightCycleEnabled) { - // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it - m_TimeOfDaySecs += (double)a_Dt / 1000.0; + // We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it + m_TimeOfDay += a_Dt; // Wrap time of day each 20 minutes (1200 seconds) - if (m_TimeOfDaySecs > 1200.0) + if (m_TimeOfDay > std::chrono::minutes(20)) { - m_TimeOfDaySecs -= 1200.0; + m_TimeOfDay -= std::chrono::minutes(20); } - m_TimeOfDay = static_cast<int>(m_TimeOfDaySecs * 20.0); - // Updates the sky darkness based on current time of day UpdateSkyDarkness(); // Broadcast time update every 40 ticks (2 seconds) - if (m_LastTimeUpdate < m_WorldAge - 40) + if (m_LastTimeUpdate < m_WorldAge - cTickTime(40)) { BroadcastTimeUpdate(); - m_LastTimeUpdate = m_WorldAge; + m_LastTimeUpdate = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge); } } @@ -912,23 +905,23 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_ChunkMap->Tick(a_Dt); - TickClients(a_Dt); + TickClients(a_Dt.count()); TickQueuedBlocks(); TickQueuedTasks(); TickScheduledTasks(); - GetSimulatorManager()->Simulate(a_Dt); + GetSimulatorManager()->Simulate(a_Dt.count()); - TickWeather(a_Dt); + TickWeather(a_Dt.count()); m_ChunkMap->FastSetQueuedBlocks(); - if (m_WorldAge - m_LastSave > 60 * 5 * 20) // Save each 5 minutes + if (m_WorldAge - m_LastSave > std::chrono::minutes(5)) // Save each 5 minutes { SaveAllChunks(); } - if (m_WorldAge - m_LastUnload > 10 * 20) // Unload every 10 seconds + if (m_WorldAge - m_LastUnload > std::chrono::minutes(5)) // Unload every 10 seconds { UnloadUnusedChunks(); } @@ -974,7 +967,7 @@ void cWorld::TickWeather(float a_Dt) -void cWorld::TickMobs(float a_Dt) +void cWorld::TickMobs(std::chrono::milliseconds a_Dt) { // _X 2013_10_22: This is a quick fix for #283 - the world needs to be locked while ticking mobs cWorld::cLock Lock(*this); @@ -995,7 +988,7 @@ void cWorld::TickMobs(float a_Dt) for (size_t i = 0; i < ARRAYCOUNT(AllFamilies); i++) { cMonster::eFamily Family = AllFamilies[i]; - int SpawnDelay = cMonster::GetSpawnDelay(Family); + cTickTime SpawnDelay = cTickTime(cMonster::GetSpawnDelay(Family)); if ( (m_LastSpawnMonster[Family] > m_WorldAge - SpawnDelay) || // Not reached the needed ticks before the next round MobCensus.IsCapped(Family) @@ -1003,7 +996,7 @@ void cWorld::TickMobs(float a_Dt) { continue; } - m_LastSpawnMonster[Family] = m_WorldAge; + m_LastSpawnMonster[Family] = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge); cMobSpawner Spawner(Family, m_AllowedMobs); if (Spawner.CanSpawnAnything()) { @@ -1067,7 +1060,7 @@ void cWorld::TickScheduledTasks(void) // Move all the due tasks from m_ScheduledTasks into Tasks: for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-basd for, we're modifying the container { - if ((*itr)->m_TargetTick < WorldAge) + if ((*itr)->m_TargetTick < std::chrono::duration_cast<cTickTimeLong>(WorldAge).count()) { auto next = itr; ++next; @@ -1142,7 +1135,7 @@ void cWorld::TickClients(float a_Dt) void cWorld::UpdateSkyDarkness(void) { - int TempTime = (int)m_TimeOfDay; + int TempTime = std::chrono::duration_cast<cTickTime>(m_TimeOfDay).count(); if (TempTime <= TIME_SUNSET) { m_SkyDarkness = 0; @@ -1423,14 +1416,15 @@ void cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, NIBBLETYPE a_Sapling { cNoise Noise(m_Generator.GetSeed()); sSetBlockVector Logs, Other; + auto WorldAge = (int)(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff); switch (a_SaplingMeta & 0x07) { - case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; - case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; - case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; - case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; - case E_META_SAPLING_ACACIA: GetAcaciaTreeImage (a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; - case E_META_SAPLING_DARK_OAK: GetDarkoakTreeImage(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), Logs, Other); break; + case E_META_SAPLING_APPLE: GetAppleTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; + case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; + case E_META_SAPLING_CONIFER: GetConiferTreeImage(a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; + case E_META_SAPLING_JUNGLE: GetJungleTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; + case E_META_SAPLING_ACACIA: GetAcaciaTreeImage (a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; + case E_META_SAPLING_DARK_OAK: GetDarkoakTreeImage(a_X, a_Y, a_Z, Noise, WorldAge, Logs, Other); break; } Other.insert(Other.begin(), Logs.begin(), Logs.end()); Logs.clear(); @@ -1445,7 +1439,7 @@ void cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z) { cNoise Noise(m_Generator.GetSeed()); sSetBlockVector Logs, Other; - GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(m_WorldAge & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other); + GetTreeImageByBiome(a_X, a_Y, a_Z, Noise, (int)(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other); Other.insert(Other.begin(), Logs.begin(), Logs.end()); Logs.clear(); GrowTreeImage(Other); @@ -2406,7 +2400,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { continue; } - ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay, m_IsDaylightCycleEnabled); + ch->SendTimeUpdate(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count(), std::chrono::duration_cast<cTickTimeLong>(m_TimeOfDay).count(), m_IsDaylightCycleEnabled); } } @@ -2608,7 +2602,7 @@ bool cWorld::HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const void cWorld::UnloadUnusedChunks(void) { - m_LastUnload = m_WorldAge; + m_LastUnload = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge); m_ChunkMap->UnloadUnusedChunks(); } @@ -3084,7 +3078,7 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk void cWorld::SaveAllChunks(void) { - m_LastSave = m_WorldAge; + m_LastSave = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge); m_ChunkMap->SaveAllChunks(); } @@ -3113,7 +3107,7 @@ void cWorld::QueueTask(std::unique_ptr<cTask> a_Task) void cWorld::ScheduleTask(int a_DelayTicks, cTask * a_Task) { - Int64 TargetTick = a_DelayTicks + m_WorldAge; + Int64 TargetTick = a_DelayTicks + std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count(); // Insert the task into the list of scheduled tasks, ordered by its target tick cCSLock Lock(m_CSScheduledTasks); |