diff --git a/doc/lua_api.txt b/doc/lua_api.txt index afeb53cd67a5..b150abfc80d1 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3783,6 +3783,10 @@ This is basically a reference to a C++ `ServerActiveObject` * `0`...`1`: Overrides day-night ratio, controlling sunlight to a specific amount * `nil`: Disables override, defaulting to sunlight based on day-night cycle * `get_day_night_ratio()`: returns the ratio or nil if it isn't overridden +* `set_time_offset(offset)` + * Adds offset to the time of the player + e.g. TimeOfDay is 12000 and the offset of the player is 1000 then the time of the player is 13000 +* `get_time_offset()` returns the players time of day offset * `set_local_animation(stand/idle, walk, dig, walk+dig, frame_speed=frame_speed)`: set animation for player model in third person view diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 6ecdb2798d93..7ddbd4657b15 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -69,6 +69,16 @@ class RemotePlayer : public Player *ratio = m_day_night_ratio; } + void setTimeOffset(s16 offset) + { + m_time_offset = offset; + } + + s16 getTimeOffset() + { + return m_time_offset; + } + void setHotbarImage(const std::string &name) { hud_hotbar_image = name; } std::string getHotbarImage() const { return hud_hotbar_image; } @@ -161,6 +171,9 @@ class RemotePlayer : public Player bool m_day_night_ratio_do_override = false; float m_day_night_ratio; + + s16 m_time_offset = 0; + std::string hud_hotbar_image = ""; std::string hud_hotbar_selected_image = ""; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 3afd21ec3b22..6fb5ff3c77df 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1720,6 +1720,40 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L) return 1; } +// set_time_offset(self, offset) +int ObjectRef::l_set_time_offset(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + int offset_i = luaL_checknumber(L, 2); + s16 offset = offset_i % 24000; + player->setTimeOffset(offset); + getServer(L)->SendTimeOfDay(player->getPeerId(), + getEnv(L)->getTimeOfDay(), g_settings->getFloat("time_speed")); + + lua_pushboolean(L, true); + return 1; +} + +// get_time_offset(self) +int ObjectRef::l_get_time_offset(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + RemotePlayer *player = getplayer(ref); + if (!player) + return 0; + + u16 offset = player->getTimeOffset(); + lua_pushnumber(L, offset); + + return 1; +} + ObjectRef::ObjectRef(ServerActiveObject *object): m_object(object) { @@ -1854,6 +1888,8 @@ const luaL_Reg ObjectRef::methods[] = { luamethod(ObjectRef, get_clouds), luamethod(ObjectRef, override_day_night_ratio), luamethod(ObjectRef, get_day_night_ratio), + luamethod(ObjectRef, set_time_offset), + luamethod(ObjectRef, get_time_offset), luamethod(ObjectRef, set_local_animation), luamethod(ObjectRef, get_local_animation), luamethod(ObjectRef, set_eye_offset), diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index 2a76d8a706c3..aed0ae2ce32f 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -316,6 +316,12 @@ class ObjectRef : public ModApiBase { // get_day_night_ratio(self) static int l_get_day_night_ratio(lua_State *L); + // set_time_offset(self, offset) + static int l_set_time_offset(lua_State *L); + + // get_time_offset(self) + static int l_get_time_offset(lua_State *L); + // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed) static int l_set_local_animation(lua_State *L); diff --git a/src/server.cpp b/src/server.cpp index d011089c3d3a..097883fe68e9 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1800,13 +1800,29 @@ void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override, void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed) { - NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id); - pkt << time << time_speed; if (peer_id == PEER_ID_INEXISTENT) { - m_clients.sendToAll(&pkt); + std::vector clients = m_clients.getClientIDs(); + for (const session_t peer_id : clients) { + RemotePlayer *player = m_env->getPlayer(peer_id); + if (player) + continue; + NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id); + u16 time_offset = player->getTimeOffset(); + u16 ntime = (time+time_offset); + pkt << ntime << time_speed; + Send(&pkt); + } } else { + RemotePlayer *player = m_env->getPlayer(peer_id); + // When the player is joining, player is NULL + if (!player) + return; + NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id); + u16 time_offset = player->getTimeOffset(); + u16 ntime = (time+time_offset); + pkt << ntime << time_speed; Send(&pkt); } } diff --git a/src/server.h b/src/server.h index ae7511bdf160..53e6d1ae0459 100644 --- a/src/server.h +++ b/src/server.h @@ -337,6 +337,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void SendPlayerBreath(PlayerSAO *sao); void SendInventory(PlayerSAO* playerSAO); void SendMovePlayer(session_t peer_id); + void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); virtual bool registerModStorage(ModMetadata *storage); virtual void unregisterModStorage(const std::string &name); @@ -373,7 +374,6 @@ class Server : public con::PeerHandler, public MapEventReceiver, void SendChatMessage(session_t peer_id, const ChatMessage &message); - void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); void SendPlayerHP(session_t peer_id); void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], diff --git a/util/travis/clang-format-whitelist.txt b/util/travis/clang-format-whitelist.txt index f522d46cd0b6..1692ac1a6381 100644 --- a/util/travis/clang-format-whitelist.txt +++ b/util/travis/clang-format-whitelist.txt @@ -406,3 +406,5 @@ src/voxelalgorithms.h src/voxel.cpp src/voxel.h src/wieldmesh.cpp +src/remoteplayer.h +src/gui/guiConfirmRegistration.cpp