Woot! Have to check this out...
Code archives/Networking/FPSNetUpdate
This code has been declared by its author to be Public Domain code.
Download source code
| This is a fully networked FPS deathmatch game with server listing via Gnet. 3 weapons (Semi-Automatic, Shotgun, and Flamethrower) are included with various strengths and weaknesses. Everything is done using Blitz3D code with no extra media. The only additional library needed is Gnet which is included in the source code below. |
;====== FPSNet: A NETWORKED FIRST PERSON SHOOTER EXAMPLE ================== ;====== UTILIZING ONLY BUILT IN BLITZ3D FEATURES ========================== ;====== A CODESKETCH BY JEREMY ALESSI ===================================== ;====== THANKS MARK SIBLY FOR GNET ======================================== ;====== WASD OR CURSORS MOVE, MOUSE LOOKS, LEFT MOUSE BUTTON SHOOTS ======= ;====== SPACE BAR OR 0 ON NUMPAD JUMPS, PRESS C TO CHAT =================== ;====== PRESS 2 TO UNLOCK MOUSE FROM CENTER (USEFUL TO PLAY =============== ;====== AND ALSO BE ABLE TO MULTITASK IF NEED BE) PRESS 1 TO RELOCK ======= ;====== MOUSE BACK TO CENTER OF SCREEN ==================================== ;====== YEAH EVERYONE HAS THE SOURCE ... DON'T CHEAT! ===================== ;====== INCLUDES ========================================================== ;Include "gnet_inc.bb" This is included at the bottom of this source! ;========================================================================== ;====== GRAPHICS ========================================================== Graphics3D(640, 480, 16, 2) SetBuffer BackBuffer() HidePointer ;========================================================================== ;====== COLLISIONS ======================================================== Global BODY = 1 Global SCENE = 2 Collisions(BODY,SCENE, 2, 2) Collisions(BODY,BODY, 2, 2) ;========================================================================== ;====== GLOBALS =========================================================== Global gameState$ = "Title Screen" ;Mousehit Vars Global mb1pressed, mb2pressed ;Keyhit Vars Global upKeyPressed, downKeyPressed, leftKeyPressed, rightKeyPressed, enterKeyPressed, spaceKeyPressed Global chatKeyPressed ;Font Vars Global font, bigFont ;Menu Var Global menuCount ;Server Vars Global serverCount Global serverPointer ;Local Player Network Vars Global localPlayerName$, localPlayerPointer ;Scenery Vars Global level,copySprite, lightPivot ;Camera Var Global camera ;Player Gameplay Vars Global health#, shot, shot2, shot3, shotTimer#, positionUpdateTimer#, serverRefreshTimer#, hosting Global vX#, vY#, vZ#, oldX#, oldY#, oldZ#, centerMouse = True, enteringChat = False, chat$ Global copyPowerUp, weapon$ = "Semi-Automatic", powerUpSpawned, ammo# = 50, randPos, randNum Global justDied# ;========================================================================== ;====== INCOMING ========================================================== Dim incoming$(100) ;========================================================================== ;====== CONTENTS OF A KEY ================================================= Dim keys$(237) LoadKeyboardContent() ;========================================================================== ;====== SHOT ARRAY ======================================================== Dim pickedArray(3,3) ;========================================================================== ;====== TYPES ============================================================= Type Player Field iD, name$, mesh[10], score End Type Type Particle Field mesh, name$, alpha# Field vX#, vY#, vZ# End Type Type chatMsg Field msg$, born#, from End Type Type powerUp Field mesh, name$ End Type ;========================================================================== ;====== INITIAL SETUP ===================================================== Setup("Title Screen") ;========================================================================== ;========================================================================== .Main ;====== RUN =============================================================== period=1000 / 30 tweentime = MilliSecs()-period While 1 ;====== CALCULATE TWEEN =================================================== Repeat elapsed = MilliSecs() - tweentime Until elapsed ticks = elapsed/period tween# = Float(elapsed Mod period) / Float(period) ;========================================================================== ;====== MAIN LOOP ========================================================= For k=1 To ticks tweentime = tweentime+period If k = ticks Then CaptureWorld If KeyDown(1) If Not GNET_RemoveServer("FPSNetUpdate") If hosting = True RuntimeError "Failed to remove server" EndIf EndIf ClearWorld() End EndIf UpdateLogic() UpdateWorld Next RenderWorld(tween#) Draw() Flip Wend ;=========================================================================== ;====== UPDATE LOGIC ======================================================= Function UpdateLogic() Select gameState$ Case "Title Screen" UpdateTitleInput() UpdateTitleScreen() Case "Game" DetectPowerUpCollision() UpdateGameInput() ControlChat() UpdateLights() UpdateCamera() UpdatePlayerMovement() HostSpawnPowerups() UpdateParticles() UpdateNetwork() UpdateCenterMouse() End Select End Function ;=========================================================================== ;====== DRAW =============================================================== Function Draw() Select gameState$ Case "Title Screen" DrawTitleScreen() Case "Game" DrawGamePlay() End Select End Function ;=========================================================================== ;====== UPDATE TITLE INPUT ================================================= Function UpdateTitleInput() mb1pressed = MouseHit(1) mb2pressed = MouseHit(2) upKeyPressed = KeyHit(17) Or KeyHit(200) downKeyPressed = KeyHit(31) Or KeyHit(208) leftKeyPressed = KeyHit(30) Or KeyHit(203) rightKeyPressed = KeyHit(32) Or KeyHit(205) enterKeyPressed = KeyHit(28) spaceKeyPressed = KeyHit(57) End Function ;=========================================================================== ;====== UPDATE GAME INPUT ================================================== Function UpdateGameInput() chatKeyPressed = KeyHit(46) enterKeyPressed = KeyHit(28) End Function ;=========================================================================== ;====== UPDATE CENTER MOUSE ================================================ Function UpdateCenterMouse() If centerMouse = True MoveMouse(CorrectX(320), CorrectY(240)) EndIf If KeyHit(2) centerMouse = True EndIf If KeyHit(3) centerMouse = False EndIf End Function ;=========================================================================== ;====== UPDATE TITLE SCREEN ================================================ Function UpdateTitleScreen() If upKeyPressed And menuCount > 0 menuCount = menuCount - 1 EndIf If downKeyPressed And menuCount < serverCount - 1 menuCount = menuCount + 1 EndIf If enterKeyPressed gns.GNET_Server = Object.GNET_Server(serverPointer) If JoinNetGame(gns\server$, gns\ip$) FlushKeys Color(255,0,0) Locate(200,130) localPlayerName$ = Input("Name - ") Delay(500) FlushKeys p.Player = New Player localPlayerPointer = Handle(p.Player) p\iD = CreateNetPlayer(localPlayerName$) Setup("Game") hosting = False EndIf EndIf If spaceKeyPressed FlushKeys Color(255,0,0) Locate(200,130) localPlayerName$ = Input("Name - ") Delay(500) FlushKeys If HostNetGame(localPlayerName$) = 2 If GNET_AddServer("FPSNetUpdate", localPlayerName$) p.Player = New Player localPlayerPointer = Handle(p.Player) p\iD = CreateNetPlayer(localPlayerName$) Setup("Game") hosting = True serverRefreshTimer# = MilliSecs() Else RuntimeError("Failed to Add Server!") EndIf Else RuntimeError("Failed to Create Net Game!") EndIf EndIf End Function ;=========================================================================== ;====== UPDATE PLAYER MOVEMENT ============================================= Function UpdatePlayerMovement() If enteringChat Return p.Player = Object.Player(localPlayerPointer) oldX# = EntityX(p\mesh[1]) oldY# = EntityY(p\mesh[1]) oldZ# = EntityZ(p\mesh[1]) If KeyDown(17) Or KeyDown(200) MoveEntity(p\mesh[1], 0, 0, .5) EndIf If KeyDown(31) Or KeyDown(208) MoveEntity(p\mesh[1], 0, 0, -.5) EndIf If KeyDown(30) Or KeyDown(203) MoveEntity(p\mesh[1], -.5, 0, 0) EndIf If KeyDown(32) Or KeyDown(205) MoveEntity(p\mesh[1], .5, 0, 0) EndIf numColls = CountCollisions(p\mesh[1]) If numColls = 0 vY# = vY# - .01 Else vY# = 0 EndIf If (KeyDown(57) Or KeyDown(82)) And numColls > 0 vY# = .2 EndIf TranslateEntity(p\mesh[1],0, vY#, 0) RotateEntity(p\mesh[1], 0, EntityYaw(p\mesh[1]) - MouseXSpeed(), 0) vX# = EntityX(p\mesh[1]) - oldX# vY# = EntityY(p\mesh[1]) - oldY# vZ# = EntityZ(p\mesh[1]) - oldZ# End Function ;=========================================================================== ;====== UPDATE LIGHTS ====================================================== Function UpdateLights() TurnEntity(lightPivot, 0, 10, 0) End Function ;=========================================================================== ;====== UPDATE CAMERA ====================================================== Function UpdateCamera() p.Player = Object.Player(localPlayerPointer) shot = 0 shot2 = 0 shot3 = 0 If MouseDown(1) Select weapon$ Case "Semi-Automatic" If shotTimer# + 200 < MilliSecs() And ammo# > 0 ammo# = ammo# - 1 shot = CameraPick(camera, CorrectX(320), CorrectY(240)) shotTimer# = MilliSecs() If shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 50, 50, 50, 10) SendNetMsg(4,"1," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf Case "Shotgun" If shotTimer# + 750 < MilliSecs() And ammo# >= 3 ammo# = ammo# - 3 For i = 1 To 3 Select i Case 1 shot = CameraPick(camera, CorrectX(320 - 20), CorrectY(240)) Case 2 shot2 = CameraPick(camera, CorrectX(320), CorrectY(240)) Case 3 shot3 = CameraPick(camera, CorrectX(320 + 20), CorrectY(240)) End Select pickedArray(i,1) = PickedX() pickedArray(i,2) = PickedY() pickedArray(i,3) = PickedZ() Next shotTimer# = MilliSecs() If shot Or shot2 Or shot3 For i = 1 To 3 If (i = 1 And shot <> 0) Or (i = 2 And shot2 <> 0) Or (i = 3 And shot3 <> 0) CreateSomeParticles(pickedArray(i,1), pickedArray(i,2), pickedArray(i,3), 200, 200, 200, 10) EndIf Next SendNetMsg(4,"2," + pickedArray(1,1) + "," + pickedArray(1,2) + "," + pickedArray(1,3) + "," + pickedArray(2,1) + "," + pickedArray(2,2) + "," + pickedArray(2,3) + "," + pickedArray(3,1) + "," + pickedArray(3,2) + "," + pickedArray(3,3) + "-", p\iD, 0, 0) EndIf EndIf Case "Flamethrower" If shotTimer# + 50 < MilliSecs() And ammo# >= .1 ammo# = ammo# - .1 pvX# = vX# + (EntityX(p\mesh[3], True) - EntityX(p\mesh[2], True)) / 10 pvY# = vY# + (EntityY(p\mesh[3], True) - EntityY(p\mesh[2], True)) / 10 pvZ# = vZ# + (EntityZ(p\mesh[3], True) - EntityZ(p\mesh[2], True)) / 10 SendNetMsg(9, pvX# + "," + pvY# + "," + pvZ# + "-", p\iD, 0, 0) CreateSomeParticles(EntityX(p\mesh[2],True), EntityY(p\mesh[2], True), EntityZ(p\mesh[2], True), 255, 200, 100, 10, pvX# + Rnd(-.05, .05), pvY# + Rnd(-.05, .05), pvZ#, "Flame") shot = LinePick(EntityX(camera, True), EntityY(camera, True), EntityZ(camera, True), EntityX(p\mesh[3], True) - EntityX(camera, True), EntityY(p\mesh[3], True) - EntityY(camera, True), EntityZ(p\mesh[3], True) - EntityZ(camera, True)) shotTimer# = MilliSecs() If shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 200, 100, 10, "Flame") SendNetMsg(4,"3," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf End Select EndIf RotateEntity(camera,EntityPitch(camera) + MouseYSpeed(),0,0) If EntityPitch(camera) > 90 RotateEntity(camera, 90, 0, 0) EndIf If EntityPitch(camera) < - 90 RotateEntity(camera, -90, 0, 0) EndIf End Function ;=========================================================================== ;====== UPDATE NETWORK ===================================================== Function UpdateNetwork() While RecvNetMsg() Select NetMsgType() Case 1 For p.Player = Each Player If p\iD = NetMsgFrom() DecodeIncomingMessage(NetMsgData$()) PositionEntity(p\mesh[1], incoming$(1), incoming$(2), incoming$(3)) RotateEntity(p\mesh[1], incoming$(4), incoming$(5), 0) If incoming$(6) <> "" p\score = incoming$(6) EndIf EndIf Next Case 2 p.Player = Object.Player(localPlayerPointer) CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 10) If justDied# + 500 < MilliSecs() DecodeIncomingMessage(NetMsgData$()) Select incoming$(1) Case 1 health# = health# - 5 Case 2 count = 0 If incoming$(2) <> 0 count = count + 1 EndIf If incoming$(3) <> 0 count = count + 1 EndIf If incoming$(4) <> 0 count = count + 1 EndIf health# = health# - (5 * count) Case 3 health# = health# - 25 End Select EndIf If health# <= 0 health# = 100 PositionEntity(p\mesh[1],5,1,Rand(0, 50)) SendNetMsg(3, "1", p\iD, NetMsgFrom(), 1) CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 100) SendNetMsg(5, "1",p\iD, 0, 0) justDied# = MilliSecs() EndIf Case 3 p.Player = Object.Player(localPlayerPointer) p\score = p\score + 1 Case 4 DecodeIncomingMessage(NetMsgData$()) Select incoming$(1) Case 1 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 50, 50, 50, 10) Case 2 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 255, 255, 255, 10) CreateSomeParticles(incoming$(5), incoming$(6), incoming$(7), 255, 255, 255, 10) CreateSomeParticles(incoming$(8), incoming$(9), incoming$(10), 255, 255, 255, 10) Case 3 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 255, 200, 100, 10) End Select Case 5 For p.Player = Each Player If p\iD = NetMsgFrom() CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 100) EndIf Next Case 6 c.chatMsg = New chatMsg c\msg = NetMsgData$() c\born# = MilliSecs() c\from = NetMsgFrom() Case 7 DecodeIncomingMessage(NetMsgData$()) pup.powerUp = New powerUp pup\mesh = CopyEntity(copyPowerup) powerUpSpawned = True PositionEntity(pup\mesh, EntityX(GetChild(level, incoming$(1)), True), EntityY(GetChild(level, incoming$(1)), True) + 2, EntityZ(GetChild(level, incoming$(1)), True)) Select incoming$(2) Case 1 pup\name$ = "Semi-Automatic" EntityColor(pup\mesh, 255, 255, 255) Case 2 pup\name$ = "Shotgun" EntityColor(pup\mesh, 100, 100, 255) Case 3 pup\name$ = "Flamethrower" EntityColor(pup\mesh, 200, 150, 100) End Select randPos = incoming$(1) randNum = incoming$(2) Case 8 For pup.powerUp = Each powerUP FreeEntity(pup\mesh) Delete(pup) Next powerUpSpawned = False Case 9 For op.Player = Each Player If op\iD = NetMsgFrom() DecodeIncomingMessage(NetMsgData$()) CreateSomeParticles(EntityX(op\mesh[2],True), EntityY(op\mesh[2], True), EntityZ(op\mesh[2], True), 255, 200, 100, 10, incoming$(1) + Rnd(-.05, .05), incoming$(2) + Rnd(-.05, .05), incoming$(3), "Flame") EndIf Next Case 100 p.Player = New Player p\iD = NetMsgFrom() p\mesh[1] = CreateSphere(8) p\name$ = NetPlayerName$(p\iD) EntityColor(p\mesh[1], 0, 255, 0) PositionEntity(p\mesh[1], 5, 1.5, Rand(50,100)) EntityType(p\mesh[1],BODY) EntityRadius(p\mesh[1], 1.5) EntityPickMode(p\mesh[1], 2) p\mesh[2] = CreateCube(p\mesh[1]) PositionEntity(p\mesh[2], 1, -.5, 1) ScaleEntity(p\mesh[2], .1, .1, .4) EntityColor(p\mesh[2], 20, 20, 20) p\mesh[3] = CreatePivot(p\mesh[1]) PositionEntity(p\mesh[3], 0, 0, 5) If hosting p.Player = Object.Player(localPlayerPointer) SendNetMsg(7, randPos + "," + randNum + "-", p\iD#, NetMsgFrom(), 1) EndIf Case 101 For p.Player = Each Player If p\iD = NetMsgFrom() FreeEntity(p\mesh[1]) Delete(p) EndIf Next Case 102 GNET_AddServer("FPSNetUpdate", localPlayerName$) hosting = True End Select Wend p.Player = Object.Player(localPlayerPointer) If positionUpdateTimer# + 50 < MilliSecs() SendNetMsg(1, EntityX(p\mesh[1]) + "," + EntityY(p\mesh[1]) + "," + EntityZ(p\mesh[1]) + "," + EntityPitch(camera) + "," + EntityYaw(p\mesh[1]) + "," + p\score + "-", p\iD, 0, 0) positionUpdateTimer# = MilliSecs() EndIf For op.Player = Each Player Select weapon$ Case "Semi-Automatic" If shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(2, "1-", p\iD, op\iD, 0) EndIf Case "Shotgun" If shot = op\mesh[1] Or shot2 = op\mesh[1] Or shot3 = op\mesh[1] Select op\mesh[1] Case shot CreateSomeParticles(pickedArray(1, 1), pickedArray(1, 2), pickedArray(1, 3), 255, 0, 0, 10) Case shot2 CreateSomeParticles(pickedArray(2, 1), pickedArray(2, 2), pickedArray(2, 3), 255, 0, 0, 10) Case shot3 CreateSomeParticles(pickedArray(3, 1), pickedArray(3, 2), pickedArray(3, 3), 255, 0, 0, 10) End Select SendNetMsg(2, "2," + Left(Str(shot), 1) + "," + Left(Str(shot2), 1) + "," + Left(Str(shot3), 1) + "-", p\iD, op\iD, 0) EndIf Case "Flamethrower" If shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(2, "3-", p\iD, op\iD, 0) EndIf End Select Next If hosting = True If serverRefreshTimer# + 250000 < MilliSecs() GNET_RefreshServer( "FPSNetUpdate",localPlayerName$ ) serverRefreshTimer# = MilliSecs() EndIf EndIf End Function ;=========================================================================== ;====== UPDATE PARTICLES =================================================== Function UpdateParticles() For p.Particle = Each Particle If p\alpha# <= 0 FreeEntity(p\mesh) Delete(p) Else Select p\name$ Case "Flame" TranslateEntity(p\mesh,p\vX#, p\vY#, p\vZ# ) p\alpha# = p\alpha# - Rnd(.3) EntityAlpha(p\mesh, p\alpha#) Default p\vY# = p\vY# - .01 TranslateEntity(p\mesh,p\vX#, p\vY#, p\vZ#) p\alpha# = p\alpha# - .02 EntityAlpha(p\mesh, p\alpha#) End Select EndIf Next End Function ;=========================================================================== ;====== DRAW TITLE SCREEN ================================================== Function DrawTitleScreen() Cls FPSNetText(font, 320, 0, String$("+",80), 1, 1, 100, 100, 100) FPSNetText(font, 320, 480, String$("+",80), 1, 1, 100, 100, 100) For i = 0 To 640 Step 640 For j = 10 To 470 Step 10 FPSNetText(font, i, j, "+", 1, 1, 100, 100, 100) Next Next FPSNetText(bigFont, 320, 30, "FPSNet:", 1, 1, 255, 0, 0) FPSNetText(font, 320, 60, "A NETWORKED First Person Shooter Example", 1, 1, 100, 100, 100) FPSNetText(font, 320, 80, "Press Up/Down to Select a Game to Join!", 1, 1, 100, 100, 100) FPSNetText(font, 320, 100, "Press Space to Host a New Game!", 1, 1, 100, 100, 100) FPSNetText(font, 320, 120, "Games In Progress:" , 1, 1, 200, 255, 150) serverCount = 0 For gns.GNET_Server = Each GNET_Server Select serverCount Case menuCount FPSNetText(font, 320, 160 + 20 * serverCount, gns\server$ + " - Press Enter to Join ...", 1, 1, 255, 255, 255) serverPointer = Handle(gns) Default FPSNetText(font, 320, 160 + 20 * serverCount, gns\server$, 1, 1, 100, 100, 100) End Select serverCount = serverCount + 1 Next End Function ;=========================================================================== ;====== DRAW GAMEPLAY ====================================================== Function DrawGamePlay() Select weapon$ Case "Semi-Automatic" FPSNetText(font, 320, 240, "+", 1, 1, 255, 255, 255) Case "Shotgun" FPSNetText(font, 300, 240, "+", 1, 1, 255, 255, 255) FPSNetText(font, 320, 240, "+", 1, 1, 255, 255, 255) FPSNetText(font, 340, 240, "+", 1, 1, 255, 255, 255) Case "Flamethrower" FPSNetText(font, 320, 240, "()", 1, 1, 255, 200, 100) End Select p.Player = Object.Player(localPlayerPointer) FPSNetText(font, 0, 0, "Your Score: " + p\score, 0, 0, 255, 0, 0) FPSNetText(font, 150, 0, "Health: ", 0, 0, 0, 255, 0) Color(255, 0, 0) Rect(CorrectX(221), CorrectY(4), CorrectX(health#), CorrectY(10), 1) Color(255, 255, 255) Rect(CorrectX(220), CorrectY(2), CorrectX(102), CorrectY(14), 0) FPSNetText(font, 400, 0, "Ammo: " + Int(ammo#), 0, 0, 255, 255, 255) printI = 50 For c.chatMsg = Each chatMsg secondsAround = (MilliSecs() - c\born#) / 50 FPSNetText(font, 0, 0 + printI, NetPlayerName(c\from) + " - " + c\msg$, 0, 0, 255 - secondsAround, 255 - secondsAround, 255 - secondsAround) printI = printI + 15 Next If enteringChat = True FPSNetText(font, 0, 460, localPlayerName$ + " - " + chat$, 0, 0, 255, 255, 255) EndIf For p.Player = Each Player If Handle(p.Player) <> localPlayerPointer CameraProject(camera, EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1])) FPSNetText(font, ProjectedX(), ProjectedY() - 20, p\name$ + " - " + p\score, 1, 1, 255, 255, 255) EndIf Next End Function ;=========================================================================== ;====== DETECT POWERUP COLLISION =========================================== Function DetectPowerUpCollision() If Not powerUpSpawned Return p.Player = Object.Player(localPlayerPointer) For pup.powerUp = Each powerUp If EntityDistance(p\mesh[1], pup\mesh) < 3 If weapon$ = pup\name$ Select weapon$ Case "Semi-Automatic" ammo# = ammo# + 50 Case "Shotgun" ammo# = ammo# + 45 Case "Flamethrower" ammo# = ammo# + 30 End Select Else Select pup\name$ Case "Semi-Automatic" ammo# = 50 Case "Shotgun" ammo# = 45 Case "Flamethrower" ammo# = 30 End Select EndIf weapon$ = pup\name$ powerUpSpawned = False FreeEntity(pup\mesh) Delete(pup) SendNetMsg(8, "", p\iD, 0, 1) EndIf Next End Function ;=========================================================================== ;====== HOST SPAWN POWERUPS ================================================ Function HostSpawnPowerups() If (Not hosting) Or (powerUpSpawned) Return EndIf randPos = Rand(1, CountChildren(level)) pup.powerUp = New powerUp pup\mesh = CopyEntity(copyPowerUp) PositionEntity(pup\mesh, EntityX(GetChild(level, randPos), True), EntityY(GetChild(level, randPos), True) + 2, EntityZ(GetChild(level, randPos), True)) randNum = Rand(1,3) Select randNum Case 1 pup\name$ = "Semi-Automatic" EntityColor(pup\mesh, 255, 255, 255) Case 2 pup\name$ = "Shotgun" EntityColor(pup\mesh, 100, 100, 255) Case 3 pup\name$ = "Flamethrower" EntityColor(pup\mesh, 200, 150, 100) End Select p.Player = Object.Player(localPlayerPointer) SendNetMsg(7, randPos + "," + randNum + "-", p\iD#, 0, 1) powerUpSpawned = True End Function ;=========================================================================== ;====== CONTROL CHAT ======================================================= Function ControlChat() If chatKeyPressed enteringChat = True FlushKeys EndIf If enterKeyPressed And enteringChat = True p.Player = Object.Player(localPlayerPointer) c.chatMsg = New chatMsg c\msg$ = chat$ c\born# = MilliSecs() c\from = p\iD SendNetMsg(6, chat$, p\iD , 0, 0) chat$ = "" enteringChat = False EndIf If enteringChat = True EnterChat() EndIf For c.chatMsg = Each chatMsg If c\born# + 10000 < MilliSecs() Delete(c) EndIf Next End Function ;=========================================================================== ;====== CREATE SOME ParticleS ============================================== Function CreateSomeParticles(x#, y#, z#, r, g, b, numParticles, optvX# = 0, optvY# = 0, optvZ# = 0, passedName$ = "") For i = 1 To numParticles p.Particle = New Particle p\mesh = CopyEntity(copySprite) If passedName$ <> "" p\name$ = passedName$ EndIf PositionEntity(p\mesh,x#, y#, z#, True) EntityColor(p\mesh, r, g, b) If optvX# = 0 p\vX# = Rnd(-.2, .2) Else p\vx# = optvX# EndIf If optvY# = 0 p\vY# = Rnd(.2) Else p\vY# = optvY# EndIf If optvZ# = 0 p\vZ# = Rnd(-.2, .2) Else p\vZ# = optvZ# EndIf p\alpha = 1 Next End Function ;=========================================================================== ;====== SETUP ============================================================== Function Setup(mode$) Select mode$ Case "Title Screen" font = LoadFont("Arial",20,1) bigFont = LoadFont("Arial",50,1) GNET_ListServers() Case "Game" gameState$ = "Game" p.Player = Object.Player(localPlayerPointer) p\mesh[1] = CreatePivot() PositionEntity(p\mesh[1], 5, 1.5, Rand(0, 50)) EntityType(p\mesh[1],BODY) EntityRadius(p\mesh[1], 1.5) health# = 100 p\score = 0 p\name$ = localPlayerName$ camera = CreateCamera(p\mesh[1]) CameraRange(camera,.1, 500) p\mesh[2] = CreateCube(camera) PositionEntity(p\mesh[2], 1, -.5, 1) ScaleEntity(p\mesh[2], .1, .1, .4) EntityColor(p\mesh[2], 20, 20, 20) p\mesh[3] = CreatePivot(camera) PositionEntity(p\mesh[3], 0, 0, 5) LoadLevel() PointEntity(p\mesh[1], level) MoveMouse(CorrectX(320), CorrectY(240)) End Select End Function ;=========================================================================== ;====== LOAD LEVEL ========================================================= Function LoadLevel() copyPowerUp = CreateSphere() HideEntity(copyPowerUp) copySprite = CreateSprite() ScaleSprite(copySprite, .1, .1) EntityFX(copySprite, 1+8) HideEntity(copySprite) level = CreatePlane(16) EntityPickMode(level, 2) For i = -1 To 1 Step 2 For j = -4 To 4 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube, 100, 100, 100) PositionEntity(cube, i * 10, 1, j * 10) Next Next For i = 1 To 8 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube,100,100,100) PositionEntity(cube, 0, i * 2, i * 5) Next For i = 1 To 8 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube,100,100,100) PositionEntity(cube, 0, i * 2, i * -5) Next EntityType(level,SCENE) lightPivot = CreatePivot() NameEntity(lightPivot,"Light Pivot") light = CreateLight(3,lightPivot) NameEntity(light, "light1") PositionEntity(light,25, 25, 0) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 255, 0, 0) light = CreateLight(3,lightPivot) NameEntity(light, "light2") PositionEntity(light,-25, 25, 0) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 0, 0, 255) light = CreateLight(3,lightPivot) NameEntity(light, "light3") PositionEntity(light,0, 25, 25) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 0, 255, 0) End Function ;=========================================================================== ;====== FPSNET TEXT ======================================================== Function FPSNetText(fontType, X, Y, theText$, centerX = 0, centerY = 0,r = 255, g = 255, b = 255) Color(r, g, b) SetFont(fontType) Text(CorrectX(X), CorrectY(Y), theText$, centerX, centerY) End Function ;========================================================================== ;====== CORRECTX ========================================================== Function CorrectX(pixel) Return (pixel * GraphicsWidth() / 640) End Function ;========================================================================== ;====== CORRECTY ========================================================== Function CorrectY(pixel) Return (pixel * GraphicsHeight() / 480) End Function ;========================================================================== ;====== DECODE INCOMING MESSAGE =========================================== Function DecodeIncomingMessage(message$) For i = 1 To 100 incoming$(i) = "" Next i = 1 part = 1 incoming$(part) = Mid(message$, i, 1) i = i + 1 While Mid(message$, i, 1)<>"-" While Mid(message$, i, 1)<>"," incoming$(part)=incoming$(part)+Mid(message$, i, 1) i = i + 1 If Mid(message$, i, 1)="-" Exit EndIf Wend If Mid(message$, i, 1)="," i = i + 1 part = part + 1 incoming$(part) = Mid(message$, i, 1) i = i + 1 EndIf Wend End Function ;========================================================================== ;====== ENTER CHAT ======================================================== Function EnterChat() For i = 1 To 237 If (i >= 2 And i <= 11) Or (i >= 16 And i <= 25) Or (i >= 30 And i <= 38) Or (i >= 44 And i <= 50) If KeyHit(i) If Len(chat$) <= 25 chat$ = chat$ + keys$(i) EndIf EndIf EndIf Next If KeyHit(14) And Len(chat$) >= 1 And keytimer# + 100 < MilliSecs() chat$ = Left(chat$,Len(chat$) - 1) keytimer# = MilliSecs() EndIf If KeyHit(211) And Len(chat$) >= 1 And keytimer# + 100 < MilliSecs() chat$ = Right(chat$,Len(chat$) - 1) keytimer# = MilliSecs() EndIf If KeyHit(57) And Len(chat$) <= 25 And keytimer# + 100 < MilliSecs() chat$ = chat$ + " " keytimer# = MilliSecs() EndIf If KeyHit(53) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "?" EndIf If KeyHit(2) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "!" EndIf If KeyHit(3) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "@" EndIf If KeyHit(4) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "#" EndIf If KeyHit(5) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "$" EndIf If KeyHit(6) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "%" EndIf If KeyHit(7) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "^" EndIf If KeyHit(8) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "&" EndIf If KeyHit(9) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "*" EndIf If KeyHit(10) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "(" EndIf If KeyHit(11) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + ")" EndIf If KeyHit(12) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "-" EndIf If KeyHit(13) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "+" EndIf If KeyHit(40) chat$ = chat$ + "'" EndIf If KeyHit(51) chat$ = chat$ + "," EndIf End Function ;========================================================================== ;===== KEYS CONTENT ======================================================= Function LoadKeyboardContent() keys$(1) = "ESCAPE" keys$(2) = "1" keys$(3) = "2" keys$(4) = "3" keys$(5) = "4" keys$(6) = "5" keys$(7) = "6" keys$(8) = "7" keys$(9) = "8" keys$(10) = "9" keys$(11) = "0" keys$(12) = "-" keys$(13) = "=" keys$(14) = "BACKSPACE" keys$(15) = "TAB" keys$(16) = "Q" keys$(17) = "W" keys$(18) = "E" keys$(19) = "R" keys$(20) = "T" keys$(21) = "Y" keys$(22) = "U" keys$(23) = "I" keys$(24) = "O" keys$(25) = "P" keys$(26) = "[" keys$(27) = "]" keys$(28) = "ENTER" keys$(29) = "LEFTCONTROL" keys$(30) = "A" keys$(31) = "S" keys$(32) = "D" keys$(33) = "F" keys$(34) = "G" keys$(35) = "H" keys$(36) = "J" keys$(37) = "K" keys$(38) = "L" keys$(39) = ";" keys$(40) = "'" keys$(41) = "GRAVE" keys$(42) = "LEFTSHIFT" keys$(43) = "BACKSLASH(\)" keys$(44) = "Z" keys$(45) = "X" keys$(46) = "C" keys$(47) = "V" keys$(48) = "B" keys$(49) = "N" keys$(50) = "M" keys$(51) = "COMMA(,)" keys$(52) = "PERIOD(.)" keys$(53) = "SLASH(/)" keys$(54) = "RIGHTSHIFT" keys$(55) = "MULTIPLY(*)NUMPAD" keys$(56) = "LEFTALT/MENU" keys$(57) = "SPACE" keys$(58) = "CAPITAL" keys$(59) = "F1" keys$(60) = "F2" keys$(61) = "F3" keys$(62) = "F4" keys$(63) = "F5" keys$(64) = "F6" keys$(65) = "F7" keys$(66) = "F8" keys$(67) = "F9" keys$(68) = "F10" keys$(69) = "NUMLOCK" keys$(70) = "SCROLLLOCK" keys$(71) = "NUMPAD7" keys$(72) = "NUMPAD8" keys$(73) = "NUMPAD9" keys$(74) = "SUBTRACT(-)NUMPAD" keys$(75) = "NUMPAD4" keys$(76) = "NUMPAD5" keys$(77) = "NUMPAD6" keys$(78) = "ADD(+)NUMPAD" keys$(79) = "NUMPAD1" keys$(80) = "NUMPAD2" keys$(81) = "NUMPAD3" keys$(82) = "NUMPAD0" keys$(83) = "DECIMAL(.)NUMPAD" keys$(84) = "-" keys$(85) = "-" keys$(86) = "OEM_102" keys$(87) = "F11" keys$(88) = "F12" keys$(89) = "-" keys$(90) = "-" keys$(91) = "-" keys$(92) = "-" keys$(93) = "-" keys$(94) = "-" keys$(95) = "-" keys$(96) = "-" keys$(97) = "-" keys$(98) = "-" keys$(99) = "-" keys$(100) = "F13" keys$(101) = "F14" keys$(102) = "F15" keys$(103) = "-" keys$(104) = "-" keys$(105) = "-" keys$(106) = "-" keys$(107) = "-" keys$(108) = "-" keys$(109) = "-" keys$(110) = "-" keys$(111) = "-" keys$(112) = "KANA" keys$(113) = "-" keys$(114) = "-" keys$(115) = "ABNT_C1" keys$(116) = "-" keys$(117) = "-" keys$(118) = "-" keys$(119) = "-" keys$(120) = "-" keys$(121) = "CONVERT" keys$(122) = "-" keys$(123) = "NOCONVERT" keys$(124) = "-" keys$(125) = "YEN" keys$(126) = "ABNT_C2" keys$(127) = "-" keys$(128) = "-" keys$(129) = "-" keys$(130) = "-" keys$(131) = "-" keys$(132) = "-" keys$(133) = "-" keys$(134) = "-" keys$(135) = "-" keys$(136) = "-" keys$(137) = "-" keys$(138) = "-" keys$(139) = "-" keys$(140) = "-" keys$(141) = "EQUALS" keys$(142) = "-" keys$(143) = "-" keys$(144) = "PREVTRACK" keys$(145) = "AT" keys$(146) = "COLON(:)" keys$(147) = "UNDERLINE" keys$(148) = "KANJI" keys$(149) = "STOP" keys$(150) = "AX" keys$(151) = "UNLABELED" keys$(152) = "-" keys$(153) = "NEXTTRACK" keys$(154) = "-" keys$(155) = "-" keys$(156) = "ENTER (NUMPAD)" keys$(157) = "RIGHTCONTROL" keys$(158) = "-" keys$(159) = "-" keys$(160) = "MUTE" keys$(161) = "CALCULATOR" keys$(162) = "PLAY/PAUSE" keys$(163) = "-" keys$(164) = "MEDIASTOP" keys$(165) = "-" keys$(166) = "-" keys$(167) = "-" keys$(168) = "-" keys$(169) = "-" keys$(170) = "-" keys$(171) = "-" keys$(172) = "-" keys$(173) = "-" keys$(174) = "VOLUMEDOWN" keys$(175) = "-" keys$(176) = "VOLUMEUP" keys$(177) = "-" keys$(178) = "WEBHOME" keys$(179) = "COMMA(,)" keys$(180) = "-" keys$(181) = "DIVIDE(/)" keys$(182) = "-" keys$(183) = "SYSREQ" keys$(184) = "RIGHTALT/MENU" keys$(185) = "-" keys$(186) = "-" keys$(187) = "-" keys$(188) = "-" keys$(189) = "-" keys$(190) = "-" keys$(191) = "-" keys$(192) = "-" keys$(193) = "-" keys$(194) = "-" keys$(195) = "-" keys$(196) = "-" keys$(197) = "PAUSE" keys$(198) = "-" keys$(199) = "HOME" keys$(200) = "UP" keys$(201) = "PAGEUP/PRIOR" keys$(202) = "-" keys$(203) = "LEFT" keys$(204) = "-" keys$(205) = "RIGHT" keys$(206) = "-" keys$(207) = "END" keys$(208) = "DOWN" keys$(209) = "NEXT" keys$(210) = "INSERT" keys$(211) = "DELETE" keys$(212) = "-" keys$(213) = "-" keys$(214) = "-" keys$(215) = "-" keys$(216) = "-" keys$(217) = "-" keys$(218) = "-" keys$(219) = "LEFTWINDWOS" keys$(220) = "RIGHTWINDOWS" keys$(221) = "APPS" keys$(222) = "POWER" keys$(223) = "SLEEP" keys$(224) = "-" keys$(225) = "-" keys$(226) = "-" keys$(227) = "WAKE" keys$(228) = "-" keys$(229) = "WEBSEARCH" keys$(230) = "WEBFAVORITES" keys$(231) = "WEBREFRESH" keys$(232) = "WEBSTOP" keys$(233) = "WEBFORWARD" keys$(234) = "WEBBACK" keys$(235) = "MYCOMPUTER" keys$(236) = "MAIL" keys$(237) = "MEDIASELECT" End Function ;========================================================================== ;====== GNET SOURCE CODE ================================================== Const GNET_HOST$="www.blitzbasic.com" Const GNET_PORT=80 Const GNET_GET$="/gnet/gnet.php" Type GNET_Server Field game$,server$,ip$ End Type Function GNET_Esc$( t$ ) t$=Replace$( t$,"&","" ) t$=Replace$( t$,"%","" ) t$=Replace$( t$,"'","" ) t$=Replace$( t$,Chr$(34),"" ) t$=Replace$( t$," ","_" ) Return t$ End Function Function GNET_Open( opt$ ) t=OpenTCPStream( GNET_HOST$,GNET_PORT ) If Not t Return 0 WriteLine t,"GET "+GNET_GET$+"?opt="+opt$+" HTTP/1.0" WriteLine t,"HOST: "+GNET_HOST$ WriteLine t,"" While ReadLine$(t)<>"" Wend Return t End Function Function GNET_Exec( opt$,game$,server$ ) opt$=opt$+"&game="+GNET_Esc$(game$) If server$<>"" opt$=opt$+"&server="+GNET_Esc$(server$) t=GNET_Open( opt$ ) If Not t Return 0 ok=False If( ReadLine$(t)="OK" ) ok=True CloseTCPStream t Return ok End Function Function GNET_Ping$() t=GNET_Open( "ping" ) If Not t Return 0 ip$=ReadLine$(t) CloseTCPStream t Return ip$ End Function Function GNET_AddServer( game$,server$="" ) Return GNET_Exec( "add",game$,server$ ) End Function Function GNET_RefreshServer( game$,server$="" ) Return GNET_Exec( "ref",game$,server$ ) End Function Function GNET_RemoveServer( game$ ) Return GNET_Exec( "rem",game$,"" ) End Function Function GNET_ListServers( game$="" ) Delete Each GNET_Server t=GNET_Open( "list" ) If Not t Return 0 Repeat t_game$=ReadLine$(t) If t_game$="" Exit t_server$=ReadLine$(t) t_ip$=ReadLine(t) If game$="" Or game$=t_game$ p.GNET_Server=New GNET_Server p\game$=t_game$ p\server$=t_server$ p\ip$=t_ip$ EndIf Forever CloseTCPStream t Return 1 End Function ;========================================================================== |
Comments
If you can't find anyone to play with you can practise with some Bots !
Added Bots with very simple A.I.
All Bots are Host controlled and will scan for and attack all human players and will collect weapons/ammo - they use up ammo in exactly the same way as a human player.
Bots can have a skill rating of from 1 to 10 affecting rate of turn,rate of fire,alertness and accuracy.
You can assign a skill level to all bots or random values.
Bots have a kills score as well.
Thanks to Fredborg's 3d line of sight function.
.bb and .exe
http://webzoom.freewebs.com/smiff/botnetfps.zip
Added Bots with very simple A.I.
All Bots are Host controlled and will scan for and attack all human players and will collect weapons/ammo - they use up ammo in exactly the same way as a human player.
Bots can have a skill rating of from 1 to 10 affecting rate of turn,rate of fire,alertness and accuracy.
You can assign a skill level to all bots or random values.
Bots have a kills score as well.
Thanks to Fredborg's 3d line of sight function.
.bb and .exe
http://webzoom.freewebs.com/smiff/botnetfps.zip
;====== FPSNet: A NETWORKED FIRST PERSON SHOOTER EXAMPLE ================== ;====== UTILIZING ONLY BUILT IN BLITZ3D FEATURES ========================== ;====== A CODESKETCH BY JEREMY ALESSI ===================================== ;====== THANKS MARK SIBLY FOR GNET ======================================== ;====== BOT CODE ADDED BY SMIFF 20/09/2004 ;====== WASD OR CURSORS MOVE, MOUSE LOOKS, LEFT MOUSE BUTTON SHOOTS ======= ;====== SPACE BAR OR 0 ON NUMPAD JUMPS, PRESS C TO CHAT =================== ;====== PRESS 2 TO UNLOCK MOUSE FROM CENTER (USEFUL TO PLAY =============== ;====== AND ALSO BE ABLE TO MULTITASK IF NEED BE) PRESS 1 TO RELOCK ======= ;====== MOUSE BACK TO CENTER OF SCREEN ==================================== ;====== YEAH EVERYONE HAS THE SOURCE ... DON'T CHEAT! ===================== ;====== INCLUDES ========================================================== ;Include "gnet_inc.bb" This is included at the bottom of this source! ;========================================================================== ;====== GRAPHICS ========================================================== Graphics3D(640, 480, 16, 2) SetBuffer BackBuffer() HidePointer ;========================================================================== ;====== COLLISIONS ======================================================== Global BODY = 1 Global SCENE = 2 Collisions(BODY,SCENE, 2, 2) Collisions(BODY,BODY, 2, 2) ;========================================================================== ;====== GLOBALS =========================================================== Global gameState$ = "Title Screen" ;Mousehit Vars Global mb1pressed, mb2pressed ;Keyhit Vars Global upKeyPressed, downKeyPressed, leftKeyPressed, rightKeyPressed, enterKeyPressed, spaceKeyPressed Global chatKeyPressed ;Font Vars Global font, bigFont ;Menu Var Global menuCount ;Server Vars Global serverCount Global serverPointer ;Local Player Network Vars Global localPlayerName$, localPlayerPointer ;Scenery Vars Global level,copySprite, lightPivot ;Camera Var Global camera ;Player Gameplay Vars Global health#, shot, shot2, shot3, shotTimer#, positionUpdateTimer#, serverRefreshTimer#, hosting Global vX#, vY#, vZ#, oldX#, oldY#, oldZ#, centerMouse = True, enteringChat = False, chat$ Global copyPowerUp, weapon$ = "Semi-Automatic", powerUpSpawned, ammo# = 50, randPos, randNum Global justDied#,respawndelay#=7000 ;Bot globals Global bots=1,botskillbots=1,botpositionUpdateTimer# Global giro=CreatePivot() ;Bot movement constants Const walk=1 Const backup=2 Const strafeL=4 Const strafeR=8 Const jump=16 Const rotate=32 ;bot state constants Const scan=1 Const attack=2 Const getammo=4 Const respawn=8 ;========================================================================== ;====== INCOMING ========================================================== Dim incoming$(100) ;========================================================================== ;====== CONTENTS OF A KEY ================================================= Dim keys$(237) LoadKeyboardContent() ;========================================================================== ;====== SHOT ARRAY ======================================================== Dim pickedArray(3,3) ;========================================================================== ;====== TYPES ============================================================= Type Player Field iD, name$, mesh[10], score End Type Global Host.Player Type Bot Field iD, name$, mesh[10],health#,score,weapon,ammo#,skill#,range#,state,seq Field firing,shot,shot2,shot3,shotTimer#,target,targetItem,justDied#,botscantime#,timer# Field vX#, vY#, vZ#, oldX#, oldY#, oldZ# End Type Dim Botnames$(3,10) Type Particle Field mesh, name$, alpha# Field vX#, vY#, vZ# End Type Type chatMsg Field msg$, born#, from End Type Type powerUp Field mesh, name$,iD End Type ;========================================================================== ;====== INITIAL SETUP ===================================================== Setup("Title Screen") ;========================================================================== ;========================================================================== .Main ;====== RUN =============================================================== period=1000 / 30 tweentime = MilliSecs()-period While 1 ;====== CALCULATE TWEEN =================================================== Repeat elapsed = MilliSecs() - tweentime Until elapsed ticks = elapsed/period tween# = Float(elapsed Mod period) / Float(period) ;========================================================================== ;====== MAIN LOOP ========================================================= For k=1 To ticks tweentime = tweentime+period If k = ticks Then CaptureWorld If KeyDown(1) If Not GNET_RemoveServer("BOT-FPSNetUpdate") If hosting = True RuntimeError "Failed to remove server" EndIf EndIf ClearWorld() End EndIf UpdateLogic() UpdateWorld Next RenderWorld(tween#) Draw() Flip Wend ;=========================================================================== ;====== UPDATE LOGIC ======================================================= Function UpdateLogic() Select gameState$ Case "Title Screen" UpdateTitleInput() UpdateTitleScreen() Case "Game" DetectPowerUpCollision() UpdateGameInput() ControlChat() UpdateLights() UpdateBots() UpdateCamera() UpdatePlayerMovement() HostSpawnPowerups() UpdateParticles() UpdateNetwork() UpdateCenterMouse() End Select End Function ;=========================================================================== ;====== DRAW =============================================================== Function Draw() Select gameState$ Case "Title Screen" DrawTitleScreen() Case "Game" DrawGamePlay() End Select End Function ;=========================================================================== ;====== UPDATE TITLE INPUT ================================================= Function UpdateTitleInput() mb1pressed = MouseHit(1) mb2pressed = MouseHit(2) upKeyPressed = KeyHit(17) Or KeyHit(200) downKeyPressed = KeyHit(31) Or KeyHit(208) leftKeyPressed = KeyHit(30) Or KeyHit(203) rightKeyPressed = KeyHit(32) Or KeyHit(205) enterKeyPressed = KeyHit(28) spaceKeyPressed = KeyHit(57) End Function ;=========================================================================== ;====== UPDATE GAME INPUT ================================================== Function UpdateGameInput() chatKeyPressed = KeyHit(46) enterKeyPressed = KeyHit(28) End Function ;=========================================================================== ;====== UPDATE CENTER MOUSE ================================================ Function UpdateCenterMouse() If centerMouse = True MoveMouse(CorrectX(320), CorrectY(240)) EndIf If KeyHit(2) centerMouse = True EndIf If KeyHit(3) centerMouse = False EndIf End Function ;=========================================================================== ;====== UPDATE TITLE SCREEN ================================================ Function UpdateTitleScreen() If upKeyPressed And menuCount > 0 menuCount = menuCount - 1 EndIf If downKeyPressed And menuCount < serverCount - 1 menuCount = menuCount + 1 EndIf If enterKeyPressed gns.GNET_Server = Object.GNET_Server(serverPointer) If JoinNetGame(gns\server$, gns\ip$) FlushKeys Color(255,0,0) Locate(200,130) localPlayerName$ = Input("Name - ") Delay(500) FlushKeys p.Player = New Player localPlayerPointer = Handle(p.Player) p\iD = CreateNetPlayer(localPlayerName$) Setup("Game") hosting = False EndIf EndIf If spaceKeyPressed FlushKeys Color(255,0,0) Locate(150,130) localPlayerName$ = Input("Name - ") Locate(150,150) bots=Input("Number of Bots (Recommended Max 8)(0=None) - ") If bots>8 bots=8 If bots>0 Then FillBotNames() Locate(150,170) botskill=Input("Bot Skill 1-10 (0=Random) - ") End If If botskill>10 botskill=10 Delay(500) FlushKeys If HostNetGame(localPlayerName$) = 2 If GNET_AddServer("BOT-FPSNetUpdate", localPlayerName$) p.Player = New Player localPlayerPointer = Handle(p.Player) p\iD = CreateNetPlayer(localPlayerName$) Setup("Game") hosting = True serverRefreshTimer# = MilliSecs() Host.Player=p.Player Else RuntimeError("Failed to Add Server!") EndIf Else RuntimeError("Failed to Create Net Game!") EndIf For x=1 To bots HostSpawnBots() Next EndIf End Function ;=========================================================================== ;====== UPDATE PLAYER MOVEMENT ============================================= Function UpdatePlayerMovement() If enteringChat Return p.Player = Object.Player(localPlayerPointer) oldX# = EntityX(p\mesh[1]) oldY# = EntityY(p\mesh[1]) oldZ# = EntityZ(p\mesh[1]) If KeyDown(17) Or KeyDown(200) MoveEntity(p\mesh[1], 0, 0, .5) EndIf If KeyDown(31) Or KeyDown(208) MoveEntity(p\mesh[1], 0, 0, -.5) EndIf If KeyDown(30) Or KeyDown(203) MoveEntity(p\mesh[1], -.5, 0, 0) EndIf If KeyDown(32) Or KeyDown(205) MoveEntity(p\mesh[1], .5, 0, 0) EndIf numColls = CountCollisions(p\mesh[1]) If numColls = 0 vY# = vY# - .01 Else vY# = 0 EndIf If (KeyDown(57) Or KeyDown(82)) And numColls > 0 vY# = .2 EndIf TranslateEntity(p\mesh[1],0, vY#, 0) RotateEntity(p\mesh[1], 0, EntityYaw(p\mesh[1]) - MouseXSpeed(), 0) vX# = EntityX(p\mesh[1]) - oldX# vY# = EntityY(p\mesh[1]) - oldY# vZ# = EntityZ(p\mesh[1]) - oldZ# End Function ;=========================================================================== ;====== UPDATE BOTS ======================================================= Function UpdateBots() p.Player = Object.Player(localPlayerPointer) If Not hosting Then Return For b.bot=Each bot ; State Defaults If b\state=0 b\state=scan If b\seq=0 b\seq=rotate If b\ammo#<.1 Then b\state=getammo End If Select b\state Case respawn b\seq=rotate If b\timer#+respawndelay# < MilliSecs() EntityAlpha b\mesh[1],1 EntityAlpha b\mesh[2],1 b\state=scan SendNetMsg(96,b\iD+",1-",p\iD,0,1) End If Case Scan b\seq=rotate If b\botscantime# + 1000 <MilliSecs() d1=10000 d2=0 For op.player=Each player d2= EntityDistance(b\mesh[1],op\mesh[1]) If d2=<d1 Then If LineOfSight3D(b\mesh[1],op\mesh[1],1000.00) b\target=op\mesh[1] b\state=attack End If d1=d2 End If Next b\botscantime#=MilliSecs() End If Case attack If b\target >0 PositionEntity giro,EntityX(b\mesh[1]),EntityY(b\mesh[1]),EntityZ(b\mesh[1]) PointEntity giro,b\target turn#=20-b\skill# tx#=curveangle#(EntityPitch(giro),EntityPitch(b\mesh[1]),turn#) ty#=curveangle#(EntityYaw(giro),EntityYaw(b\mesh[1]),turn#) RotateEntity b\mesh[1],tx#,ty#,0 If EntityDistance(b\mesh[1],b\target)<b\range# b\seq=jump If LineOfSight3D(b\mesh[1],b\target,b\range,90-b\skill) b\firing=True;not yet used ! shoot=Rand(1,15-b\skill) If shoot=1 Then Botshoot(b.bot) Else b\firing=False End If Else b\seq=walk b\firing=False End If Else b\state=scan b\firing=False End If Case getammo b\seq=walk If powerUpSpawned pup.powerUp=First powerUp b\targetItem=pup\mesh PositionEntity giro,EntityX(b\mesh[1]),EntityY(b\mesh[1]),EntityZ(b\mesh[1]) PointEntity giro,b\targetItem turn#=10-b\skill#;allow more agility when collectimg items tx#=curveangle#(EntityPitch(giro),EntityPitch(b\mesh[1]),turn#) ty#=curveangle#(EntityYaw(giro),EntityYaw(b\mesh[1]),turn#) RotateEntity b\mesh[1],tx#,ty#,0 If DetectBotPowerUpCollision(b.bot) b\state=attack End If End If End Select Next .movebot For b.bot = Each bot numColls = CountCollisions(b\mesh[1]) b\oldX# = EntityX(b\mesh[1]) b\oldY# = EntityY(b\mesh[1]) b\oldZ# = EntityZ(b\mesh[1]) If (b\seq And walk) ;KeyDown(17) Or KeyDown(200) If b\target>0 d#=EntityDistance(b\mesh[1],b\target) speed#=curvevalue#(d,b\vZ#,20) If speed#>.5 speed#=.5 MoveEntity(b\mesh[1], 0, 0, speed#) Else MoveEntity(b\mesh[1], 0, 0, .5) End If EndIf If b\seq And backup;KeyDown(31) Or KeyDown(208) MoveEntity(b\mesh[1], 0, 0, -.5) EndIf If b\seq And strafeL;KeyDown(30) Or KeyDown(203) MoveEntity(b\mesh[1], -.5, 0, 0) EndIf If b\seq And strafeR;KeyDown(32) Or KeyDown(205) MoveEntity(b\mesh[1], .5, 0, 0) EndIf If b\seq And rotate TurnEntity (b\mesh[1],0,.5+(b\skill/20),0) End If ;numColls = CountCollisions(b\mesh[1]) If numColls = 0 b\vY# = b\vY# - .01 Else b\vY# = 0 EndIf If b\seq = jump And (EntityCollided(b\mesh[1],SCENE)>0) b\vY# = .2 EndIf TranslateEntity(b\mesh[1],0, b\vY#, 0) b\vX# = EntityX(b\mesh[1]) - b\oldX# b\vY# = EntityY(b\mesh[1]) - b\oldY# b\vZ# = EntityZ(b\mesh[1]) - b\oldZ# Next If botpositionUpdateTimer# + 50 < MilliSecs() p.Player = Object.Player(localPlayerPointer) For b.bot= Each bot SendNetMsg(91, b\iD+","+EntityX(b\mesh[1]) + "," + EntityY(b\mesh[1]) + "," + EntityZ(b\mesh[1]) + "," + EntityPitch(b\mesh[1]) + "," + EntityYaw(b\mesh[1]) + "," + b\score+ "," +b\ammo+ "," +b\state + "," +b\seq + "," +b\health + "," + b\weapon +" ," + b\range +"-", p\iD, 0, 0) Next botpositionUpdateTimer# = MilliSecs() EndIf End Function Function BotShoot(b.bot) p.Player = Object.Player(localPlayerPointer) TFormVector 0,0,100,b\mesh[1],0 Local dx# = TFormedX() Local dy# = TFormedY() Local dz# = TFormedZ() b\shot = 0 b\shot2 = 0 b\shot3 = 0 Select b\weapon Case 1;"Semi-Automatic" If b\shotTimer# + 200 < MilliSecs() And b\ammo# > 0 b\ammo# = b\ammo# - 1 b\shot = LinePick(EntityX(b\mesh[1]),EntityY(b\mesh[1]),EntityZ(b\mesh[1]), dx#,dy#,dz#,0.1) b\shotTimer# = MilliSecs() If b\shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 50, 50, 50, 10) SendNetMsg(4,"1," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf Case 2;"Shotgun" If b\shotTimer# + 750 < MilliSecs() And b\ammo# >= 3 b\ammo# = b\ammo# - 3 For i = 1 To 3 Select i Case 1 b\shot = LinePick(EntityX(b\mesh[1])-0.5,EntityY(b\mesh[1]),EntityZ(b\mesh[1]), dx#-0.5,dy#,dz#,0.01) Case 2 b\shot2 = LinePick(EntityX(b\mesh[1]),EntityY(b\mesh[1]),EntityZ(b\mesh[1]), dx#,dy#,dz#,0.01) Case 3 b\shot3 = LinePick(EntityX(b\mesh[1])+0.5,EntityY(b\mesh[1]),EntityZ(b\mesh[1]), dx#+0.5,dy#,dz#,0.01) End Select pickedArray(i,1) = PickedX() pickedArray(i,2) = PickedY() pickedArray(i,3) = PickedZ() Next b\shotTimer# = MilliSecs() If b\shot Or b\shot2 Or b\shot3 For i = 1 To 3 If (i = 1 And b\shot <> 0) Or (i = 2 And b\shot2 <> 0) Or (i = 3 And b\shot3 <> 0) CreateSomeParticles(pickedArray(i,1), pickedArray(i,2), pickedArray(i,3), 200, 200, 200, 10) EndIf Next SendNetMsg(4,"2," + pickedArray(1,1) + "," + pickedArray(1,2) + "," + pickedArray(1,3) + "," + pickedArray(2,1) + "," + pickedArray(2,2) + "," + pickedArray(2,3) + "," + pickedArray(3,1) + "," + pickedArray(3,2) + "," + pickedArray(3,3) + "-", p\iD, 0, 0) EndIf EndIf Case 3;"Flamethrower" If b\shotTimer# + 50 < MilliSecs() And b\ammo# >= .1 b\ammo# = b\ammo# - .1 pvX# = b\vX# + (EntityX(b\mesh[3], True) - EntityX(b\mesh[2], True)) / 10 pvY# = b\vY# + (EntityY(b\mesh[3], True) - EntityY(b\mesh[2], True)) / 10 pvZ# = b\vZ# + (EntityZ(b\mesh[3], True) - EntityZ(b\mesh[2], True)) / 10 SendNetMsg(90, pvX# + "," + pvY# + "," + pvZ# + ","+b\iD+ "-", p\iD, 0, 0) CreateSomeParticles(EntityX(b\mesh[2],True), EntityY(b\mesh[2], True), EntityZ(b\mesh[2], True), 255, 200, 100, 10, pvX# + Rnd(-.05, .05), pvY# + Rnd(-.05, .05), pvZ#, "Flame") b\shot = LinePick(EntityX(b\mesh[1], True), EntityY(b\mesh[1], True), EntityZ(b\mesh[1], True), EntityX(b\mesh[3], True) - EntityX(b\mesh[1], True), EntityY(b\mesh[3], True) - EntityY(b\mesh[1], True), EntityZ(b\mesh[3], True) - EntityZ(b\mesh[1], True)) shotTimer# = MilliSecs() If b\shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 200, 100, 10, "Flame") SendNetMsg(4,"3," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf End Select ;;; For op.Player = Each Player Select b\weapon Case 1;"Semi-Automatic" If b\shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) If Handle(op.Player)=localPlayerPointer health#=health#-5 SendNetMsg(5, "1,10-", p\iD, 0, 0) Else SendNetMsg(2, "1,"+b\iD+"-", p\iD, op\iD, 0) End If EndIf Case 2;"Shotgun" If b\shot = op\mesh[1] Or shot2 = op\mesh[1] Or shot3 = op\mesh[1] Select op\mesh[1] Case b\shot If Handle(op.Player)=localPlayerPointer health#=health#-5 SendNetMsg(5, "2,10-", p\iD, 0, 0) End If CreateSomeParticles(pickedArray(1, 1), pickedArray(1, 2), pickedArray(1, 3), 255, 0, 0, 10) Case b\shot2 If Handle(op.Player)=localPlayerPointer health#=health#-5 SendNetMsg(5, "2,10-", p\iD, 0, 0) End If CreateSomeParticles(pickedArray(2, 1), pickedArray(2, 2), pickedArray(2, 3), 255, 0, 0, 10) Case b\shot3 If Handle(op.Player)=localPlayerPointer health#=health#-5 SendNetMsg(5, "2,10-", p\iD, 0, 0) End If CreateSomeParticles(pickedArray(3, 1), pickedArray(3, 2), pickedArray(3, 3), 255, 0, 0, 10) End Select SendNetMsg(2, "2," + Left(Str(shot), 1) + "," + Left(Str(shot2), 1) + "," + Left(Str(shot3), 1)+","+b\iD+"-", p\iD, op\iD, 0) EndIf Case 3;"Flamethrower" If b\shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) If Handle(op.Player)=localPlayerPointer health#=health#-10 SendNetMsg(5, "3,10-", p\iD, 0, 0) Else SendNetMsg(2, "3,"+b\iD+"-", p\iD, op\iD ,0) End If EndIf End Select If health# <= 0;respawn health# = 100 ; SendNetMsg(3, "1", p\iD, NetMsgFrom(), 1) b\score=b\score+1 b\target=0 b\state=scan CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 100) SendNetMsg(5, "1-",p\iD, 0, 0) justDied# = MilliSecs() PositionEntity(p\mesh[1],5,1,Rand(0, 50)) EndIf Next End Function ;=========================================================================== ;====== UPDATE LIGHTS ====================================================== Function UpdateLights() TurnEntity(lightPivot, 0, 10, 0) End Function ;=========================================================================== ;====== UPDATE CAMERA ====================================================== Function UpdateCamera() p.Player = Object.Player(localPlayerPointer) shot = 0 shot2 = 0 shot3 = 0 If MouseDown(1) Select weapon$ Case "Semi-Automatic" If shotTimer# + 200 < MilliSecs() And ammo# > 0 ammo# = ammo# - 1 shot = CameraPick(camera, CorrectX(320), CorrectY(240)) shotTimer# = MilliSecs() If shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 50, 50, 50, 10) SendNetMsg(4,"1," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf Case "Shotgun" If shotTimer# + 750 < MilliSecs() And ammo# >= 3 ammo# = ammo# - 3 For i = 1 To 3 Select i Case 1 shot = CameraPick(camera, CorrectX(320 - 20), CorrectY(240)) Case 2 shot2 = CameraPick(camera, CorrectX(320), CorrectY(240)) Case 3 shot3 = CameraPick(camera, CorrectX(320 + 20), CorrectY(240)) End Select pickedArray(i,1) = PickedX() pickedArray(i,2) = PickedY() pickedArray(i,3) = PickedZ() Next shotTimer# = MilliSecs() If shot Or shot2 Or shot3 For i = 1 To 3 If (i = 1 And shot <> 0) Or (i = 2 And shot2 <> 0) Or (i = 3 And shot3 <> 0) CreateSomeParticles(pickedArray(i,1), pickedArray(i,2), pickedArray(i,3), 200, 200, 200, 10) EndIf Next SendNetMsg(4,"2," + pickedArray(1,1) + "," + pickedArray(1,2) + "," + pickedArray(1,3) + "," + pickedArray(2,1) + "," + pickedArray(2,2) + "," + pickedArray(2,3) + "," + pickedArray(3,1) + "," + pickedArray(3,2) + "," + pickedArray(3,3) + "-", p\iD, 0, 0) EndIf EndIf Case "Flamethrower" If shotTimer# + 50 < MilliSecs() And ammo# >= .1 ammo# = ammo# - .1 pvX# = vX# + (EntityX(p\mesh[3], True) - EntityX(p\mesh[2], True)) / 10 pvY# = vY# + (EntityY(p\mesh[3], True) - EntityY(p\mesh[2], True)) / 10 pvZ# = vZ# + (EntityZ(p\mesh[3], True) - EntityZ(p\mesh[2], True)) / 10 SendNetMsg(9, pvX# + "," + pvY# + "," + pvZ# + "-", p\iD, 0, 0) CreateSomeParticles(EntityX(p\mesh[2],True), EntityY(p\mesh[2], True), EntityZ(p\mesh[2], True), 255, 200, 100, 10, pvX# + Rnd(-.05, .05), pvY# + Rnd(-.05, .05), pvZ#, "Flame") shot = LinePick(EntityX(camera, True), EntityY(camera, True), EntityZ(camera, True), EntityX(p\mesh[3], True) - EntityX(camera, True), EntityY(p\mesh[3], True) - EntityY(camera, True), EntityZ(p\mesh[3], True) - EntityZ(camera, True)) shotTimer# = MilliSecs() If shot CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 200, 100, 10, "Flame") SendNetMsg(4,"3," + PickedX() + "," + PickedY() + "," + PickedZ() + "-", p\iD, 0, 0) EndIf EndIf End Select EndIf RotateEntity(camera,EntityPitch(camera) + MouseYSpeed(),0,0) If EntityPitch(camera) > 90 RotateEntity(camera, 90, 0, 0) EndIf If EntityPitch(camera) < - 90 RotateEntity(camera, -90, 0, 0) EndIf End Function ;=========================================================================== ;====== UPDATE NETWORK ===================================================== Function UpdateNetwork() While RecvNetMsg() Select NetMsgType() Case 1;move player For p.Player = Each Player If p\iD = NetMsgFrom() DecodeIncomingMessage(NetMsgData$()) PositionEntity(p\mesh[1], incoming$(1), incoming$(2), incoming$(3)) RotateEntity(p\mesh[1], incoming$(4), incoming$(5), 0) If incoming$(6) <> "" p\score = incoming$(6) EndIf EndIf Next Case 2;hit,blood & respawn shotbybot=0 p.Player = Object.Player(localPlayerPointer) CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 10) If justDied# + 500 < MilliSecs() DecodeIncomingMessage(NetMsgData$()) Select incoming$(1) Case 1 health# = health# - 5 If incoming$(2)<>"" shotbybot=incoming$(2) End If Case 2 If incoming$(5)<>"" shotbybot=incoming$(5) End If count = 0 If incoming$(2) <> 0 count = count + 1 EndIf If incoming$(3) <> 0 count = count + 1 EndIf If incoming$(4) <> 0 count = count + 1 EndIf health# = health# - (5 * count) Case 3 health# = health# - 25 If incoming$(2)<>"" shotbybot=incoming$(2) End If End Select EndIf If health# <= 0;respawn health# = 100 SendNetMsg(3, shotbybot+"-", p\iD, NetMsgFrom(), 1) CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, 100) SendNetMsg(5, "1-",p\iD, 0, 0) justDied# = MilliSecs() PositionEntity(p\mesh[1],5,1,Rand(0, 50)) EndIf Case 3;increase score for kill: update local player or bot if hosting DecodeIncomingMessage(NetMsgData$()) If incoming$(1)<>"0" For b.bot=Each bot If b\iD=incoming$(1) b\score=b\score+1 b\target=0 b\state=scan End If Next Else p.Player = Object.Player(localPlayerPointer) p\score = p\score + 1 End If Case 4;bullet hit particles DecodeIncomingMessage(NetMsgData$()) Select incoming$(1) Case 1 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 50, 50, 50, 10) Case 2 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 255, 255, 255, 10) CreateSomeParticles(incoming$(5), incoming$(6), incoming$(7), 255, 255, 255, 10) CreateSomeParticles(incoming$(8), incoming$(9), incoming$(10), 255, 255, 255, 10) Case 3 CreateSomeParticles(incoming$(2), incoming$(3), incoming$(4), 255, 200, 100, 10) End Select Case 5;player blood DecodeIncomingMessage(NetMsgData$()) If incoming(2)<>"" numparticles=incoming$(2) Else numparticles=100 End If For p.Player = Each Player If p\iD = NetMsgFrom() CreateSomeParticles(EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1]), 255, 0, 0, numparticles) EndIf Next Case 6 c.chatMsg = New chatMsg c\msg = NetMsgData$() c\born# = MilliSecs() c\from = NetMsgFrom() Case 7;host spawns pup DecodeIncomingMessage(NetMsgData$()) pup.powerUp = New powerUp pup\mesh = CopyEntity(copyPowerup) powerUpSpawned = True PositionEntity(pup\mesh, EntityX(GetChild(level, incoming$(1)), True), EntityY(GetChild(level, incoming$(1)), True) + 2, EntityZ(GetChild(level, incoming$(1)), True)) Select incoming$(2) Case 1 pup\name$ = "Semi-Automatic" EntityColor(pup\mesh, 255, 255, 255) Case 2 pup\name$ = "Shotgun" EntityColor(pup\mesh, 100, 100, 255) Case 3 pup\name$ = "Flamethrower" EntityColor(pup\mesh, 200, 150, 100) End Select randPos = incoming$(1) randNum = incoming$(2) Case 8;pup taken For pup.powerUp = Each powerUP FreeEntity(pup\mesh) Delete(pup) Next powerUpSpawned = False Case 9;flame particles For op.Player = Each Player If op\iD = NetMsgFrom() DecodeIncomingMessage(NetMsgData$()) CreateSomeParticles(EntityX(op\mesh[2],True), EntityY(op\mesh[2], True), EntityZ(op\mesh[2], True), 255, 200, 100, 10, incoming$(1) + Rnd(-.05, .05), incoming$(2) + Rnd(-.05, .05), incoming$(3), "Flame") EndIf Next Case 90;bot flame particles DecodeIncomingMessage(NetMsgData$()) For b.bot = Each bot If b\iD = incoming$(4) CreateSomeParticles(EntityX(b\mesh[2],True), EntityY(b\mesh[2], True), EntityZ(b\mesh[2], True), 255, 200, 100, 10, incoming$(1) + Rnd(-.05, .05), incoming$(2) + Rnd(-.05, .05), incoming$(3), "Flame") EndIf Next Case 91;move & update bot - extra bot info only sent incase host drops out ! DecodeIncomingMessage(NetMsgData$()) For b.bot=Each bot If b\iD=incoming$(1) PositionEntity(b\mesh[1], incoming$(2), incoming$(3), incoming$(4)) RotateEntity(b\mesh[1], incoming$(5), incoming$(6), 0) If incoming$(7) <> "" b\score = incoming$(7) EndIf ;; Only really needed by hosting machine If incoming$(8) <> "" b\ammo# = incoming$(8) EndIf If incoming$(9) <> "" b\state = incoming$(9) EndIf If incoming$(10) <> "" b\seq = incoming$(10) EndIf If incoming$(11) <> "" b\health# = incoming$(11) EndIf If incoming$(12) <> "" b\weapon = incoming$(12) EndIf If incoming$(13) <> "" b\range = incoming$(13) EndIf EndIf Next Case 92; Bot hit & resspawn DecodeIncomingMessage(NetMsgData$()) For b.bot= Each bot If b\iD=incoming$(5) CreateSomeParticles(EntityX(b\mesh[1]), EntityY(b\mesh[1]), EntityZ(b\mesh[1]), 255, 0, 0, 10) ; End Of Client Section If hosting If b\justDied# + 500 < MilliSecs() Select incoming$(1) Case 1 b\health# = b\health# - 5 Case 2 count = 0 If incoming$(2) <> 0 count = count + 1 EndIf If incoming$(3) <> 0 count = count + 1 EndIf If incoming$(4) <> 0 count = count + 1 EndIf b\health# = b\health# - (5 * count) Case 3 b\health# = b\health# - 25 End Select EndIf If b\ammo#>0 Then For op.player=Each player If op\iD=NetMsgFrom() b\target=op\mesh[1] b\state=attack End If Next End If If b\health# <= 0;respawn p.Player = Object.Player(localPlayerPointer) b\health# = 100 b\target=0 b\state=respawn RotateEntity b\mesh[1],0,Rand(0,360),0 SendNetMsg(3, "0-", p\iD, NetMsgFrom(), 1) CreateSomeParticles(EntityX(b\mesh[1]), EntityY(b\mesh[1]), EntityZ(b\mesh[1]), 255, 0, 0, 100) b\justDied# = MilliSecs() PositionEntity(b\mesh[1],5,1,Rand(0, 50)) EntityAlpha b\mesh[1],0 EntityAlpha b\mesh[2],0 b\timer#=MilliSecs() SendNetMsg(96,b\iD+",0-",p\iD,0,1) EndIf End If End If ;hosting Next Case 95;bot die blood DecodeIncomingMessage(NetMsgData$()) For b.bot = Each bot If b\iD = incoming$(1) CreateSomeParticles(EntityX(b\mesh[1]), EntityY(b\mesh[1]), EntityZ(b\mesh[1]), 255, 0, 0, 100) EndIf Next Case 99; spawn client bots DecodeIncomingMessage(NetMsgData$()) b.bot = New bot b\iD = incoming$(1) b\mesh[1] = CreateSphere(8) b\name$ = incoming$(2) EntityColor(b\mesh[1], 255, 255, 0) PositionEntity(b\mesh[1],incoming$(3), incoming$(4), incoming$(5)) EntityType(b\mesh[1],BODY) EntityRadius(b\mesh[1], 1.5) EntityPickMode(b\mesh[1], 2) b\mesh[2] = CreateCube(b\mesh[1]) PositionEntity(b\mesh[2], 1, -.5, 1) ScaleEntity(b\mesh[2], .1, .1, .4) EntityColor(b\mesh[2], 20, 20, 20) b\mesh[3] = CreatePivot(b\mesh[1]) PositionEntity(b\mesh[3], 0, 0, 5) b\weapon=incoming$(6) b\health=100 Case 96;bot hide/show DecodeIncomingMessage(NetMsgData$()) For b.bot = Each bot If b\iD = incoming$(1) Select incoming$(2) Case 1 ShowEntity b\mesh[1] Case 0 HideEntity b\mesh[1] End Select EndIf Next Case 100; new player joined p.Player = New Player p\iD = NetMsgFrom() p\mesh[1] = CreateSphere(8) p\name$ = NetPlayerName$(p\iD) EntityColor(p\mesh[1], 0, 255, 0) PositionEntity(p\mesh[1], 5, 1.5, Rand(50,100)) EntityType(p\mesh[1],BODY) EntityRadius(p\mesh[1], 1.5) EntityPickMode(p\mesh[1], 2) p\mesh[2] = CreateCube(p\mesh[1]) PositionEntity(p\mesh[2], 1, -.5, 1) ScaleEntity(p\mesh[2], .1, .1, .4) EntityColor(p\mesh[2], 20, 20, 20) p\mesh[3] = CreatePivot(p\mesh[1]) PositionEntity(p\mesh[3], 0, 0, 5) If hosting p.Player = Object.Player(localPlayerPointer) SendNetMsg(7, randPos + "," + randNum + "-", p\iD#, NetMsgFrom(), 1) For b.bot=Each bot SendNetMsg(99, b\iD+ "," +b\name$+ "," +EntityX(b\mesh[1],True) + "," + EntityY(b\mesh[1],True) + "," +EntityZ(b\mesh[1],True) +","+ b\weapon+"-", p\iD#, NetMsgFrom(), 1) Next EndIf Case 101;player left For p.Player = Each Player For b.bot=Each bot If b\target=p\mesh[1] b\target=0 End If Next If p\iD = NetMsgFrom() FreeEntity(p\mesh[1]) Delete(p) EndIf Next Case 102;host left GNET_AddServer("FPSNetUpdate", localPlayerName$) hosting = True host.Player=Object.Player(localPlayerPointer) End Select Wend p.Player = Object.Player(localPlayerPointer) If positionUpdateTimer# + 50 < MilliSecs() SendNetMsg(1, EntityX(p\mesh[1]) + "," + EntityY(p\mesh[1]) + "," + EntityZ(p\mesh[1]) + "," + EntityPitch(camera) + "," + EntityYaw(p\mesh[1]) + "," + p\score + "-", p\iD, 0, 0) positionUpdateTimer# = MilliSecs() EndIf .detect_player_shoots_player For op.Player = Each Player Select weapon$ Case "Semi-Automatic" If shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(2, "1-", p\iD, op\iD, 0) EndIf Case "Shotgun" If shot = op\mesh[1] Or shot2 = op\mesh[1] Or shot3 = op\mesh[1] Select op\mesh[1] Case shot CreateSomeParticles(pickedArray(1, 1), pickedArray(1, 2), pickedArray(1, 3), 255, 0, 0, 10) Case shot2 CreateSomeParticles(pickedArray(2, 1), pickedArray(2, 2), pickedArray(2, 3), 255, 0, 0, 10) Case shot3 CreateSomeParticles(pickedArray(3, 1), pickedArray(3, 2), pickedArray(3, 3), 255, 0, 0, 10) End Select SendNetMsg(2, "2," + Left(Str(shot), 1) + "," + Left(Str(shot2), 1) + "," + Left(Str(shot3), 1) + "-", p\iD, op\iD, 0) EndIf Case "Flamethrower" If shot = op\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(2, "3-", p\iD, op\iD, 0) EndIf End Select Next .detect_player_shoots_bots If bots For b.bot = Each bot ret=0 Select weapon$ Case "Semi-Automatic" If shot = b\mesh[1] CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(92, "1,0,0,0,"+b\iD+"-", p\iD, 0, 0) If hosting b\health# = b\health# - 5:ret=1 EndIf Case "Shotgun" If shot = b\mesh[1] Or shot2 = b\mesh[1] Or shot3 = b\mesh[1] Select b\mesh[1] Case shot If hosting b\health# = b\health# - 5:ret=1 CreateSomeParticles(pickedArray(1, 1), pickedArray(1, 2), pickedArray(1, 3), 255, 0, 0, 10) Case shot2 If hosting b\health# = b\health# - 5:ret=1 CreateSomeParticles(pickedArray(2, 1), pickedArray(2, 2), pickedArray(2, 3), 255, 0, 0, 10) Case shot3 If hosting b\health# = b\health# - 5:ret=1 CreateSomeParticles(pickedArray(3, 1), pickedArray(3, 2), pickedArray(3, 3), 255, 0, 0, 10) End Select SendNetMsg(92, "2," + Left(Str(shot), 1) + "," + Left(Str(shot2), 1) + "," + Left(Str(shot3), 1)+ "," + b\iD+ "-", p\iD, 0, 0) EndIf Case "Flamethrower" If shot = b\mesh[1] If hosting b\health# = b\health# - 25:ret=1 CreateSomeParticles(PickedX(), PickedY(), PickedZ(), 255, 0, 0, 10) SendNetMsg(92, "3,0,0,0,"+b\iD+"-", p\iD, 0, 0) EndIf End Select If hosting p.Player = Object.Player(localPlayerPointer) If ret And (b\ammo#>0) b\target=p\mesh[1] b\state=attack b\seq=walk End If If b\health# <= 0;respawn b\health# = 100 p\score=p\score+1 CreateSomeParticles(EntityX(b\mesh[1]), EntityY(b\mesh[1]), EntityZ(b\mesh[1]), 255, 0, 0, 100) SendNetMsg(95, b\iD+"-",p\iD, 0, 0) b\justDied# = MilliSecs() PositionEntity(b\mesh[1],Rand(0,50),1.5,Rand(0, 50)) b\target=0 b\state=respawn RotateEntity b\mesh[1],0,Rand(0,360),0 EntityAlpha b\mesh[1],0 EntityAlpha b\mesh[2],0 b\timer#=MilliSecs() SendNetMsg(96,b\iD+",0-",p\iD,0,1) EndIf End If Next End If ;bots ;p.Player = Object.Player(localPlayerPointer) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; If hosting = True If serverRefreshTimer# + 250000 < MilliSecs() ; GNET_RefreshServer( "FPSNetUpdate",localPlayerName$ ) serverRefreshTimer# = MilliSecs() EndIf EndIf End Function ;=========================================================================== ;====== UPDATE ParticleS =================================================== Function UpdateParticles() For p.Particle = Each Particle If p\alpha# <= 0 FreeEntity(p\mesh) Delete(p) Else Select p\name$ Case "Flame" TranslateEntity(p\mesh,p\vX#, p\vY#, p\vZ# ) p\alpha# = p\alpha# - Rnd(.3) EntityAlpha(p\mesh, p\alpha#) Default p\vY# = p\vY# - .01 TranslateEntity(p\mesh,p\vX#, p\vY#, p\vZ#) p\alpha# = p\alpha# - .02 EntityAlpha(p\mesh, p\alpha#) End Select EndIf Next End Function ;=========================================================================== ;====== DRAW TITLE SCREEN ================================================== Function DrawTitleScreen() Cls FPSNetText(font, 320, 0, String$("+",80), 1, 1, 100, 100, 100) FPSNetText(font, 320, 480, String$("+",80), 1, 1, 100, 100, 100) For i = 0 To 640 Step 640 For j = 10 To 470 Step 10 FPSNetText(font, i, j, "+", 1, 1, 100, 100, 100) Next Next FPSNetText(bigFont, 320, 30, "BOT-FPSNet:", 1, 1, 255, 0, 0) FPSNetText(font, 320, 60, "A NETWORKED First Person Shooter Example", 1, 1, 100, 100, 100) FPSNetText(font, 320, 80, "Press Up/Down to Select a Game to Join!", 1, 1, 100, 100, 100) FPSNetText(font, 320, 100, "Press Space to Host a New Game!", 1, 1, 100, 100, 100) FPSNetText(font, 320, 120, "Games In Progress:" , 1, 1, 200, 255, 150) serverCount = 0 For gns.GNET_Server = Each GNET_Server Select serverCount Case menuCount FPSNetText(font, 320, 160 + 20 * serverCount, gns\server$ + " - Press Enter to Join ...", 1, 1, 255, 255, 255) serverPointer = Handle(gns) Default FPSNetText(font, 320, 160 + 20 * serverCount, gns\server$, 1, 1, 100, 100, 100) End Select serverCount = serverCount + 1 Next End Function ;=========================================================================== ;====== DRAW GAMEPLAY ====================================================== Function DrawGamePlay() Select weapon$ Case "Semi-Automatic" FPSNetText(font, 320, 240, "+", 1, 1, 255, 255, 255) Case "Shotgun" FPSNetText(font, 300, 240, "+", 1, 1, 255, 255, 255) FPSNetText(font, 320, 240, "+", 1, 1, 255, 255, 255) FPSNetText(font, 340, 240, "+", 1, 1, 255, 255, 255) Case "Flamethrower" FPSNetText(font, 320, 240, "()", 1, 1, 255, 200, 100) End Select p.Player = Object.Player(localPlayerPointer) FPSNetText(font, 0, 0, "Your Score: " + p\score, 0, 0, 255, 0, 0) FPSNetText(font, 150, 0, "Health: ", 0, 0, 0, 255, 0) Color(255, 0, 0) Rect(CorrectX(221), CorrectY(4), CorrectX(health#), CorrectY(10), 1) Color(255, 255, 255) Rect(CorrectX(220), CorrectY(2), CorrectX(102), CorrectY(14), 0) FPSNetText(font, 400, 0, "Ammo: " + Int(ammo#), 0, 0, 255, 255, 255) printI = 50 For c.chatMsg = Each chatMsg secondsAround = (MilliSecs() - c\born#) / 50 FPSNetText(font, 0, 0 + printI, NetPlayerName(c\from) + " - " + c\msg$, 0, 0, 255 - secondsAround, 255 - secondsAround, 255 - secondsAround) printI = printI + 15 Next If enteringChat = True FPSNetText(font, 0, 460, localPlayerName$ + " - " + chat$, 0, 0, 255, 255, 255) EndIf For p.Player = Each Player If Handle(p.Player) <> localPlayerPointer CameraProject(camera, EntityX(p\mesh[1]), EntityY(p\mesh[1]), EntityZ(p\mesh[1])) FPSNetText(font, ProjectedX(), ProjectedY() - 20, p\name$ + " - " + p\score, 1, 1, 255, 255, 255) EndIf Next For b.bot = Each bot If b\state<>respawn CameraProject(camera, EntityX(b\mesh[1]), EntityY(b\mesh[1]), EntityZ(b\mesh[1])) FPSNetText(font, ProjectedX(), ProjectedY() - 20, b\name$ + " - " + b\score, 1, 1, 255, 255, 255) End If Next End Function ;=========================================================================== ;====== DETECT POWERUP COLLISION =========================================== Function DetectPowerUpCollision() If Not powerUpSpawned Return p.Player = Object.Player(localPlayerPointer) For pup.powerUp = Each powerUp If EntityDistance(p\mesh[1], pup\mesh) < 3 If weapon$ = pup\name$ Select weapon$ Case "Semi-Automatic" ammo# = ammo# + 50 Case "Shotgun" ammo# = ammo# + 45 Case "Flamethrower" ammo# = ammo# + 30 End Select Else Select pup\name$ Case "Semi-Automatic" ammo# = 50 Case "Shotgun" ammo# = 45 Case "Flamethrower" ammo# = 30 End Select EndIf weapon$ = pup\name$ powerUpSpawned = False FreeEntity(pup\mesh) Delete(pup) SendNetMsg(8, "", p\iD, 0, 1) EndIf Next End Function ;=========================================================================== ;====== DETECT BOT POWERUP COLLISION =========================================== Function DetectBotPowerUpCollision(b.bot) p.Player = Object.Player(localPlayerPointer) For pup.powerUp = Each powerUp If EntityDistance(b\mesh[1], pup\mesh) < 3 If b\weapon = pup\iD Select b\weapon Case 1;"Semi-Automatic" b\ammo# = b\ammo# + 50 Case 2;"Shotgun" b\ammo# = b\ammo# + 45 Case 3;"Flamethrower" b\ammo# = b\ammo# + 30 End Select Else Select pup\iD Case 1;"Semi-Automatic" b\ammo# = 50 b\range#=40 Case 2;"Shotgun" b\ammo# = 45 b\range#=10 Case 3;"Flamethrower" b\ammo# = 30 b\range=5 End Select b\weapon = pup\iD EndIf b\weapon = pup\iD powerUpSpawned = False FreeEntity(pup\mesh) Delete(pup) SendNetMsg(8, "", p\iD, 0, 1) Return 1 EndIf Return 0 Next End Function ;=========================================================================== ;====== HOST SPAWN POWERUPS ================================================ Function HostSpawnPowerups() If (Not hosting) Or (powerUpSpawned) Return EndIf randPos = Rand(1, CountChildren(level)) pup.powerUp = New powerUp pup\mesh = CopyEntity(copyPowerUp) PositionEntity(pup\mesh, EntityX(GetChild(level, randPos), True), EntityY(GetChild(level, randPos), True) + 2, EntityZ(GetChild(level, randPos), True)) randNum = Rand(1,3) Select randNum Case 1 pup\name$ = "Semi-Automatic" pup\iD=1 EntityColor(pup\mesh, 255, 255, 255) Case 2 pup\name$ = "Shotgun" pup\iD=2 EntityColor(pup\mesh, 100, 100, 255) Case 3 pup\name$ = "Flamethrower" pup\iD=3 EntityColor(pup\mesh, 200, 150, 100) End Select p.Player = Object.Player(localPlayerPointer) SendNetMsg(7, randPos + "," + randNum + "-", p\iD#, 0, 1) powerUpSpawned = True End Function ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++++Spawn Bots+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function HostSpawnBots() If (Not hosting) Return randPosX = Rand(1, 40) randPosZ = Rand(1, 40) randPosY=1.5 b.bot = New bot b\iD = Handle(b.bot) b\mesh[1] = CreateSphere(8) PositionEntity(b\mesh[1],randPosX, 1.5,randPosZ) EntityColor(b\mesh[1], 255, 255, 0) EntityType(b\mesh[1],BODY) EntityRadius(b\mesh[1], 1.5) EntityPickMode(b\mesh[1], 2) b\mesh[2] = CreateCube(b\mesh[1]) PositionEntity(b\mesh[2], 1, -.5, 1) ScaleEntity(b\mesh[2], .1, .1, .4) EntityColor(b\mesh[2], 20, 20, 20) b\mesh[3] = CreatePivot(b\mesh[1]) PositionEntity(b\mesh[3], 0, 0, 5) b\seq=rotate b\target=0 b\state=scan b\health=100 b\name$=botnames$(0,Rand(0,9))+botnames$(1,Rand(0,9))+botnames$(2,Rand(0,9)) If botskill=0 Then b\skill=Rand(1,10) Else b\skill#=botskill End If randNum = Rand(1,3) Select randNum Case 1 b\weapon = 1;"Semi-Automatic" b\ammo#=50 b\range#=40 Case 2 b\weapon = 2;"Shotgun" b\ammo=45 b\range#=10 Case 3 b\weapon = 3;"Flamethrower" b\ammo#=30 b\range#=5 End Select p.Player = Object.Player(localPlayerPointer) SendNetMsg(99, b\iD+ "," +b\name$+ "," +randPosX + "," +randPosY+ "," + randPosZ + "," +b\weapon+"-", p\iD#, 0, 1) BotSpawned = True End Function ;=========================================================================== ;====== CONTROL CHAT ======================================================= Function ControlChat() If chatKeyPressed enteringChat = True FlushKeys EndIf If enterKeyPressed And enteringChat = True p.Player = Object.Player(localPlayerPointer) c.chatMsg = New chatMsg c\msg$ = chat$ c\born# = MilliSecs() c\from = p\iD SendNetMsg(6, chat$, p\iD , 0, 0) chat$ = "" enteringChat = False EndIf If enteringChat = True EnterChat() EndIf For c.chatMsg = Each chatMsg If c\born# + 10000 < MilliSecs() Delete(c) EndIf Next End Function ;=========================================================================== ;====== CREATE SOME ParticleS ============================================== Function CreateSomeParticles(x#, y#, z#, r, g, b, numParticles, optvX# = 0, optvY# = 0, optvZ# = 0, passedName$ = "") For i = 1 To numParticles p.Particle = New Particle p\mesh = CopyEntity(copySprite) If passedName$ <> "" p\name$ = passedName$ EndIf PositionEntity(p\mesh,x#, y#, z#, True) EntityColor(p\mesh, r, g, b) If optvX# = 0 p\vX# = Rnd(-.2, .2) Else p\vx# = optvX# EndIf If optvY# = 0 p\vY# = Rnd(.2) Else p\vY# = optvY# EndIf If optvZ# = 0 p\vZ# = Rnd(-.2, .2) Else p\vZ# = optvZ# EndIf p\alpha = 1 Next End Function ;=========================================================================== ;====== SETUP ============================================================== Function Setup(mode$) SeedRnd MilliSecs() Select mode$ Case "Title Screen" font = LoadFont("Arial",20,1) bigFont = LoadFont("Arial",50,1) GNET_ListServers() Case "Game" gameState$ = "Game" p.Player = Object.Player(localPlayerPointer) p\mesh[1] = CreatePivot() PositionEntity(p\mesh[1], 5, 1.5, Rand(0, 50)) EntityType(p\mesh[1],BODY) EntityRadius(p\mesh[1], 1.5) EntityPickMode(p\mesh[1], 1) health# = 100 p\score = 0 p\name$ = localPlayerName$ camera = CreateCamera(p\mesh[1]) CameraRange(camera,.1, 500) p\mesh[2] = CreateCube(camera) PositionEntity(p\mesh[2], 1, -.5, 1) ScaleEntity(p\mesh[2], .1, .1, .4) EntityColor(p\mesh[2], 20, 20, 20) p\mesh[3] = CreatePivot(camera) PositionEntity(p\mesh[3], 0, 0, 5) LoadLevel() PointEntity(p\mesh[1], level) MoveMouse(CorrectX(320), CorrectY(240)) End Select End Function ;=========================================================================== ;====== LOAD LEVEL ========================================================= Function LoadLevel() copyPowerUp = CreateSphere() HideEntity(copyPowerUp) copySprite = CreateSprite() ScaleSprite(copySprite, .05, .05) EntityFX(copySprite, 1+8) HideEntity(copySprite) level = CreatePlane(16) EntityPickMode(level, 2) For i = -1 To 1 Step 2 For j = -4 To 4 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube, 100, 100, 100) PositionEntity(cube, i * 10, 1, j * 10) Next Next For i = 1 To 8 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube,100,100,100) PositionEntity(cube, 0, i * 2, i * 5) Next For i = 1 To 8 cube = CreateCube(level) EntityType(cube, SCENE) EntityPickMode(cube, 2) EntityColor(cube,100,100,100) PositionEntity(cube, 0, i * 2, i * -5) Next EntityType(level,SCENE) lightPivot = CreatePivot() NameEntity(lightPivot,"Light Pivot") light = CreateLight(3,lightPivot) NameEntity(light, "light1") PositionEntity(light,25, 25, 0) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 255, 0, 0) light = CreateLight(3,lightPivot) NameEntity(light, "light2") PositionEntity(light,-25, 25, 0) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 0, 0, 255) light = CreateLight(3,lightPivot) NameEntity(light, "light3") PositionEntity(light,0, 25, 25) RotateEntity(light, 90, 0, 0) LightRange(light, 500) LightColor(light, 0, 255, 0) End Function ;=========================================================================== ;====== FPSNET TEXT ======================================================== Function FPSNetText(fontType, X, Y, theText$, centerX = 0, centerY = 0,r = 255, g = 255, b = 255) Color(r, g, b) SetFont(fontType) Text(CorrectX(X), CorrectY(Y), theText$, centerX, centerY) End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; LineOfSight3D() ; ; Usage: ; observer = Entity that is looking ; target = Entity that the observer is looking for ; viewrange = How far can the observer see (in units) ; viewangle = How wide is the view of the observer (in degrees) ; ; Created by Mikkel Fredborg - Use as you please ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function LineOfSight3D(observer,target,viewrange#=10.0,viewangle# = 90.0) ;distance between observer and target Local dist# = EntityDistance(observer,target) ;check if the target is within viewrange If dist<=viewrange ;observer vector TFormVector 0,0,1,observer,0 Local ox# = TFormedX() Local oy# = TFormedY() Local oz# = TFormedZ() ;pick vector Local dx# = (EntityX(target,True)-EntityX(observer,True))/dist# Local dy# = (EntityY(target,True)-EntityY(observer,True))/dist# Local dz# = (EntityZ(target,True)-EntityZ(observer,True))/dist# ;dot product Local dot# = ox*dx + oy*dy + oz*dz ;check if the target is within the viewangle If dot => Cos(viewangle/2.0) ; check if something is blocking the view If LinePick(EntityX(observer,True),EntityY(observer,True),EntityZ(observer,True),dx*viewrange,dy*viewrange,dz*viewrange,0.01)=target ; observer can see target so shoot the m'f***** Return True End If End If End If ; observer cannot see target Return False End Function Function curvevalue#(newvalue#,oldvalue#,increments# ) If increments>1 Then oldvalue#=oldvalue#-(oldvalue#-newvalue#)/increments If increments<=1 Then oldvalue=newvalue Return oldvalue# End Function ;------------------------------------------------------- ; function to move one angle to another with acceleration ;------------------------------------------------------- Function curveangle#( newangle#,oldangle#,increments#) If increments>1 If (oldangle+360)-newangle<NEWANGLE-OLDANGLE Then OLDANGLE=360+OLDANGLE If (newangle+360)-oldangle<OLDANGLE-NEWANGLE Then NEWANGLE=360+NEWANGLE oldangle=oldangle-(oldangle-newangle)/increments EndIf If increments<=1 oldangle=newangle Return oldangle End Function ;========================================================================== ;====== CORRECTX ========================================================== Function CorrectX(pixel) Return (pixel * GraphicsWidth() / 640) End Function ;========================================================================== ;====== CORRECTY ========================================================== Function CorrectY(pixel) Return (pixel * GraphicsHeight() / 480) End Function ;========================================================================== ;====== DECODE INCOMING MESSAGE =========================================== Function DecodeIncomingMessage(message$) For i = 1 To 100 incoming$(i) = "" Next i = 1 part = 1 incoming$(part) = Mid(message$, i, 1) i = i + 1 While Mid(message$, i, 1)<>"-" While Mid(message$, i, 1)<>"," incoming$(part)=incoming$(part)+Mid(message$, i, 1) i = i + 1 If Mid(message$, i, 1)="-" Exit EndIf Wend If Mid(message$, i, 1)="," i = i + 1 part = part + 1 incoming$(part) = Mid(message$, i, 1) i = i + 1 EndIf Wend End Function ;========================================================================== ;====== ENTER CHAT ======================================================== Function EnterChat() For i = 1 To 237 If (i >= 2 And i <= 11) Or (i >= 16 And i <= 25) Or (i >= 30 And i <= 38) Or (i >= 44 And i <= 50) If KeyHit(i) If Len(chat$) <= 25 chat$ = chat$ + keys$(i) EndIf EndIf EndIf Next If KeyHit(14) And Len(chat$) >= 1 And keytimer# + 100 < MilliSecs() chat$ = Left(chat$,Len(chat$) - 1) keytimer# = MilliSecs() EndIf If KeyHit(211) And Len(chat$) >= 1 And keytimer# + 100 < MilliSecs() chat$ = Right(chat$,Len(chat$) - 1) keytimer# = MilliSecs() EndIf If KeyHit(57) And Len(chat$) <= 25 And keytimer# + 100 < MilliSecs() chat$ = chat$ + " " keytimer# = MilliSecs() EndIf If KeyHit(53) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "?" EndIf If KeyHit(2) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "!" EndIf If KeyHit(3) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "@" EndIf If KeyHit(4) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "#" EndIf If KeyHit(5) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "$" EndIf If KeyHit(6) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "%" EndIf If KeyHit(7) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "^" EndIf If KeyHit(8) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "&" EndIf If KeyHit(9) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "*" EndIf If KeyHit(10) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "(" EndIf If KeyHit(11) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + ")" EndIf If KeyHit(12) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "-" EndIf If KeyHit(13) And Len(chat$) <= 25 And (KeyDown(42) Or KeyDown(54)) chat$ = chat$ + "+" EndIf If KeyHit(40) chat$ = chat$ + "'" EndIf If KeyHit(51) chat$ = chat$ + "," EndIf End Function ;========================================================================== ;===== KEYS CONTENT ======================================================= Function LoadKeyboardContent() keys$(1) = "ESCAPE" keys$(2) = "1" keys$(3) = "2" keys$(4) = "3" keys$(5) = "4" keys$(6) = "5" keys$(7) = "6" keys$(8) = "7" keys$(9) = "8" keys$(10) = "9" keys$(11) = "0" keys$(12) = "-" keys$(13) = "=" keys$(14) = "BACKSPACE" keys$(15) = "TAB" keys$(16) = "Q" keys$(17) = "W" keys$(18) = "E" keys$(19) = "R" keys$(20) = "T" keys$(21) = "Y" keys$(22) = "U" keys$(23) = "I" keys$(24) = "O" keys$(25) = "P" keys$(26) = "[" keys$(27) = "]" keys$(28) = "ENTER" keys$(29) = "LEFTCONTROL" keys$(30) = "A" keys$(31) = "S" keys$(32) = "D" keys$(33) = "F" keys$(34) = "G" keys$(35) = "H" keys$(36) = "J" keys$(37) = "K" keys$(38) = "L" keys$(39) = ";" keys$(40) = "'" keys$(41) = "GRAVE" keys$(42) = "LEFTSHIFT" keys$(43) = "BACKSLASH(\)" keys$(44) = "Z" keys$(45) = "X" keys$(46) = "C" keys$(47) = "V" keys$(48) = "B" keys$(49) = "N" keys$(50) = "M" keys$(51) = "COMMA(,)" keys$(52) = "PERIOD(.)" keys$(53) = "SLASH(/)" keys$(54) = "RIGHTSHIFT" keys$(55) = "MULTIPLY(*)NUMPAD" keys$(56) = "LEFTALT/MENU" keys$(57) = "SPACE" keys$(58) = "CAPITAL" keys$(59) = "F1" keys$(60) = "F2" keys$(61) = "F3" keys$(62) = "F4" keys$(63) = "F5" keys$(64) = "F6" keys$(65) = "F7" keys$(66) = "F8" keys$(67) = "F9" keys$(68) = "F10" keys$(69) = "NUMLOCK" keys$(70) = "SCROLLLOCK" keys$(71) = "NUMPAD7" keys$(72) = "NUMPAD8" keys$(73) = "NUMPAD9" keys$(74) = "SUBTRACT(-)NUMPAD" keys$(75) = "NUMPAD4" keys$(76) = "NUMPAD5" keys$(77) = "NUMPAD6" keys$(78) = "ADD(+)NUMPAD" keys$(79) = "NUMPAD1" keys$(80) = "NUMPAD2" keys$(81) = "NUMPAD3" keys$(82) = "NUMPAD0" keys$(83) = "DECIMAL(.)NUMPAD" keys$(84) = "-" keys$(85) = "-" keys$(86) = "OEM_102" keys$(87) = "F11" keys$(88) = "F12" keys$(89) = "-" keys$(90) = "-" keys$(91) = "-" keys$(92) = "-" keys$(93) = "-" keys$(94) = "-" keys$(95) = "-" keys$(96) = "-" keys$(97) = "-" keys$(98) = "-" keys$(99) = "-" keys$(100) = "F13" keys$(101) = "F14" keys$(102) = "F15" keys$(103) = "-" keys$(104) = "-" keys$(105) = "-" keys$(106) = "-" keys$(107) = "-" keys$(108) = "-" keys$(109) = "-" keys$(110) = "-" keys$(111) = "-" keys$(112) = "KANA" keys$(113) = "-" keys$(114) = "-" keys$(115) = "ABNT_C1" keys$(116) = "-" keys$(117) = "-" keys$(118) = "-" keys$(119) = "-" keys$(120) = "-" keys$(121) = "CONVERT" keys$(122) = "-" keys$(123) = "NOCONVERT" keys$(124) = "-" keys$(125) = "YEN" keys$(126) = "ABNT_C2" keys$(127) = "-" keys$(128) = "-" keys$(129) = "-" keys$(130) = "-" keys$(131) = "-" keys$(132) = "-" keys$(133) = "-" keys$(134) = "-" keys$(135) = "-" keys$(136) = "-" keys$(137) = "-" keys$(138) = "-" keys$(139) = "-" keys$(140) = "-" keys$(141) = "EQUALS" keys$(142) = "-" keys$(143) = "-" keys$(144) = "PREVTRACK" keys$(145) = "AT" keys$(146) = "COLON(:)" keys$(147) = "UNDERLINE" keys$(148) = "KANJI" keys$(149) = "STOP" keys$(150) = "AX" keys$(151) = "UNLABELED" keys$(152) = "-" keys$(153) = "NEXTTRACK" keys$(154) = "-" keys$(155) = "-" keys$(156) = "ENTER (NUMPAD)" keys$(157) = "RIGHTCONTROL" keys$(158) = "-" keys$(159) = "-" keys$(160) = "MUTE" keys$(161) = "CALCULATOR" keys$(162) = "PLAY/PAUSE" keys$(163) = "-" keys$(164) = "MEDIASTOP" keys$(165) = "-" keys$(166) = "-" keys$(167) = "-" keys$(168) = "-" keys$(169) = "-" keys$(170) = "-" keys$(171) = "-" keys$(172) = "-" keys$(173) = "-" keys$(174) = "VOLUMEDOWN" keys$(175) = "-" keys$(176) = "VOLUMEUP" keys$(177) = "-" keys$(178) = "WEBHOME" keys$(179) = "COMMA(,)" keys$(180) = "-" keys$(181) = "DIVIDE(/)" keys$(182) = "-" keys$(183) = "SYSREQ" keys$(184) = "RIGHTALT/MENU" keys$(185) = "-" keys$(186) = "-" keys$(187) = "-" keys$(188) = "-" keys$(189) = "-" keys$(190) = "-" keys$(191) = "-" keys$(192) = "-" keys$(193) = "-" keys$(194) = "-" keys$(195) = "-" keys$(196) = "-" keys$(197) = "PAUSE" keys$(198) = "-" keys$(199) = "HOME" keys$(200) = "UP" keys$(201) = "PAGEUP/PRIOR" keys$(202) = "-" keys$(203) = "LEFT" keys$(204) = "-" keys$(205) = "RIGHT" keys$(206) = "-" keys$(207) = "END" keys$(208) = "DOWN" keys$(209) = "NEXT" keys$(210) = "INSERT" keys$(211) = "DELETE" keys$(212) = "-" keys$(213) = "-" keys$(214) = "-" keys$(215) = "-" keys$(216) = "-" keys$(217) = "-" keys$(218) = "-" keys$(219) = "LEFTWINDWOS" keys$(220) = "RIGHTWINDOWS" keys$(221) = "APPS" keys$(222) = "POWER" keys$(223) = "SLEEP" keys$(224) = "-" keys$(225) = "-" keys$(226) = "-" keys$(227) = "WAKE" keys$(228) = "-" keys$(229) = "WEBSEARCH" keys$(230) = "WEBFAVORITES" keys$(231) = "WEBREFRESH" keys$(232) = "WEBSTOP" keys$(233) = "WEBFORWARD" keys$(234) = "WEBBACK" keys$(235) = "MYCOMPUTER" keys$(236) = "MAIL" keys$(237) = "MEDIASELECT" End Function ;========================================================================== ;====== GNET SOURCE CODE ================================================== Const GNET_HOST$="www.blitzbasic.com" Const GNET_PORT=80 Const GNET_GET$="/gnet/gnet.php" Type GNET_Server Field game$,server$,ip$ End Type Function GNET_Esc$( t$ ) t$=Replace$( t$,"&","" ) t$=Replace$( t$,"%","" ) t$=Replace$( t$,"'","" ) t$=Replace$( t$,Chr$(34),"" ) t$=Replace$( t$," ","_" ) Return t$ End Function Function GNET_Open( opt$ ) t=OpenTCPStream( GNET_HOST$,GNET_PORT ) If Not t Return 0 WriteLine t,"GET "+GNET_GET$+"?opt="+opt$+" HTTP/1.0" WriteLine t,"HOST: "+GNET_HOST$ WriteLine t,"" While ReadLine$(t)<>"" Wend Return t End Function Function GNET_Exec( opt$,game$,server$ ) opt$=opt$+"&game="+GNET_Esc$(game$) If server$<>"" opt$=opt$+"&server="+GNET_Esc$(server$) t=GNET_Open( opt$ ) If Not t Return 0 ok=False If( ReadLine$(t)="OK" ) ok=True CloseTCPStream t Return ok End Function Function GNET_Ping$() t=GNET_Open( "ping" ) If Not t Return 0 ip$=ReadLine$(t) CloseTCPStream t Return ip$ End Function Function GNET_AddServer( game$,server$="" ) Return GNET_Exec( "add",game$,server$ ) End Function Function GNET_RefreshServer( game$,server$="" ) Return GNET_Exec( "ref",game$,server$ ) End Function Function GNET_RemoveServer( game$ ) Return GNET_Exec( "rem",game$,"" ) End Function Function GNET_ListServers( game$="" ) Delete Each GNET_Server t=GNET_Open( "list" ) If Not t Return 0 Repeat t_game$=ReadLine$(t) If t_game$="" Exit t_server$=ReadLine$(t) t_ip$=ReadLine(t) If game$="" Or game$=t_game$ p.GNET_Server=New GNET_Server p\game$=t_game$ p\server$=t_server$ p\ip$=t_ip$ EndIf Forever CloseTCPStream t Return 1 End Function ;========================================================================== Function FillBotNames() Restore startdata For x=0 To 2 For y=0 To 9 Read Botnames$(x,y) Next Next End Function .startdata Data "Ar","As","Ba","Bo","Co","Di","Da","Ma","No","Ze" Data "son","kan","lon","ran","tel","rax","ham","sak","gro","nix" Data "dus","ious","frey","eta","ala","una","oss","ara","ini","eka"
awesome
There's a little bug - if you kill a bot when he's going for ammo he stays invisible when he respawns - easy to fix !
I might use the basic engine of this for my new FPS.
This is very nice, and I just started to play a bit more with it. I'd really love to use this.
But I have a probem when the host quits (gnet 1.1), an existing client becomes the new host, but when a new client want's to enter now, the login screen waits forever. Can somebody help me to fix this? Tha!
But I have a probem when the host quits (gnet 1.1), an existing client becomes the new host, but when a new client want's to enter now, the login screen waits forever. Can somebody help me to fix this? Tha!
thanks guys.
Great Updates!
Um, when i try to get somone else to join it says "Game already started" and quits. WHY??