• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

2D arrays

Level 6
Joined
Feb 22, 2025
Messages
85
Hi, was trying to create Angelic Armaments, so before u see the code gotta say I know there's a lot of memory cleanup missing and safety checking and reseting variables and polishing, typos etc..., I just want the foundation to work first; also is there a way to simplify this lol? The idea was to spawn 6 missiles which would rotate and rise around the caster and after 4 seconds if they acquire the target they would rush towards it, else get removed; additionally was considering periodic area damage while they orbit and follow the caster( which I'll add later);
!!! I'm getting an unexpected error at setting X,Y end of line, It's not reading DEGTORAD, like there's no space to continue the code, so I'm asking is there a simple way to do this without using fake 2d arrays :")

The Code:
----------------------------------------------------------------
  • AA Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Angelic Armaments
    • Actions
      • Set AA_Index = (AA_Index + 1)
      • Set AA_Caster[AA_Index] = (Triggering unit)
      • Set AA_Timer[AA_Index] = 4.00
      • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set AA_Angle[((AA_Index x 10) + AA_Loop_B)] = (60.00 x ((Real(AA_Loop_B)) - 1.00))
          • Unit - Create 1 Spear Idle for (Owner of AA_Caster[AA_Index]) at (Position of AA_Caster[AA_Index]) facing Default building facing degrees
          • Set AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)] = (Last created unit)
          • Unit - Add a 5.00 second Generic expiration timer to AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)]
          • Unit - Add Crow Form to AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)]
          • Unit - Remove Crow Form from AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)]
          • Unit - Pause AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)]
          • Set AA_Flying_Height[((AA_Loop_A x 10) + AA_Loop_B)] = 150.00
          • Animation - Change AA_Spear_Idle[((AA_Index x 10) + AA_Loop_B)] flying height to 150.00 at 0.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AA_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on AA Orbit <gen>
        • Else - Actions
  • AA Orbit
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer AA_Loop_A) from 1 to AA_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AA_Caster[AA_Loop_A] is alive) Equal to True
              • AA_Loop_A Less than or equal to AA_Index
            • Then - Actions
              • Set AA_Timer[AA_Loop_A] = (AA_Timer[AA_Loop_A] - 0.03)
              • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
                • Loop - Actions
                  • Set AA_Angle[((AA_Loop_A x 10) + AA_Loop_B)] = ((AA_Angle[((AA_Loop_A x 10) + AA_Loop_B)] + 15.00) mod 360.00)
                  • Set AA_TempPoint = (Position of AA_Caster[AA_Loop_A])
                  • Set AA_Offset = (AA_TempPoint offset by 200.00 towards AA_Angle[((AA_Loop_A x 10) + AA_Loop_B)] degrees.)
                  • Custom script: call SetUnitX( udg_AA_Spear_Idle[( udg_AA_Loop_A * 10) + udg_AA_Loop_B], GetLocationX( udg_AA_Offset))
                  • Custom script: call SetUnitY( udg_AA_Spear_Idle[( udg_AA_Loop_A * 10) + udg_AA_Loop_B], GetLocationY( udg_AA_Offset))
                  • Set AA_Flying_Height[((AA_Loop_A x 10) + AA_Loop_B)] = (AA_Flying_Height[((AA_Loop_A x 10) + AA_Loop_B)] + 2.50)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AA_Flying_Height[((AA_Loop_A x 10) + AA_Loop_B)] Greater than or equal to 250.00
                    • Then - Actions
                      • Animation - Change AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)] flying height to AA_Flying_Height[((AA_Loop_A x 10) + AA_Loop_B)] at 0.00
                    • Else - Actions
                  • Custom script: call RemoveLocation( udg_AA_TempPoint)
                  • Custom script: call RemoveLocation( udg_AA_Offset)
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Timer[AA_Loop_A] Less than or equal to 0.01
            • Then - Actions
              • Trigger - Turn on AA Launch <gen>
            • Else - Actions
  • AA Launch
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer AA_Loop_A) from 1 to AA_Index, do (Actions)
        • Loop - Actions
          • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
            • Loop - Actions
              • Set AA_Spear_TempPoint = (Position of AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)])
              • Set AA_TargetGroup = (Units within 1000.00 of AA_Spear_TempPoint matching (((((Matching unit) is A structure) Equal to False) and (((Matching unit) is alive) Equal to True)) and ((((Matching unit) is hidden) Equal to False) and (((Matching unit) belongs to an enemy of (Owner of A
              • Set AA_Target[AA_Loop_A] = (Random unit from AA_TargetGroup)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_Target[((AA_Loop_A x 10) + AA_Loop_B)] Not equal to No unit
                • Then - Actions
                  • Set AA_TargetPoint = (Position of AA_Target[((AA_Loop_A x 10) + AA_Loop_B)])
                  • Set AA_Speed[((AA_Loop_A x 10) + AA_Loop_B)] = 40.00
                  • Set AA_Launch_Angle[((AA_Loop_A x 10) + AA_Loop_B)] = (Angle from (Position of AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)]) to (Position of AA_Target[((AA_Loop_A x 10) + AA_Loop_B)]))
                  • Set AA_Boolean[((AA_Loop_A x 10) + AA_Loop_B)] = True
                  • Trigger - Turn on AA Missile Movement <gen>
                • Else - Actions
                  • Set AA_Boolean[((AA_Loop_A x 10) + AA_Loop_B)] = False
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_Boolean[((AA_Loop_A x 10) + AA_Loop_B)] Equal to False
                • Then - Actions
                  • Unit - Kill AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)]
                • Else - Actions
          • Custom script: call DestroyGroup( udg_AA_TargetGroup)
  • AA Missile Movement
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer AA_Loop_A) from 1 to AA_Index, do (Actions)
        • Loop - Actions
          • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_Boolean[((AA_Loop_A x 10) + AA_Loop_B)] Equal to True
                • Then - Actions
                  • Custom script: call SetUnitX(udg_AA_Spear_Idle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B], GetUnitX(udg_AA_Spear_Idle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] + udg_AA_Speed[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] * Cos(udg_AA_Launch_Angle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] * bj_D
                  • Custom script: call SetUnitY(udg_AA_Spear_Idle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B], GetUnitY(udg_AA_Spear_Idle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] + udg_AA_Speed[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] * Sin(udg_AA_Launch_Angle[(udg_AA_Loop_A * 10) + udg_AA_Loop_B] * bj_D
                  • Set AA_Spear_TempPoint = (Position of AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)])
                  • Set AA_TargetPoint = (Position of AA_Target[((AA_Loop_A x 10) + AA_Loop_B)])
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Distance between AA_Spear_TempPoint and AA_TargetPoint) Less than or equal to 10.00
                    • Then - Actions
                      • Unit - Kill AA_Spear_Idle[((AA_Loop_A x 10) + AA_Loop_B)]
                      • Unit - Cause AA_Caster[((AA_Loop_A x 10) + AA_Loop_B)] to damage AA_Target[((AA_Loop_A x 10) + AA_Loop_B)], dealing 1000.00 damage of attack type Spells and damage type Normal
                    • Else - Actions
                • Else - Actions
----------------------------------------------
Didn't get to test the Movement trigger since I can't fit the code :")
 
For starters, I would recommend using an integer variable to store the index. That way the 2D-array usage becomes a lot cleaner to read and easier to manage. For example, you could introduce an integer variable "CurrentIndex" to use throughout the trigger:
  • For each (Integer AA_Loop_A) from 1 to AA_Index, do (Actions)
    • Loop - Actions
      • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set AA_CurrentIndex = ((AA_Loop_A x 10) + AA_Loop_B)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Boolean[AA_CurrentIndex] Equal to True
            • Then - Actions
              • Custom script: call SetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex], GetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Cos(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD))
              • Custom script: call SetUnitY(udg_AA_Spear_Idle[udg_AA_CurrentIndex], GetUnitY(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Sin(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD))
              • -------- etc. --------
            • Else - Actions
If you still run into issues with fitting it all into a single custom script line, you can use other intermediate variables, e.g. a "Real" variable, to store the "new X" result separately, e.g. if you had a real variable named "TempReal":
  • Custom script: set udg_TempReal = GetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Cos(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD)
  • Custom script: call SetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex], udg_TempReal)
Then you could do the same for the Y-coordinate as well.
 
Level 6
Joined
Feb 22, 2025
Messages
85
For starters, I would recommend using an integer variable to store the index. That way the 2D-array usage becomes a lot cleaner to read and easier to manage. For example, you could introduce an integer variable "CurrentIndex" to use throughout the trigger:
  • For each (Integer AA_Loop_A) from 1 to AA_Index, do (Actions)
    • Loop - Actions
      • For each (Integer AA_Loop_B) from 1 to 6, do (Actions)
        • Loop - Actions
          • Set AA_CurrentIndex = ((AA_Loop_A x 10) + AA_Loop_B)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Boolean[AA_CurrentIndex] Equal to True
            • Then - Actions
              • Custom script: call SetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex], GetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Cos(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD))
              • Custom script: call SetUnitY(udg_AA_Spear_Idle[udg_AA_CurrentIndex], GetUnitY(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Sin(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD))
              • -------- etc. --------
            • Else - Actions
If you still run into issues with fitting it all into a single custom script line, you can use other intermediate variables, e.g. a "Real" variable, to store the "new X" result separately, e.g. if you had a real variable named "TempReal":
  • Custom script: set udg_TempReal = GetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex] + udg_AA_Speed[udg_AA_CurrentIndex] * Cos(udg_AA_Launch_Angle[udg_AA_CurrentIndex] * bj_DEG_TO_RAD)
  • Custom script: call SetUnitX(udg_AA_Spear_Idle[udg_AA_CurrentIndex], udg_TempReal)
Then you could do the same for the Y-coordinate as well.
Thanks!!!, would never imagine to store it that way lol, yeah it's more readable I was throwing up while writing arrays :") :goblin_boom:
 
Top