I’m planning to do something similar with overrun attacks in a game (overruns being where a hex has units of both sides). Haven’t done it yet, but think I have a plan that might work for you too.
My theory is:
A. Each unit has a Dynamic Property called “dAccountedFor” that is set to ‘1’ with trigger “trAccount” or ‘0’ with “trAcountClear”
B. Each unit also has a Global Key Command that sends hotkey “trAccount” to all units within 0 range (in theory this should mean all pieces in the same stack). Trigger using “trAccountStack”. Might need to tweak a bit (I’m not sure if stacked pieces have the same X and Y, or if they’re offset by the same amount as the stack offset).
C. Each unit has a Set Global Property triggered by “trIncrement” that increments “gCount” by 1. May optionally add trigger to set to ‘0’ on “trAccountClear”.
D. Finally each unit has a Trigger Action called by “trCountStacks”, with conditions “dAccountedFor==0 && dFired==1” (last condition is whatever indicates that the hex or unit in hex has fired and the stack should be counted). Calls “trAccountStack” and then “trIncrement”.
When you want to count stacks that have fired (or some other property):
Reset “dAccountedFor” by sending “trAccountClear” to everything (via either Global Key Command or some other method). This will change status to 0, and each piece will reset global counter to ‘0’ (simple but slightly overkill…you could just add this to command to a single At-Start Unit instead).
Send “trCountStacks” to all pieces (again the method is up to you). Once the command hits the first fired unit in a stack, it’ll increment the global counter and set other counters in the stack so that they won’t respond to the count command when it eventually gets around to them. Sort of like when asked, the first piece yells “I’m hear” and every other piece says “Sorry, I’m already accounted for”.
The two commands above could be combined by a dummy piece Trigger Action or a Multi-Action Button.
For efficiency, you can set the trCountStacks trigger to only send to units that have fired. Won’t change the results, but pieces that haven’t fired won’t have to bother running the commands.
Of course you can set names and triggers to whatever makes sense for you. Make sure your Global Key Command and the AccountedFor trigger don’t try to use the same name (i.e. the GKC in the example is “trAccountStack”, not “trAccount”). If you screw that up (or forget to send the “trAccount” command), you’ll have a nice infinite loop where every piece keeps calling it’s friends, which call their friends (including the first piece), etc. Program’ll detect it and let you know something’s up (it’s actually very friendly that way).
If you try it, let me know how it works.
After a bit more thought (while writing this…though I left the previous since it’s a bit more thorough), you might be able to simplify things by throwing the condition into the GKCs and using a common trigger name.
dAccountedFor set to 1 with trAccount
Set Global Property incremented with trAccount
Global Key Command called by trAccount with condition “dAccountedFor==0&&dFired==1” (and still range = 0)
Reset values, then call outside Global Key Command to send trAccount to units with “dAccountedFor==0&&dFired==1”.
I’m pretty sure it checks each piece as it comes to it rather than checking all pieces, making a list, and only then running commands on each piece in the list. In theory, even though every piece starts with dAccountedFor==0, by the time it gets around to them they may have changed (and won’t fire).
This way it won’t even bother asking pieces that have already been accounted for (or haven’t fired). Saves quite a few traits and trigger checks (and might reduce running time) but easier to screw up.