From 526ef51758f65d4db995c51b82bd2e760f43e4c1 Mon Sep 17 00:00:00 2001 From: Beats <61994374+beats-dh@users.noreply.github.com> Date: Fri, 27 May 2022 15:56:22 -0300 Subject: [PATCH] Fix Event Scheduler (#239) This works directly with: https://github.com/opentibiabr/otservbr-global/pull/471 --- config.lua.dist | 9 +- data/XML/events.xml | 4 +- data/events/scripts/player.lua | 101 +++++++++++++--- data/global.lua | 18 +-- data/lib/core/functions/functions.lua | 11 +- data/lib/core/storages.lua | 1 + .../scripts/daily_reward/daily_reward.lua | 30 ++--- data/scripts/creaturescripts/advance_save.lua | 39 ++++++ data/scripts/creaturescripts/login.lua | 60 ++++++++++ data/scripts/globalevents/startup.lua | 31 +++++ data/scripts/talkactions/god/reload.lua | 7 +- .../talkactions/player/server_info.lua | 2 +- src/CMakeLists.txt | 2 + src/config/config_definitions.hpp | 1 + src/config/configmanager.cpp | 9 +- .../monsters/spawns/spawn_monster.cpp | 11 +- src/creatures/monsters/spawns/spawn_monster.h | 2 +- src/creatures/players/grouping/party.cpp | 6 +- src/creatures/players/grouping/party.h | 2 +- src/creatures/players/player.cpp | 12 +- src/creatures/players/player.h | 6 +- src/game/game.cpp | 86 -------------- src/game/game.h | 37 ------ src/game/scheduling/events_scheduler.cpp | 111 ++++++++++++++++++ src/game/scheduling/events_scheduler.hpp | 86 ++++++++++++++ src/lua/creature/events.cpp | 14 +-- src/lua/creature/events.h | 2 +- .../functions/core/game/config_functions.hpp | 1 + .../functions/core/game/game_functions.cpp | 18 --- .../functions/core/game/game_functions.hpp | 8 -- src/lua/functions/events/events_functions.hpp | 2 + .../events/events_scheduler_functions.cpp | 47 ++++++++ .../events/events_scheduler_functions.hpp | 46 ++++++++ src/otserv.cpp | 10 +- 34 files changed, 586 insertions(+), 246 deletions(-) create mode 100644 data/scripts/creaturescripts/advance_save.lua create mode 100644 src/game/scheduling/events_scheduler.cpp create mode 100644 src/game/scheduling/events_scheduler.hpp create mode 100644 src/lua/functions/events/events_scheduler_functions.cpp create mode 100644 src/lua/functions/events/events_scheduler_functions.hpp diff --git a/config.lua.dist b/config.lua.dist index 4c4b2dd6637..581cee0cc0d 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -214,12 +214,13 @@ globalServerSaveTime = "06:00:00" sortLootByChance = false -- Rates --- NOTE: rateExp, rateSkill and rateMagic is used as a fallback only +-- NOTE: rateExp, rateSkill and rateMagic are only used when 'rateUseStages = false' -- To configure rates see file data/stages.lua +rateUseStages = false rateExp = 1 -rateSkill = 50 -rateLoot = 3 -rateMagic = 25 +rateSkill = 1 +rateLoot = 1 +rateMagic = 1 rateSpawn = 1 -- Today regeneration condition over an loop every 1 second, diff --git a/data/XML/events.xml b/data/XML/events.xml index c59ad0b4609..e2cdd69c24f 100644 --- a/data/XML/events.xml +++ b/data/XML/events.xml @@ -6,8 +6,8 @@
- - + +
diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua index 70a603e6695..1594eb57c85 100644 --- a/data/events/scripts/player.lua +++ b/data/events/scripts/player.lua @@ -272,8 +272,43 @@ local function useStamina(player) player:setStamina(staminaMinutes) end -function Player:onGainExperience(source, exp, rawExp) - if not source or source:isPlayer() then +local function useStaminaXpBoost(player) + if not player then + return false + end + + local staminaMinutes = player:getExpBoostStamina() / 60 + if staminaMinutes == 0 then + return + end + + local playerId = player:getId() + if not playerId then + return false + end + + local currentTime = os.time() + local timePassed = currentTime - nextUseXpStamina[playerId] + if timePassed <= 0 then + return + end + + if timePassed > 60 then + if staminaMinutes > 2 then + staminaMinutes = staminaMinutes - 2 + else + staminaMinutes = 0 + end + nextUseXpStamina[playerId] = currentTime + 120 + else + staminaMinutes = staminaMinutes - 1 + nextUseXpStamina[playerId] = currentTime + 60 + end + player:setExpBoostStamina(staminaMinutes * 60) +end + +function Player:onGainExperience(target, exp, rawExp) + if not target or target:isPlayer() then return exp end @@ -285,31 +320,49 @@ function Player:onGainExperience(source, exp, rawExp) end -- Experience Stage Multiplier - local expStage = getRateFromTable(experienceStages, self:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) - exp = exp * expStage - baseExp = rawExp * expStage + local expStage = getRateFromTable(experienceStages, self:getLevel(), configManager.getNumber(configKeys.RATE_EXPERIENCE)) + + -- Event scheduler + if SCHEDULE_EXP_RATE ~= 100 then + expStage = math.max(0, (expStage * SCHEDULE_EXP_RATE)/100) + end + + -- Store Bonus + useStaminaXpBoost(self) -- Use store boost stamina + + local Boost = self:getExpBoostStamina() + local stillHasBoost = Boost > 0 + local storeXpBoostAmount = stillHasBoost and self:getStoreXpBoost() or 0 + + self:setStoreXpBoost(storeXpBoostAmount) - -- Stamina modifier + -- Stamina Bonus + local staminaBoost = 1 if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then useStamina(self) - local staminaMinutes = self:getStamina() - if staminaMinutes > 2400 and self:isPremium() then - exp = exp * 1.5 - elseif staminaMinutes <= 840 then - exp = exp * 0.5 - end + if staminaMinutes > 2340 and self:isPremium() then + staminaBoost = 1.5 + elseif staminaMinutes <= 840 then + staminaBoost = 0.5 --TODO destroy loot of people with 840- stamina + end + self:setStaminaXpBoost(staminaBoost * 100) + end + + -- Boosted creature + if target:getName():lower() == (Game.getBoostedCreature()):lower() then + exp = exp * 2 end -- Prey system if configManager.getBoolean(configKeys.PREY_ENABLED) then - local monsterType = source:getType() + local monsterType = target:getType() if monsterType and monsterType:raceId() > 0 then exp = math.ceil((exp * self:getPreyExperiencePercentage(monsterType:raceId())) / 100) end end - return exp + return math.max((exp * expStage + (exp * (storeXpBoostAmount/100))) * staminaBoost) end function Player:onLoseExperience(exp) @@ -321,10 +374,24 @@ function Player:onGainSkillTries(skill, tries) return tries end - if skill == SKILL_MAGLEVEL then - return tries * configManager.getNumber(configKeys.RATE_MAGIC) + -- Event scheduler skill rate + local STAGES_DEFAULT = skillsStages or nil + local SKILL_DEFAULT = self:getSkillLevel(skill) + local RATE_DEFAULT = configManager.getNumber(configKeys.RATE_SKILL) + + if(skill == SKILL_MAGLEVEL) then -- Magic Level + STAGES_DEFAULT = magicLevelStages or nil + SKILL_DEFAULT = self:getBaseMagicLevel() + RATE_DEFAULT = configManager.getNumber(configKeys.RATE_MAGIC) end - return tries * configManager.getNumber(configKeys.RATE_SKILL) + + skillOrMagicRate = getRateFromTable(STAGES_DEFAULT, SKILL_DEFAULT, RATE_DEFAULT) + + if SCHEDULE_SKILL_RATE ~= 100 then + skillOrMagicRate = math.max(0, (skillOrMagicRate * SCHEDULE_SKILL_RATE) / 100) + end + + return tries / 100 * (skillOrMagicRate * 100) end function Player:onChangeZone(zone) diff --git a/data/global.lua b/data/global.lua index 626234e1742..6affec445dc 100644 --- a/data/global.lua +++ b/data/global.lua @@ -35,6 +35,7 @@ weatherConfig = { SCHEDULE_LOOT_RATE = 100 SCHEDULE_EXP_RATE = 100 SCHEDULE_SKILL_RATE = 100 +SCHEDULE_SPAWN_RATE = 100 -- MARRY PROPOSED_STATUS = 1 @@ -65,23 +66,6 @@ if damageImpact == nil then damageImpact = {} end -do -- Event Schedule rates - local lootRate = Game.getEventSLoot() - if lootRate ~= 100 then - SCHEDULE_LOOT_RATE = lootRate - end - - local expRate = Game.getEventSExp() - if expRate ~= 100 then - SCHEDULE_EXP_RATE = expRate - end - - local skillRate = Game.getEventSSkill() - if skillRate ~= 100 then - SCHEDULE_SKILL_RATE = skillRate - end -end - table.contains = function(array, value) for _, targetColumn in pairs(array) do if targetColumn == value then diff --git a/data/lib/core/functions/functions.lua b/data/lib/core/functions/functions.lua index ef882a8e683..a8973e18f93 100644 --- a/data/lib/core/functions/functions.lua +++ b/data/lib/core/functions/functions.lua @@ -62,7 +62,8 @@ function getFormattedWorldTime() end function getLootRandom() - return math.random(0, MAX_LOOTCHANCE) * 100 / (configManager.getNumber(configKeys.RATE_LOOT) * SCHEDULE_LOOT_RATE) + local multi = (configManager.getNumber(configKeys.RATE_LOOT) * SCHEDULE_LOOT_RATE) + return math.random(0, MAX_LOOTCHANCE) * 100 / math.max(1, multi) end local start = os.time() @@ -81,9 +82,11 @@ debug.sethook(function(event, line) end, "l") function getRateFromTable(t, level, default) - for _, rate in ipairs(t) do - if level >= rate.minlevel and (not rate.maxlevel or level <= rate.maxlevel) then - return rate.multiplier + if (t ~= nil) then + for _, rate in ipairs(t) do + if level >= rate.minlevel and (not rate.maxlevel or level <= rate.maxlevel) then + return rate.multiplier + end end end return default diff --git a/data/lib/core/storages.lua b/data/lib/core/storages.lua index 068654a6a12..61586d80aee 100644 --- a/data/lib/core/storages.lua +++ b/data/lib/core/storages.lua @@ -43,6 +43,7 @@ Storage = { } GlobalStorage = { + XpDisplayMode = 65006, ExampleQuest = { Example = 60000 } diff --git a/data/modules/scripts/daily_reward/daily_reward.lua b/data/modules/scripts/daily_reward/daily_reward.lua index 95bb6c79cf9..174ea2ec7f8 100644 --- a/data/modules/scripts/daily_reward/daily_reward.lua +++ b/data/modules/scripts/daily_reward/daily_reward.lua @@ -232,21 +232,21 @@ DailyReward.retrieveHistoryEntries = function(playerId) return entries end -DailyReward.loadDailyReward = function(playerId, source) +DailyReward.loadDailyReward = function(playerId, target) local player = Player(playerId) if not player then return false end - if source ~= 0 then - source = REWARD_FROM_SHRINE + if target ~= 0 then + target = REWARD_FROM_SHRINE else - source = REWARD_FROM_PANEL + target = REWARD_FROM_PANEL end player:sendCollectionResource(ClientPackets.JokerResource, player:getJokerTokens()) player:sendCollectionResource(ClientPackets.CollectionResource, player:getCollectionTokens()) player:sendDailyReward() - player:sendOpenRewardWall(source) + player:sendOpenRewardWall(target) player:sendDailyRewardCollectionState(DailyReward.isRewardTaken(player:getId()) and DAILY_REWARD_COLLECTED or DAILY_REWARD_NOTCOLLECTED) return true end @@ -273,8 +273,8 @@ DailyReward.pickedReward = function(playerId) return true end -DailyReward.isShrine = function(source) - if source ~= 0 then +DailyReward.isShrine = function(target) + if target ~= 0 then return false else return true @@ -349,9 +349,9 @@ DailyReward.init = function(playerId) player:loadDailyRewardBonuses() end -DailyReward.processReward = function(playerId, source) +DailyReward.processReward = function(playerId, target) DailyReward.pickedReward(playerId) - DailyReward.loadDailyReward(playerId, source) + DailyReward.loadDailyReward(playerId, target) local player = Player(playerId) if player then player:loadDailyRewardBonuses() @@ -405,8 +405,8 @@ function Player.selectDailyReward(self, msg) return false end - local source = msg:getByte() -- 0 -> shrine / 1 -> tibia panel - if not DailyReward.isShrine(source) then + local target = msg:getByte() -- 0 -> shrine / 1 -> tibia panel + if not DailyReward.isShrine(target) then if self:getCollectionTokens() < 1 then self:sendError("You do not have enough collection tokens to proceed.") return false @@ -477,7 +477,7 @@ function Player.selectDailyReward(self, msg) -- Registering history DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z " .. self:getDayStreak() + 1 .. ". Picked items: " .. description) - DailyReward.processReward(playerId, source) + DailyReward.processReward(playerId, target) end local reward = nil @@ -501,7 +501,7 @@ function Player.selectDailyReward(self, msg) -- end -- DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z -- " .. self:getDayStreak() + 1 .. ". Picked reward: " .. description) - -- DailyReward.processReward(playerId, source) + -- DailyReward.processReward(playerId, target) -- end if (dailyTable.type == DAILY_REWARD_TYPE_XP_BOOST) then @@ -509,14 +509,14 @@ function Player.selectDailyReward(self, msg) self:setStoreXpBoost(50) DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z " .. self:getDayStreak() + 1 .. ". Picked reward: XP Bonus for " .. reward .. " minutes.") - DailyReward.processReward(playerId, source) + DailyReward.processReward(playerId, target) end if (dailyTable.type == DAILY_REWARD_TYPE_PREY_REROLL) then self:addPreyCards(reward) DailyReward.insertHistory(self:getGuid(), self:getDayStreak(), "Claimed reward no. \z " .. self:getDayStreak() + 1 .. ". Picked reward: " .. reward .. "x Prey bonus reroll(s)") - DailyReward.processReward(playerId, source) + DailyReward.processReward(playerId, target) end return true diff --git a/data/scripts/creaturescripts/advance_save.lua b/data/scripts/creaturescripts/advance_save.lua new file mode 100644 index 00000000000..ab2905e1c19 --- /dev/null +++ b/data/scripts/creaturescripts/advance_save.lua @@ -0,0 +1,39 @@ +local config = { + heal = true, + save = true, + effect = false +} + +local advanceSave = CreatureEvent("AdvanceSave") + +function advanceSave.onAdvance(player, skill, oldLevel, newLevel) + if skill ~= SKILL_LEVEL or newLevel <= oldLevel then + return true + end + + if config.effect then + player:getPosition():sendMagicEffect(math.random(CONST_ME_FIREWORK_YELLOW, CONST_ME_FIREWORK_BLUE)) + player:say('LEVEL UP!', TALKTYPE_MONSTER_SAY) + end + + if config.heal then + player:addHealth(player:getMaxHealth()) + end + + if config.save then + player:save() + end + + if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then + local baseRate = getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXPERIENCE)) + -- Event scheduler + if SCHEDULE_EXP_RATE ~= 100 then + baseRate = math.max(0, (baseRate * SCHEDULE_EXP_RATE)/100) + end + player:setBaseXpGain(baseRate * 100) + end + + return true +end + +advanceSave:register() diff --git a/data/scripts/creaturescripts/login.lua b/data/scripts/creaturescripts/login.lua index efe62ff5b08..ea22cb2a7c1 100644 --- a/data/scripts/creaturescripts/login.lua +++ b/data/scripts/creaturescripts/login.lua @@ -40,6 +40,66 @@ function login.onLogin(player) onExerciseTraining[player:getId()] = nil player:setTraining(false) end + + -- Boosted creature + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Today's boosted creature: " .. Game.getBoostedCreature() .. " \ + Boosted creatures yield more experience points, carry more loot than usual and respawn at a faster rate.") + + if SCHEDULE_EXP_RATE ~= 100 then + if SCHEDULE_EXP_RATE > 100 then + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Exp Rate Event! Monsters yield more experience points than usual \ + Happy Hunting!") + else + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Exp Rate Decreased! Monsters yield less experience points than usual.") + end + end + + if SCHEDULE_SPAWN_RATE ~= 100 then + if SCHEDULE_SPAWN_RATE > 100 then + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Spawn Rate Event! Monsters respawn at a faster rate \ + Happy Hunting!") + else + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Spawn Rate Decreased! Monsters respawn at a slower rate.") + end + end + + if SCHEDULE_LOOT_RATE ~= 100 then + if SCHEDULE_LOOT_RATE > 100 then + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Loot Rate Event! Monsters carry more loot than usual \ + Happy Hunting!") + else + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Loot Rate Decreased! Monsters carry less loot than usual.") + end + end + + if SCHEDULE_SKILL_RATE ~= 100 then + if SCHEDULE_SKILL_RATE > 100 then + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Skill Rate Event! Your skills progresses at a higher rate \ + Happy Hunting!") + else + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Skill Rate Decreased! Your skills progresses at a lower rate.") + end + end + + local playerId = player:getId() + + -- Stamina + nextUseStaminaTime[playerId] = 1 + + -- EXP Stamina + nextUseXpStamina[playerId] = 1 + + -- Set Client XP Gain Rate -- + local rateExp = 1 + if Game.getStorageValue(GlobalStorage.XpDisplayMode) > 0 then + rateExp = getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXPERIENCE)) + if SCHEDULE_EXP_RATE ~= 100 then + rateExp = math.max(0, (rateExp * SCHEDULE_EXP_RATE)/100) + end + end + + player:setBaseXpGain(rateExp * 100) + return true end diff --git a/data/scripts/globalevents/startup.lua b/data/scripts/globalevents/startup.lua index d3135d4fdfa..fbcfbd1645e 100644 --- a/data/scripts/globalevents/startup.lua +++ b/data/scripts/globalevents/startup.lua @@ -49,6 +49,37 @@ function startup.onStartup() local position = town:getTemplePosition() db.query("INSERT INTO `towns` (`id`, `name`, `posx`, `posy`, `posz`) VALUES (" .. town:getId() .. ", " .. db.escapeString(town:getName()) .. ", " .. position.x .. ", " .. position.y .. ", " .. position.z .. ")") end + + do -- Event Schedule rates + local lootRate = EventsScheduler.getEventSLoot() + if lootRate ~= 100 then + SCHEDULE_LOOT_RATE = lootRate + end + + local expRate = EventsScheduler.getEventSExp() + if expRate ~= 100 then + SCHEDULE_EXP_RATE = expRate + end + + local skillRate = EventsScheduler.getEventSSkill() + if skillRate ~= 100 then + SCHEDULE_SKILL_RATE = skillRate + end + + local spawnRate = EventsScheduler.getSpawnMonsterSchedule() + if spawnRate ~= 100 then + SCHEDULE_SPAWN_RATE = spawnRate + end + + if expRate ~= 100 or lootRate ~= 100 or spawnRate ~= 100 or skillRate ~= 100 then + Spdlog.info("Events: " .. "Exp: " .. expRate .. "%, " .. "loot: " .. lootRate .. "%, " .. "Spawn: " .. spawnRate .. "%, " .. "Skill: ".. skillRate .."%") + end + end + + -- Client XP Display Mode + -- 0 = ignore exp rate /stage + -- 1 = include exp rate / stage + Game.setStorageValue(GlobalStorage.XpDisplayMode, 1) end startup:register() diff --git a/data/scripts/talkactions/god/reload.lua b/data/scripts/talkactions/god/reload.lua index c1ed4e7e154..a184a2c79d0 100644 --- a/data/scripts/talkactions/god/reload.lua +++ b/data/scripts/talkactions/god/reload.lua @@ -30,7 +30,12 @@ local reloadTypes = { ["raids"] = RELOAD_TYPE_RAIDS, ["scripts"] = RELOAD_TYPE_SCRIPTS, - ["libs"] = RELOAD_TYPE_GLOBAL + + ["libs"] = RELOAD_TYPE_GLOBAL, + + ["stages"] = RELOAD_TYPE_STAGES, + + ["imbuements"] = RELOAD_TYPE_IMBUEMENTS } local reload = TalkAction("/reload") diff --git a/data/scripts/talkactions/player/server_info.lua b/data/scripts/talkactions/player/server_info.lua index a5ef27e81a3..db7669abfa1 100644 --- a/data/scripts/talkactions/player/server_info.lua +++ b/data/scripts/talkactions/player/server_info.lua @@ -2,7 +2,7 @@ local serverInfo = TalkAction("!serverinfo") function serverInfo.onSay(player, words, param) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Server Info:" - .. "\nExp rate: " .. getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXP)) + .. "\nExp rate: " .. getRateFromTable(experienceStages, player:getLevel(), configManager.getNumber(configKeys.RATE_EXPERIENCE)) .. "\nSkill rate: " .. configManager.getNumber(configKeys.RATE_SKILL) .. "\nMagic rate: " .. configManager.getNumber(configKeys.RATE_MAGIC) .. "\nLoot rate: " .. configManager.getNumber(configKeys.RATE_LOOT)) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f6acacff2da..61a20d69d10 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -176,6 +176,7 @@ target_sources(${PROJECT_NAME} game/movement/position.cpp game/movement/teleport.cpp game/scheduling/scheduler.cpp + game/scheduling/events_scheduler.cpp game/scheduling/tasks.cpp io/fileloader.cpp io/iobestiary.cpp @@ -242,6 +243,7 @@ target_sources(${PROJECT_NAME} lua/functions/creatures/player/vocation_functions.cpp lua/functions/events/action_functions.cpp lua/functions/events/creature_event_functions.cpp + lua/functions/events/events_scheduler_functions.cpp lua/functions/events/global_event_functions.cpp lua/functions/events/move_event_functions.cpp lua/functions/events/talk_action_functions.cpp diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp index 1e408ba5c0e..943a9689a21 100644 --- a/src/config/config_definitions.hpp +++ b/src/config/config_definitions.hpp @@ -73,6 +73,7 @@ enum booleanConfig_t { TOGGLE_IMBUEMENT_SHRINE_STORAGE, AUTOLOOT, AUTOBANK, + RATE_USE_STAGES, LAST_BOOLEAN_CONFIG }; diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 3568b916a3c..d4e937237df 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -183,6 +183,7 @@ bool ConfigManager::load() boolean[TOGGLE_SAVE_INTERVAL_CLEAN_MAP] = getGlobalBoolean(L, "toggleSaveIntervalCleanMap", false); boolean[ONLY_PREMIUM_ACCOUNT] = getGlobalBoolean(L, "onlyPremiumAccount", false); + boolean[RATE_USE_STAGES] = getGlobalBoolean(L, "rateUseStages", false); boolean[TOGGLE_IMBUEMENT_SHRINE_STORAGE] = getGlobalBoolean(L, "toggleImbuementShrineStorage", true); string[DEFAULT_PRIORITY] = getGlobalString(L, "defaultPriority", "high"); @@ -202,10 +203,10 @@ bool ConfigManager::load() integer[PZ_LOCKED] = getGlobalNumber(L, "pzLocked", 60000); integer[DEFAULT_DESPAWNRANGE] = getGlobalNumber(L, "deSpawnRange", 2); integer[DEFAULT_DESPAWNRADIUS] = getGlobalNumber(L, "deSpawnRadius", 50); - integer[RATE_EXPERIENCE] = getGlobalNumber(L, "rateExp", 5); - integer[RATE_SKILL] = getGlobalNumber(L, "rateSkill", 3); - integer[RATE_LOOT] = getGlobalNumber(L, "rateLoot", 2); - integer[RATE_MAGIC] = getGlobalNumber(L, "rateMagic", 3); + integer[RATE_EXPERIENCE] = getGlobalNumber(L, "rateExp", 1); + integer[RATE_SKILL] = getGlobalNumber(L, "rateSkill", 1); + integer[RATE_LOOT] = getGlobalNumber(L, "rateLoot", 1); + integer[RATE_MAGIC] = getGlobalNumber(L, "rateMagic", 1); integer[RATE_SPAWN] = getGlobalNumber(L, "rateSpawn", 1); integer[HOUSE_PRICE] = getGlobalNumber(L, "housePriceEachSQM", 1000); integer[ACTIONS_DELAY_INTERVAL] = getGlobalNumber(L, "timeBetweenActions", 200); diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index 2e2724b5a0f..55b8f0f8dcf 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -23,6 +23,7 @@ #include "game/game.h" #include "creatures/monsters/monster.h" #include "game/scheduling/scheduler.h" +#include "game/scheduling/events_scheduler.hpp" #include "utils/pugicast.h" #include "lua/creature/events.h" @@ -46,7 +47,7 @@ bool SpawnsMonster::loadFromXML(const std::string& filemonstername) this->filemonstername = filemonstername; loaded = true; - uint32_t eventschedule = g_game().getSpawnMonsterSchedule(); + uint32_t eventschedule = g_eventsScheduler().getSpawnMonsterSchedule(); std::string boostedNameGet = g_game().getBoostedMonsterName(); for (auto spawnMonsterNode : doc.child("monsters").children()) { @@ -94,20 +95,18 @@ bool SpawnsMonster::loadFromXML(const std::string& filemonstername) centerPos.z ); - int32_t boostedrate; + int32_t boostedrate = 1; if (nameAttribute.value() == boostedNameGet) { boostedrate = 2; - } else { - boostedrate = 1; } - uint32_t interval = pugi::cast(childMonsterNode.attribute("spawntime").value()) * 100000 / (g_configManager().getNumber(RATE_SPAWN) * boostedrate * eventschedule); + uint32_t interval = pugi::cast(childMonsterNode.attribute("spawntime").value()) * 1000 * 100 / std::max((uint32_t)1, (g_configManager().getNumber(RATE_SPAWN) * boostedrate * eventschedule)); if (interval >= MONSTER_MINSPAWN_INTERVAL && interval <= MONSTER_MAXSPAWN_INTERVAL) { spawnMonster.addMonster(nameAttribute.as_string(), pos, dir, static_cast(interval)); } else { if (interval <= MONSTER_MINSPAWN_INTERVAL) { - SPDLOG_WARN("[SpawnsMonster::loadFromXml] - {} {} spawntime can not be less than {} seconds", nameAttribute.as_string(), pos.toString(), MONSTER_MINSPAWN_INTERVAL / 1000); + SPDLOG_WARN("[SpawnsMonster::loadFromXml] - {} {} spawntime cannot be less than {} seconds, set to {} by default.", nameAttribute.as_string(), pos.toString(), MONSTER_MINSPAWN_INTERVAL / 1000, MONSTER_MINSPAWN_INTERVAL / 1000); spawnMonster.addMonster(nameAttribute.as_string(), pos, dir, MONSTER_MINSPAWN_INTERVAL); } else { SPDLOG_WARN("[SpawnsMonster::loadFromXml] - {} {} spawntime can not be more than {} seconds", nameAttribute.as_string(), pos.toString(), MONSTER_MAXSPAWN_INTERVAL / 1000); } diff --git a/src/creatures/monsters/spawns/spawn_monster.h b/src/creatures/monsters/spawns/spawn_monster.h index 663bbc802f2..82498cdc0d9 100644 --- a/src/creatures/monsters/spawns/spawn_monster.h +++ b/src/creatures/monsters/spawns/spawn_monster.h @@ -70,7 +70,7 @@ class SpawnMonster Position centerPos; int32_t radius; - uint32_t interval = 60000; + uint32_t interval = 30000; uint32_t checkSpawnMonsterEvent = 0; static bool findPlayer(const Position& pos); diff --git a/src/creatures/players/grouping/party.cpp b/src/creatures/players/grouping/party.cpp index ed58f4a9176..2d204acc13b 100644 --- a/src/creatures/players/grouping/party.cpp +++ b/src/creatures/players/grouping/party.cpp @@ -365,14 +365,14 @@ bool Party::setSharedExperience(Player* player, bool newSharedExpActive) return true; } -void Party::shareExperience(uint64_t experience, Creature* source/* = nullptr*/) +void Party::shareExperience(uint64_t experience, Creature* target/* = nullptr*/) { uint64_t shareExperience = experience; g_events().eventPartyOnShareExperience(this, shareExperience); for (Player* member : memberList) { - member->onGainSharedExperience(shareExperience, source); + member->onGainSharedExperience(shareExperience, target); } - leader->onGainSharedExperience(shareExperience, source); + leader->onGainSharedExperience(shareExperience, target); } bool Party::canUseSharedExperience(const Player* player) const diff --git a/src/creatures/players/grouping/party.h b/src/creatures/players/grouping/party.h index cab2e8116dc..37fdf58d461 100644 --- a/src/creatures/players/grouping/party.h +++ b/src/creatures/players/grouping/party.h @@ -66,7 +66,7 @@ class Party } bool canOpenCorpse(uint32_t ownerId) const; - void shareExperience(uint64_t experience, Creature* source = nullptr); + void shareExperience(uint64_t experience, Creature* target = nullptr); bool setSharedExperience(Player* player, bool sharedExpActive); bool isSharedExperienceActive() const { return sharedExpActive; diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 1ee431a28b3..cc6743ff91f 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -2125,7 +2125,7 @@ void Player::addManaSpent(uint64_t amount) } } -void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = false*/) +void Player::addExperience(Creature* target, uint64_t exp, bool sendText/* = false*/) { uint64_t currLevelExp = Player::getExpForLevel(level); uint64_t nextLevelExp = Player::getExpForLevel(level + 1); @@ -2137,7 +2137,7 @@ void Player::addExperience(Creature* source, uint64_t exp, bool sendText/* = fal return; } - g_events().eventPlayerOnGainExperience(this, source, exp, rawExp); + g_events().eventPlayerOnGainExperience(this, target, exp, rawExp); if (exp == 0) { return; } @@ -4410,13 +4410,13 @@ bool Player::onKilledCreature(Creature* target, bool lastHit/* = true*/) return unjustified; } -void Player::gainExperience(uint64_t gainExp, Creature* source) +void Player::gainExperience(uint64_t gainExp, Creature* target) { if (hasFlag(PlayerFlag_NotGainExperience) || gainExp == 0 || staminaMinutes == 0) { return; } - addExperience(source, gainExp, true); + addExperience(target, gainExp, true); } void Player::onGainExperience(uint64_t gainExp, Creature* target) @@ -4435,9 +4435,9 @@ void Player::onGainExperience(uint64_t gainExp, Creature* target) gainExperience(gainExp, target); } -void Player::onGainSharedExperience(uint64_t gainExp, Creature* source) +void Player::onGainSharedExperience(uint64_t gainExp, Creature* target) { - gainExperience(gainExp, source); + gainExperience(gainExp, target); } bool Player::isImmune(CombatType_t type) const diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index 13c3c75967b..81aeef15a6f 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -768,7 +768,7 @@ class Player final : public Creature, public Cylinder void onTargetCreatureGainHealth(Creature* target, int32_t points) override; bool onKilledCreature(Creature* target, bool lastHit = true) override; void onGainExperience(uint64_t gainExp, Creature* target) override; - void onGainSharedExperience(uint64_t gainExp, Creature* source); + void onGainSharedExperience(uint64_t gainExp, Creature* target); void onAttackedCreatureBlockHit(BlockType_t blockType) override; void onBlockHit() override; void onChangeZone(ZoneType_t zone) override; @@ -2042,8 +2042,8 @@ class Player final : public Creature, public Cylinder void checkLootContainers(const Item* item); - void gainExperience(uint64_t exp, Creature* source); - void addExperience(Creature* source, uint64_t exp, bool sendText = false); + void gainExperience(uint64_t exp, Creature* target); + void addExperience(Creature* target, uint64_t exp, bool sendText = false); void removeExperience(uint64_t exp, bool sendText = false); void updateInventoryWeight(); diff --git a/src/game/game.cpp b/src/game/game.cpp index 7d8201d6b32..29a3e0d03b2 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -164,92 +164,6 @@ void Game::setWorldType(WorldType_t type) worldType = type; } -bool Game::loadScheduleEventFromXml() -{ - pugi::xml_document doc; - pugi::xml_parse_result result = doc.load_file("data/XML/events.xml"); - if (!result) { - printXMLError("Error - Game::loadScheduleEventFromXml", "data/XML/events.xml", result); - return false; - } - - int16_t daysNow; - time_t t = time(NULL); - tm* timePtr = localtime(&t); - int16_t daysMath = ((timePtr->tm_year + 1900) * 365) + ((timePtr->tm_mon + 1) * 30) + (timePtr->tm_mday); - - for (auto schedNode : doc.child("events").children()) { - std::string ss_d; - std::stringstream ss; - - pugi::xml_attribute attr; - if ((attr = schedNode.attribute("name"))) { - ss_d = attr.as_string(); - ss << "> " << ss_d << " event"; - } - - int year; - int day; - int month; - - if (!(attr = schedNode.attribute("enddate"))) { - continue; - } else { - ss_d = attr.as_string(); - sscanf(ss_d.c_str(), "%d/%d/%d", &month, &day, &year); - daysNow = ((year * 365) + (month * 30) + day); - if (daysMath > daysNow) { - continue; - } - } - - if (!(attr = schedNode.attribute("startdate"))) { - continue; - } else { - ss_d = attr.as_string(); - sscanf(ss_d.c_str(), "%d/%d/%d", &month, &day, &year); - daysNow = ((year * 365) + (month * 30) + day); - if (daysMath < daysNow) { - continue; - } - } - - if ((attr = schedNode.attribute("script")) && !(g_scripts().loadEventSchedulerScripts(attr.as_string()))) { - SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", - attr.as_string()); - return false; - } - - for (auto schedENode : schedNode.children()) { - if ((schedENode.attribute("exprate"))) { - uint16_t exprate = pugi::cast(schedENode.attribute("exprate").value()); - g_game().setExpSchedule(exprate); - ss << " exp: " << (exprate - 100) << "%"; - } - - if ((schedENode.attribute("lootrate"))) { - uint16_t lootrate = pugi::cast(schedENode.attribute("lootrate").value()); - g_game().setLootSchedule(lootrate); - ss << ", loot: " << (lootrate - 100) << "%"; - } - - if ((schedENode.attribute("spawnrate"))) { - uint32_t spawnrate = pugi::cast(schedENode.attribute("spawnrate").value()); - g_game().setSpawnMonsterSchedule(spawnrate); - ss << ", spawn: " << (spawnrate - 100) << "%"; - } - - if ((schedENode.attribute("skillrate"))) { - uint16_t skillrate = pugi::cast(schedENode.attribute("skillrate").value()); - g_game().setSkillSchedule(skillrate); - ss << ", skill: " << (skillrate - 100) << "%"; - } - } - SPDLOG_INFO(ss.str()); - } - return true; -} - void Game::setGameState(GameState_t newState) { if (gameState == GAME_STATE_SHUTDOWN) { diff --git a/src/game/game.h b/src/game/game.h index 8b68fc690ae..66ea682766d 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -108,8 +108,6 @@ class Game void removeTeamFinderListed(uint32_t leaderGuid) { teamFinderMap.erase(leaderGuid); } - // Event schedule xml load - bool loadScheduleEventFromXml(); Cylinder* internalGetCylinder(Player* player, const Position& pos) const; Thing* internalGetThing(Player* player, const Position& pos, int32_t index, @@ -515,35 +513,6 @@ class Game tilesToClean.clear(); } - // Event schedule - uint16_t getExpSchedule() const { - return expSchedule; - } - void setExpSchedule(uint16_t exprate) { - expSchedule = (expSchedule * exprate)/100; - } - - uint16_t getLootSchedule() const { - return lootSchedule; - } - void setLootSchedule(uint16_t lootrate) { - lootSchedule = (lootSchedule * lootrate)/100; - } - - uint32_t getSpawnMonsterSchedule() const { - return spawnMonsterSchedule; - } - void setSpawnMonsterSchedule(uint32_t spawnrate) { - spawnMonsterSchedule = (spawnMonsterSchedule * spawnrate)/100; - } - - uint16_t getSkillSchedule() const { - return skillSchedule; - } - void setSkillSchedule(uint16_t skillrate) { - skillSchedule = (skillSchedule * skillrate)/100; - } - void playerInspectItem(Player* player, const Position& pos); void playerInspectItem(Player* player, uint16_t itemId, uint8_t itemCount, bool cyclopedia); @@ -660,12 +629,6 @@ class Game GameState_t gameState = GAME_STATE_NORMAL; WorldType_t worldType = WORLD_TYPE_PVP; - // Event schedule - uint16_t expSchedule = 100; - uint16_t lootSchedule = 100; - uint16_t skillSchedule = 100; - uint32_t spawnMonsterSchedule = 100; - LightState_t lightState = LIGHT_STATE_DAY; LightState_t currentLightState = lightState; uint8_t lightLevel = LIGHT_LEVEL_DAY; diff --git a/src/game/scheduling/events_scheduler.cpp b/src/game/scheduling/events_scheduler.cpp new file mode 100644 index 00000000000..4c18bdfb553 --- /dev/null +++ b/src/game/scheduling/events_scheduler.cpp @@ -0,0 +1,111 @@ +/** + * The Forgotten Server - a free and open-source MMORPG server emulator + * Copyright (C) 2019 Mark Samman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "otpch.h" + +#include "utils/pugicast.h" + +#include "game/scheduling/events_scheduler.hpp" +#include "lua/scripts/scripts.h" + +bool EventsScheduler::loadScheduleEventFromXml() const +{ + pugi::xml_document doc; + if (pugi::xml_parse_result result = doc.load_file("data/XML/events.xml"); !result) { + printXMLError("Error - EventsScheduler::loadScheduleEventFromXml", "data/XML/events.xml", result); + consoleHandlerExit(); + return false; + } + + int daysNow; + time_t t = time(nullptr); + const tm* timePtr = localtime(&t); + int daysMath = ((timePtr->tm_year + 1900) * 365) + ((timePtr->tm_mon + 1) * 30) + (timePtr->tm_mday); + + for (auto schedNode : doc.child("events").children()) { + std::string ss_d; + std::stringstream ss; + + pugi::xml_attribute attr; + if ((attr = schedNode.attribute("name"))) { + ss_d = attr.as_string(); + ss << ss_d << " event"; + } + + int16_t year; + int16_t day; + int16_t month; + + if (!(attr = schedNode.attribute("enddate"))) { + continue; + } else { + ss_d = attr.as_string(); + sscanf(ss_d.c_str(), "%hd/%hd/%hd", &month, &day, &year); + daysNow = ((year * 365) + (month * 30) + day); + if (daysMath > daysNow) { + continue; + } + } + + if (!(attr = schedNode.attribute("startdate"))) { + continue; + } else { + ss_d = attr.as_string(); + sscanf(ss_d.c_str(), "%hd/%hd/%hd", &month, &day, &year); + daysNow = ((year * 365) + (month * 30) + day); + if (daysMath < daysNow) { + continue; + } + } + + if ((attr = schedNode.attribute("script")) && (!(g_scripts().loadEventSchedulerScripts(attr.as_string())))) { + SPDLOG_WARN("Can not load the file '{}' on '/events/scripts/scheduler/'", + attr.as_string()); + return false; + } + + for (auto schedENode : schedNode.children()) { + if ((schedENode.attribute("exprate"))) { + uint16_t exprate = pugi::cast(schedENode.attribute("exprate").value()); + g_eventsScheduler().setExpSchedule(exprate); + ss << " exp: " << exprate << "%"; + } + + if ((schedENode.attribute("lootrate"))) { + uint16_t lootrate = pugi::cast(schedENode.attribute("lootrate").value()); + g_eventsScheduler().setLootSchedule(lootrate); + ss << ", loot: " << lootrate << "%"; + } + + if ((schedENode.attribute("spawnrate"))) { + uint32_t spawnrate = pugi::cast(schedENode.attribute("spawnrate").value()); + g_eventsScheduler().setSpawnMonsterSchedule(spawnrate); + ss << ", spawn: " << spawnrate << "%"; + } + + if ((schedENode.attribute("skillrate"))) { + uint16_t skillrate = pugi::cast(schedENode.attribute("skillrate").value()); + g_eventsScheduler().setSkillSchedule(skillrate); + ss << ", skill: " << skillrate << "%"; + break; + } + } + } + return true; +} diff --git a/src/game/scheduling/events_scheduler.hpp b/src/game/scheduling/events_scheduler.hpp new file mode 100644 index 00000000000..d7954a5fa02 --- /dev/null +++ b/src/game/scheduling/events_scheduler.hpp @@ -0,0 +1,86 @@ +/** + * The Forgotten Server - a free and open-source MMORPG server emulator + * Copyright (C) 2019 Mark Samman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_HPP_ +#define SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_HPP_ + +// #include + +#include "utils/tools.h" + +class EventsScheduler +{ + public: + EventsScheduler() = default; + + // Singleton - ensures we don't accidentally copy it. + EventsScheduler(const EventsScheduler&) = delete; + EventsScheduler& operator=(const EventsScheduler&) = delete; + + static EventsScheduler& getInstance() { + // Guaranteed to be destroyed + static EventsScheduler instance; + // Instantiated on first use + return instance; + } + + // Event schedule xml load + bool loadScheduleEventFromXml() const; + + // Event schedule + uint16_t getExpSchedule() const { + return expSchedule; + } + void setExpSchedule(uint16_t exprate) { + expSchedule = (expSchedule * exprate)/100; + } + + uint32_t getLootSchedule() const { + return lootSchedule; + } + void setLootSchedule(uint32_t lootrate) { + lootSchedule = (lootSchedule * lootrate)/100; + } + + uint32_t getSpawnMonsterSchedule() const { + return spawnMonsterSchedule; + } + void setSpawnMonsterSchedule(uint32_t spawnrate) { + spawnMonsterSchedule = (spawnMonsterSchedule * spawnrate)/100; + } + + uint16_t getSkillSchedule() const { + return skillSchedule; + } + void setSkillSchedule(uint16_t skillrate) { + skillSchedule = (skillSchedule * skillrate)/100; + } + + private: + // Event schedule + uint16_t expSchedule = 100; + uint32_t lootSchedule = 100; + uint16_t skillSchedule = 100; + uint32_t spawnMonsterSchedule = 100; + +}; + +constexpr auto g_eventsScheduler = &EventsScheduler::getInstance; + +#endif // SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_HPP_ diff --git a/src/lua/creature/events.cpp b/src/lua/creature/events.cpp index 44ef5092faa..23b0380237c 100644 --- a/src/lua/creature/events.cpp +++ b/src/lua/creature/events.cpp @@ -1029,8 +1029,8 @@ bool Events::eventPlayerOnTradeAccept(Player* player, Player* target, Item* item return scriptInterface.callFunction(4); } -void Events::eventPlayerOnGainExperience(Player* player, Creature* source, uint64_t& exp, uint64_t rawExp) { - // Player:onGainExperience(source, exp, rawExp) +void Events::eventPlayerOnGainExperience(Player* player, Creature* target, uint64_t& exp, uint64_t rawExp) { + // Player:onGainExperience(target, exp, rawExp) // rawExp gives the original exp which is not multiplied if (info.playerOnGainExperience == -1) { return; @@ -1038,9 +1038,9 @@ void Events::eventPlayerOnGainExperience(Player* player, Creature* source, uint6 if (!scriptInterface.reserveScriptEnv()) { SPDLOG_ERROR("[Events::eventPlayerOnGainExperience - " - "Player {} source {}] " + "Player {} target {}] " "Call stack overflow. Too many lua script calls being nested.", - player->getName(), source->getName()); + player->getName(), target->getName()); return; } @@ -1053,9 +1053,9 @@ void Events::eventPlayerOnGainExperience(Player* player, Creature* source, uint6 LuaScriptInterface::pushUserdata(L, player); LuaScriptInterface::setMetatable(L, -1, "Player"); - if (source) { - LuaScriptInterface::pushUserdata(L, source); - LuaScriptInterface::setCreatureMetatable(L, -1, source); + if (target) { + LuaScriptInterface::pushUserdata(L, target); + LuaScriptInterface::setCreatureMetatable(L, -1, target); } else { lua_pushnil(L); } diff --git a/src/lua/creature/events.h b/src/lua/creature/events.h index 5b908071755..dd87999c969 100644 --- a/src/lua/creature/events.h +++ b/src/lua/creature/events.h @@ -121,7 +121,7 @@ class Events { bool eventPlayerOnTurn(Player* player, Direction direction); bool eventPlayerOnTradeRequest(Player* player, Player* target, Item* item); bool eventPlayerOnTradeAccept(Player* player, Player* target, Item* item, Item* targetItem); - void eventPlayerOnGainExperience(Player* player, Creature* source, uint64_t& exp, uint64_t rawExp); + void eventPlayerOnGainExperience(Player* player, Creature* target, uint64_t& exp, uint64_t rawExp); void eventPlayerOnLoseExperience(Player* player, uint64_t& exp); void eventPlayerOnGainSkillTries(Player* player, skills_t skill, uint64_t& tries); bool eventPlayerOnRemoveCount(Player* player, Item * item); diff --git a/src/lua/functions/core/game/config_functions.hpp b/src/lua/functions/core/game/config_functions.hpp index ee6d83392ed..11ef224a5a9 100644 --- a/src/lua/functions/core/game/config_functions.hpp +++ b/src/lua/functions/core/game/config_functions.hpp @@ -176,6 +176,7 @@ class ConfigFunctions final : LuaScriptInterface { registerEnumIn(L, "configKeys", SAVE_INTERVAL_TYPE) registerEnumIn(L, "configKeys", TOGGLE_SAVE_INTERVAL_CLEAN_MAP) registerEnumIn(L, "configKeys", SAVE_INTERVAL_TIME) + registerEnumIn(L, "configKeys", RATE_USE_STAGES) registerEnumIn(L, "configKeys", TOGGLE_IMBUEMENT_SHRINE_STORAGE) registerEnumIn(L, "configKeys", GLOBAL_SERVER_SAVE_TIME) diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 67ada0787f2..929075db99f 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -74,24 +74,6 @@ int GameFunctions::luaGameCreateNpcType(lua_State* L) { return 1; } -int GameFunctions::luaGamegetEventSLoot(lua_State* L) { - // Game.getEventSLoot() - lua_pushnumber(L, g_game().getLootSchedule()); - return 1; -} - -int GameFunctions::luaGamegetEventSSkill(lua_State* L) { - // Game.getEventSSkill() - lua_pushnumber(L, g_game().getSkillSchedule()); - return 1; -} - -int GameFunctions::luaGamegetEventSExp(lua_State* L) { - // Game.getEventSExp() - lua_pushnumber(L, g_game().getExpSchedule()); - return 1; -} - int GameFunctions::luaGameGetSpectators(lua_State* L) { // Game.getSpectators(position[, multifloor = false[, onlyPlayer = false[, minRangeX = 0[, maxRangeX = 0[, minRangeY = 0[, maxRangeY = 0]]]]]]) const Position& position = getPosition(L, 1); diff --git a/src/lua/functions/core/game/game_functions.hpp b/src/lua/functions/core/game/game_functions.hpp index 33466cc9533..2a11786a3b1 100644 --- a/src/lua/functions/core/game/game_functions.hpp +++ b/src/lua/functions/core/game/game_functions.hpp @@ -32,10 +32,6 @@ class GameFunctions final : LuaScriptInterface { registerMethod(L, "Game", "createNpcType", GameFunctions::luaGameCreateNpcType); registerMethod(L, "Game", "createMonsterType", GameFunctions::luaGameCreateMonsterType); - registerMethod(L, "Game", "getEventSLoot", GameFunctions::luaGamegetEventSLoot); - registerMethod(L, "Game", "getEventSSkill", GameFunctions::luaGamegetEventSSkill); - registerMethod(L, "Game", "getEventSExp", GameFunctions::luaGamegetEventSExp); - registerMethod(L, "Game", "getSpectators", GameFunctions::luaGameGetSpectators); registerMethod(L, "Game", "getBoostedCreature", GameFunctions::luaGameGetBoostedCreature); @@ -88,10 +84,6 @@ class GameFunctions final : LuaScriptInterface { static int luaGameCreateMonsterType(lua_State* L); static int luaGameCreateNpcType(lua_State* L); - static int luaGamegetEventSLoot(lua_State* L); - static int luaGamegetEventSSkill(lua_State* L); - static int luaGamegetEventSExp(lua_State* L); - static int luaGameGetSpectators(lua_State* L); static int luaGameGetBoostedCreature(lua_State* L); diff --git a/src/lua/functions/events/events_functions.hpp b/src/lua/functions/events/events_functions.hpp index 359e9971ed4..70aab668a3c 100644 --- a/src/lua/functions/events/events_functions.hpp +++ b/src/lua/functions/events/events_functions.hpp @@ -23,6 +23,7 @@ #include "lua/scripts/luascript.h" #include "lua/functions/events/action_functions.hpp" #include "lua/functions/events/creature_event_functions.hpp" +#include "lua/functions/events/events_scheduler_functions.hpp" #include "lua/functions/events/global_event_functions.hpp" #include "lua/functions/events/move_event_functions.hpp" #include "lua/functions/events/talk_action_functions.hpp" @@ -32,6 +33,7 @@ class EventFunctions final : LuaScriptInterface { static void init(lua_State* L) { ActionFunctions::init(L); CreatureEventFunctions::init(L); + EventsSchedulerFunctions::init(L); GlobalEventFunctions::init(L); MoveEventFunctions::init(L); TalkActionFunctions::init(L); diff --git a/src/lua/functions/events/events_scheduler_functions.cpp b/src/lua/functions/events/events_scheduler_functions.cpp new file mode 100644 index 00000000000..bcfa4979a8e --- /dev/null +++ b/src/lua/functions/events/events_scheduler_functions.cpp @@ -0,0 +1,47 @@ +/** + * The Forgotten Server - a free and open-source MMORPG server emulator + * Copyright (C) 2019 Mark Samman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "otpch.h" + +#include "game/scheduling/events_scheduler.hpp" +#include "lua/functions/events/events_scheduler_functions.hpp" + +int EventsSchedulerFunctions::luaEventsSchedulergetEventSLoot(lua_State* L) { + // EventsScheduler.getEventSLoot + lua_pushnumber(L, g_eventsScheduler().getLootSchedule()); + return 1; +} + +int EventsSchedulerFunctions::luaEventsSchedulergetEventSSkill(lua_State* L) { + // EventsScheduler.getEventSSkill + lua_pushnumber(L, g_eventsScheduler().getSkillSchedule()); + return 1; +} + +int EventsSchedulerFunctions::luaEventsSchedulergetEventSExp(lua_State* L) { + // EventsScheduler.getEventSExp + lua_pushnumber(L, g_eventsScheduler().getExpSchedule()); + return 1; +} + +int EventsSchedulerFunctions::luaEventsSchedulergetSpawnMonsterSchedule(lua_State* L) { + // EventsScheduler.getSpawnMonsterSchedule + lua_pushnumber(L, g_eventsScheduler().getSpawnMonsterSchedule()); + return 1; +} diff --git a/src/lua/functions/events/events_scheduler_functions.hpp b/src/lua/functions/events/events_scheduler_functions.hpp new file mode 100644 index 00000000000..2ba31fd6d0b --- /dev/null +++ b/src/lua/functions/events/events_scheduler_functions.hpp @@ -0,0 +1,46 @@ +/** + * The Forgotten Server - a free and open-source MMORPG server emulator + * Copyright (C) 2019 Mark Samman + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_FUNCTIONS_HPP_ +#define SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_FUNCTIONS_HPP_ + +#include + +#include "lua/scripts/lua_environment.hpp" +#include "lua/scripts/luascript.h" + +class EventsSchedulerFunctions final : private LuaScriptInterface { + public: + static void init(lua_State* L) { + registerTable(L, "EventsScheduler"); + + registerMethod(L, "EventsScheduler", "getEventSLoot", EventsSchedulerFunctions::luaEventsSchedulergetEventSLoot); + registerMethod(L, "EventsScheduler", "getEventSSkill", EventsSchedulerFunctions::luaEventsSchedulergetEventSSkill); + registerMethod(L, "EventsScheduler", "getEventSExp", EventsSchedulerFunctions::luaEventsSchedulergetEventSExp); + registerMethod(L, "EventsScheduler", "getSpawnMonsterSchedule", EventsSchedulerFunctions::luaEventsSchedulergetSpawnMonsterSchedule); + } + + private: + static int luaEventsSchedulergetEventSLoot(lua_State* L); + static int luaEventsSchedulergetEventSSkill(lua_State* L); + static int luaEventsSchedulergetEventSExp(lua_State* L); + static int luaEventsSchedulergetSpawnMonsterSchedule(lua_State* L); +}; + +#endif // SRC_GAME_SCHEDUNLING_EVENTS_SCHEDULER_FUNCTIONS_HPP_ diff --git a/src/otserv.cpp b/src/otserv.cpp index cf63b968463..76f27595274 100644 --- a/src/otserv.cpp +++ b/src/otserv.cpp @@ -31,7 +31,7 @@ #include "database/databasetasks.h" #include "game/game.h" #include "game/scheduling/scheduler.h" -#include "game/scheduling/tasks.h" +#include "game/scheduling/events_scheduler.hpp" #include "io/iomarket.h" #include "lua/creature/events.h" #include "lua/modules/modules.h" @@ -140,8 +140,10 @@ void loadModules() { // Lua Env modulesLoadHelper((g_luaEnvironment.loadFile("data/global.lua") == 0), "data/global.lua"); - modulesLoadHelper((g_luaEnvironment.loadFile("data/stages.lua") == 0), - "data/stages.lua"); + if (g_configManager().getBoolean(RATE_USE_STAGES)) { + modulesLoadHelper((g_luaEnvironment.loadFile("data/stages.lua") == 0), + "data/stages.lua"); + } modulesLoadHelper((g_luaEnvironment.loadFile("data/startup/startup.lua") == 0), "data/startup/startup.lua"); modulesLoadHelper((g_luaEnvironment.loadFile("data/npclib/load.lua") == 0), @@ -151,7 +153,7 @@ void loadModules() { "data/scripts/libs"); modulesLoadHelper(g_vocations().loadFromXml(), "data/XML/vocations.xml"); - modulesLoadHelper(g_game().loadScheduleEventFromXml(), + modulesLoadHelper(g_eventsScheduler().loadScheduleEventFromXml(), "data/XML/events.xml"); modulesLoadHelper(Outfits::getInstance().loadFromXml(), "data/XML/outfits.xml");