• 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 TFS 0.3.6 pass all array variables as a one param through doRemoveItem TFS function.

waqmaz

Member
Joined
Jun 17, 2015
Messages
203
Reaction score
11
Hello. I've been coding since a few days in lua. I've wrote simple functions:
Code:
local itemsID = {
    [1] = { 2471, 2130},
    -- [2] = { 5456, 777, 1148},
}

local quantity = {
    [1] = { 1, 2},
    -- [2] = { 100, 50, 2},
}

local function getItem(nr)
    for i = 1, #itemsID[nr] do
        return itemsID[nr][i]
    end
end

local function getQuantity(nr)
    for i = 1, #quantity[nr] do
        return quantity[nr][i]
    end
end

local function removeThat(get_items, get_quantity, cid)

    if (getPlayerItemCount(cid, get_items) >= get_quantity) then
        doPlayerRemoveItem(cid, get_items, get_quantity)
    end

    return true
end


function onUse(cid, item, fromPosition, itemEx, toPosition)

    if item.uid == 4767 then
        removeThat(getItem(1), getQuantity(1), cid)
    end

    return true
end

What I want to get is to remove all variables from itemsID array where [1] and their quantity from quantity array where [1], using doPlayerRemoveItem(cid, itemid, count[, subtype]) function from TFS 0.3.6.
So player should have removed 1 * item 2471 and 2 * item 2130.
Something like this:
Code:
doPlayerRemoveItem(cid, {2471, 2130}, {1,2})
Can someone help me? Maybe I should do it another way? Thanks.
 
Last edited:
you cant use return in loops, when it hits the return it will stop executing that function and return to where it was called, so it will only ever return the stuff where i = 1

if i got you right, you want to make a table with several items / different amounts of each item, and remove all of them with the associated quantity?
 
hello.
yes, I "want to make a table with several items / different amounts of each item, and remove all of them with the associated quantity".
Ofcourse, it can be done like this:
Code:
local itemsID = {
[1] = { item = 2471, amount = 10},
[2] = { item = 2130, amount = 5},
}

please, help me loop through item and amount and put it inside doPlayerRemoveItem(cid, item, amount) or something like that. I can't get it. ;/

can be done like this or something:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)

    if item.uid == 4767 then

        doPlayerRemoveItem(cid, item[i], amount[i])

    end
   
    return true
end
 
Last edited:
Code:
local t1 = {
    [4767] = {2471, 1, 2130, 2}
}
local t2 = {
    [4767] = {{id = 2471, n = 1}, {id = 2130, n = 2}}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local tmp = t[item.uid]
    if tmp then
        for i=1,#tmp,1 do    -- t2 table
            doRemoveItem(cid, tmp[i].id, tmp[i].n)
        end
        for i=1,#tmp,2 do    -- t1 table
            doRemoveItem(cid, tmp[i], tmp[i+1])
        end
    return true
end
i did 2 examples of tables, the for loops are named to which one they use, but this is an easy way to do this
however to remove items and if player has the items and then give something youd have to check if it can be removed also etc
 
just a few hints
you don't need the
Code:
[1] = or [2] =
if you insert a table without an index, it'll by ordered by numeric index starting at 1
for your solution you can do this a few ways.
1)
Code:
for key, value in ipairs(itemsID) do
doPlayerRemoveItem(cid, value.item, value.amount)
end
2)
Code:
for i = 1, #itemsID do
doPlayerRemoveItem(cid, itemsID[i].item, itemsID[i].amount)
end
 
Code:
i did 2 examples of tables, the for loops are named to which one they use, but this is an easy way to do this
Men, You are a genius! That's exactly, what I wanted! Thanks! I learn much from Your posts everyday! Thanks again! Big Thanks! A few changes and it works perfectly!:)
 
Code:
local t1 = {
    [4767] = {2471, 1, 2130, 2}
}
local t2 = {
    [4767] = {{id = 2471, n = 1}, {id = 2130, n = 2}}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
    local tmp = t[item.uid]
    if tmp then
        for i=1,#tmp,1 do    -- t2 table
            doRemoveItem(cid, tmp[i].id, tmp[i].n)
        end
        for i=1,#tmp,2 do    -- t1 table
            doRemoveItem(cid, tmp[i], tmp[i+1])
        end
    return true
end
i did 2 examples of tables, the for loops are named to which one they use, but this is an easy way to do this
however to remove items and if player has the items and then give something youd have to check if it can be removed also etc

Following your code I wrote what I wanted yesterday and it works very well.
I can easy get an index of an arrau, using function onUse by putting item.uid like:
Code:
local t = {
    [4767] = {},
    [4768] = {},
    [4769] = {}
}

function onUse(cid, item, fromPosition, itemEx, toPosition)
-- t[item.uid] THIS IS WHAT I NEEDED :)
return true
end
Now I try to get a target as an array index, using the same way, but i doesn't work. I've tried the following ways:
Code:
local t =  {
    ['Orc'] = {},
    ['Troll'] = {}
}

function onKill(cid, target)

    -- these 3 "if" tries doesn't work. on the right you see what it returns in console
    if getCreatureName(t[target]) then -- CREATURE NOT FOUND
    if getCreatureName(target) == getCreatureName(t[target]) then -- CREATURE NOT FOUND
    if getCreatureName(target) == t[target] then -- NOTHING
        print('works')
    end
      
    -- these 3 "if" tries doesn't work too. on the right you see what it returns in console  
    for i = 1, #t[target], 1 do
        if getCreatureName(t[target][i]) then -- GIVES ETERNAL LOOP
        if getCreatureName(target) == getCreatureName(t[target][i]) -- NOTHING
        if getCreatureName(target) == t[target][i] then  -- GIVES ETERNAL LOOP
            print('works')
        end
    end  

    return true
end

How can I print a name of the monster as an index of the array like it was in function onUse (item.uid). Here I want the name (target). I have no idea, sitting around 3th hour at this...
 
Code:
for k,v in pairs(t) do
if getCreatureName(target) == k then
print('works')
end
Oh, thanks. But I formed wrong my qustion. If you could help me, I would be glad forever...
I have an array:
Code:
local t =  {
    ['Orc'] = {
        {pos = {x = 950,  y = 1063,  z = 7},  id = 1037},
        {pos = {x = 951,  y = 1063,  z = 7},  id = 1037}
    },
    ['Troll'] = {
        {pos = {x = 953,  y = 1070,  z = 7},  id = 5154},
        {pos = {x = 953,  y = 1071,  z = 7},  id = 1036},
        {pos = {x = 953,  y = 1072,  z = 7},  id = 5154}
    }
}

When Troll or Orc is killed then console says who of them was killed. What I want now is to say positions (pos) of each monsters.
I've just tried this way, but doesn't work:
Code:
function onKill(cid, target)

    for k,v in pairs(t) do
        if getCreatureName(target) == k then
    
            print(k) -- says Orc or Troll / works
    
            for i = 1, #t[k].pos, 1 do
                print(t[k][i].pos)
            end
    
        end
    end

    return true
end

I am not really sure, I know what I am doing. Loops are hard to understand. In a function ouUse, I got pos like this
Code:
t[item.uid][i].pos
So how to get pos of each monster the same way?
 
Last edited:
EDIT:
Code:
local t =  {
    ['Orc'] = {
        {pos = {x = 950,  y = 1063,  z = 7},  id = 1037},
        {pos = {x = 951,  y = 1063,  z = 7},  id = 1037}
    },
    ['Troll'] = {
        {pos = {x = 953,  y = 1070,  z = 7},  id = 5154},
        {pos = {x = 953,  y = 1071,  z = 7},  id = 1036},
        {pos = {x = 953,  y = 1072,  z = 7},  id = 5154}
    }
}

function onKill(cid, target)
    for k,v in pairs(t) do
        if getCreatureName(target) == k then
            for i = 1, #t, 1 do
            print("Name: ".. k)
            print("Position: ".. v[i].pos) 
        end
    end
end
return true
end
 
Last edited:
dont use pairs with a table like that in onkill, just do
Code:
 local tmp = t[getCreatureName(target)]
if tmp then
bla bla
@waqmaz target in onKill is a CID, so you have to get the name, for example if you kill a troll getCreatureName(target) will return 'troll', and you have a table in t at the position of 'troll', so t['troll'] or just directly t[getCreatureName(target)] will find it
are you trying to print the position of the killed monster?
 
dont use pairs with a table like that in onkill, just do
Code:
 local tmp = t[getCreatureName(target)]
if tmp then
bla bla
@waqmaz target in onKill is a CID, so you have to get the name, for example if you kill a troll getCreatureName(target) will return 'troll', and you have a table in t at the position of 'troll', so t['troll'] or just directly t[getCreatureName(target)] will find it
are you trying to print the position of the killed monster?

Code:
local t =  {
    ['Orc'] = {
        {pos = {x = 950,  y = 1063,  z = 7},  id = 1037},
        {pos = {x = 951,  y = 1063,  z = 7},  id = 1037}
    },
    ['Troll'] = {
        {pos = {x = 953,  y = 1070,  z = 7},  id = 5154},
        {pos = {x = 953,  y = 1071,  z = 7},  id = 1036},
        {pos = {x = 953,  y = 1072,  z = 7},  id = 5154}
    }
}

function onKill(cid, target)
    local tmp = t[getCreatureName(target)]
    if tmp then
        for i = 1, #t, 1 do
        print("Name: ".. k)
        print("Position: ".. v[i].pos) 
    end
end
return true
end
Something like this?
 
yeah, but if you want to use name also id to
local name = getCreatureName(target)
local tmp = t[name]
then you can replace ..k with ..name :)
 
Should be what you're looking for @waqmaz
Code:
local t =  {
    ['Orc'] = {
        {pos = {x = 950,  y = 1063,  z = 7},  id = 1037},
        {pos = {x = 951,  y = 1063,  z = 7},  id = 1037}
    },
    ['Troll'] = {
        {pos = {x = 953,  y = 1070,  z = 7},  id = 5154},
        {pos = {x = 953,  y = 1071,  z = 7},  id = 1036},
        {pos = {x = 953,  y = 1072,  z = 7},  id = 5154}
    }
}

function onKill(cid, target)
    local name = getCreatureName(target)
    local tmp = t[name]
    if tmp then
        for i = 1, #t, 1 do
        print("Name: ".. name)
        print("Position: ".. v[i].pos) 
    end
end
return true
end
 
Code:
print("Position: ".. v[i].pos)
What should be instead of "v"? I ask, because these doesnt work:
Code:
        for i = 1, #t, 1 do
            print(t[i].pos)
        end

        for i = 1, #t, 1 do
            print(tmp[i].pos)
        end

        for i = 1, #t, 1 do
            print(name[i].pos)
        end

Thanks, guys. You help me a lot, but it doesn't work. Everyday I am more skilled, because of you.
/EDIT
I 'm seeing you've just edited your post. Gonna check it.
 
Last edited:
for i=1,#tmp,1 do
print(tmp.pos)
end
you're trying to do a for loop for the size of #t, but t is the array with 'orc' and 'troll', and a table like
table = {
['troll'] = x,
['orc'] = y
}
will return 0 doing #table
the # operator for tables works in such a way that it tries to go through the table like table[1], table[2] etc, always adding 1, and when table[n] is nil, it will end and return how many positions it has found, so for example
table = {[1] = true, [2] = true}
table2 = {[1] = true, [3] = true}
for table it will test table[1], works, table[2], works, table[3] doesnt work, so it returns 2 since it found 2 valid positions
for table2 it will try table[1], works, table[2], doesnt work so it returns 1, even though table[3] exist, it will never get around to checking that, since if it doesnt cancel when it find a position in the table that is nil, it will loop forever
however, you can write your own function that works for all kinds of table like
Code:
local tableSize(t)
local n = 0
for pos, _ in pairs(t) do
n = n+1
end
return n
end
and it will return the full size of the table
 
EDIT:
Code:
local t =  {
    ['Orc'] = {
        {pos = {x = 950,  y = 1063,  z = 7},  id = 1037},
        {pos = {x = 951,  y = 1063,  z = 7},  id = 1037}
    },
    ['Troll'] = {
        {pos = {x = 953,  y = 1070,  z = 7},  id = 5154},
        {pos = {x = 953,  y = 1071,  z = 7},  id = 1036},
        {pos = {x = 953,  y = 1072,  z = 7},  id = 5154}
    }
}

function onKill(cid, target)
    for k,v in pairs(t) do
        if getCreatureName(target) == k then
            for i = 1, #t, 1 do
            print("Name: ".. k)
            print("Position: ".. v[i].pos)
        end
    end
end
return true
end

Thanks for trying, but your script does not work. I really lose my mind at it.
 
for i=1,#tmp,1 do
print(tmp.pos)
end
you're trying to do a for loop for the size of #t, but t is the array with 'orc' and 'troll', and a table like
table = {
['troll'] = x,
['orc'] = y
}
will return 0 doing #table
the # operator for tables works in such a way that it tries to go through the table like table[1], table[2] etc, always adding 1, and when table[n] is nil, it will end and return how many positions it has found, so for example
table = {[1] = true, [2] = true}
table2 = {[1] = true, [3] = true}
for table it will test table[1], works, table[2], works, table[3] doesnt work, so it returns 2 since it found 2 valid positions
for table2 it will try table[1], works, table[2], doesnt work so it returns 1, even though table[3] exist, it will never get around to checking that, since if it doesnt cancel when it find a position in the table that is nil, it will loop forever
however, you can write your own function that works for all kinds of table like
Code:
local tableSize(t)
local n = 0
for pos, _ in pairs(t) do
n = n+1
end
return n
end
and it will return the full size of the table
Thank you for that worthfull text. According to what you have said, I've done an example:
Code:
function onKill(cid, target)

    if t[getCreatureName(target)] then
        for i = 1, #t[getCreatureName(target)] do
            print(t[getCreatureName(target)][i].pos)
        end
    end
   
    return true
end
The problem of that, it doesn't work. I really do not know why. It should return all "pos" of targeted target ("i").
 
Back
Top