/*-----------------------------------------------------------------------------------*\
| Simple Velocity System |
| by Vercas |
| requires: - TerrainPathability |
| by Rising_Dusk |
| - Table2 |
| by Vercas (me) |
| |
| This is meant to be a simple velocity system for other people to use in their |
| systems or just to knock the hell out of units! |
| |
| |
| Application Programming Interface (API): |
| |
| Vel.add( unit, x, y, z ) -> nothing |
| This sets a unit's velocity to your given values DIVIDED BY 20!! |
| For safety reasons! |
| Vel.addAng( unit, ground angle, air angle, distance ) -> nothing |
| This calculates and sets the unit's velocity to the given values. |
| This is a 3D polar projection formula, and I hope you understand it! |
\*-----------------------------------------------------------------------------------*/
/**/library Velocity initializer Init requires TerrainPathability, Table2/***********/
struct Vel
static constant real INTERVAL = 0.01 //100 times per second.
static constant real REDUCTION = 0.03 //3%
static constant boolean ADD_CROW_FORM = true //To enable Z-axis velocity!
static handle_real_Table x
static handle_real_Table y
static handle_real_Table z
static trigger engine = CreateTrigger ( )
static group flyers = CreateGroup ( )
static location L = Location ( 0, 0 )
static method set takes unit u, real a, real b, real c returns nothing
set Vel.x[u] = a / 20
set Vel.y[u] = b / 20
set Vel.z[u] = c / 20
endmethod
static method add takes unit u, real a, real b, real c returns nothing
set Vel.x[u] = Vel.x[u] + a / 20
set Vel.y[u] = Vel.y[u] + b / 20
set Vel.z[u] = Vel.z[u] + c / 20
endmethod
static method setAng takes unit u, real yaw, real pitch, real distance returns nothing
local real ld = distance * Cos ( pitch * bj_DEGTORAD )
local real lz = distance * Sin ( pitch * bj_DEGTORAD )
local real lx = ld * Cos ( yaw * bj_DEGTORAD )
local real ly = ld * Sin ( yaw * bj_DEGTORAD )
set Vel.x[u] = lx
set Vel.y[u] = ly
set Vel.z[u] = lz
endmethod
static method addAng takes unit u, real yaw, real pitch, real distance returns nothing
local real ld = distance * Cos ( pitch * bj_DEGTORAD )
local real lz = distance * Sin ( pitch * bj_DEGTORAD )
local real lx = ld * Cos ( yaw * bj_DEGTORAD )
local real ly = ld * Sin ( yaw * bj_DEGTORAD )
set Vel.x[u] = Vel.x[u] + lx
set Vel.y[u] = Vel.y[u] + ly
set Vel.z[u] = Vel.z[u] + lz
endmethod
private static method Throw takes nothing returns nothing
local unit u = GetEnumUnit ( )
local real ux = GetUnitX ( u )
local real uy = GetUnitY ( u )
local real uz = GetUnitFlyHeight ( u )
local real vx = Vel.x[u]
local real vy = Vel.y[u]
local real vz = Vel.z[u]
local real tx = ux + vx
local real ty = uy + vy
local real tz
local real red = 1. - Vel.REDUCTION
if IsTerrainWalkable ( tx, uy ) then
call SetUnitX ( u, tx )
endif
if IsTerrainWalkable ( ux, ty ) then
call SetUnitY ( u, ty )
endif
if vz > 1. then
call MoveLocation ( Vel.L, GetUnitX( u ), GetUnitY( u ) )
set tz = uz+vz-GetLocationZ ( Vel.L )
call MoveLocation ( Vel.L, ux, uy )
set tz = tz +GetLocationZ ( Vel.L )
call SetUnitFlyHeight ( u , tz, 0. )
set Vel.z[u] = vz * red
elseif vz > 0.01 then
set Vel.z[u] = -0.1
elseif vz < 0. and uz > 0. then
set vz = vz * ( 1.0 + Vel.REDUCTION )
if uz > vz then
call SetUnitFlyHeight ( u, uz + vz, 0. )
else
call SetUnitFlyHeight ( u, 0. , 0. )
set vz = 0.
endif
set Vel.z[u] = vz
endif
if -0.5 < vx and vx < 0.5 then
set Vel.x[u] = 0.
else
set Vel.x[u] = vx * red
endif
if -0.5 < vy and vy < 0.5 then
set Vel.y[u] = 0.
else
set Vel.y[u] = vy * red
endif
set u = null
endmethod
private static method Check takes nothing returns boolean
local unit u = GetFilterUnit ( )
local boolean b = ( Vel.x[u] != 0. or Vel.y[u] != 0. or Vel.z[u] != 0. )
set u = null
return b
endmethod
private static method Prepare takes nothing returns nothing
call GroupClear ( Vel.flyers )
call GroupEnumUnitsInRect ( Vel.flyers, bj_mapInitialPlayableArea, Condition( function Vel.Check ) )
call ForGroup ( Vel.flyers, function Vel.Throw )
endmethod
static method setup takes nothing returns nothing
set .x = handle_real_Table.create ( )
set .y = handle_real_Table.create ( )
set .z = handle_real_Table.create ( )
call TriggerRegisterTimerEvent ( Vel.engine, Vel.INTERVAL, true )
call TriggerAddAction ( Vel.engine, function Vel.Prepare )
endmethod
endstruct
private function AddCrow takes nothing returns nothing
local unit u = GetTriggerUnit ( )
call UnitAddAbility ( u, 'Amrf' )
call UnitRemoveAbility ( u, 'Amrf' )
set u = null
endfunction
private function Cond takes nothing returns boolean
return GetUnitAbilityLevel ( GetFilterUnit( ), 'Amrf' ) == 0
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger ( )
local region r = CreateRegion ( )
if Vel.ADD_CROW_FORM then
call RegionAddRect ( r, GetWorldBounds( ) )
call TriggerRegisterEnterRegion ( t, r, Condition( function Cond ) )
call TriggerAddAction ( t, function AddCrow )
endif
call Vel.setup ( )
set t = null
set r = null
endfunction
endlibrary