Prozix
New Member
- Reaction score
- 7
my code
JASS:
library ExtraPhysicsFunctions
function GetTerrainZ takes real x, real y returns real z
local unit u = CreateUnit(Player(12),039;hnth039;, x, y, 0)
local location l = GetUnitLoc(u)
local real r = GetLocationZ(l)
call RemoveLocation(l)
call RemoveUnit(u)
return r
endfunction
endlibrary
JASS:
library Physics initializer Init requires ExtraPhysicsFunctions
//--------------------------------------------------------
globals
private constant real STANDARD_MASS = 10.0
private constant real GRAVITY_ACCELERATION = 9.81
private constant real FRICTION = 0.98
private constant integer ORDER_RIGHT_CLICK = 851971
private constant integer ORDER_MOVE = 851986
private constant integer ORDER_ATTACK_MOVE = 851983
endglobals
//--------------------------------------------------------
function IsMoveOrder takes integer order returns boolean
return order==ORDER_RIGHT_CLICK or order==ORDER_MOVE or order==ORDER_ATTACK_MOVE
endfunction
struct vec
real x
real y
real z
static method Create takes nothing returns vec
local vec v = vec.allocate()
call v.SetXYZ(0,0,0)
return v
endmethod
//SET-------------------------------------
method SetByVec takes vec v returns nothing
set .x = v.x
set .y = v.y
set .z = v.z
endmethod
method SetXYAutoZ takes real x, real y returns nothing
set .x = x
set .y = y
set .z = GetTerrainZ(x, y)
endmethod
method SetXYZ takes real x, real y, real z returns nothing
set .x = x
set .y = y
set .z = z
endmethod
//OPERATORS-------------------------------------
method Add takes vec v returns nothing
set .x = .x + v.x
set .y = .y + v.y
set .z = .z + v.z
endmethod
method Substract takes vec v returns nothing
set .x = .x - v.x
set .y = .y - v.y
set .z = .z - v.z
endmethod
method MultiplyByVec takes vec v returns nothing
set .x = .x * v.x
set .y = .y * v.y
set .z = .z * v.z
endmethod
method MultiplyByReal takes real r returns nothing
set .x = .x * r
set .y = .y * r
set .z = .z * r
endmethod
//MISC--------------------------------------------
static method CrossProduct takes vec v1, vec v2 returns vec
local vec v = vec.create()
call v.SetXYZ((v1.y*v2.z - v1.z*v2.y), (v1.z*v2.x - v1.x*v2.z), (v1.x*v2.y - v1.y*v2.x))
return v
endmethod
method Print takes nothing returns nothing
call BJDebugMsg("vec(" + R2S(.x) + "; " + R2S(.y) + "; " + R2S(.z) + ")")
endmethod
method AngleWithXY takes nothing returns real
local real alpha
local real ANS
//calculate alpha
set ANS = SquareRoot(.x*.x + .y*.y)
if ANS == 0.0 then
set alpha = bj_PI/2
else
set alpha = Atan(.z/ANS)
endif
return alpha
endmethod
method Size takes nothing returns real
return SquareRoot(.x*.x + .y*.y + .z*.z)
endmethod
endstruct
globals
vec uVel
endglobals
//--------------------------------------------------------
private function Update takes nothing returns nothing
local unit u = gg_unit_Hblm_0001
local real alpha = 0.0 //angle between surface and z=0
local real oX = GetUnitX(u)
local real oY = GetUnitY(u)
local real Fz = STANDARD_MASS * GRAVITY_ACCELERATION
//points
local vec p1 = vec.Create()
local vec p2 = vec.Create()
local vec p3 = vec.Create()
//face vectors
local vec v1 = vec.Create()
local vec v2 = vec.Create()
//normal
local vec n
local vec a = vec.Create()
//START doing things
call p1.SetXYAutoZ(oX + 10, oY)
call p2.SetXYAutoZ(oX - 8, oY+6)
call p3.SetXYAutoZ(oX - 8, oY-6)
call v1.SetXYZ(p2.x-p1.x, p2.y-p1.y, p2.z-p1.z)
call v2.SetXYZ(p3.x-p1.x, p3.y-p1.y, p3.z-p1.z)
set n = vec.CrossProduct(v1, v2) //point perpendicular to v1 and v2
set alpha = bj_PI/2 - n.AngleWithXY() //2PI(triangle)-PI/2-angle of the normal = angle of the surface with z=0
call a.SetByVec(n)
call a.MultiplyByReal(Fz*Cos(alpha)/n.Size())
//call a.Print()
call uVel.Add(a)
call uVel.MultiplyByReal(FRICTION)
if IsMoveOrder(GetUnitCurrentOrder(u)) or uVel.Size() < 1 then
call uVel.SetXYZ(0,0,0)
else
set oX = oX+uVel.x/20
set oY = oY+uVel.y/20
//map bounds. can be done better, this is a temporary solution
if oX > GetRectMaxX(bj_mapInitialPlayableArea)-64 then
set oX = GetRectMaxX(bj_mapInitialPlayableArea)-64
if uVel.x > 0 then
set uVel.x = -uVel.x
endif
elseif oX < GetRectMinX(bj_mapInitialPlayableArea)+64 then
set oX = GetRectMinX(bj_mapInitialPlayableArea)+64
if uVel.x < 0 then
set uVel.x = -uVel.x
endif
endif
if oY > GetRectMaxY(bj_mapInitialPlayableArea)-64 then
set oY = GetRectMaxY(bj_mapInitialPlayableArea)-64
if uVel.y > 0 then
set uVel.y = -uVel.y
endif
elseif oY < GetRectMinY(bj_mapInitialPlayableArea)+64 then
set oY = GetRectMinY(bj_mapInitialPlayableArea)+64
if uVel.y < 0 then
set uVel.y = -uVel.y
endif
endif
call SetUnitX(u, oX)
call SetUnitY(u, oY)
call SetUnitFacing(u, Rad2Deg(Atan2(uVel.y,uVel.x)))
endif
//cleanup
call p1.destroy()
call p2.destroy()
call p3.destroy()
call v1.destroy()
call v2.destroy()
call n.destroy()
call a.destroy()
endfunction
//--------------------------------------------------------
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterTimerEvent(t, 0.03, true)
call TriggerAddAction(t, function Update)
set uVel = vec.Create()
endfunction
endlibrary