End of refactor for the Entities

This commit is contained in:
Sebastian Bularca
2026-03-30 00:33:07 +02:00
parent 00c1764fdb
commit 30f319a52d
11 changed files with 215 additions and 210 deletions

View File

@@ -9,25 +9,39 @@ namespace Nox.Game {
[Serializable] [Serializable]
public sealed class CharacterTemplate { public sealed class CharacterTemplate {
public string id; public Guid id = Guid.NewGuid();
public string displayName; public string displayName = "New Character";
public EntityAttributes attributes; public CharacterRace race = (CharacterRace)GetRandomInt(1, Enum.GetValues(typeof(CharacterRace)).Length-1);
public CharacterRace characterRace; public CharacterClass @class = (CharacterClass)GetRandomInt(1, Enum.GetValues(typeof(CharacterClass)).Length-1);
public CharacterClass characterClass; public EntityAttributes attributes = GetDefaultAttributes();
public EntityStats stats;
public PerksData perksData = new(); 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] [Serializable]
public sealed class CustomCharacterCreationRequest { public sealed class CustomCharacterCreationRequest {
public string id; public Guid id = Guid.Empty;
public string displayName; public string displayName;
public CharacterRace characterRace; public CharacterRace race;
public CharacterClass characterClass; public CharacterClass @class;
public EntityStats stats; public EntityStats stats;
public EntityAttributes attributes; public EntityAttributes attributes;
public PerksData perksData = new(); public PerksData perks = new();
public ModifiersData modifiersData = new(); public ModifiersData modifiers = new();
} }
public sealed class CharacterFactory : ICharacterFactory { public sealed class CharacterFactory : ICharacterFactory {
@@ -53,18 +67,18 @@ namespace Nox.Game {
var stats = statsFactory.Create(request.attributes); var stats = statsFactory.Create(request.attributes);
var character = new CharacterDefinition { var character = new CharacterDefinition {
ID = string.IsNullOrWhiteSpace(request.id) ? Guid.NewGuid().ToString("N") : request.id, ID = request.id == Guid.Empty ? Guid.NewGuid() : request.id,
DisplayName = request.displayName, Name = request.displayName,
race = request.characterRace, Race = request.race,
@class = request.characterClass, Class = request.@class,
role = CharacterRole.Protagonist, Role = CharacterRole.Protagonist,
Attributes = attributes, Attributes = attributes,
Stats = stats, Stats = stats,
perksData = request.perksData ?? new PerksData(), Perks = request.perks ?? new PerksData(),
activeModifiers = request.modifiersData ?? new ModifiersData() Modifiers = request.modifiers ?? new ModifiersData()
}; };
AddStartingPerks(character, request.perksData); AddStartingPerks(character, request.perks);
return character; return character;
} }
@@ -73,21 +87,23 @@ namespace Nox.Game {
throw new ArgumentNullException(nameof(template)); throw new ArgumentNullException(nameof(template));
} }
var attributes = attributesFactory.Create(template.attributes); template.perksData ??= new PerksData();
template.modifiersData ??= new ModifiersData();
var character = new CharacterDefinition { var character = new CharacterDefinition {
ID = string.IsNullOrWhiteSpace(template.id) ? Guid.NewGuid().ToString("N") : template.id, ID = template.id == Guid.Empty ? Guid.NewGuid() : template.id,
DisplayName = template.displayName, Name = template.displayName,
race = template.characterRace, Race = template.race,
@class = template.characterClass, Class = template.@class,
role = role, Role = role,
Attributes = attributes, Attributes = attributesFactory.Create(template.attributes),
Stats = statsFactory.Create(attributes), Stats = statsFactory.Create(template.attributes),
perksData = new PerksData(), Perks = template.perksData,
activeModifiers = new ModifiersData() Modifiers = template.modifiersData
}; };
AddStartingPerks(character, template.perksData); AddStartingPerks(character, template.perksData);
AddStartingModifiers(character, template.modifiersData);
return character; return character;
} }
@@ -97,7 +113,17 @@ namespace Nox.Game {
} }
foreach(var perkId in perkData.perks.Distinct()) { 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);
} }
} }
} }

View File

@@ -2,13 +2,13 @@ namespace Nox.Game {
public interface ICharacterSystems { public interface ICharacterSystems {
IPerkFactory PerkFactory { get; } IPerkFactory PerkFactory { get; }
IModfiersFactory ModifiersFactory { get; } IModifiersFactory ModifiersFactory { get; }
ICharacterFactory CharacterFactory { get; } ICharacterFactory CharacterFactory { get; }
IPartyFactory PartyFactory { get; } IPartyFactory PartyFactory { get; }
} }
public sealed class CharacterSystems : ICharacterSystems { 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; ModifiersFactory = modifiersFactory;
PerkFactory = perkFactory; PerkFactory = perkFactory;
CharacterFactory = characterFactory; CharacterFactory = characterFactory;
@@ -16,7 +16,7 @@ namespace Nox.Game {
} }
public IPerkFactory PerkFactory { get; } public IPerkFactory PerkFactory { get; }
public IModfiersFactory ModifiersFactory { get; } public IModifiersFactory ModifiersFactory { get; }
public ICharacterFactory CharacterFactory { get; } public ICharacterFactory CharacterFactory { get; }
public IPartyFactory PartyFactory { get; } public IPartyFactory PartyFactory { get; }
} }

View File

@@ -8,7 +8,7 @@ namespace Nox.Game {
CharacterRegistry characterRegistry, CharacterRegistry characterRegistry,
ModifiersRegistry modifiersRegistry) { ModifiersRegistry modifiersRegistry) {
IPerkFactory perkFactory = new PerkFactory(perksRegistry); IPerkFactory perkFactory = new PerkFactory(perksRegistry);
IModfiersFactory modifiersFactory = new ModifiersFactory(modifiersRegistry); IModifiersFactory modifiersFactory = new ModifiersFactory(modifiersRegistry);
ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(characterRegistry); ICharacterAttributesFactory attributesFactory = new CharacterAttributesFactory(characterRegistry);
ICharacterStatsFactory statsFactory = new CharacterStatsFactory(characterRegistry); ICharacterStatsFactory statsFactory = new CharacterStatsFactory(characterRegistry);
ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory); ICharacterFactory characterFactory = new CharacterFactory(attributesFactory, statsFactory, perkFactory);

View File

@@ -48,8 +48,8 @@ namespace Nox.Game {
var partyDefinition = testingSet.partyDefinition; var partyDefinition = testingSet.partyDefinition;
foreach(var member in partyDefinition.members) { foreach(var member in partyDefinition.members) {
var baseSettings = starterCharacterSettings.defaultEntityAttributes; var baseSettings = starterCharacterSettings.defaultEntityAttributes;
var classAttributes = starterCharacterSettings.classBonuses.FirstOrDefault(c => c.@class == member.@class)?.bonusAttributes; var classAttributes = starterCharacterSettings.classBonuses.FirstOrDefault(c => c.@class == member.Class)?.bonusAttributes;
var racialAttributes = starterCharacterSettings.racialBonuses.FirstOrDefault(rb => rb.race == member.race)?.bonusAttributes; var racialAttributes = starterCharacterSettings.racialBonuses.FirstOrDefault(rb => rb.race == member.Race)?.bonusAttributes;
if (classAttributes != null && racialAttributes != null) { if (classAttributes != null && racialAttributes != null) {
member.Attributes += baseSettings + classAttributes + racialAttributes; member.Attributes += baseSettings + classAttributes + racialAttributes;
} }

View File

@@ -6,10 +6,16 @@ using UnityEngine;
namespace Nox.Game { namespace Nox.Game {
public interface IEntityDefinition { public interface IEntityDefinition {
string ID { get; } Guid ID { get; }
string DisplayName { get; } string Name { get; }
CharacterRace Race { get; }
CharacterClass Class { get; }
CharacterRole Role { get; }
EntityAttributes Attributes { get; } EntityAttributes Attributes { get; }
EntityStats Stats { get; } EntityStats Stats { get; }
PerksData Perks { get; }
ModifiersData Modifiers { get; }
} }
public enum StatType { public enum StatType {
@@ -51,22 +57,21 @@ namespace Nox.Game {
[Serializable] [Serializable]
public sealed class Stat { public sealed class Stat {
private readonly StatType health; public StatType stat;
public StatType type;
public int value; public int value;
public Stat(StatType health, int value) { public Stat(StatType stat, int value) {
this.health = health; this.stat = stat;
this.value = value; this.value = value;
} }
} }
[Serializable] [Serializable]
public sealed record Attribute { public sealed record Attribute {
private readonly int values;
public AttributeType attribute; public AttributeType attribute;
public int value; public int value;
public Attribute(AttributeType attributeType, int values) { public Attribute(AttributeType attribute, int value) {
this.values = values; this.attribute = attribute;
this.value = value;
} }
} }
@@ -89,55 +94,37 @@ namespace Nox.Game {
public Stat[] stats; public Stat[] stats;
public int GetValue(StatType statType) { public int GetValue(StatType statType) {
return stats.First(stat => stat.type == statType).value; return stats.First(stat => stat.stat == statType).value;
} }
} }
[Serializable] [Serializable]
public sealed class CharacterDefinition : IEntityDefinition { public class CharacterDefinition : IEntityDefinition {
[SerializeField] private string id; public Guid ID { get; set; }
[SerializeField] private string displayName; [field: SerializeField] public string Name { get; set; }
public CharacterRace race; [field: SerializeField] public CharacterRace Race { get; set; }
public CharacterClass @class; [field: SerializeField] public CharacterClass Class { get; set; }
public CharacterRole role; [field: SerializeField] public CharacterRole Role { get; set; }
[SerializeField] private EntityAttributes attributes; [field: SerializeField] public EntityAttributes Attributes { get; set; }
[SerializeField] private EntityStats stats; [field: SerializeField] public EntityStats Stats { get; set; }
public PerksData perksData = new(); [field: SerializeField] public PerksData Perks { get; set; }
public ModifiersData activeModifiers = new(); [field: SerializeField] public ModifiersData Modifiers { get; set; }
public CharacterDefinition Clone() { public CharacterDefinition Clone() {
return new CharacterDefinition { return new CharacterDefinition {
id = id, ID = Guid.NewGuid(),
displayName = displayName, Name = Name,
role = role, Role = Role,
race = race, Race = Race,
@class = @class, Class = Class,
attributes = new EntityAttributes(), Attributes = Attributes,
stats = new EntityStats(), Stats = Stats,
perksData = new PerksData(), Perks = Perks,
activeModifiers = new ModifiersData() 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] [Serializable]
@@ -146,9 +133,9 @@ namespace Nox.Game {
public List<CharacterDefinition> members = new(); public List<CharacterDefinition> members = new();
[JsonIgnore] [JsonIgnore]
public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.role == CharacterRole.Protagonist); public CharacterDefinition Protagonist => members.FirstOrDefault(m => m.Role == CharacterRole.Protagonist);
[JsonIgnore] [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();
} }
} }

View File

@@ -1,14 +1,26 @@
using Jovian.InspectorTools; using Jovian.InspectorTools;
using Jovian.Logger;
using Mono.Cecil;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine;
namespace Nox.Game { namespace Nox.Game {
public interface IModfiersFactory { public interface IModifier {
IReadOnlyCollection<ModifierDefinition> GetAll(); string Name { get; }
ModifierDefinition GetById(Guid modifierId); Guid Id { get; }
IReadOnlyCollection<ModifierDefinition> GetModifiersFor(CharacterDefinition character); StatType StatType { get; }
bool TryAddModifier(CharacterDefinition character, string modiferId); 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 { public enum ModifierOperation {
@@ -20,44 +32,65 @@ namespace Nox.Game {
} }
[Serializable] [Serializable]
public sealed class ModifierDefinition { public sealed class ModifierDefinition : IModifier {
public string name; [field: SerializeField] public string Name { get; set; }
[ReadOnly] public Guid Id { get; set; }
public Guid id = Guid.NewGuid(); [field: SerializeField] public StatType StatType { get; set; }
public StatType statType; [field: SerializeField] public AttributeType AttributeType { get; set; }
public AttributeType attributeType; [field: SerializeField] public ModifierOperation Operation { get; set; }
public ModifierOperation operation; [field: SerializeField] public float Value { get; set; }
public float value;
} }
[Serializable] [Serializable]
public sealed class ModifiersData { 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 ModifiersRegistry modifiersRegistry;
private readonly Dictionary<Guid, ModifierDefinition> modifierPool = new (); private readonly Dictionary<Guid, IModifier> modifierPool = new ();
public ModifiersFactory(ModifiersRegistry modifiersRegistry) { public ModifiersFactory(ModifiersRegistry modifiersRegistry) {
this.modifiersRegistry = modifiersRegistry; this.modifiersRegistry = modifiersRegistry;
var allAvailableModifiers = modifiersRegistry.modifiersData; var allAvailableModifiers = modifiersRegistry.modifiersData;
foreach(var modifier in allAvailableModifiers.modifiers) { 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; return modifiersRegistry.modifiersData.modifiers;
} }
public ModifierDefinition GetById(Guid modifierId) { public IModifier GetById(Guid modifierId) {
return modifiersRegistry.modifiersData.modifiers.FirstOrDefault(m => m.id == modifierId); return modifiersRegistry.modifiersData.modifiers.FirstOrDefault(m => m.Id == modifierId);
} }
public IReadOnlyCollection<ModifierDefinition> GetModifiersFor(CharacterDefinition character) { public IReadOnlyCollection<IModifier> GetModifiersFor(IEntityDefinition character) {
throw new NotImplementedException(); return character.Modifiers.modifiers;
} }
public bool TryAddModifier(CharacterDefinition character, string modiferId) { public bool TryAddModifier(IEntityDefinition character, Guid modifierId) {
throw new NotImplementedException(); 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;
} }
} }
} }

View File

@@ -10,55 +10,28 @@ namespace Nox.Game {
} }
public PartyDefinition CreatePartyForNewRun(int companionCount) { public PartyDefinition CreatePartyForNewRun(int companionCount) {
var protagonist = characterFactory.CreateCustomProtagonist(new CustomCharacterCreationRequest { var protagonist = characterFactory.CreateCustomProtagonist(new CustomCharacterCreationRequest {
id = "protagonist", displayName = "John Doe",
displayName = "The Warden",
attributes = new EntityAttributes(), attributes = new EntityAttributes(),
perksData = new PerksData(){ perks = new PerksData(){
perks = new List<PerkDefinition>() 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 = { CharacterTemplate[] companionTemplates = {
// new() { new() {
// id = "companion-bruiser", displayName = "Rook",
// displayName = "Rook", attributes = rook_attributes,
// attributes = new EntityAttributes { might = 5, reflex = 2, knowledge = 1 }, perksData = new PerksData(){
// perksData = new PerksData(){ perks = new List<PerkDefinition>()
// 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>()
// }
// }
}; };
var companions = new List<CharacterDefinition>(); var companions = new List<CharacterDefinition>();

View File

@@ -24,13 +24,13 @@ namespace Nox.Game {
}; };
var protagonistClone = protagonist.Clone(); var protagonistClone = protagonist.Clone();
protagonistClone.role = CharacterRole.Protagonist; protagonistClone.Role = CharacterRole.Protagonist;
party.members.Add(protagonistClone); party.members.Add(protagonistClone);
if(companions != null) { if(companions != null) {
foreach(var companion in companions.Where(c => c != null)) { foreach(var companion in companions.Where(c => c != null)) {
var companionClone = companion.Clone(); var companionClone = companion.Clone();
companionClone.role = CharacterRole.Companion; companionClone.Role = CharacterRole.Companion;
party.members.Add(companionClone); party.members.Add(companionClone);
} }
} }
@@ -44,13 +44,13 @@ namespace Nox.Game {
throw new ArgumentException($"Party size {party.members.Count} exceeds max {party.maxPartySize}."); 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) { if(protagonistCount != 1) {
throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}."); throw new ArgumentException($"Party must contain exactly one protagonist, found {protagonistCount}.");
} }
int uniqueIds = party.members var uniqueIds = party.members
.Where(m => !string.IsNullOrWhiteSpace(m.ID)) .Where(m => m.ID != Guid.Empty)
.Select(m => m.ID) .Select(m => m.ID)
.Distinct() .Distinct()
.Count(); .Count();

View File

@@ -1,23 +1,29 @@
using Jovian.InspectorTools; using Jovian.Logger;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine;
namespace Nox.Game { namespace Nox.Game {
public interface IPerk {
Guid Id { get; }
string Name { get; }
ModifiersData Modifiers { get; }
}
public interface IPerkFactory { public interface IPerkFactory {
IReadOnlyCollection<PerkDefinition> GetAll(); IReadOnlyCollection<IPerk> GetAll();
PerkDefinition GetById(Guid perkId); IPerk GetById(Guid perkId);
IReadOnlyCollection<PerkDefinition> GetPerksFor(CharacterDefinition character); IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character);
bool TryAddPerk(CharacterDefinition character, Guid perkId); bool TryAddPerk(IEntityDefinition character, Guid perkId);
} }
[Serializable] [Serializable]
public sealed class PerkDefinition { public sealed class PerkDefinition : IPerk {
public string name; [field: SerializeField] public string Name { get; set; }
[ReadOnly] [field: SerializeField] public ModifiersData Modifiers { get; set; }
public Guid id; public Guid Id { get; set; }
public ModifiersData modifiers = new ();
} }
[Serializable] [Serializable]
@@ -26,7 +32,7 @@ namespace Nox.Game {
} }
public sealed class PerkFactory : IPerkFactory { public sealed class PerkFactory : IPerkFactory {
private readonly Dictionary<Guid, PerkDefinition> perkPool = new (); private readonly Dictionary<Guid, IPerk> perkPool = new ();
public PerkFactory(PerksRegistry perksRegistry) { public PerkFactory(PerksRegistry perksRegistry) {
if(!perksRegistry) { if(!perksRegistry) {
@@ -34,37 +40,41 @@ namespace Nox.Game {
} }
var allAvailablePerks = perksRegistry.perksData; var allAvailablePerks = perksRegistry.perksData;
foreach(var perk in allAvailablePerks.perks) { 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(); return perkPool.Values.ToList();
} }
public PerkDefinition GetById(Guid perkId) { public IPerk GetById(Guid perkId) {
perkPool.TryGetValue(perkId, out var perk); perkPool.TryGetValue(perkId, out var perk);
return perk; return perk;
} }
public IReadOnlyCollection<PerkDefinition> GetPerksFor(CharacterDefinition character) { public IReadOnlyCollection<IPerk> GetPerksFor(IEntityDefinition character) {
if(character == null) { if(character == null) {
return perkPool.Values.ToList(); return perkPool.Values.ToList();
} }
var ownedPerkIds = character.perksData.perks var ownedPerkIds = character.Perks.perks
.Select(p => p.id) .Select(p => p.Id)
.ToHashSet(); .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) { if(character == null) {
return false; 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; return false;
} }
@@ -72,10 +82,11 @@ namespace Nox.Game {
return false; return false;
} }
character.perksData.perks.Add(new PerkDefinition { character.Perks.perks.Add(new PerkDefinition {
id = perk.id, Id = perk.Id,
name = perk.name Name = perk.Name
}); });
return true; return true;
} }
} }

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace Nox.Game { namespace Nox.Game {

View File

@@ -33,33 +33,16 @@ MonoBehaviour:
value: 1 value: 1
defaultEntityStats: defaultEntityStats:
stats: stats:
- type: 3 - stat: 1
value: 1 value: 1
- type: 1 - stat: 2
value: 0 value: 0
- type: 2 - stat: 3
value: 0 value: 0
- type: 4 - stat: 4
value: 0 value: 0
defaultPerksData: defaultPerksData:
perks: [] 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: [] racialBonuses: []
classBonuses: classBonuses:
- class: 1 - class: 1
@@ -69,11 +52,4 @@ MonoBehaviour:
stats: [] stats: []
startingPerks: startingPerks:
perks: [] perks: []
permanentModifiers:
modifiers:
- name: Warrior Health per MGT
statType: 1
attributeType: 0
operation: 3
value: 4
maxPartySize: 4 maxPartySize: 4