From 32fdef9b1c04eb512ad59605e133eecaa0da5784 Mon Sep 17 00:00:00 2001 From: k0t9i Date: Wed, 1 Feb 2023 00:30:20 +0400 Subject: [PATCH] feat: add skills --- Client/App.xaml.cs | 2 + .../Application/ViewModels/MainViewModel.cs | 27 +++++- .../ViewModels/SkillListViewModel.cs | 66 ++++++++++++++ Client/Application/Views/MainWindow.xaml | 86 ++++++++++++++++++- Client/Bot.cs | 2 + Client/Client.csproj | 4 - Client/Domain/Entities/Hero.cs | 10 +-- Client/Domain/Entities/Skill.cs | 52 +++++++++++ Client/Domain/Events/SkillCreatedEvent.cs | 20 +++++ Client/Domain/Events/SkillDeletedEvent.cs | 19 ++++ Client/Domain/Service/EntityHandler.cs | 3 +- Client/Domain/Service/SkillHandler.cs | 30 +++++++ .../Factories/EntityHandlerFactory.cs | 3 + 13 files changed, 310 insertions(+), 14 deletions(-) create mode 100644 Client/Application/ViewModels/SkillListViewModel.cs create mode 100644 Client/Domain/Entities/Skill.cs create mode 100644 Client/Domain/Events/SkillCreatedEvent.cs create mode 100644 Client/Domain/Events/SkillDeletedEvent.cs create mode 100644 Client/Domain/Service/SkillHandler.cs diff --git a/Client/App.xaml.cs b/Client/App.xaml.cs index 34e7a67..2d73d01 100644 --- a/Client/App.xaml.cs +++ b/Client/App.xaml.cs @@ -93,12 +93,14 @@ namespace Client .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) + .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton(); } diff --git a/Client/Application/ViewModels/MainViewModel.cs b/Client/Application/ViewModels/MainViewModel.cs index 3721277..96243b3 100644 --- a/Client/Application/ViewModels/MainViewModel.cs +++ b/Client/Application/ViewModels/MainViewModel.cs @@ -24,7 +24,9 @@ namespace Client.Application.ViewModels EventHandlerInterface, EventHandlerInterface, EventHandlerInterface, - EventHandlerInterface + EventHandlerInterface, + EventHandlerInterface, + EventHandlerInterface { public void Handle(HeroCreatedEvent @event) { @@ -71,9 +73,32 @@ namespace Client.Application.ViewModels ChatMessages.Add(new ChatMessageViewModel(@event.Message)); } + public void Handle(SkillCreatedEvent @event) + { + if (hero != null) + { + if (@event.Skill.IsActive) + { + ActiveSkills.Add(new SkillListViewModel(@event.Skill)); + } + else + { + PassiveSkills.Add(new SkillListViewModel(@event.Skill)); + } + } + } + + public void Handle(SkillDeletedEvent @event) + { + ActiveSkills.RemoveAll(x => x.Id == @event.Id); + PassiveSkills.RemoveAll(x => x.Id == @event.Id); + } + public ObservableCollection ChatMessages { get; } = new ObservableCollection(); public ObservableCollection Creatures { get; } = new ObservableCollection(); public ObservableCollection Drops { get; } = new ObservableCollection(); + public ObservableCollection ActiveSkills { get; } = new ObservableCollection(); + public ObservableCollection PassiveSkills { get; } = new ObservableCollection(); public HeroSummaryInfoViewModel? Hero { get; private set; } public Hero? hero; } diff --git a/Client/Application/ViewModels/SkillListViewModel.cs b/Client/Application/ViewModels/SkillListViewModel.cs new file mode 100644 index 0000000..c6d51ba --- /dev/null +++ b/Client/Application/ViewModels/SkillListViewModel.cs @@ -0,0 +1,66 @@ +using Client.Domain.Common; +using Client.Domain.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Application.ViewModels +{ + public class SkillListViewModel : ObservableObject + { + public uint Id => skill.Id; + public string Name => skill.Name; + public uint Level => skill.Level; + public string Description=> skill.Description; + public string IconName => "/Assets/icons/" + skill.IconName + ".png"; + public bool IsActive => skill.IsActive; + public bool IsReadyToUse => skill.IsReadyToUse; + public bool IsBusy => !skill.IsReadyToUse; + public uint Cost => skill.Cost; + public int Range => skill.Range; + + public SkillListViewModel(Skill skill) + { + this.skill = skill; + + skill.PropertyChanged += Skill_PropertyChanged; + } + + private void Skill_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "Description") + { + OnPropertyChanged("Description"); + } + if (e.PropertyName == "IsReadyToUse") + { + OnPropertyChanged("IsBusy"); + OnPropertyChanged("IsReadyToUse"); + } + if (e.PropertyName == "Level") + { + OnPropertyChanged("Level"); + } + if (e.PropertyName == "Cost") + { + OnPropertyChanged("Cost"); + } + if (e.PropertyName == "Range") + { + OnPropertyChanged("Range"); + } + if (e.PropertyName == "Name") + { + OnPropertyChanged("Name"); + } + if (e.PropertyName == "IconName") + { + OnPropertyChanged("IconName"); + } + } + + private readonly Skill skill; + } +} diff --git a/Client/Application/Views/MainWindow.xaml b/Client/Application/Views/MainWindow.xaml index 71814d8..879a575 100644 --- a/Client/Application/Views/MainWindow.xaml +++ b/Client/Application/Views/MainWindow.xaml @@ -5,6 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Client" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" + xmlns:ctrls="clr-namespace:System.Windows.Controls;assembly=PresentationFramework" xmlns:converters="clr-namespace:Client.Application.Converters" xmlns:components="clr-namespace:Client.Application.Components" mc:Ignorable="d" @@ -21,11 +22,12 @@ + - + @@ -96,6 +98,86 @@ + + Skills + + + + Active + + + + + + + + + + + + + + + + + Passive + + + + + + + + + + + + + + + + + + @@ -107,7 +189,7 @@ - + diff --git a/Client/Bot.cs b/Client/Bot.cs index 602b007..054a56d 100644 --- a/Client/Bot.cs +++ b/Client/Bot.cs @@ -73,6 +73,8 @@ namespace Client eventBus.Subscrbe((EventHandlerInterface)viewModel); eventBus.Subscrbe((EventHandlerInterface)viewModel); eventBus.Subscrbe((EventHandlerInterface)viewModel); + eventBus.Subscrbe((EventHandlerInterface)viewModel); + eventBus.Subscrbe((EventHandlerInterface)viewModel); eventBus.Subscrbe((EventHandlerInterface)serviceProvider.GetRequiredService()); eventBus.Subscrbe((EventHandlerInterface)serviceProvider.GetRequiredService()); diff --git a/Client/Client.csproj b/Client/Client.csproj index 71a183b..8b3c85d 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -29,8 +29,4 @@ - - - - diff --git a/Client/Domain/Entities/Hero.cs b/Client/Domain/Entities/Hero.cs index 35c301f..f1995c1 100644 --- a/Client/Domain/Entities/Hero.cs +++ b/Client/Domain/Entities/Hero.cs @@ -7,11 +7,6 @@ namespace Client.Domain.Entities { public class Hero : ObservableObject, EntityInterface, CreatureInterface { - private FullName fullName; - private Phenotype phenotype; - private CreatureInterface? target; - private uint targetId; - public uint Id { get; set; } public Transform Transform { get; set; } public VitalStats VitalStats { get; set; } @@ -96,5 +91,10 @@ namespace Client.Domain.Entities OnPropertyChanged("Name"); } } + + private FullName fullName; + private Phenotype phenotype; + private CreatureInterface? target; + private uint targetId; } } diff --git a/Client/Domain/Entities/Skill.cs b/Client/Domain/Entities/Skill.cs new file mode 100644 index 0000000..38672c7 --- /dev/null +++ b/Client/Domain/Entities/Skill.cs @@ -0,0 +1,52 @@ +using Client.Domain.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Domain.Entities +{ + public class Skill : ObservableObject, EntityInterface + { + public uint Id { get; set; } + public uint Level { get => level; set { if (value != level) { level = value; OnPropertyChanged(); } } } + public bool IsActive { get; set; } + public uint Cost { get => cost; set { if (value != cost) { cost = value; OnPropertyChanged(); } } } + public int Range { get => range; set { if (value != range) { range = value; OnPropertyChanged(); } } } + public string Name { get => name; set { if (value != name) { name = value; OnPropertyChanged(); } } } + public string Description { get => description; set { if (value != description) { description = value; OnPropertyChanged(); } } } + public string IconName { get => iconName; set { if (value != iconName) { iconName = value; OnPropertyChanged(); } } } + public bool IsToggled { get => isToggled; set { if (value != isToggled) { isToggled = value; OnPropertyChanged(); } } } + public bool IsCasting { get => isCasting; set { if (value != isCasting) { isCasting = value; OnPropertyChanged(); } } } + public bool IsReloading { get => isReloading; set { if (value != isReloading) { isReloading = value; OnPropertyChanged(); } } } + public bool IsReadyToUse { get => isReadyToUse; set { if (value != isReadyToUse) { isReadyToUse = value; OnPropertyChanged(); } } } + + public Skill(uint id, uint level, bool isActive, uint cost, int range, string name, string description, string iconName, bool isToggled, bool isCasting, bool isReloading, bool isReadyToUse) + { + Id = id; + this.level = level; + IsActive = isActive; + this.cost = cost; + this.range = range; + Name = name; + this.description = description; + IconName = iconName; + this.isToggled = isToggled; + this.isCasting = isCasting; + this.isReloading = isReloading; + this.isReadyToUse = isReadyToUse; + } + + private string description; + private uint cost; + private int range; + private bool isToggled; + private bool isCasting; + private bool isReloading; + private bool isReadyToUse; + private uint level; + private string name; + private string iconName; + } +} diff --git a/Client/Domain/Events/SkillCreatedEvent.cs b/Client/Domain/Events/SkillCreatedEvent.cs new file mode 100644 index 0000000..fd37ce5 --- /dev/null +++ b/Client/Domain/Events/SkillCreatedEvent.cs @@ -0,0 +1,20 @@ +using Client.Domain.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Domain.Events +{ + public class SkillCreatedEvent : EventInterface + { + public readonly Skill Skill; + + public SkillCreatedEvent(Skill skill) + { + Skill = skill; + } + } +} + diff --git a/Client/Domain/Events/SkillDeletedEvent.cs b/Client/Domain/Events/SkillDeletedEvent.cs new file mode 100644 index 0000000..d8c8bd5 --- /dev/null +++ b/Client/Domain/Events/SkillDeletedEvent.cs @@ -0,0 +1,19 @@ +using Client.Domain.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Domain.Events +{ + public class SkillDeletedEvent : EventInterface + { + public readonly uint Id; + + public SkillDeletedEvent(uint id) + { + Id = id; + } + } +} diff --git a/Client/Domain/Service/EntityHandler.cs b/Client/Domain/Service/EntityHandler.cs index 92f9108..324b907 100644 --- a/Client/Domain/Service/EntityHandler.cs +++ b/Client/Domain/Service/EntityHandler.cs @@ -45,8 +45,7 @@ namespace Client.Domain.Service public T? GetEntity(uint id) { - T? result = null; - + T? result; entities.TryGetValue(id, out result); return result; diff --git a/Client/Domain/Service/SkillHandler.cs b/Client/Domain/Service/SkillHandler.cs new file mode 100644 index 0000000..c81ad10 --- /dev/null +++ b/Client/Domain/Service/SkillHandler.cs @@ -0,0 +1,30 @@ +using Client.Domain.Entities; +using Client.Domain.Events; +using Client.Domain.Factories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Domain.Service +{ + public class SkillHandler : EntityHandler + { + public override void OnCreate(Skill entity) + { + eventBus.Publish(new SkillCreatedEvent(entity)); + } + public override void OnDelete(Skill entity) + { + eventBus.Publish(new SkillDeletedEvent(entity.Id)); + } + + public SkillHandler(EntityFactoryInterface factory, EventBusInterface eventBus) : base(factory) + { + this.eventBus = eventBus; + } + + private readonly EventBusInterface eventBus; + } +} diff --git a/Client/Infrastructure/Factories/EntityHandlerFactory.cs b/Client/Infrastructure/Factories/EntityHandlerFactory.cs index 2d97347..3958939 100644 --- a/Client/Infrastructure/Factories/EntityHandlerFactory.cs +++ b/Client/Infrastructure/Factories/EntityHandlerFactory.cs @@ -36,6 +36,9 @@ namespace Client.Infrastructure.Factories case MessageTypeEnum.Chat: result = serviceProvider.GetService(); break; + case MessageTypeEnum.Skill: + result = serviceProvider.GetService(); + break; } if (result == null)