• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

Lua Soul ring

_M4G0_

Intermediate OT User
Joined
Feb 6, 2016
Messages
550
Solutions
17
Reaction score
108
LUA:
local function addSoul(player)
local soulring = player:getSlotItem(CONST_SLOT_RING)
if item == soulring then
player:addSoul(player:getSoul() + 2)
end
end

function onEquip(player, item, slot)
addEvent(addSoul, 1000, player)
end


function onDeEquip(player, item, slot)
stopEvent(addSoul)
end
anyone can help in this script ?
there is basically if the player use the ring add 2 soul points
tfs 1.2
 
Last edited:
Solution
odd, seems like addEvent doesnt like local tables
works, tested
LUA:
runningSoulEvents = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    runningSoulEvents[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    local slotItem = player:getSlotItem(slot)
    if slotItem and slotItem == item then
        doAddSoul(player:getId())
    end
    return true
end

function onDeEquip(player, item, slot)
    stopEvent(runningSoulEvents[player:getId()])
    runningSoulEvents[player:getId()] = nil
    return true
end
I don't use 1.2..
But eff it.
Try this (guessing on the onDeEquip function..)
Also, I've been told passing the player data around is unsafe...
But I use it like this on my 0.3.7 server.
So who knows. xD
LUA:
local soul_ring = {}

local function addSoul(player, n)
   if not player:isPlayer then
       return true
   end
   if soul_ring[player] == n then
       player:addSoul(player:getSoul() + 2)
       soul_ring[player] = soul_ring[player] + 1
       addEvent(addSoul, 1000, player, n + 1)
   end
end

function onEquip(player, item, slot)
   soul_ring[player] = 1
   addEvent(addSoul, 1000, player, 1)
   return true
end

function onDeEquip(player, item, slot)
   soul_ring[player] = 0
   return true
end
 
You want so it adds every 1 second 2 sould poults? Or only once?

This line is wrong:
Code:
player:addSoul(player:getSoul() + 2)
You probably mean just:
Code:
player:addSoul(2)

Also here:
Code:
if item == soulring then
As item, you probably mean item id? You need to declare it. Like
Code:
local item = 2160
(just example)

Also, you have twice onEquip event, the second you meant probably is onDeEquip.

If you want to stopEvent, then you need to use event id. The id is returned when you use addEvent.

So, you basically do like this. Declare at top array for storing event ids.
Code:
local events = {}

Then, in onEquip, you do:
Code:
events[cid] = addEvent(addSoul, 1000, player)

And in onDeEquip:
Code:
if(events[cid] ~= nil) then
    stopEvent(events[cid])
end
 
I don't use 1.2..
But eff it.
Try this (guessing on the onDeEquip function..)
Also, I've been told passing the player data around is unsafe...
But I use it like this on my 0.3.7 server.
So who knows. xD
LUA:
local soul_ring = {}

local function addSoul(player, n)
   if not player:isPlayer then
       return true
   end
   if soul_ring[player] == n then
       player:addSoul(player:getSoul() + 2)
       soul_ring[player] = soul_ring[player] + 1
       addEvent(addSoul, 1000, player, n + 1)
   end
end

function onEquip(player, item, slot)
   soul_ring[player] = 1
   addEvent(addSoul, 1000, player, 1)
   return true
end

function onDeEquip(player, item, slot)
   soul_ring[player] = 0
   return true
end
you don't need to check if a player is a player, nothing but a player can trigger equip/deequip functions

You want so it adds every 1 second 2 sould poults? Or only once?

This line is wrong:
Code:
player:addSoul(player:getSoul() + 2)
You probably mean just:
Code:
player:addSoul(2)

Also here:
Code:
if item == soulring then
As item, you probably mean item id? You need to declare it. Like
Code:
local item = 2160
(just example)

Also, you have twice onEquip event, the second you meant probably is onDeEquip.

If you want to stopEvent, then you need to use event id. The id is returned when you use addEvent.

So, you basically do like this. Declare at top array for storing event ids.
Code:
local events = {}

Then, in onEquip, you do:
Code:
events[cid] = addEvent(addSoul, 1000, player)

And in onDeEquip:
Code:
if(events[cid] ~= nil) then
    stopEvent(events[cid])
end
passing userdata through addevent is unsafe, use cid

LUA:
local events = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    events[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    if player:getStorageValue(88857) == -1 then
        doAddSoul(player:getId())
        player:setStorageValue(88857, 1)
    end
    return true
end

function onDeEquip(player, item, slot)
    stopEvent(events[player:getId()])
    events[player:getId()] = nil
    player:setStorageValue(88857, -1)
    return true
end
 
Last edited:
you don't need to check if a player is a player, nothing but a player can trigger equip/deequip functions


passing userdata through addevent is unsafe, use cid

LUA:
local events = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    events[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    if player:getSlotItem(slot) == item then
        doAddSoul(player:getId())
    end
    return true
end


function onDeEquip(player, item, slot)
    stopEvent(events[player:getId()])
    return true
end
it's work but not stop after deequip
 
you don't need to check if a player is a player, nothing but a player can trigger equip/deequip functions


passing userdata through addevent is unsafe, use cid

LUA:
local events = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    events[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    if player:getStorageValue(88857) == -1 then
        doAddSoul(player:getId())
        player:setStorageValue(88857, 1)
    end
    return true
end

function onDeEquip(player, item, slot)
    stopEvent(events[player:getId()])
    events[player:getId()] = nil
    player:setStorageValue(88857, -1)
    return true
end
I'll just assume 1.0+ is stupid forever. :cool:

And what is this line even doing?
Code:
if not player then
What does that even accomplish.
Is cid not the creature id?
Creature id = random string of numbers
Code:
if not random_string_of_numbers then

Anyways, I'll just stop posting in 1.x+ threads.
 
you 100% sure?
i'm using the same format i used for someone else's script, did the same thing but mana instead of soul
try de equipping it, relog, and try again
after full soul
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory
yes im sure, its stop after relog but dont stop on de equip
 
Last edited:
What does that even accomplish.
Is cid not the creature id?
Creature id = random string of numbers
because Creature are a lua metatable, if you want the old 'cid' thing then you need to call creature:getId(), Creature() are just a callable table (aka metable) with functions, what that line is doing is just checking if the table Player(id) exists, because tfs alaways assign NIL for errors, otherwise push a meta table with Player and Creature functions.
i think you shouldn't stop posting on 1.x topics, use that to expand your lua capacities abilities, i don't mean use tfs 1.x, but try creating yourself some meta tables, search for that, it's a great tool from lua, im sure you can use that in your project =)
 
because Creature are a lua metatable, if you want the old 'cid' thing then you need to call creature:getId(), Creature() are just a callable table (aka metable) with functions, what that line is doing is just checking if the table Player(id) exists, because tfs alaways assign NIL for errors, otherwise push a meta table with Player and Creature functions.
i think you shouldn't stop posting on 1.x topics, use that to expand your lua capacities abilities, i don't mean use tfs 1.x, but try creating yourself some meta tables, search for that, it's a great tool from lua, im sure you can use that in your project =)
Yeah, I've learned by trial and error over the years.
I'll probably be a 0.3.7 noob forever, that can't explain shit to anyone. :D
But yeah, I'll just ignore 1.x+ threads forever. :rolleyes:
 
after full soul
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory

Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
not enough memory
yes im sure, its stop after relog but dont stop on de equip
how do you have it set in movements.xml?
you are using a script for onDeEquip right? and not function in the xml?
restart your server, one of the events might have kept going
 
how do you have it set in movements.xml?
you are using a script for onDeEquip right? and not function in the xml?
restart your server, one of the events might have kept going
LUA:
    <movevent event="DeEquip" itemid="24324" slot="ring" script="new/soulring.lua" />
    <movevent event="Equip" itemid="24324" slot="ring" level="200" script="new/soulring.lua" />
 
odd, seems like addEvent doesnt like local tables
works, tested
LUA:
runningSoulEvents = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    runningSoulEvents[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    local slotItem = player:getSlotItem(slot)
    if slotItem and slotItem == item then
        doAddSoul(player:getId())
    end
    return true
end

function onDeEquip(player, item, slot)
    stopEvent(runningSoulEvents[player:getId()])
    runningSoulEvents[player:getId()] = nil
    return true
end
 
Solution
odd, seems like addEvent doesnt like local tables
works, tested
LUA:
runningSoulEvents = {}

local soulAmount = 2

local function doAddSoul(cid)
    local player = Player(cid)
    if not player then
        return
    end
    player:addSoul(soulAmount)
    runningSoulEvents[cid] = addEvent(doAddSoul, 1000, cid)
end

function onEquip(player, item, slot)
    -- only execute it once since the bug still exists where equip triggers twice
    local slotItem = player:getSlotItem(slot)
    if slotItem and slotItem == item then
        doAddSoul(player:getId())
    end
    return true
end

function onDeEquip(player, item, slot)
    stopEvent(runningSoulEvents[player:getId()])
    runningSoulEvents[player:getId()] = nil
    return true
end
thanks for the script
 
Back
Top