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 ModifiersData modifiersData = 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 stats = statsFactory.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 = stats, perksData = request.perksData ?? new PerksData(), activeModifiers = request.modifiersData ?? 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); } } } }