diff --git a/Assets/Code/Core/EntryPoint.cs b/Assets/Code/Core/EntryPoint.cs index 96e4db6..d1f83c3 100644 --- a/Assets/Code/Core/EntryPoint.cs +++ b/Assets/Code/Core/EntryPoint.cs @@ -99,7 +99,7 @@ namespace Nox.Core { saveSystem = new SaveSystem(saveSerializer, saveStorage, saveSlotManager, saveSettings); var adventuredata = new AdventureData(); - var characterSystems = DefaultCharacterSystemsFactory.Create(maxPartySize: 8); + var characterSystems = DefaultCharacterSystemsFactory.Create(maxPartySize: 4, new PerkRegistry(), new CharacterRegistry()); var partyCreatorModel = new PartyCreatorModel(characterSystems.CharacterFactory, characterSystems.PartyFactory); applicationStates = new Dictionary { diff --git a/Assets/Code/Core/GameDataState.cs b/Assets/Code/Core/GameDataState.cs index 857658d..b33d3e3 100644 --- a/Assets/Code/Core/GameDataState.cs +++ b/Assets/Code/Core/GameDataState.cs @@ -11,7 +11,7 @@ namespace Nox.Core { public Vector3? savedPartyPosition; public GameState ActiveGameState { get; set; } public PlayMode ActivePlayMode { get; set; } - public PartyData ActiveParty { get; set; } + public PartyDefinition ActiveParty { get; set; } public PlayMode PreviousPlayMode { get; private set; } diff --git a/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs b/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs deleted file mode 100644 index 3f6c3b9..0000000 --- a/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs +++ /dev/null @@ -1,469 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Nox.Game { - public enum CharacterRole { - Protagonist, - Companion - } - - [Serializable] - public sealed class CharacterAttributes { - public int might; - public int reflex; - public int knowledge; - - public int Total => might + reflex + knowledge; - } - - [Serializable] - public sealed class CharacterStats { - public int maxHealth; - public int maxStamina; - public float dodgeStaminaLossMultiplier; - } - - [Serializable] - public sealed class PerkDefinition { - public string id; - public string name; - public string mechanicalBonus; - public string thematicPenalty; - } - - [Serializable] - public sealed class CharacterData { - public string id; - public string displayName; - public CharacterRole role; - public int level; - public int experience; - public CharacterAttributes attributes; - public CharacterStats stats; - public List perks = new List(); - - public CharacterData Clone() { - return new CharacterData { - id = id, - displayName = displayName, - role = role, - level = level, - experience = experience, - attributes = new CharacterAttributes { - might = attributes?.might ?? 0, - reflex = attributes?.reflex ?? 0, - knowledge = attributes?.knowledge ?? 0 - }, - stats = new CharacterStats { - maxHealth = stats?.maxHealth ?? 0, - maxStamina = stats?.maxStamina ?? 0, - dodgeStaminaLossMultiplier = stats?.dodgeStaminaLossMultiplier ?? 1f - }, - perks = perks.Select(p => new PerkDefinition { - id = p.id, - name = p.name, - mechanicalBonus = p.mechanicalBonus, - thematicPenalty = p.thematicPenalty - }).ToList() - }; - } - } - - [Serializable] - public sealed class CharacterTemplate { - public string id; - public string displayName; - public CharacterAttributes attributes; - public int level = 1; - public int experience; - public List startingPerkIds = new List(); - } - - [Serializable] - public sealed class CustomCharacterCreationRequest { - public string id; - public string displayName; - public int mightPoints; - public int reflexPoints; - public int knowledgePoints; - public List startingPerkIds = new List(); - } - - [Serializable] - public sealed class PartyData { - public List members = new List(); - public int maxPartySize; - - [JsonIgnore] - public CharacterData Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist); - [JsonIgnore] - public IReadOnlyList Companions => members.Where(m => m.role == CharacterRole.Companion).ToList(); - } - - public interface ICharacterAttributesFactory { - CharacterAttributes Create(int might, int reflex, int knowledge); - CharacterAttributes CreateFromPointAllocation(int mightPoints, int reflexPoints, int knowledgePoints); - } - - public interface ICharacterStatsFactory { - CharacterStats Create(CharacterAttributes attributes); - } - - public interface IPerkFactory { - IReadOnlyCollection GetAll(); - PerkDefinition GetById(string perkId); - IReadOnlyCollection GetAvailableFor(CharacterData character); - bool TryAddPerk(CharacterData character, string perkId); - } - - public interface ICharacterFactory { - CharacterData CreateCustomProtagonist(CustomCharacterCreationRequest request); - CharacterData CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion); - } - - public interface IPartyFactory { - PartyData Create(CharacterData protagonist, IEnumerable companions = null); - } - - public interface ICharacterSystems { - IPerkFactory PerkFactory { get; } - ICharacterFactory CharacterFactory { get; } - IPartyFactory PartyFactory { get; } - } - - public sealed class CharacterFactoryOptions { - public int baseMight = 1; - public int baseReflex = 1; - public int baseKnowledge = 1; - public int customAttributePointBudget = 10; - public int startingLevel = 1; - } - - public sealed class CharacterStatsFactoryOptions { - public int baseHealth = 10; - public int baseStamina = 5; - public int mightHealthBonus = 3; - public int mightStaminaBonus = 1; - public int knowledgeStaminaBonus = 2; - public float baseDodgeStaminaLossMultiplier = 1f; - public float reflexDodgeStaminaLossReduction = 0.03f; - public float minDodgeStaminaLossMultiplier = 0.4f; - } - - public sealed class PartyFactoryOptions { - public int minPartySize = 1; - public int maxPartySize = 4; - public bool enforceUniqueCharacterIds = true; - } - - public sealed class CharacterSystems : ICharacterSystems { - public CharacterSystems(IPerkFactory perkFactory, ICharacterFactory characterFactory, IPartyFactory partyFactory) { - PerkFactory = perkFactory; - CharacterFactory = characterFactory; - PartyFactory = partyFactory; - } - - public IPerkFactory PerkFactory { get; } - public ICharacterFactory CharacterFactory { get; } - public IPartyFactory PartyFactory { get; } - } - - public static class DefaultCharacterSystemsFactory { - public static ICharacterSystems Create(int maxPartySize = 8) { - IPerkFactory perkFactory = new PerkFactory(CreateDefaultPerks()); - ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(new CharacterFactoryOptions { - baseMight = 1, - baseReflex = 1, - baseKnowledge = 1, - customAttributePointBudget = 10, - startingLevel = 1 - }); - ICharacterStatsFactory statsFactory = new CharacterStatsFactory(); - ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory); - IPartyFactory partyFactory = new PartyFactory(new PartyFactoryOptions { - minPartySize = 1, - maxPartySize = maxPartySize, - enforceUniqueCharacterIds = true - }); - - return new CharacterSystems(perkFactory, characterFactory, partyFactory); - } - - private static IEnumerable CreateDefaultPerks() { - return new[] { - new PerkDefinition { id = "iron-will", name = "Iron Will", mechanicalBonus = "+1 max health per level", thematicPenalty = "-1 social flexibility in dialogue checks" }, - new PerkDefinition { id = "steadfast", name = "Steadfast", mechanicalBonus = "-10% stamina loss when bracing", thematicPenalty = "-10% movement speed in retreat events" }, - new PerkDefinition { id = "nimble-step", name = "Nimble Step", mechanicalBonus = "-15% dodge stamina loss", thematicPenalty = "+10% stamina loss on heavy actions" }, - new PerkDefinition { id = "lorekeeper", name = "Lorekeeper", mechanicalBonus = "+15% knowledge event success", thematicPenalty = "-10% intimidation success chance" }, - new PerkDefinition { id = "bulwark", name = "Bulwark", mechanicalBonus = "+2 base defense checks", thematicPenalty = "-1 reflex in stealth checks" }, - new PerkDefinition { id = "pathfinder", name = "Pathfinder", mechanicalBonus = "+15% scouting event success", thematicPenalty = "-1 max health during ambush events" } - }; - } - } - - public sealed class CharacterAttributesFactory : ICharacterAttributesFactory { - private readonly CharacterFactoryOptions options; - - public CharacterAttributesFactory(CharacterFactoryOptions options = null) { - this.options = options ?? new CharacterFactoryOptions(); - } - - public CharacterAttributes Create(int might, int reflex, int knowledge) { - if(might < 0 || reflex < 0 || knowledge < 0) { - throw new ArgumentOutOfRangeException(nameof(might), "attributes cannot be negative."); - } - - return new CharacterAttributes { - might = might, - reflex = reflex, - knowledge = knowledge - }; - } - - public CharacterAttributes CreateFromPointAllocation(int mightPoints, int reflexPoints, int knowledgePoints) { - if(mightPoints < 0 || reflexPoints < 0 || knowledgePoints < 0) { - throw new ArgumentOutOfRangeException(nameof(mightPoints), "Point allocation cannot be negative."); - } - - int allocated = mightPoints + reflexPoints + knowledgePoints; - if(allocated > options.customAttributePointBudget) { - throw new ArgumentException($"Allocated {allocated} points but budget is {options.customAttributePointBudget}."); - } - - return new CharacterAttributes { - might = options.baseMight + mightPoints, - reflex = options.baseReflex + reflexPoints, - knowledge = options.baseKnowledge + knowledgePoints - }; - } - } - - public sealed class CharacterStatsFactory : ICharacterStatsFactory { - private readonly CharacterStatsFactoryOptions options; - - public CharacterStatsFactory(CharacterStatsFactoryOptions options = null) { - this.options = options ?? new CharacterStatsFactoryOptions(); - } - - public CharacterStats Create(CharacterAttributes attributes) { - if(attributes == null) { - throw new ArgumentNullException(nameof(attributes)); - } - - int maxHealth = options.baseHealth + attributes.might * options.mightHealthBonus; - int maxStamina = options.baseStamina + - attributes.might * options.mightStaminaBonus + - attributes.knowledge * options.knowledgeStaminaBonus; - float dodgeMultiplier = options.baseDodgeStaminaLossMultiplier - - attributes.reflex * options.reflexDodgeStaminaLossReduction; - dodgeMultiplier = Math.Max(options.minDodgeStaminaLossMultiplier, dodgeMultiplier); - - return new CharacterStats { - maxHealth = maxHealth, - maxStamina = maxStamina, - dodgeStaminaLossMultiplier = dodgeMultiplier - }; - } - } - - public sealed class PerkFactory : IPerkFactory { - private readonly Dictionary perkPool; - - public PerkFactory(IEnumerable perkPool) { - if(perkPool == null) { - throw new ArgumentNullException(nameof(perkPool)); - } - - this.perkPool = perkPool - .Where(p => p != null && !string.IsNullOrWhiteSpace(p.id)) - .GroupBy(p => p.id) - .ToDictionary(g => g.Key, g => g.First()); - } - - public IReadOnlyCollection GetAll() { - return perkPool.Values.ToList(); - } - - public PerkDefinition GetById(string perkId) { - if(string.IsNullOrWhiteSpace(perkId)) { - return null; - } - - perkPool.TryGetValue(perkId, out PerkDefinition perk); - return perk; - } - - public IReadOnlyCollection GetAvailableFor(CharacterData character) { - if(character == null) { - return perkPool.Values.ToList(); - } - - HashSet ownedPerkIds = character.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(CharacterData character, string perkId) { - if(character == null || string.IsNullOrWhiteSpace(perkId)) { - return false; - } - - if(character.perks.Any(p => p != null && p.id == perkId)) { - return false; - } - - if(!perkPool.TryGetValue(perkId, out PerkDefinition perk)) { - return false; - } - - character.perks.Add(new PerkDefinition { - id = perk.id, - name = perk.name, - mechanicalBonus = perk.mechanicalBonus, - thematicPenalty = perk.thematicPenalty - }); - return true; - } - } - - public sealed class CharacterFactory : ICharacterFactory { - private readonly CharacterFactoryOptions options; - private readonly ICharacterAttributesFactory attributesFactory; - private readonly ICharacterStatsFactory statsFactory; - private readonly IPerkFactory perkFactory; - - public CharacterFactory( - ICharacterAttributesFactory attributesFactory, - ICharacterStatsFactory statsFactory, - IPerkFactory perkFactory, - CharacterFactoryOptions options = null) { - this.attributesFactory = attributesFactory ?? throw new ArgumentNullException(nameof(attributesFactory)); - this.statsFactory = statsFactory ?? throw new ArgumentNullException(nameof(statsFactory)); - this.perkFactory = perkFactory ?? throw new ArgumentNullException(nameof(perkFactory)); - this.options = options ?? new CharacterFactoryOptions(); - } - - public CharacterData CreateCustomProtagonist(CustomCharacterCreationRequest request) { - if(request == null) { - throw new ArgumentNullException(nameof(request)); - } - - CharacterAttributes attributes = attributesFactory.CreateFromPointAllocation( - request.mightPoints, - request.reflexPoints, - request.knowledgePoints); - - CharacterData character = new CharacterData { - id = string.IsNullOrWhiteSpace(request.id) ? Guid.NewGuid().ToString("N") : request.id, - displayName = request.displayName, - role = CharacterRole.Protagonist, - level = options.startingLevel, - experience = 0, - attributes = attributes, - stats = statsFactory.Create(attributes) - }; - - AddStartingPerks(character, request.startingPerkIds); - return character; - } - - public CharacterData CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion) { - if(template == null) { - throw new ArgumentNullException(nameof(template)); - } - - CharacterAttributes sourceAttributes = template.attributes ?? attributesFactory.Create(0, 0, 0); - CharacterAttributes attributes = attributesFactory.Create( - sourceAttributes.might, - sourceAttributes.reflex, - sourceAttributes.knowledge); - - CharacterData character = new CharacterData { - id = string.IsNullOrWhiteSpace(template.id) ? Guid.NewGuid().ToString("N") : template.id, - displayName = template.displayName, - role = role, - level = template.level <= 0 ? options.startingLevel : template.level, - experience = template.experience, - attributes = attributes, - stats = statsFactory.Create(attributes) - }; - - AddStartingPerks(character, template.startingPerkIds); - return character; - } - - private void AddStartingPerks(CharacterData character, IEnumerable perkIds) { - if(perkIds == null) { - return; - } - - foreach(string perkId in perkIds.Distinct()) { - perkFactory.TryAddPerk(character, perkId); - } - } - } - - public sealed class PartyFactory : IPartyFactory { - private readonly PartyFactoryOptions options; - - public PartyFactory(PartyFactoryOptions options = null) { - this.options = options ?? new PartyFactoryOptions(); - } - - public PartyData Create(CharacterData protagonist, IEnumerable companions = null) { - if(protagonist == null) { - throw new ArgumentNullException(nameof(protagonist)); - } - - PartyData party = new PartyData { - maxPartySize = options.maxPartySize <= 0 ? int.MaxValue : options.maxPartySize - }; - - CharacterData protagonistClone = protagonist.Clone(); - protagonistClone.role = CharacterRole.Protagonist; - party.members.Add(protagonistClone); - - if(companions != null) { - foreach(CharacterData companion in companions.Where(c => c != null)) { - CharacterData companionClone = companion.Clone(); - companionClone.role = CharacterRole.Companion; - party.members.Add(companionClone); - } - } - - ValidateParty(party); - return party; - } - - private void ValidateParty(PartyData party) { - if(party.members.Count < options.minPartySize) { - throw new ArgumentException($"Party size {party.members.Count} is below minimum {options.minPartySize}."); - } - - if(party.members.Count > party.maxPartySize) { - throw new ArgumentException($"Party size {party.members.Count} exceeds max {party.maxPartySize}."); - } - - int protagonistCount = party.members.Count(m => m.role == CharacterRole.Protagonist); - if(protagonistCount != 1) { - throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}."); - } - - if(options.enforceUniqueCharacterIds) { - int uniqueIds = party.members - .Where(m => !string.IsNullOrWhiteSpace(m.id)) - .Select(m => m.id) - .Distinct() - .Count(); - if(uniqueIds != party.members.Count) { - throw new ArgumentException("Party contains duplicate or missing character ids."); - } - } - } - } -} diff --git a/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs.meta b/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs.meta deleted file mode 100644 index d7649a9..0000000 --- a/Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: ec5c743399d71cd41b2db4f9a7e5dec1 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs b/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs new file mode 100644 index 0000000..16348cc --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs @@ -0,0 +1,23 @@ +using System; + +namespace Nox.Game { + public interface ICharacterAttributesFactory { + EntityAttributes Create(EntityAttributes attributes); + } + + public sealed class CharacterAttributesFactory : ICharacterAttributesFactory { + private readonly CharacterRegistry characterRegistry; + + public CharacterAttributesFactory(CharacterRegistry characterRegistry) { + this.characterRegistry = characterRegistry; + } + + public EntityAttributes Create(EntityAttributes attributes) { + if(attributes.might <= 0 || attributes.reflex <= 0 || attributes.knowledge <= 0 || attributes.perception <= 0) { + throw new ArgumentOutOfRangeException( "attributes cannot be zero or negative.", new ArgumentException() ); + } + + return attributes; + } + } +} diff --git a/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs.meta b/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs.meta new file mode 100644 index 0000000..3f243c9 --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterAttributesFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1c5d19a12e554fd981cec483ccfcff68 +timeCreated: 1774183852 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/CharacterFactory.cs b/Assets/Code/GameState/Entities/CharacterFactory.cs new file mode 100644 index 0000000..f27802b --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterFactory.cs @@ -0,0 +1,107 @@ +using System; +using System.Linq; + +namespace Nox.Game { + public interface ICharacterFactory { + CharacterDefinition CreateCustomProtagonist(CustomCharacterCreationRequest request); + CharacterDefinition CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion); + } + + [Serializable] + public sealed class CharacterTemplate { + public string id; + public string displayName; + public EntityAttributes attributes; + public CharacterRace characterRace; + public CharacterClass characterClass; + public EntityStats stats; + public PerksData perksData = new (); + } + + [Serializable] + public sealed class CustomCharacterCreationRequest { + public string id; + public string displayName; + public CharacterRace characterRace; + public CharacterClass characterClass; + public EntityStats stats; + public EntityAttributes attributes; + public PerksData perksData = new(); + } + + public sealed class CharacterFactory : ICharacterFactory { + private readonly ICharacterAttributesFactory attributesFactory; + private readonly ICharacterStatsFactory statsFactory; + private readonly IPerkFactory perkFactory; + + public CharacterFactory( + ICharacterAttributesFactory attributesFactory, + ICharacterStatsFactory statsFactory, + IPerkFactory perkFactory) { + this.attributesFactory = attributesFactory ?? throw new ArgumentNullException(nameof(attributesFactory)); + this.statsFactory = statsFactory ?? throw new ArgumentNullException(nameof(statsFactory)); + this.perkFactory = perkFactory ?? throw new ArgumentNullException(nameof(perkFactory)); + } + + public CharacterDefinition CreateCustomProtagonist(CustomCharacterCreationRequest request) { + if(request == null) { + throw new ArgumentNullException(nameof(request)); + } + + var attributes = attributesFactory.Create(request.attributes); + + var character = new CharacterDefinition { + ID = string.IsNullOrWhiteSpace(request.id) ? Guid.NewGuid().ToString("N") : request.id, + DisplayName = request.displayName, + race = request.characterRace, + @class = request.characterClass, + role = CharacterRole.Protagonist, + Attributes = attributes, + Stats = { + level = statsFactory.Create(attributes).level, + health = statsFactory.Create(attributes).health, + stamina = statsFactory.Create(attributes).stamina, + experience = statsFactory.Create(attributes).experience + }, + perksData = new PerksData(), + activeModifiers = new ModifiersData() + }; + + AddStartingPerks(character, request.perksData); + return character; + } + + public CharacterDefinition CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion) { + if(template == null) { + throw new ArgumentNullException(nameof(template)); + } + + var attributes = attributesFactory.Create(template.attributes); + + var character = new CharacterDefinition { + ID = string.IsNullOrWhiteSpace(template.id) ? Guid.NewGuid().ToString("N") : template.id, + DisplayName = template.displayName, + race = template.characterRace, + @class = template.characterClass, + role = role, + Attributes = attributes, + Stats = statsFactory.Create(attributes), + perksData = new PerksData(), + activeModifiers = new ModifiersData() + }; + + AddStartingPerks(character, template.perksData); + return character; + } + + private void AddStartingPerks(CharacterDefinition character, PerksData perkData) { + if(perkData?.perks == null || perkData.perks.Count == 0) { + return; + } + + foreach(var perkId in perkData.perks.Distinct()) { + perkFactory.TryAddPerk(character, perkId.id); + } + } + } +} diff --git a/Assets/Code/GameState/Entities/CharacterFactory.cs.meta b/Assets/Code/GameState/Entities/CharacterFactory.cs.meta new file mode 100644 index 0000000..ba9d812 --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0033c4836b0d4fbbb6e4dde0ac23a2f6 +timeCreated: 1774183767 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/CharacterRegistry.cs b/Assets/Code/GameState/Entities/CharacterRegistry.cs new file mode 100644 index 0000000..ae3712c --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterRegistry.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace Nox.Game { + [CreateAssetMenu(fileName = "CharacterRegistry", menuName = "Nox/Database/Entities/Character Registry")] + public class CharacterRegistry: ScriptableObject { + public CharacterDefinition defaultCharacter; + public List characters = new (); + } +} diff --git a/Assets/Code/GameState/Entities/CharacterRegistry.cs.meta b/Assets/Code/GameState/Entities/CharacterRegistry.cs.meta new file mode 100644 index 0000000..80e1924 --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterRegistry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 91e3086d6951456e9a8a59fcbac0f750 +timeCreated: 1774179358 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/CharacterStatsFactory.cs b/Assets/Code/GameState/Entities/CharacterStatsFactory.cs new file mode 100644 index 0000000..a3bc65c --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterStatsFactory.cs @@ -0,0 +1,37 @@ +using System; + +namespace Nox.Game { + public interface ICharacterStatsFactory { + EntityStats Create(EntityAttributes attributes); + } + + public sealed class CharacterStatsFactoryOptions { + public EntityStats entityStats = new EntityStats() { + health = 10, + stamina = 10, + level = 1, + experience = 0 + }; + } + + public sealed class CharacterStatsFactory : ICharacterStatsFactory { + private readonly CharacterStatsFactoryOptions options; + + public CharacterStatsFactory(CharacterStatsFactoryOptions options = null) { + this.options = options ?? new CharacterStatsFactoryOptions(); + } + + public EntityStats Create(EntityAttributes attributes) { + if(attributes == null) { + throw new ArgumentNullException(nameof(attributes)); + } + + // int maxHealth = options.baseHealth + attributes.might * options.mightHealthBonus; + // int maxStamina = options.baseStamina + + // attributes.might * options.mightStaminaBonus + + // attributes.knowledge * options.knowledgeStaminaBonus; + + return new EntityStats { }; + } + } +} diff --git a/Assets/Code/GameState/Entities/CharacterStatsFactory.cs.meta b/Assets/Code/GameState/Entities/CharacterStatsFactory.cs.meta new file mode 100644 index 0000000..1bba19c --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterStatsFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 75a241c095744a518eb8d1c1b14d24e4 +timeCreated: 1774183822 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/CharacterSystems.cs b/Assets/Code/GameState/Entities/CharacterSystems.cs new file mode 100644 index 0000000..5643fb3 --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterSystems.cs @@ -0,0 +1,20 @@ +namespace Nox.Game { + + public interface ICharacterSystems { + IPerkFactory PerkFactory { get; } + ICharacterFactory CharacterFactory { get; } + IPartyFactory PartyFactory { get; } + } + + public sealed class CharacterSystems : ICharacterSystems { + public CharacterSystems(IPerkFactory perkFactory, ICharacterFactory characterFactory, IPartyFactory partyFactory) { + PerkFactory = perkFactory; + CharacterFactory = characterFactory; + PartyFactory = partyFactory; + } + + public IPerkFactory PerkFactory { get; } + public ICharacterFactory CharacterFactory { get; } + public IPartyFactory PartyFactory { get; } + } +} diff --git a/Assets/Code/GameState/Entities/CharacterSystems.cs.meta b/Assets/Code/GameState/Entities/CharacterSystems.cs.meta new file mode 100644 index 0000000..163466e --- /dev/null +++ b/Assets/Code/GameState/Entities/CharacterSystems.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e9cec54a2252457595e3a97d3dcd755d +timeCreated: 1774184077 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs b/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs new file mode 100644 index 0000000..7b11849 --- /dev/null +++ b/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs @@ -0,0 +1,19 @@ +using System; + +namespace Nox.Game { + public static class DefaultCharacterSystemsFactory { + public static ICharacterSystems Create(int maxPartySize, PerkRegistry perkRegistry, CharacterRegistry characterRegistry) { + IPerkFactory perkFactory = new PerkFactory(perkRegistry); + ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(characterRegistry); + ICharacterStatsFactory statsFactory = new CharacterStatsFactory(); + ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory); + IPartyFactory partyFactory = new PartyFactory(new PartyFactoryOptions { + minPartySize = 1, + maxPartySize = maxPartySize, + enforceUniqueCharacterIds = true + }); + + return new CharacterSystems(perkFactory, characterFactory, partyFactory); + } + } +} diff --git a/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs.meta b/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs.meta new file mode 100644 index 0000000..dcb332e --- /dev/null +++ b/Assets/Code/GameState/Entities/DefaultCharacterSystemsFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 60db4014b69d403db42ee766204eb2d7 +timeCreated: 1774183978 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs b/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs new file mode 100644 index 0000000..a8784f3 --- /dev/null +++ b/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +namespace Nox.Game { + [CreateAssetMenu(fileName = "EntitiesBaseSettings", menuName = "Nox/Database/Entities/EntitiesBaseSettings")] + public class EntitiesBaseSettings: ScriptableObject { + [Header("Character Creation")] + public int startAttributesPool = 12; + public int startLevel = 1; + + public RacialBonus [] racialBonuses; + } + + public class RacialBonus { + public CharacterRace race; + public CharacterClass characterClass; + public int bonus; + } +} diff --git a/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs.meta b/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs.meta new file mode 100644 index 0000000..c26b857 --- /dev/null +++ b/Assets/Code/GameState/Entities/EntitiesBaseSettings.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1bbecc15c7cd4a7ca90ce17b3d3d75f0 +timeCreated: 1774184829 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/EntitiesDefinitions.cs b/Assets/Code/GameState/Entities/EntitiesDefinitions.cs new file mode 100644 index 0000000..5bbcd86 --- /dev/null +++ b/Assets/Code/GameState/Entities/EntitiesDefinitions.cs @@ -0,0 +1,130 @@ +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 CharacterRole { + None, + Protagonist, + Companion + } + + public enum CharacterClass { + None, + Warrior, + Rogue, + Mage, + Herald + } + + public enum CharacterRace { + None, + Human, + DarkElf, + Tunneler + } + + [Serializable] + public sealed class EntityAttributes { + public int might; + public int reflex; + public int knowledge; + public int perception; + + public int Total => might + reflex + knowledge; + } + + [Serializable] + public sealed class EntityStats { + public int health; + public int stamina; + public int level; + public int experience; + } + + [Serializable] + public sealed class PerkDefinition { + public string id; + public string name; + public ModifiersData modifiers = new (); + } + + [Serializable] + public sealed class PerksData { + public List perks = new (); + } + + [Serializable] + public sealed class CharacterDefinition : IEntityDefinition { + [SerializeField] private string id; + [SerializeField] private string displayName; + public CharacterRace race; + public CharacterClass @class; + public CharacterRole role; + [SerializeField] EntityAttributes attributes; + [SerializeField] 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 { + might = attributes?.might ?? 1, + reflex = attributes?.reflex ?? 1, + knowledge = attributes?.knowledge ?? 1 + }, + stats = new EntityStats { + health = stats?.health ?? 1, + stamina = stats?.stamina ?? 1 + }, + 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 List members = new(); + public int maxPartySize; + + [JsonIgnore] + public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist); + + [JsonIgnore] + public IReadOnlyList Companions => members.Where(m => m.role == CharacterRole.Companion).ToList(); + } +} diff --git a/Assets/Code/GameState/Entities/IEntity.cs.meta b/Assets/Code/GameState/Entities/EntitiesDefinitions.cs.meta similarity index 100% rename from Assets/Code/GameState/Entities/IEntity.cs.meta rename to Assets/Code/GameState/Entities/EntitiesDefinitions.cs.meta diff --git a/Assets/Code/GameState/Entities/IEntity.cs b/Assets/Code/GameState/Entities/IEntity.cs deleted file mode 100644 index 9a5ca6b..0000000 --- a/Assets/Code/GameState/Entities/IEntity.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace v { - public interface IEntity { - - } -} diff --git a/Assets/Code/GameState/Entities/ModifiersHandler.cs b/Assets/Code/GameState/Entities/ModifiersHandler.cs new file mode 100644 index 0000000..a10c664 --- /dev/null +++ b/Assets/Code/GameState/Entities/ModifiersHandler.cs @@ -0,0 +1,31 @@ +using System; + +namespace Nox.Game { + + public enum ModifierType { + None, + Flat, + Addition, + Multiplication, + Percentage + } + + [Serializable] + public sealed class Modifier { + public string id; + public ModifierType type; + public float value; + } + + [Serializable] + public sealed class ModifiersData { + public Modifier[] modifiers; + } + + public class ModifiersHandler { + private readonly ModifiersData modifiersData; + public ModifiersHandler(ModifiersData modifiersData) { + this.modifiersData = modifiersData; + } + } +} diff --git a/Assets/Code/GameState/Entities/ModifiersHandler.cs.meta b/Assets/Code/GameState/Entities/ModifiersHandler.cs.meta new file mode 100644 index 0000000..e4ec4f8 --- /dev/null +++ b/Assets/Code/GameState/Entities/ModifiersHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 130a7ebdbcf2417392d8fc3f9ae76eb2 +timeCreated: 1774176049 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/PartyCreatorModel.cs b/Assets/Code/GameState/Entities/PartyCreatorModel.cs index 6315286..197b790 100644 --- a/Assets/Code/GameState/Entities/PartyCreatorModel.cs +++ b/Assets/Code/GameState/Entities/PartyCreatorModel.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + namespace Nox.Game { public class PartyCreatorModel { private readonly ICharacterFactory characterFactory; @@ -6,50 +8,60 @@ namespace Nox.Game { this.characterFactory = characterFactory; this.partyFactory = partyFactory; } - public PartyData CreatePartyForNewRun(int companionCount) { + public PartyDefinition CreatePartyForNewRun(int companionCount) { var protagonist = characterFactory.CreateCustomProtagonist(new CustomCharacterCreationRequest { id = "protagonist", displayName = "The Warden", - mightPoints = 4, - reflexPoints = 3, - knowledgePoints = 3, - startingPerkIds = new System.Collections.Generic.List { "iron-will" } + attributes = new EntityAttributes(), + perksData = new PerksData(){ + perks = new List() + } }); CharacterTemplate[] companionTemplates = { new() { id = "companion-bruiser", displayName = "Rook", - attributes = new CharacterAttributes { might = 5, reflex = 2, knowledge = 1 }, - startingPerkIds = new System.Collections.Generic.List { "steadfast" } + attributes = new EntityAttributes { might = 5, reflex = 2, knowledge = 1 }, + perksData = new PerksData(){ + perks = new List() + } }, new() { id = "companion-scout", displayName = "Sable", - attributes = new CharacterAttributes { might = 2, reflex = 5, knowledge = 1 }, - startingPerkIds = new System.Collections.Generic.List { "nimble-step" } + attributes = new EntityAttributes { might = 2, reflex = 5, knowledge = 1 }, + perksData = new PerksData(){ + perks = new List() + } }, new() { id = "companion-scholar", displayName = "Quill", - attributes = new CharacterAttributes { might = 1, reflex = 2, knowledge = 5 }, - startingPerkIds = new System.Collections.Generic.List { "lorekeeper" } + attributes = new EntityAttributes { might = 1, reflex = 2, knowledge = 5 }, + perksData = new PerksData(){ + perks = new List() + } }, new() { id = "companion-vanguard", displayName = "Brant", - attributes = new CharacterAttributes { might = 4, reflex = 3, knowledge = 2 }, - startingPerkIds = new System.Collections.Generic.List { "bulwark" } + attributes = new EntityAttributes { might = 4, reflex = 3, knowledge = 2 }, + perksData = new PerksData(){ + perks = new List() + } }, new() { id = "companion-tracker", displayName = "Mira", - attributes = new CharacterAttributes { might = 2, reflex = 4, knowledge = 3 }, - startingPerkIds = new System.Collections.Generic.List { "pathfinder" } + attributes = new EntityAttributes { might = 2, reflex = 4, knowledge = 3 }, + perksData = new PerksData(){ + perks = new List() + } } }; - var companions = new System.Collections.Generic.List(); + var companions = new List(); for(var i = 0; i < companionCount && i < companionTemplates.Length; i++) { companions.Add(characterFactory.CreateFromTemplate(companionTemplates[i], CharacterRole.Companion)); } diff --git a/Assets/Code/GameState/Entities/PartyFactory.cs b/Assets/Code/GameState/Entities/PartyFactory.cs new file mode 100644 index 0000000..984cd70 --- /dev/null +++ b/Assets/Code/GameState/Entities/PartyFactory.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Nox.Game { + public interface IPartyFactory { + PartyDefinition Create(CharacterDefinition protagonist, IEnumerable companions = null); + } + + public sealed class PartyFactoryOptions { + public int minPartySize = 1; + public int maxPartySize = 4; + public bool enforceUniqueCharacterIds = true; + } + + public sealed class PartyFactory : IPartyFactory { + private readonly PartyFactoryOptions options; + + public PartyFactory(PartyFactoryOptions options = null) { + this.options = options ?? new PartyFactoryOptions(); + } + + public PartyDefinition Create(CharacterDefinition protagonist, IEnumerable companions = null) { + if(protagonist == null) { + throw new ArgumentNullException(nameof(protagonist)); + } + + PartyDefinition party = new PartyDefinition { + maxPartySize = options.maxPartySize <= 0 ? int.MaxValue : options.maxPartySize + }; + + CharacterDefinition protagonistClone = protagonist.Clone(); + protagonistClone.role = CharacterRole.Protagonist; + party.members.Add(protagonistClone); + + if(companions != null) { + foreach(CharacterDefinition companion in companions.Where(c => c != null)) { + CharacterDefinition companionClone = companion.Clone(); + companionClone.role = CharacterRole.Companion; + party.members.Add(companionClone); + } + } + + ValidateParty(party); + return party; + } + + private void ValidateParty(PartyDefinition party) { + if(party.members.Count < options.minPartySize) { + throw new ArgumentException($"Party size {party.members.Count} is below minimum {options.minPartySize}."); + } + + if(party.members.Count > party.maxPartySize) { + throw new ArgumentException($"Party size {party.members.Count} exceeds max {party.maxPartySize}."); + } + + int protagonistCount = party.members.Count(m => m.role == CharacterRole.Protagonist); + if(protagonistCount != 1) { + throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}."); + } + + if(options.enforceUniqueCharacterIds) { + int uniqueIds = party.members + .Where(m => !string.IsNullOrWhiteSpace(m.ID)) + .Select(m => m.ID) + .Distinct() + .Count(); + if(uniqueIds != party.members.Count) { + throw new ArgumentException("Party contains duplicate or missing character ids."); + } + } + } + } +} diff --git a/Assets/Code/GameState/Entities/PartyFactory.cs.meta b/Assets/Code/GameState/Entities/PartyFactory.cs.meta new file mode 100644 index 0000000..f7a5a83 --- /dev/null +++ b/Assets/Code/GameState/Entities/PartyFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f54ae3aaf9da4f5eaeb6d1cafe83a74f +timeCreated: 1774183779 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/PerkFactory.cs b/Assets/Code/GameState/Entities/PerkFactory.cs new file mode 100644 index 0000000..77a51da --- /dev/null +++ b/Assets/Code/GameState/Entities/PerkFactory.cs @@ -0,0 +1,73 @@ +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(PerkRegistry perkRegistry) { + if(perkRegistry == null) { + throw new ArgumentNullException(nameof(perkRegistry)); + } + var allAvailablePerks = perkRegistry.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; + } + } +} diff --git a/Assets/Code/GameState/Entities/PerkFactory.cs.meta b/Assets/Code/GameState/Entities/PerkFactory.cs.meta new file mode 100644 index 0000000..54283a8 --- /dev/null +++ b/Assets/Code/GameState/Entities/PerkFactory.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1de2461f550e4ef8a324d5746222898f +timeCreated: 1774183789 \ No newline at end of file diff --git a/Assets/Code/GameState/Entities/PerkRegistry.cs b/Assets/Code/GameState/Entities/PerkRegistry.cs new file mode 100644 index 0000000..bec3cc1 --- /dev/null +++ b/Assets/Code/GameState/Entities/PerkRegistry.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace Nox.Game { + [CreateAssetMenu(fileName = "PerksRegistry", menuName = "Nox/Database/Entities/Perks Registry")] + public class PerkRegistry : ScriptableObject { + public PerksData perksData; + } +} diff --git a/Assets/Code/GameState/Entities/PerkRegistry.cs.meta b/Assets/Code/GameState/Entities/PerkRegistry.cs.meta new file mode 100644 index 0000000..e0493a5 --- /dev/null +++ b/Assets/Code/GameState/Entities/PerkRegistry.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0adb42b13ce44d8792247246a49e9c3f +timeCreated: 1774179294 \ No newline at end of file diff --git a/Assets/Code/GameState/NoxSaveData.cs b/Assets/Code/GameState/NoxSaveData.cs index 35d236a..53919bb 100644 --- a/Assets/Code/GameState/NoxSaveData.cs +++ b/Assets/Code/GameState/NoxSaveData.cs @@ -33,7 +33,7 @@ namespace Nox.Game { gameDataState.activeSessionId = latestSession.sessionId; gameDataState.savedPartyPosition = saveData.partyPosition.ToVector3(); - gameDataState.ActiveParty = saveData.partyData; + gameDataState.ActiveParty = saveData.partyDefinition; adventureData = saveData.adventureData; return saveData; @@ -53,7 +53,7 @@ namespace Nox.Game { public AdventureData adventureData; // Party - public PartyData partyData; + public PartyDefinition partyDefinition; public SerializableVector3 partyPosition; } diff --git a/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs b/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs index 736d5a4..3b60f78 100644 --- a/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs +++ b/Assets/Code/GameState/PlayModes/AdventurePlayMode.cs @@ -22,7 +22,7 @@ namespace Nox.Game { private readonly PlayModeSettings bootstrapSettings; private readonly GameDataState gameDataState; private readonly ISaveSystem saveSystem; - private PartyData partyData; + private PartyDefinition partyDefinition; private AdventureData adventureData; private AdventureModePrefabs scenePrefabs; private ICameraController cameraController; @@ -40,14 +40,14 @@ namespace Nox.Game { public AdventurePlayMode( PlatformSettings platformSettings, - PartyData partyData, + PartyDefinition partyDefinition, PlayModeSettings bootstrapSettings, GameDataState gameDataState, ISaveSystem saveSystem, AdventureSettings adventureSettings, AdventureData adventureData) { this.platformSettings = platformSettings; - this.partyData = partyData; + this.partyDefinition = partyDefinition; this.bootstrapSettings = bootstrapSettings; this.gameDataState = gameDataState; this.saveSystem = saveSystem; @@ -73,7 +73,7 @@ namespace Nox.Game { inputActions.Player.Enable(); inputActions.UI.PauseMenu.Enable(); Debug.Log("Entering Adventure Play Mode"); - if(partyData == null) { + if(partyDefinition == null) { var sessions = saveSystem.GetAllSessions().OrderByDescending(s => s.lastSaveDateUtc).ToList(); if(sessions.Count == 0) { return; @@ -156,7 +156,7 @@ namespace Nox.Game { public NoxSavedDataSet CaptureNoxSaveData() { return new NoxSavedDataSet { activePlayMode = PlayMode.Adventure, - partyData = partyData, + partyDefinition = partyDefinition, partyPosition = partyRef ? SerializableVector3.FromVector3(partyRef.transform.position) : SerializableVector3.Zero }; } diff --git a/Assets/Code/GameState/PlayModes/CombatPlayMode.cs b/Assets/Code/GameState/PlayModes/CombatPlayMode.cs index 0a92467..94ade46 100644 --- a/Assets/Code/GameState/PlayModes/CombatPlayMode.cs +++ b/Assets/Code/GameState/PlayModes/CombatPlayMode.cs @@ -5,17 +5,17 @@ using UnityEngine; namespace Nox.Game { public class CombatPlayMode : IPlayMode { private readonly PlatformSettings platformSettings; - private readonly PartyData partyData; + private readonly PartyDefinition partyDefinition; - public CombatPlayMode(PlatformSettings platformSettings, PartyData partyData) { + public CombatPlayMode(PlatformSettings platformSettings, PartyDefinition partyDefinition) { this.platformSettings = platformSettings; - this.partyData = partyData; + this.partyDefinition = partyDefinition; } public bool IsGameModeInitialized { get; private set; } public void EnterPlayMode() { - if(partyData == null) { + if(partyDefinition == null) { Debug.LogWarning("CombatPlayMode started without PartyData."); } diff --git a/Assets/Code/GameState/PlayModes/RestPlayMode.cs b/Assets/Code/GameState/PlayModes/RestPlayMode.cs index e9154af..eb82104 100644 --- a/Assets/Code/GameState/PlayModes/RestPlayMode.cs +++ b/Assets/Code/GameState/PlayModes/RestPlayMode.cs @@ -5,17 +5,17 @@ using UnityEngine; namespace Nox.Game { public class RestPlayMode : IPlayMode { private readonly PlatformSettings platformSettings; - private readonly PartyData partyData; + private readonly PartyDefinition partyDefinition; - public RestPlayMode(PlatformSettings platformSettings, PartyData partyData) { + public RestPlayMode(PlatformSettings platformSettings, PartyDefinition partyDefinition) { this.platformSettings = platformSettings; - this.partyData = partyData; + this.partyDefinition = partyDefinition; } public bool IsGameModeInitialized { get; private set; } public void EnterPlayMode() { - if(partyData == null) { + if(partyDefinition == null) { Debug.LogWarning("RestPlayMode started without PartyData."); } diff --git a/Assets/Code/GameState/PlayModes/TownPlayMode.cs b/Assets/Code/GameState/PlayModes/TownPlayMode.cs index 1bb446a..e220bd9 100644 --- a/Assets/Code/GameState/PlayModes/TownPlayMode.cs +++ b/Assets/Code/GameState/PlayModes/TownPlayMode.cs @@ -5,17 +5,17 @@ using UnityEngine; namespace Nox.Game { public class TownPlayMode : IPlayMode { private readonly PlatformSettings platformSettings; - private readonly PartyData partyData; + private readonly PartyDefinition partyDefinition; - public TownPlayMode(PlatformSettings platformSettings, PartyData partyData) { + public TownPlayMode(PlatformSettings platformSettings, PartyDefinition partyDefinition) { this.platformSettings = platformSettings; - this.partyData = partyData; + this.partyDefinition = partyDefinition; } public bool IsGameModeInitialized { get; private set; } public void EnterPlayMode() { - if(partyData == null) { + if(partyDefinition == null) { Debug.LogWarning("TownPlayMode started without PartyData."); } diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 705b44e..1eb63ea 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,5 +1,11 @@ { "dependencies": { + "ayellowpaper.serialized-dictionary": { + "version": "file:SerializedDictionary-main", + "depth": 0, + "source": "embedded", + "dependencies": {} + }, "com.jovian.savesystem": { "version": "file:com.jovian.savesystem", "depth": 0,