diff --git a/.github/workflows/build-windows-solution.yml b/.github/workflows/build-windows-solution.yml
index 58dcf97f159..4b2f5fb306c 100644
--- a/.github/workflows/build-windows-solution.yml
+++ b/.github/workflows/build-windows-solution.yml
@@ -17,6 +17,9 @@ on:
env:
CMAKE_BUILD_PARALLEL_LEVEL: 2
MAKEFLAGS: "-j 2"
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ VCPKG_ROOT: ${{ github.workspace }}/vcpkg
+ VCPKG_TRIPLET: x64-windows
jobs:
cancel-runs:
@@ -55,8 +58,16 @@ jobs:
./bootstrap-vcpkg.bat
./vcpkg integrate install
+ - name: Print useful paths
+ run: |
+ Write-Host "Workspace: $env:GITHUB_WORKSPACE"
+ Write-Host "Vcpkg Path: $env:GITHUB_WORKSPACE\vcpkg"
+ Write-Host "Triplet: ${{ matrix.triplet }}"
+
- name: Build project
- run: msbuild.exe /p:VcpkgEnableManifest=true /p:Configuration=Debug /p:Platform=x64 /p:VcpkgRoot=$env:GITHUB_WORKSPACE/vcpkg vcproj/canary.sln
+ env:
+ GITHUB_WORKSPACE: ${{ github.workspace }}
+ run: msbuild.exe /p:VcpkgEnableManifest=true /p:Configuration=Debug /p:Platform=x64 /p:GITHUB_WORKSPACE="$env:GITHUB_WORKSPACE" vcproj/canary.sln
- name: Upload artifacts
uses: actions/upload-artifact@main
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8730b5057fb..9c8ffef6c0a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -113,7 +113,6 @@ option(RUN_TESTS_AFTER_BUILD "Run tests when building" OFF) # By default, tests
# *****************************************************************************
# Add project
# *****************************************************************************
-add_subdirectory(src/protobuf)
add_subdirectory(src)
if(BUILD_TESTS)
diff --git a/cmake/modules/BaseConfig.cmake b/cmake/modules/BaseConfig.cmake
index b79167ed6a2..6f58a2eebdb 100644
--- a/cmake/modules/BaseConfig.cmake
+++ b/cmake/modules/BaseConfig.cmake
@@ -1,3 +1,5 @@
+cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
+
# *****************************************************************************
# CMake Features
# *****************************************************************************
@@ -69,6 +71,7 @@ option(DEBUG_LOG "Enable Debug Log" OFF)
option(ASAN_ENABLED "Build this target with AddressSanitizer" OFF)
option(BUILD_STATIC_LIBRARY "Build using static libraries" OFF)
option(SPEED_UP_BUILD_UNITY "Compile using build unity for speed up build" ON)
+option(USE_PRECOMPILED_HEADER "Compile using precompiled header" ON)
# === ASAN ===
if(ASAN_ENABLED)
diff --git a/cmake/modules/CanaryLib.cmake b/cmake/modules/CanaryLib.cmake
index 957a83c7a3e..202d25efa33 100644
--- a/cmake/modules/CanaryLib.cmake
+++ b/cmake/modules/CanaryLib.cmake
@@ -14,27 +14,22 @@ add_subdirectory(lib)
add_subdirectory(kv)
add_subdirectory(lua)
add_subdirectory(map)
+add_subdirectory(protobuf)
add_subdirectory(security)
add_subdirectory(server)
add_subdirectory(utils)
# Add more global sources - please add preferably in the sub_directory CMakeLists.
-set(ProtobufFiles
- protobuf/appearances.pb.cc
- protobuf/kv.pb.cc
-)
-
-# Add more global sources - please add preferably in the sub_directory CMakeLists.
-target_sources(${PROJECT_NAME}_lib PRIVATE canary_server.cpp ${ProtobufFiles})
-
-# Skip unity build inclusion for protobuf files
-set_source_files_properties(
- ${ProtobufFiles} PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON
-)
-
+target_sources(${PROJECT_NAME}_lib PRIVATE canary_server.cpp)
# Add public pre compiler header to lib, to pass down to related targets
-target_precompile_headers(${PROJECT_NAME}_lib PUBLIC pch.hpp)
+if (NOT SPEED_UP_BUILD_UNITY)
+ target_precompile_headers(${PROJECT_NAME}_lib PUBLIC pch.hpp)
+endif()
+
+if(NOT SPEED_UP_BUILD_UNITY AND USE_PRECOMPILED_HEADERS)
+ target_compile_definitions(${PROJECT_NAME}_lib PUBLIC -DUSE_PRECOMPILED_HEADER)
+endif()
# *****************************************************************************
# Build flags - need to be set before the links and sources
@@ -52,8 +47,8 @@ if(MSVC)
MODULE_LINKER_FLAGS "/LTCG"
EXE_LINKER_FLAGS "/LTCG")
else()
- include(CheckIPOSupported)
- check_ipo_supported(RESULT result)
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT result)
if(result)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=auto")
message(STATUS "IPO/LTO enabled with -flto=auto for non-MSVC compiler.")
@@ -102,14 +97,15 @@ target_link_libraries(${PROJECT_NAME}_lib
unofficial::argon2::libargon2
unofficial::libmariadb
unofficial::mariadbclient
- opentelemetry-cpp::common
- opentelemetry-cpp::metrics
- opentelemetry-cpp::api
- opentelemetry-cpp::ext
- opentelemetry-cpp::sdk
- opentelemetry-cpp::logs
- opentelemetry-cpp::ostream_metrics_exporter
- opentelemetry-cpp::prometheus_exporter
+ opentelemetry-cpp::common
+ opentelemetry-cpp::metrics
+ opentelemetry-cpp::api
+ opentelemetry-cpp::ext
+ opentelemetry-cpp::sdk
+ opentelemetry-cpp::logs
+ opentelemetry-cpp::ostream_metrics_exporter
+ opentelemetry-cpp::prometheus_exporter
+ protobuf
)
if(CMAKE_BUILD_TYPE MATCHES Debug)
@@ -121,8 +117,10 @@ endif()
if (MSVC)
if(BUILD_STATIC_LIBRARY)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC jsoncpp_static)
+ set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
else()
target_link_libraries(${PROJECT_NAME}_lib PUBLIC jsoncpp_lib)
+ set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "")
endif()
target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${MYSQL_CLIENT_LIBS})
diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua
index 116a87fec56..11cd653f0ae 100644
--- a/data-otservbr-global/lib/core/storages.lua
+++ b/data-otservbr-global/lib/core/storages.lua
@@ -3071,6 +3071,10 @@ GlobalStorage = {
AftershockHealth = 60174,
ForeshockStage = 60175,
AftershockStage = 60176,
+ RuptureResonanceStage = 60177,
+ RuptureResonanceActive = 60178,
+ EradicatorWeak = 60178,
+ EradicatorReleaseT = 60179,
OutburstStage = 60180,
OutburstHealth = 60181,
OutburstChargingKilled = 60182,
diff --git a/data-otservbr-global/scripts/actions/other/potions.lua b/data-otservbr-global/scripts/actions/other/potions.lua
index febc3ed9d3e..921eb551aeb 100644
--- a/data-otservbr-global/scripts/actions/other/potions.lua
+++ b/data-otservbr-global/scripts/actions/other/potions.lua
@@ -268,13 +268,12 @@ function flaskPotion.onUse(player, item, fromPosition, target, toPosition, isHot
player:addAchievementProgress("Potion Addict", 100000)
target:say("Aaaah...", MESSAGE_POTION)
- if fromPosition.x == CONTAINER_POSITION and not container == store_inbox then
- local container = Container(item:getParent().uid)
- if player:getStorageValueByName("talkaction.potions.flask") ~= 1 then
+ local deactivatedFlasks = player:kv():get("talkaction.potions.flask") or false
+ if not deactivatedFlasks then
+ if fromPosition.x == CONTAINER_POSITION then
+ local container = Container(item:getParent().uid)
container:addItem(potion.flask, 1)
- end
- else
- if player:getStorageValueByName("talkaction.potions.flask") ~= 1 then
+ else
player:addItem(potion.flask, 1)
end
end
diff --git a/data-otservbr-global/scripts/actions/quests/heart_of_destruction/rupture_lever.lua b/data-otservbr-global/scripts/actions/quests/heart_of_destruction/rupture_lever.lua
index 3c335c70716..ecb892cef8e 100644
--- a/data-otservbr-global/scripts/actions/quests/heart_of_destruction/rupture_lever.lua
+++ b/data-otservbr-global/scripts/actions/quests/heart_of_destruction/rupture_lever.lua
@@ -1,130 +1,41 @@
--- FUNCTIONS
-local function doCheckArea()
- local upConer = { x = 32324, y = 31239, z = 14 } -- upLeftCorner
- local downConer = { x = 32347, y = 31263, z = 14 } -- downRightCorner
-
- for i = upConer.x, downConer.x do
- for j = upConer.y, downConer.y do
- for k = upConer.z, downConer.z do
- local room = { x = i, y = j, z = k }
- local tile = Tile(room)
- if tile then
- local creatures = tile:getCreatures()
- if creatures and #creatures > 0 then
- for _, creature in pairs(creatures) do
- local player = Player(creature)
- if player then
- return true
- end
- end
- end
- end
- end
- end
- end
- return false
-end
-
-local function clearArea()
- local upConer = { x = 32324, y = 31239, z = 14 } -- upLeftCorner
- local downConer = { x = 32347, y = 31263, z = 14 } -- downRightCorner
-
- for i = upConer.x, downConer.x do
- for j = upConer.y, downConer.y do
- for k = upConer.z, downConer.z do
- local room = { x = i, y = j, z = k }
- local tile = Tile(room)
- if tile then
- local creatures = tile:getCreatures()
- if creatures and #creatures > 0 then
- for _, creatureUid in pairs(creatures) do
- local creature = Creature(creatureUid)
- if creature then
- if creature:isPlayer() then
- creature:teleportTo({ x = 32088, y = 31321, z = 13 })
- elseif creature:isMonster() then
- creature:remove()
- end
- end
- end
- end
- end
- end
- end
- end
-end
--- FUNCTIONS END
-
-local heartDestructionRupture = Action()
-function heartDestructionRupture.onUse(player, item, fromPosition, itemEx, toPosition)
- local config = {
- playerPositions = {
- Position(32309, 31248, 14),
- Position(32309, 31249, 14),
- Position(32309, 31250, 14),
- Position(32309, 31251, 14),
- Position(32309, 31252, 14),
- },
-
- newPos = { x = 32335, y = 31257, z = 14 },
- }
-
- local pushPos = { x = 32309, y = 31248, z = 14 }
-
- if item.actionid == 14327 then
- if item.itemid == 8911 then
- if player:getPosition().x == pushPos.x and player:getPosition().y == pushPos.y and player:getPosition().z == pushPos.z then
- local storePlayers = {}
- for i = 1, #config.playerPositions do
- local tile = Tile(Position(config.playerPositions[i]))
- if tile then
- local playerTile = tile:getTopCreature()
- if playerTile and playerTile:isPlayer() then
- storePlayers[#storePlayers + 1] = playerTile
- end
- end
- end
-
- if doCheckArea() == false then
- clearArea()
-
- local players
-
- for i = 1, #storePlayers do
- players = storePlayers[i]
- config.playerPositions[i]:sendMagicEffect(CONST_ME_POFF)
- players:teleportTo(config.newPos)
- players:setBossCooldown("Rupture", os.time() + configManager.getNumber(configKeys.BOSS_DEFAULT_TIME_TO_FIGHT_AGAIN))
- end
- Position(config.newPos):sendMagicEffect(11)
-
- areaRupture1 = addEvent(clearArea, 15 * 60000)
-
- ruptureResonanceStage = 0
- resonanceActive = false
-
- Game.createMonster("Spark of Destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("Spark of Destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("Spark of Destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("Spark of Destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("Rupture", { x = 32332, y = 31250, z = 14 }, false, true)
-
- local vortex = Tile({ x = 32326, y = 31250, z = 14 }):getItemById(23482)
- if vortex then
- vortex:transform(23483)
- vortex:setActionId(14343)
- end
- else
- player:sendTextMessage(19, "Someone is in the area.")
- end
- else
- return true
+local config = {
+ boss = {
+ name = "Rupture",
+ position = Position(32332, 31250, 14),
+ },
+ playerPositions = {
+ { pos = Position(32309, 31248, 14), teleport = Position(32335, 31257, 14), effect = CONST_ME_TELEPORT },
+ { pos = Position(32309, 31249, 14), teleport = Position(32335, 31257, 14), effect = CONST_ME_TELEPORT },
+ { pos = Position(32309, 31250, 14), teleport = Position(32335, 31257, 14), effect = CONST_ME_TELEPORT },
+ { pos = Position(32309, 31251, 14), teleport = Position(32335, 31257, 14), effect = CONST_ME_TELEPORT },
+ { pos = Position(32309, 31252, 14), teleport = Position(32335, 31257, 14), effect = CONST_ME_TELEPORT },
+ },
+ specPos = {
+ from = Position(32324, 31239, 14),
+ to = Position(32347, 31263, 14),
+ },
+ monsters = {
+ { name = "Spark of Destruction", pos = Position(32331, 31254, 14) },
+ { name = "Spark of Destruction", pos = Position(32338, 31254, 14) },
+ { name = "Spark of Destruction", pos = Position(32330, 31250, 14) },
+ { name = "Spark of Destruction", pos = Position(32338, 31250, 14) },
+ },
+ onUseExtra = function()
+ Game.setStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceStage, -1)
+ Game.setStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceActive, -1)
+
+ local tile = Tile(Position(32326, 31250, 14))
+ if tile then
+ local vortex = tile:getItemById(23482)
+ if vortex then
+ vortex:transform(23483)
+ vortex:setActionId(14343)
end
end
- item:transform(item.itemid == 8911 and 8912 or 8911)
- end
- return true
-end
+ end,
+ exit = Position(32088, 31321, 13),
+}
-heartDestructionRupture:aid(14327)
-heartDestructionRupture:register()
+local lever = BossLever(config)
+lever:aid(14327)
+lever:register()
diff --git a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua
index 9951dcd71e7..00915af16a8 100644
--- a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua
+++ b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_heal.lua
@@ -1,7 +1,9 @@
local ruptureHeal = CreatureEvent("RuptureHeal")
+
function ruptureHeal.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
- local healthGain = math.random(5000, 10000)
- if attacker and attacker:isPlayer() and resonanceActive == true then
+ local resonanceActive = Game.getStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceActive)
+ if attacker and attacker:isPlayer() and resonanceActive == 1 then
+ local healthGain = math.random(5000, 10000)
creature:addHealth(healthGain)
creature:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN)
end
diff --git a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua
index 3736d47d7c0..fbbbfefbf12 100644
--- a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua
+++ b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/rupture_resonance.lua
@@ -1,50 +1,37 @@
+local function createSpawnWave(stage)
+ Game.createMonster("Spark of Destruction", Position(32331, 31254, 14), false, true)
+ Game.createMonster("Spark of Destruction", Position(32338, 31254, 14), false, true)
+ Game.createMonster("Spark of Destruction", Position(32330, 31250, 14), false, true)
+ Game.createMonster("Spark of Destruction", Position(32338, 31250, 14), false, true)
+ Game.createMonster("Damage Resonance", Position(32332, 31250, 14), false, true)
+ Game.setStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceStage, stage)
+ Game.setStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceActive, 1)
+end
+
local ruptureResonance = CreatureEvent("RuptureResonance")
+
function ruptureResonance.onThink(creature)
if not creature or not creature:isMonster() then
return false
end
- local hp = (creature:getHealth() / creature:getMaxHealth()) * 100
- if hp <= 80 and ruptureResonanceStage == 0 and resonanceActive == false then
- Game.createMonster("spark of destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("damage resonance", { x = 32332, y = 31250, z = 14 }, false, true)
- ruptureResonanceStage = 1
- resonanceActive = true
- elseif hp <= 60 and ruptureResonanceStage == 1 and resonanceActive == false then
- Game.createMonster("spark of destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("damage resonance", { x = 32332, y = 31250, z = 14 }, false, true)
- ruptureResonanceStage = 2
- resonanceActive = true
- elseif hp <= 40 and ruptureResonanceStage == 2 and resonanceActive == false then
- Game.createMonster("spark of destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("damage resonance", { x = 32332, y = 31250, z = 14 }, false, true)
- ruptureResonanceStage = 3
- resonanceActive = true
- elseif hp <= 25 and ruptureResonanceStage == 3 and resonanceActive == false then
- Game.createMonster("spark of destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("damage resonance", { x = 32332, y = 31250, z = 14 }, false, true)
- ruptureResonanceStage = 4
- resonanceActive = true
- elseif hp <= 10 and ruptureResonanceStage == 4 and resonanceActive == false then
- Game.createMonster("spark of destruction", { x = 32331, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31254, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32330, y = 31250, z = 14 }, false, true)
- Game.createMonster("spark of destruction", { x = 32338, y = 31250, z = 14 }, false, true)
- Game.createMonster("damage resonance", { x = 32332, y = 31250, z = 14 }, false, true)
- ruptureResonanceStage = -1
- resonanceActive = true
+ local ruptureResonanceStage = Game.getStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceStage) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceStage) or 0
+ local resonanceActive = Game.setStorageValue(GlobalStorage.HeartOfDestruction.RuptureResonanceActive)
+
+ local thresholds = {
+ { limit = 80, stage = 0, wave = 1 },
+ { limit = 60, stage = 1, wave = 2 },
+ { limit = 40, stage = 2, wave = 3 },
+ { limit = 25, stage = 3, wave = 4 },
+ { limit = 10, stage = 4, wave = -1 },
+ }
+
+ local hpPercent = (creature:getHealth() / creature:getMaxHealth()) * 100
+ for _, threshold in ipairs(thresholds) do
+ if hpPercent <= threshold.limit and ruptureResonanceStage == threshold.stage and resonanceActive ~= 1 then
+ createSpawnWave(threshold.wave)
+ break
+ end
end
return true
diff --git a/data/XML/storages.xml b/data/XML/storages.xml
index 171eec35a7a..735b4c62ed8 100644
--- a/data/XML/storages.xml
+++ b/data/XML/storages.xml
@@ -29,6 +29,5 @@ When adding a new range or storage, make sure that the ranges do not overlap, an
-
diff --git a/data/libs/achievements_lib.lua b/data/libs/achievements_lib.lua
index 2b0f441ad29..d95fed99b69 100644
--- a/data/libs/achievements_lib.lua
+++ b/data/libs/achievements_lib.lua
@@ -570,10 +570,6 @@ achievements = {
[475] = { name = "Taskmaster", grade = 1, points = 2, description = "Having hunted and bested them all, you live for the thrill of the hunt!" },
[476] = { name = "Verminbane", grade = 1, points = 2, description = "And so it begins!" },
- --12.60
- [480] = { name = "Honorary Rascoohan", grade = 1, points = 2, description = "When in Rascacoon, do as the Rascoohans do!" },
- [481] = { name = "Release the Kraken", grade = 1, points = 3, description = "Riding around on this squishy companion gives you the feeling of flying through the air... uhm... swimming through the seven seas!" },
-
--Custom
[477] = { name = "Waypoint Explorer", grade = 1, points = 1, description = "You've explored all the towns of Tibia and discovered each town's waypoint." },
[478] = { name = "Up the Molehill", grade = 1, points = 3, description = "Putting this candle stump on your new mount was kind of a waiting game. You're even tempted to call it whack-a-mole. But in the end you found a loyal companion for your journeys into the depths." },
diff --git a/data/scripts/talkactions/player/flask.lua b/data/scripts/talkactions/player/flask.lua
index f3ccdb0bb7a..232b9485602 100644
--- a/data/scripts/talkactions/player/flask.lua
+++ b/data/scripts/talkactions/player/flask.lua
@@ -5,12 +5,12 @@ function flask.onSay(player, words, param)
player:sendCancelMessage("You need to specify on/off param.")
return true
end
- if param == "on" and player:getStorageValueByName("talkaction.potions.flask") ~= 1 then
- player:setStorageValueByName("talkaction.potions.flask", 1)
+ if param == "on" then
+ player:kv():set("talkaction.potions.flask", true)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You will not receive flasks!")
player:getPosition():sendMagicEffect(CONST_ME_REDSMOKE)
elseif param == "off" then
- player:setStorageValueByName("talkaction.potions.flask", 0)
+ player:kv():remove("talkaction.potions.flask")
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You will receive flasks.")
player:getPosition():sendMagicEffect(CONST_ME_REDSMOKE)
end
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index abd35c09c36..2abd46f06c2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,3 +1,5 @@
+cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
+
# Base configurations and settings for the project
include(BaseConfig)
include(GNUInstallDirs)
diff --git a/src/account/account_definitions.hpp b/src/account/account_definitions.hpp
index 0948055f2b5..b6867e47b13 100644
--- a/src/account/account_definitions.hpp
+++ b/src/account/account_definitions.hpp
@@ -9,7 +9,10 @@
#pragma once
-#include
+#ifndef USE_PRECOMPILED_HEADERS
+ #include
+ #include
+#endif
namespace account {
enum Errors : uint8_t {
diff --git a/src/creatures/combat/spells.cpp b/src/creatures/combat/spells.cpp
index 013d1b4a1ff..a0554fdcbbe 100644
--- a/src/creatures/combat/spells.cpp
+++ b/src/creatures/combat/spells.cpp
@@ -16,6 +16,8 @@
#include "lua/scripts/lua_environment.hpp"
#include "creatures/players/wheel/player_wheel.hpp"
+#include "lua/global/lua_variant.hpp"
+
Spells::Spells() = default;
Spells::~Spells() = default;
diff --git a/src/creatures/combat/spells.hpp b/src/creatures/combat/spells.hpp
index 4a237ff391d..804ec62f930 100644
--- a/src/creatures/combat/spells.hpp
+++ b/src/creatures/combat/spells.hpp
@@ -20,6 +20,8 @@ class InstantSpell;
class RuneSpell;
class Spell;
+struct LuaVariant;
+
using VocSpellMap = std::map;
class Spells final : public Scripts {
diff --git a/src/creatures/creatures_definitions.hpp b/src/creatures/creatures_definitions.hpp
index 71c607b64c3..674f0b6775c 100644
--- a/src/creatures/creatures_definitions.hpp
+++ b/src/creatures/creatures_definitions.hpp
@@ -9,8 +9,18 @@
#pragma once
-// Enum
+#ifndef USE_PRECOMPILED_HEADERS
+ #include
+ #include
+ #include