My first vJass spell, doesn't work, need help

Saldu

New Member
Reaction score
1
Hi,
This is my first vJass spell and for some reason it won't do as I want it to, in fact, nothing happens at all. It parses, so I guess I must have made some error on my side, but I can't find it atm.
The spell is supposed (at first, for testing) to pick every unit in a 500 aoe, damage every unit in this aoe for 125 damage per level and spawn 1 + drain damage/350 units
The spell itself is based on channel, aoe of 500, point target.
UNIT1-5 are the unit types to be spawned for spell level 1-5.

Most important would be to know what I did wrong, I know that I still have some leaks in there, might have some variables too much, and I'm sure I could do the 5 "if"s somehow better, but getting the spell to work has priority.

JASS:

scope DrainDoerkness initializer init

globals
private constant integer SPELLID='A00N' 
private constant integer UNIT1='h003'
private constant integer UNIT2='h004'
private constant integer UNIT3='h005'
private constant integer UNIT4='h006'
private constant integer UNIT5='h002'
private constant attacktype ATKTYPE = ATTACK_TYPE_CHAOS
private constant damagetype DMGTYPE = DAMAGE_TYPE_UNIVERSAL
private constant weapontype WPNTYPE = WEAPON_TYPE_WHOKNOWS
private player TempPlayer
endglobals



private function conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELLID
    endfunction
    
private function unitfilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), TempPlayer) == true and GetWidgetLife(GetFilterUnit()) > 0.405
endfunction
    
private function actions takes nothing returns nothing
local location targetloc=GetSpellTargetLoc()
local player p=GetOwningPlayer(GetTriggerUnit())
local group g=CreateGroup()
local unit u
local unit damager=GetTriggerUnit()
local real draincount
local integer lvl=GetUnitAbilityLevel(u, 'A00N')
local integer spawncount
local integer unittospawn
set TempPlayer=p
call GroupEnumUnitsInRangeOfLoc(g, targetloc, 500, Condition(function unitfilter))
loop
set u=FirstOfGroup(g)
        exitwhen u==null
        call GroupRemoveUnit(g, u)
        set draincount=draincount+(125*lvl)
        call UnitDamageTarget(damager, u, 125*lvl, true, true, ATKTYPE, DMGTYPE, WPNTYPE)
    endloop
    set spawncount=1+R2I(draincount)/350
    if lvl==1 then
    set unittospawn=UNIT1
    elseif lvl==2 then
    set unittospawn=UNIT2
    elseif lvl==3 then
    set unittospawn=UNIT3
    elseif lvl==4 then
    set unittospawn=UNIT4
    elseif lvl==5 then
    set unittospawn=UNIT5
    endif
    loop
    call CreateUnitAtLoc(p, unittospawn, targetloc, 270)
    set spawncount=spawncount-1
    exitwhen spawncount <=0.9
    endloop
    call DestroyGroup(g)
    call RemoveLocation(targetloc)
    set damager=null


 endfunction

//===========================================================================
private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function conditions))
        call TriggerAddAction(t, function actions)
    endfunction
endscope
 

Saldu

New Member
Reaction score
1
that's what I tried, but when I try to declare the globals like

JASS:
globals
private constant integer array UNIT[1]='h003'
private constant integer array UNIT[2]='h004'
//bla
endglobals

it will not parse, saying that I already declared a variable in the first line, and would be trying to declare it again in the second line.
 
Reaction score
341
You cannot give arrays initial values. You're going to need to do something like this;

JASS:
scope yourscope initializer onInit

globals
    private constant integer array UNIT
endglobals

private function onInit takes nothing returns nothing
    set UNIT[1]='h003'
    set UNIT[2]='h004'
endfunction

endscope
 

Saldu

New Member
Reaction score
1
Well, thanks for that optimization, but that was of course not the problem that the spell stops working somewhere between the

call GroupEnumUnitsInRangeOfLoc(g, targetloc, 500, Condition(function unitfilter))

and the call UnitDamageTarget(damager, u, 125*lvl, true, true, ATKTYPE, DMGTYPE, WPNTYPE)

lines, since there is no damage dealt when I try to use it.
 

Saldu

New Member
Reaction score
1
All right again :)

But even if my draincount wouldnt exist at all, the damage should still be applied, and 1 unit should be spawned.
 
Reaction score
341
All right again :)

But even if my draincount wouldnt exist at all, the damage should still be applied, and 1 unit should be spawned.

Actually, no.

Your doing set draincount=draincount+(125*lvl). And as of now that means;

set draincount =null+(125*lvl), you cannot add a number to null, and it's pausing your thread.

Try setting it to zero and tell me if the problem persists.
 

Saldu

New Member
Reaction score
1
Yeah I did that, and there is still no damage dealt and no single unit spawned, so I'm pretty much down to my group selection or my channel spell. Does an aoe targetted spell return a target point? (the center probably?)
The filter function can't bug it, since it still doesn't work if I set the filter to simply return true without checking anything. Have to go offline now, will try with a normal blizzard instead of my channel when I'm back.
 
Reaction score
341
Change call GroupEnumUnitsInRangeOfLoc(g, targetloc, 500, Condition(function unitfilter))

to

call GroupEnumUnitsInRangeOfLoc(g, targetloc, 500, Filter(function unitfilter))
 

Saldu

New Member
Reaction score
1
omg my error was so easy and still I overlooked it over and over again

JASS:
local integer lvl=GetUnitAbilityLevel(u, 'A00N')


had the wrong unit to take the abil level from :banghead:, everything working now.

€: btw, my first loop leaks a unit everytime, doesn't it? However, I can't null it properly since the condition for the loop to finish is "u=null" and if I would null it everytime the loop runs, the loop would end on the first run. How would I fix this?
 

RaiJin

New Member
Reaction score
40
You cannot give arrays initial values. You're going to need to do something like this;

JASS:

scope yourscope initializer onInit

globals
    private constant integer array UNIT
endglobals

private function onInit takes nothing returns nothing
    set UNIT[1]='h003'
    set UNIT[2]='h004'
endfunction

endscope


correct me if im wrong but, im pretty sure you can't have constant arrays can you?
 

Saldu

New Member
Reaction score
1
Well, they don't need to be constant if I'm careful to never change them, right?

Now I just need to know if the unit in the first loop leaks, and how I would go about removing the leak, since nulling it inside the loop would stop the loop, but nulling it outside isn't possible since it changes in each run of the loop.
 
Reaction score
341
Well, they don't need to be constant if I'm careful to never change them, right?

Now I just need to know if the unit in the first loop leaks, and how I would go about removing the leak, since nulling it inside the loop would stop the loop, but nulling it outside isn't possible since it changes in each run of the loop.

Your loop doesn't leak.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top