Guest User

Knockback3D

a guest
Jun 9th, 2012
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.38 KB | None | 0 0
  1.  
  2. library Knockback3D initializer i requires IsTerrainWalkable
  3.     private struct knockDat
  4.         unit u
  5.         real xOffs
  6.         real yOffs
  7.         real zOffs
  8.     endstruct
  9.  
  10.     globals
  11.         private constant boolean USE_MOVESPEED_MODIFIERS=true //This defines whether or not units should have their movespeed set to 0 and then back to "default" speed (Using GetUnitDefaultMoveSpeed()). If false, units in mid air can still fully control themselves.
  12.         private constant integer CROW_ID='Arav'
  13.         private constant real FIDELITY=1./30. //How often the periodic trigger fires. A value of (1./30.) represents 30 frames per second.
  14.         private constant real BOUNCE_COEFFICIENT=.4 //How much momentum is retained when a unit bounces. A value of .4 means 40% of the z velocity is retained.
  15.         private constant real FRICTION=.15 //What percentage of momentum is lost while a unit is sliding. A value of .15 means that 85% of the unit's speed is retained with each slide iteration.
  16.         private constant real GRAVITY=FIDELITY*41.25 //The downward acceleration of all units in the stack. A value of FIDELITY*41.25 means they accelerate downwards by 41.25 game units per second.
  17.         private constant real MAX_Z_VELOCITY_TO_BOUNCE=FIDELITY*-300. //This represents a minimum fall-speed for a unit to bounce. For a value of (-10.), units have to have a negative zVelocity of at least 10, or they won't bounce.
  18.         private constant real MIN_FLY_HEIGHT=5. //This is the minimum height a unit can be at to be considered "sliding" (friction is applied to it)
  19.         private constant real MIN_FOR_KNOCKBACK=FIDELITY*30. //This is the minimum horizontal velocity a unit can be sliding at before it is removed from the stack.
  20.         private constant real MIN_FRICTION_FOR_EFFECT=FIDELITY*180. //While a sliding unit's horizontal velocity is higher than this number, a "friction" effect is spawned.
  21.         private constant real MIN_Z_VELOCITY_TO_BECOME_AIRBORNE=FIDELITY*150. //This is the minimum z-velocity of a unit to actually have it's flying height changed. Otherwise, it just slides.
  22.         private constant real DESTRUCTABLE_ENUM_RADIUS=130. //This is the distance from the center of a sliding unit to a nearby destructable for it to be destroyed. Note that the radius is coverted to a square and therefor the user must consider this value *Sqrt(2).
  23.         private constant real MIN_VEL_DESTROY_DESTRUCTABLE=FIDELITY*300. //This is the minimum horizontal velocity a unit must have to destroy a destructable. You can set this to a very high number to disable the feature.
  24.         private constant real DESTROY_DESTRUCTABLE_MOMENTUM_CONSERVED=BOUNCE_COEFFICIENT //This is the percentage of momentum to conserve if a sliding unit destroys a destructable. Default value is the same as BOUNCE_COEFFICIENT
  25.         private constant real MAX_HEIGHT_DESTROY_DESTRUCTABLE=150. //This is the height below which a unit in the stack is elligible to destroy a destructable. Ideally it should be the average height of your destructables.
  26.         private constant string FRICTION_MODEL="Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" //This is the model to spawn when a unit's horizontal velocity > MIN_FRICTION_FOR_EFFECT
  27.         private boolean hitDestructable
  28.         private effect fx
  29.         private integer dbIndex=-1
  30.         private knockDat array knockDB
  31.         private location zLoc=Location(0.,0.)
  32.         private real minX
  33.         private real maxX
  34.         private real minY
  35.         private real maxY
  36.         private rect rct
  37.         private timer time=CreateTimer()
  38.     endglobals
  39.  
  40.     private function getZ takes real x, real y returns real
  41.         call MoveLocation(zLoc,x,y)
  42.         return GetLocationZ(zLoc)
  43.     endfunction
  44.    
  45.     private function d takes nothing returns nothing
  46.         local destructable des=GetEnumDestructable()
  47.         if GetDestructableLife(des)>0. then
  48.             call KillDestructable(des)
  49.             set hitDestructable=true
  50.         endif
  51.         set des=null
  52.     endfunction
  53.    
  54.     private function p takes nothing returns nothing
  55.         local boolean newInMap
  56.         local integer index=0
  57.         local real flyHeight
  58.         local real unitX
  59.         local real unitY
  60.         local real heightDifference
  61.         local real newX
  62.         local real newY
  63.         local real vel2d
  64.         local knockDat tempDat
  65.         loop
  66.             exitwhen index>dbIndex
  67.             set tempDat=knockDB[index]
  68.             set unitX=GetUnitX(tempDat.u)
  69.             set unitY=GetUnitY(tempDat.u)
  70.             set newX=unitX+tempDat.xOffs
  71.             set newY=unitY+tempDat.yOffs
  72.             set newInMap=newX>minX and newX<maxX and newY>minY and newY<maxY
  73.             set flyHeight=GetUnitFlyHeight(tempDat.u)
  74.             set vel2d=(tempDat.xOffs*tempDat.xOffs+tempDat.yOffs*tempDat.yOffs)
  75.             if flyHeight<MIN_FLY_HEIGHT then
  76.                 if IsTerrainWalkable(newX,newY) and newInMap then
  77.                     call SetUnitX(tempDat.u,unitX+tempDat.xOffs)
  78.                     call SetUnitY(tempDat.u,unitY+tempDat.yOffs)
  79.                     set tempDat.xOffs=tempDat.xOffs*(1.-FRICTION)
  80.                     set tempDat.yOffs=tempDat.yOffs*(1.-FRICTION)
  81.                     static if USE_MOVESPEED_MODIFIERS then
  82.                         call SetUnitMoveSpeed(tempDat.u,GetUnitDefaultMoveSpeed(tempDat.u))
  83.                     endif
  84.                     if vel2d>MIN_FRICTION_FOR_EFFECT then
  85.                         set fx=AddSpecialEffect(FRICTION_MODEL,unitX,unitY)
  86.                         call DestroyEffect(fx)
  87.                     endif
  88.                 else
  89.                     set tempDat.xOffs=0
  90.                     set tempDat.yOffs=0
  91.                 endif
  92.                 if tempDat.zOffs<MAX_Z_VELOCITY_TO_BOUNCE then
  93.                     set tempDat.zOffs=tempDat.zOffs*-1.*BOUNCE_COEFFICIENT
  94.                 endif
  95.                 if tempDat.zOffs>MIN_Z_VELOCITY_TO_BECOME_AIRBORNE then
  96.                     call SetUnitFlyHeight(tempDat.u,flyHeight+tempDat.zOffs,0)
  97.                     set tempDat.zOffs=tempDat.zOffs-GRAVITY
  98.                 endif
  99.             elseif newInMap then
  100.                 set tempDat.zOffs=tempDat.zOffs-GRAVITY
  101.                 set heightDifference=getZ(newX,newY)-getZ(unitX,unitY)
  102.                 call SetUnitFlyHeight(tempDat.u,flyHeight+tempDat.zOffs-heightDifference,0)
  103.                 call SetUnitX(tempDat.u,newX)
  104.                 call SetUnitY(tempDat.u,newY)
  105.                 static if USE_MOVESPEED_MODIFIERS then
  106.                     call SetUnitMoveSpeed(tempDat.u,0)
  107.                 endif
  108.             endif
  109.             if vel2d<MIN_FOR_KNOCKBACK and tempDat.zOffs>MAX_Z_VELOCITY_TO_BOUNCE and tempDat.zOffs<-1*MAX_Z_VELOCITY_TO_BOUNCE and flyHeight<MIN_FLY_HEIGHT then
  110.                 set knockDB[index]=knockDB[dbIndex]
  111.                 set dbIndex=dbIndex-1
  112.                 call SetUnitFlyHeight(tempDat.u,0,0)
  113.                 static if USE_MOVESPEED_MODIFIERS then
  114.                     call SetUnitMoveSpeed(tempDat.u,GetUnitDefaultMoveSpeed(tempDat.u))
  115.                 endif
  116.                 call tempDat.destroy()
  117.                 set index=index-1
  118.                 if dbIndex<0 then
  119.                     call PauseTimer(time)
  120.                 endif
  121.             endif
  122.             if vel2d>MIN_VEL_DESTROY_DESTRUCTABLE and flyHeight<MAX_HEIGHT_DESTROY_DESTRUCTABLE then
  123.                 set hitDestructable=false
  124.                 call MoveRectTo(rct,newX,newY)
  125.                 call EnumDestructablesInRect(rct,null,function d)
  126.                 if hitDestructable then
  127.                     set tempDat.xOffs=tempDat.xOffs*DESTROY_DESTRUCTABLE_MOMENTUM_CONSERVED
  128.                     set tempDat.yOffs=tempDat.yOffs*DESTROY_DESTRUCTABLE_MOMENTUM_CONSERVED
  129.                 endif
  130.             endif
  131.             set index=index+1
  132.         endloop
  133.     endfunction
  134.    
  135.     private function getUnitIndexFromStack takes unit u returns integer
  136.         local integer index=0
  137.         local integer returner=-1
  138.         local knockDat tempDat
  139.         loop
  140.             exitwhen index>dbIndex or returner!=-1
  141.             set tempDat=knockDB[index]
  142.             if tempDat.u==u then
  143.                 set returner=index
  144.             endif
  145.             set index=index+1
  146.         endloop
  147.         return returner
  148.     endfunction
  149.    
  150.     public function add takes unit u, real velocity, real angleInRads, real zAngleInRads returns nothing //make sure setVel matches this!
  151.         local integer index=getUnitIndexFromStack(u)
  152.         local knockDat tempDat
  153.         local real instVel=velocity*FIDELITY
  154.         if index==-1 then
  155.             set tempDat=knockDat.create()
  156.             set tempDat.u=u
  157.             set tempDat.xOffs=instVel*Cos(angleInRads)*Cos(zAngleInRads) //Warning! Don't send angles in degrees to these functions if you value your life!
  158.             set tempDat.yOffs=instVel*Sin(angleInRads)*Cos(zAngleInRads)
  159.             set tempDat.zOffs=instVel*Sin(zAngleInRads)
  160.             set dbIndex=dbIndex+1
  161.             set knockDB[dbIndex]=tempDat
  162.             if UnitAddAbility(tempDat.u,CROW_ID) then
  163.                 call UnitRemoveAbility(tempDat.u,CROW_ID)
  164.             endif
  165.             if dbIndex==0 then
  166.                 call TimerStart(time,FIDELITY,true,function p)
  167.             endif
  168.         else
  169.             set tempDat=knockDB[index]
  170.             set tempDat.xOffs=tempDat.xOffs+instVel*Cos(angleInRads)*Cos(zAngleInRads)
  171.             set tempDat.yOffs=tempDat.yOffs+instVel*Sin(angleInRads)*Cos(zAngleInRads)
  172.             set tempDat.zOffs=tempDat.zOffs+instVel*Sin(zAngleInRads)
  173.         endif
  174.     endfunction
  175.    
  176.     public function setVel takes unit u, real velocity, real angleInRads, real zAngleInRads returns nothing //make sure this matches add!
  177.         local integer index=getUnitIndexFromStack(u)
  178.         local knockDat tempDat
  179.         local real instVel=velocity*FIDELITY
  180.         if index==-1 then
  181.         set tempDat=knockDat.create()
  182.             set tempDat.u=u
  183.             set tempDat.xOffs=instVel*Cos(angleInRads)*Cos(zAngleInRads)
  184.             set tempDat.yOffs=instVel*Sin(angleInRads)*Cos(zAngleInRads)
  185.             set tempDat.zOffs=instVel*Sin(zAngleInRads)
  186.             set dbIndex=dbIndex+1
  187.             set knockDB[dbIndex]=tempDat
  188.             if UnitAddAbility(tempDat.u,CROW_ID) then
  189.                 call UnitRemoveAbility(tempDat.u,CROW_ID)
  190.             endif
  191.             if dbIndex==0 then
  192.                 call TimerStart(time,FIDELITY,true,function p)
  193.             endif
  194.         else
  195.             set tempDat=knockDB[index]
  196.             set tempDat.xOffs=instVel*Cos(angleInRads)*Cos(zAngleInRads)
  197.             set tempDat.yOffs=instVel*Sin(angleInRads)*Cos(zAngleInRads)
  198.             set tempDat.zOffs=instVel*Sin(zAngleInRads)
  199.         endif
  200.     endfunction
  201.    
  202.     public function updateMapArea takes rect rct returns nothing
  203.         set minX=GetRectMinX(rct)
  204.         set minY=GetRectMinY(rct)
  205.         set maxX=GetRectMaxX(rct)
  206.         set maxY=GetRectMaxY(rct)
  207.     endfunction
  208.    
  209.     private function i takes nothing returns nothing
  210.         set rct=Rect(-1*DESTRUCTABLE_ENUM_RADIUS,-1*DESTRUCTABLE_ENUM_RADIUS,DESTRUCTABLE_ENUM_RADIUS,DESTRUCTABLE_ENUM_RADIUS)
  211.         set minX=GetRectMinX(bj_mapInitialPlayableArea)
  212.         set maxX=GetRectMaxX(bj_mapInitialPlayableArea)
  213.         set minY=GetRectMinY(bj_mapInitialPlayableArea)
  214.         set maxY=GetRectMaxY(bj_mapInitialPlayableArea)
  215.     endfunction
  216. endlibrary
Advertisement
Add Comment
Please, Sign In to add comment