server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/ServerConfigs/RecipeManager.cs
2026-02-10 18:21:30 +01:00

143 lines
No EOL
4.9 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PhoenixLib.Caching;
using PhoenixLib.Logging;
using WingsEmu.DTOs.Recipes;
using WingsEmu.Game;
using WingsEmu.Game.Items;
using WingsEmu.Game.Managers.ServerData;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Plugins.BasicImplementations.ServerConfigs.ImportObjects;
using WingsEmu.Plugins.BasicImplementations.ServerConfigs.ImportObjects.Recipes;
namespace WingsEmu.Plugins.BasicImplementations.ServerConfigs;
public class RecipeManager : IRecipeManager
{
private readonly IEnumerable<RecipeImportFile> _files;
private readonly HashSet<Recipe> _generalRecipes = new();
private readonly IItemsManager _itemsManager;
private readonly IRecipeFactory _recipeFactory;
private readonly IKeyValueCache<List<Recipe>> _recipes;
public RecipeManager(IEnumerable<RecipeImportFile> files, IRecipeFactory recipeFactory, IKeyValueCache<List<Recipe>> recipes, IItemsManager itemsManager)
{
_files = files;
_recipes = recipes;
_itemsManager = itemsManager;
_recipeFactory = recipeFactory;
}
public async Task InitializeAsync()
{
var recipes = new List<RecipeDTO>();
foreach (RecipeObject recipeObject in _files.SelectMany(x => x.Recipes))
{
if (recipeObject == null)
{
continue;
}
RecipeDTO recipe = recipeObject.ToDto();
IGameItem producerItem = _itemsManager.GetItem(recipe.ProducedItemVnum);
if (producerItem is null)
{
Log.Warn("[RECIPE] Item not found: " + recipe.Id +
$" on recipe ProducerItemVnum: {recipe.ProducerItemVnum} | ProducerNpc: {recipe.ProducerNpcVnum} | Producer: {recipe.ProducerMapNpcId}");
}
List<RecipeItemDTO> items = new();
if (recipeObject.Items != null)
{
short slot = 0;
foreach (RecipeItemObject recipeItem in recipeObject.Items)
{
if (recipeItem == null)
{
continue;
}
IGameItem item = _itemsManager.GetItem(recipeItem.ItemVnum);
if (item is null)
{
Log.Warn("[RECIPE] Item not found: " + recipeItem.ItemVnum +
$" on recipe ProducerItemVnum: {recipe.ProducerItemVnum} | ProducerNpc: {recipe.ProducerNpcVnum} | Producer: {recipe.ProducerMapNpcId}");
continue;
}
items.Add(recipeItem.ToDto(slot));
slot++;
}
}
recipe.Items = items;
recipes.Add(recipe);
}
int count = 0;
foreach (RecipeDTO recipe in recipes)
{
if (recipe.Items == null)
{
continue;
}
Recipe gameRecipe = _recipeFactory.CreateRecipe(recipe);
_generalRecipes.Add(gameRecipe);
count++;
if (gameRecipe.ProducerItemVnum.HasValue)
{
string key = $"item-{gameRecipe.ProducerItemVnum.Value}";
List<Recipe> list = _recipes.Get(key);
if (list == null)
{
list = new List<Recipe>();
_recipes.Set(key, list);
}
list.Add(gameRecipe);
continue;
}
if (gameRecipe.ProducerNpcVnum.HasValue)
{
string key = $"npcVnum-{gameRecipe.ProducerNpcVnum.Value}";
List<Recipe> list = _recipes.Get(key);
if (list == null)
{
list = new List<Recipe>();
_recipes.Set(key, list);
}
list.Add(gameRecipe);
continue;
}
if (gameRecipe.ProducerMapNpcId.HasValue)
{
string key = $"mapNpc-{gameRecipe.ProducerMapNpcId.Value}";
List<Recipe> list = _recipes.Get(key);
if (list == null)
{
list = new List<Recipe>();
_recipes.Set(key, list);
}
list.Add(gameRecipe);
}
}
Log.Info($"[RECIPE_MANAGER] Loaded {count.ToString()} recipes");
}
public IReadOnlyList<Recipe> GetRecipesByProducerItemVnum(int itemVnum) => _recipes.Get($"item-{itemVnum}");
public IReadOnlyList<Recipe> GetRecipesByNpcId(long mapNpcId) => _recipes.Get($"mapNpc-{mapNpcId}");
public IReadOnlyList<Recipe> GetRecipesByNpcMonsterVnum(int npcVNum) => _recipes.Get($"npcVnum-{npcVNum}");
public IReadOnlyList<Recipe> GetRecipeByProducedItemVnum(int itemVnum) => _generalRecipes.Where(x => x != null && x.ProducedItemVnum == itemVnum).ToList();
}