using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Nox.Game { public interface IEntityDefinition { string ID { get; } string DisplayName { get; } EntityAttributes Attributes { get; } EntityStats Stats { get; } } public enum StatType { None, Health, Stamina, Level, Experience } public enum AttributeType { None, Might, Reflex, Knowledge, Perception } public enum CharacterRole { None, Protagonist, Companion } public enum CharacterClass { None, Warrior, Rogue, Mage, Herald } public enum CharacterRace { None, Human, DarkElf, Tunneler } [Serializable] public sealed class Stat { private readonly StatType health; public StatType type; public int value; public Stat(StatType health, int value) { this.health = health; this.value = value; } } [Serializable] public sealed record Attribute { private readonly int values; public AttributeType attribute; public int value; public Attribute(AttributeType attributeType, int values) { this.values = values; } } [Serializable] public sealed class EntityAttributes { public Attribute[] attributes; public static EntityAttributes operator +(EntityAttributes a, EntityAttributes b) { return new EntityAttributes { attributes = a.attributes .Select(attr => new Attribute(attr.attribute, attr.value + b.attributes .First(attr2 => attr2.attribute == attr.attribute).value)) .ToArray() }; } } [Serializable] public sealed class EntityStats { public Stat[] stats; public int GetValue(StatType statType) { return stats.First(stat => stat.type == statType).value; } } [Serializable] public sealed class CharacterDefinition : IEntityDefinition { [SerializeField] private string id; [SerializeField] private string displayName; public CharacterRace race; public CharacterClass @class; public CharacterRole role; [SerializeField] private EntityAttributes attributes; [SerializeField] private EntityStats stats; public PerksData perksData = new(); public ModifiersData activeModifiers = new(); public CharacterDefinition Clone() { return new CharacterDefinition { id = id, displayName = displayName, role = role, race = race, @class = @class, attributes = new EntityAttributes(), stats = new EntityStats(), perksData = new PerksData(), activeModifiers = new ModifiersData() }; } public string ID { get => id; set => id = value; } public string DisplayName { get => displayName; set => displayName = value; } public EntityAttributes Attributes { get => attributes; set => attributes = value; } public EntityStats Stats { get => stats; set => stats = value; } } [Serializable] public sealed class PartyDefinition { public int maxPartySize; public List members = new(); [JsonIgnore] public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist); [JsonIgnore] public IReadOnlyList Companions => members.Where(m => m.role == CharacterRole.Companion).ToList(); } }