forked from Shardstone/trail-into-darkness
First commit on my server, yey!
This commit is contained in:
469
Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs
Normal file
469
Assets/Code/GameState/Entities/CharacterAndPartyFactories.cs
Normal file
@@ -0,0 +1,469 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Nox.Game {
|
||||
public enum CharacterRole {
|
||||
Protagonist,
|
||||
Companion
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterAttributes {
|
||||
public int might;
|
||||
public int reflex;
|
||||
public int knowledge;
|
||||
|
||||
public int Total => might + reflex + knowledge;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterStats {
|
||||
public int maxHealth;
|
||||
public int maxStamina;
|
||||
public float dodgeStaminaLossMultiplier;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class PerkDefinition {
|
||||
public string id;
|
||||
public string name;
|
||||
public string mechanicalBonus;
|
||||
public string thematicPenalty;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterData {
|
||||
public string id;
|
||||
public string displayName;
|
||||
public CharacterRole role;
|
||||
public int level;
|
||||
public int experience;
|
||||
public CharacterAttributes attributes;
|
||||
public CharacterStats stats;
|
||||
public List<PerkDefinition> perks = new List<PerkDefinition>();
|
||||
|
||||
public CharacterData Clone() {
|
||||
return new CharacterData {
|
||||
id = id,
|
||||
displayName = displayName,
|
||||
role = role,
|
||||
level = level,
|
||||
experience = experience,
|
||||
attributes = new CharacterAttributes {
|
||||
might = attributes?.might ?? 0,
|
||||
reflex = attributes?.reflex ?? 0,
|
||||
knowledge = attributes?.knowledge ?? 0
|
||||
},
|
||||
stats = new CharacterStats {
|
||||
maxHealth = stats?.maxHealth ?? 0,
|
||||
maxStamina = stats?.maxStamina ?? 0,
|
||||
dodgeStaminaLossMultiplier = stats?.dodgeStaminaLossMultiplier ?? 1f
|
||||
},
|
||||
perks = perks.Select(p => new PerkDefinition {
|
||||
id = p.id,
|
||||
name = p.name,
|
||||
mechanicalBonus = p.mechanicalBonus,
|
||||
thematicPenalty = p.thematicPenalty
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterTemplate {
|
||||
public string id;
|
||||
public string displayName;
|
||||
public CharacterAttributes attributes;
|
||||
public int level = 1;
|
||||
public int experience;
|
||||
public List<string> startingPerkIds = new List<string>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CustomCharacterCreationRequest {
|
||||
public string id;
|
||||
public string displayName;
|
||||
public int mightPoints;
|
||||
public int reflexPoints;
|
||||
public int knowledgePoints;
|
||||
public List<string> startingPerkIds = new List<string>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class PartyData {
|
||||
public List<CharacterData> members = new List<CharacterData>();
|
||||
public int maxPartySize;
|
||||
|
||||
[JsonIgnore]
|
||||
public CharacterData Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist);
|
||||
[JsonIgnore]
|
||||
public IReadOnlyList<CharacterData> Companions => members.Where(m => m.role == CharacterRole.Companion).ToList();
|
||||
}
|
||||
|
||||
public interface ICharacterAttributesFactory {
|
||||
CharacterAttributes Create(int might, int reflex, int knowledge);
|
||||
CharacterAttributes CreateFromPointAllocation(int mightPoints, int reflexPoints, int knowledgePoints);
|
||||
}
|
||||
|
||||
public interface ICharacterStatsFactory {
|
||||
CharacterStats Create(CharacterAttributes attributes);
|
||||
}
|
||||
|
||||
public interface IPerkFactory {
|
||||
IReadOnlyCollection<PerkDefinition> GetAll();
|
||||
PerkDefinition GetById(string perkId);
|
||||
IReadOnlyCollection<PerkDefinition> GetAvailableFor(CharacterData character);
|
||||
bool TryAddPerk(CharacterData character, string perkId);
|
||||
}
|
||||
|
||||
public interface ICharacterFactory {
|
||||
CharacterData CreateCustomProtagonist(CustomCharacterCreationRequest request);
|
||||
CharacterData CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion);
|
||||
}
|
||||
|
||||
public interface IPartyFactory {
|
||||
PartyData Create(CharacterData protagonist, IEnumerable<CharacterData> companions = null);
|
||||
}
|
||||
|
||||
public interface ICharacterSystems {
|
||||
IPerkFactory PerkFactory { get; }
|
||||
ICharacterFactory CharacterFactory { get; }
|
||||
IPartyFactory PartyFactory { get; }
|
||||
}
|
||||
|
||||
public sealed class CharacterFactoryOptions {
|
||||
public int baseMight = 1;
|
||||
public int baseReflex = 1;
|
||||
public int baseKnowledge = 1;
|
||||
public int customAttributePointBudget = 10;
|
||||
public int startingLevel = 1;
|
||||
}
|
||||
|
||||
public sealed class CharacterStatsFactoryOptions {
|
||||
public int baseHealth = 10;
|
||||
public int baseStamina = 5;
|
||||
public int mightHealthBonus = 3;
|
||||
public int mightStaminaBonus = 1;
|
||||
public int knowledgeStaminaBonus = 2;
|
||||
public float baseDodgeStaminaLossMultiplier = 1f;
|
||||
public float reflexDodgeStaminaLossReduction = 0.03f;
|
||||
public float minDodgeStaminaLossMultiplier = 0.4f;
|
||||
}
|
||||
|
||||
public sealed class PartyFactoryOptions {
|
||||
public int minPartySize = 1;
|
||||
public int maxPartySize = 4;
|
||||
public bool enforceUniqueCharacterIds = true;
|
||||
}
|
||||
|
||||
public sealed class CharacterSystems : ICharacterSystems {
|
||||
public CharacterSystems(IPerkFactory perkFactory, ICharacterFactory characterFactory, IPartyFactory partyFactory) {
|
||||
PerkFactory = perkFactory;
|
||||
CharacterFactory = characterFactory;
|
||||
PartyFactory = partyFactory;
|
||||
}
|
||||
|
||||
public IPerkFactory PerkFactory { get; }
|
||||
public ICharacterFactory CharacterFactory { get; }
|
||||
public IPartyFactory PartyFactory { get; }
|
||||
}
|
||||
|
||||
public static class DefaultCharacterSystemsFactory {
|
||||
public static ICharacterSystems Create(int maxPartySize = 8) {
|
||||
IPerkFactory perkFactory = new PerkFactory(CreateDefaultPerks());
|
||||
ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(new CharacterFactoryOptions {
|
||||
baseMight = 1,
|
||||
baseReflex = 1,
|
||||
baseKnowledge = 1,
|
||||
customAttributePointBudget = 10,
|
||||
startingLevel = 1
|
||||
});
|
||||
ICharacterStatsFactory statsFactory = new CharacterStatsFactory();
|
||||
ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory);
|
||||
IPartyFactory partyFactory = new PartyFactory(new PartyFactoryOptions {
|
||||
minPartySize = 1,
|
||||
maxPartySize = maxPartySize,
|
||||
enforceUniqueCharacterIds = true
|
||||
});
|
||||
|
||||
return new CharacterSystems(perkFactory, characterFactory, partyFactory);
|
||||
}
|
||||
|
||||
private static IEnumerable<PerkDefinition> CreateDefaultPerks() {
|
||||
return new[] {
|
||||
new PerkDefinition { id = "iron-will", name = "Iron Will", mechanicalBonus = "+1 max health per level", thematicPenalty = "-1 social flexibility in dialogue checks" },
|
||||
new PerkDefinition { id = "steadfast", name = "Steadfast", mechanicalBonus = "-10% stamina loss when bracing", thematicPenalty = "-10% movement speed in retreat events" },
|
||||
new PerkDefinition { id = "nimble-step", name = "Nimble Step", mechanicalBonus = "-15% dodge stamina loss", thematicPenalty = "+10% stamina loss on heavy actions" },
|
||||
new PerkDefinition { id = "lorekeeper", name = "Lorekeeper", mechanicalBonus = "+15% knowledge event success", thematicPenalty = "-10% intimidation success chance" },
|
||||
new PerkDefinition { id = "bulwark", name = "Bulwark", mechanicalBonus = "+2 base defense checks", thematicPenalty = "-1 reflex in stealth checks" },
|
||||
new PerkDefinition { id = "pathfinder", name = "Pathfinder", mechanicalBonus = "+15% scouting event success", thematicPenalty = "-1 max health during ambush events" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CharacterAttributesFactory : ICharacterAttributesFactory {
|
||||
private readonly CharacterFactoryOptions options;
|
||||
|
||||
public CharacterAttributesFactory(CharacterFactoryOptions options = null) {
|
||||
this.options = options ?? new CharacterFactoryOptions();
|
||||
}
|
||||
|
||||
public CharacterAttributes Create(int might, int reflex, int knowledge) {
|
||||
if(might < 0 || reflex < 0 || knowledge < 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(might), "attributes cannot be negative.");
|
||||
}
|
||||
|
||||
return new CharacterAttributes {
|
||||
might = might,
|
||||
reflex = reflex,
|
||||
knowledge = knowledge
|
||||
};
|
||||
}
|
||||
|
||||
public CharacterAttributes CreateFromPointAllocation(int mightPoints, int reflexPoints, int knowledgePoints) {
|
||||
if(mightPoints < 0 || reflexPoints < 0 || knowledgePoints < 0) {
|
||||
throw new ArgumentOutOfRangeException(nameof(mightPoints), "Point allocation cannot be negative.");
|
||||
}
|
||||
|
||||
int allocated = mightPoints + reflexPoints + knowledgePoints;
|
||||
if(allocated > options.customAttributePointBudget) {
|
||||
throw new ArgumentException($"Allocated {allocated} points but budget is {options.customAttributePointBudget}.");
|
||||
}
|
||||
|
||||
return new CharacterAttributes {
|
||||
might = options.baseMight + mightPoints,
|
||||
reflex = options.baseReflex + reflexPoints,
|
||||
knowledge = options.baseKnowledge + knowledgePoints
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CharacterStatsFactory : ICharacterStatsFactory {
|
||||
private readonly CharacterStatsFactoryOptions options;
|
||||
|
||||
public CharacterStatsFactory(CharacterStatsFactoryOptions options = null) {
|
||||
this.options = options ?? new CharacterStatsFactoryOptions();
|
||||
}
|
||||
|
||||
public CharacterStats Create(CharacterAttributes attributes) {
|
||||
if(attributes == null) {
|
||||
throw new ArgumentNullException(nameof(attributes));
|
||||
}
|
||||
|
||||
int maxHealth = options.baseHealth + attributes.might * options.mightHealthBonus;
|
||||
int maxStamina = options.baseStamina +
|
||||
attributes.might * options.mightStaminaBonus +
|
||||
attributes.knowledge * options.knowledgeStaminaBonus;
|
||||
float dodgeMultiplier = options.baseDodgeStaminaLossMultiplier -
|
||||
attributes.reflex * options.reflexDodgeStaminaLossReduction;
|
||||
dodgeMultiplier = Math.Max(options.minDodgeStaminaLossMultiplier, dodgeMultiplier);
|
||||
|
||||
return new CharacterStats {
|
||||
maxHealth = maxHealth,
|
||||
maxStamina = maxStamina,
|
||||
dodgeStaminaLossMultiplier = dodgeMultiplier
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PerkFactory : IPerkFactory {
|
||||
private readonly Dictionary<string, PerkDefinition> perkPool;
|
||||
|
||||
public PerkFactory(IEnumerable<PerkDefinition> perkPool) {
|
||||
if(perkPool == null) {
|
||||
throw new ArgumentNullException(nameof(perkPool));
|
||||
}
|
||||
|
||||
this.perkPool = perkPool
|
||||
.Where(p => p != null && !string.IsNullOrWhiteSpace(p.id))
|
||||
.GroupBy(p => p.id)
|
||||
.ToDictionary(g => g.Key, g => g.First());
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<PerkDefinition> GetAll() {
|
||||
return perkPool.Values.ToList();
|
||||
}
|
||||
|
||||
public PerkDefinition GetById(string perkId) {
|
||||
if(string.IsNullOrWhiteSpace(perkId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
perkPool.TryGetValue(perkId, out PerkDefinition perk);
|
||||
return perk;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<PerkDefinition> GetAvailableFor(CharacterData character) {
|
||||
if(character == null) {
|
||||
return perkPool.Values.ToList();
|
||||
}
|
||||
|
||||
HashSet<string> ownedPerkIds = character.perks
|
||||
.Where(p => p != null && !string.IsNullOrWhiteSpace(p.id))
|
||||
.Select(p => p.id)
|
||||
.ToHashSet();
|
||||
|
||||
return perkPool.Values.Where(p => !ownedPerkIds.Contains(p.id)).ToList();
|
||||
}
|
||||
|
||||
public bool TryAddPerk(CharacterData character, string perkId) {
|
||||
if(character == null || string.IsNullOrWhiteSpace(perkId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(character.perks.Any(p => p != null && p.id == perkId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!perkPool.TryGetValue(perkId, out PerkDefinition perk)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
character.perks.Add(new PerkDefinition {
|
||||
id = perk.id,
|
||||
name = perk.name,
|
||||
mechanicalBonus = perk.mechanicalBonus,
|
||||
thematicPenalty = perk.thematicPenalty
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CharacterFactory : ICharacterFactory {
|
||||
private readonly CharacterFactoryOptions options;
|
||||
private readonly ICharacterAttributesFactory attributesFactory;
|
||||
private readonly ICharacterStatsFactory statsFactory;
|
||||
private readonly IPerkFactory perkFactory;
|
||||
|
||||
public CharacterFactory(
|
||||
ICharacterAttributesFactory attributesFactory,
|
||||
ICharacterStatsFactory statsFactory,
|
||||
IPerkFactory perkFactory,
|
||||
CharacterFactoryOptions options = null) {
|
||||
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.options = options ?? new CharacterFactoryOptions();
|
||||
}
|
||||
|
||||
public CharacterData CreateCustomProtagonist(CustomCharacterCreationRequest request) {
|
||||
if(request == null) {
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
CharacterAttributes attributes = attributesFactory.CreateFromPointAllocation(
|
||||
request.mightPoints,
|
||||
request.reflexPoints,
|
||||
request.knowledgePoints);
|
||||
|
||||
CharacterData character = new CharacterData {
|
||||
id = string.IsNullOrWhiteSpace(request.id) ? Guid.NewGuid().ToString("N") : request.id,
|
||||
displayName = request.displayName,
|
||||
role = CharacterRole.Protagonist,
|
||||
level = options.startingLevel,
|
||||
experience = 0,
|
||||
attributes = attributes,
|
||||
stats = statsFactory.Create(attributes)
|
||||
};
|
||||
|
||||
AddStartingPerks(character, request.startingPerkIds);
|
||||
return character;
|
||||
}
|
||||
|
||||
public CharacterData CreateFromTemplate(CharacterTemplate template, CharacterRole role = CharacterRole.Companion) {
|
||||
if(template == null) {
|
||||
throw new ArgumentNullException(nameof(template));
|
||||
}
|
||||
|
||||
CharacterAttributes sourceAttributes = template.attributes ?? attributesFactory.Create(0, 0, 0);
|
||||
CharacterAttributes attributes = attributesFactory.Create(
|
||||
sourceAttributes.might,
|
||||
sourceAttributes.reflex,
|
||||
sourceAttributes.knowledge);
|
||||
|
||||
CharacterData character = new CharacterData {
|
||||
id = string.IsNullOrWhiteSpace(template.id) ? Guid.NewGuid().ToString("N") : template.id,
|
||||
displayName = template.displayName,
|
||||
role = role,
|
||||
level = template.level <= 0 ? options.startingLevel : template.level,
|
||||
experience = template.experience,
|
||||
attributes = attributes,
|
||||
stats = statsFactory.Create(attributes)
|
||||
};
|
||||
|
||||
AddStartingPerks(character, template.startingPerkIds);
|
||||
return character;
|
||||
}
|
||||
|
||||
private void AddStartingPerks(CharacterData character, IEnumerable<string> perkIds) {
|
||||
if(perkIds == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(string perkId in perkIds.Distinct()) {
|
||||
perkFactory.TryAddPerk(character, perkId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class PartyFactory : IPartyFactory {
|
||||
private readonly PartyFactoryOptions options;
|
||||
|
||||
public PartyFactory(PartyFactoryOptions options = null) {
|
||||
this.options = options ?? new PartyFactoryOptions();
|
||||
}
|
||||
|
||||
public PartyData Create(CharacterData protagonist, IEnumerable<CharacterData> companions = null) {
|
||||
if(protagonist == null) {
|
||||
throw new ArgumentNullException(nameof(protagonist));
|
||||
}
|
||||
|
||||
PartyData party = new PartyData {
|
||||
maxPartySize = options.maxPartySize <= 0 ? int.MaxValue : options.maxPartySize
|
||||
};
|
||||
|
||||
CharacterData protagonistClone = protagonist.Clone();
|
||||
protagonistClone.role = CharacterRole.Protagonist;
|
||||
party.members.Add(protagonistClone);
|
||||
|
||||
if(companions != null) {
|
||||
foreach(CharacterData companion in companions.Where(c => c != null)) {
|
||||
CharacterData companionClone = companion.Clone();
|
||||
companionClone.role = CharacterRole.Companion;
|
||||
party.members.Add(companionClone);
|
||||
}
|
||||
}
|
||||
|
||||
ValidateParty(party);
|
||||
return party;
|
||||
}
|
||||
|
||||
private void ValidateParty(PartyData party) {
|
||||
if(party.members.Count < options.minPartySize) {
|
||||
throw new ArgumentException($"Party size {party.members.Count} is below minimum {options.minPartySize}.");
|
||||
}
|
||||
|
||||
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}.");
|
||||
}
|
||||
|
||||
if(options.enforceUniqueCharacterIds) {
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec5c743399d71cd41b2db4f9a7e5dec1
|
||||
5
Assets/Code/GameState/Entities/IEntity.cs
Normal file
5
Assets/Code/GameState/Entities/IEntity.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace v {
|
||||
public interface IEntity {
|
||||
|
||||
}
|
||||
}
|
||||
3
Assets/Code/GameState/Entities/IEntity.cs.meta
Normal file
3
Assets/Code/GameState/Entities/IEntity.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98b50e969ea0412ca3575cd28b6018b7
|
||||
timeCreated: 1772574533
|
||||
60
Assets/Code/GameState/Entities/PartyCreatorModel.cs
Normal file
60
Assets/Code/GameState/Entities/PartyCreatorModel.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
namespace Nox.Game {
|
||||
public class PartyCreatorModel {
|
||||
private readonly ICharacterFactory characterFactory;
|
||||
private readonly IPartyFactory partyFactory;
|
||||
public PartyCreatorModel(ICharacterFactory characterFactory, IPartyFactory partyFactory) {
|
||||
this.characterFactory = characterFactory;
|
||||
this.partyFactory = partyFactory;
|
||||
}
|
||||
public PartyData CreatePartyForNewRun(int companionCount) {
|
||||
var protagonist = characterFactory.CreateCustomProtagonist(new CustomCharacterCreationRequest {
|
||||
id = "protagonist",
|
||||
displayName = "The Warden",
|
||||
mightPoints = 4,
|
||||
reflexPoints = 3,
|
||||
knowledgePoints = 3,
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "iron-will" }
|
||||
});
|
||||
|
||||
CharacterTemplate[] companionTemplates = {
|
||||
new() {
|
||||
id = "companion-bruiser",
|
||||
displayName = "Rook",
|
||||
attributes = new CharacterAttributes { might = 5, reflex = 2, knowledge = 1 },
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "steadfast" }
|
||||
},
|
||||
new() {
|
||||
id = "companion-scout",
|
||||
displayName = "Sable",
|
||||
attributes = new CharacterAttributes { might = 2, reflex = 5, knowledge = 1 },
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "nimble-step" }
|
||||
},
|
||||
new() {
|
||||
id = "companion-scholar",
|
||||
displayName = "Quill",
|
||||
attributes = new CharacterAttributes { might = 1, reflex = 2, knowledge = 5 },
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "lorekeeper" }
|
||||
},
|
||||
new() {
|
||||
id = "companion-vanguard",
|
||||
displayName = "Brant",
|
||||
attributes = new CharacterAttributes { might = 4, reflex = 3, knowledge = 2 },
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "bulwark" }
|
||||
},
|
||||
new() {
|
||||
id = "companion-tracker",
|
||||
displayName = "Mira",
|
||||
attributes = new CharacterAttributes { might = 2, reflex = 4, knowledge = 3 },
|
||||
startingPerkIds = new System.Collections.Generic.List<string> { "pathfinder" }
|
||||
}
|
||||
};
|
||||
|
||||
var companions = new System.Collections.Generic.List<CharacterData>();
|
||||
for(var i = 0; i < companionCount && i < companionTemplates.Length; i++) {
|
||||
companions.Add(characterFactory.CreateFromTemplate(companionTemplates[i], CharacterRole.Companion));
|
||||
}
|
||||
|
||||
return partyFactory.Create(protagonist, companions);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Code/GameState/Entities/PartyCreatorModel.cs.meta
Normal file
3
Assets/Code/GameState/Entities/PartyCreatorModel.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f231d6e487bc4577847de98936498bde
|
||||
timeCreated: 1772644731
|
||||
6
Assets/Code/GameState/Entities/PartyReference.cs
Normal file
6
Assets/Code/GameState/Entities/PartyReference.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
public class PartyReference : MonoBehaviour {
|
||||
}
|
||||
}
|
||||
2
Assets/Code/GameState/Entities/PartyReference.cs.meta
Normal file
2
Assets/Code/GameState/Entities/PartyReference.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 067750df0e87b834bbbb239b7c03abb4
|
||||
Reference in New Issue
Block a user