From 13ec0f24bd37d5969d2ec7d8331500e8bf3ea4c0 Mon Sep 17 00:00:00 2001 From: Luan Luciano Date: Sat, 9 Dec 2023 17:31:12 -0300 Subject: [PATCH] feat: boss mechanics Anomaly (#1983) --- data-otservbr-global/lib/core/storages.lua | 4 + .../heart_of_destruction/anomaly_lever.lua | 162 ++++-------------- .../anomaly_transform.lua | 52 +++--- .../charged_anomaly_death.lua | 23 ++- .../heart_of_destruction/vortex_anomaly.lua | 9 +- .../scripts/spells/monster/charge_vortex.lua | 51 ++---- 6 files changed, 104 insertions(+), 197 deletions(-) diff --git a/data-otservbr-global/lib/core/storages.lua b/data-otservbr-global/lib/core/storages.lua index 93e2bf9364d..34928957379 100644 --- a/data-otservbr-global/lib/core/storages.lua +++ b/data-otservbr-global/lib/core/storages.lua @@ -3069,6 +3069,10 @@ GlobalStorage = { TotalUsurperCommanders = 60171, -- Global }, }, + HeartOfDestruction = { + -- Reserved storage from 60172 - 60177 + ChargedAnomaly = 60172, + }, FuryGates = 65000, Yakchal = 65001, PitsOfInfernoLevers = 65002, diff --git a/data-otservbr-global/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua b/data-otservbr-global/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua index e99e126c824..3cac20d9624 100644 --- a/data-otservbr-global/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua +++ b/data-otservbr-global/scripts/actions/quests/heart_of_destruction/anomaly_lever.lua @@ -1,129 +1,39 @@ --- FUNCTIONS -local function doCheckArea() - local upConer = { x = 32258, y = 31237, z = 14 } -- upLeftCorner - local downConer = { x = 32284, y = 31262, 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 = 32258, y = 31237, z = 14 } -- upLeftCorner - local downConer = { x = 32284, y = 31262, 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 = 32104, y = 31329, z = 12 }) - elseif creature:isMonster() then - creature:remove() - end - end - end - end - end - end - end - end -end --- FUNCTIONS END - -local heartDestructionAnomaly = Action() -function heartDestructionAnomaly.onUse(player, item, fromPosition, itemEx, toPosition) - local config = { - playerPositions = { - Position(32245, 31245, 14), - Position(32245, 31246, 14), - Position(32245, 31247, 14), - Position(32245, 31248, 14), - Position(32245, 31249, 14), - }, - - newPos = { x = 32271, y = 31257, z = 14 }, - } - - local pushPos = { x = 32245, y = 31245, z = 14 } - - if item.actionid == 14325 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("Anomaly", os.time() + configManager.getNumber(configKeys.BOSS_DEFAULT_TIME_TO_FIGHT_AGAIN)) - end - Position(config.newPos):sendMagicEffect(11) - - areaAnomaly1 = addEvent(clearArea, 15 * 60000) - - Game.setStorageValue(14322, 0) -- Anomaly Stages - - Game.createMonster("Spark of Destruction", { x = 32267, y = 31253, z = 14 }, false, true) - Game.createMonster("Spark of Destruction", { x = 32274, y = 31255, z = 14 }, false, true) - Game.createMonster("Spark of Destruction", { x = 32274, y = 31249, z = 14 }, false, true) - Game.createMonster("Spark of Destruction", { x = 32267, y = 31249, z = 14 }, false, true) - Game.createMonster("Anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - - local vortex = Tile({ x = 32261, y = 31250, z = 14 }):getItemById(23482) - if vortex then - vortex:transform(23483) - vortex:setActionId(14324) - end - else - player:sendTextMessage(19, "Someone is in the area.") - end - else - return true +local config = { + boss = { + name = "Anomaly", + position = Position(32271, 31249, 14), + }, + playerPositions = { + { pos = Position(32245, 31245, 14), teleport = Position(32271, 31257, 14), effect = CONST_ME_TELEPORT }, + { pos = Position(32245, 31246, 14), teleport = Position(32271, 31257, 14), effect = CONST_ME_TELEPORT }, + { pos = Position(32245, 31247, 14), teleport = Position(32271, 31257, 14), effect = CONST_ME_TELEPORT }, + { pos = Position(32245, 31248, 14), teleport = Position(32271, 31257, 14), effect = CONST_ME_TELEPORT }, + { pos = Position(32245, 31249, 14), teleport = Position(32271, 31257, 14), effect = CONST_ME_TELEPORT }, + }, + specPos = { + from = Position(32258, 31237, 14), + to = Position(32284, 31262, 14), + }, + monsters = { + { name = "Spark of Destruction", pos = Position(32267, 31253, 14) }, + { name = "Spark of Destruction", pos = Position(32274, 31255, 14) }, + { name = "Spark of Destruction", pos = Position(32274, 31249, 14) }, + { name = "Spark of Destruction", pos = Position(32267, 31249, 14) }, + }, + onUseExtra = function() + Game.setStorageValue(GlobalStorage.HeartOfDestruction.ChargedAnomaly, 0) + local tile = Tile(Position(32261, 31250, 14)) + if tile then + local vortex = tile:getItemById(23482) + if vortex then + vortex:transform(23483) + vortex:setActionId(14324) end end - item:transform(item.itemid == 8911 and 8912 or 8911) - end - return true -end + end, + exit = Position(32182, 31250, 14), +} -heartDestructionAnomaly:aid(14325) -heartDestructionAnomaly:register() +local lever = BossLever(config) +lever:aid(14325) +lever:register() diff --git a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua index 1e4b5852d9d..cc0b32fa35a 100644 --- a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua +++ b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/anomaly_transform.lua @@ -1,42 +1,34 @@ +local function createSpawnAnomalyRoom(valueGlobalStorage) + Game.createMonster("Spark of Destruction", Position(32267, 31253, 14), false, true) + Game.createMonster("Spark of Destruction", Position(32274, 31255, 14), false, true) + Game.createMonster("Spark of Destruction", Position(32274, 31249, 14), false, true) + Game.createMonster("Spark of Destruction", Position(32267, 31249, 14), false, true) + Game.createMonster("Charged Anomaly", Position(32271, 31249, 14), false, true) + Game.setStorageValue(GlobalStorage.HeartOfDestruction.ChargedAnomaly, valueGlobalStorage + 1) +end + local anomalyTransform = CreatureEvent("AnomalyTransform") + function anomalyTransform.onThink(creature) - if not creature or not creature:isMonster() then + if not creature then return false end - local hp = (creature:getHealth() / creature:getMaxHealth()) * 100 - if hp <= 75 and Game.getStorageValue(14322) == 0 then + local anomalyGlobalStorage = Game.getStorageValue(GlobalStorage.HeartOfDestruction.ChargedAnomaly) + local hpPercent = (creature:getHealth() / creature:getMaxHealth()) * 100 + + if hpPercent <= 75 and anomalyGlobalStorage == 0 then creature:remove() - Game.createMonster("spark of destruction", { x = 32267, y = 31253, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31255, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31249, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32267, y = 31249, z = 14 }, false, true) - Game.createMonster("charged anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - Game.setStorageValue(14322, 1) - elseif hp <= 50 and Game.getStorageValue(14322) == 1 then + createSpawnAnomalyRoom(anomalyGlobalStorage) + elseif hpPercent <= 50 and anomalyGlobalStorage == 1 then creature:remove() - Game.createMonster("spark of destruction", { x = 32267, y = 31253, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31255, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31249, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32267, y = 31249, z = 14 }, false, true) - Game.createMonster("charged anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - Game.setStorageValue(14322, 2) - elseif hp <= 25 and Game.getStorageValue(14322) == 2 then + createSpawnAnomalyRoom(anomalyGlobalStorage) + elseif hpPercent <= 25 and anomalyGlobalStorage == 2 then creature:remove() - Game.createMonster("spark of destruction", { x = 32267, y = 31253, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31255, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31249, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32267, y = 31249, z = 14 }, false, true) - Game.createMonster("charged anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - Game.setStorageValue(14322, 3) - elseif hp <= 5 and Game.getStorageValue(14322) == 3 then + createSpawnAnomalyRoom(anomalyGlobalStorage) + elseif hpPercent <= 5 and anomalyGlobalStorage == 3 then creature:remove() - Game.createMonster("spark of destruction", { x = 32267, y = 31253, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31255, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32274, y = 31249, z = 14 }, false, true) - Game.createMonster("spark of destruction", { x = 32267, y = 31249, z = 14 }, false, true) - Game.createMonster("charged anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - Game.setStorageValue(14322, 4) + createSpawnAnomalyRoom(anomalyGlobalStorage) end return true end diff --git a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua index ce44a75d501..b1eba8e4fc7 100644 --- a/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua +++ b/data-otservbr-global/scripts/creaturescripts/quests/heart_of_destruction/charged_anomaly_death.lua @@ -1,3 +1,8 @@ +local config = { + bossName = "Anomaly", + bossPosition = Position(32271, 31249, 14), +} + local monsterTable = { [1] = 72500, [2] = 145000, @@ -8,12 +13,20 @@ local monsterTable = { local chargedAnomalyDeath = CreatureEvent("ChargedAnomalyDeath") function chargedAnomalyDeath.onDeath(creature) - for storageValue, health in pairs(monsterTable) do - if Game.getStorageValue(14322) == storageValue then - local monster = Game.createMonster("anomaly", { x = 32271, y = 31249, z = 14 }, false, true) - monster:addHealth(-health) - end + if not creature then + return true + end + + local healthRemove = monsterTable[Game.getStorageValue(GlobalStorage.HeartOfDestruction.ChargedAnomaly)] + if not healthRemove then + return true end + + local boss = Game.createMonster(config.bossName, bossPosition, false, true) + if boss then + boss:addHealth(-healthRemove) + end + return true end diff --git a/data-otservbr-global/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua b/data-otservbr-global/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua index 3808d3fc98c..26c4ac34923 100644 --- a/data-otservbr-global/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua +++ b/data-otservbr-global/scripts/movements/quests/heart_of_destruction/vortex_anomaly.lua @@ -1,18 +1,23 @@ local vortexAnomaly = MoveEvent() +vortexAnomaly:type("stepin") + function vortexAnomaly.onStepIn(creature, item, position, fromPosition) + if not creature then + return true + end + if item.itemid == 22894 then if creature:isMonster() then if creature:getName():lower() == "charged anomaly" then creature:addHealth(-6000, COMBAT_DROWNDAMAGE) end - elseif isPlayer(creature) then + elseif creature:isPlayer() then creature:addHealth(-100, COMBAT_ENERGYDAMAGE) end end return true end -vortexAnomaly:type("stepin") vortexAnomaly:id(22894) vortexAnomaly:register() diff --git a/data-otservbr-global/scripts/spells/monster/charge_vortex.lua b/data-otservbr-global/scripts/spells/monster/charge_vortex.lua index 1efc07973fe..4cf96614b78 100644 --- a/data-otservbr-global/scripts/spells/monster/charge_vortex.lua +++ b/data-otservbr-global/scripts/spells/monster/charge_vortex.lua @@ -1,51 +1,34 @@ -local mathCount = 0 - -local positions = {} +local positions = { + Position(32264, 31253, 14), + Position(32269, 31258, 14), + Position(32275, 31255, 14), + Position(32280, 31253, 14), + Position(32271, 31248, 14), + Position(32264, 31245, 14), + Position(32270, 31240, 14), + Position(32269, 31253, 14), + Position(32275, 31245, 14), + Position(32276, 31250, 14), + Position(32266, 31249, 14), +} local function createVortex() - local storedPositions = { - { x = 32264, y = 31253, z = 14 }, - { x = 32269, y = 31258, z = 14 }, - { x = 32275, y = 31255, z = 14 }, - { x = 32280, y = 31253, z = 14 }, - { x = 32271, y = 31248, z = 14 }, - { x = 32264, y = 31245, z = 14 }, - { x = 32270, y = 31240, z = 14 }, - { x = 32269, y = 31253, z = 14 }, - { x = 32275, y = 31245, z = 14 }, - { x = 32276, y = 31250, z = 14 }, - { x = 32266, y = 31249, z = 14 }, - } - - if mathCount == 0 then - positions = storedPositions - end - - local r1 = math.random(#positions) - - local tile = Tile(positions[r1]) - + local tile = Tile(positions[math.random(#positions)]) if tile then local ground = tile:getGround() if ground then ground:transform(22894) - addEvent(function(pos) - local tile = Tile(pos) + addEvent(function(positionInAddEvent) + local tile = Tile(positionInAddEvent) if tile then local ground = tile:getGround() if ground then ground:transform(23049) end end - end, 10 * 1000, tile:getPosition()) -- 10*1000 = 10 SECONDS - mathCount = mathCount + 1 - table.remove(positions, r1) + end, 10 * 1000, tile:getPosition()) -- 10 seconds end end - - if mathCount == 11 then - mathCount = 0 - end end local spell = Spell("instant")