diff --git a/src/RavenNest.Blazor.Services/AIAssistanceService.cs b/src/RavenNest.Blazor.Services/AIAssistanceService.cs index 13574c69..d285515d 100644 --- a/src/RavenNest.Blazor.Services/AIAssistanceService.cs +++ b/src/RavenNest.Blazor.Services/AIAssistanceService.cs @@ -23,12 +23,12 @@ public class AIAssistanceFunctionCallbacks { private readonly GameData gameData; private readonly IServerManager serverManager; - private readonly IItemManager itemManager; + private readonly ItemManager itemManager; public AIAssistanceFunctionCallbacks( GameData gameData, IServerManager serverManager, - IItemManager itemManager) + ItemManager itemManager) : base() { this.gameData = gameData; diff --git a/src/RavenNest.Blazor.Services/ItemService.cs b/src/RavenNest.Blazor.Services/ItemService.cs index 42f995af..a36d4ad5 100644 --- a/src/RavenNest.Blazor.Services/ItemService.cs +++ b/src/RavenNest.Blazor.Services/ItemService.cs @@ -14,12 +14,12 @@ namespace RavenNest.Blazor.Services public class ItemService : RavenNestService { private readonly GameData gameData; - private readonly IItemManager itemManager; + private readonly ItemManager itemManager; private readonly IReadOnlyList availableAttributes; public ItemService( GameData gameData, - IItemManager itemManager, + ItemManager itemManager, IHttpContextAccessor accessor, SessionInfoProvider sessionInfoProvider) : base(accessor, sessionInfoProvider) diff --git a/src/RavenNest.Blazor/Controllers/ItemsController.cs b/src/RavenNest.Blazor/Controllers/ItemsController.cs index 2f3c5452..ec861a3d 100644 --- a/src/RavenNest.Blazor/Controllers/ItemsController.cs +++ b/src/RavenNest.Blazor/Controllers/ItemsController.cs @@ -15,13 +15,13 @@ public class ItemsController : ControllerBase { private readonly GameData gameData; private readonly SessionInfoProvider sessionInfoProvider; - private readonly IItemManager itemManager; + private readonly ItemManager itemManager; private readonly IAuthManager authManager; public ItemsController( GameData gameData, SessionInfoProvider sessionInfoProvider, - IItemManager itemManager, + ItemManager itemManager, IAuthManager authManager) { this.gameData = gameData; diff --git a/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor b/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor index cb5d9fed..e3a9d642 100644 --- a/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor +++ b/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor @@ -1,6 +1,7 @@ @layout AdminLayout @page "/admin/items" @using Microsoft.AspNetCore.Hosting; +@using RavenNest.BusinessLogic.Game; @using RavenNest.Models; @using System.IO; @inject RavenNest.Blazor.Services.AuthService AuthService @@ -16,7 +17,7 @@
@*Model="editedItem"*@ - +
×
Form
@@ -114,29 +115,29 @@ @if (CanBeEquipped()) { -
-

Level Requirements

-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
+
+

Level Requirements

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+

Appearance

@@ -253,7 +254,7 @@
- +
@@ -311,7 +312,6 @@
@@ -330,19 +330,72 @@ else { + +
+ + + + + + + + + + + + + + + + + + + +
+ - - - - - - - - - + + + + + + + + + @@ -350,8 +403,8 @@ { - - + - - - - - - - + + + + + -
NameStatsLevel ReqCategoryItem TypeMaterial TypeCrafting LevelVendor PriceCrafting RequirementsNameStatsLevel ReqCategoryItem TypeMaterial TypeCrafting LevelVendor PriceCrafting Requirements
@item.Name + @item.Name @if (item.WeaponAim > 0) { @item.WeaponAim @@ -386,7 +439,7 @@ @item.ArmorPower } + @if (item.RequiredAttackLevel > 0) { @@ -416,19 +469,19 @@ } @item.Category@item.Type@item.Material@item.RequiredCraftingLevel@item.ShopSellPrice  + @item.Category@item.Type@item.Material@item.RequiredCraftingLevel@item.ShopSellPrice  @foreach (var req in item.CraftingRequirements) { - var reqItem = items.First(x => x.Id == req.ResourceItemId); + var reqItem = availableItems.First(x => x.Id == req.ResourceItemId); @(reqItem.Name) x@(req.Amount)  } + @@ -458,7 +511,9 @@ private string unmodifiedJson; private RavenNest.Models.SessionInfo session; + private RavenNest.Models.ItemCollection availableItems; private RavenNest.Models.ItemCollection items; + private ItemFilter itemFilter = ItemFilter.All; private void ShowForm() { @@ -503,12 +558,19 @@ jsonPresentation = Newtonsoft.Json.JsonConvert.SerializeObject(editedItem, Newtonsoft.Json.Formatting.Indented); } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { CreateContext(); session = AuthService.GetSession(); isAdmin = session != null && session.Administrator; - LoadItems(); + await LoadItems(); + } + + private void SelectItemFilter(ItemFilter newItemFilter) + { + itemFilter = newItemFilter; + items = new Models.ItemCollection(availableItems.Where(x => Filter(x)).OrderBy(x => x.Name)); + InvokeAsync(StateHasChanged); } private bool ItemImageExists() @@ -604,7 +666,7 @@ var result = await ItemService.DeleteItemAsync(itemId); if (result) { - items = new Models.ItemCollection((await ItemService.GetItemsAsync()).OrderBy(x => x.Name)); + await LoadItems(); updateError = ""; } else @@ -627,7 +689,7 @@ var result = await ItemService.AddOrUpdateItemAsync(editedItem); if (result) { - items = new Models.ItemCollection((await ItemService.GetItemsAsync()).OrderBy(x => x.Name)); + await LoadItems(); updateError = ""; } else @@ -645,10 +707,15 @@ editedItem.CraftingRequirements.Add(new ItemCraftingRequirement()); } - private async void LoadItems() + private async Task LoadItems() { - items = new Models.ItemCollection((await ItemService.GetItemsAsync()).OrderBy(x => x.Name)); - StateHasChanged(); + availableItems = new Models.ItemCollection((await ItemService.GetItemsAsync()).OrderBy(x => x.Name)); + items = new Models.ItemCollection(availableItems.OrderBy(x => x.Name)); + } + + private bool Filter(Models.Item item) + { + return ItemService.Filter(itemFilter, item); } public class ItemEdit : RavenNest.Models.Item diff --git a/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor.css b/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor.css index a65b586e..0d298515 100644 --- a/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor.css +++ b/src/RavenNest.Blazor/Pages/Admin/ItemManagement.razor.css @@ -215,6 +215,12 @@ label.input-label { background: linear-gradient(90deg, rgba(0,60,130,1) 0%, rgba(0,88,205,1) 100%); } +.btn.btn-close { + position: absolute; + right: 0; + top: 0; +} + h2 { font-size: 16pt; } diff --git a/src/RavenNest.Blazor/Startup.cs b/src/RavenNest.Blazor/Startup.cs index 5536e472..27841346 100644 --- a/src/RavenNest.Blazor/Startup.cs +++ b/src/RavenNest.Blazor/Startup.cs @@ -356,7 +356,7 @@ private static void RegisterServices(IServiceCollection services) services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/RavenNest.Blazor/wwwroot/css/site.css b/src/RavenNest.Blazor/wwwroot/css/site.css index 87fd4ad1..d38bc6dd 100644 --- a/src/RavenNest.Blazor/wwwroot/css/site.css +++ b/src/RavenNest.Blazor/wwwroot/css/site.css @@ -1394,7 +1394,7 @@ form.item-editor-form { position: absolute; left: 25px; right: 25px; - top: 40px; + top: 50px; bottom: 70px; display: flex; } diff --git a/src/RavenNest.BusinessLogic/Data/GameData.cs b/src/RavenNest.BusinessLogic/Data/GameData.cs index 7f0c22e5..8f2f2597 100644 --- a/src/RavenNest.BusinessLogic/Data/GameData.cs +++ b/src/RavenNest.BusinessLogic/Data/GameData.cs @@ -511,18 +511,67 @@ public GameData( private void MergeInventoryItems() { - bool CanMerge(InventoryItem i) + bool CanMergeInvItem(InventoryItem i) { return !i.Equipped && string.IsNullOrEmpty(i.Enchantment) && string.IsNullOrEmpty(i.Tag) && i.TransmogrificationId == null; } + bool CanMergeStashItem(UserBankItem i) + { + return string.IsNullOrEmpty(i.Enchantment) && string.IsNullOrEmpty(i.Tag) && i.TransmogrificationId == null; + } + + foreach (var ubi in this.userBankItems.Entities) + { + if (!ubi.Soulbound) + { + // see if we should be soulbound or not. + var item = GetItem(ubi.ItemId); + if (item == null || !item.Soulbound) continue; + ubi.Soulbound = item.Soulbound; + } + } + + foreach (var u in this.users.Entities) + { + var items = GetUserBankItems(u.Id); + var mergable = new Dictionary(); + foreach (var item in items) + { + if (!CanMergeStashItem(item)) + { + continue; + } + + if (mergable.TryGetValue(item.ItemId, out var other)) + { + other.Amount += item.Amount; + item.Amount = 0; + Remove(item); + } + else + { + mergable[item.ItemId] = item; + } + } + } + foreach (var c in this.characters.Entities) { var items = GetInventoryItems(c.Id); var mergable = new Dictionary(); foreach (var item in items) { - if (!CanMerge(item)) + if (!item.Soulbound) + { + var i = GetItem(item.ItemId); + if (item.Soulbound != i.Soulbound) + { + item.Soulbound = i.Soulbound; + } + } + + if (!CanMergeInvItem(item)) { continue; } diff --git a/src/RavenNest.BusinessLogic/Extensions/ModelMapper.cs b/src/RavenNest.BusinessLogic/Extensions/ModelMapper.cs index 694317eb..8b8c215c 100644 --- a/src/RavenNest.BusinessLogic/Extensions/ModelMapper.cs +++ b/src/RavenNest.BusinessLogic/Extensions/ModelMapper.cs @@ -264,7 +264,7 @@ public static RavenNest.Models.InventoryItem Map(InventoryItem items) Enchantment = items.Enchantment, Flags = items.Flags ?? 0, Name = items.Name, - Soulbound = items.Soulbound.GetValueOrDefault(), + Soulbound = items.Soulbound, TransmogrificationId = items.TransmogrificationId, }; } diff --git a/src/RavenNest.BusinessLogic/Game/Managers/IItemManager.cs b/src/RavenNest.BusinessLogic/Game/Managers/ItemManager.cs similarity index 95% rename from src/RavenNest.BusinessLogic/Game/Managers/IItemManager.cs rename to src/RavenNest.BusinessLogic/Game/Managers/ItemManager.cs index 6d172921..208f1c39 100644 --- a/src/RavenNest.BusinessLogic/Game/Managers/IItemManager.cs +++ b/src/RavenNest.BusinessLogic/Game/Managers/ItemManager.cs @@ -7,22 +7,10 @@ namespace RavenNest.BusinessLogic.Game { - public interface IItemManager - { - bool Upsert(Item item); - ItemCollection GetAllItems(); - Item GetItem(Guid itemId); - bool TryAddItem(Item item); - bool TryUpdateItem(Item item); - bool RemoveItem(Guid itemId); - RedeemableItemCollection GetRedeemableItems(); - } - - public class ItemManager : IItemManager + public sealed class ItemManager { private const double ItemCacheDurationSeconds = 10 * 60; private readonly IMemoryCache memoryCache; - private readonly GameData gameData; public ItemManager( diff --git a/src/RavenNest.BusinessLogic/Game/Managers/PlayerManager.cs b/src/RavenNest.BusinessLogic/Game/Managers/PlayerManager.cs index ca12901c..d460104f 100644 --- a/src/RavenNest.BusinessLogic/Game/Managers/PlayerManager.cs +++ b/src/RavenNest.BusinessLogic/Game/Managers/PlayerManager.cs @@ -1532,7 +1532,7 @@ private void SendItemAddEvent(DataModels.InventoryItem item, long amount, Charac TransmogrificationId = item.TransmogrificationId, Flags = item.Flags.GetValueOrDefault(), Tag = item.Tag, - Soulbound = item.Soulbound.GetValueOrDefault(), + Soulbound = item.Soulbound, }; var session = gameData.GetSessionByUserId(sessionUserId.Value); @@ -2084,7 +2084,7 @@ private static DataModels.UserBankItem CreateBankItem(Character character, DataM Flags = item.Flags ?? 0, ItemId = item.ItemId, Name = item.Name, - Soulbound = item.Soulbound.GetValueOrDefault(), + Soulbound = item.Soulbound, Tag = item.Tag, TransmogrificationId = item.TransmogrificationId, UserId = character.UserId diff --git a/src/RavenNest.BusinessLogic/Providers/InventoryProvider.cs b/src/RavenNest.BusinessLogic/Providers/InventoryProvider.cs index a890c26c..1e1948b7 100644 --- a/src/RavenNest.BusinessLogic/Providers/InventoryProvider.cs +++ b/src/RavenNest.BusinessLogic/Providers/InventoryProvider.cs @@ -1341,7 +1341,7 @@ public static bool CanBeStacked(ReadOnlyInventoryItem item) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CanBeStacked(DataModels.InventoryItem item) { - return item != null && item.TransmogrificationId == null && string.IsNullOrEmpty(item.Enchantment) && !item.Soulbound.GetValueOrDefault(); + return item != null && item.TransmogrificationId == null && string.IsNullOrEmpty(item.Enchantment) && !item.Soulbound; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1495,7 +1495,7 @@ public static ReadOnlyInventoryItem Create(GameData gameData, InventoryItem item item.Equipped, item.Tag, item.Flags.GetValueOrDefault(), - item.Soulbound.GetValueOrDefault(), + item.Soulbound, i, GetEquipmentSlot((ItemType)i.Type)); } diff --git a/src/RavenNest.DataModels/InventoryItem.cs b/src/RavenNest.DataModels/InventoryItem.cs index 0a570576..80a4b2e6 100644 --- a/src/RavenNest.DataModels/InventoryItem.cs +++ b/src/RavenNest.DataModels/InventoryItem.cs @@ -12,7 +12,7 @@ public partial class InventoryItem : Entity private long? amount; public long? Amount { get => amount; set => Set(ref amount, value); } private bool equipped; public bool Equipped { get => equipped; set => Set(ref equipped, value); } private string tag; public string Tag { get => tag; set => Set(ref tag, value); } - private bool? soulbound; public bool? Soulbound { get => soulbound; set => Set(ref soulbound, value); } + private bool soulbound; public bool Soulbound { get => soulbound; set => Set(ref soulbound, value); } private Guid? transmogrificationId; public Guid? TransmogrificationId { get => transmogrificationId; set => Set(ref transmogrificationId, value); } private int? flags; public int? Flags { get => flags; set => Set(ref flags, value); } diff --git a/src/RavenNest.Models/ItemCraftingRequirement.cs b/src/RavenNest.Models/ItemCraftingRequirement.cs index 4dd21bb6..4d126ec2 100644 --- a/src/RavenNest.Models/ItemCraftingRequirement.cs +++ b/src/RavenNest.Models/ItemCraftingRequirement.cs @@ -9,4 +9,16 @@ public class ItemCraftingRequirement public Guid ResourceItemId { get; set; } public int Amount { get; set; } } -} \ No newline at end of file + + public class ItemRecipe + { + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + + public int RequiredLevel { get; set; } + public int RequiredSkill { get; set; } + + + } +}