From 83ebce55a86dcd31ebd89c301822f8af0daa2d98 Mon Sep 17 00:00:00 2001 From: Karin Date: Sat, 1 Jun 2024 01:44:39 -0300 Subject: [PATCH 01/15] fix: checking if the item is container in playerBuyItem (#2672) --- src/game/game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index 621e3593816..899a89549d9 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -5165,7 +5165,7 @@ void Game::playerBuyItem(uint32_t playerId, uint16_t itemId, uint8_t count, uint return; } - if (inBackpacks) { + if (inBackpacks || it.isContainer()) { uint32_t maxContainer = static_cast(g_configManager().getNumber(MAX_CONTAINER, __FUNCTION__)); auto backpack = player->getInventoryItem(CONST_SLOT_BACKPACK); auto mainBackpack = backpack ? backpack->getContainer() : nullptr; From 7e7a6109f521e87bcd82296ee570fff62d7a66c1 Mon Sep 17 00:00:00 2001 From: Marco Date: Sat, 1 Jun 2024 14:41:18 -0300 Subject: [PATCH 02/15] refactor: experience calculation efficiency and increase level cap (#2631) --- data/scripts/talkactions/god/add_skill.lua | 7 +------ src/creatures/players/player.hpp | 5 ++--- src/lua/functions/core/game/game_functions.cpp | 11 +++++++++++ src/lua/functions/core/game/game_functions.hpp | 2 ++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/data/scripts/talkactions/god/add_skill.lua b/data/scripts/talkactions/god/add_skill.lua index 20644582325..09d240ece4d 100644 --- a/data/scripts/talkactions/god/add_skill.lua +++ b/data/scripts/talkactions/god/add_skill.lua @@ -16,11 +16,6 @@ local function getSkillId(skillName) end end -local function getExpForLevel(level) - level = level - 1 - return ((50 * level * level * level) - (150 * level * level) + (400 * level)) / 3 -end - local addSkill = TalkAction("/addskill") function addSkill.onSay(player, words, param) @@ -54,7 +49,7 @@ function addSkill.onSay(player, words, param) local ch = split[2]:sub(1, 1) if ch == "l" or ch == "e" then targetLevel = target:getLevel() + count - targetExp = getExpForLevel(targetLevel) + targetExp = Game.getExperienceForLevel(targetLevel) addExp = targetExp - target:getExperience() target:addExperience(addExp, false) elseif ch == "m" then diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 58bebfb9f2f..c0761704db4 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -230,9 +230,8 @@ class Player final : public Creature, public Cylinder, public Bankable { void addList() override; void removePlayer(bool displayEffect, bool forced = true); - static uint64_t getExpForLevel(int32_t lv) { - lv--; - return ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL; + static uint64_t getExpForLevel(const uint32_t level) { + return (((level - 6ULL) * level + 17ULL) * level - 12ULL) / 6ULL * 100ULL; } uint16_t getStaminaMinutes() const { diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp index 0fdbc96f4d6..4858b3ab264 100644 --- a/src/lua/functions/core/game/game_functions.cpp +++ b/src/lua/functions/core/game/game_functions.cpp @@ -191,6 +191,17 @@ int GameFunctions::luaGameloadMapChunk(lua_State* L) { return 0; } +int GameFunctions::luaGameGetExperienceForLevel(lua_State* L) { + // Game.getExperienceForLevel(level) + const uint32_t level = getNumber(L, 1); + if (level == 0) { + reportErrorFunc("Level must be greater than 0."); + } else { + lua_pushnumber(L, Player::getExpForLevel(level)); + } + return 1; +} + int GameFunctions::luaGameGetMonsterCount(lua_State* L) { // Game.getMonsterCount() lua_pushnumber(L, g_game().getMonstersOnline()); diff --git a/src/lua/functions/core/game/game_functions.hpp b/src/lua/functions/core/game/game_functions.hpp index 7f3b642e97d..70e81061c9c 100644 --- a/src/lua/functions/core/game/game_functions.hpp +++ b/src/lua/functions/core/game/game_functions.hpp @@ -28,6 +28,7 @@ class GameFunctions final : LuaScriptInterface { registerMethod(L, "Game", "loadMap", GameFunctions::luaGameLoadMap); registerMethod(L, "Game", "loadMapChunk", GameFunctions::luaGameloadMapChunk); + registerMethod(L, "Game", "getExperienceForLevel", GameFunctions::luaGameGetExperienceForLevel); registerMethod(L, "Game", "getMonsterCount", GameFunctions::luaGameGetMonsterCount); registerMethod(L, "Game", "getPlayerCount", GameFunctions::luaGameGetPlayerCount); registerMethod(L, "Game", "getNpcCount", GameFunctions::luaGameGetNpcCount); @@ -103,6 +104,7 @@ class GameFunctions final : LuaScriptInterface { static int luaGameLoadMap(lua_State* L); static int luaGameloadMapChunk(lua_State* L); + static int luaGameGetExperienceForLevel(lua_State* L); static int luaGameGetMonsterCount(lua_State* L); static int luaGameGetPlayerCount(lua_State* L); static int luaGameGetNpcCount(lua_State* L); From 3b90a6970a7d91c8c58e1faf49a8af40f35a6835 Mon Sep 17 00:00:00 2001 From: Leandro Date: Sat, 1 Jun 2024 15:32:11 -0300 Subject: [PATCH 03/15] feat: place monster spawn with default time if not set correctly (#2671) --- config.lua.dist | 1 + src/config/config_enums.hpp | 1 + src/config/configmanager.cpp | 1 + src/creatures/monsters/spawns/spawn_monster.cpp | 10 +++++++++- 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/config.lua.dist b/config.lua.dist index 447a90647c2..9d1ed2fa681 100644 --- a/config.lua.dist +++ b/config.lua.dist @@ -511,6 +511,7 @@ bossDefaultTimeToFightAgain = 20 * 60 * 60 -- 20 hours bossDefaultTimeToDefeat = 20 * 60 -- 20 minutes -- Monsters +defaultRespawnTime = 60 deSpawnRange = 2 deSpawnRadius = 50 diff --git a/src/config/config_enums.hpp b/src/config/config_enums.hpp index 22043f42525..0e53c97546e 100644 --- a/src/config/config_enums.hpp +++ b/src/config/config_enums.hpp @@ -50,6 +50,7 @@ enum ConfigKey_t : uint16_t { DATA_DIRECTORY, DAY_KILLS_TO_RED, DEATH_LOSE_PERCENT, + DEFAULT_RESPAWN_TIME, DEFAULT_DESPAWNRADIUS, DEFAULT_DESPAWNRANGE, DEFAULT_PRIORITY, diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp index e1345bbac4b..35d2cf3b1be 100644 --- a/src/config/configmanager.cpp +++ b/src/config/configmanager.cpp @@ -225,6 +225,7 @@ bool ConfigManager::load() { loadIntConfig(L, CRITICALCHANCE, "criticalChance", 10); loadIntConfig(L, DAY_KILLS_TO_RED, "dayKillsToRedSkull", 3); loadIntConfig(L, DEATH_LOSE_PERCENT, "deathLosePercent", -1); + loadIntConfig(L, DEFAULT_RESPAWN_TIME, "defaultRespawnTime", 60); loadIntConfig(L, DEFAULT_DESPAWNRADIUS, "deSpawnRadius", 50); loadIntConfig(L, DEFAULT_DESPAWNRANGE, "deSpawnRange", 2); loadIntConfig(L, DEPOTCHEST, "depotChest", 4); diff --git a/src/creatures/monsters/spawns/spawn_monster.cpp b/src/creatures/monsters/spawns/spawn_monster.cpp index ef5912c8052..968b90d8cae 100644 --- a/src/creatures/monsters/spawns/spawn_monster.cpp +++ b/src/creatures/monsters/spawns/spawn_monster.cpp @@ -94,7 +94,15 @@ bool SpawnsMonster::loadFromXML(const std::string &filemonstername) { weight = pugi::cast(weightAttribute.value()); } - spawnMonster.addMonster(nameAttribute.as_string(), pos, dir, pugi::cast(childMonsterNode.attribute("spawntime").value()) * 1000, weight); + uint32_t scheduleInterval = g_configManager().getNumber(DEFAULT_RESPAWN_TIME, __FUNCTION__); + + try { + scheduleInterval = pugi::cast(childMonsterNode.attribute("spawntime").value()); + } catch (...) { + g_logger().warn("Failed to add schedule interval to monster: {}, interval: {}. Setting to default respawn time: {}", nameAttribute.value(), childMonsterNode.attribute("spawntime").value(), scheduleInterval); + } + + spawnMonster.addMonster(nameAttribute.as_string(), pos, dir, scheduleInterval * 1000, weight); } } } From 8d74ea6db7c663fdc199fc39be3d137fa685544c Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Sun, 2 Jun 2024 00:02:44 -0300 Subject: [PATCH 04/15] fix: possible memory leak in connection (#2668) May never be called async_wait and therefore may leave the connection stuck in limbo. --- src/server/network/connection/connection.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/network/connection/connection.cpp b/src/server/network/connection/connection.cpp index 1c575ff00d0..3effd52f829 100644 --- a/src/server/network/connection/connection.cpp +++ b/src/server/network/connection/connection.cpp @@ -105,7 +105,7 @@ void Connection::accept(Protocol_ptr protocolPtr) { void Connection::acceptInternal(bool toggleParseHeader) { readTimer.expires_from_now(std::chrono::seconds(CONNECTION_READ_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + readTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); try { asio::async_read(socket, asio::buffer(msg.getBuffer(), HEADER_LENGTH), [self = shared_from_this(), toggleParseHeader](const std::error_code &error, std::size_t N) { @@ -147,7 +147,7 @@ void Connection::parseProxyIdentification(const std::error_code &error) { connectionState = CONNECTION_STATE_READINGS; try { readTimer.expires_from_now(std::chrono::seconds(CONNECTION_READ_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + readTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); // Read the remainder of proxy identification asio::async_read(socket, asio::buffer(msg.getBuffer(), remainder), [self = shared_from_this()](const std::error_code &error, std::size_t N) { self->parseProxyIdentification(error); }); @@ -208,7 +208,7 @@ void Connection::parseHeader(const std::error_code &error) { try { readTimer.expires_from_now(std::chrono::seconds(CONNECTION_READ_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + readTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); // Read packet content msg.setLength(size + HEADER_LENGTH); @@ -275,7 +275,7 @@ void Connection::parsePacket(const std::error_code &error) { try { readTimer.expires_from_now(std::chrono::seconds(CONNECTION_READ_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + readTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); if (!skipReadingNextPacket) { // Wait to the next packet @@ -289,7 +289,7 @@ void Connection::parsePacket(const std::error_code &error) { void Connection::resumeWork() { readTimer.expires_from_now(std::chrono::seconds(CONNECTION_READ_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + readTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); try { asio::async_read(socket, asio::buffer(msg.getBuffer(), HEADER_LENGTH), [self = shared_from_this()](const std::error_code &error, std::size_t N) { self->parseHeader(error); }); @@ -358,7 +358,7 @@ uint32_t Connection::getIP() { void Connection::internalSend(const OutputMessage_ptr &outputMessage) { writeTimer.expires_from_now(std::chrono::seconds(CONNECTION_WRITE_TIMEOUT)); - readTimer.async_wait([self = shared_from_this()](const std::error_code &error) { Connection::handleTimeout(std::weak_ptr(self), error); }); + writeTimer.async_wait([self = std::weak_ptr(shared_from_this())](const std::error_code &error) { Connection::handleTimeout(self, error); }); try { asio::async_write(socket, asio::buffer(outputMessage->getOutputBuffer(), outputMessage->getLength()), [self = shared_from_this()](const std::error_code &error, std::size_t N) { self->onWriteOperation(error); }); From 02a7bc0c85c3a9cc0817b59950679a2b355f6c71 Mon Sep 17 00:00:00 2001 From: Pedro Cruz Date: Mon, 3 Jun 2024 15:44:36 -0300 Subject: [PATCH 05/15] feat: equipments winter update 2023 (#2608) --- data/items/items.xml | 290 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) diff --git a/data/items/items.xml b/data/items/items.xml index e7e73d9753b..9fdc89bbd8f 100644 --- a/data/items/items.xml +++ b/data/items/items.xml @@ -75820,5 +75820,295 @@ Granted by TibiaGoals.com"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 2db5fee1f44a6d5cadca8db6a9ef9defdbad67f0 Mon Sep 17 00:00:00 2001 From: miah-sebastian Date: Tue, 4 Jun 2024 18:42:36 -0400 Subject: [PATCH 06/15] fix: opentelemetry linker error (#2678) --- vcpkg.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vcpkg.json b/vcpkg.json index 1f821379bad..eed7e776ee0 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -18,6 +18,11 @@ "spdlog", "zlib", "bshoshany-thread-pool", + { + "name": "opentelemetry-cpp", + "default-features": true, + "features": ["otlp-http", "prometheus"] + }, { "name": "libmariadb", "features": [ From 4af13eefdcc71f900587f3f4e9afa8083a1fe1ae Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 4 Jun 2024 22:17:28 -0300 Subject: [PATCH 07/15] fix: small adjustments and corrections to the core (#2524) - Previously, players were not being removed from the room upon killing the boss, as the relevant script was confined to rlmap only. This update ensures its functionality across any datapack. - Hirelings are now accessible beyond rlmap environments. - Addressed an issue with the loading of VIP days library. - Relocated the large sea shell asset to the core. - Implemented VIP status check and associated actions. - Transferred weapons scripts to the core. --- .../scripts/actions/other/large_sea_shell.lua | 28 ----- .../scripts/weapons/scripted_weapons.lua | 101 ------------------ data-otservbr-global/lib/others/load.lua | 1 - .../scripts/creaturescripts/customs/vip.lua | 20 ---- .../creaturescripts/others/forge_kill.lua | 12 --- .../{bosslever.lua => boss_lever.lua} | 0 data/libs/functions/load.lua | 10 +- data/libs/systems/load.lua | 1 + .../libs/systems/vip.lua | 20 ++-- .../scripts/actions/items/hireling_lamp.lua | 7 +- .../actions/objects/large_seashell.lua | 30 ++++++ .../monster/boss_lever_death.lua | 7 ++ .../creaturescripts/monster}/forge_kill.lua | 0 .../player}/adventure_blessing_login.lua | 1 + data/scripts/creaturescripts/player/login.lua | 24 ++++- .../scripts/weapons/dawnport_weapons.lua | 0 .../scripts/weapons/scripts/burst_arrow.lua | 0 .../scripts/weapons/scripts/diamond_arrow.lua | 0 .../scripts/weapons/scripts/poison_arrow.lua | 0 .../scripts/weapons/scripts/viper_star.lua | 0 20 files changed, 75 insertions(+), 187 deletions(-) delete mode 100644 data-canary/scripts/actions/other/large_sea_shell.lua delete mode 100644 data-canary/scripts/weapons/scripted_weapons.lua delete mode 100644 data-otservbr-global/scripts/creaturescripts/customs/vip.lua delete mode 100644 data-otservbr-global/scripts/creaturescripts/others/forge_kill.lua rename data/libs/functions/{bosslever.lua => boss_lever.lua} (100%) rename data-otservbr-global/lib/others/vip_system.lua => data/libs/systems/vip.lua (61%) rename data-otservbr-global/scripts/actions/other/hirelinglamp.lua => data/scripts/actions/items/hireling_lamp.lua (93%) create mode 100644 data/scripts/actions/objects/large_seashell.lua rename data-otservbr-global/scripts/globalevents/others/bosslever_death.lua => data/scripts/creaturescripts/monster/boss_lever_death.lua (99%) rename {data-canary/scripts/creaturescripts => data/scripts/creaturescripts/monster}/forge_kill.lua (100%) rename {data-otservbr-global/scripts/creaturescripts/others => data/scripts/creaturescripts/player}/adventure_blessing_login.lua (99%) rename data-otservbr-global/scripts/weapons/dawnport_weapon.lua => data/scripts/weapons/dawnport_weapons.lua (100%) rename {data-otservbr-global => data}/scripts/weapons/scripts/burst_arrow.lua (100%) rename {data-otservbr-global => data}/scripts/weapons/scripts/diamond_arrow.lua (100%) rename {data-otservbr-global => data}/scripts/weapons/scripts/poison_arrow.lua (100%) rename {data-otservbr-global => data}/scripts/weapons/scripts/viper_star.lua (100%) diff --git a/data-canary/scripts/actions/other/large_sea_shell.lua b/data-canary/scripts/actions/other/large_sea_shell.lua deleted file mode 100644 index b396bd70611..00000000000 --- a/data-canary/scripts/actions/other/large_sea_shell.lua +++ /dev/null @@ -1,28 +0,0 @@ -local largeSeaShell = Action() - -function largeSeaShell.onUse(player, item, fromPosition, target, toPosition, isHotkey) - if player:getStorageValue(Storage.DelayLargeSeaShell) <= os.time() then - local chance = math.random(100) - local msg = "" - if chance <= 16 then - doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -200, -200, CONST_ME_NONE) - msg = "Ouch! You squeezed your fingers." - elseif chance > 16 and chance <= 64 then - Game.createItem(math.random(281, 282), 1, player:getPosition()) - msg = "You found a beautiful pearl." - else - msg = "Nothing is inside." - end - player:say(msg, TALKTYPE_MONSTER_SAY, false, player, item:getPosition()) - item:transform(198) - item:decay() - player:setStorageValue(Storage.DelayLargeSeaShell, os.time() + 20 * 60 * 60) - item:getPosition():sendMagicEffect(CONST_ME_BUBBLES) - else - player:say("You have already opened a shell today.", TALKTYPE_MONSTER_SAY, false, player, item:getPosition()) - end - return true -end - -largeSeaShell:id(197) -largeSeaShell:register() diff --git a/data-canary/scripts/weapons/scripted_weapons.lua b/data-canary/scripts/weapons/scripted_weapons.lua deleted file mode 100644 index 93e677d43cd..00000000000 --- a/data-canary/scripts/weapons/scripted_weapons.lua +++ /dev/null @@ -1,101 +0,0 @@ -local burstArea = createCombatArea({ - { 1, 1, 1 }, - { 1, 3, 1 }, - { 1, 1, 1 }, -}) - -local burstCombat = Combat() -burstCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) -burstCombat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_EXPLOSIONAREA) -burstCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_BURSTARROW) -burstCombat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) -burstCombat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) -burstCombat:setParameter(COMBAT_PARAM_IMPACTSOUND, SOUND_EFFECT_TYPE_BURST_ARROW_EFFECT) -burstCombat:setParameter(COMBAT_PARAM_CASTSOUND, SOUND_EFFECT_TYPE_DIST_ATK_BOW) -burstCombat:setArea(burstArea) - -local burstarrow = Weapon(WEAPON_AMMO) -burstarrow.onUseWeapon = function(player, variant) - if player:getSkull() == SKULL_BLACK then - return false - end - - return burstCombat:execute(player, variant) -end - -burstarrow:id(3449) -burstarrow:action("removecount") -burstarrow:register() - -local poisonCombat = Combat() -poisonCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) -poisonCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_POISONARROW) -poisonCombat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) -poisonCombat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) - -local poisonarrow = Weapon(WEAPON_AMMO) -poisonarrow.onUseWeapon = function(player, variant) - if not poisonCombat:execute(player, variant) then - return false - end - - player:addDamageCondition(Creature(variant:getNumber()), CONDITION_POISON, DAMAGELIST_LOGARITHMIC_DAMAGE, 3) - return true -end - -poisonarrow:id(3448) -poisonarrow:action("removecount") -poisonarrow:register() - -local viperCombat = Combat() -viperCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) -viperCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_GREENSTAR) -viperCombat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) -viperCombat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) - -local viperstar = Weapon(WEAPON_DISTANCE) -viperstar.onUseWeapon = function(player, variant) - if not viperCombat:execute(player, variant) then - return false - end - - if math.random(1, 100) <= 90 then - return false - end - - player:addDamageCondition(Creature(variant:getNumber()), CONDITION_POISON, DAMAGELIST_LOGARITHMIC_DAMAGE, 2) - return true -end - -viperstar:id(7366) -viperstar:breakChance(9) -viperstar:register() - -local diamondArea = createCombatArea({ - { 0, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1 }, - { 1, 1, 3, 1, 1 }, - { 1, 1, 1, 1, 1 }, - { 0, 1, 1, 1, 0 }, -}) - -local diamondCombat = Combat() -diamondCombat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) -diamondCombat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_ENERGYHIT) -diamondCombat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_DIAMONDARROW) -diamondCombat:setParameter(COMBAT_PARAM_IMPACTSOUND, SOUND_EFFECT_TYPE_DIAMOND_ARROW_EFFECT) -diamondCombat:setParameter(COMBAT_PARAM_CASTSOUND, SOUND_EFFECT_TYPE_DIST_ATK_BOW) -diamondCombat:setParameter(COMBAT_PARAM_BLOCKARMOR, true) -diamondCombat:setFormula(COMBAT_FORMULA_SKILL, 0, 0, 1, 0) -diamondCombat:setArea(diamondArea) - -local diamondarrow = Weapon(WEAPON_AMMO) -diamondarrow.onUseWeapon = function(player, variant) - return diamondCombat:execute(player, variant) -end - -diamondarrow:id(ITEM_OLD_DIAMOND_ARROW) -diamondarrow:action("removecount") -diamondarrow:level(150) -diamondarrow:wieldUnproperly(true) -diamondarrow:register() diff --git a/data-otservbr-global/lib/others/load.lua b/data-otservbr-global/lib/others/load.lua index 1052efb7bd6..031c8fb2026 100644 --- a/data-otservbr-global/lib/others/load.lua +++ b/data-otservbr-global/lib/others/load.lua @@ -1,2 +1 @@ dofile(DATA_DIRECTORY .. "/lib/others/dawnport.lua") -dofile(DATA_DIRECTORY .. "/lib/others/vip_system.lua") diff --git a/data-otservbr-global/scripts/creaturescripts/customs/vip.lua b/data-otservbr-global/scripts/creaturescripts/customs/vip.lua deleted file mode 100644 index 0ae99c00f2d..00000000000 --- a/data-otservbr-global/scripts/creaturescripts/customs/vip.lua +++ /dev/null @@ -1,20 +0,0 @@ -local playerLogin = CreatureEvent("VipLogin") - -function playerLogin.onLogin(player) - if configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) then - local wasVip = player:kv():scoped("account"):get("vip-system") or false - if wasVip and not player:isVip() then - player:onRemoveVip() - end - if not wasVip and player:isVip() then - player:onAddVip(player:getVipDays()) - end - - if player:isVip() then - CheckPremiumAndPrint(player, MESSAGE_LOGIN) - end - end - return true -end - -playerLogin:register() diff --git a/data-otservbr-global/scripts/creaturescripts/others/forge_kill.lua b/data-otservbr-global/scripts/creaturescripts/others/forge_kill.lua deleted file mode 100644 index 3e454d84d14..00000000000 --- a/data-otservbr-global/scripts/creaturescripts/others/forge_kill.lua +++ /dev/null @@ -1,12 +0,0 @@ -local forgeKill = CreatureEvent("ForgeSystemMonster") - -function forgeKill.onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) - local targetMonster = creature:getMonster() - if not targetMonster then - return true - end - - return ForgeMonster:onDeath(creature, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) -end - -forgeKill:register() diff --git a/data/libs/functions/bosslever.lua b/data/libs/functions/boss_lever.lua similarity index 100% rename from data/libs/functions/bosslever.lua rename to data/libs/functions/boss_lever.lua diff --git a/data/libs/functions/load.lua b/data/libs/functions/load.lua index c63276d9444..0fab2c3cb5e 100644 --- a/data/libs/functions/load.lua +++ b/data/libs/functions/load.lua @@ -1,14 +1,15 @@ -- Load core functions dofile(CORE_DIRECTORY .. "/libs/functions/bit.lua") dofile(CORE_DIRECTORY .. "/libs/functions/bitwise_flags.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/boss_lever.lua") dofile(CORE_DIRECTORY .. "/libs/functions/combat.lua") dofile(CORE_DIRECTORY .. "/libs/functions/constants.lua") dofile(CORE_DIRECTORY .. "/libs/functions/container.lua") dofile(CORE_DIRECTORY .. "/libs/functions/creature.lua") -dofile(CORE_DIRECTORY .. "/libs/functions/functions.lua") -dofile(CORE_DIRECTORY .. "/libs/functions/gematelier.lua") dofile(CORE_DIRECTORY .. "/libs/functions/fs.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/functions.lua") dofile(CORE_DIRECTORY .. "/libs/functions/game.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/gematelier.lua") dofile(CORE_DIRECTORY .. "/libs/functions/item.lua") dofile(CORE_DIRECTORY .. "/libs/functions/itemtype.lua") dofile(CORE_DIRECTORY .. "/libs/functions/lever.lua") @@ -20,14 +21,13 @@ dofile(CORE_DIRECTORY .. "/libs/functions/player.lua") dofile(CORE_DIRECTORY .. "/libs/functions/position.lua") dofile(CORE_DIRECTORY .. "/libs/functions/pronouns.lua") dofile(CORE_DIRECTORY .. "/libs/functions/quests.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/queue.lua") dofile(CORE_DIRECTORY .. "/libs/functions/revscriptsys.lua") +dofile(CORE_DIRECTORY .. "/libs/functions/set.lua") dofile(CORE_DIRECTORY .. "/libs/functions/spawn.lua") dofile(CORE_DIRECTORY .. "/libs/functions/spectators.lua") -dofile(CORE_DIRECTORY .. "/libs/functions/bosslever.lua") dofile(CORE_DIRECTORY .. "/libs/functions/string.lua") dofile(CORE_DIRECTORY .. "/libs/functions/tables.lua") dofile(CORE_DIRECTORY .. "/libs/functions/teleport.lua") dofile(CORE_DIRECTORY .. "/libs/functions/tile.lua") dofile(CORE_DIRECTORY .. "/libs/functions/vocation.lua") -dofile(CORE_DIRECTORY .. "/libs/functions/set.lua") -dofile(CORE_DIRECTORY .. "/libs/functions/queue.lua") diff --git a/data/libs/systems/load.lua b/data/libs/systems/load.lua index 5c7073ad64e..281b8b1d466 100644 --- a/data/libs/systems/load.lua +++ b/data/libs/systems/load.lua @@ -9,4 +9,5 @@ dofile(CORE_DIRECTORY .. "/libs/systems/hazard.lua") dofile(CORE_DIRECTORY .. "/libs/systems/hireling.lua") dofile(CORE_DIRECTORY .. "/libs/systems/raids.lua") dofile(CORE_DIRECTORY .. "/libs/systems/reward_boss.lua") +dofile(CORE_DIRECTORY .. "/libs/systems/vip.lua") dofile(CORE_DIRECTORY .. "/libs/systems/zones.lua") diff --git a/data-otservbr-global/lib/others/vip_system.lua b/data/libs/systems/vip.lua similarity index 61% rename from data-otservbr-global/lib/others/vip_system.lua rename to data/libs/systems/vip.lua index 5a393157c8c..9e76fd8ad80 100644 --- a/data-otservbr-global/lib/others/vip_system.lua +++ b/data/libs/systems/vip.lua @@ -1,16 +1,10 @@ local config = { - activationMessage = "You have received %s VIP days.", - activationMessageType = MESSAGE_EVENT_ADVANCE, - - expirationMessage = "Your VIP days ran out.", - expirationMessageType = MESSAGE_ADMINISTRATOR, - outfits = {}, mounts = {}, } function Player.onRemoveVip(self) - self:sendTextMessage(config.expirationMessageType, config.expirationMessage) + self:sendTextMessage(MESSAGE_ADMINISTRATOR, "Your VIP status has expired. All VIP benefits have been removed.") for _, outfit in ipairs(config.outfits) do self:removeOutfit(outfit) @@ -21,13 +15,14 @@ function Player.onRemoveVip(self) end local playerOutfit = self:getOutfit() - if table.contains(config.outfits, self:getOutfit().lookType) then + if table.contains(config.outfits, playerOutfit.lookType) then if self:getSex() == PLAYERSEX_FEMALE then playerOutfit.lookType = 136 else playerOutfit.lookType = 128 end playerOutfit.lookAddons = 0 + self:setOutfit(playerOutfit) end @@ -36,7 +31,7 @@ end function Player.onAddVip(self, days, silent) if not silent then - self:sendTextMessage(config.activationMessageType, string.format(config.activationMessage, days)) + self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("You have been granted %s days of VIP status.", days)) end for _, outfit in ipairs(config.outfits) do @@ -52,16 +47,15 @@ end function CheckPremiumAndPrint(player, msgType) if player:getVipDays() == 0xFFFF then - player:sendTextMessage(msgType, "You have infinite amount of VIP days left.") + player:sendTextMessage(msgType, "You have an unlimited VIP status.") return true end local playerVipTime = player:getVipTime() if playerVipTime < os.time() then - local msg = "You do not have VIP on your account." - player:sendTextMessage(msgType, msg) + player:sendTextMessage(msgType, "Your VIP status is currently inactive.") return true end - player:sendTextMessage(msgType, string.format("You have %s of VIP time left.", getFormattedTimeRemaining(playerVipTime))) + player:sendTextMessage(msgType, string.format("You have %s of VIP time remaining.", getFormattedTimeRemaining(playerVipTime))) end diff --git a/data-otservbr-global/scripts/actions/other/hirelinglamp.lua b/data/scripts/actions/items/hireling_lamp.lua similarity index 93% rename from data-otservbr-global/scripts/actions/other/hirelinglamp.lua rename to data/scripts/actions/items/hireling_lamp.lua index 8117b5366bc..0ffed1fa744 100644 --- a/data-otservbr-global/scripts/actions/other/hirelinglamp.lua +++ b/data/scripts/actions/items/hireling_lamp.lua @@ -2,8 +2,9 @@ local hirelingLamp = Action() function hirelingLamp.onUse(player, item, fromPosition, target, toPosition, isHotkey) local spawnPosition = player:getPosition() - local hireling_id = item:getCustomAttribute("Hireling") + local hirelingId = item:getCustomAttribute("Hireling") local house = spawnPosition and spawnPosition:getTile() and spawnPosition:getTile():getHouse() or nil + if not house then player:getPosition():sendMagicEffect(CONST_ME_POFF) player:sendTextMessage(MESSAGE_FAILURE, "You may use this only inside a house.") @@ -22,10 +23,10 @@ function hirelingLamp.onUse(player, item, fromPosition, target, toPosition, isHo return false end - local hireling = getHirelingById(hireling_id) + local hireling = getHirelingById(hirelingId) if not hireling then player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There was an error creating the hireling and it has been deleted, please, contact server admin.") - logger.warn("[hirelingLamp.onUse] Player {} is using hireling with id {} not exist in the database", player:getName(), hireling_id) + logger.warn("[hirelingLamp.onUse] Player {} is using hireling with id {} not exist in the database", player:getName(), hirelingId) logger.error("Deleted the lamp") item:remove(1) return true diff --git a/data/scripts/actions/objects/large_seashell.lua b/data/scripts/actions/objects/large_seashell.lua new file mode 100644 index 00000000000..c6d767146ec --- /dev/null +++ b/data/scripts/actions/objects/large_seashell.lua @@ -0,0 +1,30 @@ +local largeSeashell = Action() + +function largeSeashell.onUse(player, item, fromPosition, target, toPosition, isHotkey) + if player:hasExhaustion("delay-large-seashell") then + player:say("You have already opened a shell today.", TALKTYPE_MONSTER_SAY, false, player, item:getPosition()) + return true + end + + local chance = math.random(100) + local message = "Nothing is inside." + + if chance <= 16 then + doTargetCombatHealth(0, player, COMBAT_PHYSICALDAMAGE, -200, -200, CONST_ME_NONE) + message = "Ouch! You squeezed your fingers." + elseif chance > 16 and chance <= 64 then + Game.createItem(math.random(281, 282), 1, player:getPosition()) + message = "You found a beautiful pearl." + player:addAchievementProgress("Shell Seeker", 100) + end + + player:setExhaustion("delay-large-seashell", 20 * 60 * 60) + player:say(message, TALKTYPE_MONSTER_SAY, false, player, item:getPosition()) + item:transform(198) + item:decay() + item:getPosition():sendMagicEffect(CONST_ME_BUBBLES) + return true +end + +largeSeashell:id(197) +largeSeashell:register() diff --git a/data-otservbr-global/scripts/globalevents/others/bosslever_death.lua b/data/scripts/creaturescripts/monster/boss_lever_death.lua similarity index 99% rename from data-otservbr-global/scripts/globalevents/others/bosslever_death.lua rename to data/scripts/creaturescripts/monster/boss_lever_death.lua index 9538fe15eb7..a2c58d1e43b 100644 --- a/data-otservbr-global/scripts/globalevents/others/bosslever_death.lua +++ b/data/scripts/creaturescripts/monster/boss_lever_death.lua @@ -1,22 +1,28 @@ local onBossDeath = CreatureEvent("BossLeverOnDeath") + function onBossDeath.onDeath(creature) if not creature then return true end + local name = creature:getName() local key = "boss." .. toKey(name) local zone = Zone(key) + if not zone then return true end + local bossLever = BossLever[name] if not bossLever then return true end + if bossLever.timeoutEvent then stopEvent(bossLever.timeoutEvent) bossLever.timeoutEvent = nil end + if bossLever.timeAfterKill > 0 then zone:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The " .. name .. " has been defeated. You have " .. bossLever.timeAfterKill .. " seconds to leave the room.") bossLever.timeoutEvent = addEvent(function(zn) @@ -26,4 +32,5 @@ function onBossDeath.onDeath(creature) end return true end + onBossDeath:register() diff --git a/data-canary/scripts/creaturescripts/forge_kill.lua b/data/scripts/creaturescripts/monster/forge_kill.lua similarity index 100% rename from data-canary/scripts/creaturescripts/forge_kill.lua rename to data/scripts/creaturescripts/monster/forge_kill.lua diff --git a/data-otservbr-global/scripts/creaturescripts/others/adventure_blessing_login.lua b/data/scripts/creaturescripts/player/adventure_blessing_login.lua similarity index 99% rename from data-otservbr-global/scripts/creaturescripts/others/adventure_blessing_login.lua rename to data/scripts/creaturescripts/player/adventure_blessing_login.lua index df04052716f..8ebf88a72e9 100644 --- a/data-otservbr-global/scripts/creaturescripts/others/adventure_blessing_login.lua +++ b/data/scripts/creaturescripts/player/adventure_blessing_login.lua @@ -1,6 +1,7 @@ dofile(CORE_DIRECTORY .. "/modules/scripts/blessings/blessings.lua") local adventurerBlessingLogin = CreatureEvent("AdventurerBlessingLogin") + function adventurerBlessingLogin.onLogin(player) return Blessings.doAdventurerBlessing(player) end diff --git a/data/scripts/creaturescripts/player/login.lua b/data/scripts/creaturescripts/player/login.lua index 34d139a047d..fbe4f9e63b6 100644 --- a/data/scripts/creaturescripts/player/login.lua +++ b/data/scripts/creaturescripts/player/login.lua @@ -49,10 +49,8 @@ function playerLoginGlobal.onLogin(player) end -- Boosted - player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Today's boosted creature: " .. Game.getBoostedCreature() .. " \ - Boosted creatures yield more experience points, carry more loot than usual and respawn at a faster rate.") - player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, "Today's boosted boss: " .. Game.getBoostedBoss() .. " \ - Boosted bosses contain more loot and count more kills for your Bosstiary.") + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, string.format("Today's boosted creature: %s.\nBoosted creatures yield more experience points, carry more loot than usual, and respawn at a faster rate.", Game.getBoostedCreature())) + player:sendTextMessage(MESSAGE_BOOSTED_CREATURE, string.format("Today's boosted boss: %s.\nBoosted bosses contain more loot and count more kills for your Bosstiary.", Game.getBoostedBoss())) -- Rewards local rewards = #player:getRewardList() @@ -118,6 +116,24 @@ function playerLoginGlobal.onLogin(player) player:setStaminaXpBoost(player:getFinalBonusStamina() * 100) player:getFinalLowLevelBonus() + -- Updates the player's VIP status and executes corresponding actions if applicable. + if configManager.getBoolean(configKeys.VIP_SYSTEM_ENABLED) then + local isVipNow = player:isVip() + local wasVip = player:kv():scoped("account"):get("vip-system") or false + + if wasVip ~= isVipNow then + if wasVip then + player:onRemoveVip() + else + player:onAddVip(player:getVipDays()) + end + end + + if isVipNow then + CheckPremiumAndPrint(player, MESSAGE_LOGIN) + end + end + -- Set Ghost Mode if player:getGroup():getId() >= GROUP_TYPE_GAMEMASTER then player:setGhostMode(true) diff --git a/data-otservbr-global/scripts/weapons/dawnport_weapon.lua b/data/scripts/weapons/dawnport_weapons.lua similarity index 100% rename from data-otservbr-global/scripts/weapons/dawnport_weapon.lua rename to data/scripts/weapons/dawnport_weapons.lua diff --git a/data-otservbr-global/scripts/weapons/scripts/burst_arrow.lua b/data/scripts/weapons/scripts/burst_arrow.lua similarity index 100% rename from data-otservbr-global/scripts/weapons/scripts/burst_arrow.lua rename to data/scripts/weapons/scripts/burst_arrow.lua diff --git a/data-otservbr-global/scripts/weapons/scripts/diamond_arrow.lua b/data/scripts/weapons/scripts/diamond_arrow.lua similarity index 100% rename from data-otservbr-global/scripts/weapons/scripts/diamond_arrow.lua rename to data/scripts/weapons/scripts/diamond_arrow.lua diff --git a/data-otservbr-global/scripts/weapons/scripts/poison_arrow.lua b/data/scripts/weapons/scripts/poison_arrow.lua similarity index 100% rename from data-otservbr-global/scripts/weapons/scripts/poison_arrow.lua rename to data/scripts/weapons/scripts/poison_arrow.lua diff --git a/data-otservbr-global/scripts/weapons/scripts/viper_star.lua b/data/scripts/weapons/scripts/viper_star.lua similarity index 100% rename from data-otservbr-global/scripts/weapons/scripts/viper_star.lua rename to data/scripts/weapons/scripts/viper_star.lua From 8af607bdf87ab8004ed01e9557175f2d33116eec Mon Sep 17 00:00:00 2001 From: Paulo Henrique Lisboa Date: Tue, 11 Jun 2024 10:05:04 -0300 Subject: [PATCH 08/15] fix: docker ubuntu package and start.sh permission (#2681) --- docker/Dockerfile.dev | 6 +++--- docker/data/start.sh | 4 ++-- docker/docker-compose.yml | 2 -- start.sh | 0 4 files changed, 5 insertions(+), 7 deletions(-) mode change 100644 => 100755 start.sh diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 161a80a2e21..4cd63334d5e 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -1,10 +1,10 @@ # Stage 1: Download all dependencies -FROM ubuntu:23.04 AS dependencies +FROM ubuntu:24.04 AS dependencies RUN --mount=type=cache,target=/var/cache/apt \ apt-get update && apt-get install -y --no-install-recommends cmake git \ unzip build-essential ca-certificates curl zip unzip tar \ - pkg-config ninja-build autoconf automake libtool \ + pkg-config ninja-build autoconf automake libtool glibc-tools \ python3 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -32,7 +32,7 @@ COPY recompile.sh CMakeLists.txt CMakePresets.json vcpkg.json ./ RUN ./recompile.sh "/opt" # Stage 3: execute -FROM ubuntu:23.04 AS prod +FROM ubuntu:24.04 AS prod COPY --from=build /srv/build/build/linux-release/bin/canary /bin/canary WORKDIR /srv/canary ENTRYPOINT ["/srv/canary/start.sh", "canary"] diff --git a/docker/data/start.sh b/docker/data/start.sh index db688b488d0..c7d10fa0fdb 100755 --- a/docker/data/start.sh +++ b/docker/data/start.sh @@ -10,8 +10,8 @@ OT_SERVER_LOGIN_PORT="${OT_SERVER_LOGIN_PORT:-7171}" OT_SERVER_GAME_PORT="${OT_SERVER_GAME_PORT:-7172}" OT_SERVER_STATUS_PORT="${OT_SERVER_STATUS_PORT:-7171}" OT_SERVER_TEST_ACCOUNTS="${OT_SERVER_TEST_ACCOUNTS:-false}" -OT_SERVER_DATA="${OT_SERVER_DATA:-data-canary}" -OT_SERVER_MAP="${OT_SERVER_MAP:-https://github.com/opentibiabr/otservbr-global/releases/download/v1.5.0/otservbr.otbm}" +OT_SERVER_DATA="${OT_SERVER_DATA:-data-otservbr-global}" +OT_SERVER_MAP="${OT_SERVER_MAP:-https://github.com/opentibiabr/canary/releases/download/v3.1.0/otservbr.otbm}" echo "" echo "===== Print Variables =====" diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 46a2fb619b2..88fd938e500 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,5 +1,3 @@ ---- -version: '3.8' name: otbr services: database: diff --git a/start.sh b/start.sh old mode 100644 new mode 100755 From ede4b035bcb3c664bd42c757f1d4466b8d7b5c43 Mon Sep 17 00:00:00 2001 From: Felipe Paluco <87909998+FelipePaluco@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:05:20 -0300 Subject: [PATCH 09/15] feat: rebalancing monsters (#2683) --- data-canary/monster/demons/fury.lua | 2 +- data-canary/monster/demons/juggernaut.lua | 4 ++-- .../monster/aquatics/quara_constrictor.lua | 2 +- .../monster/aquatics/quara_hydromancer.lua | 2 +- .../monster/aquatics/quara_mantassin.lua | 2 +- .../monster/aquatics/quara_pincher.lua | 2 +- .../monster/aquatics/quara_predator.lua | 2 +- data-otservbr-global/monster/bosses/splasher.lua | 2 +- .../monster/constructs/clay_guardian.lua | 2 +- .../monster/constructs/infected_weeper.lua | 2 +- .../monster/constructs/lava_golem.lua | 3 +-- .../monster/constructs/magma_crawler.lua | 8 ++++---- .../monster/constructs/orewalker.lua | 3 +-- .../monster/constructs/stone_devourer.lua | 2 +- data-otservbr-global/monster/constructs/weeper.lua | 6 +++--- .../monster/demons/hellfire_fighter.lua | 2 +- .../monster/elementals/cliff_strider.lua | 6 +++--- .../monster/elementals/earth_elemental.lua | 4 ++-- .../monster/elementals/high_voltage_elemental.lua | 2 +- .../monster/elementals/ironblight.lua | 2 +- .../monster/elementals/massive_earth_elemental.lua | 4 ++-- .../monster/elementals/sulphur_spouter.lua | 2 +- .../monster/humanoids/lost_basher.lua | 6 +++--- .../monster/humanoids/lost_berserker.lua | 12 +++++------- .../monster/humanoids/lost_husher.lua | 9 ++++----- .../monster/humanoids/lost_thrower.lua | 6 +++--- data-otservbr-global/monster/magicals/armadile.lua | 13 +++++-------- .../monster/magicals/choking_fear.lua | 2 +- data-otservbr-global/monster/magicals/phantasm.lua | 2 +- .../monster/magicals/retching_horror.lua | 2 +- .../monster/mammals/mutated_bat.lua | 2 +- .../monster/plants/hideous_fungus.lua | 13 ++++++------- .../monster/plants/humongous_fungus.lua | 7 +++---- .../quests/bigfoots_burden/bosses/abyssador.lua | 2 +- .../quests/bigfoots_burden/bosses/gnomevil.lua | 2 +- .../quests/bigfoots_burden/humorless_fungus.lua | 9 +++------ .../bosses/the_count_of_the_core.lua | 2 +- .../bosses/the_duke_of_the_depths.lua | 2 +- .../bosses/ferumbras_mortal_shell.lua | 2 +- .../quests/ferumbras_ascendant/bosses/mazoran.lua | 2 +- .../quests/ferumbras_ascendant/bosses/plagirath.lua | 2 +- .../quests/ferumbras_ascendant/bosses/ragiaz.lua | 2 +- .../quests/ferumbras_ascendant/bosses/razzagorn.lua | 2 +- .../quests/ferumbras_ascendant/bosses/shulgrax.lua | 2 +- .../quests/ferumbras_ascendant/bosses/tarbaz.lua | 2 +- .../quests/ferumbras_ascendant/bosses/zamulosh.lua | 2 +- .../monster/quests/in_service_of_yalahar/inky.lua | 2 +- .../quests/in_service_of_yalahar/sharptooth.lua | 2 +- .../monster/reptiles/seacrest_serpent.lua | 2 +- .../monster/reptiles/young_sea_serpent.lua | 2 +- .../monster/undeads/betrayed_wraith.lua | 2 +- .../monster/undeads/blightwalker.lua | 7 +++---- .../monster/undeads/crypt_warrior.lua | 2 +- .../monster/undeads/falcon_knight.lua | 2 +- .../monster/undeads/falcon_paladin.lua | 2 +- .../monster/undeads/hand_of_cursed_fate.lua | 4 ++-- .../monster/undeads/skeleton_elite_warrior.lua | 2 +- .../monster/undeads/undead_dragon.lua | 2 +- .../monster/undeads/undead_elite_gladiator.lua | 2 +- .../monster/vermins/cave_devourer.lua | 4 ++-- .../monster/vermins/chasm_spawn.lua | 4 ++-- data-otservbr-global/monster/vermins/deepworm.lua | 2 +- data-otservbr-global/monster/vermins/diremaw.lua | 2 +- data-otservbr-global/monster/vermins/drillworm.lua | 2 +- .../monster/vermins/tunnel_tyrant.lua | 4 ++-- ...d_,master_oberon.lua => grand_master_oberon.lua} | 0 66 files changed, 105 insertions(+), 119 deletions(-) rename data-otservbr-global/scripts/actions/bosses_levers/{grand_,master_oberon.lua => grand_master_oberon.lua} (100%) diff --git a/data-canary/monster/demons/fury.lua b/data-canary/monster/demons/fury.lua index 3835050ce67..a01553afeed 100644 --- a/data-canary/monster/demons/fury.lua +++ b/data-canary/monster/demons/fury.lua @@ -125,7 +125,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 30 }, + { type = COMBAT_ICEDAMAGE, percent = 5 }, { type = COMBAT_HOLYDAMAGE, percent = 30 }, { type = COMBAT_DEATHDAMAGE, percent = -10 }, } diff --git a/data-canary/monster/demons/juggernaut.lua b/data-canary/monster/demons/juggernaut.lua index 7b3e3d1795b..704ce847f13 100644 --- a/data-canary/monster/demons/juggernaut.lua +++ b/data-canary/monster/demons/juggernaut.lua @@ -27,8 +27,8 @@ monster.Bestiary = { The Blood Halls, The Vats, The Hive, The Shadow Nexus, a room deep in Formorgar Mines, Roshamuul Prison, Oramond Dungeon, Grounds of Destruction.", } -monster.health = 20000 -monster.maxHealth = 20000 +monster.health = 18000 +monster.maxHealth = 18000 monster.race = "blood" monster.corpse = 6335 monster.speed = 170 diff --git a/data-otservbr-global/monster/aquatics/quara_constrictor.lua b/data-otservbr-global/monster/aquatics/quara_constrictor.lua index 02b4877620e..c04460f1f50 100644 --- a/data-otservbr-global/monster/aquatics/quara_constrictor.lua +++ b/data-otservbr-global/monster/aquatics/quara_constrictor.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Quara Constrictor") local monster = {} monster.description = "a quara constrictor" -monster.experience = 250 +monster.experience = 380 monster.outfit = { lookType = 46, lookHead = 0, diff --git a/data-otservbr-global/monster/aquatics/quara_hydromancer.lua b/data-otservbr-global/monster/aquatics/quara_hydromancer.lua index 4129dcfe81c..07c3ffbfda3 100644 --- a/data-otservbr-global/monster/aquatics/quara_hydromancer.lua +++ b/data-otservbr-global/monster/aquatics/quara_hydromancer.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Quara Hydromancer") local monster = {} monster.description = "a quara hydromancer" -monster.experience = 800 +monster.experience = 950 monster.outfit = { lookType = 47, lookHead = 0, diff --git a/data-otservbr-global/monster/aquatics/quara_mantassin.lua b/data-otservbr-global/monster/aquatics/quara_mantassin.lua index 53594881d50..3e857cab7f2 100644 --- a/data-otservbr-global/monster/aquatics/quara_mantassin.lua +++ b/data-otservbr-global/monster/aquatics/quara_mantassin.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Quara Mantassin") local monster = {} monster.description = "a quara mantassin" -monster.experience = 400 +monster.experience = 600 monster.outfit = { lookType = 72, lookHead = 0, diff --git a/data-otservbr-global/monster/aquatics/quara_pincher.lua b/data-otservbr-global/monster/aquatics/quara_pincher.lua index 200aed87628..09fea436314 100644 --- a/data-otservbr-global/monster/aquatics/quara_pincher.lua +++ b/data-otservbr-global/monster/aquatics/quara_pincher.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Quara Pincher") local monster = {} monster.description = "a quara pincher" -monster.experience = 1200 +monster.experience = 1500 monster.outfit = { lookType = 77, lookHead = 0, diff --git a/data-otservbr-global/monster/aquatics/quara_predator.lua b/data-otservbr-global/monster/aquatics/quara_predator.lua index e513aa5712c..b12719e26f8 100644 --- a/data-otservbr-global/monster/aquatics/quara_predator.lua +++ b/data-otservbr-global/monster/aquatics/quara_predator.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Quara Predator") local monster = {} monster.description = "a quara predator" -monster.experience = 1600 +monster.experience = 1850 monster.outfit = { lookType = 20, lookHead = 0, diff --git a/data-otservbr-global/monster/bosses/splasher.lua b/data-otservbr-global/monster/bosses/splasher.lua index 60b89710c4f..426d3be3c26 100644 --- a/data-otservbr-global/monster/bosses/splasher.lua +++ b/data-otservbr-global/monster/bosses/splasher.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Splasher") local monster = {} monster.description = "Splasher" -monster.experience = 500 +monster.experience = 1500 monster.outfit = { lookType = 47, lookHead = 0, diff --git a/data-otservbr-global/monster/constructs/clay_guardian.lua b/data-otservbr-global/monster/constructs/clay_guardian.lua index 804d671bdf9..fb28abe50c3 100644 --- a/data-otservbr-global/monster/constructs/clay_guardian.lua +++ b/data-otservbr-global/monster/constructs/clay_guardian.lua @@ -107,7 +107,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 35 }, + { type = COMBAT_ICEDAMAGE, percent = 20 }, { type = COMBAT_HOLYDAMAGE, percent = 0 }, { type = COMBAT_DEATHDAMAGE, percent = 40 }, } diff --git a/data-otservbr-global/monster/constructs/infected_weeper.lua b/data-otservbr-global/monster/constructs/infected_weeper.lua index e302618f3eb..2b7d97f0479 100644 --- a/data-otservbr-global/monster/constructs/infected_weeper.lua +++ b/data-otservbr-global/monster/constructs/infected_weeper.lua @@ -105,7 +105,7 @@ monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 50 }, { type = COMBAT_ENERGYDAMAGE, percent = 25 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, - { type = COMBAT_FIREDAMAGE, percent = 100 }, + { type = COMBAT_FIREDAMAGE, percent = -100 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/constructs/lava_golem.lua b/data-otservbr-global/monster/constructs/lava_golem.lua index aed9ad864c0..5c3f695cf32 100644 --- a/data-otservbr-global/monster/constructs/lava_golem.lua +++ b/data-otservbr-global/monster/constructs/lava_golem.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Lava Golem") local monster = {} monster.description = "a lava golem" -monster.experience = 6200 +monster.experience = 7900 monster.outfit = { lookType = 491, lookHead = 0, @@ -109,7 +109,6 @@ monster.loot = { monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -400 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -350, maxDamage = -700, length = 8, spread = 0, effect = CONST_ME_FIREATTACK, target = false }, - { name = "combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -600, maxDamage = -1300, length = 8, spread = 3, effect = CONST_ME_MORTAREA, target = false }, { name = "lava golem soulfire", interval = 2000, chance = 15, target = false }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -220, maxDamage = -350, radius = 4, effect = CONST_ME_FIREAREA, target = true }, { name = "speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 3, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000 }, diff --git a/data-otservbr-global/monster/constructs/magma_crawler.lua b/data-otservbr-global/monster/constructs/magma_crawler.lua index 39c58ab8838..bf5f7ac4feb 100644 --- a/data-otservbr-global/monster/constructs/magma_crawler.lua +++ b/data-otservbr-global/monster/constructs/magma_crawler.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Magma Crawler") local monster = {} monster.description = "a magma crawler" -monster.experience = 2700 +monster.experience = 3900 monster.outfit = { lookType = 492, lookHead = 0, @@ -35,7 +35,7 @@ monster.manaCost = 0 monster.changeTarget = { interval = 4000, - chance = 10, + chance = 5, } monster.strategiesTarget = { @@ -118,7 +118,7 @@ monster.defenses = { defense = 45, armor = 84, mitigation = 2.51, - { name = "invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE }, + { name = "invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE }, } monster.elements = { @@ -129,7 +129,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 10 }, + { type = COMBAT_ICEDAMAGE, percent = 0 }, { type = COMBAT_HOLYDAMAGE, percent = 0 }, { type = COMBAT_DEATHDAMAGE, percent = 25 }, } diff --git a/data-otservbr-global/monster/constructs/orewalker.lua b/data-otservbr-global/monster/constructs/orewalker.lua index 767b8a049ae..3e1dc4deedd 100644 --- a/data-otservbr-global/monster/constructs/orewalker.lua +++ b/data-otservbr-global/monster/constructs/orewalker.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Orewalker") local monster = {} monster.description = "an orewalker" -monster.experience = 4800 +monster.experience = 5900 monster.outfit = { lookType = 490, lookHead = 0, @@ -112,7 +112,6 @@ monster.attacks = { { name = "combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1500, length = 6, spread = 3, effect = CONST_ME_GROUNDSHAKER, target = false }, -- poison { name = "condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -800, maxDamage = -1080, radius = 3, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = true }, - { name = "drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_SOUND_PURPLE, target = false, duration = 6000 }, { name = "speed", interval = 2000, chance = 15, speedChange = -800, radius = 2, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000 }, } diff --git a/data-otservbr-global/monster/constructs/stone_devourer.lua b/data-otservbr-global/monster/constructs/stone_devourer.lua index 5a9174c3129..39c85402870 100644 --- a/data-otservbr-global/monster/constructs/stone_devourer.lua +++ b/data-otservbr-global/monster/constructs/stone_devourer.lua @@ -118,7 +118,7 @@ monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 10 }, { type = COMBAT_ENERGYDAMAGE, percent = 30 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, - { type = COMBAT_FIREDAMAGE, percent = 100 }, + { type = COMBAT_FIREDAMAGE, percent = -5 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/constructs/weeper.lua b/data-otservbr-global/monster/constructs/weeper.lua index 75a8d7ebb42..cfc7c6b0d68 100644 --- a/data-otservbr-global/monster/constructs/weeper.lua +++ b/data-otservbr-global/monster/constructs/weeper.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Weeper") local monster = {} monster.description = "a weeper" -monster.experience = 4800 +monster.experience = 5800 monster.outfit = { lookType = 489, lookHead = 0, @@ -55,7 +55,7 @@ monster.flags = { canPushCreatures = true, staticAttackChance = 70, targetDistance = 1, - runHealth = 570, + runHealth = 0, healthHidden = false, isBlockable = false, canWalkOnEnergy = false, @@ -101,7 +101,7 @@ monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_FIREDAMAGE, minDamage = -400, maxDamage = -1000, length = 8, spread = 0, effect = CONST_ME_FIREATTACK, target = false }, { name = "combat", interval = 3000, chance = 100, type = COMBAT_FIREDAMAGE, minDamage = -80, maxDamage = -250, radius = 3, effect = CONST_ME_HITBYFIRE, target = false }, - { name = "speed", interval = 2000, chance = 10, speedChange = -800, length = 5, spread = 0, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000 }, + { name = "speed", interval = 2000, chance = 10, speedChange = -600, length = 5, spread = 0, effect = CONST_ME_BLOCKHIT, target = false, duration = 30000 }, } monster.defenses = { diff --git a/data-otservbr-global/monster/demons/hellfire_fighter.lua b/data-otservbr-global/monster/demons/hellfire_fighter.lua index 6a90b5af06d..2ae5b00303a 100644 --- a/data-otservbr-global/monster/demons/hellfire_fighter.lua +++ b/data-otservbr-global/monster/demons/hellfire_fighter.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Hellfire Fighter") local monster = {} monster.description = "a hellfire fighter" -monster.experience = 3400 +monster.experience = 3800 monster.outfit = { lookType = 243, lookHead = 0, diff --git a/data-otservbr-global/monster/elementals/cliff_strider.lua b/data-otservbr-global/monster/elementals/cliff_strider.lua index 2690f356f23..2e143d42796 100644 --- a/data-otservbr-global/monster/elementals/cliff_strider.lua +++ b/data-otservbr-global/monster/elementals/cliff_strider.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Cliff Strider") local monster = {} monster.description = "a cliff strider" -monster.experience = 5700 +monster.experience = 7100 monster.outfit = { lookType = 497, lookHead = 0, @@ -119,7 +119,7 @@ monster.attacks = { { name = "cliff strider skill reducer", interval = 2000, chance = 10, target = false }, { name = "cliff strider electrify", interval = 2000, chance = 15, range = 1, target = false }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -1000, length = 6, spread = 0, effect = CONST_ME_GROUNDSHAKER, target = false }, - { name = "combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, radius = 4, effect = CONST_ME_YELLOWENERGY, target = false }, + { name = "combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -100, maxDamage = -300, radius = 4, effect = CONST_ME_YELLOWENERGY, target = false }, } monster.defenses = { @@ -130,7 +130,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 10 }, - { type = COMBAT_ENERGYDAMAGE, percent = 100 }, + { type = COMBAT_ENERGYDAMAGE, percent = 5 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 20 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, diff --git a/data-otservbr-global/monster/elementals/earth_elemental.lua b/data-otservbr-global/monster/elementals/earth_elemental.lua index f71d6a7964d..4c3b3e11aa3 100644 --- a/data-otservbr-global/monster/elementals/earth_elemental.lua +++ b/data-otservbr-global/monster/elementals/earth_elemental.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Earth Elemental") local monster = {} monster.description = "an earth elemental" -monster.experience = 450 +monster.experience = 550 monster.outfit = { lookType = 301, lookHead = 0, @@ -117,7 +117,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 85 }, + { type = COMBAT_ICEDAMAGE, percent = 5 }, { type = COMBAT_HOLYDAMAGE, percent = 50 }, { type = COMBAT_DEATHDAMAGE, percent = 40 }, } diff --git a/data-otservbr-global/monster/elementals/high_voltage_elemental.lua b/data-otservbr-global/monster/elementals/high_voltage_elemental.lua index ca99e57527e..3d6806a707b 100644 --- a/data-otservbr-global/monster/elementals/high_voltage_elemental.lua +++ b/data-otservbr-global/monster/elementals/high_voltage_elemental.lua @@ -102,7 +102,7 @@ monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 35 }, { type = COMBAT_ENERGYDAMAGE, percent = 100 }, { type = COMBAT_EARTHDAMAGE, percent = -15 }, - { type = COMBAT_FIREDAMAGE, percent = 100 }, + { type = COMBAT_FIREDAMAGE, percent = -100 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/elementals/ironblight.lua b/data-otservbr-global/monster/elementals/ironblight.lua index 593069318ed..7cb7c7c58fc 100644 --- a/data-otservbr-global/monster/elementals/ironblight.lua +++ b/data-otservbr-global/monster/elementals/ironblight.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Ironblight") local monster = {} monster.description = "an ironblight" -monster.experience = 4400 +monster.experience = 5400 monster.outfit = { lookType = 498, lookHead = 0, diff --git a/data-otservbr-global/monster/elementals/massive_earth_elemental.lua b/data-otservbr-global/monster/elementals/massive_earth_elemental.lua index e894319b6ec..1b131e7c7ae 100644 --- a/data-otservbr-global/monster/elementals/massive_earth_elemental.lua +++ b/data-otservbr-global/monster/elementals/massive_earth_elemental.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Massive Earth Elemental") local monster = {} monster.description = "a massive earth elemental" -monster.experience = 950 +monster.experience = 1100 monster.outfit = { lookType = 285, lookHead = 0, @@ -119,7 +119,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 100 }, + { type = COMBAT_ICEDAMAGE, percent = 15 }, { type = COMBAT_HOLYDAMAGE, percent = 50 }, { type = COMBAT_DEATHDAMAGE, percent = 45 }, } diff --git a/data-otservbr-global/monster/elementals/sulphur_spouter.lua b/data-otservbr-global/monster/elementals/sulphur_spouter.lua index 6f574cc0a07..79ebcf8db4b 100644 --- a/data-otservbr-global/monster/elementals/sulphur_spouter.lua +++ b/data-otservbr-global/monster/elementals/sulphur_spouter.lua @@ -105,7 +105,7 @@ monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 0 }, { type = COMBAT_ENERGYDAMAGE, percent = 0 }, { type = COMBAT_EARTHDAMAGE, percent = 0 }, - { type = COMBAT_FIREDAMAGE, percent = 100 }, + { type = COMBAT_FIREDAMAGE, percent = 25 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/humanoids/lost_basher.lua b/data-otservbr-global/monster/humanoids/lost_basher.lua index e19aef97f78..f8866bdd177 100644 --- a/data-otservbr-global/monster/humanoids/lost_basher.lua +++ b/data-otservbr-global/monster/humanoids/lost_basher.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Lost Basher") local monster = {} monster.description = "a lost basher" -monster.experience = 1800 +monster.experience = 2300 monster.outfit = { lookType = 538, lookHead = 0, @@ -61,7 +61,7 @@ monster.flags = { healthHidden = false, isBlockable = false, canWalkOnEnergy = false, - canWalkOnFire = false, + canWalkOnFire = true, canWalkOnPoison = true, } @@ -126,7 +126,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 20 }, + { type = COMBAT_ICEDAMAGE, percent = 0 }, { type = COMBAT_HOLYDAMAGE, percent = 0 }, { type = COMBAT_DEATHDAMAGE, percent = 15 }, } diff --git a/data-otservbr-global/monster/humanoids/lost_berserker.lua b/data-otservbr-global/monster/humanoids/lost_berserker.lua index cd48787df95..cbc7012ff95 100644 --- a/data-otservbr-global/monster/humanoids/lost_berserker.lua +++ b/data-otservbr-global/monster/humanoids/lost_berserker.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Lost Berserker") local monster = {} monster.description = "a lost berserker" -monster.experience = 4400 +monster.experience = 4800 monster.outfit = { lookType = 496, lookHead = 0, @@ -111,27 +111,25 @@ monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -501 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -300, range = 7, shootEffect = CONST_ANI_WHIRLWINDAXE, target = false }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_PHYSICALDAMAGE, minDamage = 0, maxDamage = -250, range = 7, radius = 3, shootEffect = CONST_ANI_EXPLOSION, effect = CONST_ME_EXPLOSIONAREA, target = true }, - { name = "combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, radius = 5, effect = CONST_ME_MAGIC_RED, target = false }, + { name = "combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -50, maxDamage = -100, radius = 5, effect = CONST_ME_MAGIC_RED, target = false }, { name = "speed", interval = 2000, chance = 10, speedChange = -800, radius = 2, effect = CONST_ME_MAGIC_RED, target = false, duration = 20000 }, - { name = "drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_STUN, target = true, duration = 6000 }, } monster.defenses = { defense = 40, armor = 80, mitigation = 2.40, - { name = "invisible", interval = 2000, chance = 5, effect = CONST_ME_TELEPORT }, } monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 20 }, - { type = COMBAT_ENERGYDAMAGE, percent = 17 }, + { type = COMBAT_ENERGYDAMAGE, percent = 100 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 10 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 40 }, + { type = COMBAT_ICEDAMAGE, percent = 10 }, { type = COMBAT_HOLYDAMAGE, percent = 0 }, { type = COMBAT_DEATHDAMAGE, percent = 15 }, } @@ -139,7 +137,7 @@ monster.elements = { monster.immunities = { { type = "paralyze", condition = true }, { type = "outfit", condition = false }, - { type = "invisible", condition = true }, + { type = "invisible", condition = false }, { type = "bleed", condition = false }, } diff --git a/data-otservbr-global/monster/humanoids/lost_husher.lua b/data-otservbr-global/monster/humanoids/lost_husher.lua index d8167f9710d..419bae1ab96 100644 --- a/data-otservbr-global/monster/humanoids/lost_husher.lua +++ b/data-otservbr-global/monster/humanoids/lost_husher.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Lost Husher") local monster = {} monster.description = "a lost husher" -monster.experience = 1800 +monster.experience = 1100 monster.outfit = { lookType = 537, lookHead = 0, @@ -61,7 +61,7 @@ monster.flags = { healthHidden = false, isBlockable = false, canWalkOnEnergy = false, - canWalkOnFire = false, + canWalkOnFire = true, canWalkOnPoison = true, } @@ -103,7 +103,6 @@ monster.loot = { monster.attacks = { { name = "combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -300, length = 6, spread = 0, effect = CONST_ME_BLACKSMOKE, target = false }, - { name = "combat", interval = 2000, chance = 10, type = COMBAT_MANADRAIN, minDamage = -150, maxDamage = -250, radius = 5, effect = CONST_ME_BLACKSMOKE, target = false }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_DEATHDAMAGE, minDamage = -150, maxDamage = -200, range = 7, shootEffect = CONST_ANI_SUDDENDEATH, effect = CONST_ME_MORTAREA, target = false }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -150, maxDamage = -250, range = 7, radius = 2, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_MAGIC_GREEN, target = true }, { name = "drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_SOUND_RED, target = false, duration = 6000 }, @@ -125,7 +124,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 15 }, + { type = COMBAT_ICEDAMAGE, percent = 0 }, { type = COMBAT_HOLYDAMAGE, percent = -10 }, { type = COMBAT_DEATHDAMAGE, percent = 20 }, } @@ -133,7 +132,7 @@ monster.elements = { monster.immunities = { { type = "paralyze", condition = true }, { type = "outfit", condition = false }, - { type = "invisible", condition = true }, + { type = "invisible", condition = false }, { type = "bleed", condition = false }, } diff --git a/data-otservbr-global/monster/humanoids/lost_thrower.lua b/data-otservbr-global/monster/humanoids/lost_thrower.lua index c2a87f0d551..21a14bce085 100644 --- a/data-otservbr-global/monster/humanoids/lost_thrower.lua +++ b/data-otservbr-global/monster/humanoids/lost_thrower.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Lost Thrower") local monster = {} monster.description = "a lost thrower" -monster.experience = 1200 +monster.experience = 1500 monster.outfit = { lookType = 539, lookHead = 0, @@ -61,7 +61,7 @@ monster.flags = { healthHidden = false, isBlockable = false, canWalkOnEnergy = false, - canWalkOnFire = false, + canWalkOnFire = true, canWalkOnPoison = true, } @@ -117,7 +117,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 15 }, + { type = COMBAT_ICEDAMAGE, percent = -5 }, { type = COMBAT_HOLYDAMAGE, percent = 0 }, { type = COMBAT_DEATHDAMAGE, percent = 10 }, } diff --git a/data-otservbr-global/monster/magicals/armadile.lua b/data-otservbr-global/monster/magicals/armadile.lua index beca89510f4..98665845d28 100644 --- a/data-otservbr-global/monster/magicals/armadile.lua +++ b/data-otservbr-global/monster/magicals/armadile.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Armadile") local monster = {} monster.description = "an armadile" -monster.experience = 2900 +monster.experience = 3200 monster.outfit = { lookType = 487, lookHead = 0, @@ -56,8 +56,8 @@ monster.flags = { canPushItems = false, canPushCreatures = true, staticAttackChance = 90, - targetDistance = 4, - runHealth = 300, + targetDistance = 1, + runHealth = 0, healthHidden = false, isBlockable = false, canWalkOnEnergy = false, @@ -102,9 +102,7 @@ monster.loot = { monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -150 }, - { name = "drunk", interval = 2000, chance = 15, radius = 4, effect = CONST_ME_FIREAREA, target = true, duration = 5000 }, - { name = "combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = -430, maxDamage = -550, range = 7, effect = CONST_ME_MAGIC_BLUE, target = false }, - -- poison + { name = "drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_FIREAREA, target = true, duration = 5000 }, { name = "condition", type = CONDITION_POISON, interval = 2000, chance = 15, minDamage = -200, maxDamage = -400, radius = 4, effect = CONST_ME_POISONAREA, target = false }, } @@ -112,14 +110,13 @@ monster.defenses = { defense = 25, armor = 66, mitigation = 1.96, - { name = "invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_RED }, } monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 5 }, { type = COMBAT_ENERGYDAMAGE, percent = 15 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, - { type = COMBAT_FIREDAMAGE, percent = 20 }, + { type = COMBAT_FIREDAMAGE, percent = 0 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/magicals/choking_fear.lua b/data-otservbr-global/monster/magicals/choking_fear.lua index 16361bab0e9..604ca5cdaa6 100644 --- a/data-otservbr-global/monster/magicals/choking_fear.lua +++ b/data-otservbr-global/monster/magicals/choking_fear.lua @@ -124,7 +124,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 10 }, - { type = COMBAT_ENERGYDAMAGE, percent = 15 }, + { type = COMBAT_ENERGYDAMAGE, percent = 2 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 100 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, diff --git a/data-otservbr-global/monster/magicals/phantasm.lua b/data-otservbr-global/monster/magicals/phantasm.lua index 9dc266f8bb3..36c0baed405 100644 --- a/data-otservbr-global/monster/magicals/phantasm.lua +++ b/data-otservbr-global/monster/magicals/phantasm.lua @@ -70,7 +70,7 @@ monster.light = { monster.summon = { maxSummons = 4, summons = { - { name = "Phantasm Summon", chance = 20, interval = 2000, count = 4 }, + { name = "Phantasm Summon", chance = 35, interval = 2000, count = 4 }, }, } diff --git a/data-otservbr-global/monster/magicals/retching_horror.lua b/data-otservbr-global/monster/magicals/retching_horror.lua index a6814343eaf..0479a7cb368 100644 --- a/data-otservbr-global/monster/magicals/retching_horror.lua +++ b/data-otservbr-global/monster/magicals/retching_horror.lua @@ -113,7 +113,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 5 }, - { type = COMBAT_ENERGYDAMAGE, percent = 10 }, + { type = COMBAT_ENERGYDAMAGE, percent = -3 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 85 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, diff --git a/data-otservbr-global/monster/mammals/mutated_bat.lua b/data-otservbr-global/monster/mammals/mutated_bat.lua index 211ca62d2ad..dfea480341b 100644 --- a/data-otservbr-global/monster/mammals/mutated_bat.lua +++ b/data-otservbr-global/monster/mammals/mutated_bat.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Mutated Bat") local monster = {} monster.description = "a mutated bat" -monster.experience = 615 +monster.experience = 750 monster.outfit = { lookType = 307, lookHead = 0, diff --git a/data-otservbr-global/monster/plants/hideous_fungus.lua b/data-otservbr-global/monster/plants/hideous_fungus.lua index a80ba080fd7..275adb03b2f 100644 --- a/data-otservbr-global/monster/plants/hideous_fungus.lua +++ b/data-otservbr-global/monster/plants/hideous_fungus.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Hideous Fungus") local monster = {} monster.description = "a hideous fungus" -monster.experience = 2900 +monster.experience = 3700 monster.outfit = { lookType = 499, lookHead = 0, @@ -57,7 +57,7 @@ monster.flags = { canPushCreatures = true, staticAttackChance = 90, targetDistance = 4, - runHealth = 275, + runHealth = 0, healthHidden = false, isBlockable = false, canWalkOnEnergy = true, @@ -71,9 +71,9 @@ monster.light = { } monster.summon = { - maxSummons = 2, + maxSummons = 1, summons = { - { name = "humorless fungus", chance = 10, interval = 2000, count = 2 }, + { name = "humorless fungus", chance = 10, interval = 2000, count = 1 }, }, } @@ -110,7 +110,6 @@ monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -450 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -250, maxDamage = -430, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = false }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_ICEDAMAGE, minDamage = -250, maxDamage = -550, length = 8, spread = 0, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEAREA, target = false }, - { name = "speed", interval = 2000, chance = 10, speedChange = -600, radius = 1, effect = CONST_ME_MAGIC_RED, target = true, duration = 60000 }, { name = "drunk", interval = 2000, chance = 10, range = 7, radius = 5, shootEffect = CONST_ANI_SMALLSTONE, effect = CONST_ME_STUN, target = true, duration = 4000 }, -- poison { name = "condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -640, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false }, @@ -121,14 +120,14 @@ monster.defenses = { armor = 60, mitigation = 1.74, { name = "combat", interval = 2000, chance = 15, type = COMBAT_HEALING, minDamage = 275, maxDamage = 350, effect = CONST_ME_MAGIC_BLUE, target = false }, - { name = "invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE }, + { name = "invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE, duration = 2000 }, } monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 0 }, { type = COMBAT_ENERGYDAMAGE, percent = 15 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, - { type = COMBAT_FIREDAMAGE, percent = 5 }, + { type = COMBAT_FIREDAMAGE, percent = -5 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/plants/humongous_fungus.lua b/data-otservbr-global/monster/plants/humongous_fungus.lua index 942684e732c..09f301a6a59 100644 --- a/data-otservbr-global/monster/plants/humongous_fungus.lua +++ b/data-otservbr-global/monster/plants/humongous_fungus.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Humongous Fungus") local monster = {} monster.description = "a humongous fungus" -monster.experience = 2600 +monster.experience = 2900 monster.outfit = { lookType = 488, lookHead = 0, @@ -104,7 +104,7 @@ monster.loot = { monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -330 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_EARTHDAMAGE, minDamage = -180, maxDamage = -350, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = false }, - { name = "poisonfield", interval = 2000, chance = 20, radius = 4, target = false }, + { name = "poisonfield", interval = 2000, chance = 10, radius = 4, target = false }, -- poison { name = "condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -500, maxDamage = -1000, length = 8, spread = 0, effect = CONST_ME_GREEN_RINGS, target = false }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_LIFEDRAIN, minDamage = -130, maxDamage = -260, length = 5, spread = 0, effect = CONST_ME_MAGIC_RED, target = false }, @@ -117,14 +117,13 @@ monster.defenses = { armor = 70, mitigation = 2.02, { name = "combat", interval = 2000, chance = 10, type = COMBAT_HEALING, minDamage = 225, maxDamage = 380, effect = CONST_ME_MAGIC_BLUE, target = false }, - { name = "invisible", interval = 2000, chance = 15, effect = CONST_ME_MAGIC_BLUE }, } monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 0 }, { type = COMBAT_ENERGYDAMAGE, percent = 15 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, - { type = COMBAT_FIREDAMAGE, percent = 5 }, + { type = COMBAT_FIREDAMAGE, percent = -10 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, diff --git a/data-otservbr-global/monster/quests/bigfoots_burden/bosses/abyssador.lua b/data-otservbr-global/monster/quests/bigfoots_burden/bosses/abyssador.lua index 24c993fda5b..1ca0ff1ca75 100644 --- a/data-otservbr-global/monster/quests/bigfoots_burden/bosses/abyssador.lua +++ b/data-otservbr-global/monster/quests/bigfoots_burden/bosses/abyssador.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Abyssador") local monster = {} monster.description = "Abyssador" -monster.experience = 50000 +monster.experience = 400000 monster.outfit = { lookType = 495, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/bigfoots_burden/bosses/gnomevil.lua b/data-otservbr-global/monster/quests/bigfoots_burden/bosses/gnomevil.lua index cd287d83709..8d410c85d26 100644 --- a/data-otservbr-global/monster/quests/bigfoots_burden/bosses/gnomevil.lua +++ b/data-otservbr-global/monster/quests/bigfoots_burden/bosses/gnomevil.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Gnomevil") local monster = {} monster.description = "Gnomevil" -monster.experience = 45000 +monster.experience = 400000 monster.outfit = { lookType = 504, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/bigfoots_burden/humorless_fungus.lua b/data-otservbr-global/monster/quests/bigfoots_burden/humorless_fungus.lua index 19ab3230231..ead6b096fbf 100644 --- a/data-otservbr-global/monster/quests/bigfoots_burden/humorless_fungus.lua +++ b/data-otservbr-global/monster/quests/bigfoots_burden/humorless_fungus.lua @@ -13,8 +13,8 @@ monster.outfit = { lookMount = 0, } -monster.health = 2500 -monster.maxHealth = 2500 +monster.health = 1600 +monster.maxHealth = 1600 monster.race = "venom" monster.corpse = 16083 monster.speed = 115 @@ -70,17 +70,14 @@ monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -475 }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_EARTHDAMAGE, minDamage = -40, maxDamage = -197, range = 7, shootEffect = CONST_ANI_SMALLEARTH, effect = CONST_ME_SMALLPLANTS, target = true }, { name = "combat", interval = 2000, chance = 10, type = COMBAT_ICEDAMAGE, minDamage = 0, maxDamage = -525, range = 7, shootEffect = CONST_ANI_SNOWBALL, effect = CONST_ME_ICEAREA, target = true }, - -- poison { name = "condition", type = CONDITION_POISON, interval = 2000, chance = 10, minDamage = -400, maxDamage = -640, range = 7, radius = 3, effect = CONST_ME_HITBYPOISON, target = false }, - { name = "drunk", interval = 2000, chance = 10, range = 7, radius = 4, effect = CONST_ME_STUN, target = true, duration = 4000 }, } monster.defenses = { defense = 0, armor = 0, - -- mitigation = ???, { name = "combat", interval = 2000, chance = 5, type = COMBAT_HEALING, minDamage = 0, maxDamage = 230, effect = CONST_ME_MAGIC_BLUE, target = false }, - { name = "invisible", interval = 2000, chance = 10, effect = CONST_ME_MAGIC_BLUE }, + { name = "invisible", interval = 2000, chance = 5, effect = CONST_ME_MAGIC_BLUE }, } monster.elements = { diff --git a/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua b/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua index d611e78d84b..17cb6520d29 100644 --- a/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua +++ b/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_count_of_the_core.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("The Count of the Core") local monster = {} monster.description = "The Count Of The Core" -monster.experience = 40000 +monster.experience = 300000 monster.outfit = { lookType = 1046, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua b/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua index d654288c405..99053b93882 100644 --- a/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua +++ b/data-otservbr-global/monster/quests/dangerous_depth/bosses/the_duke_of_the_depths.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("The Duke of the Depths") local monster = {} monster.description = "The Duke Of The Depths" -monster.experience = 40000 +monster.experience = 300000 monster.outfit = { lookType = 1047, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua index 90b3124369a..7ad855bc88a 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ferumbras_mortal_shell.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Ferumbras Mortal Shell") local monster = {} monster.description = "Ferumbras Mortal Shell" -monster.experience = 500000 +monster.experience = 2000000 monster.outfit = { lookType = 229, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/mazoran.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/mazoran.lua index 0e0822e3d72..3f32bac95d4 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/mazoran.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/mazoran.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Mazoran") local monster = {} monster.description = "Mazoran" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 842, lookHead = 77, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/plagirath.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/plagirath.lua index 625f10cf7fc..364b4f864a8 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/plagirath.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/plagirath.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Plagirath") local monster = {} monster.description = "Plagirath" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 862, lookHead = 84, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua index 9701dc7d0f9..df016edfd84 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/ragiaz.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Ragiaz") local monster = {} monster.description = "Ragiaz" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 862, lookHead = 76, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua index 67d218c5ee0..066e22237c0 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/razzagorn.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Razzagorn") local monster = {} monster.description = "Razzagorn" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 842, lookHead = 78, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua index c0de2c0c362..72c908104af 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/shulgrax.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Shulgrax") local monster = {} monster.description = "Shulgrax" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 842, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua index 583167460e1..30b99353cdf 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/tarbaz.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Tarbaz") local monster = {} monster.description = "Tarbaz" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 842, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua index 5a441ff10f1..03fa92d3394 100644 --- a/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua +++ b/data-otservbr-global/monster/quests/ferumbras_ascendant/bosses/zamulosh.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Zamulosh") local monster = {} monster.description = "Zamulosh" -monster.experience = 250000 +monster.experience = 500000 monster.outfit = { lookType = 862, lookHead = 16, diff --git a/data-otservbr-global/monster/quests/in_service_of_yalahar/inky.lua b/data-otservbr-global/monster/quests/in_service_of_yalahar/inky.lua index 49025f4c6c4..bbc58881ee4 100644 --- a/data-otservbr-global/monster/quests/in_service_of_yalahar/inky.lua +++ b/data-otservbr-global/monster/quests/in_service_of_yalahar/inky.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Inky") local monster = {} monster.description = "Inky" -monster.experience = 250 +monster.experience = 700 monster.outfit = { lookType = 46, lookHead = 0, diff --git a/data-otservbr-global/monster/quests/in_service_of_yalahar/sharptooth.lua b/data-otservbr-global/monster/quests/in_service_of_yalahar/sharptooth.lua index 583df08b8b5..0325642344c 100644 --- a/data-otservbr-global/monster/quests/in_service_of_yalahar/sharptooth.lua +++ b/data-otservbr-global/monster/quests/in_service_of_yalahar/sharptooth.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Sharptooth") local monster = {} monster.description = "Sharptooth" -monster.experience = 1600 +monster.experience = 3000 monster.outfit = { lookType = 20, lookHead = 0, diff --git a/data-otservbr-global/monster/reptiles/seacrest_serpent.lua b/data-otservbr-global/monster/reptiles/seacrest_serpent.lua index 9be39aaa571..04b7dba7416 100644 --- a/data-otservbr-global/monster/reptiles/seacrest_serpent.lua +++ b/data-otservbr-global/monster/reptiles/seacrest_serpent.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Seacrest Serpent") local monster = {} monster.description = "a seacrest serpent" -monster.experience = 2600 +monster.experience = 2900 monster.outfit = { lookType = 675, lookHead = 0, diff --git a/data-otservbr-global/monster/reptiles/young_sea_serpent.lua b/data-otservbr-global/monster/reptiles/young_sea_serpent.lua index 961ff8204c6..98e8744b7b1 100644 --- a/data-otservbr-global/monster/reptiles/young_sea_serpent.lua +++ b/data-otservbr-global/monster/reptiles/young_sea_serpent.lua @@ -108,7 +108,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = -20 }, { type = COMBAT_ENERGYDAMAGE, percent = -10 }, - { type = COMBAT_EARTHDAMAGE, percent = 100 }, + { type = COMBAT_EARTHDAMAGE, percent = -5 }, { type = COMBAT_FIREDAMAGE, percent = 30 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, diff --git a/data-otservbr-global/monster/undeads/betrayed_wraith.lua b/data-otservbr-global/monster/undeads/betrayed_wraith.lua index 0c0648acda5..201887a7712 100644 --- a/data-otservbr-global/monster/undeads/betrayed_wraith.lua +++ b/data-otservbr-global/monster/undeads/betrayed_wraith.lua @@ -112,7 +112,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 0 }, - { type = COMBAT_ENERGYDAMAGE, percent = 100 }, + { type = COMBAT_ENERGYDAMAGE, percent = 10 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 100 }, { type = COMBAT_LIFEDRAIN, percent = 100 }, diff --git a/data-otservbr-global/monster/undeads/blightwalker.lua b/data-otservbr-global/monster/undeads/blightwalker.lua index 28706adeb50..d900484b19f 100644 --- a/data-otservbr-global/monster/undeads/blightwalker.lua +++ b/data-otservbr-global/monster/undeads/blightwalker.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Blightwalker") local monster = {} monster.description = "a blightwalker" -monster.experience = 5850 +monster.experience = 6400 monster.outfit = { lookType = 246, lookHead = 0, @@ -108,9 +108,8 @@ monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -490 }, { name = "combat", interval = 2000, chance = 20, type = COMBAT_EARTHDAMAGE, minDamage = -220, maxDamage = -405, range = 7, radius = 1, shootEffect = CONST_ANI_POISON, target = true }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -65, maxDamage = -135, radius = 4, effect = CONST_ME_MAGIC_GREEN, target = false }, - { name = "drunk", interval = 2000, chance = 10, radius = 3, effect = CONST_ME_HITBYPOISON, target = false, duration = 5000 }, { name = "blightwalker curse", interval = 2000, chance = 15, target = false }, - { name = "speed", interval = 2000, chance = 15, speedChange = -300, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 30000 }, + { name = "speed", interval = 2000, chance = 10, speedChange = -300, range = 7, shootEffect = CONST_ANI_POISON, target = true, duration = 15000 }, } monster.defenses = { @@ -127,7 +126,7 @@ monster.elements = { { type = COMBAT_LIFEDRAIN, percent = 0 }, { type = COMBAT_MANADRAIN, percent = 0 }, { type = COMBAT_DROWNDAMAGE, percent = 0 }, - { type = COMBAT_ICEDAMAGE, percent = 50 }, + { type = COMBAT_ICEDAMAGE, percent = 15 }, { type = COMBAT_HOLYDAMAGE, percent = -30 }, { type = COMBAT_DEATHDAMAGE, percent = 100 }, } diff --git a/data-otservbr-global/monster/undeads/crypt_warrior.lua b/data-otservbr-global/monster/undeads/crypt_warrior.lua index 5de0ab637ba..dad0cbe7529 100644 --- a/data-otservbr-global/monster/undeads/crypt_warrior.lua +++ b/data-otservbr-global/monster/undeads/crypt_warrior.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Crypt Warrior") local monster = {} monster.description = "a crypt warrior" -monster.experience = 4200 +monster.experience = 6050 monster.outfit = { lookType = 298, lookHead = 0, diff --git a/data-otservbr-global/monster/undeads/falcon_knight.lua b/data-otservbr-global/monster/undeads/falcon_knight.lua index 54a23130758..2e2ac28a1fe 100644 --- a/data-otservbr-global/monster/undeads/falcon_knight.lua +++ b/data-otservbr-global/monster/undeads/falcon_knight.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Falcon Knight") local monster = {} monster.description = "a falcon knight" -monster.experience = 5985 +monster.experience = 6300 monster.outfit = { lookType = 1071, lookHead = 57, diff --git a/data-otservbr-global/monster/undeads/falcon_paladin.lua b/data-otservbr-global/monster/undeads/falcon_paladin.lua index 799143fe943..cc6a41571e4 100644 --- a/data-otservbr-global/monster/undeads/falcon_paladin.lua +++ b/data-otservbr-global/monster/undeads/falcon_paladin.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Falcon Paladin") local monster = {} monster.description = "a falcon paladin" -monster.experience = 6544 +monster.experience = 6900 monster.outfit = { lookType = 1071, lookHead = 57, diff --git a/data-otservbr-global/monster/undeads/hand_of_cursed_fate.lua b/data-otservbr-global/monster/undeads/hand_of_cursed_fate.lua index b1f76414dd4..527d0708730 100644 --- a/data-otservbr-global/monster/undeads/hand_of_cursed_fate.lua +++ b/data-otservbr-global/monster/undeads/hand_of_cursed_fate.lua @@ -108,7 +108,7 @@ monster.loot = { monster.attacks = { { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -520, condition = { type = CONDITION_POISON, totalDamage = 380, interval = 4000 } }, - { name = "combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -920, range = 1, target = false }, + { name = "combat", interval = 2000, chance = 15, type = COMBAT_MANADRAIN, minDamage = 0, maxDamage = -620, range = 1, target = false }, { name = "drunk", interval = 2000, chance = 10, radius = 4, effect = CONST_ME_SMALLCLOUDS, target = false, duration = 3000 }, { name = "combat", interval = 2000, chance = 15, type = COMBAT_LIFEDRAIN, minDamage = -220, maxDamage = -880, range = 1, effect = CONST_ME_SMALLCLOUDS, target = false }, } @@ -124,7 +124,7 @@ monster.defenses = { monster.elements = { { type = COMBAT_PHYSICALDAMAGE, percent = 0 }, - { type = COMBAT_ENERGYDAMAGE, percent = 100 }, + { type = COMBAT_ENERGYDAMAGE, percent = 5 }, { type = COMBAT_EARTHDAMAGE, percent = 100 }, { type = COMBAT_FIREDAMAGE, percent = 100 }, { type = COMBAT_LIFEDRAIN, percent = 0 }, diff --git a/data-otservbr-global/monster/undeads/skeleton_elite_warrior.lua b/data-otservbr-global/monster/undeads/skeleton_elite_warrior.lua index a0cc7545b99..25ebd9c1f6d 100644 --- a/data-otservbr-global/monster/undeads/skeleton_elite_warrior.lua +++ b/data-otservbr-global/monster/undeads/skeleton_elite_warrior.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Skeleton Elite Warrior") local monster = {} monster.description = "a skeleton elite warrior" -monster.experience = 4500 +monster.experience = 4800 monster.outfit = { lookType = 298, lookHead = 0, diff --git a/data-otservbr-global/monster/undeads/undead_dragon.lua b/data-otservbr-global/monster/undeads/undead_dragon.lua index 2ab63af8b77..b9039c5d914 100644 --- a/data-otservbr-global/monster/undeads/undead_dragon.lua +++ b/data-otservbr-global/monster/undeads/undead_dragon.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Undead Dragon") local monster = {} monster.description = "an undead dragon" -monster.experience = 7200 +monster.experience = 7500 monster.outfit = { lookType = 231, lookHead = 0, diff --git a/data-otservbr-global/monster/undeads/undead_elite_gladiator.lua b/data-otservbr-global/monster/undeads/undead_elite_gladiator.lua index 0f66c87cb21..10d1d5b08bc 100644 --- a/data-otservbr-global/monster/undeads/undead_elite_gladiator.lua +++ b/data-otservbr-global/monster/undeads/undead_elite_gladiator.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Undead Elite Gladiator") local monster = {} monster.description = "an undead elite gladiator" -monster.experience = 4740 +monster.experience = 5090 monster.outfit = { lookType = 306, lookHead = 0, diff --git a/data-otservbr-global/monster/vermins/cave_devourer.lua b/data-otservbr-global/monster/vermins/cave_devourer.lua index 1283ac20b81..17d89dfb176 100644 --- a/data-otservbr-global/monster/vermins/cave_devourer.lua +++ b/data-otservbr-global/monster/vermins/cave_devourer.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Cave Devourer") local monster = {} monster.description = "a cave devourer" -monster.experience = 2380 +monster.experience = 3380 monster.outfit = { lookType = 1036, lookHead = 0, @@ -88,7 +88,7 @@ monster.loot = { { name = "slime heart", chance = 13770, maxCount = 4 }, { name = "cave devourer legs", chance = 17160 }, { id = 3049, chance = 2540 }, -- stealth ring - { name = "suspicious device", chance = 420 }, + { name = "suspicious device", chance = 850 }, } monster.attacks = { diff --git a/data-otservbr-global/monster/vermins/chasm_spawn.lua b/data-otservbr-global/monster/vermins/chasm_spawn.lua index 0764367a1d0..9f27f57b006 100644 --- a/data-otservbr-global/monster/vermins/chasm_spawn.lua +++ b/data-otservbr-global/monster/vermins/chasm_spawn.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Chasm Spawn") local monster = {} monster.description = "a chasm spawn" -monster.experience = 2700 +monster.experience = 3600 monster.outfit = { lookType = 1037, lookHead = 0, @@ -89,7 +89,7 @@ monster.loot = { { name = "green crystal shard", chance = 7850 }, { name = "violet crystal shard", chance = 4690 }, { name = "mushroom backpack", chance = 610 }, - { name = "suspicious device", chance = 520 }, + { name = "suspicious device", chance = 850 }, } monster.attacks = { diff --git a/data-otservbr-global/monster/vermins/deepworm.lua b/data-otservbr-global/monster/vermins/deepworm.lua index 91b2ded8752..21775b2c673 100644 --- a/data-otservbr-global/monster/vermins/deepworm.lua +++ b/data-otservbr-global/monster/vermins/deepworm.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Deepworm") local monster = {} monster.description = "a deepworm" -monster.experience = 2300 +monster.experience = 2520 monster.outfit = { lookType = 1033, lookHead = 0, diff --git a/data-otservbr-global/monster/vermins/diremaw.lua b/data-otservbr-global/monster/vermins/diremaw.lua index b89c47c99e7..fd74c4e2be6 100644 --- a/data-otservbr-global/monster/vermins/diremaw.lua +++ b/data-otservbr-global/monster/vermins/diremaw.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Diremaw") local monster = {} monster.description = "a diremaw" -monster.experience = 2500 +monster.experience = 2770 monster.outfit = { lookType = 1034, lookHead = 0, diff --git a/data-otservbr-global/monster/vermins/drillworm.lua b/data-otservbr-global/monster/vermins/drillworm.lua index 3cf92fce18a..a435dc16ca3 100644 --- a/data-otservbr-global/monster/vermins/drillworm.lua +++ b/data-otservbr-global/monster/vermins/drillworm.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Drillworm") local monster = {} monster.description = "a drillworm" -monster.experience = 858 +monster.experience = 1200 monster.outfit = { lookType = 527, lookHead = 0, diff --git a/data-otservbr-global/monster/vermins/tunnel_tyrant.lua b/data-otservbr-global/monster/vermins/tunnel_tyrant.lua index f8e3b7bfb03..c2b8eb2df90 100644 --- a/data-otservbr-global/monster/vermins/tunnel_tyrant.lua +++ b/data-otservbr-global/monster/vermins/tunnel_tyrant.lua @@ -2,7 +2,7 @@ local mType = Game.createMonsterType("Tunnel Tyrant") local monster = {} monster.description = "a tunnel tyrant" -monster.experience = 3400 +monster.experience = 4420 monster.outfit = { lookType = 1035, lookHead = 0, @@ -87,7 +87,7 @@ monster.loot = { { name = "crystal mace", chance = 1580 }, { id = 23508, chance = 3010 }, -- energy vein { name = "crystalline armor", chance = 860 }, - { name = "suspicious device", chance = 1290 }, + { name = "suspicious device", chance = 1850 }, } monster.attacks = { diff --git a/data-otservbr-global/scripts/actions/bosses_levers/grand_,master_oberon.lua b/data-otservbr-global/scripts/actions/bosses_levers/grand_master_oberon.lua similarity index 100% rename from data-otservbr-global/scripts/actions/bosses_levers/grand_,master_oberon.lua rename to data-otservbr-global/scripts/actions/bosses_levers/grand_master_oberon.lua From f56af162772371b5a109e2514ff12341b7693148 Mon Sep 17 00:00:00 2001 From: Felipe Paluco <87909998+FelipePaluco@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:37:27 -0300 Subject: [PATCH 10/15] fix: sam sellable missing items (#2685) --- data-otservbr-global/npc/sam.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/data-otservbr-global/npc/sam.lua b/data-otservbr-global/npc/sam.lua index cd3a517c147..fdca8c02f01 100644 --- a/data-otservbr-global/npc/sam.lua +++ b/data-otservbr-global/npc/sam.lua @@ -210,6 +210,7 @@ npcConfig.shop = { { itemName = "legion helmet", clientId = 3374, sell = 22 }, { itemName = "longsword", clientId = 3285, buy = 160, sell = 51 }, { itemName = "mace", clientId = 3286, buy = 90, sell = 30 }, + { itemName = "magic plate armor", clientId = 3366, sell = 6400 }, { itemName = "morning star", clientId = 3282, buy = 430, sell = 100 }, { itemName = "orcish axe", clientId = 3316, sell = 350 }, { itemName = "plate armor", clientId = 3357, buy = 1200, sell = 400 }, @@ -227,16 +228,16 @@ npcConfig.shop = { { itemName = "steel shield", clientId = 3409, buy = 240, sell = 80 }, { itemName = "studded armor", clientId = 3378, buy = 90, sell = 25 }, { itemName = "studded club", clientId = 3336, sell = 10 }, - { itemName = "studded helmet", clientId = 3376, buy = 63 }, - { itemName = "studded legs", clientId = 3362, buy = 50 }, - { itemName = "studded shield", clientId = 3426, buy = 50 }, - { itemName = "sword", clientId = 3264, buy = 85 }, - { itemName = "throwing knife", clientId = 3298, buy = 25 }, - { itemName = "two handed sword", clientId = 3265, buy = 950 }, - { itemName = "viking helmet", clientId = 3367, buy = 265 }, - { itemName = "viking shield", clientId = 3431, buy = 260 }, - { itemName = "war hammer", clientId = 3279, buy = 10000 }, - { itemName = "wooden shield", clientId = 3412, buy = 15 }, + { itemName = "studded helmet", clientId = 3376, buy = 63, sell = 20 }, + { itemName = "studded legs", clientId = 3362, buy = 50, sell = 15 }, + { itemName = "studded shield", clientId = 3426, buy = 50, sell = 16 }, + { itemName = "sword", clientId = 3264, buy = 85, sell = 25 }, + { itemName = "throwing knife", clientId = 3298, buy = 25, sell = 2 }, + { itemName = "two handed sword", clientId = 3265, buy = 950, sell = 450 }, + { itemName = "viking helmet", clientId = 3367, buy = 265, sell = 66 }, + { itemName = "viking shield", clientId = 3431, buy = 260, sell = 85 }, + { itemName = "war hammer", clientId = 3279, buy = 10000, sell = 470 }, + { itemName = "wooden shield", clientId = 3412, buy = 15, sell = 5 }, } -- On buy npc shop message npcType.onBuyItem = function(npc, player, itemId, subType, amount, ignore, inBackpacks, totalCost) From 552eaefeca2530fee2194da37498fc21083ce2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Lu=C3=ADs=20Lucarelo=20Lamonato?= Date: Tue, 11 Jun 2024 10:39:55 -0300 Subject: [PATCH 11/15] fix: mispelled storages in freequests.lua and add some quests (#2658) --- .../creaturescripts/customs/freequests.lua | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/data-otservbr-global/scripts/creaturescripts/customs/freequests.lua b/data-otservbr-global/scripts/creaturescripts/customs/freequests.lua index ad0e8d49b73..6f7e00e77f6 100644 --- a/data-otservbr-global/scripts/creaturescripts/customs/freequests.lua +++ b/data-otservbr-global/scripts/creaturescripts/customs/freequests.lua @@ -60,15 +60,15 @@ local questTable = { { storage = Storage.InServiceofYalahar.DoorToMatrix, storageValue = 1 }, { storage = Storage.InServiceofYalahar.DoorToQuara, storageValue = 1 }, { storage = Storage.CultsOfTibia.Questline, storageValue = 7 }, - { storage = Storage.CultsOfTibia.Minotaurs.jamesfrancisTask, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Minotaurs.JamesfrancisTask, storageValue = 1 }, { storage = Storage.CultsOfTibia.Minotaurs.Mission, storageValue = 1 }, - { storage = Storage.CultsOfTibia.Minotaurs.bossTimer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Minotaurs.BossTimer, storageValue = 1 }, { storage = Storage.CultsOfTibia.MotA.Mission, storageValue = 1 }, - { storage = Storage.CultsOfTibia.MotA.Pedra1, storageValue = 1 }, - { storage = Storage.CultsOfTibia.MotA.Pedra2, storageValue = 1 }, - { storage = Storage.CultsOfTibia.MotA.Pedra3, storageValue = 1 }, - { storage = Storage.CultsOfTibia.MotA.Respostas, storageValue = 1 }, - { storage = Storage.CultsOfTibia.MotA.Perguntaid, storageValue = 1 }, + { storage = Storage.CultsOfTibia.MotA.Stone1, storageValue = 1 }, + { storage = Storage.CultsOfTibia.MotA.Stone2, storageValue = 1 }, + { storage = Storage.CultsOfTibia.MotA.Stone3, storageValue = 1 }, + { storage = Storage.CultsOfTibia.MotA.Answer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.MotA.QuestionId, storageValue = 1 }, { storage = Storage.CultsOfTibia.Barkless.Mission, storageValue = 1 }, { storage = Storage.CultsOfTibia.Barkless.sulphur, storageValue = 4 }, { storage = Storage.CultsOfTibia.Barkless.Tar, storageValue = 3 }, @@ -76,19 +76,19 @@ local questTable = { { storage = Storage.CultsOfTibia.Barkless.Objects, storageValue = 1 }, { storage = Storage.CultsOfTibia.Barkless.Temp, storageValue = 1 }, { storage = Storage.CultsOfTibia.Orcs.Mission, storageValue = 1 }, - { storage = Storage.CultsOfTibia.Orcs.lookType, storageValue = 1 }, - { storage = Storage.CultsOfTibia.Orcs.bossTimer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Orcs.LookType, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Orcs.BossTimer, storageValue = 1 }, { storage = Storage.CultsOfTibia.Life.Mission, storageValue = 7 }, - { storage = Storage.CultsOfTibia.Life.bossTimer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Life.BossTimer, storageValue = 1 }, { storage = Storage.CultsOfTibia.Humans.Mission, storageValue = 1 }, { storage = Storage.CultsOfTibia.Humans.Vaporized, storageValue = 1 }, { storage = Storage.CultsOfTibia.Humans.Decaying, storageValue = 1 }, - { storage = Storage.CultsOfTibia.Humans.bossTimer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Humans.BossTimer, storageValue = 1 }, { storage = Storage.CultsOfTibia.Misguided.Mission, storageValue = 1 }, { storage = Storage.CultsOfTibia.Misguided.Monsters, storageValue = 1 }, { storage = Storage.CultsOfTibia.Misguided.Exorcisms, storageValue = 1 }, { storage = Storage.CultsOfTibia.Misguided.Time, storageValue = 1 }, - { storage = Storage.CultsOfTibia.Misguided.bossTimer, storageValue = 1 }, + { storage = Storage.CultsOfTibia.Misguided.BossTimer, storageValue = 1 }, { storage = Storage.CultsOfTibia.Minotaurs.EntranceAccessDoor, storageValue = 1 }, { storage = Storage.CultsOfTibia.Minotaurs.AccessDoor, storageValue = 1 }, { storage = Storage.ExplorerSociety.QuestLine, storageValue = 1 }, @@ -119,6 +119,7 @@ local questTable = { { storage = Storage.ForgottenKnowledge.LloydKilled, storageValue = 1 }, { storage = Storage.ForgottenKnowledge.LadyTenebrisKilled, storageValue = 1 }, { storage = Storage.ForgottenKnowledge.AccessMachine, storageValue = 1 }, + { storage = Storage.ForgottenKnowledge.AccessLavaTeleport, storageValue = 1 }, { storage = Storage.BarbarianTest.Questline, storageValue = 8 }, { storage = Storage.BarbarianTest.Mission01, storageValue = 3 }, { storage = Storage.BarbarianTest.Mission02, storageValue = 3 }, @@ -146,8 +147,8 @@ local questTable = { { storage = Storage.DjinnWar.MaridFaction.Mission02, storageValue = 2 }, { storage = Storage.DjinnWar.MaridFaction.RataMari, storageValue = 2 }, { storage = Storage.DjinnWar.MaridFaction.Mission03, storageValue = 3 }, - { storage = Storage.TheWayToYalahar.Questline, storageValue = 1 }, - { storage = Storage.SearoutesAroundYalahar.TownsCounter, storageValue = 1 }, + { storage = Storage.TheWayToYalahar.QuestLine, storageValue = 1 }, + { storage = Storage.SearoutesAroundYalahar.TownsCounter, storageValue = 5 }, { storage = Storage.SearoutesAroundYalahar.AbDendriel, storageValue = 1 }, { storage = Storage.SearoutesAroundYalahar.Darashia, storageValue = 1 }, { storage = Storage.SearoutesAroundYalahar.Venore, storageValue = 1 }, @@ -205,7 +206,7 @@ local questTable = { { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.KingTibianus, storageValue = 1 }, { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Leeland, storageValue = 1 }, { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Angus, storageValue = 1 }, - { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Wydrin, storageValue = 1 }, + { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Wyrdin, storageValue = 1 }, { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Telas, storageValue = 1 }, { storage = Storage.Quest.U8_54.TheNewFrontier.Mission05.Humgolf, storageValue = 1 }, { storage = Storage.TheShatteredIsles.DefaultStart, storageValue = 3 }, @@ -314,6 +315,7 @@ local questTable = { { storage = Storage.FerumbrasAscension.TarbazDoor, storageValue = 1 }, { storage = Storage.FerumbrasAscension.HabitatsAccess, storageValue = 1 }, { storage = Storage.FerumbrasAscension.TheLordOfTheLiceAccess, storageValue = 1 }, + { storage = Storage.FerumbrasAscension.Statue, storageValue = 1 }, { storage = Storage.Quest.U12_00.TheDreamCourts.AndrewDoor, storageValue = 1 }, @@ -372,11 +374,19 @@ local questTable = { { storage = Storage.OutfitQuest.DefaultStart, storageValue = 1 }, { storage = Storage.HeroRathleton.AccessDoor, storageValue = 1 }, - { storage = Storage.HeroRathleton.FastWay, storageValue = 1 }, + { storage = Storage.HeroRathleton.AccessTeleport1, storageValue = 1 }, + { storage = Storage.HeroRathleton.AccessTeleport2, storageValue = 1 }, + { storage = Storage.HeroRathleton.AccessTeleport3, storageValue = 1 }, -- Sea Serpent Quest { storage = Storage.Quest.U8_2.FishForASerpent.QuestLine, storageValue = 5 }, { storage = Storage.Quest.U8_2.TheHuntForTheSeaSerpent.QuestLine, storageValue = 2 }, + + --The White Raven Monastery + { storage = Storage.WhiteRavenMonastery.QuestLog, storageValue = 1 }, + { storage = Storage.WhiteRavenMonastery.Passage, storageValue = 1 }, + { storage = Storage.WhiteRavenMonastery.Diary, storageValue = 2 }, + { storage = Storage.WhiteRavenMonastery.Door, storageValue = 1 }, } -- from Position: (33201, 31762, 1) From 5d0d1c9e0947dee376461a51caa828c430521ca7 Mon Sep 17 00:00:00 2001 From: Karin Date: Wed, 12 Jun 2024 10:17:48 -0300 Subject: [PATCH 12/15] fix: prevent guests to rotate dummy (#2684) --- src/game/game.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/game.cpp b/src/game/game.cpp index 899a89549d9..fed3a3910a1 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -126,6 +126,10 @@ namespace InternalGame { if (isGuest && !isItemInGuestInventory && !item->isLadder() && !item->canBeUsedByGuests()) { return false; } + + if (isGuest && item->isDummy()) { + return false; + } } return true; From 201aa8cb940bab3c2db6779a0dee3be3ae218198 Mon Sep 17 00:00:00 2001 From: Beats Date: Wed, 12 Jun 2024 10:43:03 -0300 Subject: [PATCH 13/15] feat: shared_ptr: familiar, groups and reload: familiars, outfits (#2556) --- CMakePresets.json | 1 + data/scripts/talkactions/god/reload.lua | 3 + src/creatures/appearance/mounts/mounts.cpp | 2 +- src/creatures/appearance/outfit/outfit.cpp | 37 +++-- src/creatures/appearance/outfit/outfit.hpp | 14 +- src/creatures/players/grouping/familiars.cpp | 7 +- src/creatures/players/grouping/familiars.hpp | 5 +- src/creatures/players/grouping/groups.cpp | 4 +- src/creatures/players/grouping/groups.hpp | 4 +- src/creatures/players/player.cpp | 6 +- src/creatures/players/player.hpp | 11 +- src/game/functions/game_reload.cpp | 154 ++++++++++-------- src/game/functions/game_reload.hpp | 50 +++--- src/game/game.cpp | 4 +- src/game/game.hpp | 2 + src/io/functions/iologindata_load_player.cpp | 4 +- .../creatures/player/group_functions.cpp | 16 +- src/server/network/protocol/protocolgame.cpp | 2 +- 18 files changed, 184 insertions(+), 142 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 92ef2d33c6a..49f631e1921 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -54,6 +54,7 @@ "DEBUG_LOG": "ON", "ASAN_ENABLED": "OFF", "BUILD_STATIC_LIBRARY": "OFF", + "SPEED_UP_BUILD_UNITY": "OFF", "VCPKG_TARGET_TRIPLET": "x64-windows" } }, diff --git a/data/scripts/talkactions/god/reload.lua b/data/scripts/talkactions/god/reload.lua index 20b9431dbba..d0c0cdd45a8 100644 --- a/data/scripts/talkactions/god/reload.lua +++ b/data/scripts/talkactions/god/reload.lua @@ -7,6 +7,7 @@ local reloadTypes = { ["configuration"] = RELOAD_TYPE_CONFIG, ["core"] = RELOAD_TYPE_CORE, ["events"] = RELOAD_TYPE_EVENTS, + ["familiar"] = RELOAD_TYPE_FAMILIARS, ["global"] = RELOAD_TYPE_CORE, ["group"] = RELOAD_TYPE_GROUPS, ["groups"] = RELOAD_TYPE_GROUPS, @@ -20,6 +21,8 @@ local reloadTypes = { ["monsters"] = RELOAD_TYPE_MONSTERS, ["mount"] = RELOAD_TYPE_MOUNTS, ["mounts"] = RELOAD_TYPE_MOUNTS, + ["outfit"] = RELOAD_TYPE_OUTFITS, + ["outfits"] = RELOAD_TYPE_OUTFITS, ["npc"] = RELOAD_TYPE_NPCS, ["npcs"] = RELOAD_TYPE_NPCS, ["raid"] = RELOAD_TYPE_RAIDS, diff --git a/src/creatures/appearance/mounts/mounts.cpp b/src/creatures/appearance/mounts/mounts.cpp index 7051d04ddb8..7014d0b026b 100644 --- a/src/creatures/appearance/mounts/mounts.cpp +++ b/src/creatures/appearance/mounts/mounts.cpp @@ -29,7 +29,7 @@ bool Mounts::loadFromXml() { } for (auto mountNode : doc.child("mounts").children()) { - uint16_t lookType = pugi::cast(mountNode.attribute("clientid").value()); + auto lookType = pugi::cast(mountNode.attribute("clientid").value()); if (g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS, __FUNCTION__) && lookType != 0 && !g_game().isLookTypeRegistered(lookType)) { g_logger().warn("{} - An unregistered creature mount with id '{}' was blocked to prevent client crash.", __FUNCTION__, lookType); continue; diff --git a/src/creatures/appearance/outfit/outfit.cpp b/src/creatures/appearance/outfit/outfit.cpp index 9e96c60e756..97120659333 100644 --- a/src/creatures/appearance/outfit/outfit.cpp +++ b/src/creatures/appearance/outfit/outfit.cpp @@ -14,6 +14,10 @@ #include "utils/tools.hpp" #include "game/game.hpp" +Outfits &Outfits::getInstance() { + return inject(); +} + bool Outfits::reload() { for (auto &outfitsVector : outfits) { outfitsVector.clear(); @@ -41,7 +45,7 @@ bool Outfits::loadFromXml() { continue; } - uint16_t type = pugi::cast(attr.value()); + auto type = pugi::cast(attr.value()); if (type > PLAYERSEX_LAST) { g_logger().warn("[Outfits::loadFromXml] - Invalid outfit type {}", type); continue; @@ -53,7 +57,7 @@ bool Outfits::loadFromXml() { continue; } - if (uint16_t lookType = pugi::cast(lookTypeAttribute.value()); + if (auto lookType = pugi::cast(lookTypeAttribute.value()); g_configManager().getBoolean(WARN_UNSAFE_SCRIPTS, __FUNCTION__) && lookType != 0 && !g_game().isLookTypeRegistered(lookType)) { g_logger().warn("[Outfits::loadFromXml] An unregistered creature looktype type with id '{}' was ignored to prevent client crash.", lookType); @@ -74,7 +78,22 @@ bool Outfits::loadFromXml() { return true; } -std::shared_ptr Outfits::getOutfitByLookType(PlayerSex_t sex, uint16_t lookType) const { +std::shared_ptr Outfits::getOutfitByLookType(const std::shared_ptr &player, uint16_t lookType, bool isOppositeOutfit) const { + if (!player) { + g_logger().error("[{}] - Player not found", __FUNCTION__); + return nullptr; + } + + auto sex = player->getSex(); + if (sex != PLAYERSEX_FEMALE && sex != PLAYERSEX_MALE) { + g_logger().error("[{}] - Sex invalid or player: {}", __FUNCTION__, player->getName()); + return nullptr; + } + + if (isOppositeOutfit) { + sex = (sex == PLAYERSEX_MALE) ? PLAYERSEX_FEMALE : PLAYERSEX_MALE; + } + auto it = std::ranges::find_if(outfits[sex], [&lookType](const auto &outfit) { return outfit->lookType == lookType; }); @@ -84,15 +103,3 @@ std::shared_ptr Outfits::getOutfitByLookType(PlayerSex_t sex, uint16_t l } return nullptr; } - -/** - * Get the oposite sex equivalent outfit - * @param sex current sex - * @param lookType current looktype - * @return const pointer to the outfit or nullptr if it could not be found. - */ - -std::shared_ptr Outfits::getOpositeSexOutfitByLookType(PlayerSex_t sex, uint16_t lookType) const { - PlayerSex_t searchSex = (sex == PLAYERSEX_MALE) ? PLAYERSEX_FEMALE : PLAYERSEX_MALE; - return getOutfitByLookType(searchSex, lookType); -} diff --git a/src/creatures/appearance/outfit/outfit.hpp b/src/creatures/appearance/outfit/outfit.hpp index 30b84d1aca2..0d89a2c932d 100644 --- a/src/creatures/appearance/outfit/outfit.hpp +++ b/src/creatures/appearance/outfit/outfit.hpp @@ -12,8 +12,10 @@ #include "declarations.hpp" #include "lib/di/container.hpp" +class Player; + struct OutfitEntry { - constexpr OutfitEntry(uint16_t initLookType, uint8_t initAddons) : + constexpr explicit OutfitEntry(uint16_t initLookType, uint8_t initAddons) : lookType(initLookType), addons(initAddons) { } uint16_t lookType; @@ -42,16 +44,12 @@ struct ProtocolOutfit { class Outfits { public: - static Outfits &getInstance() { - return inject(); - } - - std::shared_ptr getOpositeSexOutfitByLookType(PlayerSex_t sex, uint16_t lookType) const; + static Outfits &getInstance(); - bool loadFromXml(); bool reload(); + bool loadFromXml(); - [[nodiscard]] std::shared_ptr getOutfitByLookType(PlayerSex_t sex, uint16_t lookType) const; + [[nodiscard]] std::shared_ptr getOutfitByLookType(const std::shared_ptr &player, uint16_t lookType, bool isOppositeOutfit = false) const; [[nodiscard]] const std::vector> &getOutfits(PlayerSex_t sex) const { return outfits[sex]; } diff --git a/src/creatures/players/grouping/familiars.cpp b/src/creatures/players/grouping/familiars.cpp index a922013f19b..6e923b823dc 100644 --- a/src/creatures/players/grouping/familiars.cpp +++ b/src/creatures/players/grouping/familiars.cpp @@ -10,10 +10,15 @@ #include "pch.hpp" #include "creatures/players/grouping/familiars.hpp" +#include "lib/di/container.hpp" #include "config/configmanager.hpp" #include "utils/pugicast.hpp" #include "utils/tools.hpp" +Familiars &Familiars::getInstance() { + return inject(); +} + bool Familiars::reload() { for (auto &familiarsVector : familiars) { familiarsVector.clear(); @@ -42,7 +47,7 @@ bool Familiars::loadFromXml() { continue; } - uint16_t vocation = pugi::cast(attr.value()); + auto vocation = pugi::cast(attr.value()); if (vocation > VOCATION_LAST) { g_logger().warn("[Familiars::loadFromXml] - Invalid familiar vocation {}", vocation); continue; diff --git a/src/creatures/players/grouping/familiars.hpp b/src/creatures/players/grouping/familiars.hpp index 8f553af9fbe..9eda7d95ba2 100644 --- a/src/creatures/players/grouping/familiars.hpp +++ b/src/creatures/players/grouping/familiars.hpp @@ -9,6 +9,7 @@ #pragma once +#include "declarations.hpp" #include "lib/di/container.hpp" struct FamiliarEntry { @@ -32,9 +33,7 @@ struct Familiar { class Familiars { public: - static Familiars &getInstance() { - return inject(); - } + static Familiars &getInstance(); bool loadFromXml(); bool reload(); diff --git a/src/creatures/players/grouping/groups.cpp b/src/creatures/players/grouping/groups.cpp index 27ae68d9fd4..937fa848f3f 100644 --- a/src/creatures/players/grouping/groups.cpp +++ b/src/creatures/players/grouping/groups.cpp @@ -43,7 +43,7 @@ PlayerFlags_t Groups::getFlagFromNumber(uint8_t value) { return magic_enum::enum_value(value); } -bool Groups::reload() const { +bool Groups::reload() { // Clear groups g_game().groups.getGroups().clear(); return g_game().groups.load(); @@ -99,7 +99,7 @@ bool Groups::load() { return true; } -std::shared_ptr Groups::getGroup(uint16_t id) { +std::shared_ptr Groups::getGroup(uint16_t id) const { if (auto it = std::find_if(groups_vector.begin(), groups_vector.end(), [id](auto group_it) { return group_it->id == id; }); diff --git a/src/creatures/players/grouping/groups.hpp b/src/creatures/players/grouping/groups.hpp index d76914e2632..af319e95772 100644 --- a/src/creatures/players/grouping/groups.hpp +++ b/src/creatures/players/grouping/groups.hpp @@ -24,9 +24,9 @@ class Groups { public: static uint8_t getFlagNumber(PlayerFlags_t playerFlags); static PlayerFlags_t getFlagFromNumber(uint8_t value); - bool reload() const; + static bool reload(); bool load(); - std::shared_ptr getGroup(uint16_t id); + [[nodiscard]] std::shared_ptr getGroup(uint16_t id) const; std::vector> &getGroups() { return groups_vector; } diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 4109eb77472..2b10c0f77ee 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -4914,7 +4914,7 @@ bool Player::canWear(uint16_t lookType, uint8_t addons) const { return true; } - const auto &outfit = Outfits::getInstance().getOutfitByLookType(sex, lookType); + const auto &outfit = Outfits::getInstance().getOutfitByLookType(getPlayer(), lookType); if (!outfit) { return false; } @@ -5001,7 +5001,7 @@ bool Player::removeOutfitAddon(uint16_t lookType, uint8_t addons) { return false; } -bool Player::getOutfitAddons(const std::shared_ptr outfit, uint8_t &addons) const { +bool Player::getOutfitAddons(const std::shared_ptr &outfit, uint8_t &addons) const { if (group->access) { addons = 3; return true; @@ -5826,7 +5826,7 @@ bool Player::toggleMount(bool mount) { return false; } - const auto &playerOutfit = Outfits::getInstance().getOutfitByLookType(getSex(), defaultOutfit.lookType); + const auto &playerOutfit = Outfits::getInstance().getOutfitByLookType(getPlayer(), defaultOutfit.lookType); if (!playerOutfit) { return false; } diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index c0761704db4..19e3af5ca9c 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -476,7 +476,12 @@ class Player final : public Creature, public Cylinder, public Bankable { return blessings[index - 1] != 0; } uint8_t getBlessingCount(uint8_t index) const { - return blessings[index - 1]; + if (index > 0 && index <= blessings.size()) { + return blessings[index - 1]; + } else { + g_logger().error("[{}] - index outside range 0-10.", __FUNCTION__); + return 0; + } } std::string getBlessingsName() const; @@ -1031,7 +1036,7 @@ class Player final : public Creature, public Cylinder, public Bankable { void addOutfit(uint16_t lookType, uint8_t addons); bool removeOutfit(uint16_t lookType); bool removeOutfitAddon(uint16_t lookType, uint8_t addons); - bool getOutfitAddons(const std::shared_ptr outfit, uint8_t &addons) const; + bool getOutfitAddons(const std::shared_ptr &outfit, uint8_t &addons) const; bool canFamiliar(uint16_t lookType) const; void addFamiliar(uint16_t lookType); @@ -2853,7 +2858,7 @@ class Player final : public Creature, public Cylinder, public Bankable { uint16_t lastStatsTrainingTime = 0; uint16_t staminaMinutes = 2520; - std::vector blessings = { 0, 0, 0, 0, 0, 0, 0, 0 }; + std::vector blessings = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint16_t maxWriteLen = 0; uint16_t baseXpGain = 100; uint16_t voucherXpBoost = 0; diff --git a/src/game/functions/game_reload.cpp b/src/game/functions/game_reload.cpp index 0fc74bcee71..d9d9eb1f449 100644 --- a/src/game/functions/game_reload.cpp +++ b/src/game/functions/game_reload.cpp @@ -22,7 +22,7 @@ GameReload::GameReload() = default; GameReload::~GameReload() = default; -bool GameReload::init(Reload_t reloadTypes) const { +bool GameReload::init(Reload_t reloadTypes) { switch (reloadTypes) { case Reload_t::RELOAD_TYPE_ALL: return reloadAll(); @@ -32,34 +32,38 @@ bool GameReload::init(Reload_t reloadTypes) const { return reloadConfig(); case Reload_t::RELOAD_TYPE_EVENTS: return reloadEvents(); - case Reload_t::RELOAD_TYPE_CORE: - return reloadCore(); + case Reload_t::RELOAD_TYPE_MODULES: + return reloadModules(); + case Reload_t::RELOAD_TYPE_OUTFITS: + return reloadOutfits(); + case Reload_t::RELOAD_TYPE_MOUNTS: + return reloadMounts(); + case Reload_t::RELOAD_TYPE_FAMILIARS: + return reloadFamiliars(); case Reload_t::RELOAD_TYPE_IMBUEMENTS: return reloadImbuements(); + case Reload_t::RELOAD_TYPE_VOCATIONS: + return reloadVocations(); + case Reload_t::RELOAD_TYPE_CORE: + return reloadCore(); + case Reload_t::RELOAD_TYPE_GROUPS: + return reloadGroups(); + case Reload_t::RELOAD_TYPE_SCRIPTS: + return reloadScripts(); case Reload_t::RELOAD_TYPE_ITEMS: return reloadItems(); - case Reload_t::RELOAD_TYPE_MODULES: - return reloadModules(); case Reload_t::RELOAD_TYPE_MONSTERS: return reloadMonsters(); - case Reload_t::RELOAD_TYPE_MOUNTS: - return reloadMounts(); case Reload_t::RELOAD_TYPE_NPCS: return reloadNpcs(); case Reload_t::RELOAD_TYPE_RAIDS: return reloadRaids(); - case Reload_t::RELOAD_TYPE_SCRIPTS: - return reloadScripts(); - case Reload_t::RELOAD_TYPE_GROUPS: - return reloadGroups(); - case Reload_t::RELOAD_TYPE_VOCATIONS: - return reloadVocations(); default: return false; } } -uint8_t GameReload::getReloadNumber(Reload_t reloadTypes) const { +uint8_t GameReload::getReloadNumber(Reload_t reloadTypes) { return magic_enum::enum_integer(reloadTypes); } @@ -78,7 +82,7 @@ void logReloadStatus(const std::string &name, bool result) { * If it is necessary to call elsewhere, seriously think about creating a function that calls this * Changing this to public may cause some unexpected behavior or bug */ -bool GameReload::reloadAll() const { +bool GameReload::reloadAll() { std::vector reloadResults; reloadResults.reserve(magic_enum::enum_count()); @@ -93,25 +97,62 @@ bool GameReload::reloadAll() const { return std::ranges::any_of(reloadResults, [](bool result) { return result; }); } -bool GameReload::reloadChat() const { +bool GameReload::reloadChat() { const bool result = g_chat().load(); logReloadStatus("Chat", result); return result; } -bool GameReload::reloadConfig() const { +bool GameReload::reloadConfig() { const bool result = g_configManager().reload(); logReloadStatus("Config", result); return result; } -bool GameReload::reloadEvents() const { +bool GameReload::reloadEvents() { const bool result = g_events().loadFromXml(); logReloadStatus("Events", result); return result; } -bool GameReload::reloadCore() const { +bool GameReload::reloadModules() { + const bool result = g_modules().reload(); + logReloadStatus("Modules", result); + return result; +} + +bool GameReload::reloadOutfits() { + const bool result = g_game().outfits.reload(); + logReloadStatus("Outfits", result); + return result; +} + +bool GameReload::reloadMounts() { + const bool result = g_game().mounts.reload(); + logReloadStatus("Mounts", result); + return result; +} + +bool GameReload::reloadFamiliars() { + const bool result = g_game().familiars.reload(); + logReloadStatus("Familiars", result); + return result; +} + +bool GameReload::reloadImbuements() { + const bool result = g_imbuements().reload(); + logReloadStatus("Imbuements", result); + return result; +} + +bool GameReload::reloadVocations() { + const bool result = g_vocations().reload(); + reloadScripts(); + logReloadStatus("Vocations", result); + return result; +} + +bool GameReload::reloadCore() { const auto &coreFolder = g_configManager().getString(CORE_DIRECTORY, __FUNCTION__); const bool coreLoaded = g_luaEnvironment().loadFile(coreFolder + "/core.lua", "core.lua") == 0; @@ -126,25 +167,38 @@ bool GameReload::reloadCore() const { return false; } -bool GameReload::reloadImbuements() const { - const bool result = g_imbuements().reload(); - logReloadStatus("Imbuements", result); +bool GameReload::reloadGroups() { + const bool result = g_game().groups.reload(); + logReloadStatus("Groups", result); return result; } -bool GameReload::reloadItems() const { - const bool result = Item::items.reload(); - logReloadStatus("Items", result); - return result; +bool GameReload::reloadScripts() { + g_scripts().clearAllScripts(); + Zone::clearZones(); + + const auto &datapackFolder = g_configManager().getString(DATA_DIRECTORY, __FUNCTION__); + const auto &coreFolder = g_configManager().getString(CORE_DIRECTORY, __FUNCTION__); + + g_scripts().loadScripts(coreFolder + "/scripts/lib", true, false); + g_scripts().loadScripts(datapackFolder + "/scripts", false, true); + g_scripts().loadScripts(coreFolder + "/scripts", false, true); + + // It should come last, after everything else has been cleaned up. + reloadMonsters(); + reloadNpcs(); + reloadItems(); + logReloadStatus("Scripts", true); + return true; } -bool GameReload::reloadModules() const { - const bool result = g_modules().reload(); - logReloadStatus("Modules", result); +bool GameReload::reloadItems() { + const bool result = Item::items.reload(); + logReloadStatus("Items", result); return result; } -bool GameReload::reloadMonsters() const { +bool GameReload::reloadMonsters() { g_monsters().clear(); const auto &datapackFolder = g_configManager().getString(DATA_DIRECTORY, __FUNCTION__); const auto &coreFolder = g_configManager().getString(CORE_DIRECTORY, __FUNCTION__); @@ -161,50 +215,14 @@ bool GameReload::reloadMonsters() const { } } -bool GameReload::reloadMounts() const { - const bool result = g_game().mounts.reload(); - logReloadStatus("Mounts", result); - return result; -} - -bool GameReload::reloadNpcs() const { +bool GameReload::reloadNpcs() { const bool result = g_npcs().reload(); logReloadStatus("NPCs", result); return result; } -bool GameReload::reloadRaids() const { +bool GameReload::reloadRaids() { const bool result = g_game().raids.reload() && g_game().raids.startup(); logReloadStatus("Raids", result); return result; } - -bool GameReload::reloadScripts() const { - g_scripts().clearAllScripts(); - Zone::clearZones(); - - const auto &datapackFolder = g_configManager().getString(DATA_DIRECTORY, __FUNCTION__); - const auto &coreFolder = g_configManager().getString(CORE_DIRECTORY, __FUNCTION__); - - g_scripts().loadScripts(coreFolder + "/scripts/lib", true, false); - g_scripts().loadScripts(datapackFolder + "/scripts", false, true); - g_scripts().loadScripts(coreFolder + "/scripts", false, true); - - // It should come last, after everything else has been cleaned up. - reloadMonsters(); - reloadNpcs(); - logReloadStatus("Scripts", true); - return true; -} - -bool GameReload::reloadGroups() const { - const bool result = g_game().groups.reload(); - logReloadStatus("Groups", result); - return result; -} - -bool GameReload::reloadVocations() const { - const bool result = g_vocations().reload(); - logReloadStatus("Vocations", result); - return result; -} diff --git a/src/game/functions/game_reload.hpp b/src/game/functions/game_reload.hpp index 45ff35c01a2..0f59046a9d4 100644 --- a/src/game/functions/game_reload.hpp +++ b/src/game/functions/game_reload.hpp @@ -19,17 +19,19 @@ enum class Reload_t : uint8_t { RELOAD_TYPE_CHAT, RELOAD_TYPE_CONFIG, RELOAD_TYPE_EVENTS, - RELOAD_TYPE_CORE, + RELOAD_TYPE_MODULES, + RELOAD_TYPE_OUTFITS, + RELOAD_TYPE_MOUNTS, + RELOAD_TYPE_FAMILIARS, RELOAD_TYPE_IMBUEMENTS, + RELOAD_TYPE_VOCATIONS, + RELOAD_TYPE_CORE, + RELOAD_TYPE_GROUPS, + RELOAD_TYPE_SCRIPTS, RELOAD_TYPE_ITEMS, - RELOAD_TYPE_MODULES, RELOAD_TYPE_MONSTERS, - RELOAD_TYPE_MOUNTS, RELOAD_TYPE_NPCS, RELOAD_TYPE_RAIDS, - RELOAD_TYPE_SCRIPTS, - RELOAD_TYPE_GROUPS, - RELOAD_TYPE_VOCATIONS, // Every is last RELOAD_TYPE_LAST @@ -48,25 +50,27 @@ class GameReload : public Game { return inject(); } - bool init(Reload_t reloadType) const; - uint8_t getReloadNumber(Reload_t reloadTypes) const; + static bool init(Reload_t reloadType); + static uint8_t getReloadNumber(Reload_t reloadTypes); private: - bool reloadAll() const; - bool reloadChat() const; - bool reloadConfig() const; - bool reloadEvents() const; - bool reloadCore() const; - bool reloadImbuements() const; - bool reloadItems() const; - bool reloadModules() const; - bool reloadMonsters() const; - bool reloadMounts() const; - bool reloadNpcs() const; - bool reloadRaids() const; - bool reloadScripts() const; - bool reloadGroups() const; - bool reloadVocations() const; + static bool reloadAll(); + static bool reloadChat(); + static bool reloadConfig(); + static bool reloadEvents(); + static bool reloadModules(); + static bool reloadOutfits(); + static bool reloadMounts(); + static bool reloadFamiliars(); + static bool reloadImbuements(); + static bool reloadVocations(); + static bool reloadCore(); + static bool reloadGroups(); + static bool reloadScripts(); + static bool reloadItems(); + static bool reloadMonsters(); + static bool reloadNpcs(); + static bool reloadRaids(); }; constexpr auto g_gameReload = GameReload::getInstance; diff --git a/src/game/game.cpp b/src/game/game.cpp index fed3a3910a1..57daddded2e 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -4261,7 +4261,7 @@ void Game::playerSetShowOffSocket(uint32_t playerId, Outfit_t &outfit, const Pos name << item->getName() << " displaying the "; bool outfited = false; if (outfit.lookType != 0) { - const auto &outfitInfo = Outfits::getInstance().getOutfitByLookType(player->getSex(), outfit.lookType); + const auto &outfitInfo = Outfits::getInstance().getOutfitByLookType(player, outfit.lookType); if (!outfitInfo) { return; } @@ -5927,7 +5927,7 @@ void Game::playerChangeOutfit(uint32_t playerId, Outfit_t outfit, uint8_t isMoun outfit.lookMount = randomMount->clientId; } - const auto playerOutfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), outfit.lookType); + const auto playerOutfit = Outfits::getInstance().getOutfitByLookType(player, outfit.lookType); if (!playerOutfit) { outfit.lookMount = 0; } diff --git a/src/game/game.hpp b/src/game/game.hpp index 3a199254259..b4be8facd09 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -582,8 +582,10 @@ class Game { bool hasDistanceEffect(uint16_t effectId); Groups groups; + Familiars familiars; Map map; Mounts mounts; + Outfits outfits; Raids raids; std::unique_ptr m_appearancesPtr; diff --git a/src/io/functions/iologindata_load_player.cpp b/src/io/functions/iologindata_load_player.cpp index 6273f8fefbb..8f7cf461fdf 100644 --- a/src/io/functions/iologindata_load_player.cpp +++ b/src/io/functions/iologindata_load_player.cpp @@ -66,7 +66,7 @@ bool IOLoginDataLoad::preLoadPlayer(std::shared_ptr player, const std::s } player->setGUID(result->getNumber("id")); - std::shared_ptr group = g_game().groups.getGroup(result->getNumber("group_id")); + const auto &group = g_game().groups.getGroup(result->getNumber("group_id")); if (!group) { g_logger().error("Player {} has group id {} which doesn't exist", player->name, result->getNumber("group_id")); return false; @@ -118,7 +118,7 @@ bool IOLoginDataLoad::loadPlayerFirst(std::shared_ptr player, DBResult_p player->setAccount(result->getNumber("account_id")); } - std::shared_ptr group = g_game().groups.getGroup(result->getNumber("group_id")); + const auto &group = g_game().groups.getGroup(result->getNumber("group_id")); if (!group) { g_logger().error("Player {} has group id {} which doesn't exist", player->name, result->getNumber("group_id")); return false; diff --git a/src/lua/functions/creatures/player/group_functions.cpp b/src/lua/functions/creatures/player/group_functions.cpp index 5acc16d72a9..f547eec1590 100644 --- a/src/lua/functions/creatures/player/group_functions.cpp +++ b/src/lua/functions/creatures/player/group_functions.cpp @@ -17,7 +17,7 @@ int GroupFunctions::luaGroupCreate(lua_State* L) { // Group(id) uint32_t id = getNumber(L, 2); - std::shared_ptr group = g_game().groups.getGroup(id); + const auto &group = g_game().groups.getGroup(id); if (group) { pushUserdata(L, group); setMetatable(L, -1, "Group"); @@ -29,7 +29,7 @@ int GroupFunctions::luaGroupCreate(lua_State* L) { int GroupFunctions::luaGroupGetId(lua_State* L) { // group:getId() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { lua_pushnumber(L, group->id); } else { @@ -40,7 +40,7 @@ int GroupFunctions::luaGroupGetId(lua_State* L) { int GroupFunctions::luaGroupGetName(lua_State* L) { // group:getName() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { pushString(L, group->name); } else { @@ -51,7 +51,7 @@ int GroupFunctions::luaGroupGetName(lua_State* L) { int GroupFunctions::luaGroupGetFlags(lua_State* L) { // group:getFlags() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { std::bitset flags; for (uint8_t i = 0; i < magic_enum::enum_integer(PlayerFlags_t::FlagLast); ++i) { @@ -68,7 +68,7 @@ int GroupFunctions::luaGroupGetFlags(lua_State* L) { int GroupFunctions::luaGroupGetAccess(lua_State* L) { // group:getAccess() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { pushBoolean(L, group->access); } else { @@ -79,7 +79,7 @@ int GroupFunctions::luaGroupGetAccess(lua_State* L) { int GroupFunctions::luaGroupGetMaxDepotItems(lua_State* L) { // group:getMaxDepotItems() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { lua_pushnumber(L, group->maxDepotItems); } else { @@ -90,7 +90,7 @@ int GroupFunctions::luaGroupGetMaxDepotItems(lua_State* L) { int GroupFunctions::luaGroupGetMaxVipEntries(lua_State* L) { // group:getMaxVipEntries() - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { lua_pushnumber(L, group->maxVipEntries); } else { @@ -101,7 +101,7 @@ int GroupFunctions::luaGroupGetMaxVipEntries(lua_State* L) { int GroupFunctions::luaGroupHasFlag(lua_State* L) { // group:hasFlag(flag) - std::shared_ptr group = getUserdataShared(L, 1); + const auto &group = getUserdataShared(L, 1); if (group) { auto flag = static_cast(getNumber(L, 2)); pushBoolean(L, group->flags[Groups::getFlagNumber(flag)]); diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 751da531273..98bacfc5e12 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -4055,7 +4055,7 @@ void ProtocolGame::sendCyclopediaCharacterInspection() { // Outfit description playerDescriptionSize++; msg.addString("Outfit", "ProtocolGame::sendCyclopediaCharacterInspection - Outfit"); - if (const auto outfit = Outfits::getInstance().getOutfitByLookType(player->getSex(), player->getDefaultOutfit().lookType)) { + if (const auto outfit = Outfits::getInstance().getOutfitByLookType(player, player->getDefaultOutfit().lookType)) { msg.addString(outfit->name, "ProtocolGame::sendCyclopediaCharacterInspection - outfit->name"); } else { msg.addString("unknown", "ProtocolGame::sendCyclopediaCharacterInspection - unknown"); From e20e7eb68b24eafdbc13b1c3c72928ee8caf3ee1 Mon Sep 17 00:00:00 2001 From: Luan Luciano Date: Wed, 12 Jun 2024 10:43:24 -0300 Subject: [PATCH 14/15] feat: monster rename functionality (#2621) --- ...{create_monster.lua => manage_monster.lua} | 32 +++++++++++++++++- src/creatures/monsters/monster.cpp | 33 ++++++++++++++++++- src/creatures/monsters/monster.hpp | 20 ++++++----- src/creatures/players/player.hpp | 9 +++-- .../creatures/monster/monster_functions.cpp | 20 ++++++++++- .../creatures/monster/monster_functions.hpp | 2 ++ src/server/network/protocol/protocolgame.cpp | 33 ++++++++++++++----- src/server/network/protocol/protocolgame.hpp | 1 + 8 files changed, 128 insertions(+), 22 deletions(-) rename data/scripts/talkactions/god/{create_monster.lua => manage_monster.lua} (83%) diff --git a/data/scripts/talkactions/god/create_monster.lua b/data/scripts/talkactions/god/manage_monster.lua similarity index 83% rename from data/scripts/talkactions/god/create_monster.lua rename to data/scripts/talkactions/god/manage_monster.lua index ce5869a2eee..da110d59265 100644 --- a/data/scripts/talkactions/god/create_monster.lua +++ b/data/scripts/talkactions/god/manage_monster.lua @@ -56,7 +56,7 @@ local createMonster = TalkAction("/m") -- @param param: String containing the command parameters. -- Format: "/m monstername, monstercount, [fiendish/influenced level], spawnRadius, [forceCreate]" -- Example: "/m rat, 10, fiendish, 5, true" --- @param: the last param is by default "false", if add "," or any value i'ts set to true +-- @param: the last param is by default "false", if add "," or any value it's set to true -- @return true if the command is executed successfully, false otherwise. function createMonster.onSay(player, words, param) -- create log @@ -127,3 +127,33 @@ end createMonster:separator(" ") createMonster:groupType("god") createMonster:register() + +----------------- Rename monster name ----------------- +local setMonsterName = TalkAction("/setmonstername") + +-- @function setMonsterName.onSay +-- @desc TalkAction to rename nearby monsters within a radius of 4 sqm. +-- Format: "/setmonstername newName" +function setMonsterName.onSay(player, words, param) + if param == "" then + player:sendCancelMessage("Command param required.") + return true + end + + local split = param:split(",") + local monsterNewName = split[1] + + local spectators, spectator = Game.getSpectators(player:getPosition(), false, false, 4, 4, 4, 4) + for i = 1, #spectators do + spectator = spectators[i] + if spectator:isMonster() then + spectator:setName(monsterNewName) + end + end + + return true +end + +setMonsterName:separator(" ") +setMonsterName:groupType("god") +setMonsterName:register() diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp index fccc19b05e5..5e0a7d16bb4 100644 --- a/src/creatures/monsters/monster.cpp +++ b/src/creatures/monsters/monster.cpp @@ -33,7 +33,7 @@ std::shared_ptr Monster::createMonster(const std::string &name) { Monster::Monster(const std::shared_ptr mType) : Creature(), - strDescription(asLowerCaseString(mType->nameDescription)), + nameDescription(asLowerCaseString(mType->nameDescription)), mType(mType) { defaultOutfit = mType->info.outfit; currentOutfit = mType->info.outfit; @@ -64,6 +64,37 @@ void Monster::removeList() { g_game().removeMonster(static_self_cast()); } +const std::string &Monster::getName() const { + if (name.empty()) { + return mType->name; + } + return name; +} + +void Monster::setName(const std::string &name) { + if (getName() == name) { + return; + } + + this->name = name; + + // NOTE: Due to how client caches known creatures, + // it is not feasible to send creature update to everyone that has ever met it + auto spectators = Spectators().find(position, true); + for (const auto &spectator : spectators) { + if (const auto &tmpPlayer = spectator->getPlayer()) { + tmpPlayer->sendUpdateTileCreature(static_self_cast()); + } + } +} + +const std::string &Monster::getNameDescription() const { + if (nameDescription.empty()) { + return mType->nameDescription; + } + return nameDescription; +} + bool Monster::canWalkOnFieldType(CombatType_t combatType) const { switch (combatType) { case COMBAT_ENERGYDAMAGE: diff --git a/src/creatures/monsters/monster.hpp b/src/creatures/monsters/monster.hpp index bf9a39e4133..6c45fa3eaca 100644 --- a/src/creatures/monsters/monster.hpp +++ b/src/creatures/monsters/monster.hpp @@ -41,21 +41,22 @@ class Monster final : public Creature { } } - void removeList() override; void addList() override; + void removeList() override; + + const std::string &getName() const override; + void setName(const std::string &name); - const std::string &getName() const override { - return mType->name; - } // Real monster name, set on monster creation "createMonsterType(typeName)" const std::string &getTypeName() const override { return mType->typeName; } - const std::string &getNameDescription() const override { - return mType->nameDescription; - } + const std::string &getNameDescription() const override; + void setNameDescription(const std::string &nameDescription) { + this->nameDescription = nameDescription; + }; std::string getDescription(int32_t) override { - return strDescription + '.'; + return nameDescription + '.'; } CreatureType_t getType() const override { @@ -363,7 +364,8 @@ class Monster final : public Creature { uint16_t forgeStack = 0; ForgeClassifications_t monsterForgeClassification = ForgeClassifications_t::FORGE_NORMAL_MONSTER; - std::string strDescription; + std::string name; + std::string nameDescription; std::shared_ptr mType; SpawnMonster* spawnMonster = nullptr; diff --git a/src/creatures/players/player.hpp b/src/creatures/players/player.hpp index 19e3af5ca9c..947acedca54 100644 --- a/src/creatures/players/player.hpp +++ b/src/creatures/players/player.hpp @@ -153,8 +153,8 @@ class Player final : public Creature, public Cylinder, public Bankable { const std::string &getName() const override { return name; } - void setName(std::string newName) { - this->name = std::move(newName); + void setName(const std::string &name) { + this->name = name; } const std::string &getTypeName() const override { return name; @@ -1075,6 +1075,11 @@ class Player final : public Creature, public Cylinder, public Bankable { client->sendRemoveTileThing(pos, stackpos); } } + void sendUpdateTileCreature(const std::shared_ptr creature) { + if (client) { + client->sendUpdateTileCreature(creature->getPosition(), creature->getTile()->getClientIndexOfCreature(static_self_cast(), creature), creature); + } + } void sendUpdateTile(std::shared_ptr updateTile, const Position &pos) { if (client) { client->sendUpdateTile(updateTile, pos); diff --git a/src/lua/functions/creatures/monster/monster_functions.cpp b/src/lua/functions/creatures/monster/monster_functions.cpp index 1591053c391..273f6af5c99 100644 --- a/src/lua/functions/creatures/monster/monster_functions.cpp +++ b/src/lua/functions/creatures/monster/monster_functions.cpp @@ -77,7 +77,7 @@ int MonsterFunctions::luaMonsterSetType(lua_State* L) { } // Assign new MonsterType monster->mType = mType; - monster->strDescription = asLowerCaseString(mType->nameDescription); + monster->nameDescription = asLowerCaseString(mType->nameDescription); monster->defaultOutfit = mType->info.outfit; monster->currentOutfit = mType->info.outfit; monster->skull = mType->info.skull; @@ -529,6 +529,24 @@ int MonsterFunctions::luaMonsterGetName(lua_State* L) { return 1; } +int MonsterFunctions::luaMonsterSetName(lua_State* L) { + // monster:setName(name[, nameDescription]) + auto monster = getUserdataShared(L, 1); + if (!monster) { + reportErrorFunc(getErrorDesc(LUA_ERROR_MONSTER_NOT_FOUND)); + pushBoolean(L, false); + return 0; + } + + monster->setName(getString(L, 2)); + if (lua_gettop(L) >= 3) { + monster->setNameDescription(getString(L, 3)); + } + + pushBoolean(L, true); + return 1; +} + int MonsterFunctions::luaMonsterHazard(lua_State* L) { // get: monster:hazard() ; set: monster:hazard(hazard) std::shared_ptr monster = getUserdataShared(L, 1); diff --git a/src/lua/functions/creatures/monster/monster_functions.hpp b/src/lua/functions/creatures/monster/monster_functions.hpp index bf2785ae430..dd1c3827344 100644 --- a/src/lua/functions/creatures/monster/monster_functions.hpp +++ b/src/lua/functions/creatures/monster/monster_functions.hpp @@ -56,6 +56,7 @@ class MonsterFunctions final : LuaScriptInterface { registerMethod(L, "Monster", "isForgeable", MonsterFunctions::luaMonsterIsForgeable); registerMethod(L, "Monster", "getName", MonsterFunctions::luaMonsterGetName); + registerMethod(L, "Monster", "setName", MonsterFunctions::luaMonsterSetName); registerMethod(L, "Monster", "hazard", MonsterFunctions::luaMonsterHazard); registerMethod(L, "Monster", "hazardCrit", MonsterFunctions::luaMonsterHazardCrit); @@ -116,6 +117,7 @@ class MonsterFunctions final : LuaScriptInterface { static int luaMonsterIsForgeable(lua_State* L); static int luaMonsterGetName(lua_State* L); + static int luaMonsterSetName(lua_State* L); static int luaMonsterHazard(lua_State* L); static int luaMonsterHazardCrit(lua_State* L); diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 98bacfc5e12..8cf0660a262 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -5947,7 +5947,7 @@ void ProtocolGame::sendCreatureTurn(std::shared_ptr creature, uint32_t NetworkMessage msg; msg.addByte(0x6B); msg.addPosition(creature->getPosition()); - msg.addByte(stackPos); + msg.addByte(static_cast(stackPos)); msg.add(0x63); msg.add(creature->getID()); msg.addByte(creature->getDirection()); @@ -6385,7 +6385,7 @@ void ProtocolGame::sendAddTileItem(const Position &pos, uint32_t stackpos, std:: NetworkMessage msg; msg.addByte(0x6A); msg.addPosition(pos); - msg.addByte(stackpos); + msg.addByte(static_cast(stackpos)); AddItem(msg, item); writeToOutputBuffer(msg); } @@ -6398,7 +6398,7 @@ void ProtocolGame::sendUpdateTileItem(const Position &pos, uint32_t stackpos, st NetworkMessage msg; msg.addByte(0x6B); msg.addPosition(pos); - msg.addByte(stackpos); + msg.addByte(static_cast(stackpos)); AddItem(msg, item); writeToOutputBuffer(msg); } @@ -6413,6 +6413,23 @@ void ProtocolGame::sendRemoveTileThing(const Position &pos, uint32_t stackpos) { writeToOutputBuffer(msg); } +void ProtocolGame::sendUpdateTileCreature(const Position &pos, uint32_t stackpos, const std::shared_ptr creature) { + if (!canSee(pos)) { + return; + } + + NetworkMessage msg; + msg.addByte(0x6B); + msg.addPosition(pos); + msg.addByte(static_cast(stackpos)); + + bool known; + uint32_t removedKnown; + checkCreatureAsKnown(creature->getID(), known, removedKnown); + AddCreature(msg, creature, false, removedKnown); + writeToOutputBuffer(msg); +} + void ProtocolGame::sendUpdateTile(std::shared_ptr tile, const Position &pos) { if (!canSee(pos)) { return; @@ -6484,7 +6501,7 @@ void ProtocolGame::sendAddCreature(std::shared_ptr creature, const Pos NetworkMessage msg; msg.addByte(0x6A); msg.addPosition(pos); - msg.addByte(stackpos); + msg.addByte(static_cast(stackpos)); bool known; uint32_t removedKnown; @@ -6641,7 +6658,7 @@ void ProtocolGame::sendMoveCreature(std::shared_ptr creature, const Po } else { msg.addByte(0x6D); msg.addPosition(oldPos); - msg.addByte(oldStackPos); + msg.addByte(static_cast(oldStackPos)); msg.addPosition(newPos); } @@ -6676,7 +6693,7 @@ void ProtocolGame::sendMoveCreature(std::shared_ptr creature, const Po NetworkMessage msg; msg.addByte(0x6D); msg.addPosition(oldPos); - msg.addByte(oldStackPos); + msg.addByte(static_cast(oldStackPos)); msg.addPosition(newPos); writeToOutputBuffer(msg); } @@ -7836,7 +7853,7 @@ void ProtocolGame::RemoveTileThing(NetworkMessage &msg, const Position &pos, uin msg.addByte(0x6C); msg.addPosition(pos); - msg.addByte(stackpos); + msg.addByte(static_cast(stackpos)); } void ProtocolGame::sendKillTrackerUpdate(std::shared_ptr corpse, const std::string &name, const Outfit_t creatureOutfit) { @@ -8279,7 +8296,7 @@ void ProtocolGame::reloadCreature(std::shared_ptr creature) { if (knownCreatureSet.contains(creature->getID())) { msg.addByte(0x6B); msg.addPosition(creature->getPosition()); - msg.addByte(stackpos); + msg.addByte(static_cast(stackpos)); AddCreature(msg, creature, false, 0); } else { sendAddCreature(creature, creature->getPosition(), stackpos, false); diff --git a/src/server/network/protocol/protocolgame.hpp b/src/server/network/protocol/protocolgame.hpp index 0386093cfc4..100ca199b77 100644 --- a/src/server/network/protocol/protocolgame.hpp +++ b/src/server/network/protocol/protocolgame.hpp @@ -393,6 +393,7 @@ class ProtocolGame final : public Protocol { void sendAddTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item); void sendUpdateTileItem(const Position &pos, uint32_t stackpos, std::shared_ptr item); void sendRemoveTileThing(const Position &pos, uint32_t stackpos); + void sendUpdateTileCreature(const Position &pos, uint32_t stackpos, const std::shared_ptr creature); void sendUpdateTile(std::shared_ptr tile, const Position &pos); void sendAddCreature(std::shared_ptr creature, const Position &pos, int32_t stackpos, bool isLogin); From 7c3393a1015ff4d8c1f43c5988b33f489302e20f Mon Sep 17 00:00:00 2001 From: Renato Machado Date: Wed, 12 Jun 2024 10:48:41 -0300 Subject: [PATCH 15/15] fix: crash on shutdown (#2676) --- src/lib/thread/thread_pool.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/thread/thread_pool.cpp b/src/lib/thread/thread_pool.cpp index 702f0c05504..b2f51ef8f9d 100644 --- a/src/lib/thread/thread_pool.cpp +++ b/src/lib/thread/thread_pool.cpp @@ -26,7 +26,7 @@ #endif ThreadPool::ThreadPool(Logger &logger) : - logger(logger), BS::thread_pool(std::max(getNumberOfCores(), DEFAULT_NUMBER_OF_THREADS)) { + BS::thread_pool(std::max(getNumberOfCores(), DEFAULT_NUMBER_OF_THREADS)), logger(logger) { start(); } @@ -35,6 +35,7 @@ void ThreadPool::start() { } void ThreadPool::shutdown() { - stopped = true; logger.info("Shutting down thread pool..."); + stopped = true; + wait(); }