Currently working on a top down wargame. Your dudes and dudettes are represent by Active objects called Units and Mobs - the Mobs being the individual figures within the overall Unit. So one specific Unit, when referenced, encompasses both the Unit Active, and each Mob Active that is part of that Unit collective. Following along? Here's a visual; https://twitter.com/4burner/status/879337293256867840
These Mobs have stats, and occasionally special rules. Also, the Unit itself has a list of stats and special rules independent of the Mobs, and will also inherit stats and special rules from the Mobs within it. A quick example of this inheritance is how far a Unit can move on any given turn - This is worked out by iterating through the Move stats of the Mobs within the Unit, and selecting the (s)lowest, representing a Unit being only able to move cohesively at the speed of the slowest member of the group.
Similar to this, the Special Rules will often be Inherited by the Unit. Because individual Mobs don't take action - the Unit does - this means that if you wanted to cast an ability that a Mob has, you select the Unit, and the relevant casting option will appear. For example - The Orderguard Battalion Commander has an ability called Rally. Whilst the specific Mob representing the Commander is alive, the Unit can cast Rally in the relevant phase. If the Commander is removed as a casualty, the Unit can no longer cast the ability, and it won't appear when the Unit is selected.
Since the Specials list is modular, I have devised a way to iterate through and refresh the list of Specials any given Unit has at any time. That part is relatively straight-forward.
Here's where it gets tricky. The Specials themselves are contained within a large (and expanding) index, with each Special having a corresponding ID#. Also, this index, and therefore the Specials themselves are divided into 3 categories; Cast, Self, and Effect. Cast is an ability you cast ala Rally above. Self is a Passive ability that triggers automatically. Effect is the -result- of a casting, generally speaking. For example;
Telemetry (ID#199) is a CAST. This Unit, as an action, can cast Telemetry on an Enemy Unit. (Will give the target Unit Special ID#201 Telemetry (2) - See below)
Telemetry Link (ID#200) is a SELF. Units with this Self gain +1 to Hit Enemy Units marked with Telemetry.
Telemetry (2) (ID#201) is an EFFECT. It does nothing to the Unit directly, but grants a bonus to Units with the above Self when they target this Unit.
Now - I have all this data collated into an Array. The X index is a reference to each Unit (IE Unit#3's Specials are written to Array X=3), the Y index is the Specials Index itself (So if there's a value in Y=200, that tells me the Unit has the Self "Telemetry Link"), and the Z index is simply player 1 and 2.
When it comes to actually programming the game, I don't want the values referenced from the Array, but from the Actives. This is so the flow remains consistent throughout the Engine - The Array is for hard data and doesn't get changed or referenced directly - for the most part - everything is done with the Alt Vals of the Active Objects. So I've got Alt Vals 100-399 of the Units reserved for the Specials. The Engine reads through the Specials Array, and writes the Values to the Unit Alt Vals. 101-199 is for Casting Options, 201-299 is for the Self specials, and 301-399 for Effects. 100,200, and 300 are value holders that tell me how many Special values are actually written for any given Unit. So if a Unit had 3 Effects on it currently, Alt Val 300 will read 3. This is done for a number of reasons, most importantly so that when it comes time to bring up a Unit's info in the display, I can construct the loops in such a way that I know that Casting options are always in 101-199, etc etc.
And so we come to the actual question! When iterating through the Specials array, and putting the values into the relevant AltVal sections, you may have noticed that they are not in order. So it's not like Effects are Index190-240, there are entries from all 3 categories scattered throughout the Index. Which means that I have unfortunately come up with no better option of writing to the AltVals other than individually having a loop for each Index entry. Example:
On Loop "Special 199"
-> Write Value 199 to AltVal 101+(value of AltVal 100)
-> Add 1 to AltVal 100
On Loop "Special 200"
-> Write Value 200 to AltVal 201+(value of AltVal 200)
->Add 1 to AltVal 200
On Loop "Special 201"
-> Write Value 201 to AltVal 301+(Value of AltVal 300)
-> Add 1 to AltVal 300
So there are only 3 loops really, which differentiate where values should be written to, but since I can't run the same loop for a range I have to specify each individual value and run the write version of the loop. So I have ended up with something like 260 Events, which does not seem at all efficient.
I am curious if someone can think of a better method for this. As a caveat, I can't change the Index values, because they are data that has been created wayyyyyyy back in the Army selection and creation screens - a lot of the pregame stuff also uses these values and therefore they are set in stone.
Thanks all. If I can clarify anything, please let me know. This took way too many attempts to make it readable and even then I don't know how successful I was.