• 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 Help with "Basic" .Lua (movements) Scripting

Jaki Maoh

Member
Joined
Sep 13, 2017
Messages
52
Reaction score
11
Hello Community!
I can't figure out what is wrong with the script. 😵‍💫
Lua:
local resp_stone = 5000
local aid_small = 50001
    
    local function addbacksmall()
    -- local stoner = doCreateItem(1294, 1, position) -- commented because does not work here
    local stoner = Game.createItem(1294, 1, position)
        stoner:setActionId(aid_small)
    end
    

    
    function onRemoveItem(item, tile, position)
    if item.actionid == aid_small then
        position:sendMagicEffect(1) -- just to check if the script is responding
        -- item:removeAttribute(ACTIONID) -- trying to remove the aID after the  item is moved (failing miserably)
        -- addEvent(function() doCreateItem(1294, 1, position) end, 5000) -- in one line i could make it respawn, but not attribute the action ID
        addEvent(addbacksmall, resp_stone) -- trying to make a local function to add the aID when respawning the small stone to the map.

    end
    return true
end
The idea is to add back (to the original tile) a small stone after x time with addEvent function.
The problems:
1 when the item is created, it spawns without the aID needed to activate the onRemoveItem function.
2 when the player moves the original item from tile, it holds the aID as an attribute and creates a new stone whenever it is moved (infinite times).

XML:
<movevent event="RemoveItem" actionid="50001" script="small_stones.lua" />
    <!-- <movevent event="RemoveItem" itemid="1294" script="small_stones.lua" /> -->

How should I approach this, any ideas?🤔

Thanks in advance,
Jaki
 
Solution
(Bump) Made some modifications, but did not manage to get the expected result.

I've tried to make a check using some functions
getItemById
getTileItemById
getThingfromPos
, "if", and "if not", but kept getting this errors
attempt to call method 'X' (a nil value)
attempt to index local 'X' (a nil value)
attempt to index global 'X' (a nil value)
attempt to index a nil value
attempt to call field 'X' (a nil value)

Here is the xml
XML:
<movevent event="RemoveItem" tileitem="1" actionid="50001" script="small_stones.lua"/>
    <!-- <movevent event="RemoveItem" actionid="50001" script="small_stones.lua"/> -->

Here is the .lua
Lua:
function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294...
Hmmm.. I'll make some changes and come back to the thread then, ;)
Thanks @Xikini!!!
You can't give special attributes to stackable items, or you get all sorts of issues.

The only solution is to use a non-stackable item or make the tile have the actionid for the trigger, instead of the small stone.
 
(Bump) Made some modifications, but did not manage to get the expected result.

I've tried to make a check using some functions
getItemById
getTileItemById
getThingfromPos
, "if", and "if not", but kept getting this errors
attempt to call method 'X' (a nil value)
attempt to index local 'X' (a nil value)
attempt to index global 'X' (a nil value)
attempt to index a nil value
attempt to call field 'X' (a nil value)

Here is the xml
XML:
<movevent event="RemoveItem" tileitem="1" actionid="50001" script="small_stones.lua"/>
    <!-- <movevent event="RemoveItem" actionid="50001" script="small_stones.lua"/> -->

Here is the .lua
Lua:
function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        position:sendMagicEffect(1)
        -- addEvent(addsmallstone, 2000) -- local function (better way?) did not manage to make it work at all
        -- if not tile:getTileItemById(1294) then 
        addEvent(function() doCreateItem(1294, 1, position) end, 3000) -- only way i've managed to make it work
        -- else
        -- position:sendMagicEffect(2)
        -- end   
    end
    return true
end

Any ideas?

(1) Ideal situation: the script ignores if player adds the stone to tile, in attempt to make it spawn multiple times
(2) More feasable situation, maybe: the scripts always checks if already stone (id1294) is on tile before addEvent takes place.
Thanks again,
Jaki
 
(Bump) Made some modifications, but did not manage to get the expected result.

I've tried to make a check using some functions
getItemById
getTileItemById
getThingfromPos
, "if", and "if not", but kept getting this errors
attempt to call method 'X' (a nil value)
attempt to index local 'X' (a nil value)
attempt to index global 'X' (a nil value)
attempt to index a nil value
attempt to call field 'X' (a nil value)

Here is the xml
XML:
<movevent event="RemoveItem" tileitem="1" actionid="50001" script="small_stones.lua"/>
    <!-- <movevent event="RemoveItem" actionid="50001" script="small_stones.lua"/> -->

Here is the .lua
Lua:
function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        position:sendMagicEffect(1)
        -- addEvent(addsmallstone, 2000) -- local function (better way?) did not manage to make it work at all
        -- if not tile:getTileItemById(1294) then
        addEvent(function() doCreateItem(1294, 1, position) end, 3000) -- only way i've managed to make it work
        -- else
        -- position:sendMagicEffect(2)
        -- end 
    end
    return true
end

Any ideas?

(1) Ideal situation: the script ignores if player adds the stone to tile, in attempt to make it spawn multiple times
(2) More feasable situation, maybe: the scripts always checks if already stone (id1294) is on tile before addEvent takes place.
Thanks again,
Jaki
Good effort.

Here would be my solution.
XML:
<movevent event="RemoveItem" tileitem="1" actionid="45001" script="small_stones.lua"/>
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    if #players > 0 then
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
        return
    end
   
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
 
Solution
Good effort.

Here would be my solution.
XML:
<movevent event="RemoveItem" tileitem="1" actionid="45001" script="small_stones.lua"/>
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    if #players > 0 then
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
        return
    end
  
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
Did not test it yet, later I'll come back and edit this comment.
Thanks for all the time you put into it, the result looks like will be impressive and the outcome, even better that expected!
Thanks again,
Jaki
 
Well hopefully it works as you want xD

If it doesn't, let me know.
Thank you for waiting, I tested the script, and worked flawlessly, but, I had one last request. Is it possible to make it so the scripts ignores players from the staff? I've tried to add one line and got this error:
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/movements/scripts/small_stones.lua:7: attempt to compare nil with number
stack traceback:
        [C]: in function '__lt'
        data/movements/scripts/small_stones.lua:7: in function <data/movements/scripts/small_stones.lua:3>

Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #players > 0 then
            if Player:getAccountType() < ACCOUNT_TYPE_GOD then    -- modification 01
                addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
                return
            end
        end    -- modification 01
      
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
 
Thank you for waiting, I tested the script, and worked flawlessly, but, I had one last request. Is it possible to make it so the scripts ignores players from the staff? I've tried to add one line and got this error:
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/movements/scripts/small_stones.lua:7: attempt to compare nil with number
stack traceback:
        [C]: in function '__lt'
        data/movements/scripts/small_stones.lua:7: in function <data/movements/scripts/small_stones.lua:3>

Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
        if #players > 0 then
            if Player:getAccountType() < ACCOUNT_TYPE_GOD then    -- modification 01
                addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
                return
            end
        end    -- modification 01
     
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
Try this
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby 
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    for v, k in pairs(players) do
        local player = Player(v)
        if player and not player:getGroup():getAccess() then
            players = 1
            break
        end
    end
    if players > 0 then
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
        return
    end
    
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
 
Try this
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    for v, k in pairs(players) do
        local player = Player(v)
        if player and not player:getGroup():getAccess() then
            players = 1
            break
        end
    end
    if players > 0 then
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
        return
    end
   
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/movements/scripts/small_stones.lua:13: attempt to compare number with table
stack traceback:
        [C]: in function '__lt'
        data/movements/scripts/small_stones.lua:13: in function <data/movements/scripts/small_stones.lua:3>
got this on the log
😕
 
Code:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/movements/scripts/small_stones.lua:13: attempt to compare number with table
stack traceback:
        [C]: in function '__lt'
        data/movements/scripts/small_stones.lua:13: in function <data/movements/scripts/small_stones.lua:3>
got this on the log
😕
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby 
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    for v, k in pairs(players) do
        local player = Player(v)
        if player and not player:getGroup():getAccess() then
            addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
            return
        end
    end
    
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
 
Lua:
local small_stones = {}

local function spawnItemWhenNoPlayersNearby(position, itemId, amount)
    -- check if a player is nearby
    local players = Game.getSpectators(position, false, true, 7, 7, 5, 5)
    for v, k in pairs(players) do
        local player = Player(v)
        if player and not player:getGroup():getAccess() then
            addEvent(spawnItemWhenNoPlayersNearby, 5000, position, itemId, amount)
            return
        end
    end
   
    -- if no player nearby, create item and remove from table so a new addEvent can be triggered
    Game.createItem(itemId, amount, position)
    for i = 1, #small_stones do
        if small_stones[i] then
            if position == small_stones[i][1] then
                small_stones[i] = nil
                return
            end
        end
    end
end

function onRemoveItem(moveitem, tile, position, cid)
    if moveitem.itemid == 1294 then
        -- loop through and check if this tile has a running addEvent
        for i = 1, #small_stones do
            if small_stones[i] then
                if position == small_stones[i][1] then
                    return true
                end
            end
        end
        -- if no addEvent running, add position to table, and start addEvent
        small_stones[#small_stones + 1] = {position}
        addEvent(spawnItemWhenNoPlayersNearby, 5000, position, 1294, 1)
    end
    return true
end
It works, but at this moment it ignores if player is at sight and respawn the stone.
(tested player by himself and in the presence of a god)
 
It works, but at this moment it ignores if player is at sight and respawn the stone.
(tested player by himself and in the presence of a god)
change
Lua:
local player = Player(v)
to
Lua:
local player = Player(k)
 
change
Lua:
local player = Player(v)
to
Lua:
local player = Player(k)
Woah, it works like a charm now, it really did bring a smile to this one's face 👏👏👏
Thanks for all the help @Xikini !!!
On a ending tone, do you perhaps have some useful links and tutorials here from Otland that you recommend for the humans that want to get better at scripting?
Thanks again!
Jaki
 
Woah, it works like a charm now, it really did bring a smile to this one's face 👏👏👏
Thanks for all the help @Xikini !!!
On a ending tone, do you perhaps have some useful links and tutorials here from Otland that you recommend for the humans that want to get better at scripting?
Thanks again!
Jaki

 
Back
Top