using Client.Domain.Common; using Client.Domain.Entities; using Client.Domain.Service; using Client.Domain.ValueObjects; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; using System.Windows.Media.Animation; using System.Collections.Specialized; using Client.Application.Commands; using System.Reflection.Metadata; using System.Windows; namespace Client.Application.ViewModels { public class MapViewModel : ObservableObject { public Hero? Hero { get => hero; set { if (hero != value) { if (hero != null) { hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; } hero = value; if (hero != null) { hero.Transform.Position.PropertyChanged += HeroPosition_PropertyChanged; } UpdateMap(); } } } public double ViewportWidth { get => viewportWidth; set { if (viewportWidth != value) { viewportWidth = value; UpdateMap(); } } } public double ViewportHeight { get => viewportHeight; set { if (viewportHeight != value) { viewportHeight = value; UpdateMap(); } } } public float Scale { get => scale; set { if (scale != value) { scale = value; UpdateMap(); OnPropertyChanged(); } } } private void HeroPosition_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { UpdateMap(); } private void UpdateMap() { foreach (var block in Blocks) { block.Visible = false; } if (hero != null) { var blocks = selector.SelectImages((float)ViewportWidth, (float)ViewportHeight, hero.Transform.Position, Scale); foreach (var block in blocks) { if (this.blocks.ContainsKey(block.Id)) { this.blocks[block.Id].MapBlock.DeltaX = block.DeltaX; this.blocks[block.Id].MapBlock.DeltaY = block.DeltaY; this.blocks[block.Id].MapBlock.Size = block.Size; } else { var model = new MapBlockViewModel(block); this.blocks.Add(block.Id, model); Blocks.Add(model); } this.blocks[block.Id].Visible = true; } foreach (var creature in Creatures) { creature.Scale = scale; creature.VieportSize = new Vector3((float)ViewportWidth, (float)ViewportHeight, 0); } foreach (var drop in Drops) { drop.Scale = scale; drop.VieportSize = new Vector3((float)ViewportWidth, (float)ViewportHeight, 0); } } } public ICommand MouseLeftClickCommand { get; } private void OnLeftMouseClick(object? obj) { if (obj == null) { return; } if (hero == null) { return; } Point mousePos = Mouse.GetPosition((IInputElement)obj); var location = new Vector3( (float)(mousePos.X - ViewportWidth / 2) * scale + hero.Transform.Position.X, (float)(mousePos.Y - ViewportHeight / 2) * scale + hero.Transform.Position.Y, hero.Transform.Position.Z ); worldHandler.RequestMoveToLocation(location); } public MapViewModel(WorldHandler worldHandler) { Creatures.CollectionChanged += Creatures_CollectionChanged; Drops.CollectionChanged += Drops_CollectionChanged; this.worldHandler = worldHandler; MouseLeftClickCommand = new RelayCommand(OnLeftMouseClick); } private void Drops_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems != null) { foreach (var item in e.NewItems) { var creature = (DropMapViewModel)item; creature.Scale = scale; creature.VieportSize = new Vector3((float)ViewportWidth, (float)ViewportHeight, 0); } } } private void Creatures_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems != null) { foreach (var item in e.NewItems) { var creature = (CreatureMapViewModel)item; creature.Scale = scale; creature.VieportSize = new Vector3((float)ViewportWidth, (float)ViewportHeight, 0); } } } public ObservableCollection Blocks { get; } = new ObservableCollection(); public ObservableCollection Creatures { get; } = new ObservableCollection(); public ObservableCollection Drops { get; } = new ObservableCollection(); private MapImageSelector selector = new MapImageSelector(); private Dictionary blocks = new Dictionary(); private Hero? hero; private float scale = 8; private double viewportWidth = 0; private double viewportHeight = 0; private readonly WorldHandler worldHandler; } }