Checking against all of a table simultaneously (solved)
I'm trying to fix up 4zk's gas script and I've got everything set up nicely. The only problem is that I have to check an actor's (in MovableMan.Actor) ID against the ID of all the actors in the table of masked actors. for i = 1 , #self.Masked do doesn't work because it doesn't act as and. Essentially I'm hoping to get a method of doing if actor.ID ~= self.Masked[1].ID and actor.ID ~= self.Masked[2].ID ... then for #self.Masked. I've been trying for probably way too long and by brain is now frustrated and doing stupid things so I decided to give up and ask for help. I'm not sure how much sense all of this makes but here's the script to clarify things. All my failed or partially succesful attempts have been taken out so it's just the base of it. Just replace the gas grenade script with it if you want to test it.
Code:
function Create(self) self.GasTimer = Timer(); self.GasInterval = 100; end --PresetMan:ReloadAllScripts() function Update(self) if self.GasTimer:IsPastSimMS(self.GasInterval) then
self.Masked = {} local mask = {} local masked = {} for i = 1 , MovableMan:GetMOIDCount()-1 do mask[#mask + 1] = MovableMan:GetMOFromID(i); end for i = 1 , #mask do if string.find(mask[i].PresetName, "Mask") and mask[i].ClassName == "Attachable" then masked[i] = MovableMan:GetMOFromID(mask[i].RootID); if MovableMan:IsActor(masked[i]) and masked[i].ClassName == "AHuman" then self.Masked[#self.Masked + 1] = ToAHuman(masked[i]); end end end for actor in MovableMan.Actors do if not string.find(actor.PresetName,"Robot") and not string.find(actor.PresetName,"Brain") and not string.find(actor.PresetName,"Drone") and not string.find(actor.PresetName,"Turret") and not string.find(actor.PresetName,"Dummy") and not string.find(actor.PresetName,"Dreadnought") and actor.PresetName ~= "Blast Runner" and actor.ClassName ~= "ACDropShip" and actor.ClassName ~= "ACRocket" and actor.ClassName ~= "ADoor" then if SceneMan:ShortestDistance(self.Pos,actor.Pos,SceneMan.SceneWrapsX).Magnitude < 50 then for i = 1 , #self.Masked do if actor.ID ~= self.Masked[i].ID then if actor.Health > 0 then actor:FlashWhite(150); --actor.Health = actor.Health - (40 / actor.Mass + 0.1) / 2 end end --print (tostring(i).."/"..tostring(#self.Masked).." "..tostring(self.Masked[i])); end end end end self.GasTimer:Reset(); end end
Last edited by Bad Boy on Sun Jul 08, 2012 5:15 am, edited 1 time in total.
Re: Checking against all members in a table simultaneously
Bump, I know there are some very knowledgeable people here and I'd love help or at least someone letting me know if it can't be done. That said, I'm pretty sure it's doable but my brain just couldn't quite sort it out without hitting a road block of some sort and getting sidetracked.
Fri Jul 06, 2012 4:25 pm
Zuriki
Joined: Wed Feb 11, 2009 11:01 pm Posts: 28
Re: Checking against all members in a table simultaneously
I don't understand the first part "it doesn't act as and."?
Re: Checking against all members in a table simultaneously
If it did it'd work. What I mean by that is
Code:
for i = 1 , #self.Masked do if actor.ID ~= self.Masked[i].ID
is not the same as
Code:
if actor.ID ~= self.Masked[1].ID and actor.ID ~= self.Masked[2].ID and ... actor.ID ~= self.Masked[#self.Masked].ID
and the latter is what I want.
If there's some way to do this directly by iterating over all of them simultaneously then that'd be work. Otherwise some sort of logic which'd continue the series til it reaches #self.Masked would be fine too. I don't know of the former and I couldn't (and probably still can't) quite figure out how to do the latter.
Fri Jul 06, 2012 11:09 pm
CaveCricket48
Joined: Tue Jun 12, 2007 11:52 pm Posts: 13143 Location: Here
Re: Checking against all members in a table simultaneously
Like this?
Code:
local disIsCounter = 0; for i = 1, #self.datTable do if actor.ID ~= self.datTable[i].ID then disIsCounter = disIsCounter + 1; else break; end end if disIsCounter == #self.datTable then print("ACTION"); end
Sat Jul 07, 2012 5:18 am
Zuriki
Joined: Wed Feb 11, 2009 11:01 pm Posts: 28
Re: Checking against all members in a table simultaneously
No, he's saying for loops don't complete all their iterations instantaneously. Which I'm pretty sure they're supposed to, but I can't verify that...
All I could suggest is trying one of the other loops like while or repeat until, and see if you have better luck with one of those...
Re: Checking against all members in a table simultaneously
I'll try your script out Cave Cricket but I don't think it's what I want, unless I'm reading it wrong Zuriki, you're right on the money, I'm glad I didn't do too bad a job of explaining it And yeah, I thought it was supposed to act simultaneously too but that doesn't seem to be the case. I've tried a using while loop and manually increasing i with little success and though I've never used repeat loops I'm not sure if it'd help much either. I guess I'll have to keep trying.
Sun Jul 08, 2012 12:34 am
CaveCricket48
Joined: Tue Jun 12, 2007 11:52 pm Posts: 13143 Location: Here
Re: Checking against all members in a table simultaneously
If I read correctly, you want make sure that the actor's ID is not equal to any of the object IDs in the table, right?
Re: Checking against all members in a table simultaneously
Yep, and if it's not a member of that table make it lose health or whatever. Your script seems to be the same as what I put up except it serves a different purpose, i.e. increasing a count when it finds actors not in the table. However, like mine it doesn't work properly, because
Code:
for i = 1 , #self.table do if actor.ID ~= self.table[i].ID then
seems to act like
Code:
if actor.ID ~= self.table[1].ID or actor.ID ~= self.table[2].ID... or actor.ID ~= self.table[#self.table].ID then
Sort of edit, since I meant to post this earlier then edit it in: I just finished putting in your script and yeah, it doesn't seem to work, or maybe I'm trying to apply it incorrectly.
______________________________
Real edit, I figured it out, please allow me a moment to revel in my cleverness Because for i = 1 etc checks or instead of and, it allows you to see if something is a member of a table. Use that to return true in a function and you can check if it doesn't return true to find what's not in the table properly. Now I feel dumb for not thinking of it last time For anyone interested, here's the code:
Code:
function Create(self) self.GasTimer = Timer(); self.GasInterval = 100; end function Update(self) if self.GasTimer:IsPastSimMS(self.GasInterval) then
self.Masked = {} local mask = {} local masked = {} for i = 1 , MovableMan:GetMOIDCount()-1 do mask[#mask + 1] = MovableMan:GetMOFromID(i); end for i = 1 , #mask do if string.find(mask[i].PresetName, "Mask") and mask[i].ClassName == "Attachable" then --mask[i].ToDelete = true; --Uncomment to demask masked troops masked[i] = MovableMan:GetMOFromID(mask[i].RootID); if MovableMan:IsActor(masked[i]) and masked[i].ClassName == "AHuman" then self.Masked[#self.Masked + 1] = ToAHuman(masked[i]); end end end for actor in MovableMan.Actors do if not string.find(actor.PresetName,"Robot") and not string.find(actor.PresetName,"Brain") and not string.find(actor.PresetName,"Drone") and not string.find(actor.PresetName,"Turret") and not string.find(actor.PresetName,"Dummy") and not string.find(actor.PresetName,"Dreadnought") and actor.PresetName ~= "Blast Runner" and actor.ClassName ~= "ACDropShip" and actor.ClassName ~= "ACRocket" and actor.ClassName ~= "ADoor" then if SceneMan:ShortestDistance(self.Pos,actor.Pos,SceneMan.SceneWrapsX).Magnitude < 50 then if TableCheck(self , actor) ~= true then if actor.Health > 0 then --actor:FlashWhite(150); --Uncomment to make them turn white as well actor.Health = actor.Health - (40 / actor.Mass + 0.1) / 2 end end end end end self.GasTimer:Reset(); end end function TableCheck(self , actor) for i = 1 , #self.Masked do if actor.ID == self.Masked[i].ID then return true; end end end
Sun Jul 08, 2012 4:42 am
TheLastBanana
DRL Developer
Joined: Wed Dec 13, 2006 5:27 am Posts: 3138 Location: A little south and a lot west of Moscow
Re: Checking against all of a table simultaneously (solved)
The only time code ever executes simultaneously is in separate threads of execution, which aren't supported in CC and certainly don't occur in a standard for loop.
Re: Checking against all of a table simultaneously (solved)
After quickly doublechecking with google I have to say, fair enough, I'd be surprised if that was supported in CC's lua (since CC doesn't have multithread support at all if I'm not too confused) or occurred in a normal for loop. I made the mistake because I was used to using a for loop to figure out if something is in a table, which made me assume it happened simultaneously. Of course if I'd thought it through I would have realised it needs to not happen simultaneously for that to work.
Sun Jul 08, 2012 6:07 am
CaveCricket48
Joined: Tue Jun 12, 2007 11:52 pm Posts: 13143 Location: Here
Re: Checking against all of a table simultaneously (solved)
You missed the part where it checks the counter against the number of items in the table. If the actor's ID does not match any of the IDs in the table, the counter would be equal to the size of the table. If the actor ID DOES match one of the IDs in the table, the loop breaks and the counter is not equal to the size of the table.
That means that if the actor ID matches on in the table, counter < #table If the actor ID does not match any ID in the table, counter == #table
Anyways, glad you found your own solution.
Edit: Alternatively, and a more simple piece:
Code:
local matchNone = true; for i = 1, #self.datTable do if actor.ID == self.datTable[i].ID then matchNone = false; break; end end if matchNone then print("ACTION"); end
Re: Checking against all of a table simultaneously (solved)
Ah, I see now, that's clever and yep, I completely missed it.
The second way you posted is much the same as what I ended up doing, though more compact. I was planning on doing pretty much that but was worried about having mixups with the local variable because I was planning to define it outside of the for actor in MovableMan.Actors loop, i.e. I wasn't thinking clearly
Thanks for the help though, I'm sure it'll be useful to someone else somewhere down the line.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum