HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Bug in code

12-09-2008, 02:36 AM#1
cleeezzz
Collapse JASS:
library CAS requires CSData,CSSafety,HandyFunctions,FSL

globals
    private constant real Start = 50.00   
    private constant real Scale = 1.00            
    private constant real Fly_height = 60.00   
    private constant attacktype A = ATTACK_TYPE_CHAOS
    private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
    private unit Caster = null
endglobals

private function FilterIsEnemyAlive takes nothing returns boolean
    return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and (GetWidgetLife(GetFilterUnit())>0.405) and (IsUnitVisible(GetFilterUnit(),GetOwningPlayer(Caster)) or not UnitHasBuffBJ(GetFilterUnit(),'BOwk') or GetUnitTypeId(GetFilterUnit()) == 'oeye' ))
endfunction  

private function GravFilter takes nothing returns boolean
    return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))) and (GetWidgetLife(GetFilterUnit())>0.405) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO))
endfunction  

private function FilterIsEnemyAlive2 takes nothing returns boolean
    return (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))) and (GetWidgetLife(GetFilterUnit())>0.405) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE))
endfunction

private function KillTrees takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction
               
//=======================================================================
struct Arrow
    //! runtextmacro PUI()
    unit u
    unit d
    integer lvl
    real moved
    real cd
    real maxd
    real dmg
    real angle
    real anglechange
    real r
    real plx
    real ply
    real bases
    group g
    timer t
    boolean spell
    string sfx
    boolean grav
    real csd
    real acceleration

    
    static method create takes integer ut, unit u, integer lvl, real cx, real cy, real tx, real ty, real period, real r, real moved, real bases, real acceleration, real maxd, real dmg, unit items returns Arrow
        local integer index
        local item    indexItem
        local integer lvl2
        local integer i
        local unit ru
        local unit tu
        local item Item
        local integer II
        local real angle = AngleXY(cx,cy,tx,ty)
        local unit arrow
        local Arrow d = Arrow.allocate()
        local DS e
            if GetUnitTypeId(u) == 'H00I' then
                set e = DS[u]
                set ru = e.u
            else
                set ru = u
            endif
        set arrow = CreateUnit(GetOwningPlayer(ru),ut, PolarProjectionX (cx, Start, angle), PolarProjectionY (cy, Start, angle) , Rad2Deg(angle))
        set lvl2 = GetUnitAbilityLevel(ru,'A01X')
        set Arrow[arrow] = d
        set d.t = NewTimer()
        set d.u = ru
        set d.cd = Start
        set d.csd = 0
        set d.maxd = maxd
        set d.angle = angle
        set d.dmg = dmg
        set d.g = NewGroup()
        set d.r = r
        set d.d = arrow
        set d.lvl = lvl
        set d.plx = GetUnitX(d.d)
        set d.ply = GetUnitY(d.d)
        set d.acceleration = acceleration
        call GroupAddUnit(Arrows,d.d)
        call SetUnitMoveSpeed(d.d, moved)
        set d.bases = bases
        set d.moved = moved
        set d.spell = false
        set d.sfx = null
        set d.spell = false
        set d.anglechange = 0                
        call SetUnitPathing(d.d,false)
        call SetUnitScale(d.d,Scale,Scale,Scale)
        call SetUnitFlyHeight(d.d,Fly_height,0.00)
                
        call TimerStart(d.t,period,true,function Arrow.Execute)
        call SetCSData(d.t,d)
        set arrow = null
        set tu = null
        
        return Arrow[d.d]
    endmethod
    
    public static method SA takes integer ut, unit u, integer lvl, real cx, real cy, real tx, real ty, real period, real r, real moved, real bases, real acceleration, real maxd, real dmg, unit items returns nothing    
        call Arrow.create(ut,u,lvl,cx,cy,tx,ty,period,r,moved,bases,acceleration,maxd,dmg,items)
    endmethod

    
    static method Execute takes nothing returns nothing
        local real x
        local real y
        local real cx
        local real cy
        local real tx
        local real ty
        local real x2
        local real y2
        local real a
        local unit u
        local group g
        local group g2
        local group g3
        local real dist
        local real rdist
        local real angle
        local integer i = 0
        local TargetStruct e
        local Arrow d = GetCSData(GetExpiredTimer())
        set Caster = d.u

        set x = GetUnitX(d.d)
        set y = GetUnitY(d.d)
        set rdist = DistanceXY( x, y, d.plx, d.ply)
        if lvl >= 1 then
            set d.dmg = d.dmg + ((rdist/100)*lvl)
        endif
        
        set d.cd = d.cd + rdist
        set d.plx = x
        set d.ply = y
        
            if GetUnitState(d.d,UNIT_STATE_LIFE) < .405 then
                call d.release()
                return
            endif
            if d.cd >= d.maxd then
                call d.release()
                return
            endif
            
        call SetUnitFacing(d.d,GetUnitFacing(d.d) + d.anglechange)
        set d.anglechange = 0        
        set d.angle =  Deg2Rad(GetUnitFacing(d.d))
        set x = PolarProjectionX(x, d.moved, d.angle)
        set y = PolarProjectionY(y, d.moved, d.angle)
            if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then
                call d.release()
                return
            endif
            
        call SetUnitX(d.d, x)
        call SetUnitY(d.d, y)
            if d.moved < d.bases then
                set d.moved = d.moved + d.acceleration
            endif
        set g = NewGroup()
        set g2 = NewGroup()
        call GroupEnumUnitsInRange(g,x,y,d.r,Condition(function FilterIsEnemyAlive))
        call GroupEnumUnitsInRange(g2,x,y,100,Condition(function FilterIsEnemyAlive2))
        call GroupAddGroupAdv(g2,g)
        call ReleaseGroup(g2)
        set g2 = null
        set u = FirstOfGroup(g)
            if u == null then
                call GroupClear(d.g)
            else
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                    if not(IsUnitInGroup(u,d.g)) then
                        call GroupAddUnit(d.g,u)
                        call UnitDamageTarget(d.d,u,d.dmg ,false,false,A,D,null)
                    endif 
                call GroupRemoveUnit(g,u)                
            endloop
            endif
        set u = null
        call ReleaseGroup(g)
        set g = null                            
    endmethod
    
    method onDestroy takes nothing returns nothing
        call RemoveUnit(.d)
        set .u = null
        set .d = null
        call GroupRemoveUnit(Arrows,.d)
        call ReleaseGroup(.g)
        set .g = null
        call ReleaseTimer(.t)
        set .t = null
        set .spell = false
        set .grav = false
        set .sfx = null

    endmethod
endstruct

endlibrary


this is a projectile code

this code works fine for 800 - 1900 uses (used a counter with BJDebugs)
after that, every time i use it, it stops working. (Stops working as in, it can only have one projectile at a time, it removes all other projectiles in the map. ) im guessing it has something to do with CSData such as going over its limit, but it never gave me a warning message.
12-09-2008, 02:41 AM#2
Ammorth
make sure debug mode is enabled when saving with JassHelper.
12-09-2008, 02:56 AM#3
cleeezzz
debug mode crashes the game O_O

disabled a bunch of triggers and found out the error, it wasnt csdata, it was PUI

the error was WARNING: PUI - Bad unit handle

but why did i get this error? and by the time i get here, i have 14k handles all created from the code posted above (if possible, anyone help leak check? XD)


edit:

Collapse JASS:
// this happens when requesting unit index for removed unit
        debug if index == 0 then
        debug     call BJDebugMsg("|c00FFCC00WARNING: PUI - Bad unit handle")
        debug endif
but the code never requests PUI for a removed unit...
12-10-2008, 02:43 AM#4
cleeezzz
Collapse JASS:
        call RemoveUnit(.d)
        set .d = null
        call GroupRemoveUnit(Arrows,.d)

i removed a null unit from the group..

Fixed, however, if possible, can anyone do a quick leak check.