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

How to cancel a started event?

Sparkles

snek
Joined
Mar 1, 2009
Messages
320
Solutions
27
Reaction score
148
Location
Norway, Tromsø
I think I might be blind, but eh.
Im trying to kick players from the Demon Oak area after x amount of seconds, so they dont block it for others.
Somehow, using the normal axe on the tree after entering doesn't stop the event, can someone please tell me what im doing wrong here?

lua:

Lua:
 function onUse(player, item, fromPosition, target, toPosition, isHotkey)
        local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)
        for i = 1, #specs do
            spec = specs[i]
            if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then 
                if spec:isPlayer() then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
                return true
                end
            end
            if spec:isMonster() then
            spec:remove()
            end
        end
        
      
local function kickbois(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end


            
        
        if target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) < 1 then
            if player:getLevel(cid) >= 120 then
                player:teleportTo(DEMON_OAK_ENTER_POSITION)
                addEvent(kickbois, 20000, player.uid)
                player:setStorageValue(Storage.DemonOak.Progress, 1)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
            end 
        elseif target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) == 1 then
            player:teleportTo(DEMON_OAK_KICK_POSITION)
            stopEvent(kickbois)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
            
        end

end
 
Solution
You are setting kickOutEvent to nil every time you use an item. Move kickOutEvent out of that function and try to remove local before it. So something like that:
Lua:
kickOutEvent = nil

function kickPlayerOut(cid)
    local player = Player(cid)

    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)

    for i = 1, #specs do
        spec = specs[i]

        if player:getStorageValue(Storage.DemonOak.Progress) < 1 or...
Each event gets an ID once they are declared, so you have to point to the ID in order to stop the event.
This script will only kick the player that uses the lever, though.
Lua:
local function kickbois(cid)
   local player = Player(cid)
   if player then
       player:teleportTo(DEMON_OAK_KICK_POSITION)
       player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
   end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
  local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)
    for i = 1, #specs do
      spec = specs[i]
      if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then
        if spec:isPlayer() then
          player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
          return true
        end
      end
      if spec:isMonster() then
        spec:remove()
      end
  end

  local timeOutEvent = nil
  if target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) < 1 then
    if player:getLevel(cid) >= 120 then
      -- Restarting the event
      if timeOutEvent then
        stopEvent(timeOutEvent)
      end
      player:teleportTo(DEMON_OAK_ENTER_POSITION)
      timeOutEvent = addEvent(kickbois, 20000, player:getId())
      player:setStorageValue(Storage.DemonOak.Progress, 1)
      player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
    else
      player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
    end
  elseif target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) == 1 then
    player:teleportTo(DEMON_OAK_KICK_POSITION)
    stopEvent(timeOutEvent)
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
  end
end
 
Well that didn't work, it changed nothing. When the player uses the "axe" on the tree, and when he uses it on the tree again, he exits and should stop the kick event.
Im at a loss here :\
 
You might be able to figure out yourself with this quick explanation on how events work.

Lua:
-- Declaring variable that will store eventId
local eventId = nil

-- Example function
local function example()
  print("Event has been called")
end

-- Calling event
-- This line stores eventId on the variable and schedules event call
eventId = addEvent(example, 5 * 1000)

-- Stopping event
-- This line will stop the event
stopEvent(eventId)

-- Therefore the event won't never be called, unless we get rid of the stopEvent line
 
You're saying that the eventId is storing the value for the event, and by setting the value of that to a function you can simply cancel the function by stopping the eventId (value of the event)?
 
This is what I have tried, but it still wont work.
From a quick glance your kick function might not be able to access the localized memory?
dont remember if this is possible

local timeOutEvent = nil

copy paste whole script you have atm plx

if you want to make sure that the stopEvent is being called add it to another function with a print, from there you can debug whats goin on.

heres some pseudo, can put this wherever stopEvent is called
Code:
local function kickStopEvent()  --I forgot if stopEvent deletes instance or sets var  to 0 or false..
  stopEvent(eventVar)
  if(eventVar>0 )then
      print("found event not stopped "..eventVar)
  elseif(eventVar==nil )then
      print("event not found or was stopped "..eventVar)
  else
    print("event was stopped "..eventVar)
  end
return true
end

kickStopEvent()
Notice where @Westwol declares eventId

Hope that helps :)
 
Last edited:
I've made the event:
Lua:
local function kickPlayerOut(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end

Then set up an empty kickOutEvent value:
Lua:
 local kickOutEvent = nil

Then set the value of kickOutEvent = to the actual event:
Lua:
 kickOutEvent = addEvent(kickPlayerOut, 4000, player:getId())

But when running this it wont stop:
Lua:
 stopEvent(kickOutEvent)


--EDIT--
The actual event part of the script works, but I cant cancel it once its started.
 
Lua:
local function kickPlayerOut(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end


function onUse(player, item, fromPosition, target, toPosition, isHotkey)
        local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)
        for i = 1, #specs do
            spec = specs[i]
            if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then 
                if spec:isPlayer() then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
                return true
                end
            end
            if spec:isMonster() then
            spec:remove()
            end
        end
        

local kickOutEvent = nil
            
        if target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) < 1 then
            if player:getLevel(cid) >= 120 then
                    if kickOutEvent then
                        stopEvent(kickOutEvent)
                    end 
                player:teleportTo(DEMON_OAK_ENTER_POSITION)
                kickOutEvent = addEvent(kickPlayerOut, 4000, player:getId())
                player:setStorageValue(Storage.DemonOak.Progress, 1)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
            end 
        elseif target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) == 1 then
            stopEvent(kickOutEvent)
            player:teleportTo(DEMON_OAK_KICK_POSITION)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
            
        end

end
 
You are setting kickOutEvent to nil every time you use an item. Move kickOutEvent out of that function and try to remove local before it. So something like that:
Lua:
kickOutEvent = nil

function kickPlayerOut(cid)
    local player = Player(cid)

    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)

    for i = 1, #specs do
        spec = specs[i]

        if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
                return true
            end
        end

        if spec:isMonster() then
            spec:remove()
        end
    end

    if target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) < 1 then
        if player:getLevel(cid) >= 120 then
            if kickOutEvent then
                stopEvent(kickOutEvent)
            end

            player:teleportTo(DEMON_OAK_ENTER_POSITION)
            kickOutEvent = addEvent(kickPlayerOut, 4000, player:getId())
            player:setStorageValue(Storage.DemonOak.Progress, 1)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
        end
    elseif target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) == 1 then
        if kickOutEvent then
            stopEvent(kickOutEvent)
        end

        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end
 
Last edited:
Solution
Jesus, im stupid,

changed from this
Lua:
 local function kickPlayerOut(cid)

to this
Lua:
 function kickPlayerOut(cid)
solved my issues! yay! thanks for the help boii
 
You are setting kickOutEvent to nil every time you use an item. Move kickOutEvent out of that function and try to remove local before it. So something like that:
Lua:
kickOutEvent = nil

local function kickPlayerOut(cid)
    local player = Player(cid)

    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local specs, spec = Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)

    for i = 1, #specs do
        spec = specs[i]

        if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then
            if spec:isPlayer() then
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
                return true
            end
        end

        if spec:isMonster() then
            spec:remove()
        end
    end

    if target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) < 1 then
        if player:getLevel(cid) >= 120 then
            if kickOutEvent then
                stopEvent(kickOutEvent)
            end

            player:teleportTo(DEMON_OAK_ENTER_POSITION)
            kickOutEvent = addEvent(kickPlayerOut, 4000, player:getId())
            player:setStorageValue(Storage.DemonOak.Progress, 1)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
        else
            player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
        end
    elseif target.actionid == 50250 and target.itemid == 2709 and player:getStorageValue(Storage.DemonOak.Progress) == 1 then
        if kickOutEvent then
            stopEvent(kickOutEvent)
        end

        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end
Jesus, im stupid,

changed from this
Lua:
 local function kickPlayerOut(cid)

to this
Lua:
 function kickPlayerOut(cid)
solved my issues! yay! thanks for the help boii
You're right about it being outside the function but it's not really necessary to remove the local before it unless you plan on using a dofile and using it outside of this script. Also I'm not 100% sure but i'm worried that if you use this single int variable instead of an array you would have issues. For example, if you have a second player trigger the addEvent before the first one is activated or cancelled. Then the variable would be filled and you wouldn't be able to cancel the first event.

I would do the script like this, I also made some fixes to help it look cleaner. Untested tho so hopefully no errors.
Lua:
local kickOutEvent = {}

local function kickPlayerOut(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end


function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local cid = player.uid
    for key, spec in pairs(Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)) do
        if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then
            if spec:isPlayer() then
                return player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
            end
        end
        if spec:isMonster() then
            spec:remove()
        end
    end

    if target.actionid == 50250 and target.itemid == 2709 then       
        if player:getStorageValue(Storage.DemonOak.Progress) < 1 then
            if player:getLevel(cid) >= 120 then
                if kickOutEvent[cid] then
                    stopEvent(kickOutEvent[cid])
                    kickOutEvent[cid] = nil
                end
                kickOutEvent[cid] = addEvent(kickPlayerOut, 4000, cid)
                player:teleportTo(DEMON_OAK_ENTER_POSITION)
                player:setStorageValue(Storage.DemonOak.Progress, 1)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
            end
        elseif player:getStorageValue(Storage.DemonOak.Progress) == 1 then
            if kickOutEvent[cid] then
                stopEvent(kickOutEvent[cid])
                kickOutEvent[cid] = nil
            end
            player:teleportTo(DEMON_OAK_KICK_POSITION)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
        end
    end
    return true
end
 
Jesus, im stupid,

changed from this
Lua:
 local function kickPlayerOut(cid)

to this
Lua:
 function kickPlayerOut(cid)
solved my issues! yay! thanks for the help boii
please note that @kor script is creating a global variable that can cause problems when other players click on the quest, the var is global at that point not local per player. (Script is correct it will work with 1 tester just might have logic errors with multiple ppl.)
 
Last edited:
please note that his script is creating a global variable that can cause problems when other players click on the quest, the var is global at that point not local per player. The function can be global just not the event var.

change kickOutEvent = nil to local kickOutEvent = nil or try Apollos script it should work, although the array is unneeded code.
I'm still curious about this, because I did a test of my own and it seems that this way still could cause issues if a second player activates the script before the original addEvent is cancelled or activated. Maybe I'm not understanding something yet.

3549235493

In this test I cast the spell by CM Apollos then by Riku and it seems like it filled the variable so it won't be able to be used to stop event later.
 
I'm still curious about this, because I did a test of my own and it seems that this way still could cause issues if a second player activates the script before the original addEvent is cancelled or activated. Maybe I'm not understanding something yet.

View attachment 35492View attachment 35493

In this test I cast the spell by CM Apollos then by Riku and it seems like it filled the variable so it won't be able to be used to stop event later.
Might be how spells are loaded thru distro? dunno it works on action files for me. try on an action file, if not then you are correct but I swear in my distro I have a lot of localized eventID's above my functions in actions on OTHire. il have to recheck cant remember

I think its how spells are handled globally? idk im prob wrong
 
Last edited:
Might be how spells are loaded thru distro? dunno it works on action files for me. try on an action file, if not then you are correct but I swear in my distro I have a lot of localized eventID's above my functions in actions on OTHire.

With your spell script if that was an action file each time that someone would use that script it would always initialize test to nil.. so I think its how spells are handled.
Same result through actions. It must be a difference between distro's. I'm testing on latest TFS.
 
Same result through actions. It must be a difference between distro's. I'm testing on latest TFS.

A quick check you were right im stoned, I forgot I had scrapped using Events and used recursion xD I swore I had been able to localize events but I guess not, always treats it as global like you said. Have to use that global table method.

CcS4vt5.png

I love recursion its op.

a few ways to do this with storage values, other types of localization and recursion

could always send over cid in a parameter with the onkick then add some kind of check

but

use apollos script tho, what OP asked for :)
 
Last edited:
You're right about it being outside the function but it's not really necessary to remove the local before it unless you plan on using a dofile and using it outside of this script. Also I'm not 100% sure but i'm worried that if you use this single int variable instead of an array you would have issues. For example, if you have a second player trigger the addEvent before the first one is activated or cancelled. Then the variable would be filled and you wouldn't be able to cancel the first event.

I would do the script like this, I also made some fixes to help it look cleaner. Untested tho so hopefully no errors.
Lua:
local kickOutEvent = {}

local function kickPlayerOut(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
    end
end


function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local cid = player.uid
    for key, spec in pairs(Game.getSpectators(DEMON_OAK_POSITION, false, false, 9, 9, 6, 6)) do
        if player:getStorageValue(Storage.DemonOak.Progress) < 1 or player:getStorageValue(Storage.DemonOak.Progress) == 2 then
            if spec:isPlayer() then
                return player:sendTextMessage(MESSAGE_STATUS_SMALL, "Someone is already in there!")
            end
        end
        if spec:isMonster() then
            spec:remove()
        end
    end

    if target.actionid == 50250 and target.itemid == 2709 then      
        if player:getStorageValue(Storage.DemonOak.Progress) < 1 then
            if player:getLevel(cid) >= 120 then
                if kickOutEvent[cid] then
                    stopEvent(kickOutEvent[cid])
                    kickOutEvent[cid] = nil
                end
                kickOutEvent[cid] = addEvent(kickPlayerOut, 4000, cid)
                player:teleportTo(DEMON_OAK_ENTER_POSITION)
                player:setStorageValue(Storage.DemonOak.Progress, 1)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'It seems that you have discovered an Ultimate Challenge.')
            else
                player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to advance to level 120 before going into this place.')
            end
        elseif player:getStorageValue(Storage.DemonOak.Progress) == 1 then
            if kickOutEvent[cid] then
                stopEvent(kickOutEvent[cid])
                kickOutEvent[cid] = nil
            end
            player:teleportTo(DEMON_OAK_KICK_POSITION)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You should discuss your findings with Oldrak.')
        end
    end
    return true
end
Im going to have to test this when I get back home.
 
This script does indeed work as intended, thanks for the help. But this is a local event when using this item only(?) I need to put this in two separate scripts and tried copy pasting but then I get this error:
Code:
table index is nil
stack traceback: 
[C]: in function '__newindex'
at this line
Lua:
kickOutEvent[cid] = addEvent(kickPlayerOut, 60000, cid)
And yet again, I cant figure out why. wtf

I'd think that when I added this:
Lua:
local kickOutEvent = {}

local function kickPlayerOut(cid)
    local player = Player(cid)
    if player then
        player:teleportTo(DEMON_OAK_KICK_POSITION)
        player:setStorageValue(Storage.DemonOak.Progress, 2)
        player:setStorageValue(cStorage, 0)
        player:setStorageValue(progress, 0)
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You took too long to finish the quest!')
    end
end
That it would define kickOutEvent as the registered event of kickPlayerOut and not return a nil value?

wadu heck
 
Back
Top