diff options
Diffstat (limited to 'src/World.cpp')
-rw-r--r-- | src/World.cpp | 216 |
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) : |