using System; using System.Collections.Generic; using System.Linq; namespace Nox.Game { public interface IPerkFactory { IReadOnlyCollection GetAll(); PerkDefinition GetById(string perkId); IReadOnlyCollection GetPerksFor(CharacterDefinition character); bool TryAddPerk(CharacterDefinition character, string perkId); } public sealed class PerkFactory : IPerkFactory { private readonly Dictionary perkPool = new (); public PerkFactory(PerksRegistry perksRegistry) { if(perksRegistry == null) { throw new ArgumentNullException(nameof(perksRegistry)); } var allAvailablePerks = perksRegistry.perksData; foreach(var perk in allAvailablePerks.perks) { perkPool.Add(perk.id, perk); } } public IReadOnlyCollection GetAll() { return perkPool.Values.ToList(); } public PerkDefinition GetById(string perkId) { if(string.IsNullOrWhiteSpace(perkId)) { return null; } perkPool.TryGetValue(perkId, out var perk); return perk; } public IReadOnlyCollection GetPerksFor(CharacterDefinition character) { if(character == null) { return perkPool.Values.ToList(); } var ownedPerkIds = character.perksData.perks .Where(p => p != null && !string.IsNullOrWhiteSpace(p.id)) .Select(p => p.id) .ToHashSet(); return perkPool.Values.Where(p => !ownedPerkIds.Contains(p.id)).ToList(); } public bool TryAddPerk(CharacterDefinition character, string perkId) { if(character == null || string.IsNullOrWhiteSpace(perkId)) { return false; } if(character.perksData.perks.Any(p => p != null && p.id == perkId)) { return false; } if(!perkPool.TryGetValue(perkId, out PerkDefinition perk)) { return false; } character.perksData.perks.Add(new PerkDefinition { id = perk.id, name = perk.name }); return true; } } }