• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[Trigger] Complicated unit creation system with arrays

Status
Not open for further replies.
Level 3
Joined
Jun 24, 2004
Messages
42
I'm not 100% sure how I will explain this, so I'll do my best. Long Story short, I NEED HELP!

Before I try to explain, let me point out that I would prefer any help I get in GUI, as I'm not very good with JASS (I can read it very well, but as for creating triggers using it, it takes me a while).

Basically I want to create a unit creation system for my map to decrease the number of triggers I have (~350) and make adding new units to the map much much easier on me.

In my current system, you take 2 units to a circle of power and they are 'fused' together to become a stronger unit. Right now I have to create a new trigger every time I want to add new units to the map. I was hoping to maybe set a variable to every single unit in the map during initialization and then just using simple integer conditions to determine which units are in the circle and which units to create.

This is something like what I currently use:
  • Fuse Wolf to Captain
    • Events
      • Unit - A unit enters Fusion Circle <gen>
    • Conditions
      • (Level of (Entering unit)) Equal to 3
    • Actions
      • If ((Number of units in (Units in Fusion Circle <gen>(((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to |c0000FF00Wolf|r)))) Equal to 0) then do (Skip remaining actions) else do (Do nothing)
      • If ((Number of units in (Units in Fusion Circle <gen>(((Owner of (Matching unit)) Equal to (Owner of (Triggering unit))) and ((Unit-type of (Matching unit)) Equal to |c0000FF00Captain|r)))) Equal to 0) then do (Skip remaining actions) else do (Do nothing)
      • Unit - Create 1 |c0000FF00Armor Horse|r for (Owner of (Triggering unit)) at (Center of Fused Unit Appear <gen>) facing Default building facing (270.0) degrees
      • Unit Group - Pick every unit in (Random 1 units from (Units in Fusion Circle <gen>(((Unit-type of (Matching unit)) Equal to |c0000FF00Wolf|r) and ((Owner of (Matching unit)) Equal to (Owner of (Triggering unit)))))) and do (Unit - Remove (Picked unit) from the game)
      • Unit Group - Destroy unit group (Last created unit group)
      • Unit Group - Pick every unit in (Random 1 units from (Units in Fusion Circle <gen>(((Unit-type of (Matching unit)) Equal to |c0000FF00Captain|r) and ((Owner of (Matching unit)) Equal to (Owner of (Triggering unit)))))) and do (Unit - Remove (Picked unit) from the game)
      • Unit Group - Destroy unit group (Last created unit group)
Keep in mind I have to create a new trigger EVERY time I add a unit to the map. Its very very time consuming, especially since there are WELL over 200 units in the map.

What I want to do is shrink all of these down to a SINGLE trigger using variables. I do know how I can create the unit, but I don't know how to do the integer checks to tell if the two units in the fusion circle are able to fuse, and then fuse them.

Example of what I want to do:
  • Init Variables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Level3Unit[1] = Wolf
      • Set Level3Unit[2] = Captain
      • Set Level4Unit[1] = Armor Horse

Then I want to create a single trigger for the fusions that checks which 2 units entered the fusion circle and if they are able to fuse together, and then fuse them into the appropriate unit.

I realize I'll probably need more variables, like a variable that is set equal to the unit-type of which unit a certain unit fuses to, such as:

  • Init Variables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set Level3Unit[1] = Wolf
      • Set Level3Unit[2] = Captain
      • Set Level4Unit[1] = Armor Horse
      • Set Level3Fuse[1] = Captain
      • Set Level3Fuse[2] = Wolf
And then do something like:

  • Level 3 Fusion Trigger
    • Events
      • Unit - A unit enters Fusion Circle <gen>
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Fusion Circle <gen> contains Level3Unit[Integer A]) Equal to True
              • (Fusion Circle <gen> contains Level3Fuse[Integer A]) Equal to True
            • Then - Actions
              • Unit - Create 1 Level4Unit[Integer A] for (Owner of (Triggering unit)) at (Center of Fusion Unit Create <gen>) facing Default building facing (270.0) degrees
            • Else - Actions
              • Do Nothing
I hope someone is catching on now. Can someone give me a little help cutting down my 200+ triggers into a single trigger containing my new fusion system?
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
I think this should work, but it needs some work to make it so all players can be in the same region at the same time or it will be bugged when 2 players enter the region.

(and by the way, use the TRIGGER tags not jass tags [trig.ger]text[/trig.ger] without the dots)

  • Unknown
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Unit-type of (Triggering unit)) Equal to Footman
              • Boolean[1] Equal to False
        • Then - Actions
          • Set Boolean[1] = True
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Unit-type of (Triggering unit)) Equal to Riderless Horse
              • Boolean[2] Equal to False
        • Then - Actions
          • Set Boolean[2] = True
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • Boolean[1] Equal to True
              • Boolean[2] Equal to True
        • Then - Actions
          • Set Boolean[1] = False
          • Set Boolean[2] = False
          • Unit - Create 1 Knight for (Owner of (Triggering unit)) at (Center of (Playable map area)) facing Default building facing degrees
        • Else - Actions

You would need to use loops (Integer[A] , Integer) if you do not want this trigger to be about 200 lines long.
If you don't know how to use them ask and ill explain.
 
Level 3
Joined
Jun 24, 2004
Messages
42
That doesn't help things at all, especially since I still have to specify unit types in the trigger, meaning I'll have to either create 200 triggers for my units or make one trigger 200 lines long.

I'm trying to get away without specifying unit types in the trigger directly, I want to use an arrayed unit-type variable for this so I can loop it and use the integers inside of the array to check which units have entered the circle and which units to create as a result.

So putting unit-type conditions directly in the trigger will not help what so ever.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Right im sorry didn't notice.
You could make it this way, but I don't find any solution for the regions problem, since you either need to specify region in the event, or make a condition of "region containing unit" and so you will always get stuck with either a huge trigger or a huge number of triggers.

  • Unknown
    • Events
      • Unit - A unit enters Region <gen>
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 2, do (Actions)
        • Loop - Actions
          • Set Integer[(Integer A)] = (Number of units in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Unit_Type[(Integer A)])))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • Integer[(Integer A)] Equal to 1
            • Then - Actions
              • Set Boolean[(Integer A)] = True
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • Boolean[1] Equal to True
              • Boolean[2] Equal to True
        • Then - Actions
          • Set Boolean[1] = False
          • Set Boolean[2] = False
          • Unit - Create 1 Footman for (Owner of (Triggering unit)) at (Center of (Playable map area)) facing Default building facing degrees
        • Else - Actions
 
Level 3
Joined
Jun 24, 2004
Messages
42
I guess that helps a little, although I still have the problem of specifying the unit created in the trigger, the footman as you chose. This would STILL require me to create ~200 triggers. The regions are not a problem, the region used for every single trigger is the exact same.

I guess I'll have to come up with a number system for the unit-type array so that I can just add the numbers together to create the fused unit.

Thanks anyway.
 
Well, It was harder than I thought. But I think that one should work fine.
However, it's only for Fusions that requires 2 Units and not more.

Fusion_FirstUnit[n] is the first required unit to fuse.
Fusion_SecondUnit[n] is obviously the second required unit.
Fusion_ThirdUnit[n] is the finished fused unit.
Fusion_DoubleUnit[n] checks if you're using 2 Units of the same Type and is working according to it.
Fusion_TotalFusions counts all Fusions that are possible to loop until that point.
  • FusionINIT
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Footmen + Horse = Knight --------
      • Set Fusion_TotalFusions = (Fusion_TotalFusions + 1)
      • Set Fusion_FirstUnit[Fusion_TotalFusions] = Footman
      • Set Fusion_SecondUnit[Fusion_TotalFusions] = Riderless Horse
      • Set Fusion_ThirdUnit[Fusion_TotalFusions] = Knight
      • Set Fusion_DoubleUnit[Fusion_TotalFusions] = False
      • -------- Peasant + Knight = Paladin --------
      • Set Fusion_TotalFusions = (Fusion_TotalFusions + 1)
      • Set Fusion_FirstUnit[Fusion_TotalFusions] = Peasant
      • Set Fusion_SecondUnit[Fusion_TotalFusions] = Knight
      • Set Fusion_ThirdUnit[Fusion_TotalFusions] = Paladin
      • Set Fusion_DoubleUnit[Fusion_TotalFusions] = False
      • -------- Paladin + Paladin = Lord Garithos --------
      • Set Fusion_TotalFusions = (Fusion_TotalFusions + 1)
      • Set Fusion_FirstUnit[Fusion_TotalFusions] = Paladin
      • Set Fusion_SecondUnit[Fusion_TotalFusions] = Paladin
      • Set Fusion_ThirdUnit[Fusion_TotalFusions] = Lord Garithos
      • Set Fusion_DoubleUnit[Fusion_TotalFusions] = True
  • Fusion
    • Events
      • Unit - A unit enters Fusion <gen>
    • Conditions
    • Actions
      • For each (Integer A) from 1 to Fusion_TotalFusions, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Fusion_DoubleUnit[(Integer A)] Equal to False
            • Then - Actions
              • Set TempGroup1 = (Units in FusionCheck <gen> matching (((Unit-type of (Matching unit)) Equal to Fusion_FirstUnit[(Integer A)]) and ((Owner of (Matching unit)) Equal to (Owner of (Entering unit)))))
              • Set TempGroup2 = (Units in FusionCheck <gen> matching (((Unit-type of (Matching unit)) Equal to Fusion_SecondUnit[(Integer A)]) and ((Owner of (Matching unit)) Equal to (Owner of (Entering unit)))))
              • Set TempUnit1 = (Random unit from TempGroup1)
              • Set TempUnit2 = (Random unit from TempGroup2)
              • Custom script: call DestroyGroup(udg_TempGroup1)
              • Custom script: call DestroyGroup(udg_TempGroup2)
            • Else - Actions
              • Set TempGroup1 = (Units in Fusion <gen> matching (((Unit-type of (Matching unit)) Equal to Fusion_FirstUnit[(Integer A)]) and ((Owner of (Matching unit)) Equal to (Owner of (Entering unit)))))
              • Set TempUnit1 = (Random unit from TempGroup1)
              • Unit - Set the custom value of TempUnit1 to 1
              • Set TempGroup1 = (Units in FusionCheck <gen> matching (((Unit-type of (Matching unit)) Equal to Fusion_FirstUnit[(Integer A)]) and (((Owner of (Matching unit)) Equal to (Owner of (Entering unit))) and ((Custom value of (Matching unit)) Equal to 1))))
              • Set TempGroup2 = (Units in FusionCheck <gen> matching (((Unit-type of (Matching unit)) Equal to Fusion_SecondUnit[(Integer A)]) and (((Owner of (Matching unit)) Equal to (Owner of (Entering unit))) and ((Custom value of (Matching unit)) Equal to 0))))
              • Set TempUnit1 = (Random unit from TempGroup1)
              • Set TempUnit2 = (Random unit from TempGroup2)
              • Custom script: call DestroyGroup(udg_TempGroup1)
              • Custom script: call DestroyGroup(udg_TempGroup2)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • (Number of units in (Units in FusionCheck <gen>)) Greater than 1
                  • TempUnit1 Not equal to TempUnit2
                  • ((FusionCheck <gen> contains TempUnit1) Equal to True) and ((FusionCheck <gen> contains TempUnit2) Equal to True)
                  • (Owner of TempUnit1) Equal to (Owner of (Entering unit))
                  • (Owner of TempUnit2) Equal to (Owner of (Entering unit))
            • Then - Actions
              • Unit - Create 1 Fusion_ThirdUnit[(Integer A)] for (Owner of (Entering unit)) at (Center of FusionComplete <gen>) facing Default building facing degrees
              • Unit - Remove TempUnit1 from the game
              • Unit - Remove TempUnit2 from the game
              • Set TempUnit1 = No unit
              • Set TempUnit2 = No unit
            • Else - Actions
              • Set TempUnit1 = No unit
              • Set TempUnit2 = No unit
  • FusionFix
    • Events
      • Unit - A unit leaves Fusion <gen>
    • Conditions
    • Actions
      • Unit - Set the custom value of (Leaving unit) to 0
 

Attachments

  • Fusion_System.w3x
    20.3 KB · Views: 41
Level 3
Joined
Jun 24, 2004
Messages
42
Thats a lot closer to what I was looking for, but still not quite flexible enough. The main problem is, there are 12 level 3 units and each one can fuse with any other level 3 unit. There are no specific there.

I guess I could just leave the level 3's the way they are and use that system from above for my level 4 and up fusions.
 
Level 3
Joined
Jun 24, 2004
Messages
42
I think it's not neccessary to define the unit level, since you define what specific unit can fuse with another. Let's say if you haven't added the Unit1(lvl3) + Unit2(lvl4) fusion, it wont work. But possible.

No its just that there really aren't any specifics when it comes to certain units. I can't just specify that this one fuses with that one when it also fuses with 10+ other units. I would either have to redo the arrays or create several more variables.
 
Level 9
Joined
Oct 17, 2007
Messages
547
I think u still have to make 200 triggers for that unless ur really good wit JASS i dont see any shortcut in GUI, arrays only works if u want to choose something out of "random" like calling the array and make the index random numbers. If u're planing to use those triggers that many times in a game.. i recommend u clean up those loc and unit group leaks.
 
Level 3
Joined
Jun 24, 2004
Messages
42
I was thinking about setting specific numbers to each unit that were spaced out pretty far. For example I would set Level3Unit[6] = Captain and Level3Unit[148] = Mage and then do a Create 1 Level3Unit[6+148]

I dunno though, I guess this system will be a little more complicated than I thought.
 
Status
Not open for further replies.
Top