fix: fix toggle soulshot method

This commit is contained in:
k0t9i
2023-02-10 19:00:56 +04:00
parent 81e26a7e52
commit 7276b24249
22 changed files with 261 additions and 70 deletions

View File

@ -95,7 +95,7 @@ namespace Client
.AddTransient(typeof(EntityFactoryInterface<Player>), typeof(EntityFactory<Player>)) .AddTransient(typeof(EntityFactoryInterface<Player>), typeof(EntityFactory<Player>))
.AddTransient(typeof(EntityFactoryInterface<ChatMessage>), typeof(EntityFactory<ChatMessage>)) .AddTransient(typeof(EntityFactoryInterface<ChatMessage>), typeof(EntityFactory<ChatMessage>))
.AddTransient(typeof(EntityFactoryInterface<Skill>), typeof(EntityFactory<Skill>)) .AddTransient(typeof(EntityFactoryInterface<Skill>), typeof(EntityFactory<Skill>))
.AddTransient(typeof(EntityFactoryInterface<BaseItem>), typeof(ItemFactory)) .AddTransient(typeof(EntityFactoryInterface<ItemInterface>), typeof(ItemFactory))
.AddSingleton<HeroHandler>() .AddSingleton<HeroHandler>()
.AddSingleton<DropHandler>() .AddSingleton<DropHandler>()

View File

@ -0,0 +1,36 @@
<Button x:Class="Client.Application.Components.Item"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Client.Application.Components"
xmlns:services="clr-namespace:Client.Application.Services"
mc:Ignorable="d"
ToolTipService.ShowOnDisabled="True"
x:Name="root">
<Button.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding MouseLeftClickCommand}" />
<MouseBinding Gesture="RightClick" Command="{Binding MouseRightClickCommand}" />
</Button.InputBindings>
<Button.Resources>
<services:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<services:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
<DataTemplate x:Key="ToolTipContent">
<StackPanel MaxWidth="300">
<TextBlock Text="{Binding ItemName,Mode=OneWay}" TextWrapping="Wrap" FontWeight="Bold" FontSize="14" Margin="0,0,0,5" />
<TextBlock
TextWrapping="Wrap"
Text="{Binding Source={x:Reference root},Path=Description,Mode=OneWay}"
/>
</StackPanel>
</DataTemplate>
</Button.Resources>
<Button.Content>
<Grid>
<Image Source="{Binding Path=ImageSource,ElementName=root}" Height="32" Width="32" />
</Grid>
</Button.Content>
<Button.ToolTip >
<ContentControl ContentTemplate="{StaticResource ToolTipContent}"/>
</Button.ToolTip>
</Button>

View File

@ -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
{
/// <summary>
/// Interaction logic for Item.xaml
/// </summary>
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); }
}
}
}

View File

@ -44,7 +44,7 @@ namespace Client.Application.ViewModels
worldHandler.RequestMoveToEntity(Id); worldHandler.RequestMoveToEntity(Id);
} }
public CreatureListViewModel(CreatureInterface creature, Hero hero, WorldHandler worldHandler) public CreatureListViewModel(WorldHandler worldHandler, CreatureInterface creature, Hero hero)
{ {
creature.PropertyChanged += Creature_PropertyChanged; creature.PropertyChanged += Creature_PropertyChanged;
creature.Transform.Position.PropertyChanged += Position_PropertyChanged; creature.Transform.Position.PropertyChanged += Position_PropertyChanged;

View File

@ -82,7 +82,7 @@ namespace Client.Application.ViewModels
worldHandler.RequestMoveToEntity(Id); worldHandler.RequestMoveToEntity(Id);
} }
public CreatureMapViewModel(CreatureInterface creature, Hero hero, WorldHandler worldHandler) public CreatureMapViewModel(WorldHandler worldHandler, CreatureInterface creature, Hero hero)
{ {
this.creature = creature; this.creature = creature;
this.hero = hero; this.hero = hero;

View File

@ -79,7 +79,7 @@ namespace Client.Application.ViewModels
worldHandler.RequestMoveToEntity(Id); worldHandler.RequestMoveToEntity(Id);
} }
public DropListViewModel(Drop drop, Hero hero, WorldHandler worldHandler) public DropListViewModel(WorldHandler worldHandler, Drop drop, Hero hero)
{ {
this.drop = drop; this.drop = drop;
this.hero = hero; this.hero = hero;

View File

@ -61,7 +61,7 @@ namespace Client.Application.ViewModels
worldHandler.RequestMoveToEntity(Id); worldHandler.RequestMoveToEntity(Id);
} }
public DropMapViewModel(Drop drop, Hero hero, WorldHandler worldHandler) public DropMapViewModel(WorldHandler worldHandler, Drop drop, Hero hero)
{ {
this.drop = drop; this.drop = drop;
this.hero = hero; this.hero = hero;

View File

@ -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;
}
}

View File

@ -59,7 +59,7 @@ namespace Client.Application.ViewModels
{ {
if (hero != null) if (hero != null)
{ {
Creatures.Add(new CreatureListViewModel(@event.Creature, hero, worldHandler)); Creatures.Add(new CreatureListViewModel(worldHandler, @event.Creature, hero));
AddCreature(@event.Creature); AddCreature(@event.Creature);
} }
} }
@ -74,8 +74,8 @@ namespace Client.Application.ViewModels
{ {
if (hero != null) if (hero != null)
{ {
Drops.Add(new DropListViewModel(@event.Drop, hero, worldHandler)); Drops.Add(new DropListViewModel(worldHandler, @event.Drop, hero));
Map.Drops.Add(new DropMapViewModel(@event.Drop, hero, worldHandler)); Map.Drops.Add(new DropMapViewModel(worldHandler, @event.Drop, hero));
} }
} }
@ -115,20 +115,28 @@ namespace Client.Application.ViewModels
{ {
if (hero != null) 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) public void Handle(ItemDeletedEvent @event)
{ {
Items.RemoveAll(x => x.Id == @event.Id); Items.RemoveAll(x => x.Id == @event.Id);
QuestItems.RemoveAll(x => x.Id == @event.Id);
} }
private void AddCreature(CreatureInterface creature) private void AddCreature(CreatureInterface creature)
{ {
if (hero != null) 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<DropListViewModel> Drops { get; } = new ObservableCollection<DropListViewModel>(); public ObservableCollection<DropListViewModel> Drops { get; } = new ObservableCollection<DropListViewModel>();
public ObservableCollection<SkillListViewModel> ActiveSkills { get; } = new ObservableCollection<SkillListViewModel>(); public ObservableCollection<SkillListViewModel> ActiveSkills { get; } = new ObservableCollection<SkillListViewModel>();
public ObservableCollection<SkillListViewModel> PassiveSkills { get; } = new ObservableCollection<SkillListViewModel>(); public ObservableCollection<SkillListViewModel> PassiveSkills { get; } = new ObservableCollection<SkillListViewModel>();
public ObservableCollection<BaseItem> Items { get; } = new ObservableCollection<BaseItem>(); public ObservableCollection<ItemListViewModel> Items { get; } = new ObservableCollection<ItemListViewModel>();
public ObservableCollection<ItemListViewModel> QuestItems { get; } = new ObservableCollection<ItemListViewModel>();
public HeroSummaryInfoViewModel? Hero { get; private set; } public HeroSummaryInfoViewModel? Hero { get; private set; }
public MapViewModel Map { get; private set; } public MapViewModel Map { get; private set; }
public Hero? hero; public Hero? hero;

View File

@ -0,0 +1,23 @@
<ItemsControl x:Class="Client.Application.Views.ItemPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Client.Application.Views"
xmlns:components="clr-namespace:Client.Application.Components"
mc:Ignorable="d">
<ItemsControl.ItemTemplate>
<DataTemplate>
<components:Item
ImageSource="{Binding Path=IconName,Mode=OneWay}"
ItemName="{Binding Path=Name,Mode=OneWay}"
Description="{Binding Path=Description,Mode=OneWay}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

View File

@ -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
{
/// <summary>
/// Interaction logic for ItemPanel.xaml
/// </summary>
public partial class ItemPanel : ItemsControl
{
public ItemPanel()
{
InitializeComponent();
}
}
}

View File

@ -140,50 +140,13 @@
<TabItem> <TabItem>
<TabItem.Header>Items</TabItem.Header> <TabItem.Header>Items</TabItem.Header>
<TabItem.Content> <TabItem.Content>
<ItemsControl ItemsSource="{Binding Path=Items}"> <views:ItemPanel ItemsSource="{Binding Items,Mode=OneWay}" />
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button>
<Button.Resources>
<services:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<services:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
<DataTemplate x:Key="ToolTipContent">
<StackPanel MaxWidth="300">
<TextBlock TextWrapping="Wrap" FontWeight="Bold" FontSize="14" Margin="0,0,0,5">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name" Mode="OneWay" />
<Binding Path="Amount" Mode="OneWay" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</Button.Resources>
<Button.Content>
<Grid>
<!--Image Source="{Binding Path=ImageSource}" Height="32" Width="32" /-->
<TextBlock Text="{Binding Name,Mode=OneWay}" />
</Grid>
</Button.Content>
<Button.ToolTip >
<ContentControl ContentTemplate="{StaticResource ToolTipContent}"/>
</Button.ToolTip>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</TabItem.Content> </TabItem.Content>
</TabItem> </TabItem>
<TabItem> <TabItem>
<TabItem.Header>Quest Items</TabItem.Header> <TabItem.Header>Quest Items</TabItem.Header>
<TabItem.Content> <TabItem.Content>
<Label Content="Under construction" /> <views:ItemPanel ItemsSource="{Binding QuestItems,Mode=OneWay}" />
</TabItem.Content> </TabItem.Content>
</TabItem> </TabItem>
</TabControl> </TabControl>

View File

@ -32,4 +32,13 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Update="Application\Components\Item.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Application\Views\ItemPanel.xaml.cs">
<SubType>Code</SubType>
</Compile>
</ItemGroup>
</Project> </Project>

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Client.Domain.Entities namespace Client.Domain.Entities
{ {
public abstract class BaseItem : EntityInterface public abstract class BaseItem
{ {
public uint Id { get; set; } public uint Id { get; set; }
public uint ItemId { get; set; } public uint ItemId { get; set; }

View File

@ -7,11 +7,13 @@ using System.Threading.Tasks;
namespace Client.Domain.Entities namespace Client.Domain.Entities
{ {
public class EtcItem : BaseItem public class EtcItem : BaseItem, ItemInterface
{ {
public uint Amount { get => amount; set => amount = value; } public uint Amount { get => amount; set => amount = value; }
public bool IsQuest { get; set; } public bool IsQuest { get; set; }
public bool IsAutoused { get => isAutoused; set => isAutoused = value; } 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) : 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) base(id, itemId, type, name, iconName, description, mana, weight)
{ {

View File

@ -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; }
}
}

View File

@ -9,9 +9,9 @@ namespace Client.Domain.Events
{ {
public class ItemCreatedEvent : EventInterface public class ItemCreatedEvent : EventInterface
{ {
public readonly BaseItem Item; public readonly ItemInterface Item;
public ItemCreatedEvent(BaseItem item) public ItemCreatedEvent(ItemInterface item)
{ {
Item = item; Item = item;
} }

View File

@ -9,18 +9,18 @@ using System.Threading.Tasks;
namespace Client.Domain.Service namespace Client.Domain.Service
{ {
public class ItemHander : EntityHandler<BaseItem> public class ItemHander : EntityHandler<ItemInterface>
{ {
public override void OnCreate(BaseItem entity) public override void OnCreate(ItemInterface entity)
{ {
eventBus.Publish(new ItemCreatedEvent(entity)); eventBus.Publish(new ItemCreatedEvent(entity));
} }
public override void OnDelete(BaseItem entity) public override void OnDelete(ItemInterface entity)
{ {
eventBus.Publish(new ItemDeletedEvent(entity.Id)); eventBus.Publish(new ItemDeletedEvent(entity.Id));
} }
public ItemHander(EntityFactoryInterface<BaseItem> factory, EventBusInterface eventBus) : base(factory) public ItemHander(EntityFactoryInterface<ItemInterface> factory, EventBusInterface eventBus) : base(factory)
{ {
this.eventBus = eventBus; this.eventBus = eventBus;
} }

View File

@ -268,7 +268,7 @@ namespace Client.Domain.Service
public void Handle(ItemDeletedEvent @event) public void Handle(ItemDeletedEvent @event)
{ {
items.Remove(@event.Id, out BaseItem? value); items.Remove(@event.Id, out ItemInterface? value);
} }
#endregion #endregion
@ -282,7 +282,7 @@ namespace Client.Domain.Service
private ConcurrentDictionary<uint, CreatureInterface> creatures = new ConcurrentDictionary<uint, CreatureInterface>(); private ConcurrentDictionary<uint, CreatureInterface> creatures = new ConcurrentDictionary<uint, CreatureInterface>();
private ConcurrentDictionary<uint, Drop> drops = new ConcurrentDictionary<uint, Drop>(); private ConcurrentDictionary<uint, Drop> drops = new ConcurrentDictionary<uint, Drop>();
private ConcurrentDictionary<uint, Skill> skills = new ConcurrentDictionary<uint, Skill>(); private ConcurrentDictionary<uint, Skill> skills = new ConcurrentDictionary<uint, Skill>();
private ConcurrentDictionary<uint, BaseItem> items = new ConcurrentDictionary<uint, BaseItem>(); private ConcurrentDictionary<uint, ItemInterface> items = new ConcurrentDictionary<uint, ItemInterface>();
private readonly OutgoingMessageBuilderInterface outgoingMessageBuilder; private readonly OutgoingMessageBuilderInterface outgoingMessageBuilder;
private readonly TransportInterface transport; private readonly TransportInterface transport;
} }

View File

@ -11,9 +11,9 @@ using System.Threading.Tasks;
namespace Client.Infrastructure.Factories namespace Client.Infrastructure.Factories
{ {
public class ItemFactory : EntityFactoryInterface<BaseItem> public class ItemFactory : EntityFactoryInterface<ItemInterface>
{ {
public BaseItem? Create(string data) public ItemInterface? Create(string data)
{ {
var type = JsonConvert.DeserializeObject<ItemType>(data, settings); var type = JsonConvert.DeserializeObject<ItemType>(data, settings);
@ -33,7 +33,7 @@ namespace Client.Infrastructure.Factories
throw new ArgumentException("Invalid item type " + type.Type.ToString()); 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); JsonConvert.PopulateObject(data, entity, settings);
} }

View File

@ -40,13 +40,15 @@ namespace Interlude
return result; return result;
} }
const Entities::BaseItem& GetItem(uint32_t objectId) const const std::shared_ptr<Entities::BaseItem> GetItem(uint32_t objectId) const
{ {
std::unique_lock<std::shared_timed_mutex>(m_Mutex);
if (m_Items.find(objectId) != m_Items.end()) 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) : ItemRepository(const NetworkHandlerWrapper& networkHandler, const ItemFactory& factory, EntityFinder& finder) :

View File

@ -100,13 +100,13 @@ namespace Interlude
void ToggleAutouseSoulshot(int objectId) const override void ToggleAutouseSoulshot(int objectId) const override
{ {
const auto item = m_ItemRespository.GetItem(objectId); const auto item = m_ItemRespository.GetItem(objectId);
if (item.GetId()) if (item)
{ {
const auto etcItem = static_cast<const Entities::EtcItem&>(item); const auto etcItem = static_cast<const Entities::EtcItem*>(item.get());
L2ParamStack* stack = new L2ParamStack(2); L2ParamStack* stack = new L2ParamStack(2);
stack->PushBack((void*)etcItem.GetItemId()); stack->PushBack((void*)etcItem->GetItemId());
stack->PushBack((void*)(etcItem.IsAutoused() ? 0 : 1)); stack->PushBack((void*)(etcItem->IsAutoused() ? 0 : 1));
m_NetworkHandler.RequestAutoSoulShot(*stack); m_NetworkHandler.RequestAutoSoulShot(*stack);