- Joined
- Mar 27, 2012
- Messages
- 3,232
So far I've created pretty much everything I need for the system to work.
Now I'm working on the API, to make it easier to actually use it.
That's where I've come across a problem.
I don't know how to derive horisontal and vertical speed when I have source location, target location, projectile speed.
Now I'm working on the API, to make it easier to actually use it.
That's where I've come across a problem.
I don't know how to derive horisontal and vertical speed when I have source location, target location, projectile speed.
JASS:
globals
//Constants
real ConstantGravity = 1
real ConstantFriction = 1
real ConstantFrictionFactor = 0.95
real LoopPeriod = 0.03
/*
ANYTHING below this point is not meant to be customized/changed
*/
//Derivatives
real PeriodFriction = ConstantFriction * LoopPeriod
real PeriodFrictionFactor = ConstantFrictionFactor * LoopPeriod
real PeriodGravity = ConstantGravity * LoopPeriod
//Unit Data
real array HorisontalAngle
real array HorisontalVelocity
real array VerticalVelocity
//System Data
integer UnitsLooped
group HorisontalVelocityGroup = CreateGroup()
group VerticalVelocityGroup = CreateGroup()
trigger GravityLoopTrig
endglobals
library GravityProjectile //requires optional ExtraFunctions
//Loop functions
function LoopVertical takes nothing returns nothing
local unit u = GetEnumUnit()
local integer Data = GetUnitUserData(u) //Get the data of the unit or we won't know anything
local real VerticalSpeed = VerticalVelocity[Data] //Clearly based on unit data
call SetUnitFlyHeight(u,GetUnitFlyHeight(u)-VerticalSpeed,LoopPeriod)
set VerticalSpeed = VerticalSpeed + PeriodGravity //Gravity
if GetUnitFlyHeight(u) <= 0 then //To not fall through the ground
set VerticalVelocity[Data] = 0
call GroupRemoveUnit(VerticalVelocityGroup,u)
call SetUnitFlyHeight(u,0,LoopPeriod)
endif
set UnitsLooped = UnitsLooped + 1
endfunction
function LoopHorisontal takes nothing returns nothing
local unit u = GetEnumUnit()
local integer Data = GetUnitUserData(u)
local real HorisontalSpeed = HorisontalVelocity[Data]
local real Angle = HorisontalAngle[Data]//Horisontal, as seen
local real x = GetUnitX(u)
local real y = GetUnitY(u)
set x = x + HorisontalSpeed * Cos(Angle * bj_DEGTORAD)
set y = y + HorisontalSpeed * Cos(Angle * bj_DEGTORAD)
call SetUnitX(u,x)
call SetUnitY(u,y)
if GetUnitFlyHeight(u) <= 0 then //If the unit is on ground, then it is affected by friction
set HorisontalVelocity[Data] = HorisontalVelocity[Data] * ConstantFrictionFactor - ConstantFriction
endif
if HorisontalVelocity[Data] <= 0 then //Without this units will start moving back after stopping
call GroupRemoveUnit(HorisontalVelocityGroup,u)
endif
set UnitsLooped = UnitsLooped + 1
endfunction
//Loops
function GravityLoop takes nothing returns boolean
call ForGroup(VerticalVelocityGroup,function LoopVertical)
call ForGroup(HorisontalVelocityGroup,function LoopHorisontal)
if UnitsLooped == 0 then
call DisableTrigger(GravityLoopTrig)
endif
return false
endfunction
//API functions
function ProjectileLaunch takes unit u,real Direction,real HorisontalSpeed,real VerticalSpeed returns nothing
local integer Data = GetUnitUserData(u)
if HorisontalSpeed > 0 then
set HorisontalAngle[Data] = Direction
set HorisontalVelocity[Data] = HorisontalSpeed
call GroupAddUnit(HorisontalVelocityGroup,u)
endif
if VerticalSpeed > 0 then
set VerticalVelocity[Data] = VerticalSpeed
endif
endfunction
function ProjectileLaunchToAngle takes unit u,real Direction,real Angle,real Speed returns nothing
endfunction
function ProjectileLaunchToPoint takes unit u, real x2, real y2, real Speed,boolean High returns nothing
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local real Direction = bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
if High then //Whether to use the higher or lower angle(since all targets can be reached with both in the same time)
else
endif
//bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
//call ProjectileLaunch(u,Direction,HorisontalSpeed,VerticalSpeed)
endfunction
//++Setting up the system(name unchanged so I won't have to call it myself)
function InitTrig_GravityProjectile takes nothing returns nothing
call TriggerAddCondition(GravityLoopTrig,function GravityLoop)
call TriggerRegisterTimerEvent(GravityLoopTrig,LoopPeriod,true)
endfunction
endlibrary