HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Drag Unit Function

04-04-2006, 04:35 AM#1
hourglasseye
Hey guys,

I made this function that is supposed to forcefully drag a unit from one point to another... like it was being sucked or vacuumed or something. The problem is, the movement is kinda crappy. It doesn't look like it slides. And when more than one unit is being dragged, the game lags. Can you help me optimize it or suggest a different way of writing it? Here is the code:

Collapse JASS:
//===========================================================================
//	Drag Unit Custom Script
//===========================================================================

function DragUnit takes unit slider, location start, location end, real rate returns nothing
    local real angle = AngleBetweenPoints(start,end)
    local real distancetotal = DistanceBetweenPoints(start,end)
    local real distanceleft = distancetotal
    local location targetpt
    if(GetAttachedBoolean(slider,"sliding") == false) then
        call AttachBoolean(slider,"sliding",true)
        call SetUnitPathing( slider, false )
        call PauseUnit(slider,true)
        loop
            exitwhen( distanceleft < 1 )
            set distanceleft = distanceleft - rate
            call RemoveLocation( targetpt )
            set targetpt = PolarProjectionBJ(start, distancetotal - distanceleft, angle)
            call SetUnitPositionLoc( slider, targetpt )
            call RemoveLocation(targetpt)
            call TriggerSleepAction(0)
        endloop
        call AttachBoolean(slider,"sliding",false)
        call SetUnitPathing( slider, true )
        call PauseUnit(slider,false)
    endif
    call RemoveLocation(targetpt)
    call RemoveLocation(start)
    call RemoveLocation(end)
    set targetpt = null
    set start = null
    set end = null
    set slider = null
endfunction
04-04-2006, 05:16 AM#2
MaD[Lion]
the reason it lags is cus u use the TriggerSleepAction(), this will make a laggy movement no matter what, you should therefore use periodic event for dragging a unit.

this is a jass unit-drag system i made earlier, it's crap but it works. I'm working on another system which is better. And more simple than this.

Collapse JASS:
//----------------------------------
// function set a units movement properties
//
function MoveUnitProperties takes unit U, boolean a, boolean b returns nothing

 //(a=true):move unit with absolute height
 //(a=false):move unit related to terrain height
 //(b=true):move unit to new position over given time in sec
 //(b=false):move unit to new position by a given speed

 call StoreBoolean(udg_cache,I2S(H2I(U)),"move mode",a)
 call StoreBoolean(udg_cache,I2S(H2I(U)),"speed mode",b)
endfunction

//----------------------------------
// move unit function
//
function MoveUnitFunction takes nothing returns nothing
 local string unitStr=I2S(H2I(GetEnumUnit()))
 local unit U=I2U(GetStoredInteger(udg_cache,unitStr,"unit"))
 local integer time=GetStoredInteger(udg_cache,unitStr,"time")
 local location tmp_loc=GetUnitLoc(U)
 local real sX=GetStoredReal(udg_cache,I2S(H2I(U)),"sX")
 local real sY=GetStoredReal(udg_cache,I2S(H2I(U)),"sY")
 local real sZ=GetStoredReal(udg_cache,I2S(H2I(U)),"sZ")
 local real fZ=GetStoredReal(udg_cache,I2S(H2I(U)),"fZ")
 local real uZ=GetLocationZ(tmp_loc)
 local real dZ=(uZ-GetStoredReal(udg_cache,I2S(H2I(U)),"uZ"))
 local integer int=GetStoredInteger(udg_cache,I2S(H2I(U)),"int")
 local boolean mode=GetStoredBoolean(udg_cache,I2S(H2I(U)),"move mode")

 if ((time>=0)) then
  call SetUnitX(U, GetLocationX(tmp_loc)+sX)
  call SetUnitY(U, GetLocationY(tmp_loc)+sY)

  //switch absolute/relative height change
  if (mode==true) then
   call SetUnitFlyHeight(U,(fZ+(sZ*(int+1)))-dZ,0)
  else
   call SetUnitFlyHeight(U,fZ+(sZ*(int+1)),0)
  endif

  //store modifiable vars
  call StoreInteger(udg_cache,I2S(H2I(U)),"int",int+1)
  call StoreInteger(udg_cache,I2S(H2I(U)),"time",time-1)
 else
  call GroupRemoveUnit(I2G(GetStoredInteger(udg_cache,"unit_group","move_unit")),U)
 endif

 //clean up
 call RemoveLocation(tmp_loc)
endfunction

//----------------------------------
// move unit absolute/relative
//
function MoveUnit takes unit U, location P, real Z, real T returns nothing
 local location tmp_loc=GetUnitLoc(U)
 local boolean b=GetStoredBoolean(udg_cache,I2S(H2I(U)),"speed mode") 
 local real sX
 local real sY
 local real sZ
 local real X=GetLocationX(P)
 local real Y=GetLocationY(P)
 local real uX=GetLocationX(tmp_loc)
 local real uY=GetLocationY(tmp_loc)
 local real uZ=GetLocationZ(tmp_loc)
 local real fZ=GetUnitFlyHeight(U)
 local real distance=SquareRoot(Pow((Y-uY),2)+Pow((X-uX),2))
 local integer time=0
 set Z=GetLocationZ(P)-uZ+Z

 //U=unit - P=location - Z=height - T=time/speed

 //
 //calculations
 //

 //calculate move by time times
 if (b==true and T>0.02) then
  set time=R2I(T/0.02)
 endif

 //calculate move by speed times
 if (b==false and T>0) then
  set time=R2I((distance/T)/0.02)
 endif

 //calculate speed
 if ((time>0)) then
  set sX=(X-uX)/time
  set sY=(Y-uY)/time
  set sZ=(Z-fZ)/time
 else
  set sX=(X-uX)
  set sY=(Y-uY)
  set sZ=(Z-fZ)
 endif

 //store vars
 call StoreReal(udg_cache,I2S(H2I(U)),"sX",sX)
 call StoreReal(udg_cache,I2S(H2I(U)),"sY",sY)
 call StoreReal(udg_cache,I2S(H2I(U)),"sZ",sZ)
 call StoreReal(udg_cache,I2S(H2I(U)),"uZ",uZ)
 call StoreReal(udg_cache,I2S(H2I(U)),"fZ",fZ)
 call StoreInteger(udg_cache,I2S(H2I(U)),"int",0)
 call StoreInteger(udg_cache,I2S(H2I(U)),"time",time)
 call StoreInteger(udg_cache,I2S(H2I(U)),"unit",H2I(U))
 call GroupRemoveUnit(I2G(GetStoredInteger(udg_cache,"unit_group","move_unit")),U)
 call GroupAddUnit(I2G(GetStoredInteger(udg_cache,"unit_group","move_unit")),U)

 //clean up
 call RemoveLocation(P)
 call RemoveLocation(tmp_loc)
endfunction

//----------------------------------
// function move periodic
//
function MoveUnitActions takes nothing returns nothing
 call ForGroup(I2G(GetStoredInteger(udg_cache,"unit_group","move_unit")), function MoveUnitFunction)
endfunction

//----------------------------------
// function periodic event
//
function Periodic takes nothing returns nothing
    local trigger Move_Unit=CreateTrigger()
    call TriggerRegisterTimerEventPeriodic(Move_Unit, 0.02)
    call TriggerAddAction(Move_Unit,function MoveUnitActions)
endfunction

//----------------------------------
// create unitgroup in cache
//
function CreateCacheGroup takes string T returns nothing
 call StoreInteger(udg_cache,"unit_group",T,H2I(CreateGroup()))
endfunction
04-04-2006, 02:05 PM#3
hourglasseye
Periodic huh. Yeah, I think I've read about waits not being accurate or something. I'll look at how you did it. I can't understand it yet. Haha... But I'll do my best. So, what this does is to move a group of units stored in the game cache periodically towards a location... Was that right? I need to get used to JASS some more so I can understand this better. Thanks eh? I'd study your code, but since I'm not in dire need of a drag function yet, I'll have to get to it later.
04-04-2006, 04:56 PM#4
Vexorian
from what I can see you are over removing targetpt .