示例#1
0
 public PartialGameStateUpdateAction(GameCore game, PseudoFullGameWorldState last = null)
 {
     if (last != null)
     {
         StatePartial = PseudoFullGameWorldState.Create(game).MakeDelta(last);
     }
     else
     {
         StatePartial = PseudoFullGameWorldState.Create(game);
     }
 }
示例#2
0
        public ServerPlayer AddPlayer(ServerPlayer player)
        {
            if (Players.Contains(player))
            {
                return(player);
            }

            player.Player.Id = Game.AvailablePlayerId;
            Game.AddPlayer(player.Player);
            _players.Add(player);

            //Queue the game state for them, delaying 1sec for connect messages to be processed fully
            Timers.CreateTimer(a =>
            {
                MessageProcessor.SendPrivateMessage(player,
                                                    new GameCreatedAction());
                MessageProcessor.SendPrivateMessage(player,
                                                    new FullGameStateSentAction(Game));
            }, TimeSpan.FromSeconds(1));
            //Announce that they joined
            ChatHandler.SendMessage($"{player.Player.Username} joined the server");

            player.LastSentState             = PseudoFullGameWorldState.Create(Game);
            player.Player.OnPropertyChanged -= Player_PropertyChanged;
            player.Player.OnPropertyChanged += Player_PropertyChanged;

            MessageProcessor.SendMessage(new PlayerUpdateAction(player.Player, Game));

            //Create a state sync loop
            Timers.CreateReccuringTimer(t =>
            {
                if (Players.Contains(player))
                {
                    var message          = new PartialGameStateUpdateAction(Game, player.LastSentState);
                    player.LastSentState = message.StatePartial;
                    //do state sync
                    MessageProcessor.SendPrivateMessage(player, message);
                }
                else
                {
                    //Disconnect
                    Timers.RemoveTimer(t);
                }
            }, Configuration.StateSyncRate);

            //Special case for hotjoin

            if (Game.HasStarted && Game.Gamemode.HotJoinEnabled)
            {
                var time = ServerSettings.Instance.TimeToWaitForPlayersReady.Value;
                Timers.CreateReccuringTimer((t) =>
                {
                    if (!Game.Running || !Game.Gamemode.HotJoinEnabled)
                    {
                        t.Remove();
                    }

                    MessageProcessor.SendPrivateMessage(player, new CountdownStartedAction(time));
                    time -= TimeSpan.FromMilliseconds(16.666);

                    if (time < TimeSpan.Zero)
                    {
                        t.Remove();
                    }
                    if (player.IsReady)
                    {
                        t.Remove();
                        MessageProcessor.SendPrivateMessage(player, new CountdownStartedAction(TimeSpan.FromSeconds(-1)));
                    }
                }, TimeSpan.FromSeconds(0.01));
            }

            return(player);
        }
示例#3
0
 public PseudoFullGameWorldState GetDeltaState(PseudoFullGameWorldState lastSentState) =>
 CurrentState.MakeDelta(lastSentState);
示例#4
0
        public void Compute(GameCore game, PseudoFullGameWorldState state)
        {
            ElapsedTime = TimeSpan.Zero;
            _game       = game;
            _corrections.Clear();
            foreach (var obj in state.ObjectStates)
            {
                if (_game.GameObjectsById.ContainsKey(obj.Key))
                {
                    var gameObj = _game.GameObjectsById[obj.Key];
                    if (!obj.Value.PositionChanged && !obj.Value.RotationChanged)
                    {
                        continue;
                    }

                    //Handle destroyed
                    if (obj.Value.WasDestroyed)
                    {
                        game.ImmediatelyForceObjectDestruction(gameObj);
                        continue;
                    }

                    //Apply the non interpolated updates
                    gameObj.IsSensor = obj.Value.IsSensorObject;
                    gameObj.IsStatic = obj.Value.IsStaticObject;

                    if (obj.Value.RestitutionChanged)
                    {
                        gameObj.Restitution = obj.Value.Restitution;
                    }
                    if (obj.Value.RotationChanged)
                    {
                        gameObj.Rotation = obj.Value.Rotation;
                    }
                    if (obj.Value.RotationVelocityChanged)
                    {
                        gameObj.AngularVelocity = obj.Value.RotationVelocity;
                    }
                    if (obj.Value.SizeChanged)
                    {
                        gameObj.Size = obj.Value.Size.ToVector2();
                    }
                    if (obj.Value.VelocityChanged)
                    {
                        gameObj.LinearVelocity = obj.Value.Velocity.ToVector2();
                    }

                    Vector2 dist;
                    if (obj.Value.PositionChanged)
                    {
                        dist = obj.Value.Position - gameObj.Position;
                    }
                    else
                    {
                        dist = Vector2.Zero;
                    }

                    float rot;
                    if (obj.Value.RotationChanged)
                    {
                        rot = obj.Value.Rotation - gameObj.Rotation;
                    }
                    else
                    {
                        rot = 0;
                    }

                    //Apply directly if it's too large
                    if (DistanceCorrectionLimit < Math.Abs(dist.X) ||
                        DistanceCorrectionLimit < Math.Abs(dist.Y) ||
                        RotationCorrectionLimit < rot)
                    {
                        gameObj.Position = obj.Value.Position;
                        gameObj.Rotation = obj.Value.Rotation;
                    }
                    else
                    {
                        //Correct slowly if it's small
                        var corr = new PseudoStateObjectCorrection();
                        corr.DistanceOffset = dist;
                        corr.RotationOffset = rot;
                        corr.Object         = gameObj;
                        _corrections.Add(corr);
                    }
                }
            }
        }
示例#5
0
 protected override void DeserializeInternal(NetIncomingMessage message)
 {
     StatePartial = PseudoFullGameWorldState.Read(message);
 }