1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

{DEPRECATED / OUTDATED} Dynamic Values Storage

Discussion in 'Trigger (GUI) Editor Tutorials' started by Kingz, Mar 25, 2009.

  1. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6

    Dynamic values storage



    One note, this was called Paladon's integer array indexing system but after talking to PurplePoot he explained me why it cannot be named like that.

    Contents:


    -Introduction


    What is Dynamic values storage? It's and easy to use variable system used by spell makers to make Multi Unit instancable spells.
    Why use it? It is easy and i found no other way than it, though other ways exist.
    What do you need to use it - nothing it isn't a custom script or anything like that it is simply a variable based system.
    Can you make any spell in GUI MUI with this - the answer is yes.
    Okay without delay i will now introduce you how to set up before using the system.

    -Variables


    For using the system itself you only need 1 integer array variable, example:
    - index[] - this is the integer variable we are going to use for indexing
    Now how does it work that is pretty easy once you trigger out the first spell with this system, we are going to use several arrays of the variable index[]
    and i will explain the trigger below:
    Trigger

    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) *spell*
    • Actions
      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • index[1] Equal to (==) 0
        • Then - Actions
          • Trigger - Turn on loop <gen>
        • Else - Actions
      • Set index[1] = (index[1] + 1)
      • Set index[2] = (index[2] + 1)



    Now maybe you are asking yourself why are we using index[1] and index[2] for? Here is why:
    -index[1] variable we are going to increase and decrease whenever we initialize or finish the effect of the desired spell so if it is 0 when we begin to cast
    it we turn on the loop gen which will be our periodic trigger while when the spell effect finishes we decrease it and if it is 0 again then there are no more instances
    of our spells running and we can turn off the periodic trigger and reset the index[2] variable.
    -index[2] variable we are going to use for storing variables like units/damage/locations,etc. We are only going to increase it and never decrease it, why?
    Imagine you have 2 spells running at the same time and you decrease the index[2] value and the second spells variables get mixed up with the first one.
    So how to stop piling up of index[2] value? Easy when the spell effect finishes and we decrease index[1] variable we will if the index[1] is equal to 0(that means no spell instances are running)
    and we can reset the index[2] to 0.
    Now in loop triggers we are going to use index[n] variable where the n will vary from 2-y.
    Example:
    Trigger

    • loop
      • Events
        • Time - Every 1.00 seconds of game time
      • Conditions
      • Actions
        • Do Multiple ActionsFor each (Integer index[3]) from 1 to index[2], do (Actions)
          • Loop - Actions


    Why are we going to use index[3] variable and not for example LoopIntegerA? Cause IntegerA can cause a strange blizzard bug and it's cleaner this way.
    Now what we are doing in the trigger is we are going to cycle through each value of index[2] variable using index[3] variable, in plain words:
    you have 3 spell instances running and now each second you want an effect to happen so we cycle through each spell casted and do it's action while not messing up the
    other 2 spell instances by using the index through we stored them.

    -Making a first MUI spell with Dynamic Values Storage method


    Now the first MUI spell we are going to make is a DOT(damage over time) one.
    We will base it on storm bolt and rename it to Heart Stab.
    Then we prepare the necesary variables we have in mind:
    • unit array variable - target // for storing the target into a variable
    • unit array variable - damage_source // for gold/exp proper gain
    • real array variable - dpi // damage per interval
    • real array variable - duration // spell duration
    • string variable - dpi_effect // string of our damage effect
    • real array variable - damage_interval // damage interval in seconds
    • real array variable - interval_check // this variable will always have a starting value of 0 cause we are going to use it for damage interval checking

    Now the initial trigger setup:
    Trigger

    • HS init
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to (==) Heart Stab
      • Actions
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • index[1] Equal to (==) 0
          • Then - Actions
            • Trigger - Turn on loop <gen>
          • Else - Actions
        • -------- We check is there an active spell instance running already by the value of index[1] --------
        • -------- --- --------
        • Set index[1] = (index[1] + 1)
        • -------- We increase the index we are going to use for checking is there an active spell going on --------
        • -------- --- --------
        • Set index[2] = (index[2] + 1)
        • -------- We increase the index variable we are going to use for storing variables --------
        • -------- --- --------
        • Set damage_source[index[2]] = (Casting unit)
        • -------- we store the caster for damaging unit refrence --------
        • -------- --- --------
        • Set target[index[2]] = (Target unit of ability being cast)
        • -------- we store the target for the periodic events --------
        • -------- --- --------
        • Set damage_interval[index[2]] = 1.00
        • -------- we define the damage interval --------
        • -------- --- --------
        • Set dpi[index[2]] = 15.00
        • -------- we define the damage dealt per interval to the target --------
        • -------- --- --------
        • Set duration[index[2]] = 10.00
        • -------- we define the spell duration --------
        • -------- --- --------
        • Set dpi_effect = Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
        • -------- on the end we define the periodic damage effect string this shouldn't need to be a array variable if you don't plan on changing it depending on the spell level --------
        • -------- --- --------
        • Set interval_check = 0
        • -------- variable used for damage interval checking --------


    That is it, we stored all the values we need into variables which we stored via integer index for future use and now we can make the loop trigger.
    Now the most important thing we forgot, we didn't made it multi leveled, but with several modifications we can easily do that.
    Spells without multi level support aren't good so if you wish to make MUI spells at least add multi level suport to them.
    We are going to modify the values to our desire, i modifed them like this:
    Trigger

    • HS init
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to (==) Heart Stab
      • Actions
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • index[1] Equal to (==) 0
          • Then - Actions
            • Trigger - Turn on loop <gen>
          • Else - Actions
        • -------- We check is there an active spell instance running already by the value of index[1] --------
        • -------- --- --------
        • Set index[1] = (index[1] + 1)
        • -------- We increase the index we are going to use for checking is there an active spell going on --------
        • -------- --- --------
        • Set index[2] = (index[2] + 1)
        • -------- We increase the index variable we are going to use for storing variables --------
        • -------- --- --------
        • Set damage_source[index[2]] = (Casting unit)
        • -------- we store the caster for damaging unit refrence --------
        • -------- --- --------
        • Set target[index[2]] = (Target unit of ability being cast)
        • -------- we store the target for the periodic events --------
        • -------- --- --------
        • Set damage_interval[index[2]] = (1.25 - (0.25 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the damage interval --------
        • -------- --- --------
        • Set dpi[index[2]] = (10.00 + (5.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the damage dealt per interval to the target --------
        • -------- --- --------
        • Set duration[index[2]] = (5.00 + (5.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the spell duration --------
        • -------- --- --------
        • Set dpi_effect = Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
        • -------- on the end we define the periodic damage effect string this shouldn't need to be a array variable if you don't plan on changing it depending on the spell level --------
        • -------- --- --------
        • Set interval_check = 0
        • -------- variable used for damage interval checking --------


    And now we set up the settings for a multi leveled spell, the next step is making the loop trigger.
    First of all our damage_interval is a multiple of 0.25 so we are going to use a trigger which runs every 0.25 seconds.
    Then we are going to cycle through the index[2] values with index[3] variable.
    The loop trigger should look like this:
    Trigger

    • loop
      • Events
        • Time - Every 0.25 seconds of game time
      • Conditions
      • Actions
        • Do Multiple ActionsFor each (Integer index[3]) from 1 to index[2], do (Actions)
          • Loop - Actions
            • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • duration[index[3]] Greater than (>) 0.00
              • Then - Actions
                • Set duration[index[3]] = (duration[index[3]] - 0.25)
                • -------- we decrease the spell duration by 0.25 --------
                • -------- --- --------
                • Set interval_check[index[3]] = (interval_check[index[3]] + 0.25)
                • -------- we increase the interval_check variable --------
                • -------- --- --------
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • interval_check[index[3]] Greater than or equal to (>=) damage_interval[index[3]]
                    • Then - Actions
                      • Set interval_check[index[3]] = 0.00
                      • -------- we reset the interval_check variable --------
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • (target[index[3]] is alive) Equal to (==) True
                          • Then - Actions
                            • Unit - Cause damage_source[index[3]] to damage target[index[3]], dealing dpi[index[3]] damage of attack type Spells and damage type Normal
                            • -------- we damage the target dealing damage per interval --------
                            • -------- --- --------
                            • Special Effect - Create a special effect attached to the chest of target[index[3]] using dpi_effect
                            • Special Effect - Destroy (Last created special effect)
                            • -------- we create and destroy the periodic damage effect on the unit, i prefer using chest attach point --------
                          • Else - Actions
                            • Set duration[index[3]] = 0.00
                      • -------- if the target is alive we do actions if not we set the spell duration to 0 --------
                    • Else - Actions
                • -------- if the interval_check is equal or larger than damage interval we do actions --------
                • -------- --- --------
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • duration[index[3]] Equal to (==) 0.00
                    • Then - Actions
                      • Set index[1] = (index[1] - 1)
                      • -------- we reduce the index[1] variable cause one spell instance has ended --------
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • index[1] Equal to (==) 0
                          • Then - Actions
                            • Set index[2] = 0
                            • -------- we reset the index[2] to 0 cause there aren't any active spells running --------
                            • -------- --- --------
                            • Trigger - Turn off (This trigger)
                            • -------- we turn off this trigger, it is pointless for it to run if there isn't any spell for it to affect --------
                            • -------- --- --------
                            • Game - Display to (All players) the text: off
                            • -------- we can display a "debug" message to check will the trigger turn off when there aren't any other active spell --------
                          • Else - Actions
                      • -------- if the index[1] is 0 there are no active spell and we do actions --------
                    • Else - Actions
                • -------- if the spell duration is 0 we do actions --------
              • Else - Actions


    All parts of the trigger are commented if you don't understand something feel free to pm me or post your question here.
    There is a demo map attached which contains the spell we made feel free to test it's MUI-ness and does it bug.
    http://www.hiveworkshop.com/forums/attachment.php?attachmentid=52316&stc=1&d=1239785960


    -Using loops


    Now i am not talking about loop trigger or anything periodic, i am talking about loops used in spells. An example of loop would be:
    Trigger

    • Actions
      • Do Multiple ActionsFor each (Integer A) from 1 to 10, do (Actions)
        • Loop - Actions


    Now what can we do with loops? We can easily set up several functions like creating units/special effects and instead of writing a bunch fo lines to create
    a circle effect we just run a loop for the desired number of effects.
    In this example i will show you how to use loops to make an Incendiary Blast spell.
    I suggest everyone to use channel to make custom spells cause it is intended for that.
    The spell idea will be:
    • deals x damage to the target
    • if the target dies it will create several fire particles flying away(we will use loops for this)
    • upon fall the fire particles will deal damage in 150 AOE
    Okay first of all we are gonna need a dummy unit. What is a dummy unit? It is a unit without a model or with a model acting like a missile.
    The dummy we are going to use will use a custom model called dummy.mdx which has no model at all but has attachment points.
    Upon importing we set the dummy to use it and we set up our dummy changing:
    • it's abilities(i always add invulnerable and locust ability)
    • it's name
    • it's classification(if it is a worker)
    • change it's attacks enabled to none if attack is enables
    • change it's colision to 0
    • change it's movement type to fly(recommended)
    • change it's food cost to 0

    The dummy is prepared and now we make our trigger.
    I will comment all the variables i used in the trigger to make it easier to understand.
    Trigger

    • IB init
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to (==) Incendiary Blast
      • Actions
        • -------- First of all the first effect of the spell is instantly used so we can use array variables without indexing. --------
        • -------- - --------
        • Set IB_temp_real[0] = (50.00 + (100.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- - --------
        • Set IB_particle_count = 5
        • -------- We are going to use this variable for our loop --------
        • -------- - --------
        • Set IB_owner = (Owner of (Casting unit))
        • -------- - --------
        • Set IB_leak_point[1] = (Position of (Target unit of ability being cast))
        • -------- - --------
        • Unit - Cause (Casting unit) to damage (Target unit of ability being cast), dealing IB_temp_real[0] damage of attack type Spells and damage type Normal
        • Special Effect - Create a special effect attached to the chest of (Target unit of ability being cast) using Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
        • Special Effect - Destroy (Last created special effect)
        • -------- Causes instant damage and creates and destroys the explosion effect --------
        • -------- - --------
          • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Target unit of ability being cast) is dead) Equal to (==) True
            • Then - Actions
              • Set IB_temp_real[1] = (X of IB_leak_point[1])
              • Set IB_temp_real[2] = (Y of IB_leak_point[1])
              • Set IB_leak_point[2] = (Point(IB_temp_real[1], IB_temp_real[2]))
              • -------- We set up a point at which the particles start to move --------
                • Do Multiple ActionsFor each (Integer A) from 1 to IB_particle_count, do (Actions)
                  • Loop - Actions
                    • -------- - --------
                    • -------- Now we are going to set up a dummy(missile) parameters and it's indexing --------
                    • -------- - --------
                      • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • IB_loop_index[1] Equal to (==) 0
                        • Then - Actions
                          • Trigger - Turn on IB loop <gen>
                        • Else - Actions
                    • -------- - --------
                    • Set IB_loop_index[1] = (IB_loop_index[1] + 1)
                    • Set IB_loop_index[2] = (IB_loop_index[2] + 1)
                    • -------- We set up the integers used for indexing cause we will move the dummy unit every 0.03 second so we need indexing --------
                    • -------- - --------
                    • Set IB_loop_angle[IB_loop_index[2]] = (Random angle)
                    • -------- Defines the angle at which the particle moves --------
                    • -------- - --------
                    • Set IB_loop_max_distance[IB_loop_index[2]] = (Random real number between 150.00 and 300.00)
                    • -------- Defines the maximum distance which the missile travels --------
                    • -------- - --------
                    • Set IB_loop_damage_source[IB_loop_index[2]] = (Casting unit)
                    • -------- we store the caster for damage manipulation upon missile death --------
                    • -------- - --------
                    • Set IB_loop_damage[IB_loop_index[2]] = (25.00 + (25.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
                    • -------- we set the damage dealt around the missile upon it's death --------
                    • -------- - --------
                    • Set IB_loop_max_height[IB_loop_index[2]] = (Random real number between 300.00 and 500.00)
                    • -------- - --------
                    • Set IB_loop_speed[IB_loop_index[2]] = 6.00
                    • -------- We define the missile speed, it shouldn't be too high value to ensure a nice look of the spell --------
                    • -------- - --------
                    • Unit - Create 1 Dummy for IB_owner at IB_leak_point[2] facing IB_loop_angle[IB_loop_index[2]] degrees
                    • Unit - Turn collision for (Last created unit) Off
                    • Set IB_loop_missile_unit[IB_loop_index[2]] = (Last created unit)
                    • -------- We create the dummy(missile) and set it to a variable for loop movement --------
                    • -------- - --------
                    • Animation - Change (Last created unit)'s size to (50.00%, 50.00%, 50.00%) of its original size
                    • -------- We can change the dummies size/scale to scale the model attached to it --------
                    • -------- - --------
                    • Special Effect - Create a special effect attached to the chest of (Last created unit) using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                    • Set IB_loop_gfx[IB_loop_index[2]] = (Last created special effect)
                    • -------- We attach an model to the dummy and set the effect into a variable for later leak removal --------
                    • -------- - --------
                    • Set IB_loop_current_distance[IB_loop_index[2]] = 0.00
              • -------- We cycle through actions using integerA while the cycle number is defined by IB_particle_count variable --------
              • Custom script: call RemoveLocation(udg_IB_leak_point[2])
            • Else - Actions
        • Custom script: call RemoveLocation(udg_IB_leak_point[1])
        • -------- If the target died we create particles via loop --------
        • -------- - --------
        • -------- - --------
        • -------- That is all if the target is alive our spell has ended and there was no need for indexing --------


    Now we have set up our initial trigger and used the loop function for creating missile/particles instead of coping the same thing 5 times.
    This is quite usefull cause it shortens the time needed to do a lot of things.
    Now that we have set up our initial trigger we supose the target unit has died so we have created the dummy and now we need to move it.
    Be aware that the model dummy.mdx i used doesn't support Z angle changing but there is a one that does.
    I won't complicate the spell with that but i am going to use a parabola function which i will try to explaing better to you.
    Here is the parabola code we are going to use:
    Code (vJASS):

    function ParabolaZ takes real h, real d, real x returns real
     return (4 * h / d) * (d - x) * (x / d)
    endfunction
     

    Explanation:
    The function takes the real h which represents the maximum height we want the missile to achieve.
    The function takes the real d which represents the maximum distance we want the missile to be able to reach.
    The function takes the real x which represents the current distance the missile has traveled.
    Then the function calculates all the data we gave it and returns a height real.
    It can also be done via GUI but it will be messy.
    I will use a GUI version of parabola calculation.

    Here is how the loop trigger will look like:
    Trigger

    • IB loop
      • Events
        • Time - Every 0.03 seconds of game time
      • Conditions
      • Actions
        • Do Multiple ActionsFor each (Integer IB_loop_index[3]) from 1 to IB_loop_index[2], do (Actions)
          • Loop - Actions
            • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • IB_loop_missile_unit[IB_loop_index[3]] Not equal to (!=) No unit
              • Then - Actions
                • Set IB_loop_leak_point[1] = (Position of IB_loop_missile_unit[IB_loop_index[3]])
                • Set IB_loop_leak_point[2] = (IB_loop_leak_point[1] offset by IB_loop_speed[IB_loop_index[3]] towards IB_loop_angle[IB_loop_index[3]] degrees)
                • -------- We store the points we are going to use to avoid leaks. --------
                • -------- - --------
                • Unit - Move IB_loop_missile_unit[IB_loop_index[3]] instantly to IB_loop_leak_point[2]
                • -------- We move the dummy to the previously stored point --------
                • -------- - --------
                • Set IB_loop_current_distance[IB_loop_index[3]] = (IB_loop_current_distance[IB_loop_index[3]] + IB_loop_speed[IB_loop_index[3]])
                • -------- We increase the current distance variable which is used for parabola and for distance checking, it's initial value is almost always 0 --------
                • -------- - --------
                • Set IB_loop_temp_real[1] = IB_loop_max_height[IB_loop_index[3]]
                • Set IB_loop_temp_real[2] = IB_loop_max_distance[IB_loop_index[3]]
                • Set IB_loop_temp_real[3] = IB_loop_current_distance[IB_loop_index[3]]
                • -------- These are the variables we are going to use for parabola calculations, i used a IB_loop_temp_real variable to make it as simple as i can --------
                • -------- - --------
                • Custom script: set udg_IB_loop_temp_real[4] = ( 4 * udg_IB_loop_temp_real[1] / udg_IB_loop_temp_real[2]) * ( udg_IB_loop_temp_real[2] - udg_IB_loop_temp_real[3] ) * ( udg_IB_loop_temp_real[3] / udg_IB_loop_temp_real[2] )
                • -------- This variable is the calculation of parabola and it's value it the height we are going to asign to the missile, i used a custom script cause it is much easier than to calculate it in GUI --------
                • -------- - --------
                • Animation - Change IB_loop_missile_unit[IB_loop_index[3]] flying height to IB_loop_temp_real[4] at 0.00
                • -------- We aply the height change to the missile --------
                • -------- - --------
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • IB_loop_current_distance[IB_loop_index[3]] Greater than (>) IB_loop_max_distance[IB_loop_index[3]]
                    • Then - Actions
                      • Custom script: if udg_IB_loop_tmp_group[udg_IB_loop_index[3]] == null then
                      • Custom script: set udg_IB_loop_tmp_group[udg_IB_loop_index[3]] = CreateGroup()
                      • Custom script: endif
                      • -------- These 3 lines of custom scripts are used to avoid leaks, if IB_loop_tmp_group is equal to nothing we create it, else we do nothing --------
                      • -------- - --------
                      • Set IB_loop_tmp_group[IB_loop_index[3]] = (Units within 200.00 of IB_loop_leak_point[2] matching ((((Matching unit) is A structure) Equal to (==) False) and ((((Matching unit) is alive) Equal to (==) True) and ((((Matching unit) is A flying unit) Equal to (==) False) and ((((Matching unit) is Magic I
                      • -------- Okay i know this looks like a really big complex thing but it's simple, we set the group to match all units within 200 AOE of position of our missile and then we add conditions --------
                      • -------- - --------
                      • Custom script: set bj_wantDestroyGroup = true
                      • -------- This custom script sets the next used group to be destroyed after it is used, i prefer manualy destroying groups with "call DestroyGroup(n)" than this but this is easy to remember --------
                      • -------- - --------
                      • Unit Group - Pick every unit in IB_loop_tmp_group[IB_loop_index[3]] and do (Actions)
                        • Loop - Actions
                          • Unit - Cause IB_loop_damage_source[IB_loop_index[3]] to damage (Picked unit), dealing IB_loop_damage[IB_loop_index[3]] damage of attack type Spells and damage type Normal
                          • Special Effect - Create a special effect attached to the chest of (Picked unit) using Abilities\Weapons\FireBallMissile\FireBallMissile.mdl
                          • Special Effect - Destroy (Last created special effect)
                      • -------- we pick every unit we put in the group previously, damage them and create + destroy a special effect --------
                      • -------- - --------
                      • Unit - Kill IB_loop_missile_unit[IB_loop_index[3]]
                      • -------- We kill the dummy, cause we need it no more --------
                      • -------- - --------
                      • Special Effect - Destroy IB_loop_gfx[IB_loop_index[3]]
                      • -------- we destroy the effect we attached to evade leaks --------
                      • -------- - --------
                      • Special Effect - Create a special effect at IB_loop_leak_point[2] using Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
                      • -------- we create a effect at the impact point of the missile just for eyecandy --------
                      • -------- - --------
                      • Special Effect - Destroy (Last created special effect)
                      • -------- we destroy the last created effect to prevent leaks --------
                      • -------- - --------
                      • Custom script: set udg_IB_loop_missile_unit[udg_IB_loop_index[3]] = null
                      • -------- We null the missile_unit to make sure the actions won't repeat even if the effect has ended --------
                      • -------- - --------
                      • Set IB_loop_index[1] = (IB_loop_index[1] - 1)
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • IB_loop_index[1] Equal to (==) 0
                          • Then - Actions
                            • Set IB_loop_index[2] = 0
                            • Trigger - Turn off (This trigger)
                          • Else - Actions
                      • -------- i already explained what we do here before, if you don't know what i am talking about check the first part of the tutorial and the attached map. --------
                      • -------- - --------
                    • Else - Actions
                • -------- - --------
                • Custom script: set udg_IB_loop_temp_real[1] = 0
                • Custom script: set udg_IB_loop_temp_real[2] = 0
                • Custom script: set udg_IB_loop_temp_real[3] = 0
                • Custom script: set udg_IB_loop_temp_real[4] = 0
                • -------- setting the variables to 0 --------
                • -------- - --------
                • Custom script: call RemoveLocation(udg_IB_loop_leak_point[2])
                • Custom script: call RemoveLocation(udg_IB_loop_leak_point[1])
                • -------- removing leaks --------
              • Else - Actions



    Now maybe you asked yourself why do we destroy special effects we create instantly? It prevents leaks but is still usefull cause it will make the speical effect play it's death animation.
    Note: Some effects don't have death animation so they will play their whole animatiom(thunderclap for example) but this is most usefull for missile effects cause they all have death animations.
    You may notice i used some custom scripts where i could have used GUI functions, why? I find it easier, it would be pain in GUI to calculate:
    Code (vJASS):
    ( 4 * udg_IB_loop_temp_real[1] / udg_IB_loop_temp_real[2]) * ( udg_IB_loop_temp_real[2] - udg_IB_loop_temp_real[3] ) * ( udg_IB_loop_temp_real[3] / udg_IB_loop_temp_real[2] )

    I used custom scripts cause that is JASS codes in GUI, you can manipulate both GUI and JASS like this.
    Also the most important thing about custom scripts is that you can't make a decent spell with locations and unit groups without them.
    Why? You need them to clean leaks or it will affect the FPS.
    Also you may notice i used point variables called IB_leak_point and IB_loop_leak_point and i didn't used indexes on them, only simple values.
    I did that cause they are immediatly used and destroyed so there is no point in their indexing.
    This also aplies to IB_temp_real and IB_loop_temp_real variables, but as reals cannot be destroyed and don't leak i just set their values to 0.
    That concludes our loop part.
    http://www.hiveworkshop.com/forums/attachment.php?attachmentid=52317&stc=1&d=1239785960

    -Avoiding trigger overflow


    What do i mean with this? I recently saw a map with 70-80 triggers and that was a system!
    Now what did the maker of the system do, he made a trigger like this:
    Trigger

    • Events
      • Player - Player 1 (Red) Presses the Left Arrow key
    • Conditions
    • Actions


    For each player and a 4 periodic triggers for each player.
    Now to avoid that you can use array variables but what hapens when you use too much periodic triggers? It is uneficent.
    To avoid that you can easily make a trigger that runs each 0.01 second and checks is the time to do actions now.
    I wouldn't recommend doing this for all triggers but if you have a spell which uses multiple effects(example fading + location change) you can do the following:
    Trigger

    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • -------- I will comment only the first part of these variable cycles cause the second is the same --------
        • Do Multiple ActionsFor each (Integer General_index1[3]) from 1 to General_index1[2], do (Actions)
          • Loop - Actions
            • Set interval_check1[General_index1[3]] = (interval_check1[General_index1[3]] + 0.01)
            • -------- We increase our real array which we use for interval checking --------
            • -------- - --------
              • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • interval_check1[General_index1[3]] Greater than or equal to (>=) interval1[General_index1[3]]
                • Then - Actions
                  • Set interval_check1[General_index1[3]] = 0.00
                  • -------- Reseting the interval check variable --------
                  • -------- - --------
                  • -------- actions here --------
                • Else - Actions
            • -------- if the interval check variable value is equal to the interval variable value we reset the interval check variable value to 0 and do the actions we wanted --------
      • -------- - --------
        • Do Multiple ActionsFor each (Integer General_index2[3]) from 1 to General_index2[2], do (Actions)
          • Loop - Actions
            • Set interval_check2[General_index2[3]] = (interval_check2[General_index2[3]] + 0.01)
              • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • interval_check2[General_index2[3]] Greater than or equal to (>=) interval2[General_index2[3]]
                • Then - Actions
                  • Set interval_check2[General_index2[3]] = 0.00
                  • -------- actions here --------
                • Else - Actions
            • -------- actions here --------
      • -------- - --------
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Multiple ConditionsAnd - All (Conditions) are true
              • Conditions
                • General_index1[1] Equal to (==) 0
                • General_index2[1] Equal to (==) 0
          • Then - Actions
            • -------- If the values of the primary indexes is 0 --------
            • -------- - --------
            • Set General_index1[2] = 0
            • Set General_index2[2] = 0
            • Trigger - Turn off (This trigger)
            • -------- we reset the indexes we use for variables array and turn off the trigger --------
          • Else - Actions
      • -------- What we do here is we check for all indexes we used in the loop if their primary index value is 0 then if it is we set their secondary indexing value to 0 and turn off the trigger --------


    And that is that, if all loop effects aren't active we just turn off the trigger and reset their indexes.
    This concludes this part of the tutorial.

    -PGS(Paladon's General System)


    Not tested with latest versions of WC3, may cause issues.
    The map contains 3 trigger which are used as the PGS.
    It contains:
    • tree revival
    • unit revival
    • other stuff

    http://www.hiveworkshop.com/forums/attachment.php?attachmentid=52320&stc=1&d=1239785960

    Dynamic values storage with DIR system



    First of all what is DIR system? Is an addition to the indexing system which makes the index used for actual indexing get recycled.
    To impement it we are going to take example #1.
    Now we are going to add several new variables:
    • HS_dyn_index => Integer variable, not array
    • HS_index_selected => Boolean variable, not array
    • HS_index_is_empty => Boolean variable, array

    First of all you should know how the the basics i wrote about in the upper section of the tutorial, if you don't know first read the upper part of the tutorial.
    Now we are going to make some changes, first of all we won't be using HS_index[2] for indexing, instead we are going to use HS_dyn for indexing.
    The second boolean variable is going to be used to make sure that HS_dyn_index carries an value which is not already taken.
    The HS_index_is_empty[] we are going to use in the loop trigger for checking if the array is free again.
    Now after reworking the initial HS init trigger it looks like this:
    Trigger

    • HS init
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to (==) Heart Stab
      • Actions
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • HS_index[1] Equal to (==) 0
          • Then - Actions
            • Trigger - Turn on loop <gen>
          • Else - Actions
        • -------- We check is there an active spell instance running already by the value of index[1] --------
        • -------- --- --------
        • Set HS_index[1] = (HS_index[1] + 1)
        • -------- We increase the index we are going to use for checking is there an active spell going on --------
        • -------- --- --------
        • Set HS_index_selected = False
        • -------- We haven't selected the value of HS_dyn index which we are going to use for indexing so we set this to false --------
        • -------- --- --------
          • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • HS_dyn_index Less than (<) HS_index[2]
              • HS_index_is_empty[HS_dyn_index] Equal to (==) True
              • HS_dyn_index Not equal to (!=) 0
            • Then - Actions
              • -------- If the conditions are true that mean we already declared a HS_dyn_index in the loop trigger and it's unused so we don't set the HS_dyn index to any other value, we just simply leave it at the current value and set HS_index_selected = true --------
              • Set HS_index_selected = True
            • Else - Actions
              • Do Multiple ActionsFor each (Integer HS_index[0]) from 1 to HS_index[2], do (Actions)
                • Loop - Actions
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • HS_index_selected Equal to (==) False
                      • HS_index_is_empty[HS_index[0]] Equal to (==) True
                    • Then - Actions
                      • -------- If we have found an unused array and the HS_dyn_index isn't already selected we set the HS_dyn_index to that value and set the HS_index_selected to true to make sure the loop stops --------
                      • Set HS_dyn_index = HS_index[0]
                      • -------- We set the value of the dynamic index to first empty array value and declare that we have selected the index --------
                      • -------- --- --------
                      • Set HS_index_selected = True
                      • -------- We declare that the index is selected so the loop stops --------
                    • Else - Actions
              • -------- We cycle throug HS_index[2] searching for an empty index by using HS_index_is_empy boolean, i am going to use HS_index[0] for cycling in this case --------
              • -------- --- --------
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • HS_index_selected Equal to (==) False
                  • Then - Actions
                    • -------- If HS_index_selected is false that means we didn't found any free array value so we increase the value of HS_index[2] and set the value of HS_dyn_index to it so we avoid conflicts --------
                    • Set HS_index[2] = (HS_index[2] + 1)
                    • -------- Increasing HS_index[2] value by 1 --------
                    • -------- --- --------
                    • Set HS_dyn_index = HS_index[2]
                    • -------- Setting the HS_dyn_index to the value of HS_index[2] --------
                  • Else - Actions
              • -------- If there weren't any free array value when we cycled through the HS_index[2] we increase the HS_index[2] value and set the HS_dyn_index to match the value of HS_index[2] --------
        • Game - Display to (All players) the text: (Debug Message: Storing Index Value: + (String(HS_dyn_index)))
        • -------- Dynamic Index Recycling --------
        • Set HS_index_is_empty[HS_dyn_index] = False
        • -------- We now set the HS_index_is_empty to false cause we are going to use the HS_dyn_index for an array for indexing --------
        • -------- --- --------
        • Set damage_source[HS_dyn_index] = (Casting unit)
        • -------- we store the caster for damaging unit refrence --------
        • -------- --- --------
        • Set target[HS_dyn_index] = (Target unit of ability being cast)
        • -------- we store the target for the periodic events --------
        • -------- --- --------
        • Set damage_interval[HS_dyn_index] = (1.25 - (0.25 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the damage interval --------
        • -------- --- --------
        • Set dpi[HS_dyn_index] = (10.00 + (5.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the damage dealt per interval to the target --------
        • -------- --- --------
        • Set duration[HS_dyn_index] = (5.00 + (5.00 x (Real((Level of (Ability being cast) for (Casting unit))))))
        • -------- we define the spell duration --------
        • -------- --- --------
        • Set dpi_effect = Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
        • -------- on the end we define the periodic damage effect string this shouldn't need to be a array variable if you don't plan on changing it depending on the spell level --------
        • -------- --- --------
        • Set interval_check[HS_dyn_index] = 0.00
        • -------- variable used for damage interval checking --------

    The trigger is well commented but if you have any additional questions feel free ask in this thread or send me a private message.
    Now we aren't finished we still need to dynamicaly free the index arrays when they aren't used we will do so in the loop trigger:
    Trigger
    • loop
      • Events
        • Time - Every 0.25 seconds of game time
      • Conditions
      • Actions
        • Do Multiple ActionsFor each (Integer HS_index[3]) from 1 to HS_index[2], do (Actions)
          • Loop - Actions
            • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • duration[HS_index[3]] Greater than (>) 0.00
              • Then - Actions
                • Set duration[HS_index[3]] = (duration[HS_index[3]] - 0.25)
                • -------- we decrease the spell duration by 0.25 --------
                • -------- --- --------
                • Set interval_check[HS_index[3]] = (interval_check[HS_index[3]] + 0.25)
                • -------- we increase the interval_check variable --------
                • -------- --- --------
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • interval_check[HS_index[3]] Greater than or equal to (>=) damage_interval[HS_index[3]]
                    • Then - Actions
                      • Set interval_check[HS_index[3]] = 0.00
                      • -------- we reset the interval_check variable --------
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • (target[HS_index[3]] is alive) Equal to (==) True
                          • Then - Actions
                            • Unit - Cause damage_source[HS_index[3]] to damage target[HS_index[3]], dealing dpi[HS_index[3]] damage of attack type Spells and damage type Normal
                            • -------- we damage the target dealing damage per interval --------
                            • -------- --- --------
                            • Special Effect - Create a special effect attached to the chest of target[HS_index[3]] using dpi_effect
                            • Special Effect - Destroy (Last created special effect)
                            • -------- we create and destroy the periodic damage effect on the unit, i prefer using chest attach point --------
                          • Else - Actions
                            • Set duration[HS_index[3]] = 0.00
                      • -------- if the target is alive we do actions if not we set the spell duration to 0 --------
                    • Else - Actions
                • -------- if the interval_check is equal or larger than damage interval we do actions --------
                • -------- --- --------
                  • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • duration[HS_index[3]] Less than or equal to (<=) 0.00
                    • Then - Actions
                      • Set HS_index[1] = (HS_index[1] - 1)
                      • -------- we reduce the index[1] variable cause one spell instance has ended --------
                      • -------- --- --------
                      • Set HS_index_is_empty[HS_index[3]] = True
                      • -------- This spell instance has finished it's effect and we "free" the array using this variable --------
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • HS_index_selected Equal to (==) False
                          • Then - Actions
                            • Set HS_dyn_index = HS_index[3]
                            • -------- We set the HS_dyn_index to an value of this index so the next time when the spell is cast it has an value of an array that is not taken --------
                            • -------- --- --------
                            • Set HS_index_selected = True
                            • -------- We have just set an value for HS_dyn_index so we have selected the index we are going to use the next time a spell using this indexing is cast --------
                          • Else - Actions
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • HS_index[1] Not equal to (!=) 0
                            • HS_index[3] Equal to (==) HS_index[2]
                          • Then - Actions
                            • Set HS_index[2] = (HS_index[2] - 1)
                            • Game - Display to (All players) the text: Debug Message: Loop...
                          • Else - Actions
                      • -------- If this is the spell instance which uses the highest value of HS_index[2] we can reduce the HS_index[2] value to shorten the loop process --------
                      • -------- --- --------
                        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • HS_index[1] Equal to (==) 0
                          • Then - Actions
                            • Set HS_index[2] = 0
                            • -------- we reset the index[2] to 0 cause there aren't any active spells running --------
                            • -------- --- --------
                            • Set HS_dyn_index = 0
                            • -------- We also reset the HS_dyn_index to 0 --------
                            • -------- --- --------
                            • Trigger - Turn off (This trigger)
                            • -------- we turn off this trigger, it is pointless for it to run if there isn't any spell for it to affect --------
                            • -------- --- --------
                            • Game - Display to (All players) the text: off
                            • -------- we can display a "debug" message to check will the trigger turn off when there aren't any other active spell --------
                          • Else - Actions
                      • -------- if the index[1] is 0 there are no active spell and we do actions --------
                    • Else - Actions
                • -------- if the spell duration is 0 we do actions --------
              • Else - Actions
                • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • HS_index[1] Not equal to (!=) 0
                    • HS_index[3] Equal to (==) HS_index[2]
                  • Then - Actions
                    • Set HS_index[2] = (HS_index[2] - 1)
                    • Game - Display to (All players) the text: Debug Message: Loop...
                  • Else - Actions
                • -------- If this is the spell instance which uses the highest value of HS_index[2] we can reduce the HS_index[2] value to shorten the loop process and cause it didn't mathc the condition it means it isn't doing anything so we decrease the index --------

    To test dynamic indexing recycling i have made a timer and a debug message in the demo map.
    This way there is a possibility to exceed maximum array size and to do it you must:
    • Cast the spell every 1 second
    • If we take the spell lasts 15 seconds that means 15 instances per unit max
    • So that means you will exceed the array limit if you have about 550 units casting the spell in the same time every single second
    Possible but i think only in theory.
    I think the tutorial may be aproved now that i fixed the issue and implanted Dynamic Index Recycling in the tutorial.
    Demo Map:
    http://www.hiveworkshop.com/forums/attachment.php?attachmentid=52319&stc=1&d=1239786126
    NOTE: The name of the map is MUI example 4 cause i deleted a part of my tutorial that had the MUI example 3 map.
    Credits:
    Moyack for the parabola formula

    Now this is where the tutorial ends for now. I may add more informations and chapters but for now this should do.
    I hope this helped you^^
     

    Attached Files:

    Last edited by a moderator: Sep 27, 2011
  2. Palaslayer

    Palaslayer

    Joined:
    Jun 16, 2008
    Messages:
    1,779
    Resources:
    66
    Icons:
    62
    Packs:
    1
    Spells:
    2
    Tutorials:
    1
    Resources:
    66
  3. NiddHogg-kun

    NiddHogg-kun

    Joined:
    Sep 24, 2007
    Messages:
    268
    Resources:
    2
    Icons:
    2
    Resources:
    2
    good toturial but you forgot to say that there is no way to make Meathook ^^
    i tried 3 times o_O
     
  4. Palaslayer

    Palaslayer

    Joined:
    Jun 16, 2008
    Messages:
    1,779
    Resources:
    66
    Icons:
    62
    Packs:
    1
    Spells:
    2
    Tutorials:
    1
    Resources:
    66
    sure that it is impossible?
     
  5. Yixx

    Yixx

    Joined:
    Oct 12, 2008
    Messages:
    1,492
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Found one mistake in your whole thing ^^
    At least i think it should have 'check' between 'will' and 'if'
    But whatever! That is a minor thing,,

    The tutorial is nice! You really explain how to use the indexing in more ways!
    The only thing is readability, I myself would have set the triggers (and one jass function) in (hidden) (/hidden) taggs, since it reads easier and makes the post shorter (à vu, if you know what i mean),,
    And i suggest next time you make the triggers and copy them ,cause some things arent like in normal WE (Or did you use a 3rd party tool?),, this is also for readability and for noobs that will ask: 'Where can you find the "(==)" part of that condition?'
    But just a suggestion ;)

    Other then this: A great tutorial which really explains why GUI isnt that bad after al! =D
    +rep
     
  6. NiddHogg-kun

    NiddHogg-kun

    Joined:
    Sep 24, 2007
    Messages:
    268
    Resources:
    2
    Icons:
    2
    Resources:
    2
    yes i am sure i tried one spell. It works but in sometime it will not work becouse of max array size(~~8000) so it will bug
    i tried to recycle that spell. Well i will send you the spell and you will check if you want ^^


    EDIT:
    meh:
    vBulletin Message
    Invalid Attachment specified. If you followed a valid link, please notify the administrator
     
  7. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    @Yixx
    Ah it shows like that to me...
    I don't know why, possibly cause of the newgen + UMSWE + WEU it automaticaly adds that....
    But i think the users won't have a hard time understanding that "equal to" is "==".

    @All
    Please tell me for any kind of bugs in the code/maps.
    Feedback or suggestion are welcome.
    Also i am from Serbia, it's not like my native language is English...
    So cut the slack on the typos/grammar please...
     
  8. Rmx

    Rmx

    Joined:
    Aug 27, 2007
    Messages:
    1,088
    Resources:
    18
    Icons:
    3
    Spells:
    15
    Resources:
    18
    BombShell Tutorial actually i learned something about unit Groups.

    Also i have been using this system for a long time and it works 10/10.

    Kingz GREAT JOB and + REP.

    @Nidhogg-Kun and Palaslayer
    Yes u can do a meat hook, i have done it and will be uploading it in my newest spellpack, also this system is BULETPROOF u can do everything with ;)

    .....to all of ... look at the irony i made Paladon Judgment spell in GUI but not gonna upload it ;) .

    Review : DO NOT NEED A REVIEW 10/10 ... OFC ....

    BTW why this Parabola u can use Paladon system JUMP also it is 99% Parabola and more easy ;)
     
  9. Paladon

    Paladon

    Joined:
    Dec 6, 2007
    Messages:
    2,083
    Resources:
    42
    Icons:
    28
    Packs:
    2
    Spells:
    12
    Resources:
    42
    I made a meathook in GUI, of course multi unit instancable, some time ago.
    Shall i search it for you?

    Next to that, the tutorial looks good.

    EDIT: Nidd, 8000 array limit, do you really need 8000 projectile (meathook) effects at the same time? o_O
     
    Last edited: Mar 26, 2009
  10. Kwah

    Kwah

    Joined:
    May 9, 2007
    Messages:
    3,391
    Resources:
    8
    Icons:
    5
    Maps:
    1
    Tutorials:
    2
    Resources:
    8
    Yes.

    Anyway. Poke me on Sunday and I'll critique this.

    EDIT: WHAR ARE MAH CREDITS?
     
    Last edited: Mar 29, 2009
  11. Mage_Goo

    Mage_Goo

    Joined:
    Jun 1, 2008
    Messages:
    366
    Resources:
    2
    Spells:
    2
    Resources:
    2
    nice tutorial...
    now I'm learning how to use (possibly make) MUI index.....
    hmm, one question:
    if (example) unit cast a long use spell that using this index (like triggered immolation) and there was unit that cast the same spell, and another unit cast it again, the first then finish it, and another cast it, etc.... and by any chance, the index[1] never drop to zero, and when it reach above 80000, it will cause bug, am i right?

    and for the parabolic formula, why not use this:
    he say this can be done in GUI and work.
    [thread=18324]see the thread here[/thread]

    Overall, great job. +rep
     
  12. NiddHogg-kun

    NiddHogg-kun

    Joined:
    Sep 24, 2007
    Messages:
    268
    Resources:
    2
    Icons:
    2
    Resources:
    2
    y Paladon please search it for me ^^
     
  13. Rmx

    Rmx

    Joined:
    Aug 27, 2007
    Messages:
    1,088
    Resources:
    18
    Icons:
    3
    Spells:
    15
    Resources:
    18
    @Mage-Goo

    Well even if they cast it alot do u think in any kind of map there will be 8000 HERO with the same spell ???? also u can apply a Recycle system ;) to recycle ur spell so when someone finishes it will recycle him and drop -1 ;)
     
  14. PurplePoot

    PurplePoot

    Joined:
    Dec 14, 2005
    Messages:
    11,161
    Resources:
    3
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    Resources:
    3
    Blah. Wasteful and doesn't work for a lot of implementations. You should look into how vJass allocates indexes and then implement that algorithm into GUI.

    It's a nasty problem though. I wrote a tutorial using aforementioned method but some GUIers found it hard to understand because of that, while others (such as here) write tutorials using significantly worse methods that break down for many things, but are easier to understand.
     
  15. Rmx

    Rmx

    Joined:
    Aug 27, 2007
    Messages:
    1,088
    Resources:
    18
    Icons:
    3
    Spells:
    15
    Resources:
    18
    PurplePoot ur mistaken u like vJass very much but there is alot of GUIers.
    And By the way when i learned the index system from Paladon and started to use
    indexing and making my spells, after that i saw that JASS is much much easy than GUI.
    Now i'm learning Jass and it's much easy to me after i learned GUI alot ;)

    this Tutorial is GREAT ! A+ ..... i will accept it and approve it with my eyes closed x)
     
    Last edited: Mar 26, 2009
  16. TheBlooddancer

    TheBlooddancer

    Joined:
    Jun 24, 2008
    Messages:
    2,911
    Resources:
    0
    Resources:
    0
    Please put the triggers in hidden tags for all us who doesn't have 1200 x 2800 screens.
     
  17. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    Okay i will put hidden tags around the triggers.
    But how do you do that?
     
  18. Yixx

    Yixx

    Joined:
    Oct 12, 2008
    Messages:
    1,492
    Resources:
    3
    Spells:
    3
    Resources:
    3
    it uses:
    [hidden.][/hidden.]
    Only both without the '.' ,, try it yourself ;)
     
  19. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    Okay i found it, it's the spyglass button in the advanced editing options.
    Right from the trigger tags.
    EDIT:
    Added the hidden tags to the tutorial.
     
  20. Palaslayer

    Palaslayer

    Joined:
    Jun 16, 2008
    Messages:
    1,779
    Resources:
    66
    Icons:
    62
    Packs:
    1
    Spells:
    2
    Tutorials:
    1
    Resources:
    66
    u didnt know that ^^