• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Limiting Unit Amounts

Status
Not open for further replies.
Level 3
Joined
May 1, 2008
Messages
27
Most often than not you will use:
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Player - Limit training of UNIT to # for (Player((Integer A)))
Or... something to that effect. However, this in my opinion looks really bad when all of a sudden that unit's icon vanishes.

Now before we begin, I expect you to know GUI/Trigger basics, and understand how to clean common leaks. I only use Unit Groups in this, so if you know how to clean those that's great (I do it myself in this tutorial), but it's better if you go learn how to if you don't.

Say you wanted something like "No UNIT" to "appear" in that unit's Requirements, and it to be greyed out instead. This looks a lot more refined, and at least now, the player knows why they can't create that unit anymore.

Create the unit itself you're going to add a limit to, then create a copy of that unit (preferably add "(At limit)" or something to that effect in the copy's Editor Suffix). In the Requirements of the copy, add another unit called "No UNIT" or "Less than # UNIT" (Depends on how many you want it limited to). It doesn't matter what you use, as long as it is called "No UNIT" or "Less than # UNIT".

Then follow these triggers:


  • UNIT Limit
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set UNITLimit[(Integer A)] = 3
          • Player - Make UNIT (At Limit) Unavailable for training/construction by (Player((Integer A)))
          • -------- Init Check --------
          • Set TempUGroup = (Units owned by (Player((Integer A))) of type UNIT)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in TempUGroup) Greater than or equal to UNITLimit[(Integer A)]
            • Then - Actions
              • Player - Make UNIT Unavailable for training/construction by (Player((Integer A)))
              • Player - Make UNIT (At Limit) Available for training/construction by (Player((Integer A)))
            • Else - Actions
              • Do nothing
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in TempUGroup) Greater than or equal to 1
            • Then - Actions
              • Unit - Set the custom value of (Random unit from TempUGroup) to 1
            • Else - Actions
              • Do nothing
          • Custom script: call DestroyGroup (udg_TempUGroup)
  • UNIT Limit OnOff
    • Events
      • Unit - A unit Begins construction
      • Unit - A unit Cancels construction
      • Unit - A unit Finishes training a unit
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Constructing structure)) Equal to UNIT
          • (Trained unit-type) Equal to UNIT
          • (Unit-type of (Dying unit)) Equal to UNIT
    • Actions
      • Set TempUGroup = (Units owned by (Triggering player) of type UNIT)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TempUGroup) Greater than or equal to UNITLimit[(Player number of (Triggering player))]
        • Then - Actions
          • Player - Make UNIT Unavailable for training/construction by (Triggering player)
          • Player - Make UNIT (At Limit) Available for training/construction by (Triggering player)
        • Else - Actions
          • Do nothing
      • Wait 0.10 game-time seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TempUGroup) Less than UNITLimit[(Player number of (Triggering player))]
        • Then - Actions
          • Player - Make UNIT Available for training/construction by (Triggering player)
          • Player - Make UNIT (At Limit) Unavailable for training/construction by (Triggering player)
        • Else - Actions
          • Do nothing
      • Custom script: call DestroyGroup (udg_TempUGroup)

  • UNIT Limit
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 12, do (Actions)
        • Loop - Actions
          • Set UNITLimit[(Integer A)] = 10
          • Player - Make UNIT 1 (At Limit) Unavailable for training/construction by (Player((Integer A)))
          • Player - Make UNIT 2 (At Limit) Unavailable for training/construction by (Player((Integer A)))
          • -------- Init Check --------
          • Set TempUGroupA[1] = (Units owned by (Player((Integer A))) of type UNIT 1)
          • Set TempUGroupA[2] = (Units owned by (Player((Integer A))) of type UNIT 2)
          • Set UNITCurrent = 0
          • For each (Integer B) from 1 to 2, do (Actions)
            • Loop - Actions
              • Set UNITCurrent = (UNITCurrent + (Number of units in TempUGroupA[(Integer B)]))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UNITCurrent Greater than or equal to UNITLimit[(Integer A)]
            • Then - Actions
              • Player - Make UNIT 1 Unavailable for training/construction by (Player((Integer A)))
              • Player - Make UNIT 2 Unavailable for training/construction by (Player((Integer A)))
              • Player - Make UNIT 1 (At Limit) Available for training/construction by (Player((Integer A)))
              • Player - Make UNIT 2 (At Limit) Available for training/construction by (Player((Integer A)))
            • Else - Actions
              • Do nothing
          • Custom script: call DestroyGroup (udg_TempUGroupA[1])
          • Custom script: call DestroyGroup (udg_TempUGroupA[2])
  • UNIT Limit OnOff
    • Events
      • Unit - A unit Begins construction
      • Unit - A unit Cancels construction
      • Unit - A unit Finishes training a unit
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Constructing structure)) Equal to UNIT 1
          • (Unit-type of (Constructing structure)) Equal to UNIT 2
          • (Trained unit-type) Equal to UNIT 1
          • (Trained unit-type) Equal to UNIT 2
          • (Unit-type of (Dying unit)) Equal to UNIT 1
          • (Unit-type of (Dying unit)) Equal to UNIT 2
    • Actions
      • Set TempUGroupA[1] = (Units owned by (Triggering player) of type UNIT 1)
      • Set TempUGroupA[2] = (Units owned by (Triggering player) of type UNIT 2)
      • Set UNITCurrent = 0
      • For each (Integer A) from 1 to 2, do (Actions)
        • Loop - Actions
          • Set UNITCurrent = (UNITCurrent + (Number of units in TempUGroupA[(Integer A)]))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UNITCurrent Greater than or equal to UNITLimit[(Player number of (Triggering player))]
        • Then - Actions
          • Player - Make UNIT 1 Unavailable for training/construction by (Triggering player)
          • Player - Make UNIT 2 Unavailable for training/construction by (Triggering player)
          • Player - Make UNIT 1 (At Limit) Available for training/construction by (Triggering player)
          • Player - Make UNIT 2 (At Limit) Available for training/construction by (Triggering player)
        • Else - Actions
          • Do nothing
      • Wait 0.10 game-time seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UNITCurrent Less than UNITLimit[(Player number of (Triggering player))]
        • Then - Actions
          • Player - Make UNIT 1 Available for training/construction by (Triggering player)
          • Player - Make UNIT 2 Available for training/construction by (Triggering player)
          • Player - Make UNIT 1 (At Limit) Unavailable for training/construction by (Triggering player)
          • Player - Make UNIT 2 (At Limit) Unavailable for training/construction by (Triggering player)
        • Else - Actions
          • Do nothing
      • Custom script: call DestroyGroup (udg_TempUGroupA[1])
      • Custom script: call DestroyGroup (udg_TempUGroupA[2])

You can set the maximum amount by changing what UNIT_Limit[] is set to. Also rename that to whatever your unit is called.

Also, these triggers work with both units and structures.

PS: Some of you may be wondering "Why is there a second if statement in the OnOff trigger? Why not just put it in the "Else" of the first? Similarly, why is that "Wait" there?
I tried that. It worked at first, then out of nowhere stopped working. For some reason it would never register anymore that the unit was actually "dead" the "instant" it was dead. So I added a wait, then a second if statement.
Regardless it still works as desired.

Also, if any trigger novices would like me to make an example map, I will.
 
Last edited:
Status
Not open for further replies.
Top