diff --git a/Client/App.xaml.cs b/Client/App.xaml.cs index e003cfb..b366357 100644 --- a/Client/App.xaml.cs +++ b/Client/App.xaml.cs @@ -95,7 +95,7 @@ namespace Client .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) .AddTransient(typeof(EntityFactoryInterface), typeof(EntityFactory)) - .AddTransient(typeof(EntityFactoryInterface), typeof(ItemFactory)) + .AddTransient(typeof(EntityFactoryInterface), typeof(ItemFactory)) .AddSingleton() .AddSingleton() diff --git a/Client/Application/Components/Item.xaml b/Client/Application/Components/Item.xaml new file mode 100644 index 0000000..2ee4ea2 --- /dev/null +++ b/Client/Application/Components/Item.xaml @@ -0,0 +1,36 @@ + diff --git a/Client/Application/Components/Item.xaml.cs b/Client/Application/Components/Item.xaml.cs new file mode 100644 index 0000000..04b3b43 --- /dev/null +++ b/Client/Application/Components/Item.xaml.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace Client.Application.Components +{ + /// + /// Interaction logic for Item.xaml + /// + public partial class Item : Button + { + public static readonly DependencyProperty ImageSourceProperty = + DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(Item), new PropertyMetadata(default(ImageSource))); + public static readonly DependencyProperty ItemNameProperty = + DependencyProperty.Register("ItemName", typeof(string), typeof(Item), new PropertyMetadata("Item")); + public static readonly DependencyProperty DescriptionProperty = + DependencyProperty.Register("Description", typeof(string), typeof(Item), new PropertyMetadata("")); + + public Item() + { + InitializeComponent(); + } + + public ImageSource ImageSource + { + get { return (ImageSource)GetValue(ImageSourceProperty); } + set { SetValue(ImageSourceProperty, value); } + } + public string ItemName + { + get { return (string)GetValue(ItemNameProperty); } + set { SetValue(ItemNameProperty, value); } + } + public string? Description + { + get { return (string?)GetValue(DescriptionProperty); } + set { SetValue(DescriptionProperty, value); } + } + } +} diff --git a/Client/Application/ViewModels/CreatureListViewModel.cs b/Client/Application/ViewModels/CreatureListViewModel.cs index 01d4715..469ece6 100644 --- a/Client/Application/ViewModels/CreatureListViewModel.cs +++ b/Client/Application/ViewModels/CreatureListViewModel.cs @@ -44,7 +44,7 @@ namespace Client.Application.ViewModels worldHandler.RequestMoveToEntity(Id); } - public CreatureListViewModel(CreatureInterface creature, Hero hero, WorldHandler worldHandler) + public CreatureListViewModel(WorldHandler worldHandler, CreatureInterface creature, Hero hero) { creature.PropertyChanged += Creature_PropertyChanged; creature.Transform.Position.PropertyChanged += Position_PropertyChanged; diff --git a/Client/Application/ViewModels/CreatureMapViewModel.cs b/Client/Application/ViewModels/CreatureMapViewModel.cs index 2534d8a..2cb5fb2 100644 --- a/Client/Application/ViewModels/CreatureMapViewModel.cs +++ b/Client/Application/ViewModels/CreatureMapViewModel.cs @@ -82,7 +82,7 @@ namespace Client.Application.ViewModels worldHandler.RequestMoveToEntity(Id); } - public CreatureMapViewModel(CreatureInterface creature, Hero hero, WorldHandler worldHandler) + public CreatureMapViewModel(WorldHandler worldHandler, CreatureInterface creature, Hero hero) { this.creature = creature; this.hero = hero; diff --git a/Client/Application/ViewModels/DropListViewModel.cs b/Client/Application/ViewModels/DropListViewModel.cs index 972a5b0..f934db5 100644 --- a/Client/Application/ViewModels/DropListViewModel.cs +++ b/Client/Application/ViewModels/DropListViewModel.cs @@ -79,7 +79,7 @@ namespace Client.Application.ViewModels worldHandler.RequestMoveToEntity(Id); } - public DropListViewModel(Drop drop, Hero hero, WorldHandler worldHandler) + public DropListViewModel(WorldHandler worldHandler, Drop drop, Hero hero) { this.drop = drop; this.hero = hero; diff --git a/Client/Application/ViewModels/DropMapViewModel.cs b/Client/Application/ViewModels/DropMapViewModel.cs index d70426f..58e4147 100644 --- a/Client/Application/ViewModels/DropMapViewModel.cs +++ b/Client/Application/ViewModels/DropMapViewModel.cs @@ -61,7 +61,7 @@ namespace Client.Application.ViewModels worldHandler.RequestMoveToEntity(Id); } - public DropMapViewModel(Drop drop, Hero hero, WorldHandler worldHandler) + public DropMapViewModel(WorldHandler worldHandler, Drop drop, Hero hero) { this.drop = drop; this.hero = hero; diff --git a/Client/Application/ViewModels/ItemListViewModel.cs b/Client/Application/ViewModels/ItemListViewModel.cs new file mode 100644 index 0000000..4a66ea3 --- /dev/null +++ b/Client/Application/ViewModels/ItemListViewModel.cs @@ -0,0 +1,46 @@ +using Client.Application.Commands; +using Client.Application.Components; +using Client.Domain.Common; +using Client.Domain.Entities; +using Client.Domain.Service; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Client.Application.ViewModels +{ + public class ItemListViewModel : ObservableObject + { + public uint Id => item.Id; + public string Name => item.Name; + public string Description => item.FullDescription; + public string IconName => "/Assets/icons/" + item.IconName + ".png"; + + public ICommand MouseLeftClickCommand { get; } + public ICommand MouseRightClickCommand { get; } + private void OnLeftMouseClick(object? obj) + { + worldHandler.RequestUseItem(Id); + } + private void OnRightMouseClick(object? obj) + { + worldHandler.RequestToggleAutouseSoulshot(Id); + } + + public ItemListViewModel(WorldHandler worldHandler, ItemInterface item) + { + this.worldHandler = worldHandler; + this.item = item; + + //skill.PropertyChanged += Skill_PropertyChanged; + MouseLeftClickCommand = new RelayCommand(OnLeftMouseClick); + MouseRightClickCommand = new RelayCommand(OnRightMouseClick); + } + + private readonly WorldHandler worldHandler; + private readonly ItemInterface item; + } +} diff --git a/Client/Application/ViewModels/MainViewModel.cs b/Client/Application/ViewModels/MainViewModel.cs index 7ee0ee9..dcf42df 100644 --- a/Client/Application/ViewModels/MainViewModel.cs +++ b/Client/Application/ViewModels/MainViewModel.cs @@ -59,7 +59,7 @@ namespace Client.Application.ViewModels { if (hero != null) { - Creatures.Add(new CreatureListViewModel(@event.Creature, hero, worldHandler)); + Creatures.Add(new CreatureListViewModel(worldHandler, @event.Creature, hero)); AddCreature(@event.Creature); } } @@ -74,8 +74,8 @@ namespace Client.Application.ViewModels { if (hero != null) { - Drops.Add(new DropListViewModel(@event.Drop, hero, worldHandler)); - Map.Drops.Add(new DropMapViewModel(@event.Drop, hero, worldHandler)); + Drops.Add(new DropListViewModel(worldHandler, @event.Drop, hero)); + Map.Drops.Add(new DropMapViewModel(worldHandler, @event.Drop, hero)); } } @@ -115,20 +115,28 @@ namespace Client.Application.ViewModels { if (hero != null) { - Items.Add(@event.Item); + if (!@event.Item.IsQuest) + { + Items.Add(new ItemListViewModel(worldHandler, @event.Item)); + } + else + { + QuestItems.Add(new ItemListViewModel(worldHandler, @event.Item)); + } } } public void Handle(ItemDeletedEvent @event) { Items.RemoveAll(x => x.Id == @event.Id); + QuestItems.RemoveAll(x => x.Id == @event.Id); } private void AddCreature(CreatureInterface creature) { if (hero != null) { - Map.Creatures.Add(new CreatureMapViewModel(creature, hero, worldHandler)); + Map.Creatures.Add(new CreatureMapViewModel(worldHandler, creature, hero)); } } @@ -148,7 +156,8 @@ namespace Client.Application.ViewModels public ObservableCollection Drops { get; } = new ObservableCollection(); public ObservableCollection ActiveSkills { get; } = new ObservableCollection(); public ObservableCollection PassiveSkills { get; } = new ObservableCollection(); - public ObservableCollection Items { get; } = new ObservableCollection(); + public ObservableCollection Items { get; } = new ObservableCollection(); + public ObservableCollection QuestItems { get; } = new ObservableCollection(); public HeroSummaryInfoViewModel? Hero { get; private set; } public MapViewModel Map { get; private set; } public Hero? hero; diff --git a/Client/Application/Views/ItemPanel.xaml b/Client/Application/Views/ItemPanel.xaml new file mode 100644 index 0000000..44a0439 --- /dev/null +++ b/Client/Application/Views/ItemPanel.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/Client/Application/Views/ItemPanel.xaml.cs b/Client/Application/Views/ItemPanel.xaml.cs new file mode 100644 index 0000000..9a4cf74 --- /dev/null +++ b/Client/Application/Views/ItemPanel.xaml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace Client.Application.Views +{ + /// + /// Interaction logic for ItemPanel.xaml + /// + public partial class ItemPanel : ItemsControl + { + public ItemPanel() + { + InitializeComponent(); + } + } +} diff --git a/Client/Application/Views/MainWindow.xaml b/Client/Application/Views/MainWindow.xaml index 816d0c9..16011a9 100644 --- a/Client/Application/Views/MainWindow.xaml +++ b/Client/Application/Views/MainWindow.xaml @@ -140,50 +140,13 @@ Items - - - - - - - - - - - - + Quest Items - diff --git a/Client/Client.csproj b/Client/Client.csproj index aeefb06..3e06c22 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -32,4 +32,13 @@ + + + Code + + + Code + + + diff --git a/Client/Domain/Entities/BaseItem.cs b/Client/Domain/Entities/BaseItem.cs index ae8bb29..9a8ebdc 100644 --- a/Client/Domain/Entities/BaseItem.cs +++ b/Client/Domain/Entities/BaseItem.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace Client.Domain.Entities { - public abstract class BaseItem : EntityInterface + public abstract class BaseItem { public uint Id { get; set; } public uint ItemId { get; set; } diff --git a/Client/Domain/Entities/EtcItem.cs b/Client/Domain/Entities/EtcItem.cs index 7273ccb..3255ed6 100644 --- a/Client/Domain/Entities/EtcItem.cs +++ b/Client/Domain/Entities/EtcItem.cs @@ -7,11 +7,13 @@ using System.Threading.Tasks; namespace Client.Domain.Entities { - public class EtcItem : BaseItem + public class EtcItem : BaseItem, ItemInterface { public uint Amount { get => amount; set => amount = value; } public bool IsQuest { get; set; } public bool IsAutoused { get => isAutoused; set => isAutoused = value; } + public string FullDescription { get => Description; } + public EtcItem(uint id, uint itemId, ItemTypeEnum type, string name, string iconName, string description, int mana, uint weight, uint amount, bool isQuest, bool isAutoused) : base(id, itemId, type, name, iconName, description, mana, weight) { diff --git a/Client/Domain/Entities/ItemInterface.cs b/Client/Domain/Entities/ItemInterface.cs new file mode 100644 index 0000000..598a7c8 --- /dev/null +++ b/Client/Domain/Entities/ItemInterface.cs @@ -0,0 +1,24 @@ +using Client.Domain.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Client.Domain.Entities +{ + public interface ItemInterface : EntityInterface + { + uint ItemId { get; set; } + ItemTypeEnum Type { get; set; } + string Name { get; set; } + string IconName { get; set; } + string Description { get; set; } + int Mana { get; set; } + uint Weight { get; set; } + uint Amount { get; set; } + bool IsQuest { get; set; } + bool IsAutoused { get; set; } + string FullDescription { get; } + } +} diff --git a/Client/Domain/Events/ItemCreatedEvent.cs b/Client/Domain/Events/ItemCreatedEvent.cs index adda961..47362f7 100644 --- a/Client/Domain/Events/ItemCreatedEvent.cs +++ b/Client/Domain/Events/ItemCreatedEvent.cs @@ -9,9 +9,9 @@ namespace Client.Domain.Events { public class ItemCreatedEvent : EventInterface { - public readonly BaseItem Item; + public readonly ItemInterface Item; - public ItemCreatedEvent(BaseItem item) + public ItemCreatedEvent(ItemInterface item) { Item = item; } diff --git a/Client/Domain/Service/ItemHandler.cs b/Client/Domain/Service/ItemHandler.cs index 85524c8..3f770e5 100644 --- a/Client/Domain/Service/ItemHandler.cs +++ b/Client/Domain/Service/ItemHandler.cs @@ -9,18 +9,18 @@ using System.Threading.Tasks; namespace Client.Domain.Service { - public class ItemHander : EntityHandler + public class ItemHander : EntityHandler { - public override void OnCreate(BaseItem entity) + public override void OnCreate(ItemInterface entity) { eventBus.Publish(new ItemCreatedEvent(entity)); } - public override void OnDelete(BaseItem entity) + public override void OnDelete(ItemInterface entity) { eventBus.Publish(new ItemDeletedEvent(entity.Id)); } - public ItemHander(EntityFactoryInterface factory, EventBusInterface eventBus) : base(factory) + public ItemHander(EntityFactoryInterface factory, EventBusInterface eventBus) : base(factory) { this.eventBus = eventBus; } diff --git a/Client/Domain/Service/WorldHandler.cs b/Client/Domain/Service/WorldHandler.cs index 2c0f637..4355839 100644 --- a/Client/Domain/Service/WorldHandler.cs +++ b/Client/Domain/Service/WorldHandler.cs @@ -268,7 +268,7 @@ namespace Client.Domain.Service public void Handle(ItemDeletedEvent @event) { - items.Remove(@event.Id, out BaseItem? value); + items.Remove(@event.Id, out ItemInterface? value); } #endregion @@ -282,7 +282,7 @@ namespace Client.Domain.Service private ConcurrentDictionary creatures = new ConcurrentDictionary(); private ConcurrentDictionary drops = new ConcurrentDictionary(); private ConcurrentDictionary skills = new ConcurrentDictionary(); - private ConcurrentDictionary items = new ConcurrentDictionary(); + private ConcurrentDictionary items = new ConcurrentDictionary(); private readonly OutgoingMessageBuilderInterface outgoingMessageBuilder; private readonly TransportInterface transport; } diff --git a/Client/Infrastructure/Factories/ItemFactory.cs b/Client/Infrastructure/Factories/ItemFactory.cs index ae7ad31..9f97733 100644 --- a/Client/Infrastructure/Factories/ItemFactory.cs +++ b/Client/Infrastructure/Factories/ItemFactory.cs @@ -11,9 +11,9 @@ using System.Threading.Tasks; namespace Client.Infrastructure.Factories { - public class ItemFactory : EntityFactoryInterface + public class ItemFactory : EntityFactoryInterface { - public BaseItem? Create(string data) + public ItemInterface? Create(string data) { var type = JsonConvert.DeserializeObject(data, settings); @@ -33,7 +33,7 @@ namespace Client.Infrastructure.Factories throw new ArgumentException("Invalid item type " + type.Type.ToString()); } - public void Update(BaseItem entity, string data) + public void Update(ItemInterface entity, string data) { JsonConvert.PopulateObject(data, entity, settings); } diff --git a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h index 373fe9a..f72a435 100644 --- a/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h +++ b/L2BotDll/Versions/Interlude/Repositories/ItemRepository.h @@ -40,13 +40,15 @@ namespace Interlude return result; } - const Entities::BaseItem& GetItem(uint32_t objectId) const + const std::shared_ptr GetItem(uint32_t objectId) const { + std::unique_lock(m_Mutex); + if (m_Items.find(objectId) != m_Items.end()) { - return m_Items.at(objectId).get(); + return m_Items.at(objectId); } - return Entities::BaseItem(); + return nullptr; } ItemRepository(const NetworkHandlerWrapper& networkHandler, const ItemFactory& factory, EntityFinder& finder) : diff --git a/L2BotDll/Versions/Interlude/Services/HeroService.h b/L2BotDll/Versions/Interlude/Services/HeroService.h index bf96b81..9782574 100644 --- a/L2BotDll/Versions/Interlude/Services/HeroService.h +++ b/L2BotDll/Versions/Interlude/Services/HeroService.h @@ -100,13 +100,13 @@ namespace Interlude void ToggleAutouseSoulshot(int objectId) const override { const auto item = m_ItemRespository.GetItem(objectId); - if (item.GetId()) + if (item) { - const auto etcItem = static_cast(item); + const auto etcItem = static_cast(item.get()); L2ParamStack* stack = new L2ParamStack(2); - stack->PushBack((void*)etcItem.GetItemId()); - stack->PushBack((void*)(etcItem.IsAutoused() ? 0 : 1)); + stack->PushBack((void*)etcItem->GetItemId()); + stack->PushBack((void*)(etcItem->IsAutoused() ? 0 : 1)); m_NetworkHandler.RequestAutoSoulShot(*stack);