So I've used:
map:get_entities_in_rectangle(x, y, width, height)
which gave me back a nice entity iterator.
The problem is, I only want some of those entities. For example, I might want only entities where:
entity:get_type() == "custom_entity" and entity:get_model() == "trash"
I know how to loop through it and build a new array, but I'd like to learn how to create a new entity iterator. Is it possible to do this without dumping the contents of the first iterator into an array first? I'm new to Lua and trying to figure this out. :)
Thanks!
The best way to do that is exactly the way you are doing it:
for entity in map:get_entities_in_rectangle(x, y, width, height) do
if entity:get_type() == "custom_entity" and entity:get_model() == "trash" then
-- blablabla cats meow meow!
end
end
Always put the stronger condition in the outer built-in iterator, because that one is optimized. (For instance, getting first the custom entities and later the "rectangle overlapping" condition would be slightly slower). In this case you cannot do it with only 1 loop (you need to filter with "if" conditions).
What I'm trying to do is actually return a new entity iterator. For context, I'm making an item similar to the gust jar in Minish Cap. I'm wanting item:get_suckable_entities() to return an entity iterator containing items of a certain type in a certain region so I can loop over it.
I just managed to finish writing this code:
-- Get suckable entities
function item:get_suckable_entities()
local map = self:get_map()
-- Get entities in suckable rectangle
local entities = map:get_entities_in_rectangle(self:get_suckable_rectangle())
-- Filter only suckable types
filtered = {}
for entity in entities do
for model in item:get_suckable_models() do
if entity:get_type() == "custom_entity" and entity:get_model() == model then
table.insert(filtered, entity)
end
end
end
function filtered_entities()
local i = 0
local n = table.getn(filtered)
return function()
i = i + 1
if i <= n then return filtered[i] end
end
end
return filtered_entities()
end
It totally works, but I was hoping there would be a way to achieve this without dumping everything into a filtered table first and then creating a new iterator out of that table.
Thanks for your reply. :)
EDIT: My full code is now here for context https://gitlab.com/voadi/voadi/blob/master/data/items/vacuum.lua
This library seems to do what I want, but it doesn't look possible in normal Lua: https://github.com/starwing/luaiter
It has a fitlerout(func, iter) function.
We are planning to do this in Solarus 1.7: https://gitlab.com/solarus-games/solarus/issues/843