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

Lua [TFS 1.2] execute function while player online

Ovnyx

Member
Joined
Jul 25, 2017
Messages
163
Solutions
2
Reaction score
7
hi guys, i wanted to know if i can do a function that while player is online, is cheking for example
if he has a magic sword on the bp, and when it get the sword then the script will do something?
maybe can be possible creating a Thread to be executed in concurrence while player is on?

PD: off corse im not asking for someone to build the script, i just wanted to know if its or not possible, and maybe what functions i can use to bukld my idea.

i hope i make my self understand and thanks in advice!!!

Ovnyx.
 
Solution
you can't pass objects through addEvent since it's unsafe because they could be removed before the time of execution (more specifically creatures, tiles, items)
you have to pass the uid through and reconstruct the object
Lua:
function test(cid)
    local player = Player(cid)
    -- check if player still exists, player will return a userdata if the constructor was successful, nil if it wasn't
    if not player then
        return -- stop the rest of the function from executing
    end
    player:getPosition():sendMagicEffect(CONST_ME_HITBYFIRE)
    addEvent(test, 2000, cid)
end

function onSay(player, words, param)
    if param == "talk" then
        test(player:getId()
    end
    return true
end
it's hard to understand exactly what you want, could you try to clarify what you need?
specifically this line (i don't know what you're trying to say)
if he has a magic sword on the bp, and when it get the sword then the script will do something?
 
Lua:
--Once function is called. it will run every 60 seconds until player logout
function myFunction(cid)
    player = Player(cid)
    if player then
        --Add whatever you want it to do here
        addEvent(myFunction, 60000, cid)
    end
    return true
end
And in creaturescripts/login.lua add this line anywhere between onLogin() and end:
Lua:
myFunction(player.uid)

For example your function could look like this, making player get a message every 60 seconds if he has a magic sword in his inventory
Lua:
function myFunction(cid)
    player = Player(cid)
    if player then
        if player:getItemCount(2400) > 0 then
            player:sendTextMessage(22, "You have a magic sword!")
        end
        addEvent(myFunction, 60000, cid)
    end
    return true
end

Edit:
rename "myFunction" to whatever you want this function to be named,
and remember to change addEvent(myFunction~ as well.
 
hi thanks for your answers,

it's hard to understand exactly what you want, could you try to clarify what you need?
specifically this line (i don't know what you're trying to say)

ok ill try to explain my self.

I.E
i have this functions:
Code:
function checkMoney()
   if player:isPzLocked() == true then
         print("player locked!")

so what i want its to all time the player is online, this function will be executed, checking if the player is or not pz locked, so when that event occur the funciton will do his purpose.

its more clearly now?

thanks in advice!!

PD: @OpenTibiaServer maybe as you said "addEvent" is what im looking?
 
hi thanks for your answers,



ok ill try to explain my self.

I.E
i have this functions:
Code:
function checkMoney()
   if player:isPzLocked() == true then
         print("player locked!")

so what i want its to all time the player is online, this function will be executed, checking if the player is or not pz locked, so when that event occur the funciton will do his purpose.

its more clearly now?

thanks in advice!!

PD: @OpenTibiaServer maybe as you said "addEvent" is what im looking?

Addevent will execute the function after a given time, if you have addEvent inside the function as well, it will loop itself.
Just make sure you use it like I did in my function, throwing addEvent AFTER confirming the player is still online.

player = Player(cid)
if player is online, then "player" is true.
 
okay thank you very much :D
im going to test this until i fully understand how this works, this is really helpfull

one question please, if i put a "addEvent" in my function how much "time" should i add as parameter in that case?

edit: what is the creature:register/unregisterEvent purpose? is it the same as add event but for creatures that are not players?
 
Last edited:
creature events and events with addEvent are completely different
addEvent schedules a function to execute at a later time, the time is what you want.
we can't tell you what interval you want to check each player, that's for you to define.
addEvent(print, 1000, "hi") will run print("hi") after 1000 milliseconds (1 second).
creature:registerEvent(eventName) registers an event to the creature from creaturescripts
the event name should be the same in creaturescripts.xml, so if you had something like
XML:
<event type="death" name="some death" script="death script.lua"/>
you would register the event to a creature using creature:registerEvent("some death")
creaturescript events will not execute unless they are registered to a creature
here's more information on how to use addEvent
[How-to] Using addEvent()
 
o_Oo_Oo_O
wow thanks, both are what i was looking for!!, i will test them later

For example your function could look like this, making player get a message every 60 seconds if he has a magic sword in his inventory
Lua:
function myFunction(cid)
    player = Player(cid)
    if player then
        if player:getItemCount(2400) > 0 then
            player:sendTextMessage(22, "You have a magic sword!")
        end
        addEvent(myFunction, 60000, cid)
    end
    return true
end

Edit:
rename "myFunction" to whatever you want this function to be named,
and remember to change addEvent(myFunction~ as well.

@OpenTibiaServer
hi i m testing this and i get this error:


this the simple thing im using to test:
Code:
    elseif param == "talk" then
        print(player:getName())
        local position = player:getPosition()
        local function test(position)
            position:sendMagicEffect(CONST_ME_HITBYFIRE)
            addEvent(test,2000)
        end
        test(position)

first time it shows the magic eevent but passing the 2 seconds when it should do it again its when i got that error.

any idea whats happening? i tried giving the params while calling the method in the addevent but i got a stack overflow error.

EDIT: I tried creating the functions as local in login.lua an call there the function and it works but only 1 time it doesnt loop it self :/ tried adding player as third parameter to the addEvent but its the same


PD: Sorry for double post :/
 
Last edited by a moderator:
@OpenTibiaServer
hi i m testing this and i get this error:


this the simple thing im using to test:
Code:
    elseif param == "talk" then
        print(player:getName())
        local position = player:getPosition()
        local function test(position)
            position:sendMagicEffect(CONST_ME_HITBYFIRE)
            addEvent(test,2000)
        end
        test(position)

first time it shows the magic eevent but passing the 2 seconds when it should do it again its when i got that error.

any idea whats happening? i tried giving the params while calling the method in the addevent but i got a stack overflow error.

EDIT: I tried creating the functions as local in login.lua an call there the function and it works but only 1 time it doesnt loop it self :/ tried adding player as third parameter to the addEvent but its the same


PD: Sorry for double post :/
don't use function test() middle of another function.
move it out of the function it's in :)

Lua:
    elseif param == "talk" then
        print(player:getName())
        local position = player:getPosition()
        test(position)
    end
   
function test(position)
    position:sendMagicEffect(CONST_ME_HITBYFIRE)
    addEvent(test,2000, position)
end
 
thanks for your answer, all this is running in a talkaction function so i use diferent params to test diferent things by using the same talkaction, so i can define test functions out of the talkaction function or how is the correct way todo this or where should this "functions" be written to use them in addEvent?

what im trying is that when i run the talkaction !test talk, then it add to the player the event with "test" function (im doing this just to test and understand how to correct use this addEvent so i can use it on complex scripts)

thanks in advice

Onvyx.
 
Last edited:
thanks for your answer, all this is running in a talkaction function so i use diferent params to test diferent things by using the same talkaction, so i can define test functions out of the talkaction function or how is the correct way todo this or where should this "functions" be written to use them in addEvent?

what im trying is that when i run the talkaction !test talk, then it add to the player the event with "test" function (im doing this just to test and understand how to correct use this addEvent so i can use it on complex scripts)

thanks in advice

Onvyx.
no problems :)
For a function, you decide how many variables you need.
Lua:
function getPlayerStatus(variable1, variable2, variable3, variable4, variable5)
With addEvent, you can use as many variables as needed, like:
Lua:
addEvent(getPlayerStatus, 60000, variable1, variable2, variable3, variable4, variable5)

If you have a function like this without variables:
Lua:
function saveGame()
    return doSaveGame()
end
You could use addEvent like this:
Lua:
addEvent(saveGame, 60000, 0)

With that you'll pass a static '0' as a variable and wont need anything else :)
 
no problems :)
For a function, you decide how many variables you need.
Lua:
function getPlayerStatus(variable1, variable2, variable3, variable4, variable5)
With addEvent, you can use as many variables as needed, like:
Lua:
addEvent(getPlayerStatus, 60000, variable1, variable2, variable3, variable4, variable5)

If you have a function like this without variables:
Lua:
function saveGame()
    return doSaveGame()
end
You could use addEvent like this:
Lua:
addEvent(saveGame, 60000, 0)

With that you'll pass a static '0' as a variable and wont need anything else :)


hi thanks for this information, im sorry if im too annoying with a lot of question, but i like to learn new things and practice them, i only got another queston:

this is the function im using to test the add event:
Code:
function test(player)
    local position = player:getPosition()
    position:sendMagicEffect(CONST_ME_HITBYFIRE)
    if player then
        addEvent(test,2000,player)
    end
end


function onSay(player, words, param)
    if param == "talk" then
        print(player:getName())
        test(player)

what i want to know if is that test functions declared outside the Onsay, its properly positioned, because i put in in login .lua this function, and it works just 1 time, the second time it throws a error saying that the third argument its unsafe, i supose its the player argument, so this is what is confusing me a lot, maybe parameteres cant be a userdata only numeric or string values?

EDIT: yeah as i spected a player should not be sended as parameter, i used position as parameter, then i get player position and send that as parameter and i make this work, ill continue doing tests, but i guess the topic can be closed.

thanks for all your answers guys! they are really helpfull, bless
 
Last edited:
you can't pass objects through addEvent since it's unsafe because they could be removed before the time of execution (more specifically creatures, tiles, items)
you have to pass the uid through and reconstruct the object
Lua:
function test(cid)
    local player = Player(cid)
    -- check if player still exists, player will return a userdata if the constructor was successful, nil if it wasn't
    if not player then
        return -- stop the rest of the function from executing
    end
    player:getPosition():sendMagicEffect(CONST_ME_HITBYFIRE)
    addEvent(test, 2000, cid)
end

function onSay(player, words, param)
    if param == "talk" then
        test(player:getId()
    end
    return true
end
 
Solution
you can't pass objects through addEvent since it's unsafe because they could be removed before the time of execution (more specifically creatures, tiles, items)
you have to pass the uid through and reconstruct the object
Lua:
function test(cid)
    local player = Player(cid)
    -- check if player still exists, player will return a userdata if the constructor was successful, nil if it wasn't
    if not player then
        return -- stop the rest of the function from executing
    end
    player:getPosition():sendMagicEffect(CONST_ME_HITBYFIRE)
    addEvent(test, 2000, cid)
end

function onSay(player, words, param)
    if param == "talk" then
        test(player:getId()
    end
    return true
end

wow, i didnt think about using player id to reconstruct the object, thats an excelent idea, gonna use it, thanks a lot man!
 
hey sorry about double post but i find something interesting, i do things as you said @Static_, and they work perfectly, now the question is that i tried the same with a player summon, and it works too, so i can add events to creatures as if they were players? or its beter (more efficient) to do it by the creature:registerEvent(), because maybe this could cause lag or freezes if the script its to heavy

sorry for keep doing a lot of questions!
 
Back
Top