• 🏆 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] Having a building require two of four buildings

Status
Not open for further replies.
Level 4
Joined
Jan 2, 2016
Messages
66
The background info: I am designing an Elementals race. There is a group of four buildings, each associated with Fire, Air, Water, or Earth; and there is an advanced building that requires you to have at least two of those four in order to build it.

Here's my first attempt at the trigger that governs this. I'm using an upgrade research for the requirement. It's not working, and I'm not sure what's wrong. Also, this feels cumbersome, is there a more efficient way to do this?

  • Two Elemental Shrines
    • Events
      • Unit - A unit Finishes construction
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Fire Temple
          • (Unit-type of (Triggering unit)) Equal to Spire of Clouds
          • (Unit-type of (Triggering unit)) Equal to Scrying Pool
          • (Unit-type of (Triggering unit)) Equal to Earthen Dome
    • Actions
      • -------- Initialize --------
      • Set FireShrines = 0
      • Set AirShrines = 0
      • Set WaterShrines = 0
      • Set EarthShrines = 0
      • Set ElementalShrines = 0
      • Unit Group - Pick every unit in (Units owned by (Owner of (Triggering unit)) matching (((Picked unit) is A structure) Equal to True)) and do (Actions)
        • Loop - Actions
          • -------- Check for Fire Shrine --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Picked unit)) Equal to Fire Temple
            • Then - Actions
              • Set FireShrines = 1
            • Else - Actions
          • -------- Check for Air Shrine --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Picked unit)) Equal to Spire of Clouds
            • Then - Actions
              • Set AirShrines = 1
            • Else - Actions
          • -------- Check for Water Shrine --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Picked unit)) Equal to Scrying Pool
            • Then - Actions
              • Set WaterShrines = 1
            • Else - Actions
          • -------- Check for Earth Shrine --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Picked unit)) Equal to Earthen Dome
            • Then - Actions
              • Set EarthShrines = 1
            • Else - Actions
      • -------- Total Count --------
      • Set ElementalShrines = (ElementalShrines + FireShrines)
      • Set ElementalShrines = (ElementalShrines + AirShrines)
      • Set ElementalShrines = (ElementalShrines + WaterShrines)
      • Set ElementalShrines = (ElementalShrines + EarthShrines)
      • -------- Set Research Level --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ElementalShrines Greater than or equal to 2
        • Then - Actions
          • Player - Set the current research level of At least two of Fire Shrine Spire of Clouds, Scrying Pool, or Earthen Dome (Upgrade 1) to 1 for (Owner of (Triggering unit))
        • Else - Actions
          • Player - Set the current research level of At least two of Fire Shrine Spire of Clouds, Scrying Pool, or Earthen Dome (Upgrade 1) to 0 for (Owner of (Triggering unit))
 
Level 4
Joined
Sep 13, 2014
Messages
106
You should replace the IF conditions with "If number of units in [Units of Type "Shrine XXX] is greater or equal 1".

Well, I'm not sure that's true, because then you would have to search for units of type shrine every time you want to run the trigger. This way it's stored in a simple variable.

Well, never mind, looking though the trigger, what you should do is just add the constructed building to the variables, and seperately, when one dies or is cancelled, you should take one away. In the constructing trigger you should have basically the last bit.
 
Level 4
Joined
Jan 2, 2016
Messages
66
You should replace the IF conditions with "If number of units in [Units of Type "Shrine XXX] is greater or equal 1".

I've changed it according to this. The trigger is now

  • Two Elemental Shrines
    • Events
      • Unit - A unit Dies
      • Unit - A unit Finishes construction
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to Fire Temple
          • (Unit-type of (Triggering unit)) Equal to Spire of Clouds
          • (Unit-type of (Triggering unit)) Equal to Scrying Pool
          • (Unit-type of (Triggering unit)) Equal to Earthen Dome
    • Actions
      • -------- Initialize --------
      • Set FireShrines = 0
      • Set AirShrines = 0
      • Set WaterShrines = 0
      • Set EarthShrines = 0
      • Set ElementalShrines = 0
      • -------- Check for Fire Shrine --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in (Units owned by (Owner of (Triggering unit)) of type Fire Temple)) Greater than or equal to 1
        • Then - Actions
          • Set FireShrines = 1
          • Game - Display to (All players) the text: Fire Shrine: TRUE
        • Else - Actions
          • Set FireShrines = 0
          • Game - Display to (All players) the text: Fire Shrine: FALSE
      • -------- Check for Air Shrine --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in (Units owned by (Owner of (Triggering unit)) of type Spire of Clouds)) Greater than or equal to 1
        • Then - Actions
          • Set AirShrines = 1
          • Game - Display to (All players) the text: Air Shrine: TRUE
        • Else - Actions
          • Set AirShrines = 0
          • Game - Display to (All players) the text: Air Shrine: FALSE
      • -------- Check for Water Shrine --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in (Units owned by (Owner of (Triggering unit)) of type Scrying Pool)) Greater than or equal to 1
        • Then - Actions
          • Set WaterShrines = 1
          • Game - Display to (All players) the text: Water Shrine: TRUE
        • Else - Actions
          • Set WaterShrines = 0
          • Game - Display to (All players) the text: Water Shrine: FALSE
      • -------- Check for Earth Shrine --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in (Units owned by (Owner of (Triggering unit)) of type Earthen Dome)) Greater than or equal to 1
        • Then - Actions
          • Set EarthShrines = 1
          • Game - Display to (All players) the text: Earth Shrine: TRUE
        • Else - Actions
          • Set EarthShrines = 0
          • Game - Display to (All players) the text: Earth Shrine: FALSE
      • -------- Total Count --------
      • Set ElementalShrines = (ElementalShrines + FireShrines)
      • Set ElementalShrines = (ElementalShrines + AirShrines)
      • Set ElementalShrines = (ElementalShrines + WaterShrines)
      • Set ElementalShrines = (ElementalShrines + EarthShrines)
      • -------- Set Research Level --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ElementalShrines Greater than or equal to 2
        • Then - Actions
          • Unit - Create 1 At least two of Fire Shrine, Spire of Clouds, Scrying Pool, or Earthen Dome for (Owner of (Triggering unit)) at (Point(0.00, 0.00)) facing Default building facing degrees
        • Else - Actions
          • Unit Group - Pick every unit in (Units owned by (Owner of (Triggering unit))) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to At least two of Fire Shrine, Spire of Clouds, Scrying Pool, or Earthen Dome
                • Then - Actions
                  • Unit - Remove (Picked unit) from the game
                • Else - Actions
                  • Do nothing
I'm no longer using a research for the requirement, because it didn't work to turn off the availability (it even says on the tooltip for that action that "Tech cannot be unlearned" through it). This works to create the dummy building that is the requirement once I have two elemental shrines. The problem is that the dummy requirement building won't go away once I destroy one of the shrines.
 
Level 4
Joined
Sep 13, 2014
Messages
106
I think this should work (haven't tested though)

  • InitShrineVariable
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set ElementType[0] = Blah
      • Set ElementType[1] = Blah
      • Set ElementType[2] = Blah
      • Set ElementType[3] = Blah
  • ShrineConstruct
    • Events
      • Unit - A unit Begins construction
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to BlahBlahBlah
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Blah
        • Then - Actions
          • Set ElementNumber[(Key Whichever one)] = ((Key Whichever one) + 1)
        • Else - Actions
      • Trigger - Run ShrineUpdate <gen> (checking conditions)
  • ShrineDestroy
    • Events
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to BlahBlahBlah
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Blah
        • Then - Actions
          • Set ElementNumber[(Key Whichever one)] = ((Key Whichever one) - 1)
        • Else - Actions
      • Trigger - Run ShrineUpdate <gen> (checking conditions)
  • ShrineUpdate
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((ElementNumber[0] + ElementNumber[1]) + (ElementNumber[2] + ElementNumber[3])) Greater than or equal to 2
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RequirementUnit Equal to No unit
            • Then - Actions
              • Unit - Create 1 ReqiurementUnit for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
            • Else - Actions
        • Else - Actions
          • Unit - Remove RequirementUnit from the game
 
Level 4
Joined
Jan 2, 2016
Messages
66
I think this should work (haven't tested though)

  • InitShrineVariable
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set ElementType[0] = Blah
      • Set ElementType[1] = Blah
      • Set ElementType[2] = Blah
      • Set ElementType[3] = Blah
  • ShrineConstruct
    • Events
      • Unit - A unit Begins construction
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to BlahBlahBlah
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Blah
        • Then - Actions
          • Set ElementNumber[(Key Whichever one)] = ((Key Whichever one) + 1)
        • Else - Actions
      • Trigger - Run ShrineUpdate <gen> (checking conditions)
  • ShrineDestroy
    • Events
      • Unit - A unit Dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Unit-type of (Triggering unit)) Equal to BlahBlahBlah
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Blah
        • Then - Actions
          • Set ElementNumber[(Key Whichever one)] = ((Key Whichever one) - 1)
        • Else - Actions
      • Trigger - Run ShrineUpdate <gen> (checking conditions)
  • ShrineUpdate
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((ElementNumber[0] + ElementNumber[1]) + (ElementNumber[2] + ElementNumber[3])) Greater than or equal to 2
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RequirementUnit Equal to No unit
            • Then - Actions
              • Unit - Create 1 ReqiurementUnit for Player 1 (Red) at (Center of (Playable map area)) facing Default building facing degrees
            • Else - Actions
        • Else - Actions
          • Unit - Remove RequirementUnit from the game

I seem to have gotten this working based on your work.

  • ShrineInitialize
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set FireShrines = 0
      • Set AirShrines = 0
      • Set WaterShrines = 0
      • Set EarthShrines = 0
  • ShrineConstruct
    • Events
      • Unit - A unit Finishes construction
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Fire Temple
        • Then - Actions
          • Set FireShrines = (FireShrines + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Spire of Clouds
        • Then - Actions
          • Set AirShrines = (AirShrines + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Scrying Pool
        • Then - Actions
          • Set WaterShrines = (WaterShrines + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Earthen Dome
        • Then - Actions
          • Set EarthShrines = (EarthShrines + 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (FireShrines + (AirShrines + (WaterShrines + EarthShrines))) Greater than or equal to 2
              • (Number of units in (Units owned by (Owner of (Triggering unit)) matching ((Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome))) Equal to 0
        • Then - Actions
          • Unit - Create 1 At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome for (Owner of (Triggering unit)) at (Center of (Playable map area)) facing Default building facing degrees
        • Else - Actions
          • Do nothing
  • ShrineDestroy
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is A structure) Equal to True
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Fire Temple
        • Then - Actions
          • Set FireShrines = (FireShrines - 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Spire of Clouds
        • Then - Actions
          • Set AirShrines = (AirShrines - 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Scrying Pool
        • Then - Actions
          • Set WaterShrines = (WaterShrines - 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to Earthen Dome
        • Then - Actions
          • Set EarthShrines = (EarthShrines - 1)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • (FireShrines + (AirShrines + (WaterShrines + EarthShrines))) Less than 2
        • Then - Actions
          • Unit Group - Pick every unit in (Units owned by (Owner of (Triggering unit))) and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome
                • Then - Actions
                  • Unit - Remove (Picked unit) from the game
                • Else - Actions
        • Else - Actions
          • Do nothing
One thing I couldn't figure out is how you did this part:

  • If - Conditions
    • RequirementUnit Equal to No unit
I looked through all the drop-down menus and couldn't find this. What condition is it?
 
Level 4
Joined
Sep 13, 2014
Messages
106
Actually, I just noticed, make sure you fix my location leak, you create your requirement unit at Centre of playable map area, which creates a point. The region "playable map area" doesn't leak, but taking the centre of it does.

Also, yeah, use

  • RequirementUnit Equal to No unit
(unit comparision)

rather than

  • (Number of units in (Units owned by (Owner of (Triggering unit)) matching ((Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome))) Equal to 0
which leaks. Basically create a variable that holds the requirement unit, you will actually need to make it an array for MPI (multi-player instance-ability), and use that rather than unit groups. Either that or add them to the unit group as they are created and loop through when you need to act on some individual player's one.

Also, in the following action, "Matching unit" is the correct value rather than "Picked unit"

  • (Number of units in (Units owned by (Owner of (Triggering unit)) matching ((Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome))) Equal to 0
Also, looking back, I have no idea why I went absolutely bonkers and used "ReqiurementUnit" being serperate to "RequirementUnit" note the u and i swapped places. And I forgot to set "RequirementUnit" equal to the unit created of type "ReqiurementUnit".

I think you will need to change a moderate... Actually my triggers are horrible, I keep finding things wrong with them, you will need to change a lot. Basically I think all I wanted to do was give an example of what I meant, with variables holding the number of shrines and being incremented or decremented as they were built or destroyed.
 
Level 4
Joined
Jan 2, 2016
Messages
66
Actually, I just noticed, make sure you fix my location leak, you create your requirement unit at Centre of playable map area, which creates a point. The region "playable map area" doesn't leak, but taking the centre of it does.

To clean up the leak, would it be sufficient to just use a "Remove last created point" action right after creating the Requirement Building?


Also, yeah, use

  • RequirementUnit Equal to No unit
(unit comparision)

rather than

  • (Number of units in (Units owned by (Owner of (Triggering unit)) matching ((Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome))) Equal to 0
which leaks. Basically create a variable that holds the requirement unit, you will actually need to make it an array for MPI (multi-player instance-ability), and use that rather than unit groups. Either that or add them to the unit group as they are created and loop through when you need to act on some individual player's one.

So, here, RequirementUnit is a variable of type "Unit"? And its value is set to the At Least Two... unit when I create that unit? Then when the unit is destroyed, the variable will have the value "No unit"?


Also, in the following action, "Matching unit" is the correct value rather than "Picked unit"

  • (Number of units in (Units owned by (Owner of (Triggering unit)) matching ((Unit-type of (Picked unit)) Equal to At least two of Fire Temple, Spire of Clouds, Scrying Pool, or Earthen Dome))) Equal to 0

Good to know how to do this. Thanks.


Also, looking back, I have no idea why I went absolutely bonkers and used "ReqiurementUnit" being serperate to "RequirementUnit" note the u and i swapped places. And I forgot to set "RequirementUnit" equal to the unit created of type "ReqiurementUnit".

I think you will need to change a moderate... Actually my triggers are horrible, I keep finding things wrong with them, you will need to change a lot. Basically I think all I wanted to do was give an example of what I meant, with variables holding the number of shrines and being incremented or decremented as they were built or destroyed.

Regarding MPI, I think I would just make each Shrine variable into a 12-entry array. Then FireShrines[1] is the number of Fire Temples controlled by Player 1, FireShines[2] is the number of Fire Temples controlled by Player 2, and so on. Is there a way to convert the Player's number into an integer? Like Player 1 would return 1, Player 2 would return 2, and so on? So I could use that for the array index.
 
Level 4
Joined
Sep 13, 2014
Messages
106
I'm not sure there is a "Last Created Point" variable/function. Or even a GUI remove point function. Unless you use some extension to the world editor. So I'm pretty sure you'd have to do it the normal way, by storing it in a variable and destroying it afterwards. Although if one exists it should work.

Yes.

Cool.

Use Player - Player Number when choosing the integer.
 
Status
Not open for further replies.
Top