forked from Shardstone/trail-into-darkness
95 lines
2.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|