HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Diablo Lightning Spell, problem with defining and storing group

07-15-2007, 12:34 PM#1
Just_a°fOol
hey

I made this diablo1 lightning spell the last week and it works really good (although it might be more complicated than it could be) but the fact that every unit damaged by the lightning is damaged more than one time, which shouldn't be.

I add the units to the group "hT" (hit targets) and filter them later...
but unfortunately something doesn't work there

I really tried everything, but nothing seems so solve this problem...
so...what am I doing wrong?

Wish

here the trigger:
Collapse JASS:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function I2U takes integer i returns unit
    return i
    return null
endfunction

function I2G takes integer i returns group
    return i
    return null
endfunction

function I2E takes integer i returns effect
    return i
    return null
endfunction

constant function Lightning_Code takes nothing returns integer
    return 'A000' //the raw code for the dummy ability
endfunction

function Trig_Spell_Lightning_Conditions takes nothing returns boolean
    if ( GetSpellAbilityId() == Lightning_Code() ) then
        return true
    endif
    return false
endfunction

function Spell_Lightning_TimerFunc takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit f
    
    local string mk = I2S(H2I(t))
    local unit c = I2U( GetStoredInteger(udg_GC,mk,"caster") )
    local real a = GetStoredReal(udg_GC,mk,"angle")
    local real v = GetStoredReal(udg_GC,mk,"velocity")
    local real r = GetStoredReal(udg_GC,mk,"range")
    local real dmg = GetStoredReal(udg_GC,mk,"dmg")
    local integer e_count = GetStoredInteger(udg_GC,mk,"e_count")
    local group hT = I2G( GetStoredInteger(udg_GC,mk,"hT") )
    local real sl_x = GetStoredReal(udg_GC,mk,"sl_x")
    local real sl_y = GetStoredReal(udg_GC,mk,"sl_y")
    local real nl_x = GetStoredReal(udg_GC,mk,"nl_x") + (Cos(Deg2Rad(a))*v)
    local real nl_y = GetStoredReal(udg_GC,mk,"nl_y") + (Sin(Deg2Rad(a))*v)
    local effect array e
    local integer i = 1

    local location l = Location(nl_x,nl_y)

    loop
        exitwhen i > e_count
        set e[i] = I2E( GetStoredInteger(udg_GC,mk,"effect"+I2S(i)) ) //set effects
        set i = i + 1
    endloop
    
    set udg_GroupTemp = GetUnitsInRangeOfLocAll(110.00,l)
    loop
        set f = FirstOfGroup(udg_GroupTemp)
        exitwhen f == null
        if IsUnitAliveBJ(f) == true and IsUnitEnemy(f, GetOwningPlayer(c)) == true and IsUnitInGroup(f,hT) == false then
            call UnitDamageTargetBJ(c,f,dmg,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNKNOWN)
            call GroupAddUnit(hT,f)
        endif
        call GroupRemoveUnit(udg_GroupTemp,f)
    endloop 
    call DestroyGroup(udg_GroupTemp)
    
    if SquareRoot( ((nl_x - sl_x)*(nl_x - sl_x)) + ((nl_y - sl_y)*(nl_y - sl_y)) ) < r then
        call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",nl_x,nl_y)
        if not(e[e_count] == e[e_count - 1]) then
            call DestroyEffect(e[e_count])       //destroy last effect
        endif
        set i = e_count
        loop
            exitwhen i == 1
            set e[i] = e[i-1]
            set i = i - 1
        endloop
        set e[1] = GetLastCreatedEffectBJ()
        call StoreInteger(udg_GC,mk,"e_count",e_count)
        call StoreReal(udg_GC,mk,"nl_x",nl_x)
        call StoreReal(udg_GC,mk,"nl_y",nl_y)
        call StoreInteger(udg_GC,mk,"hT",H2I(hT))
    else      
        call DestroyEffect(e[e_count])
        set e[e_count] = e[e_count - 1]
        set e_count = e_count - 1
        if e[1] == null then
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushStoredMissionBJ(mk,udg_GC)
            set c = null
            set t = null
            call DestroyGroup(hT)
            set hT = null
        endif    
    endif

    call RemoveLocation(l)
    set l = null    
    set c = null
    set t = null    
    set c = null
    set f = null
    set mk = null
endfunction

function Trig_Spell_Lightning_Actions takes nothing returns nothing
    local unit f //filter unit
    local string mk
    local integer i = 1 //index
    
    local timer t = CreateTimer()
    
//vars to save:    
    local unit c = GetSpellAbilityUnit()
    local effect array e
    local real a = AngleBetweenPoints(GetUnitLoc(c),GetSpellTargetLoc())
    local real v = ( (GetUnitAbilityLevel(c,Lightning_Code())*5) + 15) //units per timer, 20/25/30/35 every 0.03 seconds
    local real r = ( (GetUnitAbilityLevel(c,Lightning_Code())*300) + 900 ) //range: 1200/1500/1800/2100
    local integer e_count = ( (GetUnitAbilityLevel(c,Lightning_Code())*5) + 5) //number of effects, 10/15/20/25
    local group hT = CreateGroup() //already hit targets
    local real dmg = (GetUnitAbilityLevel(c,Lightning_Code()) * 55.00) //damage amount, 55/110/165/220
    local real sl_x = GetUnitX(c)
    local real sl_y = GetUnitY(c)
    local real tl_x = GetLocationX(GetSpellTargetLoc())
    local real tl_y = GetLocationY(GetSpellTargetLoc())
    local real nl_x = sl_x + (Cos(a)*v)
    local real nl_y = sl_y + (Sin(a)*v)
    call RemoveLocation(GetUnitLoc(c))
    call RemoveLocation(GetSpellTargetLoc())
    
    
    
//first action:
    call AddSpecialEffect("Abilities\\Weapons\\Bolt\\BoltImpact.mdl",nl_x,nl_y)
//effects are saved later
    call GroupEnumUnitsInRange(udg_GroupTemp,nl_x,nl_y,110.00,null)
    loop
        set f = FirstOfGroup(udg_GroupTemp)
        exitwhen f == null
        if IsUnitAliveBJ(f) == true and IsUnitEnemy(f, GetOwningPlayer(c)) == true and IsUnitInGroup(f,hT) == false then
            call UnitDamageTargetBJ(c,f,dmg,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNKNOWN)
            call GroupAddUnit(hT,f)
        endif
        call GroupRemoveUnit(udg_GroupTemp,f)
    endloop
    call DestroyGroup(udg_GroupTemp)
    
//store variables
    set mk = I2S(H2I(t))
    call StoreInteger(udg_GC,mk,"caster",H2I(c))
    call StoreReal(udg_GC,mk,"sl_x",sl_x)
    call StoreReal(udg_GC,mk,"sl_y",sl_y)
    call StoreReal(udg_GC,mk,"angle",a)
    call StoreReal(udg_GC,mk,"velocity",v)
    call StoreReal(udg_GC,mk,"range",r)
    call StoreReal(udg_GC,mk,"dmg",dmg)
    call StoreInteger(udg_GC,mk,"e_count",e_count)
    call StoreReal(udg_GC,mk,"nl_x",nl_x)
    call StoreReal(udg_GC,mk,"nl_y",nl_y)
    call StoreInteger(udg_GC,mk,"hT",H2I(hT))       
    loop
        exitwhen i > e_count                                   //saved
        set e[i] = GetLastCreatedEffectBJ()                    //the
        call StoreInteger(udg_GC,mk,"effect"+I2S(i),H2I(e[i])) //effects
        set i = i + 1                                          //here
    endloop
    
    call TimerStart(t,0.03,true,function Spell_Lightning_TimerFunc)
    
    set mk = null
    set c = null
    set f = null
endfunction

//==== Init Trigger Spell_Lightning ====
function InitTrig_Spell_Lightning takes nothing returns nothing
    set gg_trg_Spell_Lightning = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Spell_Lightning, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Spell_Lightning, Condition(function Trig_Spell_Lightning_Conditions))
    call TriggerAddAction(gg_trg_Spell_Lightning, function Trig_Spell_Lightning_Actions)
endfunction
07-15-2007, 01:02 PM#2
TheSecretArts
add lots of debug msgs to see what is being called and what isnt. Also it can help you find if there was a problem setting variables and such.
07-15-2007, 01:17 PM#3
CommanderZ
I like using pings for this. Insert one ForGroup loop before the loop where you do the damage with the function which will ping every single unit in the group.
07-16-2007, 03:53 PM#4
Just_a°fOol
sry commander
i don't understand what you mean
never heard of "pings"
:(
07-16-2007, 11:40 PM#5
Pyrogasm
You know, an in-game ping. The colored "!" things. He's saying like so:
Collapse JASS:
    loop
        set f = FirstOfGroup(udg_GroupTemp)
        exitwhen f == null
        call PingMinimap(GetUnitX(f), GetUnitY(f), 1.00)
        if IsUnitAliveBJ(f) == true and IsUnitEnemy(f, GetOwningPlayer(c)) == true and IsUnitInGroup(f,hT) == false then
            call UnitDamageTargetBJ(c,f,dmg,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_UNKNOWN)
            call GroupAddUnit(hT,f)
        endif
        call GroupRemoveUnit(udg_GroupTemp,f)
    endloop

It'll show you which units are being picked.
07-17-2007, 08:12 AM#6
CommanderZ
Ping is the thing you spam when you hit alt and start clicking somewhere on map or game area :P
07-17-2007, 06:15 PM#7
Just_a°fOol
well
units are picked

but the group "hT" is empty
how come??
I really wonder
oO

edit:
okay...now I'm just laughing my ass off
i don't know exactly what i changed now
but
now it works pretty good ^^