HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

auto-trap system performance problems

01-24-2008, 03:09 AM#1
SockSquirrelMouthwash
I'm trying to get this little system in my map where any traps that are made are added to udg_trapgroup which is periodically checked by this function every second:

Collapse JASS:
globals
    private unit q
endglobals

private function Trap_Enemy_Filter takes nothing returns boolean
     if ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(q)) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 ) then
         return true
     endif
     return false
endfunction

private function automatictrapchecker takes nothing returns nothing
    local group g = CreateGroup()
    local unit u
    local real x
    local real y
    local boolexpr cond = Condition(function Trap_Enemy_Filter)
        
    loop
        set u = FirstOfGroup(udg_trapgroup)
        exitwhen u == null
        if ( GetUnitUserData(u) == 0 ) then 
            set x = GetLocationX(GetUnitLoc(u))
            set y = GetLocationY(GetUnitLoc(u))
            set q = u
            call GroupEnumUnitsInRange(g, x, y, GetUnitPointValue(u)-50, IFFconditions)
            if ( CountUnitsInGroup(g) > 0 and GetUnitState(u, UNIT_STATE_LIFE) > 0) then
                call SetUnitUserData(u, 100)
                call KillUnit(u)
                call GroupRemoveUnit(udg_trapgroup,u)
            endif
            call GroupClear(g)
        endif
    endloop
    call DestroyGroup(g)
    set u = null
    set g = null
endfunction

The problem is when there are units in udg_trapgroup the game starts becoming semi-choppy every second, whenever the function is executed. How can I optimize this function to eliminate the performance issue? or is that just the nature with loops with groups?
01-24-2008, 03:21 AM#2
The Elite
well for a start you can replace:
Collapse JASS:
private function Trap_Enemy_Filter takes nothing returns boolean
     if ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(q)) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 ) then
         return true
     endif
     return false
endfunction
with
Collapse JASS:
private function Trap_Enemy_Filter takes nothing returns boolean
     return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(q)) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
endfunction
01-24-2008, 03:42 AM#3
SockSquirrelMouthwash
Quote:
Originally Posted by The_Elite
well for a start you can replace:
Collapse JASS:
private function Trap_Enemy_Filter takes nothing returns boolean
     if ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(q)) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 ) then
         return true
     endif
     return false
endfunction
with
Collapse JASS:
private function Trap_Enemy_Filter takes nothing returns boolean
     return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(q)) == true ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitIdType(GetUnitTypeId(GetFilterUnit()), UNIT_TYPE_HERO) == true ) and (GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0
endfunction
Thanks for the tip, that'll greatly simplify some triggers I have in my maps!

Hmmmm found out why it was choppy, each time I run the function the loop would continue indefinitely since u would never be null if none of the traps in the group ever met that condition... so I revamped it and it's now working fine:

Collapse JASS:
private function AutoTrapTrigger takes nothing returns nothing
    local group g = CreateGroup()
    local group chk = CreateGroup()
    local unit u
    local real x
    local real y
    local boolexpr cond = Condition(function Trap_Enemy_Filter)
    
    call GroupAddGroup(udg_trapgroup, chk)
    loop
        set u = FirstOfGroup(chk)
        exitwhen u == null
        if ( GetUnitUserData(u) == 0 ) then 
            set x = GetLocationX(GetUnitLoc(u))
            set y = GetLocationY(GetUnitLoc(u))
            set q = u
            call GroupEnumUnitsInRange(g, x, y, GetUnitPointValue(u)-50, cond)
            if ( CountUnitsInGroup(g) > 0 and GetUnitState(u, UNIT_STATE_LIFE) > 0) then
                call SetUnitUserData(u, 100)
                call KillUnit(u)
                call GroupRemoveUnit(udg_trapgroup,u)
            endif
            call GroupClear(g)
        endif
        call GroupRemoveUnit(chk,u)
    endloop
    call DestroyGroup(chk)
    call DestroyGroup(g)
    set chk = null
    set u = null
    set g = null
endfunction

although any optimizing suggestions are always welcome!