예제 #1
0
        public VisibleEntity GetEntityByPoint(Point p)
        {
            var mousePoint = p.Add(Document.ViewPoint);

            for (int i = Document.Items.Count - 1; i >= 0; i--)
            {
                VisibleEntity Item = Document.Items[i];

                if (new Rectangle(Item.Location, Item.Size).Contains(mousePoint))
                {
                    return(Item);
                }
            }
            return(null);
        }
예제 #2
0
        public static Theme GetThemeFromItemNoFlow(VisibleEntity Item)
        {
            Theme ItemTheme = ThemeConfig.Directory.ContainsKey(Item.Type()) ? ThemeConfig.Directory[Item.Type()] : null;

            if (ItemTheme == null)
            {
                ItemTheme = ThemeConfig.DefaultTheme;

                if (ItemTheme == null) // Cant draw..., maybe the next one will have a set theme...
                {
                    return(null);
                }
            }

            return(ItemTheme);
        }
예제 #3
0
        protected override void OnMouseMove(MouseEventArgs e)
        {
            bool RefreshScreen = false;

            if (IsMouseWheenDown)
            {
                Document.ViewPoint = IsSpaceDown ?
                                     Document.ViewPoint.Add(e.Location.Sub(OffsetMiddleClick).Mul(2)) :
                                     Document.ViewPoint.Sub(e.Location.Sub(OffsetMiddleClick));

                OffsetMiddleClick = e.Location;

                RefreshScreen = true;
            }

            if (IsLeftMouseDown)
            {
                if (DragItem != null)
                {
                    DragItem.Location = OffsetClick.Add(e.Location);
                    RefreshScreen     = true;
                }
                else if (IsDraggingPoint)
                {
                    LeftClickDragLocation = e.Location;
                    RefreshScreen         = true;
                }
            }
            else
            {
                var prev = HoverItem;
                HoverItem = GetEntityByPoint(e.Location);
                if (prev != HoverItem)
                {
                    RefreshScreen = true;
                }
            }
            if (RefreshScreen)
            {
                Refresh();
            }
            base.OnMouseMove(e);
        }
예제 #4
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            IsLeftMouseDown  = e.Button == MouseButtons.Left;
            IsMouseWheenDown = e.Button == MouseButtons.Middle;
            IsDraggingPoint  = false;

            if (IsLeftMouseDown)
            {
                LeftClickDown = e.Location;

                var FoundItem = GetEntityByPoint(LeftClickDown);
                ClickedOn = FoundItem;
                DragItem  = null;

                if (FoundItem != null)
                {
                    OffsetClick = FoundItem.Location.Sub(LeftClickDown);

                    if (new Rectangle(FoundItem.Location, new Size(FoundItem.Size.Width, GetThemeFromItem(FoundItem).HeaderHeight)).Contains(LeftClickDown.Add(Document.ViewPoint)))
                    {
                        // Drag!
                        DragItem = FoundItem;
                    }
                    else
                    {
                        if (FoundItem.ConnectionRules == ConnectionRules.Both || FoundItem.ConnectionRules == ConnectionRules.Output)
                        {
                            LeftClickDragLocation = LeftClickDown;
                            IsDraggingPoint       = true;
                        }
                    }
                }

                FocusedItem = FoundItem;
            }
            if (IsMouseWheenDown)
            {
                OffsetMiddleClick = e.Location;
            }

            base.OnMouseDown(e);
        }
예제 #5
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            IsLeftMouseDown = e.Button == MouseButtons.Left;
            if (IsLeftMouseDown)
            {
                IsLeftMouseDown = false;
                if (IsDraggingPoint)
                {
                    var FoundItem = GetEntityByPoint(LeftClickDragLocation);

                    if (FoundItem != null)
                    {
                        FoundItem.AddConnection(new NodeConnection()
                        {
                            Output = ClickedOn, Input = FoundItem
                        });
                    }
                    ClickedOn = null;

                    IsDraggingPoint = false;
                }
            }
            IsMouseWheenDown = e.Button == MouseButtons.Middle;
            if (IsMouseWheenDown)
            {
                IsMouseWheenDown = false;
            }

            if (DragItem != null)
            {
                Document.Items.Remove(DragItem);
                Document.Items.Add(DragItem);

                DragItem = null;
            }


            Refresh();

            base.OnMouseUp(e);
        }
예제 #6
0
        public Theme GetThemeFromItem(VisibleEntity Item)
        {
            Theme ItemTheme = ThemeConfig.Directory.ContainsKey(Item.Type()) ? ThemeConfig.Directory[Item.Type()] : null;

            if (ItemTheme == null)
            {
                ItemTheme = ThemeConfig.DefaultTheme;

                if (ItemTheme == null) // Cant draw..., maybe the next one will have a set theme...
                {
                    return(null);
                }
            }

            if (Item == FocusedItem)
            {
                if (ItemTheme.FocusedTheme == null && ThemeConfig.DefaultTheme.FocusedTheme != null)
                {
                    ItemTheme = ThemeConfig.DefaultTheme.FocusedTheme;
                }
                else if (ItemTheme.FocusedTheme != null)
                {
                    ItemTheme = ItemTheme.FocusedTheme;
                }
            }
            else if (Item == HoverItem)
            {
                if (ItemTheme.HoverTheme == null && ThemeConfig.DefaultTheme.HoverTheme != null)
                {
                    ItemTheme = ThemeConfig.DefaultTheme.HoverTheme;
                }
                else if (ItemTheme.HoverTheme != null)
                {
                    ItemTheme = ItemTheme.HoverTheme;
                }
            }

            return(ItemTheme);
        }
예제 #7
0
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            if (Document == null || Document.Items.Count == 0)
            {
                return;
            }

            // for testing.
            //if(P1 != null && P2 != null)
            //{
            //    e.Graphics.DrawCurve(Pens.Black, GetPointsFrom(P1, P2));
            //}

            List <VisibleEntity> NotVisible = new List <VisibleEntity>();
            List <VisibleEntity> Visible    = new List <VisibleEntity>();

            Rectangle ViewRectangle = new Rectangle(this.Document.ViewPoint, this.Size);

            for (int i = 0, length = Document.Items.Count; i < length; i++)
            {
                VisibleEntity Item = Document.Items[i];
                if (DragItem != Item)
                {
                    if (ViewRectangle.IntersectsWith(new Rectangle(Item.Location, Item.Size)))
                    {
                        Visible.Add(Item);
                    }
                    else
                    {
                        NotVisible.Add(Item);
                    }
                }
            }

            for (int i = 0, length = Visible.Count; i < length; i++)
            {
                // Render Connections
                VisibleEntity Item = Document.Items[i];
                Point         ItemLocationInView = Item.Location.Sub(Document.ViewPoint);

                foreach (var connection in Item.Connections)
                {
                    if (connection.Input != null && connection.Output != null)
                    {
                        Point Point2;

                        if (connection.Input == Item)
                        {
                            Point2 = connection.Output.Location.Sub(Document.ViewPoint);
                        }
                        else if (connection.Output == Item)
                        {
                            Point2 = connection.Input.Location.Sub(Document.ViewPoint);
                        }
                        else
                        {
                            continue;
                        }

                        e.Graphics.DrawLine(Pens.Black, ItemLocationInView, Point2);
                    }
                }
            }

            for (int i = 0, length = Visible.Count; i < length; i++)
            {
                // Render Connections
                VisibleEntity Item = Document.Items[i];
                Item.Render(GetThemeFromItem(Item), e.Graphics, Item.Location.Sub(Document.ViewPoint));
            }

            if (DragItem != null)
            {
                Point ItemLocationInView = DragItem.Location.Sub(Document.ViewPoint);

                DragItem.Render(GetThemeFromItem(DragItem), e.Graphics, ItemLocationInView);

                foreach (var connection in DragItem.Connections)
                {
                    if (connection.Input != null && connection.Output != null)
                    {
                        Point Point2;

                        if (connection.Input == DragItem)
                        {
                            Point2 = connection.Output.Location.Sub(Document.ViewPoint);
                        }
                        else if (connection.Output == DragItem)
                        {
                            Point2 = connection.Input.Location.Sub(Document.ViewPoint);
                        }
                        else
                        {
                            continue;
                        }

                        e.Graphics.DrawLine(Pens.Black, ItemLocationInView, Point2);
                    }
                }
            }

            if (DrawNodesNotVisible)
            {
                Point Centre = new Point(Document.ViewPoint.X + this.Size.Width / 2, Document.ViewPoint.Y + this.Size.Height / 2);

                for (int i = 0, length = NotVisible.Count; i < length; i++)
                {
                    //NotVisible[i]
                    if (NotVisible[i].Connections.Count > 0)
                    {
                        Point ItemLocationInView = NotVisible[i].Location.Sub(Document.ViewPoint);

                        foreach (var connection in NotVisible[i].Connections)
                        {
                            if (connection.Input != null && connection.Output != null)
                            {
                                Point Point2;

                                if (connection.Input == NotVisible[i])
                                {
                                    if (NotVisible.Contains(connection.Output))
                                    {
                                        continue;
                                    }
                                    Point2 = connection.Output.Location.Sub(Document.ViewPoint);
                                }
                                else if (connection.Output == NotVisible[i])
                                {
                                    if (NotVisible.Contains(connection.Input))
                                    {
                                        continue;
                                    }
                                    Point2 = connection.Input.Location.Sub(Document.ViewPoint);
                                }
                                else
                                {
                                    continue;
                                }

                                e.Graphics.DrawLine(Pens.Black, ItemLocationInView, Point2);
                            }
                        }
                    }


                    // Get Distance?
                    double Distance = NotVisible[i].Location.GetDistanceBetweenPoints(Centre);
                    var    Item     = NotVisible[i];
                    if (Item.Type().Name.Length > 0)
                    {
                        Theme theme = GetThemeFromItem(Item);
                        using (SolidBrush brush = new SolidBrush(theme.Forecolor))
                        {
                            // #TODO# WORK OUT WHERE WE SHOULD DRAW NODE


                            //TextRenderer.DrawText(e.Graphics, Item.Type().Name, theme.Font, , theme.Forecolor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                        }
                    }
                }
            }

            if (IsDraggingPoint)
            {
                //                private Point LeftClickDown;
                //private Point LeftClickDragLocation;
                e.Graphics.DrawLine(Pens.Black, LeftClickDown, LeftClickDragLocation);
            }

            if (DrawLocation)
            {
                TextRenderer.DrawText(e.Graphics, string.Format("Location: {0}\r\nVisible: {1}\r\nHidden: {2}\r\nTotal: {3}",
                                                                Document.ViewPoint, Document.Items.Count - NotVisible.Count, NotVisible.Count, Document.Items.Count)
                                      , this.Font, Point.Empty, this.ForeColor);
            }
        }
예제 #8
0
        VisibleEntity AddEntity( [NotNull] Player player ) {
            if( player == null ) throw new ArgumentNullException( "player" );
            if (freePlayerIDs.Count > 0) {
                var newEntity = new VisibleEntity(VisibleEntity.HiddenPosition, freePlayerIDs.Pop(), player.Info.Rank);
                entities.Add(player, newEntity);
#if DEBUG_MOVEMENT
                Logger.Log( LogType.Debug, "AddEntity: {0} added {1} ({2})", Name, newEntity.Id, player.Name );
#endif
				Position pos = new Position(0, 0, 0);
				if (player.World != null) {
					pos = player.WorldMap.Spawn;
				}
                if (Supports(CpeExtension.ExtPlayerList2)) {
                    Send(Packet.MakeExtAddEntity2(newEntity.Id, player.Info.Rank.Color + player.Name,
						(player.Info.skinName == "" ? player.Name : player.Info.skinName), pos, this));
                    Send(Packet.MakeTeleport(newEntity.Id, player.Position));
                } else {
                    Send(Packet.MakeAddEntity(newEntity.Id, player.Info.Rank.Color + player.Name,
                        player.WorldMap.Spawn));
                    Send(Packet.MakeTeleport(newEntity.Id, player.Position));
                }
                if (Supports(CpeExtension.ChangeModel)) {
                    string addedModel = player.Info.IsAFK ? player.AFKModel : player.Info.Mob;
                    if (Info.Rank.CanSee(player.Info.Rank) && (addedModel.ToLower().Equals("air") || addedModel.ToLower().Equals("0"))) {
                        addedModel = "Humanoid";
                    }
                    Send(Packet.MakeChangeModel((byte)newEntity.Id, addedModel));
                }
                return newEntity;
            } else {
                throw new InvalidOperationException("Player.AddEntity: Ran out of entity IDs.");
            }
        }        
예제 #9
0
파일: Session.cs 프로젝트: fragmer/fCraft
        void MoveEntity( VisibleEntity entity, Position newPos ) {
            Position oldPos = entity.LastKnownPosition;

            // calculate difference between old and new positions
            Position delta = new Position {
                X = (short)(newPos.X - oldPos.X),
                Y = (short)(newPos.Y - oldPos.Y),
                H = (short)(newPos.H - oldPos.H),
                R = (byte)Math.Abs( newPos.R - oldPos.R ),
                L = (byte)Math.Abs( newPos.L - oldPos.L )
            };

            bool posChanged = (delta.X != 0) || (delta.Y != 0) || (delta.H != 0);
            bool rotChanged = (delta.R != 0) || (delta.L != 0);

            if( skipUpdates ) {
                int distSquared = delta.X * delta.X + delta.Y * delta.Y + delta.H * delta.H;
                // movement optimization
                if( distSquared < SkipMovementThresholdSquared &&
                    (delta.R * delta.R + delta.L * delta.L) < SkipRotationThresholdSquared &&
                    !entity.SkippedLastMove ) {

                    entity.SkippedLastMove = true;
                    return;
                }
                entity.SkippedLastMove = false;
            }

            Packet packet;
            // create the movement packet
            if( partialUpdates && delta.FitsIntoByte() && fullUpdateCounter < FullPositionUpdateInterval ) {
                if( posChanged && rotChanged ) {
                    // incremental position + rotation update
                    packet = PacketWriter.MakeMoveRotate( entity.Id, new Position {
                        X = delta.X,
                        Y = delta.Y,
                        H = delta.H,
                        R = newPos.R,
                        L = newPos.L
                    } );

                } else if( posChanged ) {
                    // incremental position update
                    packet = PacketWriter.MakeMove( entity.Id, delta );

                } else if( rotChanged ) {
                    // absolute rotation update
                    packet = PacketWriter.MakeRotate( entity.Id, newPos );
                } else {
                    return;
                }

            } else {
                // full (absolute position + rotation) update
                packet = PacketWriter.MakeTeleport( entity.Id, newPos );
            }

            entity.LastKnownPosition = newPos;
            SendNow( packet );
        }
예제 #10
0
파일: Session.cs 프로젝트: fragmer/fCraft
 void ReAddEntity( VisibleEntity entity, Player player, Position newPos ) {
     SendNow( PacketWriter.MakeRemoveEntity( entity.Id ) );
     SendNow( PacketWriter.MakeAddEntity( entity.Id, player.GetListName(), newPos ) );
     entity.LastKnownPosition = newPos;
 }
예제 #11
0
파일: Session.cs 프로젝트: fragmer/fCraft
 void ShowEntity( VisibleEntity entity, Position newPos ) {
     entity.Hidden = false;
     entity.LastKnownPosition = newPos;
     SendNow( PacketWriter.MakeTeleport( entity.Id, newPos ) );
 }
예제 #12
0
파일: Session.cs 프로젝트: fragmer/fCraft
 void HideEntity( VisibleEntity entity ) {
     entity.Hidden = true;
     entity.LastKnownPosition = VisibleEntity.HiddenPosition;
     SendNow( PacketWriter.MakeTeleport( entity.Id, VisibleEntity.HiddenPosition ) );
 }
예제 #13
0
파일: Session.cs 프로젝트: fragmer/fCraft
 void AddEntity( Player player, Position newPos ) {
     var pos = new VisibleEntity( newPos, freePlayerIDs.Pop(), player.Info.Rank );
     entities.Add( player, pos );
     SendNow( PacketWriter.MakeAddEntity( pos.Id, player.GetListName(), newPos ) );
 }
예제 #14
0
 void AddEntity([NotNull] Player player, Position newPos)
 {
     if (player == null) throw new ArgumentNullException("player");
     if (freePlayerIDs.Count > 0)
     {
         var pos = new VisibleEntity(newPos, freePlayerIDs.Pop(), player.Info.Rank);
         entities.Add(player, pos);
         SendNow(PacketWriter.MakeAddEntity(entities[player].Id, player.Info.Rank.Color + player.Name, newPos));
         if (ClassiCube && Heartbeat.ClassiCube())
         {
             SendNow(PacketWriter.MakeExtAddEntity((byte)entities[player].Id, player.ListName, player.Name));
             SendNow(PacketWriter.MakeExtAddPlayerName((short)pos.Id, player.Name, player.ListName, player.Info.Rank.ClassyName, (byte)player.Info.Rank.Index));
         }
     }
 }
예제 #15
0
 void AddEntity( [NotNull] Player player, Position newPos )
 {
     if( player == null ) throw new ArgumentNullException( "player" );
     if( freePlayerIDs.Count > 0 ) {
         var pos = new VisibleEntity( newPos, freePlayerIDs.Pop(), player.Info.Rank );
         entities.Add( player, pos );
         SendNow( PacketWriter.MakeAddEntity( pos.Id, player.ListName, newPos ) );
     }
 }
예제 #16
0
        VisibleEntity AddEntity( [NotNull] Player player ) {
            if( player == null ) throw new ArgumentNullException( "player" );
            if( freePlayerIDs.Count > 0 ) {
                var newEntity = new VisibleEntity( VisibleEntity.HiddenPosition, freePlayerIDs.Pop(), player.Info.Rank );
                entities.Add( player, newEntity );
#if DEBUG_MOVEMENT
                Logger.Log( LogType.Debug, "AddEntity: {0} added {1} ({2})", Name, newEntity.Id, player.Name );
#endif
                SendNow( PacketWriter.MakeAddEntity( newEntity.Id, player.ListName, newEntity.LastKnownPosition ) );
                return newEntity;
            } else {
                throw new InvalidOperationException( "Player.AddEntity: Ran out of entity IDs." );
            }
        }
예제 #17
0
        void UpdateVisibleEntities() {
            if( World == null ) PlayerOpException.ThrowNoWorld( this );

            // handle following the spectatee
            if( spectatedPlayer != null ) {
                if( !spectatedPlayer.IsOnline || !CanSee( spectatedPlayer ) ) {
                    Message( "Stopped spectating {0}&S (disconnected)", spectatedPlayer.ClassyName );
                    spectatedPlayer = null;
                } else {
                    Position spectatePos = spectatedPlayer.Position;
                    World spectateWorld = spectatedPlayer.World;
                    if( spectateWorld == null ) {
                        throw new InvalidOperationException( "Trying to spectate player without a world." );
                    }
                    if( spectateWorld != World ) {
                        if( CanJoin( spectateWorld ) ) {
                            postJoinPosition = spectatePos;
                            if( JoinWorldNow( spectateWorld, false, WorldChangeReason.SpectateTargetJoined ) ) {
                                Message( "Joined {0}&S to continue spectating {1}",
                                         spectateWorld.ClassyName,
                                         spectatedPlayer.ClassyName );
                            } else {
                                Message( "Stopped spectating {0}&S (cannot join {1}&S)",
                                         spectatedPlayer.ClassyName,
                                         spectateWorld.ClassyName );
                                spectatedPlayer = null;
                            }
                        } else {
                            Message( "Stopped spectating {0}&S (cannot join {1}&S)",
                                     spectatedPlayer.ClassyName,
                                     spectateWorld.ClassyName );
                            spectatedPlayer = null;
                        }
                    } else if( spectatePos != Position ) {
                        SendNow( Packet.MakeSelfTeleport( spectatePos ) );
                    }
                    if (SpectatedPlayer.Info.heldBlock != Info.heldBlock && SpectatedPlayer.Supports(CpeExtension.HeldBlock))
                    {
                        SendNow(Packet.MakeHoldThis(SpectatedPlayer.Info.heldBlock, false));
                    }
                }
            }

            // check every player on the current world
            Player[] worldPlayerList = World.Players;
            Position pos = Position;
            foreach (Bot bot in World.Bots.Where(b => b.World == World)) {
                if (!bot.oldModel.ToLower().Equals(bot.Model.ToLower()) && Supports(CpeExtension.ChangeModel)) {
                    Send(Packet.MakeChangeModel((byte)bot.ID, bot.Model));
                    bot.oldModel = bot.Model;
                }
                if (bot.oldSkinName != bot.SkinName && Supports(CpeExtension.ExtPlayerList2)) {
                    Send(Packet.MakeRemoveEntity(bot.ID));
					Send(Packet.MakeExtAddEntity2(bot.ID, bot.Name, (bot.SkinName == "" ? bot.Name : bot.SkinName), bot.Position, this));
                    Send(Packet.MakeChangeModel((byte)bot.ID, bot.Model));
                    bot.oldSkinName = bot.SkinName;
                }
                
            }
            for( int i = 0; i < worldPlayerList.Length; i++ ) {
                Player otherPlayer = worldPlayerList[i];
                // Fetch or create a VisibleEntity object for the player
                VisibleEntity entity;
                if (!otherPlayer.CanSee(this))
                    goto skip;
                if (otherPlayer != this) {
                    if (otherPlayer.entities.TryGetValue(this, out entity)) {
                        entity.MarkedForRetention = true;
                    } else {
                        entity = otherPlayer.AddEntity(this);
                    }
                } else {
                    entity = new VisibleEntity(Position, -1, Info.Rank);
                }
                if (Info.oldskinName != Info.skinName && otherPlayer.Supports(CpeExtension.ExtPlayerList2)) {
					otherPlayer.Send(Packet.MakeExtAddEntity2(entity.Id, Info.Rank.Color + Name, 
						(Info.skinName == "" ? Name : Info.skinName), WorldMap.Spawn, otherPlayer));
                    if (otherPlayer == this) {
                        otherPlayer.Send(Packet.MakeTeleport(entity.Id, Position));
                    }

                }
                if ((Info.oldMob != Info.Mob || Info.oldafkMob != Info.afkMob) && otherPlayer.Supports(CpeExtension.ChangeModel)) {

                    string thisModel = Info.IsAFK ? AFKModel : Info.Mob;
                    if (otherPlayer.Info.Rank.CanSee(Info.Rank) && (thisModel.ToLower().Equals("air") || thisModel.ToLower().Equals("0"))) {
                        thisModel = "Humanoid";
                    }
                    otherPlayer.Send(Packet.MakeChangeModel((byte)entity.Id, thisModel));
                }
            skip:

                if (otherPlayer == this) {
                    continue;
                }
                if (!CanSee(otherPlayer))
                    continue;
                if (entities.TryGetValue(otherPlayer, out entity)) {
                    entity.MarkedForRetention = true;
                } else {
                    entity = AddEntity(otherPlayer);
                }

                Position otherPos = otherPlayer.Position;
                int distance = pos.DistanceSquaredTo( otherPos );

                // Re-add player if their rank changed (to maintain correct name colors/prefix)
                if( entity.LastKnownRank != otherPlayer.Info.Rank ) {
                    ReAddEntity( entity, otherPlayer );
                    entity.LastKnownRank = otherPlayer.Info.Rank;
                }

                if( entity.Hidden ) {
                    if( distance < entityShowingThreshold && CanSeeMoving( otherPlayer ) ) {
                        ShowEntity( entity, otherPos );
                    }

                } else {
                    if( distance > entityHidingThreshold || !CanSeeMoving( otherPlayer ) ) {
                        HideEntity( entity );

                    } else if( entity.LastKnownPosition != otherPos ) {
                        MoveEntity( entity, otherPos );
                    }
                }

                if (spectatedPlayer == otherPlayer) { //Hide player being spectated
                    HideEntity(entity);
                } else if (otherPlayer.spectatedPlayer == this) { //Hide player spectating you
                    HideEntity(entity);
                } else if (otherPlayer.IsSpectating) { //Is other player spectating?...
                    if (CanSee(otherPlayer)) { //...Update location of player who is able to be seen while hidden
                        MoveEntity(entity, entity.LastKnownPosition);
                    } else { //..Hide other player
                        HideEntity(entity);
                    }
                }
            }
            Info.oldskinName = Info.skinName;
            Info.oldMob = Info.Mob;
            Info.oldafkMob = Info.afkMob;

            // Find entities to remove (not marked for retention).
            foreach( var pair in entities ) {
                if( pair.Value.MarkedForRetention ) {
                    pair.Value.MarkedForRetention = false;
                } else {
                    playersToRemove.Push( pair.Key );
                }
            }

            // Remove non-retained entities
            while( playersToRemove.Count > 0 ) {
                RemoveEntity( playersToRemove.Pop() );
            }

            fullUpdateCounter++;
            if( fullUpdateCounter >= FullPositionUpdateInterval ) {
                fullUpdateCounter = 0;
            }
        }