Skip to content

Commit

Permalink
Move world time and light to lua (otland#4583)
Browse files Browse the repository at this point in the history
* Move world time and light to lua

* Some fix

* Remove duplicated checks and move return to last fn line

* Move world packet to lua
  • Loading branch information
ramon-bernardo authored Dec 10, 2023
1 parent 561d7b0 commit 3877aa9
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 160 deletions.
45 changes: 45 additions & 0 deletions data/lib/core/game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,48 @@ function Game.getUnpromotedVocations()
end
return vocations
end

do
local worldLightLevel = 0
local worldLightColor = 0

function Game.getWorldLight()
return worldLightLevel, worldLightColor
end

function Game.setWorldLight(color, level)
if not configManager.getBoolean(configKeys.DEFAULT_WORLD_LIGHT) then
return
end

local previousColor = worldLightColor
local previousLevel = worldLightLevel
worldLightColor = color
worldLightLevel = level

if worldLightColor ~= previousColor or worldLightLevel ~= previousLevel then
for _, player in ipairs(Game.getPlayers()) do
player:sendWorldLight(worldLightColor, worldLightLevel)
end
end
end
end

do
local worldTime = 0

function Game.getWorldTime()
return worldTime
end

function Game.setWorldTime(time)
worldTime = time

-- quarter-hourly update to client clock near the minimap
if worldTime % 15 == 0 then
for _, player in ipairs(Game.getPlayers()) do
player:sendWorldTime(worldTime)
end
end
end
end
20 changes: 20 additions & 0 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,23 @@ end
function Player.getAccountStorageValue(self, key)
return Game.getAccountStorageValue(self:getAccountId(), key)
end

function Player.sendWorldLight(self, color, level)
local msg = NetworkMessage()
msg:addByte(0x82)
msg:addByte(self:getGroup():getAccess() and 0xFF or level)
msg:addByte(color)
msg:sendToPlayer(self)
msg:delete()
return true
end

function Player.sendWorldTime(self, time)
local msg = NetworkMessage()
msg:addByte(0xEF)
msg:addByte(time / 60) -- hour
msg:addByte(time % 60) -- min
msg:sendToPlayer(self)
msg:delete()
return true
end
12 changes: 12 additions & 0 deletions data/scripts/creaturescripts/player/world_light_time.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
local event = CreatureEvent("WorldTimeAndLight")

function event.onLogin(player)
local worldTime = Game.getWorldTime()
player:sendWorldTime(worldTime)

local worldLightColor, worldLightLevel = Game.getWorldLight()
player:sendWorldLight(worldLightColor, worldLightLevel)
return true
end

event:register()
51 changes: 51 additions & 0 deletions data/scripts/globalevents/world_light.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
local event = GlobalEvent("WorldLight")

local lightConfig = {
day = 250,
night = 40
}

local worldConfig = {
sunrise = 360,
dayTime = 480,
sunset = 1080,
nightTime = 1200
}

local lightChange = {
sunrise = math.floor((lightConfig.day - lightConfig.night) / (worldConfig.dayTime - worldConfig.sunrise) * 100) / 100,
sunset = math.floor((lightConfig.day - lightConfig.night) / (worldConfig.nightTime - worldConfig.sunset) * 100) / 100
}

do
-- load default values
local defaultColor = 215
local defaultLevel = lightConfig.day
Game.setWorldLight(defaultColor, defaultLevel)
end

local function calculateWorldLightLevel()
local worldTime = Game.getWorldTime()
if worldTime >= worldConfig.sunrise and worldTime <= worldConfig.dayTime then
return ((worldConfig.dayTime - worldConfig.sunrise) - (worldConfig.dayTime - worldTime)) * lightChange.sunrise + lightConfig.night
elseif worldTime >= worldConfig.sunset and worldTime <= worldConfig.nightTime then
return lightConfig.day - ((worldTime - worldConfig.sunset) * lightChange.sunset)
elseif worldTime >= worldConfig.nightTime or worldTime < worldConfig.sunrise then
return lightConfig.night
end
return lightConfig.day
end

function event.onTime(interval)
if not configManager.getBoolean(configKeys.DEFAULT_WORLD_LIGHT) then
return true
end

local worldLightColor, worldLightLevel = Game.getWorldLight()
local level = calculateWorldLightLevel()
Game.setWorldLight(worldLightColor, level)
return true
end

event:interval(10000) -- 10 seconds
event:register()
16 changes: 16 additions & 0 deletions data/scripts/globalevents/world_time.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
local event = GlobalEvent("WorldTime")

-- 1h realtime = 1day worldtime
-- 2.5s realtime = 1min worldtime
-- worldTime is calculated in minutes

function event.onTime(interval)
local currentTime = os.time()
local time = os.date("*t", currentTime)
local worldTime = (time.sec + (time.min * 60)) / 2.5
Game.setWorldTime(worldTime)
return true
end

event:interval(2500) -- 2.5 seconds
event:register()
48 changes: 0 additions & 48 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,7 @@ Game::~Game()
void Game::start(ServiceManager* manager)
{
serviceManager = manager;
updateWorldTime();

if (g_config.getBoolean(ConfigManager::DEFAULT_WORLD_LIGHT)) {
g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL, [this]() { checkLight(); }));
}
g_scheduler.addEvent(createSchedulerTask(EVENT_CREATURE_THINK_INTERVAL, [this]() { checkCreatures(0); }));
g_scheduler.addEvent(createSchedulerTask(EVENT_DECAYINTERVAL, [this]() { checkDecay(); }));
}
Expand Down Expand Up @@ -4875,50 +4871,6 @@ void Game::checkDecay()
cleanup();
}

void Game::checkLight()
{
g_scheduler.addEvent(createSchedulerTask(EVENT_LIGHTINTERVAL, [this]() { checkLight(); }));
uint8_t previousLightLevel = lightLevel;
updateWorldLightLevel();

if (previousLightLevel != lightLevel) {
LightInfo lightInfo = getWorldLightInfo();

for (const auto& it : players) {
it.second->sendWorldLight(lightInfo);
}
}
}

void Game::updateWorldLightLevel()
{
if (getWorldTime() >= GAME_SUNRISE && getWorldTime() <= GAME_DAYTIME) {
lightLevel = ((GAME_DAYTIME - GAME_SUNRISE) - (GAME_DAYTIME - getWorldTime())) * float(LIGHT_CHANGE_SUNRISE) +
LIGHT_NIGHT;
} else if (getWorldTime() >= GAME_SUNSET && getWorldTime() <= GAME_NIGHTTIME) {
lightLevel = LIGHT_DAY - ((getWorldTime() - GAME_SUNSET) * float(LIGHT_CHANGE_SUNSET));
} else if (getWorldTime() >= GAME_NIGHTTIME || getWorldTime() < GAME_SUNRISE) {
lightLevel = LIGHT_NIGHT;
} else {
lightLevel = LIGHT_DAY;
}
}

void Game::updateWorldTime()
{
g_scheduler.addEvent(createSchedulerTask(EVENT_WORLDTIMEINTERVAL, [this]() { updateWorldTime(); }));
time_t osTime = time(nullptr);
tm* timeInfo = localtime(&osTime);
worldTime = (timeInfo->tm_sec + (timeInfo->tm_min * 60)) / 2.5f;

// quarter-hourly update to client clock near the minimap
if (worldTime % 15 == 0) {
for (const auto& it : players) {
it.second->sendWorldTime();
}
}
}

void Game::shutdown()
{
std::cout << "Shutting down..." << std::flush;
Expand Down
32 changes: 0 additions & 32 deletions src/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,6 @@ class Game
size_t getNpcsOnline() const { return npcs.size(); }
uint32_t getPlayersRecord() const { return playersRecord; }

LightInfo getWorldLightInfo() const { return {lightLevel, lightColor}; }
void setWorldLightInfo(LightInfo lightInfo)
{
lightLevel = lightInfo.level;
lightColor = lightInfo.color;
for (const auto& it : players) {
it.second->sendWorldLight(lightInfo);
}
}
void updateWorldLightLevel();

ReturnValue internalMoveCreature(Creature* creature, Direction direction, uint32_t flags = 0);
ReturnValue internalMoveCreature(Creature& creature, Tile& toTile, uint32_t flags = 0);

Expand Down Expand Up @@ -466,9 +455,6 @@ class Game

void startDecay(Item* item);

int16_t getWorldTime() { return worldTime; }
void updateWorldTime();

void sendOfflineTrainingDialog(Player* player);

const std::unordered_map<uint32_t, Player*>& getPlayers() const { return players; }
Expand Down Expand Up @@ -558,24 +544,6 @@ class Game

ModalWindow offlineTrainingWindow{std::numeric_limits<uint32_t>::max(), "Choose a Skill", "Please choose a skill:"};

static constexpr uint8_t LIGHT_DAY = 250;
static constexpr uint8_t LIGHT_NIGHT = 40;
// 1h realtime = 1day worldtime
// 2.5s realtime = 1min worldtime
// worldTime is calculated in minutes
static constexpr int16_t GAME_SUNRISE = 360;
static constexpr int16_t GAME_DAYTIME = 480;
static constexpr int16_t GAME_SUNSET = 1080;
static constexpr int16_t GAME_NIGHTTIME = 1200;
static constexpr float LIGHT_CHANGE_SUNRISE =
static_cast<int>(float(float(LIGHT_DAY - LIGHT_NIGHT) / float(GAME_DAYTIME - GAME_SUNRISE)) * 100) / 100.0f;
static constexpr float LIGHT_CHANGE_SUNSET =
static_cast<int>(float(float(LIGHT_DAY - LIGHT_NIGHT) / float(GAME_NIGHTTIME - GAME_SUNSET)) * 100) / 100.0f;

uint8_t lightLevel = LIGHT_DAY;
uint8_t lightColor = 215;
int16_t worldTime = 0;

GameState_t gameState = GAME_STATE_NORMAL;
WorldType_t worldType = WORLD_TYPE_PVP;

Expand Down
42 changes: 0 additions & 42 deletions src/luascript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1081,15 +1081,6 @@ void LuaScriptInterface::registerFunctions()
// getDepotId(uid)
lua_register(luaState, "getDepotId", LuaScriptInterface::luaGetDepotId);

// getWorldTime()
lua_register(luaState, "getWorldTime", LuaScriptInterface::luaGetWorldTime);

// getWorldLight()
lua_register(luaState, "getWorldLight", LuaScriptInterface::luaGetWorldLight);

// setWorldLight(level, color)
lua_register(luaState, "setWorldLight", LuaScriptInterface::luaSetWorldLight);

// getWorldUpTime()
lua_register(luaState, "getWorldUpTime", LuaScriptInterface::luaGetWorldUpTime);

Expand Down Expand Up @@ -3595,39 +3586,6 @@ int LuaScriptInterface::luaDebugPrint(lua_State* L)
return 0;
}

int LuaScriptInterface::luaGetWorldTime(lua_State* L)
{
// getWorldTime()
int16_t time = g_game.getWorldTime();
lua_pushnumber(L, time);
return 1;
}

int LuaScriptInterface::luaGetWorldLight(lua_State* L)
{
// getWorldLight()
LightInfo lightInfo = g_game.getWorldLightInfo();
lua_pushnumber(L, lightInfo.level);
lua_pushnumber(L, lightInfo.color);
return 2;
}

int LuaScriptInterface::luaSetWorldLight(lua_State* L)
{
// setWorldLight(level, color)
if (g_config.getBoolean(ConfigManager::DEFAULT_WORLD_LIGHT)) {
pushBoolean(L, false);
return 1;
}

LightInfo lightInfo;
lightInfo.level = getNumber<uint8_t>(L, 1);
lightInfo.color = getNumber<uint8_t>(L, 2);
g_game.setWorldLightInfo(lightInfo);
pushBoolean(L, true);
return 1;
}

int LuaScriptInterface::luaGetWorldUpTime(lua_State* L)
{
// getWorldUpTime()
Expand Down
3 changes: 0 additions & 3 deletions src/luascript.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,7 @@ class LuaScriptInterface
static int luaGetDepotId(lua_State* L);

// get world info
static int luaGetWorldTime(lua_State* L);
static int luaGetWorldUpTime(lua_State* L);
static int luaGetWorldLight(lua_State* L);
static int luaSetWorldLight(lua_State* L);

// get subtype name
static int luaGetSubTypeName(lua_State* L);
Expand Down
12 changes: 0 additions & 12 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -991,18 +991,6 @@ class Player final : public Creature, public Cylinder
client->sendCloseTrade();
}
}
void sendWorldLight(LightInfo lightInfo)
{
if (client) {
client->sendWorldLight(lightInfo);
}
}
void sendWorldTime()
{
if (client) {
client->sendWorldTime();
}
}
void sendChannelsDialog()
{
if (client) {
Expand Down
21 changes: 0 additions & 21 deletions src/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1649,23 +1649,6 @@ void ProtocolGame::sendCreatureLight(const Creature* creature)
writeToOutputBuffer(msg);
}

void ProtocolGame::sendWorldLight(LightInfo lightInfo)
{
NetworkMessage msg;
AddWorldLight(msg, lightInfo);
writeToOutputBuffer(msg);
}

void ProtocolGame::sendWorldTime()
{
int16_t time = g_game.getWorldTime();
NetworkMessage msg;
msg.addByte(0xEF);
msg.addByte(time / 60); // hour
msg.addByte(time % 60); // min
writeToOutputBuffer(msg);
}

void ProtocolGame::sendCreatureWalkthrough(const Creature* creature, bool walkthrough)
{
if (!canSee(creature)) {
Expand Down Expand Up @@ -2844,10 +2827,6 @@ void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos
// send store inbox
sendInventoryItem(CONST_SLOT_STORE_INBOX, player->getStoreInbox()->getItem());

// gameworld time of the day
sendWorldLight(g_game.getWorldLightInfo());
sendWorldTime();

// player light level
sendCreatureLight(creature);

Expand Down
Loading

0 comments on commit 3877aa9

Please sign in to comment.