我试图找到一种更聪明的方法来解决这个问题。
这是与游戏相关的代码的摘录,它循环通过每个背包的每个插槽,直到它找到一把铲子和一根绳子
local continue
local foundShovel, foundRope
for i = 0, Container.GetLast():Index() do -- looping trough backpacks
local cont = Container(i)
for j = 0, cont:ItemCount()-1 do -- looping trough each slot
local id = cont:GetItemData(j).id -- Getting ID of that slot
foundShovel, foundRope = GetToolIndex(id,0) or foundShovel,GetToolIndex(id,1) or foundRope -- confusing...
if foundShovel and foundRope then
continue = true
break
end
end
if continue then
-- do something i need to do
end
end
end
-- Switches ID to corresponding index :
function GetToolIndex(id,retrn)
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 retrn == 0 then
return shovel[id]
elseif return == 1 then
retrn rope[id]
end
end
但它不起作用,我认为这种方法必须有更好的方法,如果我需要在一个表中找到X值而不是仅仅2?我希望我的问题可以在这里理解。
答案 0 :(得分:3)
好吧,将所有数据存储在表中要好得多,而不是调用函数来获取容器数据。
无论如何这里有一个脚本可以获取所有背包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
示例:
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();
修改强>
经过一段时间的考虑,您似乎试图检查用户是否具有该特定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 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