Files
trail-into-darkness/Assets/Code/GameState/Entities/PartyFactory.cs

63 lines
2.4 KiB
C#

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 PartyFactory : IPartyFactory {
private readonly CharacterBaseSettings characterBaseSettings;
public PartyFactory(CharacterBaseSettings characterBaseSettings) {
this.characterBaseSettings = characterBaseSettings;
}
public PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> companions = null) {
if(protagonist == null) {
throw new ArgumentNullException(nameof(protagonist));
}
var party = new PartyDefinition {
maxPartySize = characterBaseSettings.maxPartySize <= 0 ? int.MaxValue : characterBaseSettings.maxPartySize
};
var protagonistClone = protagonist.Clone();
protagonistClone.role = CharacterRole.Protagonist;
party.members.Add(protagonistClone);
if(companions != null) {
foreach(var companion in companions.Where(c => c != null)) {
var companionClone = companion.Clone();
companionClone.role = CharacterRole.Companion;
party.members.Add(companionClone);
}
}
ValidateParty(party);
return party;
}
private void ValidateParty(PartyDefinition party) {
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}.");
}
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.");
}
}
}
}