Today I made this jumping system, and it working quite well, with one exception: when the unit is jumping above terrain with different level - the movement isn't smooth. The unit starts going down, then up again, and it's really bothering me.
Here is the library:
I will also post the map, in case you want to see how it looks like.
You just need to press "M" and choose where to jump
It looks how it's supposed to when jumping on even terrain, but when jumping above "holes" or "pools" - that's when it becomes problematic..
Here is the library:
JASS:
library Jumping
globals
public constant real Tick = 0.05
constant real Acceleration = 98.1*Tick
private timer Ticker = CreateTimer()
private boolean On = false
public real X
public real Y
public unit Unit
public boolean End = false
public integer Index
private real sqDist
endglobals
struct Jumper
unit u
real array x[2]
real array y[2]
real array z[2]
real a
real array Vz[2]
real speed
trigger tr
readonly thistype next
readonly thistype prev
static method operator first takes nothing returns thistype
return thistype(0).next
endmethod
static method operator last takes nothing returns thistype
return thistype(0).prev
endmethod
static method create takes nothing returns thistype
local thistype this = thistype.allocate()
set thistype(0).next.prev = this
set this.next = thistype(0).next
set this.prev = thistype(0)
set thistype(0).next = this
if not On then
call TimerStart(Ticker, Tick, false, function thistype.jump)
set On = true
endif
return this
endmethod
method onDestroy takes nothing returns nothing
if this.first == this.last then
set On = false
endif
set this.next.prev = this.prev
set this.prev.next = this.next
endmethod
static method jump takes nothing returns nothing
local thistype this = thistype.first
loop
exitwhen this == 0
set sqDist = (this.x[1] - this.x[0])*(this.x[1] - this.x[0]) + (this.y[1] - this.y[0])*(this.y[1] - this.y[0])
set End = sqDist <= this.speed*this.speed
if End then
set this.x[0] = this.x[1]
set this.y[0] = this.y[1]
set this.z[0] = this.z[1]
set sqDist = 0
else
set this.x[0] = this.x[0] + this.speed*Cos(this.a)
set this.y[0] = this.y[0] + this.speed*Sin(this.a)
set this.z[0] = this.z[0] + this.Vz[0] + (this.Vz[1] - GetTerrainCliffLevel(this.x[0], this.y[0]))
set this.Vz[0] = this.Vz[0] - Acceleration
endif
call SetUnitX(this.u, this.x[0])
call SetUnitY(this.u, this.y[0])
call SetUnitFlyHeight(u, this.z[0], 100000)
if this.tr != null then
set Unit = this.u
set X = this.x[0]
set Y = this.y[0]
set sqDist = (this.x[1] - X)*(this.x[1] - X) + (this.y[1] - Y)*(this.y[1] - Y)
set Index = this
call TriggerEvaluate(this.tr)
endif
if End then
call PauseUnit(this.u, false)
call thistype.destroy(this)
endif
set this = this.next
endloop
if On then
call TimerStart(Ticker, Tick, false, function thistype.jump)
endif
endmethod
endstruct
function Jump takes unit u, real x, real y, real speed, trigger tr returns Jumper
local Jumper jump = Jumper.create()
local real distance
call UnitAddAbility(u, 'Arav')
call UnitRemoveAbility(u, 'Arav')
//call PauseUnit(u, true)
set jump.u = u
set jump.x[1] = x
set jump.y[1] = y
set jump.x[0] = GetUnitX(u)
set jump.y[0] = GetUnitY(u)
set jump.Vz[1] = GetTerrainCliffLevel(jump.x, jump.y)
set jump.z[0] = GetUnitFlyHeight(u) + jump.Vz[1]
set jump.z[1] = GetTerrainCliffLevel(x,y)
set jump.speed = speed*Tick
set distance = SquareRoot((jump.x[1] - jump.x[0])*(jump.x[1] - jump.x[0]) + (jump.y[1] - jump.y[0])*(jump.y[1] - jump.y[0]))
set jump.Vz[0] = ((distance/jump.speed)*Acceleration/2) + ((jump.z[1] - jump.z[0])/(distance/jump.speed))
set jump.a = Atan2(jump.y[1] - jump.y[0], jump.x[1] - jump.x[0])
set jump.tr = tr
return jump
endfunction
endlibrary
I will also post the map, in case you want to see how it looks like.
You just need to press "M" and choose where to jump
It looks how it's supposed to when jumping on even terrain, but when jumping above "holes" or "pools" - that's when it becomes problematic..