How do I make a "moving breath of fire", and how do I make doodads (like rocks) block its effect?

Level 4
Joined
Nov 16, 2019
Messages
55
I am trying to make a dragon boss-fight, and I want to make a breath of fire spell, that makes the dragon spew fire in a circular movement around it.

And on top of that, I'd like to know how to make environment, such as a large rock or stone-pillar, capable of blocking the spell. So that if your character stands behind this rock during the fight, the breath of fire will not hit that character at all.
 

Uncle

Warcraft Moderator
Level 48
Joined
Aug 10, 2018
Messages
4,697
Here's a working example of a firebreath ability. I think it turned out great.

I used this system Line Segment Enumeration .v2.1a to create a line effect for better targeting. Normally you have to use circles and pick units within a circular radius around a point. But with this we can basically make regions that can be angled in any direction and pick units inside of them.

How it works:
So the Firebreath ability uses 4 Fireballs (by default), the first one starting near the Dragon's mouth. Each Fireball extends outwards further than the previous one, covering a small distance. Enemies within 100 range of these Fireballs take damage every 0.04 seconds.

Fireball 1 damages enemies from 25 to 100 distance
Fireball 2 damages enemies from 100 to 175 distance
Fireball 3 damages enemies from 175 to 250 distance
Fireball 4 damages enemies from 250 to 325 distance

If one of these Fireballs comes into contact with a blocking Destructible (like rocks/pillar) that Fireball and any fireball beyond it is destroyed (temporarily) preventing the damage from being dealt. This gives the effect that the Destructible is blocking the Fireballs and it looks sweet :D

With some more tweaking and adjustments it could look way better as well.

Configure these variables to your liking.
  • Dragon Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- The Dragon --------
      • Set VariableSet Dragon = Dragon 0000 <gen>
      • -------- --------
      • -------- How many Fireballs? --------
      • Set VariableSet Dragon_FireballCount = 4
      • -------- --------
      • -------- Fireball Art --------
      • Set VariableSet Dragon_FireballArt = Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
      • -------- --------
      • -------- Fireball Height (1 = First ball closest to the dragon's head) --------
      • Set VariableSet Dragon_FireballHeight[1] = 200.00
      • Set VariableSet Dragon_FireballHeight[2] = 150.00
      • Set VariableSet Dragon_FireballHeight[3] = 100.00
      • Set VariableSet Dragon_FireballHeight[4] = 50.00
      • -------- --------
      • -------- Destructible Types that block Fireballs --------
      • -------- You can add more but you'll have to add them to the OR Conditions in the Firebreath Loop trigger. The conditions are in the DestructableCounter Loop --------
      • Set VariableSet Dragon_Destructibles[1] = Rock Chunks (New)
      • Set VariableSet Dragon_Destructibles[2] = Rock Chunks (New)
      • Set VariableSet Dragon_Destructibles[3] = Rock Chunks (New)
You can edit the Event for this trigger to whatever you want. This starts the Firebreath effect.
  • Dragon Firebreath
    • Events
      • Time - Every 8.00 seconds of game time
    • Conditions
    • Actions
      • -------- Real[0] = Starting Angle --------
      • -------- Real[1] = Loc 1 Offset --------
      • -------- Real[2] = Loc 2 Offset --------
      • -------- --------
      • -------- Set Starting Variables --------
      • Set VariableSet Dragon_Real[0] = 180.00
      • Set VariableSet Dragon_Real[1] = -50.00
      • Set VariableSet Dragon_Real[2] = 0.00
      • Set VariableSet Dragon_Counter = 0
      • Unit - Make Dragon face 180.00 over 0.04 seconds
      • -------- --------
      • -------- This plays the Dragon's attack animation (by using this Index method it won't cause orders to interrupt the animation) --------
      • Custom script: call SetUnitAnimationByIndex(udg_Dragon, 1)
      • -------- --------
      • Countdown Timer - Start Dragon_Timer as a Repeating timer that will expire in 0.04 seconds
This Timer runs every 0.04 seconds by default. Most of the variables are designed around this interval, if you adjust it you will have to adjust the other variables as well such as Dragon_Real(0) and Dragon_Counter.

There's more variables you can configure in here to tweak the effect. LSE_Offset allows you to adjust the AoE of the Firebreath. Dragon_Real(0) allows you to adjust the Angle increment every 0.04 seconds (it's near the bottom). Dragon_Counter determines the Duration of the effect (In this case it ends at 75 because it's the equivalent of 3.00 seconds --> 0.75*4).
  • Dragon Firebreath Loop
    • Events
      • Time - Dragon_Timer expires
    • Conditions
    • Actions
      • -------- Real[0] = Current Angle --------
      • -------- Real[1] = Loc 1 Offset --------
      • -------- Real[2] = Loc 2 Offset --------
      • -------- --------
      • -------- LSE_Offset = The damage radius of the Firebreath --------
      • Set VariableSet LSE_Offset = 100.00
      • -------- --------
      • Set VariableSet Dragon_Skip = False
      • Set VariableSet Dragon_Real[1] = -50.00
      • Set VariableSet Dragon_Real[2] = 0.00
      • Unit Group - Remove all units from Dragon_Group.
      • -------- --------
      • For each (Integer Dragon_Loop) from 1 to Dragon_FireballCount, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Dragon_Skip Equal to False
            • Then - Actions
              • Set VariableSet Dragon_Real[1] = (Dragon_Real[1] + 75.00)
              • Set VariableSet Dragon_Real[2] = (Dragon_Real[1] + 75.00)
              • Set VariableSet LSE_Loc_1 = ((Position of Dragon) offset by Dragon_Real[1] towards Dragon_Real[0] degrees.)
              • Set VariableSet LSE_Loc_2 = ((Position of Dragon) offset by Dragon_Real[2] towards Dragon_Real[0] degrees.)
              • Set VariableSet LSE_DestructableCounter = 0
              • Trigger - Run LSE_GetDestructables (ignoring conditions)
              • For each (Integer LSE_Loop) from 0 to LSE_DestructableCounter, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (Destructible-type of LSE_Destructable[LSE_Loop]) Equal to Dragon_Destructibles[1]
                          • (Destructible-type of LSE_Destructable[LSE_Loop]) Equal to Dragon_Destructibles[2]
                          • (Destructible-type of LSE_Destructable[LSE_Loop]) Equal to Dragon_Destructibles[3]
                    • Then - Actions
                      • Set VariableSet Dragon_Skip = True
                    • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Dragon_Skip Equal to False
                • Then - Actions
                  • -------- Firebreath Special Effect --------
                  • Special Effect - Create a special effect at LSE_Loc_2 using Dragon_FireballArt
                  • Special Effect - Set Height of (Last created special effect) to: Dragon_FireballHeight[Dragon_Loop]
                  • Special Effect - Set Scale of (Last created special effect) to 1.20
                  • Set VariableSet Delayed_Duration = 0.10
                  • Trigger - Run Delayed Destroy Effect <gen> (ignoring conditions)
                  • -------- --------
                  • Unit Group - Remove all units from LSE_Group.
                  • Trigger - Run LSE_GetUnits (ignoring conditions)
                  • Unit Group - Pick every unit in LSE_Group and do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ((Picked unit) is in Dragon_Group.) Equal to False
                          • ((Picked unit) belongs to an enemy of (Owner of Dragon).) Equal to True
                          • ((Picked unit) is alive) Equal to True
                          • ((Picked unit) is invulnerable) Equal to False
                          • ((Picked unit) is hidden) Equal to False
                        • Then - Actions
                          • -------- Damage --------
                          • Unit - Cause Dragon to damage (Picked unit), dealing 10.00 damage of attack type Spells and damage type Normal
                          • Unit Group - Add (Picked unit) to Dragon_Group
                          • -------- --------
                          • -------- Damaged Special Effect --------
                          • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Spells\Other\ImmolationRed\ImmolationRedDamage.mdl
                          • Set VariableSet Delayed_Duration = 0.50
                          • Trigger - Run Delayed Destroy Effect <gen> (ignoring conditions)
                        • Else - Actions
                • Else - Actions
              • Custom script: call RemoveLocation(udg_LSE_Loc_1)
              • Custom script: call RemoveLocation(udg_LSE_Loc_2)
            • Else - Actions
      • -------- --------
      • -------- Increase Angle (60 degrees per second) --------
      • Set VariableSet Dragon_Real[0] = (Dragon_Real[0] + 2.40)
      • Unit - Make Dragon 0000 <gen> face Dragon_Real[0] over 0.04 seconds
      • -------- --------
      • Set VariableSet Dragon_Counter = (Dragon_Counter + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Dragon_Counter Equal to 75
        • Then - Actions
          • Countdown Timer - Pause Dragon_Timer
          • Animation - Reset Dragon's animation
          • Unit - Make Dragon 0000 <gen> face 270.00 over 1.00 seconds
        • Else - Actions
This is a neat little system I added. It allows you to destroy a Special Effect after a delay. 3 easy steps:
1) Create your special effect
2) Set Delayed_Duration equal to how long you want to wait before the Special Effect is destroyed
3) Run Delayed Destroy Effect (ignoring conditions)
  • Delayed Destroy Effect
    • Events
    • Conditions
    • Actions
      • Custom script: local effect udg_Delayed_Sfx = GetLastCreatedEffectBJ()
      • Wait Delayed_Duration seconds
      • Special Effect - Destroy Delayed_Sfx
      • Custom script: set udg_Delayed_Sfx = null
Edit: Uploaded v2, increased it from 4 to 8 fireball segments and adjusted the offset. Looks a decent bit better now.
 

Attachments

  • Dragon Firebreath Ex 2.w3m
    31.4 KB · Views: 17
Last edited:

Uncle

Warcraft Moderator
Level 48
Joined
Aug 10, 2018
Messages
4,697
Good luck finding an effect which can be changed dynamically enough. Yes you can filter targets by code but the visuals will be misleading af
Yeah, a flamethrower effect will be difficult to manage but if you break up the firebreath into segments like I did in my example it can be done. You simply hide any segment and each segment beyond it that comes into contact with a Destructible.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
I cannot test the map, invalid level data so cannot see exactly how it looks.
But I REALLY doubt you can make it look remotely decent in terms of visuals. You'd have to make multiple smaller models like 10x of the fire doodad. However not only would this be ugly, it would also be clunky as removing one of the small details would probably remove too much of the fire.
 

Uncle

Warcraft Moderator
Level 48
Joined
Aug 10, 2018
Messages
4,697
Remotely decent isn't hard to achieve for a game like warcraft 3. This ain't star citizen.
 
Top