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

65 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using ZLinq;
namespace Nox.Game {
public interface IPartyFactory {
PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> companions = null);
}
public sealed class PartyFactory : IPartyFactory {
private readonly PartySettings partySettings;
private readonly StarterCharacterSettings starterCharacterSettings;
public PartyFactory(PartySettings partySettings, StarterCharacterSettings starterCharacterSettings) {
this.partySettings = partySettings;
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 = partySettings.maxPartySize <= 0 ? int.MaxValue : partySettings.maxPartySize
};
var protagonistClone = protagonist.Clone();
protagonistClone.Role = CharacterRole.Protagonist;
party.members.Add(protagonistClone);
if(companions != null) {
foreach(var companion in companions.AsValueEnumerable().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}.");
}
var protagonistCount = party.members.AsValueEnumerable().Count(m => m.Role == CharacterRole.Protagonist);
if(protagonistCount != 1) {
throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}.");
}
var uniqueIds = party.members.AsValueEnumerable()
.Where(m => m.Id != Guid.Empty)
.Select(m => m.Id)
.Distinct()
.Count();
if(uniqueIds != party.members.Count) {
throw new ArgumentException("Party contains duplicate or missing character ids.");
}
}
}
}