From 9046125a959151ecb943df7dda1e0bdf47731a23 Mon Sep 17 00:00:00 2001 From: LP Date: Sat, 16 Sep 2023 17:06:19 +0100 Subject: [PATCH] Moved race and class to entity vars This is a big change but hopefully makes things far more extensible in the long run. --- appveyor.yml | 2 +- .../Types/CombatEntityVariableTypes.cs | 2 +- src/OpenRpg.Core/Classes/DefaultClass.cs | 10 ++-- src/OpenRpg.Core/Classes/DefaultMultiClass.cs | 36 +++++++++++++ src/OpenRpg.Core/Classes/IClass.cs | 5 +- src/OpenRpg.Core/Classes/IClassTemplate.cs | 2 +- src/OpenRpg.Core/Classes/IHasClass.cs | 7 --- src/OpenRpg.Core/Classes/IHasMultiClass.cs | 9 ---- src/OpenRpg.Core/Classes/IMultiClass.cs | 14 ++++++ src/OpenRpg.Core/Common/IDataTemplate.cs | 7 +++ src/OpenRpg.Core/Common/IHasTemplate.cs | 7 +++ src/OpenRpg.Core/Entity/DefaultEntity.cs | 2 - .../Entity/DefaultEntityTemplate.cs | 7 +++ .../Entity/DefaultUniqueEntity.cs | 9 ++++ src/OpenRpg.Core/Entity/IEntity.cs | 2 +- src/OpenRpg.Core/Entity/IEntityTemplate.cs | 9 ++++ src/OpenRpg.Core/Entity/IUniqueEntity.cs | 9 ++++ .../Extensions/EntityVariableExtensions.cs | 37 ++++++++++++++ .../Extensions/IClassVariableExtensions.cs | 18 +++++++ ...tion.cs => DefaultModificationTemplate.cs} | 2 +- .../Modifications/IHasModifications.cs | 2 +- ...dification.cs => IModificationTemplate.cs} | 2 +- src/OpenRpg.Core/OpenRpg.Core.csproj | 2 + src/OpenRpg.Core/Races/IRaceTemplate.cs | 2 +- .../Entity/DefaultEntityStatsVariables.cs | 2 +- ...eVariables.cs => IEntityStatsVariables.cs} | 0 src/OpenRpg.Core/Types/ClassVariableTypes.cs | 10 ++++ ...leTypes.cs => EntityStatsVariableTypes.cs} | 2 +- src/OpenRpg.Core/Types/EntityVariableTypes.cs | 5 +- src/OpenRpg.Items/DefaultItem.cs | 2 +- .../IItemEntityVariableExtensions.cs | 10 ++++ .../Extensions/IItemExtensions.cs | 2 +- src/OpenRpg.Items/IItem.cs | 2 +- .../Types/ItemEntityVariableTypes.cs | 5 +- src/OpenRpg.Quests/DefaultQuestState.cs | 28 +++++++++++ .../QuestEntityVariableExtensions.cs | 9 ++++ ...utation.cs => DefaultFactionReputation.cs} | 2 +- src/OpenRpg.Quests/IQuestState.cs | 12 +++++ .../Types/QuestEntityVariableTypes.cs | 3 +- .../Variables/DefaultFactionVariables.cs | 1 - .../Variables/DefaultQuestStateVariables.cs | 13 ----- .../Variables/IQuestStateVariables.cs | 7 --- .../CombatEntityVariableExtensionTests.cs | 21 ++++++++ .../Core/EntityVariableExtensionTests.cs | 46 +++++++++++++++++ .../Items/ItemEntityVariableExtensionTests.cs | 50 +++++++++++++++++++ .../OpenRpg.UnitTests.csproj | 2 + .../Quest/ItemEntityVariableExtensionTests.cs | 34 +++++++++++++ 47 files changed, 405 insertions(+), 67 deletions(-) create mode 100644 src/OpenRpg.Core/Classes/DefaultMultiClass.cs delete mode 100644 src/OpenRpg.Core/Classes/IHasClass.cs delete mode 100644 src/OpenRpg.Core/Classes/IHasMultiClass.cs create mode 100644 src/OpenRpg.Core/Classes/IMultiClass.cs create mode 100644 src/OpenRpg.Core/Common/IDataTemplate.cs create mode 100644 src/OpenRpg.Core/Common/IHasTemplate.cs create mode 100644 src/OpenRpg.Core/Entity/DefaultEntityTemplate.cs create mode 100644 src/OpenRpg.Core/Entity/DefaultUniqueEntity.cs create mode 100644 src/OpenRpg.Core/Entity/IEntityTemplate.cs create mode 100644 src/OpenRpg.Core/Entity/IUniqueEntity.cs create mode 100644 src/OpenRpg.Core/Extensions/EntityVariableExtensions.cs create mode 100644 src/OpenRpg.Core/Extensions/IClassVariableExtensions.cs rename src/OpenRpg.Core/Modifications/{DefaultModification.cs => DefaultModificationTemplate.cs} (85%) rename src/OpenRpg.Core/Modifications/{IModification.cs => IModificationTemplate.cs} (63%) rename src/OpenRpg.Core/Stats/Entity/{IEntityStateVariables.cs => IEntityStatsVariables.cs} (100%) create mode 100644 src/OpenRpg.Core/Types/ClassVariableTypes.cs rename src/OpenRpg.Core/Types/{StatsVariableTypes.cs => EntityStatsVariableTypes.cs} (66%) create mode 100644 src/OpenRpg.Quests/DefaultQuestState.cs rename src/OpenRpg.Quests/Factions/{FactionReputation.cs => DefaultFactionReputation.cs} (92%) create mode 100644 src/OpenRpg.Quests/IQuestState.cs delete mode 100644 src/OpenRpg.Quests/Variables/DefaultQuestStateVariables.cs delete mode 100644 src/OpenRpg.Quests/Variables/IQuestStateVariables.cs create mode 100644 src/OpenRpg.UnitTests/Combat/CombatEntityVariableExtensionTests.cs create mode 100644 src/OpenRpg.UnitTests/Core/EntityVariableExtensionTests.cs create mode 100644 src/OpenRpg.UnitTests/Items/ItemEntityVariableExtensionTests.cs create mode 100644 src/OpenRpg.UnitTests/Quest/ItemEntityVariableExtensionTests.cs diff --git a/appveyor.yml b/appveyor.yml index 8b000b8..53e500b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.30.{build} +version: 0.31.{build} branches: only: - master diff --git a/src/OpenRpg.Combat/Types/CombatEntityVariableTypes.cs b/src/OpenRpg.Combat/Types/CombatEntityVariableTypes.cs index 7a2fe7a..20d9a20 100644 --- a/src/OpenRpg.Combat/Types/CombatEntityVariableTypes.cs +++ b/src/OpenRpg.Combat/Types/CombatEntityVariableTypes.cs @@ -4,6 +4,6 @@ namespace OpenRpg.Combat.Types { public interface CombatEntityVariableTypes : EntityVariableTypes { - public static readonly int ActiveEffects = 10; + public static readonly int ActiveEffects = 20; } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/DefaultClass.cs b/src/OpenRpg.Core/Classes/DefaultClass.cs index 040d32c..3aadfde 100644 --- a/src/OpenRpg.Core/Classes/DefaultClass.cs +++ b/src/OpenRpg.Core/Classes/DefaultClass.cs @@ -4,16 +4,12 @@ namespace OpenRpg.Core.Classes { public class DefaultClass : IClass { - public int Level { get; set; } - public IClassTemplate ClassTemplate { get; set; } + public IClassTemplate Template { get; set; } = new DefaultClassTemplate(); public IClassVariables Variables { get; set; } = new DefaultClassVariables(); public DefaultClass(){} - public DefaultClass(int level, IClassTemplate classTemplate) - { - Level = level; - ClassTemplate = classTemplate; - } + public DefaultClass(IClassTemplate template) + { Template = template; } } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/DefaultMultiClass.cs b/src/OpenRpg.Core/Classes/DefaultMultiClass.cs new file mode 100644 index 0000000..4a6856c --- /dev/null +++ b/src/OpenRpg.Core/Classes/DefaultMultiClass.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; + +namespace OpenRpg.Core.Classes +{ + public class DefaultMultiClass : IMultiClass + { + public Dictionary InternalClasses { get; set; } = new Dictionary(); + + public IEnumerable Classes => InternalClasses.Values; + + public void AddClass(IClass classToAdd) + { + if (!HasClass(classToAdd.Template.Id)) + { InternalClasses.Add(classToAdd.Template.Id, classToAdd); } + } + + public void RemoveClass(int classTemplateId) + { + if (HasClass(classTemplateId)) + { InternalClasses.Remove(classTemplateId); } + } + + public IClass GetClass(int classTemplateId) + { return HasClass(classTemplateId) ? InternalClasses[classTemplateId] : null; } + + public bool HasClass(int classTemplateId) + { return InternalClasses.ContainsKey(classTemplateId); } + + public DefaultMultiClass() + {} + + public DefaultMultiClass(IEnumerable classes) + { InternalClasses = classes.ToDictionary(x => x.Template.Id, x => x); } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/IClass.cs b/src/OpenRpg.Core/Classes/IClass.cs index d8b6ec9..124bc9d 100644 --- a/src/OpenRpg.Core/Classes/IClass.cs +++ b/src/OpenRpg.Core/Classes/IClass.cs @@ -1,11 +1,10 @@ using OpenRpg.Core.Classes.Variables; +using OpenRpg.Core.Common; using OpenRpg.Core.Variables.General; namespace OpenRpg.Core.Classes { - public interface IClass : IHasVariables + public interface IClass : IHasVariables, IHasTemplate { - int Level { get; set; } - IClassTemplate ClassTemplate { get; } } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/IClassTemplate.cs b/src/OpenRpg.Core/Classes/IClassTemplate.cs index 9b093df..0d54344 100644 --- a/src/OpenRpg.Core/Classes/IClassTemplate.cs +++ b/src/OpenRpg.Core/Classes/IClassTemplate.cs @@ -6,7 +6,7 @@ namespace OpenRpg.Core.Classes { - public interface IClassTemplate : IHasDataId, IHasEffects, IHasRequirements, IHasLocaleDescription, IHasVariables + public interface IClassTemplate : IDataTemplate, IHasEffects, IHasRequirements, IHasVariables { } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/IHasClass.cs b/src/OpenRpg.Core/Classes/IHasClass.cs deleted file mode 100644 index 0313e44..0000000 --- a/src/OpenRpg.Core/Classes/IHasClass.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace OpenRpg.Core.Classes -{ - public interface IHasClass - { - IClass Class { get; } - } -} \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/IHasMultiClass.cs b/src/OpenRpg.Core/Classes/IHasMultiClass.cs deleted file mode 100644 index 1ce58dd..0000000 --- a/src/OpenRpg.Core/Classes/IHasMultiClass.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace OpenRpg.Core.Classes -{ - public interface IHasMultiClass - { - IEnumerable Classes { get; } - } -} \ No newline at end of file diff --git a/src/OpenRpg.Core/Classes/IMultiClass.cs b/src/OpenRpg.Core/Classes/IMultiClass.cs new file mode 100644 index 0000000..01b3c1a --- /dev/null +++ b/src/OpenRpg.Core/Classes/IMultiClass.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace OpenRpg.Core.Classes +{ + public interface IMultiClass + { + IEnumerable Classes { get; } + + void AddClass(IClass classToAdd); + void RemoveClass(int classIdToRemove); + IClass GetClass(int classIdGet); + bool HasClass(int classTemplateId); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Common/IDataTemplate.cs b/src/OpenRpg.Core/Common/IDataTemplate.cs new file mode 100644 index 0000000..89c98b5 --- /dev/null +++ b/src/OpenRpg.Core/Common/IDataTemplate.cs @@ -0,0 +1,7 @@ +namespace OpenRpg.Core.Common +{ + public interface IDataTemplate : IHasDataId, IHasLocaleDescription + { + + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Common/IHasTemplate.cs b/src/OpenRpg.Core/Common/IHasTemplate.cs new file mode 100644 index 0000000..60e0e2a --- /dev/null +++ b/src/OpenRpg.Core/Common/IHasTemplate.cs @@ -0,0 +1,7 @@ +namespace OpenRpg.Core.Common +{ + public interface IHasTemplate where T : IDataTemplate + { + T Template { get; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Entity/DefaultEntity.cs b/src/OpenRpg.Core/Entity/DefaultEntity.cs index f0516f4..9a33ce2 100644 --- a/src/OpenRpg.Core/Entity/DefaultEntity.cs +++ b/src/OpenRpg.Core/Entity/DefaultEntity.cs @@ -1,4 +1,3 @@ -using System; using OpenRpg.Core.State.Entity; using OpenRpg.Core.Stats.Entity; using OpenRpg.Core.Variables.Entity; @@ -10,7 +9,6 @@ namespace OpenRpg.Core.Entity /// public class DefaultEntity : IEntity { - public Guid UniqueId { get; set; } = Guid.NewGuid(); public string NameLocaleId { get; set; } = string.Empty; public string DescriptionLocaleId { get; set; } = string.Empty; public IEntityStatsVariables Stats { get; set; } = new DefaultEntityStatsVariables(); diff --git a/src/OpenRpg.Core/Entity/DefaultEntityTemplate.cs b/src/OpenRpg.Core/Entity/DefaultEntityTemplate.cs new file mode 100644 index 0000000..55026b4 --- /dev/null +++ b/src/OpenRpg.Core/Entity/DefaultEntityTemplate.cs @@ -0,0 +1,7 @@ +namespace OpenRpg.Core.Entity +{ + public class DefaultEntityTemplate : DefaultEntity, IEntityTemplate + { + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Entity/DefaultUniqueEntity.cs b/src/OpenRpg.Core/Entity/DefaultUniqueEntity.cs new file mode 100644 index 0000000..eb63327 --- /dev/null +++ b/src/OpenRpg.Core/Entity/DefaultUniqueEntity.cs @@ -0,0 +1,9 @@ +using System; + +namespace OpenRpg.Core.Entity +{ + public class DefaultUniqueEntity : DefaultEntity, IUniqueEntity + { + public Guid UniqueId { get; set; } = Guid.NewGuid(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Entity/IEntity.cs b/src/OpenRpg.Core/Entity/IEntity.cs index b409744..cc81e00 100644 --- a/src/OpenRpg.Core/Entity/IEntity.cs +++ b/src/OpenRpg.Core/Entity/IEntity.cs @@ -16,7 +16,7 @@ namespace OpenRpg.Core.Entity /// to add additional requirements on but this gives a building block to allow more functionality in /// the base layers. /// - public interface IEntity : IIsUnique, IHasLocaleDescription, + public interface IEntity : IHasLocaleDescription, IHasState, IHasStats, IHasVariables {} } \ No newline at end of file diff --git a/src/OpenRpg.Core/Entity/IEntityTemplate.cs b/src/OpenRpg.Core/Entity/IEntityTemplate.cs new file mode 100644 index 0000000..6deb82d --- /dev/null +++ b/src/OpenRpg.Core/Entity/IEntityTemplate.cs @@ -0,0 +1,9 @@ +using OpenRpg.Core.Common; + +namespace OpenRpg.Core.Entity +{ + public interface IEntityTemplate : IDataTemplate, IEntity + { + + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Entity/IUniqueEntity.cs b/src/OpenRpg.Core/Entity/IUniqueEntity.cs new file mode 100644 index 0000000..58085da --- /dev/null +++ b/src/OpenRpg.Core/Entity/IUniqueEntity.cs @@ -0,0 +1,9 @@ +using OpenRpg.Core.Common; + +namespace OpenRpg.Core.Entity +{ + public interface IUniqueEntity : IIsUnique, IEntity + { + + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Extensions/EntityVariableExtensions.cs b/src/OpenRpg.Core/Extensions/EntityVariableExtensions.cs new file mode 100644 index 0000000..703e55c --- /dev/null +++ b/src/OpenRpg.Core/Extensions/EntityVariableExtensions.cs @@ -0,0 +1,37 @@ +using OpenRpg.Core.Classes; +using OpenRpg.Core.Races; +using OpenRpg.Core.Types; +using OpenRpg.Core.Variables.Entity; + +namespace OpenRpg.Core.Extensions +{ + public static class EntityVariableExtensions + { + public static bool HasRace(this IEntityVariables vars) + { return vars.ContainsKey(EntityVariableTypes.Race); } + + public static IRaceTemplate Race(this IEntityVariables vars) + { return vars[EntityVariableTypes.Race] as IRaceTemplate; } + + public static void Race(this IEntityVariables vars, IRaceTemplate race) + { vars[EntityVariableTypes.Race] = race; } + + public static bool HasClass(this IEntityVariables vars) + { return vars.ContainsKey(EntityVariableTypes.Class); } + + public static IClass Class(this IEntityVariables vars) + { return vars[EntityVariableTypes.Class] as IClass; } + + public static void Class(this IEntityVariables vars, IClass classToUse) + { vars[EntityVariableTypes.Class] = classToUse; } + + public static bool HasMultiClass(this IEntityVariables vars) + { return vars.ContainsKey(EntityVariableTypes.MultiClasses); } + + public static IMultiClass MultiClass(this IEntityVariables vars) + { return vars[EntityVariableTypes.MultiClasses] as IMultiClass; } + + public static void MultiClass(this IEntityVariables vars, IMultiClass multiClass) + { vars[EntityVariableTypes.MultiClasses] = multiClass; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Extensions/IClassVariableExtensions.cs b/src/OpenRpg.Core/Extensions/IClassVariableExtensions.cs new file mode 100644 index 0000000..974c899 --- /dev/null +++ b/src/OpenRpg.Core/Extensions/IClassVariableExtensions.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Linq; +using OpenRpg.Core.Classes.Variables; +using OpenRpg.Core.Effects; +using OpenRpg.Core.Types; + +namespace OpenRpg.Core.Extensions +{ + public static class IClassVariableExtensions + { + public static int Level(this IClassVariables vars) => (int)vars.Get(ClassVariableTypes.Level); + public static void Level(this IClassVariables vars, int level) => vars[ClassVariableTypes.Level] = level; + + public static int Experience(this IClassVariables vars) => (int)vars.Get(ClassVariableTypes.Experience); + public static void Experience(this IClassVariables vars, int experience) => vars[ClassVariableTypes.Experience] = experience; + public static void AddExperience(this IClassVariables state, int change) => state.Experience(state.Experience() + change); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Modifications/DefaultModification.cs b/src/OpenRpg.Core/Modifications/DefaultModificationTemplate.cs similarity index 85% rename from src/OpenRpg.Core/Modifications/DefaultModification.cs rename to src/OpenRpg.Core/Modifications/DefaultModificationTemplate.cs index 097dcbc..ceb8864 100644 --- a/src/OpenRpg.Core/Modifications/DefaultModification.cs +++ b/src/OpenRpg.Core/Modifications/DefaultModificationTemplate.cs @@ -4,7 +4,7 @@ namespace OpenRpg.Core.Modifications { - public class DefaultModification : IModification + public class DefaultModificationTemplate : IModificationTemplate { public int Id { get; set; } public IEnumerable Effects { get; set; } = Array.Empty(); diff --git a/src/OpenRpg.Core/Modifications/IHasModifications.cs b/src/OpenRpg.Core/Modifications/IHasModifications.cs index f5568da..1975242 100644 --- a/src/OpenRpg.Core/Modifications/IHasModifications.cs +++ b/src/OpenRpg.Core/Modifications/IHasModifications.cs @@ -4,6 +4,6 @@ namespace OpenRpg.Core.Modifications { public interface IHasModifications { - IEnumerable Modifications { get; } + IEnumerable Modifications { get; } } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Modifications/IModification.cs b/src/OpenRpg.Core/Modifications/IModificationTemplate.cs similarity index 63% rename from src/OpenRpg.Core/Modifications/IModification.cs rename to src/OpenRpg.Core/Modifications/IModificationTemplate.cs index e07ed71..f504b10 100644 --- a/src/OpenRpg.Core/Modifications/IModification.cs +++ b/src/OpenRpg.Core/Modifications/IModificationTemplate.cs @@ -3,7 +3,7 @@ namespace OpenRpg.Core.Modifications { - public interface IModification : IHasDataId, IHasEffects, IHasLocaleDescription + public interface IModificationTemplate : IDataTemplate, IHasEffects { int ModificationType { get; } } diff --git a/src/OpenRpg.Core/OpenRpg.Core.csproj b/src/OpenRpg.Core/OpenRpg.Core.csproj index e4fa29c..305907a 100644 --- a/src/OpenRpg.Core/OpenRpg.Core.csproj +++ b/src/OpenRpg.Core/OpenRpg.Core.csproj @@ -11,6 +11,8 @@ rpg game-development xna monogame unity godot 8 + + diff --git a/src/OpenRpg.Core/Races/IRaceTemplate.cs b/src/OpenRpg.Core/Races/IRaceTemplate.cs index 237165b..e6aa1b2 100644 --- a/src/OpenRpg.Core/Races/IRaceTemplate.cs +++ b/src/OpenRpg.Core/Races/IRaceTemplate.cs @@ -6,7 +6,7 @@ namespace OpenRpg.Core.Races { - public interface IRaceTemplate : IHasDataId, IHasEffects, IHasRequirements, IHasLocaleDescription, IHasVariables + public interface IRaceTemplate : IDataTemplate, IHasEffects, IHasRequirements, IHasVariables { } } \ No newline at end of file diff --git a/src/OpenRpg.Core/Stats/Entity/DefaultEntityStatsVariables.cs b/src/OpenRpg.Core/Stats/Entity/DefaultEntityStatsVariables.cs index 8839e6e..cce2932 100644 --- a/src/OpenRpg.Core/Stats/Entity/DefaultEntityStatsVariables.cs +++ b/src/OpenRpg.Core/Stats/Entity/DefaultEntityStatsVariables.cs @@ -6,7 +6,7 @@ namespace OpenRpg.Core.Stats.Entity { public class DefaultEntityStatsVariables : DefaultVariables, IEntityStatsVariables { - public DefaultEntityStatsVariables(IDictionary internalVariables = null) : base(CoreVariableTypes.EntityStateVariables, internalVariables) + public DefaultEntityStatsVariables(IDictionary internalVariables = null) : base(CoreVariableTypes.EntityStatsVariables, internalVariables) { } } diff --git a/src/OpenRpg.Core/Stats/Entity/IEntityStateVariables.cs b/src/OpenRpg.Core/Stats/Entity/IEntityStatsVariables.cs similarity index 100% rename from src/OpenRpg.Core/Stats/Entity/IEntityStateVariables.cs rename to src/OpenRpg.Core/Stats/Entity/IEntityStatsVariables.cs diff --git a/src/OpenRpg.Core/Types/ClassVariableTypes.cs b/src/OpenRpg.Core/Types/ClassVariableTypes.cs new file mode 100644 index 0000000..e54a093 --- /dev/null +++ b/src/OpenRpg.Core/Types/ClassVariableTypes.cs @@ -0,0 +1,10 @@ +namespace OpenRpg.Core.Types +{ + public interface ClassVariableTypes + { + public static readonly int Unknown = 0; + + public static readonly int Level = 1; + public static readonly int Experience = 2; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Core/Types/StatsVariableTypes.cs b/src/OpenRpg.Core/Types/EntityStatsVariableTypes.cs similarity index 66% rename from src/OpenRpg.Core/Types/StatsVariableTypes.cs rename to src/OpenRpg.Core/Types/EntityStatsVariableTypes.cs index 6c3b051..0ba0722 100644 --- a/src/OpenRpg.Core/Types/StatsVariableTypes.cs +++ b/src/OpenRpg.Core/Types/EntityStatsVariableTypes.cs @@ -1,6 +1,6 @@ namespace OpenRpg.Core.Types { - public interface StatsVariableTypes + public interface EntityStatsVariableTypes { public static readonly int Unknown = 0; } diff --git a/src/OpenRpg.Core/Types/EntityVariableTypes.cs b/src/OpenRpg.Core/Types/EntityVariableTypes.cs index 3552785..10e55d4 100644 --- a/src/OpenRpg.Core/Types/EntityVariableTypes.cs +++ b/src/OpenRpg.Core/Types/EntityVariableTypes.cs @@ -2,7 +2,10 @@ namespace OpenRpg.Core.Types { public interface EntityVariableTypes { - // Unknown public static readonly int Unknown = 0; + + public static readonly int Race = 1; + public static readonly int Class = 2; + public static readonly int MultiClasses = 3; } } \ No newline at end of file diff --git a/src/OpenRpg.Items/DefaultItem.cs b/src/OpenRpg.Items/DefaultItem.cs index efac771..b6a95f3 100644 --- a/src/OpenRpg.Items/DefaultItem.cs +++ b/src/OpenRpg.Items/DefaultItem.cs @@ -11,7 +11,7 @@ public class DefaultItem : IUniqueItem public Guid UniqueId { get; set; } = Guid.NewGuid(); public IItemTemplate ItemTemplate { get; set; } = new DefaultItemTemplate(); - public IEnumerable Modifications { get; set;} = new List(); + public IEnumerable Modifications { get; set;} = new List(); public IItemVariables Variables { get; set; } = new DefaultItemVariables(); } } \ No newline at end of file diff --git a/src/OpenRpg.Items/Extensions/IItemEntityVariableExtensions.cs b/src/OpenRpg.Items/Extensions/IItemEntityVariableExtensions.cs index 806e3f9..a8a9acb 100644 --- a/src/OpenRpg.Items/Extensions/IItemEntityVariableExtensions.cs +++ b/src/OpenRpg.Items/Extensions/IItemEntityVariableExtensions.cs @@ -1,6 +1,7 @@ using OpenRpg.Core.Variables.Entity; using OpenRpg.Items.Equipment; using OpenRpg.Items.Inventory; +using OpenRpg.Items.Loot; using OpenRpg.Items.Types; namespace OpenRpg.Items.Extensions @@ -27,5 +28,14 @@ public static IInventory Inventory(this IEntityVariables vars) public static void Inventory(this IEntityVariables vars, IInventory inventory) { vars[ItemEntityVariableTypes.Inventory] = inventory; } + + public static bool HasLootTable(this IEntityVariables vars) + { return vars.ContainsKey(ItemEntityVariableTypes.LootTable); } + + public static ILootTable LootTable(this IEntityVariables vars) + { return vars[ItemEntityVariableTypes.LootTable] as ILootTable; } + + public static void LootTable(this IEntityVariables vars, ILootTable lootTable) + { vars[ItemEntityVariableTypes.LootTable] = lootTable; } } } \ No newline at end of file diff --git a/src/OpenRpg.Items/Extensions/IItemExtensions.cs b/src/OpenRpg.Items/Extensions/IItemExtensions.cs index c99b103..1451572 100644 --- a/src/OpenRpg.Items/Extensions/IItemExtensions.cs +++ b/src/OpenRpg.Items/Extensions/IItemExtensions.cs @@ -22,7 +22,7 @@ public static IItem Clone(this DefaultItem item) { ItemTemplate = item.ItemTemplate, Variables = (item.Variables as DefaultItemVariables).Clone(), - Modifications = new List(item.Modifications) + Modifications = new List(item.Modifications) }; } diff --git a/src/OpenRpg.Items/IItem.cs b/src/OpenRpg.Items/IItem.cs index 439ae96..7c10560 100644 --- a/src/OpenRpg.Items/IItem.cs +++ b/src/OpenRpg.Items/IItem.cs @@ -8,7 +8,7 @@ namespace OpenRpg.Items public interface IItem { IItemTemplate ItemTemplate { get; } - IEnumerable Modifications { get; } + IEnumerable Modifications { get; } IItemVariables Variables { get; } } } \ No newline at end of file diff --git a/src/OpenRpg.Items/Types/ItemEntityVariableTypes.cs b/src/OpenRpg.Items/Types/ItemEntityVariableTypes.cs index 020b695..0f79ede 100644 --- a/src/OpenRpg.Items/Types/ItemEntityVariableTypes.cs +++ b/src/OpenRpg.Items/Types/ItemEntityVariableTypes.cs @@ -4,7 +4,8 @@ namespace OpenRpg.Items.Types { public interface ItemEntityVariableTypes : EntityVariableTypes { - public static readonly int Equipment = 1; - public static readonly int Inventory = 2; + public static readonly int Equipment = 10; + public static readonly int Inventory = 11; + public static readonly int LootTable = 12; } } \ No newline at end of file diff --git a/src/OpenRpg.Quests/DefaultQuestState.cs b/src/OpenRpg.Quests/DefaultQuestState.cs new file mode 100644 index 0000000..d391bad --- /dev/null +++ b/src/OpenRpg.Quests/DefaultQuestState.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using OpenRpg.Quests.Types; + +namespace OpenRpg.Quests +{ + public class DefaultQuestState : IQuestState + { + public Dictionary InternalQuestStates { get; set; } = new Dictionary(); + + public IReadOnlyDictionary QuestStates => InternalQuestStates; + + public int GetQuestState(int questId) + { + return InternalQuestStates.TryGetValue(questId, out var state) + ? state + : QuestStateTypes.QuestNotStarted; + } + + public void SetQuestState(int questId, int questState) + { InternalQuestStates[questId] = questState; } + + public DefaultQuestState() + {} + + public DefaultQuestState(Dictionary questStates) + { InternalQuestStates = questStates; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs b/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs index 79b4600..35b4aa2 100644 --- a/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs +++ b/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs @@ -14,5 +14,14 @@ public static IFactionReputation FactionReputation(this IEntityVariables vars) public static void FactionReputation(this IEntityVariables vars, IFactionReputation factionReputation) { vars[QuestEntityVariableTypes.FactionReputation] = factionReputation; } + + public static bool HasQuestState(this IEntityVariables vars) + { return vars.ContainsKey(QuestEntityVariableTypes.QuestState); } + + public static IQuestState QuestState(this IEntityVariables vars) + { return vars[QuestEntityVariableTypes.QuestState] as IQuestState; } + + public static void QuestState(this IEntityVariables vars, IQuestState questState) + { vars[QuestEntityVariableTypes.QuestState] = questState; } } } \ No newline at end of file diff --git a/src/OpenRpg.Quests/Factions/FactionReputation.cs b/src/OpenRpg.Quests/Factions/DefaultFactionReputation.cs similarity index 92% rename from src/OpenRpg.Quests/Factions/FactionReputation.cs rename to src/OpenRpg.Quests/Factions/DefaultFactionReputation.cs index e6f3773..bf91376 100644 --- a/src/OpenRpg.Quests/Factions/FactionReputation.cs +++ b/src/OpenRpg.Quests/Factions/DefaultFactionReputation.cs @@ -2,7 +2,7 @@ namespace OpenRpg.Quests.Factions { - public class FactionReputation : IFactionReputation + public class DefaultFactionReputation : IFactionReputation { public Dictionary InternalFactionReputation { get; set; } = new Dictionary(); diff --git a/src/OpenRpg.Quests/IQuestState.cs b/src/OpenRpg.Quests/IQuestState.cs new file mode 100644 index 0000000..d29574e --- /dev/null +++ b/src/OpenRpg.Quests/IQuestState.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace OpenRpg.Quests +{ + public interface IQuestState + { + IReadOnlyDictionary QuestStates { get; } + + int GetQuestState(int questId); + void SetQuestState(int questId, int questState); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs b/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs index 1e7731d..f63a36f 100644 --- a/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs +++ b/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs @@ -4,6 +4,7 @@ namespace OpenRpg.Quests.Types { public interface QuestEntityVariableTypes : EntityVariableTypes { - public static int FactionReputation = 20; + public static int FactionReputation = 30; + public static int QuestState = 31; } } \ No newline at end of file diff --git a/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs b/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs index 8ed5f1f..2df3ec2 100644 --- a/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs +++ b/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using OpenRpg.Core.Variables; using OpenRpg.Core.Variables.General; using OpenRpg.Quests.Types; diff --git a/src/OpenRpg.Quests/Variables/DefaultQuestStateVariables.cs b/src/OpenRpg.Quests/Variables/DefaultQuestStateVariables.cs deleted file mode 100644 index 83b30b2..0000000 --- a/src/OpenRpg.Quests/Variables/DefaultQuestStateVariables.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using OpenRpg.Core.Variables; -using OpenRpg.Quests.Types; - -namespace OpenRpg.Quests.Variables -{ - public class DefaultQuestStateVariables : DefaultVariables, IQuestStateVariables - { - public DefaultQuestStateVariables(IDictionary internalVariables = null) : base(QuestVariableTypes.QuestStateVariables, internalVariables) - { - } - } -} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Variables/IQuestStateVariables.cs b/src/OpenRpg.Quests/Variables/IQuestStateVariables.cs deleted file mode 100644 index 0d3bfe4..0000000 --- a/src/OpenRpg.Quests/Variables/IQuestStateVariables.cs +++ /dev/null @@ -1,7 +0,0 @@ -using OpenRpg.Core.Variables; - -namespace OpenRpg.Quests.Variables -{ - public interface IQuestStateVariables : IVariables - {} -} \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/Combat/CombatEntityVariableExtensionTests.cs b/src/OpenRpg.UnitTests/Combat/CombatEntityVariableExtensionTests.cs new file mode 100644 index 0000000..b6a1421 --- /dev/null +++ b/src/OpenRpg.UnitTests/Combat/CombatEntityVariableExtensionTests.cs @@ -0,0 +1,21 @@ +using OpenRpg.Combat.Effects; +using OpenRpg.Combat.Extensions; +using OpenRpg.Core.Variables.Entity; +using Xunit; + +namespace OpenRpg.UnitTests.Combat; + +public class CombatEntityVariableExtensionTests +{ + [Fact] + public void should_correctly_handle_activeeffects_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasActiveEffects()); + + var dummyActiveEffects = new DefaultActiveEffects(); + entityVars.ActiveEffects(dummyActiveEffects); + Assert.True(entityVars.HasActiveEffects()); + Assert.Equal(entityVars.ActiveEffects(), dummyActiveEffects); + } +} \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/Core/EntityVariableExtensionTests.cs b/src/OpenRpg.UnitTests/Core/EntityVariableExtensionTests.cs new file mode 100644 index 0000000..58c5b1e --- /dev/null +++ b/src/OpenRpg.UnitTests/Core/EntityVariableExtensionTests.cs @@ -0,0 +1,46 @@ +using OpenRpg.Core.Classes; +using OpenRpg.Core.Extensions; +using OpenRpg.Core.Races; +using OpenRpg.Core.Variables.Entity; +using Xunit; + +namespace OpenRpg.UnitTests.Core; + +public class EntityVariableExtensionTests +{ + [Fact] + public void should_correctly_handle_race_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasRace()); + + var dummyRaceTemplate = new DefaultRaceTemplate(); + entityVars.Race(dummyRaceTemplate); + Assert.True(entityVars.HasRace()); + Assert.Equal(entityVars.Race(), dummyRaceTemplate); + } + + [Fact] + public void should_correctly_handle_class_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasClass()); + + var dummyClass = new DefaultClass(); + entityVars.Class(dummyClass); + Assert.True(entityVars.HasClass()); + Assert.Equal(entityVars.Class(), dummyClass); + } + + [Fact] + public void should_correctly_handle_multiclass_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasMultiClass()); + + var dummyMultiClass = new DefaultMultiClass(); + entityVars.MultiClass(dummyMultiClass); + Assert.True(entityVars.HasMultiClass()); + Assert.Equal(entityVars.MultiClass(), dummyMultiClass); + } +} \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/Items/ItemEntityVariableExtensionTests.cs b/src/OpenRpg.UnitTests/Items/ItemEntityVariableExtensionTests.cs new file mode 100644 index 0000000..74a4798 --- /dev/null +++ b/src/OpenRpg.UnitTests/Items/ItemEntityVariableExtensionTests.cs @@ -0,0 +1,50 @@ +using OpenRpg.Core.Classes; +using OpenRpg.Core.Extensions; +using OpenRpg.Core.Races; +using OpenRpg.Core.Variables.Entity; +using OpenRpg.Items.Equipment; +using OpenRpg.Items.Extensions; +using OpenRpg.Items.Inventory; +using OpenRpg.Items.Loot; +using Xunit; + +namespace OpenRpg.UnitTests.Items; + +public class ItemEntityVariableExtensionTests +{ + [Fact] + public void should_correctly_handle_inventory_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasInventory()); + + var dummyInventory = new DefaultInventory(); + entityVars.Inventory(dummyInventory); + Assert.True(entityVars.HasInventory()); + Assert.Equal(entityVars.Inventory(), dummyInventory); + } + + [Fact] + public void should_correctly_handle_equipment_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasEquipment()); + + var dummyEquipment = new DefaultEquipment(); + entityVars.Equipment(dummyEquipment); + Assert.True(entityVars.HasEquipment()); + Assert.Equal(entityVars.Equipment(), dummyEquipment); + } + + [Fact] + public void should_correctly_handle_loot_table_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasLootTable()); + + var dummyLootTable = new DefaultLootTable(); + entityVars.LootTable(dummyLootTable); + Assert.True(entityVars.HasLootTable()); + Assert.Equal(entityVars.LootTable(), dummyLootTable); + } +} \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj index 877a1bc..9fc2ffa 100644 --- a/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj +++ b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj @@ -26,8 +26,10 @@ + + diff --git a/src/OpenRpg.UnitTests/Quest/ItemEntityVariableExtensionTests.cs b/src/OpenRpg.UnitTests/Quest/ItemEntityVariableExtensionTests.cs new file mode 100644 index 0000000..8fcfb91 --- /dev/null +++ b/src/OpenRpg.UnitTests/Quest/ItemEntityVariableExtensionTests.cs @@ -0,0 +1,34 @@ +using OpenRpg.Core.Variables.Entity; +using OpenRpg.Quests; +using OpenRpg.Quests.Extensions; +using OpenRpg.Quests.Factions; +using Xunit; + +namespace OpenRpg.UnitTests.Quest; + +public class QuestEntityVariableExtensionTests +{ + [Fact] + public void should_correctly_handle_faction_reputation_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasFactionReputation()); + + var dummyFactionRep = new DefaultFactionReputation(); + entityVars.FactionReputation(dummyFactionRep); + Assert.True(entityVars.HasFactionReputation()); + Assert.Equal(entityVars.FactionReputation(), dummyFactionRep); + } + + [Fact] + public void should_correctly_handle_quest_state_on_entity() + { + var entityVars = new DefaultEntityVariables(); + Assert.False(entityVars.HasQuestState()); + + var dummyQuestState = new DefaultQuestState(); + entityVars.QuestState(dummyQuestState); + Assert.True(entityVars.HasQuestState()); + Assert.Equal(entityVars.QuestState(), dummyQuestState); + } +} \ No newline at end of file