• 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] Using addEvent()

Evan

A splendid one to behold
Senator
Premium User
Joined
May 6, 2009
Messages
7,019
Solutions
1
Reaction score
1,029
Location
United States
I'm gonna get straight to the point and make this very simple. I had a thread already written up before this one, but I got too complex, if you want to get into the more complex stuff, feel free to post here, we can talk about it. Making this tutorial complex to understand is not my goal.

BDgDKxL.gif


So, what is addEvent()?
It is a method that calls a function or evaluates an expression after a specified number of milliseconds.
In layman's terms, it runs code after X milliseconds.

Quick reminders:
  • 1000 milliseconds = 1 second
  • It is only executed once
  • stopEvent() will prevent the function to run
Functions and Parameters:
  • addEvent(callback, milliseconds, ...)
    • callback - REQUIRED
      • The function that will be executed
    • milliseconds - REQUIRED
      • The time in milliseconds to wait before executing the function
    • ... - OPTIONAL
      • Additional parameters to pass into the callback function

  • stopEvent(eventid)
    • eventid - REQUIRED
      • The eventid of the addEvent you're planning to end

All you need to remember is that addEvent() simply sets a wait time to the callback function before it executes.
So, whatever the function is in callback parameter, it will execute that after whatever the wait time is in the milliseconds parameter.
If the function in the callback parameter has any parameters itself, it needs to be included as additional parameters (...) in addEvent().

To put in pictures;
sK227hh.png


Learning by Example
Lua:
function sendHelloMessage(playerid)
    local player = Player(playerid)
    if not player then
        return false
    end
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Hello")
    return true
end

function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    addEvent(sendHelloMessage, 3000, cid)
    return true
end

sp8LMOI.png


Can you guess what this script does?
It sends a blue-colored "Hello" message to the player's console, 3 seconds after using an object.

EzYRM6S.png

Remember, callback is the function that will be executed at the end of the wait time.
Additional parameters (...) are only required if the callback function requires parameters.

Another example with a walk-through...

18cF7Uw.gif


Okay, so based on what you know so far, how can you accomplish this one?
Take a note on what is going on:
  1. A pillar is blocking the path to the next room
  2. I pull lever to the right, pillar disappears (with magic effect)
  3. 3 seconds later, pillar comes back (with magic effect) and lever moves back to the left
  4. If the lever is to the right and you use it, nothing happens
Here's what we'll do, since we're "using" something (lever), it has to be an onUse action script.
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)

    return true
end

Next, we want to make the lever go to the right and disappear the pillar (with poff magic effect).
If we go back to the notes, a left lever (1945) and a right lever (1946) do two different things,
so we want to make sure we check for the lever before doing their respective jobs.

Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946) 
    elseif item.itemid == 1946 then
        return false
    end
    return true
end
You should now have something like this

4LdmfOH.gif


What's the last and most important thing we need left? The pillar to come back 3 seconds later.
When I pull the lever, the pillar disappears. From the moment it disappears, I want to start the 3 second wait time right away, so it must be within the block where it disappears the pillar.
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946)

        addEvent(callback, milliseconds, ...) -- RIGHT HERE
 
    elseif item.itemid == 1946 then
        return false
    end
    return true
end

Now we need to make the addEvent() do what we want it to do.
If you look at the notes under #3, we said the wall comes back (with magic effect) and lever is moved to the left

In this case, instead of making a separate function for the server to "save", we can just use lambda/anonymous functions in the callback parameter. Don't worry, it's super easy; in my second post, you can read more about it.

Constructing the addEvent() (step-by-step)
Focusing on the addEvent(), we should have this:
Lua:
addEvent(function()
      --
   end, 3000)

Inside this function(), we want the pillar to reappear (magic effect POFF too) and the lever to move back to the left.
In order to tell the function which position to create the pillar and send the POFF magic effect, we have to pass it into the function through a parameter.
Lua:
addEvent(function(pillarPos)
      --    
   end, 3000, pilarTile:getPosition())

We also need to 'get' the lever object in order to flip it back to the left.
Again, in order to tell the function which lever to 'get', we need to pass it as a parameter.
Lua:
addEvent(function(pillarPos, lever)
      --    
   end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))

Now function() has all the information it needs, let's make it do what it needs to do!
Lua:
addEvent(function(pillarPos, lever)
      Game.createItem(1515, 1, pillarPos)      -- Create pillar
      pillarPos:sendMagicEffect(CONST_ME_POFF) -- Send POFF effect
      lever:transform(1945)                    -- Flip lever to the left
   end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))

TADA! With all this code
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946)

        addEvent(function(pillarPos, lever)
            Game.createItem(1515, 1, pillarPos)      -- Create pillar
            pillarPos:sendMagicEffect(CONST_ME_POFF) -- Send POFF effect
            lever:transform(1945)                    -- Flip lever to the left
        end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))
  
    elseif item.itemid == 1946 then
        return false
    end
    return true
end
We have this!
18cF7Uw.gif





PLEASE! If you have any questions, comments, concerns, please post here!
 
Last edited by a moderator:
stopEvent()
As mentioned before, stopEvent(eventid) basically prevents an addEvent() from happening.
It takes one parameter (required) too, eventid.

What is eventid?
It's the id of the addEvent() you plan to cease.

When you call addEvent(), it returns an id value to help identify different events.

So, how can we stop an event? Simply set the addEvent() to an identifier (variable).
Don't worry, the addEvent() will still run
Lua:
local event = addEvent(callback, milliseconds, ...)
Then you can use that variable to end that specific addEvent().
Lua:
stopEvent(event)

Lambda/Anonymous Functions
function() end is called a lambda function (or called anonymous function). They are not bound to any identifier.
They are often used as an argument that requires a function (callback parameter in our case).
So, pretty much, it is a function that doesn't have a name.

Kac85Hf.png


Though, if you create your own function (like in the first part of the picture above), the server will already have it saved.
In certain situations, creating your own outside function can be more efficient than using lambda/anonymous functions.
 
Last edited by a moderator:
Rainbow Outfit
Some of you have requested the rainbow outfit, here it is. It was merely for display.

BDgDKxL.gif

Lua:
function rainbowOutfit(cid, looktype, index)
    local colors = {94, 77, 79, 82, 87, 90}
    local creature = Creature(cid)
    if not creature then
        return
    end
    creature:setOutfit({
        lookType = looktype,
        lookHead = colors[((index) % 6) + 1],
        lookBody = colors[((index + 1) % 6) + 1],
        lookLegs = colors[((index + 2) % 6) + 1],
        lookFeet = colors[((index + 3) % 6) + 1]
    })
    if index > 6 then
        index = 0
    end
    addEvent(rainbowOutfit, 100, creature:getId(), looktype, index + 1)
end

A good way to stop the rainbow outfit is to set the eventid to the character as a storage value, then use that storage value to end it when necessary.
 
Last edited by a moderator:
Good tutorial, but I've got some suggestions.

You should change this:
Code:
function sendHelloMessage(playerid)
To this:
Code:
local function sendHelloMessage(playerid)
Defining global functions if you don't need them in other scripts is just bad and should be avoided. :)

You also forgot to mention about one very important thing - that userdata values should never be passed to addEvent, cause it might crash the server.
 
Code:
function rainbowOutfit(cid, looktype, index)
    local colors = {94, 77, 79, 82, 87, 90}
    local creature = Creature(cid)
    if not creature then
        return
    end
    creature:setOutfit({
        lookType = looktype,
        lookHead = colors[((index) % 6) + 1],
        lookBody = colors[((index + 1) % 6) + 1],
        lookLegs = colors[((index + 2) % 6) + 1],
        lookFeet = colors[((index + 3) % 6) + 1]
    })
    if index > 6 then
        index = 0
    end
    addEvent(rainbowOutfit, 100, creature:getId(), looktype, index + 1)
end

A good way to stop the rainbow outfit is to set the eventid to the character as a storage value, then use that storage value to end it when necessary.
Fine example of recursion :)
 
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
local pillarTile = Tile(X, Y, Z)

if item.itemid == 1945 then
pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
pillarTile:getItemById(1515):remove()
Item(item.uid):transform(1946)

addEvent(function(pillarPos, lever)
Game.createItem(1515, 1, pillarPos) -- Create pillar
pillarPos:sendMagicEffect(CONST_ME_POFF) -- Send POFF effect
lever:transform(1945) -- Flip lever to the left
end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))

elseif item.itemid == 1946 then
return false
end
return true
end

wow, helps me a lot! TY~~!!!
 
Last edited:
I'm gonna get straight to the point and make this very simple. I had a thread already written up before this one, but I got too complex, if you want to get into the more complex stuff, feel free to post here, we can talk about it. Making this tutorial complex to understand is not my goal.

BDgDKxL.gif


So, what is addEvent()?
It is a method that calls a function or evaluates an expression after a specified number of milliseconds.
In layman's terms, it runs code after X milliseconds.

Quick reminders:
  • 1000 milliseconds = 1 second
  • It is only executed once
  • stopEvent() will prevent the function to run
Functions and Parameters:
  • addEvent(callback, milliseconds, ...)
    • callback - REQUIRED
      • The function that will be executed
    • milliseconds - REQUIRED
      • The time in milliseconds to wait before executing the function
    • ... - OPTIONAL
      • Additional parameters to pass into the callback function

  • stopEvent(eventid)
    • eventid - REQUIRED
      • The eventid of the addEvent you're planning to end

All you need to remember is that addEvent() simply sets a wait time to the callback function before it executes.
So, whatever the function is in callback parameter, it will execute that after whatever the wait time is in the milliseconds parameter.
If the function in the callback parameter has any parameters itself, it needs to be included as additional parameters (...) in addEvent().

To put in pictures;
sK227hh.png


Learning by Example
Code:
function sendHelloMessage(playerid)
    local player = Player(playerid)
    if not player then
        return false
    end
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Hello")
    return true
end

function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    addEvent(sendHelloMessage, 3000, cid)
    return true
end

sp8LMOI.png


Can you guess what this script does?
It sends a blue-colored "Hello" message to the player's console, 3 seconds after using an object.

EzYRM6S.png

Remember, callback is the function that will be executed at the end of the wait time.
Additional parameters (...) are only required if the callback function requires parameters.

Another example with a walk-through...

18cF7Uw.gif


Okay, so based on what you know so far, how can you accomplish this one?

Take a note on what is going on:
  1. A pillar is blocking the path to the next room
  2. I pull lever to the right, pillar disappears (with magic effect)
  3. 3 seconds later, pillar comes back (with magic effect) and lever moves back to the left
  4. If the lever is to the right and you use it, nothing happens
Here's what we'll do, since we're "using" something (lever), it has to be an onUse action script.
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)

    return true
end

Next, we want to make the lever go to the right and disappear the pillar (with poff magic effect).
If we go back to the notes, a left lever (1945) and a right lever (1946) do two different things,
so we want to make sure we check for the lever before doing their respective jobs.

Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946) 
    elseif item.itemid == 1946 then
        return false
    end
    return true
end
You should now have something like this

4LdmfOH.gif


What's the last and most important thing we need left? The pillar to come back 3 seconds later.
When I pull the lever, the pillar disappears. From the moment it disappears, I want to start the 3 second wait time right away, so it must be within the block where it disappears the pillar.
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946)

        addEvent(callback, milliseconds, ...) -- RIGHT HERE
 
    elseif item.itemid == 1946 then
        return false
    end
    return true
end

Now we need to make the addEvent() do what we want it to do.
If you look at the notes under #3, we said the wall comes back (with magic effect) and lever is moved to the left

In this case, instead of making a separate function for the server to "save", we can just use lambda/anonymous functions in the callback parameter. Don't worry, it's super easy; in my second post, you can read more about it.

Constructing the addEvent() (step-by-step)
Focusing on the addEvent(), we should have this:
Code:
addEvent(function()
      --
   end, 3000)

Inside this function(), we want the pillar to reappear (magic effect POFF too) and the lever to move back to the left.
In order to tell the function which position to create the pillar and send the POFF magic effect, we have to pass it into the function through a parameter.
Code:
addEvent(function(pillarPos)
      --    
   end, 3000, pilarTile:getPosition())

We also need to 'get' the lever object in order to flip it back to the left.
Again, in order to tell the function which lever to 'get', we need to pass it as a parameter.
Code:
addEvent(function(pillarPos, lever)
      --   
   end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))

Now function() has all the information it needs, let's make it do what it needs to do!
Code:
addEvent(function(pillarPos, lever)
      Game.createItem(1515, 1, pillarPos)      -- Create pillar
      pillarPos:sendMagicEffect(CONST_ME_POFF) -- Send POFF effect
      lever:transform(1945)                    -- Flip lever to the left
   end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))

TADA! With all this code
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition, isHotkey)
    local pillarTile = Tile(X, Y, Z)

    if item.itemid == 1945 then
        pillarTile:getPosition():sendMagicEffect(CONST_ME_POFF)
        pillarTile:getItemById(1515):remove()
        Item(item.uid):transform(1946)

        addEvent(function(pillarPos, lever)
            Game.createItem(1515, 1, pillarPos)      -- Create pillar
            pillarPos:sendMagicEffect(CONST_ME_POFF) -- Send POFF effect
            lever:transform(1945)                    -- Flip lever to the left
        end, 3000, pillarTile:getPosition(), Tile(toPosition):getItemById(1946))
 
    elseif item.itemid == 1946 then
        return false
    end
    return true
end
We have this!
18cF7Uw.gif





PLEASE! If you have any questions, comments, concerns, please post here!


Hey mate, I have a problem because I want to remove a wall and I want it to get back again, I tried using your script but doesnt work cuz you are using pillar I think :/ I dont know how to it with a wall I have tried alot, using otx 3.7 tibia client 10.98.
 
Hey mate, I have a problem because I want to remove a wall and I want it to get back again, I tried using your script but doesnt work cuz you are using pillar I think :/ I dont know how to it with a wall I have tried alot, using otx 3.7 tibia client 10.98.
make a support thread and show your script
 
Hello mate, can u help me please?
I have a tile that give a player an addEvent(FunctionName,VariableTime,cid)
I created another tile that remove that addEvent. But isn't working, can u help me with that?
Remove a existent addEvent in other script can be done? If yes, how?
 
hi
im trying out for first time to work with addevent at all so I need some quick help.
addEvent(function(effect) Game.sendAnimatedText('Test', player:getPosition(), 210) end, 1*1000)

how do I make this execute every sec untill stopEvent have been used?
 
hi
im trying out for first time to work with addevent at all so I need some quick help.
addEvent(function(effect) Game.sendAnimatedText('Test', player:getPosition(), 210) end, 1*1000)

how do I make this execute every sec untill stopEvent have been used?
Lua:
function delayedAnimatedText(cid)
    local player = Player(cid)
    if player then
        Game.sendAnimatedText('Test', player:getPosition(), 210)
        addEvent(delayedAnimatedText, 1 * 1000, cid)
    end
end

eventId = addEvent(delayedAnimatedText, 1 * 1000, player:getId())

stopEvent(eventId)
 
Back
Top