forked from Shardstone/trail-into-darkness
a bit more work on the system to create a default character set and testable environment for that
This commit is contained in:
@@ -126,7 +126,7 @@ MonoBehaviour:
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: 9e8339bc69fe33641a8fbc5bffd0ebd5
|
||||
m_Address: EntitiesBaseSettings
|
||||
m_Address: CharacterBaseSettings
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
@@ -201,6 +201,11 @@ MonoBehaviour:
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: f37df040ec9864f4dbafe3f5e6dfe4d9
|
||||
m_Address: DefaultPartySettings
|
||||
m_ReadOnly: 0
|
||||
m_SerializedLabels: []
|
||||
FlaggedDuringContentUpdateRestriction: 0
|
||||
- m_GUID: fe393ace9b354375a9cb14cdbbc28be4
|
||||
m_Address: Assets/TextMesh Pro/Shaders/TMP_SDF-Mobile.shader
|
||||
m_ReadOnly: 0
|
||||
|
||||
@@ -99,11 +99,14 @@ namespace Nox.Core {
|
||||
saveSystem = new SaveSystem(saveSerializer, saveStorage, saveSlotManager, saveSettings);
|
||||
|
||||
var adventureData = new AdventureData();
|
||||
|
||||
var characterBaseSettings = Addressables.LoadAssetAsync<CharacterBaseSettings>("CharacterBaseSettings").WaitForCompletion();
|
||||
var perKRegistry = Addressables.LoadAssetAsync<PerkRegistry>("PerkRegistry").WaitForCompletion();
|
||||
var perKRegistry = Addressables.LoadAssetAsync<PerksRegistry>("PerksRegistry ").WaitForCompletion();
|
||||
var characterRegistry = Addressables.LoadAssetAsync<CharacterRegistry>("CharacterRegistry").WaitForCompletion();
|
||||
var defaultPartySettings = Addressables.LoadAssetAsync<DefaultPartySettings>("DefaultPartySettings").WaitForCompletion();
|
||||
|
||||
var characterSystems = DefaultCharacterSystemsFactory.Create(characterBaseSettings, perKRegistry, characterRegistry);
|
||||
var partyCreatorModel = new PartyCreatorModel(characterSystems.CharacterFactory, characterSystems.PartyFactory);
|
||||
var partyCreatorModel = new PartyCreatorModel(characterSystems.CharacterFactory, characterSystems.PartyFactory, defaultPartySettings);
|
||||
|
||||
applicationStates = new Dictionary<GameState, IGameState> {
|
||||
[GameState.BootState] = new SplashGameState(bootstrapReferences, gameDataState),
|
||||
|
||||
@@ -2,13 +2,10 @@ using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
[CreateAssetMenu(fileName = "EntitiesBaseSettings", menuName = "Nox/Database/Entities/EntitiesBaseSettings")]
|
||||
[CreateAssetMenu(fileName = "CharacterBaseSettings", menuName = "Nox/Database/Entities/CharacterBaseSettings")]
|
||||
public class CharacterBaseSettings: ScriptableObject {
|
||||
|
||||
[Header("Character General Defaults")]
|
||||
public int startAttributesPool = 12;
|
||||
|
||||
[Header("Character Creation Defaults")]
|
||||
public DistributionPointsPerClass distributionPointsPerClass;
|
||||
public EntityAttributes defaultEntityAttributes;
|
||||
public EntityStats defaultEntityStats;
|
||||
public PerksData defaultPerksData;
|
||||
@@ -25,18 +22,24 @@ namespace Nox.Game {
|
||||
[Serializable]
|
||||
public sealed class RacialBonuses {
|
||||
public CharacterRace race;
|
||||
public EntityAttributes defaultEntityAttributes;
|
||||
public EntityStats defaultEntityStats;
|
||||
public PerksData perksData;
|
||||
public ModifiersData modifiersData;
|
||||
public EntityAttributes bonusAttributes;
|
||||
public EntityStats bonusStats;
|
||||
public PerksData startingPerks;
|
||||
public ModifiersData permanentModifiers;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class ClassBonuses {
|
||||
public CharacterClass @class;
|
||||
public EntityAttributes defaultEntityAttributes;
|
||||
public EntityStats defaultEntityStats;
|
||||
public PerksData perksData;
|
||||
public ModifiersData modifiersData;
|
||||
public EntityAttributes bonusAttributes;
|
||||
public EntityStats bonusStats;
|
||||
public PerksData startingPerks;
|
||||
public ModifiersData permanentModifiers;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class DistributionPointsPerClass {
|
||||
public CharacterClass @class;
|
||||
public int points;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,12 @@ using System;
|
||||
|
||||
namespace Nox.Game {
|
||||
public static class DefaultCharacterSystemsFactory {
|
||||
public static ICharacterSystems Create(CharacterBaseSettings characterBaseSettings, PerkRegistry perkRegistry, CharacterRegistry characterRegistry) {
|
||||
IPerkFactory perkFactory = new PerkFactory(perkRegistry);
|
||||
public static ICharacterSystems Create(CharacterBaseSettings characterBaseSettings, PerksRegistry perksRegistry, CharacterRegistry characterRegistry) {
|
||||
IPerkFactory perkFactory = new PerkFactory(perksRegistry);
|
||||
ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(characterRegistry);
|
||||
ICharacterStatsFactory statsFactory = new CharacterStatsFactory();
|
||||
ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory);
|
||||
IPartyFactory partyFactory = new PartyFactory(new PartyFactoryOptions {
|
||||
minPartySize = 1,
|
||||
maxPartySize = characterBaseSettings.maxPartySize,
|
||||
enforceUniqueCharacterIds = true
|
||||
});
|
||||
IPartyFactory partyFactory = new PartyFactory(characterBaseSettings);
|
||||
|
||||
return new CharacterSystems(perkFactory, characterFactory, partyFactory);
|
||||
}
|
||||
|
||||
66
Assets/Code/GameState/Entities/DefaultPartySettings.cs
Normal file
66
Assets/Code/GameState/Entities/DefaultPartySettings.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
[CreateAssetMenu(fileName = "DefaultPartySettings", menuName = "Nox/Database/Entities/Default Party Settings")]
|
||||
public class DefaultPartySettings : ScriptableObject {
|
||||
[Header("This will be default starting set")]
|
||||
public string startingSetId;
|
||||
|
||||
[Header("Party Definition Sets")]
|
||||
public List<PartyDefinitionSet> partyDefinitionSets;
|
||||
|
||||
[Header("Testing Party Definition Sets")]
|
||||
public CharacterBaseSettings characterBaseSettings;
|
||||
|
||||
private void OnValidate() {
|
||||
if(String.IsNullOrEmpty(startingSetId)) {
|
||||
Debug.LogError("DefaultPartySettings: startingSetId cannot be null or empty");
|
||||
return;
|
||||
}
|
||||
foreach(var partyDefinitionSet in partyDefinitionSets) {
|
||||
var partyDefinition = partyDefinitionSet.partyDefinition;
|
||||
if(partyDefinition == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(var i = 0; i < partyDefinition.maxPartySize; i++) {
|
||||
if (partyDefinition.members.Count <= i) {
|
||||
partyDefinition.members.Add(new CharacterDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
if(partyDefinitionSets.FirstOrDefault(pds => pds.id == partyDefinitionSet.id && pds.isTestingSet) != null) {
|
||||
var testingSet = partyDefinitionSets.FirstOrDefault(pds => pds.id == partyDefinitionSet.id && pds.isTestingSet);
|
||||
ApplyClassAndRacialBonuses(testingSet);
|
||||
}
|
||||
|
||||
if(partyDefinition.members.Count <= partyDefinition.maxPartySize) {
|
||||
continue;
|
||||
}
|
||||
Debug.LogError($"Party definition '{partyDefinitionSet.id}' has more members than the maximum allowed size.Removing extra members.");
|
||||
partyDefinition.members.RemoveRange(partyDefinition.maxPartySize, partyDefinition.members.Count - partyDefinition.maxPartySize);
|
||||
}
|
||||
}
|
||||
private void ApplyClassAndRacialBonuses(PartyDefinitionSet testingSet) {
|
||||
var partyDefinition = testingSet.partyDefinition;
|
||||
foreach(var member in partyDefinition.members) {
|
||||
var baseSettings = characterBaseSettings.defaultEntityAttributes;
|
||||
var classAttributes = characterBaseSettings.classBonuses.FirstOrDefault(c => c.@class == member.@class)?.bonusAttributes;
|
||||
var racialAttributes = characterBaseSettings.racialBonuses.FirstOrDefault(rb => rb.race == member.race)?.bonusAttributes;
|
||||
if (classAttributes != null && racialAttributes != null) {
|
||||
member.Attributes += baseSettings + classAttributes + racialAttributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class PartyDefinitionSet {
|
||||
public string id;
|
||||
public bool isTestingSet;
|
||||
public PartyDefinition partyDefinition;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff702898b3cd4100b9b8230f04711fa9
|
||||
timeCreated: 1774195937
|
||||
@@ -40,7 +40,14 @@ namespace Nox.Game {
|
||||
public int knowledge;
|
||||
public int perception;
|
||||
|
||||
public int Total => might + reflex + knowledge;
|
||||
public static EntityAttributes operator +(EntityAttributes a, EntityAttributes b) {
|
||||
return new EntityAttributes {
|
||||
might = a.might + b.might,
|
||||
reflex = a.reflex + b.reflex,
|
||||
knowledge = a.knowledge + b.knowledge,
|
||||
perception = a.perception + b.perception
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -118,8 +125,8 @@ namespace Nox.Game {
|
||||
|
||||
[Serializable]
|
||||
public sealed class PartyDefinition {
|
||||
public List<CharacterDefinition> members = new();
|
||||
public int maxPartySize;
|
||||
public List<CharacterDefinition> members = new();
|
||||
|
||||
[JsonIgnore]
|
||||
public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist);
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Nox.Game {
|
||||
public class PartyCreatorModel {
|
||||
private readonly ICharacterFactory characterFactory;
|
||||
private readonly IPartyFactory partyFactory;
|
||||
public PartyCreatorModel(ICharacterFactory characterFactory, IPartyFactory partyFactory) {
|
||||
public PartyCreatorModel(ICharacterFactory characterFactory, IPartyFactory partyFactory, DefaultPartySettings defaultPartySettings) {
|
||||
this.characterFactory = characterFactory;
|
||||
this.partyFactory = partyFactory;
|
||||
}
|
||||
|
||||
@@ -7,17 +7,11 @@ namespace Nox.Game {
|
||||
PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> companions = null);
|
||||
}
|
||||
|
||||
public sealed class PartyFactoryOptions {
|
||||
public int minPartySize = 1;
|
||||
public int maxPartySize = 4;
|
||||
public bool enforceUniqueCharacterIds = true;
|
||||
}
|
||||
|
||||
public sealed class PartyFactory : IPartyFactory {
|
||||
private readonly PartyFactoryOptions options;
|
||||
private readonly CharacterBaseSettings characterBaseSettings;
|
||||
|
||||
public PartyFactory(PartyFactoryOptions options = null) {
|
||||
this.options = options ?? new PartyFactoryOptions();
|
||||
public PartyFactory(CharacterBaseSettings characterBaseSettings) {
|
||||
this.characterBaseSettings = characterBaseSettings;
|
||||
}
|
||||
|
||||
public PartyDefinition Create(CharacterDefinition protagonist, IEnumerable<CharacterDefinition> companions = null) {
|
||||
@@ -25,17 +19,17 @@ namespace Nox.Game {
|
||||
throw new ArgumentNullException(nameof(protagonist));
|
||||
}
|
||||
|
||||
PartyDefinition party = new PartyDefinition {
|
||||
maxPartySize = options.maxPartySize <= 0 ? int.MaxValue : options.maxPartySize
|
||||
var party = new PartyDefinition {
|
||||
maxPartySize = characterBaseSettings.maxPartySize <= 0 ? int.MaxValue : characterBaseSettings.maxPartySize
|
||||
};
|
||||
|
||||
CharacterDefinition protagonistClone = protagonist.Clone();
|
||||
var protagonistClone = protagonist.Clone();
|
||||
protagonistClone.role = CharacterRole.Protagonist;
|
||||
party.members.Add(protagonistClone);
|
||||
|
||||
if(companions != null) {
|
||||
foreach(CharacterDefinition companion in companions.Where(c => c != null)) {
|
||||
CharacterDefinition companionClone = companion.Clone();
|
||||
foreach(var companion in companions.Where(c => c != null)) {
|
||||
var companionClone = companion.Clone();
|
||||
companionClone.role = CharacterRole.Companion;
|
||||
party.members.Add(companionClone);
|
||||
}
|
||||
@@ -46,10 +40,6 @@ namespace Nox.Game {
|
||||
}
|
||||
|
||||
private void ValidateParty(PartyDefinition 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}.");
|
||||
}
|
||||
@@ -59,7 +49,6 @@ namespace Nox.Game {
|
||||
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)
|
||||
@@ -71,4 +60,3 @@ namespace Nox.Game {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@ namespace Nox.Game {
|
||||
public sealed class PerkFactory : IPerkFactory {
|
||||
private readonly Dictionary<string, PerkDefinition> perkPool = new ();
|
||||
|
||||
public PerkFactory(PerkRegistry perkRegistry) {
|
||||
if(perkRegistry == null) {
|
||||
throw new ArgumentNullException(nameof(perkRegistry));
|
||||
public PerkFactory(PerksRegistry perksRegistry) {
|
||||
if(perksRegistry == null) {
|
||||
throw new ArgumentNullException(nameof(perksRegistry));
|
||||
}
|
||||
var allAvailablePerks = perkRegistry.perksData;
|
||||
var allAvailablePerks = perksRegistry.perksData;
|
||||
foreach(var perk in allAvailablePerks.perks) {
|
||||
perkPool.Add(perk.id, perk);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
[CreateAssetMenu(fileName = "PerksRegistry", menuName = "Nox/Database/Entities/Perks Registry")]
|
||||
public class PerkRegistry : ScriptableObject {
|
||||
public class PerksRegistry : ScriptableObject {
|
||||
public PerksData perksData;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ MonoBehaviour:
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1bbecc15c7cd4a7ca90ce17b3d3d75f0, type: 3}
|
||||
m_Name: EntitiesBaseSettings
|
||||
m_Name: CharacterBaseSettings
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.CharacterBaseSettings
|
||||
startAttributesPool: 12
|
||||
defaultEntityAttributes:
|
||||
103
Assets/Database/Entities/DefaultPartySettings.asset
Normal file
103
Assets/Database/Entities/DefaultPartySettings.asset
Normal file
@@ -0,0 +1,103 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ff702898b3cd4100b9b8230f04711fa9, type: 3}
|
||||
m_Name: DefaultPartySettings
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Nox.Game.DefaultPartySettings
|
||||
partyDefinitionSets:
|
||||
- id: startingParty1
|
||||
partyDefinition:
|
||||
maxPartySize: 4
|
||||
members:
|
||||
- id:
|
||||
displayName:
|
||||
race: 0
|
||||
class: 0
|
||||
role: 0
|
||||
attributes:
|
||||
might: 0
|
||||
reflex: 0
|
||||
knowledge: 0
|
||||
perception: 0
|
||||
stats:
|
||||
health: 0
|
||||
stamina: 0
|
||||
level: 0
|
||||
experience: 0
|
||||
perksData:
|
||||
perks: []
|
||||
activeModifiers:
|
||||
modifiers: []
|
||||
- id:
|
||||
displayName:
|
||||
race: 0
|
||||
class: 0
|
||||
role: 0
|
||||
attributes:
|
||||
might: 0
|
||||
reflex: 0
|
||||
knowledge: 0
|
||||
perception: 0
|
||||
stats:
|
||||
health: 0
|
||||
stamina: 0
|
||||
level: 0
|
||||
experience: 0
|
||||
perksData:
|
||||
perks: []
|
||||
activeModifiers:
|
||||
modifiers: []
|
||||
- id:
|
||||
displayName:
|
||||
race: 0
|
||||
class: 0
|
||||
role: 0
|
||||
attributes:
|
||||
might: 0
|
||||
reflex: 0
|
||||
knowledge: 0
|
||||
perception: 0
|
||||
stats:
|
||||
health: 0
|
||||
stamina: 0
|
||||
level: 0
|
||||
experience: 0
|
||||
perksData:
|
||||
perks: []
|
||||
activeModifiers:
|
||||
modifiers: []
|
||||
- id:
|
||||
displayName:
|
||||
race: 0
|
||||
class: 0
|
||||
role: 0
|
||||
attributes:
|
||||
might: 0
|
||||
reflex: 0
|
||||
knowledge: 0
|
||||
perception: 0
|
||||
stats:
|
||||
health: 0
|
||||
stamina: 0
|
||||
level: 0
|
||||
experience: 0
|
||||
perksData:
|
||||
perks: []
|
||||
activeModifiers:
|
||||
modifiers: []
|
||||
attributesPointDistribution:
|
||||
might: 0
|
||||
reflex: 0
|
||||
knowledge: 0
|
||||
perception: 0
|
||||
distributionPointsPerClass:
|
||||
class: 0
|
||||
points: 0
|
||||
8
Assets/Database/Entities/DefaultPartySettings.asset.meta
Normal file
8
Assets/Database/Entities/DefaultPartySettings.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f37df040ec9864f4dbafe3f5e6dfe4d9
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user