diff --git a/cb_source/Client.cb b/cb_source/Client.cb index 12d96d9..7395921 100644 --- a/cb_source/Client.cb +++ b/cb_source/Client.cb @@ -18,6 +18,9 @@ gPacketWaitTimer = 0 Global gReconnectToServer gReconnectToServer = False +Global gChangeTeam +gChangeTeam = -1 + //================================================================================ // Liitytään peliin //================================================================================ @@ -285,11 +288,13 @@ Function ClientLoop() If gSessionComplete = False And player\loggedIn = True And player\health > 0 And volAdjust = False Then obj = player\obj - If MouseMoveX() <> 0 Or MouseMoveY() <> 0 Then + If MouseMoveX() <> 0 Or MouseMoveY() <> 0 And player\team <> 0 Then // Jos hiiri liikkuu niin käännetään sitä kohti RotateObject obj, -GetAngle(ObjectX(obj), ObjectY(obj), MouseWX(), MouseWY()) // Tähtäin näkyviin ShowMouse gImages(IMG_SIGHT) + ElseIf player\team = 0 Then + ShowMouse Off EndIf // hided = False @@ -303,13 +308,12 @@ Function ClientLoop() // EndIf If LeftKey() Or RightKey() Then ShowMouse OFF - If gControlMode = 1 Then + If gControlMode = 1 And player\team <> 0 Then If KeyDown(cbKeyW) Or UpKey() Then MoveObject obj, PxPerSec(FORWARD_SPEED) * 100.0 / aWeapon( player\weapon, WPNF_WEIGHT ) If KeyDown(cbKeyS) Or DownKey() Then MoveObject obj, -PxPerSec(BACKWARD_SPEED) * 100.0 / aWeapon( player\weapon, WPNF_WEIGHT ) If KeyDown(cbKeyA) Then MoveObject obj, 0, -PxPerSec(SIDESTEP_SPEED) * 100.0 / aWeapon( player\weapon, WPNF_WEIGHT ) If KeyDown(cbKeyD) Then MoveObject obj, 0, PxPerSec(SIDESTEP_SPEED) * 100.0 / aWeapon( player\weapon, WPNF_WEIGHT ) - EndIf - If gControlMode = 2 Then + ElseIf gControlMode = 2 Then moveX = 0 moveY = 0 If KeyDown(cbKeyW) Then moveY = PxPerSec(FORWARD_SPEED) * 100.0 / aWeapon( player\weapon, WPNF_WEIGHT ) @@ -404,10 +408,12 @@ Function ClientLoop() // GameUpdate() If gSessionComplete = False Then CloneCameraPosition player\obj - If gCameraMode =< 1 Then - CloneCameraPosition player\obj - ElseIf gCameraMode => 2 Then - PositionCamera ObjectX(player\obj)+(MouseX()-ScreenWidth()/2)/1.2, ObjectY(player\obj)-(MouseY()-ScreenHeight()/2)/1.2 + If player\team <> 0 Then + If gCameraMode =< 1 Then + CloneCameraPosition player\obj + ElseIf gCameraMode => 2 Then + PositionCamera ObjectX(player\obj)+(MouseX()-ScreenWidth()/2)/1.2, ObjectY(player\obj)-(MouseY()-ScreenHeight()/2)/1.2 + EndIf EndIf EndIf @@ -498,7 +504,7 @@ Function ClientLoop() Exit EndIf If gKickedOut Then Exit - + If player\team = 0 Then ResetObjectCollision player\obj If player\loggedIn Then DrawScreen UpdateGame2() PlayMusic() @@ -1152,7 +1158,7 @@ Function SendDataToServer() If aWeapon(player\weapon, WPNF_AMMO) > 0 Then ammoExists = True // Tutkitaan voidaanko lähettää tieto ampumisesta shootNow = 0 - If (MouseDown(1) = True Or KeyDown(cbKeySpace) = True) And (player\weapon<>WPN_PISTOL Or gNotShotYet = True) And gConsoleMode = False And gDevConsole = False And gSessionComplete = False And player\spawnTime = 0 Then + If (MouseDown(1) = True Or KeyDown(cbKeySpace) = True) And (player\weapon<>WPN_PISTOL Or gNotShotYet = True) And gConsoleMode = False And gDevConsole = False And gSessionComplete = False And player\spawnTime = 0 And player\team <> 0 Then // Onko ase latingissa If player\lastShoot + aWeapon(player\weapon, WPNF_RELOADTIME) < Timer() And player\health > 0 Then // Onko ammuksia @@ -1190,6 +1196,11 @@ Function SendDataToServer() _Net_PutString(gServerMap) EndIf + If gChangeTeam <> -1 Then + _Net_PutByte(NET_TEAMINFO) + _Net_PutByte(gChangeTeam) + gChangeTeam = -1 + EndIf _Net_PutByte(NET_END) gBbsOutCount = gBbsOutCount + MEMBlockSize(gNetMemBlock)-4 diff --git a/cb_source/Config.cb b/cb_source/Config.cb index 45a4c84..2a2de46 100644 --- a/cb_source/Config.cb +++ b/cb_source/Config.cb @@ -83,6 +83,14 @@ gDisableSpeedhackTest = False Global gCameraMode gCameraMode = 1 +// Maksimi aika sekunteina kauanko pelaaja voi olla katsojana +Global gMaxSpectatorTime +gMaxSpectatorTime = 300 // 5min + +// Aika joka pelaajan pitää odottaa ennenkuin pääsee katsojaksi +Global gSpectatorDelay +gSpectatorDelay = 10 + ReadConfig() //-------------------------------------------------------------------------------- // Luetaan asetukset jos tiedosto on olemassa @@ -115,6 +123,8 @@ Function ReadConfig() If key = "MAPSERVER" Then gMapServerUrl = value If key = "DISABLESPEEDHACKTEST" Then gDisableSpeedhackTest = value If key = "CAMERAMODE" Then gCameraMode = value + If key = "MAXSPECTATORTIME" Then gMaxSpectatorTime = value + If key = "SPECTATORDELAY" Then gSpectatorDelay = value Wend CloseFile f EndIf @@ -145,5 +155,7 @@ Function SaveConfig() WriteLine f, "MapServer=" + Replace( gMapServerUrl, "=", "=" ) WriteLine f, "DisableSpeedhackTest=" + gDisableSpeedhackTest WriteLine f, "CameraMode=" + gCameraMode + WriteLine f, "MaxSpectatorTime=" + gMaxSpectatorTime + WriteLine f, "SpectatorDelay=" + gSpectatorDelay CloseFile f EndFunction diff --git a/cb_source/Console.cb b/cb_source/Console.cb index 7a26a40..ae1c8ac 100644 --- a/cb_source/Console.cb +++ b/cb_source/Console.cb @@ -22,9 +22,11 @@ Const CONSOLE_ROWS = 25 // Komennot // Komentojen toiminnallisuus tapahtuu RunCommand-funktiossa //-------------------------------------------------------------------------------- -Const COMMAND_HELP = 0 -Const COMMAND_QUIT = 1 -Const COMMAND_COUNT = 1 +Const COMMAND_HELP = 0 +Const COMMAND_QUIT = 1 +Const COMMAND_JOIN = 2 +Const COMMAND_SPECTATE = 3 +Const COMMAND_COUNT = 3 Const CMD_NAME = 0 // Name Const CMD_ARGS = 1 // Arguments @@ -46,6 +48,14 @@ aCommands(COMMAND_QUIT, CMD_NAME) = "quit" aCommands(COMMAND_QUIT, CMD_ARGS) = "" aCommands(COMMAND_QUIT, CMD_DESC) = "Quits the game" +aCommands(COMMAND_JOIN, CMD_NAME) = "join" +aCommands(COMMAND_JOIN, CMD_ARGS) = "[team]" +aCommands(COMMAND_JOIN, CMD_DESC) = "Joins to team, team can be 0 for spectator, if left blank it will join to game" // Myöhemmin myös 1 ja 2 + +aCommands(COMMAND_SPECTATE, CMD_NAME) = "spectate" +aCommands(COMMAND_SPECTATE, CMD_ARGS) = "" +aCommands(COMMAND_SPECTATE, CMD_DESC) = "Joins to spectators" + Global gDevConsoleText$, gDevConsoleInput, gDevConsoleACId gDevConsoleACId = -1 @@ -139,6 +149,21 @@ Function RunCommand(_command$, _output = 1) // Odotellaan vielä puoli sekuntia Wait 500 - (Timer() - t) End + + + // Syntax: join + ElseIf cmdId = COMMAND_JOIN Then + team = GetArgument("team", _command, cmdId, 1) + If team < 0 Or team > 2 Then + out = "Team must be 0 for spectator or 1 for joining to game" // Myöhemmin myös tiimit 1 ja 2 + Else + gChangeTeam = team // Jos 0, liittyy katsojaksi, jos jotain muuta liittyy peliin ja serveri päättää tiimin tällä hetkellä + EndIf + + // Syntax: spectate + ElseIf cmdId = COMMAND_SPECTATE Then + gChangeTeam = 0 + EndIf Else out = out + "Unknown command '" + cmd + "'." diff --git a/cb_source/Game.cb b/cb_source/Game.cb index db2df02..174c18f 100644 --- a/cb_source/Game.cb +++ b/cb_source/Game.cb @@ -172,7 +172,7 @@ Function GameUpdate() // Soitellaan tyhjäkäyntiääniä playIdle = False - If player\weapon = WPN_CHAINSAW And player\health > 0 Then + If player\weapon = WPN_CHAINSAW And player\health > 0 And player\team <> 0 Then If player\playerId = gCurrentPlayerId Then If aWeapon(WPN_CHAINSAW, WPNF_AMMO) > 0 Then playIdle = True @@ -220,7 +220,7 @@ Function GameUpdate() UpdateRadar(player\obj) // Varmistetaan että pelaaja pysyy kartalla - If InMap(ObjectX(player\obj), ObjectY(player\obj)) = True Then + If InMap(ObjectX(player\obj), ObjectY(player\obj)) = True Or player\team = 0 Then // Jos pelaaja on kartalla niin talletetaan valid-position player\lastValidX = ObjectX(player\obj) player\lastValidY = ObjectY(player\obj) @@ -274,7 +274,7 @@ Function GameUpdate() If player\zombie = True Then player\hasAmmos = True // Onko pelaaja kuollut - If player\health <= 0 Then + If player\health <= 0 And player\team <> 0 Then // Jos kuolemasta on kulunut tarpeeksi aikaa niin herätetään If player\timeToDeath + DEATH_DELAY < Timer() Then SpawnObject(player\obj) @@ -855,6 +855,7 @@ Function Login(_in, _playerId = 0) //COM1 If player\loggedIn = True Then gPlayerCount - 1 player\loggedIn = False player\admin = False + player\team = 1 WriteLog(player\name + " logged out") // Lähetetään viesti kaikille muille paitsi boteille For plr.PLAYERS = Each PLAYERS @@ -1130,7 +1131,7 @@ Function AnimatePlayers() player\prevPosY = oy lp# = player\legPos lp = WrapAngle(lp + Distance(ox, oy, px, py) * 3.0) - If player\playerId = gCurrentPlayerId Then + If player\playerId = gCurrentPlayerId And player\team <> 0 Then If (player\legPos <= 90 And lp > 90) Or (player\legPos <= 270 And lp > 270) Then PlayGameSound(SND_FOOTSTEP, CameraX(), CameraY() + 1500) EndIf diff --git a/cb_source/NetMatch_TheEnd.cb b/cb_source/NetMatch_TheEnd.cb index e77c80c..98b1e04 100644 --- a/cb_source/NetMatch_TheEnd.cb +++ b/cb_source/NetMatch_TheEnd.cb @@ -28,7 +28,7 @@ EndIf SAFEEXIT OFF Const NM_VERSION$ = "2.5" -Const NM_REVISION$ = "" +Const NM_REVISION$ = "a" // Jos palvelinta ei tarvitse päivittää muutosten yhteydessä, nostetaan vain NM_PATCH // muuttujan arvoa. Tämä nollataan aina kun tulee uusi revision tai versio. Const NM_PATCH = 0 diff --git a/cb_source/Player.cb b/cb_source/Player.cb index 3faac2c..3b342b0 100644 --- a/cb_source/Player.cb +++ b/cb_source/Player.cb @@ -116,6 +116,8 @@ Type PLAYERS Field lag As Integer // Pelaajan lagi millisekunneissa Field spHackTimer As Integer // Viimeisimmässä nopeuden tarkistuksessa otettu Timer() Field handShooted As Byte // Kummalla kädellä on viimeksi ammuttu (pistooli) 0=vasen 1=oikea + Field toSpectator As Byte // Kertoo jos pelaaja on menossa katsojaksi + Field spectatorTime As Integer // Milloin pelaaja liittyi katsojaksi EndType //-------------------------------------------------------------------------------- diff --git a/cb_source/Server.cb b/cb_source/Server.cb index b886158..f1c804a 100644 --- a/cb_source/Server.cb +++ b/cb_source/Server.cb @@ -5,6 +5,7 @@ //******************************************************************************** Global gBotFreeze As Byte +Global gLastWarnTime As Integer // Aika milloin viimeksi pelaajaa varoitettiin potkuista // cbNetworkin Gosub-toteutusta varten tarvittavat muuttujat. Dim gs_valueInt As Integer @@ -346,6 +347,36 @@ ServerLoop: Goto returnToLoop EndIf + // Pelaajan heitto katsojaksi + If player\toSpectator = True And player\spectatorTime + gSpectatorDelay*1000 < Timer() Then + SetTeam(player\playerId,0) + player\health = -10 + player\death = True + player\timeToDeath = Timer() + player\toSpectator = False + player\spectatorTime = Timer() + + newMsg.NET_MESSAGES = New( NET_MESSAGES ) + newMsg\msgType = NET_SERVERMSG + newMsg\toPlayer = gCurrentPlayerId + newMsg\msgText = "You have been moved to spectators, AFK timeout is set to "+gMaxSpectatorTime+"s" + EndIf + + // Varoitetaan pelaajaa 5s välein jos ollaan potkimassa ulos + If player\team = 0 And gMaxSpectatorTime > 0 And Timer() - player\spectatorTime > gMaxSpectatorTime*1000 - 31000 And Timer() - gLastWarnTime > 5000 Then + timeLeft = (gMaxSpectatorTime*1000 - (Timer() - player\spectatorTime))/1000 + newMsg.NET_MESSAGES = New( NET_MESSAGES ) + newMsg\msgType = NET_SERVERMSG + newMsg\toPlayer = gCurrentPlayerId + newMsg\msgText = "You have to join to the game in "+timeLeft+" seconds or you will be kicked out" + gLastWarnTime = Timer() + EndIf + + // Liian kauan katsojana + If player\team = 0 And gMaxSpectatorTime > 0 And player\spectatorTime + gMaxSpectatorTime*1000 < Timer() Then + KickPlayer(player\playerId, 0, "Too long as a spectator") + EndIf + // Lasketaan pelaajan ja serverin välinen lagi player\lag = ( Timer() - player\lastActivity ) @@ -379,7 +410,7 @@ ServerLoop: picked = gs_valueByte // Poimitun itemin id (0, jos ei poimittu) // Arvot päivitetän vain jos pelaaja on hengissä - If player\death = False Then + If player\death = False And player\team <> 0 Then player\x = x player\y = y player\angle = angle @@ -425,7 +456,7 @@ ServerLoop: EndIf EndIf EndIf - If player\health > 0 Then player\death = False + If player\health > 0 And player\team <> 0 Then player\death = False If player\loggedIn = False Then //COM1 gPlayerCount + 1 player\loggedIn = True @@ -458,6 +489,55 @@ ServerLoop: Gosub gs_GetString player\mapName = Trim(gs_valueString) + ElseIf netmsg = NET_TEAMINFO Then + Gosub gs_GetByte + team = gs_valueByte + If team = 0 And player\team <> 0 And gMaxSpectatorTime >= 0 Then // Pelaaja haluaa katsojaksi + player\toSpectator = True + player\spectatorTime = Timer() + newMsg.NET_MESSAGES = New( NET_MESSAGES ) + newMsg\msgType = NET_SERVERMSG + newMsg\toPlayer = gCurrentPlayerId + newMsg\msgText = "You will be moved to spectators in "+gSpectatorDelay+" seconds" + ElseIf gMaxSpectatorTime < 0 Then + newMsg.NET_MESSAGES = New( NET_MESSAGES ) + newMsg\msgType = NET_SERVERMSG + newMsg\toPlayer = gCurrentPlayerId + newMsg\msgText = "Spectator mode is disabled on this server" + ElseIf team <> 0 Then + team = 1 + greenplayers = 0 + redplayers = 0 + If gPlayMode = TDM Then + For plr.PLAYERS = Each PLAYERS + If plr\active = True Then + If plr\team = 1 Then greenplayers + 1 + If plr\team = 2 Then redplayers + 1 + EndIf + Next plr + If greenplayers 0 Then visible = True - x1 = ObjectX(player\obj) - y1 = ObjectY(player\obj) - x2 = ObjectX(plr\obj) - y2 = ObjectY(plr\obj) - If Abs(x1 - x2) > 750 Then visible = False - If Abs(y1 - y2) > 650 Then visible = False - + If player\team <> 0 Then + x1 = ObjectX(player\obj) + y1 = ObjectY(player\obj) + x2 = ObjectX(plr\obj) + y2 = ObjectY(plr\obj) + If Abs(x1 - x2) > 750 Then visible = False + If Abs(y1 - y2) > 650 Then visible = False + EndIf + // Onko näkyvissä tai voidaanko muuten lähettää - If sendNames = True Or visible = True Or plr\health <= 0 Then + If sendNames = True Or visible = True Or plr\health <= 0 And plr\team <> 0 Then // Näkyy gs_valueByte = NET_PLAYER : Gosub gs_PutByte // Pelaajan tietoja gs_valueByte = plr\playerId : Gosub gs_PutByte // Pelaajan tunnus @@ -544,7 +626,7 @@ ServerLoop: gs_valueByte = plr\health : Gosub gs_PutByte // Terveys gs_valueShort = plr\kills : Gosub gs_PutShort // Tapot gs_valueShort = plr\deaths : Gosub gs_PutShort // Kuolemat - ElseIf gRadarArrows = True Or gPlayMode=TDM Then + ElseIf gRadarArrows = True Or gPlayMode=TDM And plr\team <> 0 Then // Ei näy. Lähetetään tutkatieto If player\team = plr\team And gRadarArrows = False Then gs_valueByte = NET_RADAR : Gosub gs_PutByte @@ -864,6 +946,7 @@ Function KickPlayer( _playerId, _kickerId, _reason$ = "" ) player\loggedIn = False player\active = False player\admin = False + player\team = 1 // Lähetetään viesti kaikille muille paitsi boteille For plr.PLAYERS = Each PLAYERS If plr\active = True And plr\zombie = False Then