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.
Heres the struct it references
Also, the step method is ran every .015 seconds.
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)==039;h000039;) 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)==039;h000039;) then
call KillUnit(tempu)
endif
if (GetUnitTypeId(tempu)!=039;h000039;) 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 = 039;opeo039;
integer utype_tnt = 039;h000039;
integer utype_box = 039;h001039;
//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.