this is not a part of the official release, but here goes.
(nick it and you will pay a great consequence.(I'll send the boys round :) )
Global MainEng:TEngine
Global camList:TList
Include "tactics.bmx"
Include "col.bmx"
Include "rscript.bmx"
Global BallCam:TCamera
Global RViewMode
Global ActiveBot:Bot
Global TrackBot:Bot
Global TotFps,AcFps,Frames,LastM
Const FPS=30
Global Display:TBatch = New TBatch 'Spawn batch visualizer.
Local Why:String
Global period=1000/FPS
Global time=MilliSecs()-period
Global Arena:Level = Null
Team.Init()
Global MainBall:Ball = New Ball
bot.bots = CreateList()
bot.botlist = CreateList()
bot.activeBots = CreateList()
inf.Init()
Global Visual:TBatch = New TBatch
Team.Visuals = Visual
registerFuncs(rifas)
Global Sun:TLight
Global TopLight:TLight
'Basic Shadow Information.
Global bShadow:TEntity[255]
Global BallMark:TEntity
Global ActiveMark:TEntity
rifas.addfunc(setuprifa,"InitRifa")
Function SetUpRifa:Int(ls:Byte Ptr)
bShadow[0] = TFileIo.LoadEntity("media\roboshadow.b3d")
If bShadow[0] = Null Throw "Roboshadow.b3d not found."
bShadow[0].UsePipeline( New TVertexArray )
TopLight:TLight = New TLight
TopLight.Y=300
TopLight.Diffuse(50,255,255,1)
TopLight.Sync()
SetUpSun()
ActiveMark:TEntity = TFileIO.LoadEntity("Media\RoboBase.b3d")
ActiveMark.UsePipeline(New TVertexArray)
BallMark:TEntity = New TEntity
TEntity.Clone( ActiveMark,BallMark ) 'Return of Clone strikes back.
ballCam = New Tcamera
ballCam.Viewport(20,20,200,200)
End Function
Global oMark:TEntity[50000],oCount
rifas.Load("Script\config.txt")
rifas.Run()
If MainEng = Null Throw "Environment script must create main engine context"
Main_Error.failOn( 505090909)
Function fprint(txt:String)
WriteLine debugStream,txt
End Function
'Main_Error.printFunction( fprint )
Global debugStream:TStream = WriteFile( "Debug.Txt" )
Type Level
Field colMap:Tentity
Function Load:Level(File:String)
Out:Level = New Level
fPath:String = ExtractDir( file)
Out.Mesh = TFileIo.LoadEntity( File)
out.colmap =tfileIo.loadentity(fPath+"/"+StripAll(File)+"_col.b3d")
If out.colmap = Null Throw "Col map "+fPath+"! not fond"
out.colmap.updatenormals()
If out.colmap=Null Throw "Collision map not found"
TGame.AddStatic( Out.colmap )
Out.Mesh.UsePipeline( New TVertexArray )
Local nFile:String = fPath+"/"+StripAll(File)+"_ai.b3d"
Out.AiMap = TFileIo.LoadEntity(NFile)
Out.AiMap.UsePipeline( New TVertexArray )
If Out.Mesh = Null Throw "Could not open level file :"+File
If Out.AiMap = Null Throw "Could not open ai map file :"+File
out.nodeMap = out.aimap
Map:TEntity =TEntity( Out.AiMap.GetChild(1))
'Map:TEntity = out.AiMap
If Map = Null
Throw "Ai map does not contain a _ai tagged node. File:"+File
EndIf
Map.UpdateNormals()
Out.AiMap = Map
Map.AddMaterial( New TMaterial )
Map.ScaleMesh( 1,1,-1 )
Tactic.FindNodes( Out.NodeMap )
'Map.UsePipeline( New TVertexArray )
Visual.AddEntity( Out.Mesh )
Visual.AddEntity( ActiveMark )
Visual.AddEntity( BallMark )
Return Out
End Function
'Ai map specific
Field nodeMap:TEntity
'end ai map
Method Render()
If Mesh = Null Throw "mesh not present in level data"
' vCam.RenderEntity( Mesh )
' vcam.renderentity( aimap )
End Method
Field Mesh:TEntity
Field Col:TEntity
Field AiMap:TEntity
End Type
Type Team
Function init()
aTeam = New Team[25]
End Function
Field Tact:Tactic
Function UseTactics(Tea:Team,Id:String)
Tea.Tact = Tactic.GetTactics( Id )
End Function
Function Create:Team(Name:String,Nick:String)
Local Out:Team = New Team
Out.Name = Name
aTeam[teamcount]=out
out.nick = nick
out.TeamID = teamCount
teamcount:+1
out.tact = New Tactic
out.bots =CreateList()
Return out
End Function
Field TeamID:Byte
Method AddBot:Bot(BotType:String,PlayerName:String="",Posi:String="")
Master:Bot = Bot.FindMaster( BotType )
If Master = Null
Bot.LoadBotType( BotType )
Master = Bot.FindMaster( BotType )
If Master = Null Throw "Cannot add bot of non existent bot type "+BotType+" For player "+PlayerName
EndIf
TBot:Bot = Bot.Spawn( Master,Team( Self ),PlayerName )
ListAddLast Bots,tBot
NewId=TeamId+1
Local APos:String = Posi+NewId
Print "Bot team>"+name+" Team Pos Node>"+Apos
tbot.zone = tactic.addPosition( tact,apos )
If tbot.zone = Null
RuntimeError "Position "+Apos+" Not valid"
EndIf
tbot.x=tbot.zone.x
tbot.z=tbot.zone.z
Return tBot
End Method
Method Sync()
For TBot:Bot = EachIn Bots
Visuals.AddEntity( Tbot )
Next
End Method
Global Visuals:TBatch
Function reset()
teamcount=0
End Function
Field Name:String
Field nick:String 'nickname.
Field Played:Int,Won:Int,Drawn:Int,Lost:Int
Field MetalGhosts:Int
Field Bots:TList
Field Money:Int
Global aTeam:Team[]
Global TeamCount
End Type
'eam.Init(
Type Ball
Method New()
Drag= 0.98
Bounce = 0.66
Friction = 0.93
End Method
Method Render()
' vCam.RenderEntity( Mesh)
' Vcam.RenderEntity( BallMark )
End Method
Method Kick(Xf!,Yf!,zF!)
Xi=xi+Xf
yi=yi+yf
zi=zi+zf
End Method
Method Undo()
Mesh.X = OldX
Mesh.Z = OldZ
Mesh.Y = OldY
End Method
Field oldx!,oldy!,oldz!
Method push( fx!,fy!,fz! )
xi = fx
yi =fy
zi= fz
End Method
Method Give( Now:Tentity )
has = Now
End Method
Field Has:TEntity
Method MoldBall( Mold:TEntity, Base:TEntity )
Local xd! = mesh.x-oldx
Local yd! = mesh.y-oldy
Local zd! = mesh.z-oldz
xd=0-xd
yd=0-yd
zd=0-zd
surfI=0
For surf:Tsurface = EachIn base.surface
Local mSurf:Tsurface= tSurface(mold.surface.valueatindex(surfI))
For vertI=0 To surf.verts.length-6 Step 3
x! = surf.verts[verti]
y! = surf.verts[vertI+1]
z! = surf.verts[vertI+2]
xv! = xd-x
yv! = yd-y
zv! = zd-z
msurf.verts[vertI]=x+xv
msurf.verts[vertI+1]=y+yv
msurf.verts[vertI+2]=z+zv '+Sin(y*200)*3
Next
msurf.pipeline.sync()
surfI:+1
Next
eInd=0
For tent:tentity = EachIn mold.pchild
sent:tentity = tentity(base.pchild.valueatindex( eInd ))
moldball( tent,sent)
eind:+1
Next
End Method
Method update()
Local Profile=Profiler.Enter("Update")
'moldBall(Mesh,ballmod )
' oldX=mesh.x
' oldY=mesh.y
' oldZ=mesh.Z
' MoldBall( Mesh,BallMod )
If Yi>-2 Yi:-0.1
Local nx!,ny!,nz!
Nx=Mesh.X+Xi
Ny=Mesh.Y+yi
Nz=Mesh.Z+zi
' Yi:-0.3
Local Width!=350,Depth!=340,Height!=40
If mesh.y<2.1
Xi:*Friction
ZI:*Friction
EndIf
' Yi:-0.2
' If yi>2 yi=2
' If yi<-2 yi=-2
If ny<=2
yI=Abs( yi)*Bounce
If YI<(Weight*8)
Yi=0
Mesh.Y = 2
EndIf
Ny = Mesh.Y
EndIf
' If Ny>50
' Ny = Mesh.Y
' Yi=-Abs(YI)
' EndIf
' If Nx<-Depth
' Xi=Abs(XI)*Bounce
' Nx=Mesh.X
' Else If Nx>Depth
' NX=Mesh.X
' Xi=-Abs(XI)*Bounce
' EndIf
' If Nz<-Width
' Zi=Abs(Zi)*Bounce
' Nz=Mesh.Z
' Else If nz>Width
' Zi=-Abs(zi)*Bounce
' Nz=Mesh.Z
' EndIf
BallYaw! = ATan2( zi*4,xi*4)
If Sqr(zi*zi+xi*xi)>0.1
BallMark.Rotate( 0,BallYaw,0 )
EndIf
BallMark.X = Mesh.X
BallMark.Z = Mesh.Z
Mesh.X = Nx
Mesh.Y = Ny
Mesh.Z = Nz
FlushMem
If has=Null
Else
EndIf
LeaveFunction( Profile )
End Method
Field lx!,lz!
Field Bounce:Double
Field Friction:Double
Field Mesh:TEntity,drag:Double
Field XI:Double,YI:Double,ZI:Double
End Type
Type Bot Extends TEntity
Global IDC:Short
Field Id:Short
Field InfM:Inf
Global BotPath:String
Global BotList:TList
Function register(botType:String)
ListAddLast botList,botType
End Function
Field Zone:Position
Function LoadBotType:Byte( BotType:String )
'For check:String =EachIn botlist
' check= check.tolower()
' If botType = check
Print "Loading Bot Type"+BotTYpe
Local Temp:REngine = New REngine
registerFuncs( temp)
temp.load("Bot/"+botType+"/setup.txt")
Print "About to run bot initilization"
temp.run()
Print "Run ok"
' Print "Load type "+BotType
Return True
' EndIf
'Next
End Function
Function getBot:Bot(num:Int)
Return bot(activebots.valueatindex( num ))
End Function
Method New()
InfM = Inf.Create(0,0,0,-500,0,30,Bot.Idc)
Bot.Idc:+1
Id = bot.idc-1
Active = False
TurnSpeed = 0.1
Brain = IAL.Create( Bot(Self) )
'active = True
BasicShadow = New TEntity
TEntity.Clone( bShadow[0],BasicShadow)
Visual.AddEntity(BasicShadow)
' Display.AddEntity(BasicShadow)
End Method
Function SetName( in:Bot,nName:String )
in.name = nname
End Function
Function getName:String( in:bot )
Return in.name
End Function
Field BasicShadow:TEntity
Method Place( nX!,nY!,nZ!)
x=nx
y=ny
z=nz
End Method
Function FindMaster:Bot( Name:String)
Name = Name.ToLower()
For tBot:Bot = EachIn Bots
Local TName:String = tBot.name.tolower()
If tname.find( name)<>-1 Return tBot
Next
Return Null
End Function
Function Load:Bot(File:String)
Local Out:Bot
Print "Loading base bot "+File
If FileSize(file)<5 RuntimeError file
' Throw "Entity::"+file
Local Tmp:Tentity = TFileIo.LoadEntity( File )
If tmp = Null Throw "Unable to Load Bot:"+File
Out = New Bot
Local Nu:TEntity
Nu = TEntity( out )
Tmp.Parent( TEntity( Out) )
Out.UsePipeline( New TVertexArray )
ListAddLast Bot.Bots,Out
' Visual.AddEntity(Out)
TGame.AddSphere( Out,15,0,20,0)
Return Out
End Function
Function Spawn:Bot( From:Bot,Owner:Team,bName:String)
Local Out:Bot
?debug
If From = Null Throw "Cannot clone nulality."
?
Out = New Bot
Print "Spawning "+From.Name+" Bot"
TEntity.Clone( From,Out )
Out.Name = bName
out.localcache = from.localCache
out.place( Rnd(-50,50),0,Rnd(-50,50))
ListAddLast Bot.ActiveBots,Out
'Display.AddEntity( Out )
Visual.AddEntity( Out )
Return Out
End Function
Function RenderActive()
For Local TmpBot:Bot = EachIn ActiveBots
' Vcam.RenderEntity( TmpBot )
' vCam.RenderEntity( tmpBot.basicshadow )
Next
' '''' Vcam.RenderEntity( ActiveMark )
End Function
Function SpawnBot:Bot( Name:String)
End Function
Method FindNear()
End Method
Field control:Byte
Method Update()
Local Mx:Double,My:Double
InfM.x=x
infm.y=y
infm.z=z
If Active=True
ActiveMark.X = X
ActiveMark.Y = 1
ActiveMark.Z = Z
ActiveMark.Rotate(0,Yaw,0)
'Keyboard
Select control
Case 1
mx=JoyX()
my=JoyY()
Case 0
If KeyDown(KEY_A)
my=-1
EndIf
If KeyDown(KEY_S)
Mx=-1
EndIf
If KeyDown(KEY_D)
My=1
End If
If KeyDown(KEY_W)
mx=1
EndIf
'Joypad
End Select
Else
Brain.Cycle( mx,my )
EndIf
Mx:*0.8
My:*0.8
Local Mag! = Sqr(Mx*mx+My*my)
If mag>0.2
aYaw:Double = ATan2(my*10,mx*10)
If aYaw<0 aYaw:+360
EndIf
Lean! = Sqr( Xi*Xi+Zi*zi) * 40
pback! = -xi*8.6
oback! = zi*8.6
' If oback<-30 oback=-30
'If oback>30 oback=30
' EndIf
'pback:+ joyz()*40
'oback:+ -joyv()*40
If Yaw<aYaw
D1! = aYaw-Yaw
D2! = Yaw+(360-aYaw)
If D2>D1
Rotate(pback,Yaw+(aYaw-Yaw)*TurnSpeed,oback)
Else
Rotate(pBack,Yaw-D2*TurnSpeed,oback)
EndIf
Else
D1! = Yaw-aYaw
D2! = aYaw+(360-Yaw)
If D2>D1
Rotate(pback,Yaw+(aYaw-Yaw)*TurnSpeed,oback)
Else
Rotate(pBack,Yaw+D2*TurnSpeed,oback)
EndIf
EndIf
If Yaw<0 Yaw=360.0+Yaw
If Yaw>360 Yaw:-360
' Move(0,0,Sqr(xi*xi+yi*yi)*0.01)
If Mag>0.05
Xi:+My*0.2
Zi:+Mx*0.2
EndIf
XI:*0.96
Zi:*0.96
If Sqr( xi*xi+zi*zi)>0.05
Z:+Xi
X:+Zi
EndIf
BasicShadow.X = X
BasicShadow.Z = Z
basicshadow.y=2
End Method
Function UpdateAll()
For B:Bot = EachIn ActiveBots
B.Update()
Xd! = B.X - MainBall.Mesh.x
Zd! = B.Z - MainBall.Mesh.Z
'yd! = (B.Y) - MainBall.Mesh.Y
Dis! = Sqr(xd*xd+zd*zd)
If Dis<12
If Sqr( MainBall.Xi*MainBall.XI+MainBall.Zi*MainBall.ZI)<9
B.hasBall = True
EndIf
EndIf
If B.HasBall=True 'And Dis<8.0+DisMod!
Ent:TEntity = Tentity( b)
If KeyDown(KEY_SPACE)
ImpulseMod!=0.2
EndIf
tX! = B.X+B.Xi*4
TZ! = B.z+B.Zi*4
vx! = tx-mainball.mesh.x
vz! = tz-mainball.mesh.z
If Sqr(vx*vx+vz*vz)>2
MainBall.xi:+vx*0.05 '*(0.3+ImpulseMod)
MainBall.zi:+vz*0.05 '*(0.3+ImpulseMod)
Else
EndIf
B.DisMod=4
BallMark.Y =4
If KeyDown( Key_Up) Or JoyDown(1)
If ShotIn=0
shotin=1
MainBall.Xi:+Cos(B.Yaw)*4
MainBall.Yi=Rnd(0,1)
MainBall.Zi:+Sin(B.Yaw)*4
B.HasBall=False
EndIf
Else
ShotIn = 0
EndIf
Else
B.DisMod:*0.94
BallMark.Y=2
EndIf
If B.hasBall=True
If B.DisMod<0.1 B.hasBall = False
EndIf
Next
End Function
Field DisMod!
Field HasBall:Int
Field xI!,zi!,shotIn:Byte
Field aYaw:Double
Field TeamI:Byte
Field Mx:Double,My:Double
Field Face:Double
Field Active:Byte
Field Cpu:Short
Field TurnSpeed:Double
Field Brain:IAL
Field LastTri[1000],LastC 'Memory
Global ActiveBots:TList
Global Bots:TList
End Type
Type Junction
Method New()
Port[0]=-1
End Method
Field X!,Y!,Z!
Field This:Short
Field Port:Int[25],Cons:Int
Field Fear:Byte,Attract:Byte
Field Weight:Float[25]
End Type
Type Path
Method AddWayPoint( Junct:Junction)
Junc[jc] = Junct
Jc:+1
End Method
Method Update()
If goJunc=Null
goJunc = Junc[Jc-1]
EndIf
End Method
Field Owner:Bot
Field Junc:Junction[300],Jc
Field TarJunc:Junction
Field GoJunc:Junction
Field PathFind:Byte
Field GoMode
End Type
Type Inf
Function init()
ignoreId=-1
IList = CreateList()
End Function
Function Create:inf( X!,Y,Z!,BaseEffect!,Mode=0,Radius=20,id=0)
Local out:inf = New inf
out.x=x
out.id=id
out.effect=baseeffect
out.y=y
out.z=z
out.radius=radius
ListAddLast ilist,out
Return out
End Function
Global ignoreId
Function ScoreAt:Double(x!,y!,z!,id=0)
TotScore!=0
For i:Inf = EachIn iList
If ignoreId=i.id Continue
xd!=i.x-x
yd!=i.y-y
zd!=i.z-z
td!= Sqr(xd*xd+yd*yd+zd*zd)/i.Radius
If td<0 td=0
If td>1 td=1
td=1-td
Select i.mode
Case 0
score!=i.Effect*td
Case 1
Throw "Not supported"
End Select
TotScore:+Score
Next
'If totScore<>0
'Print "Tot Score>"+TotScore
'endif
Return TotScore
End Function
Function Reset()
ClearList iList
ignoreId0=-1
End Function
Field id:Short
Field X!,Y!,Z!
Field Mode,Radius!
Field Effect!
Global IList:TList
End Type
Inf.Init()
Type IAL
Function Create:Ial( Own:Bot )
Out:Ial = New Ial
out.owner = own
' ial.setupjstar( out,own )
Return out
End Function
Function SetUpJStar(out:ial,own:bot)
Out.Asurf = Arena.AiMap.GetSurface(1)
Out.Tris = Out.ASurf.Tris
Out.Verts = Out.aSurf.verts
Out.TriC = Out.Asurf.Triangles()
Out.VertC = out.asurf.vertices()
main_Error.invoke "Ai Map Verts>"+Out.vertC+" Tris>"+Out.TriC
' out.junc = New Junction[Out.Verts.length/3]
out.ResetJunctions()
Out.Owner = Own
End Function
Method ResetJunctions()
Vert=0
While Vert<Verts.Length/3
Junc[Vert] = New Junction
Junc[Vert].This = Vert
Junc[Vert].X = Verts[Vert*3]
Junc[Vert].Y = Verts[Vert*3+1]
Junc[Vert].Z = Verts[Vert*3+2]
Local Con = 0
J=0
While J<Tris.Length
If Tris[J] = Vert
Junc[Vert].Port[Con] = Tris[j+1]
Junc[Vert].Port[Con+1] = Tris[J+2]
con:+2
EndIf
If Tris[J+1] = Vert
Junc[Vert].port[Con] = Tris[j]
Junc[Vert].port[con+1] = tris[j+2]
con:+2
EndIf
If Tris[J+2] = Vert
Junc[vert].port[Con] = Tris[j]
Junc[Vert].port[con+1] = Tris[j+1]
con:+2
EndIf
J:+3
Wend
Junc[Vert].Cons = Con
'Print "Cons>"+Junc[vert].cons
Vert:+1
Wend
End Method
Method PlaceNear( X,Y,Z)
TriI = NearestTri(X,Y,Z)
Owner.X = TriX
Owner.Y = TriY
Owner.Z = TriZ
End Method
Method NearTri:Int()
Return NearestTri( owner.x,owner.y,owner.z)
End Method
Field lastJUP
Method UpdateJuncs()
Return
ms=MilliSecs()
If ms-lastJup>5
lastJup=ms
While J<vertC
k=0
junct:junction = junc[j]
cons = junct.cons
While k<cons
junct.weight[k]:*0.93
k:+1
Wend
j:+1
Wend
' Print "Update junctions"
EndIf
End Method
Method NetMove:Double( from:Junction,StopAT:Int=10,LastD!=0,Score!=0,Par:Junction=Null)
bJump!=99999
If stopAt<0 Return Score
Local bJunc:Junction
xd! = from.x-tjunc.x
zd! = from.z-tjunc.z
td! = Sqr(xd*xd+zd*zd)
BigScore!=-9999999
OrigScore=Score
Score!:+LastD-Td+Inf.ScoreAt( from.x,from.y,from.z)
For j=0 To from.cons-1
way:junction = junc[from.port[j]]
' If Way<>From 'Prevent back tracking.
NewScore! =NetMove( Way,StopAt-1,Td,Score,From)-from.weight[j]
'NewScore:-from.weight[j]
If newScore>BigScore
' If newScore>Junc
BigScore=NewScore
bJunc = Way
WayI=J
EndIf
' EndIf
Next
from.weight[wayI]:+bigScore '22
' Marker(bJunc.x,3,bjunc.z)
NetJuncOut = bJunc
Return Score+BigScore
End Method
Field NetJuncOut:Junction
Field TempAng!
Field AngTurns!,Fear!,Attract!
Field MovA!
Field Task,TargetX!,TargetY!,TargetZ!
Const MoveTo =1,SneakTo=2
Field LastAng
Field Been:BSTree
Method Cycle( MoveX:Double Var,MoveY:Double Var)
Select Task
Case IAL.MoveTo
updateJuncs()
' If aJunc =Null
aJunc= JuncNear(owner.x,owner.y,owner.z)
' endif
inf.ignoreId =owner.id
Xd!=ajunc.x-tjunc.x
zd!=ajunc.z-tjunc.z
aDist!=Sqr(xd*xd+zd*zd)
BestScore!=NetMove(aJunc,2,ADist,0,Null)
xd!=owner.x-tJunc.x
zd!=owner.z-tJunc.z
td!=Sqr(Xd*xd+zd*zd)
gJunc:Junction =NetJuncOut
If gJunc = Null
Task = 0
Return
EndIf
If Td<12
' Task=0
Return
'Print "New Junc"
' aJunc = gJunc
EndIf
VertAt = Ajunc.this*3
Marker( Verts[vertat],5+Cos(locA)*3.5,verts[VertAt+2])
' TVert = tJunc.this*3
' Marker( Verts[TVert],5+Cos(LocA)*3.5,Verts[tvert+2] )
If gJunc<>Null
If gJunc=aJunc
Else
Xd! = gjunc.x-owner.x
zd! = gjunc.z-owner.z
ang! = ATan2(zd,xd)
td! = Sqr(xd*xd+yd*yd)
ms! = td/20.0
If ms>1 ms=1
If ms<0 ms=0
ms=1
ms=1-AngTurns/20
ms=1
If ms<0 ms=0
If ms>0.9 ms=0.9
movex=Cos(ang)*ms
movey=Sin(ang)*ms
EndIf
EndIf
LocA:+15
Return
End Select
End Method
Field MainPath:Path
Field TurnMod!
Method PathCycle( Vert:Int)
Vert:/3
Local Star:Int[60],Con:Short
While J<Tris.Length-1
If Tris[J] = Vert
Star[Con] = Tris[j+1]
Star[Con+1] = Tris[J+2]
con:+2
EndIf
If Tris[J+1] = Vert
Star[Con] = Tris[j]
Star[con+1] = tris[j+2]
con:+2
EndIf
If Tris[J+2] = Vert
Star[Con] = Tris[j]
Star[con] = Tris[j+1]
con:+2
EndIf
J:+3
Wend
For J=0 To Verts.Length/3
Next
Throw "Vert>"+Vert+" Has "+Con+" Connected Verts!"
End Method
Field LocA:Float
Method SmartMove( X!,Y!,Z!)
Task = IAL.MoveTO
TargetX =X
TargetY =Y
TargetZ =Z
aJunc = JuncNear(Owner.X,Owner.Y,Owner.Z)
tJunc = JuncNear(x,y,z)
If ajunc=tjunc
'Print "Already there!"
'Task = 0
'Return
EndIf
If aJunc = Null
Throw "No Active Junction"
EndIf
End Method
Field tJunc:Junction 'target junction
Method JuncNear:Junction(X!,Y!,Z!)
Return Junc[NearVert(X,Y,Z)/3]
End Method
Field aJunc:Junction
Method NearVert( X!,Y!,Z!)
Local Xd!,Yd!,Zd!
Local VertI=0
Local CloseD!,CloseV:Int
CloseD=999999999
While VertI<Verts.Length
Xd = X-Verts[VertI]
Zd = Z-Verts[VertI+2]
Td = Sqr(Xd*Xd+Zd*Zd)
If Td<CloseD
CloseD=TD
CloseV=VertI
End If
VertI:+3
Wend
Return CloseV
End Method
'debug stuff
Field debugMark
Field goMark,cMark
Method FillTri(TriIndex)
v0 = Tris[TriIndex]
v1 = Tris[TriIndex+1]
v2 = Tris[TriIndex+2]
xMi!= min3( verts[v0],verts[v1],verts[v2])
xMa!= max3( verts[v0],verts[v1],verts[v2])
FillX = xmi+(xma-xmi)/2.0
yMi!= min3( verts[v0+1],verts[v1+1],verts[v2+1])
yMa!= max3( verts[v0+1],verts[v1+1],verts[v2+1])
FillY! =yMi+(yMa-yMi)/2.0
zMi! = min3( verts[v0+2],verts[v1+2],verts[v2+2])
zMa!= max3( verts[v0+2],verts[v1+2],verts[v2+2])
FillZ! = zMi+(zMa-zMi)/2.0
End Method
'
Field FillX!,FillY!,FillZ!
Method NearestTri:Int( X!,Y!,Z!)
TriI=0
Temp:TProfile =Profiler.Enter("Nearest Tri")
It=0
Local Sd!=9999999
While TriI<(TriC*3)
V0 = Tris[TriI]*3
V1 = Tris[TriI+1]*3
V2 = Tris[TriI+2]*3
xMi!= min3( verts[v0],verts[v1],verts[v2])
xMa!= max3( verts[v0],verts[v1],verts[v2])
vX = xmi+(xma-xmi)/2.0
yMi!= min3( verts[v0+1],verts[v1+1],verts[v2+1])
yMa!= max3( verts[v0+1],verts[v1+1],verts[v2+1])
vY! =yMi+(yMa-yMi)/2.0
zMi! = min3( verts[v0+2],verts[v1+2],verts[v2+2])
zMa!= max3( verts[v0+2],verts[v1+2],verts[v2+2])
vZ! = zMi+(zMa-zMi)/2.0
tD! = Dist( x,y,z,vx,vy,vz )
If tD<sd
sd = td
TriX = Vx
TriY = vY
triZ = vZ
'TriX = Verts[v0]
' TriY = Verts[v0+1]
'TriZ = Verts[v0+2]
NearI = TriI
EndIf
TriI:+3
Wend
Temp.Leave()
Return NearI
End Method
Field TriX!,TriY!,TriZ!
Method max3!(v1!,v2!,v3!)
If v1>v2
If v1>v3
Return v1
EndIf
Return v3
Else If v2>v3
Return v2
Else
Return v3
EndIf
End Method
Method min3!(v1!,v2!,v3!)
If v1<v2
If v1<v3
Return v1
EndIf
Return v3
Else If v2<v3
Return v2
Else
Return v3
EndIf
End Method
Method Dist:Double(X!,Y!,z!,x2!,y2!,z2!)
xd! = x2-x
yd! = y2-y
zd! = z2-z
Return Sqr(xd*xd+yd*yd+zd*zd)
Return Sqr( (x2-x)^2+(y2-y)^2+(z2-z)^2)
End Method
Field Owner:Bot
Field TriI:Int
Field Tris:Int[],Verts:Double[]
Field Junc:Junction[10000]
Field aSurf:TSurface,VertC:Int,TriC:Int
End Type
Bot.ActiveBots = CreateList()
Bot.Bots = CreateList()
Function marker:Int(x!,y!,z!)
If oMark[oCount] = Null
oMark[oCount] = New TEntity
EndIf
TEntity.Clone( ActiveMark,oMark[oCount] )
oMark[oCount].x=x
oMark[oCount].y=y
oMark[oCount].z=z
oCount:+1
Return ocount-1
End Function
'-----------
Function removeMarker(id:Int)
Return
If id<(ocount-1)
omark[id] =omark[ocount-1]
EndIf
If ocount>0
ocount:-1
EndIf
End Function
Function renderMarker()
For Local j=0 To oCount-1
' vcam.renderentity( omark[j] )
Next
End Function
Function resetMarker()
ocount=0
End Function
Local Players:Bot[255]
MainBall.Mesh.Y=5
Function Nope()
Repeat
Delay 20
Until KeyDown(K_ESCAPE)
End Function
Function SetUpSun()
Sun:TLight = New TLight
Sun.Ambient( 32,32,32,1)
Sun.Diffuse( 32,32,32,1)
Sun.Specular(0,0,0,0)
Sun.Constant( 0.2 )
Sun.Linear( 0.001 )
Sun.Quadratic( 0.0001 )
Sun.Sync()
TopLight.Ambient(32,32,32,0)
TopLight.Diffuse(255,0,0,0)
TopLight.Specular( 1,1,1,0)
TopLight.Constant( 0.1 )
TopLight.Linear( 0.001 )
TopLight.Quadratic( 0.0001 )
TopLight.Y=50
topLight.Sync()
End Function
' ************************************************************************
Type TVector
Const VINVALID:Byte=0 ; Const VDEFAULT:Byte=1 ; Const VUNIT:Byte=2
Field _x:Double , _y:Double , _z:Double
Field _Status:Byte
' ********************************************************************
' Constructor
' ********************************************************************
Function Constructor:TVector(a:Double, b:Double, c:Double)
result:TVector=New TVector
result._x=a ; result._y=b ; result._z=c
result._Status=VDEFAULT
Return result
End Function
Function Constructor1:TVector(v:TVector)
result:TVector=New TVector
result._x=v._x ; result._y=v._y ; result._z=v._z ; result._Status=v._Status
Return result
End Function
' ********************************************************************
' Selectors
' ********************************************************************
Method x:Double()
Return _x
End Method
Method y:Double()
Return _y
End Method
Method z:Double()
Return _z
End Method
Method isUnit()
Return _Status=VUNIT
End Method
Method isDefault()
Return _Status=VDEFAULT
End Method
Method isValid()
Return _Status<>VINVALID
End Method
' ********************************************************************
' Magnitude
' ********************************************************************
Method mag:Double()
If isValid() Then
If isUnit() Then
Return 1.0
Else
Return Sqr(x()*x() + y()*y() + z()*z())
EndIf
Else
Return 0.0
EndIf
End Method
Method magSqr:Double()
If isValid() Then
If isUnit() Then
Return 1.0
Else
Return x()*x() + y()*y() + z()*z()
EndIf
Else
Return 0.0
EndIf
End Method
' ********************************************************************
' Dot or scalar product
' ********************************************************************
Function dot1:Double(v1:TVector, v2:TVector)
Return v1.dot(v2)
End Function
Method dot:Double(v:TVector)
If isValid() And v.isValid() Then
Return x()*v.x() + y()*v.y() + z()*v.z()
Else
Return 0.0
EndIf
End Method
' ********************************************************************
' Distance between two vectors
' ********************************************************************
Method dist:Double(v:TVector)
VEC:TVector=TVector.Constructor((_x-v._x),(_y-v._y),(_z-v._z))
Return VEC.mag()
End Method
Method distSqr:Double(v:TVector)
VEC:TVector=TVector.Constructor((_x-v._x),(_y-v._y),(_z-v._z))
Return VEC.magSqr()
End Method
' ********************************************************************
' Make a unit vector
' ********************************************************************
Method unit:TVector()
If isDefault() Then
rep:Double=Self.mag()
If rep<EPSILON Then
_x=0.0
_y=0.0
_z=0.0
Else
temp:Double=1.0/rep
_x:*temp
_y:*temp
_z:*temp
EndIf
_Status = VUNIT
EndIf
Return Self
End Method
Function unit1:TVector(v:TVector)
VEC:TVector=TVector.Constructor(v._x, v._y, v._z)
Return VEC.unit()
End Function
Function unit2:TVector(v:TVector, result:TVector)
result._x=v._x ; result._y=v._y ; result._z=v._z ; result._Status=v._Status
Return result.unit()
End Function
' ********************************************************************
' Make a default vector
' ********************************************************************
Method V_defaut:TVector()
If isUnit() Then
_Status = VDEFAULT
EndIf
Return Self
End Method
Function V_defaut1:TVector(v:TVector)
VEC:TVector=TVector.Constructor(v._x, v._y, v._z)
Return VEC.V_defaut()
End Function
Function V_defaut2:TVector(v:TVector, result:TVector)
result._x=v._x ; result._y=v._y ; result._z=v._z ; result._Status=v._Status
Return result.V_defaut()
End Function
' ********************************************************************
' Optimised arithmetic methods
' Return a TVector (Function, don't operate with this TVector)
' ********************************************************************
' Addition 2 vectors and return new vector (Result = v1 + v2)
Function Addition:TVector(v1:TVector, v2:TVector)
result:TVector=New TVector
If v1.isValid() And v2.isValid() Then
result._x = v1._x + v2._x
result._y = v1._y + v2._y
result._z = v1._z + v2._z
result._Status = VDEFAULT
EndIf
Return result
End Function
' Substract 2 vectors and return new vector (Result = v1 - v2)
Function Substract:TVector(v1:TVector, v2:TVector)
result:TVector=New TVector
If v1.isValid() And v2.isValid() Then
result._x = v1._x - v2._x
result._y = v1._y - v2._y
result._z = v1._z - v2._z
result._Status = VDEFAULT
EndIf
Return result
End Function
' Crossproduct of 2 vectors and return new vector (Result = v1 * v2)
Function Cross:TVector(v1:TVector, v2:TVector)
result:TVector=New TVector
If v1.isValid() And v2.isValid() Then
result._x = v1._y * v2._z - v1._z * v2._y
result._y = v1._z * v2._x - v1._x * v2._z
result._z = v1._x * v2._y - v1._y * v2._x
result._Status = VDEFAULT
EndIf
Return result
End Function
' Invert a vector and return new vector (Result = -(v1))
Function Invert:TVector(v1:TVector)
result:TVector=New TVector
If v1.isValid() Then
result._x = - v1._x
result._y = - v1._y
result._z = - v1._z
result._Status = VDEFAULT
EndIf
Return result
End Function
' Multiply 1 vector by scale and return new vector (Result = v1 * scale)
Function Multiply:TVector(v1:TVector, scale:Double)
result:TVector=New TVector
If v1.isValid() Then
result._x = v1._x * scale
result._y = v1._y * scale
result._z = v1._z * scale
result._Status = VDEFAULT
EndIf
Return result
End Function
' ********************************************************************
' Operator
' ( Method, operate with this TVector )
' ********************************************************************
' Negat this vector and return a vector ( result = - self ) (v2=v1.Negat())
Method Negat:TVector()
Return TVector.Invert(Self)
End Method
' Assign a vector to this vector ( self = v1 ) (v2=v2.Equal(v1))
Method Equal:TVector(v1:TVector)
_x=v1._x ; _y=v1._y ; _z=v1._z ; _Status=v1._Status
End Method
' Add to this vector a vector and return this vector ( self :+ v1 ) (v2=v2.AddEqual(v1))
Method AddEqual:TVector(v1:TVector)
Return TVector.Addition(Self, v1)
End Method
' Sub to this vector a vector and return this vector ( self :- v1 ) (v2=v2.SubEqual(v1))
Method SubEqual:TVector(v1:TVector)
Return TVector.Substract(Self, v1)
End Method
' Mult this vector by a vector and return this vector (Crossproduct) ( self :* v1 ) (v2=v2.MultEqualVec(v1))
Method MultEqualVec:TVector(v1:TVector)
Return TVector.Cross(Self, v1)
End Method
' Mult this vector by a val and return this vector ( self :* value ) (v2=v2.MultEqualVal(scale))
Method MultEqualVal:TVector(scale:Double)
Return TVector.Multiply(Self, scale)
End Method
' Add to this vector a vector and return a vector ( result = self + v1 ) (v3=v1.Add(v2))
Method Add:TVector(v1:TVector)
Return TVector.Addition(Self, v1)
End Method
' Sub to this vector a vector and return a vector ( result = self - v1 ) (v3=v1.Sub(v2))
Method Sub:TVector(v1:TVector)
Return TVector.Substract(Self, v1)
End Method
' Mult to this vector a vector and return a vector (Crossproduct) ( result = self * v1 ) (v3=v1.MultVec(v2))
Method MultVec:TVector(v1:TVector)
Return TVector.Cross(Self, v1)
End Method
' Mult to this vector by a value and return a vector ( result = self * scale ) (v3=v1.MultVal(scale))
Method MultVal:TVector(scale:Double)
Return TVector.Multiply(Self, scale)
End Method
End Type
' *******