//using System; //using System.Data; //using System.Text; //using System.Threading; //using System.Collections.ObjectModel; //using Holo.Virtual.Users; //using Holo.Virtual.Rooms.Pathfinding; //using Ion.Storage; //namespace Holo.Virtual.Rooms.Games //{ // internal class Game // { // #region Declares // /// // /// The gameLobby object where this game is hosted in. // /// // internal gameLobby Lobby; // /// // /// Indicates if this game is of the type 'BattleBall'. If false, then the game is of the type 'SnowStorm'. // /// // internal bool isBattleBall; // /// // /// The ID of this game. // /// // internal int ID; // /// // /// The display name of this game. // /// // internal string Name; // /// // /// The ID of the map that is played with this game. // /// // internal int mapID; // /// // /// The total amount of gametime in seconds. // /// // internal int totalTime; // /// // /// The amount of gametime is seconds that is still left on this game. // /// // internal int leftTime; // internal gameState State; // /// // /// BattleBall only. The numbers of the enabled powerups for this game. // /// // internal int[] enabledPowerups; // /// // /// The gamePlayer object (bbPlayer or ssPlayer) of the virtual user that has created this game. // /// // internal gamePlayer Owner; // /// // /// Collection with the gamePlayer objects of the virtual users that have 'checked in' to this game sub and should receive updates about team status etc. // /// // internal Collection Subviewers = new Collection(); // internal Collection[] Teams; // #region Map declares // #region Enumerators etc // internal enum gameState { Waiting = 0, Started = 1, Ended = 2 }; // /// // /// Represents the state of a tile on the gamemap in a game of 'BattleBall'. // /// // private enum bbTileState { Default = 0, Touched = 1, Clicked = 2, Pressed = 3, Sealed = 4 } // /// // /// Represents the color of the team that owns a tile on the gamemap in a game of 'BattleBall'. // /// // private enum bbTileColor { Disabled = -2, Default = -1, Red = 0, Blue = 1, Yellow = 2, Green = 3 } // #endregion // /// // /// The amount of seconds that the 'loading game' bar still has to be displayed. // /// // private int leftCountdownSeconds = Config.Game_Countdown_Seconds; // /// // /// The length of the arena. // private int bX; // /// // /// The max width of the arena. // /// // private int bY; // /// // /// The heightmap of the arena. // /// // internal string Heightmap; // private byte[,] Height; // private bool[,] Blocked; // private bbTileState[,] bbTState; // private bbTileColor[,] bbTColor; // private Thread updateHandler; // #endregion // #endregion // #region Constructors/destructor // /// // /// Initializes a 'BattleBall' game. // /// // /// The gameLobby object of the lobby where this game is hosted in. // /// The ID of this game. // /// The display name of this game. // /// The ID of the map that is played with this game. // /// The amount of teams that is used with the game. // /// The numbers of the enabled powerups for this game. // /// The gamePlayer instance of the virtual user that has created this game. // internal Game(gameLobby Lobby, int ID, string Name, int mapID, int teamAmount, int[] enabledPowerups, gamePlayer Owner) // { // this.Lobby = Lobby; // this.ID = ID; // this.Name = Name; // this.mapID = mapID; // this.Owner = Owner; // this.enabledPowerups = enabledPowerups; // this.totalTime = Config.Game_BattleBall_gameLength_Seconds; // this.leftTime = Config.Game_BattleBall_gameLength_Seconds; // this.isBattleBall = true; // // Dimension teams // this.Teams = new Collection[teamAmount]; // for (int i = 0; i < teamAmount; i++) // Teams[i] = new Collection(); // } // /// // /// Initializes a 'SnowStorm' game. // /// // /// The gameLobby object of the lobby where this game is hosted in. // /// The ID of this game. // /// The display name of this game. // /// The ID of the map that is played with this game. // /// The amount of teams that is used with the game. // /// The total amount of gametime in seconds. // /// The gamePlayer instance of the virtual user that has created this game. // internal Game(gameLobby Lobby, int ID, string Name, int mapID, int teamAmount, int totalTime, gamePlayer Owner) // { // this.Lobby = Lobby; // this.ID = ID; // this.Name = Name; // this.mapID = mapID; // this.Owner = Owner; // this.totalTime = totalTime; // this.leftTime = totalTime; // this.isBattleBall = false; // // Dimension teams // this.Teams = new Collection[teamAmount]; // for (int i = 0; i < teamAmount; i++) // Teams[i] = new Collection(); // } // /// // /// Stops the game, and removes all players and subviewers from the game. // /// // internal void Abort() // { // try { updateHandler.Abort(); } // catch { } // string Data = "Cm" + "H"; // for (int i = 0; i < Teams.Length; i++) // foreach (gamePlayer Member in Teams[i]) // { // if (Member.User != null) // { // if (State == gameState.Waiting) // Member.User.sendData(Data); // Member.User.gamePlayer = null; // } // } // foreach (gamePlayer subViewer in Subviewers) // { // if (subViewer.User != null) // { // if (State == gameState.Waiting) // subViewer.User.sendData(Data); // subViewer.User.gamePlayer = null; // } // } // } // #endregion // #region Player management // /// // /// Moves a player to a certain team, or removes a player from the game. // /// // /// The gamePlayer object of the player to move. // /// The ID of the team where the player was in before. If the player is new to the game, then this parameter should be -1. // /// The ID of the team where the player is moving to. If the player is leaving the game, then this parameter should be -1. // internal void movePlayer(gamePlayer Player, int fromTeamID, int toTeamID) // { // try // { // if (fromTeamID != -1) // Remove player from previous team // Teams[fromTeamID].Remove(Player); // if (toTeamID != -1) // User added to team // { // if (Teams[toTeamID].Contains(Player) == false) // Teams[toTeamID].Add(Player); // Player.teamID = toTeamID; // } // else // { // Teams[Player.teamID].Remove(Player); // Player.User.gamePlayer = null; // } // sendData("Ci" + this.Sub); // } // catch { } // } // /// // /// Indicates if the game can be launched. Games are 'launchable' when there are atleast two teams with players. // /// // internal bool Launchable // { // get // { // int activeTeamCount = 0; // for (int i = 0; i < Teams.Length; i++) // if (Teams[i].Count != 0) // This team has got players // activeTeamCount++; // return (activeTeamCount > 1); // Atleast two teams with players // } // } // /// // /// Returns a boolean that indicates if a certain team has space left for new team members. On error, false is returned. // /// // /// The ID of the team to check. // internal bool teamHasSpace(int teamID) // { // try // { // int m = 0; // int l = Teams.Length; // if (l == 2) // m = 6; // else if (l == 3) // m = 4; // else if (l == 4) // m = 3; // return (Teams[teamID].Count < m); // } // catch { return false; } // } // /// // /// Sends a single packet to all players, spectators and subviewers of this game. // /// // /// The packet to send. // internal void sendData(string Data) // { // for (int i = 0; i < Teams.Length; i++) // foreach (gamePlayer Member in Teams[i]) // Member.sendData(Data); // if (State == gameState.Waiting) // Game hasn't started yet // { // foreach (gamePlayer subViewer in Subviewers) // subViewer.sendData(Data); // } // } // #endregion // #region Properties // internal string Sub // { // get // { // StringBuilder Entry = new StringBuilder(Encoding.encodeVL64((int)State)); // if (Launchable) // Atleast two teams with waiting players // Entry.Append("I"); // 1 = Game can be started // else // Entry.Append("H"); // 0 = Game can't be started yet // Entry.Append(Name + Convert.ToChar(2) + Encoding.encodeVL64(Owner.roomUID) + Owner.User._Username + Convert.ToChar(2)); // if (isBattleBall == false) // SnowStorm game // Entry.Append(Encoding.encodeVL64(totalTime)); // Entry.Append(Encoding.encodeVL64(mapID) + Encoding.encodeVL64(0) + Encoding.encodeVL64(Teams.Length)); // for (int i = 0; i < Teams.Length; i++) // { // Entry.Append(Encoding.encodeVL64(Teams[i].Count)); // foreach (gamePlayer Member in Teams[i]) // Entry.Append(Encoding.encodeVL64(Member.roomUID) + Member.User._Username + Convert.ToChar(2)); // } // if (isBattleBall) // BattleBall game // { // for (int i = 0; i < enabledPowerups.Length; i++) // Entry.Append(enabledPowerups[i] + ","); // Entry.Append("9" + Convert.ToChar(2)); // } // else // SnowStorm game // Entry.Append(Encoding.encodeVL64(leftTime) + Encoding.encodeVL64(mapID)); // return Entry.ToString(); // } // } // #endregion // #region Arena // internal void startGame() // { // State = gameState.Started; // foreach (gamePlayer subViewer in Subviewers) // subViewer.sendData(this.Sub); // using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) // { // this.Heightmap = dbClient.getString("SELECT heightmap FROM games_maps WHERE type = '" + Lobby.Type + "' AND id = '" + mapID + "'"); // } // string[] _H = Heightmap.Split(Convert.ToChar(13)); // this.bX = _H[0].Length; // this.bY = _H.Length - 1; // string[] _T = null; // if (isBattleBall) // { // this.bbTState = new bbTileState[bX, bY]; // this.bbTColor = new bbTileColor[bX, bY]; // using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) // { // _T = dbClient.getString("SELECT bb_tilemap FROM games_maps WHERE type = 'bb' AND id = '" + mapID + "'").Split(Convert.ToChar(13)); // } // } // this.Height = new byte[bX, bY]; // this.Blocked = new bool[bX, bY]; // for (int y = 0; y < bY; y++) // { // for (int x = 0; x < bX; x++) // { // string q = _H[y].Substring(x, 1); // if (q == "x") // { // Blocked[x, y] = true; // if (isBattleBall) // { // bbTColor[x, y] = bbTileColor.Disabled; // bbTState[x, y] = bbTileState.Sealed; // } // } // else // { // Height[x, y] = Convert.ToByte(q); // if (isBattleBall) // { // if (_T[y].Substring(x, 1) == "1") // bbTColor[x, y] = bbTileColor.Default; // else // { // bbTColor[x, y] = bbTileColor.Disabled; // bbTState[x, y] = bbTileState.Sealed; // } // } // } // } // } // int j = 0; // for (int i = 0; i < Teams.Length; i++) // { // if (Teams[i].Count == 0) // Empty team // continue; // DataRow dRow; // using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) // { // dRow = dbClient.getRow("SELECT x,y,z FROM games_maps_playerspawns WHERE type = '" + Lobby.Type + "' AND mapid = '" + mapID + "' AND teamid = '" + i + "'"); // } // int spawnX = Convert.ToInt32(dRow["x"]); // int spawnY = Convert.ToInt32(dRow["y"]); // byte spawnZ = Convert.ToByte(dRow["z"]); // bool Flip = false; // foreach (gamePlayer Player in Teams[i]) // { // Player.roomUID = j; // rs: // try // { // while (Blocked[spawnX, spawnY]) // { // if (spawnZ == 0 || spawnZ == 2) // { // if (Flip) // spawnX -= 1; // else // spawnX += 1; // } // else if (spawnZ == 4 || spawnZ == 6) // { // if (Flip) // spawnY -= 1; // else // spawnY += 1; // } // } // Flip = (Flip != true); // } // catch { Flip = (Flip != true); goto rs; } // Out of range of map, reverse spawn // Blocked[spawnX, spawnY] = true; // Player.X = spawnX; // Player.Y = spawnY; // Player.Z = spawnZ; // Player.H = Height[spawnX, spawnY]; // Player.goalX = -1; // Player.enteringGame = true; // j++; // Out.WriteLine("Assigned spawnpoint [" + spawnX + "," + spawnY + "] to player [" + j + ", team id: " + Player.teamID + "]"); // } // } // sendData("Cq" + Encoding.encodeVL64(-1)); // Send players to arena // new Eucalypt.commonDelegate(countDownTicker).BeginInvoke(null, null); // Start countdown bar // } // /// // /// Counts // /// // private void countDownTicker() // { // while (leftCountdownSeconds > 0) // { // leftCountdownSeconds--; // Thread.Sleep(1000); // } // using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) // { // for (int i = 0; i < Teams.Length; i++) // foreach (gamePlayer Player in Teams[i]) // { // Player.User._Tickets -= 2; // Player.User.sendData("A|" + Player.User._Tickets); // dbClient.runQuery("UPDATE users SET tickets = '" + Player.User._Tickets + "' WHERE id = '" + Player.User.userID + "' LIMIT 1"); // } // } // // Start game // updateHandler = new Thread(new ThreadStart(updateLoop)); // updateHandler.Start(); // sendData("Cw" + Encoding.encodeVL64(totalTime)); // } // internal string getMap() // { // StringBuilder Setup = new StringBuilder(); // if (isBattleBall) // { // Setup.Append("I" + Encoding.encodeVL64(leftCountdownSeconds) + Encoding.encodeVL64(Config.Game_Countdown_Seconds) + "H" + Encoding.encodeVL64(bX) + Encoding.encodeVL64(bY)); // for (int y = 0; y < bY; y++) // for (int x = 0; x < bX; x++) // Setup.Append(Encoding.encodeVL64((int)bbTColor[x, y]) + Encoding.encodeVL64((int)bbTState[x, y])); // Setup.Append("IH"); // } // else // Setup.Append("holo.cast.not_finished"); // return Setup.ToString(); // } // internal string getPlayers() // { // StringBuilder Setup = null; // StringBuilder Helper = new StringBuilder(); // Random RND = new Random(DateTime.Now.Millisecond * totalTime); // if (isBattleBall) // { // int p = 0; // for (int i = 0; i < Teams.Length; i++) // foreach (gamePlayer Player in Teams[i]) // { // Out.WriteLine(Player.roomUID + "!"); // Helper.Append("H" + Encoding.encodeVL64(p) + Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64(Player.H) + Encoding.encodeVL64(Player.Z) + "HM" + Player.User._Username + Convert.ToChar(2) + Player.User._Mission + Convert.ToChar(2) + Player.User._Figure + Convert.ToChar(2) + Player.User._Sex + Convert.ToChar(2) + Encoding.encodeVL64(Player.teamID) + Encoding.encodeVL64(Player.roomUID)); // p++; // } // Setup = new StringBuilder("I" + Encoding.encodeVL64(leftCountdownSeconds) + Encoding.encodeVL64(Config.Game_Countdown_Seconds) + Encoding.encodeVL64(p)); // Setup.Append(Helper.ToString()); // Helper = null; // Setup.Append(Encoding.encodeVL64(bX) + Encoding.encodeVL64(bY)); // for (int y = 0; y < bY; y++) // for (int x = 0; x < bX; x++) // Setup.Append(Encoding.encodeVL64((int)bbTColor[x, y]) + Encoding.encodeVL64((int)bbTState[x, y])); // Setup.Append("IH"); // } // else // Setup.Append("holo.cast.not_finished"); // return Setup.ToString(); // } // private void updateLoop() // { // if (isBattleBall) // { // int teamAmount = Teams.Length; // int[] teamScores = new int[teamAmount]; // bool subtrSecond = false; // int activeTeamAmount = 0; // for (int i = 0; i < teamAmount; i++) // { // if (Teams[i].Count > 0) // activeTeamAmount++; // else // teamScores[i] = -1; // } // Random RND = new Random(DateTime.Now.Millisecond * teamAmount); // while (leftTime > 0) // { // int[] Amounts = new int[3]; // [0] = unit amount, [1] = updated tile amount, [2] = moving units amount // StringBuilder Players = new StringBuilder(); // StringBuilder updatedTiles = new StringBuilder(); // StringBuilder Movements = new StringBuilder(); // for (int i = 0; i < teamAmount; i++) // foreach (gamePlayer Player in Teams[i]) // { // Players.Append("H" + Encoding.encodeVL64(Player.roomUID) + Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64(Player.H) + Encoding.encodeVL64(Player.Z) + "HM"); // if (Player.bbColorTile) // { // Player.bbColorTile = false; // updatedTiles.Append(Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64((int)bbTColor[Player.X, Player.Y]) + Encoding.encodeVL64((int)bbTState[Player.X, Player.Y])); // Amounts[1]++; // } // if (Player.goalX != -1) // { // Coord Next = gamePathfinder.getNextStep(Player.X, Player.Y, Player.goalX, Player.goalY); // if (Next.X != -1 && Blocked[Next.X, Next.Y] == false) // { // Amounts[2]++; // Movements.Append("J" + Encoding.encodeVL64(Player.roomUID) + Encoding.encodeVL64(Next.X) + Encoding.encodeVL64(Next.Y)); // if (Next.X == Player.goalX && Next.Y == Player.goalY) // Player.goalX = -1; // Blocked[Player.X, Player.Y] = false; // Blocked[Next.X, Next.Y] = true; // Player.Z = Rotation.Calculate(Player.X, Player.Y, Next.X, Next.Y); // Player.X = Next.X; // Player.Y = Next.Y; // Player.H = Height[Next.X, Next.Y]; // if (bbTState[Next.X, Next.Y] != bbTileState.Sealed) // { // if (bbTColor[Next.X, Next.Y] == (bbTileColor)Player.teamID) // Already property of this team, increment the state // bbTState[Next.X, Next.Y]++; // else // { // bbTState[Next.X, Next.Y] = bbTileState.Touched; // bbTColor[Next.X, Next.Y] = (bbTileColor)Player.teamID; // } // int extraPoints = 0; // switch ((int)bbTState[Next.X, Next.Y]) // Check the new status and calculate extra points // { // case 1: // extraPoints = activeTeamAmount; // break; // case 2: // extraPoints = activeTeamAmount * 3; // break; // case 3: // extraPoints = activeTeamAmount * 5; // break; // case 4: // extraPoints = activeTeamAmount * 7; // break; // } // teamScores[Player.teamID] += extraPoints; // Player.Score += extraPoints; // Player.bbColorTile = true; // } // } // else // Player.goalX = -1; // Stop moving // } // Amounts[0]++; // } // string scoreString = "H" + Encoding.encodeVL64(teamAmount); // for (int i = 0; i < teamAmount; i++) // scoreString += Encoding.encodeVL64(teamScores[i]); // sendData("Ct" + Encoding.encodeVL64(Amounts[0]) + Players.ToString() + Encoding.encodeVL64(Amounts[1]) + updatedTiles.ToString() + scoreString + "I" + Encoding.encodeVL64(Amounts[2]) + Movements.ToString()); // if (subtrSecond) // leftTime--; // subtrSecond = (subtrSecond != true); // Thread.Sleep(470); // } // State = gameState.Ended; // StringBuilder Scores = new StringBuilder("Cx" + Encoding.encodeVL64(Config.Game_scoreWindow_restartGame_Seconds) + Encoding.encodeVL64(teamAmount)); // for (int i = 0; i < teamAmount; i++) // { // int memberAmount = Teams[i].Count; // if (memberAmount > 0) // { // Scores.Append(Encoding.encodeVL64(memberAmount)); // using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) // { // foreach (gamePlayer Player in Teams[i]) // { // Scores.Append(Encoding.encodeVL64(Player.roomUID)); // if (Player.User != null) // { // dbClient.runQuery("UPDATE users SET bb_playedgames = bb_playedgames + 1,bb_totalpoints = bb_totalpoints + " + Player.Score + " WHERE id = '" + Player.User.userID + "' LIMIT 1"); // Scores.Append(Player.User._Username + Convert.ToChar(2)); // } // else // Scores.Append("M"); // Scores.Append(Encoding.encodeVL64(Player.Score)); // } // } // Scores.Append(Encoding.encodeVL64(teamScores[i])); // } // else // Scores.Append("M"); // } // sendData(Scores.ToString()); // } // } // private Coord[] getSurfaceTiles(Coord Start) // { // return null; // } // #endregion // } //} using System; using System.Data; using System.Text; using System.Threading; using System.Collections.ObjectModel; using Holo.Virtual.Users; using Holo.Virtual.Rooms.Pathfinding; using Ion.Storage; namespace Holo.Virtual.Rooms.Games { internal class Game { #region Declares /// /// Indicates if this game is of the type 'BattleBall'. If false, then the game is of the type 'SnowStorm'. /// internal bool isBattleBall; /// /// The ID of this game. /// internal int ID; /// /// The ID of the map that is played with this game. /// internal int mapID; /// /// The total amount of gametime in seconds. /// internal int totalTime; /// /// Indicates if this game is private or not /// internal bool isPrivate; /// /// The amount of gametime is seconds that is still left on this game. /// internal int leftTime; internal gameState State; /// /// BattleBall only. The numbers of the enabled powerups for this game. /// internal int[] enabledPowerups; /// /// The gamePlayer object (bbPlayer or ssPlayer) of the virtual user that has created this game. /// internal gamePlayer Owner; /// /// Collection with the gamePlayer objects of the virtual users that have 'checked in' to this game sub and should receive updates about team status etc. /// internal Collection Subviewers = new Collection(); internal Collection[] Teams; #region Map declares #region Enumerators etc internal enum gameState { Waiting = 0, Started = 1, Ended = 2 }; /// /// Represents the state of a tile on the gamemap in a game of 'BattleBall'. /// private enum bbTileState { Default = 0, Touched = 1, Clicked = 2, Pressed = 3, Sealed = 4 } /// /// Represents the color of the team that owns a tile on the gamemap in a game of 'BattleBall'. /// private enum bbTileColor { Disabled = -2, Default = -1, Red = 0, Blue = 1, Yellow = 2, Green = 3 } #endregion /// /// The amount of seconds that the 'loading game' bar still has to be displayed. /// private int leftCountdownSeconds = Config.Game_Countdown_Seconds; /// /// The length of the arena. private int bX; /// /// The max width of the arena. /// private int bY; /// /// The heightmap of the arena. /// internal string Heightmap; private byte[,] Height; private bool[,] Blocked; private bbTileState[,] bbTState; private bbTileColor[,] bbTColor; private Thread updateHandler; #endregion #endregion #region Constructors/destructor /// /// Initializes a 'BattleBall' game. /// /// The gameLobby object of the lobby where this game is hosted in. /// The ID of this game. /// The display name of this game. /// The ID of the map that is played with this game. /// The amount of teams that is used with the game. /// The numbers of the enabled powerups for this game. /// The gamePlayer instance of the virtual user that has created this game. internal Game(int ID, int mapID, int teamAmount, int[] enabledPowerups, bool isPrivate, gamePlayer Owner) { this.isPrivate = isPrivate; this.ID = ID; this.mapID = mapID; this.Owner = Owner; this.enabledPowerups = enabledPowerups; this.totalTime = Config.Game_BattleBall_gameLength_Seconds; this.leftTime = Config.Game_BattleBall_gameLength_Seconds; this.isBattleBall = true; // Dimension teams this.Teams = new Collection[teamAmount]; for (int i = 0; i < teamAmount; i++) Teams[i] = new Collection(); } /// /// Initializes a 'SnowStorm' game. /// /// The gameLobby object of the lobby where this game is hosted in. /// The ID of this game. /// The display name of this game. /// The ID of the map that is played with this game. /// The amount of teams that is used with the game. /// The total amount of gametime in seconds. /// The gamePlayer instance of the virtual user that has created this game. internal Game(int ID, int mapID, int teamAmount, int totalTime, gamePlayer Owner) { this.ID = ID; this.mapID = mapID; this.Owner = Owner; this.totalTime = totalTime; this.leftTime = totalTime; this.isBattleBall = false; // Dimension teams this.Teams = new Collection[teamAmount]; for (int i = 0; i < teamAmount; i++) Teams[i] = new Collection(); } /// /// Stops the game, and removes all players and subviewers from the game. /// internal void Abort() { try { updateHandler.Abort(); } catch { } string Data = "Cm" + "H"; for (int i = 0; i < Teams.Length; i++) foreach (gamePlayer Member in Teams[i]) { if (Member.User != null) { if (State == gameState.Waiting) Member.User.sendData(Data); Member.User.gamePlayer = null; } } foreach (gamePlayer subViewer in Subviewers) { if (subViewer.User != null) { if (State == gameState.Waiting) subViewer.User.sendData(Data); subViewer.User.gamePlayer = null; } } } #endregion #region Player management /// /// Moves a player to a certain team, or removes a player from the game. /// /// The gamePlayer object of the player to move. /// The ID of the team where the player was in before. If the player is new to the game, then this parameter should be -1. /// The ID of the team where the player is moving to. If the player is leaving the game, then this parameter should be -1. internal void movePlayer(gamePlayer Player, int fromTeamID, int toTeamID) { try { if (fromTeamID != -1) // Remove player from previous team Teams[fromTeamID].Remove(Player); if (toTeamID != -1) // User added to team { if (Teams[toTeamID].Contains(Player) == false) Teams[toTeamID].Add(Player); Player.teamID = toTeamID; } else { Teams[Player.teamID].Remove(Player); Player.User.gamePlayer = null; } // sendData("Ci" + this.Sub); } catch { } } /// /// Indicates if the game can be launched. Games are 'launchable' when there are atleast two teams with players. /// internal bool Launchable { get { int activeTeamCount = 0; for (int i = 0; i < Teams.Length; i++) if (Teams[i].Count != 0) // This team has got players activeTeamCount++; return (activeTeamCount > 1); // Atleast two teams with players } } /// /// Returns a boolean that indicates if a certain team has space left for new team members. On error, false is returned. /// /// The ID of the team to check. internal bool teamHasSpace(int teamID) { try { int ID = teamID - 1; int m = 0; int l = Teams.Length; if (l == 2) m = 6; else if (l == 3) m = 4; else if (l == 4) m = 3; return (Teams[ID].Count < m); } catch { return false; } } /// /// Sends a single packet to all players, spectators and subviewers of this game. /// /// The packet to send. internal void sendData(string Data) { for (int i = 0; i < Teams.Length; i++) foreach (gamePlayer Member in Teams[i]) Member.User.sendData(Data); if (State == gameState.Waiting) // Game hasn't started yet { foreach (gamePlayer subViewer in Subviewers) subViewer.User.sendData(Data); } } #endregion #region Properties internal string Info { get { StringBuilder Entry = new StringBuilder(Encoding.encodeVL64(ID)); Entry.Append("SnowStorm level 6"); Entry.Append(Convert.ToChar(2)); Entry.Append("I"); Entry.Append(Encoding.encodeVL64(mapID)); Entry.Append(Encoding.encodeVL64(1)); // Snowstorm only, time Entry.Append(Encoding.encodeVL64(getPlayerCount())); Entry.Append(Encoding.encodeVL64(12)); Entry.Append(Owner.User._Username); Entry.Append(Convert.ToChar(2)); Entry.Append("I"); // UNKNOWN Entry.Append(Encoding.encodeVL64(Teams.Length)); Entry.Append(Encoding.encodeVL64(getPlayerCount())); // UNKNOWN for (int i = 0; i < Teams.Length; i++) { int h = 0; foreach (gamePlayer Member in Teams[i]) { Entry.Append(Encoding.encodeVL64(h)); Entry.Append(Member.User._Username); Entry.Append(Convert.ToChar(2)); Entry.Append(Member.User._Figure); Entry.Append(Convert.ToChar(2)); Entry.Append(Member.User._Sex.ToString().ToLower()); Entry.Append(Convert.ToChar(2)); h++; } } //Entry.Append(Convert.ToChar(2)); //Entry.Append("JXKA"); // UNKNOWN //Entry.Append("Fa" //+ "RP" //+ "SnowStorm level 6" //+ "" //+ "I" //+ "RA" //+ "I" //+ "RA" //+ "PC" //+ "Monsta." //+ "" //+ "RA" //+ "I" //+ "I"); //Entry.Append("H" //+ "Monsta." //+ "" //+ "hd-190-1.ch-255-81.lg-280-89.sh-906-63.hr-831-61.he-1609-62" //+ "" //+ "m" //+ ""); /* + "I" + "BUCK245" + "" + "hd-180-16.ch-260-82.lg-285-64.sh-906-64.hr-155-38.ea-1404-64" + "" + "m" + "" + "J" + "bourno25" + "" + "hr-889-40.hd-207-30.ch-267-62.lg-281-62.sh-906-62.ea-1404-64.wa-2012-.ha-1002-64.ca-1802-.fa-1205-64" + "" + "m" + "" + "K" + "rosiebear999" + "" + "hr-545-34.hd-600-7.ch-630-62.lg-700-64.sh-725-62.ea-1406-62.fa-1204-62" + "" + "f" + "" + "PA" + "addzy1996" + "" + "hd-205-12.ch-260-71.lg-270-64.sh-305-71.hr-165-39.ha-1010-71" + "" + "m" + "" + "QA" + "MallonBopper" + "" + "hd-180-1.ch-255-64.lg-280-64.sh-300-64.wa-2002-.hr-165-48" + "" + "m" + ""*/ //Entry.Append("HXKA"); return Entry.ToString(); } } #endregion #region Arena internal void startGame() { State = gameState.Started; // foreach (gamePlayer subViewer in Subviewers) // subViewer.sendData(this.Sub); using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { this.Heightmap = dbClient.getString("SELECT heightmap FROM games_maps WHERE id = '" + mapID + "'"); } string[] _H = Heightmap.Split(Convert.ToChar(13)); this.bX = _H[0].Length; this.bY = _H.Length - 1; string[] _T = null; if (isBattleBall) { this.bbTState = new bbTileState[bX, bY]; this.bbTColor = new bbTileColor[bX, bY]; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { _T = dbClient.getString("SELECT bb_tilemap FROM games_maps WHERE type = 'bb' AND id = '" + mapID + "'").Split(Convert.ToChar(13)); } } this.Height = new byte[bX, bY]; this.Blocked = new bool[bX, bY]; for (int y = 0; y < bY; y++) { for (int x = 0; x < bX; x++) { string q = _H[y].Substring(x, 1); if (q == "x") { Blocked[x, y] = true; if (isBattleBall) { bbTColor[x, y] = bbTileColor.Disabled; bbTState[x, y] = bbTileState.Sealed; } } else { Height[x, y] = Convert.ToByte(q); if (isBattleBall) { if (_T[y].Substring(x, 1) == "1") bbTColor[x, y] = bbTileColor.Default; else { bbTColor[x, y] = bbTileColor.Disabled; bbTState[x, y] = bbTileState.Sealed; } } } } } int j = 0; for (int i = 0; i < Teams.Length; i++) { if (Teams[i].Count == 0) // Empty team continue; DataRow dRow; using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { dRow = dbClient.getRow("SELECT x,y,z FROM games_maps_playerspawns WHERE mapid = '" + mapID + "' AND teamid = '" + i + "'"); } int spawnX = Convert.ToInt32(dRow["x"]); int spawnY = Convert.ToInt32(dRow["y"]); byte spawnZ = Convert.ToByte(dRow["z"]); bool Flip = false; foreach (gamePlayer Player in Teams[i]) { Player.roomUID = j; rs: try { while (Blocked[spawnX, spawnY]) { if (spawnZ == 0 || spawnZ == 2) { if (Flip) spawnX -= 1; else spawnX += 1; } else if (spawnZ == 4 || spawnZ == 6) { if (Flip) spawnY -= 1; else spawnY += 1; } } Flip = (Flip != true); } catch { Flip = (Flip != true); goto rs; } // Out of range of map, reverse spawn Blocked[spawnX, spawnY] = true; Player.X = spawnX; Player.Y = spawnY; Player.Z = spawnZ; Player.H = Height[spawnX, spawnY]; Player.goalX = -1; Player.enteringGame = true; j++; Out.WriteLine("Assigned spawnpoint [" + spawnX + "," + spawnY + "] to player [" + j + ", team id: " + Player.teamID + "]"); } } sendData("FP" + Encoding.encodeVL64(-1)); // Send players to arena sendData("FR"); sendData("FS"); new Eucalypt.commonDelegate(countDownTicker).BeginInvoke(null, null); // Start countdown bar } /// /// Counts /// private void countDownTicker() { while (leftCountdownSeconds > 0) { leftCountdownSeconds--; Thread.Sleep(1000); } using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { for (int i = 0; i < Teams.Length; i++) foreach (gamePlayer Player in Teams[i]) { Player.User._Tickets -= 2; Player.User.sendData("A|" + Player.User._Tickets); dbClient.runQuery("UPDATE users SET tickets = '" + Player.User._Tickets + "' WHERE id = '" + Player.User.userID + "' LIMIT 1"); } } // Start game updateHandler = new Thread(new ThreadStart(updateLoop)); updateHandler.Start(); sendData("Cw" + Encoding.encodeVL64(totalTime)); } internal string getMap() { StringBuilder Setup = new StringBuilder(); if (isBattleBall) { Setup.Append("I" + Encoding.encodeVL64(leftCountdownSeconds) + Encoding.encodeVL64(Config.Game_Countdown_Seconds) + "H" + Encoding.encodeVL64(bX) + Encoding.encodeVL64(bY)); for (int y = 0; y < bY; y++) for (int x = 0; x < bX; x++) Setup.Append(Encoding.encodeVL64((int)bbTColor[x, y]) + Encoding.encodeVL64((int)bbTState[x, y])); Setup.Append("IH"); } else Setup.Append("holo.cast.not_finished"); return Setup.ToString(); } internal string getPlayers() { StringBuilder Setup = null; StringBuilder Helper = new StringBuilder(); Random RND = new Random(DateTime.Now.Millisecond * totalTime); if (isBattleBall) { int p = 0; for (int i = 0; i < Teams.Length; i++) foreach (gamePlayer Player in Teams[i]) { Out.WriteLine(Player.roomUID + "!"); Helper.Append("H" + Encoding.encodeVL64(p) + Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64(Player.H) + Encoding.encodeVL64(Player.Z) + "HM" + Player.User._Username + Convert.ToChar(2) + Player.User._Mission + Convert.ToChar(2) + Player.User._Figure + Convert.ToChar(2) + Player.User._Sex + Convert.ToChar(2) + Encoding.encodeVL64(Player.teamID) + Encoding.encodeVL64(Player.roomUID)); p++; } Setup = new StringBuilder("I" + Encoding.encodeVL64(leftCountdownSeconds) + Encoding.encodeVL64(Config.Game_Countdown_Seconds) + Encoding.encodeVL64(p)); Setup.Append(Helper.ToString()); Helper = null; Setup.Append(Encoding.encodeVL64(bX) + Encoding.encodeVL64(bY)); for (int y = 0; y < bY; y++) for (int x = 0; x < bX; x++) Setup.Append(Encoding.encodeVL64((int)bbTColor[x, y]) + Encoding.encodeVL64((int)bbTState[x, y])); Setup.Append("IH"); } else Setup.Append("holo.cast.not_finished"); return Setup.ToString(); } internal int getPlayerCount() { int p = 0; for (int i = 0; i < Teams.Length; i++) foreach (gamePlayer Player in Teams[i]) p++; return p; } internal bool addPlayer(gamePlayer Player, int team) { team = team - 1; if (teamHasSpace(team)) { Teams[team].Add(Player); return true; } else for (int i = 0; i < Teams.Length; i++) { if (teamHasSpace(i)) { Teams[i].Add(Player); return true; } } return false; } private void updateLoop() { if (isBattleBall) { int teamAmount = Teams.Length; int[] teamScores = new int[teamAmount]; bool subtrSecond = false; int activeTeamAmount = 0; for (int i = 0; i < teamAmount; i++) { if (Teams[i].Count > 0) activeTeamAmount++; else teamScores[i] = -1; } Random RND = new Random(DateTime.Now.Millisecond * teamAmount); while (leftTime > 0) { int[] Amounts = new int[3]; // [0] = unit amount, [1] = updated tile amount, [2] = moving units amount StringBuilder Players = new StringBuilder(); StringBuilder updatedTiles = new StringBuilder(); StringBuilder Movements = new StringBuilder(); for (int i = 0; i < teamAmount; i++) foreach (gamePlayer Player in Teams[i]) { Players.Append("H" + Encoding.encodeVL64(Player.roomUID) + Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64(Player.H) + Encoding.encodeVL64(Player.Z) + "HM"); if (Player.bbColorTile) { Player.bbColorTile = false; updatedTiles.Append(Encoding.encodeVL64(Player.X) + Encoding.encodeVL64(Player.Y) + Encoding.encodeVL64((int)bbTColor[Player.X, Player.Y]) + Encoding.encodeVL64((int)bbTState[Player.X, Player.Y])); Amounts[1]++; } if (Player.goalX != -1) { Coord Next = gamePathfinder.getNextStep(Player.X, Player.Y, Player.goalX, Player.goalY); if (Next.X != -1 && Blocked[Next.X, Next.Y] == false) { Amounts[2]++; Movements.Append("J" + Encoding.encodeVL64(Player.roomUID) + Encoding.encodeVL64(Next.X) + Encoding.encodeVL64(Next.Y)); if (Next.X == Player.goalX && Next.Y == Player.goalY) Player.goalX = -1; Blocked[Player.X, Player.Y] = false; Blocked[Next.X, Next.Y] = true; Player.Z = Rotation.Calculate(Player.X, Player.Y, Next.X, Next.Y); Player.X = Next.X; Player.Y = Next.Y; Player.H = Height[Next.X, Next.Y]; if (bbTState[Next.X, Next.Y] != bbTileState.Sealed) { if (bbTColor[Next.X, Next.Y] == (bbTileColor)Player.teamID) // Already property of this team, increment the state bbTState[Next.X, Next.Y]++; else { bbTState[Next.X, Next.Y] = bbTileState.Touched; bbTColor[Next.X, Next.Y] = (bbTileColor)Player.teamID; } int extraPoints = 0; switch ((int)bbTState[Next.X, Next.Y]) // Check the new status and calculate extra points { case 1: extraPoints = activeTeamAmount; break; case 2: extraPoints = activeTeamAmount * 3; break; case 3: extraPoints = activeTeamAmount * 5; break; case 4: extraPoints = activeTeamAmount * 7; break; } teamScores[Player.teamID] += extraPoints; Player.Score += extraPoints; Player.bbColorTile = true; } } else Player.goalX = -1; // Stop moving } Amounts[0]++; } string scoreString = "H" + Encoding.encodeVL64(teamAmount); for (int i = 0; i < teamAmount; i++) scoreString += Encoding.encodeVL64(teamScores[i]); sendData("Ct" + Encoding.encodeVL64(Amounts[0]) + Players.ToString() + Encoding.encodeVL64(Amounts[1]) + updatedTiles.ToString() + scoreString + "I" + Encoding.encodeVL64(Amounts[2]) + Movements.ToString()); if (subtrSecond) leftTime--; subtrSecond = (subtrSecond != true); Thread.Sleep(470); } State = gameState.Ended; StringBuilder Scores = new StringBuilder("Cx" + Encoding.encodeVL64(Config.Game_scoreWindow_restartGame_Seconds) + Encoding.encodeVL64(teamAmount)); for (int i = 0; i < teamAmount; i++) { int memberAmount = Teams[i].Count; if (memberAmount > 0) { Scores.Append(Encoding.encodeVL64(memberAmount)); using (DatabaseClient dbClient = Eucalypt.dbManager.GetClient()) { foreach (gamePlayer Player in Teams[i]) { Scores.Append(Encoding.encodeVL64(Player.roomUID)); if (Player.User != null) { dbClient.runQuery("UPDATE users SET bb_playedgames = bb_playedgames + 1,bb_totalpoints = bb_totalpoints + " + Player.Score + " WHERE id = '" + Player.User.userID + "' LIMIT 1"); Scores.Append(Player.User._Username + Convert.ToChar(2)); } else Scores.Append("M"); Scores.Append(Encoding.encodeVL64(Player.Score)); } } Scores.Append(Encoding.encodeVL64(teamScores[i])); } else Scores.Append("M"); } sendData(Scores.ToString()); } } private Coord[] getSurfaceTiles(Coord Start) { return null; } #endregion } }