Files
trail-into-darkness/Assets/Code/GameState/Entities/PerkFactory.cs
2026-04-02 09:12:37 +02:00

95 lines
2.8 KiB
C#

using Jovian.Logger;
using System;
using System.Collections.Generic;
using ZLinq;
using UnityEngine;
namespace Nox.Game {
public interface IPerk {
Guid Id { get; }
string Name { get; }
ModifiersData Modifiers { get; }
}
public interface IPerkFactory {
IReadOnlyCollection<IPerk> GetAll();
IPerk GetById(Guid perkId);
IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character);
bool TryAddPerk(IEntityDefinition character, Guid perkId);
}
[Serializable]
public sealed class PerkDefinition : IPerk {
[field: SerializeField] public string Name { get; set; }
[field: SerializeField] public ModifiersData Modifiers { get; set; }
public Guid Id { get; set; }
}
[Serializable]
public sealed class PerksData {
public List<PerkDefinition> perks = new ();
}
public sealed class PerkFactory : IPerkFactory {
private readonly Dictionary<Guid, IPerk> perkPool = new ();
public PerkFactory(PerksRegistry perksRegistry) {
if(!perksRegistry) {
throw new ArgumentNullException(nameof(perksRegistry));
}
var allAvailablePerks = perksRegistry.perksData;
foreach(var perk in allAvailablePerks.perks) {
perkPool.Add(perk.Id, perk);
}
}
public IReadOnlyCollection<IPerk> GetAll() {
return perkPool.Values.AsValueEnumerable().ToList();
}
public IPerk GetById(Guid perkId) {
perkPool.TryGetValue(perkId, out var perk);
return perk;
}
public IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character) {
if(character == null) {
return perkPool.Values.AsValueEnumerable().ToList();
}
var ownedPerkIds = character.Perks.perks.AsValueEnumerable()
.Select(p => p.Id)
.ToHashSet();
return perkPool.Values.AsValueEnumerable().Where(p => !ownedPerkIds.Contains(p.Id)).ToList();
}
public bool TryAddPerk(IEntityDefinition character, Guid perkId) {
if(character == null) {
return false;
}
if(perkId == Guid.Empty) {
GlobalLogger.LogException("Cannot add a perk with an empty Id!", LogCategory.GameLogic);
}
if(character.Perks.perks.AsValueEnumerable().Any(p => p != null && p.Id == perkId)) {
return false;
}
if(!perkPool.TryGetValue(perkId, out var perk)) {
return false;
}
character.Perks.perks.Add(new PerkDefinition {
Id = perk.Id,
Name = perk.Name,
Modifiers = perk.Modifiers
});
return true;
}
}
}