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: