diff --git a/appveyor.yml b/appveyor.yml index f1a39cc..8b000b8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.29.{build} +version: 0.30.{build} branches: only: - master diff --git a/build/pack.bat b/build/pack.bat index 3f5d7de..bce98d8 100644 --- a/build/pack.bat +++ b/build/pack.bat @@ -1,4 +1,4 @@ -set version=0.19.00 +set version=0.29.00 dotnet pack ../src/OpenRpg.Core -c Release -o ../../_dist /p:version=%version% dotnet pack ../src/OpenRpg.Items -c Release -o ../../_dist /p:version=%version% dotnet pack ../src/OpenRpg.Combat -c Release -o ../../_dist /p:version=%version% @@ -10,4 +10,5 @@ dotnet pack ../src/OpenRpg.Quests -c Release -o ../../_dist /p:version=%version% dotnet pack ../src/OpenRpg.Genres.Fantasy -c Release -o ../../_dist /p:version=%version% dotnet pack ../src/OpenRpg.Cards -c Release -o ../../_dist /p:version=%version% dotnet pack ../src/OpenRpg.CurveFunctions -c Release -o ../../_dist /p:version=%version% -dotnet pack ../src/OpenRpg.Tags -c Release -o ../../_dist /p:version=%version% \ No newline at end of file +dotnet pack ../src/OpenRpg.Tags -c Release -o ../../_dist /p:version=%version% +dotnet pack ../src/OpenRpg.Items.TradeSkills -c Release -o ../../_dist /p:version=%version% \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Calculator/ITradeSkillCalculator.cs b/src/OpenRpg.Items.TradeSkills/Calculator/ITradeSkillCalculator.cs new file mode 100644 index 0000000..d2a4c46 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Calculator/ITradeSkillCalculator.cs @@ -0,0 +1,12 @@ +namespace OpenRpg.Items.TradeSkills.Calculator +{ + public interface ITradeSkillCalculator + { + float MinimumPointThreshold { get; set; } + float PointMultiplier { get; set; } + float MaximumSkillDifference { get; set; } + + bool CanUseSkill(int skillScore, int skillDifficulty); + int CalculateSkillUpPointsFor(int skillScore, int skillDifficulty); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Calculator/TradeSkillCalculator.cs b/src/OpenRpg.Items.TradeSkills/Calculator/TradeSkillCalculator.cs new file mode 100644 index 0000000..e1069d9 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Calculator/TradeSkillCalculator.cs @@ -0,0 +1,36 @@ +using System; +using OpenRpg.CurveFunctions; +using OpenRpg.CurveFunctions.Scaling; +using OpenRpg.Items.TradeSkills.Calculator; + +public class TradeSkillCalculator : ITradeSkillCalculator +{ + public float MinimumPointThreshold { get; set; } = 0.5f; + public float PointMultiplier { get; set; } = 1.0f; + public float MaximumSkillDifference { get; set; } = 10.0f; + + public IScalingFunction SkillPointCurve { get; } + + public TradeSkillCalculator() + { + SkillPointCurve = new ScalingFunction(PresetCurves.InverseLinear, 0, 1, 0, MaximumSkillDifference); + } + + public bool CanUseSkill(int skillScore, int skillDifficulty) + { + var skillDifference = skillDifficulty - skillScore; + var absoluteScore = Math.Abs(skillDifference); + return absoluteScore <= MaximumSkillDifference; + } + + public int CalculateSkillUpPointsFor(int skillScore, int skillDifficulty) + { + var skillDifference = skillDifficulty - skillScore; + var absoluteScore = Math.Abs(skillDifference); + if (absoluteScore > MaximumSkillDifference) { return 0; } + + var result = SkillPointCurve.Plot(absoluteScore); + if (result < MinimumPointThreshold) { return 0; } + return (int)Math.Round(result * PointMultiplier); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Crafting/ItemCraftingTemplate.cs b/src/OpenRpg.Items.TradeSkills/Crafting/ItemCraftingTemplate.cs new file mode 100644 index 0000000..dd24ae1 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Crafting/ItemCraftingTemplate.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace OpenRpg.Items.TradeSkills.Crafting +{ + public class ItemCraftingTemplate : TradeSkillTemplate + { + /// + /// The items required to craft this template + /// + public List InputItems { get; set; } = new List(); + + /// + /// The items output from this template + /// + public List OutputItems { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Extensions/InventoryExtensions.cs b/src/OpenRpg.Items.TradeSkills/Extensions/InventoryExtensions.cs new file mode 100644 index 0000000..a3e498c --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Extensions/InventoryExtensions.cs @@ -0,0 +1,35 @@ +using OpenRpg.Items.Extensions; +using OpenRpg.Items.Inventory; +using OpenRpg.Items.TradeSkills.Crafting; + +namespace OpenRpg.Items.TradeSkills.Extensions +{ + public static class InventoryExtensions + { + public static bool HasItemsRequiredFor(this IInventory inventory, ItemCraftingTemplate craftingTemplate) + { + foreach (var itemEntry in craftingTemplate.InputItems) + { + if (itemEntry.Variables.HasAmount()) + { + var amount = itemEntry.Variables.Amount(); + if (!inventory.HasItem(itemEntry.ItemTemplateId, amount)) + { return false; } + } + else if (itemEntry.Variables.HasWeight()) + { + var weight = itemEntry.Variables.Weight(); + if (!inventory.HasItem(itemEntry.ItemTemplateId, weight)) + { return false; } + } + else + { + if (!inventory.HasItem(itemEntry.ItemTemplateId)) + { return false; } + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Extensions/TradeSkillItemEntryExtensions.cs b/src/OpenRpg.Items.TradeSkills/Extensions/TradeSkillItemEntryExtensions.cs new file mode 100644 index 0000000..2ef27fd --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Extensions/TradeSkillItemEntryExtensions.cs @@ -0,0 +1,28 @@ +using System; +using OpenRpg.Items.TradeSkills.Types; +using OpenRpg.Items.TradeSkills.Variables; + +namespace OpenRpg.Items.TradeSkills.Extensions +{ + public static class TradeSkillItemEntryExtensions + { + public static bool HasAmount(this TradeSkillItemEntryVariables variables) + { return variables.ContainsKey(TradeSkillItemEntryVariableTypes.Amount); } + + public static int Amount(this TradeSkillItemEntryVariables variables) + { + var amountObject = variables.Get(TradeSkillItemEntryVariableTypes.Amount); + var amount = Convert.ToInt32(amountObject); + return amount == 0 ? 1 : amount; + } + + public static void Amount(this TradeSkillItemEntryVariables variables, int value) + { variables[TradeSkillItemEntryVariableTypes.Amount] = value; } + + public static bool HasWeight(this TradeSkillItemEntryVariables variables) + { return variables.ContainsKey(TradeSkillItemEntryVariableTypes.Weight); } + + public static float Weight(this TradeSkillItemEntryVariables variables) => Convert.ToSingle(variables.Get(TradeSkillItemEntryVariableTypes.Weight)); + public static void Weight(this TradeSkillItemEntryVariables variables, float value) => variables[TradeSkillItemEntryVariableTypes.Weight] = value; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Gathering/ItemGatheringTemplate.cs b/src/OpenRpg.Items.TradeSkills/Gathering/ItemGatheringTemplate.cs new file mode 100644 index 0000000..09dbe6a --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Gathering/ItemGatheringTemplate.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace OpenRpg.Items.TradeSkills.Gathering +{ + public class ItemGatheringTemplate : TradeSkillTemplate + { + /// + /// The items output from this template + /// + public List OutputItems { get; set; } = new List(); + } +} diff --git a/src/OpenRpg.Items.TradeSkills/ITradeSkillTemplate.cs b/src/OpenRpg.Items.TradeSkills/ITradeSkillTemplate.cs new file mode 100644 index 0000000..b19e062 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/ITradeSkillTemplate.cs @@ -0,0 +1,29 @@ +using OpenRpg.Core.Common; +using OpenRpg.Core.Requirements; +using OpenRpg.Items.TradeSkills.Variables; + +namespace OpenRpg.Items.TradeSkills +{ + public interface ITradeSkillTemplate : IHasDataId, IHasRequirements + { + /// + /// Time in seconds for the action to complete i.e gathered/created + /// + public float TimeToComplete { get; } + + /// + /// The category of trade skill type + /// + public int SkillType { get; } + + /// + /// Indicates how difficult this is to get, effects gather/creation rates and level up rates + /// + public int SkillDifficulty { get; } + + /// + /// Variables for this template + /// + public ITradeSkillTemplateVariables Variables { get; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/OpenRpg.Items.TradeSkills.csproj b/src/OpenRpg.Items.TradeSkills/OpenRpg.Items.TradeSkills.csproj new file mode 100644 index 0000000..328caaa --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/OpenRpg.Items.TradeSkills.csproj @@ -0,0 +1,21 @@ + + + + 0.0.0 + netstandard2.1 + OpenRpg.Items.TradeSkills + Grofit (LP) + https://github.com/openrpg/OpenRpg/blob/master/LICENSE + https://github.com/openrpg/OpenRpg + Adds the notion of trade skills such as gathering or crafting to OpenRpg + rpg game-development xna monogame unity godot + 8 + + + + + + + + + diff --git a/src/OpenRpg.Items.TradeSkills/TradeSkillItemEntry.cs b/src/OpenRpg.Items.TradeSkills/TradeSkillItemEntry.cs new file mode 100644 index 0000000..f07f5c0 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/TradeSkillItemEntry.cs @@ -0,0 +1,11 @@ +using OpenRpg.Items.TradeSkills.Variables; + +namespace OpenRpg.Items.TradeSkills +{ + public class TradeSkillItemEntry + { + public int ItemTemplateId { get; set; } + + public TradeSkillItemEntryVariables Variables { get; set; } = new DefaultTradeSkillItemEntryVariables(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/TradeSkillTemplate.cs b/src/OpenRpg.Items.TradeSkills/TradeSkillTemplate.cs new file mode 100644 index 0000000..1c00f0e --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/TradeSkillTemplate.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using OpenRpg.Core.Requirements; +using OpenRpg.Items.TradeSkills.Variables; + +namespace OpenRpg.Items.TradeSkills +{ + public class TradeSkillTemplate : ITradeSkillTemplate + { + /// + /// The Id for this template + /// + public int Id { get; set; } + + /// + /// Gathering time in seconds, per unit gathered + /// + public float TimeToComplete { get; set; } = 1.0f; + + /// + /// The category of skill type used for Gathering + /// + public int SkillType { get; set; } + + /// + /// Indicates how difficult this is to get, effects if you can use the trade skill and skill up rates + /// + public int SkillDifficulty { get; set; } + + /// + /// Requirements needed before this tradeskill is allowed + /// + public IEnumerable Requirements { get; set; } = Array.Empty(); + + /// + /// Variables for this template + /// + public ITradeSkillTemplateVariables Variables { get; set; } = new DefaultTradeSkillTemplateVariables(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Trading/ITrader.cs b/src/OpenRpg.Items.TradeSkills/Trading/ITrader.cs new file mode 100644 index 0000000..036e422 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Trading/ITrader.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace OpenRpg.Items.TradeSkills.Trading +{ + public interface ITrader + { + IReadOnlyList Items { get; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Trading/ItemTradeEntry.cs b/src/OpenRpg.Items.TradeSkills/Trading/ItemTradeEntry.cs new file mode 100644 index 0000000..b621d1a --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Trading/ItemTradeEntry.cs @@ -0,0 +1,14 @@ +using OpenRpg.Items.TradeSkills.Variables; + +namespace OpenRpg.Items.TradeSkills.Trading +{ + public class ItemTradeEntry + { + public int ItemTemplateId { get; set; } + + public float BuyRate { get; set; } + public float SellRate { get; set; } + + private IItemTradeTradeEntryVariables Variables { get; set; } = new DefaultItemTradeEntryVariables(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Types/ItemCoreVariableTypes.cs b/src/OpenRpg.Items.TradeSkills/Types/ItemCoreVariableTypes.cs new file mode 100644 index 0000000..cff5a63 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Types/ItemCoreVariableTypes.cs @@ -0,0 +1,12 @@ +using OpenRpg.Items.Types; + +namespace OpenRpg.Items.TradeSkills.Types +{ + public interface TradeSkillCoreVariableTypes : ItemCoreVariableTypes + { + public static int TradeSkillTemplateVariables = 50; + public static int TraderVariables = 51; + public static int ItemTradeEntryVariables = 52; + public static int TradeSkillItemEntryVariables = 53; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Types/TradeSkillItemEntryVariableTypes.cs b/src/OpenRpg.Items.TradeSkills/Types/TradeSkillItemEntryVariableTypes.cs new file mode 100644 index 0000000..07e4d8d --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Types/TradeSkillItemEntryVariableTypes.cs @@ -0,0 +1,10 @@ +namespace OpenRpg.Items.TradeSkills.Types +{ + public interface TradeSkillItemEntryVariableTypes + { + public static readonly int Unknown = 0; + + public static readonly int Amount = 1; + public static readonly int Weight = 2; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Types/TradeSkillTypes.cs b/src/OpenRpg.Items.TradeSkills/Types/TradeSkillTypes.cs new file mode 100644 index 0000000..6996f7a --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Types/TradeSkillTypes.cs @@ -0,0 +1,7 @@ +namespace OpenRpg.Items.TradeSkills.Types +{ + public interface TradeSkillTypes + { + public static readonly int Unknown = 0; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/DefaultItemTradeEntryVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/DefaultItemTradeEntryVariables.cs new file mode 100644 index 0000000..6aabf18 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/DefaultItemTradeEntryVariables.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using OpenRpg.Core.Variables; +using OpenRpg.Items.TradeSkills.Types; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public class DefaultItemTradeEntryVariables : DefaultVariables, IItemTradeTradeEntryVariables + { + public DefaultItemTradeEntryVariables(IDictionary internalVariables = null) : base(TradeSkillCoreVariableTypes.ItemTradeEntryVariables, internalVariables) + { + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillItemEntryVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillItemEntryVariables.cs new file mode 100644 index 0000000..b0d487e --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillItemEntryVariables.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using OpenRpg.Core.Variables; +using OpenRpg.Items.TradeSkills.Types; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public class DefaultTradeSkillItemEntryVariables : DefaultVariables, TradeSkillItemEntryVariables + { + public DefaultTradeSkillItemEntryVariables(IDictionary internalVariables = null) : base(TradeSkillCoreVariableTypes.TradeSkillItemEntryVariables, internalVariables) + { + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillTemplateVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillTemplateVariables.cs new file mode 100644 index 0000000..6ff6bcb --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTradeSkillTemplateVariables.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using OpenRpg.Core.Variables; +using OpenRpg.Items.TradeSkills.Types; +using OpenRpg.Items.Types; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public class DefaultTradeSkillTemplateVariables : DefaultVariables, ITradeSkillTemplateVariables + { + public DefaultTradeSkillTemplateVariables(IDictionary internalVariables = null) : base(TradeSkillCoreVariableTypes.TradeSkillTemplateVariables, internalVariables) + { + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/DefaultTraderVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTraderVariables.cs new file mode 100644 index 0000000..6fa7f2e --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/DefaultTraderVariables.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using OpenRpg.Core.Variables; +using OpenRpg.Items.TradeSkills.Types; +using OpenRpg.Items.Types; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public class DefaultTraderVariables : DefaultVariables, ITraderVariables + { + public DefaultTraderVariables(IDictionary internalVariables = null) : base(TradeSkillCoreVariableTypes.TraderVariables, internalVariables) + { + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/IItemTradeTradeEntryVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/IItemTradeTradeEntryVariables.cs new file mode 100644 index 0000000..7d6e1b7 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/IItemTradeTradeEntryVariables.cs @@ -0,0 +1,7 @@ +using OpenRpg.Core.Variables; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public interface IItemTradeTradeEntryVariables : IVariables + {} +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/ITradeSkillTemplateVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/ITradeSkillTemplateVariables.cs new file mode 100644 index 0000000..2366ab6 --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/ITradeSkillTemplateVariables.cs @@ -0,0 +1,7 @@ +using OpenRpg.Core.Variables; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public interface ITradeSkillTemplateVariables : IVariables + {} +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/ITraderVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/ITraderVariables.cs new file mode 100644 index 0000000..df353fb --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/ITraderVariables.cs @@ -0,0 +1,7 @@ +using OpenRpg.Core.Variables; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public interface ITraderVariables : IVariables + {} +} \ No newline at end of file diff --git a/src/OpenRpg.Items.TradeSkills/Variables/TradeSkillItemEntryVariables.cs b/src/OpenRpg.Items.TradeSkills/Variables/TradeSkillItemEntryVariables.cs new file mode 100644 index 0000000..b5ab4bc --- /dev/null +++ b/src/OpenRpg.Items.TradeSkills/Variables/TradeSkillItemEntryVariables.cs @@ -0,0 +1,7 @@ +using OpenRpg.Core.Variables; + +namespace OpenRpg.Items.TradeSkills.Variables +{ + public interface TradeSkillItemEntryVariables : IVariables + {} +} \ No newline at end of file diff --git a/src/OpenRpg.Items/Extensions/IItemVariablesExtensions.cs b/src/OpenRpg.Items/Extensions/IItemVariablesExtensions.cs index 213de41..3ad52b5 100644 --- a/src/OpenRpg.Items/Extensions/IItemVariablesExtensions.cs +++ b/src/OpenRpg.Items/Extensions/IItemVariablesExtensions.cs @@ -31,7 +31,7 @@ public static void Amount(this IItemVariables variables, int value) public static bool HasWeight(this IItemVariables variables) { return variables.ContainsKey(ItemVariableTypes.Weight); } - public static int Weight(this IItemVariables variables) => Convert.ToInt32(variables.Get(ItemVariableTypes.Weight)); - public static void Weight(this IItemVariables variables, int value) => variables[ItemVariableTypes.Weight] = value; + public static float Weight(this IItemVariables variables) => Convert.ToSingle(variables.Get(ItemVariableTypes.Weight)); + public static void Weight(this IItemVariables variables, float value) => variables[ItemVariableTypes.Weight] = value; } } \ No newline at end of file diff --git a/src/OpenRpg.Items/Extensions/ItemTemplateVariablesExtensions.cs b/src/OpenRpg.Items/Extensions/ItemTemplateVariablesExtensions.cs index 2070b1b..da4b31f 100644 --- a/src/OpenRpg.Items/Extensions/ItemTemplateVariablesExtensions.cs +++ b/src/OpenRpg.Items/Extensions/ItemTemplateVariablesExtensions.cs @@ -1,6 +1,6 @@ using System; -using OpenRpg.Items.Templates; using OpenRpg.Items.Types; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Extensions { diff --git a/src/OpenRpg.Items/Extensions/LootTableEntryVariablesExtensions.cs b/src/OpenRpg.Items/Extensions/LootTableEntryVariablesExtensions.cs index ba5f357..d5ac888 100644 --- a/src/OpenRpg.Items/Extensions/LootTableEntryVariablesExtensions.cs +++ b/src/OpenRpg.Items/Extensions/LootTableEntryVariablesExtensions.cs @@ -2,6 +2,7 @@ using OpenRpg.Items.Loot; using OpenRpg.Items.Templates; using OpenRpg.Items.Types; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Extensions { diff --git a/src/OpenRpg.Items/Loot/DefaultLootTableEntry.cs b/src/OpenRpg.Items/Loot/DefaultLootTableEntry.cs index 6017e60..bb12fda 100644 --- a/src/OpenRpg.Items/Loot/DefaultLootTableEntry.cs +++ b/src/OpenRpg.Items/Loot/DefaultLootTableEntry.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using OpenRpg.Core.Requirements; using OpenRpg.Items.Templates; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Loot { diff --git a/src/OpenRpg.Items/Loot/ILootTableEntry.cs b/src/OpenRpg.Items/Loot/ILootTableEntry.cs index a2652db..5b4e6b8 100644 --- a/src/OpenRpg.Items/Loot/ILootTableEntry.cs +++ b/src/OpenRpg.Items/Loot/ILootTableEntry.cs @@ -1,5 +1,5 @@ using OpenRpg.Core.Requirements; -using OpenRpg.Items.Templates; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Loot { diff --git a/src/OpenRpg.Items/OpenRpg.Items.csproj b/src/OpenRpg.Items/OpenRpg.Items.csproj index 7361993..9487c74 100644 --- a/src/OpenRpg.Items/OpenRpg.Items.csproj +++ b/src/OpenRpg.Items/OpenRpg.Items.csproj @@ -16,4 +16,5 @@ + diff --git a/src/OpenRpg.Items/Templates/DefaultItemTemplate.cs b/src/OpenRpg.Items/Templates/DefaultItemTemplate.cs index da1781b..8ba965c 100644 --- a/src/OpenRpg.Items/Templates/DefaultItemTemplate.cs +++ b/src/OpenRpg.Items/Templates/DefaultItemTemplate.cs @@ -3,6 +3,7 @@ using OpenRpg.Core.Effects; using OpenRpg.Core.Modifications; using OpenRpg.Core.Requirements; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Templates { diff --git a/src/OpenRpg.Items/Templates/IItemTemplate.cs b/src/OpenRpg.Items/Templates/IItemTemplate.cs index cd77af8..98d6ba8 100644 --- a/src/OpenRpg.Items/Templates/IItemTemplate.cs +++ b/src/OpenRpg.Items/Templates/IItemTemplate.cs @@ -3,6 +3,7 @@ using OpenRpg.Core.Effects; using OpenRpg.Core.Modifications; using OpenRpg.Core.Requirements; +using OpenRpg.Items.Variables; namespace OpenRpg.Items.Templates { diff --git a/src/OpenRpg.Items/Templates/DefaultItemTemplateVariables.cs b/src/OpenRpg.Items/Variables/DefaultItemTemplateVariables.cs similarity index 91% rename from src/OpenRpg.Items/Templates/DefaultItemTemplateVariables.cs rename to src/OpenRpg.Items/Variables/DefaultItemTemplateVariables.cs index 085e90b..31495df 100644 --- a/src/OpenRpg.Items/Templates/DefaultItemTemplateVariables.cs +++ b/src/OpenRpg.Items/Variables/DefaultItemTemplateVariables.cs @@ -2,7 +2,7 @@ using OpenRpg.Core.Variables; using OpenRpg.Items.Types; -namespace OpenRpg.Items.Templates +namespace OpenRpg.Items.Variables { public class DefaultItemTemplateVariables : DefaultVariables, IItemTemplateVariables { diff --git a/src/OpenRpg.Items/Loot/DefaultLootTableEntryVariables.cs b/src/OpenRpg.Items/Variables/DefaultLootTableEntryVariables.cs similarity index 92% rename from src/OpenRpg.Items/Loot/DefaultLootTableEntryVariables.cs rename to src/OpenRpg.Items/Variables/DefaultLootTableEntryVariables.cs index 1efbd80..5d4fc8e 100644 --- a/src/OpenRpg.Items/Loot/DefaultLootTableEntryVariables.cs +++ b/src/OpenRpg.Items/Variables/DefaultLootTableEntryVariables.cs @@ -2,7 +2,7 @@ using OpenRpg.Core.Variables; using OpenRpg.Items.Types; -namespace OpenRpg.Items.Loot +namespace OpenRpg.Items.Variables { public class DefaultLootTableEntryVariables : DefaultVariables, ILootTableEntryVariables { diff --git a/src/OpenRpg.Items/Templates/IItemTemplateVariables.cs b/src/OpenRpg.Items/Variables/IItemTemplateVariables.cs similarity index 75% rename from src/OpenRpg.Items/Templates/IItemTemplateVariables.cs rename to src/OpenRpg.Items/Variables/IItemTemplateVariables.cs index 747bb46..dde4ffb 100644 --- a/src/OpenRpg.Items/Templates/IItemTemplateVariables.cs +++ b/src/OpenRpg.Items/Variables/IItemTemplateVariables.cs @@ -1,6 +1,6 @@ using OpenRpg.Core.Variables; -namespace OpenRpg.Items.Templates +namespace OpenRpg.Items.Variables { public interface IItemTemplateVariables : IVariables {} diff --git a/src/OpenRpg.Items/Loot/ILootTableEntryVariables.cs b/src/OpenRpg.Items/Variables/ILootTableEntryVariables.cs similarity index 76% rename from src/OpenRpg.Items/Loot/ILootTableEntryVariables.cs rename to src/OpenRpg.Items/Variables/ILootTableEntryVariables.cs index b2d4b06..80faa68 100644 --- a/src/OpenRpg.Items/Loot/ILootTableEntryVariables.cs +++ b/src/OpenRpg.Items/Variables/ILootTableEntryVariables.cs @@ -1,6 +1,6 @@ using OpenRpg.Core.Variables; -namespace OpenRpg.Items.Loot +namespace OpenRpg.Items.Variables { public interface ILootTableEntryVariables : IVariables {} diff --git a/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs b/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs new file mode 100644 index 0000000..79b4600 --- /dev/null +++ b/src/OpenRpg.Quests/Extensions/QuestEntityVariableExtensions.cs @@ -0,0 +1,18 @@ +using OpenRpg.Core.Variables.Entity; +using OpenRpg.Quests.Factions; +using OpenRpg.Quests.Types; + +namespace OpenRpg.Quests.Extensions +{ + public static class QuestEntityVariableExtensions + { + public static bool HasFactionReputation(this IEntityVariables vars) + { return vars.ContainsKey(QuestEntityVariableTypes.FactionReputation); } + + public static IFactionReputation FactionReputation(this IEntityVariables vars) + { return vars[QuestEntityVariableTypes.FactionReputation] as IFactionReputation; } + + public static void FactionReputation(this IEntityVariables vars, IFactionReputation factionReputation) + { vars[QuestEntityVariableTypes.FactionReputation] = factionReputation; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Factions/DefaultFaction.cs b/src/OpenRpg.Quests/Factions/DefaultFaction.cs new file mode 100644 index 0000000..42cc82d --- /dev/null +++ b/src/OpenRpg.Quests/Factions/DefaultFaction.cs @@ -0,0 +1,12 @@ +using OpenRpg.Quests.Variables; + +namespace OpenRpg.Quests.Factions +{ + public class DefaultFaction : IFaction + { + public int Id { get; set; } + public string NameLocaleId { get; set; } = string.Empty; + public string DescriptionLocaleId { get; set; } = string.Empty; + public IFactionVariables Variables { get; set; } = new DefaultFactionVariables(); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Factions/FactionReputation.cs b/src/OpenRpg.Quests/Factions/FactionReputation.cs new file mode 100644 index 0000000..e6f3773 --- /dev/null +++ b/src/OpenRpg.Quests/Factions/FactionReputation.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +namespace OpenRpg.Quests.Factions +{ + public class FactionReputation : IFactionReputation + { + public Dictionary InternalFactionReputation { get; set; } = new Dictionary(); + + public int GetReputation(int factionId) + { return InternalFactionReputation.TryGetValue(factionId, out var value) ? value : 0; } + + public int ChangeReputation(int factionId, int amount) + { + if (!InternalFactionReputation.ContainsKey(factionId)) + { + InternalFactionReputation.Add(factionId, amount); + return amount; + } + + var current = InternalFactionReputation[factionId]; + var newTotal = current + amount; + InternalFactionReputation[factionId] = newTotal; + return newTotal; + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Factions/IFaction.cs b/src/OpenRpg.Quests/Factions/IFaction.cs new file mode 100644 index 0000000..be157df --- /dev/null +++ b/src/OpenRpg.Quests/Factions/IFaction.cs @@ -0,0 +1,10 @@ +using OpenRpg.Core.Common; +using OpenRpg.Quests.Variables; + +namespace OpenRpg.Quests.Factions +{ + public interface IFaction : IHasDataId, IHasLocaleDescription + { + IFactionVariables Variables { get; } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Factions/IFactionReputation.cs b/src/OpenRpg.Quests/Factions/IFactionReputation.cs new file mode 100644 index 0000000..201ecef --- /dev/null +++ b/src/OpenRpg.Quests/Factions/IFactionReputation.cs @@ -0,0 +1,8 @@ +namespace OpenRpg.Quests.Factions +{ + public interface IFactionReputation + { + int GetReputation(int factionId); + int ChangeReputation(int factionId, int amount); + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/OpenRpg.Quests.csproj b/src/OpenRpg.Quests/OpenRpg.Quests.csproj index b6fcef6..4db688a 100644 --- a/src/OpenRpg.Quests/OpenRpg.Quests.csproj +++ b/src/OpenRpg.Quests/OpenRpg.Quests.csproj @@ -16,4 +16,6 @@ + + diff --git a/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs b/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs new file mode 100644 index 0000000..1e7731d --- /dev/null +++ b/src/OpenRpg.Quests/Types/QuestEntityVariableTypes.cs @@ -0,0 +1,9 @@ +using OpenRpg.Core.Types; + +namespace OpenRpg.Quests.Types +{ + public interface QuestEntityVariableTypes : EntityVariableTypes + { + public static int FactionReputation = 20; + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Types/QuestVariableTypes.cs b/src/OpenRpg.Quests/Types/QuestVariableTypes.cs index bafa959..c8c5f39 100644 --- a/src/OpenRpg.Quests/Types/QuestVariableTypes.cs +++ b/src/OpenRpg.Quests/Types/QuestVariableTypes.cs @@ -7,5 +7,6 @@ public interface QuestVariableTypes : CoreVariableTypes public static int QuestVariables = 30; public static int QuestStateVariables = 31; public static int TriggerVariables = 32; + public static int FactionVariables = 33; } } \ No newline at end of file diff --git a/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs b/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs new file mode 100644 index 0000000..38ddbf0 --- /dev/null +++ b/src/OpenRpg.Quests/Variables/DefaultFactionVariables.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using OpenRpg.Core.Variables; +using OpenRpg.Quests.Types; + +namespace OpenRpg.Quests.Variables +{ + public class DefaultFactionVariables : DefaultVariables, IFactionVariables + { + public DefaultFactionVariables(IDictionary internalVariables = null) : base(QuestVariableTypes.FactionVariables, internalVariables) + { + } + } +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Variables/IFactionVariables.cs b/src/OpenRpg.Quests/Variables/IFactionVariables.cs new file mode 100644 index 0000000..76e61ec --- /dev/null +++ b/src/OpenRpg.Quests/Variables/IFactionVariables.cs @@ -0,0 +1,7 @@ +using OpenRpg.Core.Variables; + +namespace OpenRpg.Quests.Variables +{ + public interface IFactionVariables : IVariables + {} +} \ No newline at end of file diff --git a/src/OpenRpg.Quests/Variables/IQuestVariables.cs b/src/OpenRpg.Quests/Variables/IQuestVariables.cs index 4567d08..6a7c3ed 100644 --- a/src/OpenRpg.Quests/Variables/IQuestVariables.cs +++ b/src/OpenRpg.Quests/Variables/IQuestVariables.cs @@ -3,7 +3,5 @@ namespace OpenRpg.Quests.Variables { public interface IQuestVariables : IVariables - { - - } + {} } \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/Crafting/TradeSkillCalculatorTests.cs b/src/OpenRpg.UnitTests/Crafting/TradeSkillCalculatorTests.cs new file mode 100644 index 0000000..9ecf0f5 --- /dev/null +++ b/src/OpenRpg.UnitTests/Crafting/TradeSkillCalculatorTests.cs @@ -0,0 +1,39 @@ +using Xunit; + +namespace OpenRpg.UnitTests.Crafting; + +public class TradeSkillCalculatorTests +{ + [Theory] + [InlineData(1, 1, 1, true)] + [InlineData(0, 1, 1, true)] + [InlineData(0, 2, 1, false)] + [InlineData(0, 2, 2, true)] + [InlineData(10, 100, 10, false)] + [InlineData(10, 100, 80, false)] + [InlineData(10, 100, 90, true)] + public void should_correctly_work_out_skill_use(int skillScore, int skillDifficulty, int maxSkillDifference, bool shouldBeAbleToUse) + { + var tradeSkillCalculator = new TradeSkillCalculator() { MaximumSkillDifference = maxSkillDifference }; + var canUse = tradeSkillCalculator.CanUseSkill(skillScore, skillDifficulty); + Assert.Equal(shouldBeAbleToUse, canUse); + } + + [Theory] + [InlineData(1, 1, 10, 0.5f, 1, 1)] + [InlineData(1, 1, 10, 0.5f, 3, 3)] + [InlineData(1, 10, 10, 0.5f, 1, 0)] + [InlineData(1, 10, 10, 0.1f, 5, 1)] + [InlineData(1, 5, 10, 0.1f, 5, 3)] + public void should_correctly_work_out_skill_up_points(int skillScore, int skillDifficulty, int maxSkillDifference, float minimumPointThreshold, float pointMultiplier, int expectedPoints) + { + var tradeSkillCalculator = new TradeSkillCalculator() + { + MinimumPointThreshold = minimumPointThreshold, + PointMultiplier = pointMultiplier, + MaximumSkillDifference = maxSkillDifference + }; + var actualPoints = tradeSkillCalculator.CalculateSkillUpPointsFor(skillScore, skillDifficulty); + Assert.Equal(expectedPoints, actualPoints); + } +} \ No newline at end of file diff --git a/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj index d86128e..877a1bc 100644 --- a/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj +++ b/src/OpenRpg.UnitTests/OpenRpg.UnitTests.csproj @@ -24,8 +24,10 @@ + + diff --git a/src/OpenRpg.sln b/src/OpenRpg.sln index dbddcb3..bea4616 100644 --- a/src/OpenRpg.sln +++ b/src/OpenRpg.sln @@ -42,6 +42,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Localization", "Localizatio EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRpg.Tags", "OpenRpg.Tags\OpenRpg.Tags.csproj", "{1F967BA2-0B0B-4305-B564-05EC9C49D308}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRpg.Items.TradeSkills", "OpenRpg.Items.TradeSkills\OpenRpg.Items.TradeSkills.csproj", "{70FCB73C-8493-4B0F-AA13-F3BA65AE86AB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -96,6 +98,10 @@ Global {1F967BA2-0B0B-4305-B564-05EC9C49D308}.Debug|Any CPU.Build.0 = Debug|Any CPU {1F967BA2-0B0B-4305-B564-05EC9C49D308}.Release|Any CPU.ActiveCfg = Release|Any CPU {1F967BA2-0B0B-4305-B564-05EC9C49D308}.Release|Any CPU.Build.0 = Release|Any CPU + {70FCB73C-8493-4B0F-AA13-F3BA65AE86AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70FCB73C-8493-4B0F-AA13-F3BA65AE86AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70FCB73C-8493-4B0F-AA13-F3BA65AE86AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70FCB73C-8493-4B0F-AA13-F3BA65AE86AB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {86FD715B-0B33-40EB-B8AC-25EE62398A66} = {6BE3D2A4-F53A-4879-868E-A7522A445FE9} @@ -110,5 +116,6 @@ Global {A3AACDFF-0D4B-4B4C-801E-6369BA9C8B6B} = {B374DC71-CEDE-42CC-A6E2-5D35577B08BA} {5C2FF42D-8E29-4EDE-84D0-47D24FFFFBB9} = {167FBCA2-476D-4BA4-818A-FA4ED80E6197} {1F967BA2-0B0B-4305-B564-05EC9C49D308} = {1566BC2E-78DC-4998-BEC8-65CEC3EC9A88} + {70FCB73C-8493-4B0F-AA13-F3BA65AE86AB} = {7C187634-FF6B-4A6E-AAD2-FCA3C97C1E5A} EndGlobalSection EndGlobal