• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[Heart of Destruction] World Devourer final boss

kimokimo

Kimo
Joined
Jan 25, 2011
Messages
821
Solutions
6
Reaction score
156
GitHub
karimadnan
latest

latest
latest
latest

World Devourer final Heart of Destruction boss, with room shifting mechanic

Events/vars required
Code:
To minions (Destruction, Rage, Hunger)
"minionsKill"

To World Devourer
"world_devourer_spawns"

To global.lua
WORLD_DEVOURER_ACTIVE = false
Lua:
local config = {
    kickPos = Position(32213, 31375, 14), --Position players get kicked at
    finalRoom = Position(32272, 31354, 14), --Final room with World Devourer
    state = GlobalStorage.HeartOfDestruction.WorldDevourerState, --State of how many minions killed
    shift = Storage.HeartOfDestruction.devourerShift, --Shifting time storage
    timer = Storage.HeartOfDestruction.WorldDevourerTimer, --Cool down storage
    room = Storage.HeartOfDestruction.WorldDevourerRoom, --Timeout kick storage
    newPos = {
        Position(32244, 31378, 14), -- Hunger
        Position(32271, 31322, 14), -- Destruction
        Position(32299, 31378, 14) --Rage
    },
    sparks = {
        Position(32275, 31343, 14),
        Position(32277, 31352, 14),
        Position(32274, 31347, 14),
        Position(32272, 31353, 14),
        Position(32270, 31341, 14)
    },
    arenas = {
        { --Arena 3 (The Destruction)
            center = Position(32271, 31316, 14),
            di = {20, 21}
        },
        { --Arena 2 (The Rage)
            center = Position(32299, 31372, 14),
            di = {20, 21}
        },
        { --Arena 1 (The Hunger)
            center = Position(32244, 31372, 14),
            di = {20, 21}
        },
        { --Arena 4 (World Devourer)
            center = Position(32272, 31348, 14),
            di = {20, 21}
        }
    }
}

local function worldDevourerPlayers(arenas) -- return players in pits
    local players = 0
    for i = 1, #config.arenas do
        if i <= arenas then
            local di1, di2 = config.arenas[i].di[1], config.arenas[i].di[2]
            local specs = Game.getSpectators(config.arenas[i].center, false, true, di1, di1, di2, di2)
            if #specs > 0 then
                players = players + #specs
            end
        end
    end
    return players
end

local minionsKill = CreatureEvent("minionsKill")
function minionsKill.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified)
    local targetMonster = creature:getMonster()
    if not targetMonster or targetMonster:getMaster() then
        return true
    end

    local value = Game.getStorageValue(config.state)
    Game.setStorageValue(config.state, value + 1)
    if Game.getStorageValue(config.state) >= 3 then
        WORLD_DEVOURER_ACTIVE = true
    end
    return true
end
minionsKill:register()

local devourerShifting = GlobalEvent("devourerShifting")
function devourerShifting.onThink()
    if worldDevourerPlayers(3) > 0 then
        for i = 1, #config.arenas do
            if i < 4 then
                local di1, di2 = config.arenas[i].di[1], config.arenas[i].di[2]
                local specs = Game.getSpectators(config.arenas[i].center, false, true, di1, di1, di2, di2)
                for p = 1, #specs do
                    if specs[p]:isPlayer() then
                        if not WORLD_DEVOURER_ACTIVE then
                            if specs[p]:getStorageValue(config.shift) <= os.time() then
                                specs[p]:teleportTo(config.newPos[i])
                                specs[p]:setStorageValue(config.shift, os.time() + 30)
                                specs[p]:say('A polarity shift moves you into another part of the heart of destruction.', TALKTYPE_MONSTER_SAY, false, specs[p])
                            end
                        else
                            specs[p]:teleportTo(config.finalRoom)
                            specs[p]:say("With the Rage, Hunger and Destruction gone, you're sucked into the heart of destruction!! THE WORLD DEVOURER AWAITS YOU!", TALKTYPE_MONSTER_SAY, false, specs[p])
                        end
                    end
                end
            end
        end
    end
    return true
end
devourerShifting:interval(10000)
devourerShifting:register()

local world_devourer_spawns = CreatureEvent('world_devourer_spawns')
world_devourer_spawns:type('healthchange')
function world_devourer_spawns.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType)
    local health = creature:getMaxHealth() * 0.05
        creature:setStorageValue(1, creature:getStorageValue(1) + primaryDamage + secondaryDamage)
        if creature:getStorageValue(1) >= health then
            creature:setStorageValue(1, 0)
            local summons = {'Greed', 'Frenzy', 'Disruption'}
            local newPosition = creature:getClosestFreePosition(creature:getPosition(), true)
            local chosen = Game.createMonster(summons[math.random(#summons)], newPosition, true, true)
            if not chosen then
                return true
            end
        end
    return primaryDamage, primaryType, -secondaryDamage, secondaryType
end
world_devourer_spawns:register()

local function cleanWorldDevourer(stor) --Clean arena after time
    for i = 1, #config.arenas do
        local di1, di2 = config.arenas[i].di[1], config.arenas[i].di[2]
        local specs = Game.getSpectators(config.arenas[i].center, false, false, di1, di1, di2, di2)
        for p = 1, #specs do
            if specs[p]:isPlayer() then
                if specs[p]:getStorageValue(stor) <= os.time() then
                    specs[p]:teleportTo(config.kickPos)
                    specs[p]:say('Your time is out, You have failed to disrupt the heart of destruction!', TALKTYPE_MONSTER_SAY, false, specs[p])
                end
            elseif specs[p]:isMonster() and not specs[p]:getMaster() then
                specs[p]:remove()
            end
        end
    end
    return true
end

local function cleanDevourer() -- Clean arena on entrance
    for i = 1, #config.arenas do
        local di1, di2 = config.arenas[i].di[1], config.arenas[i].di[2]
        local specs = Game.getSpectators(config.arenas[i].center, false, false, di1, di1, di2, di2)
        for p = 1, #specs do
            if specs[p]:isMonster() then
                specs[p]:remove()
            end
        end
    end
    return true
end

local worldDevourerLever = Action()
function worldDevourerLever.onUse(player, item, fromPosition, target, toPosition, isHotkey)

    if item.itemid == 9825 then
      
        if worldDevourerPlayers(4) > 0 then
            player:sendCancelMessage('A team is already fighting with World Devourer')
            return true
        end
      
        if player:getPosition() ~= Position(32272, 31374, 14) then
            player:sendCancelMessage('Sorry, not possible.')
            return true
        end
      
        cleanDevourer()
        WORLD_DEVOURER_ACTIVE = false
        Game.setStorageValue(config.state, 0)
        local teleport = Tile(Position(32281, 31348, 14)):getItemById(26138)

        if teleport then
            teleport:transform(26139)
            teleport:setActionId(14348)
        end

        Game.createMonster('The Hunger', Position(32244, 31372, 14), false, true)
        Game.createMonster('The Rage', Position(32299, 31372, 14), false, true)
        Game.createMonster('The Destruction', Position(32271, 31315, 14), false, true)
        Game.createMonster('World Devourer', Position(32271, 31346, 14), false, true)
        for i = 1, #config.sparks do
            Game.createMonster('Spark Of Destruction', config.sparks[i], true, true)
        end
        for y = 31374, 31378 do
            for x = 32271, 32273 do
            local playerTile = Tile(Position(x, y, 14)):getTopCreature()
                if playerTile and playerTile:isPlayer() then
                    playerTile:getPosition():sendMagicEffect(CONST_ME_POFF)
                    playerTile:teleportTo(config.newPos[x - 32270])
                    playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
                    playerTile:setStorageValue(config.shift, os.time() + 30)
                    playerTile:setStorageValue(config.timer, os.time() + 96 * 3600)
                    playerTile:setStorageValue(config.room, os.time() + 60 * 60)
                end
            end
        end

        addEvent(cleanWorldDevourer, 60 * 60 * 1000, config.room)
        player:say('You have 60 minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.', TALKTYPE_MONSTER_SAY, false, player)
        item:transform(9826)
    elseif item.itemid == 9826 then
        item:transform(9825)
    end
    return true
end
worldDevourerLever:aid(14332)
worldDevourerLever:register()

local greedTp = MoveEvent()
function greedTp.onStepIn(creature, item, position, fromPosition)
        if creature:isMonster() then
            if item:getId() == 26125 then
                if isInArray({'world devourer', 'the hunger'}, creature:getName():lower()) then
                    local tile = Tile(item:getPosition())
                    if tile then
                        local ground = tile:getGround()
                        if ground then
                            ground:transform(26126)
                            ground:decay()
                        end
                    end
                end
            elseif item:getId() == 26126 then
                if creature:getName():lower() == 'greed' then
                    creature:remove()
                    local tile = Tile(item:getPosition())
                    if tile then
                        local ground = tile:getGround()
                        if ground then
                            ground:transform(26125)
                            ground:decay()
                        end
                    end
                end
            end
        end
    return true
end
greedTp:id(26125, 26126)
greedTp:register()
 
Last edited:
Back
Top