예제 #1
0
파일: Player.cs 프로젝트: Cyral/Bricklayer
        /// <summary>
        /// Calculates the Y velocity accounting for jumping and
        /// animates accordingly.
        /// </summary>
        /// <remarks>
        /// During the accent of a jump, the Y velocity is completely
        /// overridden by a power curve. During the decent, gravity takes
        /// over. The jump velocity is controlled by the jumpTime field
        /// which measures time into the accent of the current jump.
        /// </remarks>
        /// <param name="velocityY">
        /// The player's current velocity along the Y axis.
        /// </param>
        /// <returns>
        /// A new Y velocity if beginning or continuing a jump.
        /// Otherwise, the existing Y velocity.
        /// </returns>
        protected float DoJump(float velocityY, GameTime gameTime)
        {
            // If the player wants to jump
            if (IsJumping)
            {
                // Begin or continue a jump
                if ((!WasJumping && IsOnGround) || JumpTime > 0.0f)
                {
                    if (JumpTime == 0)
                        JumpDirection = GravityDirection; //Set the direction this jump started from
                    if (JumpTime == 0 && IsMine)
                    {
                        //Send message we are now jumping
                        PlayerStateMessage msg = new PlayerStateMessage(this);
                        msg.IsJumping = true;
                        Game.NetManager.Send(msg);
                    }
                    JumpTime += (float)gameTime.ElapsedGameTime.TotalSeconds; //Incriment jump timer
                }

                //If we are in the ascent of the jump
                if (0.0f < JumpTime && JumpTime <= MaxJumpTime)
                {
                    //Fully override the vertical velocity with a power curve that gives players more control over the top of the jump
                    velocityY = (JumpDirection == GravityDirection.Up || JumpDirection == GravityDirection.Left ? -1 : 1) * (JumpLaunchVelocity * (1.0f - (float)Math.Pow(JumpTime / MaxJumpTime, JumpControlPower)));
                }
                else
                {
                    if (JumpTime > 0 && IsMine)
                    {
                        //Tell others we are falling now
                        PlayerStateMessage msg = new PlayerStateMessage(this);
                        msg.IsJumping = false;
                        Game.NetManager.Send(msg);
                    }
                    JumpTime = 0.0f;   // Reached the apex of the jump
                    IsJumping = false;
                }
            }
            else
            {
                //Tell others we have landed
                if (JumpTime > 0 && IsMine)
                    Game.NetManager.Send(new PlayerStateMessage(this));
                // Continues not jumping or cancels a jump in progress
                JumpTime = 0.0f;
            }
            WasJumping = IsJumping;

            return velocityY;
        }
예제 #2
0
        /// <summary>
        /// Handles a data message (The bulk of all messages recieved, containing player movements, block places, etc)
        /// </summary>
        private void HandleDataMessage(NetIncomingMessage im)
        {
            MessageTypes messageType = (MessageTypes)im.ReadByte(); //Find the type of data message sent
            switch (messageType)
            {
                case MessageTypes.Lobby: //Lobby list packet
                    {
                        if (Game.CurrentGameState == GameState.Lobby)
                        {
                            LobbyScreen screen = MainWindow.ScreenManager.Current as LobbyScreen;
                            LobbyMessage msg = new LobbyMessage(im);
                            screen.Name = msg.ServerName;
                            screen.Description = msg.Description;
                            screen.Intro = msg.Intro;
                            screen.Online = msg.Online;
                            screen.Rooms = msg.Rooms;
                            screen.Lobby.LoadRooms();
                        }
                        break;
                    }
                case MessageTypes.PlayerJoin: //Player join message
                    {
                        PlayerJoinMessage user = new PlayerJoinMessage(im);
                        //Add player to map
                        Map.Players.Add(new Player(Map, Map.Spawn, user.Username, user.ID) { Tint = user.Color });
                        //Add user to userlist
                        (MainWindow.ScreenManager.Current as GameScreen).PlayerList.Items.Add(user.Username);
                        if (user.ID != Game.MyID && recievedInit) //Broadcast join message to chat
                        {
                            (MainWindow.ScreenManager.Current as GameScreen).SystemChat(user.Username + " [color:LightGray]has[/color] [color:LightGreen]joined.[/color]");
                        }
                        if (user.Me)
                        {
                            //Let game know of it's own player
                            Game.MyID = user.ID;
                            Game.MyIndex = (byte)Map.Players.IndexOf(Map.Players.First(x => x.ID == Game.MyID));
                            Game.Me.Tint = Game.MyColor;
                        }
                        break;
                    }
                case MessageTypes.PlayerLeave: //Player leave message
                    {
                        PlayerLeaveMessage user = new PlayerLeaveMessage(im);
                        //Remove player
                        if (user.ID != Game.MyID)
                        {
                            Player player = (Player)Map.PlayerFromID(user.ID);
                            Map.Players.Remove((Player)Map.PlayerFromID(user.ID));
                            (MainWindow.ScreenManager.Current as GameScreen).PlayerList.Items.Remove(player.Username);
                            (MainWindow.ScreenManager.Current as GameScreen).SystemChat(player.Username + " [color:LightGray]has[/color] [color:IndianRed]left.[/color]");
                            //Rebuild indexes
                            for (int i = 0; i < Map.Players.Count; i++)
                            {
                                Map.Players[i].Index = i;
                                if (Map.Players[i].ID == Game.MyID)
                                    Game.MyIndex = (byte)i;
                            }
                        }
                        break;
                    }
                case MessageTypes.PlayerStatus: //Player move message
                    {
                        if (Game.CurrentGameState == GameState.Game)
                        {
                            PlayerStateMessage user = new PlayerStateMessage(im);
                            Player player = (Player)Map.PlayerFromID(user.ID);
                            player.SimulationState.Position = user.Position.ToVector2();
                            player.SimulationState.Velocity = user.Velocity.ToVector2();
                            player.SimulationState.Movement = user.Movement.ToVector2();
                            if (!recievedInit) //If we have not recieved init (meaning we are not in game yet), set the initial positions directly so interpolation doesn't mess with them
                                player.DisplayState.Position = player.SimulationState.Position;
                            player.VirtualJump = user.IsJumping;
                        }
                        break;
                    }
                case MessageTypes.Block: //Block place message
                    {
                        if (Game.CurrentGameState == GameState.Game)
                        {
                            BlockMessage msg = new BlockMessage(im);
                            BlockType block = BlockType.FromID(msg.BlockID);
                            if (Map.CanPlaceBlock(msg.X, msg.Y, msg.Z, block))
                                Map.Tiles[msg.X, msg.Y, msg.Z].Block = block;
                        }
                        break;
                    }
                case MessageTypes.PlayerSmiley: //Smiley change message
                    {
                        if (Game.CurrentGameState == GameState.Game)
                        {
                            PlayerSmileyMessage msg = new PlayerSmileyMessage(im);
                            Player p = (Player)Map.PlayerFromID(msg.ID);
                            p.Smiley = msg.Smiley;
                        }
                        break;
                    }
                case MessageTypes.PlayerMode: //Player mode change message
                    {
                        if (Game.CurrentGameState == GameState.Game)
                        {
                            PlayerModeMessage mode = new PlayerModeMessage(im);
                            Map.PlayerFromID(mode.ID).Mode = (PlayerMode)mode.Mode;
                        }
                        break;
                    }
                case MessageTypes.Chat: //Chat message
                    {
                        if (Game.CurrentGameState == GameState.Game)
                        {
                            ChatMessage chat = new ChatMessage(im);
                            (MainWindow.ScreenManager.Current as GameScreen).AddChat(Map.PlayerFromID(chat.ID).Username, chat.Message);
                        }
                        break;
                    }
                case MessageTypes.Init: //Initialization message with world data
                    {
                        Game.Map = new Bricklayer.Client.World.Map(game, 1, 1);
                        InitMessage msg = new InitMessage(im, Map);

                        Game.Map.Minimap = new Minimap(Game.Map, msg.Width, msg.Height) { Position = new Microsoft.Xna.Framework.Vector2(8, 8) };
                        Game.Map.CreateCamera();

                        Game.CurrentGameState = GameState.Game;
                        (MainWindow.ScreenManager.Current as GameScreen).Show();
                        (MainWindow.ScreenManager.Current as GameScreen).SystemChat("Connected to [color:LightGray]" + Game.Host + ":" + Game.Port + "[/color]");
                        recievedInit = true;
                        break;
                    }
            }
        }
예제 #3
0
        /// <summary>
        /// Handles all actions for recieving data messages (Such as movement, block placing, etc)
        /// </summary>
        /// <param name="inc">The incoming message</param>
        private void ProcessDataMessage(NetIncomingMessage inc)
        {
            Player sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
            Map map = null;
            if (sender != null)
                map = (Map)sender.Map;
            MessageTypes type = (MessageTypes)Enum.Parse(typeof(MessageTypes), inc.ReadByte().ToString());
            switch (type)
            {
                //When a player request to recieve a message
                case MessageTypes.Request:
                    {
                        MessageTypes request = new RequestMessage(inc).RequestType;

                        //Request to recieve lobby data
                        if (request == MessageTypes.Lobby)
                        {
                            List<LobbySaveData> rooms = new List<LobbySaveData>();
                            foreach (Map m in Maps)
                            {
                                rooms.Add(LobbySaveData.FromMap(m));
                            }
                            LobbyMessage msg = new LobbyMessage(Server.Config.Name, Server.Config.Decription, Server.Config.Intro, NetworkManager.NetServer.ConnectionsCount, rooms);
                            NetManager.Send(msg, inc.SenderConnection);
                        }
                        break;
                    }
                //When a player exits to the lobby
                case MessageTypes.PlayerLeave:
                    {
                        PlayerLeaveMessage user = new PlayerLeaveMessage(inc);
                        user.ID = sender.ID;
                        Log.WriteLine(LogType.Room, "{0} has left: {1}", sender.Username, sender.Map.Name);
                        //Remove player
                        map.Players.Remove(sender);
                        RebuildIndexes(map);
                        //Send to players
                        NetManager.Broadcast(sender.Map, new PlayerLeaveMessage(sender.ID));
                        IO.SaveMap((Bricklayer.Server.World.Map)sender.Map);
                        sender = null;
                        break;
                    }
                //When a player moves
                case MessageTypes.PlayerStatus:
                    {
                        PlayerStateMessage state = new PlayerStateMessage(inc);
                        state.ID = sender.ID;
                        //Clamp position in bounds
                        state.Position = new Point((int)MathHelper.Clamp(state.Position.X, Tile.Width, (map.Width * Tile.Width) - (Tile.Width * 2)), (int)MathHelper.Clamp(state.Position.Y, Tile.Height, (map.Height * Tile.Height) - (Tile.Height * 2)));
                        sender.SimulationState.Position = state.Position.ToVector2();
                        sender.SimulationState.Velocity = state.Velocity.ToVector2();
                        sender.SimulationState.Movement = state.Movement.ToVector2();
                        sender.IsJumping = state.IsJumping;

                        NetManager.BroadcastExcept(state, sender);
                        break;
                    }
                //When a player places a block
                case MessageTypes.Block:
                    {
                        BlockMessage state = new BlockMessage(inc);
                        BlockType block = BlockType.FromID(state.BlockID);
                        //Verify Block (Make sure it is in bounds and it has changed, no use sending otherwise)
                        //TODO: Punish players spamming invalid data (Because official client should never send it)
                        if (map.InBounds(state.X, state.Y, state.Z) && map.Tiles[state.X, state.Y, state.Z].Block.ID != block.ID)
                        {
                            map.Tiles[state.X, state.Y, state.Z].Block = block;
                            NetManager.Broadcast(sender.Map, state);
                        }
                        break;
                    }
                //When a player sends a chat message
                case MessageTypes.Chat:
                    {
                        ChatMessage chat = new ChatMessage(inc);
                        chat.ID = sender.ID;

                        //Verify length
                        if (chat.Message.Length > ChatMessage.MaxLength)
                            chat.Message = chat.Message.Truncate(ChatMessage.MaxLength);
                        NetManager.BroadcastExcept(chat, sender);

                        //Log message
                        Log.WriteLine(LogType.Chat, ConsoleColor.Gray, "<{0}> {1}", sender.Username, chat.Message);
                        break;
                    }
                //When a player changes smiley
                case MessageTypes.PlayerSmiley:
                    {
                        PlayerSmileyMessage smiley = new PlayerSmileyMessage(inc);
                        smiley.ID = sender.ID;
                        if (sender.Smiley != smiley.Smiley)
                        {
                            sender.Smiley = smiley.Smiley;
                            NetManager.BroadcastExcept(smiley, sender);
                        }
                        break;
                    }
                //When a player changes mode (Ex: godmode to normal
                case MessageTypes.PlayerMode:
                    {
                        PlayerModeMessage mode = new PlayerModeMessage(inc);
                        mode.ID = sender.ID;
                        if (sender.Mode != mode.Mode)
                        {
                            sender.Mode = mode.Mode;
                            NetManager.BroadcastExcept(mode, sender);
                        }
                        break;
                    }

                //When a player requests to join a room
                case MessageTypes.JoinRoom:
                    {
                        if (sender == null) //If the sender isn't null, then they are already in a room
                        {
                            JoinRoomMessage msg = new JoinRoomMessage(inc);
                            int newMap = Maps.IndexOf(Server.MapFromID(msg.ID));
                            LoginMessage login = Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier]; //Fetch stored login from dictionary
                            Maps[newMap].Players.Add(new Player(Maps[newMap], Maps[newMap].Spawn, login.Username, inc.SenderConnection.RemoteUniqueIdentifier, Server.FindEmptyID(Maps[newMap])) { Tint = login.Color });
                            sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
                            NetManager.Send(new InitMessage(sender.Map), sender);
                            //Send message to player notifing he is connected and ready
                            NetManager.Send(new PlayerJoinMessage(sender.Username, sender.ID, true, sender.Tint), sender);

                            //Log message
                            Log.WriteLine(LogType.Room, "{0} joined: {1}", login.Username, Maps[newMap].Name);
                            //Send message to everyone notifying of new user
                            NetManager.BroadcastExcept(new PlayerJoinMessage(sender.Username, sender.ID, false, sender.Tint), sender);
                            //Let new player know of all existing players and their states (Mode, Position, Smiley)
                            foreach (Player player in sender.Map.Players)
                            {
                                if (player.ID != sender.ID)
                                {
                                    NetManager.Send(new PlayerJoinMessage(player.Username, player.ID, false, player.Tint), sender);
                                    NetManager.Send(new PlayerStateMessage(player), sender);
                                    if (player.Mode != PlayerMode.Normal)
                                        NetManager.Send(new PlayerModeMessage(player), sender);
                                    if (player.Smiley != SmileyType.Default)
                                        NetManager.Send(new PlayerSmileyMessage(player, player.Smiley), sender);
                                }
                            }
                        }
                        break;
                    }
                //When a player requests to make a room
                case MessageTypes.CreateRoom: //If the sender isn't null, then they are already in a room
                    {
                        if (sender == null)
                        {
                            CreateRoomMessage msg = new CreateRoomMessage(inc);
                            Map newMap = Server.CreateMap(msg.Name, msg.Description);
                            LoginMessage login = Server.Logins[inc.SenderConnection.RemoteUniqueIdentifier]; //Fetch stored login from dictionary
                            newMap.Players.Add(new Player(newMap, newMap.Spawn, login.Username, inc.SenderConnection.RemoteUniqueIdentifier, Server.FindEmptyID(newMap)) { Tint = login.Color });
                            sender = Server.PlayerFromRUI(inc.SenderConnection.RemoteUniqueIdentifier, true);
                            //Send message to player notifing he is connected and ready
                            NetManager.Send(new InitMessage(sender.Map), sender);
                            NetManager.Send(new PlayerJoinMessage(sender.Username, sender.ID, true, sender.Tint), sender);
                            //Log message
                            Log.WriteLine(LogType.Room, "{0} created room: {1}", login.Username, newMap.Name);
                        }
                        break;
                    }
            }
        }