• 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!

Attempt to index a nil value stack traceback

mattehj

Member
Joined
Oct 8, 2009
Messages
83
Reaction score
16
I just cant figgure out what is wrong. I've used this for another boss that works fine, The only difference is that this monster have an space bar.

[Lua script error: C:\Users\M\data\scripts\quests\egna_bossar\black_ninja.lua:callback
[2021-31-05 03:26:36.743] [error] ...nkar bra\data\scripts\quests\egna_bossar\black_ninja.lua:34: attempt to index a nil value
stack traceback:
[C]: in function '__index'
...\data\scripts\quests\egna_bossar\black_ninja.lua:34: in function <...a\data\scripts\quests\egna_bossar\black_ninja.lua:23>


Lua:
-- lever to black ninja

local config = {
    requiredLevel = 200,
    daily = true,
    roomCenterPosition = Position(33291, 27224, 13),
    playerPositions = {
        Position(33288, 27243, 13),
        Position(33389, 27243, 13),
        Position(33390, 27243, 13),
        Position(33391, 27243, 13),
        Position(33392, 27243, 13)
    },
    teleportPosition = Position(33291, 27221, 13),
    bossPosition = Position(33291, 27229, 13),

        kickMinutes = 15, -- minutes
        kickPosition = Position(33289, 27247, 13)
}

local leverboss = Action()

function leverboss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == 9825 then
        -- Check if the player that pulled the lever is on the correct position
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end
        
        local team, participant = {}

        for i = 1, #config.playerPositions do
            participant = Tile(config.playerPositions[i]):getTopCreature()
            
            -- Check there is a participant player
            if participant and participant:isPlayer() then
                -- Check participant level
                if participant:getLevel() < config.requiredLevel then
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE,
                        "All the players need to be level ".. config.requiredLevel .." or higher.")
                    return true
                end

                -- -- Check participant boss timer
                if config.daily and participant:getStorageValue(Storage.EgnaBossar.Blackninja) > os.time() then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendCancelMessage("Not all players are ready yet from last battle.")
                    return true
                end

                team[#team + 1] = participant
            end
        end

        -- Check if a team currently inside the boss room
        local specs, spec = Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)
        for i = 1, #specs do
            spec = specs[i]
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end

            spec:remove()
        end

        -- Spawn boss
        Game.createMonster("Black Ninja", config.bossPosition)

        -- Teleport team participants
        for i = 1, #team do
            team[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            team[i]:teleportTo(config.teleportPosition)
            -- Assign boss timer
            team[i]:setStorageValue(Storage.EgnaBossar.Blackninja, os.time() + 20*60*60) -- 20 hours
        end
        
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)

                    -- remove all creatures and teleport to players after 15 minutes
        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end

    item:transform(9825)
    return true
end

leverboss:uid(13002)
leverboss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
 
I just cant figgure out what is wrong. I've used this for another boss that works fine, The only difference is that this monster have an space bar.

[Lua script error: C:\Users\M\data\scripts\quests\egna_bossar\black_ninja.lua:callback
[2021-31-05 03:26:36.743] [error] ...nkar bra\data\scripts\quests\egna_bossar\black_ninja.lua:34: attempt to index a nil value
stack traceback:
[C]: in function '__index'
...\data\scripts\quests\egna_bossar\black_ninja.lua:34: in function <...a\data\scripts\quests\egna_bossar\black_ninja.lua:23>


Lua:
-- lever to black ninja

local config = {
    requiredLevel = 200,
    daily = true,
    roomCenterPosition = Position(33291, 27224, 13),
    playerPositions = {
        Position(33288, 27243, 13),
        Position(33389, 27243, 13),
        Position(33390, 27243, 13),
        Position(33391, 27243, 13),
        Position(33392, 27243, 13)
    },
    teleportPosition = Position(33291, 27221, 13),
    bossPosition = Position(33291, 27229, 13),

        kickMinutes = 15, -- minutes
        kickPosition = Position(33289, 27247, 13)
}

local leverboss = Action()

function leverboss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == 9825 then
        -- Check if the player that pulled the lever is on the correct position
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end
    
        local team, participant = {}

        for i = 1, #config.playerPositions do
            participant = Tile(config.playerPositions[i]):getTopCreature()
        
            -- Check there is a participant player
            if participant and participant:isPlayer() then
                -- Check participant level
                if participant:getLevel() < config.requiredLevel then
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE,
                        "All the players need to be level ".. config.requiredLevel .." or higher.")
                    return true
                end

                -- -- Check participant boss timer
                if config.daily and participant:getStorageValue(Storage.EgnaBossar.Blackninja) > os.time() then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendCancelMessage("Not all players are ready yet from last battle.")
                    return true
                end

                team[#team + 1] = participant
            end
        end

        -- Check if a team currently inside the boss room
        local specs, spec = Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)
        for i = 1, #specs do
            spec = specs[i]
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end

            spec:remove()
        end

        -- Spawn boss
        Game.createMonster("Black Ninja", config.bossPosition)

        -- Teleport team participants
        for i = 1, #team do
            team[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            team[i]:teleportTo(config.teleportPosition)
            -- Assign boss timer
            team[i]:setStorageValue(Storage.EgnaBossar.Blackninja, os.time() + 20*60*60) -- 20 hours
        end
    
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)

                    -- remove all creatures and teleport to players after 15 minutes
        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end

    item:transform(9825)
    return true
end

leverboss:uid(13002)
leverboss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
In situations like this, you need to use prints to find out exactly where it's breaking.

In my mind, I believe the issue in on line 46.. where it's possible that the storage value is getting a nil value.. but that's just my assumption.

We'll let the prints figure it out for us. :)

So, test this out, and check console to find out where the script is actually breaking.

Lua:
-- lever to black ninja

local config = {
    requiredLevel = 200,
    daily = true,
    roomCenterPosition = Position(33291, 27224, 13),
    playerPositions = {
        Position(33288, 27243, 13),
        Position(33389, 27243, 13),
        Position(33390, 27243, 13),
        Position(33391, 27243, 13),
        Position(33392, 27243, 13)
    },
    teleportPosition = Position(33291, 27221, 13),
    bossPosition = Position(33291, 27229, 13),
   
    kickMinutes = 15, -- minutes
    kickPosition = Position(33289, 27247, 13)
}

local leverboss = Action()

function leverboss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == 9825 then
        -- Check if the player that pulled the lever is on the correct position
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end
       
        local team, participant = {}
        print("------")
        for i = 1, #config.playerPositions do
            print("loop " .. i)
            participant = Tile(config.playerPositions[i]):getTopCreature()
           
            -- Check there is a participant player
            if participant and participant:isPlayer() then
                print("participant found..")
                -- Check participant level
                print("checking level..")
                if participant:getLevel() < config.requiredLevel then
                    print("not required level. exit 1")
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All the players need to be level ".. config.requiredLevel .." or higher.")
                    return true
                end
   
                -- -- Check participant boss timer
                print("checking storage requirements..")
                if config.daily and participant:getStorageValue(Storage.EgnaBossar.Blackninja) > os.time() then
                    print("storage issue for participant. exit 2")
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendCancelMessage("Not all players are ready yet from last battle.")
                    return true
                end
   
                print("adding participant to team.")
                team[#team + 1] = participant
            end
        end
        print("all participants have been added to a team.")
   
        -- Check if a team currently inside the boss room
        local specs, spec = Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)
        for i = 1, #specs do
            spec = specs[i]
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end
   
            spec:remove()
        end
   
        -- Spawn boss
        Game.createMonster("Black Ninja", config.bossPosition)
   
        -- Teleport team participants
        print("attempting to use participant details..")
        for i = 1, #team do
            team[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            team[i]:teleportTo(config.teleportPosition)
            -- Assign boss timer
            team[i]:setStorageValue(Storage.EgnaBossar.Blackninja, os.time() + 20*60*60) -- 20 hours
        end
        print("participant information used successfully.")
       
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)
   
                    -- remove all creatures and teleport to players after 15 minutes
        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end
   
    item:transform(9825)
    return true
end

leverboss:uid(13002)
leverboss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
 
This is the same code that you published in this thread Timer to kill boss, which you marked as solved, it is rare that it is failing in this case However I have slightly modified the code to make it cleaner, and change the configuration of the boss name and the unique ID of the lever to the configuration table, so that it is less tedious when configuring, you should try

Lua:
local config = {
    leverUniqueID = 49006,
    requiredLevel = 100,
    daily = true,
    bossName = "Duke Krule",
    storage = Storage.GraveDanger.KruleTimer,
    roomCenterPosition = Position(33456, 31472, 13),
    playerPositions = {
        Position(33455, 31493, 13),
        Position(33456, 31493, 13),
        Position(33457, 31493, 13),
        Position(33458, 31493, 13),
        Position(33459, 31493, 13)
    },
    teleportPosition = Position(33456, 31480, 13),
    bossPosition = Position(33456, 31472, 13),

    kickMinutes = 15, -- minutes
    kickPosition = Position(0, 0, 0)
}

local leverBoss = Action()

function leverBoss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == 9825 then
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end

        local participants = {}
        for _, playerPos in pairs(config.playerPositions) do
            local tile = Tile(playerPos)
            if tile then
                local participant = tile:getTopCreature()
                if participant and participant:isPlayer() then
                    if participant:getLevel() < config.requiredLevel then
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("All the players need to be level %d or higher.", config.requiredLevel))
                        return true
                    end

                    if config.daily and participant:getStorageValue(config.storage) > os.time() then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        player:sendCancelMessage("Not all players are ready yet from last battle.")
                        return true
                    end

                    participants[#participants +1] = participant
                end
            end
        end

        for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
            if spectator:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end
            spectator:remove()
        end

        local boss = Game.createMonster(config.bossName, config.bossPosition)
        if boss then boss:registerEvent("CancelKickEvent") end

        for _, participant in pairs(participants) do
            participant:getPosition():sendMagicEffect(CONST_ME_POFF)
            participant:teleportTo(config.teleportPosition)
            participant:setStorageValue(config.storage, os.time() + 20*60*60)
        end
        
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)

        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end

    item:transform(9825)
    return true
end

leverBoss:uid(config.leverUniqueID)
leverBoss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
 
Last edited:
This is the same code that you published in this thread Timer to kill boss, which you marked as solved, it is rare that it is failing in this case However I have slightly modified the code to make it cleaner, and change the configuration of the boss name and the unique ID of the lever to the configuration table, so that it is less tedious when configuring, you should try

Lua:
local config = {
    leverUniqueID = 49006,
    requiredLevel = 100,
    daily = true,
    bossName = "Duke Krule",
    roomCenterPosition = Position(33456, 31472, 13),
    playerPositions = {
        Position(33455, 31493, 13),
        Position(33456, 31493, 13),
        Position(33457, 31493, 13),
        Position(33458, 31493, 13),
        Position(33459, 31493, 13)
    },
    teleportPosition = Position(33456, 31480, 13),
    bossPosition = Position(33456, 31472, 13),

    kickMinutes = 15, -- minutes
    kickPosition = Position(0, 0, 0)
}

local leverBoss = Action()

function leverBoss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == 9825 then
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end

        local participants = {}
        for _, playerPos in pairs(config.playerPositions) do
            local tile = Tile(playerPos)
            if tile then
                local participant = tile:getTopCreature()
                if participant and participant:isPlayer() then
                    if participant:getLevel() < config.requiredLevel then
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("All the players need to be level %d or higher.", config.requiredLevel))
                        return true
                    end

                    if config.daily and participant:getStorageValue(Storage.GraveDanger.KruleTimer) > os.time() then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        player:sendCancelMessage("Not all players are ready yet from last battle.")
                        return true
                    end

                    participants[#participants +1] = participant
                end
            end
        end

        for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
            if spectator:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end
            spectator:remove()
        end

        local boss = Game.createMonster(config.bossName, config.bossPosition)
        if boss then boss:registerEvent("CancelKickEvent") end

        for _, participant in pairs(participants) do
            participant:getPosition():sendMagicEffect(CONST_ME_POFF)
            participant:teleportTo(config.teleportPosition)
            participant:setStorageValue(Storage.GraveDanger.KruleTimer, os.time() + 20*60*60)
        end
       
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)

        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end

    item:transform(9825)
    return true
end

leverBoss:uid(config.leverUniqueID)
leverBoss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
note that the boss being summoned and the storages have been changed in @OP's posted script.

If he uses your script as-is, he may get false positives and/or issues in other scripts if he fails to update lines 5, 41 and 66 accordingly.
 
Isn't better check first the participant and after check participant:isPlayer()?

Lua:
if participant then
    if participant:isPlayer() then
        ...
    end
end
I think you have not paid very good attention in the code, there is no situation in which you try to verify if it is a player if the participant is nil

Lua:
if participant and participant:isPlayer() then

Logical Operators In Lua 5.1:
 
In situations like this, you need to use prints to find out exactly where it's breaking.

In my mind, I believe the issue in on line 46.. where it's possible that the storage value is getting a nil value.. but that's just my assumption.

We'll let the prints figure it out for us. :)

So, test this out, and check console to find out where the script is actually breaking.

Lua:
-- lever to black ninja

local config = {
    requiredLevel = 200,
    daily = true,
    roomCenterPosition = Position(33291, 27224, 13),
    playerPositions = {
        Position(33288, 27243, 13),
        Position(33389, 27243, 13),
        Position(33390, 27243, 13),
        Position(33391, 27243, 13),
        Position(33392, 27243, 13)
    },
    teleportPosition = Position(33291, 27221, 13),
    bossPosition = Position(33291, 27229, 13),
  
    kickMinutes = 15, -- minutes
    kickPosition = Position(33289, 27247, 13)
}

local leverboss = Action()

function leverboss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item.itemid == 9825 then
        -- Check if the player that pulled the lever is on the correct position
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end
      
        local team, participant = {}
        print("------")
        for i = 1, #config.playerPositions do
            print("loop " .. i)
            participant = Tile(config.playerPositions[i]):getTopCreature()
          
            -- Check there is a participant player
            if participant and participant:isPlayer() then
                print("participant found..")
                -- Check participant level
                print("checking level..")
                if participant:getLevel() < config.requiredLevel then
                    print("not required level. exit 1")
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "All the players need to be level ".. config.requiredLevel .." or higher.")
                    return true
                end
  
                -- -- Check participant boss timer
                print("checking storage requirements..")
                if config.daily and participant:getStorageValue(Storage.EgnaBossar.Blackninja) > os.time() then
                    print("storage issue for participant. exit 2")
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                    player:sendCancelMessage("Not all players are ready yet from last battle.")
                    return true
                end
  
                print("adding participant to team.")
                team[#team + 1] = participant
            end
        end
        print("all participants have been added to a team.")
  
        -- Check if a team currently inside the boss room
        local specs, spec = Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)
        for i = 1, #specs do
            spec = specs[i]
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end
  
            spec:remove()
        end
  
        -- Spawn boss
        Game.createMonster("Black Ninja", config.bossPosition)
  
        -- Teleport team participants
        print("attempting to use participant details..")
        for i = 1, #team do
            team[i]:getPosition():sendMagicEffect(CONST_ME_POFF)
            team[i]:teleportTo(config.teleportPosition)
            -- Assign boss timer
            team[i]:setStorageValue(Storage.EgnaBossar.Blackninja, os.time() + 20*60*60) -- 20 hours
        end
        print("participant information used successfully.")
      
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)
  
                    -- remove all creatures and teleport to players after 15 minutes
        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end
  
    item:transform(9825)
    return true
end

leverboss:uid(13002)
leverboss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()

Ok now i get this:
loop 1
participant found..
checking level..
checking storage requirements..
adding participant to team.
loop 2
[2021-31-05 09:10:30.915] [error] Lua script error: C:\data\scripts\quests\egna_bossar\black_ninja.lua:callback
[2021-31-05 09:10:30.915] [error] ...\data\scripts\quests\egna_bossar\black_ninja.lua:35: attempt to index a nil value
stack traceback:
[C]: in function '__index'
\data\scripts\quests\egna_bossar\black_ninja.lua:35: in function <...nkar bra\data\scripts\quests\egna_bossar\black_ninja.lua:23>
Post automatically merged:

This is the same code that you published in this thread Timer to kill boss, which you marked as solved, it is rare that it is failing in this case However I have slightly modified the code to make it cleaner, and change the configuration of the boss name and the unique ID of the lever to the configuration table, so that it is less tedious when configuring, you should try

Lua:
local config = {
    leverUniqueID = 49006,
    requiredLevel = 100,
    daily = true,
    bossName = "Duke Krule",
    storage = Storage.GraveDanger.KruleTimer,
    roomCenterPosition = Position(33456, 31472, 13),
    playerPositions = {
        Position(33455, 31493, 13),
        Position(33456, 31493, 13),
        Position(33457, 31493, 13),
        Position(33458, 31493, 13),
        Position(33459, 31493, 13)
    },
    teleportPosition = Position(33456, 31480, 13),
    bossPosition = Position(33456, 31472, 13),

    kickMinutes = 15, -- minutes
    kickPosition = Position(0, 0, 0)
}

local leverBoss = Action()

function leverBoss.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == 9825 then
        if player:getPosition() ~= config.playerPositions[1] then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You can\'t start the battle.")
            return true
        end

        local participants = {}
        for _, playerPos in pairs(config.playerPositions) do
            local tile = Tile(playerPos)
            if tile then
                local participant = tile:getTopCreature()
                if participant and participant:isPlayer() then
                    if participant:getLevel() < config.requiredLevel then
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("All the players need to be level %d or higher.", config.requiredLevel))
                        return true
                    end

                    if config.daily and participant:getStorageValue(config.storage) > os.time() then
                        player:getPosition():sendMagicEffect(CONST_ME_POFF)
                        player:sendCancelMessage("Not all players are ready yet from last battle.")
                        return true
                    end

                    participants[#participants +1] = participant
                end
            end
        end

        for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
            if spectator:isPlayer() then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "A team is already inside the boss room.")
                return true
            end
            spectator:remove()
        end

        local boss = Game.createMonster(config.bossName, config.bossPosition)
        if boss then boss:registerEvent("CancelKickEvent") end

        for _, participant in pairs(participants) do
            participant:getPosition():sendMagicEffect(CONST_ME_POFF)
            participant:teleportTo(config.teleportPosition)
            participant:setStorageValue(config.storage, os.time() + 20*60*60)
        end
       
        config.teleportPosition:sendMagicEffect(CONST_ME_ENERGYAREA)

        config.kickEventId = addEvent(function ()
            for _, spectator in pairs(Game.getSpectators(config.roomCenterPosition, false, false, 14, 14, 13, 13)) do
                if spectator:isPlayer() then
                    spectator:teleportTo(config.kickPosition, false)
                    spectator:sendCancelMessage("Time is up!")
                else
                    spectator:remove()
                end
            end
            config.kickPosition:sendMagicEffect(CONST_ME_TELEPORT)
        end, config.kickMinutes * 60 * 1000)
    end

    item:transform(9825)
    return true
end

leverBoss:uid(config.leverUniqueID)
leverBoss:register()

local cancelKickEvent = CreatureEvent("CancelKickEvent")
function cancelKickEvent.onDeath(...) stopEvent(config.kickEventId) return true end
cancelKickEvent:register()
This worked, But i'm still curious why the old didn't work !
 
Last edited:
Ok now i get this:
loop 1
participant found..
checking level..
checking storage requirements..
adding participant to team.
loop 2
[2021-31-05 09:10:30.915] [error] Lua script error: C:\data\scripts\quests\egna_bossar\black_ninja.lua:callback
[2021-31-05 09:10:30.915] [error] ...\data\scripts\quests\egna_bossar\black_ninja.lua:35: attempt to index a nil value
stack traceback:
[C]: in function '__index'
\data\scripts\quests\egna_bossar\black_ninja.lua:35: in function <...nkar bra\data\scripts\quests\egna_bossar\black_ninja.lua:23>
Post automatically merged:


This worked, But i'm still curious why the old didn't work !
Probably because the tile at that position didn't exist.
If the tile doesn't exist, it pulls a nil value when trying to find the top creature.
 
Probably because the tile at that position didn't exist.
If the tile doesn't exist, it pulls a nil value when trying to find the top creature.
That's wierd, Because i copied the positions from that script to sarahs script, and her worked xD so I didnt change them
 
That's wierd, Because i copied the positions from that script to sarahs script, and her worked xD so I didnt change them
Sarah's script confirms if the tile exists before attempting to use it.
Lua:
            local tile = Tile(playerPos)
            if tile then
It's a failsafe in case something in the config is doing something wrong.

Where in the other script, it attempts to create the tile, and immediately use it.
Lua:
participant = Tile(config.playerPositions[i]):getTopCreature()
So your second position, probably is missing a tile.

---

If the map and config are setup correctly you don't need to confirm the tile exists, but it's best practice to check for the tile before using it.
Post automatically merged:

That's wierd, Because i copied the positions from that script to sarahs script, and her worked xD so I didnt change them
To further clarify, look at your positions.
It starts out as 33288, then immediately jumps 100 positions using 33389
Lua:
    playerPositions = {
        Position(33288, 27243, 13), -- 332
        Position(33389, 27243, 13), -- 333
        Position(33390, 27243, 13), -- 333
        Position(33391, 27243, 13), -- 333
        Position(33392, 27243, 13) -- 333
    },

So while Sarah's method "fixes" the issue, it's only a false positive.
The real issue is that your positions are setup incorrectly.
 
Last edited:
Back
Top