Skip to content

Commit

Permalink
world light to lua / effect & mastereffect
Browse files Browse the repository at this point in the history
  • Loading branch information
MillhioreBT committed Dec 13, 2023
1 parent 4e7231e commit f52b7dc
Show file tree
Hide file tree
Showing 19 changed files with 210 additions and 205 deletions.
2 changes: 1 addition & 1 deletion .lua-format
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ continuation_indent_width: 1
use_tab: true
tab_width: 4
chop_down_table: true
column_limit: 130
column_limit: 100
39 changes: 39 additions & 0 deletions data/lib/core/game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,42 @@ do
return table.concat(response, " ")
end
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
100 changes: 43 additions & 57 deletions data/lib/core/player.lua
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
local foodCondition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)

function Player.feed(self, food)
local condition =
self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
if condition then
condition:setTicks(condition:getTicks() + (food * 1000))
else
local vocation = self:getVocation()
if not vocation then return nil end

foodCondition:setTicks(food * 1000)
foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN,
vocation:getHealthGainAmount())
foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS,
vocation:getHealthGainTicks() * 1000)
foodCondition:setParameter(CONDITION_PARAM_MANAGAIN,
vocation:getManaGainAmount())
foodCondition:setParameter(CONDITION_PARAM_MANATICKS,
vocation:getManaGainTicks() * 1000)
foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN, vocation:getHealthGainAmount())
foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS, vocation:getHealthGainTicks() * 1000)
foodCondition:setParameter(CONDITION_PARAM_MANAGAIN, vocation:getManaGainAmount())
foodCondition:setParameter(CONDITION_PARAM_MANATICKS, vocation:getManaGainTicks() * 1000)

self:addCondition(foodCondition)
end
return true
end

function Player.getClosestFreePosition(self, position, extended)
if self:getGroup():getAccess() and self:getAccountType() >= ACCOUNT_TYPE_GOD then
return position
end
if self:getGroup():getAccess() and self:getAccountType() >= ACCOUNT_TYPE_GOD then return position end
return Creature.getClosestFreePosition(self, position, extended)
end

Expand All @@ -39,22 +32,13 @@ function Player.hasFlag(self, flag) return self:getGroup():hasFlag(flag) end

function Player.getLossPercent(self)
local blessings = 0
local lossPercent = {
[0] = 100,
[1] = 70,
[2] = 45,
[3] = 25,
[4] = 10,
[5] = 0
}
local lossPercent = {[0] = 100, [1] = 70, [2] = 45, [3] = 25, [4] = 10, [5] = 0}

for i = 1, 5 do if self:hasBlessing(i) then blessings = blessings + 1 end end
return lossPercent[blessings]
end

function Player.getPremiumTime(self)
return math.max(0, self:getPremiumEndsAt() - os.time())
end
function Player.getPremiumTime(self) return math.max(0, self:getPremiumEndsAt() - os.time()) end

function Player.setPremiumTime(self, seconds)
self:setPremiumEndsAt(os.time() + seconds)
Expand All @@ -74,21 +58,14 @@ function Player.removePremiumTime(self, seconds)
return true
end

function Player.getPremiumDays(self)
return math.floor(self:getPremiumTime() / 86400)
end
function Player.getPremiumDays(self) return math.floor(self:getPremiumTime() / 86400) end

function Player.addPremiumDays(self, days)
return self:addPremiumTime(days * 86400)
end
function Player.addPremiumDays(self, days) return self:addPremiumTime(days * 86400) end

function Player.removePremiumDays(self, days)
return self:removePremiumTime(days * 86400)
end
function Player.removePremiumDays(self, days) return self:removePremiumTime(days * 86400) end

function Player.isPremium(self)
return self:getPremiumTime() > 0 or
configManager.getBoolean(configKeys.FREE_PREMIUM) or
return self:getPremiumTime() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) or
self:hasFlag(PlayerFlag_IsAlwaysPremium)
end

Expand All @@ -97,14 +74,12 @@ function Player.sendCancelMessage(self, message)
return self:sendTextMessage(MESSAGE_STATUS_SMALL, message)
end

function Player.isUsingOtClient(self)
return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX
end
function Player.isUsingOtClient(self) return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX end

function Player.sendExtendedOpcode(self, opcode, buffer)
if not self:isUsingOtClient() then return false end

local networkMessage <close> = NetworkMessage()
local networkMessage<close> = NetworkMessage()
networkMessage:addByte(0x32)
networkMessage:addByte(opcode)
networkMessage:addString(buffer)
Expand All @@ -125,8 +100,8 @@ function Player.transferMoneyTo(self, target, amount)
if targetPlayer then
targetPlayer:setBankBalance(targetPlayer:getBankBalance() + amount)
else
db.query("UPDATE `players` SET `balance` = `balance` + " .. amount ..
" WHERE `id` = '" .. target.guid .. "'")
db.query("UPDATE `players` SET `balance` = `balance` + " .. amount .. " WHERE `id` = '" ..
target.guid .. "'")
end

self:setBankBalance(self:getBankBalance() - amount)
Expand Down Expand Up @@ -163,9 +138,7 @@ function Player.canCarryMoney(self, amount)

-- If player don't have enough available inventory slots to carry this money
local backpack = self:getSlotItem(CONST_SLOT_BACKPACK)
if not backpack or backpack:getEmptySlots(true) < inventorySlots then
return false
end
if not backpack or backpack:getEmptySlots(true) < inventorySlots then return false end
return true
end

Expand Down Expand Up @@ -215,12 +188,11 @@ function Player.addLevel(self, amount, round)
local level, amount = self:getLevel(), amount or 1
if amount > 0 then
return self:addExperience(Game.getExperienceForLevel(level + amount) -
(round and self:getExperience() or
Game.getExperienceForLevel(level)))
(round and self:getExperience() or Game.getExperienceForLevel(level)))
else
return self:removeExperience(((round and self:getExperience() or
Game.getExperienceForLevel(level)) -
Game.getExperienceForLevel(level + amount)))
return self:removeExperience(
((round and self:getExperience() or Game.getExperienceForLevel(level)) -
Game.getExperienceForLevel(level + amount)))
end
end

Expand All @@ -238,8 +210,7 @@ function Player.addMagicLevel(self, value)
else
value = math.min(currentMagLevel, math.abs(value))
while value > 0 do
sum = sum +
self:getVocation():getRequiredManaSpent(currentMagLevel - value + 1)
sum = sum + self:getVocation():getRequiredManaSpent(currentMagLevel - value + 1)
value = value - 1
end

Expand All @@ -253,19 +224,15 @@ function Player.addSkillLevel(self, skillId, value)

if value > 0 then
while value > 0 do
sum = sum +
self:getVocation()
:getRequiredSkillTries(skillId, currentSkillLevel + value)
sum = sum + self:getVocation():getRequiredSkillTries(skillId, currentSkillLevel + value)
value = value - 1
end

return self:addSkillTries(skillId, sum - self:getSkillTries(skillId))
else
value = math.min(currentSkillLevel, math.abs(value))
while value > 0 do
sum = sum +
self:getVocation()
:getRequiredSkillTries(skillId, currentSkillLevel - value + 1)
sum = sum + self:getVocation():getRequiredSkillTries(skillId, currentSkillLevel - value + 1)
value = value - 1
end

Expand Down Expand Up @@ -297,3 +264,22 @@ function Player.removeTibiaCoins(self, removeCoins)
if tibiaCoins < removeCoins then return false end
return self:setTibiaCoins(tibiaCoins - removeCoins)
end

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

function Player.sendWorldTime(self, time)
if self:getClient().version < 1272 then return false end
local msg<close> = NetworkMessage()
msg:addByte(0xEF)
msg:addByte(time / 60) -- hour
msg:addByte(time % 60) -- min
msg:sendToPlayer(self)
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()
44 changes: 44 additions & 0 deletions data/scripts/globalevents/world_light.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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 math.floor(((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()
17 changes: 17 additions & 0 deletions data/scripts/globalevents/world_time.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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 sec = os.date("%S", currentTime)
local min = os.date("%M", currentTime)
local worldTime = (sec + (min * 60)) / 2.5
Game.setWorldTime(worldTime)
return true
end

event:interval(2500) -- 2.5 seconds
event:register()
2 changes: 1 addition & 1 deletion data/scripts/lib/register_monster_type.lua
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ end
registerMonsterType.summons = function(mtype, mask)
if type(mask.summons) == "table" then
for k, v in pairs(mask.summons) do
mtype:addSummon(v.name, v.interval, v.chance)
mtype:addSummon(v.name, v.interval, v.chance, v.effect, v.masterEffect)
end
end
end
Expand Down
42 changes: 0 additions & 42 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ Game::~Game()
void Game::start(ServiceManager* manager)
{
serviceManager = manager;
updateWorldTime();

if (g_config[ConfigKeysBoolean::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 @@ -4588,43 +4583,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);
struct tm timeInfo = fmt::localtime(osTime);
worldTime = (timeInfo.tm_sec + (timeInfo.tm_min * 60)) / 2.5f;
}

void Game::shutdown()
{
std::cout << "Shutting down..." << std::flush;
Expand Down
Loading

0 comments on commit f52b7dc

Please sign in to comment.