• 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!
  • If you're using Gesior 2012 or MyAAC, please review this thread for information about a serious security vulnerability and a fix.

[TFS 1.3][REQUEST] Lever to fight boss with cooldown

pdrhtdn

New Member
Joined
Feb 8, 2022
Messages
5
Reaction score
0
Hi everyone, I've been digging here and on other forums a way to add a cooldown to a lever so the player (solo or in a team of 5) that pulls it can only pull again after 20 hours. For example I've been working on Duke Krule, and I got this so far:
Lua:
local config = {
    centerRoom = Position(33456, 31473, 13),
    BossPosition = Position(33456, 31473, 13),
    newPosition = Position(33457, 31466, 13)
}

local graveDangerDukeKruleLever = Action()
function graveDangerDukeKruleLever.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    
    
    if item.itemid == 9825 then
        if player:getPosition() ~= Position(33455, 31493, 13) then
            item:transform(9826)
            return true
        end
    end
    if item.itemid == 9825 then
        local specs, spec = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15)
        for i = 1, #specs do
            spec = specs[i]
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Duke Krule right now.")
                return true
            end
        end
        Game.createMonster("Duke Krule", config.BossPosition, true, true)
        for x = 33455, 33459 do
            local playerTile = Tile(Position(x, 31493, 13)):getTopCreature()
            if playerTile and playerTile:isPlayer() then
                playerTile:getPosition():sendMagicEffect(CONST_ME_POFF)
                playerTile:teleportTo(config.newPosition)
                playerTile:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
            end
        end
        addEvent(clearForgotten, 30 * 60 * 1000, Position(33446, 33462, 13), Position(33465, 31482, 13), Position(32347, 32167, 12))
        item:transform(9826)
    elseif item.itemid == 9826 then
        item:transform(9825)
    end
    return true
end

graveDangerDukeKruleLever:uid(30498)
graveDangerDukeKruleLever:register()

Also, the boss should disappear if the player leaves the room or got killed by it. Appreciate all the help! 😄
 

slayzer

Klaffen
Joined
Dec 28, 2008
Messages
299
Solutions
3
Reaction score
49
Location
Norway
Don't have time to make the script right now but possible solutions:
1. You could store the current time + 20 hours as storage value for all players.
Lua:
--Add cooldown
local storageValueForBoss = 1234
local cooldown = 1000 * 60 * 60 * 20
local now = os.mtime()

spec:setStorageValue(storageValueForBoss, now + cooldown)


--Later:
if spec:getStorageValue(storageValueForBoss) > os.mtime() then
    --Dont allow player to enter
end

2. To make boss disappear you could add an event that every minute checks if any players are still in the boss room. Use same logic as what you did for "Someone is fighting with Duke Krule right now.".
Lua:
  local function checkIfPlayersAlive(cid)
    local boss = Creature(cid)
    if not boss then
        return true
    end

    local spectators = Game.getSpectators(config.centerRoom, false, false, 15, 15, 15, 15)
    if not spectators or #spectators == 0 then
        boss:remove()
    else
        addEvent(checkIfPlayersAlive, 60000, cid)
    end
end

local boss =  Game.createMonster("Duke Krule", config.BossPosition, true, true)
   addEvent(checkIfPlayersAlive, 1000 * 60, boss:getId())

If you need help slotting into your script then i might have more time later

EDIT: Fixed an error i made with setting storage value (forgot now)
 
Last edited:

pink_panther

Excellent OT User
Joined
Sep 10, 2016
Messages
1,115
Solutions
13
Reaction score
561
Location
Kazordoon
Mine is a Movement, as it's a just a teleporter to enter.

Will have a timer and limit of 1 person in the boss room at a time.

Should be pretty easy to change it to a lever action if you want to, i just figured it was more work adding a lever 😂

Lua:
local function roomIsOccupied(centerPosition, rangeX, rangeY)
    local spectators = Game.getSpectators(centerPosition, false, true, rangeX, rangeX, rangeY, rangeY)
    if #spectators ~= 0 then
        return true
    end

    return false
end

function clearBossRoom(playerId, bossId, centerPosition, rangeX, rangeY, exitPosition)
    local spectators, spectator = Game.getSpectators(centerPosition, false, false, rangeX, rangeX, rangeY, rangeY)
    for i = 1, #spectators do
        spectator = spectators[i]
        if spectator:isPlayer() and spectator.uid == playerId then
            spectator:teleportTo(exitPosition)
            exitPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end

        if spectator:isMonster() and spectator.uid == bossId then
            spectator:remove()
        end
    end
end

local bosses = {
    [1139] = {bossName = 'Stonecracker', storage = 10, playerPosition = Position(33259, 31700, 15), bossPosition = Position(33256, 31704, 15), centerPosition = Position(33259, 31700, 15), rangeX = 8, rangeY = 8},
    [1152] = {bossName = 'Kerberos', storage = 10, playerPosition = Position(32048, 32577, 15), bossPosition = Position(32042, 32568, 15), centerPosition = Position(32042, 32568, 15), rangeX = 18, rangeY = 18},
    


}


function onStepIn(creature, item, position, fromPosition)
    local player = creature:getPlayer()
    if not player then
        return true
    end
    
    local boss = bosses[item:getMovementId()]
    if not boss then
        return true
    end


    
    if roomIsOccupied(boss.centerPosition, boss.rangeX, boss.rangeY) then
        player:say('This boss room is currently occupied.', TALKTYPE_MONSTER_SAY)
        player:teleportTo(fromPosition)
        player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
        return true
    end
    
    local monster = Game.createMonster(boss.bossName, boss.bossPosition)
    if not monster then
        return true
    end
    
    player:teleportTo(boss.playerPosition)
    boss.playerPosition:sendMagicEffect(CONST_ME_TELEPORT)


    addEvent(clearBossRoom, 60 * 10 * 1000, player.uid, monster.uid, boss.centerPosition, boss.rangeX, boss.rangeY, fromPosition)
    player:say('You have ten minutes to kill and loot this boss. Otherwise you will lose that chance and will be kicked out.', TALKTYPE_MONSTER_SAY)
    return true
end
 

slayzer

Klaffen
Joined
Dec 28, 2008
Messages
299
Solutions
3
Reaction score
49
Location
Norway
Not tested.

Storage value is a table in the database used for storing values related to a character. Can be used for storing things like monster kills (for tasks) and quest completion.
In this case i use it to store the current time + 20 hours.

Note: I have not tested this code (I am not at home).

Lua:
local config = {
    centerRoom = Position(33456, 31473, 13),
    BossPosition = Position(33456, 31473, 13),
    newPosition = Position(33457, 31466, 13),
    cooldownStorageValue = 9999, -- Use a free value. So something you dont use for a quest in your server
    cooldown = 1000 * 60 * 60 * 20 -- 20 hours
}

local function teleportPlayers()
    local now = os.mtime()

    for x = 33455, 33459 do
        local playerTile = Tile(Position(x, 31493, 13))
        if playerTile ~= nil and playerTile:getTopCreature() ~= nil then
            local player = playerTile:getTopCreature()

            if player:isPlayer() then
                player:getPosition():sendMagicEffect(CONST_ME_POFF)
                player:teleportTo(config.newPosition)
                player:getPosition():sendMagicEffect(CONST_ME_TELEPORT)

                player:setStorageValue(cooldownStorageValue, now + cooldown)
            end
        end
    end
end

local function playerHasCooldown()
    local now = os.mtime()

    for x = 33455, 33459 do
        local playerTile = Tile(Position(x, 31493, 13))
        if playerTile ~= nil and playerTile:getTopCreature() ~= nil then
            local player = playerTile:getTopCreature()

            -- Here i check if a player has fought the boss in the past 20 hours.
            if player:isPlayer() and player:getStorageValue(config.cooldownStorageValue) > now then
                return player
            end
        end
    end

    return nil
end

local function checkIfPlayersAlive(cid)
    local boss = Creature(cid)
    if not boss then
        return true
    end

    local spectators = Game.getSpectators(config.centerRoom, false, true, 15, 15, 15, 15)
        if not spectators or #spectators == 0 then
            boss:remove()
    else
        addEvent(checkIfPlayersAlive, 60000, cid)
    end
end

local graveDangerDukeKruleLever = Action()
function graveDangerDukeKruleLever.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    
    -- Only player on this position can pull the lever
    if player:getPosition() ~= Position(33455, 31493, 13) then
        return true
    end

    if item.itemid == 9825 then
        item:transform(9826)
    else
        item:transform(9825)
    end

    local spectators = Game.getSpectators(config.centerRoom, false, true, 15, 15, 15, 15) -- Finds only players since 3rd parameter is true
    if spectators and #spectators > 0 then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Someone is fighting with Duke Krule right now.")
        return true
    end

    local playerWithCooldown = someoneHasCooldown()
    if playerWithCooldown ~= nil then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, playerWithCooldown:getName() .. " needs to wait before fighting the boss again.")
        return true
    end

    teleportPlayers()

    local boss = Game.createMonster("Duke Krule", config.BossPosition, true, true)

    addEvent(checkIfPlayersAlive, 1000 * 60, boss:getId()) -- Checks if players are still alive every 60 sec
    addEvent(clearForgotten, 30 * 60 * 1000, Position(33446, 33462, 13), Position(33465, 31482, 13), Position(32347, 32167, 12)) -- Not sure waht this function does


    return true
end

graveDangerDukeKruleLever:uid(30498)
graveDangerDukeKruleLever:register()
 
Top