summaryrefslogtreecommitdiffstats
path: root/src/World.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World.cpp')
-rw-r--r--src/World.cpp216
1 files changed, 81 insertions, 135 deletions
diff --git a/src/World.cpp b/src/World.cpp
index 5920b83fe..824ebf3fa 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -166,7 +166,13 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
m_ChunkMap(),
m_bAnimals(true),
m_Weather(eWeather_Sunny),
- m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
+ m_WeatherInterval(24000), // Guaranteed 1 game-day of sunshine at server start :)
+ m_MaxSunnyTicks(180000), // 150 real-world minutes -+
+ m_MinSunnyTicks(12000), // 10 real-world minutes |
+ m_MaxRainTicks(24000), // 20 real-world minutes +- all values adapted from Vanilla 1.7.2
+ m_MinRainTicks(12000), // 10 real-world minutes |
+ m_MaxThunderStormTicks(15600), // 13 real-world minutes |
+ m_MinThunderStormTicks(3600), // 3 real-world minutes -+
m_MaxCactusHeight(3),
m_MaxSugarcaneHeight(4),
m_IsCactusBonemealable(false),
@@ -244,17 +250,25 @@ int cWorld::GetDefaultWeatherInterval(eWeather a_Weather)
{
case eWeather_Sunny:
{
- return 14400 + (m_TickRand.randInt() % 4800); // 12 - 16 minutes
+ auto dif = m_MaxSunnyTicks - m_MinSunnyTicks + 1;
+ return m_MinSunnyTicks + (m_TickRand.randInt() % dif);
}
case eWeather_Rain:
{
- return 9600 + (m_TickRand.randInt() % 7200); // 8 - 14 minutes
+ auto dif = m_MaxRainTicks - m_MinRainTicks + 1;
+ return m_MinRainTicks + (m_TickRand.randInt() % dif);
}
case eWeather_ThunderStorm:
{
- return 2400 + (m_TickRand.randInt() % 4800); // 2 - 6 minutes
+ auto dif = m_MaxThunderStormTicks - m_MinThunderStormTicks + 1;
+ return m_MinThunderStormTicks + (m_TickRand.randInt() % dif);
}
}
+
+ #ifndef __clang__
+ ASSERT(!"Unknown weather");
+ return -1;
+ #endif
}
@@ -472,6 +486,29 @@ void cWorld::Start(void)
m_IsDaylightCycleEnabled = IniFile.GetValueSetB("General", "IsDaylightCycleEnabled", true);
int GameMode = IniFile.GetValueSetI("General", "Gamemode", static_cast<int>(m_GameMode));
int Weather = IniFile.GetValueSetI("General", "Weather", static_cast<int>(m_Weather));
+
+ // Load the weather frequency data:
+ if (m_Dimension == dimOverworld)
+ {
+ m_MaxSunnyTicks = IniFile.GetValueSetI("Weather", "MaxSunnyTicks", m_MaxSunnyTicks);
+ m_MinSunnyTicks = IniFile.GetValueSetI("Weather", "MinSunnyTicks", m_MinSunnyTicks);
+ m_MaxRainTicks = IniFile.GetValueSetI("Weather", "MaxRainTicks", m_MaxRainTicks);
+ m_MinRainTicks = IniFile.GetValueSetI("Weather", "MinRainTicks", m_MinRainTicks);
+ m_MaxThunderStormTicks = IniFile.GetValueSetI("Weather", "MaxThunderStormTicks", m_MaxThunderStormTicks);
+ m_MinThunderStormTicks = IniFile.GetValueSetI("Weather", "MinThunderStormTicks", m_MinThunderStormTicks);
+ if (m_MaxSunnyTicks < m_MinSunnyTicks)
+ {
+ std::swap(m_MaxSunnyTicks, m_MinSunnyTicks);
+ }
+ if (m_MaxRainTicks < m_MinRainTicks)
+ {
+ std::swap(m_MaxRainTicks, m_MinRainTicks);
+ }
+ if (m_MaxThunderStormTicks < m_MinThunderStormTicks)
+ {
+ std::swap(m_MaxThunderStormTicks, m_MinThunderStormTicks);
+ }
+ }
if (GetDimension() == dimOverworld)
{
@@ -644,6 +681,11 @@ eWeather cWorld::ChooseNewWeather()
return ((m_TickRand.randInt() % 256) < 32) ? eWeather_ThunderStorm : eWeather_Sunny;
}
}
+
+ #ifndef __clang__
+ ASSERT(!"Unknown weather");
+ return eWeather_Sunny;
+ #endif
}
@@ -839,7 +881,6 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
TickClients(static_cast<float>(a_Dt.count()));
TickQueuedBlocks();
TickQueuedTasks();
- TickScheduledTasks();
GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count()));
@@ -962,55 +1003,39 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt)
void cWorld::TickQueuedTasks(void)
{
- // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks
- cTasks Tasks;
- {
- cCSLock Lock(m_CSTasks);
- std::swap(Tasks, m_Tasks);
- }
-
- // Execute and delete each task:
- for (cTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
- {
- (*itr)->Run(*this);
- } // for itr - m_Tasks[]
-}
-
-
-
-
-
-void cWorld::TickScheduledTasks(void)
-{
// Move the tasks to be executed to a seperate vector to avoid deadlocks on accessing m_Tasks
- cScheduledTasks Tasks;
+ decltype(m_Tasks) Tasks;
{
- cCSLock Lock(m_CSScheduledTasks);
- auto WorldAge = m_WorldAge;
-
- // Move all the due tasks from m_ScheduledTasks into Tasks:
- for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-based for, we're modifying the container
+ cCSLock Lock(m_CSTasks);
+ if (m_Tasks.empty())
{
- if ((*itr)->m_TargetTick < std::chrono::duration_cast<cTickTimeLong>(WorldAge).count())
- {
- auto next = itr;
- ++next;
- Tasks.push_back(std::move(*itr));
- m_ScheduledTasks.erase(itr);
- itr = next;
- }
- else
+ return;
+ }
+
+ // Partition everything to be executed by returning false to move to end of list if time reached
+ auto MoveBeginIterator = std::partition(m_Tasks.begin(), m_Tasks.end(), [this](const decltype(m_Tasks)::value_type & a_Task)
{
- // All the eligible tasks have been moved, bail out now
- break;
+ if (a_Task.first < std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count())
+ {
+ return false;
+ }
+ return true;
}
- }
+ );
+
+ // Cut all the due tasks from m_Tasks into Tasks:
+ Tasks.insert(
+ Tasks.end(),
+ std::make_move_iterator(MoveBeginIterator),
+ std::make_move_iterator(m_Tasks.end())
+ );
+ m_Tasks.erase(MoveBeginIterator, m_Tasks.end());
}
- // Execute and delete each task:
- for (cScheduledTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
+ // Execute each task:
+ for (const auto & Task : Tasks)
{
- (*itr)->m_Task->Run(*this);
+ Task.second(*this);
} // for itr - m_Tasks[]
}
@@ -2662,7 +2687,7 @@ void cWorld::UnloadUnusedChunks(void)
void cWorld::QueueUnloadUnusedChunks(void)
{
- QueueTask(cpp14::make_unique<cWorld::cTaskUnloadUnusedChunks>());
+ QueueTask([](cWorld & a_World) { a_World.UnloadUnusedChunks(); });
}
@@ -3161,42 +3186,32 @@ void cWorld::SaveAllChunks(void)
void cWorld::QueueSaveAllChunks(void)
{
- QueueTask(std::make_shared<cWorld::cTaskSaveAllChunks>());
+ QueueTask([](cWorld & a_World) { a_World.SaveAllChunks(); });
}
-void cWorld::QueueTask(cTaskPtr a_Task)
+void cWorld::QueueTask(std::function<void(cWorld &)> a_Task)
{
cCSLock Lock(m_CSTasks);
- m_Tasks.push_back(std::move(a_Task));
+ m_Tasks.emplace_back(0, a_Task);
}
-void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld&)> a_Func)
-{
- cTaskLambda task(a_Func);
- ScheduleTask(a_DelayTicks, static_cast<cTaskPtr>(std::make_shared<cTaskLambda>(task)));
-}
-void cWorld::ScheduleTask(int a_DelayTicks, cTaskPtr a_Task)
+
+void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld &)> a_Task)
{
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);
- for (cScheduledTasks::iterator itr = m_ScheduledTasks.begin(), end = m_ScheduledTasks.end(); itr != end; ++itr)
+
+ // Insert the task into the list of scheduled tasks
{
- if ((*itr)->m_TargetTick >= TargetTick)
- {
- m_ScheduledTasks.insert(itr, cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task)));
- return;
- }
+ cCSLock Lock(m_CSTasks);
+ m_Tasks.emplace_back(TargetTick, a_Task);
}
- m_ScheduledTasks.push_back(cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task)));
}
@@ -3625,75 +3640,6 @@ void cWorld::AddQueuedPlayers(void)
////////////////////////////////////////////////////////////////////////////////
-// cWorld::cTaskSaveAllChunks:
-
-void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World)
-{
- a_World.SaveAllChunks();
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cWorld::cTaskUnloadUnusedChunks
-
-void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World)
-{
- a_World.UnloadUnusedChunks();
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cWorld::cTaskSendBlockToAllPlayers
-
-cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) :
- m_SendQueue(a_SendQueue)
-{
-}
-
-void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World)
-{
- class cPlayerCallback :
- public cPlayerListCallback
- {
- public:
- cPlayerCallback(std::vector<Vector3i> & a_SendQueue, cWorld & a_CallbackWorld) :
- m_SendQueue(a_SendQueue),
- m_World(a_CallbackWorld)
- {
- }
-
- virtual bool Item(cPlayer * a_Player)
- {
- for (std::vector<Vector3i>::const_iterator itr = m_SendQueue.begin(); itr != m_SendQueue.end(); ++itr)
- {
- m_World.SendBlockTo(itr->x, itr->y, itr->z, a_Player);
- }
- return false;
- }
-
- private:
-
- std::vector<Vector3i> m_SendQueue;
- cWorld & m_World;
-
- } PlayerCallback(m_SendQueue, a_World);
-
- a_World.ForEachPlayer(PlayerCallback);
-}
-
-void cWorld::cTaskLambda::Run(cWorld & a_World)
-{
- m_func(a_World);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
// cWorld::cChunkGeneratorCallbacks:
cWorld::cChunkGeneratorCallbacks::cChunkGeneratorCallbacks(cWorld & a_World) :