Skip to content

Commit

Permalink
improve: boss mechanics Foreshock (#2125)
Browse files Browse the repository at this point in the history
Using BossLever system.
More clean core.

---------

Co-authored-by: Eduardo Dantas <[email protected]>
  • Loading branch information
Luan Luciano and dudantas authored Feb 4, 2024
1 parent f68875c commit 5cd27cd
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 195 deletions.
4 changes: 4 additions & 0 deletions data-otservbr-global/lib/core/storages.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3067,6 +3067,10 @@ GlobalStorage = {
HeartOfDestruction = {
-- Reserved storage from 60172 - 60190
ChargedAnomaly = 60172,
ForeshockHealth = 60173,
AftershockHealth = 60174,
ForeshockStage = 60175,
AftershockStage = 60176,
RuptureResonanceStage = 60177,
RuptureResonanceActive = 60178,
EradicatorWeak = 60178,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,133 +1,42 @@
-- FUNCTIONS
local function doCheckArea()
local upConer = { x = 32197, y = 31236, z = 14 } -- upLeftCorner
local downConer = { x = 32220, y = 31260, 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 = 32197, y = 31236, z = 14 } -- upLeftCorner
local downConer = { x = 32220, y = 31260, 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 = 32230, y = 31358, z = 11 })
elseif creature:isMonster() then
creature:remove()
end
end
end
end
end
end
end
end
stopEvent(areaQuake1)
end
-- FUNCTIONS END

local heartDestructionQuake = Action()
function heartDestructionQuake.onUse(player, item, fromPosition, itemEx, toPosition)
local config = {
playerPositions = {
Position(32182, 31244, 14),
Position(32182, 31245, 14),
Position(32182, 31246, 14),
Position(32182, 31247, 14),
Position(32182, 31248, 14),
},

newPos = { x = 32208, y = 31256, z = 14 },
}

local pushPos = { x = 32182, y = 31244, z = 14 }

if item.actionid == 14329 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("Realityquake", os.time() + configManager.getNumber(configKeys.BOSS_DEFAULT_TIME_TO_FIGHT_AGAIN))
end
Position(config.newPos):sendMagicEffect(11)

areaQuake1 = addEvent(clearArea, 15 * 60000)

Game.createMonster("Spark of Destruction", { x = 32203, y = 31246, z = 14 }, false, true)
Game.createMonster("Spark of Destruction", { x = 32205, y = 31251, z = 14 }, false, true)
Game.createMonster("Spark of Destruction", { x = 32210, y = 31251, z = 14 }, false, true)
Game.createMonster("Spark of Destruction", { x = 32212, y = 31246, z = 14 }, false, true)
Game.createMonster("Foreshock", { x = 32208, y = 31248, z = 14 }, false, true)

foreshockHealth = 105000
aftershockHealth = 105000
foreshockStage = 0
aftershockStage = 0

local vortex = Tile({ x = 32199, y = 31248, z = 14 }):getItemById(23482)
if vortex then
vortex:transform(23483)
vortex:setActionId(14345)
end
else
player:sendTextMessage(19, "Someone is in the area.")
end
else
return true
local config = {
boss = {
name = "Foreshock",
position = Position(32208, 31248, 14),
},
playerPositions = {
{ pos = Position(32182, 31244, 14), teleport = Position(32208, 31256, 14), effect = CONST_ME_TELEPORT },
{ pos = Position(32182, 31245, 14), teleport = Position(32208, 31256, 14), effect = CONST_ME_TELEPORT },
{ pos = Position(32182, 31246, 14), teleport = Position(32208, 31256, 14), effect = CONST_ME_TELEPORT },
{ pos = Position(32182, 31247, 14), teleport = Position(32208, 31256, 14), effect = CONST_ME_TELEPORT },
{ pos = Position(32182, 31248, 14), teleport = Position(32208, 31256, 14), effect = CONST_ME_TELEPORT },
},
specPos = {
from = Position(32197, 31236, 14),
to = Position(32220, 31260, 14),
},
monsters = {
{ name = "Spark of Destruction", pos = Position(32203, 31246, 14) },
{ name = "Spark of Destruction", pos = Position(32205, 31251, 14) },
{ name = "Spark of Destruction", pos = Position(32210, 31251, 14) },
{ name = "Spark of Destruction", pos = Position(32212, 31246, 14) },
},
onUseExtra = function()
Game.setStorageValue(GlobalStorage.HeartOfDestruction.ForeshockHealth, 105000)
Game.setStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth, 105000)
Game.setStorageValue(GlobalStorage.HeartOfDestruction.ForeshockStage, -1)
Game.setStorageValue(GlobalStorage.HeartOfDestruction.AftershockStage, -1)
local tile = Tile(Position(32199, 31248, 14))
if tile then
local vortex = tile:getItemById(23482)
if vortex then
vortex:transform(23483)
vortex:setActionId(14345)
end
end
item:transform(item.itemid == 8911 and 8912 or 8911)
end
return true
end
end,
exit = Position(32230, 31358, 11),
}

heartDestructionQuake:aid(14329)
heartDestructionQuake:register()
local lever = BossLever(config)
lever:aid(14329)
lever:register()
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
local sparkOfDestructionPositions = {
Position(32203, 31246, 14),
Position(32205, 31251, 14),
Position(32210, 31251, 14),
Position(32212, 31246, 14),
}

local monsterTable = {
[80] = { fromStage = 0, toStage = 1 },
[60] = { fromStage = 1, toStage = 2 },
[40] = { fromStage = 2, toStage = 3 },
[20] = { fromStage = 3, toStage = 4 },
[10] = { fromStage = 4, toStage = 5 },
}

local aftershockTransform = CreatureEvent("AftershockTransform")

function aftershockTransform.onThink(creature)
if not creature:isMonster() then
if not creature or not creature:isMonster() then
return true
end

local sparkOfDestructionPositions = {
{ x = 32203, y = 31246, z = 14 },
{ x = 32205, y = 31251, z = 14 },
{ x = 32210, y = 31251, z = 14 },
{ x = 32212, y = 31246, z = 14 },
}

local monsterTable = {
[80] = { fromStage = 0, toStage = 1 },
[60] = { fromStage = 1, toStage = 2 },
[40] = { fromStage = 2, toStage = 3 },
[20] = { fromStage = 3, toStage = 4 },
[10] = { fromStage = 4, toStage = 5 },
}
local hpPercent = (creature:getHealth() / creature:getMaxHealth()) * 100
Game.setStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth, creature:getHealth())
local aftershockStage = Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockStage) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockStage) or 0

for index, value in pairs(monsterTable) do
local hp = (creature:getHealth() / creature:getMaxHealth()) * 100
aftershockHealth = creature:getHealth()
if hp <= index and aftershockStage == value.fromStage then
creature:remove()
for i = 1, #sparkOfDestructionPositions do
Game.createMonster("spark of destruction", sparkOfDestructionPositions[i], false, true)
if hpPercent <= index and aftershockStage == value.fromStage then
local monster = Game.createMonster("Foreshock", Position(32208, 31248, 14), false, true)
if monster then
creature:remove()
for i = 1, #sparkOfDestructionPositions do
Game.createMonster("Spark of Destruction", sparkOfDestructionPositions[i], false, true)
end
local foreshockHealth = Game.getStorageValue(GlobalStorage.HeartOfDestruction.ForeshockHealth) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.ForeshockHealth) or 0
monster:addHealth(-monster:getHealth() + foreshockHealth, COMBAT_PHYSICALDAMAGE)
Game.setStorageValue(GlobalStorage.HeartOfDestruction.AftershockStage, value.toStage)
return true
end
local monster = Game.createMonster("foreshock", { x = 32208, y = 31248, z = 14 }, false, true)
monster:addHealth(-monster:getHealth() + foreshockHealth, COMBAT_PHYSICALDAMAGE)
aftershockStage = value.toStage
end
end
return true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
local sparkOfDestructionPositions = {
Position(32203, 31246, 14),
Position(32205, 31251, 14),
Position(32210, 31251, 14),
Position(32212, 31246, 14),
}

local monsterTable = {
[80] = { fromStage = 0, toStage = 1 },
[60] = { fromStage = 1, toStage = 2 },
[40] = { fromStage = 2, toStage = 3 },
[20] = { fromStage = 3, toStage = 4 },
[10] = { fromStage = 4, toStage = 5 },
}

local foreshockTransform = CreatureEvent("ForeshockTransform")

function foreshockTransform.onThink(creature)
if not creature:isMonster() then
if not creature or not creature:isMonster() then
return true
end

local sparkOfDestructionPositions = {
{ x = 32203, y = 31246, z = 14 },
{ x = 32205, y = 31251, z = 14 },
{ x = 32210, y = 31251, z = 14 },
{ x = 32212, y = 31246, z = 14 },
}

local monsterTable = {
[80] = { fromStage = 0, toStage = 1 },
[60] = { fromStage = 1, toStage = 2 },
[40] = { fromStage = 2, toStage = 3 },
[20] = { fromStage = 3, toStage = 4 },
[10] = { fromStage = 4, toStage = 5 },
}
local hpPercent = (creature:getHealth() / creature:getMaxHealth()) * 100
Game.setStorageValue(GlobalStorage.HeartOfDestruction.ForeshockHealth, creature:getHealth())
local foreshockStage = Game.getStorageValue(GlobalStorage.HeartOfDestruction.ForeshockStage) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.ForeshockStage) or 0

for index, value in pairs(monsterTable) do
local hp = (creature:getHealth() / creature:getMaxHealth()) * 100
foreshockHealth = creature:getHealth()
if hp <= index and foreshockStage == value.fromStage then
creature:remove()
for i = 1, #sparkOfDestructionPositions do
Game.createMonster("spark of destruction", sparkOfDestructionPositions[i], false, true)
if hpPercent <= index and foreshockStage == value.fromStage then
local monster = Game.createMonster("Aftershock", Position(32208, 31248, 14), false, true)
if monster then
creature:remove()
for i = 1, #sparkOfDestructionPositions do
Game.createMonster("Spark of Destruction", sparkOfDestructionPositions[i], false, true)
end
local aftershockHealth = Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth) or 0
monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE)
Game.setStorageValue(GlobalStorage.HeartOfDestruction.ForeshockStage, value.toStage)
return true
end
local monster = Game.createMonster("aftershock", { x = 32208, y = 31248, z = 14 }, false, true)
monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE)
foreshockStage = value.toStage
end
end
return true
end

foreshockTransform:register()
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
local function createSparksOfDestruction()
Game.createMonster("Spark Of Destruction", Position(32203, 31246, 14), false, true)
Game.createMonster("Spark Of Destruction", Position(32205, 31251, 14), false, true)
Game.createMonster("Spark Of Destruction", Position(32210, 31251, 14), false, true)
Game.createMonster("Spark Of Destruction", Position(32212, 31246, 14), false, true)
end

local shocksDeath = CreatureEvent("ShocksDeath")

function shocksDeath.onDeath(creature)
if not creature or not creature:isMonster() then
return true
end

local name = creature:getName():lower()
if name == "foreshock" then
local monster = Game.createMonster("aftershock", { x = 32208, y = 31248, z = 14 }, false, true)
monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE)
Game.createMonster("spark of destruction", { x = 32203, y = 31246, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32205, y = 31251, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32210, y = 31251, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32212, y = 31246, z = 14 }, false, true)
end

if name == "aftershock" then
local pos = creature:getPosition()
local monster = Game.createMonster("realityquake", pos, false, true)
Game.createMonster("spark of destruction", { x = 32203, y = 31246, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32205, y = 31251, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32210, y = 31251, z = 14 }, false, true)
Game.createMonster("spark of destruction", { x = 32212, y = 31246, z = 14 }, false, true)
local creatureName = creature:getName():lower()
if creatureName == "foreshock" then
local monster = Game.createMonster("Aftershock", Position(32208, 31248, 14), false, true)
if monster then
local aftershockHealth = Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth) > 0 and Game.getStorageValue(GlobalStorage.HeartOfDestruction.AftershockHealth) or 0
monster:addHealth(-monster:getHealth() + aftershockHealth, COMBAT_PHYSICALDAMAGE)
createSparksOfDestruction()
end
elseif creatureName == "aftershock" then
local monster = Game.createMonster("Realityquake", creature:getPosition(), false, true)
if monster then
createSparksOfDestruction()
end
end
return true
end

shocksDeath:register()

0 comments on commit 5cd27cd

Please sign in to comment.