Untitled diff

Created Diff never expires
3 removals
802 lines
17 additions
816 lines
SeedRnd MilliSecs()
SeedRnd MilliSecs()


Const gameLogicFPS = 60
Const gameLogicFPS = 60


Include "Hex8.bb"
Include "UDPNetwork_lib.bb"
Include "UDPNetwork_lib.bb"


Global localID
Global localID
Global localName$ = Input("Enter your name : ")
Global localName$ = Input("Enter your name : ")
If localName = "" Then localName = "player" + Rand(100,999)
If localName = "" Then localName = "player" + Rand(100,999)


Global localPlayerMesh
Global localPlayerMesh


Type player
Type player
Field id
Field id
Field name$
Field name$
Field ping
Field ping
Field life
Field life
Field kills
Field kills
Field deaths
Field deaths
Field mesh
Field mesh
Field r,g,b
Field r,g,b


Field nextX#,nextY#,nextZ#
Field nextX#,nextY#,nextZ#
Field previousX#,previousY#,previousZ#
Field previousX#,previousY#,previousZ#
Field nextYaw#
Field nextYaw#
Field previousYaw#
Field previousYaw#
Field nextTime
Field nextTime
Field previousTime
Field previousTime
Field lastPacket
Field lastPacket
Field currentY#
Field currentY#
Field velocityY#
Field velocityY#
End Type
End Type


Type bullet
Type bullet
Field mesh
Field mesh
Field angle#
Field angle#
Field time
Field time
Field id ; id of player who fired
Field id ; id of player who fired
End Type
End Type


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Camera code from jfk EO-11110, thanks
; Camera code from jfk EO-11110, thanks
Global bounce_cam=1 ; smooth camera motion? (0/1)
Global bounce_cam=1 ; smooth camera motion? (0/1)
Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0
Global bounce_div#=10.0 ; the higher, the more sluggish the camera will follow. Recc: 3.0 to 20.0
; some globals used by ChaseCam
; some globals used by ChaseCam
Global old_x#,old_y#,old_z#
Global old_x#,old_y#,old_z#
; desired distance between camera and player mesh
; desired distance between camera and player mesh
Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis#
Global x_dis#=7.0,y_dis#=3,z_dis#=7.0,y_dis_or#=y_dis#
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; network init ----------------------------------------;
; network init ----------------------------------------;
Global localMode = Net_StartInput() ; bring the library "console" to connect
Global localMode = Net_StartInput() ; bring the library "console" to connect


If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server
If localMode = 1 Or localMode = 2 ; 1 means we are client, 2 means we are server
localId = Net_CreatePlayer(localName) ; this command inits the server or local client
localId = Net_CreatePlayer(localName) ; this command inits the server or local client
If localId = 0 ; error
If localId = 0 ; error
Net_StopNetwork() ; close the network properly
Net_StopNetwork() ; close the network properly
RuntimeError("Failed to create player.")
RuntimeError("Failed to create player.")
EndIf
EndIf
If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 1 Then AppTitle("Client : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
If localMode = 2 Then AppTitle("Server : " + localName + " (port:" + net_port + "/ ID=" + localID + ")")
Else ; error
Else ; error
Net_StopNetwork()
Net_StopNetwork()
RuntimeError("Failed to start game.")
RuntimeError("Failed to start game.")
EndIf
EndIf
;------------------------------------------------------;
;------------------------------------------------------;


Graphics3D 640,480,32,2
Graphics3D 640,480,32,2
SetBuffer BackBuffer()
SetBuffer BackBuffer()


CreateScene()
CreateScene()


Global camera = CreateCamera()
Global camera = CreateCamera()
CameraRange camera,0.1,1000
CameraRange camera,0.1,1000


; create our own local player
; create our own local player
localPlayerMesh = CreatePlayer(localID,localName)
localPlayerMesh = CreatePlayer(localID,localName)
old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position
old_x = EntityX(localPlayerMesh):old_y = EntityY(localPlayerMesh):old_z = EntityZ(localPlayerMesh) ; update camera position


; we send our color to the server
; we send our color to the server
p.player = Object.player(GetPlayer(localID))
p.player = Object.player(GetPlayer(localID))
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b)
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b)

Global cR = p\r
Global cG = p\g
Global cB = p\b


; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping)
; variables used to send our positions at a constant delay (saves bandwidth but makes a constant ping)
Global updatePosition = MilliSecs()
Global updatePosition = MilliSecs()
Global updateTick = 50
Global updateTick = 50


; chat
; chat
Global messageDisplayNumber = 10
Global messageDisplayNumber = 10
Global messageOffset
Global messageOffset
Dim message$(messageDisplayNumber)
Dim message$(messageDisplayNumber)


Global chatMode
Global chatMode
Global chatMessage$ = localName + "> "
Global chatMessage$ = localName + "> "
Global chatMillisecs = MilliSecs()
Global chatMillisecs = MilliSecs()
Global chatCursor
Global chatCursor


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
tweeningPeriod = 1000 / gameLogicFPS
tweeningPeriod = 1000 / gameLogicFPS
tweeningTime = MilliSecs() - tweeningPeriod
tweeningTime = MilliSecs() - tweeningPeriod
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
While Not KeyHit(1)
While Not KeyHit(1)


;; I use tweening from castle demo here :
;; I use tweening from castle demo here :
;;
;;
;; - this allows to have very fast execution outside the tweening loop,
;; - this allows to have very fast execution outside the tweening loop,
;; so the network is updated as fast as possible (needs Flip False)
;; so the network is updated as fast as possible (needs Flip False)
;;
;;
;; - this makes the game logic updated at a constant rate (Const FPS=)
;; - this makes the game logic updated at a constant rate (Const FPS=)
;; so no need to set deltatime (and it saves CPU time for other things)
;; so no need to set deltatime (and it saves CPU time for other things)




;; -------------------------------------------------------------------------------------------------; FAST EXECUTION (outside of tweening)
;; -------------------------------------------------------------------------------------------------; FAST EXECUTION (outside of tweening)
;; -------------------------------------------------------------------------------------------------;
;; -------------------------------------------------------------------------------------------------;
; see the function, the interpolation variables are set properly here
; see the function, the interpolation variables are set properly here
UpdateNetwork()
UpdateNetwork()
;; -------------------------------------------------------------------------------------------------;
;; -------------------------------------------------------------------------------------------------;


Repeat
Repeat
tweeningElapsed = MilliSecs() - tweeningTime
tweeningElapsed = MilliSecs() - tweeningTime
Until tweeningElapsed
Until tweeningElapsed
tweeningTicks = tweeningElapsed / tweeningPeriod
tweeningTicks = tweeningElapsed / tweeningPeriod
tweeningRate# = Float(tweeningElapsed Mod tweeningPeriod)/Float(tweeningPeriod)
tweeningRate# = Float(tweeningElapsed Mod tweeningPeriod)/Float(tweeningPeriod)
For k = 1 To tweeningTicks
For k = 1 To tweeningTicks
tweeningTime = tweeningTime + tweeningPeriod
tweeningTime = tweeningTime + tweeningPeriod
If k = tweeningTicks Then CaptureWorld
If k = tweeningTicks Then CaptureWorld
;; ---------------------------------------------------------------------------------------------; MAIN UPDATE
;; ---------------------------------------------------------------------------------------------; MAIN UPDATE
;; ---------------------------------------------------------------------------------------------;
;; ---------------------------------------------------------------------------------------------;
; update our player
; update our player
UpdateLocalPlayer()
UpdateLocalPlayer()
; the interpolation is made in this function
; the interpolation is made in this function
UpdatePlayers()
UpdatePlayers()
; update the bullets... only the server check for player kills
; update the bullets... only the server check for player kills
UpdateBullets()
UpdateBullets()


UpdateWorld()
UpdateWorld()
UpdateChaseCam(camera,localPlayerMesh)
UpdateChaseCam(camera,localPlayerMesh)
;; ---------------------------------------------------------------------------------------------;
;; ---------------------------------------------------------------------------------------------;
Next
Next
RenderWorld tweeningRate
RenderWorld tweeningRate


;; -------------------------------------------------------------------------------------------------; 2D UPDATE
;; -------------------------------------------------------------------------------------------------; 2D UPDATE
;; -------------------------------------------------------------------------------------------------;
;; -------------------------------------------------------------------------------------------------;
DrawPlayersNames()
DrawPlayersNames()
If KeyHit(28) And chatMode = 0 Then chatMode = 1:FlushKeys()
If KeyHit(28) And chatMode = 0 Then chatMode = 1:FlushKeys()
If chatMode = 1 Then UpdateChat()
If chatMode = 1 Then UpdateChat()
DrawMessages()
DrawMessages()
If KeyDown(15) Then DrawScoreTable()
If KeyDown(15) Then DrawScoreTable()
;; -------------------------------------------------------------------------------------------------;
;; -------------------------------------------------------------------------------------------------;
Flip
Flip


Wend
Wend
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Net_StopNetwork()
Net_StopNetwork()


End
End


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdateNetwork()
Function UpdateNetwork()


; update incoming packets (better check ALL incoming messages so use While Wend)
; update incoming packets (better check ALL incoming messages so use While Wend)
While Net_CheckMessage() ; will check for a new message and fill Net_MsgType, Net_MsgString$, Net_MsgFrom and Net_MsgTo variables so we can read it
While Net_CheckMessage() ; will check for a new message and fill Net_MsgType, Net_MsgString$, Net_MsgFrom and Net_MsgTo variables so we can read it
p.player = Object.player(GetPlayer(Net_MsgFrom)) ; get the player handle
p.player = Object.player(GetPlayer(Net_MsgFrom)) ; get the player handle


If Handle(p) = 0 And Net_MsgType < 100 ; we received an update packet from a player we don't know
If Handle(p) = 0 And Net_MsgType < 100 ; we received an update packet from a player we don't know
; so we ask the server who he is and return because we can't update him for now
; so we ask the server who he is and return because we can't update him for now
; the server will resend us the info in a new player "100" message
; the server will resend us the info in a new player "100" message
Net_RequestPlayer(Net_MsgFrom)
Net_RequestPlayer(Net_MsgFrom)
Return
Return
EndIf
EndIf
Select Net_MsgType ; check the type of message
Select Net_MsgType ; check the type of message
Case 1 ; chat message
Case 1 ; chat message
NewMessage(Net_MsgString)
NewMessage(Net_MsgString)
Case 2 ; player position and angle, example of packing data into string
Case 2 ; player position and angle, example of packing data into string
offset1 = Instr(Net_MsgString,"/",1)
offset1 = Instr(Net_MsgString,"/",1)
offset2 = Instr(Net_MsgString,"/",offset1+1)
offset2 = Instr(Net_MsgString,"/",offset1+1)
offset3 = Instr(Net_MsgString,"/",offset2+1)
offset3 = Instr(Net_MsgString,"/",offset2+1)
p\previousX = p\nextX
p\previousX = p\nextX
p\previousY = p\nextY
p\previousY = p\nextY
p\previousZ = p\nextZ
p\previousZ = p\nextZ
p\previousYaw = p\nextYaw
p\previousYaw = p\nextYaw
p\nextX = Left(Net_MsgString,offset1-1)
p\nextX = Left(Net_MsgString,offset1-1)
p\nextY = Mid(Net_MsgString,offset1+1,offset2-offset1-1)
p\nextY = Mid(Net_MsgString,offset1+1,offset2-offset1-1)
p\nextZ = Mid(Net_MsgString,offset2+1,offset3-offset2-1)
p\nextZ = Mid(Net_MsgString,offset2+1,offset3-offset2-1)
p\nextYaw = Right(Net_MsgString,Len(Net_MsgString)-offset3)
p\nextYaw = Right(Net_MsgString,Len(Net_MsgString)-offset3)


p\previousTime = p\nextTime
p\previousTime = p\nextTime
p\nextTime = MilliSecs()
p\nextTime = MilliSecs()
Case 3 ; update player colors
Case 3 ; update player colors
offset1 = Instr(Net_MsgString,"/",1)
offset1 = Instr(Net_MsgString,"/",1)
offset2 = Instr(Net_MsgString,"/",offset1+1)
offset2 = Instr(Net_MsgString,"/",offset1+1)
p\r = Left(Net_MsgString,offset1-1)
p\r = Left(Net_MsgString,offset1-1)
p\g = Mid(Net_MsgString,offset1+1,offset2-offset1-1)
p\g = Mid(Net_MsgString,offset1+1,offset2-offset1-1)
p\b = Right(Net_MsgString,Len(Net_MsgString)-offset2)
p\b = Right(Net_MsgString,Len(Net_MsgString)-offset2)
EntityColor p\mesh,p\r,p\g,p\b
EntityColor p\mesh,p\r,p\g,p\b
Case 4 ; a player fired
Case 4 ; a player fired
CreateBullet(Net_MsgFrom)
CreateBullet(Net_MsgFrom)
Case 5 ; a player lost some life
Case 5 ; a player lost some life
p\life = Net_MsgString
p\life = Net_MsgString
Case 6 ; a player killed another one
Case 6 ; a player killed another one
k.player = Object.player(GetPlayer(Net_MsgString)) ; killed player ID in MsgData
k.player = Object.player(GetPlayer(Net_MsgString)) ; killed player ID in MsgData
NewMessage(p\name + " killed " + k\name)
NewMessage(p\name + " killed " + k\name)
ResetPlayer(k\id)
ResetPlayer(k\id)
Case 7 ; the server sends us score update for a player
Case 7 ; the server sends us score update for a player
offset = Instr(Net_MsgString,"/",1)
offset = Instr(Net_MsgString,"/",1)
p\kills = Left(Net_MsgString,offset-1)
p\kills = Left(Net_MsgString,offset-1)
p\deaths = Right(Net_MsgString,Len(Net_MsgString)-offset)
p\deaths = Right(Net_MsgString,Len(Net_MsgString)-offset)
Case 100 ; new player connected, OR the server tells us who is already connected so we can create players when joining the game
Case 100 ; new player connected, OR the server tells us who is already connected so we can create players when joining the game
If localMode = 2
If localMode = 2
For p.player = Each player
For p.player = Each player
Net_SendMessage(2,p\nextX + "/" + p\nextY + "/" + p\nextZ + "/" + p\nextYaw,p\id,Net_MsgFrom)
Net_SendMessage(2,p\nextX + "/" + p\nextY + "/" + p\nextZ + "/" + p\nextYaw,p\id,Net_MsgFrom)
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b,p\id,Net_MsgFrom)
Net_SendMessage(3,p\r + "/" + p\g + "/" + p\b,p\id,Net_MsgFrom)
Net_SendMessage(5,p\life,p\id,Net_MsgFrom)
Net_SendMessage(5,p\life,p\id,Net_MsgFrom)
Net_SendMessage(7,p\kills+"/"+p\deaths,p\id,Net_MsgFrom)
Net_SendMessage(7,p\kills+"/"+p\deaths,p\id,Net_MsgFrom)
Next
Next
EndIf
EndIf
NewMessage(Net_MsgString + " connected")
NewMessage(Net_MsgString + " connected")
CreatePlayer(Net_MsgFrom,Net_MsgString)
CreatePlayer(Net_MsgFrom,Net_MsgString)
Case 101 ; a player has quit
Case 101 ; a player has quit
For p.player = Each player
For p.player = Each player
If Net_MsgFrom = p\id
If Net_MsgFrom = p\id
NewMessage(p\name + " disconnected")
NewMessage(p\name + " disconnected")
FreeEntity p\mesh
FreeEntity p\mesh
Delete p
Delete p
EndIf
EndIf
Next
Next
Case 102 ; host has changed
Case 102 ; host has changed
For p.player = Each player
For p.player = Each player
If Net_MsgFrom = p\id
If Net_MsgFrom = p\id
If p\id = localID
If p\id = localID
AppTitle("Server : " + localName + " (port:" + net_port + ")")
AppTitle("Server : " + localName + " (port:" + net_port + ")")
NewMessage("You are the new host")
NewMessage("You are the new host")
localMode = 2
localMode = 2
Else
Else
NewMessage(p\name + " is the new host")
NewMessage(p\name + " is the new host")
EndIf
EndIf
EndIf
EndIf
Next
Next
Case 103 ; ping update
Case 103 ; ping update
For p.player = Each player
For p.player = Each player
If Net_MsgFrom = p\id
If Net_MsgFrom = p\id
p\ping = Net_MsgString
p\ping = Net_MsgString
EndIf
EndIf
Next
Next


End Select
End Select


Wend
Wend


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdateLocalPlayer()
Function UpdateLocalPlayer()


; update our player
; update our player
p.player = Object.player(GetPlayer(localID)) ; get our player
p.player = Object.player(GetPlayer(localID)) ; get our player


; inputs
; inputs
If KeyDown(200) Then MoveEntity p\mesh,0,0,0.3
If KeyDown(200) Then MoveEntity p\mesh,0,0,0.3
If KeyDown(208) Then MoveEntity p\mesh,0,0,-0.3
If KeyDown(208) Then MoveEntity p\mesh,0,0,-0.3
If KeyDown(203) Then TurnEntity p\mesh,0,3,0
If KeyDown(203) Then TurnEntity p\mesh,0,3,0
If KeyDown(205) Then TurnEntity p\mesh,0,-3,0
If KeyDown(205) Then TurnEntity p\mesh,0,-3,0
; fire
; fire
If MouseHit(1)
If MouseHit(1)
Net_SendMessage(4,"")
Net_SendMessage(4,"")
CreateBullet(localID)
CreateBullet(localID)
EndIf
EndIf
; jump
; jump
If MouseHit(2)
If MouseHit(2)
; check if player is one the ground
; check if player is one the ground
LinePick(EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh),0,-1.2,0)
LinePick(EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh),0,-1.2,0)
If PickedEntity()
If PickedEntity()
p\velocityY = 0.5 ; set "inverse" of gravity velocity
p\velocityY = 0.5 ; set "inverse" of gravity velocity
EndIf
EndIf
EndIf
EndIf
; we create a message type "2" for player position
; we create a message type "2" for player position
If MilliSecs()-updatePosition > updateTick
If MilliSecs()-updatePosition > updateTick
Net_SendMessage(2,EntityX(p\mesh) + "/" + EntityY(p\mesh) + "/" + EntityZ(p\mesh) + "/" + EntityYaw(p\mesh))
Net_SendMessage(2,EntityX(p\mesh) + "/" + EntityY(p\mesh) + "/" + EntityZ(p\mesh) + "/" + EntityYaw(p\mesh))
updatePosition = MilliSecs()
updatePosition = MilliSecs()
EndIf
EndIf
End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdatePlayers()
Function UpdatePlayers()


For p.player = Each player
For p.player = Each player
If p\id <> localID ; update other players only
If p\id <> localID ; update other players only
;; LINEAR INTERPOLATION ;;;;;;;;;;
;; LINEAR INTERPOLATION ;;;;;;;;;;
If p\nextTime <> p\previousTime ; if both packets arrived at the same time, we can't interpolate
If p\nextTime <> p\previousTime ; if both packets arrived at the same time, we can't interpolate
curTime# = Float(MilliSecs()-p\nextTime) / Float(p\nextTime-p\previousTime) ; curTime will be ideally 0.0-1.0, if it's > 1.0 then it performs extrapolation
curTime# = Float(MilliSecs()-p\nextTime) / Float(p\nextTime-p\previousTime) ; curTime will be ideally 0.0-1.0, if it's > 1.0 then it performs extrapolation
If curTime > 1 Then curTime = 1 ; extrapolation gives anoying jittering effects
If curTime > 1 Then curTime = 1 ; extrapolation gives anoying jittering effects
; special fix for yaw as EntityYaw returns a value beetween +180 ans -180, the interpolation can go backward
; special fix for yaw as EntityYaw returns a value beetween +180 ans -180, the interpolation can go backward
If p\previousYaw < 0 Then p\previousYaw = p\previousYaw + 360
If p\previousYaw < 0 Then p\previousYaw = p\previousYaw + 360
If p\nextYaw < 0 Then p\nextYaw = p\nextYaw + 360
If p\nextYaw < 0 Then p\nextYaw = p\nextYaw + 360
If Abs(p\nextYaw-p\previousYaw) > 180
If Abs(p\nextYaw-p\previousYaw) > 180
If p\nextYaw > p\previousYaw
If p\nextYaw > p\previousYaw
p\previousYaw = p\previousYaw + 360
p\previousYaw = p\previousYaw + 360
Else
Else
p\previousYaw = p\previousYaw - 360
p\previousYaw = p\previousYaw - 360
EndIf
EndIf
EndIf
EndIf
PositionEntity p\mesh,p\previousX+(p\nextX-p\previousX)*curTime,p\previousY+(p\nextY-p\previousY)*curTime,p\previousZ+(p\nextZ-p\previousZ)*curTime
PositionEntity p\mesh,p\previousX+(p\nextX-p\previousX)*curTime,p\previousY+(p\nextY-p\previousY)*curTime,p\previousZ+(p\nextZ-p\previousZ)*curTime
RotateEntity p\mesh,0,p\previousYaw+(p\nextYaw-p\previousYaw)*curTime,0
RotateEntity p\mesh,0,p\previousYaw+(p\nextYaw-p\previousYaw)*curTime,0
Else
Else
PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
RotateEntity p\mesh,0,p\nextYaw,0
RotateEntity p\mesh,0,p\nextYaw,0
EndIf
EndIf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ResetEntity p\mesh ; reset entity is useful here because of collisions
ResetEntity p\mesh ; reset entity is useful here because of collisions


Else ; update our player, basically it just compute gravity
Else ; update our player, basically it just compute gravity
p\velocityY = p\velocityY - 0.03 ; fake gravity
p\velocityY = p\velocityY - 0.03 ; fake gravity
If EntityY(p\mesh) - p\currentY >= 0 ; if player is not falling we limit the gravity
If EntityY(p\mesh) - p\currentY >= 0 ; if player is not falling we limit the gravity
If p\velocityY < -0.03 Then p\velocityY = -0.03
If p\velocityY < -0.03 Then p\velocityY = -0.03
EndIf
EndIf
p\currentY = EntityY(p\mesh)
p\currentY = EntityY(p\mesh)
TranslateEntity p\mesh,0,p\velocityY,0
TranslateEntity p\mesh,0,p\velocityY,0
EndIf
EndIf
Next
Next


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CreatePlayer(id,name$)
Function CreatePlayer(id,name$)


For p.player = Each player
For p.player = Each player
If p\id = id Then Return ; player already connected
If p\id = id Then Return ; player already connected
Next
Next


p.player = New player
p.player = New player
p\id = id
p\id = id
p\name = name
p\name = name
p\life = 100
p\life = 100
p\mesh = CreateSphere()
p\mesh = CreateSphere()
EntityType p\mesh,2
EntityType p\mesh,2
EntityRadius p\mesh,1
EntityRadius p\mesh,1
NameEntity p\mesh,Handle(p)
NameEntity p\mesh,Handle(p)
nose = CreateSphere(8,p\mesh):EntityColor nose,255,0,0
nose = CreateSphere(8,p\mesh):EntityColor nose,255,0,0
PositionEntity nose,0,0,1
PositionEntity nose,0,0,1
ScaleEntity nose,0.3,0.3,0.3
ScaleEntity nose,0.3,0.3,0.3
eyeLeft = CreateSphere(8,p\mesh):EntityColor eyeLeft,255,255,255
eyeLeft = CreateSphere(8,p\mesh):EntityColor eyeLeft,255,255,255
PositionEntity eyeLeft ,.29,.4,.7;1
PositionEntity eyeLeft ,.29,.4,.7;1
ScaleEntity eyeLeft ,0.2,0.2,0.2
ScaleEntity eyeLeft ,0.2,0.2,0.2
pupilLeft = CreateSphere(8,p\mesh):EntityColor pupilLeft ,0,0,0
pupilLeft = CreateSphere(8,p\mesh):EntityColor pupilLeft ,0,0,0
PositionEntity pupilLeft ,.3,.4,.9;1
PositionEntity pupilLeft ,.3,.4,.9;1
ScaleEntity pupilLeft ,0.05,0.05,0.02
ScaleEntity pupilLeft ,0.05,0.05,0.02
eyeRight = CreateSphere(8,p\mesh):EntityColor eyeRight ,255,255,255
eyeRight = CreateSphere(8,p\mesh):EntityColor eyeRight ,255,255,255
PositionEntity eyeRight ,-.29,.4,.7;1
PositionEntity eyeRight ,-.29,.4,.7;1
ScaleEntity eyeRight ,0.2,0.2,0.2
ScaleEntity eyeRight ,0.2,0.2,0.2
pupilRight = CreateSphere(8,p\mesh):EntityColor pupilRight ,0,0,0
pupilRight = CreateSphere(8,p\mesh):EntityColor pupilRight ,0,0,0
PositionEntity pupilRight ,-.3,.4,.9;1
PositionEntity pupilRight ,-.3,.4,.9;1
ScaleEntity pupilRight ,0.05,0.05,0.02
ScaleEntity pupilRight ,0.05,0.05,0.02


unaBrow = CreateCone(8,1,p\mesh):EntityColor unaBrow ,0,0,0
unaBrow = CreateCone(8,1,p\mesh):EntityColor unaBrow ,0,0,0
PositionEntity unaBrow ,0,.45,.7
PositionEntity unaBrow ,0,.45,.7
RotateEntity unaBrow ,-180,0,0
RotateEntity unaBrow ,-180,0,0
ScaleEntity unaBrow ,.7,.2,.3
ScaleEntity unaBrow ,.7,.2,.3
p\nextX = -20
p\nextX = -20
p\nextY = 1
p\nextY = 1
p\nextZ = -20
p\nextZ = -20
p\nextYaw = -45
p\nextYaw = -45
p\previousX = p\nextX
p\previousX = p\nextX
p\previousY = p\nextY
p\previousY = p\nextY
p\previousZ = p\nextZ
p\previousZ = p\nextZ
p\previousYaw = p\nextYaw
p\previousYaw = p\nextYaw
p\r = Rand(255)
p\r = Rand(255)
p\g = Rand(255)
p\g = Rand(255)
p\b = Rand(255)
p\b = Rand(255)
EntityColor p\mesh,p\r,p\g,p\b
EntityColor p\mesh,p\r,p\g,p\b
PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
RotateEntity p\mesh,0,p\nextYaw,0
RotateEntity p\mesh,0,p\nextYaw,0
ResetEntity p\mesh
ResetEntity p\mesh
p\currentY = p\nextY
p\currentY = p\nextY
p\previousTime = MilliSecs()
p\previousTime = MilliSecs()
p\nextTime = MilliSecs()+1
p\nextTime = MilliSecs()+1
Return p\mesh
Return p\mesh


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function ResetPlayer(id)
Function ResetPlayer(id)


p.player = Object.player(GetPlayer(id))
p.player = Object.player(GetPlayer(id))


p\life = 100
p\life = 100


p\nextX = -20
p\nextX = -20
p\nextY = 1
p\nextY = 1
p\nextZ = -20
p\nextZ = -20
p\nextYaw = -45
p\nextYaw = -45


p\previousX = p\nextX
p\previousX = p\nextX
p\previousY = p\nextY
p\previousY = p\nextY
p\previousZ = p\nextZ
p\previousZ = p\nextZ
p\previousYaw = p\nextYaw
p\previousYaw = p\nextYaw


PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
PositionEntity p\mesh,p\nextX,p\nextY,p\nextZ
RotateEntity p\mesh,0,p\nextYaw,0
RotateEntity p\mesh,0,p\nextYaw,0
ResetEntity p\mesh
ResetEntity p\mesh
p\currentY = p\nextY
p\currentY = p\nextY
p\previousTime = MilliSecs()
p\previousTime = MilliSecs()
p\nextTime = MilliSecs()+1
p\nextTime = MilliSecs()+1


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function GetPlayer(id)
Function GetPlayer(id)


For p.player = Each player
For p.player = Each player
If p\id = id
If p\id = id
Return Handle(p)
Return Handle(p)
EndIf
EndIf
Next
Next
End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function DrawPlayersNames()
Function DrawPlayersNames()


For p.player = Each player
For p.player = Each player
Color 255,255,255
Color 255,255,255
CameraProject(camera,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh))
CameraProject(camera,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh))
If p\id <> localID Then Text ProjectedX(),ProjectedY()-60,p\name,1,1
If p\id <> localID Then Text ProjectedX(),ProjectedY()-60,p\name,1,1
Color 255,(255./100.)*p\life,(255./100.)*p\life
Color 255,(255./100.)*p\life,(255./100.)*p\life
Text ProjectedX(),ProjectedY()-40,p\life,1,1
Text ProjectedX(),ProjectedY()-40,p\life,1,1


Next
Next
End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CreateBullet(id)
Function CreateBullet(id)


p.player = Object.player(GetPlayer(id))
p.player = Object.player(GetPlayer(id))


b.bullet = New bullet
b.bullet = New bullet
b\id = p\id
b\id = p\id
b\mesh = CreateSphere(2)
b\mesh = CreateSphere(2)
ScaleEntity b\mesh,0.2,0.2,0.2
ScaleEntity b\mesh,0.2,0.2,0.2
EntityColor b\mesh,255,0,0
EntityColor b\mesh,255,0,0
PositionEntity b\mesh,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh)
PositionEntity b\mesh,EntityX(p\mesh),EntityY(p\mesh),EntityZ(p\mesh)
RotateEntity b\mesh,0,EntityYaw(p\mesh),0
RotateEntity b\mesh,0,EntityYaw(p\mesh),0
EntityType b\mesh,3
EntityType b\mesh,3
EntityRadius b\mesh,0.2
EntityRadius b\mesh,0.2
b\time = MilliSecs()
b\time = MilliSecs()


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdateBullets()
Function UpdateBullets()


For b.bullet = Each bullet
For b.bullet = Each bullet
MoveEntity b\mesh,0,0,1
MoveEntity b\mesh,0,0,1
If CountCollisions(b\mesh)
If CountCollisions(b\mesh)
If localMode = 2 ; only the server compute bullets collision with player
If localMode = 2 ; only the server compute bullets collision with player
If GetEntityType(CollisionEntity(b\mesh,1)) = 2 ; a player is hit
If GetEntityType(CollisionEntity(b\mesh,1)) = 2 ; a player is hit
touchedPlayer.player = Object.player(EntityName(CollisionEntity(b\mesh,1)))
touchedPlayer.player = Object.player(EntityName(CollisionEntity(b\mesh,1)))
touchedPlayer\life = touchedPlayer\life - 10
touchedPlayer\life = touchedPlayer\life - 10
If touchedPlayer\life > 0 ; touched
If touchedPlayer\life > 0 ; touched
Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id)
Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id)
Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id,touchedPlayer\id)
Net_SendMessage(5,touchedPlayer\life,touchedPlayer\id,touchedPlayer\id)
Else ; killed
Else ; killed
killerPlayer.player = Object.player(GetPlayer(b\id))
killerPlayer.player = Object.player(GetPlayer(b\id))
killerPlayer\kills = killerPlayer\kills + 1
killerPlayer\kills = killerPlayer\kills + 1
touchedPlayer\deaths = touchedPlayer\deaths + 1
touchedPlayer\deaths = touchedPlayer\deaths + 1
Net_SendMessage(6,touchedPlayer\id,killerPlayer\id)
Net_SendMessage(6,touchedPlayer\id,killerPlayer\id)
Net_SendMessage(6,touchedPlayer\id,killerPlayer\id,killerPlayer\id)
Net_SendMessage(6,touchedPlayer\id,killerPlayer\id,killerPlayer\id)
Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id)
Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id)
Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id,killerPlayer\id)
Net_SendMessage(7,killerPlayer\kills+"/"+killerPlayer\deaths,killerPlayer\id,killerPlayer\id)
Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id)
Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id)
Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id,touchedPlayer\id)
Net_SendMessage(7,touchedPlayer\kills+"/"+touchedPlayer\deaths,touchedPlayer\id,touchedPlayer\id)
NewMessage(killerPlayer\name + " killed " + touchedPlayer\name)
NewMessage(killerPlayer\name + " killed " + touchedPlayer\name)
ResetPlayer(touchedPlayer\id)
ResetPlayer(touchedPlayer\id)
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
FreeEntity b\mesh
FreeEntity b\mesh
Delete b
Delete b
ElseIf MilliSecs()-b\time > 2000
ElseIf MilliSecs()-b\time > 2000
FreeEntity b\mesh
FreeEntity b\mesh
Delete b
Delete b
EndIf
EndIf
Next
Next


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function NewMessage(msg$)
Function NewMessage(msg$)


messageOffset = messageOffset + 1
messageOffset = messageOffset + 1
If messageOffset > messageDisplayNumber
If messageOffset > messageDisplayNumber
messageOffset = messageOffset - 1
messageOffset = messageOffset - 1
For i = 2 To messageDisplayNumber
For i = 2 To messageDisplayNumber
message(i-1) = message(i)
message(i-1) = message(i)
Next
Next
message(messageDisplayNumber) = msg
message(messageDisplayNumber) = msg
Else
Else
message(messageOffset) = msg
message(messageOffset) = msg
EndIf
EndIf


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function DrawMessages()
Function DrawMessages()


Color 255,255,255
Color 255,255,255


For i = 1 To messageOffset
For i = 1 To messageOffset
loc = Instr (message(i), "¿",1)
Text 0,(i-1)*15,message(i)
If loc > 1 Then
colorMessage$ = Mid$(message(i), 1, Len(message(i)) - 7 )
Hex$ = Right$(message(i),6)
Set_Color_Hex(Hex$)
Text 0,(i-1)*15,colorMessage$
Else
Color 255,255,255
Text 0,(i-1)*15,message(i)
End If
Next
Next


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdateChat()
Function UpdateChat()


key = GetKey()
key = GetKey()


If key
If key
If key = 13
If key = 13
If chatMessage <> localName + "> "
If chatMessage <> localName + "> "
For i = Len(localName + "> ") To Len(chatMessage)
For i = Len(localName + "> ") To Len(chatMessage)
If Mid(chatMessage,i,1) <> " "
If Mid(chatMessage,i,1) <> " "
chatColor$ = RGB_To_TriHex(cR,cG,cB)
chatMessage = chatMessage + "¿" + chatColor$
Net_SendMessage(1,chatMessage)
Net_SendMessage(1,chatMessage)
NewMessage(chatMessage)
NewMessage(chatMessage)
Exit
Exit
EndIf
EndIf
Next
Next
EndIf
EndIf
chatMessage = localName + "> "
chatMessage = localName + "> "
chatMode = 0
chatMode = 0
ElseIf key = 8 And Len(chatMessage) > Len ( localName + "> " )
ElseIf key = 8 And Len(chatMessage) > Len ( localName + "> " )
chatMessage = Left(chatMessage,Len(chatMessage)-1)
chatMessage = Left(chatMessage,Len(chatMessage)-1)
ElseIf key > 31 And key < 127
ElseIf key > 31 And key < 127
chatMessage = chatMessage + Chr(key)
chatMessage = chatMessage + Chr(key)
EndIf
EndIf
EndIf
EndIf
Color 255,255,255
Color 255,255,255
Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,1
Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,1
Color 0,0,0
Color 0,0,0
Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,0
Rect 0,GraphicsHeight()-20,GraphicsWidth(),20,0
If MilliSecs()-chatMillisecs > 500
If MilliSecs()-chatMillisecs > 500
chatCursor = Not chatCursor
chatCursor = Not chatCursor
chatMillisecs = MilliSecs()
chatMillisecs = MilliSecs()
EndIf
EndIf
If chatCursor
If chatCursor
Text 5,GraphicsHeight()-17,chatMessage + "|"
Text 5,GraphicsHeight()-17,chatMessage + "|"
Else
Else
Text 5,GraphicsHeight()-17,chatMessage
Text 5,GraphicsHeight()-17,chatMessage
EndIf
EndIf


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function DrawScoreTable()
Function DrawScoreTable()


For p.player = Each player
For p.player = Each player
count = count + 1
count = count + 1
Next
Next
baseX = (GraphicsWidth()-350)/2
baseX = (GraphicsWidth()-350)/2
baseY = (GraphicsHeight()-(35+20*count))/2
baseY = (GraphicsHeight()-(35+20*count))/2


Color 0,0,0
Color 0,0,0
Rect baseX,baseY,350,35+20*count,1
Rect baseX,baseY,350,35+20*count,1


Color 255,192,0
Color 255,192,0
Rect baseX,baseY,350,35+20*count,0
Rect baseX,baseY,350,35+20*count,0


Text baseX+10,baseY+10,"Player Kills Deaths Ping"
Text baseX+10,baseY+10,"Player Kills Deaths Ping"
Line baseX,baseY+25,baseX+349,baseY+25
Line baseX,baseY+25,baseX+349,baseY+25


For p.player = Each player
For p.player = Each player
Color 255,255,255
Color 255,255,255
If p\id = localID Then Color 255,100,100
If p\id = localID Then Color 255,100,100
i = i + 1
i = i + 1
Text baseX+10,baseY+10+20*i,p\name
Text baseX+10,baseY+10+20*i,p\name
Text baseX+157,baseY+10+20*i,p\kills,1,0
Text baseX+157,baseY+10+20*i,p\kills,1,0
Text baseX+240,baseY+10+20*i,p\deaths,1,0
Text baseX+240,baseY+10+20*i,p\deaths,1,0
Text baseX+322,baseY+10+20*i,p\ping,1,0
Text baseX+322,baseY+10+20*i,p\ping,1,0
Next
Next


End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function UpdateChaseCam(camera,player) ; thanks to jfk EO-11110 on bb forums for this function !
Function UpdateChaseCam(camera,player) ; thanks to jfk EO-11110 on bb forums for this function !
PositionEntity camera,EntityX(player,1),EntityY(player,1),EntityZ(player,1)
PositionEntity camera,EntityX(player,1),EntityY(player,1),EntityZ(player,1)
ResetEntity camera
ResetEntity camera
x#=EntityX(player)+Sin(-EntityYaw(player)+180)*x_dis#
x#=EntityX(player)+Sin(-EntityYaw(player)+180)*x_dis#
y#=EntityY(player)+y_dis#
y#=EntityY(player)+y_dis#
z#=EntityZ(player)+Cos(-EntityYaw(player)+180)*z_dis#
z#=EntityZ(player)+Cos(-EntityYaw(player)+180)*z_dis#
obstacle=LinePick(EntityX(player),EntityY(player),EntityZ(player),(x-EntityX(player)),y_dis#,(z-EntityZ(player)),0.1)
obstacle=LinePick(EntityX(player),EntityY(player),EntityZ(player),(x-EntityX(player)),y_dis#,(z-EntityZ(player)),0.1)
If obstacle=0
If obstacle=0
new_x#=x
new_x#=x
new_y#=y
new_y#=y
new_z#=z
new_z#=z
Else
Else
new_x#=PickedX()
new_x#=PickedX()
new_y#=PickedY()
new_y#=PickedY()
new_z#=PickedZ()
new_z#=PickedZ()
EndIf
EndIf
If bounce_cam=0
If bounce_cam=0
PositionEntity camera,new_x,new_y,new_z
PositionEntity camera,new_x,new_y,new_z
Else
Else
x=old_x+((New_x-old_x)/bounce_div#)
x=old_x+((New_x-old_x)/bounce_div#)
y=old_y+((New_y-old_y)/bounce_div#)
y=old_y+((New_y-old_y)/bounce_div#)
z=old_z+((New_z-old_z)/bounce_div#)
z=old_z+((New_z-old_z)/bounce_div#)
PositionEntity camera,x,y,z
PositionEntity camera,x,y,z
EndIf
EndIf
PointEntity camera,player
PointEntity camera,player
TurnEntity camera,-20,0,0 ; if you want the player mesh more on the bottom of the screen
TurnEntity camera,-20,0,0 ; if you want the player mesh more on the bottom of the screen
old_x#=EntityX(camera)
old_x#=EntityX(camera)
old_y#=EntityY(camera)
old_y#=EntityY(camera)
old_z#=EntityZ(camera)
old_z#=EntityZ(camera)
End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CreateScene()
Function CreateScene()


texture = TextureCreate(128)
texture = TextureCreate(128)
ground = CreatePlane()
ground = CreatePlane()
EntityColor ground,150,150,150
EntityColor ground,150,150,150
EntityTexture ground,texture
EntityTexture ground,texture
cube = CreateCube():EntityColor cube,150,200,150
cube = CreateCube():EntityColor cube,150,200,150
ScaleEntity cube,5,5,5:PositionEntity cube,0,5,0
ScaleEntity cube,5,5,5:PositionEntity cube,0,5,0
EntityTexture cube,texture
EntityTexture cube,texture
sphere = CreateSphere(16):EntityColor sphere,200,150,150
sphere = CreateSphere(16):EntityColor sphere,200,150,150
ScaleEntity sphere,3,1,3:PositionEntity sphere,0,9.7,0
ScaleEntity sphere,3,1,3:PositionEntity sphere,0,9.7,0
platform = CreateCube():EntityColor platform,150,150,200
platform = CreateCube():EntityColor platform,150,150,200
ScaleEntity platform,3,1,10:PositionEntity platform,0,4.13,-13.15
ScaleEntity platform,3,1,10:PositionEntity platform,0,4.13,-13.15
TurnEntity platform,-30,0,0
TurnEntity platform,-30,0,0
EntityTexture platform,texture
EntityTexture platform,texture
FreeTexture texture
FreeTexture texture
EntityType ground,1:EntityPickMode ground,2
EntityType ground,1:EntityPickMode ground,2
EntityType cube,1:EntityPickMode cube,2
EntityType cube,1:EntityPickMode cube,2
EntityType sphere,1:EntityPickMode sphere,2
EntityType sphere,1:EntityPickMode sphere,2
EntityType platform,1:EntityPickMode platform,2
EntityType platform,1:EntityPickMode platform,2


light = CreateLight()
light = CreateLight()
TurnEntity light,30,70,0
TurnEntity light,30,70,0
;; COLLISIONS
;; COLLISIONS
Collisions 2,1,2,3 ; player to scene
Collisions 2,1,2,3 ; player to scene
Collisions 2,2,1,3 ; player to player
Collisions 2,2,1,3 ; player to player
Collisions 3,1,2,1 ; bullet to scene
Collisions 3,1,2,1 ; bullet to scene
Collisions 3,2,1,1 ; bullet to player
Collisions 3,2,1,1 ; bullet to player
End Function
End Function


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function TextureCreate(size)
Function TextureCreate(size)
texture = CreateTexture(size,size,9)
texture = CreateTexture(size,size,9)
SetBuffer TextureBuffer(texture)
SetBuffer TextureBuffer(texture)
Color 255,255,255
Color 255,255,255
Rect 0,0,size,size,1
Rect 0,0,size,size,1
Color 0,0,0
Color 0,0,0
Rect 0,0,size,size,0
Rect 0,0,size,size,0
Line 0,0,size,size
Line 0,0,size,size
Line 0,size,size,0
Line 0,size,size,0
SetBuffer BackBuffer()
SetBuffer BackBuffer()
Return texture
Return texture
End Function
End Function