forked from Shardstone/trail-into-darkness
63 lines
2.4 KiB
C#
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 StarterCharacterSettings starterCharacterSettings;
|
|
|
|
public PartyFactory(StarterCharacterSettings starterCharacterSettings) {
|
|
this.starterCharacterSettings = starterCharacterSettings;
|
|
}
|
|
|
|
public PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> companions = null) {
|
|
if(protagonist == null) {
|
|
throw new ArgumentNullException(nameof(protagonist));
|
|
}
|
|
|
|
var party = new PartyDefinition {
|
|
maxPartySize = starterCharacterSettings.maxPartySize <= 0 ? int.MaxValue : starterCharacterSettings.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.");
|
|
}
|
|
}
|
|
}
|
|
}
|