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

[JASS] lightning spell (custom)

Status
Not open for further replies.

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
Hi,
here is a lightning spell:
it can target destructable and unit
and get area damage effect when cast on a unit standing on water.
target: tree --> transform tree (4 types) into a dead tree (doesn't affect other type destructable)
target: unit --> deal 40 to 70 dmg ignore armor
if unit is in water it damage every unit within 400 range wich are also in water.
Shock effect: the lightning energize the target giving +10 mana
[Jass=]
function difusion takes nothing returns nothing
local real x1 = GetUnitX(GetEnumUnit())
local real y1 = GetUnitY(GetEnumUnit())
if IsTerrainPathable( x1, y1, PATHING_TYPE_FLOATABILITY) then
call UnitDamageTarget(GetTriggerUnit(), GetEnumUnit(), GetRandomReal(30.00, 40.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( GetEnumUnit(), UNIT_STATE_MANA, ( GetUnitState( GetEnumUnit(), UNIT_STATE_MANA ) + 10.00 ))
endif
endfunction

function Lightning takes nothing returns boolean
local real x
local real y
local integer treetype
local boolean tree
local unit targetU
local unit caster
local destructable targetD
if GetSpellAbilityId() == 'A102' then
set caster = GetTriggerUnit()
if GetSpellTargetUnit() == null then
set targetD = GetSpellTargetDestructable()
set treetype = GetDestructableTypeId(targetD)
set tree = true
set x = GetDestructableX(targetD)
set y = GetDestructableY(targetD)
else
set targetU = GetSpellTargetUnit()
set tree = false
set x = GetUnitX(targetU)
set y = GetUnitY(targetU)
endif
if tree then
if not GetDestructableLife(targetD) <= 0 and treetype == 'ATtr' or treetype == 'BTtw' or treetype == 'FTtw' or treetype == 'ZTtw' then
call DisableTrigger( gg_trg_DropItemDestructible__JASS )
call RemoveDestructable( targetD )
call EnableTrigger( gg_trg_DropItemDestructible__JASS )
call CreateDestructable( 'NTtw', x, y, 0.00, 0.90, GetRandomInt(0, 9) )
call TriggerRegisterDeathEvent( gg_trg_DropItemDestructible__JASS, bj_lastCreatedDestructable )
endif
else
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
local group g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
call ForGroup( g, function difusion )
call DestroyGroup(g)
call UnitDamageTarget(caster, targetU, GetRandomReal(0.00, 30.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(caster, targetU, GetRandomReal(30.00, 70.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( targetU, UNIT_STATE_MANA, ( GetUnitState( targetU, UNIT_STATE_MANA ) + 10.00 ))
endif
endif
endif
return false
endfunction

//===========================================================================
function InitTrig_custom_Lightning_JASS takes nothing returns nothing
set gg_trg_custom_Lightning_JASS = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_custom_Lightning_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_custom_Lightning_JASS, Condition( function Lightning ) )
endfunction
[/code]

is the Jass correct? using group enumeration is a little more difficult that previous spell.
it remove local...
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
ok here i made the change

[Jass=]
function difusion takes nothing returns nothing
local real x1 = GetUnitX(GetEnumUnit())
local real y1 = GetUnitY(GetEnumUnit())
if IsTerrainPathable( x1, y1, PATHING_TYPE_FLOATABILITY) then
call UnitDamageTarget(GetTriggerUnit(), GetEnumUnit(), GetRandomReal(30.00, 40.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( GetEnumUnit(), UNIT_STATE_MANA, ( GetUnitState( GetEnumUnit(), UNIT_STATE_MANA ) + 10.00 ))
endif
endfunction

function Lightning takes nothing returns boolean
local real x
local real y
local integer treetype
local boolean tree
local unit targetU
local unit caster
local destructable targetD
local group g
if GetSpellAbilityId() == 'A102' then
set caster = GetTriggerUnit()
if GetSpellTargetUnit() == null then
set targetD = GetSpellTargetDestructable()
set treetype = GetDestructableTypeId(targetD)
set tree = true
set x = GetDestructableX(targetD)
set y = GetDestructableY(targetD)
else
set targetU = GetSpellTargetUnit()
set tree = false
set x = GetUnitX(targetU)
set y = GetUnitY(targetU)
endif
if tree then
if GetDestructableLife(targetD) > 0 and treetype == 'ATtr' or treetype == 'BTtw' or treetype == 'FTtw' or treetype == 'ZTtw' then
call DisableTrigger( gg_trg_DropItemDestructible__JASS )
call RemoveDestructable( targetD )
call EnableTrigger( gg_trg_DropItemDestructible__JASS )
call CreateDestructable( 'NTtw', x, y, 0.00, 0.90, GetRandomInt(0, 9) )
call TriggerRegisterDeathEvent( gg_trg_DropItemDestructible__JASS, bj_lastCreatedDestructable )
endif
else
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
call ForGroup( g, function difusion )
call DestroyGroup(g)
call UnitDamageTarget(caster, targetU, GetRandomReal(0.00, 30.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(caster, targetU, GetRandomReal(30.00, 70.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( targetU, UNIT_STATE_MANA, ( GetUnitState( targetU, UNIT_STATE_MANA ) + 10.00 ))
endif
endif
set caster = null
set targetU = null
set targetD = null
endif
return false
endfunction

//===========================================================================
function InitTrig_custom_Lightning_JASS takes nothing returns nothing
set gg_trg_custom_Lightning_JASS = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_custom_Lightning_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_custom_Lightning_JASS, Condition( function Lightning ) )
endfunction
[/code]
 
Level 16
Joined
Dec 15, 2011
Messages
1,423
You forgot to null the group g in the code block where you created it. You can also use a first of group loop instead of a separate function. And your separate func won't recognize GetTriggerUnit(). You have to store it and then load it to use there. A first of group loop will help you overcome that :)

Btw you don't have a group filter func, it means all enemies, allies and the caster will be damaged.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
And your separate func won't recognize GetTriggerUnit()

It does recognize GetTriggerUnit :)

In filter functions, use GetFilterUnit, not GetEnumUnit

I also recommend FirstOfGroup loop
JASS:
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
loop
    set u = FirstOfGroup()
    exitwhen u == null
    if x and y and z then // Add filtering options here
        ...actions
    endif
    call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null

You could use one group you never destroy for this.
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
oh the first of group things look cool...
i didn't know that..i will change the code and edit...

EDIT
[Jass=]
function Lightning takes nothing returns boolean
local real x
local real y
local integer treetype
local boolean tree
local unit targetU
local unit caster
local destructable targetD
local group g
if GetSpellAbilityId() == 'A102' then
set caster = GetTriggerUnit()
if GetSpellTargetUnit() == null then
set targetD = GetSpellTargetDestructable()
set treetype = GetDestructableTypeId(targetD)
set tree = true
set x = GetDestructableX(targetD)
set y = GetDestructableY(targetD)
else
set targetU = GetSpellTargetUnit()
set tree = false
set x = GetUnitX(targetU)
set y = GetUnitY(targetU)
endif
if tree then
if GetDestructableLife(targetD) > 0 and treetype == 'ATtr' or treetype == 'BTtw' or treetype == 'FTtw' or treetype == 'ZTtw' then
call DisableTrigger( gg_trg_DropItemDestructible__JASS )
call RemoveDestructable( targetD )
call EnableTrigger( gg_trg_DropItemDestructible__JASS )
call CreateDestructable( 'NTtw', x, y, 0.00, 0.90, GetRandomInt(0, 9) )
call TriggerRegisterDeathEvent( gg_trg_DropItemDestructible__JASS, bj_lastCreatedDestructable )
endif
else
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
loop
set u = FirstOfGroup()
set x = GetUnitX(u)
set y = GetUnitY(u)
exitwhen u == null
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
call UnitDamageTarget(caster, u, GetRandomReal(30.00, 40.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( u, UNIT_STATE_MANA, ( GetUnitState( u, UNIT_STATE_MANA ) + 10.00 ))
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
call UnitDamageTarget(caster, targetU, GetRandomReal(0.00, 30.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(caster, targetU, GetRandomReal(30.00, 70.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( targetU, UNIT_STATE_MANA, ( GetUnitState( targetU, UNIT_STATE_MANA ) + 10.00 ))
endif
endif
set caster = null
set targetU = null
set targetD = null
endif
return false
endfunction

//===========================================================================
function InitTrig_custom_Lightning_JASS takes nothing returns nothing
set gg_trg_custom_Lightning_JASS = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_custom_Lightning_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_custom_Lightning_JASS, Condition( function Lightning ) )
endfunction
[/code]

the lightning, if hit a target wich stand in water will difuse electric energy around dealing damage to all unit including caster, who stand in water near enough to get affected by the radius of difusion.
 
Last edited:

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
hum, so basically i just have to reverse the ispathable..
when ispathable is true it mean it is not pathable.

about vjass, scope library i would love to learn that, and use them...
but not so easy..
i am doing the Jass class...but for now nothing on library and scope.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
dont worry vjass looked hard but i went from gui to jass to vjass in about a week its really not hard at all just look at some tutorials (i am still learning a lot. not saying i learned them all tht fast) but w vjass so much more is possible. and its so much easier especially w scopes and libraries. its worth reading the tutorials on it. gl w the jass class tho
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
only thing that is not possible without vJass is free global declaration
everything else can be done even without vJass, simply in Jass but its very hard to make so

about libs and scopes:

they allow you to use modifiers: private, public before function/struct/globals etc

it basically wraps your code to some "shell" and allows you to make functions with same name multiple times(using private keyword)

Library is a little bit stronger because it can have depedencies with keyword uses, requires.
Before I get to that let me tell you how libraries are handled:

when you declare code within library and endlibrary keywords, it is put almost to the very top of the code(right under globals and struct constructors/deconstructors) so you can call functions within library in any function in your scopes or just general code

So if you have system in library like Table and you want your own system use its code, you just do:
JASS:
library B uses A
endlibrary

library A
endlibrary

this means that all content within library A is put to the top and content from library B is put under it so you can call its functions

There is also keyword initializer, after which you put some function name and that function is run when the game loads.

You can have initializer with scopes and libraries but only the outer scope can have initializer I believe(you can have nested scopes, basically scope within scope)

with libraries, you can also have initializer together with uses/requires, example:
Oh and you can require/use multiple libraries at the same time

JASS:
library A
endlibrary

library B
endlibrary

library B initializer init uses A
    private function init takes nothing returns nothing
        //this runs when the game loads
    endfunction
endlibrary

last note: you cant have library A require library B and library B require library A, it will pop error
and thats almost all there is to those
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
thanks a lot Cokemonkey11, deathismyfriend, edo494, Doomlord.

so basically a library is a function that can be called by other function to execute a code?
[Jass=]
library Pathable
function Water take real x, real y return boolean
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
return false
else
return true
endif
endfunction
endlibrary[/code]
[Jass=]
function Lightning takes nothing returns boolean
local real x
local real y
local integer treetype
local boolean tree
local unit targetU
local unit caster
local unit u
local destructable targetD
local group g
if GetSpellAbilityId() == 'A102' then
set caster = GetTriggerUnit()
if GetSpellTargetUnit() == null then
set targetD = GetSpellTargetDestructable()
set treetype = GetDestructableTypeId(targetD)
set tree = true
set x = GetDestructableX(targetD)
set y = GetDestructableY(targetD)
else
set targetU = GetSpellTargetUnit()
set tree = false
set x = GetUnitX(targetU)
set y = GetUnitY(targetU)
endif
if tree then
if GetDestructableLife(targetD) > 0 and treetype == 'ATtr' or treetype == 'BTtw' or treetype == 'FTtw' or treetype == 'ZTtw' then
call DisableTrigger( gg_trg_DropItemDestructible__JASS )
call RemoveDestructable( targetD )
call EnableTrigger( gg_trg_DropItemDestructible__JASS )
call CreateDestructable( 'NTtw', x, y, 0.00, 0.90, GetRandomInt(0, 9) )
call TriggerRegisterDeathEvent( gg_trg_DropItemDestructible__JASS, bj_lastCreatedDestructable )
endif
else
if Condition( function Pathable_Water( x, y) ) then
set g = CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 400.00, null)
loop
set u = FirstOfGroup(g)
set x = GetUnitX(u)
set y = GetUnitY(u)
exitwhen u == null
if Condition( function Pathable_Water( x, y) ) then
call UnitDamageTarget(caster, u, GetRandomReal(30.00, 40.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( u, UNIT_STATE_MANA, ( GetUnitState( u, UNIT_STATE_MANA ) + 10.00 ))
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
call UnitDamageTarget(caster, targetU, GetRandomReal(0.00, 30.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
else
call UnitDamageTarget(caster, targetU, GetRandomReal(30.00, 70.00), false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call SetUnitState( targetU, UNIT_STATE_MANA, ( GetUnitState( targetU, UNIT_STATE_MANA ) + 10.00 ))
endif
endif
set caster = null
set targetU = null
set targetD = null
set u = null
endif
return false
endfunction

//===========================================================================
function InitTrig_custom_Lightning_JASS_Copy takes nothing returns nothing
set gg_trg_custom_Lightning_JASS_Copy = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_custom_Lightning_JASS_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_custom_Lightning_JASS_Copy, Condition( function Lightning ) )
endfunction
[/code]
 

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,540
You're close, but if you want to call "Pathable_Water", you have to declare function Water as "public" like this

public function Water takes real x, real y returns boolean

Otherwise, you have to call it like "Water" - only public functions get that Pathable_ prefix, and generally you should always use an access modifier (like public or private).
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
so basically i only need to do this:

[Jass=]
library Pathable
public function Water take real x, real y return boolean
if IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) then
return false
else
return true
endif
endfunction
endlibrary
[/code]

and then to call it (as a condition) --> if Condition( function Pathable_Water( x, y) ) then
 

ABM

ABM

Level 7
Joined
Jul 13, 2005
Messages
279
Well is this what you mean?
[Jass=]
library Pathable
public function Water take real x, real y return boolean
return not IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY)
endfunction
endlibrary
[/code]
 
Status
Not open for further replies.
Top