嗯,将所有数据存储在表中比调用函数来获取容器数据要好得多。
无论如何,这是一个脚本,它将获取所有背包 id,将它们存储在表中,然后使用每个 id 调用您的函数。
Backpack = {data = {}};
function Backpack:update(refresh)
if(#self.data==0 or refresh) then
for i = 0, Container.GetLast():Index() do
local cont = Container(i);
for j = 0,cont:ItemCount()-1 do
--table.insert(self.data,cont:GetItemData(j).id)
self.data[#self.data+1] = cont:GetItemData(j).id; -- faster than table.insert
end
end
end
end
function Backpack:refresh()
self:update(true)
end
function Backpack:find(func,...) -- func should return a value if id is good, otherwise false, add extra args to call with the function
if (not func) then
return false;
end
self:update(); -- Incase there is no inventory data;
for key,value in pairs(self.data) do
local value = func(value,...); -- calls the function with the id (as first parameter) of the 'cached' user inventory
if (value) then
return value
end
end
return false;
end
Example:
function GetToolIndex(id,return)
local shovel = {
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 , -- sneaky stabber of elitenesss(jammed)
[5710]= 1, -- light shovel
[3457] = 0 -- shovel
}
local rope = {
[646]= 1, -- elvenhair rope
[3003] = 0, -- rope
[9598] = 4 , -- whacking driller of fate
[9599]= 4 , -- whacking driller of fate(jammed)
[9596]= 3 , -- squeezing gear of girlpower
[9597]= 3 , -- squeezing gear of girlpower(jammed)
[9594]= 2 , -- sneaky stabber of elitenesss
[9595]= 2 -- sneaky stabber of elitenesss(jammed)
}
if return == 0 then
return shovel[id]
elseif return == 1 then
return rope[id]
end
end
function Test()
local shovel,rope = Backpack:find(GetToolIndex,0),Backpack:find(GetToolIndex,1)
if (shovel and rope) then
print("Shovel and rope exist");
end
end
Test();
EDIT:
经过思考一段时间后,您似乎尝试检查用户是否具有该特定 ID。
这是另一种方法,它将检查所有用户背包数据(深层表搜索),它将根据表键或表值进行搜索,它也适用于嵌套表,这应该对您有好处。
Backpack = {data = {}};
function Backpack:update(refresh)
if(#self.data==0 or refresh) then
for i = 0, Container.GetLast():Index() do
local cont = Container(i);
for j = 0,cont:ItemCount()-1 do
local data = cont:GetItemData(j); -- pretty sure this returns a table
self.data[data.id] = data; -- self.data[9598] = {...}
end
end
end
end
function Backpack:refresh()
self:update(true)
end
function Backpack:MultiTableSearch(input,value,case,index_check)
if (input and type(input) == 'table') then
if (type(value) == 'table' and value == input) then
return true;
end
for key,object in pairs(input) do
if (index_check) then
if (case and type(input)=='string' and type(key)=='string') then
if (value:lower() == key:lower()) then -- to avoid exit the loop
return true;
end
else
if (key == value) then
return true
elseif(type(object)=='table') then
return self:MultiTableSearch(object,value,case,index_check)
end
end
else
if (case and type(value)=='string' and type(object) == 'string') then
if (value:lower() == object:lower()) then
return true;
end
elseif(type(object)=='table') then
if (value == object) then
return true;
else
return self:MultiTableSearch(object,value,case)
end
else
if (object == value) then
return true;
end
end
end
end
end
return false;
end
function Backpack:exists(value,case,index_check)
self:update();
return self:MultiTableSearch(self.data,value,case,index_check)
end
-- checks the value 9598, case-insensitive is set to false,
-- index_checking is set to true (checks table index --> Backpack.data[9598], if it was set it'll return true);
if (Backpack:exists(9598,false,true)) then
print("User has whacking driller of fate");
end
if (Backpack:exists("Shovel of doom")) then -- will try to find any table-value that has the of "Shovel of doom" (case-sensitive)
print("User Shovel of doom");
end
如果您担心 MultiTableSearch 的性能(因为它看起来有点重),它相当快,运行了几次测试。
Function
function MultiTableSearch(input,value,case,index_check)
if (input and type(input) == 'table') then
if (type(value) == 'table' and value == input) then
return true;
end
for key,object in pairs(input) do
if (index_check) then
if (case and type(input)=='string' and type(key)=='string') then
if (value:lower() == key:lower()) then -- to avoid exit the loop
return true;
end
else
if (key == value) then
return true
elseif(type(object)=='table') then
return MultiTableSearch(object,value,case,index_check)
end
end
else
if (case and type(value)=='string' and type(object) == 'string') then
if (value:lower() == object:lower()) then
return true;
end
elseif(type(object)=='table') then
if (value == object) then
return true;
else
return MultiTableSearch(object,value,case)
end
else
if (object == value) then
return true;
end
end
end
end
end
return false;
end
测试(将值附加到表中并扫描嵌套表,这两个测试都是无意义的表大小)
local start_time = os.clock();
t = {}
for i=1,500000 do --500k table size
t[i]=i-1
end
print(os.clock()-start_time) -- 0.05 sec to create the table
local start_time = os.clock();
print(tostring(MultiTableSearch(t,500000,false)))-- will try to find a key with the value of 500,000
print(os.clock()-start_time) -- 0.197sec sec to scan the whole table
function nestedTable(object,times) -- creates nested table -> object={{{{..n times}}}}
if (times > 0 ) then
object[#object+1] = {times = times}
return (nestedTable(object[#object],times-1))
end
end
local start_time = os.clock();
t = {};
nestedTable(t,15000) --> will create table inside a table x 15000 times.
print(os.clock()-start_time) -- 0.007 sec to create the nested table
local start_time = os.clock();
print(tostring(MultiTableSearch(t,1,false)))-- will try to find a 1 (as a table value), the very last table value
print(os.clock()-start_time) -- 0.014 sec to find the value in the nested table