• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Making a spell MUI

Status
Not open for further replies.
Level 7
Joined
Aug 31, 2011
Messages
125
I have created a spell called Invulnerable Field and it has leaks, i know :p, but anyways i removed leaks and stuff and now the spell can be casted more than one time at a time :p. But! i am running into a problem. Its just the extra Special Effects tho, but even still what it does is...
When the spell is casted One time at a time: Success
When the spell is casted Two times/More at a time: Failed, Reason: When it it casted at first the special effects in the middle (Tome of Retraining) it does good, but once someone else uses it, the person who is casting it first, there special effects are gone and it moves instantly to the second person's special effect area... I would also like to know if i can improve the main trigger of it also, like leaks and stuff.
Heres the Trigger:
  • Invulnerable Field
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Invulnerable Field
    • Actions
      • For each (Integer A) from 1 to 72, do (Actions)
        • Loop - Actions
          • Unit - Create 1 Laser Effects (Hidden) for (Owner of (Triggering unit)) at ((Position of (Triggering unit)) offset by 700.00 towards (10.00 x (Real((Integer A)))) degrees) facing Default building facing degrees
          • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
      • Trigger - Run Special Effects <gen> (ignoring conditions)
      • Unit - Create 1 Invulnerable User for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing degrees
      • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
      • Set Laser_Taker[1] = (Last created unit)
      • Hero - Set (Last created unit) Hero-level to 6, Hide level-up graphics
      • Unit - Add Invulnerable Field (Unit) to (Last created unit)
      • Unit - Order (Last created unit) to Orc Shadow Hunter - Big Bad Voodoo
      • Unit - Create 1 Laser Taker for Neutral Hostile at (Position of (Triggering unit)) facing Default building facing degrees
      • Set Laser_Taker[2] = (Last created unit)
      • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
      • For each (Integer A) from 1 to 72, do (Actions)
        • Loop - Actions
          • Unit - Create 1 Laser Effects for (Owner of (Triggering unit)) at ((Position of (Triggering unit)) offset by 700.00 towards (30.00 x (Real((Integer A)))) degrees) facing Default building facing degrees
          • Unit - Order (Last created unit) to Human Blood Mage - Siphon Mana Laser_Taker[2]
          • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
      • Set Position = (Triggering unit)
      • Set PositionReal = (Position of Position)
      • Set UnitGroup = (Units within 700.00 of PositionReal matching (((Owner of (Matching unit)) is an enemy of (Owner of (Triggering unit))) Equal to True))
      • Unit Group - Pick every unit in UnitGroup and do (Unit - Cause (Triggering unit) to damage (Picked unit), dealing 300.00 damage of attack type Spells and damage type Normal)
      • Custom script: call RemoveLocation(udg_PositionReal)
      • Custom script: call DestroyGroup(udg_UnitGroup)
  • Special Effects
    • Events
    • Conditions
    • Actions
      • For each (Integer B) from 1 to 25, do (Actions)
        • Loop - Actions
          • Wait 1.00 seconds
          • Special Effect - Create a special effect at (Position of Laser_Taker[1]) using Abilities\Spells\Items\TomeOfRetraining\TomeOfRetrainingCaster.mdl
          • Special Effect - Destroy (Last created special effect)
Andddd,,, thats it :p. Please tell me how i can improve the spell and the special effects trigger. Thanks in advanced. ~xIceShotx
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1) You can always change "Owner of Triggering unit" for "Triggering Player".
2) If you're going to use one unit (Triggering Unit) a lot, set UnitVariable = Triggering Unit. It will improve the efficiency.
3) Position Of Triggering Unit (1 Point) with offset (Another point). You have to declare the Position of Triggering Unit in one Point Variable, and then Declare the Point with Offset in another variable. Remove both at the end
4) PositionReal = Position of Position?. Set those at the start of actions block and use them.

Special Effects:
1) NEEEEEEEEEEVER use "waits" inside any kind of Loop.

Anyway, whenever you want to make a spell casteable by several units at the same time, use Hashtables, or make some good efficient handle of variables to control stuff. (Hashtables is better for this anyway).

I don't get why're you creating 72 laser units at the same time at the same point... Twice.
 
Level 7
Joined
Aug 31, 2011
Messages
125
1) You can always change "Owner of Triggering unit" for "Triggering Player".
2) If you're going to use one unit (Triggering Unit) a lot, set UnitVariable = Triggering Unit. It will improve the efficiency.
3) Position Of Triggering Unit (1 Point) with offset (Another point). You have to declare the Position of Triggering Unit in one Point Variable, and then Declare the Point with Offset in another variable. Remove both at the end
4) PositionReal = Position of Position?. Set those at the start of actions block and use them.

Special Effects:
1) NEEEEEEEEEEVER use "waits" inside any kind of Loop.

Anyway, whenever you want to make a spell casteable by several units at the same time, use Hashtables, or make some good efficient handle of variables to control stuff. (Hashtables is better for this anyway).

Lol, thanks for the early reply xD, and number 4, it is what its supposed to be xD, i knew it was gonna be confusing, Position is just part of the trigger and the Second position its a variable xD lol
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Is not confusing... It's just done in a wrong way :p Why call Position a Unit? And why at the end of the trigger, when you can use it in all the trigger to improve efficiency? :p
 
Level 7
Joined
Aug 31, 2011
Messages
125
Is not confusing... It's just done in a wrong way :p Why call Position a Unit? And why at the end of the trigger, when you can use it in all the trigger to improve efficiency? :p

Ohhh, gotcha :p. i deleted them making a better version thats easiar to understand :p and + i am not understanding hashtables atm... :p can you give me a sample of what you mean? by like a picture? would be helpful, thanks in advanced :p ~xIceShotx
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1) I don't really know what you want to achieve..

2) I don't know how to use hashtables either :p Just some small things, but nothing too complicated... :p

Btw, you can create the Special effect in the same trigger, unless you really need that "wait 1.00".

Try improving your trigger (like it's) and edit the first post to show the improvements. using hashtables won't be so different. Btw, you need this to be 1 cast per player, or you're having multiple units casting at the same time?
 
Level 7
Joined
Aug 31, 2011
Messages
125
1) I don't really know what you want to achieve..

2) I don't know how to use hashtables either :p Just some small things, but nothing too complicated... :p

Btw, you can create the Special effect in the same trigger, unless you really need that "wait 1.00".

Try improving your trigger (like it's) and edit the first post to show the improvements. using hashtables won't be so different. Btw, you need this to be 1 cast per player, or you're having multiple units casting at the same time?

I dont get it :/
 
Level 7
Joined
Aug 31, 2011
Messages
125
Waitt actually will this do with your offset thing?

  • For each (Integer A) from 1 to 72, do (Actions)
    • Loop - Actions
      • Set Offset = (CasterPosition offset by 700.00 towards (10.00 x (Real((Integer A)))) degrees)
      • Unit - Create 1 Laser Effects (Hidden) for (Owner of Caster) at Offset facing Default building facing degrees
      • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
  • For each (Integer A) from 1 to 72, do (Actions)
    • Loop - Actions
      • Set Offset = (CasterPosition offset by 700.00 towards (30.00 x (Real((Integer A)))) degrees)
      • Unit - Create 1 Laser Effects for (Owner of Caster) at Offset facing Default building facing degrees
      • Unit - Order (Last created unit) to Human Blood Mage - Siphon Mana Laser_Taker[2]
      • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
First:
You have to remove the offset point inside the loop where you declared it, otherwise you create 72 points there for nothing. Good that you declared "CasterPosition" and then de "CasterPosition offset" that's the way to prevent leaks.

  • Set Offset = (CasterPosition offset by 700.00 towards (10.00 x (Real((Integer A)))) degrees)
This means... a 700 AoE, and will create the laser at 10º, 20º, 30º, 40º... untill 720º degrees. After 360, it will just place lasers over lasers (370º = 10º). So it will work almost the same than using "From 1 to 36"

Second:
Same than first. This time it's 30º, 60º, 90º, 120º... until 2160º, but will repeat the angle after Integer A = 12

30 x 12 = 360º and 390º = 30º



This seems like some kind of circle that is created around the target and red lasers are shoot from around to the target.



What I meant with Trigger Improve is this:

Whenever you need to retrieve some data from the game (position of / Event Response - Triggering Unit / etc.) you are giving a job to the system

(Triggering Unit) means GetTriggerUnit(). So, every time you use (Triggering Unit) you're "Getting the TriggerUnit". When you use a lot of the same, it's more efficient to declare the unit into a variable (set u = Triggering Unit) and call the variable, so the system doesn't get the Triggering Unit info over, and over, but just 1, and from there on just gets the already declared Unit variable.

Example:

  • Invulnerable Field
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Invulnerable Field
    • Actions
      • set u = Triggering Unit
      • set p = Triggering Player
      • set loc1 = Position of u
      • For each (Integer A) from 1 to 72, do (Actions)
        • Loop - Actions
          • set loc2 = loc1 offset by 700 towards (10.00 x (Real((Integer A)))) degrees
          • Unit - Create 1 Laser Effects (Hidden) for p at loc2 facing Default building facing degrees
          • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
          • Custom script: call RemoveLocation(udg_loc2)
      • Trigger - Run Special Effects <gen> (ignoring conditions)
      • Unit - Create 1 Invulnerable User for p at loc1 facing Default building facing degrees
      • Set Laser_Taker[1] = (Last created unit)
      • Unit - Add a 30.00 second Generic expiration timer to Laser_Taker[1]
      • Hero - Set Laser_Taker[1] Hero-level to 6, Hide level-up graphics
      • Unit - Add Invulnerable Field (Unit) to Laser_Taker[1]
      • Unit - Order Laser_Taker[1] to Orc Shadow Hunter - Big Bad Voodoo
      • Unit - Create 1 Laser Taker for Neutral Hostile at loc1 facing Default building facing degrees
      • Set Laser_Taker[2] = (Last created unit)
      • Unit - Add a 30.00 second Generic expiration timer to Laser_Taker[2]
      • For each (Integer A) from 1 to 72, do (Actions)
        • Loop - Actions
          • set loc2 = loc1 offset by 700 towards (30.00 x (Real((Integer A)))) degrees
          • Unit - Create 1 Laser Effects for p at loc2 facing Default building facing degrees
          • Unit - Order (Last created unit) to Human Blood Mage - Siphon Mana Laser_Taker[2]
          • Unit - Add a 30.00 second Generic expiration timer to (Last created unit)
          • Custom script: call RemoveLocation(udg_loc2)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 700.00 of loc1 matching (((Owner of (Matching unit)) is an enemy of p) Equal to True)) and do (Unit - Cause u to damage (Picked unit), dealing 300.00 damage of attack type Spells and damage type Normal)
      • Custom script: call RemoveLocation(udg_loc1)
As you can see, variables are declared first, and then used all along the trigger actions. It's much cleaner and requires less work for the system to do stuff. Parentheses '(xxx)' tells you that the system is retrieving some kind of data. If you're going to use the same data several tames, better to use it once setting it into a variable, and then use the variable.


When you're using a Generic Unit Event you can use "Triggering Player" to replace "Owner of (Triggering Unit)", because it works better, since "(Owner of (Triggering Unit))" has 2 calls GetOwningPlayer(GetTriggerUnit()). It's all about parentheses ;)



About the special effect trigger, it won't work, since you're using a "wait" action inside a loop. That' will crash and prevent the loop from working.
 
Level 7
Joined
Aug 31, 2011
Messages
125
First:
You have to remove the offset point inside the loop where you declared it, otherwise you create 72 points there for nothing. Good that you declared "CasterPosition" and then de "CasterPosition offset" that's the way to prevent leaks.

  • Set Offset = (CasterPosition offset by 700.00 towards (10.00 x (Real((Integer A)))) degrees)
This means... a 700 AoE, and will create the laser at 10º, 20º, 30º, 40º... untill 720º degrees. After 360, it will just place lasers over lasers (370º = 10º). So it will work almost the same than using "From 1 to 36"

Second:
Same than first. This time it's 30º, 60º, 90º, 120º... until 2160º, but will repeat the angle after Integer A = 12

30 x 12 = 360º and 390º = 30º



This seems like some kind of circle that is created around the target and red lasers are shoot from around to the target.

lol, heres the idea of the map i have rightt now
http://www.mediafire.com/?cwb1w4v12x0kwlq :p
Andd is there another way to use the special effects removing the waits without using hashtables? because i am not fimiliar with them :p
 
Last edited:
Level 20
Joined
Jul 14, 2011
Messages
3,213
1) I changed the "Integer A From 1 to 72" for "Integer A From 1 to 36" and works exactly the same.

2) If the damage effect is instant, why 30 secs expiration timer?. You want to damage any unit that comes inside, or just those already inside?

3) The Spell is ugly as hell xD I reduced the "Laser" from 1-72 to 1-12, and looks thin, but makes the same effect. Anyway, 24 should do.

4) I hate those variable names xD

5) why 25 special effects with 1 sec interval?

6) The reason of the special effect going somewhere else is because you're setting "Laser_Taker[1]" the new created unit, leaving the old one... You can solve this easily using a Unit Indexing System (Look in Spell Section), since it adds a custom value to each unit in the map, and you can call exactly your "Laser_Taker" based on its custom value, automatically set by the system. Another way would be using the Laser_Taker unit ID, storing into a hashtable, and using that value instead, since all units have a different id.

7) Please, update your trigger in the first post with the already suggested improvements. There are some leaks left in the trigger (in the map)

8) You are casting invulnerable every sec to the units inside. You shouldn't. You could use another trigger that every second Picks every unit around "Units of Type - YourInvulnerableCaster Unit-Type" and do: Pick every unit within 700 of (Picked Unit) and do: If/Then/Else. If the Picked unit is an enemy and doesn't have "Invulnerable" cast invulnerable to (Picked Unit). It will require a group inside a group. I'm sure there's a better way, but I'm lazy right now.
 
Level 7
Joined
Aug 31, 2011
Messages
125
2) If the damage effect is instant, why 30 secs expiration timer?. You want to damage any unit that comes inside, or just those already inside?

lol, its only a one time damage, it doesn't do it per second or whatever xD and it only damages the targets inside the field :p


8) You are casting invulnerable every sec to the units inside. You shouldn't. You could use another trigger that every second Picks every unit around "Units of Type - YourInvulnerableCaster Unit-Type" and do: Pick every unit within 700 of (Picked Unit) and do: If/Then/Else. If the Picked unit is an enemy and doesn't have "Invulnerable" cast invulnerable to (Picked Unit). It will require a group inside a group. I'm sure there's a better way, but I'm lazy right now.

lol, its not every second xD, its just the buff special effect, Inner Fire, as in the casting part only last like 1 second so the invulnerable will keep doing it again. So, the special effect is every one second but not the invulnerable :p

6) The reason of the special effect going somewhere else is because you're setting "Laser_Taker[1]" the new created unit, leaving the old one... You can solve this easily using a Unit Indexing System (Look in Spell Section), since it adds a custom value to each unit in the map, and you can call exactly your "Laser_Taker" based on its custom value, automatically set by the system. Another way would be using the Laser_Taker unit ID, storing into a hashtable, and using that value instead, since all units have a different id.

Im confused at those :/. I reallyy need help on that part alott. Thanks in advanced
 
Last edited:
Status
Not open for further replies.
Top