• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Spell] Single target aoe spell with special effect

Status
Not open for further replies.
Level 1
Joined
Jun 5, 2008
Messages
151
Hey, I am trying to create Entagling roots which deal damage like ability level x hero agility, still trying to figure out DoT damage from stats but I will make it later, the problem is that I have 2 actions first which deal damage to target unit of ability being cast and second that deal damage to everyone around that target dealing damage like 0.25 ability level x hero agility but I want to add entagling root animation to every target :( another thing is that AoE damage with triggers deal damage to every unit even my own hero and allies :( How to make it damage only enemies? Also link me to some tutorials with spell making i might want to lear some more :) I will search by myself right now too but I might miss some important threads.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
That's a lot of knowledge you seek! Good! :D
So, I'm not a huge fan of using systems if you can't create something like that yourself (with the exception of Damage Detection-systems), but there's a system on the hive that makes it really easy to add a DoT on any unit you wish. It also includes special effects, so you can add the entangling roots effect to those units.

To get only enemy units, you need to use the action "Units in range matching condition", it should look something like this:

  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 250.00 of tempLoc matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
    • Loop - Actions
You can also exclude mechanical units, buildings, dead units, ... by using the "and"-condition there and adding anything you wish to exclude (mostly boolean comparisons).

Now if you want to learn how to make spells yourself, you need to know about indexing and/or hashtables.
Indexing is a safe method with good execution speed, but it requires many variables and some time.
Hashtables are safe if used correctly, requires a minimum amount of variables and is faster to use, but has slower execution speed and needs some know-how.

As you can see, both methods have advantages and disadvantages. See which method fits you best and go with that.
Note that it's a step-by-step process. Don't expect to open those links and know everything about those methods, learning takes time.
Also, just reading doesn't do much: experiment yourself. It's the quickest way to learn.
 
Last edited by a moderator:
Level 1
Joined
Jun 5, 2008
Messages
151
thanks both of you :) Does it make any difference if you put "destroy" before actually creating something?


  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 250.00 of tempLoc matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
  • Loop - Actions
There you destroy unit group before you create it, I might be mistaken not sure.
 
Last edited by a moderator:
Level 28
Joined
Jan 26, 2007
Messages
4,789
T_T why won't you link my post about difference of Indexing and Hashtable :(

Here is it;
http://www.hiveworkshop.com/forums/2225726-post6.html
http://www.hiveworkshop.com/forums/2225735-post8.html
Very useful! :D (added it to my "Useful Links" folder).
I'll link to that thread (actually, just those posts probably) in the future, whenever someone's asking this again :3.

There's only one thing I'd like to point out: hashtables don't have to overwrite values. It's perfectly possible to create a stacking spell with hashtables without too much of a hassle.
This is especially true for spells that use missiles, but stacking poison works as well.
 
Level 33
Joined
Mar 27, 2008
Messages
8,035
There's only one thing I'd like to point out: hashtables don't have to overwrite values. It's perfectly possible to create a stacking spell with hashtables without too much of a hassle.
It's possible when each instance is attached to a dummy unit.
I said it's possible but very unefficient as you need one instance per dummy unit compared to Indexing, you don't need to have dummies at all.
 
Level 1
Joined
Jun 5, 2008
Messages
151
Hey I am trying to create a Frost Nova Spell and it actually looks nice, though its just basic w3 spell for some reason not sure(maybe just luck) I made it so it deals AoE damage after 0.5 seconds/1.5 seconds/2.5 seconds...for some reason everytime it deals damage there is an animation lol (not that I hate it.) Anyway there is my problem:


  • Frost Nova
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nova Mrozu
    • Actions
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x (Real((Intelligence of (Triggering unit) (Include bonuses))))) damage of attack type Spells and damage type Normal
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of (Position of (Target unit of ability being cast)) matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at (Position of (Target unit of ability being cast)), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 1.50 seconds of radius 200.00 at (Position of (Target unit of ability being cast)), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 4.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 3.00 seconds of radius 200.00 at (Position of (Target unit of ability being cast)), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 8.00)) damage of attack type Spells and damage type Normal

"Nova Mrozu"= Frost Nova"

I have few questions now:

Is it good idea to use WE unlimited? or basic WE is good enough?
There is a loop, which make this spell kill anything lol didnt try it on monsters with high hp, but most likely it would cause huge lag after few seconds because of this infinite loop, I tried to somehow turn of this loop adding "skip remaining actions" or "do nothing" after those 3 AoE triggers but it didnt work, also it still damage my allies, I must add more condition to Unit group probably, but most important is this loop, how to make it so AoE spell dont hurt my allies when damage is dealt by triggers? it must be inside this loop right? otherwise there is no point in creating this group, and yes I changed Temp_loc to something else :> Is it because I am not using it? I want to set Temp_loc to something but I am not sure what...set it to target of ability being cast? wont this just make temp loc this single target? I want it to be area of 200 and all unit inside of it(enemy units only)

I said infinite loop but isnt it more like this loop end after 3 seconds? and while 3 seconds expire those 0.5 second deal damage 6 times and 1.5 second 2 times? If its true then what am I supossed to do? o_O

If you advise me right way, and I manage to make this spell I will use same way to create a Holy Light spell which will deal triggered damage to undead units and heal triggered amount allies, and be unable to cast on enemies execept undead ^^ If i manage to do it I will be proud of myself lol :>

And another question:

I am trying to make blizzard skill which is Target-Ground spell, I cant figure what to put at position of:?

  • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at (Position of (Target unit of ability being cast))
Target unit of ability being cast is working fine with AoE spells like Frost Nova, because I have to target an enemy, but in case of blizzard dont target anyone but a ground...Even Thunder Clap which dont target anyone can be easly done be pointing my own character and deal damage surrounding my hero. I keep making spell after spell to learn how to make them but I have these kind of problems. I am trying to make it w/o variables, cuz I am not good at using them, I am not good at using WE lol but I am trying to learn something, and so I create spell after spell adding new things to it. I hope you can advise me in a good way to make them :)
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
tarnos12 said:
Is it good idea to use WE unlimited? or basic WE is good enough?
I used WEU a long time ago and it destroyed the maps I made with it. It's a bad idea to use it (outdated, inefficient).
Either the regular WE, or JNGP are advised.

tarnos12 said:
I said infinite loop but isnt it more like this loop end after 3 seconds? and while 3 seconds expire those 0.5 second deal damage 6 times and 1.5 second 2 times? If its true then what am I supossed to do? o_O
First: there are a lot of memory leaks in that trigger.
I don't really see an infinite loop either.
The event is "casts an ability", and unless you trigger that somewhere (make unit cast frost nova), the trigger should only run once.
The trigger should end immediately after it is fired (the damage comes after the trigger is done).
Shouldn't "Position of (Target unit of ability being cast)" be "Position of (Picked Unit)"? (Actually it should be "TempLoc", but you know what I mean).

Tarnos12 said:
I am trying to make blizzard skill which is Target-Ground spell, I cant figure what to put at position of:?
"Event Response - Target Point of Ability Being Cast".
 
Level 1
Joined
Jun 5, 2008
Messages
151
Hey I did it all ^^ Frost Nova works, I used temploc= target unit of ability being cast and then condition(action loop) to check if in range of 200 from temploc there is enemy=yes and ally=no and do actions, this way my spell dont hurt allies :) Also thanks for helping with blizzard spell its also working. I will try to make holy light now to deal damage to enemies undead/heal allies deal half damage to any other type of enemy but dont hurt mechanical :> I wonder if i can make it.


@EDIT:

and another question ^^ If i used "Temp_loc" can it be used at the same time? if 2 players use same spell or do I need to create new variable for each player and spell?

Also you said that Nova spell have lots of leaks I am reading this:

http://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/

I cannot find any leaks :( anyway I added Temp_loc again and I destroy it at the end of this trigger. Can you tell me what leaks there? I read this thread and cant seem to find anything.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I will try to make holy light now to deal damage to enemies undead/heal allies deal half damage to any other type of enemy but dont hurt mechanical :> I wonder if i can make it.
I bet you can :).

and another question ^^ If i used "Temp_loc" can it be used at the same time? if 2 players use same spell or do I need to create new variable for each player and spell?
No: re-use the same variable as much as possible (try to use the same variables in all other triggers as well).
So yeah, just 1 variable will do the trick.

Also you said that Nova spell have lots of leaks I am reading this:

http://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/

I cannot find any leaks :(

  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 200.00 of (Position of (Target unit of ability being cast)) matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
    • Loop - Actions
LEAK: "(Position of (Target unit of ability being cast))"
Good that you removed the group leak though :).

  • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at (Position of (Target unit of ability being cast)), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
LEAK: "(Position of (Target unit of ability being cast))"
(you have this action 3 times and all of them leak).

This would be the fixed trigger:
  • Frost Nova
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Nova Mrozu
    • Actions
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x (Real((Intelligence of (Triggering unit) (Include bonuses))))) damage of attack type Spells and damage type Normal
      • Set TempLoc = Position of (Target unit of ability being cast)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of TempLoc matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at TempLoc, dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 1.50 seconds of radius 200.00 at TempLoc, dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 4.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 3.00 seconds of radius 200.00 at TempLoc, dealing ((Real((Level of Nova Mrozu for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 8.00)) damage of attack type Spells and damage type Normal
    • Custom script: call RemoveLocation( udg_TempLoc )
(Edit: this might not be actually correct because it doesn't use the picked unit's location, but it's the same trigger you gave us :p).
 
Level 1
Joined
Jun 5, 2008
Messages
151
thanks :) this trigger is almost same as mine, I just didnt know that I could use temp_loc many times, so those 3x triggers should use it as well :) I will add it now and should be fine. I can see that to prevent leaks I should use variables in most cases so I can destroy it later.
 
Level 1
Joined
Jun 5, 2008
Messages
151
This theread "Things that leaks" all leaks are posted in first post?

Anyway here is my trigger, first action should not leak cuz its not position of unit right?

  • Frost Nova
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Nova Mrozu (Mage)
    • Actions
      • Set Temp_loc = (Position of (Target unit of ability being cast))
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x (Real((Intelligence of (Triggering unit) (Include bonuses))))) damage of attack type Spells and damage type Normal
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 1.50 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 4.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 3.00 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 8.00)) damage of attack type Spells and damage type Normal
      • Custom script: call RemoveLocation(udg_Temp_loc)
 
Level 1
Joined
Jun 5, 2008
Messages
151
thanks ^^ I was thinking is there maybe a thread with variables list explaining which variable can be used and for what? because there is lots of them and I have no idea what 90% of them actually is used for. Even if variable name is simple to understand that still doesnt mean I will know how and where to use it :/

Target point of ability being cast doesnt leak?
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
thanks ^^ I was thinking is there maybe a thread with variables list explaining which variable can be used and for what? because there is lots of them and I have no idea what 90% of them actually is used for. Even if variable name is simple to understand that still doesnt mean I will know how and where to use it :/

Target point of ability being cast doesnt leak?

maybe this could help ? :) Variable

and Target point of ability being cast leaks a point, you should destroy it after used.
 
Level 1
Joined
Jun 5, 2008
Messages
151
ok I will ^^ also:

  • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real...
I am trying to add Temp_loc= target unit of ability being cast but cant seem to find it...its probably because temp_loc is location variable and not unit or something?
Thats why I needed variable thread cuz I dont know what variable I need to create, thanks for link :)

so yeah I created variable Temp_unit=target unit of ability being cast and this way I can destroy another leak.
This thread you linked helps alot too there is alot of info about each variable
 
Level 1
Joined
Jun 5, 2008
Messages
151
Cant I create unit variable? Temp_unit=target unit of ability being cast? Not sure how to destroy it but probably

  • Custom script: call RemoveUnit(udg_Temp_unit)
Is that right?
 
Level 1
Joined
Jun 5, 2008
Messages
151
ah nevermind my bad...Ap0calypse already told me that this action does not leak =.=

@EDIT:

After adding Temp_loc my trigger no longer deal AoE damage ^^

  • Frost Nova
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Nova Mrozu (Mage)
    • Actions
      • Set Temp_loc = (Position of (Target unit of ability being cast))
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x (Real((Intelligence of (Triggering unit) (Include bonuses))))) damage of attack type Spells and damage type Normal
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage circular area after 0.50 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 1.50 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 4.00)) damage of attack type Spells and damage type Normal
          • Unit - Cause (Triggering unit) to damage circular area after 3.00 seconds of radius 200.00 at Temp_loc, dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 8.00)) damage of attack type Spells and damage type Normal
      • Custom script: call RemoveLocation(udg_Temp_loc)
Those 3x triggers there should be different variable with other value? if yes then can i add 2x Temp_loc= with different values and destroy it once or twice?
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
this doesn't needed if you want to deal area damage.
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
I need group, because of it AoE spells dont hurt allies but only enemies.

but you don't do anything to the picked unit, you're just dealing damage to the area. therefore, the picked units are useless.

unless you do this :
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
    • Loop - Actions
      • Unit - Cause (Triggering unit) to damage (Picked unit) dealing 500 damages of type normal and spell
but, the problem is you can't use wait.
 
Level 1
Joined
Jun 5, 2008
Messages
151
Maybe I dont understand or maybe you dont, but my spell is single target spell ^^ so If i want to deal area damage I need to pick unit which I target and deal AoE damage around it.

Frost Nova deal damage to single unit and then Aoe Damage 3 times after 0.5 second then 1.5 seconds and 3 seconds.


@btw I downloaded than JNPG but it seems that version is too old :> and when i try to load map it ask me If i want to load map created in new editor to this old one o_O
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Tarnos, here's a specific example of what your trigger does:
Say you cast the ability on a unit. There are 3 other enemy units in the area (total of 4 units).
You do 4 times (damage after 0.50 sec), 4 times (damage after 1.5 sec) and 4 times (damage after 3 sec).

The unit group you placed there does NOT filter the damage targets (so even with your trigger, allied units will get damaged as well).
And because you pick the unit group, you do N times more damage than you usually would (N being the amount of units in the unit group).

To filter the damage targets (like "only enemies"), you need to do single-target damage (see Venom's last post).
Actually, Venom explains it very well (including that waits won't work).

tarnos12 said:
@btw I downloaded than JNPG but it seems that version is too old :> and when i try to load map it ask me If i want to load map created in new editor to this old one o_O
Yeah, don't mind that. Just press "OK" and will work :).
 
Level 1
Joined
Jun 5, 2008
Messages
151
ok thanks, I will do like venom said then.

Is there any way to make jngp to use English? This way my triggers and variables would be in english too :( or the only way is to install english patch to my w3?

There is really no way to make it work including waits? because it looks better this way. What I mean is that AoE damage is dealt after 0.5 then 1.5 and 3.0 seconds and each time damage is lowered.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
I think the language depends on Warcraft 3. Not sure though.

You can't use waits inside unit groups, but you can do your trigger with waits.
  • Spell
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Channel
    • Actions
      • Custom script: local location udg_TempLoc1
      • Set TempLoc1 = (Position of (Target unit of ability being cast))
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing 100.00 damage of attack type Spells and damage type Normal
      • Wait 0.40 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of TempLoc1 matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 75.00 damage of attack type Spells and damage type Normal
      • Wait 0.90 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of TempLoc1 matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 50.00 damage of attack type Spells and damage type Normal
      • Wait 1.40 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of TempLoc1 matching (((Matching unit) belongs to an enemy of (Triggering player)) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 25.00 damage of attack type Spells and damage type Normal
      • Custom script: call RemoveLocation( udg_TempLoc1 )
      • Custom script: set udg_TempLoc1 = null
A wait lasts about 0.10 seconds longer than what you set it to (so a 0.40 second-wait will actually be closer to 0.50 seconds).
That's why the wait-times in that trigger seem a bit off.

This uses a local trick that requires a global variable. I'm not going to go into detail here unless you want me to.
You can change the damage to whatever you wish :).
 
Last edited:
Level 1
Joined
Jun 5, 2008
Messages
151
from what I know, using waits is bad or something? Everywhere when someone make trigger which use waits peoples say its bad and so on =.= lol so I never intended to use wait action...so its fine to use wait? I guess skill wont be mui anymore right?( not sure if it was mui from the start lol)

About that global variable if you can then explain it to me ^^ Its good to learn new things so I dont mind if you post about it there or link me to some post

Also I dont understand:

  • Custom script: local location udg_TempLoc1
\

and lastly you named skill channel, not sure if its just random name but my skill is not channeling skill, my unit just cast it and thats it damage is dealt as you can see in your trigger
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
The spell is still MUI, SUMI even (that's what the local trick is for).

Edit:
tarnos12 said:
you named skill channel, not sure if its just random name but my skill is not channeling skill
It's not a random name: "Channel" (neutral hero skill) is the best ability to base triggered spells on.
Its name may be misleading, because it can be anything (unit-target, point-target, instant cast), doesn't have to be a channeled spell.
endedit

tarnos12 said:
Also I dont understand:

  • Custom script: local location udg_TempLoc1
That's basically how the local trick works. I'll try to explain it (I thought I explained this somewhere else, but I can't find it anymore).
Warning: lots of text.

For this, you need to know the difference between local and global variables.
You are already familiar with global variables. They're called "global" because you can use them in any trigger you want.

The problem with globals is that they can be overwritten.
Take this trigger for example:
  • Instakill
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Instakill
    • Actions
      • Set TempUnit = (Target unit of ability being cast)
      • Wait 2.00 seconds
      • Unit - Kill TempUnit
If the spell "Instakill" is cast more than once within 2 seconds, then "TempUnit" will be overwritten and the spell will only work for the last instance.
But you can't use "Target unit of ability being cast" after a wait, because that will also fail.
So how do you solve this without the trigger becoming too complicated?

Locals.
Local variables are pretty much JASS-only.
They exist only in the trigger they're created in, and if the trigger is done, so is the local variable.
Local variables cannot be overwritten: every instance of the trigger will create a new local variable with another value.

Consider the same spell, but then with local variables:
  • Instakill
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Instakill
    • Actions
      • Custom script: local unit udg_TempUnit
      • Set TempUnit = (Target unit of ability being cast)
      • Wait 2.00 seconds
      • Unit - Kill TempUnit
It's only 1 line longer, yet it performs beautifully.
You can spam this skill all you like, it will kill every unit 2 seconds after it was cast on him.

There's only 1 minor problem with this: the local variable may be gone, but the value inside it still exists.
When a value exists and cannot get accessed anymore, it's a memory leak.
So with local variables you have an extra memory leak you need to take care of, this is done by setting the value to "null" (this means "no value").
Here's how it looks:
  • Custom script: set udg_TempUnit = null
Add that to the previous trigger and it's complete.

Note: setting the variable to null must be done after cleaning the major leak first.
This is how it should look for a location:
  • Custom script: call RemoveLocation( udg_TempLoc )
  • Custom script: set udg_TempLoc = null
What exactly do you need to know?
1) Global Variables are (by default) named "udg_" + VAR_NAME. So when you create a new variable in the variable editor called "TempLoc", the actual name is "udg_TempLoc".

2) Local variables create an extra leak (this does not count for integers, reals and booleans).
This can be solved by setting the local to null at the end of the trigger, after cleaning the first leak.
 
Level 1
Joined
Jun 5, 2008
Messages
151
ok so from what I understand I have been using global variables all the time and local temp loc would be:

not sure if its point or location? I understand that we add local script before global to make it 'special'?

  • Custom script: local point(location) udg_Temp_loc
  • Set Temp_loc = (Position of...
and since local leaks too we need to destroy them but before we do we have to destroy all other leaks first so in other words we put this last(after all other leak destroyers :D

  • Custom script: set udg_Temp_loc = null

so the trigger would be like:

  • Custom script: local point(location) udg_Temp_loc
  • Set Temp_loc = (Position of...
  • Wait 2.00 seconds
  • Unit - Deal damage at Temp_loc dealing 200 damage...
  • Custom script: call RemoveLocation(udg_Temp_loc )
  • Custom script: set udg_Temp_loc = null
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
tarnos12 said:
not sure if its point or location?
It's location. GUI mixes up some type names for no good reason.
Point = location
Unit Group = group
Player Group = force
Unit-Type, Item-Type and Ability are all integers.

tarnos12 said:
I understand that we add local script before global to make it 'special'?
Hah, I actually didn't explain this :p You don't make the global 'special', no.
In JASS, you use local type name to create a variable (a local one). An example would be local integer itemCount (this creates an integer variable named "itemCount").
They're just variables like the one you use, except that they only exist in a single instance of a trigger.

So you just create a local variable.
This might be a little weird if you're not familiar with local variables, but it has absolutely nothing to do with the global variable, except that it shares its name.
Because it shares its name, you can use the local variable in GUI (locals have a higher priority than globals) and the global will not be changed.

I reckon this is still a bit confusing? :/
 
Level 1
Joined
Jun 5, 2008
Messages
151
I kind of understand it, but still its important to use local variable before global right? and also destroy leaks creates by local variable after destroying leaks from global, so its like:

Create local temp_loc
Create udg_temp_loc
Do some actions
Call remove udg_temp_loc
local temp_loc=null

I still cant remember the exact code so I just randomly put some words, I always have to check my triggers because I cant remember custom scripts yet. I barely started to use them lol :>

ah and the reason you told me about locals is so my spell will become MUI? or you even called it SUMI not sure what it means =.= I am lost and forgot why we even talk about locals now. ^^
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
tarnos12 said:
ah and the reason you told me about locals is so my spell will become MUI? or you even called it SUMI not sure what it means =.=
You're completely right though :). SUMI means "Same-Unit Multi Instanceable" by the way (when 1 unit can cast the same spell multiple times without bugging).
If you don't use locals, then your trigger either won't be MUI, or it would become pretty complicated (using indexing or hashtables and a timed trigger).

tarnos12 said:
Create local temp_loc
Create udg_temp_loc
Do some actions
Call remove udg_temp_loc
local temp_loc=null
Hmh. What do you mean with "Create local temp_loc" and "Create udg_temp_loc"? :p
You create the global in the variable editor (the way you're used to), then you create a local variable with the same name as that global one in the trigger.

tarnos12 said:
its important to use local variable before global right?
Yes! Good point! I almost forgot to say that creating the local variable must be the first thing you do in the trigger.
It also doesn't work inside conditions, loops, unit-groups and player-groups.


Doing this is actually abusing some Warcraft 3-bug, so I can understand it's confusing :p.
Anyway, did you get the spell to work? :D.
 
Level 1
Joined
Jun 5, 2008
Messages
151
hey before I make the spell work I will explain you what I meant be "create"

Its simply a trigger custom script in other words what I wanted to say was:

  • Custom script: local point(location) udg_Temp_loc
  • Set Temp_loc = (Position of...
  • Unit - Deal damage at Temp_loc dealing 200 damage...
  • Custom script: call RemoveLocation(udg_Temp_loc )
  • Custom script: set udg_Temp_loc = null
and I asked if this is the right order, so local comes first then global then some actions and then we destroy leak from global and lastly from our local :> in other words this trigger is wrong:

  • Custom script: local point(location) udg_Temp_loc
  • Set Temp_loc = (Position of...
  • Unit - Deal damage at Temp_loc dealing 200 damage...
  • Custom script: set udg_Temp_loc = null
  • Custom script: call RemoveLocation(udg_Temp_loc )

@EDIT:

ok so I tried to create this spell the way you showed me and it didnt work ^^ I mean AoE damage didnt deal any damage at all

  • Frost Nova
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Nova Mrozu (Mage)
    • Actions
      • Custom script: local location udg_Temp_loc
      • Set Temp_loc = (Position of (Target unit of ability being cast))
      • Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x (Real((Intelligence of (Triggering unit) (Include bonuses))))) damage of attack type Spells and damage type Normal
      • Wait 0.40 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 2.00)) damage of attack type Spells and damage type Normal
      • Wait 0.90 seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 4.00)) damage of attack type Spells and damage type Normal
      • Wait 1.40 game-time seconds
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 200.00 of Temp_loc matching ((((Matching unit) belongs to an enemy of (Triggering player)) Equal to True) and (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False))) and do (Actions)
        • Loop - Actions
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing ((Real((Level of Nova Mrozu (Mage) for (Triggering unit)))) x ((Real((Intelligence of (Triggering unit) (Include bonuses)))) / 8.00)) damage of attack type Spells and damage type Normal
      • Custom script: call RemoveLocation(udg_Temp_loc)
      • Custom script: set udg_Temp_loc = null
I feel like I am missing something or that you did some kind of mistake on purpose there for me to find it lol haha ^^
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
actually, all Unit events (finishes cast, begin cast, start effect, acquiring item and else) don't have (Triggering Player) ^^, Change it to (Owner of (Triggering unit)) instead.

and i'm afraid this cause a problem ^^

  • (((Triggering unit) belongs to an ally of Player 1 (Red)) Equal to False)))
you don't need this at all, because if the Triggering Unit is an ally of Player 1(Red), then this pick action will never work.

you have two options :
1. make sure that the caster will always be an enemy of Player 1 Red
2. delete these condition.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
actually, all Unit events (finishes cast, begin cast, start effect, acquiring item and else) don't have (Triggering Player) ^^, Change it to (Owner of (Triggering unit)) instead.
Actually, they do have "Triggering Player" and it's better to use that than "Owner of (Triggering unit)" because it's 1 less function.
GUI kind-of hides this fact though.
In JASS, all "Generic unit events" (such as "A unit Starts the effect of an ability", or "A unit gains a level") are PLAYER_UNIT-events.
This clearly indicates that it registers a unit-event for a player, thus there is a triggering player.


The condition you pointed out might indeed be the flaw though. It means that the casting unit may not be an ally of Player 1 (which, in most cases, you are).
Attached a quick demo-map.
 

Attachments

  • Frost Spell.w3x
    18.4 KB · Views: 40
Level 1
Joined
Jun 5, 2008
Messages
151
thanks :) there were few errors in my spell which you corrected:

Unit group 3x matching "TRIGGERING unit" That was my first mistake, because there should be matching unit, another one was Event it was different from yours, not sure if it matters though, and last not important to make spell work( at least I think its not) but would probably make spell leak.

Custom script: call RemoveLocation(udg_Temp_loc)

Before "udg" there should be a space like:

Custom script: call RemoveLocation( udg_Temp_loc)

so yeah everything is working now and I have another question ^^ since I cannot add 1 group with few options like enemy=yes ally=no mechanical=yes etc because it will check if everything is inside target point and if something dont match then spell wont work...so How am I supossed to make spell which deal different damage or no damage at all to different unit types like undead/mechanical/ally/enemy/neutral. I want it to be like 200% Damage to undead/0% mechanical/100% enemy/10%neutral and heal ally for 100% and since I want to make this spell work, lets add something to it...If ally have some kind of buff on him healing will do 200%, if undead have some kind of buff then healing will deal 400% damage but if he have some other buff them it will be 100% same goes for other type of units...If you understand me then let me know which triggers to use and I will try to create it, and if possible delete all leaks, then post it there :) and about locals is it best to use on every spell? as far as I understand its good idea to do that to make spell mui/sumi but at the same time I noticed lots of spells which are not mui there on hive, and I was wondering why, cant they also add locals or something? or its more complicated than it seems?

Thanks to all you did I learned to make spells with adding special effect and since I can even use waits! I can make spell look nice adding special effect and even deal different damage every time, I can even make poison with this probably lol or any other DoT spell ^^

I feel like that "udg" was good but you made a mistake adding a space before it...I dont know anymore :>
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Custom script: call RemoveLocation(udg_Temp_loc)

Before "udg" there should be a space like:

Custom script: call RemoveLocation( udg_Temp_loc)

[...]

I feel like that "udg" was good but you made a mistake adding a space before it...I dont know anymore :>
Spaces don't matter in JASS. It all depends on what you prefer :).
Some people never add spaces (Example: call DoStuff(a,b,c,d)).
I always add spaces (Example: call DoStuff( a, b, c, d )).


tarnos12 said:
How am I supossed to make spell which deal different damage or no damage at all to different unit types
It depends.
Do all spells have those same damage modifications?
Do some spells share those damage modifications (e.g.: spell type "Light" deals 200% versus undead, 50% versus Tree)?
Do all spells have their own, individual, damage table?

The first and second one: a damage detection-system should function properly.
The third one: that's gonna be a lot of ITE's :/ (OR damage detection with a simple table).

tarnos12 said:
I can even make poison with this probably lol or any other DoT spell ^^
You shouldn't though! :D Waits are very unreliable and aren't that fast.
The method I just taught you is good for spells like your Frost Nova, but it is almost always better to use periodic triggers instead.
 
Level 1
Joined
Jun 5, 2008
Messages
151
Periodic triggers? :)

I am not going to make elemental damage spells like you said Light deal damage 200% to some enemies but fire deal less to water and water more to fire I dont want to do this :> I am just trying to learn how to make spells so I though next step would be creating Holy Light(Paladin spell) which heal allies for 100%(of spell damage or something, I can make each damage like in frost nova) if target enemy undead type unit then deal 200% damage, if targeted mechanical then deal 0% damage, or maybe 10% and when target neutral unit it would deal 10% damage...another thing is that if ally unit have specific buff like idk Roar or whatever healing will do 200% of basic heal :) but if ally have other buff than roar like plague or something then healing will heal for 50% of basic healing, and as for undead if he have a buff like plague then deal 100% damage(200% is basic because its undead) and if undead have some kind of buff like roar then deal him 400% damage. its complicated but If I can somehow make it with your help then I would be one step closer to make own spells :)

Not sure what do you mean by damage modification? All spells deal damage based on character ability level x hero based stats like agility but it depends on spell it could deal 2000 damage + hero agility x ability level or something

I dont know anything about damage table, what is it? o_O
 
Status
Not open for further replies.
Top