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

[Trigger] Require help with a MUI spell

Status
Not open for further replies.
Level 19
Joined
Jun 16, 2007
Messages
1,574
Hello, i'm currently learning to make MUI spells.

So started triggering a MUI Ki Blast (For my dragonball Z map)

so far this is what i have:

  • Ki Blast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ki Blast (Kamehameha)
    • Actions
      • Set KiBlast_Caster = (Triggering unit)
      • Set TempLoc00 = (Target point of ability being cast)
      • Set TempLoc01 = (Position of KiBlast_Caster)
      • Unit - Pause KiBlast_Caster
      • Animation - Play KiBlast_Caster's Spell Channel animation
      • Unit - Create 1 Ki_Head for (Owner of KiBlast_Caster) at TempLoc01 facing (Facing of KiBlast_Caster) degrees
      • Set KiBlast_Dummy[1] = (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of KiBlast_Caster) Equal to Goku (Normal)
        • Then - Actions
          • Animation - Play KiBlast_Caster's Spell Throw animation
          • Trigger - Turn on Ki Blast Mve <gen>
        • Else - Actions
  • Ki Blast Mve
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Unit - Order KiBlast_Dummy[1] to Move To TempLoc00
      • Unit - Create 1 Ki_Trail for (Owner of KiBlast_Caster) at (Position of KiBlast_Dummy[1]) facing (Facing of KiBlast_Caster) degrees
      • Unit Group - Add (Random unit from (Units owned by (Owner of KiBlast_Caster) of type Ki_Trail)) to BeamTrail
      • Unit Group - Pick every unit in (Units within 50.00 of TempLoc00) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • KiBlast_Dummy[1] Equal to (Picked unit)
            • Then - Actions
              • Trigger - Turn off (This trigger)
              • Unit - Unpause KiBlast_Caster
              • Unit - Remove KiBlast_Dummy[1] from the game
              • Unit Group - Pick every unit in BeamTrail and do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Owner of (Picked unit)) Equal to (Owner of KiBlast_Caster)
                    • Then - Actions
                      • Unit - Remove (Picked unit) from the game
                    • Else - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (KiBlast_Caster is dead) Equal to True
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Unit - Unpause KiBlast_Caster
                  • Unit - Remove KiBlast_Dummy[1] from the game
                  • Unit Group - Pick every unit in BeamTrail and do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Owner of (Picked unit)) Equal to (Owner of KiBlast_Caster)
                        • Then - Actions
                          • Unit - Remove (Picked unit) from the game
                        • Else - Actions
                • Else - Actions
The thing i need to at the moment are:
- The way i've set it up, will it be mui (After i've added in remove etc etc)
- How do i make the Mve trigger detect properly when the Beam Head touches a unit or a destructable ? and when it comes to its destination.
 
No, this is not MUI. First of all you leak locations. Position of Unit leaks.
Reference:
[•] http://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/

Second of all, you don't use an Indexing System/Hashtable. When periodic-events triggers are involved within the coding aspect, you need to make the spell MUI. Hashtables are something Jass has known for years, but GUI got it implemented recently (patch 1.24c). Hashtables are slower than Indexing systems (I used to use Indexing systems, but then I moved to Hashtables, because they are less confusing -for me-).

Hashtables:
[•] http://www.hiveworkshop.com/forums/trigger-gui-editor-tutorials-279/hashtables-mui-133407/

Indexing System:
[•] http://www.hiveworkshop.com/forums/...stanceabilty-timers-custom-values-more-96460/

I also advise you to pick some spells from the Spells section that are approved and use Indexing Systems to realize what you need. Most likely, you will need an increasing integer variable, everytime the spell is cast, and an additional for loop, in the second periodic-event trigger.
  • Trigger1
  • Set MUI = (MUI + 1)
  • Set Caster[MUI] = (Triggering unit)
The above is an example of how to store the values for MUI-enhnanced triggering.
The following trigger is how you load them back:
  • Trigger2
  • Events
    • Time - Every 1.00 seconds of game-time
  • Conditions
  • Actions
    • For each (Integer NEW_MUI) from 1 to MUI, do (Actions)
      • Loop - Actions
        • Set CasterLoad[NEW_MUI] = Caster[MUI]
This will load the triggering unit from your previous trigger. Of course, this is an example. If you were about to load the caster, you would most likely add him in a global unit group and Pick every unit in (the unit group) in your periodic trigger:
  • Trigger1
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
  • Actions
    • Unit Group - Add (Triggering unit) to X_Group
    • Trigger - Turn on Trigger2 <gen>
  • Trigger2
  • Events
    • Time - Every 1.00 seconds of game-time
  • Conditions
  • Actions
    • Unit Group - Pick every unit in X_Group and do (Actions)
      • Loop - Actions
        • Set Point1 = (Position of (Picked unit))
        • Custom script: call RemoveLocation (udg_Point1)
The trigger above will claim the position of your caster from the first trigger (it is used for many many casters at the same time) and the Custom script removes the leak from the point creation.

Finally, I would like to mention arrays. When you make a spell that will use many points, don't create one variable per point used. You can create one variable with "Array" ticked and do it like this:
  • Set Points[1] = (Position of (Triggering unit))
  • Set Points[2] = (Target point of ability being cast)
  • Custom script: call RemoveLocation (udg_Points[1])
  • Custom script: call RemoveLocation (udg_Points[2])
Notice that your actions must be before the Custom script, because, if you add an action with a reference to the Points[2] for example, after you have removed that location, it will return nothing and the action will most likely happen to the center of the map, which is where non-declared points are set by default.
So, it has to be:
  • Trigger1
  • Set Points[1] = (Position of (Triggering unit))
  • Unit - Create 1 Footman for (Owner of (Triggering unit)) at Points[1] facing default building degrees
  • Custom script: call RemoveLocation (udg_Points[1])
and NOT

  • Trigger1
  • Set Points[1] = (Position of (Triggering unit))
  • Custom script: call RemoveLocation (udg_Points[1])
  • Unit - Create 1 Footman for (Owner of (Triggering unit)) at Points[1] facing default building degrees
 
Level 19
Joined
Jun 16, 2007
Messages
1,574
I know that i still need to add in those Custom scripts, i've just haven't added them in, thats why i've said
(After i've added in remove etc etc)

At the moment just changed all my variables to:
Array's so i can add at the end (player number of (Owner of (triggering unit)))

Which will help detect which unit is which, and so i can remove the Locations, without it bugging another casters event.
 
Level 8
Joined
Apr 30, 2009
Messages
338
i was in the same boat with spells, thinking i can just use arrays.

but as soon as I learned how to use hashtables, I can make pretty much anything I need MUI and leakless.

so learn hashtables and most triggered abilities become easymode

so to get you started,

you will need a trigger that looks like this, to assign each hashtable. you may not need a hashtable for every spell, but usually if you do need to use hashtables, you only need 1 per ability (maybe even 1 per hero class if you want to be really fancy):

  • create hashtables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set h_ki_blast = (Last created hashtable)
      • Hashtable - Create a hashtable
      • Set h_ability_2 = (Last created hashtable)
Ok so you have assigned each hashtable variable to an actual hashtable.

Here is one of the more complex spells on my map that you might be able to use as a guide. It's a dagger that will slow the target up to 6 seconds based on how far it is thrown, and also teleports the caster next to the target when it hits. It has 3 triggers: trigger 1 creates the projectile and saves hashtable values to the projectile, trigger 2 determines if the dagger is still moving or if it is close enough to impact, trigger 3 runs until the slow buff is supposed to be removed.

  • Phase Dagger 01
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to ASN-2 Phase Dagger
    • Actions
      • Set temp_point = (Position of (Triggering unit))
      • Set temp_point2 = (temp_point offset by 50.00 towards (Facing of (Triggering unit)) degrees)
      • Custom script: call RemoveLocation(udg_temp_point)
      • Unit - Create 1 P.ASN-1 Phase Dagger for (Owner of (Triggering unit)) at temp_point2 facing (Facing of (Triggering unit)) degrees
      • Custom script: call RemoveLocation(udg_temp_point2)
      • Hashtable - Save 1.00 as (Key duration) of (Key (Last created unit)) in H_PhaseDagger
      • Hashtable - Save 15.00 as (Key damage) of (Key (Last created unit)) in H_PhaseDagger
      • Hashtable - Save 1500.00 as (Key speed) of (Key (Last created unit)) in H_PhaseDagger
      • Hashtable - Save Handle Of(Triggering unit) as (Key caster) of (Key (Last created unit)) in H_PhaseDagger
      • Hashtable - Save Handle Of(Target unit of ability being cast) as (Key target) of (Key (Last created unit)) in H_PhaseDagger
      • Unit Group - Add (Last created unit) to G_PhaseDaggerP
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Phase Dagger 02 <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Phase Dagger 02 <gen>
        • Else - Actions
  • Phase Dagger 02
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in G_PhaseDaggerP) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in G_PhaseDaggerP and do (Actions)
            • Loop - Actions
              • Set temp_point = (Position of (Picked unit))
              • Set temp_point2 = (Position of (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger))
              • Set temp_real = (Distance between temp_point and temp_point2)
              • Custom script: call RemoveLocation(udg_temp_point)
              • Custom script: call RemoveLocation(udg_temp_point2)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • temp_real Less than ((Load (Key speed) of (Key (Picked unit)) from H_PhaseDagger) x R_FRAME_PROJECTILES)
                • Then - Actions
                  • Set temp_point = (Position of (Picked unit))
                  • Set temp_point2 = (Position of (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger))
                  • Unit - Move (Load (Key caster) of (Key (Picked unit)) in H_PhaseDagger) instantly to temp_point, facing temp_point2
                  • Unit - Order (Load (Key caster) of (Key (Picked unit)) in H_PhaseDagger) to Attack (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger)
                  • Special Effect - Create a special effect attached to the origin of (Load (Key caster) of (Key (Picked unit)) in H_PhaseDagger) using Abilities\Spells\NightElf\Blink\BlinkTarget.mdl
                  • Special Effect - Destroy (Last created special effect)
                  • Custom script: call RemoveLocation(udg_temp_point)
                  • Unit - Create 1 D.ASN-1 Phase Dagger for (Owner of (Picked unit)) at temp_point2 facing Default building facing degrees
                  • Custom script: call RemoveLocation(udg_temp_point2)
                  • Set temp_unit = (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger)
                  • Unit - Order (Last created unit) to Human Sorceress - Slow temp_unit
                  • Hashtable - Save (Load (Key duration) of (Key (Picked unit)) from H_PhaseDagger) as (Key duration) of (Key (Last created unit)) in H_PhaseDagger
                  • Hashtable - Save Handle Oftemp_unit as (Key target) of (Key (Last created unit)) in H_PhaseDagger
                  • Unit Group - Add (Last created unit) to G_PhaseDaggerT
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Phase Dagger 03 <gen> is on) Equal to False
                    • Then - Actions
                      • Trigger - Turn on Phase Dagger 03 <gen>
                    • Else - Actions
                  • Unit - Kill (Picked unit)
                  • Unit - Cause (Load (Key caster) of (Key (Picked unit)) in H_PhaseDagger) to damage (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger), dealing (Load (Key damage) of (Key (Picked unit)) from H_PhaseDagger) damage of attack type Hero and damage type Normal
                  • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in H_PhaseDagger
                  • Unit Group - Remove (Picked unit) from G_PhaseDaggerP
                • Else - Actions
                  • Hashtable - Save ((Load (Key duration) of (Key (Picked unit)) from H_PhaseDagger) + 0.20) as (Key duration) of (Key (Last created unit)) in H_PhaseDagger
                  • Set temp_point = (Position of (Picked unit))
                  • Set temp_point2 = (Position of (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger))
                  • Set temp_real = (Angle from temp_point to temp_point2)
                  • Custom script: call RemoveLocation(udg_temp_point2)
                  • Set temp_point2 = (temp_point offset by ((Load (Key speed) of (Key (Picked unit)) from H_PhaseDagger) x R_FRAME_PROJECTILES) towards temp_real degrees)
                  • Custom script: call RemoveLocation(udg_temp_point)
                  • Unit - Move (Picked unit) instantly to temp_point2, facing temp_real degrees
                  • Custom script: call RemoveLocation(udg_temp_point2)
                  • Hashtable - Save temp_real as (Key facing) of (Key (Picked unit)) in H_PhaseDagger
        • Else - Actions
          • Trigger - Turn off (This trigger)
  • Phase Dagger 03
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in G_PhaseDaggerT) Greater than 0
        • Then - Actions
          • Unit Group - Pick every unit in G_PhaseDaggerT and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Load (Key duration) of (Key (Picked unit)) from H_PhaseDagger) Greater than 0.00
                • Then - Actions
                  • Hashtable - Save ((Load (Key duration) of (Key (Picked unit)) from H_PhaseDagger) - R_FRAME_OVERTIME) as (Key duration) of (Key (Picked unit)) in H_PhaseDagger
                • Else - Actions
                  • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in H_BlessedHammer
                  • Unit - Remove ~Phase Dagger (Assassin) buff from (Load (Key target) of (Key (Picked unit)) in H_PhaseDagger)
                  • Unit - Remove (Picked unit) from the game
                  • Unit Group - Remove (Picked unit) from G_PhaseDaggerT
        • Else - Actions
          • Trigger - Turn off (This trigger)
remember that just one wrong entry will totally fuck over the whole spell, so keep in mind which triggers do what, and then you can diagnose where the spell is messing up when it inevitably works incorrectly the first time. if it doesnt even fire, trigger 1 is bad. if the dagger is created but doesnt move, trigger 2 is bad. if the buff is either removed instantly or never, then trigger 3 is bad. it also helps to have dummy units with actual models, so they are visible, to make sure they are being created and removed properly. and then just make them have no model after you have the spell working
 
Level 6
Joined
Mar 22, 2009
Messages
276
just change all the global variables into locals.. And as much as possible compress the two triggers into one.. Also make sure that the skill cooldown is enough to finish the cast time of spell.. That is the easiest way I know to make it MUI and MPI.
Yet it is risky to compress those triggers of yours having the "Time - Every X seconds" event.. Because when you compress it with the first trigger, the Every X seconds event will be replaced with a Wait or TriggerSleepAction which is known to be buggy. But still its worth trying if you know even a little jass.
 
Status
Not open for further replies.
Top