private static ICharacterRenderProperties EnsureCorrectXAndY(ICharacterRenderProperties renderProperties, byte x, byte y)
        {
            var opposite             = renderProperties.Direction.Opposite();
            var tempRenderProperties = renderProperties
                                       .WithDirection(opposite)
                                       .WithMapX(x)
                                       .WithMapY(y);

            return(renderProperties
                   .WithMapX(tempRenderProperties.GetDestinationX())
                   .WithMapY(tempRenderProperties.GetDestinationY()));
        }
        //standing = 0
        //sitting: chair floor
        //attacking: 0 1 2   +animated (0-1-2-0)
        //walking:   0 1 2 3 +animated (0-1-2-3-0)
        //spellcast: 0 1     +animated (0-1-0)

        public override void Update(GameTime gameTime)
        {
            _currentState = Keyboard.GetState();

            var update = false;

            if (KeyPressed(Keys.D1))
            {
                _baseProperties = _baseProperties.WithGender((byte)((_baseProperties.Gender + 1) % 2));
                update          = true;
            }
            else if (KeyPressed(Keys.D2))
            {
                _baseProperties = _baseProperties.WithHairStyle((byte)((_baseProperties.HairStyle + 1) % 21));
                update          = true;
            }
            else if (KeyPressed(Keys.D3))
            {
                _baseProperties = _baseProperties.WithHatGraphic(GetNextItemGraphicMatching(ItemType.Hat, _baseProperties.HatGraphic));
                update          = true;
            }
            else if (KeyPressed(Keys.D4))
            {
                _baseProperties = _baseProperties.WithArmorGraphic(GetNextItemGraphicMatching(ItemType.Armor, _baseProperties.ArmorGraphic));
                update          = true;
            }
            else if (KeyPressed(Keys.D5))
            {
                _baseProperties = _baseProperties.WithBootsGraphic(GetNextItemGraphicMatching(ItemType.Boots, _baseProperties.BootsGraphic));
                update          = true;
            }
            else if (KeyPressed(Keys.D6) && !_isBowEquipped)
            {
                _baseProperties = _baseProperties.WithWeaponGraphic(GetNextItemGraphicMatching(ItemType.Weapon, _baseProperties.WeaponGraphic));
                update          = true;
            }
            else if (KeyPressed(Keys.D7))
            {
                _baseProperties = _baseProperties.WithShieldGraphic(GetNextItemGraphicMatching(ItemType.Shield, _baseProperties.ShieldGraphic));
                update          = true;
            }
            else if (KeyPressed(Keys.D8))
            {
                _baseProperties = _baseProperties.WithDirection((EODirection)(((int)_baseProperties.Direction + 1) % 4));
                update          = true;
            }
            else if (KeyPressed(Keys.Space))
            {
                if (!_isBowEquipped)
                {
                    _lastGraphic = _baseProperties.WeaponGraphic;
                    var firstBowWeapon = EIFFile.Data.First(x => x.Type == ItemType.Weapon && x.SubType == ItemSubType.Ranged);
                    _baseProperties = _baseProperties.WithWeaponGraphic((short)firstBowWeapon.DollGraphic);
                }
                else
                {
                    _baseProperties = _baseProperties.WithWeaponGraphic(_lastGraphic);
                }

                _isBowEquipped = !_isBowEquipped;
                update         = true;
            }

            if (update)
            {
                RefreshDisplayedCharacters();
            }

            _previousState = _currentState;

            var now = DateTime.Now;

            if ((now - _lastWalk).TotalMilliseconds > CharacterAnimator.WALK_FRAME_TIME_MS)
            {
                var rend = _renderersForDifferentStates[(int)DisplayState.WalkingAnimation];
                rend.RenderProperties = rend.RenderProperties.WithNextWalkFrame();
                _lastWalk             = now;
            }

            if ((now - _lastAttack).TotalMilliseconds > CharacterAnimator.ATTACK_FRAME_TIME_MS)
            {
                var rend = _renderersForDifferentStates[(int)DisplayState.AttackingAnimation];
                rend.RenderProperties = rend.RenderProperties.WithNextAttackFrame();
                _lastAttack           = now;
            }

            if ((now - _lastSpell).TotalMilliseconds > 280)
            {
                var rend = _renderersForDifferentStates[(int)DisplayState.SpellCastAnimation];
                rend.RenderProperties = rend.RenderProperties.WithNextSpellCastFrame();
                _lastSpell            = now;
            }

            base.Update(gameTime);
        }