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

Water Field v2.21

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Water Field

Conjures a field of water that explodes after 2 seconds.
Deals 400/800/1200 damage to all enemies in the field.
8/6/4 seconds cooldown.
Costs 50/75/100 mana



As the spell says, very easy.
This is actually my first Jass spell so please give feedback :)
EDIT: added script here now:

JASS:
constant function WATER_FIELD_DUMMY1 takes nothing returns integer    
return 'h002'
endfunction

constant function WATER_FIELD_DUMMY2 takes nothing returns integer    
return 'h003'
endfunction

function spell_filter takes nothing returns boolean    
    return GetUnitTypeId(GetFilterUnit()) == WATER_FIELD_DUMMY1()
endfunction

function spell_filter2 takes nothing returns boolean    
    return GetUnitTypeId(GetFilterUnit()) == WATER_FIELD_DUMMY2()
endfunction

function Trig_damage_conditions takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(GetTriggerUnit()) )
endfunction

function Trig_killunit takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
endfunction

function Trig_Spell_Init_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_Spell_Init_Actions takes nothing returns nothing
    local location Pos = GetSpellTargetLoc()
    local unit Caster = GetTriggerUnit()
    local real Real
    local integer i = (GetUnitAbilityLevel(Caster, 'A002' ) )
    local real x
    local real y
    local group g = CreateGroup()
    local unit u
    local real r = (GetUnitAbilityLevel(Caster, 'A002' ) )*200
    set i = 0
    loop
        exitwhen i == 6
        set x = GetSpellTargetX() + 100 * Cos(60.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 100 * Sin(60.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY1(), x, y, 270)
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 6
        set x = GetSpellTargetX() + 200 * Cos(60.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 200 * Sin(60.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY1(), x, y, 270)
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 12
        set x = GetSpellTargetX() + 300 * Cos(30.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 300 * Sin(30.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY1(), x, y, 270)
        set i = i + 1
    endloop
    call TriggerSleepAction(2.00)
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function spell_filter))
    call ForGroup( (g), function Trig_killunit)
    set i = 0
    loop
        exitwhen i == 6
        set x = GetSpellTargetX() + 100 * Cos(60.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 100 * Sin(60.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY2(), x, y, 270)
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 6
        set x = GetSpellTargetX() + 200 * Cos(60.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 200 * Sin(60.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY2(), x, y, 270)
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 12
        set x = GetSpellTargetX() + 300 * Cos(30.00 * I2R(i) * bj_DEGTORAD)
        set y = GetSpellTargetY() + 300 * Sin(30.00 * I2R(i) * bj_DEGTORAD)
        call CreateUnit(GetOwningPlayer(Caster), WATER_FIELD_DUMMY2(), x, y, 270)
        set i = i + 1
    endloop
    call GroupEnumUnitsInRange(g, GetSpellTargetX(), GetSpellTargetY(), 300, Condition(function Trig_damage_conditions))
    loop    
        set u = FirstOfGroup(g)    
        exitwhen u == null    
        call UnitDamageTarget(Caster, u ,r ,TRUE ,TRUE, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null )
    endloop
    call TriggerSleepAction (1.50)
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function spell_filter2))
    call ForGroup( (g), function Trig_killunit)
    call RemoveLocation(Pos)
    call DestroyGroup(g)
    set Pos=null
    set Caster=null
    set g=null
    endfunction

//===========================================================================
function InitTrig_Spell_Inita takes nothing returns nothing
    set gg_trg_Spell_Inita = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell_Inita, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell_Inita, Condition( function Trig_Spell_Init_Conditions ) )
    call TriggerAddAction( gg_trg_Spell_Inita, function Trig_Spell_Init_Actions )
endfunction


v.1.10
Changed dummy units so they wont attack.
Changed dummy spell so targeted units wont burn.
Still trying to fix so the spell only damages enemies of caster.
v.1.20
Fixed some leaks.
Fixed so now the spell only damages enemies.
v.1.25
Removed alot of BJ's.
v.2.00
Added spell lvls 1,2 and 3.
Now got 50/75/100 mana cost and 8/6/4 sec cooldown and 400/800/1200 damage.
v.2.10
Removed more BJ's.
Replaced array with a normal integer.
v.2.15
Changed the script abit.
No more globals now.
v.2.20
More changes in the script.
Now the dummies are easily configurable.
No leaks! =)
v.2.21
Minor changes in the script.


Keywords:
Water Aoe Jass Explotion Field
Contents

Water Field v.2.20 (Map)

Reviews
11:19, 1st Oct 2009 The_Reborn_Devil: You still have an infinite loop here: call GroupEnumUnitsInRange(g, GetSpellTargetX(), GetSpellTargetY(), 300, Condition(function Trig_damage_conditions)) loop set u = FirstOfGroup(g)...

Moderator

M

Moderator

11:19, 1st Oct 2009
The_Reborn_Devil:

You still have an infinite loop here:
JASS:
call GroupEnumUnitsInRange(g, GetSpellTargetX(), GetSpellTargetY(), 300, Condition(function Trig_damage_conditions))
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call UnitDamageTarget(Caster, u ,r ,TRUE ,TRUE, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null )
endloop
You forgot to remove units from the group.
And please don't use waits, use timers or find another solution.

PM me once you've fixed this.
 
Level 11
Joined
Jul 2, 2008
Messages
601
Why the units in a target are setted on fire? Isn't it water spell? The dummy units attack enemies (including caster since they are spawned for neutrals, huh?) so we can hear attack sounds! They even have damage, wtf? The spells damages friendly units and even the caster himself. There is no single helpful command to test the spell, even the hero doesn't revive.

Why does the water spell kills destructibles?

This spell bugs at point of OBJECT EDITOR more than at triggering itself. You've chosen dull dummy ability and don't know how to work with dummy units. You even has three of them instead of one!

If I could, I'll rate it 1/5. But now I can just vote for rejection. There is a "Triggers&Scripts" section on forum for WIPs.
 
Level 3
Joined
Mar 18, 2008
Messages
21
Why the units in a target are setted on fire? Isn't it water spell? The dummy units attack enemies (including caster since they are spawned for neutrals, huh?) so we can hear attack sounds! They even have damage, wtf? The spells damages friendly units and even the caster himself. There is no single helpful command to test the spell, even the hero doesn't revive.

Why does the water spell kills destructibles?

This spell bugs at point of OBJECT EDITOR more than at triggering itself. You've chosen dull dummy ability and don't know how to work with dummy units. You even has three of them instead of one!

If I could, I'll rate it 1/5. But now I can just vote for rejection. There is a "Triggers&Scripts" section on forum for WIPs.

Oh, well that was alot of downs, um ill delete it from here then, since it doesnt seems to be liked, and try to redo it with better result.
 
Level 6
Joined
May 1, 2009
Messages
215
That's rather easy..

  • Set (Spell_DamageGroup) equal to Unit Group - Pick All Units in (Region / Range / etc) matching conditions (picked unit*) is an enemy of (Caster_Unit) equal to true and (other conditions)
*May be matching unit, it should say somewhere which one you need in grey text

You need to work the above trigger in somewhere in your spell.
 
Level 3
Joined
Mar 18, 2008
Messages
21
That's rather easy..

  • Set (Spell_DamageGroup) equal to Unit Group - Pick All Units in (Region / Range / etc) matching conditions (picked unit*) is an enemy of (Caster_Unit) equal to true and (other conditions)
*May be matching unit, it should say somewhere which one you need in grey text

You need to work the above trigger in somewhere in your spell.

i think i used that script already, without any preformance.
JASS:
call ForGroupBJ( GetUnitsInRangeOfLocMatching(400.00, Pos, Condition(function Trig_damage_conditions)), function Trig_damage )// this is in the main function somewhere

function Trig_damage_conditions takes nothing returns boolean
    return ( GetOwningPlayer(GetEnumUnit()) != GetOwningPlayer(udg_Caster) )
endfunction
 
Level 3
Joined
Mar 18, 2008
Messages
21
omfg

just seeing the script makes me.....

it leaks locations, what makes me want to ask, why the hell you even use those..


99% is just GUI-converted...


triggering is awful.

Read tutorials adn practice pls

Um, first of all, can you tell me where it leaks locations?
And secondly, this is practice, if you read this is my first Jass spell, so try not to be rude.
Instead give me tips on how to improve it.

EDIT: @Roflcoptor, btw how can i get better without any constructive feedback? The best way to get better is to practice right? And that's what im doing so instead of just complaining, try to help me?
 
Level 9
Joined
Nov 25, 2008
Messages
194
I dont care if it is your first or hundreth spell. my first spell didnt contain any leaks.

Spell section is made for finished full working spells.

PolarProjectionBJ() leaks

and you don't clear point leak
JASS:
local location point = Get.....
.....
call RemoveLocation(point)
set point = null

is correct.
 
Level 3
Joined
Mar 18, 2008
Messages
21
I dont care if it is your first or hundreth spell. my first spell didnt contain any leaks.

Spell section is made for finished full working spells.

PolarProjectionBJ() leaks

and you don't clear point leak
JASS:
local location point = Get.....
.....
call RemoveLocation(point)
set point = null

is correct.

Well then, im sorry that im not so perfect as you are.
Thanks for the corrections.
 
Level 9
Joined
Aug 2, 2008
Messages
219
Description said:
Still trying to fix so the spell only damages enemies of caster.
I know why it damages alley units aswell.
JASS:
function Trig_damage_conditions takes nothing returns boolean
    return ( GetOwningPlayer(GetEnumUnit()) != GetOwningPlayer(udg_Caster) )
endfunction
should be changed to:
JASS:
function Trig_damage_conditions takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(udg_Caster) )
endfunction
Why don´t you merge the filter function with the action (damage) function ?
This would make it more effecient.

And by the way, your spell condition function is converted from GUI. It should look something like this.
JASS:
function Trig_Spell_Init_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

Oh and another advice. You should make some constant functions for the rawcodes. It´s just pain to go through the script and change them by hand.
 
Last edited:
o_O

  • You should seriously think about getting JNGP and making use of vJass.
  • Fix all of the BJ's except for TriggerRegisterAnyUnitEventBJ. I'm sure there is a tutorial on inlining somewhere.
  • Your local location Pos leaks, you need to RemoveLocation it.
  • Replace all of the global bj_forLoopAIndex with a local variable.
  • Use timers instead of waits, this could complicate your code a little but it's definatly worth it.
  • I think you should make some more practice spells first, and asking friends for help or posting a thread in the triggers and scripts forum.
 
Level 3
Joined
Mar 18, 2008
Messages
21
I know why it damages alley units aswell.
JASS:
function Trig_damage_conditions takes nothing returns boolean
    return ( GetOwningPlayer(GetEnumUnit()) != GetOwningPlayer(udg_Caster) )
endfunction
should be changed to:
JASS:
function Trig_damage_conditions takes nothing returns boolean
    return IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(udg_Caster) )
endfunction
Why don´t you merge the filter function with the action (damage) function ?
This would make it more effecient.

And by the way, your spell condition function is converted from GUI. It should look something like this.
JASS:
function Trig_Spell_Init_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

Oh and another advice. You should make some constant functions for the rawcodes. It´s just pain to go through the script and change them by hand.

Thanks alot! This helped enormously much! +rep for your outstanding help! :)
 
Level 3
Joined
Mar 18, 2008
Messages
21
o_O

  • You should seriously think about getting JNGP and making use of vJass.
  • Fix all of the BJ's except for TriggerRegisterAnyUnitEventBJ. I'm sure there is a tutorial on inlining somewhere.
  • Your local location Pos leaks, you need to RemoveLocation it.
  • Replace all of the global bj_forLoopAIndex with a local variable.
  • Use timers instead of waits, this could complicate your code a little but it's definatly worth it.
  • I think you should make some more practice spells first, and asking friends for help or posting a thread in the triggers and scripts forum.

Yeap, will do that, this is my first practice spell posted in the wrong place. My bad. But i still wont go to vJass before i learned Jass a bit better, thanks for your advice though. =)
 
  • You still have a bunch of BJ's.
  • Your leaking a bunch of locations (every PolarProjectionBJ)
  • This is what your script should look like without the BJ's
    JASS:
        loop
            exitwhen i[2] > i[3]
            set x = GetSpellTargetX() + 100 * Cos(60.00 * I2R(i[2]) * bj_DEGTORAD)
            set y = GetSpellTargetY() + 100 * Sin(60.00 * I2R(i[2]) * bj_DEGTORAD)
            call CreateUnit(GetOwningPlayer(Caster), 'h002', x, y, 270)
            set i[2] = i[2] + 1
        endloop
  • You should make the 'h002' configurable.
  • You don't need an integer array for the loops, you can just use the same integer over and over, just reset it to 0 each time like this;
    JASS:
    local integer i = 0
    loop
        exitwhen i == 5
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 3
        set i = i + 1
    endloop
 
Level 3
Joined
Mar 18, 2008
Messages
21
  • You still have a bunch of BJ's.
  • Your leaking a bunch of locations (every PolarProjectionBJ)
  • This is what your script should look like without the BJ's
    JASS:
        loop
            exitwhen i[2] > i[3]
            set x = GetSpellTargetX() + 100 * Cos(60.00 * I2R(i[2]) * bj_DEGTORAD)
            set y = GetSpellTargetY() + 100 * Sin(60.00 * I2R(i[2]) * bj_DEGTORAD)
            call CreateUnit(GetOwningPlayer(Caster), 'h002', x, y, 270)
            set i[2] = i[2] + 1
        endloop
  • You should make the 'h002' configurable.
  • You don't need an integer array for the loops, you can just use the same integer over and over, just reset it to 0 each time like this;
    JASS:
    local integer i = 0
    loop
        exitwhen i == 5
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i == 3
        set i = i + 1
    endloop

oh, thanks alot! +rep for all your help! :)
 
  • You can give locals inital values ( local unit caster = GetTriggerUnit()).
  • Why do you have two globals of type real and integer? Just use locals so there will be no global dependancy on your spell. People will just be able to copy and past the code without worrying about variables.
  • This is how group enums should work in JASS without using the BJ's
    JASS:
    function spell_filter takes nothing returns boolean
        return GetUnitTypeId(GetFilterUnit()) == 'h002'
    endfunction
    
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, Filter(function spell_filter))
    call ForGroup(g)
    You can see what the BJ does by holding control and clicking the red letters in Jass New Gen.
 
Level 14
Joined
Nov 18, 2007
Messages
816
Welcome to the city of JASS. Please enjoy your stay. To avoid serious injuries (such as brain damage) during your time in the world of WarCraft 3 modding, please proceed to vJass city. It's located straight ahead.

A few things to remember:
- destroying groups leaks (thank Blizzard for that)
- you must not use constants directly within your code, for this makes maintaining code a nightmare
- TriggerSleepAction() is not a good way to offset actions (because it does not pause when the "Waiting for player" dialog popps up; And because its inaccurate).
- I2R is (almost) never needed. (v)Jass supports implicit downcasting (every integer is also a real, but not every real is an integer).
 
Level 3
Joined
Mar 18, 2008
Messages
21
Welcome to the city of JASS. Please enjoy your stay. To avoid serious injuries (such as brain damage) during your time in the world of WarCraft 3 modding, please proceed to vJass city. It's located straight ahead.

A few things to remember:
- destroying groups leaks (thank Blizzard for that)
- you must not use constants directly within your code, for this makes maintaining code a nightmare
- TriggerSleepAction() is not a good way to offset actions (because it does not pause when the "Waiting for player" dialog popps up; And because its inaccurate).
- I2R is (almost) never needed. (v)Jass supports implicit downcasting (every integer is also a real, but not every real is an integer).

huh, when i read that i sounded awsome ;) thanks for the help with all that :)
I will look into vJass :)
 
Top