opentibiabr / canary

Canary Server 13.x for OpenTibia community.
https://docs.opentibiabr.com/
GNU General Public License v2.0
374 stars 619 forks source link

Drume script fix #2714

Closed joelslamospersson closed 1 month ago

joelslamospersson commented 4 months ago

Priority

Low

Area

What happened?

Since Drume is not working as real tibia should, here's a re-work and updated script version. I'd apprechiate if someone we're to test it out and try to bug it. If any issues, I'll have it fixed.

Setup: Change code to the new one, file location: canary-main/otservbr-global/scripts/quests/the_order_of_lion/action-drume.lua

Register this in lion and usurper

Location for monsters: canary-main/data-otservbr-global/monster/quests/the_order_of_lion

For Lion monster.events = { "lionCommanderDeath" }

For Usurper (Should already be inside), double check it. monster.events = { "usurperCommanderDeath" }

-- Rework made/finished 6-25-2024 7 AM (CET)
-- Tested 6 AM
local config = {
    lionPosition = {
        Position(32444, 32512, 7),
        Position(32449, 32516, 7),
        Position(32444, 32520, 7),
    },
    usurperPosition = {
        Position(32450, 32520, 7),
        Position(32444, 32516, 7),
        Position(32448, 32512, 7),
    },
    drumePosition = Position(32443, 32515, 7), -- Drume's spawn position
    kesarPosition = Position(32446, 32512, 7), -- Kesar's spawn position
    firstPlayerPosition = Position(32457, 32508, 6),
    centerPosition = Position(32439, 32523, 7), -- Center Room
    exitPosition = Position(32453, 32503, 7), -- Exit Position
    newPosition = Position(32453, 32510, 7),
    rangeX = 22,
    rangeY = 16,
    timeToKill = 20, -- time in minutes to remove the player (failed)
    debug = false -- Debug mode
}

local currentEvent = nil
local lionCommanders = {}
local usurperCommanders = {}
local lionDeaths = 0
local usurperDeaths = 0

local function debugPrint(message)
    if config.debug then
        print(message)
    end
end

-- Clear room if empty/times up
local function clearRoomDrume(centerPosition, rangeX, rangeY, resetGlobalStorage, message)
    debugPrint("Clearing room...")
    local spectators, spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY)
    for i = 1, #spectators do
        spectator = spectators[i]
        if spectator:isMonster() then
            spectator:remove()
        end
        if spectator:isPlayer() then
            spectator:teleportTo(config.exitPosition)
            spectator:sendTextMessage(MESSAGE_EVENT_ADVANCE, message or "Your time is over.")
        end
    end
    if Game.getStorageValue(resetGlobalStorage) == 1 then
        Game.setStorageValue(resetGlobalStorage, -1)
    end
    currentEvent = nil
end

-- Check for slayn usurper and lion, add for killcount to spawn Drume
local function checkUsurperCommanders()
    debugPrint("Checking Usurper Commanders... Usurper deaths: " .. usurperDeaths)
    if usurperDeaths >= 3 then
        -- All Usurper Commanders are dead, spawn Drume and Kesar
        debugPrint("All Usurper Commanders are dead. Spawning Drume and Kesar...")
        Game.createMonster("Drume", config.drumePosition)
        Game.createMonster("Kesar", config.kesarPosition)
    end
end

local function checkLionCommanders()
    debugPrint("Checking Lion Commanders... Lion deaths: " .. lionDeaths)
    if lionDeaths >= 3 then
        -- All Lion Commanders are dead, clear the room with failure message
        debugPrint("All Lion Commanders are dead. Clearing room...")
        clearRoomDrume(config.centerPosition, config.rangeX, config.rangeY, true, "All Lion Commanders have died. You have failed.")
    end
end

-- Killcount for usurper/lion
local function onLionCommanderDeath(creature)
    debugPrint("Lion Commander died.")
    lionDeaths = lionDeaths + 1
    checkLionCommanders()
    return true
end

local function onUsurperCommanderDeath(creature)
    debugPrint("Usurper Commander died.")
    usurperDeaths = usurperDeaths + 1
    checkUsurperCommanders()
    return true
end

local drumeAction = Action()
function drumeAction.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if player:getPosition() ~= config.firstPlayerPosition then
        return false
    end

    local spectators = Game.getSpectators(config.centerPosition, false, true, config.rangeX, config.rangeX, config.rangeY, config.rangeY)
    if #spectators ~= 0 then
        player:sendCancelMessage("There's someone already in the skirmish.")
        player:getPosition():sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local tempPos, tempTile, tempCreature
    local players = {}
    for x = config.firstPlayerPosition.x, config.firstPlayerPosition.x + 4 do
        tempPos = Position(x, config.firstPlayerPosition.y, config.firstPlayerPosition.z)
        tempTile = Tile(tempPos)
        if tempTile then
            tempCreature = tempTile:getTopCreature()
            if tempCreature and tempCreature:isPlayer() then
                table.insert(players, tempCreature)
            end
        end
    end
    if #players == 0 then
        return false
    end

    if not config.debug then
        for _, pi in pairs(players) do
            if not pi:canFightBoss("Drume") then
                player:sendCancelMessage("Someone of your team has already fought in the skirmish in the last 10h.")
                player:getPosition():sendMagicEffect(CONST_ME_POFF)
                return true
            end
        end
    end

    local spectators = Game.getSpectators(config.centerPosition, false, false, config.rangeX, config.rangeX, config.rangeY, config.rangeY)
    for _, creature in pairs(spectators) do
        if creature:isMonster() then
            creature:remove()
        end
    end
    lionCommanders = {}
    usurperCommanders = {}
    lionDeaths = 0
    usurperDeaths = 0
    local totalLion = 0
    local totalUsurper = 0
    local tempMonster
    for i, pos in pairs(config.lionPosition) do
        tempMonster = Game.createMonster("Lion Commander", pos)
        if not tempMonster then
            player:sendCancelMessage("There was an error, contact an admin.")
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
            return true
        end
        table.insert(lionCommanders, tempMonster)
        tempMonster:registerEvent("lionCommanderDeath")
        totalLion = totalLion + 1
    end
    for i, pos in pairs(config.usurperPosition) do
        tempMonster = Game.createMonster("Usurper Commander", pos)
        if not tempMonster then
            player:sendCancelMessage("There was an error, contact an admin.")
            player:getPosition():sendMagicEffect(CONST_ME_POFF)
            return true
        end
        table.insert(usurperCommanders, tempMonster)
        tempMonster:registerEvent("usurperCommanderDeath")
        totalUsurper = totalUsurper + 1
    end

    for _, pi in pairs(players) do
        pi:setBossCooldown("Drume", os.time() + (configManager.getNumber(configKeys.BOSS_DEFAULT_TIME_TO_FIGHT_AGAIN)))
        pi:teleportTo(config.newPosition)
        pi:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have " .. config.timeToKill .. " minutes to defeat Drume.")
    end
    if currentEvent then
        stopEvent(currentEvent)
    end

    if not config.debug then
        currentEvent = addEvent(clearRoomDrume, config.timeToKill * 60 * 1000, config.centerPosition, config.rangeX, config.rangeY, true)
    end

    config.newPosition:sendMagicEffect(CONST_ME_TELEPORT)
    toPosition:sendMagicEffect(CONST_ME_POFF)
    Game.setStorageValue(GlobalStorage.TheOrderOfTheLion.Drume.TotalLionCommanders, totalLion)
    Game.setStorageValue(GlobalStorage.TheOrderOfTheLion.Drume.TotalUsurperCommanders, totalUsurper)
    return true
end

-- Register events
local lionCommanderDeath = CreatureEvent("lionCommanderDeath")
lionCommanderDeath.onDeath = onLionCommanderDeath
lionCommanderDeath:register()

local usurperCommanderDeath = CreatureEvent("usurperCommanderDeath")
usurperCommanderDeath.onDeath = onUsurperCommanderDeath
usurperCommanderDeath:register()

drumeAction:aid(59601)
drumeAction:register()

What OS are you seeing the problem on?

Linux

Code of Conduct

Nyedson commented 4 months ago

I suggest you create a pull request. It will be faster and easier to test and modify, if necessary.

joelslamospersson commented 4 months ago

Think I created a pull request now, unsure how to do it.

I suggest you create a pull request. It will be faster and easier to test and modify, if necessary.

igorquintaes commented 4 months ago

Think I created a pull request now, unsure how to do it.

Contributing to public repositories is a bit different from contributing to your own, but it's still easy. You need to:

For future contributions, you need to keep your fork updated by syncing it.

luanluciano93 commented 3 months ago

@joelslamospersson I don't understand the purpose of the changes, what are you correcting? What wasn't working?

you just changed the logic of the content of creatureevent-commander_kills to the script itself, but I can't understand what that did.