• 🏆 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!

Mind Blast [GUI][MUI]

  • Like
Reactions: Losam and Imadori
Mind Blast
Damages units in a target area for a duration while also doing increased damage the longer the spell is active. Also drains mana by half the damage dealt.

Level 1 - Does your intelligence/3 as damage and mana drain to all units in the target area for 5 seconds. 15 second cooldown.
Level 2 - Does your intelligence/2 as damage and mana drain to all units in the target area for 7.5 seconds. 17.5 second cooldown.
Level 3 - Does your intelligence as damage and mana drain to all units in the target area for 10 seconds. 20 second cooldown.
  • Unit Indexer
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: call ExecuteFunc("InitializeUnitIndexer")
      • Custom script: endfunction
      • -------- --------
      • -------- This is the most important function - it provides an index for units as they enter the map --------
      • -------- --------
      • Custom script: function IndexUnit takes nothing returns boolean
      • Custom script: local integer pdex = udg_UDex
      • -------- --------
      • -------- You can use the boolean UnitIndexerEnabled to protect some of your undesirable units from being indexed --------
      • -------- - Example: --------
      • -------- -- Set UnitIndexerEnabled = False --------
      • -------- -- Unit - Create 1 Dummy for (Triggering player) at TempLoc facing 0.00 degrees --------
      • -------- -- Set UnitIndexerEnabled = True --------
      • -------- --------
      • -------- You can also customize the following block - if conditions are false the (Matching unit) won't be indexed. --------
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UnitIndexerEnabled Equal to True
        • Then - Actions
          • -------- --------
          • -------- Generate a unique integer index for this unit --------
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UDexRecycle Equal to 0
            • Then - Actions
              • Set UDex = (UDexGen + 1)
              • Set UDexGen = UDex
            • Else - Actions
              • Set UDex = UDexRecycle
              • Set UDexRecycle = UDexNext[UDex]
          • -------- --------
          • -------- Link index to unit, unit to index --------
          • -------- --------
          • Set UDexUnits[UDex] = (Matching unit)
          • Unit - Set the custom value of UDexUnits[UDex] to UDex
          • -------- --------
          • -------- Use a doubly-linked list to store all active indexes --------
          • -------- --------
          • Set UDexPrev[UDexNext[0]] = UDex
          • Set UDexNext[UDex] = UDexNext[0]
          • Set UDexNext[0] = UDex
          • -------- --------
          • -------- Fire index event for UDex --------
          • -------- --------
          • Set UnitIndexEvent = 0.00
          • Set UnitIndexEvent = 1.00
          • Set UnitIndexEvent = 0.00
          • Custom script: set udg_UDex = pdex
        • Else - Actions
      • Custom script: return false
      • Custom script: endfunction
      • -------- --------
      • -------- The next function is called each time a unit enters the map --------
      • -------- --------
      • Custom script: function IndexNewUnit takes nothing returns boolean
      • Custom script: local integer pdex = udg_UDex
      • Custom script: local integer ndex
      • -------- --------
      • -------- Recycle indices of units no longer in-play every (15) units created --------
      • -------- --------
      • Set UDexWasted = (UDexWasted + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UDexWasted Equal to 15
        • Then - Actions
          • Set UDexWasted = 0
          • Set UDex = UDexNext[0]
          • Custom script: loop
          • Custom script: exitwhen udg_UDex == 0
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Custom value of UDexUnits[UDex]) Equal to 0
            • Then - Actions
              • -------- --------
              • -------- Remove index from linked list --------
              • -------- --------
              • Custom script: set ndex = udg_UDexNext[udg_UDex]
              • Custom script: set udg_UDexNext[udg_UDexPrev[udg_UDex]] = ndex
              • Custom script: set udg_UDexPrev[ndex] = udg_UDexPrev[udg_UDex]
              • Set UDexPrev[UDex] = 0
              • -------- --------
              • -------- Fire deindex event for UDex --------
              • -------- --------
              • Set UnitIndexEvent = 2.00
              • Set UnitIndexEvent = 0.00
              • -------- --------
              • -------- Recycle the index for later use --------
              • -------- --------
              • Set UDexUnits[UDex] = No unit
              • Set UDexNext[UDex] = UDexRecycle
              • Set UDexRecycle = UDex
              • Custom script: set udg_UDex = ndex
            • Else - Actions
              • Set UDex = UDexNext[UDex]
          • Custom script: endloop
          • Custom script: set udg_UDex = pdex
        • Else - Actions
      • -------- --------
      • -------- Handle the entering unit (Matching unit) --------
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Custom value of (Matching unit)) Equal to 0
        • Then - Actions
          • Custom script: call IndexUnit()
        • Else - Actions
      • Custom script: return false
      • Custom script: endfunction
      • -------- --------
      • -------- The next function initializes the core of the system --------
      • -------- --------
      • Custom script: function InitializeUnitIndexer takes nothing returns nothing
      • Custom script: local integer i = 0
      • Custom script: local region re = CreateRegion()
      • Custom script: local rect r = GetWorldBounds()
      • Set UnitIndexerEnabled = True
      • Custom script: call RegionAddRect(re, r)
      • Custom script: call TriggerRegisterEnterRegion(CreateTrigger(), re, Filter(function IndexNewUnit))
      • Custom script: call RemoveRect(r)
      • Custom script: set re = null
      • Custom script: set r = null
      • Custom script: loop
      • Custom script: call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, Player(i), Filter(function IndexUnit))
      • Custom script: set i = i + 1
      • Custom script: exitwhen i == 16
      • Custom script: endloop
      • -------- --------
      • -------- This is the "Unit Indexer Initialized" event, use it instead of "Map Initialization" for best results --------
      • -------- --------
      • Set UnitIndexEvent = 3.00
      • Set UnitIndexEvent = 0.00
  • Mind Blast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Mind Blast
    • Actions
      • Set MB_Caster[MB_TempKey] = No unit
      • Unit Group - Remove MB_Caster[MB_TempKey] from MB_SpellGroup
      • Set MB_Key = (Custom value of (Triggering unit))
      • Set MB_Index = (MB_Index + 1)
      • Set MB_Caster[MB_Key] = (Triggering unit)
      • Unit Group - Add MB_Caster[MB_Key] to MB_SpellGroup
      • Set MB_AbilityLevel[MB_Key] = (Level of Mind Blast for MB_Caster[MB_Key])
      • Set MB_AbilityDamage[MB_Key] = ((Real((Intelligence of MB_Caster[MB_Key] (Include bonuses)))) + ((Real(MB_AbilityLevel[MB_Key])) / 0.50))
      • Set MB_Duration[MB_Key] = 0.00
      • Set MB_Expiration[MB_Key] = (2.50 + ((Real(MB_AbilityLevel[MB_Key])) x 2.50))
      • Set MB_TotalDamage[MB_Key] = 0.00
      • Set MB_TempPoint = (Target point of ability being cast)
      • Custom script: set udg_MB_DamageGroup[udg_MB_Key] = CreateGroup()
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 160.00 of MB_TempPoint matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) belongs to an ally of (Triggering player)) Not equal to True) and ((((Matching unit) is Magic Immune) Not equal to True) and (((Matching and do (Actions)
        • Loop - Actions
          • Unit Group - Add (Picked unit) to MB_DamageGroup[MB_Key]
      • Special Effect - Create a special effect at MB_TempPoint using Abilities\Spells\Human\MarkOfChaos\MarkOfChaosTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Trigger - Turn on Mind Blast Loop <gen>
      • Custom script: call RemoveLocation(udg_MB_TempPoint)
  • Mind Blast Loop
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in MB_SpellGroup and do (Actions)
        • Loop - Actions
          • Set MB_TempKey = (Custom value of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • MB_Duration[MB_TempKey] Greater than or equal to MB_Expiration[MB_TempKey]
                  • (MB_Caster[MB_TempKey] is dead) Equal to True
                  • (MB_Caster[MB_TempKey] has buff Sleep (Pause)) Equal to True
                  • (MB_Caster[MB_TempKey] has buff Stunned (Pause)) Equal to True
            • Then - Actions
              • Set MB_Caster[MB_TempKey] = No unit
              • Unit Group - Remove all units from MB_DamageGroup[MB_TempKey]
              • Unit Group - Remove MB_Caster[MB_TempKey] from MB_SpellGroup
              • Custom script: call DestroyGroup(udg_MB_DamageGroup[udg_MB_TempKey])
              • Set MB_Index = (MB_Index - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • MB_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
              • Set MB_AbilityLevel[MB_TempKey] = (Level of Mind Blast for MB_Caster[MB_TempKey])
              • Set MB_AbilityDamage[MB_TempKey] = ((Real((Intelligence of MB_Caster[MB_TempKey] (Include bonuses)))) / (4.00 - (Real(MB_AbilityLevel[MB_TempKey]))))
              • Set MB_TotalDamage[MB_TempKey] = (MB_Duration[MB_TempKey] + MB_AbilityDamage[MB_TempKey])
              • Set MB_Duration[MB_TempKey] = (MB_Duration[MB_TempKey] + 0.50)
              • Unit Group - Pick every unit in MB_DamageGroup[MB_TempKey] and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (((Picked unit) is Magic Immune) Equal to True) or (((Picked unit) is dead) Equal to True)
                    • Then - Actions
                      • Unit Group - Remove (Picked unit) from MB_DamageGroup[MB_TempKey]
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Percentage mana of (Picked unit)) Greater than 1.00
                          • (Percentage mana of MB_Caster[MB_TempKey]) Less than 100.00
                        • Then - Actions
                          • Unit - Set mana of (Picked unit) to ((Mana of (Picked unit)) - (MB_TotalDamage[MB_TempKey] / 2.00))
                          • Unit - Set mana of MB_Caster[MB_TempKey] to ((Mana of MB_Caster[MB_TempKey]) + (MB_TotalDamage[MB_TempKey] / 2.00))
                          • Special Effect - Create a special effect attached to the origin of (Picked unit) using Abilities\Spells\Items\TomeOfRetraining\TomeOfRetrainingCaster.mdl
                          • Special Effect - Destroy (Last created special effect)
                          • Special Effect - Create a special effect attached to the origin of MB_Caster[MB_TempKey] using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
                          • Special Effect - Destroy (Last created special effect)
                        • Else - Actions
                      • Unit - Cause MB_Caster[MB_TempKey] to damage (Picked unit), dealing MB_TotalDamage[MB_TempKey] damage of attack type Spells and damage type Normal
                      • Special Effect - Create a special effect attached to the head of (Picked unit) using Abilities\Spells\Undead\DeathandDecay\DeathandDecayTarget.mdl
                      • Special Effect - Destroy (Last created special effect)
Credit to Bribe for his Unit Indexer.
Credit to PeeKay for his Mind Crush icon.
Special thanks to Pharaoh_, Spinnaker and EvilCrizpy for helping me fix my first spell ever!
Versions
1.0
-Release

1.1
-Reworked entire spell according to EvilCrizpy's suggestion.

1.2
(Changes made according to Maker's review)
-Added importing instructions into the map.
-Now includes intelligence bonus to the damage.
-Filters out dead units and does not add them to the unit group.
-Made a better test map.

1.3
(changes made according to Pharaoh_'s review)
-Filters out magic immune units in the damage loop.
-Increases damage if units are under the spell and the hero levels up.

1.4
(changes made according to Maker's review)
-Changed the damage equation, will now work past level 3 and above
-Reduced duration of effect


How to import this spell.
To successfully import this spell into your map you must follow these 3 easy steps!

Step #1 - Make sure in your map preferences under general, that the create unknown variables is checked.
Step #2 - Copy the Mind Blast ability from the object editor to your map.
Step #3 - Copy the Unit Indexer, Mind Blast and Mind Blast Loop triggers to your map.

Your all done! If you want to import the icon as well download it here and follow it's import instructions.

Please be sure to rate and give feedback in the comments!

Keywords:
mind blast, mind, blast, target ground, ground
Contents

Mind Blast (Map)

Reviews
Mind Blast | Reviewed by Maker | 30th Jun 2013 APPROVED The spell is leakless and MUI The spell damages neural units No need to clear a group is you destroy it Don't get the current ability level in the looping...

Moderator

M

Moderator


Mind Blast | Reviewed by Maker | 30th Jun 2013
APPROVED


126248-albums6177-picture66521.png


  • The spell is leakless and MUI
126248-albums6177-picture66523.png


  • The spell damages neural units
  • No need to clear a group is you destroy it
  • Don't get the current ability level in the looping trigger.
    Use the level at time of casting
  • The importing instructions could say that any reference to
    the ability need to be set correctly
[tr]



Maker, Mind Blast v1.3, 17th Oct 2011

Can actually heal the target if ability level is > 4.
Will not work if ability level is 4, division by 0.
Check the damage equation.
Do ((Picked unit) is dead) Not equal to (!=) True in the filter functiion.
Hmm:
  • Set MB_Caster[MB_TempKey] = No unit
  • Unit Group - Remove MB_Caster[MB_TempKey] from MB_SpellGroup
  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Multiple ConditionsAnd - All (Conditions) are true
        • Conditions
          • (Percentage mana of (Picked unit)) Greater than (>) 1.00
          • (Percentage mana of MB_Caster[MB_TempKey]) Less than (<) 100.00
->
  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (Percentage mana of (Picked unit)) Greater than (>) 1.00
      • (Percentage mana of MB_Caster[MB_TempKey]) Less than (<) 100.00
Maker, 19th Aug 2011, Mind Blast v1.1

Add importing instructions into the map.
Why exclude int bonus for damage?
You should filter out dead units when adding units to Damage Group.
Otherwise the spell looks ok triggering-wise.
Pharaoh_: Review on request (updated)

• In your loop trigger, check if the picked unit is magic immune to prevent further damage (and checks).
• In your loop trigger, check the ability level of the caster, so that, in case he levels this ability up, while damaging the units, the new bonus will be applied instead (since it's a matter of personal taste, you might want to use a global boolean that checks if the user would like this change in the trigger).
• I suggest improving it and further upgrading it to support stacks. This way, if a unit is struck twice by this spell, it should be dealt the additional damage, depending on the number of sources. Right now, it looks quite flat.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Also, this indexing is really simple and potentially horrendous. I don't know why this
style is still being promoted.

The indexing works like this:

Unit casts spell; MaxSize is now 1,
Unit casts spell; MaxSize is now 2,
The first spell finishes, so when the loop starts it iterates over the empty first spell and
then gets to 2.

Now, if the spell overlapped several times, then you are looping over even more
finished spells until you can get to the working ones.

So here's the worst kick with the indexing - if the spells are always being cast, always
overlapping each other, it's doomed. You'll be looping over dozens, then hundreds then
thousands of instances waiting to get to the active ones, then you'll hit index 8191 and
your "MUI" system will completely and utterly fail.

Therefore, you want to use one of the following to make sure this does NOT happen:

Hanky's Dynamic Indexing: http://www.hiveworkshop.com/forums/spells-569/gui-dynamic-indexing-template-144325/

Hashtables: http://www.hiveworkshop.com/forums/...9/complete-beginners-guide-hashtables-197381/

Or Unit Indexer: http://www.hiveworkshop.com/forums/spells-569/gui-unit-indexer-1-2-0-2-a-197329/
 
Unless anyone has not covered this not to sure , My bad :)

But when you use the indexing event;
Dont you normally use ;
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • Index1 Equal to 0
    • Then - Actions
      • Trigger - Turn on <gen>
    • Else - Actions
Instead of having it later on in the trigger;
This allows it to detect if any instances of the spell are running?
Then in the second trigger, as i see you do, it turns if off if no one is using the spell;
I think thats right?

Evilcrizpy
 
I am trying to change the indexing to Hanky's dynamic indexing, but running into a couple problems. Here is my progress.

Ahhh okay;
Possibly for new users like your self look into bribes Unit Indexer;
Unit Indexer
and then look to my spell;
Cloud spiral
For ideas on how to use the Unit indexer into creating spells;
Would be a greater idea, till you understand the use of recycling.

Evilcrizpy
 
Level 8
Joined
Apr 23, 2010
Messages
312
Jay the Editor said:
It's more like burning the mana rather than draining the mana. Ineffective MUI system as Bribe said.
I made it so that the mana is drained from the targeted units and added to the caster so it's more like drain now. Also, I changed the indexing by using bribes unit indexer.

Spell now runs and works smoothly :)
 
I made it so that the mana is drained from the targeted units and added to the caster so it's more like drain now. Also, I changed the indexing by using bribes unit indexer.

Spell now runs and works smoothly :)

Shall test it once i get chance to download it;
But from the triggers it looks abit better.
Could do with some polishing off the triggers
Rating 3.5/5
Evilcrizpy

Edit :

Scrap that, just add remove MB_Caster from spell group,
then check if it is empty, and if true destroy spell group.
 
Last edited:
Level 8
Joined
Apr 23, 2010
Messages
312
@EvilCrizpy, ah ok that makes sense, and less variables to work with :) Thanks for the feedback by the way!

Made the changes below.
  • Unit Group - Remove MB_Caster[MB_TempKey] from MB_DamageGroup[MB_TempKey]
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (MB_SpellGroup is empty) Equal to True
    • Then - Actions
      • Trigger - Turn off (This trigger)
    • Else - Actions
 
@EvilCrizpy, ah ok that makes sense, and less variables to work with :) Thanks for the feedback by the way!

Made the changes below.
  • Unit Group - Remove MB_Caster[MB_TempKey] from MB_DamageGroup[MB_TempKey]
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (MB_SpellGroup is empty) Equal to True
    • Then - Actions
      • Trigger - Turn off (This trigger)
    • Else - Actions
No no from the MB_SpellGroup,
and do that trigger outside of the pick all units in MB_SpellGroup
Also i was wrong my bad :)
dont turn off the trigger after checking just, destroy MB_SpellGroup if it is empty, still using the index to turn off trigger,
But i guessyou can do that way :)
Less triggers
 
Level 8
Joined
Apr 23, 2010
Messages
312
Oops, I thought I did use MB_SpellGroup. So I should put the trigger below on the top of the actions?
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (MB_SpellGroup is empty) Equal to True
    • Then - Actions
      • Trigger - Turn off (This trigger)
    • Else - Actions
 
Level 12
Joined
Aug 12, 2008
Messages
349
Bribe, nope. When I start to learn MUI, I found this old indexing system is easier to understand the concept of how a spell trigger run in MUI. For a new learner, they probably find it harder in understanding custom scripts in your Unit Indexer. :3 Anyway, at least the editor of this spell (Mind Blast) starts to learn Hanky's dynamic indexing system. I guess it's all solve :3
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
anything u use twice or more should be stored into a variable and the variable should be used. example: u use picked unit a lot. store it into a tempUnit variable.

i also dont like all the groups u create and destroy by doing it this way. thats more of an opinion. this can be done without all the unit groups and just use an array indexed method.
u also wouldnt need bribes indexer if u dont use the groups.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
- No need for MB_Caster[MB_TempKey] = No unit, and alike
- No need for Remove MB_Caster[MB_TempKey] from MB_SpellGroup during cast time
- Greater than or equal to >>> Greater than
- Save the ability level during cast time not in the loop
- The pick magic immune and unit is dead should be filtered at out at casting time or check if magic immune is false and unit is alive then do the damage
- Effects should be configurables
 
Level 2
Joined
Jul 15, 2016
Messages
26
13oot-Me I have found a bug here. It is when you cast Mind Blast spell on any unit that has a spell of Spiked Carapace or Thorns Aura, it will cause you do deal the damage equal to the target unit that have been damaged.
 
Top