• 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.

1st Time making an MUI spell

Level 5
Joined
Mar 18, 2023
Messages
52
I'm going to start off saying the spell works and the MUI part works but I'm curious if there's anything I should watch out for or change. Thanks ahead of time if someone can look at it.
  • Sunbeam Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Sunbeam
    • Actions
      • Set VariableSet SunbeamIndex = (SunbeamIndex + 1)
      • Set VariableSet SunbeamCaster[SunbeamIndex] = (Triggering unit)
      • Set VariableSet SunbeamP[SunbeamIndex] = (Target point of ability being cast)
      • Set VariableSet SunbeamTimer[SunbeamIndex] = 7.00
      • -------- HP Regen/DMG --------
      • Set VariableSet SunbeamHealth[SunbeamIndex] = (42.86 x (Real((Level of Sunbeam for SunbeamCaster[SunbeamIndex]))))
      • -------- MP Regen/MP Drain --------
      • Set VariableSet SunbeamMana[SunbeamIndex] = (21.43 x (Real((Level of Sunbeam for SunbeamCaster[SunbeamIndex]))))
      • -------- Hits up to 14x --------
      • Unit - Create 1 AllUnitTypes[0] for (Owner of SunbeamCaster[SunbeamIndex]) at SunbeamP[SunbeamIndex] facing Default building facing degrees
      • Set VariableSet SunbeamDummy[SunbeamIndex] = (Last created unit)
      • Unit - Add Sunbeam Rejuvenation Aura SFX to (Last created unit)
      • Unit - Add Sunbeam Silence to (Last created unit)
      • Special Effect - Create a special effect at SunbeamP[SunbeamIndex] using Sacred Storm.mdx
      • Special Effect - Set Scale of (Last created special effect) to 2.00
      • Special Effect - Play Special Effect: (Last created special effect), Animation: Birth
      • Set VariableSet SunbeamSfx[SunbeamIndex] = (Last created special effect)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • SunbeamIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Sunbeam Loop <gen>
        • Else - Actions

  • Sunbeam Loop
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer SunbeamLoop) from 1 to SunbeamIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SunbeamTimer[SunbeamLoop] Greater than 0.00
            • Then - Actions
              • Set VariableSet SunbeamTimer[SunbeamLoop] = (SunbeamTimer[SunbeamLoop] - 0.50)
              • Set VariableSet SunbeamUG[SunbeamLoop] = (Units within 500.00 of SunbeamP[SunbeamLoop] matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) is Magic Immune) Equal to False)).)
              • Unit Group - Pick every unit in SunbeamUG[SunbeamLoop] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • ((Picked unit) belongs to an enemy of (Owner of SunbeamCaster[SunbeamLoop]).) Equal to True
                    • Then - Actions
                      • Unit - Cause SunbeamCaster[SunbeamLoop] to damage (Picked unit), dealing SunbeamHealth[SunbeamLoop] damage of attack type Spells and damage type Magic
                      • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) - SunbeamMana[SunbeamLoop])
                    • Else - Actions
                      • Unit - Set life of (Picked unit) to ((Life of (Picked unit)) + SunbeamHealth[SunbeamLoop])
                      • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) + SunbeamMana[SunbeamLoop])
              • Unit - Order SunbeamDummy[SunbeamLoop] to Neutral Dark Ranger - Silence SunbeamP[SunbeamLoop]
              • Special Effect - Create a special effect at SunbeamP[SunbeamLoop] using Abilities\Spells\Other\Levelup\LevelupCaster.mdl
              • Special Effect - Set Scale of (Last created special effect) to 6.20
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call DestroyGroup(udg_SunbeamUG[udg_SunbeamLoop])
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SunbeamTimer[SunbeamLoop] Equal to 0.00
                • Then - Actions
                  • Special Effect - Create a special effect at SunbeamP[SunbeamLoop] using Abilities\Spells\Undead\ReplenishHealth\ReplenishHealthCasterOverhead.mdl
                  • Special Effect - Set Scale of (Last created special effect) to 3.10
                  • Special Effect - Destroy (Last created special effect)
                  • Special Effect - Create a special effect at SunbeamP[SunbeamLoop] using Explosion.mdx
                  • Special Effect - Set Scale of (Last created special effect) to 3.20
                  • Special Effect - Destroy (Last created special effect)
                  • Unit - Remove SunbeamDummy[SunbeamLoop] from the game
                  • Special Effect - Destroy SunbeamSfx[SunbeamLoop]
                  • Custom script: call RemoveLocation(udg_SunbeamP[udg_SunbeamLoop])
                  • Set VariableSet SunbeamCaster[SunbeamLoop] = SunbeamCaster[SunbeamIndex]
                  • Set VariableSet SunbeamP[SunbeamLoop] = SunbeamP[SunbeamIndex]
                  • Set VariableSet SunbeamDummy[SunbeamLoop] = SunbeamDummy[SunbeamIndex]
                  • Set VariableSet SunbeamSfx[SunbeamLoop] = SunbeamSfx[SunbeamIndex]
                  • Set VariableSet SunbeamTimer[SunbeamLoop] = SunbeamTimer[SunbeamIndex]
                  • Set VariableSet SunbeamHealth[SunbeamLoop] = SunbeamHealth[SunbeamIndex]
                  • Set VariableSet SunbeamMana[SunbeamLoop] = SunbeamMana[SunbeamIndex]
                  • Set VariableSet SunbeamUG[SunbeamLoop] = SunbeamUG[SunbeamIndex]
                  • Set VariableSet SunbeamIndex = (SunbeamIndex - 1)
                  • Set VariableSet SunbeamLoop = (SunbeamLoop - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • SunbeamIndex Equal to 0
                    • Then - Actions
                      • Custom script: call RemoveLocation(udg_SunbeamP[udg_SunbeamLoop])
                      • Custom script: call DestroyGroup(udg_SunbeamUG[udg_SunbeamLoop])
                      • Trigger - Turn off (This trigger)
                    • Else - Actions
                • Else - Actions
 
Level 29
Joined
Sep 26, 2009
Messages
2,596
It looks good. What could possibly be changed is:
  • The condition in your loop "SunbeamTimer[SunbeamLoop] Equal to 0.00" is a bit of a red flag. Reason being that reals are not always precise due to rounding errors. For example the number could be 0.000001 after arithmetic operation. This could lead to situation where SunbeamTimer gets into negative values instead of having exactly value 0.00 as the lower boundary value. You could either change the condition to 'Less than or Equal to' to be sure or change the type from real to integers, since integers are always precise. Then it would not represent remaining time, but remaining ticks (i.e. how many times will the loop trigger run for given instance). In your case, it should last 7 seconds, running every 0.5 second, so 14 ticks.
  • You don't need SunbeamUG to be an array, since the group is not persisted outside loop's iteration anyway.
  • You should have no need to remove location and destroy group when you are turning the loop trigger off due to index being equal to zero. At that point of time both location and group would have already been destroyed.
  • Your unit group action inside the loop trigger will deal damage to both enemy structures and mechanical units, which may be fine, but it will also heal and regenerate mana of such type of units if they are allied, which may not be intended.
  • Allied units to the player are also neutral passive (and I believe also Neutral Extra and Neutral Victim). Perhaps you want to exclude such neutrals from both being healed and taking damage?
 
Level 5
Joined
Mar 18, 2023
Messages
52
It looks good. What could possibly be changed is:
  • The condition in your loop "SunbeamTimer[SunbeamLoop] Equal to 0.00" is a bit of a red flag. Reason being that reals are not always precise due to rounding errors. For example the number could be 0.000001 after arithmetic operation. This could lead to situation where SunbeamTimer gets into negative values instead of having exactly value 0.00 as the lower boundary value. You could either change the condition to 'Less than or Equal to' to be sure or change the type from real to integers, since integers are always precise. Then it would not represent remaining time, but remaining ticks (i.e. how many times will the loop trigger run for given instance). In your case, it should last 7 seconds, running every 0.5 second, so 14 ticks.
  • You don't need SunbeamUG to be an array, since the group is not persisted outside loop's iteration anyway.
  • You should have no need to remove location and destroy group when you are turning the loop trigger off due to index being equal to zero. At that point of time both location and group would have already been destroyed.
  • Your unit group action inside the loop trigger will deal damage to both enemy structures and mechanical units, which may be fine, but it will also heal and regenerate mana of such type of units if they are allied, which may not be intended.
  • Allied units to the player are also neutral passive (and I believe also Neutral Extra and Neutral Victim). Perhaps you want to exclude such neutrals from both being healed and taking damage?
thank you!
 
Level 6
Joined
Apr 15, 2016
Messages
118
This Group Filtering I think you should check it. It helped me a lot too, as a restarter in GUI Editing.

It actually swaps the "Unit - Pick Every Unit in Group Matching - Matching Unit looooooong command line", into more structured Conditions. Like, instead of "Matching Unit belongs to an enemy of X equal to true and Matching Unit bla bla Matching Unit like that Matching Unit is naked Matching unit has buff, etc", it does:
Conditions
Picked Unit Belongs to an Enemy of X
Picked Unit has buff
Picked Unit cries.

The tutorial says using Matching Unit is much slower than doing through conditions.
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
The tutorial says using Matching Unit is much slower than doing through conditions.
Well, it's more the idea that if you save it into a variable it only has to call the function once and then it's reused throughout the different conditions. Leaving it as Matching Unit causes it to be called every time it's referred to (even though it's always returning the same unit). Slower functionally in this instance because of course doing the same thing twice takes longer than doing it once, writing it down once, and rereading it. Actually the filterfunc used in the group enum is entirely different from an if-block, so apples to oranges and all that.
 
Level 6
Joined
Apr 15, 2016
Messages
118
It looks good. What could possibly be changed is:
  • You should have no need to remove location and destroy group when you are turning the loop trigger off due to index being equal to zero. At that point of time both location and group would have already been destroyed.
This is actually news to me. So say if you create a Location in the Int Trigger, that is an Array, you don't actually need to Destroy it in the Looping Trigger?

Edit: Oh, I see now, he actually already destroyed before. He's destroying twice.
 
Top