HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell Problem please help :(

10-06-2007, 04:36 PM#1
Tiku
okay so im making a spell that is like a mini-void, it sucks units in, (not alot), and it deals 100 damage over 4 seconds, and its aoe...

its based off the aoe spell blizzard
heres the code:
Collapse JASS:
constant function voidsfx takes nothing returns integer
    return 'h001'
endfunction

function Trig_Oblivion_Pulse_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A000' )
endfunction

function notspellimmune takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction
    
function VoidPulse takes nothing returns nothing
    local integer i = H2I(GetExpiredTimer())
    local unit u = GetHandleUnit(I2Timer(i), "caster" )
    local real x = GetHandleReal(I2Timer(i), "x" )
    local real y = GetHandleReal(I2Timer(i), "y" )
    local boolexpr check = Condition(function notspellimmune)
    local integer stop = GetHandleInt(I2Timer(i), "stop" )
    local unit void = GetHandleUnit(I2Timer(i), "void" )
    local group g
    local unit dmg   
    local real dmx
    local real dmy
    local real move
    local location l = Location(x, y) 
    
    set stop = stop+1
    call SetHandleInt(I2Timer(i), "stop", stop )
    call GroupEnumUnitsInRange(g, x, y, 450, check )
    
    if stop != 4 then
     loop
      set dmg = FirstOfGroup(g)
     exitwhen dmg == null or stop == 4
      set dmx = GetUnitX(dmg)
      set dmy = GetUnitY(dmg)
      set move = Atan2(dmy-y, dmx-x)
      call SetUnitPositionLoc(dmg, PolarProjectionBJ(l, DistanceBetweenPoints(l, GetUnitLoc(dmg)),AngleBetweenPoints(l, GetUnitLoc(dmg)))) 
      call UnitDamageTarget(u, dmg, 25.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS) 
      call GroupRemoveUnit(g, dmg)
     endloop
     else
      call DestroyTimer(I2Timer(i))
    endif
    if stop == 4 then
     call KillUnit(void)
    endif 
    set void = null
    set u = null
    set g = null 
endfunction

function Trig_Oblivion_Pulse_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local player up = GetOwningPlayer(u)
    local location aoe = GetSpellTargetLoc()
    local real x = GetLocationX(aoe)
    local real y = GetLocationY(aoe)
    local integer i = H2I(CreateTimer())
    local integer t = H2I(CreateTimer())
    local unit void = CreateUnit(up, voidsfx(), x, y, 0.0)
    
    call SetHandleHandle(I2Timer(i), "void", void )
    call SetHandleReal(I2Timer(i), "x", x )
    call SetHandleReal(I2Timer(i), "y", y )
    call SetHandleHandle(I2Timer(i), "caster", u )
    call SetHandleInt(I2Timer(i), "stop", 0 )
    call TimerStart(I2Timer(t), 0.33, true, function VoidPulse) 
endfunction

//===========================================================================
function InitTrig_Oblivion_Pulse takes nothing returns nothing
    set gg_trg_Oblivion_Pulse = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Oblivion_Pulse, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Oblivion_Pulse, Condition( function Trig_Oblivion_Pulse_Conditions ) )
    call TriggerAddAction( gg_trg_Oblivion_Pulse, function Trig_Oblivion_Pulse_Actions )
endfunction


i dont know whats wrong with it, and i used the handle vars...

please help
10-06-2007, 04:57 PM#2
Fireeye
Well, i don't know your problem, but i took a quick look and found at least 1 thing.
Collapse JASS:
function notspellimmune takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction
Replace the GetTriggerUnit() with GetFilterUnit()
if i find more i'll edit the post.

---EDIT1---
omg so many errors, i gonna rewrite it, due it CAN NOT work like this.
You're creating 2 timers, start only 1 and the other where the datas are stored is wasted.
---EDIT2--
Alright this should work (didn't test it yet), however why did you create 2 Timers?!
Hidden information:
Collapse JASS:
constant function voidsfx takes nothing returns integer
    return 'h001'
endfunction

constant function AttractSpeed takes nothing returns real
    return 5.
endfunction

function Trig_Oblivion_Pulse_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A000' )
endfunction

function notspellimmune takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction

function VoidPulse takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = GetHandleUnit(t, "caster" )
    local real x = GetHandleReal(t, "x" )
    local real y = GetHandleReal(t, "y" )
    local boolexpr check = Condition(function notspellimmune)
    local integer stop = GetHandleInt(t, "stop" )
    local unit void = GetHandleUnit(t, "void" )
    local group g = CreateGroup() //Why not using a global group over and over, no need to destroy then ...
    local unit dmg
    local real dmx
    local real dmy
    local real move
    call SetHandleInt(t, "stop", stop + 1 )
    call GroupEnumUnitsInRange(g, x, y, 450, check )
    if stop < 4 then
        loop
            set dmg = FirstOfGroup(g)
            exitwhen dmg == null or stop >= 4
            set dmx = GetUnitX(dmg)
            set dmy = GetUnitY(dmg)
            set move = Atan2(dmy-y, dmx-x)
            call SetUnitX(dmg,dmx+AttractSpeed()*Cos(move))
            call SetUnitY(dmg,dmy+AttractSpeed()*Sin(move))
            call UnitDamageTarget(u, dmg, 25.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
            call GroupRemoveUnit(g, dmg)
        endloop
    else
        call KillUnit(void)
        call FlushHandleLocals(t)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    call DestroyGroup(g)
    set t = null
    set void = null
    set u = null
    set g = null
endfunction

function Trig_Oblivion_Pulse_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local player up = GetOwningPlayer(u)
    local location aoe = GetSpellTargetLoc()
    local real x = GetLocationX(aoe)
    local real y = GetLocationY(aoe)
    local timer t = CreateTimer()
    local unit void = CreateUnit(up, voidsfx(), x, y, 0.0)
    call SetHandleHandle(t, "void", void )
    call SetHandleReal(t, "x", x )
    call SetHandleReal(t, "y", y )
    call SetHandleHandle(t, "caster", u )
    call SetHandleInt(t, "stop", 0 )
    call TimerStart(t, 0.33, true, function VoidPulse)
    call RemoveLocation(aoe)
    set aoe = null
    set u = null
    set up = null
    set t = null
    set void = null
endfunction

//===========================================================================
function InitTrig_Oblivion_Pulse takes nothing returns nothing
    set gg_trg_Oblivion_Pulse = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Oblivion_Pulse, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Oblivion_Pulse, Condition( function Trig_Oblivion_Pulse_Conditions ) )
    call TriggerAddAction( gg_trg_Oblivion_Pulse, function Trig_Oblivion_Pulse_Actions )
endfunction


---EDIT3---
You also never heard about leaks did you?
10-06-2007, 05:14 PM#3
Tiku
Really? wow, alot of errors? im not sure what happened, i changed
Collapse JASS:
function notspellimmune takes nothing returns boolean
    return IsUnitType(GetTriggerUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction

to

Collapse JASS:
function notspellimmune takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction

i dont get errors, it just still doesnt work
10-06-2007, 05:28 PM#4
Fireeye
I had to fix more than 1 problem.
Tiku don't get angry, but i think you should really learn the basic things of programming before start trying a spell or something, cause you created 2 timers, used only 1 (the wrong one) for the callback and didn't even clean leaks up (don't know if you planned to do so, but cleaning leaks is one of the fastest parts done).
I wrote a hopefully working code in my first post (as i wrote i didn't test it yet).
10-06-2007, 05:32 PM#5
Tiku
hah i wont get angry your helping me out :D

but umm, yeah i first learned GUI then traveled onto JASS.. i basically only use JASS for spell making, but im still kinda knew to alot of stuff, i mean i started learn around March of 07, so yeah :P

i know i was suppose to destroy the timers, i just wasnt exacly sure how, cause i barely started learning how to use the Handle Vars to transfer data...

but yeah im using the wrong timer?
10-06-2007, 05:36 PM#6
Fireeye
Yeah, let's analyze your trigger a bit more.
Collapse JASS:
    local integer i = H2I(CreateTimer())
    local integer t = H2I(CreateTimer())
Creates 2 Timer in Integer format (well, kinda senseless, due the SetHandeX takes a handle as first argument)
In this part you Store all Informations on the first created Timer
Collapse JASS:
    call SetHandleHandle(I2Timer(i), "void", void )
    call SetHandleReal(I2Timer(i), "x", x )
    call SetHandleReal(I2Timer(i), "y", y )
    call SetHandleHandle(I2Timer(i), "caster", u )
    call SetHandleInt(I2Timer(i), "stop", 0 )
And Here you start the 2nd Timer, so the ExpiredTimer will always be != i
Collapse JASS:
    call TimerStart(I2Timer(t), 0.33, true, function VoidPulse) 
Due this "problem" you won't ever be able to get the correct stored values (if you should ever get value != 0/null).
10-06-2007, 05:46 PM#7
Tiku
Quote:
Originally Posted by Fireeye
---EDIT2--
Alright this should work (didn't test it yet), however why did you create 2 Timers?!
Hidden information:
Collapse JASS:
constant function voidsfx takes nothing returns integer
    return 'h001'
endfunction

constant function AttractSpeed takes nothing returns real
    return 5.
endfunction

function Trig_Oblivion_Pulse_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == 'A000' )
endfunction

function notspellimmune takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) != true
endfunction

function VoidPulse takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = GetHandleUnit(t, "caster" )
    local real x = GetHandleReal(t, "x" )
    local real y = GetHandleReal(t, "y" )
    local boolexpr check = Condition(function notspellimmune)
    local integer stop = GetHandleInt(t, "stop" )
    local unit void = GetHandleUnit(t, "void" )
    local group g = CreateGroup() //Why not using a global group over and over, no need to destroy then ...
    local unit dmg
    local real dmx
    local real dmy
    local real move
    call SetHandleInt(t, "stop", stop + 1 )
    call GroupEnumUnitsInRange(g, x, y, 450, check )
    if stop < 4 then
        loop
            set dmg = FirstOfGroup(g)
            exitwhen dmg == null or stop >= 4
            set dmx = GetUnitX(dmg)
            set dmy = GetUnitY(dmg)
            set move = Atan2(dmy-y, dmx-x)
            call SetUnitX(dmg,dmx+AttractSpeed()*Cos(move))
            call SetUnitY(dmg,dmy+AttractSpeed()*Sin(move))
            call UnitDamageTarget(u, dmg, 25.0, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
            call GroupRemoveUnit(g, dmg)
        endloop
    else
        call KillUnit(void)
        call FlushHandleLocals(t)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    call DestroyGroup(g)
    set t = null
    set void = null
    set u = null
    set g = null
endfunction

function Trig_Oblivion_Pulse_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local player up = GetOwningPlayer(u)
    local location aoe = GetSpellTargetLoc()
    local real x = GetLocationX(aoe)
    local real y = GetLocationY(aoe)
    local timer t = CreateTimer()
    local unit void = CreateUnit(up, voidsfx(), x, y, 0.0)
    call SetHandleHandle(t, "void", void )
    call SetHandleReal(t, "x", x )
    call SetHandleReal(t, "y", y )
    call SetHandleHandle(t, "caster", u )
    call SetHandleInt(t, "stop", 0 )
    call TimerStart(t, 0.33, true, function VoidPulse)
    call RemoveLocation(aoe)
    set aoe = null
    set u = null
    set up = null
    set t = null
    set void = null
endfunction

//===========================================================================
function InitTrig_Oblivion_Pulse takes nothing returns nothing
    set gg_trg_Oblivion_Pulse = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Oblivion_Pulse, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Oblivion_Pulse, Condition( function Trig_Oblivion_Pulse_Conditions ) )
    call TriggerAddAction( gg_trg_Oblivion_Pulse, function Trig_Oblivion_Pulse_Actions )
endfunction


---EDIT3---
You also never heard about leaks did you?

Wow, thank you so much... it does work :D
i effin love you!!!
+Rep
thank you for everything and thank you for your time :D

and actually i have heard about leaks, but kinda were like wierd with them...