diff --git a/README.md b/README.md
index 16b6d73cb14..d3d83eecc48 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ source of the Canary, so that it will be the first repository to use this engine
To connect to the server and to take a stable experience, you can
use [mehah's otclient](https://github.com/mehah/otclient)
or [tibia client](https://github.com/dudantas/tibia-client/releases/latest) and if you want to edit something, check
-our [customized tools](https://docs.opentibiabr.com/others/downloads/tools).
+our [customized tools](https://docs.opentibiabr.com/opentibiabr/downloads/tools).
If you want edit the map, use the [own remere's map editor](https://github.com/opentibiabr/remeres-map-editor/).
diff --git a/config.lua.dist b/config.lua.dist
index 76508f6d7d7..a00bb061f81 100644
--- a/config.lua.dist
+++ b/config.lua.dist
@@ -186,6 +186,7 @@ onlyPremiumAccount = false
-- NOTE: buyAolCommandFee will add fee when player buy aol by command (!aol), active changing value more than 0 (fee value. ex: 1 = 1gp aol will be 50001)
-- NOTE: buyBlessCommandFee will add fee when player buy bless by command (!bless), active changing value between 1 and 100 (fee percent. ex: 3 = 3%, 30 = 30%)
-- NOTE: teleportPlayerToVocationRoom will enable oressa to teleport player to his/her room vocation
+-- NOTE: toggleReceiveReward = true, will enable players to choose one of reward exercise weapon by command !reward
weatherRain = false
thunderEffect = false
allConsoleLog = false
@@ -200,6 +201,7 @@ toggleTravelsFree = false
buyAolCommandFee = 0
buyBlessCommandFee = 0
teleportPlayerToVocationRoom = true
+toggleReceiveReward = false
-- Teleport summon
-- Set to true will never remove the summon
diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua
index d5f434274b0..b1795ce1dde 100644
--- a/data-otservbr-global/lib/core/storages.lua
+++ b/data-otservbr-global/lib/core/storages.lua
@@ -140,7 +140,7 @@ Storage = {
PremiumAccount = 30058,
BattleAxeQuest = 30059,
ShrineEntrance = 30060,
-
+ PlayerWeaponReward = 30061,
--[[
Old storages
Over time, this will be dropped and replaced by the table above
diff --git a/data-otservbr-global/monster/bosses/doctor_marrow.lua b/data-otservbr-global/monster/bosses/doctor_marrow.lua
new file mode 100644
index 00000000000..3de9bc41825
--- /dev/null
+++ b/data-otservbr-global/monster/bosses/doctor_marrow.lua
@@ -0,0 +1,110 @@
+local mType = Game.createMonsterType("Doctor Marrow")
+local monster = {}
+
+monster.description = "Doctor Marrow"
+monster.experience = 0
+monster.outfit = {
+ lookType = 1611,
+ lookHead = 57,
+ lookBody = 0,
+ lookLegs = 0,
+ lookFeet = 95,
+ lookAddons = 0,
+ lookMount = 0,
+}
+
+monster.health = 1800
+monster.maxHealth = 1800
+monster.race = "blood"
+monster.corpse = 18074
+monster.speed = 125
+monster.manaCost = 0
+
+monster.changeTarget = {
+ interval = 4000,
+ chance = 10,
+}
+
+monster.strategiesTarget = {
+ nearest = 80,
+ health = 10,
+ damage = 10,
+}
+
+monster.flags = {
+ summonable = false,
+ attackable = true,
+ hostile = true,
+ convinceable = false,
+ pushable = false,
+ rewardBoss = true,
+ illusionable = false,
+ canPushItems = true,
+ canPushCreatures = true,
+ critChance = 10,
+ staticAttackChance = 90,
+ targetDistance = 1,
+ runHealth = 0,
+ healthHidden = false,
+ isBlockable = false,
+ canWalkOnEnergy = true,
+ canWalkOnFire = true,
+ canWalkOnPoison = true,
+}
+
+monster.light = {
+ level = 0,
+ color = 0,
+}
+
+monster.voices = {
+ interval = 5000,
+ chance = 10,
+ { text = "You can't stop the future!", yell = false },
+}
+
+monster.attacks = {
+ { name = "melee", interval = 2000, chance = 100, minDamage = 0, maxDamage = -2800 },
+}
+
+monster.defenses = {
+ defense = 54,
+ armor = 59,
+ mitigation = 3.7,
+}
+
+monster.elements = {
+ { type = COMBAT_PHYSICALDAMAGE, percent = 0 },
+ { type = COMBAT_ENERGYDAMAGE, percent = 0 },
+ { type = COMBAT_EARTHDAMAGE, percent = 0 },
+ { type = COMBAT_FIREDAMAGE, percent = 0 },
+ { type = COMBAT_LIFEDRAIN, percent = 0 },
+ { type = COMBAT_MANADRAIN, percent = 0 },
+ { type = COMBAT_DROWNDAMAGE, percent = 0 },
+ { type = COMBAT_ICEDAMAGE, percent = 0 },
+ { type = COMBAT_HOLYDAMAGE, percent = 0 },
+ { type = COMBAT_DEATHDAMAGE, percent = 0 },
+}
+
+monster.immunities = {
+ { type = "paralyze", condition = true },
+ { type = "outfit", condition = false },
+ { type = "invisible", condition = true },
+ { type = "bleed", condition = false },
+}
+
+mType.onThink = function(monster, interval) end
+
+mType.onAppear = function(monster, creature)
+ if monster:getType():isRewardBoss() then
+ monster:setReward(true)
+ end
+end
+
+mType.onDisappear = function(monster, creature) end
+
+mType.onMove = function(monster, creature, fromPosition, toPosition) end
+
+mType.onSay = function(monster, creature, type, message) end
+
+mType:register(monster)
diff --git a/data-otservbr-global/scripts/creaturescripts/customs/reward_exercise.lua b/data-otservbr-global/scripts/creaturescripts/customs/reward_exercise.lua
new file mode 100644
index 00000000000..f17304cec00
--- /dev/null
+++ b/data-otservbr-global/scripts/creaturescripts/customs/reward_exercise.lua
@@ -0,0 +1,13 @@
+local winReward = CreatureEvent("WinReward")
+
+function winReward.onLogin(player)
+ if configManager.getBoolean(configKeys.TOGGLE_RECEIVE_REWARD) and player:getTown():getId() >= TOWNS_LIST.AB_DENDRIEL then
+ -- check user won exercise weapon and send message
+ if player:getStorageValue(tonumber(Storage.PlayerWeaponReward)) ~= 1 then
+ player:sendTextMessage(MESSAGE_LOGIN, "You can receive an exercise weapon using command !reward")
+ end
+ end
+ return true
+end
+
+winReward:register()
diff --git a/data-otservbr-global/scripts/globalevents/worldchanges/their_masters_voice.lua b/data-otservbr-global/scripts/globalevents/worldchanges/their_masters_voice.lua
index fa1b9adbe33..2061c254cf9 100644
--- a/data-otservbr-global/scripts/globalevents/worldchanges/their_masters_voice.lua
+++ b/data-otservbr-global/scripts/globalevents/worldchanges/their_masters_voice.lua
@@ -12,7 +12,7 @@ function theirmastersvoice.onStartup()
if item then
local slimeChance = math.random(100)
if slimeChance <= 30 then
- item:transform(math.random(13585, 13589))
+ item:transform(math.random(12059, 12063))
position:sendMagicEffect(CONST_ME_YELLOW_RINGS)
end
end
diff --git a/data-otservbr-global/scripts/lib/register_monster_type.lua b/data-otservbr-global/scripts/lib/register_monster_type.lua
index 68983418159..21a10d94aac 100644
--- a/data-otservbr-global/scripts/lib/register_monster_type.lua
+++ b/data-otservbr-global/scripts/lib/register_monster_type.lua
@@ -199,6 +199,9 @@ registerMonsterType.flags = function(mtype, mask)
if mask.flags.canPushCreatures ~= nil then
mtype:canPushCreatures(mask.flags.canPushCreatures)
end
+ if mask.flags.critChance ~= nil then
+ mtype:critChance(mask.flags.critChance)
+ end
if mask.flags.targetDistance then
mtype:targetDistance(math.max(1, mask.flags.targetDistance))
end
diff --git a/data-otservbr-global/world/world_changes/fury_gates/abdendriel.otbm b/data-otservbr-global/world/world_changes/fury_gates/abdendriel.otbm
index 9e6b2698eee..c41c56415e9 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/abdendriel.otbm and b/data-otservbr-global/world/world_changes/fury_gates/abdendriel.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/ankrahmun.otbm b/data-otservbr-global/world/world_changes/fury_gates/ankrahmun.otbm
index 04b378fa578..d426bf44223 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/ankrahmun.otbm and b/data-otservbr-global/world/world_changes/fury_gates/ankrahmun.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/carlin.otbm b/data-otservbr-global/world/world_changes/fury_gates/carlin.otbm
index a112b2e45e6..15f3fc688b6 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/carlin.otbm and b/data-otservbr-global/world/world_changes/fury_gates/carlin.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/darashia.otbm b/data-otservbr-global/world/world_changes/fury_gates/darashia.otbm
index 5f96244586b..4e259396824 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/darashia.otbm and b/data-otservbr-global/world/world_changes/fury_gates/darashia.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/edron.otbm b/data-otservbr-global/world/world_changes/fury_gates/edron.otbm
index 72d3239b4bb..3ad2c77ca4a 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/edron.otbm and b/data-otservbr-global/world/world_changes/fury_gates/edron.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/kazordoon.otbm b/data-otservbr-global/world/world_changes/fury_gates/kazordoon.otbm
index c1aa4744aac..4a6e4386f29 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/kazordoon.otbm and b/data-otservbr-global/world/world_changes/fury_gates/kazordoon.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/libertybay.otbm b/data-otservbr-global/world/world_changes/fury_gates/libertybay.otbm
index ac1df9d0950..c9a57e0f45f 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/libertybay.otbm and b/data-otservbr-global/world/world_changes/fury_gates/libertybay.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/porthope.otbm b/data-otservbr-global/world/world_changes/fury_gates/porthope.otbm
index f0b1b943c76..2232ecbc988 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/porthope.otbm and b/data-otservbr-global/world/world_changes/fury_gates/porthope.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/thais.otbm b/data-otservbr-global/world/world_changes/fury_gates/thais.otbm
index dfb1039d07b..a131dd8d096 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/thais.otbm and b/data-otservbr-global/world/world_changes/fury_gates/thais.otbm differ
diff --git a/data-otservbr-global/world/world_changes/fury_gates/venore.otbm b/data-otservbr-global/world/world_changes/fury_gates/venore.otbm
index 1ca21d586d1..1922f21ab60 100644
Binary files a/data-otservbr-global/world/world_changes/fury_gates/venore.otbm and b/data-otservbr-global/world/world_changes/fury_gates/venore.otbm differ
diff --git a/data/events/scripts/player.lua b/data/events/scripts/player.lua
index f176e5000c5..816aa523b70 100644
--- a/data/events/scripts/player.lua
+++ b/data/events/scripts/player.lua
@@ -445,6 +445,7 @@ end
function Player:onReportBug(message, position, category)
local name = self:getName()
+ FS.mkdir_p(string.format("%s/reports/bugs/%s", CORE_DIRECTORY, name))
local file = io.open(string.format("%s/reports/bugs/%s/report.txt", CORE_DIRECTORY, name), "a")
if not file then
diff --git a/data/items/items.xml b/data/items/items.xml
index 8c826d3fd64..d23468cabf3 100644
--- a/data/items/items.xml
+++ b/data/items/items.xml
@@ -15098,7 +15098,6 @@
-
-
-
diff --git a/data/libs/functions/fs.lua b/data/libs/functions/fs.lua
new file mode 100644
index 00000000000..f95fba51b05
--- /dev/null
+++ b/data/libs/functions/fs.lua
@@ -0,0 +1,32 @@
+FS = {}
+
+function FS.exists(path)
+ local file = io.open(path, "r")
+ if file then
+ file:close()
+ return true
+ end
+ return false
+end
+
+function FS.mkdir(path)
+ if FS.exists(path) then
+ return true
+ end
+ local success, err = os.execute("mkdir " .. path)
+ if not success then
+ return false, err
+ end
+ return true
+end
+
+function FS.mkdir_p(path)
+ if path == "" then
+ return true
+ end
+ if FS.exists(path) then
+ return true
+ end
+ FS.mkdir_p(path:match("(.*[/\\])"))
+ return FS.mkdir(path)
+end
diff --git a/data/libs/functions/load.lua b/data/libs/functions/load.lua
index 705fdf712d6..0ab33f5de11 100644
--- a/data/libs/functions/load.lua
+++ b/data/libs/functions/load.lua
@@ -5,6 +5,7 @@ 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/fs.lua")
dofile(CORE_DIRECTORY .. "/libs/functions/game.lua")
dofile(CORE_DIRECTORY .. "/libs/functions/item.lua")
dofile(CORE_DIRECTORY .. "/libs/functions/itemtype.lua")
diff --git a/data/scripts/talkactions/player/reward.lua b/data/scripts/talkactions/player/reward.lua
new file mode 100644
index 00000000000..7c2999a587e
--- /dev/null
+++ b/data/scripts/talkactions/player/reward.lua
@@ -0,0 +1,65 @@
+local config = {
+ items = {
+ { id = 35284, charges = 64000 },
+ { id = 35279, charges = 64000 },
+ { id = 35281, charges = 64000 },
+ { id = 35283, charges = 64000 },
+ { id = 35282, charges = 64000 },
+ { id = 35280, charges = 64000 },
+ },
+ storage = tonumber(Storage.PlayerWeaponReward), -- storage key, player can only win once
+}
+
+local function sendExerciseRewardModal(player)
+ local window = ModalWindow({
+ title = "Exercise Reward",
+ message = "choose a item",
+ })
+ for _, it in pairs(config.items) do
+ local iType = ItemType(it.id)
+ if iType then
+ window:addChoice(iType:getName(), function(player, button, choice)
+ if button.name ~= "Select" then
+ return true
+ end
+
+ local inbox = player:getSlotItem(CONST_SLOT_STORE_INBOX)
+ if inbox and inbox:getEmptySlots() > 0 then
+ local item = inbox:addItem(it.id, it.charges)
+ if item then
+ item:setAttribute(ITEM_ATTRIBUTE_STORE, systemTime())
+ else
+ player:sendTextMessage(MESSAGE_LOOK, "You need to have capacity and empty slots to receive.")
+ return
+ end
+ player:sendTextMessage(MESSAGE_LOOK, string.format("Congratulations, you received a %s with %i charges in your store inbox.", iType:getName(), it.charges))
+ player:setStorageValue(config.storage, 1)
+ else
+ player:sendTextMessage(MESSAGE_LOOK, "You need to have capacity and empty slots to receive.")
+ end
+ end)
+ end
+ end
+ window:addButton("Select")
+ window:addButton("Close")
+ window:setDefaultEnterButton(0)
+ window:setDefaultEscapeButton(1)
+ window:sendToPlayer(player)
+end
+
+local exerciseRewardModal = TalkAction("!reward")
+function exerciseRewardModal.onSay(player, words, param)
+ if not configManager.getBoolean(configKeys.TOGGLE_RECEIVE_REWARD) or player:getTown():getId() < TOWNS_LIST.AB_DENDRIEL then
+ return true
+ end
+ if player:getStorageValue(config.storage) > 0 then
+ player:sendTextMessage(MESSAGE_LOOK, "You already received your exercise weapon reward!")
+ return true
+ end
+ sendExerciseRewardModal(player)
+ return true
+end
+
+exerciseRewardModal:separator(" ")
+exerciseRewardModal:groupType("normal")
+exerciseRewardModal:register()
diff --git a/src/config/config_definitions.hpp b/src/config/config_definitions.hpp
index 6a785280e56..d3bf0b87eec 100644
--- a/src/config/config_definitions.hpp
+++ b/src/config/config_definitions.hpp
@@ -91,6 +91,8 @@ enum booleanConfig_t {
TOGGLE_MOUNT_IN_PZ,
TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART,
+ TOGGLE_RECEIVE_REWARD,
+
LAST_BOOLEAN_CONFIG
};
diff --git a/src/config/configmanager.cpp b/src/config/configmanager.cpp
index 940ea29eb51..d0abcc9352b 100644
--- a/src/config/configmanager.cpp
+++ b/src/config/configmanager.cpp
@@ -12,7 +12,6 @@
#include "config/configmanager.hpp"
#include "declarations.hpp"
#include "game/game.hpp"
-#include "lua/scripts/luajit_sync.hpp"
#include "server/network/webhook/webhook.hpp"
#if LUA_VERSION_NUM >= 502
@@ -393,6 +392,8 @@ bool ConfigManager::load() {
boolean[TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART] = getGlobalBoolean(L, "togglehouseTransferOnRestart", false);
+ boolean[TOGGLE_RECEIVE_REWARD] = getGlobalBoolean(L, "toggleReceiveReward", false);
+
loaded = true;
lua_close(L);
return true;
diff --git a/src/creatures/combat/combat.cpp b/src/creatures/combat/combat.cpp
index 4a8e6bd7060..75cec14c30f 100644
--- a/src/creatures/combat/combat.cpp
+++ b/src/creatures/combat/combat.cpp
@@ -73,7 +73,7 @@ CombatDamage Combat::getCombatDamage(std::shared_ptr creature, std::sh
);
} else if (formulaType == COMBAT_FORMULA_SKILL) {
std::shared_ptr
- tool = player->getWeapon();
- const Weapon* weapon = g_weapons().getWeapon(tool);
+ const WeaponShared_ptr weapon = g_weapons().getWeapon(tool);
if (weapon) {
damage.primary.value = normal_random(
static_cast(minb),
@@ -1139,41 +1139,7 @@ void Combat::doCombatHealth(std::shared_ptr caster, std::shared_ptrgetPlayer()) {
- // Critical damage
- uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
- // Charm low blow rune)
- if (target && target->getMonster() && damage.primary.type != COMBAT_HEALING) {
- uint16_t playerCharmRaceid = caster->getPlayer()->parseRacebyCharm(CHARM_LOW, false, 0);
- if (playerCharmRaceid != 0) {
- const auto mType = g_monsters().getMonsterType(target->getName());
- if (mType && playerCharmRaceid == mType->info.raceid) {
- const auto charm = g_iobestiary().getBestiaryCharm(CHARM_LOW);
- if (charm) {
- chance += charm->percent;
- g_game().sendDoubleSoundEffect(target->getPosition(), charm->soundCastEffect, charm->soundImpactEffect, caster);
- }
- }
- }
- }
- if (chance != 0 && uniform_random(1, 100) <= chance) {
- damage.critical = true;
- damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- }
-
- // Fatal hit (onslaught)
- if (auto playerWeapon = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT);
- playerWeapon != nullptr && playerWeapon->getTier()) {
- double_t fatalChance = playerWeapon->getFatalChance();
- double_t randomChance = uniform_random(0, 10000) / 100;
- if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && randomChance < fatalChance) {
- damage.fatal = true;
- damage.primary.value += static_cast(std::round(damage.primary.value * 0.6));
- damage.secondary.value += static_cast(std::round(damage.secondary.value * 0.6));
- }
- }
- }
+ applyExtensions(caster, target, damage, params);
if (canCombat) {
if (target && caster && params.distanceEffect != CONST_ANI_NONE) {
@@ -1194,27 +1160,7 @@ void Combat::doCombatHealth(std::shared_ptr caster, std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms) {
- if (caster && caster->getPlayer()) {
- // Critical damage
- uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
- if (damage.primary.type != COMBAT_HEALING && chance != 0 && uniform_random(1, 100) <= chance) {
- damage.critical = true;
- damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- }
-
- // Fatal hit (onslaught)
- if (auto playerWeapon = caster->getPlayer()->getInventoryItem(CONST_SLOT_LEFT);
- playerWeapon != nullptr && playerWeapon->getTier() > 0) {
- double_t fatalChance = playerWeapon->getFatalChance();
- double_t randomChance = uniform_random(0, 10000) / 100;
- if (damage.primary.type != COMBAT_HEALING && fatalChance > 0 && randomChance < fatalChance) {
- damage.fatal = true;
- damage.primary.value += static_cast(std::round(damage.primary.value * 0.6));
- damage.secondary.value += static_cast(std::round(damage.secondary.value * 0.6));
- }
- }
- }
+ applyExtensions(caster, nullptr, damage, params);
const auto origin = caster ? caster->getPosition() : Position();
CombatFunc(caster, origin, position, area, params, CombatHealthFunc, &damage);
}
@@ -1231,15 +1177,7 @@ void Combat::doCombatMana(std::shared_ptr caster, std::shared_ptrgetPosition(), params.impactEffect);
}
- if (caster && caster->getPlayer()) {
- // Critical damage
- uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
- if (chance != 0 && uniform_random(1, 100) <= chance) {
- damage.critical = true;
- damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- }
- }
+ applyExtensions(caster, target, damage, params);
if (canCombat) {
if (caster && target && params.distanceEffect != CONST_ANI_NONE) {
@@ -1260,15 +1198,7 @@ void Combat::doCombatMana(std::shared_ptr caster, std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms) {
- if (caster && caster->getPlayer()) {
- // Critical damage
- uint16_t chance = caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE) + (uint16_t)damage.criticalChance;
- if (chance != 0 && uniform_random(1, 100) <= chance) {
- damage.critical = true;
- damage.primary.value += (damage.primary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- damage.secondary.value += (damage.secondary.value * (caster->getPlayer()->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE) + damage.criticalDamage)) / 100;
- }
- }
+ applyExtensions(caster, nullptr, damage, params);
const auto origin = caster ? caster->getPosition() : Position();
CombatFunc(caster, origin, position, area, params, CombatManaFunc, &damage);
}
@@ -1514,7 +1444,7 @@ void ValueCallback::getMinMaxValues(std::shared_ptr player, CombatDamage
case COMBAT_FORMULA_SKILL: {
// onGetPlayerMinMaxValues(player, attackSkill, attackValue, attackFactor)
std::shared_ptr
- tool = player->getWeapon();
- const Weapon* weapon = g_weapons().getWeapon(tool);
+ const WeaponShared_ptr weapon = g_weapons().getWeapon(tool);
std::shared_ptr
- item = nullptr;
if (weapon) {
@@ -1768,13 +1698,15 @@ bool ChainPickerCallback::onChainCombat(std::shared_ptr creature, std:
//**********************************************************//
void AreaCombat::clear() {
- areas.clear();
+ std::ranges::fill(areas, nullptr);
}
AreaCombat::AreaCombat(const AreaCombat &rhs) {
hasExtArea = rhs.hasExtArea;
- for (const auto &it : rhs.areas) {
- areas[it.first] = it.second->clone();
+ for (uint_fast8_t i = 0; i <= Direction::DIRECTION_LAST; ++i) {
+ if (const auto &area = rhs.areas[i]) {
+ areas[i] = area->clone();
+ }
}
}
@@ -2078,3 +2010,64 @@ void MagicField::onStepInField(const std::shared_ptr &creature) {
creature->addCondition(conditionCopy);
}
}
+
+void Combat::applyExtensions(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms) {
+ if (damage.extension || !caster || damage.primary.type == COMBAT_HEALING) {
+ return;
+ }
+
+ g_logger().debug("[Combat::applyExtensions] - Applying extensions for {} on {}. Initial damage: {}", caster->getName(), target ? target->getName() : "null", damage.primary.value);
+
+ // Critical hit
+ uint16_t chance = 0;
+ int32_t multiplier = 50;
+ auto player = caster->getPlayer();
+ auto monster = caster->getMonster();
+ if (player) {
+ chance = player->getSkillLevel(SKILL_CRITICAL_HIT_CHANCE);
+ multiplier = player->getSkillLevel(SKILL_CRITICAL_HIT_DAMAGE);
+
+ if (target) {
+ uint16_t playerCharmRaceid = player->parseRacebyCharm(CHARM_LOW, false, 0);
+ if (playerCharmRaceid != 0) {
+ const auto mType = g_monsters().getMonsterType(target->getName());
+ if (mType && playerCharmRaceid == mType->info.raceid) {
+ const auto charm = g_iobestiary().getBestiaryCharm(CHARM_LOW);
+ if (charm) {
+ chance += charm->percent;
+ g_game().sendDoubleSoundEffect(target->getPosition(), charm->soundCastEffect, charm->soundImpactEffect, caster);
+ }
+ }
+ }
+ }
+ } else if (monster) {
+ chance = monster->critChance();
+ }
+
+ multiplier += damage.criticalDamage;
+ multiplier = 1 + multiplier / 100;
+ chance += (uint16_t)damage.criticalChance;
+
+ if (chance != 0 && uniform_random(1, 100) <= chance) {
+ damage.critical = true;
+ damage.primary.value *= multiplier;
+ damage.secondary.value *= multiplier;
+ }
+
+ if (player) {
+ // Fatal hit (onslaught)
+ if (auto playerWeapon = player->getInventoryItem(CONST_SLOT_LEFT);
+ playerWeapon != nullptr && playerWeapon->getTier() > 0) {
+ double_t fatalChance = playerWeapon->getFatalChance();
+ double_t randomChance = uniform_random(0, 10000) / 100;
+ if (fatalChance > 0 && randomChance < fatalChance) {
+ damage.fatal = true;
+ damage.primary.value += static_cast(std::round(damage.primary.value * 0.6));
+ damage.secondary.value += static_cast(std::round(damage.secondary.value * 0.6));
+ }
+ }
+ } else if (monster) {
+ damage.primary.value *= monster->getAttackMultiplier();
+ damage.secondary.value *= monster->getAttackMultiplier();
+ }
+}
diff --git a/src/creatures/combat/combat.hpp b/src/creatures/combat/combat.hpp
index 88c2db31312..2bb2d0a3589 100644
--- a/src/creatures/combat/combat.hpp
+++ b/src/creatures/combat/combat.hpp
@@ -21,8 +21,6 @@ class Spell;
class Player;
class MatrixArea;
-static const std::unique_ptr &MatrixAreaNull {};
-
// for luascript callback
class ValueCallback final : public CallBack {
public:
@@ -247,15 +245,10 @@ class AreaCombat {
}
}
- auto it = areas.find(dir);
- if (it == areas.end()) {
- return MatrixAreaNull;
- }
-
- return it->second;
+ return areas[dir];
}
- std::map> areas;
+ std::array, Direction::DIRECTION_LAST + 1> areas {};
bool hasExtArea = false;
};
@@ -267,6 +260,8 @@ class Combat {
Combat(const Combat &) = delete;
Combat &operator=(const Combat &) = delete;
+ static void applyExtensions(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms);
+
static void doCombatHealth(std::shared_ptr caster, std::shared_ptr target, CombatDamage &damage, const CombatParams ¶ms);
static void doCombatHealth(std::shared_ptr caster, const Position &position, const std::unique_ptr &area, CombatDamage &damage, const CombatParams ¶ms);
diff --git a/src/creatures/monsters/monster.cpp b/src/creatures/monsters/monster.cpp
index 4ef06634933..0ce9432ea68 100644
--- a/src/creatures/monsters/monster.cpp
+++ b/src/creatures/monsters/monster.cpp
@@ -14,7 +14,6 @@
#include "creatures/players/wheel/player_wheel.hpp"
#include "game/game.hpp"
#include "game/scheduling/dispatcher.hpp"
-#include "lua/creature/events.hpp"
#include "lua/callbacks/event_callback.hpp"
#include "lua/callbacks/events_callbacks.hpp"
#include "map/spectators.hpp"
@@ -812,12 +811,6 @@ void Monster::doAttacking(uint32_t interval) {
bool resetTicks = interval != 0;
attackTicks += interval;
- float forgeAttackBonus = 0;
- if (monsterForgeClassification > ForgeClassifications_t::FORGE_NORMAL_MONSTER) {
- uint16_t damageBase = 3;
- forgeAttackBonus = static_cast(damageBase + 100) / 100.f;
- }
-
const Position &myPos = getPosition();
const Position &targetPos = attackedCreature->getPosition();
@@ -835,20 +828,8 @@ void Monster::doAttacking(uint32_t interval) {
updateLook = false;
}
- float multiplier;
- if (maxCombatValue > 0) { // Defense
- multiplier = getDefenseMultiplier();
- } else { // Attack
- multiplier = getAttackMultiplier();
- }
-
- minCombatValue = spellBlock.minCombatValue * multiplier;
- maxCombatValue = spellBlock.maxCombatValue * multiplier;
-
- if (maxCombatValue <= 0 && forgeAttackBonus > 0) {
- minCombatValue *= static_cast(forgeAttackBonus);
- maxCombatValue *= static_cast(forgeAttackBonus);
- }
+ minCombatValue = spellBlock.minCombatValue;
+ maxCombatValue = spellBlock.maxCombatValue;
if (spellBlock.spell == nullptr) {
continue;
@@ -1913,15 +1894,8 @@ bool Monster::getCombatValues(int32_t &min, int32_t &max) {
return false;
}
- float multiplier;
- if (maxCombatValue > 0) { // Defense
- multiplier = getDefenseMultiplier();
- } else { // Attack
- multiplier = getAttackMultiplier();
- }
-
- min = minCombatValue * multiplier;
- max = maxCombatValue * multiplier;
+ min = minCombatValue;
+ max = maxCombatValue;
return true;
}
diff --git a/src/creatures/monsters/monster.hpp b/src/creatures/monsters/monster.hpp
index 5f589af0e28..858b3ac8dd8 100644
--- a/src/creatures/monsters/monster.hpp
+++ b/src/creatures/monsters/monster.hpp
@@ -77,13 +77,13 @@ class Monster final : public Creature {
return mType->info.race;
}
float getMitigation() const override {
- return mType->info.mitigation;
+ return mType->info.mitigation * getDefenseMultiplier();
}
int32_t getArmor() const override {
- return mType->info.armor;
+ return mType->info.armor * getDefenseMultiplier();
}
int32_t getDefense() const override {
- return mType->info.defense;
+ return mType->info.defense * getDefenseMultiplier();
}
Faction_t getFaction() const override {
@@ -126,6 +126,9 @@ class Monster final : public Creature {
bool canSeeInvisibility() const override {
return isImmune(CONDITION_INVISIBLE);
}
+ uint16_t critChance() const {
+ return mType->info.critChance;
+ }
uint32_t getManaCost() const {
return mType->info.manaCost;
}
@@ -325,6 +328,16 @@ class Monster final : public Creature {
bool isImmune(ConditionType_t conditionType) const override;
bool isImmune(CombatType_t combatType) const override;
+ float getAttackMultiplier() const {
+ float multiplier = mType->getAttackMultiplier();
+ return multiplier * std::pow(1.03f, getForgeStack());
+ }
+
+ float getDefenseMultiplier() const {
+ float multiplier = mType->getDefenseMultiplier();
+ return multiplier * std::pow(1.01f, getForgeStack());
+ }
+
private:
CreatureWeakHashMap friendList;
CreatureIDList targetIDList;
@@ -436,14 +449,4 @@ class Monster final : public Creature {
void doRandomStep(Direction &nextDirection, bool &result);
void onConditionStatusChange(const ConditionType_t &type);
-
- float getAttackMultiplier() const {
- float multiplier = mType->getAttackMultiplier();
- return multiplier * std::pow(1.03f, getForgeStack());
- }
-
- float getDefenseMultiplier() const {
- float multiplier = mType->getAttackMultiplier();
- return multiplier * std::pow(1.01f, getForgeStack());
- }
};
diff --git a/src/creatures/monsters/monsters.hpp b/src/creatures/monsters/monsters.hpp
index a13792fd297..b214b478e3b 100644
--- a/src/creatures/monsters/monsters.hpp
+++ b/src/creatures/monsters/monsters.hpp
@@ -128,6 +128,7 @@ class MonsterType {
int32_t changeTargetChance = 0;
int32_t defense = 0;
int32_t armor = 0;
+ uint16_t critChance = 0;
int32_t strategiesTargetNearest = 0;
int32_t strategiesTargetHealth = 0;
int32_t strategiesTargetDamage = 0;
diff --git a/src/creatures/npcs/npcs.cpp b/src/creatures/npcs/npcs.cpp
index 432b0adbe15..c18897d1c4c 100644
--- a/src/creatures/npcs/npcs.cpp
+++ b/src/creatures/npcs/npcs.cpp
@@ -11,7 +11,6 @@
#include "declarations.hpp"
#include "creatures/combat/combat.hpp"
-#include "creatures/creature.hpp"
#include "lua/scripts/lua_environment.hpp"
#include "creatures/combat/spells.hpp"
#include "creatures/npcs/npcs.hpp"
diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp
index 59b9292662d..0ec4bedf8a4 100644
--- a/src/creatures/players/player.cpp
+++ b/src/creatures/players/player.cpp
@@ -4222,7 +4222,7 @@ void Player::doAttacking(uint32_t) {
bool result = false;
std::shared_ptr
- tool = getWeapon();
- const Weapon* weapon = g_weapons().getWeapon(tool);
+ const WeaponShared_ptr weapon = g_weapons().getWeapon(tool);
uint32_t delay = getAttackSpeed();
bool classicSpeed = g_configManager().getBoolean(CLASSIC_ATTACK_SPEED);
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 88264725b41..9f853ab6b22 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -12,13 +12,11 @@
#include "lua/creature/actions.hpp"
#include "items/bed.hpp"
#include "creatures/creature.hpp"
-#include "lua/creature/creatureevent.hpp"
#include "database/databasetasks.hpp"
#include "lua/creature/events.hpp"
#include "lua/callbacks/event_callback.hpp"
#include "lua/callbacks/events_callbacks.hpp"
#include "game/game.hpp"
-#include "game/functions/game_reload.hpp"
#include "game/zones/zone.hpp"
#include "lua/global/globalevent.hpp"
#include "io/iologindata.hpp"
@@ -34,13 +32,9 @@
#include "creatures/combat/spells.hpp"
#include "lua/creature/talkaction.hpp"
#include "items/weapons/weapons.hpp"
-#include "lua/scripts/scripts.hpp"
-#include "lua/modules/modules.hpp"
#include "creatures/players/imbuements/imbuements.hpp"
-#include "account/account.hpp"
#include "creatures/players/wheel/player_wheel.hpp"
#include "creatures/npcs/npc.hpp"
-#include "creatures/npcs/npcs.hpp"
#include "server/network/webhook/webhook.hpp"
#include "protobuf/appearances.pb.h"
#include "server/network/protocol/protocollogin.hpp"
diff --git a/src/game/scheduling/events_scheduler.cpp b/src/game/scheduling/events_scheduler.cpp
index f7bd197979e..d5c71378f4a 100644
--- a/src/game/scheduling/events_scheduler.cpp
+++ b/src/game/scheduling/events_scheduler.cpp
@@ -12,7 +12,6 @@
#include "config/configmanager.hpp"
#include "game/scheduling/events_scheduler.hpp"
#include "lua/scripts/scripts.hpp"
-#include "utils/pugicast.hpp"
bool EventsScheduler::loadScheduleEventFromXml() {
pugi::xml_document doc;
diff --git a/src/game/zones/zone.cpp b/src/game/zones/zone.cpp
index e06975ff7a6..f1aa300efee 100644
--- a/src/game/zones/zone.cpp
+++ b/src/game/zones/zone.cpp
@@ -14,7 +14,6 @@
#include "creatures/monsters/monster.hpp"
#include "creatures/npcs/npc.hpp"
#include "creatures/players/player.hpp"
-#include "game/scheduling/dispatcher.hpp"
phmap::parallel_flat_hash_map> Zone::zones = {};
const static std::shared_ptr nullZone = nullptr;
diff --git a/src/io/iologindata.cpp b/src/io/iologindata.cpp
index 307d41a9cb3..f32b90568a4 100644
--- a/src/io/iologindata.cpp
+++ b/src/io/iologindata.cpp
@@ -15,7 +15,6 @@
#include "game/game.hpp"
#include "creatures/monsters/monster.hpp"
#include "creatures/players/wheel/player_wheel.hpp"
-#include "io/ioprey.hpp"
bool IOLoginData::gameWorldAuthentication(const std::string &accountDescriptor, const std::string &password, std::string &characterName, uint32_t &accountId, bool oldProtocol) {
account::Account account(accountDescriptor);
diff --git a/src/io/ioprey.cpp b/src/io/ioprey.cpp
index b81dad1fdf7..50c3070b4a0 100644
--- a/src/io/ioprey.cpp
+++ b/src/io/ioprey.cpp
@@ -9,7 +9,6 @@
#include "pch.hpp"
-#include "declarations.hpp"
#include "creatures/monsters/monster.hpp"
#include "creatures/players/player.hpp"
#include "config/configmanager.hpp"
diff --git a/src/items/item.cpp b/src/items/item.cpp
index ea04be89385..4677041e777 100644
--- a/src/items/item.cpp
+++ b/src/items/item.cpp
@@ -10,7 +10,6 @@
#include "pch.hpp"
#include "items/item.hpp"
-#include "items/functions/item/item_parse.hpp"
#include "items/containers/container.hpp"
#include "items/decay/decay.hpp"
#include "game/movement/teleport.hpp"
@@ -186,7 +185,7 @@ Item::Item(const uint16_t itemId, uint16_t itemCount /*= 0*/) :
const ItemType &it = items[id];
auto itemCharges = it.charges;
if (it.isFluidContainer() || it.isSplash()) {
- setAttribute(ItemAttribute_t::FLUIDTYPE, itemCount);
+ setAttribute(ItemAttribute_t::FLUIDTYPE, itemCount * (itemCount < sizeof(Fluids_t)));
} else if (it.stackable) {
if (itemCount != 0) {
setItemCount(static_cast(itemCount));
diff --git a/src/items/items.cpp b/src/items/items.cpp
index ca8e20e5b30..690e01a5b92 100644
--- a/src/items/items.cpp
+++ b/src/items/items.cpp
@@ -11,7 +11,6 @@
#include "items/functions/item/item_parse.hpp"
#include "items/items.hpp"
-#include "items/weapons/weapons.hpp"
#include "game/game.hpp"
#include "utils/pugicast.hpp"
diff --git a/src/items/tile.cpp b/src/items/tile.cpp
index 25f7f865688..0d9a5db0ead 100644
--- a/src/items/tile.cpp
+++ b/src/items/tile.cpp
@@ -19,7 +19,6 @@
#include "lua/creature/movement.hpp"
#include "game/movement/teleport.hpp"
#include "items/trashholder.hpp"
-#include "map/house/housetile.hpp"
#include "io/iomap.hpp"
#include "map/spectators.hpp"
diff --git a/src/items/weapons/weapons.cpp b/src/items/weapons/weapons.cpp
index 995b71518c0..08f1d75c032 100644
--- a/src/items/weapons/weapons.cpp
+++ b/src/items/weapons/weapons.cpp
@@ -17,7 +17,7 @@
Weapons::Weapons() = default;
Weapons::~Weapons() = default;
-const Weapon* Weapons::getWeapon(std::shared_ptr
- item) const {
+const WeaponShared_ptr Weapons::getWeapon(std::shared_ptr
- item) const {
if (!item) {
return nullptr;
}
@@ -33,7 +33,7 @@ void Weapons::clear() {
weapons.clear();
}
-bool Weapons::registerLuaEvent(Weapon* event) {
+bool Weapons::registerLuaEvent(WeaponShared_ptr event) {
weapons[event->getID()] = event;
return true;
}
@@ -524,7 +524,7 @@ bool WeaponDistance::useWeapon(std::shared_ptr player, std::shared_ptr mainWeaponItem = player->getWeapon(true);
- const Weapon* mainWeapon = g_weapons().getWeapon(mainWeaponItem);
+ const WeaponShared_ptr mainWeapon = g_weapons().getWeapon(mainWeaponItem);
if (mainWeapon) {
damageModifier = mainWeapon->playerWeaponCheck(player, target, mainWeaponItem->getShootRange());
} else {
diff --git a/src/items/weapons/weapons.hpp b/src/items/weapons/weapons.hpp
index 90785983e17..78a7195fb3c 100644
--- a/src/items/weapons/weapons.hpp
+++ b/src/items/weapons/weapons.hpp
@@ -21,7 +21,8 @@ class WeaponMelee;
class WeaponDistance;
class WeaponWand;
-using Weapon_ptr = std::unique_ptr;
+using WeaponUnique_ptr = std::unique_ptr;
+using WeaponShared_ptr = std::shared_ptr;
class Weapons final : public Scripts {
public:
@@ -36,16 +37,16 @@ class Weapons final : public Scripts {
return inject();
}
- const Weapon* getWeapon(std::shared_ptr
- item) const;
+ const WeaponShared_ptr getWeapon(std::shared_ptr
- item) const;
static int32_t getMaxMeleeDamage(int32_t attackSkill, int32_t attackValue);
static int32_t getMaxWeaponDamage(uint32_t level, int32_t attackSkill, int32_t attackValue, float attackFactor, bool isMelee);
- bool registerLuaEvent(Weapon* event);
+ bool registerLuaEvent(WeaponShared_ptr event);
void clear();
private:
- std::map weapons;
+ std::map weapons;
};
constexpr auto g_weapons = Weapons::getInstance;
diff --git a/src/kv/kv.cpp b/src/kv/kv.cpp
index cd2a8b974b5..e5dbc974b76 100644
--- a/src/kv/kv.cpp
+++ b/src/kv/kv.cpp
@@ -11,7 +11,6 @@
#include "kv/kv.hpp"
#include "lib/di/container.hpp"
-#include "utils/tools.hpp"
KVStore &KVStore::getInstance() {
return inject();
diff --git a/src/kv/value_wrapper.hpp b/src/kv/value_wrapper.hpp
index 9317eb6b8fd..a4e899adcb0 100644
--- a/src/kv/value_wrapper.hpp
+++ b/src/kv/value_wrapper.hpp
@@ -179,7 +179,10 @@ inline bool operator==(const ValueVariant &lhs, const ValueVariant &rhs) {
return b.contains(key) && value.get() == b.at(key).get();
});
}
- return a == b;
+ // Compares a and b if types A and B are the same, at compile-time
+ if constexpr (std::is_same_v) {
+ return a == b;
+ }
},
lhs, rhs
);
diff --git a/src/lua/callbacks/event_callback.cpp b/src/lua/callbacks/event_callback.cpp
index 6444446bde9..8510502b226 100644
--- a/src/lua/callbacks/event_callback.cpp
+++ b/src/lua/callbacks/event_callback.cpp
@@ -11,8 +11,6 @@
#include "lua/callbacks/event_callback.hpp"
-#include "lua/callbacks/event_callback.hpp"
-#include "lua/callbacks/events_callbacks.hpp"
#include "utils/tools.hpp"
#include "items/item.hpp"
#include "creatures/players/player.hpp"
diff --git a/src/lua/functions/core/game/config_functions.cpp b/src/lua/functions/core/game/config_functions.cpp
index a64f1d91b66..bdeaa226fc1 100644
--- a/src/lua/functions/core/game/config_functions.cpp
+++ b/src/lua/functions/core/game/config_functions.cpp
@@ -251,6 +251,8 @@ void ConfigFunctions::init(lua_State* L) {
registerEnumIn(L, "configKeys", VIP_FAMILIAR_TIME_COOLDOWN_REDUCTION);
registerEnumIn(L, "configKeys", TOGGLE_HOUSE_TRANSFER_ON_SERVER_RESTART);
+
+ registerEnumIn(L, "configKeys", TOGGLE_RECEIVE_REWARD);
#undef registerEnumIn
}
diff --git a/src/lua/functions/core/game/game_functions.cpp b/src/lua/functions/core/game/game_functions.cpp
index 86358f1daf7..ec59b8b1c34 100644
--- a/src/lua/functions/core/game/game_functions.cpp
+++ b/src/lua/functions/core/game/game_functions.cpp
@@ -23,7 +23,6 @@
#include "lua/creature/talkaction.hpp"
#include "lua/functions/creatures/npc/npc_type_functions.hpp"
#include "lua/scripts/lua_environment.hpp"
-#include "lua/scripts/scripts.hpp"
#include "lua/creature/events.hpp"
#include "lua/callbacks/event_callback.hpp"
#include "lua/callbacks/events_callbacks.hpp"
diff --git a/src/lua/functions/core/game/lua_enums.cpp b/src/lua/functions/core/game/lua_enums.cpp
index 8d86185290f..fc1586f3363 100644
--- a/src/lua/functions/core/game/lua_enums.cpp
+++ b/src/lua/functions/core/game/lua_enums.cpp
@@ -11,15 +11,12 @@
#include "lua/functions/core/game/lua_enums.hpp"
-#include "account/account.hpp"
#include "creatures/players/wheel/wheel_definitions.hpp"
#include "io/io_bosstiary.hpp"
#include "config/configmanager.hpp"
#include "creatures/creature.hpp"
-#include "lua/creature/creatureevent.hpp"
#include "declarations.hpp"
#include "game/functions/game_reload.hpp"
-#include "game/game.hpp"
#define registerEnumClass(luaState, enumClassType) \
{ \
diff --git a/src/lua/functions/creatures/monster/monster_type_functions.cpp b/src/lua/functions/creatures/monster/monster_type_functions.cpp
index 1beea8de66b..ba77c49a90a 100644
--- a/src/lua/functions/creatures/monster/monster_type_functions.cpp
+++ b/src/lua/functions/creatures/monster/monster_type_functions.cpp
@@ -280,6 +280,20 @@ int MonsterTypeFunctions::luaMonsterTypeCanPushCreatures(lua_State* L) {
return 1;
}
+int MonsterTypeFunctions::luaMonsterTypeCritChance(lua_State* L) {
+ // get: monsterType:critChance() set: monsterType:critChance(int)
+ const auto monsterType = getUserdataShared(L, 1);
+ if (monsterType) {
+ if (lua_gettop(L) == 2) {
+ monsterType->info.critChance = getNumber(L, 2);
+ }
+ lua_pushnumber(L, monsterType->info.critChance);
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
int32_t MonsterTypeFunctions::luaMonsterTypeName(lua_State* L) {
// get: monsterType:name() set: monsterType:name(name)
const auto monsterType = getUserdataShared(L, 1);
diff --git a/src/lua/functions/creatures/monster/monster_type_functions.hpp b/src/lua/functions/creatures/monster/monster_type_functions.hpp
index d9c513d2bce..9d892219250 100644
--- a/src/lua/functions/creatures/monster/monster_type_functions.hpp
+++ b/src/lua/functions/creatures/monster/monster_type_functions.hpp
@@ -35,6 +35,8 @@ class MonsterTypeFunctions final : LuaScriptInterface {
registerMethod(L, "MonsterType", "canPushItems", MonsterTypeFunctions::luaMonsterTypeCanPushItems);
registerMethod(L, "MonsterType", "canPushCreatures", MonsterTypeFunctions::luaMonsterTypeCanPushCreatures);
+ registerMethod(L, "MonsterType", "critChance", MonsterTypeFunctions::luaMonsterTypeCritChance);
+
registerMethod(L, "MonsterType", "name", MonsterTypeFunctions::luaMonsterTypeName);
registerMethod(L, "MonsterType", "nameDescription", MonsterTypeFunctions::luaMonsterTypeNameDescription);
@@ -260,10 +262,5 @@ class MonsterTypeFunctions final : LuaScriptInterface {
static int luaMonsterTypeAddSound(lua_State* L);
static int luaMonsterTypeGetSounds(lua_State* L);
static int luaMonsterTypedeathSound(lua_State* L);
-
- // Hazard system
- static int luaMonsterTypeHazardSystemCrit(lua_State* L);
- static int luaMonsterTypeHazardSystemDodge(lua_State* L);
- static int luaMonsterTypeHazardSystemSpawnPod(lua_State* L);
- static int luaMonsterTypeHazardSystemDamageBoost(lua_State* L);
+ static int luaMonsterTypeCritChance(lua_State* L);
};
diff --git a/src/lua/functions/items/imbuement_functions.cpp b/src/lua/functions/items/imbuement_functions.cpp
index f512e56a62b..2a4e85d7d88 100644
--- a/src/lua/functions/items/imbuement_functions.cpp
+++ b/src/lua/functions/items/imbuement_functions.cpp
@@ -9,7 +9,6 @@
#include "pch.hpp"
-#include "items/item.hpp"
#include "items/weapons/weapons.hpp"
#include "creatures/players/imbuements/imbuements.hpp"
#include "lua/functions/items/imbuement_functions.hpp"
diff --git a/src/lua/functions/items/weapon_functions.cpp b/src/lua/functions/items/weapon_functions.cpp
index 2e5fde7ff15..3a41d0ac75d 100644
--- a/src/lua/functions/items/weapon_functions.cpp
+++ b/src/lua/functions/items/weapon_functions.cpp
@@ -25,7 +25,7 @@ int WeaponFunctions::luaCreateWeapon(lua_State* L) {
case WEAPON_AXE:
case WEAPON_CLUB: {
if (auto weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) {
- pushUserdata(L, weaponPtr.get());
+ pushUserdata(L, weaponPtr);
setMetatable(L, -1, "Weapon");
weaponPtr->weaponType = type;
} else {
@@ -37,7 +37,7 @@ int WeaponFunctions::luaCreateWeapon(lua_State* L) {
case WEAPON_DISTANCE:
case WEAPON_AMMO: {
if (auto weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) {
- pushUserdata(L, weaponPtr.get());
+ pushUserdata(L, weaponPtr);
setMetatable(L, -1, "Weapon");
weaponPtr->weaponType = type;
} else {
@@ -47,7 +47,7 @@ int WeaponFunctions::luaCreateWeapon(lua_State* L) {
}
case WEAPON_WAND: {
if (auto weaponPtr = g_luaEnvironment().createWeaponObject(getScriptEnv()->getScriptInterface())) {
- pushUserdata(L, weaponPtr.get());
+ pushUserdata(L, weaponPtr);
setMetatable(L, -1, "Weapon");
weaponPtr->weaponType = type;
} else {
@@ -65,7 +65,7 @@ int WeaponFunctions::luaCreateWeapon(lua_State* L) {
int WeaponFunctions::luaWeaponAction(lua_State* L) {
// weapon:action(callback)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
std::string typeName = getString(L, 2);
std::string tmpStr = asLowerCaseString(typeName);
@@ -90,15 +90,15 @@ int WeaponFunctions::luaWeaponAction(lua_State* L) {
int WeaponFunctions::luaWeaponRegister(lua_State* L) {
// weapon:register()
- Weapon** weaponPtr = getRawUserdata(L, 1);
+ WeaponShared_ptr* weaponPtr = getRawUserDataShared(L, 1);
if (weaponPtr && *weaponPtr) {
- Weapon* weapon = *weaponPtr;
+ WeaponShared_ptr weapon = *weaponPtr;
if (weapon->weaponType == WEAPON_DISTANCE || weapon->weaponType == WEAPON_AMMO || weapon->weaponType == WEAPON_MISSILE) {
- weapon = getUserdata(L, 1);
+ weapon = getUserdataShared(L, 1);
} else if (weapon->weaponType == WEAPON_WAND) {
- weapon = getUserdata(L, 1);
+ weapon = getUserdataShared(L, 1);
} else {
- weapon = getUserdata(L, 1);
+ weapon = getUserdataShared(L, 1);
}
uint16_t id = weapon->getID();
@@ -123,7 +123,7 @@ int WeaponFunctions::luaWeaponRegister(lua_State* L) {
int WeaponFunctions::luaWeaponOnUseWeapon(lua_State* L) {
// weapon:onUseWeapon(callback)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
if (!weapon->loadCallback()) {
pushBoolean(L, false);
@@ -139,7 +139,7 @@ int WeaponFunctions::luaWeaponOnUseWeapon(lua_State* L) {
int WeaponFunctions::luaWeaponUnproperly(lua_State* L) {
// weapon:wieldedUnproperly(bool)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setWieldUnproperly(getBoolean(L, 2));
pushBoolean(L, true);
@@ -151,7 +151,7 @@ int WeaponFunctions::luaWeaponUnproperly(lua_State* L) {
int WeaponFunctions::luaWeaponLevel(lua_State* L) {
// weapon:level(lvl)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setRequiredLevel(getNumber(L, 2));
weapon->setWieldInfo(WIELDINFO_LEVEL);
@@ -164,7 +164,7 @@ int WeaponFunctions::luaWeaponLevel(lua_State* L) {
int WeaponFunctions::luaWeaponMagicLevel(lua_State* L) {
// weapon:magicLevel(lvl)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setRequiredMagLevel(getNumber(L, 2));
weapon->setWieldInfo(WIELDINFO_MAGLV);
@@ -177,7 +177,7 @@ int WeaponFunctions::luaWeaponMagicLevel(lua_State* L) {
int WeaponFunctions::luaWeaponMana(lua_State* L) {
// weapon:mana(mana)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setMana(getNumber(L, 2));
pushBoolean(L, true);
@@ -189,7 +189,7 @@ int WeaponFunctions::luaWeaponMana(lua_State* L) {
int WeaponFunctions::luaWeaponManaPercent(lua_State* L) {
// weapon:manaPercent(percent)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setManaPercent(getNumber(L, 2));
pushBoolean(L, true);
@@ -201,7 +201,7 @@ int WeaponFunctions::luaWeaponManaPercent(lua_State* L) {
int WeaponFunctions::luaWeaponHealth(lua_State* L) {
// weapon:health(health)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setHealth(getNumber(L, 2));
pushBoolean(L, true);
@@ -213,7 +213,7 @@ int WeaponFunctions::luaWeaponHealth(lua_State* L) {
int WeaponFunctions::luaWeaponHealthPercent(lua_State* L) {
// weapon:healthPercent(percent)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setHealthPercent(getNumber(L, 2));
pushBoolean(L, true);
@@ -225,7 +225,7 @@ int WeaponFunctions::luaWeaponHealthPercent(lua_State* L) {
int WeaponFunctions::luaWeaponSoul(lua_State* L) {
// weapon:soul(soul)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setSoul(getNumber(L, 2));
pushBoolean(L, true);
@@ -237,7 +237,7 @@ int WeaponFunctions::luaWeaponSoul(lua_State* L) {
int WeaponFunctions::luaWeaponBreakChance(lua_State* L) {
// weapon:breakChance(percent)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setBreakChance(getNumber(L, 2));
pushBoolean(L, true);
@@ -249,7 +249,7 @@ int WeaponFunctions::luaWeaponBreakChance(lua_State* L) {
int WeaponFunctions::luaWeaponWandDamage(lua_State* L) {
// weapon:damage(damage[min, max]) only use this if the weapon is a wand!
- WeaponWand* weapon = getUserdata(L, 1);
+ const auto &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setMinChange(getNumber(L, 2));
if (lua_gettop(L) > 2) {
@@ -266,7 +266,7 @@ int WeaponFunctions::luaWeaponWandDamage(lua_State* L) {
int WeaponFunctions::luaWeaponElement(lua_State* L) {
// weapon:element(combatType)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
if (!getNumber(L, 2)) {
std::string element = getString(L, 2);
@@ -300,7 +300,7 @@ int WeaponFunctions::luaWeaponElement(lua_State* L) {
int WeaponFunctions::luaWeaponPremium(lua_State* L) {
// weapon:premium(bool)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setNeedPremium(getBoolean(L, 2));
weapon->setWieldInfo(WIELDINFO_PREMIUM);
@@ -313,7 +313,7 @@ int WeaponFunctions::luaWeaponPremium(lua_State* L) {
int WeaponFunctions::luaWeaponVocation(lua_State* L) {
// weapon:vocation(vocName[, showInDescription = false, lastVoc = false])
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->addVocWeaponMap(getString(L, 2));
weapon->setWieldInfo(WIELDINFO_VOCREQ);
@@ -352,7 +352,7 @@ int WeaponFunctions::luaWeaponVocation(lua_State* L) {
int WeaponFunctions::luaWeaponId(lua_State* L) {
// weapon:id(id)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
weapon->setID(getNumber(L, 2));
pushBoolean(L, true);
@@ -364,7 +364,7 @@ int WeaponFunctions::luaWeaponId(lua_State* L) {
int WeaponFunctions::luaWeaponAttack(lua_State* L) {
// weapon:attack(atk)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -378,7 +378,7 @@ int WeaponFunctions::luaWeaponAttack(lua_State* L) {
int WeaponFunctions::luaWeaponDefense(lua_State* L) {
// weapon:defense(defense[, extraDefense])
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -395,7 +395,7 @@ int WeaponFunctions::luaWeaponDefense(lua_State* L) {
int WeaponFunctions::luaWeaponRange(lua_State* L) {
// weapon:range(range)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -409,7 +409,7 @@ int WeaponFunctions::luaWeaponRange(lua_State* L) {
int WeaponFunctions::luaWeaponCharges(lua_State* L) {
// weapon:charges(charges[, showCharges = true])
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
bool showCharges = true;
if (lua_gettop(L) > 2) {
@@ -428,7 +428,7 @@ int WeaponFunctions::luaWeaponCharges(lua_State* L) {
int WeaponFunctions::luaWeaponDuration(lua_State* L) {
// weapon:duration(duration[, showDuration = true])
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
bool showDuration = true;
if (lua_gettop(L) > 2) {
@@ -447,7 +447,7 @@ int WeaponFunctions::luaWeaponDuration(lua_State* L) {
int WeaponFunctions::luaWeaponDecayTo(lua_State* L) {
// weapon:decayTo([itemid = 0]
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t itemid = 0;
if (lua_gettop(L) > 1) {
@@ -465,7 +465,7 @@ int WeaponFunctions::luaWeaponDecayTo(lua_State* L) {
int WeaponFunctions::luaWeaponTransformEquipTo(lua_State* L) {
// weapon:transformEquipTo(itemid)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -479,7 +479,7 @@ int WeaponFunctions::luaWeaponTransformEquipTo(lua_State* L) {
int WeaponFunctions::luaWeaponTransformDeEquipTo(lua_State* L) {
// weapon:transformDeEquipTo(itemid)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -493,7 +493,7 @@ int WeaponFunctions::luaWeaponTransformDeEquipTo(lua_State* L) {
int WeaponFunctions::luaWeaponShootType(lua_State* L) {
// weapon:shootType(type)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -507,7 +507,7 @@ int WeaponFunctions::luaWeaponShootType(lua_State* L) {
int WeaponFunctions::luaWeaponSlotType(lua_State* L) {
// weapon:slotType(slot)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -527,7 +527,7 @@ int WeaponFunctions::luaWeaponSlotType(lua_State* L) {
int WeaponFunctions::luaWeaponAmmoType(lua_State* L) {
// weapon:ammoType(type)
- WeaponDistance* weapon = getUserdata(L, 1);
+ const auto &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -553,7 +553,7 @@ int WeaponFunctions::luaWeaponAmmoType(lua_State* L) {
int WeaponFunctions::luaWeaponHitChance(lua_State* L) {
// weapon:hitChance(chance)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -567,7 +567,7 @@ int WeaponFunctions::luaWeaponHitChance(lua_State* L) {
int WeaponFunctions::luaWeaponMaxHitChance(lua_State* L) {
// weapon:maxHitChance(max)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
@@ -581,34 +581,34 @@ int WeaponFunctions::luaWeaponMaxHitChance(lua_State* L) {
int WeaponFunctions::luaWeaponExtraElement(lua_State* L) {
// weapon:extraElement(atk, combatType)
- Weapon* weapon = getUserdata(L, 1);
+ const WeaponShared_ptr &weapon = getUserdataShared(L, 1);
if (weapon) {
uint16_t id = weapon->getID();
ItemType &it = Item::items.getItemType(id);
- it.abilities.get()->elementDamage = getNumber(L, 2);
+ it.abilities->elementDamage = getNumber(L, 2);
if (!getNumber(L, 3)) {
std::string element = getString(L, 3);
std::string tmpStrValue = asLowerCaseString(element);
if (tmpStrValue == "earth") {
- it.abilities.get()->elementType = COMBAT_EARTHDAMAGE;
+ it.abilities->elementType = COMBAT_EARTHDAMAGE;
} else if (tmpStrValue == "ice") {
- it.abilities.get()->elementType = COMBAT_ICEDAMAGE;
+ it.abilities->elementType = COMBAT_ICEDAMAGE;
} else if (tmpStrValue == "energy") {
- it.abilities.get()->elementType = COMBAT_ENERGYDAMAGE;
+ it.abilities->elementType = COMBAT_ENERGYDAMAGE;
} else if (tmpStrValue == "fire") {
- it.abilities.get()->elementType = COMBAT_FIREDAMAGE;
+ it.abilities->elementType = COMBAT_FIREDAMAGE;
} else if (tmpStrValue == "death") {
- it.abilities.get()->elementType = COMBAT_DEATHDAMAGE;
+ it.abilities->elementType = COMBAT_DEATHDAMAGE;
} else if (tmpStrValue == "holy") {
- it.abilities.get()->elementType = COMBAT_HOLYDAMAGE;
+ it.abilities->elementType = COMBAT_HOLYDAMAGE;
} else {
g_logger().warn("[WeaponFunctions:luaWeaponExtraElement] - "
"Type {} does not exist",
element);
}
} else {
- it.abilities.get()->elementType = getNumber(L, 3);
+ it.abilities->elementType = getNumber(L, 3);
}
pushBoolean(L, true);
} else {
diff --git a/src/lua/functions/items/weapon_functions.hpp b/src/lua/functions/items/weapon_functions.hpp
index 2f0d2e8ccb6..01ba6966317 100644
--- a/src/lua/functions/items/weapon_functions.hpp
+++ b/src/lua/functions/items/weapon_functions.hpp
@@ -14,7 +14,7 @@
class WeaponFunctions final : LuaScriptInterface {
public:
static void init(lua_State* L) {
- registerClass(L, "Weapon", "", WeaponFunctions::luaCreateWeapon);
+ registerSharedClass(L, "Weapon", "", WeaponFunctions::luaCreateWeapon);
registerMethod(L, "Weapon", "action", WeaponFunctions::luaWeaponAction);
registerMethod(L, "Weapon", "register", WeaponFunctions::luaWeaponRegister);
registerMethod(L, "Weapon", "id", WeaponFunctions::luaWeaponId);
diff --git a/src/lua/functions/lua_functions_loader.cpp b/src/lua/functions/lua_functions_loader.cpp
index 944849b1e6f..cf377592988 100644
--- a/src/lua/functions/lua_functions_loader.cpp
+++ b/src/lua/functions/lua_functions_loader.cpp
@@ -12,13 +12,11 @@
#include "creatures/combat/spells.hpp"
#include "creatures/monsters/monster.hpp"
#include "creatures/npcs/npc.hpp"
-#include "creatures/players/imbuements/imbuements.hpp"
#include "creatures/players/player.hpp"
#include "creatures/players/grouping/guild.hpp"
#include "game/zones/zone.hpp"
#include "game/game.hpp"
#include "game/movement/teleport.hpp"
-#include "items/weapons/weapons.hpp"
#include "lua/functions/core/core_functions.hpp"
#include "lua/functions/creatures/creature_functions.hpp"
#include "lua/functions/events/events_functions.hpp"
diff --git a/src/lua/scripts/lua_environment.hpp b/src/lua/scripts/lua_environment.hpp
index 216abb8ec78..042a21fe1d8 100644
--- a/src/lua/scripts/lua_environment.hpp
+++ b/src/lua/scripts/lua_environment.hpp
@@ -25,7 +25,7 @@ class LuaEnvironment : public LuaScriptInterface {
static bool shuttingDown;
LuaEnvironment();
- ~LuaEnvironment();
+ ~LuaEnvironment() override;
lua_State* getLuaState() override;
@@ -38,7 +38,7 @@ class LuaEnvironment : public LuaScriptInterface {
}
bool initState() override;
- bool reInitState();
+ bool reInitState() override;
bool closeState() override;
LuaScriptInterface* getTestInterface();
@@ -50,7 +50,7 @@ class LuaEnvironment : public LuaScriptInterface {
template
std::shared_ptr createWeaponObject(LuaScriptInterface* interface) {
auto weapon = std::make_shared(interface);
- int weaponId = ++lastWeaponId;
+ auto weaponId = ++lastWeaponId;
weaponMap[weaponId] = weapon;
weaponIdMap[interface].push_back(weaponId);
return weapon;
diff --git a/src/lua/scripts/luascript.hpp b/src/lua/scripts/luascript.hpp
index 80541e86d18..8f0b3b36c19 100644
--- a/src/lua/scripts/luascript.hpp
+++ b/src/lua/scripts/luascript.hpp
@@ -23,7 +23,7 @@ class LuaScriptInterface : public LuaFunctionsLoader {
LuaScriptInterface &operator=(const LuaScriptInterface &) = delete;
virtual bool initState();
- bool reInitState();
+ virtual bool reInitState();
int32_t loadFile(const std::string &file, const std::string &scriptName);
diff --git a/src/lua/scripts/script_environment.cpp b/src/lua/scripts/script_environment.cpp
index 8899a954f69..ccebdb1a8dd 100644
--- a/src/lua/scripts/script_environment.cpp
+++ b/src/lua/scripts/script_environment.cpp
@@ -9,7 +9,6 @@
#include "pch.hpp"
-#include "declarations.hpp"
#include "game/game.hpp"
#include "lua/scripts/luascript.hpp"
#include "lua/scripts/script_environment.hpp"
diff --git a/src/map/utils/qtreenode.cpp b/src/map/utils/qtreenode.cpp
index 92d0a0423ee..ace469e14aa 100644
--- a/src/map/utils/qtreenode.cpp
+++ b/src/map/utils/qtreenode.cpp
@@ -10,7 +10,6 @@
#include "pch.hpp"
#include "creatures/creature.hpp"
-#include "map/mapcache.hpp"
#include "qtreenode.hpp"
bool QTreeLeafNode::newLeaf = false;
diff --git a/src/server/network/connection/connection.cpp b/src/server/network/connection/connection.cpp
index 04e7a82a64f..c2df08b2824 100644
--- a/src/server/network/connection/connection.cpp
+++ b/src/server/network/connection/connection.cpp
@@ -12,7 +12,6 @@
#include "server/network/connection/connection.hpp"
#include "server/network/message/outputmessage.hpp"
#include "server/network/protocol/protocol.hpp"
-#include "server/network/protocol/protocolgame.hpp"
#include "game/scheduling/scheduler.hpp"
#include "game/scheduling/dispatcher.hpp"
#include "server/server.hpp"
diff --git a/src/server/network/message/networkmessage.cpp b/src/server/network/message/networkmessage.cpp
index 9c7b5a333cb..457e3b32be0 100644
--- a/src/server/network/message/networkmessage.cpp
+++ b/src/server/network/message/networkmessage.cpp
@@ -11,7 +11,6 @@
#include "server/network/message/networkmessage.hpp"
#include "items/containers/container.hpp"
-#include "creatures/creature.hpp"
int32_t NetworkMessage::decodeHeader() {
int32_t newSize = buffer[0] | buffer[1] << 8;
diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp
index 2848013701c..59c2867e519 100644
--- a/src/server/network/protocol/protocolgame.cpp
+++ b/src/server/network/protocol/protocolgame.cpp
@@ -6039,11 +6039,7 @@ void ProtocolGame::sendAllowBugReport() {
NetworkMessage msg;
msg.addByte(0x1A);
- if (player->getAccountType() >= account::ACCOUNT_TYPE_NORMAL) {
- msg.addByte(0x01);
- } else {
- msg.addByte(0x00);
- }
+ msg.addByte(0x00); // 0x01 = DISABLE bug report
writeToOutputBuffer(msg);
}