HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

my group only picks 1 unit from a group with lots of units?

06-20-2009, 12:25 PM#1
Sinnergy
What the hell, I tracked the code and found nothing that conflicts with the unit group, I used to pick groups in a loop, but now I am confused why my unit group only picks 1 unit then ends the loop? and any function inside the loop won't work with the picked unit, like I tried dealing damage on the picked unit inside the loop, and nothing works. Please don't point out unknown functions in the code, while they are already commonly used in my map, and all of them works.

I tried adding debug messages, one inside the loop, it shows the name of the unit, but doesn't deal damage on the unit, or any other function doesn't work with the picked unit.

Collapse JASS:
scope WisdomStrike initializer init

globals
    private constant integer spell = 'A01R'
    private constant integer dum = 'e007'
    private constant integer dum2 = 'e008'
    private constant string lnd = "MDX\\DustAndRocks.mdx"
    private constant string wtr = "MDX\\SlideWater.mdx"
endglobals

private struct jump
    static HandleTable T
    unit p
    integer l
    static method add takes unit p, integer l returns jump
        local jump d = jump.allocate()
        set d.p = p
        set d.l = l
        return d
    endmethod
endstruct

private struct data
    unit c
    unit u
    integer l
    integer int
    real x
    real y
    private method onDestroy takes nothing returns nothing
        set .u = null
    endmethod
endstruct

private function end takes nothing returns nothing
    local unit u = GetUnitProjectile()
    local jump d = jump(jump.T[u])
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local xedamage xe = xedamage.create()
    set xe.dtype = DTDARK
    set xe.exception = UNIT_TYPE_STRUCTURE
    call xe.damageTarget(d.p,u,60*d.l)
    call xe.destroy()
    call SetUnitFlyHeight(u,0.0,0.0)
    call IssueLastOrder(u)
    call BJDebugMsg("end")
    if IsTerrainPathingType(x,y,TERRAIN_PATHING_LAND) then
        call StartTimedEffect(AddSpecialEffect(lnd,x,y),0.5)
    elseif IsTerrainPathingType(x,y,TERRAIN_PATHING_SHALLOW) then
        call StartTimedEffect(AddSpecialEffect(wtr,x,y),0.5)
    endif
    call d.destroy()
    call jump.T.flush(u)
    set u = null
endfunction

private function callBack takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local data d = GetTimerData(t)
    local group g = NewGroup()
    local unit m
    local real tx
    local real ty
    local real a
    local unit dummy = CreateUnit(GetOwningPlayer(d.c),dum2,d.x,d.y,0.0)
    local xedamage xe = xedamage.create()
    set xe.dtype = DTDARK
    set xe.exception = UNIT_TYPE_STRUCTURE
    call xe.damageAOE(d.c,d.x,d.y,300.0,d.int * d.l)
    call xe.destroy()
    call SetUnitTimeScale(dummy,0.3)
    call SetUnitVertexColor(dummy,202,0,202,255)
    call UnitApplyTimedLife(dummy,'BTLF',1.0)
    call KillUnit(d.u)
    call earthShake(d.x,d.y,true,1.0,200.0,600.0, 200.0)
    call BJDebugMsg("blow")
    call GroupEnumUnitsInRange(g,d.x,d.y,300.0,null)
    loop
        set m = FirstOfGroup(g)
        exitwhen m == null
        if IsUnitEnemy(m,GetOwningPlayer(d.c)) and GetWidgetLife(m) > 0.405 and not IsUnitType(m,UNIT_TYPE_STRUCTURE) then
            call BJDebugMsg("pick" + GetUnitName(m))
            set tx = GetUnitX(m)
            set ty = GetUnitY(m)
            set a = Atan3(d.x,d.y,tx,ty)
            set jump.T[m] = integer(jump.add(d.c,d.l))
            call KnockBack(m,350,a,200,1000,null,function end, true)
        endif
        call GroupRemoveUnit(g,m)
    endloop
    call ReleaseGroup(g)
    call ReleaseTimer(t)
    call d.destroy()
    set g = null
    set m = null
    set t = null
    set dummy = null
endfunction

private function act takes nothing returns nothing
    local unit c = SpellEvent.CastingUnit
    local real x = SpellEvent.TargetX
    local real y = SpellEvent.TargetY
    local integer l = GetUnitAbilityLevel(c,spell)
    local timer t = NewTimer()
    local data d = data.create()
    call BJDebugMsg("start")
    set d.c = c
    set d.l = l
    set d.x = x
    set d.y = y
    set d.u = CreateUnit(GetOwningPlayer(c),dum,x,y,0.0)
    set d.int = GetHeroInt(c,true)
    call SetUnitVertexColor(d.u,202,0,202,255)
    call TimerStart(t,1.0,false,function callBack)
    call SetTimerData(t,d)
    set t = null
    set c = null
endfunction

private function init takes nothing returns nothing
    call RegisterSpellEffectResponse(spell,act)
endfunction

endscope

SpellEvent.TargetX and SpellEvent.TargetY are the coordinates of the target point
06-20-2009, 04:04 PM#2
snowtiger
Edit: nvm, my eyes are tricking me...
06-21-2009, 04:12 AM#3
Zerzax
This won't necessarily solve your problem with the first of group loop, but you might want to consider sorting through the units you find with an actual boolexpr instead of a null one (which causes a memory leak) and that may clear some things up. Also, while your extra functions may work fine on their own, what if they affect the unit enumeration? Sometimes it's harder to find the problem without seeing the whole picture.
06-21-2009, 10:58 AM#4
Anitarf
Which knockback system are you using?
06-24-2009, 10:43 AM#5
Sinnergy
done fixing the spell