using Jovian.InspectorTools; using Jovian.Logger; using System; using System.Collections.Generic; using ZLinq; using UnityEngine; namespace Nox.Game { public interface IModifier { string Name { get; } Guid Id { get; } StatType StatType { get; } AttributeType AttributeType { get; } ModifierOperation Operation { get; } float Value { get; } } public interface IModifiersFactory { IReadOnlyCollection GetAll(); IModifier GetById(Guid modifierId); IReadOnlyCollection GetModifiersFor(IEntityDefinition character); bool TryAddModifier(IEntityDefinition character, Guid modiferId); } public enum ModifierOperation { None, Flat, Addition, Multiplication, Percentage } [Serializable] public sealed class ModifierDefinition : IModifier { [field: SerializeField] public string Name { get; set; } public Guid Id { get; set; } [field: SerializeField] public StatType StatType { get; set; } [field: SerializeField] public AttributeType AttributeType { get; set; } [field: SerializeField] public ModifierOperation Operation { get; set; } [field: SerializeField] public float Value { get; set; } } [Serializable] public sealed class ModifiersData { public List modifiers = new (); } public class ModifiersFactory : IModifiersFactory { private readonly ModifiersRegistry modifiersRegistry; private readonly Dictionary modifierPool = new (); public ModifiersFactory(ModifiersRegistry modifiersRegistry) { this.modifiersRegistry = modifiersRegistry; var allAvailableModifiers = modifiersRegistry.modifiersData; foreach(var modifier in allAvailableModifiers.modifiers) { modifierPool.Add(modifier.Id, modifier); } } public IReadOnlyCollection GetAll() { return modifiersRegistry.modifiersData.modifiers; } public IModifier GetById(Guid modifierId) { return modifiersRegistry.modifiersData.modifiers.AsValueEnumerable().FirstOrDefault(m => m.Id == modifierId); } public IReadOnlyCollection GetModifiersFor(IEntityDefinition character) { return character.Modifiers.modifiers; } public bool TryAddModifier(IEntityDefinition character, Guid modifierId) { if(character == null) { return false; } if(modifierId == Guid.Empty) { GlobalLogger.LogException("Cannot add a modifier with an empty ID!", LogCategory.GameLogic); return false; } if(character.Modifiers.modifiers.AsValueEnumerable().Any(p => p != null && p.Id == modifierId)) { return false; } if(!modifierPool.TryGetValue(modifierId, out var modifier)) { return false; } character.Modifiers.modifiers.Add(new ModifierDefinition { Id = modifier.Id, Name = modifier.Name, StatType = modifier.StatType, AttributeType = modifier.AttributeType, Operation = modifier.Operation, Value = modifier.Value }); return true; } } }