forked from Shardstone/trail-into-darkness
End of refactor for the Entities
This commit is contained in:
@@ -9,25 +9,39 @@ namespace Nox.Game {
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterTemplate {
|
||||
public string id;
|
||||
public string displayName;
|
||||
public EntityAttributes attributes;
|
||||
public CharacterRace characterRace;
|
||||
public CharacterClass characterClass;
|
||||
public EntityStats stats;
|
||||
public PerksData perksData = new ();
|
||||
public Guid id = Guid.NewGuid();
|
||||
public string displayName = "New Character";
|
||||
public CharacterRace race = (CharacterRace)GetRandomInt(1, Enum.GetValues(typeof(CharacterRace)).Length-1);
|
||||
public CharacterClass @class = (CharacterClass)GetRandomInt(1, Enum.GetValues(typeof(CharacterClass)).Length-1);
|
||||
public EntityAttributes attributes = GetDefaultAttributes();
|
||||
public PerksData perksData = new();
|
||||
public ModifiersData modifiersData = 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 CustomCharacterCreationRequest {
|
||||
public string id;
|
||||
public Guid id = Guid.Empty;
|
||||
public string displayName;
|
||||
public CharacterRace characterRace;
|
||||
public CharacterClass characterClass;
|
||||
public CharacterRace race;
|
||||
public CharacterClass @class;
|
||||
public EntityStats stats;
|
||||
public EntityAttributes attributes;
|
||||
public PerksData perksData = new();
|
||||
public ModifiersData modifiersData = new();
|
||||
public PerksData perks = new();
|
||||
public ModifiersData modifiers = new();
|
||||
}
|
||||
|
||||
public sealed class CharacterFactory : ICharacterFactory {
|
||||
@@ -53,18 +67,18 @@ namespace Nox.Game {
|
||||
var stats = statsFactory.Create(request.attributes);
|
||||
|
||||
var character = new CharacterDefinition {
|
||||
ID = string.IsNullOrWhiteSpace(request.id) ? Guid.NewGuid().ToString("N") : request.id,
|
||||
DisplayName = request.displayName,
|
||||
race = request.characterRace,
|
||||
@class = request.characterClass,
|
||||
role = CharacterRole.Protagonist,
|
||||
ID = request.id == Guid.Empty ? Guid.NewGuid() : request.id,
|
||||
Name = request.displayName,
|
||||
Race = request.race,
|
||||
Class = request.@class,
|
||||
Role = CharacterRole.Protagonist,
|
||||
Attributes = attributes,
|
||||
Stats = stats,
|
||||
perksData = request.perksData ?? new PerksData(),
|
||||
activeModifiers = request.modifiersData ?? new ModifiersData()
|
||||
Perks = request.perks ?? new PerksData(),
|
||||
Modifiers = request.modifiers ?? new ModifiersData()
|
||||
};
|
||||
|
||||
AddStartingPerks(character, request.perksData);
|
||||
AddStartingPerks(character, request.perks);
|
||||
return character;
|
||||
}
|
||||
|
||||
@@ -73,21 +87,23 @@ namespace Nox.Game {
|
||||
throw new ArgumentNullException(nameof(template));
|
||||
}
|
||||
|
||||
var attributes = attributesFactory.Create(template.attributes);
|
||||
template.perksData ??= new PerksData();
|
||||
template.modifiersData ??= new ModifiersData();
|
||||
|
||||
var character = new CharacterDefinition {
|
||||
ID = string.IsNullOrWhiteSpace(template.id) ? Guid.NewGuid().ToString("N") : template.id,
|
||||
DisplayName = template.displayName,
|
||||
race = template.characterRace,
|
||||
@class = template.characterClass,
|
||||
role = role,
|
||||
Attributes = attributes,
|
||||
Stats = statsFactory.Create(attributes),
|
||||
perksData = new PerksData(),
|
||||
activeModifiers = new ModifiersData()
|
||||
ID = template.id == Guid.Empty ? Guid.NewGuid() : template.id,
|
||||
Name = template.displayName,
|
||||
Race = template.race,
|
||||
Class = template.@class,
|
||||
Role = role,
|
||||
Attributes = attributesFactory.Create(template.attributes),
|
||||
Stats = statsFactory.Create(template.attributes),
|
||||
Perks = template.perksData,
|
||||
Modifiers = template.modifiersData
|
||||
};
|
||||
|
||||
AddStartingPerks(character, template.perksData);
|
||||
AddStartingModifiers(character, template.modifiersData);
|
||||
return character;
|
||||
}
|
||||
|
||||
@@ -97,7 +113,17 @@ namespace Nox.Game {
|
||||
}
|
||||
|
||||
foreach(var perkId in perkData.perks.Distinct()) {
|
||||
perkFactory.TryAddPerk(character, perkId.id);
|
||||
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.Distinct()) {
|
||||
perkFactory.TryAddPerk(character, modifierId.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ namespace Nox.Game {
|
||||
|
||||
public interface ICharacterSystems {
|
||||
IPerkFactory PerkFactory { get; }
|
||||
IModfiersFactory ModifiersFactory { get; }
|
||||
IModifiersFactory ModifiersFactory { get; }
|
||||
ICharacterFactory CharacterFactory { get; }
|
||||
IPartyFactory PartyFactory { get; }
|
||||
}
|
||||
|
||||
public sealed class CharacterSystems : ICharacterSystems {
|
||||
public CharacterSystems(IPerkFactory perkFactory, IModfiersFactory modifiersFactory, ICharacterFactory characterFactory, IPartyFactory partyFactory) {
|
||||
public CharacterSystems(IPerkFactory perkFactory, IModifiersFactory modifiersFactory, ICharacterFactory characterFactory, IPartyFactory partyFactory) {
|
||||
ModifiersFactory = modifiersFactory;
|
||||
PerkFactory = perkFactory;
|
||||
CharacterFactory = characterFactory;
|
||||
@@ -16,7 +16,7 @@ namespace Nox.Game {
|
||||
}
|
||||
|
||||
public IPerkFactory PerkFactory { get; }
|
||||
public IModfiersFactory ModifiersFactory { get; }
|
||||
public IModifiersFactory ModifiersFactory { get; }
|
||||
public ICharacterFactory CharacterFactory { get; }
|
||||
public IPartyFactory PartyFactory { get; }
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Nox.Game {
|
||||
CharacterRegistry characterRegistry,
|
||||
ModifiersRegistry modifiersRegistry) {
|
||||
IPerkFactory perkFactory = new PerkFactory(perksRegistry);
|
||||
IModfiersFactory modifiersFactory = new ModifiersFactory(modifiersRegistry);
|
||||
IModifiersFactory modifiersFactory = new ModifiersFactory(modifiersRegistry);
|
||||
ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(characterRegistry);
|
||||
ICharacterStatsFactory statsFactory = new CharacterStatsFactory(characterRegistry);
|
||||
ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory);
|
||||
|
||||
@@ -48,8 +48,8 @@ namespace Nox.Game {
|
||||
var partyDefinition = testingSet.partyDefinition;
|
||||
foreach(var member in partyDefinition.members) {
|
||||
var baseSettings = starterCharacterSettings.defaultEntityAttributes;
|
||||
var classAttributes = starterCharacterSettings.classBonuses.FirstOrDefault(c => c.@class == member.@class)?.bonusAttributes;
|
||||
var racialAttributes = starterCharacterSettings.racialBonuses.FirstOrDefault(rb => rb.race == member.race)?.bonusAttributes;
|
||||
var classAttributes = starterCharacterSettings.classBonuses.FirstOrDefault(c => c.@class == member.Class)?.bonusAttributes;
|
||||
var racialAttributes = starterCharacterSettings.racialBonuses.FirstOrDefault(rb => rb.race == member.Race)?.bonusAttributes;
|
||||
if (classAttributes != null && racialAttributes != null) {
|
||||
member.Attributes += baseSettings + classAttributes + racialAttributes;
|
||||
}
|
||||
|
||||
@@ -6,10 +6,16 @@ using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
public interface IEntityDefinition {
|
||||
string ID { get; }
|
||||
string DisplayName { get; }
|
||||
Guid ID { get; }
|
||||
string Name { get; }
|
||||
CharacterRace Race { get; }
|
||||
CharacterClass Class { get; }
|
||||
CharacterRole Role { get; }
|
||||
EntityAttributes Attributes { get; }
|
||||
EntityStats Stats { get; }
|
||||
PerksData Perks { get; }
|
||||
ModifiersData Modifiers { get; }
|
||||
|
||||
}
|
||||
|
||||
public enum StatType {
|
||||
@@ -51,22 +57,21 @@ namespace Nox.Game {
|
||||
|
||||
[Serializable]
|
||||
public sealed class Stat {
|
||||
private readonly StatType health;
|
||||
public StatType type;
|
||||
public StatType stat;
|
||||
public int value;
|
||||
public Stat(StatType health, int value) {
|
||||
this.health = health;
|
||||
public Stat(StatType stat, int value) {
|
||||
this.stat = stat;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed record Attribute {
|
||||
private readonly int values;
|
||||
public AttributeType attribute;
|
||||
public int value;
|
||||
public Attribute(AttributeType attributeType, int values) {
|
||||
this.values = values;
|
||||
public Attribute(AttributeType attribute, int value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,55 +94,37 @@ namespace Nox.Game {
|
||||
public Stat[] stats;
|
||||
|
||||
public int GetValue(StatType statType) {
|
||||
return stats.First(stat => stat.type == statType).value;
|
||||
return stats.First(stat => stat.stat == statType).value;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class CharacterDefinition : IEntityDefinition {
|
||||
[SerializeField] private string id;
|
||||
[SerializeField] private string displayName;
|
||||
public CharacterRace race;
|
||||
public CharacterClass @class;
|
||||
public CharacterRole role;
|
||||
[SerializeField] private EntityAttributes attributes;
|
||||
[SerializeField] private EntityStats stats;
|
||||
public PerksData perksData = new();
|
||||
public ModifiersData activeModifiers = new();
|
||||
public class CharacterDefinition : IEntityDefinition {
|
||||
public Guid ID { get; set; }
|
||||
[field: SerializeField] public string Name { get; set; }
|
||||
[field: SerializeField] public CharacterRace Race { get; set; }
|
||||
[field: SerializeField] public CharacterClass Class { get; set; }
|
||||
[field: SerializeField] public CharacterRole Role { get; set; }
|
||||
[field: SerializeField] public EntityAttributes Attributes { get; set; }
|
||||
[field: SerializeField] public EntityStats Stats { get; set; }
|
||||
[field: SerializeField] public PerksData Perks { get; set; }
|
||||
[field: SerializeField] public ModifiersData Modifiers { get; set; }
|
||||
|
||||
public CharacterDefinition Clone() {
|
||||
return new CharacterDefinition {
|
||||
id = id,
|
||||
displayName = displayName,
|
||||
role = role,
|
||||
race = race,
|
||||
@class = @class,
|
||||
attributes = new EntityAttributes(),
|
||||
stats = new EntityStats(),
|
||||
perksData = new PerksData(),
|
||||
activeModifiers = new ModifiersData()
|
||||
ID = Guid.NewGuid(),
|
||||
Name = Name,
|
||||
Role = Role,
|
||||
Race = Race,
|
||||
Class = Class,
|
||||
Attributes = Attributes,
|
||||
Stats = Stats,
|
||||
Perks = Perks,
|
||||
Modifiers = Modifiers
|
||||
};
|
||||
}
|
||||
|
||||
public string ID {
|
||||
get => id;
|
||||
set => id = value;
|
||||
}
|
||||
|
||||
public string DisplayName {
|
||||
get => displayName;
|
||||
set => displayName = value;
|
||||
}
|
||||
|
||||
public EntityAttributes Attributes {
|
||||
get => attributes;
|
||||
set => attributes = value;
|
||||
}
|
||||
|
||||
public EntityStats Stats {
|
||||
get => stats;
|
||||
set => stats = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -146,9 +133,9 @@ namespace Nox.Game {
|
||||
public List<CharacterDefinition> members = new();
|
||||
|
||||
[JsonIgnore]
|
||||
public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist);
|
||||
public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.Role == CharacterRole.Protagonist);
|
||||
|
||||
[JsonIgnore]
|
||||
public IReadOnlyList<CharacterDefinition> Companions => members.Where(m => m.role == CharacterRole.Companion).ToList();
|
||||
public IReadOnlyList<CharacterDefinition> Companions => members.Where(m => m.Role == CharacterRole.Companion).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
using Jovian.InspectorTools;
|
||||
using Jovian.Logger;
|
||||
using Mono.Cecil;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
public interface IModfiersFactory {
|
||||
IReadOnlyCollection<ModifierDefinition> GetAll();
|
||||
ModifierDefinition GetById(Guid modifierId);
|
||||
IReadOnlyCollection<ModifierDefinition> GetModifiersFor(CharacterDefinition character);
|
||||
bool TryAddModifier(CharacterDefinition character, string modiferId);
|
||||
public interface IModifier {
|
||||
string Name { get; }
|
||||
Guid Id { get; }
|
||||
StatType StatType { get; }
|
||||
AttributeType AttributeType { get; }
|
||||
ModifierOperation Operation { get; }
|
||||
float Value { get; }
|
||||
}
|
||||
|
||||
public interface IModifiersFactory {
|
||||
IReadOnlyCollection<IModifier> GetAll();
|
||||
IModifier GetById(Guid modifierId);
|
||||
IReadOnlyCollection<IModifier> GetModifiersFor(IEntityDefinition character);
|
||||
bool TryAddModifier(IEntityDefinition character, Guid modiferId);
|
||||
}
|
||||
|
||||
public enum ModifierOperation {
|
||||
@@ -20,44 +32,65 @@ namespace Nox.Game {
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class ModifierDefinition {
|
||||
public string name;
|
||||
[ReadOnly]
|
||||
public Guid id = Guid.NewGuid();
|
||||
public StatType statType;
|
||||
public AttributeType attributeType;
|
||||
public ModifierOperation operation;
|
||||
public float value;
|
||||
public sealed class ModifierDefinition : IModifier {
|
||||
[field: SerializeField] public string Name { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
[field: SerializeField] public StatType StatType { get; set; }
|
||||
[field: SerializeField] public AttributeType AttributeType { get; set; }
|
||||
[field: SerializeField] public ModifierOperation Operation { get; set; }
|
||||
[field: SerializeField] public float Value { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class ModifiersData {
|
||||
public ModifierDefinition[] modifiers;
|
||||
public List<ModifierDefinition> modifiers = new ();
|
||||
}
|
||||
|
||||
public class ModifiersFactory : IModfiersFactory {
|
||||
public class ModifiersFactory : IModifiersFactory {
|
||||
private readonly ModifiersRegistry modifiersRegistry;
|
||||
private readonly Dictionary<Guid, ModifierDefinition> modifierPool = new ();
|
||||
private readonly Dictionary<Guid, IModifier> modifierPool = new ();
|
||||
|
||||
public ModifiersFactory(ModifiersRegistry modifiersRegistry) {
|
||||
this.modifiersRegistry = modifiersRegistry;
|
||||
var allAvailableModifiers = modifiersRegistry.modifiersData;
|
||||
foreach(var modifier in allAvailableModifiers.modifiers) {
|
||||
modifierPool.Add(modifier.id, modifier);
|
||||
modifierPool.Add(modifier.Id, modifier);
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<ModifierDefinition> GetAll() {
|
||||
public IReadOnlyCollection<IModifier> GetAll() {
|
||||
return modifiersRegistry.modifiersData.modifiers;
|
||||
}
|
||||
public ModifierDefinition GetById(Guid modifierId) {
|
||||
return modifiersRegistry.modifiersData.modifiers.FirstOrDefault(m => m.id == modifierId);
|
||||
public IModifier GetById(Guid modifierId) {
|
||||
return modifiersRegistry.modifiersData.modifiers.FirstOrDefault(m => m.Id == modifierId);
|
||||
}
|
||||
public IReadOnlyCollection<ModifierDefinition> GetModifiersFor(CharacterDefinition character) {
|
||||
throw new NotImplementedException();
|
||||
public IReadOnlyCollection<IModifier> GetModifiersFor(IEntityDefinition character) {
|
||||
return character.Modifiers.modifiers;
|
||||
}
|
||||
public bool TryAddModifier(CharacterDefinition character, string modiferId) {
|
||||
throw new NotImplementedException();
|
||||
public bool TryAddModifier(IEntityDefinition character, Guid modifierId) {
|
||||
if(character == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(modifierId == Guid.Empty) {
|
||||
GlobalLogger.LogException("Cannot add a modifier with an empty ID!", LogCategory.GameLogic);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(character.Modifiers.modifiers.Any(p => p != null && p.Id == modifierId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!modifierPool.TryGetValue(modifierId, out var modifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
character.Perks.perks.Add(new PerkDefinition {
|
||||
Id = modifier.Id,
|
||||
Name = modifier.Name
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,55 +10,28 @@ namespace Nox.Game {
|
||||
}
|
||||
public PartyDefinition CreatePartyForNewRun(int companionCount) {
|
||||
var protagonist = characterFactory.CreateCustomProtagonist(new CustomCharacterCreationRequest {
|
||||
id = "protagonist",
|
||||
displayName = "The Warden",
|
||||
displayName = "John Doe",
|
||||
attributes = new EntityAttributes(),
|
||||
perksData = new PerksData(){
|
||||
perks = new PerksData(){
|
||||
perks = new List<PerkDefinition>()
|
||||
}
|
||||
});
|
||||
|
||||
var rook_attributes = new EntityAttributes();
|
||||
rook_attributes.attributes = new[] {
|
||||
new Attribute(AttributeType.Might, 6),
|
||||
new Attribute(AttributeType.Knowledge, 2),
|
||||
new Attribute(AttributeType.Perception, 2),
|
||||
new Attribute(AttributeType.Reflex, 4)
|
||||
};
|
||||
CharacterTemplate[] companionTemplates = {
|
||||
// new() {
|
||||
// id = "companion-bruiser",
|
||||
// displayName = "Rook",
|
||||
// attributes = new EntityAttributes { might = 5, reflex = 2, knowledge = 1 },
|
||||
// perksData = new PerksData(){
|
||||
// perks = new List<PerkDefinition>()
|
||||
// }
|
||||
// },
|
||||
// new() {
|
||||
// id = "companion-scout",
|
||||
// displayName = "Sable",
|
||||
// attributes = new EntityAttributes { might = 2, reflex = 5, knowledge = 1 },
|
||||
// perksData = new PerksData(){
|
||||
// perks = new List<PerkDefinition>()
|
||||
// }
|
||||
// },
|
||||
// new() {
|
||||
// id = "companion-scholar",
|
||||
// displayName = "Quill",
|
||||
// attributes = new EntityAttributes { might = 1, reflex = 2, knowledge = 5 },
|
||||
// perksData = new PerksData(){
|
||||
// perks = new List<PerkDefinition>()
|
||||
// }
|
||||
// },
|
||||
// new() {
|
||||
// id = "companion-vanguard",
|
||||
// displayName = "Brant",
|
||||
// attributes = new EntityAttributes { might = 4, reflex = 3, knowledge = 2 },
|
||||
// perksData = new PerksData(){
|
||||
// perks = new List<PerkDefinition>()
|
||||
// }
|
||||
// },
|
||||
// new() {
|
||||
// id = "companion-tracker",
|
||||
// displayName = "Mira",
|
||||
// attributes = new EntityAttributes { might = 2, reflex = 4, knowledge = 3 },
|
||||
// perksData = new PerksData(){
|
||||
// perks = new List<PerkDefinition>()
|
||||
// }
|
||||
// }
|
||||
new() {
|
||||
displayName = "Rook",
|
||||
attributes = rook_attributes,
|
||||
perksData = new PerksData(){
|
||||
perks = new List<PerkDefinition>()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var companions = new List<CharacterDefinition>();
|
||||
|
||||
@@ -24,13 +24,13 @@ namespace Nox.Game {
|
||||
};
|
||||
|
||||
var protagonistClone = protagonist.Clone();
|
||||
protagonistClone.role = CharacterRole.Protagonist;
|
||||
protagonistClone.Role = CharacterRole.Protagonist;
|
||||
party.members.Add(protagonistClone);
|
||||
|
||||
if(companions != null) {
|
||||
foreach(var companion in companions.Where(c => c != null)) {
|
||||
var companionClone = companion.Clone();
|
||||
companionClone.role = CharacterRole.Companion;
|
||||
companionClone.Role = CharacterRole.Companion;
|
||||
party.members.Add(companionClone);
|
||||
}
|
||||
}
|
||||
@@ -44,13 +44,13 @@ namespace Nox.Game {
|
||||
throw new ArgumentException($"Party size {party.members.Count} exceeds max {party.maxPartySize}.");
|
||||
}
|
||||
|
||||
int protagonistCount = party.members.Count(m => m.role == CharacterRole.Protagonist);
|
||||
var protagonistCount = party.members.Count(m => m.Role == CharacterRole.Protagonist);
|
||||
if(protagonistCount != 1) {
|
||||
throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}.");
|
||||
}
|
||||
|
||||
int uniqueIds = party.members
|
||||
.Where(m => !string.IsNullOrWhiteSpace(m.ID))
|
||||
var uniqueIds = party.members
|
||||
.Where(m => m.ID != Guid.Empty)
|
||||
.Select(m => m.ID)
|
||||
.Distinct()
|
||||
.Count();
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
using Jovian.InspectorTools;
|
||||
using Jovian.Logger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
|
||||
public interface IPerk {
|
||||
Guid Id { get; }
|
||||
string Name { get; }
|
||||
ModifiersData Modifiers { get; }
|
||||
}
|
||||
|
||||
public interface IPerkFactory {
|
||||
IReadOnlyCollection<PerkDefinition> GetAll();
|
||||
PerkDefinition GetById(Guid perkId);
|
||||
IReadOnlyCollection<PerkDefinition> GetPerksFor(CharacterDefinition character);
|
||||
bool TryAddPerk(CharacterDefinition character, Guid perkId);
|
||||
IReadOnlyCollection<IPerk> GetAll();
|
||||
IPerk GetById(Guid perkId);
|
||||
IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character);
|
||||
bool TryAddPerk(IEntityDefinition character, Guid perkId);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class PerkDefinition {
|
||||
public string name;
|
||||
[ReadOnly]
|
||||
public Guid id;
|
||||
public ModifiersData modifiers = new ();
|
||||
public sealed class PerkDefinition : IPerk {
|
||||
[field: SerializeField] public string Name { get; set; }
|
||||
[field: SerializeField] public ModifiersData Modifiers { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@@ -26,7 +32,7 @@ namespace Nox.Game {
|
||||
}
|
||||
|
||||
public sealed class PerkFactory : IPerkFactory {
|
||||
private readonly Dictionary<Guid, PerkDefinition> perkPool = new ();
|
||||
private readonly Dictionary<Guid, IPerk> perkPool = new ();
|
||||
|
||||
public PerkFactory(PerksRegistry perksRegistry) {
|
||||
if(!perksRegistry) {
|
||||
@@ -34,37 +40,41 @@ namespace Nox.Game {
|
||||
}
|
||||
var allAvailablePerks = perksRegistry.perksData;
|
||||
foreach(var perk in allAvailablePerks.perks) {
|
||||
perkPool.Add(perk.id, perk);
|
||||
perkPool.Add(perk.Id, perk);
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<PerkDefinition> GetAll() {
|
||||
public IReadOnlyCollection<IPerk> GetAll() {
|
||||
return perkPool.Values.ToList();
|
||||
}
|
||||
|
||||
public PerkDefinition GetById(Guid perkId) {
|
||||
public IPerk GetById(Guid perkId) {
|
||||
perkPool.TryGetValue(perkId, out var perk);
|
||||
return perk;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<PerkDefinition> GetPerksFor(CharacterDefinition character) {
|
||||
public IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character) {
|
||||
if(character == null) {
|
||||
return perkPool.Values.ToList();
|
||||
}
|
||||
|
||||
var ownedPerkIds = character.perksData.perks
|
||||
.Select(p => p.id)
|
||||
var ownedPerkIds = character.Perks.perks
|
||||
.Select(p => p.Id)
|
||||
.ToHashSet();
|
||||
|
||||
return perkPool.Values.Where(p => !ownedPerkIds.Contains(p.id)).ToList();
|
||||
return perkPool.Values.Where(p => !ownedPerkIds.Contains(p.Id)).ToList();
|
||||
}
|
||||
|
||||
public bool TryAddPerk(CharacterDefinition character, Guid perkId) {
|
||||
public bool TryAddPerk(IEntityDefinition character, Guid perkId) {
|
||||
if(character == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(character.perksData.perks.Any(p => p != null && p.id == perkId)) {
|
||||
if(perkId == Guid.Empty) {
|
||||
GlobalLogger.LogException("Cannot add a perk with an empty Id!", LogCategory.GameLogic);
|
||||
}
|
||||
|
||||
if(character.Perks.perks.Any(p => p != null && p.Id == perkId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -72,10 +82,11 @@ namespace Nox.Game {
|
||||
return false;
|
||||
}
|
||||
|
||||
character.perksData.perks.Add(new PerkDefinition {
|
||||
id = perk.id,
|
||||
name = perk.name
|
||||
character.Perks.perks.Add(new PerkDefinition {
|
||||
Id = perk.Id,
|
||||
Name = perk.Name
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Nox.Game {
|
||||
|
||||
@@ -33,33 +33,16 @@ MonoBehaviour:
|
||||
value: 1
|
||||
defaultEntityStats:
|
||||
stats:
|
||||
- type: 3
|
||||
- stat: 1
|
||||
value: 1
|
||||
- type: 1
|
||||
- stat: 2
|
||||
value: 0
|
||||
- type: 2
|
||||
- stat: 3
|
||||
value: 0
|
||||
- type: 4
|
||||
- stat: 4
|
||||
value: 0
|
||||
defaultPerksData:
|
||||
perks: []
|
||||
defaultModifiersData:
|
||||
modifiers:
|
||||
- name: Global Health Modifier per MGT
|
||||
statType: 1
|
||||
attributeType: 0
|
||||
operation: 3
|
||||
value: 3
|
||||
- name: Global Stamina modifier per MGT
|
||||
statType: 2
|
||||
attributeType: 0
|
||||
operation: 3
|
||||
value: 1
|
||||
- name: Global Stamina Modifier per KNO
|
||||
statType: 2
|
||||
attributeType: 0
|
||||
operation: 3
|
||||
value: 2
|
||||
racialBonuses: []
|
||||
classBonuses:
|
||||
- class: 1
|
||||
@@ -69,11 +52,4 @@ MonoBehaviour:
|
||||
stats: []
|
||||
startingPerks:
|
||||
perks: []
|
||||
permanentModifiers:
|
||||
modifiers:
|
||||
- name: Warrior Health per MGT
|
||||
statType: 1
|
||||
attributeType: 0
|
||||
operation: 3
|
||||
value: 4
|
||||
maxPartySize: 4
|
||||
|
||||
Reference in New Issue
Block a user