From 1a7a67bca1bae2679483b42f89391297b52b4ade Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 7 Feb 2024 21:50:47 -0300 Subject: [PATCH] chore: organizing libraries and function locations (#2191) Organized the libs in the core folder and moved some functions to their correct files. --------- Co-authored-by: GitHub Actions Co-authored-by: Elson Costa --- data-canary/lib/core/load.lua | 1 - .../lib/core/constants.lua | 15 -- data-otservbr-global/lib/core/load.lua | 1 + data-otservbr-global/lib/lib.lua | 8 +- data-otservbr-global/lib/others/bath_tube.lua | 3 - .../others/{dawnport_lib.lua => dawnport.lua} | 2 +- data-otservbr-global/lib/others/load.lua | 4 +- .../lib/{vip => others}/vip_system.lua | 0 data/libs/daily_reward/player.lua | 120 --------- data/libs/{ => functions}/bitwise_flags.lua | 0 data/libs/functions/constants.lua | 36 +-- data/libs/functions/container.lua | 21 ++ data/libs/functions/functions.lua | 21 ++ data/libs/functions/load.lua | 2 + .../modal_window_helper.lua} | 0 data/libs/functions/monster.lua | 74 ++++++ data/libs/functions/player.lua | 248 ++++++++++++++++++ data/libs/functions/vocation.lua | 32 +++ data/libs/kill_lib.lua | 21 -- data/libs/libs.lua | 30 +-- data/libs/loyalty_lib.lua | 66 ----- data/libs/reward_boss/monster.lua | 71 ----- data/libs/reward_boss/player.lua | 57 ---- .../achievements.lua} | 0 .../concoctions.lua} | 0 .../daily_reward.lua | 0 .../encounters.lua} | 0 .../exaltation_forge.lua} | 0 data/libs/{ => systems}/exercise_training.lua | 0 data/libs/{ => systems}/familiar.lua | 0 .../features.lua} | 0 .../{hazard_lib.lua => systems/hazard.lua} | 0 .../hireling.lua} | 0 data/libs/systems/load.lua | 14 + .../libs/{raids_lib.lua => systems/raids.lua} | 0 .../{reward_boss => systems}/reward_boss.lua | 21 -- .../libs/{zones_lib.lua => systems/zones.lua} | 0 data/libs/{door.lua => tables/doors.lua} | 0 data/libs/tables/load.lua | 3 + data/libs/{window.lua => tables/windows.lua} | 0 data/libs/vocation.lua | 31 --- 41 files changed, 429 insertions(+), 473 deletions(-) rename {data-canary => data-otservbr-global}/lib/core/constants.lua (66%) delete mode 100644 data-otservbr-global/lib/others/bath_tube.lua rename data-otservbr-global/lib/others/{dawnport_lib.lua => dawnport.lua} (99%) rename data-otservbr-global/lib/{vip => others}/vip_system.lua (100%) delete mode 100644 data/libs/daily_reward/player.lua rename data/libs/{ => functions}/bitwise_flags.lua (100%) rename data/libs/{modal_window_lib.lua => functions/modal_window_helper.lua} (100%) delete mode 100644 data/libs/kill_lib.lua delete mode 100644 data/libs/loyalty_lib.lua delete mode 100644 data/libs/reward_boss/monster.lua delete mode 100644 data/libs/reward_boss/player.lua rename data/libs/{achievements_lib.lua => systems/achievements.lua} (100%) rename data/libs/{concoctions_lib.lua => systems/concoctions.lua} (100%) rename data/libs/{daily_reward => systems}/daily_reward.lua (100%) rename data/libs/{encounters_lib.lua => systems/encounters.lua} (100%) rename data/libs/{forge_lib.lua => systems/exaltation_forge.lua} (100%) rename data/libs/{ => systems}/exercise_training.lua (100%) rename data/libs/{ => systems}/familiar.lua (100%) rename data/libs/{features_lib.lua => systems/features.lua} (100%) rename data/libs/{hazard_lib.lua => systems/hazard.lua} (100%) rename data/libs/{hireling_lib.lua => systems/hireling.lua} (100%) create mode 100644 data/libs/systems/load.lua rename data/libs/{raids_lib.lua => systems/raids.lua} (100%) rename data/libs/{reward_boss => systems}/reward_boss.lua (83%) rename data/libs/{zones_lib.lua => systems/zones.lua} (100%) rename data/libs/{door.lua => tables/doors.lua} (100%) create mode 100644 data/libs/tables/load.lua rename data/libs/{window.lua => tables/windows.lua} (100%) delete mode 100644 data/libs/vocation.lua diff --git a/data-canary/lib/core/load.lua b/data-canary/lib/core/load.lua index bf9b37a52f6..33acae25735 100644 --- a/data-canary/lib/core/load.lua +++ b/data-canary/lib/core/load.lua @@ -1,3 +1,2 @@ dofile(DATA_DIRECTORY .. "/lib/core/storages.lua") -dofile(DATA_DIRECTORY .. "/lib/core/constants.lua") dofile(DATA_DIRECTORY .. "/lib/core/quests.lua") diff --git a/data-canary/lib/core/constants.lua b/data-otservbr-global/lib/core/constants.lua similarity index 66% rename from data-canary/lib/core/constants.lua rename to data-otservbr-global/lib/core/constants.lua index 7b99b309913..0672aa00c8d 100644 --- a/data-canary/lib/core/constants.lua +++ b/data-otservbr-global/lib/core/constants.lua @@ -1,18 +1,3 @@ -STACKPOS_GROUND = 0 -STACKPOS_FIRST_ITEM_ABOVE_GROUNDTILE = 1 -STACKPOS_SECOND_ITEM_ABOVE_GROUNDTILE = 2 -STACKPOS_THIRD_ITEM_ABOVE_GROUNDTILE = 3 -STACKPOS_FOURTH_ITEM_ABOVE_GROUNDTILE = 4 -STACKPOS_FIFTH_ITEM_ABOVE_GROUNDTILE = 5 -STACKPOS_TOP_CREATURE = 253 -STACKPOS_TOP_FIELD = 254 -STACKPOS_TOP_MOVABLE_ITEM_OR_CREATURE = 255 - -THING_TYPE_PLAYER = CREATURETYPE_PLAYER + 1 -THING_TYPE_MONSTER = CREATURETYPE_MONSTER + 1 -THING_TYPE_NPC = CREATURETYPE_NPC + 1 - -CONTAINER_POSITION = 0xFFFF ROSHAMUUL_MORTAR_THROWN = 20200 ROSHAMUUL_KILLED_FRAZZLEMAWS = 20201 ROSHAMUUL_KILLED_SILENCERS = 20202 diff --git a/data-otservbr-global/lib/core/load.lua b/data-otservbr-global/lib/core/load.lua index 33acae25735..bf9b37a52f6 100644 --- a/data-otservbr-global/lib/core/load.lua +++ b/data-otservbr-global/lib/core/load.lua @@ -1,2 +1,3 @@ dofile(DATA_DIRECTORY .. "/lib/core/storages.lua") +dofile(DATA_DIRECTORY .. "/lib/core/constants.lua") dofile(DATA_DIRECTORY .. "/lib/core/quests.lua") diff --git a/data-otservbr-global/lib/lib.lua b/data-otservbr-global/lib/lib.lua index 68d82d490d7..2e9ead889eb 100644 --- a/data-otservbr-global/lib/lib.lua +++ b/data-otservbr-global/lib/lib.lua @@ -1,15 +1,11 @@ -- Core API functions implemented in Lua --- Load storages first dofile(DATA_DIRECTORY .. "/lib/core/load.lua") --- Tables library -dofile(DATA_DIRECTORY .. "/lib/tables/load.lua") - -- Others library dofile(DATA_DIRECTORY .. "/lib/others/load.lua") -- Quests library dofile(DATA_DIRECTORY .. "/lib/quests/quest.lua") --- Vip System library -dofile(DATA_DIRECTORY .. "/lib/vip/vip_system.lua") +-- Tables library +dofile(DATA_DIRECTORY .. "/lib/tables/load.lua") diff --git a/data-otservbr-global/lib/others/bath_tube.lua b/data-otservbr-global/lib/others/bath_tube.lua deleted file mode 100644 index 1666a759717..00000000000 --- a/data-otservbr-global/lib/others/bath_tube.lua +++ /dev/null @@ -1,3 +0,0 @@ -BATHTUB_EMPTY = 26076 -BATHTUB_FILLED = 26077 -BATHTUB_FILLED_NOTMOVABLE = 26100 diff --git a/data-otservbr-global/lib/others/dawnport_lib.lua b/data-otservbr-global/lib/others/dawnport.lua similarity index 99% rename from data-otservbr-global/lib/others/dawnport_lib.lua rename to data-otservbr-global/lib/others/dawnport.lua index 0d63265b192..cd7e9fb585c 100644 --- a/data-otservbr-global/lib/others/dawnport_lib.lua +++ b/data-otservbr-global/lib/others/dawnport.lua @@ -1,4 +1,4 @@ -dofile(CORE_DIRECTORY .. "/libs/vocation.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/vocation.lua") Dawnport = { skillsLimit = { diff --git a/data-otservbr-global/lib/others/load.lua b/data-otservbr-global/lib/others/load.lua index 82414197a47..1052efb7bd6 100644 --- a/data-otservbr-global/lib/others/load.lua +++ b/data-otservbr-global/lib/others/load.lua @@ -1,2 +1,2 @@ -dofile(DATA_DIRECTORY .. "/lib/others/dawnport_lib.lua") -dofile(DATA_DIRECTORY .. "/lib/others/bath_tube.lua") +dofile(DATA_DIRECTORY .. "/lib/others/dawnport.lua") +dofile(DATA_DIRECTORY .. "/lib/others/vip_system.lua") diff --git a/data-otservbr-global/lib/vip/vip_system.lua b/data-otservbr-global/lib/others/vip_system.lua similarity index 100% rename from data-otservbr-global/lib/vip/vip_system.lua rename to data-otservbr-global/lib/others/vip_system.lua diff --git a/data/libs/daily_reward/player.lua b/data/libs/daily_reward/player.lua deleted file mode 100644 index 2635e7d377b..00000000000 --- a/data/libs/daily_reward/player.lua +++ /dev/null @@ -1,120 +0,0 @@ -function Player.getCollectionTokens(self) - return math.max(self:getStorageValue(DailyReward.storages.collectionTokens), 0) -end - -function Player.getJokerTokens(self) - return math.max(self:getStorageValue(DailyReward.storages.jokerTokens), 0) -end - -function Player.setJokerTokens(self, value) - self:setStorageValue(DailyReward.storages.jokerTokens, value) -end - -function Player.setCollectionTokens(self, value) - self:setStorageValue(DailyReward.storages.collectionTokens, value) -end - -function Player.getDayStreak(self) - return math.max(self:getStorageValue(DailyReward.storages.currentDayStreak), 0) -end - -function Player.setDayStreak(self, value) - self:setStorageValue(DailyReward.storages.currentDayStreak, value) -end - -function Player.getStreakLevel(self) - return self:kv():scoped("daily-reward"):get("streak") or 7 -end - -function Player.setStreakLevel(self, value) - self:kv():scoped("daily-reward"):set("streak", value) -end - -function Player.setNextRewardTime(self, value) - self:setStorageValue(DailyReward.storages.nextRewardTime, value) -end - -function Player.getNextRewardTime(self) - return math.max(self:getStorageValue(DailyReward.storages.nextRewardTime), 0) -end - -function Player.isRestingAreaBonusActive(self) - local levelStreak = self:getStreakLevel() - if levelStreak > 1 then - return true - else - return false - end -end - -function Player.getActiveDailyRewardBonusesName(self) - local msg = "" - local streakLevel = self:getStreakLevel() - if streakLevel >= 2 then - if streakLevel > 7 then - streakLevel = 7 - end - for i = DAILY_REWARD_FIRST, streakLevel do - if i ~= streakLevel then - msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. ", " - else - msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. "." - end - end - end - return msg -end - -function Player.getDailyRewardBonusesCount(self) - local count = 1 - local streakLevel = self:getStreakLevel() - if streakLevel > 2 then - if streakLevel > 7 then - streakLevel = 7 - end - for i = DAILY_REWARD_FIRST, streakLevel do - count = count + 1 - end - else - count = 0 - end - return count -end - -function Player.isBonusActiveById(self, bonusId) - local streakLevel = self:getStreakLevel() - local bonus = "locked" - if streakLevel > 2 then - if streakLevel > 7 then - streakLevel = 7 - end - if streakLevel >= bonusId then - bonus = "unlocked" - end - end - return bonus -end - -function Player.loadDailyRewardBonuses(self) - local streakLevel = self:getStreakLevel() - -- Stamina regeneration - if streakLevel >= DAILY_REWARD_STAMINA_REGENERATION then - local staminaEvent = DailyRewardBonus.Stamina[self:getId()] - if not staminaEvent then - local delay = 3 - if self:getStamina() > 2340 and self:getStamina() <= 2520 then - delay = 6 - end - DailyRewardBonus.Stamina[self:getId()] = addEvent(RegenStamina, delay * 60 * 1000, self:getId(), delay * 60 * 1000) - end - end - -- Soul regeneration - if streakLevel >= DAILY_REWARD_SOUL_REGENERATION then - local soulEvent = DailyRewardBonus.Soul[self:getId()] - if not soulEvent then - local delay = self:getVocation():getSoulGainTicks() - DailyRewardBonus.Soul[self:getId()] = addEvent(RegenSoul, delay, self:getId(), delay) - end - end - logger.debug("Player: {}, streak level: {}, active bonuses: {}", self:getName(), streakLevel, self:getActiveDailyRewardBonusesName()) -end diff --git a/data/libs/bitwise_flags.lua b/data/libs/functions/bitwise_flags.lua similarity index 100% rename from data/libs/bitwise_flags.lua rename to data/libs/functions/bitwise_flags.lua diff --git a/data/libs/functions/constants.lua b/data/libs/functions/constants.lua index fab80d300f6..e5b8d9170b0 100644 --- a/data/libs/functions/constants.lua +++ b/data/libs/functions/constants.lua @@ -1,37 +1,9 @@ CONTAINER_POSITION = 0xFFFF -ROSHAMUUL_MORTAR_THROWN = 20200 -ROSHAMUUL_KILLED_FRAZZLEMAWS = 20201 -ROSHAMUUL_KILLED_SILENCERS = 20202 -ROSHAMUUL_GOLD_RECORD = 20203 -SPIKE_FAME_POINTS = 27890 - -SPIKE_UPPER_PACIFIER_MAIN = 27891 -SPIKE_UPPER_PACIFIER_DAILY = 27892 -SPIKE_UPPER_MOUND_MAIN = 27893 -SPIKE_UPPER_MOUND_DAILY = 27894 -SPIKE_UPPER_TRACK_MAIN = 27895 -SPIKE_UPPER_TRACK_DAILY = 27896 -SPIKE_UPPER_KILL_MAIN = 27897 -SPIKE_UPPER_KILL_DAILY = 27898 - -SPIKE_MIDDLE_CHARGE_MAIN = 27899 -SPIKE_MIDDLE_CHARGE_DAILY = 27900 -SPIKE_MIDDLE_MUSHROOM_MAIN = 27901 -SPIKE_MIDDLE_MUSHROOM_DAILY = 27902 -SPIKE_MIDDLE_NEST_MAIN = 27903 -SPIKE_MIDDLE_NEST_DAILY = 27904 -SPIKE_MIDDLE_KILL_MAIN = 27905 -SPIKE_MIDDLE_KILL_DAILY = 27906 - -SPIKE_LOWER_PARCEL_MAIN = 27907 -SPIKE_LOWER_PARCEL_DAILY = 27908 -SPIKE_LOWER_UNDERCOVER_MAIN = 27909 -SPIKE_LOWER_UNDERCOVER_DAILY = 27910 -SPIKE_LOWER_LAVA_MAIN = 27911 -SPIKE_LOWER_LAVA_DAILY = 27912 -SPIKE_LOWER_KILL_MAIN = 27913 -SPIKE_LOWER_KILL_DAILY = 27914 +-- Items +BATHTUB_EMPTY = 26076 +BATHTUB_FILLED = 26077 +BATHTUB_FILLED_NOTMOVABLE = 26100 BAG_YOU_DESIRE = 34109 PRIMAL_BAG = 39546 diff --git a/data/libs/functions/container.lua b/data/libs/functions/container.lua index 15030e0caf8..f932b37dfe4 100644 --- a/data/libs/functions/container.lua +++ b/data/libs/functions/container.lua @@ -64,3 +64,24 @@ function Container:addLoot(loot) ::continue:: end end + +function Container:addRewardBossItems(itemList) + for itemId, lootInfo in pairs(itemList) do + local iType = ItemType(itemId) + if iType then + local itemCount = lootInfo.count + local charges = iType:getCharges() + if charges > 0 then + itemCount = charges + logger.debug("Adding item with 'id' to the reward container, item charges {}", iType:getId(), charges) + end + if iType:isStackable() or iType:getCharges() ~= 0 then + self:addItem(itemId, itemCount, INDEX_WHEREEVER, FLAG_NOLIMIT) + else + for i = 1, itemCount do + self:addItem(itemId, 1, INDEX_WHEREEVER, FLAG_NOLIMIT) + end + end + end + end +end diff --git a/data/libs/functions/functions.lua b/data/libs/functions/functions.lua index 48e1ff29078..46ae81e7b1f 100644 --- a/data/libs/functions/functions.lua +++ b/data/libs/functions/functions.lua @@ -1163,3 +1163,24 @@ function toboolean(value) return false end end + +-- Utility to combine onDeath event with a "kill" event for a player with a party (or not). +function onDeathForParty(creature, player, func) + if not player or not player:isPlayer() then + return + end + + local participants = Participants(player, true) + for _, participant in ipairs(participants) do + func(creature, participant) + end +end + +function onDeathForDamagingPlayers(creature, func) + for key, value in pairs(creature:getDamageMap()) do + local player = Player(key) + if player then + func(creature, player) + end + end +end diff --git a/data/libs/functions/load.lua b/data/libs/functions/load.lua index ef939a35fa7..c63276d9444 100644 --- a/data/libs/functions/load.lua +++ b/data/libs/functions/load.lua @@ -1,5 +1,6 @@ -- Load core functions dofile(CORE_DIRECTORY .. "/libs/functions/bit.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/bitwise_flags.lua") dofile(CORE_DIRECTORY .. "/libs/functions/combat.lua") dofile(CORE_DIRECTORY .. "/libs/functions/constants.lua") dofile(CORE_DIRECTORY .. "/libs/functions/container.lua") @@ -11,6 +12,7 @@ dofile(CORE_DIRECTORY .. "/libs/functions/game.lua") dofile(CORE_DIRECTORY .. "/libs/functions/item.lua") dofile(CORE_DIRECTORY .. "/libs/functions/itemtype.lua") dofile(CORE_DIRECTORY .. "/libs/functions/lever.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/modal_window_helper.lua") dofile(CORE_DIRECTORY .. "/libs/functions/monster.lua") dofile(CORE_DIRECTORY .. "/libs/functions/monstertype.lua") dofile(CORE_DIRECTORY .. "/libs/functions/party.lua") diff --git a/data/libs/modal_window_lib.lua b/data/libs/functions/modal_window_helper.lua similarity index 100% rename from data/libs/modal_window_lib.lua rename to data/libs/functions/modal_window_helper.lua diff --git a/data/libs/functions/monster.lua b/data/libs/functions/monster.lua index 0eb2333c403..f26f2a5b9b4 100644 --- a/data/libs/functions/monster.lua +++ b/data/libs/functions/monster.lua @@ -150,3 +150,77 @@ function Monster.setFiendish(self, position, player) logger.info("Player {} {} with name {} and id {} on position {}", player:getName(), success, self:getName(), self:getId(), self:getPosition():toString()) return true end + +function Monster.setReward(self, enable) + if enable then + if not self:getType():isRewardBoss() then + error("Rewards can only be enabled to rewards bosses.") + return false + end + _G.GlobalBosses[self:getId()] = {} + self:registerEvent("BossDeath") + self:registerEvent("BossThink") + else + _G.GlobalBosses[self:getId()] = nil + self:unregisterEvent("BossDeath") + self:unregisterEvent("BossThink") + end + return true +end + +function Monster:setRewardBoss() + if self:getType():isRewardBoss() then + self:setReward(true) + end +end + +local equipmentBags = { + BAG_YOU_DESIRE, + PRIMAL_BAG, + BAG_YOU_COVET, +} +do + local function isEquipment(itemType) + if table.contains(equipmentBags, itemType:getId()) then + return true + end + + local t = itemType:getType() + local equipmentTypes = { + ITEM_TYPE_ARMOR, + ITEM_TYPE_AMULET, + ITEM_TYPE_BOOTS, + ITEM_TYPE_HELMET, + ITEM_TYPE_LEGS, + ITEM_TYPE_RING, + ITEM_TYPE_SHIELD, + ITEM_TYPE_AXE, + ITEM_TYPE_CLUB, + ITEM_TYPE_DISTANCE, + ITEM_TYPE_SWORD, + ITEM_TYPE_WAND, + ITEM_TYPE_QUIVER, + } + return table.contains(equipmentTypes, t) + end + + function MonsterType.getBossReward(self, lootFactor, topScore, equipmentOnly, lootTable) + if configManager.getNumber(configKeys.RATE_LOOT) <= 0 then + return lootTable or {} + end + + return self:generateLootRoll({ + factor = lootFactor, + gut = false, + filter = function(itemType, unique) + if unique and not topScore then + return false + end + if equipmentOnly then + return not unique and isEquipment(itemType) + end + return true + end, + }, lootTable) + end +end diff --git a/data/libs/functions/player.lua b/data/libs/functions/player.lua index dd665ed7abd..4ecf446dd0d 100644 --- a/data/libs/functions/player.lua +++ b/data/libs/functions/player.lua @@ -761,3 +761,251 @@ function Player:canFightBoss(bossNameOrId) local cooldown = self:getBossCooldown(bossNameOrId) return cooldown <= os.time() end + +function Player.getCollectionTokens(self) + return math.max(self:getStorageValue(DailyReward.storages.collectionTokens), 0) +end + +function Player.getJokerTokens(self) + return math.max(self:getStorageValue(DailyReward.storages.jokerTokens), 0) +end + +function Player.setJokerTokens(self, value) + self:setStorageValue(DailyReward.storages.jokerTokens, value) +end + +function Player.setCollectionTokens(self, value) + self:setStorageValue(DailyReward.storages.collectionTokens, value) +end + +function Player.getDayStreak(self) + return math.max(self:getStorageValue(DailyReward.storages.currentDayStreak), 0) +end + +function Player.setDayStreak(self, value) + self:setStorageValue(DailyReward.storages.currentDayStreak, value) +end + +function Player.getStreakLevel(self) + return self:kv():scoped("daily-reward"):get("streak") or 7 +end + +function Player.setStreakLevel(self, value) + self:kv():scoped("daily-reward"):set("streak", value) +end + +function Player.setNextRewardTime(self, value) + self:setStorageValue(DailyReward.storages.nextRewardTime, value) +end + +function Player.getNextRewardTime(self) + return math.max(self:getStorageValue(DailyReward.storages.nextRewardTime), 0) +end + +function Player.isRestingAreaBonusActive(self) + local levelStreak = self:getStreakLevel() + if levelStreak > 1 then + return true + else + return false + end +end + +function Player.getActiveDailyRewardBonusesName(self) + local msg = "" + local streakLevel = self:getStreakLevel() + if streakLevel >= 2 then + if streakLevel > 7 then + streakLevel = 7 + end + for i = DAILY_REWARD_FIRST, streakLevel do + if i ~= streakLevel then + msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. ", " + else + msg = msg .. "" .. DailyReward.strikeBonuses[i].text .. "." + end + end + end + return msg +end + +function Player.getDailyRewardBonusesCount(self) + local count = 1 + local streakLevel = self:getStreakLevel() + if streakLevel > 2 then + if streakLevel > 7 then + streakLevel = 7 + end + for i = DAILY_REWARD_FIRST, streakLevel do + count = count + 1 + end + else + count = 0 + end + return count +end + +function Player.isBonusActiveById(self, bonusId) + local streakLevel = self:getStreakLevel() + local bonus = "locked" + if streakLevel > 2 then + if streakLevel > 7 then + streakLevel = 7 + end + if streakLevel >= bonusId then + bonus = "unlocked" + end + end + return bonus +end + +function Player.loadDailyRewardBonuses(self) + local streakLevel = self:getStreakLevel() + -- Stamina regeneration + if streakLevel >= DAILY_REWARD_STAMINA_REGENERATION then + local staminaEvent = DailyRewardBonus.Stamina[self:getId()] + if not staminaEvent then + local delay = 3 + if self:getStamina() > 2340 and self:getStamina() <= 2520 then + delay = 6 + end + DailyRewardBonus.Stamina[self:getId()] = addEvent(RegenStamina, delay * 60 * 1000, self:getId(), delay * 60 * 1000) + end + end + -- Soul regeneration + if streakLevel >= DAILY_REWARD_SOUL_REGENERATION then + local soulEvent = DailyRewardBonus.Soul[self:getId()] + if not soulEvent then + local delay = self:getVocation():getSoulGainTicks() + DailyRewardBonus.Soul[self:getId()] = addEvent(RegenSoul, delay, self:getId(), delay) + end + end + logger.debug("Player: {}, streak level: {}, active bonuses: {}", self:getName(), streakLevel, self:getActiveDailyRewardBonusesName()) +end + +function Player.getRewardChest(self, autocreate) + return self:getDepotChest(99, autocreate) +end + +function Player.inBossFight(self) + if not next(_G.GlobalBosses) then + return false + end + + local playerGuid = self:getGuid() + for _, info in pairs(_G.GlobalBosses) do + local stats = info[playerGuid] + if stats and stats.active then + return stats + end + end + return false +end + +-- For use of data/events/scripts/player.lua +function Player:executeRewardEvents(item, toPosition) + if toPosition.x == CONTAINER_POSITION then + local containerId = toPosition.y - 64 + local container = self:getContainerById(containerId) + if not container then + return true + end + + -- Do not let the player insert items into either the Reward Container or the Reward Chest + local itemId = container:getId() + if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + + -- The player also shouldn't be able to insert items into the boss corpse + local tileCorpse = Tile(container:getPosition()) + for index, value in ipairs(tileCorpse:getItems() or {}) do + if value:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2 ^ 31 - 1 and value:getName() == container:getName() then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + end + end + -- Do not let the player move the boss corpse. + if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2 ^ 31 - 1 then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + return false + end + -- Players cannot throw items on reward chest + local tileChest = Tile(toPosition) + if tileChest and tileChest:getItemById(ITEM_REWARD_CHEST) then + self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) + self:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end +end + +do + local loyaltySystem = { + enable = configManager.getBoolean(configKeys.LOYALTY_ENABLED), + titles = { + [1] = { name = "Scout of Tibia", points = 50 }, + [2] = { name = "Sentinel of Tibia", points = 100 }, + [3] = { name = "Steward of Tibia", points = 200 }, + [4] = { name = "Warden of Tibia", points = 400 }, + [5] = { name = "Squire of Tibia", points = 1000 }, + [6] = { name = "Warrior of Tibia", points = 2000 }, + [7] = { name = "Keeper of Tibia", points = 3000 }, + [8] = { name = "Guardian of Tibia", points = 4000 }, + [9] = { name = "Sage of Tibia", points = 5000 }, + [10] = { name = "Savant of Tibia", points = 6000 }, + [11] = { name = "Enlightened of Tibia", points = 7000 }, + }, + bonus = { + { minPoints = 360, percentage = 5 }, + { minPoints = 720, percentage = 10 }, + { minPoints = 1080, percentage = 15 }, + { minPoints = 1440, percentage = 20 }, + { minPoints = 1800, percentage = 25 }, + { minPoints = 2160, percentage = 30 }, + { minPoints = 2520, percentage = 35 }, + { minPoints = 2880, percentage = 40 }, + { minPoints = 3240, percentage = 45 }, + { minPoints = 3600, percentage = 50 }, + }, + messageTemplate = "Due to your long-term loyalty to " .. SERVER_NAME .. " you currently benefit from a ${bonusPercentage}% bonus on all of your skills. (You have ${loyaltyPoints} loyalty points)", + } + + function Player.initializeLoyaltySystem(self) + if not loyaltySystem.enable then + return true + end + + local playerLoyaltyPoints = self:getLoyaltyPoints() + + -- Title + local title = "" + for _, titleTable in ipairs(loyaltySystem.titles) do + if playerLoyaltyPoints >= titleTable.points then + title = titleTable.name + end + end + + if title ~= "" then + self:setLoyaltyTitle(title) + end + + -- Bonus + local playerBonusPercentage = 0 + for _, bonusTable in ipairs(loyaltySystem.bonus) do + if playerLoyaltyPoints >= bonusTable.minPoints then + playerBonusPercentage = bonusTable.percentage + end + end + + playerBonusPercentage = playerBonusPercentage * configManager.getFloat(configKeys.LOYALTY_BONUS_PERCENTAGE_MULTIPLIER) + self:setLoyaltyBonus(playerBonusPercentage) + + if self:getLoyaltyBonus() ~= 0 then + self:sendTextMessage(MESSAGE_STATUS, string.formatNamed(loyaltySystem.messageTemplate, { bonusPercentage = playerBonusPercentage, loyaltyPoints = playerLoyaltyPoints })) + end + + return true + end +end diff --git a/data/libs/functions/vocation.lua b/data/libs/functions/vocation.lua index acf31afec7b..6867a333719 100644 --- a/data/libs/functions/vocation.lua +++ b/data/libs/functions/vocation.lua @@ -1,3 +1,35 @@ +VOCATION = { + ID = { + NONE = 0, + SORCERER = 1, + DRUID = 2, + PALADIN = 3, + KNIGHT = 4, + MASTER_SORCERER = 5, + ELDER_DRUID = 6, + ROYAL_PALADIN = 7, + ELITE_KNIGHT = 8, + }, + CLIENT_ID = { + NONE = 0, + KNIGHT = 1, + PALADIN = 2, + SORCERER = 3, + DRUID = 4, + ELITE_KNIGHT = 11, + ROYAL_PALADIN = 12, + MASTER_SORCERER = 13, + ELDER_DRUID = 14, + }, + BASE_ID = { + NONE = 0, + SORCERER = 1, + DRUID = 2, + PALADIN = 3, + KNIGHT = 4, + }, +} + function Vocation.getBase(self) local base = self while base:getDemotion() do diff --git a/data/libs/kill_lib.lua b/data/libs/kill_lib.lua deleted file mode 100644 index 257be4722de..00000000000 --- a/data/libs/kill_lib.lua +++ /dev/null @@ -1,21 +0,0 @@ --- Utility to combine onDeath event with a "kill" event for a player with a party (or not). - -function onDeathForParty(creature, player, func) - if not player or not player:isPlayer() then - return - end - - local participants = Participants(player, true) - for _, participant in ipairs(participants) do - func(creature, participant) - end -end - -function onDeathForDamagingPlayers(creature, func) - for key, value in pairs(creature:getDamageMap()) do - local player = Player(key) - if player then - func(creature, player) - end - end -end diff --git a/data/libs/libs.lua b/data/libs/libs.lua index 3f013f35276..21e39982a47 100644 --- a/data/libs/libs.lua +++ b/data/libs/libs.lua @@ -7,33 +7,11 @@ dofile(CORE_DIRECTORY .. "/libs/core/global_storage.lua") -- Compatibility library for our old Lua API dofile(CORE_DIRECTORY .. "/libs/compat/compat.lua") --- Daily reward library -dofile(CORE_DIRECTORY .. "/libs/daily_reward/daily_reward.lua") -dofile(CORE_DIRECTORY .. "/libs/daily_reward/player.lua") - -- Debugging helper function for Lua developers dofile(CORE_DIRECTORY .. "/libs/debugging/dump.lua") --- Reward boss library -dofile(CORE_DIRECTORY .. "/libs/reward_boss/reward_boss.lua") -dofile(CORE_DIRECTORY .. "/libs/reward_boss/player.lua") -dofile(CORE_DIRECTORY .. "/libs/reward_boss/monster.lua") +-- Systems +dofile(CORE_DIRECTORY .. "/libs/systems/load.lua") -dofile(CORE_DIRECTORY .. "/libs/achievements_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/bitwise_flags.lua") -dofile(CORE_DIRECTORY .. "/libs/door.lua") -dofile(CORE_DIRECTORY .. "/libs/exercise_training.lua") -dofile(CORE_DIRECTORY .. "/libs/vocation.lua") -dofile(CORE_DIRECTORY .. "/libs/familiar.lua") -dofile(CORE_DIRECTORY .. "/libs/hireling_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/modal_window_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/window.lua") -dofile(CORE_DIRECTORY .. "/libs/forge_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/zones_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/hazard_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/loyalty_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/encounters_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/raids_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/concoctions_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/kill_lib.lua") -dofile(CORE_DIRECTORY .. "/libs/features_lib.lua") +-- Tables +dofile(CORE_DIRECTORY .. "/libs/tables/load.lua") diff --git a/data/libs/loyalty_lib.lua b/data/libs/loyalty_lib.lua deleted file mode 100644 index 4956a8ac339..00000000000 --- a/data/libs/loyalty_lib.lua +++ /dev/null @@ -1,66 +0,0 @@ -local loyaltySystem = { - enable = configManager.getBoolean(configKeys.LOYALTY_ENABLED), - titles = { - [1] = { name = "Scout of Tibia", points = 50 }, - [2] = { name = "Sentinel of Tibia", points = 100 }, - [3] = { name = "Steward of Tibia", points = 200 }, - [4] = { name = "Warden of Tibia", points = 400 }, - [5] = { name = "Squire of Tibia", points = 1000 }, - [6] = { name = " Warrior of Tibia", points = 2000 }, - [7] = { name = "Keeper of Tibia", points = 3000 }, - [8] = { name = "Guardian of Tibia", points = 4000 }, - [9] = { name = "Sage of Tibia", points = 5000 }, - [10] = { name = "Savant of Tibia", points = 6000 }, - [11] = { name = "Enlightened of Tibia", points = 7000 }, - }, - bonus = { - { minPoints = 360, percentage = 5 }, - { minPoints = 720, percentage = 10 }, - { minPoints = 1080, percentage = 15 }, - { minPoints = 1440, percentage = 20 }, - { minPoints = 1800, percentage = 25 }, - { minPoints = 2160, percentage = 30 }, - { minPoints = 2520, percentage = 35 }, - { minPoints = 2880, percentage = 40 }, - { minPoints = 3240, percentage = 45 }, - { minPoints = 3600, percentage = 50 }, - }, - messageTemplate = "Due to your long-term loyalty to " .. SERVER_NAME .. " you currently benefit from a ${bonusPercentage}% bonus on all of your skills. (You have ${loyaltyPoints} loyalty points)", -} - -function Player.initializeLoyaltySystem(self) - if not loyaltySystem.enable then - return true - end - - local playerLoyaltyPoints = self:getLoyaltyPoints() - - -- Title - local title = "" - for _, titleTable in ipairs(loyaltySystem.titles) do - if playerLoyaltyPoints >= titleTable.points then - title = titleTable.name - end - end - - if title ~= "" then - self:setLoyaltyTitle(title) - end - - -- Bonus - local playerBonusPercentage = 0 - for _, bonusTable in ipairs(loyaltySystem.bonus) do - if playerLoyaltyPoints >= bonusTable.minPoints then - playerBonusPercentage = bonusTable.percentage - end - end - - playerBonusPercentage = playerBonusPercentage * configManager.getFloat(configKeys.LOYALTY_BONUS_PERCENTAGE_MULTIPLIER) - self:setLoyaltyBonus(playerBonusPercentage) - - if self:getLoyaltyBonus() ~= 0 then - self:sendTextMessage(MESSAGE_STATUS, string.formatNamed(loyaltySystem.messageTemplate, { bonusPercentage = playerBonusPercentage, loyaltyPoints = playerLoyaltyPoints })) - end - - return true -end diff --git a/data/libs/reward_boss/monster.lua b/data/libs/reward_boss/monster.lua deleted file mode 100644 index cd1f6d8dc71..00000000000 --- a/data/libs/reward_boss/monster.lua +++ /dev/null @@ -1,71 +0,0 @@ -function Monster.setReward(self, enable) - if enable then - if not self:getType():isRewardBoss() then - error("Rewards can only be enabled to rewards bosses.") - return false - end - _G.GlobalBosses[self:getId()] = {} - self:registerEvent("BossDeath") - self:registerEvent("BossThink") - else - _G.GlobalBosses[self:getId()] = nil - self:unregisterEvent("BossDeath") - self:unregisterEvent("BossThink") - end - return true -end - -function Monster:setRewardBoss() - if self:getType():isRewardBoss() then - self:setReward(true) - end -end - -local equipmentBags = { - BAG_YOU_DESIRE, - PRIMAL_BAG, - BAG_YOU_COVET, -} - -local function isEquipment(itemType) - if table.contains(equipmentBags, itemType:getId()) then - return true - end - local t = itemType:getType() - local equipmentTypes = { - ITEM_TYPE_ARMOR, - ITEM_TYPE_AMULET, - ITEM_TYPE_BOOTS, - ITEM_TYPE_HELMET, - ITEM_TYPE_LEGS, - ITEM_TYPE_RING, - ITEM_TYPE_SHIELD, - ITEM_TYPE_AXE, - ITEM_TYPE_CLUB, - ITEM_TYPE_DISTANCE, - ITEM_TYPE_SWORD, - ITEM_TYPE_WAND, - ITEM_TYPE_QUIVER, - } - return table.contains(equipmentTypes, t) -end - -function MonsterType.getBossReward(self, lootFactor, topScore, equipmentOnly, lootTable) - if configManager.getNumber(configKeys.RATE_LOOT) <= 0 then - return lootTable or {} - end - - return self:generateLootRoll({ - factor = lootFactor, - gut = false, - filter = function(itemType, unique) - if unique and not topScore then - return false - end - if equipmentOnly then - return not unique and isEquipment(itemType) - end - return true - end, - }, lootTable) -end diff --git a/data/libs/reward_boss/player.lua b/data/libs/reward_boss/player.lua deleted file mode 100644 index 7a525efa2fd..00000000000 --- a/data/libs/reward_boss/player.lua +++ /dev/null @@ -1,57 +0,0 @@ -function Player.getRewardChest(self, autocreate) - return self:getDepotChest(99, autocreate) -end - -function Player.inBossFight(self) - if not next(_G.GlobalBosses) then - return false - end - - local playerGuid = self:getGuid() - for _, info in pairs(_G.GlobalBosses) do - local stats = info[playerGuid] - if stats and stats.active then - return stats - end - end - return false -end - --- For use of data/events/scripts/player.lua -function Player:executeRewardEvents(item, toPosition) - if toPosition.x == CONTAINER_POSITION then - local containerId = toPosition.y - 64 - local container = self:getContainerById(containerId) - if not container then - return true - end - - -- Do not let the player insert items into either the Reward Container or the Reward Chest - local itemId = container:getId() - if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return false - end - - -- The player also shouldn't be able to insert items into the boss corpse - local tileCorpse = Tile(container:getPosition()) - for index, value in ipairs(tileCorpse:getItems() or {}) do - if value:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2 ^ 31 - 1 and value:getName() == container:getName() then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return false - end - end - end - -- Do not let the player move the boss corpse. - if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2 ^ 31 - 1 then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - return false - end - -- Players cannot throw items on reward chest - local tileChest = Tile(toPosition) - if tileChest and tileChest:getItemById(ITEM_REWARD_CHEST) then - self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) - self:getPosition():sendMagicEffect(CONST_ME_POFF) - return false - end -end diff --git a/data/libs/achievements_lib.lua b/data/libs/systems/achievements.lua similarity index 100% rename from data/libs/achievements_lib.lua rename to data/libs/systems/achievements.lua diff --git a/data/libs/concoctions_lib.lua b/data/libs/systems/concoctions.lua similarity index 100% rename from data/libs/concoctions_lib.lua rename to data/libs/systems/concoctions.lua diff --git a/data/libs/daily_reward/daily_reward.lua b/data/libs/systems/daily_reward.lua similarity index 100% rename from data/libs/daily_reward/daily_reward.lua rename to data/libs/systems/daily_reward.lua diff --git a/data/libs/encounters_lib.lua b/data/libs/systems/encounters.lua similarity index 100% rename from data/libs/encounters_lib.lua rename to data/libs/systems/encounters.lua diff --git a/data/libs/forge_lib.lua b/data/libs/systems/exaltation_forge.lua similarity index 100% rename from data/libs/forge_lib.lua rename to data/libs/systems/exaltation_forge.lua diff --git a/data/libs/exercise_training.lua b/data/libs/systems/exercise_training.lua similarity index 100% rename from data/libs/exercise_training.lua rename to data/libs/systems/exercise_training.lua diff --git a/data/libs/familiar.lua b/data/libs/systems/familiar.lua similarity index 100% rename from data/libs/familiar.lua rename to data/libs/systems/familiar.lua diff --git a/data/libs/features_lib.lua b/data/libs/systems/features.lua similarity index 100% rename from data/libs/features_lib.lua rename to data/libs/systems/features.lua diff --git a/data/libs/hazard_lib.lua b/data/libs/systems/hazard.lua similarity index 100% rename from data/libs/hazard_lib.lua rename to data/libs/systems/hazard.lua diff --git a/data/libs/hireling_lib.lua b/data/libs/systems/hireling.lua similarity index 100% rename from data/libs/hireling_lib.lua rename to data/libs/systems/hireling.lua diff --git a/data/libs/systems/load.lua b/data/libs/systems/load.lua new file mode 100644 index 00000000000..bc52090f27b --- /dev/null +++ b/data/libs/systems/load.lua @@ -0,0 +1,14 @@ +-- Load systems functions +dofile(CORE_DIRECTORY .. "/libs/systems/achievements.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/concoctions.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/daily_reward.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/encounters.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/exaltation_forge.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/exercise_training.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/familiar.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/features.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/hazard.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/hireling.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/raids.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/reward_boss.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/zones.lua") diff --git a/data/libs/raids_lib.lua b/data/libs/systems/raids.lua similarity index 100% rename from data/libs/raids_lib.lua rename to data/libs/systems/raids.lua diff --git a/data/libs/reward_boss/reward_boss.lua b/data/libs/systems/reward_boss.lua similarity index 83% rename from data/libs/reward_boss/reward_boss.lua rename to data/libs/systems/reward_boss.lua index 5576eb62fa6..72476dfcbdd 100644 --- a/data/libs/reward_boss/reward_boss.lua +++ b/data/libs/systems/reward_boss.lua @@ -52,27 +52,6 @@ function InsertItems(buffer, info, parent, items) return info.running - start end -function Container:addRewardBossItems(itemList) - for itemId, lootInfo in pairs(itemList) do - local iType = ItemType(itemId) - if iType then - local itemCount = lootInfo.count - local charges = iType:getCharges() - if charges > 0 then - itemCount = charges - logger.debug("Adding item with 'id' to the reward container, item charges {}", iType:getId(), charges) - end - if iType:isStackable() or iType:getCharges() ~= 0 then - self:addItem(itemId, itemCount, INDEX_WHEREEVER, FLAG_NOLIMIT) - else - for i = 1, itemCount do - self:addItem(itemId, 1, INDEX_WHEREEVER, FLAG_NOLIMIT) - end - end - end - end -end - function InsertRewardItems(playerGuid, timestamp, itemList) local maxSidQueryResult = db.query("select max(`sid`) as max_sid from `player_rewards` where player_id = " .. playerGuid .. ";") local bagSid = (Result.getNumber(maxSidQueryResult, "max_sid") or 0) + 1 diff --git a/data/libs/zones_lib.lua b/data/libs/systems/zones.lua similarity index 100% rename from data/libs/zones_lib.lua rename to data/libs/systems/zones.lua diff --git a/data/libs/door.lua b/data/libs/tables/doors.lua similarity index 100% rename from data/libs/door.lua rename to data/libs/tables/doors.lua diff --git a/data/libs/tables/load.lua b/data/libs/tables/load.lua new file mode 100644 index 00000000000..4651019d840 --- /dev/null +++ b/data/libs/tables/load.lua @@ -0,0 +1,3 @@ +-- Load tables functions +dofile(CORE_DIRECTORY .. "/libs/tables/doors.lua") +dofile(CORE_DIRECTORY .. "/libs/tables/windows.lua") diff --git a/data/libs/window.lua b/data/libs/tables/windows.lua similarity index 100% rename from data/libs/window.lua rename to data/libs/tables/windows.lua diff --git a/data/libs/vocation.lua b/data/libs/vocation.lua deleted file mode 100644 index fd439de6520..00000000000 --- a/data/libs/vocation.lua +++ /dev/null @@ -1,31 +0,0 @@ -VOCATION = { - ID = { - NONE = 0, - SORCERER = 1, - DRUID = 2, - PALADIN = 3, - KNIGHT = 4, - MASTER_SORCERER = 5, - ELDER_DRUID = 6, - ROYAL_PALADIN = 7, - ELITE_KNIGHT = 8, - }, - CLIENT_ID = { - NONE = 0, - KNIGHT = 1, - PALADIN = 2, - SORCERER = 3, - DRUID = 4, - ELITE_KNIGHT = 11, - ROYAL_PALADIN = 12, - MASTER_SORCERER = 13, - ELDER_DRUID = 14, - }, - BASE_ID = { - NONE = 0, - SORCERER = 1, - DRUID = 2, - PALADIN = 3, - KNIGHT = 4, - }, -}