What's causing the slow down?

Homer

New Member
Reaction score
2
Can anyone help me optimize this function?
It is weird, because when like 8 things at the same time it slows down. and stays slow until the unit is removed. Not sure what is exactly causing it.

JASS:
function UnitDies takes nothing returns nothing
local unit u = GetDyingUnit()
local unit tempu = null
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real mag = 10
local group g2 = CreateGroup()
local unitData uD
local real distance = 0.00
local location array t_point[5]
local unitData uD_dying=GetUnitUserData(u)
//set x = GetUnitX(u)
//set y = GetUnitY(u)
//call DisplayTextToPlayer(Player(0),0,0,GetUnitName(u))         
if (GetUnitTypeId(u)=='h000') then
//call DisplayTextToPlayer(Player(0),0,0,"test2")
//call BJDebugMsg("dying unit x:"+R2S(x))
//call BJDebugMsg("dying unit y:"+R2S(y))
call GroupEnumUnitsInRange(g2,x,y,200,null) 
        loop
        set tempu = FirstOfGroup(g2)
//        call BJDebugMsg("test3")
        exitwhen tempu==null
        set uD=GetUnitUserData(tempu) 
        call GroupRemoveUnit(g2,tempu) //Do Stuff
        if (IsUnitAliveBJ(tempu)) then        
            if (GetUnitTypeId(tempu)=='h000') then
            call KillUnit(tempu)
            endif
            if (GetUnitTypeId(tempu)!='h000') then
            set t_point[0]=Location(x,y)
            set t_point[1]=Location(uD.x,uD.y)
            set distance = DistanceBetweenPoints(t_point[0],t_point[1])*.02
            if distance<1 then
            set distance=1
            endif
            
            call uD.AddForce(AngleBetweenPoints(t_point[0],t_point[1]),mag/distance)
            set uD.zforce=uD.zforce+17/distance
            endif
        endif
        call RemoveLocation (t_point[0])
        call RemoveLocation (t_point[1])
        set t_point[0]=null
        set t_point[1]=null
        endloop
        
call Explode(x,y)

endif
call DestroyGroup(g2) 
set g2 = null
call uD_dying.destroy()
call GroupRemoveUnitSimple(u, udg_physicgroup)
call TriggerSleepAction(1.0)
call RemoveUnit(u)
endfunction

//===========================================================================
function InitTrig_unit_dies takes nothing returns nothing
    local trigger trig = CreateTrigger(  )
call TriggerRegisterAnyUnitEventBJ( trig , EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( trig , function UnitDies)
endfunction


Heres the struct it references
JASS:
 function Explode takes real x, real y returns nothing
   local effect fx
   set fx=AddSpecialEffect("Objects\\Spawnmodels\\Human\\HCancelDeath\\HCancelDeath.mdl",x,y)
   call TriggerSleepAction(2)
   call DestroyEffect(fx)
   set fx = null
endfunction
struct unitData

real yforce  //up down force
real xforce  //left right force
real mag
real dir  //direction
real f=.2 //friction
real destx = 0.00  //x destination
real desty = 0.00  //y destination
real x = 0.00  //current x
real y = 0.00  //current y
real size = 1.0 //size of the object mass like system
real xprev = 0.00
real yprev = 0.00
location point  //current point
location destpoint  //destination point
real g=-.5  //gravity
real a=5   //acceleration
real z=0   //z cord, height
real zprev //previous z cord
real zforce=0 //force for height
unit u //unit
integer utype //unit type
//timer t = CreateTimer()
location  array t_point[5]
//unit types
integer utype_peon = 'opeo'
integer utype_tnt = 'h000'
integer utype_box = 'h001'
//stats
real airtime
real maxairtime
real score
real multiplier


  

    method GravityCheck takes nothing returns boolean
       if this.z>0 then
       return true
       endif
       if this.zforce!=0 then
       return true
       endif
       return false
    endmethod


    method AddForce takes real direction, real mag returns nothing
    set this.xforce=this.xforce+Cos(bj_DEGTORAD*direction)*mag
    set this.yforce=this.yforce+Sin(bj_DEGTORAD*direction)*mag    
    endmethod
    

    method Friction takes nothing returns nothing
        local real mag = 0.00
        local real dir = 0.00
        if (this.z==0) then
        //if this.xforce!=0 then
        //set this.xforce=(RAbsBJ(this.xforce)-this.f)*(this.xforce/RAbsBJ(this.xforce))
        //endif
        //if this.yforce!=0 then
        //set this.yforce=(RAbsBJ(this.yforce)-this.f)*(this.yforce/RAbsBJ(this.yforce))
        //endif
        set mag=SquareRoot((this.xforce*this.xforce)+(this.yforce*this.yforce))
        if mag!=0 then
        set this.t_point[0]=Location(this.xprev,this.yprev)
        set this.t_point[1]=Location(this.x,this.y)
        set dir = AngleBetweenPoints(this.t_point[0],this.t_point[1])
        loop
        if (dir<0) then
        set dir=dir + 360
        endif
        if (dir>360) then
        set dir=dir - 360
        endif
        if dir >=0 then
        if dir< 360 then
        exitwhen dir!=-999
        endif
        endif
        endloop
        set mag = RAbsBJ(mag) - this.f
        if RAbsBJ(mag)<this.f then
        set mag = 0
        set this.mag = mag
        call RemoveLocation (this.t_point[0])
        call RemoveLocation (this.t_point[1])
        set this.t_point[0] = null
        set this.t_point[1] = null
        endif
        set this.xforce=Cos(bj_DEGTORAD*dir)*mag
        set this.yforce=Sin(bj_DEGTORAD*dir)*mag
        endif
        //call BJDebugMsg(R2S(dir))
        endif
        if RAbsBJ(this.xforce)<this.f then
        set this.xforce=0
        endif
        if RAbsBJ(this.yforce)<this.f then
        set this.yforce=0
        endif
    endmethod
    
    method ForceExists takes nothing returns boolean
    if this.xforce!=0 then
    return true
    endif
    if this.yforce!=0 then
    return true
    endif
    return false
    endmethod 
    
    method UpdateLocation takes nothing returns nothing
        set this.xprev=this.x
        set this.yprev=this.y
        
        set this.x=GetUnitX(this.u)
        set this.y=GetUnitY(this.u)
        
        if this.ForceExists() then
        
        
        set this.x=this.x+this.xforce
        set this.y=this.y+this.yforce
        
        call SetUnitPosition( this.u, this.x,this.y )
        endif
        set this.t_point[0]=Location(this.x,this.y)
        set this.t_point[1]=Location(this.x,this.yprev)
        set this.t_point[2]=Location(this.xprev,this.y)
        if (( IsTerrainPathableBJ(this.t_point[0], PATHING_TYPE_WALKABILITY) == true ) ) then
        //call BJDebugMsg("unwalkable")
        if ( ( IsTerrainPathableBJ(this.t_point[1], PATHING_TYPE_WALKABILITY) == true ) ) then
        set this.xforce=this.xforce*-1
        endif
        if ( ( IsTerrainPathableBJ(this.t_point[2], PATHING_TYPE_WALKABILITY) == true ) ) then
        set this.yforce=this.yforce*-1
        endif
        set this.x=this.xprev
        set this.y=this.yprev
        
        call SetUnitPosition( this.u, this.x,this.y )
        else
        //call BJDebugMsg("walkable")
        endif
        call RemoveLocation (this.t_point[0])
        call RemoveLocation (this.t_point[1])
        call RemoveLocation (this.t_point[2])
        set this.t_point[0] = null
        set this.t_point[1] = null
        set this.t_point[2] = null
    endmethod
    method CrushCheck takes unitData uD returns boolean
    if this.z==0 then
    if uD.z<uD.zprev then
    if uD.z==0 then
        return true
    endif
    endif
    endif
    return false 
    endmethod
    method Step takes nothing returns nothing
        local group g = CreateGroup() 
        local unit dum
        local real dum_x
        local real dum_y
        local real mag
        local unitData uD 
        //call SetUnitScale(this.u,this.size,this.size,this.size)
        set this.zprev=this.z
        if (this.GravityCheck()) then   
            set this.zforce=this.g+this.zforce
            set this.z=this.z+this.zforce
                if (this.z<0) then
                    set this.z=0
                    set this.zforce=0
                endif
                    
        endif
        //call DisplayTextToPlayer(Player(0),0,0,R2S(this.z))
        //call DisplayTextToPlayer(Player(0),0,0,R2S(this.zforce))
        call SetUnitFlyHeightBJ( this.u, this.z, 10000.0 )
        //set this.point = Location(this.x, this.y)
        //set this.destpoint = Location(this.destx, this.desty)
        
        call this.UpdateLocation()
        call this.Friction()
        set this.utype=GetUnitTypeId(this.u)
        if this.utype!=this.utype_tnt then
        call GroupEnumUnitsInRange(g,this.x,this.y,60,null) 
        loop 
        set dum = FirstOfGroup(g)
         
        exitwhen dum==null
        set uD=GetUnitUserData(dum) 
        call GroupRemoveUnit(g,dum) //Do Stuff
        if (IsUnitAliveBJ(dum)) then
        if (GetUnitTypeId(dum)==this.utype_tnt) then
        if (this.z<=20) then        
            call KillUnit(dum)
            
        endif
        endif
        
        if (GetUnitTypeId(dum)==this.utype_box) then
        if dum!=this.u then
        if (this.CrushCheck(uD)) then
        //call BJDebugMsg("TEST")
        call BJDebugMsg("Crushed:" + GetUnitName(this.u) + " was crushed by " + GetUnitName(uD.u))
        
        else
        if RAbsBJ(this.z-uD.z)<20 then
            if this.mag+uD.mag>0 then
            set this.t_point[0]=Location(this.x,this.y)
            set this.t_point[1]=Location(uD.x,uD.y)
        call this.AddForce(AngleBetweenPoints(this.t_point[1],this.t_point[0]),uD.mag*1.5)
        call uD.AddForce(AngleBetweenPoints(this.t_point[0],this.t_point[1]),this.mag*1.5)
        call BJDebugMsg("collision:" + GetUnitName(this.u) + " with " + GetUnitName(uD.u))
        
        call RemoveLocation (this.t_point[0])
        call RemoveLocation (this.t_point[1])
        set this.t_point[0]=null
        set this.t_point[1]=null
        endif
        endif
        endif
        
        endif
        endif
        endif 
        endloop
        endif
        
        call DestroyGroup(g) 
        set g = null
        
    endmethod
    
    method init takes unit u, real size returns nothing
        
        set this.size=size
        set this.u=u
        set this.z=GetUnitFlyHeight(this.u)
        call GroupAddUnitSimple( this.u, udg_physicgroup )
    endmethod
    
endstruct


Also, the step method is ran every .015 seconds.
 

Frozenhelfir

set Gwypaas = Guhveepaws
Reaction score
56
Full code please? It looks like you're using a struct, but I can't see what it contains.

EDIT: I've done some optimizing

JASS:
scope UnitDies initializer init
globals
    private constant integer UNIT_ID = 'h000'
    private constant real MAG = 10
endglobals

private function Cond takes nothing returns boolean
    return GetUnitTypeId(GetDyingUnit()) == UNIT_ID
endfunction

private function RetTrue takes nothing returns boolean
    return true
endfunction

private function UnitDies takes nothing returns nothing
local unit u = GetDyingUnit()
local unit tempu// = null
local real x = GetUnitX(u)
local real y = GetUnitY(u)
//l//ocal real mag = 10
local group g2 = CreateGroup()
local unitData uD// = unitData.create() <== are you missing that or just not using the struct? If not just remove it.
local real distance = 0.00
local real dx //using this for optimized distbetweenpoints
local real dy //using this for optimized distbetweenpoints
//local location array t_point[5] <= you only use two of the indexes anyway... Perhaps it leaks if you don't use them all?
//either way, coords are better.
local unitData uD_dying=GetUnitUserData(u)  
    
   // if (GetUnitTypeId(u)=='h000') then  <== Move to a condition!
    call GroupEnumUnitsInRange(g2,x,y,200,Condition(function RetTrue)) 
    
        loop
        set tempu = FirstOfGroup(g2)
        exitwhen tempu==null
        
        
        set uD=GetUnitUserData(tempu) 
        call GroupRemoveUnit(g2,tempu) //Do Stuff
        
        
        if GetWidgetLife(tempu) > 0.405 then        
        
            if GetUnitTypeId(tempu)==UNIT_ID then
                call KillUnit(tempu)
            else //don't need next if statement, since the else will fire if id != UNIT_ID
            //This does take out one if check... Also indent your code in if statements...
            
                set dx = uD.x - x
                set dy = uD.y - y
                set distance = SquareRoot(dx*dx + dy*dy) * .02
                if distance < 1 then
                    set distance=1
                endif
            
                //set t_point[0]=Location(x,y)
                //set t_point[1]=Location(uD.x,uD.y)
                //set distance = DistanceBetweenPoints(t_point[0],t_point[1])*.02
                   // if distance<1 then
                      //  set distance=1
                    //endif
            
                call uD.AddForce(bj_RADTODEG * Atan2(uD.y - y, uD.x - x),MAG/distance)
                set uD.zforce=uD.zforce+17/distance
            endif
        endif
        //call RemoveLocation (t_point[0])
        //call RemoveLocation (t_point[1])
        //set t_point[0]=null
        //set t_point[1]=null
        endloop
        
call Explode(x,y)

endif
call DestroyGroup(g2) 
set g2 = null
call uD_dying.destroy()
//call GroupRemoveUnitSimple(u, udg_physicgroup)
call GroupRemoveUnit(udg_physicalgroup,u)
//call TriggerSleepAction(1.0)
call RemoveUnit(u)
endfunction

//===========================================================================
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_DEATH,Condition(function RetTrue))
        exitwhen i >= 11
        set i = i+1
    endloop
    call TriggerAddCondition(t,Condition(function Cond))
    call TriggerAddAction(t, function UnitDies)
endfunction
endscope
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top