diff --git a/config.lua.dist b/config.lua.dist index 7471d5cd768..55a211267e6 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -474,6 +474,7 @@ location = "South America" -- The URL layout is https://discord.com/api/webhooks/:id/:token -- Leave empty if you wish to disable. discordWebhookURL = "" +discordSendFooter = true -- Vip System (Get more info in: https://github.com/opentibiabr/canary/pull/1063) -- NOTE: set vipSystemEnabled to true to enable the vip system functionalities (this overrides premium checks) diff --git a/data-canary/lib/core/constants.lua b/data-canary/lib/core/constants.lua index b42d731564d..7b99b309913 100644 --- a/data-canary/lib/core/constants.lua +++ b/data-canary/lib/core/constants.lua @@ -6,7 +6,7 @@ STACKPOS_FOURTH_ITEM_ABOVE_GROUNDTILE = 4 STACKPOS_FIFTH_ITEM_ABOVE_GROUNDTILE = 5 STACKPOS_TOP_CREATURE = 253 STACKPOS_TOP_FIELD = 254 -STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE = 255 +STACKPOS_TOP_MOVABLE_ITEM_OR_CREATURE = 255 THING_TYPE_PLAYER = CREATURETYPE_PLAYER + 1 THING_TYPE_MONSTER = CREATURETYPE_MONSTER + 1 diff --git a/data-canary/lib/core/storages.lua b/data-canary/lib/core/storages.lua index 43e47ef867f..7646a8cc51e 100644 --- a/data-canary/lib/core/storages.lua +++ b/data-canary/lib/core/storages.lua @@ -8,7 +8,7 @@ Reserved player action storage key ranges (const.hpp) [2001 - 2011] Others reserved player action/storages - [100] = unmoveable/untrade/unusable items + [100] = unmovable/untrade/unusable items [101] = use pick floor [102] = well down action [103-120] = others keys action diff --git a/data-canary/scripts/runes/chameleon.lua b/data-canary/scripts/runes/chameleon.lua index 858757b1725..92168645e20 100644 --- a/data-canary/scripts/runes/chameleon.lua +++ b/data-canary/scripts/runes/chameleon.lua @@ -16,7 +16,7 @@ function rune.onCastSpell(creature, variant, isHotkey) item = Tile(position):getTopDownItem() end - if not item or item.itemid == 0 or not isMoveable(item.uid) then + if not item or item.itemid == 0 or not isMovable(item.uid) then creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) creature:getPosition():sendMagicEffect(CONST_ME_POFF) return false diff --git a/data-otservbr-global/lib/compat/compat.lua b/data-otservbr-global/lib/compat/compat.lua index f62945e6b26..cd9b8146763 100644 --- a/data-otservbr-global/lib/compat/compat.lua +++ b/data-otservbr-global/lib/compat/compat.lua @@ -35,7 +35,7 @@ STACKPOS_FOURTH_ITEM_ABOVE_GROUNDTILE = 4 STACKPOS_FIFTH_ITEM_ABOVE_GROUNDTILE = 5 STACKPOS_TOP_CREATURE = 253 STACKPOS_TOP_FIELD = 254 -STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE = 255 +STACKPOS_TOP_MOVABLE_ITEM_OR_CREATURE = 255 THING_TYPE_PLAYER = CREATURETYPE_PLAYER + 1 THING_TYPE_MONSTER = CREATURETYPE_MONSTER + 1 @@ -1094,8 +1094,8 @@ function isCorpse(uid) return i ~= nil and ItemType(i:getId()):isCorpse() or false end -isItemMoveable = isItemMovable -isMoveable = isMovable +isItemMovable = isItemMovable +isMovable = isMovable function getItemName(itemId) return ItemType(itemId):getName() @@ -1380,7 +1380,7 @@ function getThingfromPos(pos) local thing local stackpos = pos.stackpos or 0 - if stackpos == STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE then + if stackpos == STACKPOS_TOP_MOVABLE_ITEM_OR_CREATURE then thing = tile:getTopCreature() if thing == nil then local item = tile:getTopDownItem() diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua index 10e5e305f63..888da1b113f 100644 --- a/data-otservbr-global/lib/core/storages.lua +++ b/data-otservbr-global/lib/core/storages.lua @@ -8,7 +8,7 @@ Reserved player action storage key ranges (const.h) [2001 - 2011] Others reserved player action/storages - [100] = unmoveable/untrade/unusable items + [100] = unmovable/untrade/unusable items [101] = use pick floor [102] = well down action [103-120] = others keys action diff --git a/data-otservbr-global/lib/quests/svargrond_arena.lua b/data-otservbr-global/lib/quests/svargrond_arena.lua index a32fc0df6b6..660426cb64b 100644 --- a/data-otservbr-global/lib/quests/svargrond_arena.lua +++ b/data-otservbr-global/lib/quests/svargrond_arena.lua @@ -218,7 +218,7 @@ function SvargrondArena.resetPit(pitId) if movableItem and movableItem:isItem() then local itemType = ItemType(movableItem:getId()) if itemType and itemType:isMovable() and not table.contains(SvargrondArena.itemsNotErasable, movableItem:getId()) then - moveableItem:remove() + movableItem:remove() end end diff --git a/data-otservbr-global/monster/quests/marapur/timira_the_many-headed.lua b/data-otservbr-global/monster/quests/marapur/timira_the_many-headed.lua index 1351dc4e303..43d0a1502c3 100644 --- a/data-otservbr-global/monster/quests/marapur/timira_the_many-headed.lua +++ b/data-otservbr-global/monster/quests/marapur/timira_the_many-headed.lua @@ -76,9 +76,11 @@ monster.loot = { { name = "giant topaz", chance = 2041 }, { name = "dawnfire sherwani", chance = 200 }, { name = "frostflower boots", chance = 200 }, + { name = "feverbloom boots", chance = 200 }, { id = 39233, chance = 200 }, -- enchanted turtle amulet { name = "midnight tunic", chance = 200 }, { name = "midnight sarong", chance = 200 }, + { name = "naga quiver", chance = 200 }, { name = "naga sword", chance = 200 }, { name = "naga axe", chance = 200 }, { name = "naga club", chance = 200 }, diff --git a/data-otservbr-global/npc/inigo.lua b/data-otservbr-global/npc/inigo.lua index e712582ea5e..6a16d1c8158 100644 --- a/data-otservbr-global/npc/inigo.lua +++ b/data-otservbr-global/npc/inigo.lua @@ -40,7 +40,7 @@ local hints = { [8] = "Always eat as much {food} as possible. \z This way, you'll regenerate health points for a longer period of time.", [9] = "After you have killed a monster, you have 10 seconds in which the corpse \z - is not moveable and no one else but you can loot it.", + is not movable and no one else but you can loot it.", [10] = "Be careful when you approach three or more {monsters} because you only can block the attacks of two! \z In such a situation, even a few salamanders can do severe damage or even kill you.", [11] = "There are many ways to gather {food}. Many creatures drop food but you can also pick blueberries or \z diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua index 674b23a1476..74a93dbf5a9 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_corrupted.lua @@ -378,7 +378,7 @@ local ferumbrasAscendantHabitatCorrupted = Action() function ferumbrasAscendantHabitatCorrupted.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Corrupted) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely yielothax", Position(33619, 32722, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua index 9d0e73b65e9..e5b8e22f150 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_desert.lua @@ -358,7 +358,7 @@ local ferumbrasAscendantHabitatDesert = Action() function ferumbrasAscendantHabitatDesert.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Desert) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely rotworm", Position(33641, 32684, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua index 1b9bbadb1eb..1fc14c6646f 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_dimension.lua @@ -394,7 +394,7 @@ local ferumbrasAscendantHabitatDimension = Action() function ferumbrasAscendantHabitatDimension.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Dimension) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely souleater", Position(33642, 32722, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua index 0c6c998e4e1..293e65844cc 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_grass.lua @@ -426,7 +426,7 @@ local ferumbrasAscendantHabitatGlass = Action() function ferumbrasAscendantHabitatGlass.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Grass) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely frazzlemaw", Position(33642, 32666, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua index 2dd56c8abd0..b46a984a00e 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_ice.lua @@ -441,7 +441,7 @@ local ferumbrasAscendantHabitatIce = Action() function ferumbrasAscendantHabitatIce.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Ice) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely snake", Position(33642, 32702, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua index 77e288f5e5b..52b0c9b7ac7 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_mushroom.lua @@ -394,7 +394,7 @@ local ferumbrasAscendantHabitatMushroom = Action() function ferumbrasAscendantHabitatMushroom.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Mushroom) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely scorpion", Position(33617, 32684, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua index 1718b1106b8..42da59f0e93 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_roshamuul.lua @@ -467,7 +467,7 @@ local ferumbrasAscendantHabitatRoshamuul = Action() function ferumbrasAscendantHabitatRoshamuul.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Roshamuul) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely deer", Position(33619, 32666, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua index 2883193b394..2649da5694e 100644 --- a/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua +++ b/data-otservbr-global/scripts/actions/quests/ferumbras_ascendant/habitat_venom.lua @@ -449,7 +449,7 @@ local ferumbrasAscendantHabitatVenom = Action() function ferumbrasAscendantHabitatVenom.onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 9125 then if Game.getStorageValue(GlobalStorage.FerumbrasAscendant.Habitats.Venom) >= 1 then - player:say("The lever are stuck, need some time to it can be moveable again.", TALKTYPE_MONSTER_SAY) + player:say("The lever are stuck, need some time to it can be movable again.", TALKTYPE_MONSTER_SAY) return true end Game.createMonster("lovely polar bear", Position(33617, 32702, 12), true, true) diff --git a/data-otservbr-global/scripts/actions/quests/marapur/boss_lever_timira.lua b/data-otservbr-global/scripts/actions/quests/marapur/boss_lever_timira.lua index 3f9bf934ebf..9c77ed3d849 100644 --- a/data-otservbr-global/scripts/actions/quests/marapur/boss_lever_timira.lua +++ b/data-otservbr-global/scripts/actions/quests/marapur/boss_lever_timira.lua @@ -1,15 +1,13 @@ local config = { - boss = { - name = "Timira The Many-Headed", - position = Position(33815, 32703, 9), - }, + boss = { name = "Timira the Many-Headed" }, + encounter = "Timira the Many-Headed", requiredLevel = 250, playerPositions = { - { pos = Position(33809, 32702, 8), teleport = Position(33816, 32708, 9), effect = CONST_ME_TELEPORT }, - { pos = Position(33808, 32702, 8), teleport = Position(33816, 32708, 9), effect = CONST_ME_TELEPORT }, - { pos = Position(33807, 32702, 8), teleport = Position(33816, 32708, 9), effect = CONST_ME_TELEPORT }, - { pos = Position(33806, 32702, 8), teleport = Position(33816, 32708, 9), effect = CONST_ME_TELEPORT }, - { pos = Position(33805, 32702, 8), teleport = Position(33816, 32708, 9), effect = CONST_ME_TELEPORT }, + { pos = Position(33809, 32702, 8), teleport = Position(33787, 32680, 10), effect = CONST_ME_TELEPORT }, + { pos = Position(33808, 32702, 8), teleport = Position(33787, 32680, 10), effect = CONST_ME_TELEPORT }, + { pos = Position(33807, 32702, 8), teleport = Position(33787, 32680, 10), effect = CONST_ME_TELEPORT }, + { pos = Position(33806, 32702, 8), teleport = Position(33787, 32680, 10), effect = CONST_ME_TELEPORT }, + { pos = Position(33805, 32702, 8), teleport = Position(33787, 32680, 10), effect = CONST_ME_TELEPORT }, }, specPos = { from = Position(33803, 32690, 9), @@ -21,3 +19,7 @@ local config = { local lever = BossLever(config) lever:position({ x = 33810, y = 32702, z = 8 }) lever:register() + +local zone = lever:getZone() +zone:addArea({ x = 33777, y = 32673, z = 10 }, { x = 33801, y = 32700, z = 10 }) +zone:addArea({ x = 33784, y = 32701, z = 9 }, { x = 33806, y = 32716, z = 9 }) diff --git a/data-otservbr-global/scripts/actions/quests/marapur/boss_timira_fight.lua b/data-otservbr-global/scripts/actions/quests/marapur/boss_timira_fight.lua new file mode 100644 index 00000000000..df39a5799be --- /dev/null +++ b/data-otservbr-global/scripts/actions/quests/marapur/boss_timira_fight.lua @@ -0,0 +1,390 @@ +local timiraFightConfig = { + chestEquipmentChance = 200, -- with modifier x4 and lootRate x3 it gives 3,6% for equipment + getLootRandomModifier = 4, -- for more info check getLootRandom function in functions.lua + bucketsRequiredPerPlayerInFight = 2, + corruptedWaterUsePerPlayerInFight = 2, + secondsDelayForUseCorruptedWater = 8, + chestPossibleValuables = { + "crystal coin", + "amber", + "giant sapphire", + "giant amethyst", + "Raw Watermelon Tourmaline", + "Watermelon Tourmaline", + }, + chestPossibleEquipment = { + "dawnfire sherwani", + "dawnfire pantaloons", + "frostflower boots", + "feverbloom boots", + "midnight tunic", + "midnight sarong", + "naga sword", + "naga axe", + "naga club", + "naga wand", + "naga rod", + "naga crossbow", + "naga quiver", + }, +} + +local fightZone = Zone("fight.timira.encounterZone") +local firstStageZone = Zone("fight.timira.encounterZone.firstStage") +local secondStageZone = Zone("fight.timira.encounterZone.secondStage") +local bossZone = Zone("fight.timira.encounterZone.bossStage") + +firstStageZone:addArea({ x = 33787, y = 32684, z = 10 }, { x = 33793, y = 32694, z = 10 }) -- smaller than first stage area, its spawn area +secondStageZone:addArea({ x = 33793, y = 32704, z = 9 }, { x = 33802, y = 32709, z = 9 }) -- smaller than first stage area, its spawn area +bossZone:addArea({ x = 33803, y = 32690, z = 9 }, { x = 33828, y = 32715, z = 9 }) -- whole boss area + +fightZone:addArea({ x = 33777, y = 32673, z = 10 }, { x = 33801, y = 32700, z = 10 }) -- whole first stage area +fightZone:addArea({ x = 33784, y = 32701, z = 9 }, { x = 33805, y = 32711, z = 9 }) -- whole second stage area +fightZone:addArea({ x = 33803, y = 32690, z = 9 }, { x = 33828, y = 32715, z = 9 }) -- whole boss stage area + +local monstersToKeepSpawning = { + { name = "Rogue Naga", amount = 3 }, + { name = "Corrupt Naga", amount = 3 }, +} + +local stages = { + FIRST = 1, + SECOND = 2, + THIRD = 3, +} + +local firstStageConfig = { + sparklingBucketId = 39244, + badWaterBucketId = 39243, + emptyBucketId = 39242, + shatteredWaterId = 39269, + fixedShatteredWaterId = 39268, + shatteredWaterPosition = Position(33798, 32689, 10), + sparklesIds = { 1722, 1723 }, + shallowWaterPositions = { + Position(33793, 32679, 10), + Position(33794, 32679, 10), + Position(33793, 32680, 10), + Position(33794, 32680, 10), + Position(33795, 32680, 10), + Position(33793, 32681, 10), + Position(33794, 32681, 10), + Position(33795, 32681, 10), + Position(33796, 32681, 10), + Position(33794, 32682, 10), + Position(33795, 32682, 10), + Position(33796, 32682, 10), + Position(33794, 32683, 10), + Position(33795, 32683, 10), + Position(33796, 32683, 10), + }, + bucketsPostions = { + Position(33796, 32685, 10), + Position(33797, 32691, 10), + Position(33787, 32687, 10), + Position(33785, 32676, 10), + }, + shallowWaterBorderIds = { + 38125, + 38134, + 38130, + 38126, + 38136, + }, + isWaterSparkling = false, + skipedSparklingIterations = 0, + sparklingIterationsToSkip = 3, + nextStageTeleportPosition = Position(33787, 32699, 10), + rewardChestPosition = Position(33789, 32699, 10), + playersTookReward = {}, +} + +local secondStageConfig = { + nextStageTeleportPosition = Position(33804, 32704, 9), + rewardChestPosition = Position(33802, 32703, 9), + playersTookReward = {}, +} + +local activeTeleportId = 35500 +local inactiveTeleportId = 39238 +local chestId = 39390 +local activeStage = stages.FIRST +local firstStagePoints = 0 +local secondStagePoints = 0 + +local function restartShatteredWater() + local pos = firstStageConfig.shatteredWaterPosition + if pos:hasItem(firstStageConfig.fixedShatteredWaterId) then + Tile(pos):getItemById(firstStageConfig.fixedShatteredWaterId):remove(1) + Game.createItem(firstStageConfig.shatteredWaterId, 1, pos) + end +end + +local function restartBuckets() + for _, pos in ipairs(firstStageConfig.bucketsPostions) do + if not pos:hasItem(firstStageConfig.emptyBucketId) then + Game.createItem(firstStageConfig.emptyBucketId, 1, pos) + end + end +end + +local function restartTeleports() + local teleports = { firstStageConfig.nextStageTeleportPosition, secondStageConfig.nextStageTeleportPosition } + for _, pos in ipairs(teleports) do + if pos:hasItem(activeTeleportId) then + Tile(pos):getItemById(activeTeleportId):remove(1) + Game.createItem(inactiveTeleportId, 1, pos) + end + end +end + +local function removeRewardChests() + local chests = { firstStageConfig.rewardChestPosition, secondStageConfig.rewardChestPosition } + firstStageConfig.playersTookReward = {} + secondStageConfig.playersTookReward = {} + for _, pos in ipairs(chests) do + if pos:hasItem(chestId) then + Tile(pos):getItemById(chestId):remove(1) + end + end +end + +local function restart() + activeStage = stages.FIRST + firstStagePoints = 0 + secondStagePoints = 0 + firstStageConfig.isWaterSparkling = false + firstStageConfig.previousIterSkipedSparkling = false + restartShatteredWater() + restartBuckets() + restartTeleports() + removeRewardChests() +end + +local function activeZone() + local stageZones = { + [stages.FIRST] = firstStageZone, + [stages.SECOND] = secondStageZone, + [stages.THIRD] = {}, + } + return stageZones[activeStage] +end + +local encounter = Encounter("Timira the Many-Headed", { + zone = fightZone, + timeToSpawnMonsters = "10ms", +}) + +encounter + :addStage({ + start = function() + restart() + end, + }) + :autoAdvance() +encounter:addRemoveMonsters():autoAdvance() +encounter:addStage({ start = function() end }) -- FIRST stage, Action timiraBucket.onUse activates next stage + +encounter:addRemoveMonsters():autoAdvance() +encounter:addStage({ start = function() end }) -- SECOND stage, Action corruptedWater.onUse activates next stage + +encounter:addRemoveMonsters():autoAdvance() +encounter:addSpawnMonsters({ -- THIRD stage, boss fight + { + name = "Timira the Many-Headed", + positions = { Position(33815, 32703, 9) }, + }, +}) + +encounter:register() + +local function startSecondStage() + if activeStage == stages.FIRST then + local pos = firstStageConfig.shatteredWaterPosition + if pos:hasItem(firstStageConfig.shatteredWaterId) then + Tile(pos):getItemById(firstStageConfig.shatteredWaterId):remove(1) + Game.createItem(firstStageConfig.fixedShatteredWaterId, 1, pos) + end + local tpPos = firstStageConfig.nextStageTeleportPosition + if tpPos:hasItem(inactiveTeleportId) then + Tile(tpPos):getItemById(inactiveTeleportId):remove(1) + Game.createItem(activeTeleportId, 1, tpPos) + end + Game.createItem(chestId, 1, firstStageConfig.rewardChestPosition) + activeStage = stages.SECOND + encounter:nextStage() + end +end + +local function startThirdStage() + if activeStage == stages.SECOND then + local tpPos = secondStageConfig.nextStageTeleportPosition + if tpPos:hasItem(inactiveTeleportId) then + Tile(tpPos):getItemById(inactiveTeleportId):remove(1) + Game.createItem(activeTeleportId, 1, tpPos) + end + Game.createItem(chestId, 1, secondStageConfig.rewardChestPosition) + activeStage = stages.THIRD + encounter:nextStage() + end +end + +function encounter:onReset(position) + encounter:removeMonsters() + fightZone:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Timira the Many-Headed has been defeated. You have %i seconds to leave the room.", 60)) + self:addEvent(function(zn) + zn:refresh() + zn:removePlayers() + end, 60 * 1000, fightZone) +end + +local nagaSpawner = GlobalEvent("self.timira.spawner.onThink") +function nagaSpawner.onThink(interval, lastExecution) + if next(fightZone:getPlayers()) == nil then + return true + end + + if activeStage < 3 then + for _, mob in ipairs(monstersToKeepSpawning) do + if fightZone:countMonsters(mob.name) < mob.amount then + encounter:spawnMonsters({ name = mob.name, positions = { activeZone():randomPosition() } }) + end + end + end + + return true +end +nagaSpawner:interval(1000) +nagaSpawner:register() + +local sparklingWater = GlobalEvent("self.timira.water.onThink") +function sparklingWater.onThink(interval, lastExecution) + if firstStageConfig.isWaterSparkling then --Sparkling 2s passed, turn it off + for _, pos in ipairs(firstStageConfig.shallowWaterPositions) do + for _, spark in ipairs(firstStageConfig.sparklesIds) do + if pos:hasItem(spark) then + Tile(pos):getItemById(spark):remove(1) + end + end + end + firstStageConfig.isWaterSparkling = false + firstStageConfig.skipedSparklingIterations = 0 + return true + end + + if next(fightZone:getPlayers()) == nil then + return true + end + + if activeStage == stages.FIRST then + if not firstStageConfig.isWaterSparkling and firstStageConfig.skipedSparklingIterations >= firstStageConfig.sparklingIterationsToSkip then + for _, pos in ipairs(firstStageConfig.shallowWaterPositions) do + local spark = firstStageConfig.sparklesIds[math.random(1, #firstStageConfig.sparklesIds)] + Game.createItem(spark, 1, pos) + end + firstStageConfig.isWaterSparkling = true + else + firstStageConfig.skipedSparklingIterations = firstStageConfig.skipedSparklingIterations + 1 + end + end + + return true +end +sparklingWater:interval(2000) +sparklingWater:register() + +local timiraBucket = Action() +function timiraBucket.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if item.itemid == firstStageConfig.sparklingBucketId and target and target.itemid == firstStageConfig.shatteredWaterId then + if player:removeItem(firstStageConfig.sparklingBucketId, 1) then + player:addItem(firstStageConfig.emptyBucketId, 1) + toPosition:sendMagicEffect(CONST_ME_WATER_DROP) + firstStagePoints = firstStagePoints + 1 + + if activeStage == stages.FIRST and firstStagePoints >= fightZone:countPlayers() * timiraFightConfig.bucketsRequiredPerPlayerInFight then + player:say("The water has formed into a shape!", TALKTYPE_MONSTER_SAY, false, 0, firstStageConfig.shatteredWaterPosition) + startSecondStage() + return true + end + player:say("The pieces are shining!", TALKTYPE_MONSTER_SAY, false, 0, firstStageConfig.shatteredWaterPosition) + end + return true + end + if item.itemid == firstStageConfig.badWaterBucketId and target and target.itemid ~= firstStageConfig.shatteredWaterId then + if player:removeItem(firstStageConfig.badWaterBucketId, 1) then + player:addItem(firstStageConfig.emptyBucketId, 1) + local splash = Game.createItem(2886, 0, toPosition) + splash:decay() + end + return true + end + if item.itemid == firstStageConfig.emptyBucketId and target and table.contains(firstStageConfig.shallowWaterBorderIds, target.itemid) then + if player:removeItem(firstStageConfig.emptyBucketId, 1) then + if firstStageConfig.isWaterSparkling then + player:addItem(firstStageConfig.sparklingBucketId, 1) + else + player:addItem(firstStageConfig.badWaterBucketId, 1) + end + end + return true + end + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false +end +timiraBucket:id(firstStageConfig.sparklingBucketId, firstStageConfig.emptyBucketId, firstStageConfig.badWaterBucketId) +timiraBucket:register() + +local corruptedWater = Action() +function corruptedWater.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if not activeStage == stages.SECOND then + return false + end + local currentIcon = player:getIcon("timira-secondStage") + if not currentIcon or currentIcon.category ~= CreatureIconCategory_Quests or currentIcon.icon ~= CreatureIconQuests_RedShield then + secondStagePoints = secondStagePoints + 1 + if secondStagePoints >= fightZone:countPlayers() * timiraFightConfig.corruptedWaterUsePerPlayerInFight then + startThirdStage() + return true + end + player:setIcon("timira-secondStage", CreatureIconCategory_Quests, CreatureIconQuests_RedShield, 1) + addEvent(function(playerUid) + local player = Player(playerUid) + if player then + player:removeIcon("timira-secondStage") + end + return true + end, timiraFightConfig.secondsDelayForUseCorruptedWater * 1000, player:getGuid()) + return true + end + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false +end +corruptedWater:id(39267) +corruptedWater:register() + +local timiraChest = Action() +function timiraChest.onUse(player, item, fromPosition, target, toPosition, isHotkey) + local rewards = { + [firstStageConfig.rewardChestPosition.z] = firstStageConfig.playersTookReward, + [secondStageConfig.rewardChestPosition.z] = secondStageConfig.playersTookReward, + } + + if table.contains(rewards[toPosition.z], player:getGuid()) then + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The chest is empty.") + player:getPosition():sendMagicEffect(CONST_ME_POFF) + return false + end + table.insert(rewards[toPosition.z], player:getGuid()) + local randValue = getLootRandom(timiraFightConfig.getLootRandomModifier) + local itemName = timiraFightConfig.chestPossibleValuables[math.random(1, #timiraFightConfig.chestPossibleValuables)] + if randValue <= timiraFightConfig.chestEquipmentChance then + itemName = timiraFightConfig.chestPossibleEquipment[math.random(1, #timiraFightConfig.chestPossibleEquipment)] + end + + local rewardItem = ItemType(itemName) + player:addItem(rewardItem:getId(), 1) + player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have found a " .. itemName .. ".") + return true +end +timiraChest:id(chestId) +timiraChest:register() diff --git a/data-otservbr-global/scripts/actions/quests/marapur/teleports_timira.lua b/data-otservbr-global/scripts/actions/quests/marapur/teleports_timira.lua index a2ad0773c2e..862da606a05 100644 --- a/data-otservbr-global/scripts/actions/quests/marapur/teleports_timira.lua +++ b/data-otservbr-global/scripts/actions/quests/marapur/teleports_timira.lua @@ -1,9 +1,14 @@ local positions = { - { tptimiraPos = { x = 33803, y = 32700, z = 7 }, tpPos = { x = 33806, y = 32700, z = 8 } }, + { tptimiraPos = { x = 33803, y = 32700, z = 7 }, tpPos = { x = 33806, y = 32700, z = 8 } }, -- Outside to lever room teleport + { tptimiraPos = { x = 33802, y = 32700, z = 8 }, tpPos = { x = 33804, y = 32702, z = 7 } }, -- Lever room to outside teleport - { tptimiraPos = { x = 33802, y = 32700, z = 8 }, tpPos = { x = 33804, y = 32702, z = 7 } }, + { tptimiraPos = { x = 33790, y = 32678, z = 10 }, tpPos = { x = 33810, y = 32699, z = 8 } }, -- First stage to Lever room + { tptimiraPos = { x = 33787, y = 32699, z = 10 }, tpPos = { x = 33790, y = 32706, z = 9 } }, -- First stage to Second stage - { tptimiraPos = { x = 33816, y = 32710, z = 9 }, tpPos = { x = 33810, y = 32699, z = 8 } }, + { tptimiraPos = { x = 33788, y = 32708, z = 9 }, tpPos = { x = 33810, y = 32699, z = 8 } }, -- Second stage to Lever room + { tptimiraPos = { x = 33804, y = 32704, z = 9 }, tpPos = { x = 33810, y = 32705, z = 9 } }, -- Second stage to Third stage + + { tptimiraPos = { x = 33816, y = 32710, z = 9 }, tpPos = { x = 33804, y = 32702, z = 7 } }, -- BossRoom exit to outside teleport } local TpTimira = MoveEvent() diff --git a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua index ef79ffee7d4..9e8bfbeca34 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua +++ b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua @@ -68,16 +68,7 @@ function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustifi ) local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid) -- Start Webhook Player Death - local playerName = player:getName() - local playerLevel = player:getLevel() - local killerLink = string.gsub(killerName, "%s+", "+") - local playerLink = string.gsub(playerName, "%s+", "+") - local serverURL = getConfigInfo("url") - if killer and killer:isPlayer() then - Webhook.sendMessage(playerName .. " just got killed!", "**[" .. playerName .. "](" .. serverURL .. "/?characters/" .. playerLink .. ")** got killed at level " .. playerLevel .. " by **[" .. killerName .. "](" .. serverURL .. "/?characters/" .. killerLink .. ")**", WEBHOOK_COLOR_OFFLINE, announcementChannels["player-kills"]) - else - Webhook.sendMessage(playerName .. " has just died!", "**[" .. playerName .. "](" .. serverURL .. "/?characters/" .. playerLink .. ")** died at level " .. playerLevel .. " by " .. killerName, WEBHOOK_COLOR_WARNING, announcementChannels["player-kills"]) - end + Webhook.sendMessage(":skull_crossbones: " .. player:getMarkdownLink() .. " has died. Killed at level _" .. player:getLevel() .. "_ by **" .. killerName .. "**.", announcementChannels["player-kills"]) -- End Webhook Player Death local deathRecords = 0 diff --git a/data-otservbr-global/scripts/globalevents/others/global_server_save.lua b/data-otservbr-global/scripts/globalevents/others/global_server_save.lua index c65255b592b..84303a356da 100644 --- a/data-otservbr-global/scripts/globalevents/others/global_server_save.lua +++ b/data-otservbr-global/scripts/globalevents/others/global_server_save.lua @@ -17,7 +17,7 @@ local function ServerSaveWarning(time) local remainingTime = tonumber(time) - 60000 if configManager.getBoolean(configKeys.GLOBAL_SERVER_SAVE_NOTIFY_MESSAGE) then local message = "Server is saving game in " .. (remainingTime / 60000) .. " minute(s). Please logout." - Webhook.sendMessage("Server save", message, WEBHOOK_COLOR_WARNING) + Webhook.sendMessage(":floppy_disk: " .. message, announcementChannels["serverAnnouncements"]) Game.broadcastMessage(message, MESSAGE_GAME_HIGHLIGHT) end -- if greater than one minute, schedule another warning @@ -36,7 +36,7 @@ function serverSaveEvent.onTime(interval) local remainingTime = configManager.getNumber(configKeys.GLOBAL_SERVER_SAVE_NOTIFY_DURATION) * 60000 if configManager.getBoolean(configKeys.GLOBAL_SERVER_SAVE_NOTIFY_MESSAGE) then local message = "Server is saving game in " .. (remainingTime / 60000) .. " minute(s). Please logout." - Webhook.sendMessage("Server save", message, WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage(":floppy_disk: " .. message, announcementChannels["serverAnnouncements"]) Game.broadcastMessage(message, MESSAGE_GAME_HIGHLIGHT) end addEvent(ServerSaveWarning, 60000, remainingTime) -- Schedule next event in 1 minute(60000) diff --git a/data-otservbr-global/scripts/globalevents/others/startup.lua b/data-otservbr-global/scripts/globalevents/others/startup.lua index 22af76e94c2..603e50a3ba1 100644 --- a/data-otservbr-global/scripts/globalevents/others/startup.lua +++ b/data-otservbr-global/scripts/globalevents/others/startup.lua @@ -28,8 +28,8 @@ function serverstartup.onStartup() loadLuaMapUnique(ItemUnique) -- Item daily reward table -- This is temporary disabled > loadLuaMapAction(DailyRewardAction) - -- Item unmoveable table - loadLuaMapAction(ItemUnmoveableAction) + -- Item unmovable table + loadLuaMapAction(ItemUnmovableAction) -- Lever table loadLuaMapAction(LeverAction) loadLuaMapUnique(LeverUnique) diff --git a/data-otservbr-global/scripts/globalevents/spawn/rashid.lua b/data-otservbr-global/scripts/globalevents/spawn/rashid.lua index 0e21385eb75..78fd80d874e 100644 --- a/data-otservbr-global/scripts/globalevents/spawn/rashid.lua +++ b/data-otservbr-global/scripts/globalevents/spawn/rashid.lua @@ -9,7 +9,7 @@ local positionByDay = { } local function rashidwebhook(message) -- New local function that runs on delay to send webhook message. - Webhook.sendMessage("[Rashid] ", message, WEBHOOK_COLOR_ONLINE) --Sends webhook message + Webhook.sendMessage(":man_wearing_turban: " .. message, announcementChannels["serverAnnouncements"]) end local rashid = GlobalEvent("rashid") diff --git a/data-otservbr-global/scripts/globalevents/worldchanges/fury_gates.lua b/data-otservbr-global/scripts/globalevents/worldchanges/fury_gates.lua index 44c5a4c78c6..a50cc253016 100644 --- a/data-otservbr-global/scripts/globalevents/worldchanges/fury_gates.lua +++ b/data-otservbr-global/scripts/globalevents/worldchanges/fury_gates.lua @@ -101,7 +101,7 @@ local gates = { } local function Furywebhook(message) -- New local function that runs on delay to send webhook message. - Webhook.sendMessage("[Fury Gates] ", message, WEBHOOK_COLOR_ONLINE) --Sends webhook message + Webhook.sendMessage(":fire: " .. message, announcementChannels["serverAnnouncements"]) end -- FURY GATES MAP LOAD diff --git a/data-otservbr-global/scripts/globalevents/worldchanges/nightmare_isle.lua b/data-otservbr-global/scripts/globalevents/worldchanges/nightmare_isle.lua index b367b490679..fb0d3b6f672 100644 --- a/data-otservbr-global/scripts/globalevents/worldchanges/nightmare_isle.lua +++ b/data-otservbr-global/scripts/globalevents/worldchanges/nightmare_isle.lua @@ -17,7 +17,7 @@ local config = { } local function Nightmarewebhook(message) -- New local function that runs on delay to send webhook message. - Webhook.sendMessage("[Nightmare Isle] ", message, WEBHOOK_COLOR_ONLINE) --Sends webhook message + Webhook.sendMessage(":thought_balloon: " .. message, announcementChannels["serverAnnouncements"]) end local NightmareIsle = GlobalEvent("NightmareIsle") diff --git a/data-otservbr-global/scripts/globalevents/worldchanges/yasir.lua b/data-otservbr-global/scripts/globalevents/worldchanges/yasir.lua index a0bd427f568..5807c44387b 100644 --- a/data-otservbr-global/scripts/globalevents/worldchanges/yasir.lua +++ b/data-otservbr-global/scripts/globalevents/worldchanges/yasir.lua @@ -46,7 +46,7 @@ local config = { } local function yasirwebhook(message) -- New local function that runs on delay to send webhook message. - Webhook.sendMessage("[Yasir] ", message, WEBHOOK_COLOR_ONLINE) --Sends webhook message + Webhook.sendMessage(":man_wearing_turban_tone4: " .. message, announcementChannels["serverAnnouncements"]) end local yasirEnabled = true diff --git a/data-otservbr-global/scripts/spells/runes/chameleon.lua b/data-otservbr-global/scripts/spells/runes/chameleon.lua index 858757b1725..92168645e20 100644 --- a/data-otservbr-global/scripts/spells/runes/chameleon.lua +++ b/data-otservbr-global/scripts/spells/runes/chameleon.lua @@ -16,7 +16,7 @@ function rune.onCastSpell(creature, variant, isHotkey) item = Tile(position):getTopDownItem() end - if not item or item.itemid == 0 or not isMoveable(item.uid) then + if not item or item.itemid == 0 or not isMovable(item.uid) then creature:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) creature:getPosition():sendMagicEffect(CONST_ME_POFF) return false diff --git a/data-otservbr-global/startup/README.md b/data-otservbr-global/startup/README.md index cfc992c635d..e66c0c1b51a 100644 --- a/data-otservbr-global/startup/README.md +++ b/data-otservbr-global/startup/README.md @@ -39,77 +39,77 @@ Item (unique) = 40001/42000 This folder was created exclusively for tables and functions that are loaded at startup or that cannot be reloaded, thus maintaining greater organization in the files. Action IDS - Use actionID only if you need to create a function that is called multiple times in different locations. - The action is also used as storage, "x" storage is added in the player, - and the same action number gives access to a door, for example. +Use actionID only if you need to create a function that is called multiple times in different locations. +The action is also used as storage, "x" storage is added in the player, +and the same action number gives access to a door, for example. - Reserved player action storage key ranges (const.h at the source) - [10000000 - 20000000] - [1000 - 1500] - [2001 - 2011] + Reserved player action storage key ranges (const.h at the source) + [10000000 - 20000000] + [1000 - 1500] + [2001 - 2011] - Others reserved player action/storages - [100] = unmoveable/untrade/unusable items - [101] = use pick floor - [102] = down floor action - [103] = key 0010 - [103-120] = keys action - [104] = Parchment of the parchment room quest - [303] = key 0303 - [1000] = level door. Here 1 must be used followed by the level. Example: 1010 = level 10, 1100 = level 100] - [3001-3008] = key 3001/3008 - [3012] = key 3012 - [3033] = key 3033 - [3100] = key 3100 - [3142] = key 3142 - [3200] = key 3200 - [3301] = key 3301 - [3302] = key 3302 - [3303] = key 3303 - [3304] = key 3304 - [3350] = key 3350 - [3520] = key 3520 - [3600] = key 3600 - [3610] = key 3610 - [3620] = key 3620 - [3650] = key 3650 - [3666] = key 3666 - [3667] = key 3667 - [3700] = key 3700 - [3701/3703] = key 3701/3703 - [3800/3802] = key 3800/3802 - [3899] = key 3899 - [3900] = key 3900 - [3909/3917] = key 3909/3917 - [3923] = key 3923 - [3925] = key 3925 - [3930] = key 3930 - [3932] = key 3932 - [3934] = key 3934 - [3935] = key 3935 - [3936] = key 3936 - [3938] = key 3938 - [3940] = key 3940 - [3950] = key 3950 - [3960] = key 3960 - [3980] = key 3980 - [3988] = key 3988 - [4001] = key 4001 - [4009] = key 4009 - [4022] = key 4022 - [4023] = key 4023 - [4033] = key 4033 - [4037] = key 4037 - [4055] = key 4055 - [4210] = key 4210 - [4501] = key 4501 - [4502] = key 4502 - [4503] = key 4503 - [4600] = key 4600 - [4601] = key 4601 - [4603] = key 4603 - [5000] = key 5000 - [5002] = key 5002 - [5010] = key 5010 - [5050] = key 5050 - [6010] = key 6010 + Others reserved player action/storages + [100] = unmovable/untrade/unusable items + [101] = use pick floor + [102] = down floor action + [103] = key 0010 + [103-120] = keys action + [104] = Parchment of the parchment room quest + [303] = key 0303 + [1000] = level door. Here 1 must be used followed by the level. Example: 1010 = level 10, 1100 = level 100] + [3001-3008] = key 3001/3008 + [3012] = key 3012 + [3033] = key 3033 + [3100] = key 3100 + [3142] = key 3142 + [3200] = key 3200 + [3301] = key 3301 + [3302] = key 3302 + [3303] = key 3303 + [3304] = key 3304 + [3350] = key 3350 + [3520] = key 3520 + [3600] = key 3600 + [3610] = key 3610 + [3620] = key 3620 + [3650] = key 3650 + [3666] = key 3666 + [3667] = key 3667 + [3700] = key 3700 + [3701/3703] = key 3701/3703 + [3800/3802] = key 3800/3802 + [3899] = key 3899 + [3900] = key 3900 + [3909/3917] = key 3909/3917 + [3923] = key 3923 + [3925] = key 3925 + [3930] = key 3930 + [3932] = key 3932 + [3934] = key 3934 + [3935] = key 3935 + [3936] = key 3936 + [3938] = key 3938 + [3940] = key 3940 + [3950] = key 3950 + [3960] = key 3960 + [3980] = key 3980 + [3988] = key 3988 + [4001] = key 4001 + [4009] = key 4009 + [4022] = key 4022 + [4023] = key 4023 + [4033] = key 4033 + [4037] = key 4037 + [4055] = key 4055 + [4210] = key 4210 + [4501] = key 4501 + [4502] = key 4502 + [4503] = key 4503 + [4600] = key 4600 + [4601] = key 4601 + [4603] = key 4603 + [5000] = key 5000 + [5002] = key 5002 + [5010] = key 5010 + [5050] = key 5050 + [6010] = key 6010 diff --git a/data-otservbr-global/startup/tables/item_unmoveable.lua b/data-otservbr-global/startup/tables/item_unmovable.lua similarity index 89% rename from data-otservbr-global/startup/tables/item_unmoveable.lua rename to data-otservbr-global/startup/tables/item_unmovable.lua index ed7128ad6ad..cd7aa195742 100644 --- a/data-otservbr-global/startup/tables/item_unmoveable.lua +++ b/data-otservbr-global/startup/tables/item_unmovable.lua @@ -1,6 +1,6 @@ -- Look README.md for see the reserved action/unique numbers -ItemUnmoveableAction = { +ItemUnmovableAction = { -- Unmovable action, add new position and it create in-game [100] = { itemId = false, diff --git a/data-otservbr-global/startup/tables/load.lua b/data-otservbr-global/startup/tables/load.lua index fe3b5bbde5e..901dd2fe940 100644 --- a/data-otservbr-global/startup/tables/load.lua +++ b/data-otservbr-global/startup/tables/load.lua @@ -6,7 +6,7 @@ dofile(DATA_DIRECTORY .. "/startup/tables/door_level.lua") dofile(DATA_DIRECTORY .. "/startup/tables/door_quest.lua") dofile(DATA_DIRECTORY .. "/startup/tables/item.lua") dofile(DATA_DIRECTORY .. "/startup/tables/item_daily_reward.lua") -dofile(DATA_DIRECTORY .. "/startup/tables/item_unmoveable.lua") +dofile(DATA_DIRECTORY .. "/startup/tables/item_unmovable.lua") dofile(DATA_DIRECTORY .. "/startup/tables/lever.lua") dofile(DATA_DIRECTORY .. "/startup/tables/teleport.lua") dofile(DATA_DIRECTORY .. "/startup/tables/teleport_item.lua") diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua index a11be319069..fa67db083ec 100644 --- a/data/events/scripts/player.lua +++ b/data/events/scripts/player.lua @@ -1,6 +1,6 @@ local storeItemID = { -- registered item ids here are not tradable with players - -- these items can be set to moveable at items.xml + -- these items can be set to movable at items.xml -- 500 charges exercise weapons 28552, -- exercise sword 28553, -- exercise axe @@ -662,3 +662,24 @@ function Player:onChangeZone(zone) end function Player:onInventoryUpdate(item, slot, equip) end + +function Player:getURL() + local playerLink = string.gsub(self:getName(), "%s+", "+") + local serverURL = configManager.getString(configKeys.URL) + return serverURL .. "/characters/" .. playerLink +end + +function Player:getMarkdownLink() + local vocation = self:vocationAbbrev() + local emoji = ":school_satchel:" + if self:isKnight() then + emoji = ":crossed_swords:" + elseif self:isPaladin() then + emoji = ":bow_and_arrow:" + elseif self:isDruid() then + emoji = ":herb:" + elseif self:isSorcerer() then + emoji = ":crystal_ball:" + end + return "**[" .. self:getName() .. "](" .. self:getURL() .. ")** " .. emoji .. " [_" .. vocation .. "_]" +end diff --git a/data/items/items.xml b/data/items/items.xml index bce4281b538..abbe27c060c 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -11607,7 +11607,7 @@ - + @@ -35642,7 +35642,7 @@ - + @@ -35742,7 +35742,7 @@ - + @@ -42625,7 +42625,7 @@ - + @@ -50372,7 +50372,7 @@ - + diff --git a/data/libs/core/global_storage.lua b/data/libs/core/global_storage.lua index 4119be5ebb6..63d17166332 100644 --- a/data/libs/core/global_storage.lua +++ b/data/libs/core/global_storage.lua @@ -8,7 +8,7 @@ Reserved player action storage key ranges (const.hpp) [2001 - 2011] Others reserved player action/storages - [100] = unmoveable/untrade/unusable items + [100] = unmovable/untrade/unusable items [101] = use pick floor [102] = well down action [103-120] = others keys action diff --git a/data/libs/functions/player.lua b/data/libs/functions/player.lua index d494f35edd3..8bb420a5669 100644 --- a/data/libs/functions/player.lua +++ b/data/libs/functions/player.lua @@ -555,9 +555,9 @@ function Player.updateHazard(self) return true end -function Player:addItemStoreInboxEx(item, moveable, setOwner) +function Player:addItemStoreInboxEx(item, movable, setOwner) local inbox = self:getSlotItem(CONST_SLOT_STORE_INBOX) - if not moveable then + if not movable then item:setOwner(self) item:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime()) elseif setOwner then @@ -567,14 +567,14 @@ function Player:addItemStoreInboxEx(item, moveable, setOwner) return item end -function Player:addItemStoreInbox(itemId, amount, moveable, setOwner) +function Player:addItemStoreInbox(itemId, amount, movable, setOwner) local iType = ItemType(itemId) if not iType then return nil end if iType:isStackable() then while amount > iType:getStackSize() do - self:addItemStoreInboxEx(Game.createItem(itemId, iType:getStackSize()), moveable, setOwner) + self:addItemStoreInboxEx(Game.createItem(itemId, iType:getStackSize()), movable, setOwner) amount = amount - iType:getStackSize() end end @@ -582,7 +582,7 @@ function Player:addItemStoreInbox(itemId, amount, moveable, setOwner) if not item then return nil end - return self:addItemStoreInboxEx(item, moveable, setOwner) + return self:addItemStoreInboxEx(item, movable, setOwner) end ---@param monster Monster diff --git a/data/modules/scripts/gamestore/init.lua b/data/modules/scripts/gamestore/init.lua index d33485c7091..f3959c3a1e9 100644 --- a/data/modules/scripts/gamestore/init.lua +++ b/data/modules/scripts/gamestore/init.lua @@ -443,9 +443,9 @@ function parseBuyStoreOffer(playerId, msg) -- Handled errors have a code index and unhandled errors do not local pcallOk, pcallError = pcall(function() if offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM then - GameStore.processItemPurchase(player, offer.itemtype, offer.count, offer.moveable, offer.setOwner) + GameStore.processItemPurchase(player, offer.itemtype, offer.count, offer.movable, offer.setOwner) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_ITEM_UNIQUE then - GameStore.processItemPurchase(player, offer.itemtype, offer.count, offer.moveable, offer.setOwner) + GameStore.processItemPurchase(player, offer.itemtype, offer.count, offer.movable, offer.setOwner) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_POUCH then GameStore.processItemPurchase(player, offer.itemtype, offer.count) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS then @@ -459,7 +459,7 @@ function parseBuyStoreOffer(playerId, msg) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREMIUM then GameStore.processPremiumPurchase(player, offer.id) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_STACKABLE then - GameStore.processStackablePurchase(player, offer.itemtype, offer.count, offer.name, offer.moveable, offer.setOwner) + GameStore.processStackablePurchase(player, offer.itemtype, offer.count, offer.name, offer.movable, offer.setOwner) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HOUSE then GameStore.processHouseRelatedPurchase(player, offer) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_OUTFIT then @@ -482,7 +482,7 @@ function parseBuyStoreOffer(playerId, msg) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_TEMPLE then GameStore.processTempleTeleportPurchase(player) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_CHARGES then - GameStore.processChargesPurchase(player, offer.itemtype, offer.name, offer.charges, offer.moveable, offer.setOwner) + GameStore.processChargesPurchase(player, offer.itemtype, offer.name, offer.charges, offer.movable, offer.setOwner) elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HIRELING then local hirelingName = msg:getString() local sex = msg:getByte() @@ -1507,21 +1507,21 @@ end -- take a table {code = ..., message = ...} if the error is handled. When no code -- index is present the error is assumed to be unhandled. -function GameStore.processItemPurchase(player, offerId, offerCount, moveable, setOwner) +function GameStore.processItemPurchase(player, offerId, offerCount, movable, setOwner) if player:getFreeCapacity() < ItemType(offerId):getWeight(offerCount) then return error({ code = 0, message = "Please make sure you have free capacity to hold this item." }) end for t = 1, offerCount do - player:addItemStoreInbox(offerId, offerCount or 1, moveable, setOwner) + player:addItemStoreInbox(offerId, offerCount or 1, movable, setOwner) end end -function GameStore.processChargesPurchase(player, itemtype, name, charges, moveable, setOwner) +function GameStore.processChargesPurchase(player, itemtype, name, charges, movable, setOwner) if player:getFreeCapacity() < ItemType(itemtype):getWeight(1) then return error({ code = 0, message = "Please make sure you have free capacity to hold this item." }) end - player:addItemStoreInbox(itemtype, charges, moveable, setOwner) + player:addItemStoreInbox(itemtype, charges, movable, setOwner) end function GameStore.processSingleBlessingPurchase(player, blessId, count) @@ -1557,7 +1557,7 @@ function GameStore.processPremiumPurchase(player, offerId) end end -function GameStore.processStackablePurchase(player, offerId, offerCount, offerName, moveable, setOwner) +function GameStore.processStackablePurchase(player, offerId, offerCount, offerName, movable, setOwner) local function isKegItem(itemId) return itemId >= ITEM_KEG_START and itemId <= ITEM_KEG_END end diff --git a/data/npclib/npc_system/custom_modules.lua b/data/npclib/npc_system/custom_modules.lua index 10e16b956bd..f1438d39d64 100644 --- a/data/npclib/npc_system/custom_modules.lua +++ b/data/npclib/npc_system/custom_modules.lua @@ -137,7 +137,7 @@ local hints = { health points anymore, eat something.", [6] = "Always eat as much food as possible. This way, you'll regenerate health points for a longer period of time.", [7] = "After you have killed a monster, you have 10 seconds in which the corpse \z - is not moveable and no one else but you can loot it.", + is not movable and no one else but you can loot it.", [8] = "Be careful when you approach three or more monsters because you only can block the attacks of two. \z In such a situation even a few rats can do severe damage or even kill you.", [9] = "There are many ways to gather food. Many creatures drop food but you can also pick blueberries or bake \z diff --git a/data/scripts/discord_webhook/discord_webhook.lua b/data/scripts/discord_webhook/discord_webhook.lua index 756078c9f61..0aed824b278 100644 --- a/data/scripts/discord_webhook/discord_webhook.lua +++ b/data/scripts/discord_webhook/discord_webhook.lua @@ -14,7 +14,7 @@ announcementChannels = { local message = blablabla local title = test - Webhook.sendMessage(title, message, WEBHOOK_COLOR_WARNING, + Webhook.sendMessage(title, message, WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) Dev Comment: This lib can be used to add special webhook channels diff --git a/data/scripts/talkactions/gm/ban.lua b/data/scripts/talkactions/gm/ban.lua index 8a45a6c7d1b..8b46394a3e2 100644 --- a/data/scripts/talkactions/gm/ban.lua +++ b/data/scripts/talkactions/gm/ban.lua @@ -38,7 +38,7 @@ function ban.onSay(player, words, param) if target then local text = target:getName() .. " has been banned" player:sendTextMessage(MESSAGE_ADMINISTRADOR, text) - Webhook.sendMessage("Player Banned", text .. " reason: " .. reason .. ". (by: " .. player:getName() .. ")", WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage("Player Banned", text .. " reason: " .. reason .. ". (by: " .. player:getName() .. ")", WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) target:remove() else player:sendTextMessage(MESSAGE_ADMINISTRADOR, name .. " has been banned.") diff --git a/data/scripts/talkactions/gm/kick.lua b/data/scripts/talkactions/gm/kick.lua index fe7581b40e3..a7c67c5c941 100644 --- a/data/scripts/talkactions/gm/kick.lua +++ b/data/scripts/talkactions/gm/kick.lua @@ -15,7 +15,7 @@ function kick.onSay(player, words, param) return true end - Webhook.sendMessage("Player Kicked", target:getName() .. " has been kicked by " .. player:getName(), WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage("Player Kicked", target:getName() .. " has been kicked by " .. player:getName(), WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) target:remove() return true end diff --git a/data/scripts/talkactions/gm/push_town.lua b/data/scripts/talkactions/gm/push_town.lua index 7c2060839c3..cf32d148d20 100644 --- a/data/scripts/talkactions/gm/push_town.lua +++ b/data/scripts/talkactions/gm/push_town.lua @@ -18,7 +18,7 @@ function pushTown.onSay(player, words, param) targetPlayer:getPosition():sendMagicEffect(CONST_ME_HOLYAREA) local text = "Player " .. targetPlayer:getName() .. " has been teleported to temple by " .. player:getName() .. "." logger.info("[pushTown.onSay] - {}", text) - Webhook.sendMessage("Player Teleported", text, WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage("Player Teleported", text, WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) end return true end diff --git a/data/scripts/talkactions/gm/unban.lua b/data/scripts/talkactions/gm/unban.lua index d791d85b4e7..264335eeec7 100644 --- a/data/scripts/talkactions/gm/unban.lua +++ b/data/scripts/talkactions/gm/unban.lua @@ -19,7 +19,7 @@ function unban.onSay(player, words, param) Result.free(resultId) local text = param .. " has been unbanned." player:sendTextMessage(MESSAGE_ADMINISTRADOR, text) - Webhook.sendMessage("Player Unbanned", text .. " (by: " .. player:getName() .. ")", WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage("Player Unbanned", text .. " (by: " .. player:getName() .. ")", WEBHOOK_COLOR_YELLOW, announcementChannels["serverAnnouncements"]) return true end diff --git a/data/scripts/talkactions/god/close_server.lua b/data/scripts/talkactions/god/close_server.lua index a807b4f72a1..930cde5be79 100644 --- a/data/scripts/talkactions/god/close_server.lua +++ b/data/scripts/talkactions/god/close_server.lua @@ -6,7 +6,7 @@ function closeServer.onSay(player, words, param) if param == "shutdown" then Game.setGameState(GAME_STATE_SHUTDOWN) - Webhook.sendMessage("Server Shutdown", "Server was shutdown by: " .. player:getName(), WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage(":red_circle: Server was shutdown by: **" .. player:getName() .. "**", announcementChannels["serverAnnouncements"]) elseif param == "save" then if configManager.getBoolean(configKeys.GLOBAL_SERVER_SAVE_CLEAN_MAP) then cleanMap() @@ -17,15 +17,13 @@ function closeServer.onSay(player, words, param) if configManager.getBoolean(configKeys.GLOBAL_SERVER_SAVE_SHUTDOWN) then Game.setGameState(GAME_STATE_SHUTDOWN, true) end - -- Updating daily reward next server save. - UpdateDailyRewardGlobalStorage(DailyReward.storages.lastServerSave, os.time()) elseif param == "maintainance" then Game.setGameState(GAME_STATE_MAINTAIN) player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is set to maintenance mode.") else Game.setGameState(GAME_STATE_CLOSED) player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now closed.") - Webhook.sendMessage("Server Closed", "Server was closed by: " .. player:getName(), WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage(":yellow_square: Server was closed by: **" .. player:getName() .. "**", announcementChannels["serverAnnouncements"]) end return true end diff --git a/data/scripts/talkactions/god/open_server.lua b/data/scripts/talkactions/god/open_server.lua index f098d05bb99..84f0b4afe49 100644 --- a/data/scripts/talkactions/god/open_server.lua +++ b/data/scripts/talkactions/god/open_server.lua @@ -6,7 +6,7 @@ function openServer.onSay(player, words, param) Game.setGameState(GAME_STATE_NORMAL) player:sendTextMessage(MESSAGE_ADMINISTRADOR, "Server is now open.") - Webhook.sendMessage("Server Open", "Server was opened by: " .. player:getName(), WEBHOOK_COLOR_WARNING, announcementChannels["serverAnnouncements"]) + Webhook.sendMessage(":green_circle: Server was opened by: **" .. player:getName() .. "**", announcementChannels["serverAnnouncements"]) return true end diff --git a/src/canary_server.cpp b/src/canary_server.cpp index f60e0ab42f5..a3a27bfdef4 100644 --- a/src/canary_server.cpp +++ b/src/canary_server.cpp @@ -102,10 +102,10 @@ int CanaryServer::run() { if (g_configManager().getBoolean(TOGGLE_MAINTAIN_MODE, __FUNCTION__)) { g_game().setGameState(GAME_STATE_CLOSED); g_logger().warn("Initialized in maintain mode!"); - g_webhook().sendMessage("Server is now online", "The server is now online. Access is currently restricted to administrators only.", WEBHOOK_COLOR_ONLINE); + g_webhook().sendMessage(":yellow_square: Server is now **online** _(access restricted to staff)_"); } else { g_game().setGameState(GAME_STATE_NORMAL); - g_webhook().sendMessage("Server is now online", "Server has successfully started.", WEBHOOK_COLOR_ONLINE); + g_webhook().sendMessage(":green_circle: Server is now **online**"); } loaderStatus = LoaderStatus::LOADED; diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp index 920494fea9c..31aa4659e06 100644 --- a/src/config/config_definitions.hpp +++ b/src/config/config_definitions.hpp @@ -51,6 +51,7 @@ enum ConfigKey_t : uint16_t { DEPOT_BOXES, DISABLE_LEGACY_RAIDS, DISABLE_MONSTER_ARMOR, + DISCORD_SEND_FOOTER, DISCORD_WEBHOOK_DELAY_MS, DISCORD_WEBHOOK_URL, EMOTE_SPELLS, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index 090fcaf73e8..1afbc0295ae 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -152,6 +152,7 @@ bool ConfigManager::load() { loadStringConfig(L, WORLD_TYPE, "worldType", "pvp"); loadStringConfig(L, STORE_IMAGES_URL, "coinImagesURL", ""); loadStringConfig(L, DISCORD_WEBHOOK_URL, "discordWebhookURL", ""); + loadBoolConfig(L, DISCORD_SEND_FOOTER, "discordSendFooter", true); loadStringConfig(L, SAVE_INTERVAL_TYPE, "saveIntervalType", ""); loadStringConfig(L, GLOBAL_SERVER_SAVE_TIME, "globalServerSaveTime", "06:00"); loadStringConfig(L, DATA_DIRECTORY, "dataPackDirectory", "data-otservbr-global"); diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp index 35365a609dc..1e08ec3c024 100644 --- a/src/creatures/monsters/monster.cpp +++ b/src/creatures/monsters/monster.cpp @@ -552,11 +552,9 @@ bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAUL do { int32_t factionOffset = static_cast((*it)->getFaction()) * 100000; const auto dmg = damageMap.find((*it)->getID()); - if (dmg != damageMap.end()) { - if (dmg->second.total + factionOffset > mostDamage) { - mostDamage = dmg->second.total; - getTarget = *it; - } + if (dmg != damageMap.end() && dmg->second.total + factionOffset > mostDamage) { + mostDamage = dmg->second.total; + getTarget = *it; } } while (++it != resultList.end()); } @@ -1088,7 +1086,7 @@ void Monster::pushItems(std::shared_ptr tile, const Direction &nextDirecti auto it = items->begin(); while (it != items->end()) { std::shared_ptr item = *it; - if (item && item->hasProperty(CONST_PROP_MOVEABLE) && (item->hasProperty(CONST_PROP_BLOCKPATH) || item->hasProperty(CONST_PROP_BLOCKSOLID)) && item->canBeMoved()) { + if (item && item->hasProperty(CONST_PROP_MOVABLE) && (item->hasProperty(CONST_PROP_BLOCKPATH) || item->hasProperty(CONST_PROP_BLOCKSOLID)) && item->canBeMoved()) { if (moveCount < 20 && pushItem(item, nextDirection)) { ++moveCount; } else if (!item->isCorpse() && g_game().internalRemoveItem(item) == RETURNVALUE_NOERROR) { diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 867b32dbefb..0b5da33dc41 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -159,21 +159,21 @@ std::string Player::getDescription(int32_t lookDistance) { } } - if (party) { + if (m_party) { if (lookDistance == -1) { s << " Your party has "; } else { s << " " << subjectPronoun << " " << getSubjectVerb() << " in a party with "; } - size_t memberCount = party->getMemberCount() + 1; + size_t memberCount = m_party->getMemberCount() + 1; if (memberCount == 1) { s << "1 member and "; } else { s << memberCount << " members and "; } - size_t invitationCount = party->getInvitationCount(); + size_t invitationCount = m_party->getInvitationCount(); if (invitationCount == 1) { s << "1 pending invitation."; } else { @@ -844,7 +844,7 @@ uint16_t Player::getContainerIndex(uint8_t cid) const { } bool Player::canOpenCorpse(uint32_t ownerId) const { - return getID() == ownerId || (party && party->canOpenCorpse(ownerId)); + return getID() == ownerId || (m_party && m_party->canOpenCorpse(ownerId)); } uint16_t Player::getLookCorpse() const { @@ -1129,8 +1129,8 @@ void Player::sendLootStats(std::shared_ptr item, uint8_t count) { client->sendLootStats(item, count); } - if (party) { - party->addPlayerLoot(getPlayer(), item); + if (m_party) { + m_party->addPlayerLoot(getPlayer(), item); } } @@ -1282,8 +1282,8 @@ void Player::updateSupplyTracker(std::shared_ptr item) { client->sendUpdateSupplyTracker(item); } - if (party) { - party->addPlayerSupply(getPlayer(), item); + if (m_party) { + m_party->addPlayerSupply(getPlayer(), item); } } @@ -1776,8 +1776,8 @@ void Player::onRemoveCreature(std::shared_ptr creature, bool isLogout) if (auto player = getPlayer(); player == creature) { if (isLogout) { - if (party) { - party->leaveParty(player); + if (m_party) { + m_party->leaveParty(player); } if (guild) { guild->removeMember(player); @@ -1901,9 +1901,9 @@ void Player::onCreatureMove(const std::shared_ptr &creature, const std inMarket = false; } - if (party) { - party->updateSharedExperience(); - party->updatePlayerStatus(getPlayer(), oldPos, newPos); + if (m_party) { + m_party->updateSharedExperience(); + m_party->updatePlayerStatus(getPlayer(), oldPos, newPos); } if (teleport || oldPos.z != newPos.z) { @@ -2112,8 +2112,8 @@ void Player::onThink(uint32_t interval) { triggerMomentum(); auto playerTile = getTile(); const bool vipStaysOnline = isVip() && g_configManager().getBoolean(VIP_STAY_ONLINE, __FUNCTION__); + idleTime += interval; if (playerTile && !playerTile->hasFlag(TILESTATE_NOLOGOUT) && !isAccessPlayer() && !isExerciseTraining() && !vipStaysOnline) { - idleTime += interval; const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES, __FUNCTION__); if (idleTime > (kickAfterMinutes * 60000) + 60000) { removePlayer(true); @@ -2355,8 +2355,8 @@ void Player::addExperience(std::shared_ptr target, uint64_t exp, bool g_game().addCreatureHealth(static_self_cast()); g_game().addPlayerMana(static_self_cast()); - if (party) { - party->updateSharedExperience(); + if (m_party) { + m_party->updateSharedExperience(); } g_creatureEvents().playerAdvance(static_self_cast(), SKILL_LEVEL, prevLevel, level); @@ -2441,8 +2441,8 @@ void Player::removeExperience(uint64_t exp, bool sendText /* = false*/) { g_game().addCreatureHealth(static_self_cast()); g_game().addPlayerMana(static_self_cast()); - if (party) { - party->updateSharedExperience(); + if (m_party) { + m_party->updateSharedExperience(); } std::ostringstream ss; @@ -2483,6 +2483,7 @@ void Player::onBlockHit() { } void Player::onTakeDamage(std::shared_ptr attacker, int32_t damage) { + // nothing here yet } void Player::onAttackedCreatureBlockHit(BlockType_t blockType) { @@ -3378,8 +3379,8 @@ ReturnValue Player::queryRemove(const std::shared_ptr &thing, uint32_t co return RETURNVALUE_NOTPOSSIBLE; } - if (!item->isMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, flags)) { - return RETURNVALUE_NOTMOVEABLE; + if (!item->isMovable() && !hasBitSet(FLAG_IGNORENOTMOVABLE, flags)) { + return RETURNVALUE_NOTMOVABLE; } return RETURNVALUE_NOERROR; @@ -4581,8 +4582,8 @@ void Player::onAttacked() { void Player::onIdleStatus() { Creature::onIdleStatus(); - if (party) { - party->clearPlayerPoints(static_self_cast()); + if (m_party) { + m_party->clearPlayerPoints(static_self_cast()); } } @@ -4599,18 +4600,18 @@ void Player::onAttackedCreatureDrainHealth(std::shared_ptr target, int Creature::onAttackedCreatureDrainHealth(target, points); if (target) { - if (party && !Combat::isPlayerCombat(target)) { + if (m_party && !Combat::isPlayerCombat(target)) { auto tmpMonster = target->getMonster(); if (tmpMonster && tmpMonster->isHostile()) { // We have fulfilled a requirement for shared experience - party->updatePlayerTicks(static_self_cast(), points); + m_party->updatePlayerTicks(static_self_cast(), points); } } } } void Player::onTargetCreatureGainHealth(std::shared_ptr target, int32_t points) { - if (target && party) { + if (target && m_party) { std::shared_ptr tmpPlayer = nullptr; if (isPartner(tmpPlayer) && (tmpPlayer != getPlayer())) { @@ -4622,7 +4623,7 @@ void Player::onTargetCreatureGainHealth(std::shared_ptr target, int32_ } if (isPartner(tmpPlayer)) { - party->updatePlayerTicks(static_self_cast(), points); + m_party->updatePlayerTicks(static_self_cast(), points); } } } @@ -4723,8 +4724,8 @@ void Player::onGainExperience(uint64_t gainExp, std::shared_ptr target return; } - if (target && !target->getPlayer() && party && party->isSharedExperienceActive() && party->isSharedExperienceEnabled()) { - party->shareExperience(gainExp, target); + if (target && !target->getPlayer() && m_party && m_party->isSharedExperienceActive() && m_party->isSharedExperienceEnabled()) { + m_party->shareExperience(gainExp, target); // We will get a share of the experience through the sharing mechanism return; } @@ -5024,7 +5025,7 @@ Skulls_t Player::getSkullClient(std::shared_ptr creature) { return SKULL_YELLOW; } - if (party && party == player->party) { + if (m_party && m_party == player->m_party) { return SKULL_GREEN; } } @@ -5475,14 +5476,14 @@ PartyShields_t Player::getPartyShield(std::shared_ptr player) { return SHIELD_NONE; } - if (party) { - if (party->getLeader() == player) { - if (party->isSharedExperienceActive()) { - if (party->isSharedExperienceEnabled()) { + if (m_party) { + if (m_party->getLeader() == player) { + if (m_party->isSharedExperienceActive()) { + if (m_party->isSharedExperienceEnabled()) { return SHIELD_YELLOW_SHAREDEXP; } - if (party->canUseSharedExperience(player)) { + if (m_party->canUseSharedExperience(player)) { return SHIELD_YELLOW_NOSHAREDEXP; } @@ -5492,13 +5493,13 @@ PartyShields_t Player::getPartyShield(std::shared_ptr player) { return SHIELD_YELLOW; } - if (player->party == party) { - if (party->isSharedExperienceActive()) { - if (party->isSharedExperienceEnabled()) { + if (player->m_party == m_party) { + if (m_party->isSharedExperienceActive()) { + if (m_party->isSharedExperienceEnabled()) { return SHIELD_BLUE_SHAREDEXP; } - if (party->canUseSharedExperience(player)) { + if (m_party->canUseSharedExperience(player)) { return SHIELD_BLUE_NOSHAREDEXP; } @@ -5517,7 +5518,7 @@ PartyShields_t Player::getPartyShield(std::shared_ptr player) { return SHIELD_WHITEYELLOW; } - if (player->party) { + if (player->m_party) { return SHIELD_GRAY; } @@ -5525,17 +5526,17 @@ PartyShields_t Player::getPartyShield(std::shared_ptr player) { } bool Player::isInviting(std::shared_ptr player) const { - if (!player || !party || party->getLeader().get() != this) { + if (!player || !m_party || m_party->getLeader().get() != this) { return false; } - return party->isPlayerInvited(player); + return m_party->isPlayerInvited(player); } bool Player::isPartner(std::shared_ptr player) const { - if (!player || !party || player.get() == this) { + if (!player || !m_party || player.get() == this) { return false; } - return party == player->party; + return m_party == player->m_party; } bool Player::isGuildMate(std::shared_ptr player) const { @@ -5992,15 +5993,15 @@ void Player::clearModalWindows() { } uint16_t Player::getHelpers() const { - if (guild && party) { + if (guild && m_party) { const auto &guildMembers = guild->getMembersOnline(); stdext::vector_set> helperSet; helperSet.insert(helperSet.end(), guildMembers.begin(), guildMembers.end()); - helperSet.insertAll(party->getMembers()); - helperSet.insertAll(party->getInvitees()); + helperSet.insertAll(m_party->getMembers()); + helperSet.insertAll(m_party->getInvitees()); - helperSet.emplace(party->getLeader()); + helperSet.emplace(m_party->getLeader()); return static_cast(helperSet.size()); } @@ -6009,8 +6010,8 @@ uint16_t Player::getHelpers() const { return static_cast(guild->getMemberCountOnline()); } - if (party) { - return static_cast(party->getMemberCount() + party->getInvitationCount() + 1); + if (m_party) { + return static_cast(m_party->getMemberCount() + m_party->getInvitationCount() + 1); } return 0u; @@ -6913,6 +6914,12 @@ bool Player::saySpell( // Forge system void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool reduceTierLoss, uint8_t bonus, uint8_t coreCount) { + if (this->getFreeBackpackSlots() < 1) { + sendCancelMessage("You have no slots in your backpack."); + sendForgeError(RETURNVALUE_NOTENOUGHROOM); + return; + } + ForgeHistory history; history.actionType = ForgeConversion_t::FORGE_ACTION_FUSION; history.tier = tier; @@ -7121,6 +7128,12 @@ void Player::forgeFuseItems(uint16_t itemId, uint8_t tier, bool success, bool re } void Player::forgeTransferItemTier(uint16_t donorItemId, uint8_t tier, uint16_t receiveItemId) { + if (this->getFreeBackpackSlots() < 1) { + sendCancelMessage("You have no slots in your backpack."); + sendForgeError(RETURNVALUE_NOTENOUGHROOM); + return; + } + ForgeHistory history; history.actionType = ForgeConversion_t::FORGE_ACTION_TRANSFER; history.tier = tier; @@ -7644,15 +7657,15 @@ void Player::parseAttackRecvHazardSystem(CombatDamage &damage, std::shared_ptrgetMembers()) { + if (m_party) { + for (const auto partyMember : m_party->getMembers()) { if (partyMember && partyMember->getHazardSystemPoints() < points) { points = partyMember->getHazardSystemPoints(); } } - if (party->getLeader() && party->getLeader()->getHazardSystemPoints() < points) { - points = party->getLeader()->getHazardSystemPoints(); + if (m_party->getLeader() && m_party->getLeader()->getHazardSystemPoints() < points) { + points = m_party->getLeader()->getHazardSystemPoints(); } } @@ -7703,15 +7716,15 @@ void Player::parseAttackDealtHazardSystem(CombatDamage &damage, std::shared_ptr< } auto points = getHazardSystemPoints(); - if (party) { - for (const auto partyMember : party->getMembers()) { + if (m_party) { + for (const auto partyMember : m_party->getMembers()) { if (partyMember && partyMember->getHazardSystemPoints() < points) { points = partyMember->getHazardSystemPoints(); } } - if (party->getLeader() && party->getLeader()->getHazardSystemPoints() < points) { - points = party->getLeader()->getHazardSystemPoints(); + if (m_party->getLeader() && m_party->getLeader()->getHazardSystemPoints() < points) { + points = m_party->getLeader()->getHazardSystemPoints(); } } @@ -7733,7 +7746,7 @@ void Player::parseAttackDealtHazardSystem(CombatDamage &damage, std::shared_ptr< if (monster->getHazardSystemDefenseBoost()) { stage = points * static_cast(g_configManager().getNumber(HAZARD_DEFENSE_MULTIPLIER, __FUNCTION__)); if (stage != 0) { - damage.exString = "(hazard -" + std::to_string(stage / 100) + "%)"; + damage.exString = fmt::format("(hazard -{}%)", stage / 100.); damage.primary.value -= static_cast(std::ceil((static_cast(damage.primary.value) * stage) / 10000)); if (damage.secondary.value != 0) { damage.secondary.value -= static_cast(std::ceil((static_cast(damage.secondary.value) * stage) / 10000)); diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index d267f118049..9d7a555b050 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -362,10 +362,10 @@ class Player final : public Creature, public Cylinder, public Bankable { } void setParty(std::shared_ptr newParty) { - this->party = newParty; + m_party = newParty; } std::shared_ptr getParty() const { - return party; + return m_party; } int32_t getCleavePercent(bool useCharges = false) const; @@ -1821,8 +1821,8 @@ class Player final : public Creature, public Cylinder, public Bankable { } void updatePartyTrackerAnalyzer() const { - if (client && party) { - client->updatePartyTrackerAnalyzer(party); + if (client && m_party) { + client->updatePartyTrackerAnalyzer(m_party); } } @@ -2716,7 +2716,7 @@ class Player final : public Creature, public Cylinder, public Bankable { std::shared_ptr writeItem = nullptr; std::shared_ptr editHouse = nullptr; std::shared_ptr shopOwner = nullptr; - std::shared_ptr party = nullptr; + std::shared_ptr m_party = nullptr; std::shared_ptr tradePartner = nullptr; ProtocolGame_ptr client; std::shared_ptr walkTask; diff --git a/src/game/game.cpp b/src/game/game.cpp index 9d8d89315ce..4a573d31f94 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -503,7 +503,7 @@ std::shared_ptr Game::internalGetThing(std::shared_ptr player, co case STACKPOS_MOVE: { std::shared_ptr item = tile->getTopDownItem(); - if (item && item->isMoveable()) { + if (item && item->isMovable()) { thing = item; } else { thing = tile->getTopVisibleCreature(player); @@ -1185,7 +1185,7 @@ void Game::playerMoveCreature(std::shared_ptr player, std::shared_ptrisPushable() && !player->hasFlag(PlayerFlags_t::CanPushAllCreatures)) || (movingCreature->isInGhostMode() && !player->isAccessPlayer()))) { - player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); + player->sendCancelMessage(RETURNVALUE_NOTMOVABLE); return; } @@ -1447,7 +1447,7 @@ void Game::playerMoveItem(std::shared_ptr player, const Position &fromPo } if (!item->isPushable() || item->hasAttribute(ItemAttribute_t::UNIQUEID)) { - player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); + player->sendCancelMessage(RETURNVALUE_NOTMOVABLE); return; } @@ -2055,7 +2055,7 @@ ReturnValue Game::internalRemoveItem(std::shared_ptr item, int32_t count / if (count == -1) { count = item->getItemCount(); } - ReturnValue ret = cylinder->queryRemove(item, count, flags | FLAG_IGNORENOTMOVEABLE); + ReturnValue ret = cylinder->queryRemove(item, count, flags | FLAG_IGNORENOTMOVABLE); if (!force && ret != RETURNVALUE_NOERROR) { g_logger().debug("{} - Failed to execute query remove", __FUNCTION__); return ret; @@ -4425,7 +4425,7 @@ void Game::playerRequestTrade(uint32_t playerId, const Position &pos, uint8_t st if (std::shared_ptr houseTile = std::dynamic_pointer_cast(tradeItem->getTile())) { const auto &house = houseTile->getHouse(); if (house && tradeItem->getRealParent() != player && (!house->isInvited(player) || house->getHouseAccessLevel(player) == HOUSE_GUEST)) { - player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE); + player->sendCancelMessage(RETURNVALUE_NOTMOVABLE); return; } } @@ -7590,7 +7590,7 @@ void Game::dieSafely(std::string errorMsg /* = "" */) { } void Game::shutdown() { - g_webhook().sendMessage("Server is shutting down", "Shutting down...", WEBHOOK_COLOR_OFFLINE); + g_webhook().sendMessage(":red_circle: Server is shutting down..."); g_logger().info("Shutting down..."); map.spawnsMonster.clear(); @@ -9182,6 +9182,11 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con return; } + if (player->isUIExhausted()) { + player->sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED); + return; + } + if (g_configManager().getBoolean(ONLY_INVITED_CAN_MOVE_HOUSE_ITEMS, __FUNCTION__) && !InternalGame::playerCanUseItemOnHouseTile(player, item)) { player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); return; @@ -9195,8 +9200,8 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con const auto mType = g_monsters().getMonsterTypeByRaceId(static_cast(monsterRaceId), itemId == ITEM_PODIUM_OF_VIGOUR); if (!mType) { - player->sendCancelMessage(RETURNVALUE_CONTACTADMINISTRATOR); - g_logger().error("[{}] player {} is trying to add invalid monster to podium {}", __FUNCTION__, player->getName(), item->getName()); + player->sendCancelMessage(RETURNVALUE_NOTPOSSIBLE); + g_logger().debug("[{}] player {} is trying to add invalid monster to podium {}", __FUNCTION__, player->getName(), item->getName()); return; } @@ -9242,6 +9247,8 @@ void Game::playerSetMonsterPodium(uint32_t playerId, uint32_t monsterRaceId, con for (const auto &spectator : Spectators().find(pos, true)) { spectator->getPlayer()->sendUpdateTileItem(tile, pos, item); } + + player->updateUIExhausted(); } void Game::playerRotatePodium(uint32_t playerId, const Position &pos, uint8_t stackPos, const uint16_t itemId) { diff --git a/src/game/game_definitions.hpp b/src/game/game_definitions.hpp index 5abf8f4610a..17bc69dd514 100644 --- a/src/game/game_definitions.hpp +++ b/src/game/game_definitions.hpp @@ -104,10 +104,10 @@ enum HighscoreType_t : uint8_t { }; enum Webhook_Colors_t : uint32_t { - WEBHOOK_COLOR_ONLINE = 0x00FF00, - WEBHOOK_COLOR_OFFLINE = 0xFF0000, - WEBHOOK_COLOR_WARNING = 0xFFFF00, - WEBHOOK_COLOR_RAID = 0x0000FF + WEBHOOK_COLOR_GREEN = 0x00FF00, + WEBHOOK_COLOR_RED = 0xFF0000, + WEBHOOK_COLOR_YELLOW = 0xFFFF00, + WEBHOOK_COLOR_BLUE = 0x0000FF }; // Structs diff --git a/src/io/iomap.cpp b/src/io/iomap.cpp index f11e33204ce..457f3eed6bf 100644 --- a/src/io/iomap.cpp +++ b/src/io/iomap.cpp @@ -173,9 +173,9 @@ void IOMap::parseTileArea(FileStream &stream, Map &map, const Position &pos) { const auto item = std::make_shared(); item->id = id; - if (tile->isHouse() && iType.moveable) { + if (tile->isHouse() && iType.movable) { g_logger().warn("[IOMap::loadMap] - " - "Moveable item with ID: {}, in house: {}, " + "Movable item with ID: {}, in house: {}, " "at position: x {}, y {}, z {}", id, tile->houseId, x, y, z); } else if (iType.isGroundTile()) { @@ -207,9 +207,9 @@ void IOMap::parseTileArea(FileStream &stream, Map &map, const Position &pos) { if (tile->isHouse() && iType.isBed()) { // nothing - } else if (tile->isHouse() && iType.moveable) { + } else if (tile->isHouse() && iType.movable) { g_logger().warn("[IOMap::loadMap] - " - "Moveable item with ID: {}, in house: {}, " + "Movable item with ID: {}, in house: {}, " "at position: x {}, y {}, z {}", id, tile->houseId, x, y, z); } else if (iType.isGroundTile()) { diff --git a/src/io/iomapserialize.cpp b/src/io/iomapserialize.cpp index 7f351d2b617..ad1a59e67f6 100644 --- a/src/io/iomapserialize.cpp +++ b/src/io/iomapserialize.cpp @@ -138,14 +138,14 @@ bool IOMapSerialize::loadItem(PropStream &propStream, std::shared_ptr } const ItemType &iType = Item::items[id]; - if (iType.isBed() || iType.moveable || !tile || iType.isCarpet()) { + if (iType.isBed() || iType.movable || !tile || iType.isCarpet()) { // create a new item auto item = Item::CreateItem(id); if (item) { if (item->unserializeAttr(propStream)) { - // Remove only not moveable and not sleeper bed + // Remove only not movable and not sleeper bed auto bed = item->getBed(); - if (isHouseItem && iType.isBed() && bed && bed->getSleeper() == 0 && !iType.moveable) { + if (isHouseItem && iType.isBed() && bed && bed->getSleeper() == 0 && !iType.movable) { return false; } std::shared_ptr container = item->getContainer(); diff --git a/src/items/bed.cpp b/src/items/bed.cpp index 1b1a3a7266a..a1af00b2334 100644 --- a/src/items/bed.cpp +++ b/src/items/bed.cpp @@ -99,7 +99,7 @@ bool BedItem::canUse(std::shared_ptr player) { auto firstPart = keepFirstWordOnly(partName); auto nextPartOf = keepFirstWordOnly(nextPartname); g_logger().debug("First bed part name {}, second part name {}", firstPart, nextPartOf); - if (!isMoveable() || !nextBedItem->isMoveable() || firstPart != nextPartOf) { + if (!isMovable() || !nextBedItem->isMovable() || firstPart != nextPartOf) { return false; } diff --git a/src/items/containers/container.cpp b/src/items/containers/container.cpp index f5ad4cfab60..d4d55ba6cf1 100644 --- a/src/items/containers/container.cpp +++ b/src/items/containers/container.cpp @@ -44,7 +44,7 @@ std::shared_ptr Container::create(std::shared_ptr tile) { TileItemVector* itemVector = tile->getItemList(); if (itemVector) { for (auto &item : *itemVector) { - if (((item->getContainer() || item->hasProperty(CONST_PROP_MOVEABLE)) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) && !item->hasAttribute(ItemAttribute_t::UNIQUEID)) { + if (((item->getContainer() || item->hasProperty(CONST_PROP_MOVABLE)) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) && !item->hasAttribute(ItemAttribute_t::UNIQUEID)) { container->itemlist.push_front(item); item->setParent(container); } @@ -583,9 +583,9 @@ ReturnValue Container::queryRemove(const std::shared_ptr &thing, uint32_t return RETURNVALUE_NOTPOSSIBLE; } - if (!item->isMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, flags)) { - g_logger().debug("{} - Item is not moveable", __FUNCTION__); - return RETURNVALUE_NOTMOVEABLE; + if (!item->isMovable() && !hasBitSet(FLAG_IGNORENOTMOVABLE, flags)) { + g_logger().debug("{} - Item is not movable", __FUNCTION__); + return RETURNVALUE_NOTMOVABLE; } std::shared_ptr houseTile = std::dynamic_pointer_cast(getTopParent()); if (houseTile) { diff --git a/src/items/functions/item/item_parse.cpp b/src/items/functions/item/item_parse.cpp index 415aa5acb99..db0c73bdc36 100644 --- a/src/items/functions/item/item_parse.cpp +++ b/src/items/functions/item/item_parse.cpp @@ -26,7 +26,7 @@ void ItemParse::initParse(const std::string &tmpStrValue, pugi::xml_node attribu ItemParse::parseRotateTo(tmpStrValue, valueAttribute, itemType); ItemParse::parseWrapContainer(tmpStrValue, valueAttribute, itemType); ItemParse::parseWrapableTo(tmpStrValue, valueAttribute, itemType); - ItemParse::parseMoveable(tmpStrValue, valueAttribute, itemType); + ItemParse::parseMovable(tmpStrValue, valueAttribute, itemType); ItemParse::parseBlockProjectTile(tmpStrValue, valueAttribute, itemType); ItemParse::parsePickupable(tmpStrValue, valueAttribute, itemType); ItemParse::parseFloorChange(tmpStrValue, valueAttribute, itemType); @@ -196,10 +196,10 @@ void ItemParse::parseWrapableTo(const std::string &tmpStrValue, pugi::xml_attrib } } -void ItemParse::parseMoveable(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType) { +void ItemParse::parseMovable(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType) { std::string stringValue = tmpStrValue; - if (stringValue == "moveable") { - itemType.moveable = valueAttribute.as_bool(); + if (stringValue == "movable") { + itemType.movable = valueAttribute.as_bool(); } } diff --git a/src/items/functions/item/item_parse.hpp b/src/items/functions/item/item_parse.hpp index 2ebffc94266..f60277ad5d7 100644 --- a/src/items/functions/item/item_parse.hpp +++ b/src/items/functions/item/item_parse.hpp @@ -30,8 +30,8 @@ const phmap::flat_hash_map ItemParseAttribut { "wrapcontainer", ITEM_PARSE_WRAPCONTAINER }, { "wrapableto", ITEM_PARSE_WRAPABLETO }, { "unwrapableto", ITEM_PARSE_WRAPABLETO }, - { "moveable", ITEM_PARSE_MOVEABLE }, - { "movable", ITEM_PARSE_MOVEABLE }, + { "movable", ITEM_PARSE_MOVABLE }, + { "movable", ITEM_PARSE_MOVABLE }, { "blockprojectile", ITEM_PARSE_BLOCKPROJECTILE }, { "allowpickupable", ITEM_PARSE_PICKUPABLE }, { "pickupable", ITEM_PARSE_PICKUPABLE }, @@ -264,7 +264,7 @@ class ItemParse : public Items { static void parseRotateTo(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseWrapContainer(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseWrapableTo(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); - static void parseMoveable(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); + static void parseMovable(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseBlockProjectTile(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parsePickupable(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); static void parseFloorChange(const std::string &tmpStrValue, pugi::xml_attribute valueAttribute, ItemType &itemType); diff --git a/src/items/item.cpp b/src/items/item.cpp index 87a3abd7d63..2415c2a8d27 100644 --- a/src/items/item.cpp +++ b/src/items/item.cpp @@ -131,7 +131,7 @@ std::shared_ptr Item::CreateItemAsContainer(const uint16_t type, uint it.id == 0 || it.stackable || it.multiUse - || it.moveable + || it.movable || it.pickupable || it.isDepot() || it.isSplash() @@ -313,7 +313,7 @@ void Item::setID(uint16_t newid) { } } -bool Item::isOwner(uint32_t ownerId) { +bool Item::isOwner(uint32_t ownerId) const { if (getOwnerId() == ownerId) { return true; } @@ -850,7 +850,7 @@ void Item::serializeAttr(PropWriteStream &propWriteStream) const { propWriteStream.write(charges); } - if (it.moveable) { + if (it.movable) { if (auto actionId = getAttribute(ItemAttribute_t::ACTIONID)) { propWriteStream.write(ATTR_ACTION_ID); propWriteStream.write(actionId); @@ -996,25 +996,25 @@ void Item::serializeAttr(PropWriteStream &propWriteStream) const { } void Item::setOwner(std::shared_ptr owner) { - auto id = owner->getID(); + auto ownerId = owner->getID(); if (owner->getPlayer()) { - id = owner->getPlayer()->getGUID(); + ownerId = owner->getPlayer()->getGUID(); } - setOwner(id); + setOwner(ownerId); } -bool Item::isOwner(std::shared_ptr owner) { +bool Item::isOwner(std::shared_ptr owner) const { if (!owner) { return false; } - auto id = owner->getID(); - if (isOwner(id)) { + auto ownerId = owner->getID(); + if (isOwner(ownerId)) { return true; } if (owner->getPlayer()) { - id = owner->getPlayer()->getGUID(); + ownerId = owner->getPlayer()->getGUID(); } - return isOwner(id); + return isOwner(ownerId); } uint32_t Item::getOwnerId() const { @@ -1024,7 +1024,7 @@ uint32_t Item::getOwnerId() const { return 0; } -std::string Item::getOwnerName() { +std::string Item::getOwnerName() const { if (!hasOwner()) { return ""; } @@ -1044,7 +1044,7 @@ bool Item::hasProperty(ItemProperty prop) const { switch (prop) { case CONST_PROP_BLOCKSOLID: return it.blockSolid; - case CONST_PROP_MOVEABLE: + case CONST_PROP_MOVABLE: return canBeMoved(); case CONST_PROP_HASHEIGHT: return it.hasHeight; @@ -1081,7 +1081,7 @@ bool Item::canBeMoved() const { if (hasAttribute(ItemAttribute_t::ACTIONID) && immovableActionIds.contains(static_cast(getAttribute(ItemAttribute_t::ACTIONID)))) { return false; } - return isMoveable(); + return isMovable(); } void Item::checkDecayMapItemOnMove() { @@ -1904,7 +1904,7 @@ std::string Item::parseImbuementDescription(std::shared_ptr item) { bool Item::isSavedToHouses() { const auto &it = items[id]; - return it.moveable || it.isWrappable() || it.isCarpet() || getDoor() || (getContainer() && !getContainer()->empty()) || it.canWriteText || getBed() || it.m_transformOnUse; + return it.movable || it.isWrappable() || it.isCarpet() || getDoor() || (getContainer() && !getContainer()->empty()) || it.canWriteText || getBed() || it.m_transformOnUse; } SoundEffect_t Item::getMovementSound(std::shared_ptr toCylinder) const { diff --git a/src/items/item.hpp b/src/items/item.hpp index 956adad61cf..90f3c3d83ef 100644 --- a/src/items/item.hpp +++ b/src/items/item.hpp @@ -277,11 +277,11 @@ class Item : virtual public Thing, public ItemProperties, public SharedObject { virtual uint32_t getOwnerId() const; - bool isOwner(uint32_t ownerId); + bool isOwner(uint32_t ownerId) const; - std::string getOwnerName(); + std::string getOwnerName() const; - bool isOwner(std::shared_ptr owner); + bool isOwner(std::shared_ptr owner) const; bool hasOwner() const { return getOwnerId() != 0; @@ -314,7 +314,7 @@ class Item : virtual public Thing, public ItemProperties, public SharedObject { virtual void serializeAttr(PropWriteStream &propWriteStream) const; bool isPushable() override final { - return isMoveable(); + return isMovable(); } int32_t getThrowRange() const override final { return (isPickupable() ? 15 : 2); @@ -447,8 +447,8 @@ class Item : virtual public Thing, public ItemProperties, public SharedObject { bool isWrapContainer() const { return items[id].wrapContainer; } - bool isMoveable() const { - return items[id].moveable; + bool isMovable() const { + return items[id].movable; } bool isCorpse() const { return items[id].isCorpse; diff --git a/src/items/items.cpp b/src/items/items.cpp index 5b4a7419ee5..6c517c8a1ed 100644 --- a/src/items/items.cpp +++ b/src/items/items.cpp @@ -166,7 +166,7 @@ void Items::loadFromProtobuf() { iType.wrapable = true; } iType.multiUse = object.flags().multiuse(); - iType.moveable = object.flags().unmove() == false; + iType.movable = object.flags().unmove() == false; iType.canReadText = (object.flags().has_lenshelp() && object.flags().lenshelp().id() == 1112) || (object.flags().has_write() && object.flags().write().max_text_length() != 0) || (object.flags().has_write_once() && object.flags().write_once().max_text_length_once() != 0); iType.canReadText = object.flags().has_write() || object.flags().has_write_once(); iType.isVertical = object.flags().has_hook() && object.flags().hook().direction() == HOOK_TYPE_SOUTH; diff --git a/src/items/items.hpp b/src/items/items.hpp index 5320ec86ab5..b04e128fd7f 100644 --- a/src/items/items.hpp +++ b/src/items/items.hpp @@ -326,7 +326,7 @@ class ItemType { bool wrapable = false; bool wrapContainer = false; bool multiUse = false; - bool moveable = false; + bool movable = false; bool canReadText = false; bool canWriteText = false; bool isVertical = false; diff --git a/src/items/items_definitions.hpp b/src/items/items_definitions.hpp index 4e8fffd3a37..bd5c152d378 100644 --- a/src/items/items_definitions.hpp +++ b/src/items/items_definitions.hpp @@ -19,7 +19,7 @@ enum ItemProperty { CONST_PROP_BLOCKPATH, CONST_PROP_ISVERTICAL, CONST_PROP_ISHORIZONTAL, - CONST_PROP_MOVEABLE, + CONST_PROP_MOVABLE, CONST_PROP_IMMOVABLEBLOCKSOLID, CONST_PROP_IMMOVABLEBLOCKPATH, CONST_PROP_IMMOVABLENOFIELDBLOCKPATH, @@ -43,7 +43,7 @@ enum ReturnValue { RETURNVALUE_THEREISNOWAY, RETURNVALUE_DESTINATIONOUTOFREACH, RETURNVALUE_CREATUREBLOCK, - RETURNVALUE_NOTMOVEABLE, + RETURNVALUE_NOTMOVABLE, RETURNVALUE_DROPTWOHANDEDITEM, RETURNVALUE_BOTHHANDSNEEDTOBEFREE, RETURNVALUE_CANONLYUSEONEWEAPON, @@ -434,7 +434,7 @@ enum TileFlags_t : uint32_t { TILESTATE_IMMOVABLENOFIELDBLOCKPATH = 1 << 21, TILESTATE_NOFIELDBLOCKPATH = 1 << 22, TILESTATE_SUPPORTS_HANGABLE = 1 << 23, - TILESTATE_MOVEABLE = 1 << 24, + TILESTATE_MOVABLE = 1 << 24, TILESTATE_ISHORIZONTAL = 1 << 25, TILESTATE_ISVERTICAL = 1 << 26, TILESTATE_BLOCKPROJECTILE = 1 << 27, @@ -458,7 +458,7 @@ enum CylinderFlags_t { FLAG_CHILDISOWNER = 1 << 3, // Used by containers to query capacity of the carrier (player) FLAG_PATHFINDING = 1 << 4, // An additional check is done for floor changing/teleport items FLAG_IGNOREFIELDDAMAGE = 1 << 5, // Bypass field damage checks - FLAG_IGNORENOTMOVEABLE = 1 << 6, // Bypass check for mobility + FLAG_IGNORENOTMOVABLE = 1 << 6, // Bypass check for mobility FLAG_IGNOREAUTOSTACK = 1 << 7, // queryDestination will not try to stack items together }; @@ -483,7 +483,7 @@ enum ItemParseAttributes_t { ITEM_PARSE_WRAPCONTAINER, ITEM_PARSE_IMBUEMENT, ITEM_PARSE_WRAPABLETO, - ITEM_PARSE_MOVEABLE, + ITEM_PARSE_MOVABLE, ITEM_PARSE_BLOCKPROJECTILE, ITEM_PARSE_PICKUPABLE, ITEM_PARSE_FLOORCHANGE, diff --git a/src/items/tile.cpp b/src/items/tile.cpp index cc9d1160211..35264469171 100644 --- a/src/items/tile.cpp +++ b/src/items/tile.cpp @@ -39,8 +39,8 @@ bool Tile::hasProperty(ItemProperty prop) const { return hasFlag(TILESTATE_ISVERTICAL); case CONST_PROP_ISHORIZONTAL: return hasFlag(TILESTATE_ISHORIZONTAL); - case CONST_PROP_MOVEABLE: - return hasFlag(TILESTATE_MOVEABLE); + case CONST_PROP_MOVABLE: + return hasFlag(TILESTATE_MOVABLE); case CONST_PROP_IMMOVABLEBLOCKSOLID: return hasFlag(TILESTATE_IMMOVABLEBLOCKSOLID); case CONST_PROP_IMMOVABLEBLOCKPATH: @@ -357,7 +357,7 @@ std::shared_ptr Tile::getTopVisibleThing(std::shared_ptr creatu } void Tile::onAddTileItem(std::shared_ptr item) { - if ((item->hasProperty(CONST_PROP_MOVEABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { + if ((item->hasProperty(CONST_PROP_MOVABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { auto it = g_game().browseFields.find(static_self_cast()); if (it != g_game().browseFields.end()) { auto lockedCylinder = it->second.lock(); @@ -393,7 +393,7 @@ void Tile::onAddTileItem(std::shared_ptr item) { } } - if (item->isCarpet() && !item->isMoveable()) { + if (item->isCarpet() && !item->isMovable()) { if (getTopTopItem() && getTopTopItem()->canReceiveAutoCarpet()) { return; } @@ -430,7 +430,7 @@ void Tile::onAddTileItem(std::shared_ptr item) { } void Tile::onUpdateTileItem(std::shared_ptr oldItem, const ItemType &oldType, std::shared_ptr newItem, const ItemType &newType) { - if ((newItem->hasProperty(CONST_PROP_MOVEABLE) || newItem->getContainer()) || (newItem->isWrapable() && newItem->hasProperty(CONST_PROP_MOVEABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { + if ((newItem->hasProperty(CONST_PROP_MOVABLE) || newItem->getContainer()) || (newItem->isWrapable() && newItem->hasProperty(CONST_PROP_MOVABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { auto lockedCylinder = it->second.lock(); @@ -442,7 +442,7 @@ void Tile::onUpdateTileItem(std::shared_ptr oldItem, const ItemType &oldTy } } } - } else if ((oldItem->hasProperty(CONST_PROP_MOVEABLE) || oldItem->getContainer()) || (oldItem->isWrapable() && !oldItem->hasProperty(CONST_PROP_MOVEABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { + } else if ((oldItem->hasProperty(CONST_PROP_MOVABLE) || oldItem->getContainer()) || (oldItem->isWrapable() && !oldItem->hasProperty(CONST_PROP_MOVABLE) && !oldItem->hasProperty(CONST_PROP_BLOCKPATH))) { auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { auto lockedCylinder = it->second.lock(); @@ -472,7 +472,7 @@ void Tile::onUpdateTileItem(std::shared_ptr oldItem, const ItemType &oldTy } void Tile::onRemoveTileItem(const CreatureVector &spectators, const std::vector &oldStackPosVector, std::shared_ptr item) { - if ((item->hasProperty(CONST_PROP_MOVEABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVEABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { + if ((item->hasProperty(CONST_PROP_MOVABLE) || item->getContainer()) || (item->isWrapable() && !item->hasProperty(CONST_PROP_MOVABLE) && !item->hasProperty(CONST_PROP_BLOCKPATH))) { auto it = g_game().browseFields.find(getTile()); if (it != g_game().browseFields.end()) { auto lockedCylinder = it->second.lock(); @@ -523,7 +523,7 @@ void Tile::onRemoveTileItem(const CreatureVector &spectators, const std::vector< } } - if (item->isCarpet() && !item->isMoveable()) { + if (item->isCarpet() && !item->isMovable()) { if (getTopTopItem() && getTopTopItem()->canReceiveAutoCarpet()) { return; } @@ -739,7 +739,7 @@ ReturnValue Tile::queryAdd(int32_t, const std::shared_ptr &thing, uint32_ // FLAG_IGNOREBLOCKITEM is set if (ground) { const ItemType &iiType = Item::items[ground->getID()]; - if (iiType.blockSolid && (!iiType.moveable || ground->hasAttribute(ItemAttribute_t::UNIQUEID))) { + if (iiType.blockSolid && (!iiType.movable || ground->hasAttribute(ItemAttribute_t::UNIQUEID))) { return RETURNVALUE_NOTPOSSIBLE; } } @@ -747,7 +747,7 @@ ReturnValue Tile::queryAdd(int32_t, const std::shared_ptr &thing, uint32_ if (const auto items = getItemList()) { for (auto &item : *items) { const ItemType &iiType = Item::items[item->getID()]; - if (iiType.blockSolid && (!iiType.moveable || item->hasAttribute(ItemAttribute_t::UNIQUEID))) { + if (iiType.blockSolid && (!iiType.movable || item->hasAttribute(ItemAttribute_t::UNIQUEID))) { return RETURNVALUE_NOTPOSSIBLE; } } @@ -854,8 +854,8 @@ ReturnValue Tile::queryRemove(const std::shared_ptr &thing, uint32_t coun return RETURNVALUE_NOTPOSSIBLE; } - if (!item->isMoveable() && !hasBitSet(FLAG_IGNORENOTMOVEABLE, tileFlags)) { - return RETURNVALUE_NOTMOVEABLE; + if (!item->isMovable() && !hasBitSet(FLAG_IGNORENOTMOVABLE, tileFlags)) { + return RETURNVALUE_NOTMOVABLE; } return RETURNVALUE_NOERROR; @@ -1684,8 +1684,8 @@ void Tile::setTileFlags(const std::shared_ptr &item) { setFlag(TILESTATE_IMMOVABLEBLOCKPATH); } - if (item->hasProperty(CONST_PROP_MOVEABLE)) { - setFlag(TILESTATE_MOVEABLE); + if (item->hasProperty(CONST_PROP_MOVABLE)) { + setFlag(TILESTATE_MOVABLE); } if (item->hasProperty(CONST_PROP_ISHORIZONTAL)) { @@ -1745,8 +1745,8 @@ void Tile::resetTileFlags(const std::shared_ptr &item) { resetFlag(TILESTATE_IMMOVABLENOFIELDBLOCKPATH); } - if (item->hasProperty(CONST_PROP_MOVEABLE) && !hasProperty(item, CONST_PROP_MOVEABLE)) { - resetFlag(TILESTATE_MOVEABLE); + if (item->hasProperty(CONST_PROP_MOVABLE) && !hasProperty(item, CONST_PROP_MOVABLE)) { + resetFlag(TILESTATE_MOVABLE); } if (item->hasProperty(CONST_PROP_ISHORIZONTAL) && !hasProperty(item, CONST_PROP_ISHORIZONTAL)) { @@ -1796,7 +1796,7 @@ void Tile::resetTileFlags(const std::shared_ptr &item) { } } -bool Tile::isMoveableBlocking() const { +bool Tile::isMovableBlocking() const { return !ground || hasFlag(TILESTATE_BLOCKSOLID); } diff --git a/src/items/tile.hpp b/src/items/tile.hpp index 2493974c950..83f0350f9aa 100644 --- a/src/items/tile.hpp +++ b/src/items/tile.hpp @@ -132,7 +132,7 @@ class Tile : public Cylinder, public SharedObject { return static_self_cast(); } - std::shared_ptr getCylinder() override final { + std::shared_ptr getCylinder() final { return getTile(); } @@ -149,7 +149,7 @@ class Tile : public Cylinder, public SharedObject { std::shared_ptr getBottomVisibleCreature(std::shared_ptr creature) const; std::shared_ptr getTopTopItem() const; std::shared_ptr getTopDownItem() const; - bool isMoveableBlocking() const; + bool isMovableBlocking() const; std::shared_ptr getTopVisibleThing(std::shared_ptr creature); std::shared_ptr getItemByTopOrder(int32_t topOrder); diff --git a/src/items/trashholder.cpp b/src/items/trashholder.cpp index 835558d6244..40c1f0e49b4 100644 --- a/src/items/trashholder.cpp +++ b/src/items/trashholder.cpp @@ -50,7 +50,7 @@ void TrashHolder::addThing(int32_t, std::shared_ptr thing) { return; } - if (item.get() == this || !item->hasProperty(CONST_PROP_MOVEABLE)) { + if (item.get() == this || !item->hasProperty(CONST_PROP_MOVABLE)) { return; } diff --git a/src/lua/creature/raids.cpp b/src/lua/creature/raids.cpp index 3251f744e4f..f30155578b3 100644 --- a/src/lua/creature/raids.cpp +++ b/src/lua/creature/raids.cpp @@ -319,7 +319,7 @@ bool AnnounceEvent::configureRaidEvent(const pugi::xml_node &eventNode) { bool AnnounceEvent::executeEvent() { g_game().broadcastMessage(message, messageType); - g_webhook().sendMessage("Incoming raid!", message, WEBHOOK_COLOR_RAID); + g_webhook().sendMessage(fmt::format(":space_invader: {}", message)); return true; } @@ -540,7 +540,7 @@ bool AreaSpawnEvent::executeEvent() { bool success = false; for (int32_t tries = 0; tries < MAXIMUM_TRIES_PER_MONSTER; tries++) { std::shared_ptr tile = g_game().map.getTile(static_cast(uniform_random(fromPos.x, toPos.x)), static_cast(uniform_random(fromPos.y, toPos.y)), static_cast(uniform_random(fromPos.z, toPos.z))); - if (tile && !tile->isMoveableBlocking() && !tile->hasFlag(TILESTATE_PROTECTIONZONE) && tile->getTopCreature() == nullptr && g_game().placeCreature(monster, tile->getPosition(), false, true)) { + if (tile && !tile->isMovableBlocking() && !tile->hasFlag(TILESTATE_PROTECTIONZONE) && tile->getTopCreature() == nullptr && g_game().placeCreature(monster, tile->getPosition(), false, true)) { success = true; monster->setForgeMonster(false); break; diff --git a/src/lua/functions/core/game/global_functions.cpp b/src/lua/functions/core/game/global_functions.cpp index e2961e26215..2bf9549ff97 100644 --- a/src/lua/functions/core/game/global_functions.cpp +++ b/src/lua/functions/core/game/global_functions.cpp @@ -124,8 +124,8 @@ int GlobalFunctions::luaIsDepot(lua_State* L) { return 1; } -int GlobalFunctions::luaIsMoveable(lua_State* L) { - // isMoveable(uid) +int GlobalFunctions::luaIsMovable(lua_State* L) { + // isMovable(uid) // isMovable(uid) std::shared_ptr thing = getScriptEnv()->getThingByUID(getNumber(L, -1)); pushBoolean(L, thing && thing->isPushable()); diff --git a/src/lua/functions/core/game/global_functions.hpp b/src/lua/functions/core/game/global_functions.hpp index 3d83e03aa14..6ccb6c45d9d 100644 --- a/src/lua/functions/core/game/global_functions.hpp +++ b/src/lua/functions/core/game/global_functions.hpp @@ -37,7 +37,7 @@ class GlobalFunctions final : LuaScriptInterface { lua_register(L, "getWorldUpTime", GlobalFunctions::luaGetWorldUpTime); lua_register(L, "isDepot", GlobalFunctions::luaIsDepot); lua_register(L, "isInWar", GlobalFunctions::luaIsInWar); - lua_register(L, "isMovable", GlobalFunctions::luaIsMoveable); + lua_register(L, "isMovable", GlobalFunctions::luaIsMovable); lua_register(L, "isValidUID", GlobalFunctions::luaIsValidUID); lua_register(L, "saveServer", GlobalFunctions::luaSaveServer); lua_register(L, "sendChannelMessage", GlobalFunctions::luaSendChannelMessage); @@ -78,7 +78,7 @@ class GlobalFunctions final : LuaScriptInterface { static int luaGetWorldUpTime(lua_State* L); static int luaIsDepot(lua_State* L); static int luaIsInWar(lua_State* L); - static int luaIsMoveable(lua_State* L); + static int luaIsMovable(lua_State* L); static int luaIsValidUID(lua_State* L); static int luaSaveServer(lua_State* L); static int luaSendChannelMessage(lua_State* L); diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp index 306283b0b6e..6391cdffb2e 100644 --- a/src/lua/functions/core/game/lua_enums.cpp +++ b/src/lua/functions/core/game/lua_enums.cpp @@ -137,7 +137,7 @@ void LuaEnums::initOthersEnums(lua_State* L) { registerEnum(L, FLAG_CHILDISOWNER); registerEnum(L, FLAG_PATHFINDING); registerEnum(L, FLAG_IGNOREFIELDDAMAGE); - registerEnum(L, FLAG_IGNORENOTMOVEABLE); + registerEnum(L, FLAG_IGNORENOTMOVABLE); registerEnum(L, FLAG_IGNOREAUTOSTACK); // Use with house:getAccessList, house:setAccessList @@ -687,7 +687,7 @@ void LuaEnums::initConstPropEnums(lua_State* L) { registerEnum(L, CONST_PROP_BLOCKPATH); registerEnum(L, CONST_PROP_ISVERTICAL); registerEnum(L, CONST_PROP_ISHORIZONTAL); - registerEnum(L, CONST_PROP_MOVEABLE); + registerEnum(L, CONST_PROP_MOVABLE); registerEnum(L, CONST_PROP_IMMOVABLEBLOCKSOLID); registerEnum(L, CONST_PROP_IMMOVABLEBLOCKPATH); registerEnum(L, CONST_PROP_IMMOVABLENOFIELDBLOCKPATH); @@ -1130,7 +1130,7 @@ void LuaEnums::initReturnValueEnums(lua_State* L) { registerEnum(L, RETURNVALUE_THEREISNOWAY); registerEnum(L, RETURNVALUE_DESTINATIONOUTOFREACH); registerEnum(L, RETURNVALUE_CREATUREBLOCK); - registerEnum(L, RETURNVALUE_NOTMOVEABLE); + registerEnum(L, RETURNVALUE_NOTMOVABLE); registerEnum(L, RETURNVALUE_DROPTWOHANDEDITEM); registerEnum(L, RETURNVALUE_BOTHHANDSNEEDTOBEFREE); registerEnum(L, RETURNVALUE_CANONLYUSEONEWEAPON); @@ -1239,10 +1239,10 @@ void LuaEnums::initForgeEnums(lua_State* L) { // Webhook default colors void LuaEnums::initWebhookEnums(lua_State* L) { - registerEnum(L, WEBHOOK_COLOR_ONLINE); - registerEnum(L, WEBHOOK_COLOR_OFFLINE); - registerEnum(L, WEBHOOK_COLOR_WARNING); - registerEnum(L, WEBHOOK_COLOR_RAID); + registerEnum(L, WEBHOOK_COLOR_GREEN); + registerEnum(L, WEBHOOK_COLOR_RED); + registerEnum(L, WEBHOOK_COLOR_YELLOW); + registerEnum(L, WEBHOOK_COLOR_BLUE); } void LuaEnums::initBosstiaryEnums(lua_State* L) { diff --git a/src/lua/functions/core/network/webhook_functions.cpp b/src/lua/functions/core/network/webhook_functions.cpp index 7c649ce4369..43e1935d903 100644 --- a/src/lua/functions/core/network/webhook_functions.cpp +++ b/src/lua/functions/core/network/webhook_functions.cpp @@ -13,13 +13,19 @@ #include "server/network/webhook/webhook.hpp" int WebhookFunctions::luaWebhookSendMessage(lua_State* L) { - // Webhook.sendMessage(title, message, color, url = "WEBHOOK_DISCORD_URL") + // Webhook.sendMessage(title, message, color, url = "WEBHOOK_DISCORD_URL") | + // Webhook.sendMessage(message, url = "WEBHOOK_DISCORD_URL") std::string title = getString(L, 1); std::string message = getString(L, 2); uint32_t color = getNumber(L, 3, 0); - std::string url = getString(L, 4); - - g_webhook().sendMessage(title, message, color, url); + std::string url = getString(L, -1); + if (url == title) { + g_webhook().sendMessage(title); + } else if (url == message) { + g_webhook().sendMessage(title, url); + } else { + g_webhook().sendMessage(title, message, color, url); + } lua_pushnil(L); return 1; diff --git a/src/lua/functions/events/action_functions.cpp b/src/lua/functions/events/action_functions.cpp index f31b74618e9..e0e746d4149 100644 --- a/src/lua/functions/events/action_functions.cpp +++ b/src/lua/functions/events/action_functions.cpp @@ -166,8 +166,8 @@ int ActionFunctions::luaActionPosition(lua_State* L) { // If it is an item that can be removed, then it will be set as non-movable. ItemType &itemType = Item::items.getItemType(itemId); - if (itemType.moveable == true) { - itemType.moveable = false; + if (itemType.movable == true) { + itemType.movable = false; } g_game().setCreateLuaItems(position, itemId); diff --git a/src/lua/functions/items/item_functions.cpp b/src/lua/functions/items/item_functions.cpp index c8b7f26ed75..3e9190055c4 100644 --- a/src/lua/functions/items/item_functions.cpp +++ b/src/lua/functions/items/item_functions.cpp @@ -626,7 +626,7 @@ int ItemFunctions::luaItemMoveTo(lua_State* L) { return 1; } - uint32_t flags = getNumber(L, 3, FLAG_NOLIMIT | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE | FLAG_IGNORENOTMOVEABLE); + uint32_t flags = getNumber(L, 3, FLAG_NOLIMIT | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE | FLAG_IGNORENOTMOVABLE); if (item->getParent() == VirtualCylinder::virtualCylinder) { pushBoolean(L, g_game().internalAddItem(toCylinder, item, INDEX_WHEREEVER, flags) == RETURNVALUE_NOERROR); diff --git a/src/lua/functions/items/item_type_functions.cpp b/src/lua/functions/items/item_type_functions.cpp index 81711978c88..4ff757b3dcd 100644 --- a/src/lua/functions/items/item_type_functions.cpp +++ b/src/lua/functions/items/item_type_functions.cpp @@ -76,7 +76,7 @@ int ItemTypeFunctions::luaItemTypeIsMovable(lua_State* L) { // itemType:isMovable() const ItemType* itemType = getUserdata(L, 1); if (itemType) { - pushBoolean(L, itemType->moveable); + pushBoolean(L, itemType->movable); } else { lua_pushnil(L); } diff --git a/src/map/house/housetile.cpp b/src/map/house/housetile.cpp index 386b06a0873..3ed661a1c12 100644 --- a/src/map/house/housetile.cpp +++ b/src/map/house/housetile.cpp @@ -125,7 +125,7 @@ ReturnValue HouseTile::queryRemove(const std::shared_ptr &thing, uint32_t if (house && !house->isInvited(actorPlayer)) { return RETURNVALUE_NOTPOSSIBLE; } else if (house && house->getHouseAccessLevel(actorPlayer) == HOUSE_GUEST) { - return RETURNVALUE_NOTMOVEABLE; + return RETURNVALUE_NOTMOVABLE; } } return Tile::queryRemove(thing, count, flags); diff --git a/src/server/network/webhook/webhook.cpp b/src/server/network/webhook/webhook.cpp index b761210ccdb..a157a3e0c7b 100644 --- a/src/server/network/webhook/webhook.cpp +++ b/src/server/network/webhook/webhook.cpp @@ -43,12 +43,12 @@ void Webhook::run() { ); } -void Webhook::sendMessage(const std::string payload, std::string url) { +void Webhook::sendPayload(const std::string &payload, std::string url) { std::scoped_lock lock { taskLock }; webhooks.push_back(std::make_shared(payload, url)); } -void Webhook::sendMessage(const std::string title, const std::string message, int color, std::string url) { +void Webhook::sendMessage(const std::string &title, const std::string &message, int color, std::string url, bool embed) { if (url.empty()) { url = g_configManager().getString(DISCORD_WEBHOOK_URL, __FUNCTION__); } @@ -57,7 +57,19 @@ void Webhook::sendMessage(const std::string title, const std::string message, in return; } - sendMessage(getPayload(title, message, color), url); + sendPayload(getPayload(title, message, color, embed), url); +} + +void Webhook::sendMessage(const std::string &message, std::string url) { + if (url.empty()) { + url = g_configManager().getString(DISCORD_WEBHOOK_URL, __FUNCTION__); + } + + if (url.empty() || message.empty()) { + return; + } + + sendPayload(getPayload("", message, -1, false), url); } int Webhook::sendRequest(const char* url, const char* payload, std::string* response_body) const { @@ -100,7 +112,7 @@ size_t Webhook::writeCallback(void* contents, size_t size, size_t nmemb, void* u return real_size; } -std::string Webhook::getPayload(const std::string title, const std::string message, int color) const { +std::string Webhook::getPayload(const std::string &title, const std::string &message, int color, bool embed) const { std::time_t now = getTimeNow(); std::string time_buf = formatDate(now); @@ -110,14 +122,22 @@ std::string Webhook::getPayload(const std::string title, const std::string messa << time_buf; std::stringstream payload; - payload << "{ \"embeds\": [{ "; - payload << "\"title\": \"" << title << "\", "; - payload << "\"description\": \"" << message << "\", "; - payload << "\"footer\": { \"text\": \"" << footer_text.str() << "\" }, "; - if (color >= 0) { - payload << "\"color\": " << color; + if (embed) { + payload << "{ \"embeds\": [{ "; + payload << "\"title\": \"" << title << "\", "; + if (!message.empty()) { + payload << "\"description\": \"" << message << "\", "; + } + if (g_configManager().getBoolean(DISCORD_SEND_FOOTER, __FUNCTION__)) { + payload << "\"footer\": { \"text\": \"" << footer_text.str() << "\" }, "; + } + if (color >= 0) { + payload << "\"color\": " << color; + } + payload << " }] }"; + } else { + payload << "{ \"content\": \"" << (!message.empty() ? message : title) << "\" }"; } - payload << " }] }"; return payload.str(); } diff --git a/src/server/network/webhook/webhook.hpp b/src/server/network/webhook/webhook.hpp index e41e63c186f..df414f24e1d 100644 --- a/src/server/network/webhook/webhook.hpp +++ b/src/server/network/webhook/webhook.hpp @@ -30,8 +30,9 @@ class Webhook { void run(); - void sendMessage(const std::string payload, std::string url); - void sendMessage(const std::string title, const std::string message, int color, std::string url = ""); + void sendPayload(const std::string &payload, std::string url); + void sendMessage(const std::string &title, const std::string &message, int color, std::string url = "", bool embed = true); + void sendMessage(const std::string &message, std::string url = ""); private: std::mutex taskLock; @@ -43,7 +44,7 @@ class Webhook { int sendRequest(const char* url, const char* payload, std::string* response_body) const; static size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp); - std::string getPayload(const std::string title, const std::string message, int color) const; + std::string getPayload(const std::string &title, const std::string &message, int color, bool embed = true) const; }; constexpr auto g_webhook = Webhook::getInstance; diff --git a/src/utils/tools.cpp b/src/utils/tools.cpp index 150d1d2238c..56c76ac0418 100644 --- a/src/utils/tools.cpp +++ b/src/utils/tools.cpp @@ -1209,7 +1209,7 @@ const char* getReturnMessage(ReturnValue value) { case RETURNVALUE_DESTINATIONOUTOFREACH: return "Destination is out of reach."; - case RETURNVALUE_NOTMOVEABLE: + case RETURNVALUE_NOTMOVABLE: return "You cannot move this object."; case RETURNVALUE_DROPTWOHANDEDITEM: