summaryrefslogtreecommitdiffstats
path: root/src/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World.cpp')
-rw-r--r--src/World.cpp115
1 files changed, 61 insertions, 54 deletions
diff --git a/src/World.cpp b/src/World.cpp
index 69b39f831..24b1a9b40 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;
@@ -273,12 +271,17 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
#endif
m_Dimension(a_Dimension),
m_IsSpawnExplicitlySet(false),
+ m_SpawnX(0),
+ m_SpawnY(0),
+ m_SpawnZ(0),
+ m_BroadcastDeathMessages(true),
+ m_BroadcastAchievementMessages(true),
m_IsDaylightCycleEnabled(true),
- m_WorldAgeSecs(0),
- m_TimeOfDaySecs(0),
m_WorldAge(0),
m_TimeOfDay(0),
m_LastTimeUpdate(0),
+ m_LastUnload(0),
+ m_LastSave(0),
m_SkyDarkness(0),
m_GameMode(gmNotSet),
m_bEnabledPVP(false),
@@ -616,13 +619,10 @@ 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);
- m_LastSave = 0;
- m_LastUnload = 0;
-
// preallocate some memory for ticking blocks so we don't need to allocate that often
m_BlockTickQueue.reserve(1000);
m_BlockTickQueueCopy.reserve(1000);
@@ -646,10 +646,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();
@@ -840,7 +840,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();
@@ -854,7 +854,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);
@@ -870,30 +870,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);
}
}
@@ -913,23 +910,23 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
m_ChunkMap->Tick(a_Dt);
- TickClients(a_Dt);
+ TickClients(static_cast<float>(a_Dt.count()));
TickQueuedBlocks();
TickQueuedTasks();
TickScheduledTasks();
- GetSimulatorManager()->Simulate(a_Dt);
+ GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
- TickWeather(a_Dt);
+ TickWeather(static_cast<float>(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();
}
@@ -975,7 +972,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);
@@ -996,7 +993,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)
@@ -1004,7 +1001,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())
{
@@ -1068,7 +1065,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;
@@ -1143,7 +1140,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;
@@ -1424,14 +1421,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();
@@ -1446,7 +1444,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);
@@ -1464,7 +1462,7 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
sSetBlockVector b2;
for (sSetBlockVector::const_iterator itr = a_Blocks.begin(); itr != a_Blocks.end(); ++itr)
{
- if (itr->BlockType == E_BLOCK_LOG)
+ if (itr->m_BlockType == E_BLOCK_LOG)
{
b2.push_back(*itr);
}
@@ -1479,7 +1477,7 @@ void cWorld::GrowTreeImage(const sSetBlockVector & a_Blocks)
// Check that at each log's coord there's an block allowed to be overwritten:
for (sSetBlockVector::const_iterator itr = b2.begin(); itr != b2.end(); ++itr)
{
- switch (itr->BlockType)
+ switch (itr->m_BlockType)
{
CASE_TREE_ALLOWED_BLOCKS:
{
@@ -1927,6 +1925,15 @@ void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks,
+void cWorld::SetBlocks(const sSetBlockVector & a_Blocks)
+{
+ m_ChunkMap->SetBlocks(a_Blocks);
+}
+
+
+
+
+
void cWorld::ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType)
{
m_ChunkMap->ReplaceBlocks(a_Blocks, a_FilterBlockType);
@@ -2398,7 +2405,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);
}
}
@@ -2600,7 +2607,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();
}
@@ -3076,7 +3083,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();
}
@@ -3105,7 +3112,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);