factored the character system - not funtional yet

This commit is contained in:
Sebastian Bularca
2026-03-22 14:46:19 +01:00
parent 00bb430a7f
commit 0f0189726e
36 changed files with 639 additions and 513 deletions

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Nox.Game {
public interface IPartyFactory {
PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> 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<CharacterDefinition> 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.");
}
}
}
}
}