forked from Shardstone/trail-into-darkness
137 lines
5.9 KiB
C#
137 lines
5.9 KiB
C#
using System;
|
|
using ZLinq;
|
|
|
|
namespace Nox.Game {
|
|
public interface ICharacterFactory {
|
|
CharacterDefinition CreateProtagonist(CharacterCreationRequest request);
|
|
CharacterDefinition CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion);
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class CharacterTemplate : IEntityDefinition {
|
|
public Guid Id { get; set; } = Guid.NewGuid();
|
|
public string Name { get; set; } = "New Character";
|
|
public CharacterRace Race { get; set; } = (CharacterRace)GetRandomInt(1, Enum.GetValues(typeof(CharacterRace)).Length-1);
|
|
public CharacterClass Class { get; set; } = (CharacterClass)GetRandomInt(1, Enum.GetValues(typeof(CharacterClass)).Length-1);
|
|
public CharacterRole Role { get; set; } = CharacterRole.Companion;
|
|
public EntityAttributes Attributes { get; set; } = GetDefaultAttributes();
|
|
public EntityStats Stats { get; set; } = new() { stats = Array.Empty<Stat>() };
|
|
public PerksData Perks { get; set; } = new();
|
|
public ModifiersData Modifiers { get; set; } = new();
|
|
|
|
private static int GetRandomInt(int start, int end) => new Random().Next(start, end);
|
|
private static EntityAttributes GetDefaultAttributes() {
|
|
var attributes = new EntityAttributes {
|
|
attributes = new Attribute[] {
|
|
new (AttributeType.Might, 1),
|
|
new (AttributeType.Knowledge, 1),
|
|
new (AttributeType.Perception, 1),
|
|
new (AttributeType.Reflex, 1)
|
|
}
|
|
};
|
|
|
|
return attributes;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public sealed class CharacterCreationRequest : IEntityDefinition {
|
|
public Guid Id { get; set; } = Guid.Empty;
|
|
public string Name { get; set; }
|
|
public CharacterRace Race { get; set; }
|
|
public CharacterClass Class { get; set; }
|
|
public CharacterRole Role { get; set; } = CharacterRole.Protagonist;
|
|
public EntityAttributes Attributes { get; set; }
|
|
public EntityStats Stats { get; set; } = new() { stats = Array.Empty<Stat>() };
|
|
public PerksData Perks { get; set; } = new();
|
|
public ModifiersData Modifiers { get; set; } = new();
|
|
}
|
|
|
|
public sealed class CharacterFactory : ICharacterFactory {
|
|
private readonly ICharacterAttributesFactory attributesFactory;
|
|
private readonly ICharacterStatsFactory statsFactory;
|
|
private readonly IPerkFactory perkFactory;
|
|
private readonly IModifiersFactory modifiersFactory;
|
|
|
|
public CharacterFactory(
|
|
ICharacterAttributesFactory attributesFactory,
|
|
ICharacterStatsFactory statsFactory,
|
|
IPerkFactory perkFactory,
|
|
IModifiersFactory modifiersFactory) {
|
|
this.attributesFactory = attributesFactory ?? throw new ArgumentNullException(nameof(attributesFactory));
|
|
this.statsFactory = statsFactory ?? throw new ArgumentNullException(nameof(statsFactory));
|
|
this.perkFactory = perkFactory ?? throw new ArgumentNullException(nameof(perkFactory));
|
|
this.modifiersFactory = modifiersFactory ?? throw new ArgumentNullException(nameof(modifiersFactory));
|
|
}
|
|
|
|
public CharacterDefinition CreateProtagonist(CharacterCreationRequest request) {
|
|
if(request == null) {
|
|
throw new ArgumentNullException(nameof(request));
|
|
}
|
|
|
|
var attributes = attributesFactory.Create(request);
|
|
var stats = statsFactory.Create(request);
|
|
|
|
var character = new CharacterDefinition {
|
|
Id = request.Id == Guid.Empty ? Guid.NewGuid() : request.Id,
|
|
Name = request.Name,
|
|
Race = request.Race,
|
|
Class = request.Class,
|
|
Role = CharacterRole.Protagonist,
|
|
Attributes = attributes,
|
|
Stats = stats,
|
|
Perks = request.Perks ?? new PerksData(),
|
|
Modifiers = request.Modifiers ?? new ModifiersData()
|
|
};
|
|
|
|
AddStartingPerks(character, request.Perks);
|
|
return character;
|
|
}
|
|
|
|
public CharacterDefinition CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion) {
|
|
if(template == null) {
|
|
throw new ArgumentNullException(nameof(template));
|
|
}
|
|
|
|
template.Perks ??= new PerksData();
|
|
template.Modifiers ??= new ModifiersData();
|
|
|
|
var character = new CharacterDefinition {
|
|
Id = template.Id == Guid.Empty ? Guid.NewGuid() : template.Id,
|
|
Name = template.Name,
|
|
Race = template.Race,
|
|
Class = template.Class,
|
|
Role = role,
|
|
Attributes = attributesFactory.Create(template),
|
|
Stats = statsFactory.Create(template),
|
|
Perks = template.Perks,
|
|
Modifiers = template.Modifiers
|
|
};
|
|
|
|
AddStartingPerks(character, template.Perks);
|
|
AddStartingModifiers(character, template.Modifiers);
|
|
return character;
|
|
}
|
|
|
|
private void AddStartingPerks(CharacterDefinition character, PerksData perkData) {
|
|
if(perkData?.perks == null || perkData.perks.Count == 0) {
|
|
return;
|
|
}
|
|
|
|
foreach(var perkId in perkData.perks.AsValueEnumerable().Distinct()) {
|
|
perkFactory.TryAddPerk(character, perkId.Id);
|
|
}
|
|
}
|
|
|
|
private void AddStartingModifiers(CharacterDefinition character, ModifiersData modifiersData) {
|
|
if(modifiersData?.modifiers == null || modifiersData.modifiers.Count == 0) {
|
|
return;
|
|
}
|
|
|
|
foreach(var modifierId in modifiersData.modifiers.AsValueEnumerable().Distinct()) {
|
|
modifiersFactory.TryAddModifier(character, modifierId.Id);
|
|
}
|
|
}
|
|
}
|
|
}
|