1
0
Fork 0

Change TimeOfDay to WorldDate (#5160)

* Change TimeOfDay to WorldDate

* Do not wrap at 20 minutes, continue incrementing
* Fixes #4737
* Fixes #5159
This commit is contained in:
Tiger Wang 2021-03-20 20:58:19 +00:00 committed by GitHub
parent 55ba39ca0e
commit 90369deb5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 68 additions and 54 deletions

View File

@ -1870,7 +1870,7 @@ end
Type = "number", Type = "number",
}, },
{ {
Name = "TimeOfDay", Name = "WorldDate",
Type = "number", Type = "number",
}, },
{ {
@ -1878,7 +1878,7 @@ end
Type = "boolean", Type = "boolean",
}, },
}, },
Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. TimeOfDay is the current day's time, in ticks (0 - 24000). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false).", Notes = "Sends the specified time update to the client. WorldAge is the total age of the world, in ticks. WorldDate is the current date, in ticks, and is used by the client to calculate the days elapsed (F3 debug overlay's day count) and the time of day (rendered sun position). DoDaylightCycle is a bool that specifies whether the client should automatically move the sun (true) or keep it in the same place (false).",
}, },
SetClientBrand = SetClientBrand =
{ {

View File

@ -35,9 +35,6 @@ extern "C"
#include "lua/src/lauxlib.h" #include "lua/src/lauxlib.h"
} }
#include <functional>
#include "../Defines.h" #include "../Defines.h"
#include "../FunctionRef.h" #include "../FunctionRef.h"
#include "PluginManager.h" #include "PluginManager.h"

View File

@ -596,7 +596,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
{ {
ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client) ForClientsInWorld(*this, a_Exclude, [&](cClientHandle & a_Client)
{ {
a_Client.SendTimeUpdate(GetWorldAge(), GetTimeOfDay(), IsDaylightCycleEnabled()); a_Client.SendTimeUpdate(GetWorldAge(), std::chrono::duration_cast<cTickTimeLong>(m_WorldDate).count(), IsDaylightCycleEnabled());
} }
); );
} }

View File

@ -3003,9 +3003,9 @@ void cClientHandle::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_
void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle)
{ {
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); m_Protocol->SendTimeUpdate(a_WorldAge, a_WorldDate, a_DoDaylightCycle);
} }

View File

@ -219,7 +219,7 @@ public: // tolua_export
void SendTabCompletionResults (const AStringVector & a_Results); void SendTabCompletionResults (const AStringVector & a_Results);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ);
void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks); // tolua_export
void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle); // tolua_export
void SendUnleashEntity (const cEntity & a_Entity); void SendUnleashEntity (const cEntity & a_Entity);
void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); void SendUnloadChunk (int a_ChunkX, int a_ChunkZ);
void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity);

View File

@ -83,7 +83,7 @@ const int cPlayer::EATING_TICKS = 30;
cPlayer::cPlayer(const cClientHandlePtr & a_Client) : cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
Super(etPlayer, 0.6, 1.8), Super(etPlayer, 0.6, 1.8),
m_bVisible(true), m_bVisible(true),
m_FoodLevel(MAX_FOOD_LEVEL), m_FoodLevel(MAX_FOOD_LEVEL),

View File

@ -47,7 +47,7 @@ public:
CLASS_PROTODEF(cPlayer) CLASS_PROTODEF(cPlayer)
cPlayer(const cClientHandlePtr & a_Client); cPlayer(const std::shared_ptr<cClientHandle> & a_Client);
virtual ~cPlayer() override; virtual ~cPlayer() override;
// tolua_begin // tolua_begin
@ -656,7 +656,7 @@ private:
/** The item being dragged by the cursor while in a UI window */ /** The item being dragged by the cursor while in a UI window */
cItem m_DraggingItem; cItem m_DraggingItem;
cClientHandlePtr m_ClientHandle; std::shared_ptr<cClientHandle> m_ClientHandle;
cSlotNums m_InventoryPaintSlots; cSlotNums m_InventoryPaintSlots;

View File

@ -438,7 +438,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0; virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) = 0;
virtual void SendUnleashEntity (const cEntity & a_Entity) = 0; virtual void SendUnleashEntity (const cEntity & a_Entity) = 0;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0;

View File

@ -1566,18 +1566,20 @@ void cProtocol_1_8_0::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int
void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) void cProtocol_1_8_0::SendTimeUpdate(Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
if (!a_DoDaylightCycle) if (!a_DoDaylightCycle)
{ {
// When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. // Negating the date stops time from advancing on the client
a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); // (the std::min construction is to handle the case where the date is exactly zero):
a_WorldDate = std::min(-a_WorldDate, -1LL);
} }
cPacketizer Pkt(*this, pktTimeUpdate); cPacketizer Pkt(*this, pktTimeUpdate);
Pkt.WriteBEInt64(a_WorldAge); Pkt.WriteBEInt64(a_WorldAge);
Pkt.WriteBEInt64(a_TimeOfDay); Pkt.WriteBEInt64(a_WorldDate);
} }

View File

@ -119,7 +119,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override; virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_WorldDate, bool a_DoDaylightCycle) override;
virtual void SendUnleashEntity (const cEntity & a_Entity) override; virtual void SendUnleashEntity (const cEntity & a_Entity) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;

View File

@ -61,14 +61,6 @@
const int TIME_SUNSET = 12000;
const int TIME_NIGHT_START = 13187;
const int TIME_NIGHT_END = 22812;
const int TIME_SUNRISE = 23999;
const int TIME_SPAWN_DIVISOR = 148;
namespace World namespace World
@ -167,7 +159,7 @@ cWorld::cWorld(
m_BroadcastAchievementMessages(true), m_BroadcastAchievementMessages(true),
m_IsDaylightCycleEnabled(true), m_IsDaylightCycleEnabled(true),
m_WorldAge(0), m_WorldAge(0),
m_TimeOfDay(0), m_WorldDate(0),
m_WorldTickAge(0), m_WorldTickAge(0),
m_LastChunkCheck(0), m_LastChunkCheck(0),
m_LastSave(0), m_LastSave(0),
@ -483,6 +475,39 @@ void cWorld::CastThunderbolt(Vector3i a_Block)
int cWorld::GetTimeOfDay(void) const
{
using namespace std::chrono_literals;
return std::chrono::duration_cast<cTickTime>(m_WorldDate % 20min).count();
}
Int64 cWorld::GetWorldAge(void) const
{
return std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count();
}
void cWorld::SetTimeOfDay(int a_TimeOfDay)
{
using namespace std::chrono_literals;
m_WorldDate = (m_WorldDate / 20min) * 20min + cTickTime(a_TimeOfDay);
UpdateSkyDarkness();
BroadcastTimeUpdate();
}
int cWorld::GetDefaultWeatherInterval(eWeather a_Weather) const int cWorld::GetDefaultWeatherInterval(eWeather a_Weather) const
{ {
auto & Random = GetRandomProvider(); auto & Random = GetRandomProvider();
@ -967,13 +992,7 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La
if (m_IsDaylightCycleEnabled) if (m_IsDaylightCycleEnabled)
{ {
m_TimeOfDay += a_Dt; m_WorldDate += a_Dt;
// Wrap time of day every 20 minutes (1200 seconds):
if (m_TimeOfDay > std::chrono::minutes(20))
{
m_TimeOfDay -= std::chrono::minutes(20);
}
// Updates the sky darkness based on current time of day: // Updates the sky darkness based on current time of day:
UpdateSkyDarkness(); UpdateSkyDarkness();
@ -1267,7 +1286,13 @@ void cWorld::TickQueuedTasks(void)
void cWorld::UpdateSkyDarkness(void) void cWorld::UpdateSkyDarkness(void)
{ {
int TempTime = std::chrono::duration_cast<cTickTime>(m_TimeOfDay).count(); const int TIME_SUNSET = 12000;
const int TIME_NIGHT_START = 13187;
const int TIME_NIGHT_END = 22812;
const int TIME_SUNRISE = 23999;
const int TIME_SPAWN_DIVISOR = 148;
const auto TempTime = GetTimeOfDay();
if (TempTime <= TIME_SUNSET) if (TempTime <= TIME_SUNSET)
{ {
m_SkyDarkness = 0; m_SkyDarkness = 0;

View File

@ -1,10 +1,6 @@
#pragma once #pragma once
#define MAX_PLAYERS 65535
#include <functional>
#include "Simulator/SimulatorManager.h" #include "Simulator/SimulatorManager.h"
#include "ChunkMap.h" #include "ChunkMap.h"
#include "WorldStorage/WorldStorage.h" #include "WorldStorage/WorldStorage.h"
@ -26,6 +22,8 @@
class cFireSimulator; class cFireSimulator;
class cFluidSimulator; class cFluidSimulator;
class cSandSimulator; class cSandSimulator;
@ -33,9 +31,6 @@ class cRedstoneSimulator;
class cItem; class cItem;
class cPlayer; class cPlayer;
class cClientHandle; class cClientHandle;
typedef std::shared_ptr<cClientHandle> cClientHandlePtr;
typedef std::list<cClientHandlePtr> cClientHandlePtrs;
typedef std::list<cClientHandle *> cClientHandles;
class cEntity; class cEntity;
class cChunkGenerator; // The thread responsible for generating chunks class cChunkGenerator; // The thread responsible for generating chunks
class cBeaconEntity; class cBeaconEntity;
@ -120,20 +115,15 @@ public:
BroadcastTimeUpdate(); BroadcastTimeUpdate();
} }
virtual Int64 GetWorldAge (void) const override { return std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count(); } virtual int GetTimeOfDay(void) const override;
virtual int GetTimeOfDay(void) const override { return std::chrono::duration_cast<cTickTime>(m_TimeOfDay).count(); } virtual Int64 GetWorldAge(void) const override;
void SetTicksUntilWeatherChange(int a_WeatherInterval) void SetTicksUntilWeatherChange(int a_WeatherInterval)
{ {
m_WeatherInterval = a_WeatherInterval; m_WeatherInterval = a_WeatherInterval;
} }
virtual void SetTimeOfDay(int a_TimeOfDay) override virtual void SetTimeOfDay(int a_TimeOfDay) override;
{
m_TimeOfDay = cTickTime(a_TimeOfDay);
UpdateSkyDarkness();
BroadcastTimeUpdate();
}
/** Returns the default weather interval for the specific weather type. /** Returns the default weather interval for the specific weather type.
Returns -1 for any unknown weather. */ Returns -1 for any unknown weather. */
@ -1061,12 +1051,12 @@ private:
We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */ We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */
std::chrono::milliseconds m_WorldAge; std::chrono::milliseconds m_WorldAge;
/** The duration of one Minecraft day that has elapsed. /** The fully controllable age of the world.
Wraps every 20 minutes. A value used to calculate the current day, and time of day. Settable by plugins and players, and persistent.
We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */ We need sub-tick precision here, that's why we store the time in milliseconds and calculate ticks off of it. */
std::chrono::milliseconds m_TimeOfDay; std::chrono::milliseconds m_WorldDate;
/** The age of the world, in ticks. /** The time since this world began, in ticks.
Monotonic, but does not persist across restarts. Monotonic, but does not persist across restarts.
Used for less important but heavy tasks that run periodically. These tasks don't need to follow wallclock time, and slowing their rate down if TPS drops is desirable. */ Used for less important but heavy tasks that run periodically. These tasks don't need to follow wallclock time, and slowing their rate down if TPS drops is desirable. */
unsigned long long m_WorldTickAge; unsigned long long m_WorldTickAge;