Page 1 of 1
[help]How to destroy a table of entities?
Posted: Fri Nov 16, 2012 9:07 pm
by flatline
I've been using this for a spell I'm working on, Arrow protection.
In short, it should detect arrows in front of the player and destroy them. Right now, I'm using a script provided by Lark here:
viewtopic.php?f=14&t=3985
arrows = findAll(party.level, party.x, party.y, {"arrow"}, "any", false, false, true)
My quetion is:
It should return a table of entities and I want to destroy any entities it returns. What is the right way to do that?
just putting :destroy() at the end, or arrows:destroy() won't work.
Re: [help]How to destroy a table of entities?
Posted: Fri Nov 16, 2012 9:20 pm
by Komag
maybe something like
Code: Select all
for i=1,#arrows, do
arrows[i]:destroy
end
but I'm not sure
Re: [help]How to destroy a table of entities?
Posted: Sat Nov 17, 2012 1:12 am
by Lark
Yes, I it looks like that should work. Here's code that I used to destroy all items found in a square that's similar - you'd want to change "
:getWeight" to "
arrow" as indeed you've already done:
Code: Select all
local found = findAll(self.level, self.x, self.y, {":getWeight"})
for _, item in ipairs(found) do
item:destroy()
end
This code assigns the variable "
item" to each entity in the table, one at a time, and then destroys it.
Kromag's code iterates an index, "
i", over the table and references the entity by its index by using "
arrows" and knows how many items are in the table by using the # operator.
Both methods are equivalent except if you have a table with nulls which findAll won't return, so either will work. FYI the # operator will only count non-null entries so for a table like {1, 2, , , 5}, # will return 3 and the code will fail. Iterating over the table using ipairs is safer.
Cheers, -Lark
Re: [help]How to destroy a table of entities?
Posted: Sat Nov 17, 2012 3:04 am
by flatline
Here's my current script. A timer runs this approximately 3 times per second as long as the spell is up.
It won't delete any items though and I have no idea why. It is supposed to react to any entity containing the word "arrow" and delete it, but neither mid-air arrows from skeletons nor arrows lying on the ground are deleted. I really appreciate all the help so far. I'm learning a lot here, and it seems arrow deflection isn't far off (the spell will have deflection and effects added once the core principle of detecting oncoming arrows and deleting them works).
Code: Select all
function arrowshield()
local arrows = findAll(party.level, party.x, party.y, {"arrow"}, "any", true, false, true)
-- Larks solution
for _, item in ipairs(arrows) do
item:destroy()
end
--komags solution
--for i=1,#arrows do
--arrows[i]:destroy()
--end
--prints text to let you know it is running
hudPrint("one loop")
end
---Larks findAll function below this line, nothing changed from here on
function findAll(level, x, y, keys, all, surrounding, facing, facingUs)
local answers, r, dx, dy, entity, match, _ = {}, 0
all = all == "all"
local any = not all
if surrounding then r = 1 end
if facing then
dx, dy = getForward(self.facing)
x, y = x + dx, y + dy
end
if keys == nil then keys = {"*"} end
for i = x - r, x + r do
for j = y - r, y + r do
if 0 < i and i < 33 and 0 < j and j < 33 then
for entity in entitiesAt(level, i, j) do
match = true
for _, value in ipairs(keys) do
if value == "*" then pass = true
elseif string.sub(value, 1, 1) == ":" then pass = entity[(string.sub(value, 2))] ~= nil
else pass = string.find(entity.name, value) ~= nil end
if all then match = pass and match
else match = pass end
if (match and any) or ((not match) and all) then break end
end
if match then
dx, dy = getForward(entity.facing)
if (not facingUs) or (facingUs and entity.x + dx == self.x and entity.y + dy == self.y) or (self.x == entity.x and self.y == entity.y) then
answers[# answers + 1] = entity
end
end
end
end
end
end
return answers
end
Re: [help]How to destroy a table of entities?
Posted: Sat Nov 17, 2012 3:44 am
by Grimwold
Just curious if it would be easier to use the party hook onProjectileHit() which has as it's second variable the projectile that hit the party.
Something like this:
Code: Select all
onProjectileHit = function(champion,projectile)
if arrow_shield_script.arrowShieldActive() and projectile.name == "arrow" then
return false
end
end,
So we test if the spell is active and if the projectile name is "arrow" and if both conditions are met, we return false so the champion takes no damage from the arrow (you would need to modify the check if you want to protect against other types of arrow as well e.g. frost_arrow )
Re: [help]How to destroy a table of entities?
Posted: Sat Nov 17, 2012 6:36 pm
by flatline
Grimwold wrote:Just curious if it would be easier to use the party hook onProjectileHit() which has as it's second variable the projectile that hit the party.
Something like this:
Code: Select all
onProjectileHit = function(champion,projectile)
if arrow_shield_script.arrowShieldActive() and projectile.name == "arrow" then
return false
end
end,
So we test if the spell is active and if the projectile name is "arrow" and if both conditions are met, we return false so the champion takes no damage from the arrow (you would need to modify the check if you want to protect against other types of arrow as well e.g. frost_arrow )
Definitely easier. I started off with my version as an experiment to see if I could detect and destroy arrows mid-flight. It could make for some neat other spells, I thought. Still haven't figured out if the arrow can be stopped mid-flight.