• 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.
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!
  • ✅ The POLL for Hive's Texturing Contest #34 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!
  • ✅ The POLL for Hive's Techtree Contest #20 is OPEN! Vote for the TOP 3 FACTIONS! 🔗Click here to cast your vote!

Boss rain of fire on max 6 units

Level 5
Joined
Sep 20, 2024
Messages
31
Hello! I'm redesigning phase 2 of a boss fight to make it more fun.
How it should work: The boss casts a fake spell just to play a channelling animation, then max 6 enemy units within 700 range of boss get max 1 invisible unit on top of each enemy unit, the invisible unit casts level 1 rain of fire on each location of enemy unit thay spawned on top of.

Problem with current trigger: Right now the boss will spawn more than 1 invisible unit on top of each enemy unit if there are less than 6 enemy units within 700 range. If I can figure out how to make it so max 1 invisible unit spawn on top of each enemy unit then I could delete the second action (Units withint 500 range...) and greater than 2 condition which I added to reduce chance of a unit getting more than 1 rain of fire on them.

  • RainOfFire
    • Events
      • Time - Every 9.00 seconds of game time
    • Conditions
      • (Boss is hidden) Equal to False
    • Actions
      • Set VariableSet Point15 = (Position of Boss)
      • Set VariableSet UnitGroup8 = (Units within 500.00 of Point15 matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Player 1 (Red).) Equal to True)).)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in UnitGroup8) Greater than 2
        • Then - Actions
          • Unit - Order Boss to Orc Tauren Chieftain - War Stomp.
          • Set VariableSet UnitGroup9 = (Units within 700.00 of Point15 matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Player 1 (Red).) Equal to True)).)
          • Set VariableSet BossInteger2 = 0
          • Unit Group - Pick every unit in UnitGroup9 and do (Actions)
            • Loop - Actions
              • Set VariableSet BossInteger2 = (BossInteger2 + 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • BossInteger2 Less than 6
                • Then - Actions
                  • Wait (Random real number between 0.00 and 0.50) seconds
                  • Set VariableSet Point17 = (Position of (Picked unit))
                  • Unit - Create 1 Firerain (Level 1) for Player 1 (Red) at Point17 facing Default building facing degrees
                  • Unit - Order (Last created unit) to Neutral Pit Lord - Rain Of Fire Point17
                  • Unit - Add a 8.00 second Generic expiration timer to (Last created unit)
                  • Custom script: call RemoveLocation(udg_Point17)
                • Else - Actions
          • Custom script: call DestroyGroup(udg_UnitGroup9)
        • Else - Actions
      • Custom script: call DestroyGroup(udg_UnitGroup8)
      • Custom script: call RemoveLocation(udg_Point15)
 
Last edited:
It worked with removing picked unit from UnitGroup9 in the loop! Only 1 invisible unit now created for each enemy unit. Thank you.

Although the invisible units always spawn on top of the structures furthest away from the boss instead of spawning on top of random units every time. Maybe that's how the action "Unit Group - Units within 600 of point" is programmed by Blizzard, the units furthest away are always picked first. Hmm I wonder if I can somehow make it pick random units within the group.

I had some issues with rain of fire not being channelled entire time, I added an action "AI ignore guard position of last created unit" to fix it.
I had to remove the "Wait (Random real number)" because having a wait action seems to break all the actions in the loop, it's a shame since I want all invisible units to cast rain of fire after a random time between 0-0.5 seconds for a little bit more randomness. Maybe there is some other way to make them cast it after a random time hmm.

  • RainOfFire
    • Events
      • Time - Every 9.00 seconds of game time
    • Conditions
      • (Boss is hidden) Equal to False
    • Actions
      • Set VariableSet Point15 = (Position of Boss)
      • Set VariableSet UnitGroup9 = (Units within 600.00 of Point15 matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Player 1 (Red).) Equal to True)).)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in UnitGroup9) Greater than 0
        • Then - Actions
          • Unit - Order Boss to Orc Tauren Chieftain - War Stomp.
          • Set VariableSet BossInteger2 = 0
          • Unit Group - Pick every unit in UnitGroup9 and do (Actions)
            • Loop - Actions
              • Set VariableSet BossInteger2 = (BossInteger2 + 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • BossInteger2 Less than 5
                • Then - Actions
                  • Set VariableSet Point17 = (Position of (Picked unit))
                  • Unit - Create 1 Fireunit (Level 1) for Player 1 (Red) at Point17 facing Default building facing degrees
                  • AI - Ignore (Last created unit)'s guard position
                  • Unit - Order (Last created unit) to Neutral Pit Lord - Rain Of Fire Point17
                  • Unit - Add a 8.00 second Generic expiration timer to (Last created unit)
                  • Custom script: call RemoveLocation(udg_Point17)
                  • Unit Group - Remove (Picked unit) from UnitGroup9.
                • Else - Actions
        • Else - Actions
      • Custom script: call DestroyGroup(udg_UnitGroup9)
      • Custom script: call RemoveLocation(udg_Point15)
 
Last edited:
Maybe instead of looping through all units with Unit Group - Pick every unit in UnitGroup9 do an integer loop and pick unit with Set MyUnit = (Random unit from MyGroup) or Set VariableSet Point17 = (Position of (Random unit from UnitGroup9)). Of course, you'd need to remove the picked unit from your group (as you do) and verify that you actually got a unit in an if MyUnit is not No Unit

This could be ways to solve some of your problems.

Randomness is slightly harder as it requires you to store units or locations a short while. It's imo easier in code (jass or lua) than GUI, but could add the created casters to a group, and have another trigger that for example every 0.1 seconds have a 25% chance to cast at its own location.
Benefit of this methods is that it's rather simple.
Numbers might needs tweaking, but with doing it every 0.1 seconds with 25% chance to succeed, you have less than 24% to continue longer than 0.5 seconds, and 10% to continue for more than 0.8 seconds.
There are other methods involving setting up Timers, HashTable, Array and/or unit's UserData to make it more exact what you asked for at the cost of more complexity
 
The action "Unit Group - Units within 600 of point" seems to always pick structures first, but I also noticed in tests I did today that heroes are also picked first, while units such as footmen are not picked first. So it doesn't seem to be based on range but rather on unit-type (or maybe both). Interesting how Blizzard coded that action. Since heroes are also targeted first and have to run out of rain of fire perhaps it doesn't need to be random as you say it becomes too complex. I will settle with the trigger for now as it's much better now than it was.

I optimized the trigger by moving the action "Set VariableSet BossInteger2 = (BossInteger2 + 1)" so it's below the action "Unit Group - Remove (Picked unit) from UnitGroup9" and changed condition to "BossInteger2 Less than 4". I decided to go from 6 targets to 4 since the rain of fire blocks cameraview a lot, I wish the rain of fire spell would start from a lower height to prevent blocking cameraview but I guess that's how Blizzard designed the rain of fire art effect so I leave it to them. A final touch I did was reduce expiration timer of the invisible Fireunit from 8 to 7 seconds since level 1 rain of fire doesn't last that long. I prefer the GUI since I'm not a programmer.
 
The action "Unit Group - Units within 600 of point" seems to always pick structures first,
That's why I suggested doing a loop integer, and (Get Random Unit in Group), instead of "For each unit, check if it's used few-enough times".
That way you get... A random unit... Of cource you need to check that you actually got a unit out from it.

I prefer the GUI since I'm not a programmer.
It felt like it, that's why I suggested a more "easy" solution first (I.E. instead of casting instantly as you do now, just create the unit and add to group, then cast from other trigger: "every 0.X seconds, have each unit have a Y% chance to cast it"), rather than save unit-reference and timers etc. to do a proper random interval.
 
then max 6 enemy units within 700 range of boss
In Jass, there's a function that greatly simplifies this process. The function is this:
JASS:
GroupEnumUnitsInRangeCounted

I created a method to make it easier to use in your trigger, which is as follows:
1) Create a Trigger called Add Max 6 units in Boss Rain of Fire
2) Convert the Trigger to Custom Text (Trigger Editor => Select the needed trigger => Click on Edit at the top => Click on Convert to Custom Text)
3) Delete all current custom text inside the trigger
4) Copy-Paste this code inside the empty trigger:
JASS:
function FilterLivingEnemyUnitsFromBoss takes nothing returns boolean
    return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.00 and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Boss))
endfunction

function EnumUnitsInRangeOfBossCounted takes group g, real range, integer maxunits returns nothing
    local filterfunc f = Filter(function FilterLivingEnemyUnitsFromBoss)
    call GroupEnumUnitsInRangeCounted(g, GetUnitX(udg_Boss), GetUnitY(udg_Boss), range, f, maxunits)
    call DestroyFilter(f)
    set f = null
endfunction

//===========================================================================
function InitTrig_Add_Max_6_units_in_Boss_Rain_of_Fire takes nothing returns nothing
    local trigger trg = CreateTrigger()
    set trg = null
endfunction
5) Save your Map

Now you can do this on your trigger:
  • RainOfFire
  • Events
  • Time - Every 9.00 seconds of game time
  • Conditions
  • (Boss is hidden) Equal to False
  • Actions
  • Custom Script Code: call EnumUnitsInRangeOfBossCounted(udg_UnitGroup9, 700.00, 6)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • (Number of units in UnitGroup9) Greater than 0
  • Then - Actions
  • Unit - Order Boss to Orc Tauren Chieftain - War Stomp.
  • Unit Group - Pick every unit in UnitGroup9 and do (Actions)
  • Loop - Actions
  • Set VariableSet Point17 = (Position of (Picked unit))
  • Unit - Create 1 Fireunit (Level 1) for Player 1 (Red) at Point17 facing Default building facing degrees
  • AI - Ignore (Last created unit)'s guard position
  • Unit - Order (Last created unit) to Neutral Pit Lord - Rain Of Fire Point17
  • Unit - Add a 8.00 second Generic expiration timer to (Last created unit)
  • Custom script: call RemoveLocation(udg_Point17)
  • Unit Group - Remove (Picked unit) from UnitGroup9.
  • Custom script: call DestroyGroup(udg_UnitGroup9)

Note that in the custom script code, udg_UnitGroup9 represents the variable UnitGroup9, 700.00 is the total range for matching target units, and 6 is the maximum number of units that can be picked.

At another time I will look into a simple and safe way for you to be able to use again the randomness you wanted.
 
Last edited:
Back
Top