- Joined
- Feb 5, 2008
- Messages
- 18
This is like a combination of knockback and jumping system, units can be knocked across the terrain or flying in the air.
I have been using it for my maps for quite awhile but it used a ton of global variables, only recently adapted it to cscache.
This code is very efficient, you can have a lot (for a decent computer at least) of units knockback without much lag.
This only for units with foot movement type at the moment.
There is a problem with unit's Z value on water.
Thx to Vexorian for the Caster System
Code:
//============================================================================================================
//Physics Engine v1 by Damurjin
//This system is a combination of knockback and jumping, allowing ground units to be thrown
//in the air and fall realistically.
//Requires Caster System by Vexorian
//Note: You must import this as a trigger named 'Physics' if you are using GUI
//IMPORTANT:
//DisableMovement, EnableMovement and IsMoveable functions must work in order for
//ground units to fly in the air properly,
//unless you are fine with units walking in mid-air
//For default settings to work you must:
//-Change the 'Slow Aura (Tornado)' ability's movement speed reduction to -10
//-Change the 'Targets Allowed' to Self
//-Change the Gameplay Constants - Unit Minimum Speed to 0
//Available Functions:
//*Sets the speed of a unit
// SetSpeed(Unit, unit damager, XYspeed, Zspeed, angle) returns index
//
//*Adds speed to a unit
// AddSpeed(Unit, unit damager, XYspeed, Zspeed, angle, XYspeedLimit) returns index
//
//*Sets the speed of the unit so the unit will land at the destination
// SetSpeedToLoc(Unit, cause, pos, loc, XYspeed) returns nothing
//
//*Sets the speed of the unit so the unit will land at the destination after the time
// SetSpeedToLocTime (Unit, cause, pos, loc, time) returns nothing
//
//Unit - The unit that the movement will be applied to
//damager - The unit that will damage the Physics unit if it hurts itself when landing
//XYspeed - The horizontal speed in units per second
//Zspeed - The vertical speed in units per second
//XYspeedLimit - The limit of XYspeed (0 or less is considered no limit)
//pos - Position of the unit
//loc - Destination of the unit
//There are many settings available such as gravity, fall damage.
//There are 2 options available that can be disabled if you want:
//1. Flying Classification
// Adds classification to units that are high in the air
// This might be used to prevent melee units from attacking them,
// For the default settings, you could set all melee units to be unable to attack 'Ancients'
// so when a unit goes too high in the air, the Ancient classification is added and melee units
// are unable to attack them
//2. Melee Attack Disable
// Disables melee unit attacks that are high in the air
//Tip: If you want to add additional features, please try to add them in events section
//Notes:
//-Other movement systems will stack
//-While speed arguments are passed as units per second, the data is stored as
// units per execution time so it will be faster, same applies to Gravity.
//============================================================================================================
globals
//The deceleration towards the ground
real udg_Gravity = 1000
//If map limits are set to 0, then it will Get values from playable map rect (Not very accurate)
real udg_MapLimitMaxX = 0
real udg_MapLimitMaxY = 0
real udg_MapLimitMinX = 0
real udg_MapLimitMinY = 0
unit array udg_Physics_unit
trigger gg_trg_Physics
endglobals
//============================================================================================================
//Movement disabling
//Disables movement of a unit if a ground unit flies high to prevent air walking
function DisableMovement takes unit Unit returns nothing
call UnitAddAbility(Unit, 'Aasl')
endfunction
function EnableMovement takes unit Unit returns nothing
call UnitRemoveAbility(Unit, 'Aasl')
call UnitRemoveAbility(Unit, 'Basl')
endfunction
function IsMoveable takes unit Unit returns boolean
return not UnitHasBuffBJ(Unit, 'Basl')
endfunction
//============================================================================================================
//============================================================================================================
//Settings
//Returns the Storm Crow Form ability which makes flight possible
//ThIs will be added to the unit when Physics Is applied and removed when Physics Is destroyed
function GetFlightAbilityId takes nothing returns integer
return 'Arav'
endfunction
//*************************************************************************************************************
//To reduce lag made it so that many Physics objects would run in series rather than parallel
//Example: There are 10 Physics objects and the TimeOut Is 4 and execTime Is 0.01
//
//Time Indexes of Physics Objects that will execute
//0.00 ---> 0, 4, 8
//0.01 ---> 1, 5, 9
//0.02 ---> 2, 6
//0.03 ---> 3, 7
//0.04 ---> 0, 4, 8
//Sorry if you still don't understand but it is my best explanation :(
//*************************************************************************************************************
//The real execution time of any Physics Object Is timeOut * execTime
//The number of trigger executions that will be skipped
function GetPhysicsTimeOut takes nothing returns integer
return 4
endfunction
//The time the executions will occur
function GetPhysicsPeriod takes nothing returns real
return 0.01
endfunction
//The condition when a unit Is considered on the ground
//Note: A value above 0 Is recommended
function onGround takes real height returns boolean
return height < 10
endfunction
//Returns the factor of XY speed converted into Z speed when Wall bounce occurs
function GetWallBounceUp takes nothing returns real
return 0.2
endfunction
//Returns the factor of XY speed remaining by when Wall bounce occurs
function GetWallBounceBack takes nothing returns real
return 0.5
endfunction
//Returns the factor of Z speed that Is converted into damage when landing
function GetFallDamageFactor takes unit Unit returns real
return 0.
endfunction
function GetFallAttackType takes nothing returns attacktype
return ATTACK_TYPE_SIEGE
endfunction
function GetMaxPhysics takes nothing returns integer
return 200
endfunction
//Creates a effect when the unit impacts the ground, effects may be based on damage recieved
function fallArt takes unit Unit, location pos, real dmg returns nothing
local string path
if (dmg <= 0) then
return
endif
if (dmg < 50) then
set path = "Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl"
else
if (dmg < 100) then
set path = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
else
set path = "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl"
endif
endif
call DestroyEffect(AddSpecialEffectTarget(path, Unit, "origin"))
endfunction
//Returns the decrease of speed due to friction
//Note: Values are applied every execution, NOT every second
// So if you want a decrease of 25 per second, with timeOut = 4 and execTime = 0.01
// Then the value should be 25 * (4 * 0.01) = 1
function friction takes unit Unit, location pos, real height, boolean flyer returns real
//Friction only applies when the unit Is on the ground
if (not onGround(height)) then
return 0
endif
//No friction if on ice
if (GetTerrainTypeBJ(pos) == 'Nice') then
return 0
endif
//Less friction if on water
if (not IsTerrainPathableBJ(pos, PATHING_TYPE_FLOATABILITY)) then
return 0.6
endif
return 1.
endfunction
//End of settings
//============================================================================================================
//============================================================================================================
//Flying Classification
//I find it useful to reserve a unit classification so if a unit flies high,
//it will be treated as air to avoid Melee ground units attacking flying units
function GetFlyingType takes nothing returns unittype
return UNIT_TYPE_ANCIENT
endfunction
//The condition when a unit Is a flying unit
function IsHigh takes real height returns boolean
return height > 100
endfunction
//To Disable, make thIs function return false
function FlyingClassification takes nothing returns boolean
return true
endfunction
//============================================================================================================
//============================================================================================================
//Melee Attack Disable
//Disables Melee attacker's attack to prevent it attacking a ground unit
//Note: thIs method of dIsabling attack will not work for units with cargo in them
function DisableAttack takes unit Unit returns nothing
call UnitAddAbility(Unit, 'Abun')
endfunction
function EnableAttack takes unit Unit returns nothing
call UnitRemoveAbility(Unit, 'Abun')
endfunction
//To Disable, make thIs function return false
function MeleeDisable takes nothing returns boolean
return true
endfunction
//============================================================================================================
//Unless you really know what you are doing you should not modify anything below
//============================================================================================================
//Utility Functions
//These are not actually part of the Physics Engine but are needed by it
//Limits locations so they may not exceed the value of 'Map_Limit'
function MapLimits takes location loc returns location
local real x = GetLocationX(loc)
local real y = GetLocationY(loc)
if (x > udg_MapLimitMaxX or y > udg_MapLimitMaxY or x < udg_MapLimitMinX or y < udg_MapLimitMinY) then
call RemoveLocation(loc)
return Location(RMinBJ(RMaxBJ(x, udg_MapLimitMinX), udg_MapLimitMaxX), RMinBJ(RMaxBJ(y, udg_MapLimitMinY), udg_MapLimitMaxY))
else
return loc
endif
return null
endfunction
//These Z values are based on the location Z + the unit's flying height
//Note: thIs calculation Is wrong when the unit Is on water or Is a flying unit
//Gets a unit and returns the Z of the unit
function GetUnitZ takes unit Unit returns real
local real locZ
local location pos
set pos = GetUnitLoc(Unit)
set locZ = GetLocationZ(pos)
call RemoveLocation(pos)
return locZ + GetUnitFlyHeight(Unit)
endfunction
//Sets the unit's fly height
function SetUnitZ takes unit Unit, real z returns nothing
local location pos
set pos = GetUnitLoc(Unit)
call SetUnitFlyHeight(Unit, z - GetLocationZ(pos), 1000000000)
call RemoveLocation(pos)
endfunction
//Polar projection but with Map_Limit restrictions
function PolarProjectionML takes location loc, real dIstance, real angle returns location
return MapLimits(PolarProjectionBJ(loc, dIstance, angle))
endfunction
//ThIs move unit function differs from the 'SetUnitLoc' function as it ignores pathing
function SetUnitXYLoc takes unit Unit, location loc returns nothing
call SetUnitX(Unit,GetLocationX(loc))
call SetUnitY(Unit,GetLocationY(loc))
endfunction
//Returns true if the location supports the type of pathing
function IsPathable takes location loc, pathingtype path returns boolean
return not IsTerrainPathableBJ(loc, path)
endfunction
function AddUnitState takes unit Unit, unitstate state, real amount returns nothing
call SetUnitState(Unit, state, RMaxBJ(GetUnitState(Unit, state) + amount, 0))
endfunction
function IsMoving takes unit Unit returns boolean
return OrderId2StringBJ(GetUnitCurrentOrder(Unit)) != ""
endfunction
//End of Utility Functions
//============================================================================================================
//============================================================================================================
//Set and Get functions
function GetPhysicsAngle takes unit Unit returns real
return GetAttachedReal(Unit, "P_angle")
endfunction
function SetPhysicsAngle takes unit Unit, real angle returns nothing
call AttachReal(Unit, "P_angle", angle)
endfunction
function GetPhysicsHeight takes unit Unit returns real
return GetAttachedReal(Unit, "P_height")
endfunction
function SetPhysicsHeight takes unit Unit, real height returns nothing
call AttachReal(Unit, "P_height", height)
endfunction
function GetPhysicsXYSpeed takes unit Unit returns real
return GetAttachedReal(Unit, "P_XYspeed")
endfunction
function SetPhysicsXYSpeed takes unit Unit, real speed returns nothing
call AttachReal(Unit, "P_XYspeed", speed)
endfunction
function GetPhysicsZSpeed takes unit Unit returns real
return GetAttachedReal(Unit, "P_Zspeed")
endfunction
function SetPhysicsZSpeed takes unit Unit, real speed returns nothing
call AttachReal(Unit, "P_Zspeed", speed)
endfunction
function GetPhysicsDamager takes unit Unit returns unit
return GetAttachedUnit(Unit, "P_damager")
endfunction
function SetPhysicsDamager takes unit Unit, unit damager returns nothing
call AttachObject(Unit, "P_damager", damager)
endfunction
//============================================================================================================
//============================================================================================================
//Events
//These are just spaces where people can add extra functionality without changing my code
//Occurs immediately when the destructor Is called, before cleaning variables
function PhysicsDestroyEvent takes unit Unit returns nothing
endfunction
//Occurs before anything in the execution for a unit
function PhysicsExecuteEvent takes unit Unit returns nothing
endfunction
//Occurs when a unit lands on the ground
//The return value Is the Zspeed that the unit will have after the bounce
function PhysicsLandEvent takes unit Unit returns real
return 0.
endfunction
//============================================================================================================
//Physics Engine
function InitPhysics takes nothing returns nothing
local integer counter = 0
local real execTime = GetPhysicsPeriod() * I2R(GetPhysicsTimeOut())
loop
set udg_Physics_unit[counter] = null
set counter = counter + 1
exitwhen counter >= GetMaxPhysics()
endloop
set udg_Gravity = udg_Gravity * execTime * execTime
if (udg_MapLimitMaxX == 0 and udg_MapLimitMaxY == 0 and udg_MapLimitMinX == 0 and udg_MapLimitMinY == 0) then
set udg_MapLimitMaxX = GetRectMaxX(bj_mapInitialPlayableArea) - GetRectCenterX(bj_mapInitialPlayableArea)
set udg_MapLimitMaxY = GetRectMaxY(bj_mapInitialPlayableArea) - GetRectCenterY(bj_mapInitialPlayableArea)
set udg_MapLimitMinX = GetRectMinX(bj_mapInitialPlayableArea) - GetRectCenterX(bj_mapInitialPlayableArea)
set udg_MapLimitMinY = GetRectMinY(bj_mapInitialPlayableArea) - GetRectCenterY(bj_mapInitialPlayableArea)
endif
endfunction
//Handles XY plane
function XYPhysics takes unit Unit, location pos, real height returns nothing
local location loc
local real speed = GetPhysicsXYSpeed(Unit)
//Move the unit to the next location
set loc = PolarProjectionML(pos, speed, GetPhysicsAngle(Unit))
call SetUnitXYLoc(Unit, loc)
//ThIs slows the XY plane speed if the unit Is moving to a higher ground
if (onGround(height)) then
//call SetPhysicsXYSpeed(Unit, speed + (GetPhysicsHeight(Unit) - height - GetLocationZ(loc)) * execTime)
endif
call RemoveLocation(loc)
set loc = null
endfunction
//Sets the bounce angle of a Wall bounce
function SetBounceAngle takes unit Unit, location pos, location newPos returns nothing
//Check if cliff direction Is horizontal
local location loc = Location(GetLocationX(pos), GetLocationY(newPos))
local boolean pathable = IsPathable(loc, PATHING_TYPE_WALKABILITY)
local real angle = GetPhysicsAngle(Unit)
call RemoveLocation(loc)
if (pathable) then
call SetPhysicsAngle(Unit, 360 - angle)
return
endif
//Check if cliff direction Is vertical
set loc = Location(GetLocationX(newPos), GetLocationY(pos))
set pathable = IsPathable(loc, PATHING_TYPE_WALKABILITY)
call RemoveLocation(loc)
if (pathable) then
call SetPhysicsAngle(Unit, 180 - angle)
return
endif
//If cannot find then just reflect directly backwards
call SetPhysicsAngle(Unit, angle + 180)
endfunction
//Will bounce a unit back if it hits a higher cliff
function WallBounce takes unit Unit, location pos, location newPos returns nothing
local real z = GetLocationZ(pos)
local location newPos = GetUnitLoc(Unit)
local real newZ = GetLocationZ(newPos)
local real XYspeed = GetPhysicsXYSpeed(Unit)
//Bounce back only if the new location Is higher than the previous and Is unwalkable
if (z < newZ and IsTerrainPathableBJ(newPos, PATHING_TYPE_WALKABILITY)) then
call SetPhysicsZSpeed(Unit, GetPhysicsZSpeed(Unit) + XYspeed * GetWallBounceUp())
call SetPhysicsXYSpeed(Unit, GetPhysicsXYSpeed(Unit) * GetWallBounceBack())
call SetBounceAngle(Unit, pos, newPos)
endif
call RemoveLocation(pos)
endfunction
//Handles Z plane
function ZPhysics takes unit Unit, location pos, real height, boolean flyer returns nothing
local real Zspeed = GetPhysicsZSpeed(Unit)
local real sign = RSignBJ(Zspeed)
local real height = GetUnitFlyHeight(Unit)
local location loc = GetUnitLoc(Unit)
//Updates the height of the unit
call SetPhysicsHeight(Unit, RMaxBJ(GetPhysicsHeight(Unit) + Zspeed, GetLocationZ(loc)))
call SetUnitZ(Unit, GetPhysicsHeight(Unit))
//Flyers have their Z speed reduced towards 0
if (flyer) then
if (RAbsBJ(Zspeed) > udg_Gravity) then
call SetPhysicsZSpeed(Unit, Zspeed - sign * udg_Gravity)
else
call SetPhysicsZSpeed(Unit, 0)
endif
return
endif
if (not IsHigh(height)) then
call WallBounce(Unit, pos, loc)
endif
if (onGround(height)) then
call EnableMovement(Unit)
else
//If unit Is not on the ground then it Is affected by gravity
call SetPhysicsZSpeed(Unit, Zspeed - udg_Gravity)
//Movement and pathing should be Disabled if it Is going up
call DisableMovement(Unit)
endif
//A classification may be applied if the unit Is flying
if (FlyingClassification()) then
if (IsHigh(height)) then
if (not IsUnitType(Unit, GetFlyingType())) then
call UnitAddType(Unit, GetFlyingType())
//A Melee attacker cannot attack while in the air
if (MeleeDisable() and IsUnitType(Unit, UNIT_TYPE_MELEE_ATTACKER)) then
call DisableAttack(Unit)
endif
endif
else
if (IsUnitType(Unit, GetFlyingType())) then
call UnitRemoveType(Unit, GetFlyingType())
call EnableAttack(Unit)
endif
endif
endif
call RemoveLocation(loc)
endfunction
//Landing on the ground
function Landing takes unit Unit, location pos, real height returns nothing
local real Zspeed = GetPhysicsZSpeed(Unit)
local unit damager = GetPhysicsDamager(Unit)
local real dmg
//Occurs when the unit Is on ground and its Z speed Is negative
if (onGround(height) and Zspeed < 0) then
//Since it landed, z speed must be absorbed
call SetPhysicsZSpeed(Unit, PhysicsLandEvent(Unit))
call SetUnitFlyHeight(Unit, 0, 999999999)
//Damage the unit
if (GetFallDamageFactor(Unit) > 0) then
set dmg = RMaxBJ(dmg, -1 * Zspeed * GetFallDamageFactor(Unit))
call fallArt(Unit, pos, dmg)
//Locust units cannot be damaged so reduce life instead
if (GetUnitAbilityLevel(Unit, 'Aloc') == 1 or damager == null) then
call AddUnitState(Unit, UNIT_STATE_LIFE, -dmg)
else
call UnitDamageTarget(damager, Unit, dmg, false, true, GetFallAttackType(), DAMAGE_TYPE_NORMAL, null)
endif
endif
call EnableMovement(Unit)
endif
endfunction
//Destructor function, calling thIs will clean up all variables used
function PhysicsDestroy takes unit Unit, integer num returns nothing
call EnableMovement(Unit)
call PhysicsDestroyEvent(Unit)
call SetUnitFlyHeight(Unit, 0, 999999999)
call SetPhysicsAngle(Unit, 0)
call SetPhysicsHeight(Unit, 0)
call SetPhysicsZSpeed(Unit, 0)
call SetPhysicsXYSpeed(Unit, 0)
call SetPhysicsDamager(Unit, null)
call UnitRemoveAbility(Unit, GetFlightAbilityId())
set udg_Physics_unit[num] = null
endfunction
//The function that will be called every loop
function PhysicsExecute takes integer num returns nothing
local boolean flyer = not IsUnitType(udg_Physics_unit[num], UNIT_TYPE_GROUND)
local real height = GetUnitFlyHeight(udg_Physics_unit[num])
local location pos
local real XYspeed = GetPhysicsXYSpeed(udg_Physics_unit[num])
//If the unit has been removed, then set the physics unit to null
if (GetUnitName(udg_Physics_unit[num]) == null) then
set udg_Physics_unit[num] = null
endif
call PhysicsExecuteEvent(udg_Physics_unit[num])
set pos = GetUnitLoc(udg_Physics_unit[num])
call Landing(udg_Physics_unit[num], pos, height)
//Stops when:
// -The unit Is not moving in the XY plane
// -The unit Is not moving in the Z plane
// -The unit Is on the ground or Is a flying unit
if (XYspeed <= 0 and GetPhysicsZSpeed(udg_Physics_unit[num]) == 0 and (onGround(height) or flyer)) then
call PhysicsDestroy(udg_Physics_unit[num], num)
else
call XYPhysics(udg_Physics_unit[num], pos, height)
call SetPhysicsXYSpeed(udg_Physics_unit[num], XYspeed - friction(udg_Physics_unit[num], pos, height, flyer))
call ZPhysics(udg_Physics_unit[num], pos, height, flyer)
endif
call RemoveLocation(pos)
endfunction
function PhysicsExecution takes nothing returns nothing
local integer count = ModuloInteger(GetTriggerExecCount(gg_trg_Physics), GetPhysicsTimeOut())
loop
if (udg_Physics_unit[count] != null) then
call PhysicsExecute(count)
endif
set count = count + GetPhysicsTimeOut()
exitwhen count >= GetMaxPhysics()
endloop
endfunction
//End of Physics Engine
//============================================================================================================
//Function for returning array index of a Physics unit
function findPhysicsUnit takes unit Unit returns integer
local integer counter = 0
loop
if (Unit == udg_Physics_unit[counter]) then
return counter
endif
set counter = counter + 1
exitwhen counter >= GetMaxPhysics()
endloop
return -1
endfunction
//Physics constructor
function Physics takes unit Unit, unit damager, real XYspeed, real Zspeed, real angle returns integer
local integer index = findPhysicsUnit(null)
local real execTime = GetPhysicsPeriod() * I2R(GetPhysicsTimeOut())
if (index == -1 or GetUnitDefaultMoveSpeed(Unit) == 0) then
return -1
endif
set udg_Physics_unit[index] = Unit
call SetPhysicsAngle(Unit, angle)
call SetPhysicsHeight(Unit, GetUnitZ(Unit))
call SetPhysicsXYSpeed(Unit, XYspeed * execTime)
call SetPhysicsZSpeed(Unit, Zspeed * execTime)
call SetPhysicsDamager(Unit, damager)
call UnitAddAbility(Unit, GetFlightAbilityId())
return index
endfunction
//Set force to a unit
function SetForceByIndex takes integer index, real XYspeed, real Zspeed, real angle, real XYspeedLimit returns nothing
local real execTime = GetPhysicsPeriod() * I2R(GetPhysicsTimeOut())
if (XYspeedLimit > 0) then
set XYspeed = RMinBJ(XYspeed, XYspeedLimit)
endif
call SetPhysicsAngle(udg_Physics_unit[index], angle)
call SetPhysicsXYSpeed(udg_Physics_unit[index], XYspeed * execTime)
call SetPhysicsZSpeed(udg_Physics_unit[index], Zspeed * execTime)
endfunction
//============================================================================================================
//Physics Interface
//These are the functions you should use
//Set speed to a unit
function SetSpeed takes unit Unit, unit damager, real XYspeed, real Zspeed, real angle returns integer
local integer index = findPhysicsUnit(Unit)
if (index == -1) then
return Physics(Unit, damager, XYspeed, Zspeed, angle)
endif
call SetForceByIndex(index, XYspeed, Zspeed, angle, 0)
return index
endfunction
//Adds speed to a unit
function AddSpeed takes unit Unit, unit damager, real XYspeed, real Zspeed, real angle, real XYspeedLimit returns integer
local integer index = findPhysicsUnit(Unit)
local real oldXYspeed
local real oldAngle
local real Xspeed
local real Yspeed
local real execTime = GetPhysicsPeriod() * I2R(GetPhysicsTimeOut())
if (index == -1) then
return Physics(Unit, damager, XYspeed, Zspeed, angle)
endif
set oldXYspeed = GetPhysicsXYSpeed(Unit)
set oldAngle = GetPhysicsAngle(Unit)
if (XYspeedLimit < 0 and oldXYspeed > XYspeedLimit) then
return index
endif
set Xspeed = oldXYspeed / execTime * CosBJ(oldAngle) + XYspeed * CosBJ(angle)
set Yspeed = oldXYspeed / execTime * SinBJ(oldAngle) + XYspeed * SinBJ(angle)
set XYspeed = SquareRoot(Pow(Xspeed, 2) + Pow(Yspeed, 2))
set Zspeed = GetPhysicsZSpeed(Unit) / execTime + Zspeed
set angle = Atan2BJ(Yspeed, Xspeed)
call SetForceByIndex(index, XYspeed, Zspeed, angle, XYspeedLimit)
return index
endfunction
//Get a Zspeed so that the unit will land at the location
function GetZspeedToLoc takes unit Unit, location pos, location loc, real XYspeed returns real
local real Zheight = GetUnitFlyHeight(Unit)
local real time = DistanceBetweenPoints(pos, loc) / XYspeed
local real execTime = GetPhysicsPeriod() * I2R(GetPhysicsTimeOut())
return Zheight / time + 0.5 * (udg_Gravity / execTime / execTime) * time
endfunction
//Adds force so that the unit will land at the location
function SetSpeedToLoc takes unit Unit, unit damager, location pos, location loc, real XYspeed returns nothing
local real angle = AngleBetweenPoints(pos, loc)
local real Zspeed = GetZspeedToLoc(Unit, pos, loc, XYspeed)
call SetSpeed(Unit, damager, XYspeed, Zspeed, angle)
endfunction
//Adds force so that the unit will land at the location after the duration
function SetSpeedToLocTime takes unit Unit, unit damager, location pos, location loc, real time returns nothing
call SetSpeedToLoc(Unit, damager, pos, loc, DistanceBetweenPoints(pos, loc) / time)
endfunction
//End of Physics Interface
//============================================================================================================
//===========================================================================
function InitTrig_Physics takes nothing returns nothing
set gg_trg_Physics = CreateTrigger( )
call TriggerAddAction(gg_trg_Physics, function PhysicsExecution)
call TriggerRegisterTimerEventPeriodic( gg_trg_Physics, GetPhysicsPeriod() )
endfunction
I have been using it for my maps for quite awhile but it used a ton of global variables, only recently adapted it to cscache.
This code is very efficient, you can have a lot (for a decent computer at least) of units knockback without much lag.
This only for units with foot movement type at the moment.
There is a problem with unit's Z value on water.
Thx to Vexorian for the Caster System