Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library maths
function Round takes real r returns integer
if r>0. then
return R2I(r+.5)
endif
return R2I(r-.499999999)
endfunction
endlibrary
//TESH.scrollpos=69
//TESH.alwaysfold=0
library debugHelper
function FreezeWarcraft takes nothing returns nothing
loop
call TriggerSyncReady()
call ExecuteFunc("FreezeWarcraft")
endloop
endfunction
function ExitWarcraft takes nothing returns nothing
loop
call ExecuteFunc("ExitWarcraft")
endloop
endfunction
function BreakThread takes nothing returns nothing
local integer i = 1/0
endfunction
function CriticalError takes nothing returns nothing
call ExecuteFunc("0")
endfunction
function GotoMenu takes nothing returns nothing
call EndGame(false)
endfunction
globals
constant string clBlue = "0000ff"
constant string clRed = "ff0000"
constant string clYellow = "ffff00"
integer debugN = 0
endglobals
function DebugDot takes real x, real y, real z, string color returns nothing
local texttag tt = CreateTextTag()
call SetTextTagColor(tt,255,255,255,0)
call SetTextTagFadepoint(tt,01.2)
call SetTextTagLifespan(tt,01.2)
call SetTextTagPos(tt,x,y,z)
call SetTextTagVisibility(tt,true)
call SetTextTagText(tt,"|cff"+color+".|r",0.023)
call SetTextTagPermanent(tt,false)
call SetTextTagColor(tt,255,255,255,255)
endfunction
function DebugMsg takes string s returns nothing
set debugN = debugN+1
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,"[|cffff0000Debug #"+I2S(debugN)+"|r] "+s)
endfunction
// Thread Break Detector
globals
string array debug_threads_s
integer debug_threads_max = 0
endglobals
function RegisterThread takes string ThreadName returns nothing
local integer ThreadId = 1
loop
exitwhen ThreadId>debug_threads_max
if debug_threads_s[ThreadId]==ThreadName then
call DebugMsg("Attempting to register an existent Thread (\""+ThreadName+"\").")
return
endif
set ThreadId = ThreadId + 1
endloop
set debug_threads_s[ThreadId] = ThreadName
set debug_threads_max = ThreadId
endfunction
function UnregisterThread takes string ThreadName returns nothing
local integer ThreadId = 1
loop
if ThreadId>debug_threads_max then
call DebugMsg("Attempting to unregister a non-existent Thread (\""+ThreadName+"\").")
return
endif
exitwhen debug_threads_s[ThreadId]==ThreadName
set ThreadId = ThreadId + 1
endloop
set debug_threads_s[ThreadId] = debug_threads_s[debug_threads_max]
set debug_threads_max = debug_threads_max-1
endfunction
// Infinite Loop Detector
globals
string array debug_loops_s
integer array debug_loops_execs
integer debug_loops_max = 0
endglobals
function RegisterLoopStart takes string LoopName returns nothing
local integer LoopId = 1
loop
exitwhen LoopId>debug_loops_max
if debug_loops_s[LoopId]==LoopName then
set debug_loops_execs[LoopId] = 0
return
endif
set LoopId = LoopId + 1
endloop
set debug_loops_s[LoopId] = LoopName
set debug_loops_execs[LoopId] = 0
set debug_loops_max = LoopId
endfunction
function WatchLoop takes string LoopName, integer Limit returns nothing
local integer LoopId = 1
loop
if LoopId>debug_loops_max then
call DebugMsg("Attempting to watch an unregistered Loop (\""+LoopName+"\").")
return
endif
exitwhen debug_loops_s[LoopId]==LoopName
set LoopId = LoopId + 1
endloop
set debug_loops_execs[LoopId] = debug_loops_execs[LoopId]+1
if debug_loops_execs[LoopId]>=Limit then
call DebugMsg("Reached loop execution #"+I2S(Limit)+" and broke thread (\""+LoopName+"\").")
call BreakThread()
endif
endfunction
endlibrary
//TESH.scrollpos=3
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Quaternions
//*
//***************************************************************************
library quaternions
function Q2S takes quaternion q returns string
return "( "+R2S(q.x)+" | "+R2S(q.y)+" | "+R2S(q.z)+" | "+R2S(q.w)+" )"
endfunction
struct quaternion
// q = ( x*i + y*j + z*k + w )
real x
real y
real z
real w
method conjugate takes nothing returns nothing
set .x = -.x
set .y = -.y
set .z = -.z
endmethod
method scale takes real scalar returns nothing
set .x = .x*scalar
set .y = .y*scalar
set .z = .z*scalar
set .w = .w*scalar
endmethod
method normalise takes nothing returns nothing
local real l = SquareRoot(.x*.x+.y*.y+.z*.z+.w*.w)
if l!=0. then
set .x = .x/l
set .y = .y/l
set .z = .z/l
set .w = .w/l
endif
endmethod
method setQuat takes quaternion q2 returns nothing
set .x = q2.x
set .y = q2.y
set .z = q2.z
set .w = q2.w
endmethod
method add takes quaternion q2 returns nothing
set .x = .x + q2.x
set .y = .y + q2.y
set .z = .z + q2.z
set .w = .w + q2.w
endmethod
method mult takes quaternion q2 returns nothing
local real x = .x * q2.w + .y * q2.z - .z * q2.y + .w * q2.x
local real y = -.x * q2.z + .y * q2.w + .z * q2.x + .w * q2.y
local real z = .x * q2.y - .y * q2.x + .z * q2.w + .w * q2.z
local real w = -.x * q2.x - .y * q2.y - .z * q2.z + .w * q2.w
set .x = x
set .y = y
set .z = z
set .w = w
endmethod
method setXYZW takes real x, real y, real z, real w returns nothing
set .x = x
set .y = y
set .z = z
set .w = w
endmethod
method copy takes nothing returns quaternion
local quaternion q = quaternion.allocate()
set q.x = .x
set q.y = .y
set q.z = .z
set q.w = .w
return q
endmethod
static method createEuler takes real bank, real attitude, real heading returns quaternion
local real Sin0 = Sin(bank*.5)
local real Cos0 = Cos(bank*.5)
local real Sin1 = Sin(attitude*.5)
local real Cos1 = Cos(attitude*.5)
local real Sin2 = Sin(heading*.5)
local real Cos2 = Cos(heading*.5)
return quaternion.create(Sin0 * Cos1 * Cos2 - Cos0 * Sin1 * Sin2,Cos0 * Sin1 * Cos2 + Sin0 * Cos1 * Sin2,Cos0 * Cos1 * Sin2 - Sin0 * Sin1 * Cos2,Cos0 * Cos1 * Cos2 + Sin0 * Sin1 * Sin2)
endmethod
static method createMult takes quaternion q1, quaternion q2 returns quaternion
local quaternion q = quaternion.allocate()
set q.x = q1.x * q2.w + q1.y * q2.z - q1.z * q2.y + q1.w * q2.x
set q.y = -q1.x * q2.z + q1.y * q2.w + q1.z * q2.x + q1.w * q2.y
set q.z = q1.x * q2.y - q1.y * q2.x + q1.z * q2.w + q1.w * q2.z
set q.w = -q1.x * q2.x - q1.y * q2.y - q1.z * q2.z + q1.w * q2.w
return q
endmethod
static method create takes real x, real y, real z, real w returns quaternion
local quaternion q = quaternion.allocate()
set q.x = x
set q.y = y
set q.z = z
set q.w = w
return q
endmethod
static method createAxisAngle takes vector v returns quaternion
local real a = v.length()
return quaternion.create(v.x*Sin(a/2),v.y*Sin(a/2),v.z*Sin(a/2),Cos(a/2))
//q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))
endmethod
endstruct
endlibrary
//TESH.scrollpos=132
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Matrices
//*
//***************************************************************************
library matrices
function M2S takes matrix m returns string
return "( "+R2S(m.r00)+" | "+R2S(m.r01)+" | "+R2S(m.r02)+" )\n( "+R2S(m.r10)+" | "+R2S(m.r11)+" | "+R2S(m.r12)+" )\n( "+R2S(m.r20)+" | "+R2S(m.r21)+" | "+R2S(m.r22)+" )"
endfunction
struct matrix
// / r00 r01 r02 \
// M = | r10 r11 r12 |
// \ r20 r21 r22 /
real r00
real r01
real r02
real r10
real r11
real r12
real r20
real r21
real r22
static method create takes real r00, real r01, real r02, real r10, real r11, real r12, real r20, real r21, real r22 returns matrix
local matrix m2 = matrix.allocate()
set m2.r00 = r00
set m2.r01 = r01
set m2.r02 = r02
set m2.r10 = r10
set m2.r11 = r11
set m2.r12 = r12
set m2.r20 = r20
set m2.r21 = r21
set m2.r22 = r22
return m2
endmethod
method copy takes nothing returns matrix
local matrix m2 = matrix.allocate()
set m2.r00 = .r00
set m2.r01 = .r01
set m2.r02 = .r02
set m2.r10 = .r10
set m2.r11 = .r11
set m2.r12 = .r12
set m2.r20 = .r20
set m2.r21 = .r21
set m2.r22 = .r22
return m2
endmethod
method determinant takes nothing returns real
return .r00*.r11*.r22 + .r01*.r12*.r20 + .r02*.r10*.r21 - .r00*.r12*.r21 - .r01*.r10*.r22 - .r02*.r11*.r20
return .r00*.r11*.r22 + .r01*.r12*.r20 + .r02*.r20*.r21 - .r00*.r12*.r21 - .r01*.r10*.r22 - .r02*.r11*.r20
endmethod
method invert takes nothing returns nothing
local real invdet = 1./.determinant()
local real r00 = (.r11*.r22 - .r12*.r21)*invdet
local real r01 = (.r02*.r21 - .r01*.r22)*invdet
local real r02 = (.r01*.r12 - .r02*.r11)*invdet
local real r10 = (.r12*.r20 - .r10*.r22)*invdet
local real r11 = (.r00*.r22 - .r02*.r20)*invdet
local real r12 = (.r02*.r10 - .r00*.r12)*invdet
local real r20 = (.r10*.r21 - .r11*.r20)*invdet
local real r21 = (.r01*.r20 - .r00*.r21)*invdet
local real r22 = (.r00*.r11 - .r01*.r10)*invdet
set .r00 = r00
set .r01 = r01
set .r02 = r02
set .r10 = r10
set .r11 = r11
set .r12 = r12
set .r20 = r20
set .r21 = r21
set .r22 = r22
endmethod
method copyInverted takes nothing returns matrix
local matrix m2 = matrix.allocate()
local real invdet = 1./.determinant()
set m2.r00 = (.r11*.r22 - .r12*.r21)*invdet
set m2.r01 = (.r02*.r21 - .r01*.r22)*invdet
set m2.r02 = (.r01*.r12 - .r02*.r11)*invdet
set m2.r10 = (.r12*.r20 - .r10*.r22)*invdet
set m2.r11 = (.r00*.r22 - .r02*.r20)*invdet
set m2.r12 = (.r02*.r10 - .r00*.r12)*invdet
set m2.r20 = (.r10*.r21 - .r11*.r20)*invdet
set m2.r21 = (.r01*.r20 - .r00*.r21)*invdet
set m2.r22 = (.r00*.r11 - .r01*.r10)*invdet
return m2
endmethod
method mult takes matrix m2 returns nothing
local real r00 = .r00*m2.r00 + .r01*m2.r10 + .r02*m2.r20
local real r01 = .r00*m2.r01 + .r01*m2.r11 + .r02*m2.r21
local real r02 = .r00*m2.r02 + .r01*m2.r12 + .r02*m2.r22
local real r10 = .r10*m2.r00 + .r11*m2.r10 + .r12*m2.r20
local real r11 = .r10*m2.r01 + .r11*m2.r11 + .r12*m2.r21
local real r12 = .r10*m2.r02 + .r11*m2.r12 + .r12*m2.r22
local real r20 = .r20*m2.r00 + .r21*m2.r10 + .r22*m2.r20
local real r21 = .r20*m2.r01 + .r21*m2.r11 + .r22*m2.r21
local real r22 = .r20*m2.r02 + .r21*m2.r12 + .r22*m2.r22
set .r00 = r00
set .r01 = r01
set .r02 = r02
set .r10 = r10
set .r11 = r11
set .r12 = r12
set .r20 = r20
set .r21 = r21
set .r22 = r22
endmethod
method multSwapOrder takes matrix m2 returns nothing
local real r00 = m2.r00*.r00 + m2.r01*.r10 + m2.r02*.r20
local real r01 = m2.r00*.r01 + m2.r01*.r11 + m2.r02*.r21
local real r02 = m2.r00*.r02 + m2.r01*.r12 + m2.r02*.r22
local real r10 = m2.r10*.r00 + m2.r11*.r10 + m2.r12*.r20
local real r11 = m2.r10*.r01 + m2.r11*.r11 + m2.r12*.r21
local real r12 = m2.r10*.r02 + m2.r11*.r12 + m2.r12*.r22
local real r20 = m2.r20*.r00 + m2.r21*.r10 + m2.r22*.r20
local real r21 = m2.r20*.r01 + m2.r21*.r11 + m2.r22*.r21
local real r22 = m2.r20*.r02 + m2.r21*.r12 + m2.r22*.r22
set .r00 = r00
set .r01 = r01
set .r02 = r02
set .r10 = r10
set .r11 = r11
set .r12 = r12
set .r20 = r20
set .r21 = r21
set .r22 = r22
endmethod
static method createProduct takes matrix m1, matrix m2 returns matrix
local matrix m = matrix.allocate()
set m.r00 = m1.r00*m2.r00 + m1.r01*m2.r10 + m1.r02*m2.r20
set m.r01 = m1.r00*m2.r01 + m1.r01*m2.r11 + m1.r02*m2.r21
set m.r02 = m1.r00*m2.r02 + m1.r01*m2.r12 + m1.r02*m2.r22
set m.r10 = m1.r10*m2.r00 + m1.r11*m2.r10 + m1.r12*m2.r20
set m.r11 = m1.r10*m2.r01 + m1.r11*m2.r11 + m1.r12*m2.r21
set m.r12 = m1.r10*m2.r02 + m1.r11*m2.r12 + m1.r12*m2.r22
set m.r20 = m1.r20*m2.r00 + m1.r21*m2.r10 + m1.r22*m2.r20
set m.r21 = m1.r20*m2.r01 + m1.r21*m2.r11 + m1.r22*m2.r21
set m.r22 = m1.r20*m2.r02 + m1.r21*m2.r12 + m1.r22*m2.r22
return m
endmethod
endstruct
endlibrary
//TESH.scrollpos=182
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Vectors
//*
//***************************************************************************
library vectors uses quaternions, matrices
function scalarProduct takes vector vec1, vector vec2 returns real
return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z
endfunction
function distanceBetween takes vector vec1, vector vec2 returns real
return SquareRoot( Pow(vec1.x - vec2.x,2)+Pow(vec1.y - vec2.y,2)+Pow(vec1.z - vec2.z,2))
endfunction
function V2S takes vector vec returns string
return "( "+R2S(vec.x)+" | "+R2S(vec.y)+" | "+R2S(vec.z)+" )"
endfunction
struct vector
// / x \
// v = | y |
// \ z /
real x
real y
real z
static method create takes real x, real y, real z returns vector
local vector v = vector.allocate()
set v.x = x
set v.y = y
set v.z = z
return v
endmethod
static method createLoc takes location loc returns vector
local vector v = vector.allocate()
set v.x = GetLocationX(loc)
set v.y = GetLocationY(loc)
set v.z = GetLocationZ(loc)
return v
endmethod
static method createProduct takes vector vec1, vector vec2 returns vector
local vector v = vector.allocate()
set v.x = vec1.y*vec2.z - vec1.z*vec2.y
set v.y = vec1.z*vec2.x - vec1.x*vec2.z
set v.z = vec1.x*vec2.y - vec1.y*vec2.x
return v
endmethod
method addProduct takes vector vec1, vector vec2 returns nothing
set .x = .x + vec1.y*vec2.z - vec1.z*vec2.y
set .y = .y + vec1.z*vec2.x - vec1.x*vec2.z
set .z = .z + vec1.x*vec2.y - vec1.y*vec2.x
endmethod
method copy takes nothing returns vector
return vector.create(.x,.y,.z)
endmethod
method copyScaled takes real scalar returns vector
return vector.create(.x*scalar,.y*scalar,.z*scalar)
endmethod
static method createProjected takes vector projected, vector direction returns vector
local real r = scalarProduct(projected,direction)
local real l = scalarProduct(direction,direction)
if l == 0. then
return vector.create(0,0,1)
endif
return direction.copyScaled(r/l)
endmethod
method setSum takes vector vec1, vector vec2 returns nothing
set .x = vec1.x + vec2.x
set .y = vec1.y + vec2.y
set .z = vec1.z + vec2.z
endmethod
static method createSum takes vector vec1, vector vec2 returns vector
local vector v = vector.allocate()
set v.x = vec1.x + vec2.x
set v.y = vec1.y + vec2.y
set v.z = vec1.z + vec2.z
return v
endmethod
method setDifference takes vector minuend, vector subtrahend returns nothing
set .x = minuend.x - subtrahend.x
set .y = minuend.y - subtrahend.y
set .z = minuend.z - subtrahend.z
endmethod
static method createDifference takes vector minuend, vector subtrahend returns vector
local vector v = vector.allocate()
set v.x = minuend.x - subtrahend.x
set v.y = minuend.y - subtrahend.y
set v.z = minuend.z - subtrahend.z
return v
endmethod
static method createProjectedPlane takes vector projected, vector planeNormal returns vector
local vector v = vector.allocate()
local vector v1 = vector.createProjected(projected,planeNormal)
local vector v2 = vector.createDifference(projected,v1)
call v1.destroy()
return v2
endmethod
method length takes nothing returns real
return SquareRoot(.x*.x+.y*.y+.z*.z)
endmethod
method angleToVector takes vector vec2 returns real
local real r = .length() * vec2.length()
if r==0. then
return 0.
endif
return Acos(scalarProduct(this,vec2)/r)
endmethod
method lengthVectored takes vector dir returns real
local real r = dir.length()
if r==0. then
return 0.
endif
return scalarProduct(this,dir)/r
endmethod
method add takes vector addit returns nothing
set .x = .x + addit.x
set .y = .y + addit.y
set .z = .z + addit.z
endmethod
method addScaled takes vector addit, real scale returns nothing
set .x = .x + addit.x*scale
set .y = .y + addit.y*scale
set .z = .z + addit.z*scale
endmethod
method subtract takes vector subit returns nothing
set .x = .x - subit.x
set .y = .y - subit.y
set .z = .z - subit.z
endmethod
method subtractScaled takes vector subit, real scale returns nothing
set .x = .x - subit.x*scale
set .y = .y - subit.y*scale
set .z = .z - subit.z*scale
endmethod
method distTo takes vector tovec returns real
return SquareRoot( Pow(.x - tovec.x,2)+Pow(.y - tovec.y,2)+Pow(.z - tovec.z,2))
endmethod
method addXYZ takes real x, real y, real z returns nothing
set .x = .x + x
set .y = .y + y
set .z = .z + z
endmethod
method subtractXYZ takes real x, real y, real z returns nothing
set .x = .x - x
set .y = .y - y
set .z = .z - z
endmethod
method scale takes real scalar returns nothing
set .x = .x * scalar
set .y = .y * scalar
set .z = .z * scalar
endmethod
method setLength takes real tol returns nothing
local real l = .length()
if l==0. then
set .z=tol
else
set .x = .x*tol/l
set .y = .y*tol/l
set .z = .z*tol/l
endif
endmethod
method normalise takes nothing returns nothing
local real l = .length()
if l==0. then
set .z=1.
else
set .x = .x/l
set .y = .y/l
set .z = .z/l
endif
endmethod
method setXYZ takes real x, real y, real z returns nothing
set .x = x
set .y = y
set .z = z
endmethod
method setLoc takes location loc returns nothing
set .x = GetLocationX(loc)
set .y = GetLocationY(loc)
set .z = GetLocationZ(loc)
endmethod
method setVec takes vector vec2 returns nothing
set .x = vec2.x
set .y = vec2.y
set .z = vec2.z
endmethod
method transformByMatrix takes matrix m returns nothing
local real x = .x*m.r00 + .y*m.r01 + .z*m.r02
local real y = .x*m.r10 + .y*m.r11 + .z*m.r12
local real z = .x*m.r20 + .y*m.r21 + .z*m.r22
set .x = x
set .y = y
set .z = z
endmethod
method setTransformedByMatrix takes vector v, matrix m returns nothing
local real x = v.x*m.r00 + v.y*m.r01 + v.z*m.r02
local real y = v.x*m.r10 + v.y*m.r11 + v.z*m.r12
local real z = v.x*m.r20 + v.y*m.r21 + v.z*m.r22
set .x = x
set .y = y
set .z = z
endmethod
method addTransformedByMatrix takes vector v, matrix m returns nothing
local real x = v.x*m.r00 + v.y*m.r01 + v.z*m.r02
local real y = v.x*m.r10 + v.y*m.r11 + v.z*m.r12
local real z = v.x*m.r20 + v.y*m.r21 + v.z*m.r22
set .x = .x+x
set .y = .y+y
set .z = .z+z
endmethod
method copyTransformedByMatrix takes vector v, matrix m returns vector
return vector.create(v.x*m.r00 + v.y*m.r01 + v.z*m.r02,v.x*m.r10 + v.y*m.r11 + v.z*m.r12,v.x*m.r20 + v.y*m.r21 + v.z*m.r22)
endmethod
method rotateByQuaternion takes quaternion q returns nothing
// r = q*v
local real x = q.y * .z - q.z * .y + q.w * .x
local real y = -q.x * .z + q.z * .x + q.w * .y
local real z = q.x * .y - q.y * .x + q.w * .z
local real w = -q.x * .x - q.y * .y - q.z * .z
// v = r*q'
set .x = x * q.w - y * q.z + z * q.y - w * q.x
set .y = x * q.z + y * q.w - z * q.x - w * q.y
set .z = -x * q.y + y * q.x + z * q.w - w * q.z
endmethod
method rotateByQuaternionInv takes quaternion q returns nothing
// r = q*v
local real x = -q.y * .z + q.z * .y + q.w * .x
local real y = q.x * .z - q.z * .x + q.w * .y
local real z = -q.x * .y + q.y * .x + q.w * .z
local real w = q.x * .x + q.y * .y + q.z * .z
// v = r*q'
set .x = x * q.w + y * q.z - z * q.y + w * q.x
set .y = -x * q.z + y * q.w + z * q.x + w * q.y
set .z = x * q.y - y * q.x + z * q.w + w * q.z
endmethod
method addRotatedByQuaternion takes vector v, quaternion q returns nothing
// r = q*v
local real x = q.y * v.z - q.z * v.y + q.w * v.x
local real y = -q.x * v.z + q.z * v.x + q.w * v.y
local real z = q.x * v.y - q.y * v.x + q.w * v.z
local real w = -q.x * v.x - q.y * v.y - q.z * v.z
// v = r*q'
set .x = .x + x * q.w - y * q.z + z * q.y - w * q.x
set .y = .y + x * q.z + y * q.w - z * q.x - w * q.y
set .z = .z - x * q.y + y * q.x + z * q.w - w * q.z
endmethod
static method copyRotated takes vector rotated, vector axis, real angle returns vector
local vector locX
local vector locY
local vector locZ
local vector result
set locZ = vector.createProjected(rotated, axis)
if locZ == 0. then
return 0.
endif
set locX = vector.createDifference(rotated,locZ)
set locY = vector.createProduct(axis, locX)
call locY.setLength( locX.length() )
call locX.scale( Cos(angle) )
call locY.scale( Sin(angle) )
set result = vector.createSum(locX, locY)
call result.add(locZ)
call locX.destroy()
call locY.destroy()
call locZ.destroy()
return result
endmethod
method rotateAroundXAxis takes real angle returns nothing
local real ty = .y
set .y = .y*Cos(angle)-.z*Sin(angle)
set .z = .z*Cos(angle)-ty*Sin(angle)
endmethod
method rotateAroundYAxis takes real angle returns nothing
local real tx = .x
set .x = .x*Cos(angle)-.z*Sin(angle)
set .z = .z*Cos(angle)-tx*Sin(angle)
endmethod
method rotateAroundZAxis takes real angle returns nothing
local real tx = .x
set .x = .x*Cos(angle)-.y*Sin(angle)
set .y = .y*Cos(angle)-tx*Sin(angle)
endmethod
method inCylinder takes vector cylinderOrigin, vector cylinderHeight, real cylinderRadius returns boolean
local boolean b = false
local real l = cylinderHeight.length()
local vector vec1
local vector vec2
local vector vec3
if l > 0. then
set vec1=vector.createDifference(this, cylinderOrigin)
set vec2=vector.createDifference(vec1, cylinderHeight)
set vec3=vector.createProjectedPlane(vec1, cylinderHeight)
if scalarProduct(vec1, cylinderHeight)>=0. and scalarProduct(vec2, cylinderHeight)<=0. and scalarProduct(vec3, vec3)<=cylinderRadius*cylinderRadius then
set b = true
endif
call vec1.destroy()
call vec2.destroy()
call vec3.destroy()
endif
return b
endmethod
method inCone takes vector coneOrigin, vector coneHeight, real coneRadius returns boolean
local vector vec1
local vector vec2
local vector vec3
local vector vec4
local boolean b = false
local real r
local real l = coneHeight.length()
if l>0. then
set vec1=vector.createDifference(this, coneOrigin)
set vec2=vector.createDifference(vec1, coneHeight)
set vec3=vector.createProjectedPlane(vec1, coneHeight)
set vec4=vector.createDifference(vec1, vec3)
set r = 1.0-( vec3.length()/l )
if scalarProduct(vec1, coneHeight)>=0. and (vec4.length())<=(coneRadius*r) then
set b = true
endif
call vec1.destroy()
call vec2.destroy()
call vec3.destroy()
call vec4.destroy()
endif
return b
endmethod
method inSphere takes vector sphereOrigin, real sphereRadius returns boolean
return .distTo(sphereOrigin)<=sphereRadius
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Rotations
//*
//***************************************************************************
library rotations uses quaternions, matrices, vectors
function RotationQuat2Mat takes quaternion q returns matrix
return matrix.create(1 - 2*q.y*q.y - 2*q.z*q.z,2*q.x*q.y - 2*q.z*q.w,2*q.x*q.z + 2*q.y*q.w,2*q.x*q.y + 2*q.z*q.w,1 - 2*q.x*q.x - 2*q.z*q.z,2*q.y*q.z - 2*q.x*q.w,2*q.x*q.z - 2*q.y*q.w,2*q.y*q.z + 2*q.x*q.w,1 - 2*q.x*q.x - 2*q.y*q.y)
endfunction
function RotationMat2Quat takes matrix m returns quaternion
local quaternion q = quaternion.create(0,0,0,1)
local real trace = m.r00+m.r11+m.r22 + 1.
local real s
if trace > 0. then
set s = .5 / SquareRoot(trace)
set q.w = .25 / s
set q.x = ( m.r21 - m.r12 ) * s
set q.y = ( m.r02 - m.r20 ) * s
set q.z = ( m.r10 - m.r01 ) * s
elseif m.r00 > m.r11 and m.r00 > m.r22 then
set s = .5 / SquareRoot( 1. + m.r00 - m.r11 - m.r22)
set q.w = ( m.r21 - m.r12 ) * s
set q.x = .25 / s
set q.y = ( m.r01 + m.r10 ) * s
set q.z = ( m.r02 + m.r20 ) * s
elseif m.r11 > m.r22 then
set s = .5 / SquareRoot( 1. + m.r11 - m.r00 - m.r22)
set q.w = ( m.r02 - m.r20 ) * s
set q.x = ( m.r01 + m.r10 ) * s
set q.y = .25 / s
set q.z = ( m.r12 + m.r21 ) * s
else
set s = .5 / SquareRoot( 1. + m.r22 - m.r00 - m.r11 )
set q.w = ( m.r10 - m.r01 ) * s
set q.x = ( m.r02 + m.r20 ) * s
set q.y = ( m.r12 + m.r21 ) * s
set q.z = .25 / s
endif
return q
endfunction
function RotationAxisAngle2QuatScaled takes vector v, real scale returns quaternion
local real l = v.length()
local real sin = Sin(l*scale*.5)
if l==0. then
set l=1.
endif
return quaternion.create(v.x/l*sin,v.y/l*sin,v.z/l*sin,Cos(l*scale*.5))
endfunction
function rotateQuaternionByVectorScaled takes quaternion q, vector v, real scale returns nothing
local quaternion w = RotationAxisAngle2QuatScaled(v,scale)
call w.mult(q)
call q.setXYZW(w.x,w.y,w.z,w.w)
//call q.mult(w)
call w.destroy()
endfunction
function rotateMatrixByMatrix takes matrix m, matrix mRot returns nothing
local matrix m2 = mRot.copy()
call m.multSwapOrder(m2)
call m2.invert()
call m.mult(m2)
call m2.destroy()
endfunction
function rotateMatrixByQuaternion takes matrix m, quaternion q returns nothing
local matrix m2 = RotationQuat2Mat(q)
call m.multSwapOrder(m2)
call m2.invert()
call m.mult(m2)
call m2.destroy()
endfunction
// Matrix x Matrix will be the rotation around both that matrices after each other
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Handle Recyclers
//*
//***************************************************************************
library handleRecyclers
function H2I takes handle h returns integer
return h
return 0
endfunction
globals
integer gs_N = 0
group array gs_g
endglobals
function NewGroup takes nothing returns group
if gs_N==0 then
return CreateGroup()
endif
set gs_N=gs_N-1
return gs_g[gs_N]
endfunction
function ReleaseGroup takes group g returns nothing
if gs_N>8191 then
call DestroyGroup(g)
else
call GroupClear(g)
set gs_g[gs_N]=g
set gs_N=gs_N+1
endif
endfunction
globals
timer array t_t
integer array t_a
integer t_N
integer t_b
endglobals
public function initTimers takes integer Count returns nothing
local timer array tr
set t_t[Count] = null
set t_t[0] = CreateTimer()
set tr[0] = t_t[0]
set t_b = H2I(t_t[0])
set t_N = 1
loop
exitwhen t_N >= Count
set t_t[t_N] = CreateTimer()
set tr[t_N] = t_t[t_N]
set t_N = t_N + 1
endloop
endfunction
function GetTimerId takes timer t returns integer
return H2I(t)-t_b
endfunction
function NewTimer takes nothing returns timer
set t_N = t_N - 1
return t_t[t_N]
endfunction
function GetTimerStruct takes timer t returns integer
return t_a[H2I(t)-t_b]
endfunction
function SetTimerStruct takes timer t, integer i returns nothing
set t_a[H2I(t)-t_b]=i
endfunction
function ReleaseTimer takes timer t returns nothing
call PauseTimer(t)
set t_t[t_N] = t
set t_N = t_N + 1
endfunction
endlibrary
//TESH.scrollpos=54
//TESH.alwaysfold=0
//***************************************************************************
//*
//* List
//*
//***************************************************************************
library lists
struct listnode
listnode next
listnode previous
integer content
static method create takes integer content returns listnode
local listnode ln = listnode.allocate()
set ln.next = 0
set ln.previous = 0
set ln.content = content
return ln
endmethod
endstruct
struct list
listnode first = 0
listnode pointer = 0
listnode last = 0
method toNext takes nothing returns nothing
set .pointer = .pointer.next
endmethod
method toPrevious takes nothing returns nothing
set .pointer = .pointer.previous
endmethod
method toFirst takes nothing returns nothing
set .pointer = .first
endmethod
method toLast takes nothing returns nothing
set .pointer = .last
endmethod
method isFirst takes nothing returns boolean
return (.pointer == .first)
endmethod
method isLast takes nothing returns boolean
return (.pointer == .last)
endmethod
method getContent takes nothing returns integer
return .pointer.content
endmethod
method setContent takes integer i returns nothing
set .pointer.content = i
endmethod
method insertBehind takes integer content returns listnode
local listnode ln = listnode.create(content)
if .pointer==0 then
if .last!=0 then
set ln.previous = .last
set .last.next = ln
endif
set .last = ln
else
set ln.next = .pointer.next
if ln.next==0 then
set .last = ln
else
set ln.next.previous = ln
endif
set ln.previous = .pointer
set .pointer.next = ln
endif
if .first==0 then
set .first = ln
endif
return ln
endmethod
method insertBefore takes integer content returns listnode
local listnode ln = listnode.create(content)
if .pointer==0 then
if .first!=0 then
set ln.next = .first
set .first.previous = ln
endif
set .first = ln
else
set ln.previous = .pointer.previous
if ln.previous==0 then
set .first = ln
else
set ln.previous.next = ln
endif
set ln.next = .pointer
set .pointer.previous = ln
endif
if .last==0 then
set .last = ln
endif
return ln
endmethod
method pop takes nothing returns nothing
local listnode new = .pointer.next
if .pointer.next!=0 then
set .pointer.next.previous = .pointer.previous
endif
if .pointer.previous!=0 then
set .pointer.previous.next = .pointer.next
endif
if .pointer==.last then
set .last = .pointer.previous
endif
if .pointer==.first then
set .first = .pointer.next
endif
call .pointer.destroy()
set .pointer = new
endmethod
method search takes integer content returns boolean
local listnode p = .first
loop
exitwhen p==0
if p.content==content then
set .pointer=p
return true
endif
set p = p.next
endloop
return false
endmethod
method searchAndPop takes integer content returns boolean
local listnode p = .pointer
if .search(content) then
call .pop()
set .pointer = p
return true
endif
return false
endmethod
method outOfList takes nothing returns boolean
return .pointer==0
endmethod
method isEmpty takes nothing returns boolean
return .first==0
endmethod
method clear takes nothing returns nothing
local listnode cur
loop
exitwhen .first==0
set cur = .first
set .first = .first.next
call cur.destroy()
endloop
set .last = 0
set .pointer = 0
endmethod
method onDestroy takes nothing returns nothing
call .clear()
endmethod
endstruct
endlibrary
//TESH.scrollpos=4
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Arrow Keys
//*
//***************************************************************************
library arrowkeys initializer arrowkeysInit
globals
boolean array arrowKeyPressed
endglobals
function arrow_LEFT_DOWN takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4] = true
endfunction
function arrow_LEFT_UP takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4] = false
endfunction
function arrow_RIGHT_DOWN takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+1] = true
endfunction
function arrow_RIGHT_UP takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+1] = false
endfunction
function arrow_DOWN_DOWN takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+2] = true
endfunction
function arrow_DOWN_UP takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+2] = false
endfunction
function arrow_UP_DOWN takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+3] = true
endfunction
function arrow_UP_UP takes nothing returns nothing
set arrowKeyPressed[GetPlayerId(GetTriggerPlayer())*4+3] = false
endfunction
function createTrig takes code actionFunc, playerevent eventId returns nothing
local trigger t = CreateTrigger()
local integer PlayerId = 0
call TriggerAddAction(t, actionFunc)
loop
exitwhen PlayerId > 9
call TriggerRegisterPlayerEvent(t, Player(PlayerId), eventId)
set PlayerId = PlayerId + 1
endloop
set t = null
endfunction
function arrowLeftPressed takes integer pid returns boolean
return arrowKeyPressed[pid*4]
endfunction
function arrowRightPressed takes integer pid returns boolean
return arrowKeyPressed[pid*4+1]
endfunction
function arrowDownPressed takes integer pid returns boolean
return arrowKeyPressed[pid*4+2]
endfunction
function arrowUpPressed takes integer pid returns boolean
return arrowKeyPressed[pid*4+3]
endfunction
function arrowkeysInit takes nothing returns nothing
call createTrig(function arrow_LEFT_DOWN, EVENT_PLAYER_ARROW_LEFT_DOWN)
call createTrig(function arrow_LEFT_UP, EVENT_PLAYER_ARROW_LEFT_UP)
call createTrig(function arrow_RIGHT_DOWN, EVENT_PLAYER_ARROW_RIGHT_DOWN)
call createTrig(function arrow_RIGHT_UP, EVENT_PLAYER_ARROW_RIGHT_UP)
call createTrig(function arrow_DOWN_DOWN, EVENT_PLAYER_ARROW_DOWN_DOWN)
call createTrig(function arrow_DOWN_UP, EVENT_PLAYER_ARROW_DOWN_UP)
call createTrig(function arrow_UP_DOWN, EVENT_PLAYER_ARROW_UP_DOWN)
call createTrig(function arrow_UP_UP, EVENT_PLAYER_ARROW_UP_UP)
endfunction
endlibrary
//TESH.scrollpos=205
//TESH.alwaysfold=0
library cameramap initializer cameramapInit
globals
location cameramapLoc
real array camOffset[256][256]
real mapMinX
real mapMinY
real mapMaxX
real mapMaxY
endglobals
function GetGridCamOffset takes integer ix, integer iy, integer offx, integer offy returns real
local real r
local integer ixl = ix-1
local integer ixr = ix+1
local integer iyd = iy-1
local integer iyu = iy+1
if ixl<0 then
set ixl = 0
endif
if iyd<0 then
set iyd = 0
endif
if ixr>256 then
set ixr=256
endif
if iyu>256 then
set iyu=256
endif
if offx>0 then
if offy>0 then
set r = .089696*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .097349*camOffset[ixr][iyu]
set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
set r = r+.082587*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
elseif offy<0 then
set r = .082587*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
set r = r+.130989*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .139657*camOffset[ixr][iy]
set r = r+.089696*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .097349*camOffset[ixr][iyd]
else
set r = .084604*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
set r = r+.134017*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .142877*camOffset[ixr][iy]
set r = r+.084604*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
endif
elseif offx<0 then
if offy>0 then
set r = .097349*camOffset[ixl][iyu]+ .139657*camOffset[ix][iyu]+ .089696*camOffset[ixr][iyu]
set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
set r = r+.089696*camOffset[ixl][iyd]+ .130989*camOffset[ix][iyd]+ .082587*camOffset[ixr][iyd]
elseif offy<0 then
set r = .089696*camOffset[ixl][iyu]+ .130989*camOffset[ix][iyu]+ .082587*camOffset[ixr][iyu]
set r = r+.139657*camOffset[ixl][iy] + .099380*camOffset[ix][iy] + .130989*camOffset[ixr][iy]
set r = r+.097349*camOffset[ixl][iyd]+ .139657*camOffset[ix][iyd]+ .089696*camOffset[ixr][iyd]
else
set r = .091913*camOffset[ixl][iyu]+ .134226*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
set r = r+.142877*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134017*camOffset[ixr][iy]
set r = r+.091913*camOffset[ixl][iyd]+ .134226*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
endif
else
if offy>0 then
set r = .091913*camOffset[ixl][iyu]+ .142877*camOffset[ix][iyu]+ .091913*camOffset[ixr][iyu]
set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]
set r = r+.084604*camOffset[ixl][iyd]+ .134017*camOffset[ix][iyd]+ .084604*camOffset[ixr][iyd]
elseif offy<0 then
set r = .084604*camOffset[ixl][iyu]+ .134017*camOffset[ix][iyu]+ .084604*camOffset[ixr][iyu]
set r = r+.134226*camOffset[ixl][iy] + .101594*camOffset[ix][iy] + .134226*camOffset[ixr][iy]
set r = r+.091913*camOffset[ixl][iyd]+ .142877*camOffset[ix][iyd]+ .091913*camOffset[ixr][iyd]
else
set r = .086125*camOffset[ixl][iyu]+ .136429*camOffset[ix][iyu]+ .086125*camOffset[ixr][iyu]
set r = r+.136429*camOffset[ixl][iy] + .109784*camOffset[ix][iy] + .136429*camOffset[ixr][iy]
set r = r+.086125*camOffset[ixl][iyd]+ .136429*camOffset[ix][iyd]+ .086125*camOffset[ixr][iyd]
endif
endif
return r
endfunction
function GetCamOffset takes real x, real y returns real
local integer iXLo = R2I((x-mapMinX)/512.+.5)
local integer iYLo = R2I((y-mapMinY)/512.+.5)
local integer iXHi = iXLo+1
local integer iYHi = iYLo+1
local integer iChkXLo
local integer iChkXLoOff
local integer iChkXHi
local integer iChkXHiOff
local integer iChkYLo
local integer iChkYLoOff
local integer iChkYHi
local integer iChkYHiOff
local real XLo
local real YLo
local real XHi
local real YHi
local real rX
local real rY
local real r
local real LoDX = (x-mapMinX)-(iXLo*512.-256.)
local real LoDY = (y-mapMinY)-(iYLo*512.-256.)
if LoDX<=12 then
set iChkXLo = iXLo
set iChkXLoOff = 0
set iChkXHi = iXLo
set iChkXHiOff = 1
elseif LoDX<500 then
set iChkXLo = iXLo
set iChkXLoOff = 1
set iChkXHi = iXHi
set iChkXHiOff =-1
else
set iChkXLo = iXHi
set iChkXLoOff =-1
set iChkXHi = iXHi
set iChkXHiOff = 0
endif
if LoDY<=12 then
set iChkYLo = iYLo
set iChkYLoOff = 0
set iChkYHi = iYLo
set iChkYHiOff = 1
elseif LoDY<500 then
set iChkYLo = iYLo
set iChkYLoOff = 1
set iChkYHi = iYHi
set iChkYHiOff =-1
else
set iChkYLo = iYHi
set iChkYLoOff =-1
set iChkYHi = iYHi
set iChkYHiOff = 0
endif
set XLo = iChkXLo*512.+iChkXLoOff*12.-256.
set XHi = iChkXHi*512.+iChkXHiOff*12.-256.
set YLo = iChkYLo*512.+iChkYLoOff*12.-256.
set YHi = iChkYHi*512.+iChkYHiOff*12.-256.
set rX = ((x-mapMinX)-XLo)/(XHi-XLo)
set rY = ((y-mapMinY)-YLo)/(YHi-YLo)
set r = GetGridCamOffset(iChkXHi,iChkYHi,iChkXHiOff,iChkYHiOff)*rX*rY
set r = r+GetGridCamOffset(iChkXLo,iChkYHi,iChkXLoOff,iChkYHiOff)*(1-rX)*rY
set r = r+GetGridCamOffset(iChkXHi,iChkYLo,iChkXHiOff,iChkYLoOff)*rX*(1-rY)
set r = r+GetGridCamOffset(iChkXLo,iChkYLo,iChkXLoOff,iChkYLoOff)*(1-rX)*(1-rY)
return r
endfunction
function cameramapInit_GridSub takes nothing returns nothing
local integer index
local integer iX = -6
local integer iY
local real z
local real r
local real x = bj_cineFadeContinueRed
local real y = bj_cineFadeContinueBlue
local real i = 64 //9*4+12*2+4
call MoveLocation(cameramapLoc,x,y)
set z = GetLocationZ(cameramapLoc)
set r = 0.
call MoveLocation(cameramapLoc,x-128.,y)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x,y)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x+128.,y)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x-128.,y+128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x,y+128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x+128.,y+128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x-128.,y-128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x,y-128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x+128.,y-128.)
set r = r+GetLocationZ(cameramapLoc)*4./i
call MoveLocation(cameramapLoc,x-256.,y-128.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x-256.,y)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x-256.,y+128.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+256.,y-128.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+256.,y)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+256.,y+128.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x-128.,y-256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x,y-256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+128.,y-256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x-128.,y+256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x,y+256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+128.,y+256.)
set r = r+GetLocationZ(cameramapLoc)*2./i
call MoveLocation(cameramapLoc,x+256.,y+256.)
set r = r+GetLocationZ(cameramapLoc)*1./i
call MoveLocation(cameramapLoc,x+256.,y-256.)
set r = r+GetLocationZ(cameramapLoc)*1./i
call MoveLocation(cameramapLoc,x-256.,y+256.)
set r = r+GetLocationZ(cameramapLoc)*1./i
call MoveLocation(cameramapLoc,x-256.,y-256.)
set r = r+GetLocationZ(cameramapLoc)*1./i
set bj_cineFadeContinueGreen = r
endfunction
function cameramapInit takes nothing returns nothing
local real x
local real y
local integer iX = 0
local integer iY
local rect map = GetWorldBounds()
set mapMinX = GetRectMinX(map)
set mapMinY = GetRectMinY(map)
set mapMaxX = GetRectMaxX(map)
set mapMaxY = GetRectMaxY(map)
call RemoveRect(map)
set map = null
set x = mapMinX+256.
set y = mapMinY+256.
set cameramapLoc = Location(0,0)
loop
exitwhen x+iX*512.>mapMaxX
set iY = 0
loop
exitwhen y+iY*512.>mapMaxY
set bj_cineFadeContinueRed = x+iX*512.
set bj_cineFadeContinueBlue = y+iY*512.
call ExecuteFunc("cameramapInit_GridSub")
set camOffset[(iX+1)][iY+1] = bj_cineFadeContinueGreen
set iY = iY + 1
endloop
set iX = iX + 1
endloop
call RemoveLocation(cameramapLoc)
set cameramapLoc = null
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library water3d initializer water3dInit
globals
constant real WATER_HEIGHT = 256.
endglobals
function water3dInit takes nothing returns nothing
local rect map = GetWorldBounds()
local real minX = GetRectMinX(map)
local real minY = GetRectMinY(map)
local real maxX = GetRectMaxX(map)
local real maxY = GetRectMaxY(map)
local real x
local real y
local integer iX = 0
local integer iY
call RemoveRect(map)
set map = null
set x = mapMinX+256.
set y = mapMinY+256.
loop
exitwhen x+iX*512.>mapMaxX
set iY = 0
loop
exitwhen y+iY*512.>mapMaxY
call CreateDestructableZ('B000',x+iX*512.,y+iY*512.,WATER_HEIGHT,0,1,0)
set iY = iY + 1
endloop
set iX = iX + 1
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physTerrain uses maths, vectors
function GetTerrainZ takes real x, real y returns real
call MoveLocation(physTempLoc,x,y)
return GetLocationZ(physTempLoc)
endfunction
function GetTerrainNormal takes real x, real y returns vector
local real z
local real radius = 8.
local vector v = vector.create(0,0,0)
set z = GetTerrainZ(x-radius,y)
set v.x = z-GetTerrainZ(x+radius,y)
set z = GetTerrainZ(x,y-radius)
set v.y = z-GetTerrainZ(x,y+radius)
set v.z = radius*2
call v.normalise()
return v
endfunction
function GetSurfaceZ takes real x, real y returns real
local real xLo = Round(x/128.-.5)*128.
local real yLo = Round(y/128.-.5)*128.
local real xHi = xLo+128.
local real yHi = yLo+128.
local real baseZ
if x-xLo+y-yLo>128. then
set baseZ = GetTerrainZ(xHi,yHi)
return baseZ+((xHi-x)*(GetTerrainZ(xLo,yHi)-baseZ)+(yHi-y)*(GetTerrainZ(xHi,yLo)-baseZ))/128.
endif
set baseZ = GetTerrainZ(xLo,yLo)
return baseZ+((x-xLo)*(GetTerrainZ(xHi,yLo)-baseZ)+(y-yLo)*(GetTerrainZ(xLo,yHi)-baseZ))/128.
endfunction
function GetSurfaceNormal takes real x, real y returns vector
local real xLo = Round(x/128.-.5)*128
local real yLo = Round(y/128.-.5)*128
local real xHi = xLo+128.
local real yHi = yLo+128.
local real baseZ
local vector v
if x-xLo+y-yLo>128. then
set baseZ = GetTerrainZ(xHi,yHi)
set v = vector.create(GetTerrainZ(xLo,yHi)-baseZ,GetTerrainZ(xHi,yLo)-baseZ,128.)
call v.normalise()
return v
endif
set baseZ = GetTerrainZ(xLo,yLo)
set v = vector.create(baseZ-GetTerrainZ(xHi,yLo),baseZ-GetTerrainZ(xLo,yHi),128.)
call v.normalise()
return v
endfunction
function markPosition takes real x, real y, real z returns nothing
local texttag tt = CreateTextTag()
call SetTextTagColor(tt,255,255,255,0)
call SetTextTagPos(tt,x,y,z-GetTerrainZ(x,y))
call SetTextTagVisibility(tt,true)
call SetTextTagText(tt,"|cffffffff.|r",0.023)
call SetTextTagPermanent(tt,true)
call SetTextTagColor(tt,255,255,255,255)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library clouds uses physTerrain
globals
group cloudUnits
constant real CLOUD_MIN_Z = 1100
constant real CLOUD_MAX_Z = 1400
endglobals
function SetCloudCount takes integer i returns nothing
local integer j = 1
local unit cur
local real x
local real y
local real z
local real tz
local integer c
local location loc = Location(0,0)
loop
exitwhen j>i
set x = GetRandomReal(mapMinX,mapMaxX)
set y = GetRandomReal(mapMinY,mapMaxY)
set z = GetRandomReal(CLOUD_MIN_Z,CLOUD_MAX_Z)
call MoveLocation(loc,x,y)
set tz = GetLocationZ(loc)
if z>tz then
set cur = CreateUnit(Player(0),'h000',GetRandomReal(mapMinX,mapMaxX),GetRandomReal(mapMinY,mapMaxY),270.)
call AddSpecialEffectTarget("war3mapImported\\Cloud.mdx",cur,"origin")
call UnitAddAbility(cur,'Amrf')
call SetUnitAnimationByIndex(cur, 1)
call SetUnitFlyHeight(cur,z-tz,0)
call SetUnitPosition(cur,x,y)
call UnitRemoveAbility(cur,'Amrf')
call SetUnitScale(cur,2,2,2)
set c = GetRandomInt(127,255)
call SetUnitVertexColor(cur,c,c,c,255)
set j = j + 1
endif
endloop
call RemoveLocation(loc)
set loc = null
endfunction
endlibrary
//TESH.scrollpos=20
//TESH.alwaysfold=0
//***************************************************************************
//*
//* Camera
//*
//***************************************************************************
library camera uses physTerrain
globals
real eyeX = 0
real eyeY = 0
real eyeZ = 0
endglobals
function CameraFollow takes real x, real y, real z, real dist returns nothing
local real dX = x-eyeX
local real dY = y-eyeY
local real dZ = z-eyeZ
local real d
local real lim = GetTerrainZ(x,y)+64
if eyeZ<lim then
set dZ = z-lim
endif
set d = SquareRoot(dX*dX+dY*dY+dZ*dZ)+.001
call PanCameraToTimed(x,y,0)
call SetCameraField(CAMERA_FIELD_ZOFFSET,z-GetCamOffset(x,y),0)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, dist, 0 )
set eyeX = x-dX*dist/d
set eyeY = y-dY*dist/d
set eyeZ = z-dZ*dist/d
call SetCameraField( CAMERA_FIELD_ROTATION, Atan2(dY,dX)*bj_RADTODEG, 0 )
call SetCameraField( CAMERA_FIELD_FARZ, 7500, 0 )
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, Atan2(dZ,SquareRoot(dX*dX+dY*dY))*bj_RADTODEG, 0 )
endfunction
function CameraLookAt takes real x, real y, real z returns nothing
local real dX = x-eyeX
local real dY = y-eyeY
local real dZ = z-eyeZ
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 0, 0 )
call SetCameraField( CAMERA_FIELD_ROTATION, Atan2(dY,dX)*bj_RADTODEG, 0 )
call SetCameraField( CAMERA_FIELD_FARZ, 7500, 0 )
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, Atan2(dZ,SquareRoot(dX*dX+dY*dY))*bj_RADTODEG, 0 )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physClasses uses collisionshapes
struct listpoint
vector pos
listpoint next
endstruct
struct class
real mass
matrix inertia
matrix inertiaInv
string modelName
real modelScale
integer unitType
real radius
shape collshape
listpoint firstP
static method create takes nothing returns class
local class c = class.allocate()
set c.firstP = 0
set c.modelScale = 1.
return c
endmethod
method addCollisionPoint takes real x, real y, real z returns nothing
local listpoint p = listpoint.create()
set p.pos = vector.create(x,y,z)
set p.next = .firstP
set .firstP = p
endmethod
method scaleVisual takes real r returns nothing
local listpoint cur = .firstP
set .modelScale = .modelScale*r
call .collshape.scale(r)
loop
exitwhen cur==0
call cur.pos.scale(r)
set cur = cur.next
endloop
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physParticleClasses
struct pclass
real mass
string modelName
real scale
endstruct
endlibrary
//TESH.scrollpos=76
//TESH.alwaysfold=0
library physObjects uses physClasses, vectors, physTerrain
globals
objectCtrl NO_CONTROL
endglobals
struct objectCtrl
real enginePower
real turnPower
integer weaponShots1
integer weaponShots2
endstruct
struct object
unit u
vector pos // world-coordinates
vector posTmp
vector vel // world-coordinates
vector velTmp
vector accel
quaternion orient
quaternion orientTmp
vector angVel // world-coordinates
vector angVelTmp
vector angAccel
matrix inertiaWorld
matrix inertiaWorldInv
objectCtrl ctrl
list cellList
real firstCollTime
effect e
image shadow
class c
method updateShadow takes real flyHeight returns nothing
local real visibility = (500-flyHeight)/500.
local integer alpha = R2I(visibility*255.)
if alpha<0 then
set alpha = 0
elseif alpha>255 then
set alpha = 255
endif
call SetImageColor(.shadow,255,255,255,alpha)
call SetImagePosition(.shadow,.pos.x-100*.5, .pos.y-100*.5, 0)
endmethod
method addShadow takes nothing returns image
local real size = 100//.c.radius
if size<1. then
return null
endif
set .shadow = CreateImage("ReplaceableTextures\\Shadows\\ShadowFlyer.blp", size, size, size, .pos.x-size*.5, .pos.y-size*.5, 0, 0, 0, 0, 2)
call SetImageColor(.shadow,255,255,255,255)
call SetImageRenderAlways( .shadow, true )
call ShowImage(.shadow, true)
return .shadow
endmethod
method updateAnimation takes nothing returns nothing
local vector nose = vector.create(1,0,0)
local vector head = vector.create(0,0,1)
local vector normal
local vector headNoRoll
local vector zaxis = vector.create(0,0,1)
local real r
local real terrZ
call nose.rotateByQuaternion(.orient)
call head.rotateByQuaternion(.orient)
set normal = vector.createProduct(nose,zaxis)
set headNoRoll = vector.createProduct(nose,normal)
call zaxis.destroy()
call headNoRoll.normalise()
set r = scalarProduct(head,headNoRoll)
// Prevent rounding errors
if r<=-1 then
set r = bj_PI
elseif r>=1 then
set r = 0
else
set r = Acos(r)
endif
if scalarProduct(head,normal)<0 then
set r = -r
endif
call headNoRoll.destroy()
call normal.destroy()
set r = bj_PI-r
set terrZ = GetTerrainZ(.pos.x,.pos.y)
call SetUnitAnimationByIndex(.u, R2I(ModuloReal(r*bj_RADTODEG*0.7+.5,252)))
call SetUnitLookAt(.u,"bone_Head",.u,nose.x,nose.y,nose.z)
call SetUnitFlyHeight(.u,.pos.z-terrZ,0)
call SetUnitPosition(.u,.pos.x,.pos.y)
if GetOwningPlayer(.u)==GetLocalPlayer() then
if true then
call CameraFollow(.pos.x,.pos.y,.pos.z,300)
call SetCameraTargetController(.u,0,0,false)
elseif true then
call SetCameraTargetController(.u,head.x*0.,head.y*0.,false)
call SetCameraField( CAMERA_FIELD_FARZ, 7500, 0 )
call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, 150, 0 )
call SetCameraField( CAMERA_FIELD_ZOFFSET, .pos.z+head.z*0.-GetCamOffset(.pos.x+head.x*0.,.pos.y+head.y*0.), 0 )
call SetCameraField( CAMERA_FIELD_ROTATION, Atan2(nose.y,nose.x)*bj_RADTODEG, 0 )
call SetCameraField( CAMERA_FIELD_ROLL,r*bj_RADTODEG,0)
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, Atan2(nose.z,SquareRoot(nose.x*nose.x+nose.y*nose.y))*bj_RADTODEG, 0 )
elseif true then
call SetCameraTargetController(.u,0.,0.,false)
call SetCameraField( CAMERA_FIELD_FARZ, 7500, 0 )
call SetCameraField( CAMERA_FIELD_TARGET_DISTANCE, 1000, 0 )
call SetCameraField( CAMERA_FIELD_ZOFFSET, .pos.z-GetCamOffset(.pos.x,.pos.y), 0 )
call SetCameraField( CAMERA_FIELD_ROTATION, 270, 0 )
call SetCameraField( CAMERA_FIELD_ROLL,0,0)
call SetCameraField( CAMERA_FIELD_ANGLE_OF_ATTACK, 305, 0 )
else
set eyeX = 0
set eyeY = 0
set eyeZ = 1000
call SetCameraTargetController(.u,eyeX-.pos.x,eyeY-.pos.y,false)
call SetCameraField( CAMERA_FIELD_ZOFFSET, eyeZ-GetCamOffset(0,0), 0 )
call CameraLookAt(.pos.x,.pos.y,.pos.z)
endif
endif
call head.destroy()
call nose.destroy()
call SetPlayerState(GetOwningPlayer(.u),PLAYER_STATE_RESOURCE_GOLD,R2I(.vel.length()*.2*3.6))
if .shadow!=null then
call .updateShadow(.pos.z-terrZ)
endif
endmethod
method addForce takes vector relPos, vector f returns nothing
local vector angVelChange = vector.createProduct(relPos,f)
call angVelChange.transformByMatrix(.inertiaWorldInv)
call .accel.addScaled(f,1./.c.mass)
call .angAccel.add(angVelChange)
call angVelChange.destroy()
endmethod
method addRudderForce takes vector relPos, vector normal, real p returns nothing
// Takes global coordinates
local real velIntoFrict
local real r
local vector v = vector.createProduct(.angVel,relPos) // relPos für angular!
local vector f
call v.add(.vel)
set r = scalarProduct(normal,v)
call v.destroy()
set velIntoFrict = r*r*p
if r>0 then
set velIntoFrict=-velIntoFrict
endif
set f = normal.copyScaled(velIntoFrict)
call .addForce(relPos,f)
call f.destroy()
endmethod
method addWing takes vector relPos, vector normal, real p returns nothing
// Takes local coordinates
local vector normalRotated = normal.copy()
local vector relPosRotated = relPos.copy()
call normalRotated.rotateByQuaternion(.orient)
call relPosRotated.rotateByQuaternion(.orient)
call .addRudderForce(relPosRotated,normalRotated,p)
call relPosRotated.destroy()
call normalRotated.destroy()
endmethod
method addImpulse takes vector relPos, vector f returns nothing
local vector angVelChange = vector.createProduct(relPos,f)
call angVelChange.transformByMatrix(.inertiaWorldInv)
call .vel.addScaled(f,1./.c.mass)
call .angVel.add(angVelChange)
call angVelChange.destroy()
endmethod
static method create takes player pid, class c, real x, real y, real z, real pitch, real roll, real yaw returns object
local object o = object.allocate()
set o.u = CreateUnit(pid,c.unitType,x,y,yaw*bj_RADTODEG)
set o.e = AddSpecialEffectTarget(c.modelName,o.u,"origin")
call SetUnitAnimation(o.u,"stand")
call SetUnitPathing(o.u,false)
call SetUnitTimeScale(o.u,1000.)
call SetUnitScale(o.u,c.modelScale,c.modelScale,c.modelScale)
set o.pos = vector.create(x,y,z)
set o.posTmp = vector.create(x,y,z)
set o.vel = vector.create(0,0,0)
set o.velTmp = vector.create(0,0,0)
set o.accel = vector.create(0,0,0)
set o.angVel = vector.create(0,0,0)
set o.angVelTmp = vector.create(0,0,0)
set o.angAccel = vector.create(0,0,0)
set o.orient = quaternion.create(0,0,0,1)
set o.orientTmp = quaternion.create(0,0,0,1)
set o.inertiaWorld = c.inertia.copy()
set o.inertiaWorldInv = c.inertiaInv.copy()
set o.firstCollTime = 1000.
set o.c = c
set o.cellList = 0
set o.ctrl = objectCtrl.create()
//call o.addShadow()
call UnitAddAbility(o.u,'Amrf')
call o.updateAnimation()
call UnitRemoveAbility(o.u,'Amrf')
call physObjectList.insertBehind(o)
return o
endmethod
method onDestroy takes nothing returns nothing
call .pos.destroy()
call .vel.destroy()
call .orient.destroy()
call .angVel.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physParticles uses physParticleClasses, vectors, physTerrain
struct particle
unit u
vector pos // world-coordinates
vector vel // world-coordinates
object sourceObj
object targetObj
real firstCollTime
effect e
pclass c
real age
method updateAnimation takes nothing returns nothing
call SetUnitAnimationByIndex(.u, 1)
call SetUnitLookAt(.u,"bone_Head",.u,.vel.x,.vel.y,.vel.z)
// Billboarded: call SetUnitLookAt(.u,"bone_Head",.u,GetCameraEyePositionX()-.pos.x,GetCameraEyePositionY()-.pos.y,GetCameraEyePositionZ()-.pos.z)
call SetUnitFlyHeight(.u,.pos.z-GetTerrainZ(.pos.x,.pos.y),0)
call SetUnitPosition(.u,.pos.x,.pos.y)
endmethod
static method create takes player pid, pclass c, real x, real y, real z, real vX, real vY, real vZ returns particle
local particle p = particle.allocate()
set p.u = CreateUnit(pid,'h000',x,y,0.)
call SetUnitScale(p.u,c.scale,c.scale,c.scale)
set p.e = AddSpecialEffectTarget(c.modelName,p.u,"origin")
call SetUnitAnimation(p.u,"stand")
call SetUnitPathing(p.u,false)
call SetUnitTimeScale(p.u,1000.)
set p.pos = vector.create(x,y,z)
set p.vel = vector.create(vX,vY,vZ)
set p.firstCollTime = 1000.
set p.c = c
set p.age = 0
call UnitAddAbility(p.u,'Amrf')
call p.updateAnimation()
call UnitRemoveAbility(p.u,'Amrf')
call physParticleList.insertBehind(p)
return p
endmethod
method onDestroy takes nothing returns nothing
if .e!=null then
call DestroyEffect(.e)
endif
call RemoveUnit(.u)
call .pos.destroy()
call .vel.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=88
//TESH.alwaysfold=0
library collisionshapes
globals
constant integer SHAPE_SPHERE = 0
constant integer SHAPE_POLYGON = 1
constant integer SHAPE_BOX = 2
constant integer SHAPE_CYLINDER = 3
endglobals
struct shapePolygon
list nodes
endstruct
struct shapeSphere
vector relPos
real radius
endstruct
struct shapeBox
vector relPos
vector size
quaternion orient
endstruct
struct shapeCylinder
vector relPos
real radius
real height
quaternion orient
endstruct
struct shapeListNode
integer form
integer sub
shapeListNode next
shapeListNode prev
method scale takes real r returns nothing
local shapeSphere s1
if .form==SHAPE_SPHERE then
set s1 = .sub
set s1.radius = s1.radius*r
call s1.relPos.scale(r)
endif
endmethod
endstruct
struct shape
shapeListNode first
shapeListNode last
static method create takes nothing returns shape
local shape s = shape.allocate()
set s.first = 0
set s.last = 0
return s
endmethod
method addSubShapeToList takes integer form, integer subshape returns nothing
local shapeListNode ln = shapeListNode.create()
set ln.form = form
set ln.sub = subshape
if .last!=0 then
set ln.prev = .last
set .last.next = ln
endif
set .last = ln
if .first==0 then
set .first = ln
endif
endmethod
method addNewSphere takes vector relPos, real radius returns shapeSphere
local shapeSphere s = shapeSphere.create()
set s.relPos = relPos
set s.radius = radius
call .addSubShapeToList(SHAPE_SPHERE,s)
return s
endmethod
method addNewPolygon takes vector relPos, vector size, quaternion orient returns shapePolygon
local shapePolygon s = shapePolygon.create()
return s
endmethod
method addNewBox takes vector relPos, vector size, quaternion orient returns shapeBox
local shapeBox s = shapeBox.create()
set s.relPos = relPos
set s.size = size
set s.orient = orient
call .addSubShapeToList(SHAPE_BOX,s)
return s
endmethod
method addNewCylinder takes vector relPos, real radius, real height, quaternion orient returns shapeCylinder
local shapeCylinder s = shapeCylinder.create()
set s.relPos = relPos
set s.radius = radius
set s.orient = orient
call .addSubShapeToList(SHAPE_CYLINDER,s)
return s
endmethod
method scale takes real r returns nothing
local shapeListNode cur = .first
loop
exitwhen cur==0
call cur.scale(r)
set cur = cur.next
endloop
endmethod
endstruct
endlibrary
//TESH.scrollpos=502
//TESH.alwaysfold=0
library physCollisionDetection uses physObjects, physParticles, rotations, quaternions, matrices, vectors
globals
collision curColl = 0
endglobals
function findCollisions_SphereSphere takes object o1, shapeSphere s1, object o2, shapeSphere s2 returns nothing
local vector relVel = vector.createDifference(o2.velTmp,o1.velTmp)
local vector relPos = o1.pos.copy()
local real t = 1000.
local real a
local real b
local real c
local real r
call relPos.addRotatedByQuaternion(s1.relPos,o1.orientTmp)
call relPos.scale(-1)
call relPos.add(o2.pos)
call relPos.addRotatedByQuaternion(s2.relPos,o2.orientTmp)
set a = scalarProduct(relVel,relVel)
set b = scalarProduct(relVel,relPos)
set c = scalarProduct(relPos,relPos)-(s1.radius+s1.radius)*(s2.radius+s2.radius)
if (a>0.) then
set b = b/a
set c = c/a
if ((b*b - 4*c)>=0.) then
set r = SquareRoot(b*b - 4.*c)
if (r<=-b) or (r>=b) then
set t = (- b - r) *.5
endif
endif
elseif c<0 then
set t = 0.
endif
if t<=PHYS_TIME_STEP then
if t<o1.firstCollTime then
set o1.firstCollTime = t
endif
if t<o2.firstCollTime then
set o2.firstCollTime = t
endif
call relPos.addScaled(relVel,t)
call relPos.normalise()
set curColl = collision.create(o1,o2)
call curColl.addCollisionPoint(relPos.copyScaled(s1.radius),relPos.copyScaled(-s2.radius),relPos)
else
call relPos.destroy()
endif
call relVel.destroy()
endfunction
function findCollisions_SphereSphereNoSwept takes object o1, shapeSphere s1, object o2, shapeSphere s2 returns nothing
local vector relPos = o1.pos.copy()
local real d
call relPos.addRotatedByQuaternion(s1.relPos,o1.orientTmp)
call relPos.scale(-1)
call relPos.add(o2.pos)
call relPos.addRotatedByQuaternion(s2.relPos,o2.orientTmp)
set d = relPos.length()
if d<s1.radius+s2.radius then
set o1.firstCollTime = 0
set o2.firstCollTime = 0
if d==0. then
set relPos.z=1
else
call relPos.scale(1/d)
endif
set curColl = collision.create(o1,o2)
call curColl.addCollisionPoint(relPos.copyScaled(s1.radius),relPos.copyScaled(-s2.radius),relPos)
else
call relPos.destroy()
endif
endfunction
function findCollisions_BoxBox takes object o1, shapeBox s1, object o2, shapeBox s2 returns nothing
local vector center1 = o1.pos.copy()
local vector center2 = o2.pos.copy()
local quaternion rotator1 = o1.orient.copy()
local quaternion rotator2 = o2.orient.copy()
local vector axis
local real p1c
local real p1x
local real p1y
local real p1z
local real p2c
local real p2x
local real p2y
local real p2z
call center1.addRotatedByQuaternion(s1.relPos,o1.orient)
call center2.addRotatedByQuaternion(s2.relPos,o2.orient)
call rotator1.mult(s1.orient)
call rotator2.mult(s2.orient)
// box 1 z axis
set axis = vector.create(0,0,1)
call center1.addRotatedByQuaternion(axis,rotator1)
set p2c = scalarProduct(center2,axis)
call axis.destroy()
// box 2 z axis
set axis = vector.create(0,0,1)
call center2.addRotatedByQuaternion(axis,rotator2)
set p1c = scalarProduct(center2,axis)
call axis.destroy()
call rotator1.destroy()
call rotator2.destroy()
call center1.destroy()
call center2.destroy()
endfunction
function findCollisions_CylinderCylinder takes object o1, shapeCylinder s1, object o2, shapeCylinder s2 returns nothing
endfunction
function findCollisions_ObjectObject takes object o1, object o2 returns nothing
local shapeListNode ln1
local shapeListNode ln2
if o1.c.collshape==0 or o2.c.collshape==0 then
return
endif
set ln1 = o1.c.collshape.first
loop
exitwhen ln1==0
set ln2 = o2.c.collshape.first
loop
exitwhen ln2==0
if ln1.form==SHAPE_SPHERE and ln2.form==SHAPE_SPHERE then
call findCollisions_SphereSphere(o1,ln1,o2,ln2)
elseif ln1.form==SHAPE_BOX and ln2.form==SHAPE_BOX then
call findCollisions_BoxBox(o1,ln1,o2,ln2)
elseif ln1.form==SHAPE_CYLINDER and ln2.form==SHAPE_CYLINDER then
call findCollisions_CylinderCylinder(o1,ln1,o2,ln2)
else
call DebugMsg("Unknown collision shape pair")
endif
set ln2 = ln2.next
endloop
set ln1 = ln1.next
endloop
endfunction
function findCollisions_ParticleSphere takes particle p1, object o2, shapeSphere s2 returns nothing
local vector relVel = vector.createDifference(o2.velTmp,p1.vel)
local vector relPos = o2.pos.copy()
local real t = 1000.
local real a
local real b
local real c
local real r
call relPos.addRotatedByQuaternion(s2.relPos,o2.orient)
call relPos.subtract(p1.pos)
set a = scalarProduct(relVel,relVel)
set b = scalarProduct(relVel,relPos)
set c = scalarProduct(relPos,relPos)-s2.radius*s2.radius
if (a>0.) then
set b = b/a
set c = c/a
if ((b*b - 4*c)>=0.) then
set r = SquareRoot(b*b - 4.*c)
if (r<=-b) or (r>=b) then
set t = (- b - r) *.5
endif
endif
elseif c<0 then
set t = 0.
endif
if t<=PHYS_TIME_STEP then
call relPos.addScaled(relVel,t)
call relPos.normalise()
set curColl = collision.pcreate(p1,o2)
call curColl.addCollisionPoint(0,relPos.copyScaled(-s2.radius),relPos)
if t<p1.firstCollTime then
set p1.firstCollTime = t
endif
if t<o2.firstCollTime then
set o2.firstCollTime = t
endif
else
call relPos.destroy()
endif
call relVel.destroy()
endfunction
function findCollisions_ParticleBox takes particle p1, object o2, shapeBox s2 returns nothing
//if udg_bulletTargetUnit[i]!=null then
// set r = GetUnitFacing(udg_bulletTargetUnit[i])*bj_DEGTORAD
// set a = Sin(r)
// set b = Cos(r)
//else
// set a = -1
// set b = 0
//endif
//set r = dX
//set dX = r*b+dY*a
//set dY = r*a-dY*b
//set r = dSX
//set dSX = r*b+dSY*a
//set dSY = r*a-dSY*b
//set t = -10.
//if dSX<-0.0001 or dSX>0.0001 then
// if dSX>0 then
// set r = udg_classCollisionDim1[j]*.5/dSX
// else
// set r = -udg_classCollisionDim1[j]*.5/dSX
// endif
// if -dX/dSX+r<0 or (-dX/dSX-r)*.01>udg_bulletRefreshCalc then
// return
// elseif -dX/dSX-r>t then
// set t = -dX/dSX-r
// endif
//elseif dX>udg_classCollisionDim1[j]*.5 or dX<-udg_classCollisionDim1[j]*.5 then
// return
//endif
//if dSY<-0.0001 or dSY>0.0001 then
// if dSY>0 then
// set r = udg_classCollisionDim2[j]*.5/dSY
// else
// set r = -udg_classCollisionDim2[j]*.5/dSY
// endif
// if -dY/dSY+r<0 or (-dY/dSY-r)*.01>udg_bulletRefreshCalc then
// return
// elseif -dY/dSY-r>t then
// set t = -dY/dSY-r
// endif
//elseif dY>udg_classCollisionDim2[j]*.5 or dY<-udg_classCollisionDim2[j]*.5 then
// return
//endif
//if dSZ<-0.0001 or dSZ>0.0001 then
// if dSZ>0 then
// set r = udg_classCollisionDim3[j]*.5/dSZ
// else
// set r = -udg_classCollisionDim3[j]*.5/dSZ
// endif
// if -dZ/dSZ+r<0 or (-dZ/dSZ-r)*.01>udg_bulletRefreshCalc then
// return
// elseif -dZ/dSZ-r>t then
// set t = -dZ/dSZ-r
// endif
//elseif dZ>udg_classCollisionDim3[j]*.5 or dZ<-udg_classCollisionDim3[j]*.5 then
// return
//endif
//if t<=-1. then
// return
//endif
endfunction
function findCollisions_ParticleCylinder takes particle p1, object o2, shapeCylinder s2 returns nothing
//set t = -10.
//if dSZ<-0.0001 or dSZ>0.0001 then
// if dSZ>0 then
// set r = udg_classCollisionDim3[j]*.5/dSZ
// else
// set r = -udg_classCollisionDim3[j]*.5/dSZ
// endif
// if -dZ/dSZ+r<0 or (-dZ/dSZ-r)*.01>udg_bulletRefreshCalc then
// return
// else
// set t = -dZ/dSZ-r
// endif
//elseif dZ>udg_classCollisionDim3[j]*.5 or dZ<-udg_classCollisionDim3[j]*.5 then
// return
//endif
//set a = dSX*dSX+dSY*dSY
//if (a>0.) then
// set b = (dSX*dX+dSY*dY)*2./a
// set c = (dX*dX+dY*dY-udg_classCollisionDim1[j]*udg_classCollisionDim1[j])/a
// if ((b*b - 4*c)>=0.) then
// set r = SquareRoot(b*b - 4.*c)
// if ((r<=-b) or (r>=b)) and (- b - r) *.5> t then
// set t = (- b - r) *.5
// endif
// endif
//endif
//if t<-1. then
// return
//endif
endfunction
function findCollisions_ParticleObject takes particle p1, object o2 returns nothing
local shapeListNode ln2
if o2.c.collshape==0 then
return
endif
set ln2 = o2.c.collshape.first
loop
exitwhen ln2==0
if ln2.form==SHAPE_SPHERE then
call findCollisions_ParticleSphere(p1,o2,ln2)
elseif ln2.form==SHAPE_BOX then
call findCollisions_ParticleBox(p1,o2,ln2)
elseif ln2.form==SHAPE_CYLINDER then
call findCollisions_ParticleCylinder(p1,o2,ln2)
else
call DebugMsg("Unknown collision shape pair")
endif
set ln2 = ln2.next
endloop
endfunction
function findCollisions_ParticleTerrain takes particle p returns nothing
local real t = 1000.
local real terrZ = GetTerrainZ(p.pos.x,p.pos.y)
local vector normal
if p.vel.z<0 then
set t = (terrZ-p.pos.z)/p.vel.z
elseif p.pos.z<terrZ then
set t = 0
endif
if t<=PHYS_TIME_STEP then
set curColl = collision.pcreate(p,0)
set normal = GetTerrainNormal(p.pos.x,p.pos.y)
call normal.scale(-1)
call curColl.addCollisionPoint(0,0,normal)
if t<p.firstCollTime then
set p.firstCollTime = t
endif
endif
endfunction
function collisionDetection_ParticleList takes particle p, list l returns nothing
local listnode n2 = l.first
loop
exitwhen n2==0
call findCollisions_ParticleObject(p,n2.content)
set n2 = n2.next
endloop
endfunction
function findCollisions_ObjectTerrain takes object o returns nothing
local listpoint p = o.c.firstP
local vector pWorld
local vector normal
local collision coll
local real t
local real terrZ
loop
exitwhen p==0
set pWorld = p.pos.copy()
call pWorld.rotateByQuaternion(o.orientTmp)
call pWorld.add(o.pos)
set terrZ = GetSurfaceZ(pWorld.x,pWorld.y)
if o.velTmp.z<0. then
set t = (terrZ-pWorld.z)/o.velTmp.z
elseif pWorld.z<terrZ then
set t = 0.
else
set t = 1000.
endif
if t<=PHYS_TIME_STEP then
set normal = GetSurfaceNormal(pWorld.x,pWorld.y)
call normal.scale(-1.)
call pWorld.subtract(o.pos)
set curColl = collision.create(o,0)
call curColl.addCollisionPoint(pWorld,0,normal)
if t<o.firstCollTime then
set o.firstCollTime = t
endif
else
call pWorld.destroy()
endif
set p = p.next
endloop
endfunction
function collisionDetection_ObjectList takes object o, list l returns nothing
local listnode n2 = l.first
loop
exitwhen n2==0
call findCollisions_ObjectObject(o,n2.content)
set n2 = n2.next
endloop
endfunction
function collisionDetection_Object takes object o returns nothing
local integer gridX1 = R2I((o.pos.x-PHYS_BOUND_MIN_X)/physCellSizeX)
local integer gridY1 = R2I((o.pos.y-PHYS_BOUND_MIN_Y)/physCellSizeY)
local integer gridZ1 = R2I((o.pos.z-PHYS_BOUND_MIN_Z)/physCellSizeZ)
local integer gridX2
local integer gridY2
local integer gridZ2
local integer ix
local integer iy
local integer iz
if o.cellList!=0 then
call o.cellList.searchAndPop(o)
set o.cellList = 0
endif
set gridX1 = gridX1-1
set gridX2 = gridX1+1
set gridY1 = gridY1-1
set gridY2 = gridY1+1
set gridZ1 = gridZ1-1
set gridZ2 = gridZ1+1
if gridX1<0 then
set gridX1 = 0
endif
if gridY1<0 then
set gridY1 = 0
endif
if gridZ1<0 then
set gridZ1 = 0
endif
if gridX2>=PHYS_COLLISION_CELLS_X then
set gridX2 = PHYS_COLLISION_CELLS_X-1
endif
if gridY2>=PHYS_COLLISION_CELLS_Y then
set gridY2 = PHYS_COLLISION_CELLS_Y-1
endif
if gridZ2>=PHYS_COLLISION_CELLS_Z then
set gridZ2 = PHYS_COLLISION_CELLS_Z-1
endif
set ix = gridX1
loop
exitwhen ix>gridX2
set iy = gridY1
loop
exitwhen iy>gridY2
set iz = gridZ1
loop
exitwhen iz>gridZ2
call collisionDetection_ObjectList(o,physCellList[ix*PHYS_COLLISION_CELLS_Y*PHYS_COLLISION_CELLS_Z+iy*PHYS_COLLISION_CELLS_Z+iz])
set iz = iz + 1
endloop
set iy = iy + 1
endloop
set ix = ix + 1
endloop
call findCollisions_ObjectTerrain(o)
endfunction
function collisionDetection_Particle takes particle p returns nothing
local integer gridX1 = R2I((p.pos.x-PHYS_BOUND_MIN_X)/physCellSizeX)
local integer gridY1 = R2I((p.pos.y-PHYS_BOUND_MIN_Y)/physCellSizeY)
local integer gridZ1 = R2I((p.pos.z-PHYS_BOUND_MIN_Z)/physCellSizeZ)
local integer gridX2 = R2I((p.pos.x+p.vel.x*PHYS_TIME_STEP-PHYS_BOUND_MIN_X)/physCellSizeX)
local integer gridY2 = R2I((p.pos.y+p.vel.y*PHYS_TIME_STEP-PHYS_BOUND_MIN_Y)/physCellSizeY)
local integer gridZ2 = R2I((p.pos.z+p.vel.z*PHYS_TIME_STEP-PHYS_BOUND_MIN_Z)/physCellSizeZ)
local integer ix
local integer iy
local integer iz
if gridX1<gridX2 then
set gridX1 = gridX1-1
set gridX2 = gridX2+1
else
set gridX1 = gridX2-1
set gridX2 = gridX1+1
endif
if gridY1<gridY2 then
set gridY1 = gridY1-1
set gridY2 = gridY2+1
else
set gridY1 = gridY2-1
set gridY2 = gridY1+1
endif
if gridZ1<gridZ2 then
set gridZ1 = gridZ1-1
set gridZ2 = gridZ2+1
else
set gridZ1 = gridZ2-1
set gridZ2 = gridZ1+1
endif
if gridX1<0 then
set gridX1 = 0
endif
if gridY1<0 then
set gridY1 = 0
endif
if gridZ1<0 then
set gridZ1 = 0
endif
if gridX2>=PHYS_COLLISION_CELLS_X then
set gridX2 = PHYS_COLLISION_CELLS_X-1
endif
if gridY2>=PHYS_COLLISION_CELLS_Y then
set gridY2 = PHYS_COLLISION_CELLS_Y-1
endif
if gridZ2>=PHYS_COLLISION_CELLS_Z then
set gridZ2 = PHYS_COLLISION_CELLS_Z-1
endif
set ix = gridX1
loop
exitwhen ix>gridX2
set iy = gridY1
loop
exitwhen iy>gridY2
set iz = gridZ1
loop
exitwhen iz>gridZ2
call collisionDetection_ParticleList(p,physCellList[ix*PHYS_COLLISION_CELLS_Y*PHYS_COLLISION_CELLS_Z+iy*PHYS_COLLISION_CELLS_Z+iz])
set iz = iz + 1
endloop
set iy = iy + 1
endloop
set ix = ix + 1
endloop
call findCollisions_ParticleTerrain(p)
endfunction
function collisionDetection takes nothing returns nothing
local listnode n1 = physParticleList.first
loop
exitwhen n1==0
//call collisionDetection_Particle(n1.content)
call findCollisions_ParticleTerrain(n1.content)
set n1 = n1.next
endloop
set n1 = physObjectList.first
loop
exitwhen n1==0
call collisionDetection_Object(n1.content)
set n1 = n1.next
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physCollisionResponse uses physObjects, physParticles, rotations, quaternions, matrices, vectors
globals
list collisionList
endglobals
struct collisionpoint
vector rel1
vector rel2
vector normal
vector angVelChange1
vector angVelChange2
vector angMomChange1
vector angMomChange2
real denominator
collisionpoint next
static method create takes vector rel1, vector rel2, vector normal returns collisionpoint
// All Coordinates in World-Coordinates
local collisionpoint p = collisionpoint.allocate()
set p.rel1 = rel1
set p.rel2 = rel2
set p.normal = normal
set p.next = 0
set p.angMomChange1 = 0
set p.angVelChange1 = 0
set p.angMomChange2 = 0
set p.angVelChange2 = 0
return p
endmethod
method onDestroy takes nothing returns nothing
if .rel1!=0 then
call .rel1.destroy()
endif
if .rel2!=0 then
call .rel2.destroy()
endif
if .angMomChange1!=0 then
call .angMomChange1.destroy()
call .angVelChange1.destroy()
endif
if .angMomChange2!=0 then
call .angMomChange2.destroy()
call .angVelChange2.destroy()
endif
call .normal.destroy()
endmethod
endstruct
struct collision
real e
particle p1 // Either particle or object
object o1 // Only one variable written
object o2
collisionpoint cp
static method create takes object o1, object o2 returns collision
local collision coll = collision.allocate()
set coll.p1 = 0
set coll.o1 = o1
set coll.o2 = o2
set coll.e = 0.
set coll.cp = 0
call collisionList.insertBehind(coll)
return coll
endmethod
static method pcreate takes particle p1, object o2 returns collision
local collision coll = collision.allocate()
set coll.p1 = p1
set coll.o1 = 0
set coll.o2 = o2
set coll.e = 1.
set coll.cp = 0
call collisionList.insertBehind(coll)
return coll
endmethod
method addCollisionPoint takes vector rel1, vector rel2, vector normal returns collisionpoint
local collisionpoint p = collisionpoint.create(rel1,rel2,normal)
if .cp==0 then
set .cp = p
else
set p.next = .cp
set .cp = p
endif
return p
endmethod
method prepare takes nothing returns nothing
local collisionpoint p = .cp
loop
exitwhen p==0
set p.denominator = 0.
if .o1!=0 then
set p.angMomChange1 = vector.createProduct(p.rel1,p.normal)
set p.angVelChange1 = p.angMomChange1.copy()
call p.angVelChange1.transformByMatrix(.o1.inertiaWorldInv)
set p.denominator = p.denominator + 1./.o1.c.mass + scalarProduct(p.angMomChange1,p.angVelChange1)
elseif .p1!=0 then
set p.denominator = p.denominator + 1./.p1.c.mass
endif
if .o2!=0 then
set p.angMomChange2 = vector.createProduct(p.rel2,p.normal)
set p.angVelChange2 = p.angMomChange2.copy()
call p.angVelChange2.transformByMatrix(.o2.inertiaWorldInv)
set p.denominator = p.denominator + 1./.o2.c.mass + scalarProduct(p.angMomChange2,p.angVelChange2)
endif
set p = p.next
endloop
endmethod
method respond takes boolean elastic returns nothing
local vector vdiff = vector.create(0,0,0)
local real Jmod
local collisionpoint p = .cp
local real hitSpeed
local real slideSpeed
local real elasticityFactor = 0.
if elastic then
set elasticityFactor = 1.
endif
loop
exitwhen p==0
call vdiff.setXYZ(0,0,0)
if .o1!=0 then
call vdiff.add(.o1.vel)
call vdiff.addProduct(.o1.angVel,p.rel1)
elseif .p1!=0 then
call vdiff.add(.p1.vel)
endif
if .o2!=0 then
call vdiff.subtract(.o2.vel)
call vdiff.addProduct(p.rel2,.o2.angVel)
endif
// Calculate perpendicular component
set hitSpeed = scalarProduct(vdiff,p.normal)
set Jmod = (.e*elasticityFactor+1.)*hitSpeed/p.denominator
if Jmod>0 then
// Calculate slide vector
call vdiff.subtractScaled(p.normal,hitSpeed)
set slideSpeed = vdiff.length()+.001
call vdiff.scale(-Jmod/slideSpeed)
if .o1!=0 then
call .o1.vel.addScaled(p.normal,-Jmod/.o1.c.mass)
call .o1.angVel.addScaled(p.angVelChange1,-Jmod)
call .o1.addImpulse(p.rel1,vdiff)
elseif .p1!=0 then
call .p1.vel.addScaled(p.normal,-Jmod/.p1.c.mass)
call .p1.vel.add(vdiff)
endif
call vdiff.scale(-1)
if .o2!=0 then
call .o2.vel.addScaled(p.normal,Jmod/.o2.c.mass)
call .o2.angVel.addScaled(p.angVelChange2,Jmod)
call .o2.addImpulse(p.rel1,vdiff)
endif
endif
set p = p.next
endloop
call vdiff.destroy()
endmethod
method onDestroy takes nothing returns nothing
local collisionpoint p = .cp
local collisionpoint pdest
loop
exitwhen p==0
set pdest = p
set p = p.next
call pdest.destroy()
endloop
endmethod
endstruct
function collisionResponsePrepare takes nothing returns nothing
local collision coll
call collisionList.toFirst()
loop
exitwhen collisionList.outOfList()
set coll = collisionList.getContent()
call coll.prepare()
call collisionList.toNext()
endloop
endfunction
function collisionResponse takes integer enumerations, boolean elastic returns nothing
local collision coll
local integer i = 1
loop
exitwhen i > enumerations
call collisionList.toFirst()
loop
exitwhen collisionList.outOfList()
set coll = collisionList.getContent()
call coll.respond(elastic)
call collisionList.toNext()
endloop
set i = i + 1
endloop
endfunction
function collisionResponseDestroy takes nothing returns nothing
local collision coll
call collisionList.toFirst()
loop
exitwhen collisionList.outOfList()
set coll = collisionList.getContent()
call coll.destroy()
call collisionList.pop()
endloop
endfunction
endlibrary
//TESH.scrollpos=221
//TESH.alwaysfold=0
library physMain initializer physInit uses physCollisionDetection, lists, rotations
globals
list physObjectList
list physParticleList
real physCellSizeX
real physCellSizeY
real physCellSizeZ
location physTempLoc
list array physCellList
endglobals
function getCellList takes vector pos returns list
local real x = pos.x-PHYS_BOUND_MIN_X
local real y = pos.y-PHYS_BOUND_MIN_Y
local real z = pos.z-PHYS_BOUND_MIN_Z
local integer gridX = R2I(x/physCellSizeX)
local integer gridY = R2I(y/physCellSizeY)
local integer gridZ = R2I(z/physCellSizeZ)
if gridX<0 then
set gridX=0
elseif gridX>=PHYS_COLLISION_CELLS_X then
set gridX=PHYS_COLLISION_CELLS_X-1
endif
if gridY<0 then
set gridY=0
elseif gridY>=PHYS_COLLISION_CELLS_Y then
set gridY=PHYS_COLLISION_CELLS_Y-1
endif
if gridZ<0 then
set gridZ=0
elseif gridZ>=PHYS_COLLISION_CELLS_Z then
set gridZ=PHYS_COLLISION_CELLS_Z-1
endif
return physCellList[gridX*PHYS_COLLISION_CELLS_Y*PHYS_COLLISION_CELLS_Z+gridY*PHYS_COLLISION_CELLS_Z+gridZ]
endfunction
function physLoop takes nothing returns nothing
local object o
local particle p
local quaternion add
local vector frictvec
local vector accelvec
local vector angMom = vector.create(0,0,0)
local vector relPos
local vector angVelRel
local real velIntoFrict
local real r
local real rotAimAroundX
local real rotAimAroundY
local real rotAimAroundZ
local integer pid
local collision coll
// Calculate forces and predicted positions/velocities
call physObjectList.toFirst()
loop
exitwhen physObjectList.outOfList()
set o = physObjectList.getContent()
set pid = GetPlayerId(GetOwningPlayer(o.u))
// Forces
set o.accel.z = o.accel.z-PHYS_GRAVITY
set angVelRel = o.angVel.copy()
call angVelRel.rotateByQuaternionInv(o.orient)
if o.c==F22 then
// Front Wing
set frictvec = vector.create(0,0,1)
set relPos = vector.create(14*o.c.modelScale,0,0)
call o.addWing(relPos,frictvec,.02)
// Main Wings
if arrowRightPressed(pid) then
call frictvec.rotateAroundYAxis(-15*bj_DEGTORAD)
endif
if arrowLeftPressed(pid) then
call frictvec.rotateAroundYAxis(15*bj_DEGTORAD)
endif
call relPos.setXYZ(-16*o.c.modelScale,-22*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.02)
set frictvec.z=-frictvec.z
call relPos.setXYZ(-16*o.c.modelScale,22*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.02)
// Height Rudders
call frictvec.setXYZ(0,0,1)
if arrowUpPressed(pid) then
call frictvec.rotateAroundYAxis(30*bj_DEGTORAD)
endif
if arrowDownPressed(pid) then
call frictvec.rotateAroundYAxis(-30*bj_DEGTORAD)
endif
call relPos.setXYZ(-39*o.c.modelScale,-14*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.006)
call relPos.setXYZ(-39*o.c.modelScale,14*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.006)
// Side Rudders
call frictvec.setXYZ(0,1,0)
call relPos.setXYZ(-26*o.c.modelScale,11*o.c.modelScale,7*o.c.modelScale)
call o.addWing(relPos,frictvec,.008)
call relPos.setXYZ(-26*o.c.modelScale,-11*o.c.modelScale,7*o.c.modelScale)
call o.addWing(relPos,frictvec,.008)
// Frontal Friction
call frictvec.setXYZ(1,0,0)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.001)
call relPos.destroy()
call frictvec.destroy()
elseif o.c==ME109 then
// Front Wing
set frictvec = vector.create(0,0,1)
set relPos = vector.create(0,0,0)
call o.addWing(relPos,frictvec,.005)
// Main Wings
if arrowRightPressed(pid) then
call frictvec.rotateAroundYAxis(-15*bj_DEGTORAD)
endif
if arrowLeftPressed(pid) then
call frictvec.rotateAroundYAxis(15*bj_DEGTORAD)
endif
call relPos.setXYZ(6*o.c.modelScale,-62*o.c.modelScale,-6*o.c.modelScale)
call o.addWing(relPos,frictvec,.005)
set frictvec.z=-frictvec.z
call relPos.setXYZ(6*o.c.modelScale,62*o.c.modelScale,-6*o.c.modelScale)
call o.addWing(relPos,frictvec,.005)
// Height Rudders
call frictvec.setXYZ(0,0,1)
if arrowUpPressed(pid) then
call frictvec.rotateAroundYAxis(30*bj_DEGTORAD)
endif
if arrowDownPressed(pid) then
call frictvec.rotateAroundYAxis(-30*bj_DEGTORAD)
endif
call relPos.setXYZ(-104*o.c.modelScale,-20*o.c.modelScale,20*o.c.modelScale)
call o.addWing(relPos,frictvec,.002)
call relPos.setXYZ(-104*o.c.modelScale,20*o.c.modelScale,20*o.c.modelScale)
call o.addWing(relPos,frictvec,.002)
// Side Rudders
call frictvec.setXYZ(0,1,0)
call relPos.setXYZ(-104*o.c.modelScale,0,20*o.c.modelScale)
call o.addWing(relPos,frictvec,.002)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.006)
// Frontal Friction
call frictvec.setXYZ(1,0,0)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.0005)
call relPos.destroy()
call frictvec.destroy()
elseif o.c==BOMBER then
// Front Wing
set frictvec = vector.create(0,0,1)
set relPos = vector.create(60,0,0)
call o.addWing(relPos,frictvec,.01)
//set relPos = vector.create(-60,0,0)
//call o.addWing(relPos,frictvec,.05)
// Main Wings
call frictvec.setXYZ(0,0,1)
call frictvec.rotateAroundYAxis(15*bj_DEGTORAD)
if arrowRightPressed(pid) then
call frictvec.rotateAroundYAxis(-5*bj_DEGTORAD)
endif
if arrowLeftPressed(pid) then
call frictvec.rotateAroundYAxis(5*bj_DEGTORAD)
endif
call relPos.setXYZ(0,-51*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.03)
call frictvec.setXYZ(0,0,1)
call frictvec.rotateAroundYAxis(15*bj_DEGTORAD)
if arrowRightPressed(pid) then
call frictvec.rotateAroundYAxis(5*bj_DEGTORAD)
endif
if arrowLeftPressed(pid) then
call frictvec.rotateAroundYAxis(-5*bj_DEGTORAD)
endif
call relPos.setXYZ(0,51*o.c.modelScale,0)
call o.addWing(relPos,frictvec,.03)
call frictvec.setXYZ(0,0,1)
// Height Rudders
if arrowUpPressed(pid) then
call frictvec.rotateAroundYAxis(15*bj_DEGTORAD)
endif
if arrowDownPressed(pid) then
call frictvec.rotateAroundYAxis(-15*bj_DEGTORAD)
endif
call relPos.setXYZ(-72*o.c.modelScale,-23*o.c.modelScale,10*o.c.modelScale)
call o.addWing(relPos,frictvec,.005)
call relPos.setXYZ(-72*o.c.modelScale,23*o.c.modelScale,10*o.c.modelScale)
call o.addWing(relPos,frictvec,.005)
// Side Rudders
call frictvec.setXYZ(0,1,0)
call relPos.setXYZ(-74*o.c.modelScale,0,28*o.c.modelScale)
call o.addWing(relPos,frictvec,.01)
call relPos.setXYZ(60,0,0)
call o.addWing(relPos,frictvec,.01)
call relPos.setXYZ(-60,0,0)
call o.addWing(relPos,frictvec,.01)
// Frontal Friction
call frictvec.setXYZ(1,0,0)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.005)
call relPos.destroy()
call frictvec.destroy()
else
// Front Wing
set frictvec = vector.create(0,0,1)
set relPos = vector.create(0,0,0)
call o.addWing(relPos,frictvec,.005)
// Main Wings
call relPos.setXYZ(-11*o.c.modelScale,-22*o.c.modelScale,-1.7*o.c.modelScale)
call o.addWing(relPos,frictvec,.001)
set frictvec.z=-frictvec.z
call relPos.setXYZ(-11*o.c.modelScale,22*o.c.modelScale,-1.7*o.c.modelScale)
call o.addWing(relPos,frictvec,.001)
// Height Rudders
call relPos.setXYZ(-135*o.c.modelScale,-17*o.c.modelScale,-1.7*o.c.modelScale)
call o.addWing(relPos,frictvec,.001)
set frictvec.z=-frictvec.z
call relPos.setXYZ(-135*o.c.modelScale,17*o.c.modelScale,-1.7*o.c.modelScale)
call o.addWing(relPos,frictvec,.001)
// Side Rudders
call frictvec.setXYZ(0,1,0)
call relPos.setXYZ(-195*o.c.modelScale,22*o.c.modelScale,19*o.c.modelScale)
call o.addWing(relPos,frictvec,.002)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.006)
// Frontal Friction
call frictvec.setXYZ(1,0,0)
call relPos.setXYZ(0,0,0)
call o.addWing(relPos,frictvec,.001)
call relPos.destroy()
call frictvec.destroy()
endif
set relPos = vector.create(0,0,0)
if o.c==COBRA then
set accelvec = vector.create(0,0,1400+o.ctrl.enginePower)
call relPos.setXYZ(0,0,25)
if arrowRightPressed(pid) then
call accelvec.rotateAroundXAxis(20*bj_DEGTORAD)
endif
if arrowLeftPressed(pid) then
call accelvec.rotateAroundXAxis(-20*bj_DEGTORAD)
endif
if arrowUpPressed(pid) then
call accelvec.rotateAroundYAxis(-20*bj_DEGTORAD)
endif
if arrowDownPressed(pid) then
call accelvec.rotateAroundYAxis(20*bj_DEGTORAD)
endif
elseif o.c==ME109 then
set accelvec = vector.create(100+o.ctrl.enginePower,0,0)
elseif o.c==BOMBER then
set accelvec = vector.create(2200+o.ctrl.enginePower,0,0)
else
call relPos.setXYZ(-33*o.c.modelScale,0,-2*o.c.modelScale)
set accelvec = vector.create(2200+o.ctrl.enginePower,0,0)
if arrowUpPressed(pid) then
call accelvec.rotateAroundYAxis(-20*bj_DEGTORAD)
endif
if arrowDownPressed(pid) then
call accelvec.rotateAroundYAxis(20*bj_DEGTORAD)
endif
endif
call accelvec.rotateByQuaternion(o.orient)
call relPos.rotateByQuaternion(o.orient)
call o.addForce(relPos,accelvec)
call relPos.destroy()
call accelvec.destroy()
if o.c==COBRA then
set accelvec = vector.create(0,0,0)
call accelvec.addXYZ(0,0,o.ctrl.turnPower)
call accelvec.rotateByQuaternion(o.orient)
call o.angAccel.add(accelvec)
call accelvec.destroy()
endif
// Temp
call o.velTmp.setVec(o.vel)
call o.velTmp.addScaled(o.accel,PHYS_TIME_STEP)
call o.angVelTmp.setVec(o.angVel)
call o.angVelTmp.addScaled(o.angAccel,PHYS_TIME_STEP)
call o.posTmp.setVec(o.pos)
call o.posTmp.addScaled(o.velTmp,PHYS_TIME_STEP)
call o.orientTmp.setQuat(o.orient)
call rotateQuaternionByVectorScaled(o.orientTmp,o.angVelTmp,PHYS_TIME_STEP)
set o.firstCollTime = 1000.
call angVelRel.destroy()
call physObjectList.toNext()
endloop
call collisionDetection() // Also resets cell lists
call collisionResponsePrepare()
call collisionResponse(2,true)
// Add acceleration to speed, reset temporary acceleration variables
call physObjectList.toFirst()
loop
exitwhen physObjectList.outOfList()
set o = physObjectList.getContent()
call o.vel.addScaled(o.accel,PHYS_TIME_STEP)
call o.angVel.addScaled(o.angAccel,PHYS_TIME_STEP)
call o.accel.setXYZ(0,0,0)
call o.angAccel.setXYZ(0,0,0)
call physObjectList.toNext()
endloop
call collisionResponse(3,false)
call collisionResponseDestroy()
// Calculate new positions
call physObjectList.toFirst()
loop
exitwhen physObjectList.outOfList()
set o = physObjectList.getContent()
// Translate
call angMom.setTransformedByMatrix(o.angVel,o.inertiaWorldInv)
if o.firstCollTime<1. and o.firstCollTime>0. then
call o.pos.addScaled(o.velTmp,o.firstCollTime)
else
set o.firstCollTime = 0.
endif
call o.pos.addScaled(o.vel,PHYS_TIME_STEP-o.firstCollTime)
call rotateQuaternionByVectorScaled(o.orient,o.angVel,PHYS_TIME_STEP-o.firstCollTime)
call o.orient.normalise()
call o.inertiaWorld.destroy()
call o.inertiaWorldInv.destroy()
set o.inertiaWorld = o.c.inertia.copy()
call rotateMatrixByQuaternion(o.inertiaWorld,o.orient)
set o.inertiaWorldInv = o.inertiaWorld.copyInverted()
call o.angVel.setTransformedByMatrix(angMom,o.inertiaWorld)
if o.pos.x>PHYS_BOUND_MAX_X then
set o.pos.x = PHYS_BOUND_MIN_X+1.
endif
if o.pos.x<PHYS_BOUND_MIN_X then
set o.pos.x = PHYS_BOUND_MAX_X-1.
endif
if o.pos.y>PHYS_BOUND_MAX_Y then
set o.pos.y = PHYS_BOUND_MIN_Y+1.
endif
if o.pos.y<PHYS_BOUND_MIN_Y then
set o.pos.y = PHYS_BOUND_MAX_Y-1.
endif
if o.pos.z>PHYS_BOUND_MAX_Z then
set o.pos.z = PHYS_BOUND_MAX_Z
endif
set o.cellList = getCellList(o.pos)
call o.cellList.insertBehind(o)
call o.updateAnimation()
// Fire
if o.ctrl.weaponShots2>0 then
set o.ctrl.weaponShots2 = o.ctrl.weaponShots2 - 1
set p = particle.create(Player(0),BULLET,o.pos.x,o.pos.y,o.pos.z,o.vel.x,o.vel.y,o.vel.z)
set p.sourceObj = o
set accelvec = vector.create(0,0,0)
call accelvec.rotateByQuaternion(o.orient)
call p.vel.add(accelvec)
call accelvec.destroy()
endif
call physObjectList.toNext()
endloop
call angMom.destroy()
call physParticleList.toFirst()
loop
exitwhen physParticleList.outOfList()
set p = physParticleList.getContent()
set p.vel.z = p.vel.z - PHYS_GRAVITY*PHYS_TIME_STEP
call p.pos.addScaled(p.vel,PHYS_TIME_STEP)
set p.age = p.age + PHYS_TIME_STEP
if p.targetObj!=0 then
set relPos = vector.createDifference(p.targetObj.pos,p.pos)
call relPos.normalise()
call p.vel.addScaled(relPos,1500*PHYS_TIME_STEP)
call relPos.destroy()
endif
if p.pos.x>PHYS_BOUND_MAX_X then
set p.pos.x = PHYS_BOUND_MIN_X
endif
if p.pos.x<PHYS_BOUND_MIN_X then
set p.pos.x = PHYS_BOUND_MAX_X
endif
if p.pos.y>PHYS_BOUND_MAX_Y then
set p.pos.y = PHYS_BOUND_MIN_Y
endif
if p.pos.y<PHYS_BOUND_MIN_Y then
set p.pos.y = PHYS_BOUND_MAX_Y
endif
if p.age>20 then
call p.destroy()
call physParticleList.pop()
else
call p.updateAnimation()
call physParticleList.toNext()
endif
endloop
call SelectUnit(playerController[GetPlayerId(GetLocalPlayer())],true)
endfunction
function physInit takes nothing returns nothing
local integer i = 0
local integer imax = PHYS_COLLISION_CELLS_Y*PHYS_COLLISION_CELLS_Y*PHYS_COLLISION_CELLS_Z
set physObjectList = list.create()
set physParticleList = list.create()
set physTempLoc = Location(0,0)
set collisionList = list.create()
loop
exitwhen i>=imax
set physCellList[i] = list.create()
set i = i + 1
endloop
set physCellSizeX = (PHYS_BOUND_MAX_X-PHYS_BOUND_MIN_X)/PHYS_COLLISION_CELLS_X
set physCellSizeY = (PHYS_BOUND_MAX_Y-PHYS_BOUND_MIN_Y)/PHYS_COLLISION_CELLS_Y
set physCellSizeZ = (PHYS_BOUND_MAX_Z-PHYS_BOUND_MIN_Z)/PHYS_COLLISION_CELLS_Z
call TimerStart(CreateTimer(),PHYS_TIME_STEP,true,function physLoop )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library physProperties
globals
constant real PHYS_TIME_STEP = .04
constant real PHYS_GRAVITY = 50.
constant integer PHYS_COLLISION_CELLS_X = 32
constant integer PHYS_COLLISION_CELLS_Y = 32
constant integer PHYS_COLLISION_CELLS_Z = 1
constant real PHYS_BOUND_MIN_X = -10000.
constant real PHYS_BOUND_MAX_X = 10000.
constant real PHYS_BOUND_MIN_Y = -10000.
constant real PHYS_BOUND_MAX_Y = 10000.
constant real PHYS_BOUND_MIN_Z = -100.
constant real PHYS_BOUND_MAX_Z = 4000.
constant boolean PHYS_BOUND_REPEAT = true
endglobals
endlibrary
//TESH.scrollpos=11
//TESH.alwaysfold=0
library physControllers initializer physControllers_Init
globals
unit array playerController
object array playerControlledObj
endglobals
function ControlReaction takes nothing returns nothing
local integer abil = GetSpellAbilityId()
local object obj = playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
if abil=='A000' then
// Accelerate Main Engine
set obj.ctrl.enginePower = obj.ctrl.enginePower + 400
elseif abil=='A001' then
// Decelerate Main Engine
set obj.ctrl.enginePower = obj.ctrl.enginePower - 400
elseif abil=='A002' then
// Turn Right
set obj.ctrl.turnPower = obj.ctrl.turnPower + .5
elseif abil=='A003' then
// Turn Left
set obj.ctrl.turnPower = obj.ctrl.turnPower - .5
elseif abil=='A004' then
set obj.ctrl.weaponShots1 = 0
set obj.ctrl.weaponShots2 = 5
endif
endfunction
function physControllers_Init takes nothing returns nothing
local integer i = 0
local trigger t = CreateTrigger()
loop
exitwhen i>11
set playerController[i] = CreateUnit(Player(i),'h002',mapMaxX,mapMaxY,0)
set i = i + 1
endloop
call SelectUnit(playerController[GetPlayerId(GetLocalPlayer())],true)
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( t, function ControlReaction )
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_ESC_Actions takes nothing returns nothing
local object o = playerControlledObj[GetPlayerId(GetTriggerPlayer())]
if o!=0 then
call DestroyEffect(o.e)
call RemoveUnit(o.u)
if o.c==F22 then
set o.c=ME109
elseif o.c==ME109 then
set o.c=BOMBER
elseif o.c==BOMBER then
set o.c=COBRA
else
set o.c=F22
endif
set o.u = CreateUnit(GetTriggerPlayer(),o.c.unitType,o.pos.x,o.pos.y,0.)
set o.e = AddSpecialEffectTarget(o.c.modelName,o.u,"origin")
call SetUnitAnimation(o.u,"stand")
call SetUnitPathing(o.u,false)
call SetUnitTimeScale(o.u,1000.)
call SetUnitScale(o.u,o.c.modelScale,o.c.modelScale,o.c.modelScale)
call UnitAddAbility(o.u,'Amrf')
call o.updateAnimation()
call UnitRemoveAbility(o.u,'Amrf')
call o.inertiaWorld.destroy()
call o.inertiaWorldInv.destroy()
set o.inertiaWorld = o.c.inertia.copy()
call rotateMatrixByQuaternion(o.inertiaWorld,o.orient)
set o.inertiaWorldInv = o.inertiaWorld.copyInverted()
endif
endfunction
//===========================================================================
function InitTrig_ESC takes nothing returns nothing
local integer i = 0
set gg_trg_ESC = CreateTrigger( )
loop
exitwhen i>11
call TriggerRegisterPlayerEvent(gg_trg_ESC, Player(i), EVENT_PLAYER_END_CINEMATIC)
set i = i + 1
endloop
call TriggerAddAction( gg_trg_ESC, function Trig_ESC_Actions )
endfunction
//TESH.scrollpos=35
//TESH.alwaysfold=0
globals
class F22
class ME109
class BOMBER
class COBRA
pclass BULLET
pclass MISSILE
endglobals
function Trig_Nahkampf_Initialisierung_Actions takes nothing returns nothing
local integer i = 0
set F22 = class.create()
set F22.mass = 20.
set F22.inertia = matrix.create(20000,0,0, 0,40000,0, 0,0,40000)
set F22.inertiaInv = F22.inertia.copyInverted()
set F22.modelName = "war3mapImported\\FA-22 Raptor.mdx"
set F22.unitType = 'h000'
call F22.addCollisionPoint(-18,33,0)
call F22.addCollisionPoint(-18,-33,0)
call F22.addCollisionPoint(-43,21,0)
call F22.addCollisionPoint(-43,-21,0)
call F22.addCollisionPoint(50,0,-1)
call F22.addCollisionPoint(-27,14,14)
call F22.addCollisionPoint(-27,-14,14)
call F22.addCollisionPoint(-27,6.5,-5)
call F22.addCollisionPoint(-27,-6.5,-5)
call F22.addCollisionPoint(18,9,-5)
call F22.addCollisionPoint(18,-9,-5)
call F22.addCollisionPoint(27,0,6.3)
set F22.collshape = shape.create()
call F22.collshape.addNewSphere(vector.create(0,0,0),30)
set BOMBER = class.create()
set BOMBER.mass = 50.
set BOMBER.inertia = matrix.create(160000,0,0, 0,320000,0, 0,0,320000)
set BOMBER.inertiaInv = BOMBER.inertia.copyInverted()
set BOMBER.modelName = "war3mapImported\\BadgeBomber.mdx"
set BOMBER.unitType = 'h000'
call BOMBER.addCollisionPoint(80,0,0)
call BOMBER.addCollisionPoint(-81,0,11)
call BOMBER.addCollisionPoint(-84,0,38)
call BOMBER.addCollisionPoint(-77,-37,11)
call BOMBER.addCollisionPoint(-77,37,11)
call BOMBER.addCollisionPoint(-13,-90,-1)
call BOMBER.addCollisionPoint(-13,90,-1)
call BOMBER.addCollisionPoint(64,-6.5,-6.5)
call BOMBER.addCollisionPoint(64,6.5,-6.5)
call BOMBER.addCollisionPoint(-6,-6.5,-6.5)
call BOMBER.addCollisionPoint(-6,6.5,-6.5)
call BOMBER.addCollisionPoint(-60,0,0)
call BOMBER.addCollisionPoint(55,0,13)
set BOMBER.collshape = shape.create()
call BOMBER.collshape.addNewSphere(vector.create(0,0,0),300)
call BOMBER.scaleVisual(1.2)
set ME109 = class.create()
set ME109.mass = 2.
set ME109.inertia = matrix.create(500,0,0, 0,1000,0, 0,0,1000)
set ME109.inertiaInv = ME109.inertia.copyInverted()
set ME109.modelName = "war3mapImported\\ME109.mdx"
set ME109.unitType = 'h000'
call ME109.addCollisionPoint(-17,125,-2)
call ME109.addCollisionPoint(-17,-125,-2)
call ME109.addCollisionPoint(35,54,-6)
call ME109.addCollisionPoint(35,-54,-6)
call ME109.addCollisionPoint(79,0,0)
call ME109.addCollisionPoint(33,-8,-14)
call ME109.addCollisionPoint(33,8,-14)
call ME109.addCollisionPoint(-23,-8,-14)
call ME109.addCollisionPoint(-23,8,-14)
call ME109.addCollisionPoint(-122,0,10)
call ME109.addCollisionPoint(-103,0,37)
call ME109.addCollisionPoint(-103,-38,20)
call ME109.addCollisionPoint(-103,38,20)
call ME109.addCollisionPoint(13,0,19)
set ME109.collshape = shape.create()
call ME109.collshape.addNewSphere(vector.create(0,0,0),100)
call ME109.scaleVisual(5*9.87/250)
//set ME109 = BOMBER
set COBRA = class.create()
set COBRA.mass = 20.
set COBRA.inertia = matrix.create(10000,0,0, 0,20000,0, 0,0,20000)
set COBRA.inertiaInv = COBRA.inertia.copyInverted()
set COBRA.modelName = "war3mapImported\\Cobra.mdx"
set COBRA.unitType = 'h000'
call COBRA.addCollisionPoint(-200,0,-7)
call COBRA.addCollisionPoint(-207,0,43)
call COBRA.addCollisionPoint(-75,-9,-21)
call COBRA.addCollisionPoint(-75,9,-21)
call COBRA.addCollisionPoint(57,-9,-21)
call COBRA.addCollisionPoint(57,9,-21)
call COBRA.addCollisionPoint(84,-4,4)
call COBRA.addCollisionPoint(84,4,4)
call COBRA.addCollisionPoint(-4,-4,31)
call COBRA.addCollisionPoint(-4,4,31)
call COBRA.addCollisionPoint(38,-22,-33)
call COBRA.addCollisionPoint(38,22,-33)
call COBRA.addCollisionPoint(-45,-22,-33)
call COBRA.addCollisionPoint(-45,22,-33)
set COBRA.collshape = shape.create()
call COBRA.collshape.addNewSphere(vector.create(0,0,0),100)
call COBRA.scaleVisual(5*14./284.)
set BULLET = pclass.create()
set BULLET.modelName = "war3mapImported\\Bullet.mdx"
set BULLET.mass = 0.01
set BULLET.scale = 0.1
set MISSILE = pclass.create()
set MISSILE.modelName = "Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl"
set MISSILE.mass = 0.01
set MISSILE.scale = 0.1
call SetSkyModel( "Environment\\Sky\\FoggedSky\\FoggedSky.mdl" )
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, 12)
call SetTimeOfDayScale( 0 )
call EnableDragSelect(false, false)
call EnablePreSelect(false, false)
call EnableSelect(false, false)
call EnableOcclusion(false)
loop
exitwhen i>11
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
set playerControlledObj[i] = object.create(Player(i),F22,0,i*512,512,0,0,0)
call CreateFogModifierRectBJ( true, Player(i), FOG_OF_WAR_VISIBLE, GetWorldBounds() )
endif
set i = i + 1
endloop
call SetCloudCount(20)
endfunction
//===========================================================================
function InitTrig_Nahkampf_Initialisierung takes nothing returns nothing
set gg_trg_Nahkampf_Initialisierung = CreateTrigger( )
call TriggerAddAction( gg_trg_Nahkampf_Initialisierung, function Trig_Nahkampf_Initialisierung_Actions )
endfunction