First commit
This commit is contained in:
64
Assets/Code/GameState/Entities/PartyFactory.cs
Normal file
64
Assets/Code/GameState/Entities/PartyFactory.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user