HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

error in second iteration of loop

03-21-2008, 05:01 PM#1
hobo
So... I've got this loop in my action function. It picks the first unit in a group and has the hero damage him. Then checks to see if he died via the alive function. All the units in the group are footmen with .405 to 201 health. The first time through the loop it kills the target then displays "dead" but then all subsequent times through it fails to kill the target and displays "WTF!! die"
Any ideas why?

Collapse JASS:
function alive takes widget u returns boolean
return (GetWidgetLife(u) > 0.405)
endfunction


//loop extracted from actions function.
        loop

set n = FirstOfGroup(g)

            call UnitDamageTargetBJ(u,n,5000,ATTACK_TYPE_HERO,DAMAGE_TYPE_MAGIC)

            
            if alive(n) == false then
                call BJDebugMsg("dead")
         else
                call BJDebugMsg("WTF!!! die")
            endif
           
             call GroupRemoveUnit(g,n)   
            set i = i-1
            exitwhen (i == 0 or FirstOfGroup(g) == null)
         endloop   
03-21-2008, 05:37 PM#2
Rising_Dusk
Make sure your units aren't surviving the damage somehow. There could be any number of things doing this depending on your map, such as conflicting onDamage triggers or invulnerable units or whatever. Also, consider getting rid of the 'alive' function and just inlining it. Might as well post the whole function, seeing just a piece doesn't always give enough information.

Strictly based on what you've provided, though, there's no reason the unit should be displaying that it's alive unless it did, in fact, survive the damage.
03-21-2008, 05:50 PM#3
hobo
nothing else is going on damage-wise and the second unit is virtually identical to the first. I'll post the whole script but its a bit complicated.

The spell is basically force of nature for footmen instead of trees.
Collapse JASS:
scope NaturesHeart

globals
    constant integer UID_CASTERX ='e001'
    constant integer AID_NATURES_HEART = 'AEnh'
    constant integer AID_NATURES_HEART_CASTERX = 'A01G'
    constant integer UID_NATURES_HEART_FILTER_UNIT = 'hfoo'        //change this if you want     
    constant integer UID_NATURES_HEART_CASTER = 'Ekee'
    constant integer OID_NATURES_HEART = 852109 //"healingward" order converted to orderid integer
    private player p
endglobals
//------------------CONDITIONS---------------------------------//
private function Conditions takes nothing returns boolean
local boolean bOrderCorrect = GetIssuedOrderId() == OID_NATURES_HEART
local boolean bCasterCorrect = GetUnitTypeId(GetOrderedUnit()) == UID_NATURES_HEART_CASTER
local boolean bSpellCorrect =  GetSpellAbilityId() == AID_NATURES_HEART
local boolean bSpellCast = GetTriggerEventId()==EVENT_PLAYER_UNIT_SPELL_CAST 
local boolean bSpellFinish =   GetTriggerEventId()==EVENT_PLAYER_UNIT_SPELL_EFFECT
local boolean bOrderIssued =   GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER

 if bOrderCorrect and bCasterCorrect then //order issued
    return true
endif
if ((bSpellCast or bSpellFinish) and bSpellCorrect) then //casting started or finished
    return true
endif    
    return false
endfunction
//------------------END CONDITIONS---------------------------------//
//------------------NECESSITIES---------------------------------//
private function Filter takes nothing returns boolean
local unit f = GetFilterUnit()
local boolean a = alive(f)
local boolean b = GetUnitTypeId(f) == UID_NATURES_HEART_FILTER_UNIT
local boolean c = IsUnitAlly(f,p)
set f = null
return (a and b) and not c
endfunction

//------------------END NECESSITIES---------------------------------//
//------------------ACTIONS---------------------------------//
private function Actions takes nothing returns nothing
local eventid e = GetTriggerEventId()
local unit u = null
local location l = null
local group g = CreateGroup()
local integer i = 0
local unit n = null
local unit ent = null
local real facing = 0


    if e == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
        set l = GetOrderPointLoc()
        set u = GetOrderedUnit()
    else
    //call BJDebugMsg("spell Ordered or started")
        set l = GetSpellTargetLoc()
        set u = GetSpellAbilityUnit()
    endif    
    set p = GetOwningPlayer(u)
    
    call GroupEnumUnitsInRangeOfLoc(g,l,75+(75*I2R(GetUnitAbilityLevel(u,AID_NATURES_HEART))),Condition(function Filter))
    call RemoveLocation(l)

if (e != EVENT_PLAYER_UNIT_SPELL_EFFECT and FirstOfGroup(g) == null) then  // spell ordered or begun - check for targets
//call BJDebugMsg("group empty")
        call DisplayTimedTextToPlayer( p, 0.52, -1.00, 2.00, "|cffffcc00No Valid Targets in Range|r" )
        set l = GetUnitLoc(u)
        call IssuePointOrderLoc( u, "move", l) 
        //call RemoveLocation(l)
     
elseif e == EVENT_PLAYER_UNIT_SPELL_EFFECT then//its go time!
//call BJDebugMsg("spell finish")
        set i = 1+GetUnitAbilityLevel(u,AID_NATURES_HEART) //use this line to alter number of treants/footmen produced/killed
  
        loop
            //call BJDebugMsg(I2S(CountUnitsInGroup(g))+"in range")
            //call BJDebugMsg(I2S(i))
            set n = FirstOfGroup(g)
            //call BJDebugMsg(UnitId2String(GetUnitTypeId(n)))
            set l = GetUnitLoc(n)   
           
(u,n,5000,ATTACK_TYPE_HERO,DAMAGE_TYPE_MAGIC)
            
            if alive(n) == false then
                //call BJDebugMsg(I2S(i)+ "in loop")
                set facing = GetUnitFacing(n)
                set ent = CreateUnitAtLoc(p,'efon',l,facing)
                call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" ,ent,"origin"))
              set ent = null
         else
                call BJDebugMsg("WTF!!! die")
            endif
                                   
           
            call RemoveLocation(l)
            call GroupRemoveUnit(g,n)
            set n = null
            set u = null
                
            set i = i-1
            exitwhen (i == 0 or FirstOfGroup(g) == null)
         endloop   
endif 
    call DestroyGroup(g)


set t = null
set e = null
endfunction
//------------------END ACTIONS---------------------------------//

public function InitTrig takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )  
    call TriggerAddCondition( t, Condition( function Conditions ) )
    call TriggerAddAction( t, function Actions )
endfunction

endscope
03-21-2008, 06:04 PM#4
Rising_Dusk
Have you tried increasing the damage you deal to see if it matters? I can see no real reason (Your code is relatively hard to read with scattered indents and such, though) why 5000 damage would not kill a footman.
Collapse JASS:
call TimerStart(t,.01,false,function DoNothing)
What's the point of that?
03-21-2008, 06:07 PM#5
hobo
that my friend was a useless bit of a code, a typo if you will. I have edited it out.

Update----------------------------------------------------------------------

I changed the unit that was ordered to do the damage and it worked perfectly.
ummm no Idea why though, I changed it to a building.

update2------------------------------------------------------------

GOD &^$#&^%$^%$*$*
Collapse JASS:

        loop
            //call BJDebugMsg(I2S(CountUnitsInGroup(g))+"in range")
            //call BJDebugMsg(I2S(i))
            set n = FirstOfGroup(g)
            //call BJDebugMsg(UnitId2String(GetUnitTypeId(n)))
            set l = GetUnitLoc(n)   
           
(u,n,5000,ATTACK_TYPE_HERO,DAMAGE_TYPE_MAGIC)
            
            if alive(n) == false then
                //call BJDebugMsg(I2S(i)+ "in loop")
                set facing = GetUnitFacing(n)
                set ent = CreateUnitAtLoc(p,'efon',l,facing)
                call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\NightElf\\EntBirthTarget\\EntBirthTarget.mdl" ,ent,"origin"))
              set ent = null
         else
                call BJDebugMsg("WTF!!! die")
            endif
                                   
           
            call RemoveLocation(l)
            call GroupRemoveUnit(g,n)
            set n = null
         ===>set u = null<==== should be outside of loop!

            set i = i-1
            exitwhen (i == 0 or FirstOfGroup(g) == null)
         endloop   

endif 
    call DestroyGroup(g)
set e = null
endfunction

thanks for the replies RD
btw isn't there some way to do highlighting here?
03-22-2008, 08:11 AM#6
Pyrogasm
Yeah, you can highlight your code.