From 1ea186e5ec0e3d9990a7ac8e40cc4eeaf38c21e4 Mon Sep 17 00:00:00 2001 From: zerratar Date: Tue, 1 Aug 2023 18:48:17 +0200 Subject: [PATCH] make it possible to set a cooldown on item collection from skills. This acts as a minimal interval between gains --- GameDataSimulation/Program.cs | 34 +++++++++++++------ .../Simulations/MiningDropSimulation.cs | 4 +-- .../Pages/Admin/ItemDropManagement.razor | 20 ++++++++++- src/RavenNest.BusinessLogic/Data/GameData.cs | 4 +++ .../Processors/Tasks/CraftingTaskProcessor.cs | 1 - .../Processors/Tasks/ResourceTaskProcessor.cs | 34 ++++++++++--------- .../Processors/Tasks/SimpleDropHandler.cs | 28 +++++++++++++-- src/RavenNest.DataModels/Achievement.cs | 8 +++++ src/RavenNest.DataModels/AchievementReward.cs | 11 ++++++ .../CharacterAchievement.cs | 11 ++++++ src/RavenNest.DataModels/ResourceItemDrop.cs | 1 + src/RavenNest.DataModels/UserAchievement.cs | 11 ++++++ 12 files changed, 134 insertions(+), 33 deletions(-) create mode 100644 src/RavenNest.DataModels/Achievement.cs create mode 100644 src/RavenNest.DataModels/AchievementReward.cs create mode 100644 src/RavenNest.DataModels/CharacterAchievement.cs create mode 100644 src/RavenNest.DataModels/UserAchievement.cs diff --git a/GameDataSimulation/Program.cs b/GameDataSimulation/Program.cs index e6fab1d7..342d9967 100644 --- a/GameDataSimulation/Program.cs +++ b/GameDataSimulation/Program.cs @@ -7,20 +7,32 @@ using GMath = RavenNest.BusinessLogic.GameMath; var villages = new List(); -for (var j = 0; j < 7; j++) +//for (var j = 0; j < 7; j++) +//{ +// var level = j == 0 ? 1 : (j * 50) - 1; +// for (var i = 0; i < 4; i++) +// { +// var population = (i % 4) * 10;//100; +// villages.Add(new UserVillage +// { +// Level = level, +// Name = "Village " + j + "#" + i, +// Population = population +// }); +// } +//} + +for (var i = 0; i < 15; i++) { - var level = j == 0 ? 1 : (j * 50) - 1; - for (var i = 0; i < 4; i++) + var population = i * 10;//100; + villages.Add(new UserVillage { - var population = (i % 4) * 10;//100; - villages.Add(new UserVillage - { - Level = level, - Name = "Village " + j + "#" + i, - Population = population - }); - } + Level = 1, + Name = "Village " + 1 + "#" + i, + Population = population + }); } + //var villages = new UserVillage[] //{ // new UserVillage { Level = 10, Population = 25, Name = "Someone" }, diff --git a/GameDataSimulation/Simulations/MiningDropSimulation.cs b/GameDataSimulation/Simulations/MiningDropSimulation.cs index 92fd756d..f3aa4a20 100644 --- a/GameDataSimulation/Simulations/MiningDropSimulation.cs +++ b/GameDataSimulation/Simulations/MiningDropSimulation.cs @@ -125,7 +125,7 @@ private void UpdateResourceGain(ResourceContext ctx, Action onUpdate) } } - private void AddDrop(int miningLevel, Action onDrop) + private void AddDrop(int skillLevel, Action onDrop) { var multiDrop = Random.NextDouble(); var isMultiDrop = multiDrop <= 0.1; @@ -135,7 +135,7 @@ private void AddDrop(int miningLevel, Action onDrop) foreach (var res in ResourceTaskProcessor.DefaultDroppableResources.OrderByDescending(x => x.SkillLevel)) { chance = Random.NextDouble(); - if (miningLevel >= res.SkillLevel && (chance <= res.GetDropChance(miningLevel))) + if (skillLevel >= res.SkillLevel && (chance <= res.GetDropChance(skillLevel))) { onDrop(res); diff --git a/src/RavenNest.Blazor/Pages/Admin/ItemDropManagement.razor b/src/RavenNest.Blazor/Pages/Admin/ItemDropManagement.razor index f5b06e97..89abc20e 100644 --- a/src/RavenNest.Blazor/Pages/Admin/ItemDropManagement.razor +++ b/src/RavenNest.Blazor/Pages/Admin/ItemDropManagement.razor @@ -43,6 +43,11 @@ +
+ + +
+
@@ -118,6 +123,7 @@ Skill Level Req Drop Chance + Cooldown @@ -130,6 +136,7 @@ @(item.Skill != null ? RavenNest.DataModels.Skills.SkillNames[item.Skill.Value] : "") @item.LevelRequirement @item.DropChance + @item.Cooldown @@ -269,6 +276,7 @@ if (d != null) { DropChance = d.DropChance.ToString(); + Cooldown = d.Cooldown.GetValueOrDefault().ToString(); ItemName = d.ItemName; ItemId = d.ItemId.ToString(); @@ -282,6 +290,7 @@ return; } + Cooldown = 0.ToString(); DropChance = 0.01.ToString(); SkillLevel = 1; } @@ -293,6 +302,7 @@ Drop.ItemId = toCopy.ItemId; Drop.ItemName = toCopy.ItemName; Drop.DropChance = toCopy.DropChance; + Drop.Cooldown = toCopy.Cooldown; Drop.LevelRequirement = toCopy.LevelRequirement; Drop.Skill = toCopy.Skill; return true; @@ -340,6 +350,12 @@ double.TryParse(DropChance, out dropChance); } + var cooldown = 0.0; + if (!string.IsNullOrEmpty(Cooldown)) + { + double.TryParse(Cooldown, out cooldown); + } + if (TargetItem != null) { return new RavenNest.DataModels.ResourceItemDrop @@ -349,7 +365,8 @@ ItemName = TargetItem.Name, DropChance = dropChance, LevelRequirement = SkillLevel, - Skill = index + Skill = index, + Cooldown = cooldown }; } @@ -362,6 +379,7 @@ public string ItemId { get; set; } public string Skill { get; set; } public string DropChance { get; set; } + public string Cooldown { get; set; } public int SkillLevel { get; set; } } } \ No newline at end of file diff --git a/src/RavenNest.BusinessLogic/Data/GameData.cs b/src/RavenNest.BusinessLogic/Data/GameData.cs index 8f2f2597..b68f975a 100644 --- a/src/RavenNest.BusinessLogic/Data/GameData.cs +++ b/src/RavenNest.BusinessLogic/Data/GameData.cs @@ -54,6 +54,10 @@ public class GameData : IDisposable private readonly EntitySet vendorItems; + private readonly EntitySet achievements; + private readonly EntitySet userAchievements; + private readonly EntitySet characterAchievements; + private readonly EntitySet clanInvites; private readonly EntitySet clans; private readonly EntitySet clanRoles; diff --git a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/CraftingTaskProcessor.cs b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/CraftingTaskProcessor.cs index 4057b98f..f0b3d7b5 100644 --- a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/CraftingTaskProcessor.cs +++ b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/CraftingTaskProcessor.cs @@ -1,5 +1,4 @@ using RavenNest.BusinessLogic.Data; -using RavenNest.BusinessLogic.Providers; using RavenNest.DataModels; using System; diff --git a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/ResourceTaskProcessor.cs b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/ResourceTaskProcessor.cs index 6840a73c..7b7fdcf8 100644 --- a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/ResourceTaskProcessor.cs +++ b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/ResourceTaskProcessor.cs @@ -26,20 +26,20 @@ static ResourceTaskProcessor() { DefaultDroppableResources = new List() { - new ResourceDrop(Guid.Parse("49D53A1E-55F7-4537-9A5B-0560B1C0F465"), "Ethereum", 0.003, 280, 6), - new ResourceDrop(Guid.Parse("BA6ED0AD-2FE6-46BF-9A99-5528657FF40E"), "Lionite", 0.005, 240, 6), - new ResourceDrop(Guid.Parse("17c3f9b1-57d6-4219-bbc7-9e929757babf"), "Phantom Core", 0.01, 200, 6), - new ResourceDrop(Guid.Parse("f9b7e6a3-4e4a-4e4a-b79d-42a3cf2a16c8"), "Abraxas Spirit", 0.02, 170, 6), - new ResourceDrop(Guid.Parse("0dc620c2-b726-4928-9f1c-fcf61aaa2542"), "Dragon Scale", 0.025, 130, 6), - new ResourceDrop(Guid.Parse("40781EB8-1EBF-4C0C-9A11-6E8033C9953C"), "Rune Nugget", 0.075, 70, 6), - new ResourceDrop(Guid.Parse("E32A6F17-653C-4AF3-A3A1-D0C6674FE4D5"), "Adamantite Nugget", 0.1, 50, 6), - new ResourceDrop(Guid.Parse("FEE5E07E-4397-44A9-9E3A-ED0465CE29FC"), "Gold Nugget", 0.135, 30, 6), - new ResourceDrop(Guid.Parse("B3411B33-59F6-4443-A70C-6576B6EC74EC"), "Mithril Nugget", 0.135, 30, 6), - new ResourceDrop(Guid.Parse("F5A6063F-CC99-48BF-BC79-F764CD87373A"), "Ruby", 0.135, 25, 6), - new ResourceDrop(Guid.Parse("48C94F6C-6119-48A2-88EA-F7649F816DA4"), "Emerald", 0.135, 20, 6), - new ResourceDrop(Guid.Parse("723A48A0-E3CB-4EBD-9966-EE8323B11DC0"), "Sapphire", 0.15, 10, 6), - new ResourceDrop(Guid.Parse("EF674846-817E-41B7-B378-85E64D2CCF5D"), "Steel Nugget", 0.185, 10, 6), - new ResourceDrop(Guid.Parse("CC61E4A3-B00E-4FD4-9160-16A6466787E6"), "Iron Nugget", 0.2, 1, 6), + new ResourceDrop(Guid.Parse("49D53A1E-55F7-4537-9A5B-0560B1C0F465"), "Ethereum", 0.003, 0, 280, 6), + new ResourceDrop(Guid.Parse("BA6ED0AD-2FE6-46BF-9A99-5528657FF40E"), "Lionite", 0.005, 0,240, 6), + new ResourceDrop(Guid.Parse("17c3f9b1-57d6-4219-bbc7-9e929757babf"), "Phantom Core", 0.01, 0, 200, 6), + new ResourceDrop(Guid.Parse("f9b7e6a3-4e4a-4e4a-b79d-42a3cf2a16c8"), "Abraxas Spirit", 0.02, 0, 170, 6), + new ResourceDrop(Guid.Parse("0dc620c2-b726-4928-9f1c-fcf61aaa2542"), "Dragon Scale", 0.025, 0, 130, 6), + new ResourceDrop(Guid.Parse("40781EB8-1EBF-4C0C-9A11-6E8033C9953C"), "Rune Nugget", 0.075, 0, 70, 6), + new ResourceDrop(Guid.Parse("E32A6F17-653C-4AF3-A3A1-D0C6674FE4D5"), "Adamantite Nugget", 0.1, 0, 50, 6), + new ResourceDrop(Guid.Parse("FEE5E07E-4397-44A9-9E3A-ED0465CE29FC"), "Gold Nugget", 0.135, 0, 30, 6), + new ResourceDrop(Guid.Parse("B3411B33-59F6-4443-A70C-6576B6EC74EC"), "Mithril Nugget", 0.135, 0, 30, 6), + new ResourceDrop(Guid.Parse("F5A6063F-CC99-48BF-BC79-F764CD87373A"), "Ruby", 0.135, 0, 25, 6), + new ResourceDrop(Guid.Parse("48C94F6C-6119-48A2-88EA-F7649F816DA4"), "Emerald", 0.135, 0, 20, 6), + new ResourceDrop(Guid.Parse("723A48A0-E3CB-4EBD-9966-EE8323B11DC0"), "Sapphire", 0.15, 0, 10, 6), + new ResourceDrop(Guid.Parse("EF674846-817E-41B7-B378-85E64D2CCF5D"), "Steel Nugget", 0.185, 0, 10, 6), + new ResourceDrop(Guid.Parse("CC61E4A3-B00E-4FD4-9160-16A6466787E6"), "Iron Nugget", 0.2, 0, 1, 6), }; } @@ -114,14 +114,16 @@ public class ResourceDrop public Guid Id { get; } public string Name { get; } public double DropChance { get; } + public double Cooldown { get; } public int SkillLevel { get; set; } public int? SkillIndex { get; set; } - public ResourceDrop(Guid id, string name, double dropChance, int skillLevel, int? skillIndex) + public ResourceDrop(Guid id, string name, double dropChance, double cooldown, int skillLevel, int? skillIndex) { Id = id; Name = name; DropChance = dropChance; + Cooldown = cooldown; SkillLevel = skillLevel; SkillIndex = skillIndex; } @@ -133,7 +135,7 @@ public double GetDropChance(int playerSkillLevel) public static implicit operator ResourceDrop(ResourceItemDrop source) { - return new ResourceDrop(source.ItemId, source.ItemName, source.DropChance, source.LevelRequirement, source.Skill); + return new ResourceDrop(source.ItemId, source.ItemName, source.DropChance, source.Cooldown ?? 0, source.LevelRequirement, source.Skill); } } } diff --git a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/SimpleDropHandler.cs b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/SimpleDropHandler.cs index 2bd4fcb9..94a5270a 100644 --- a/src/RavenNest.BusinessLogic/Game/Processors/Tasks/SimpleDropHandler.cs +++ b/src/RavenNest.BusinessLogic/Game/Processors/Tasks/SimpleDropHandler.cs @@ -1,5 +1,4 @@ using RavenNest.BusinessLogic.Data; -using RavenNest.BusinessLogic.Providers; using RavenNest.DataModels; using System; using System.Collections.Generic; @@ -11,6 +10,7 @@ public class SimpleDropHandler { private readonly string skill; private readonly List drops = new List(); + private readonly Dictionary dropTimes = new Dictionary(); private bool initialized; public SimpleDropHandler(string skill) @@ -30,7 +30,14 @@ public void LoadDrops(GameData gameData) } } - public bool TryDropItem(ResourceTaskProcessor resProcessor, GameData gameData, PlayerInventoryProvider inventoryProvider, GameSession session, Character character, int skillLevel, Func canDrop = null) + public bool TryDropItem( + ResourceTaskProcessor resProcessor, + GameData gameData, + PlayerInventoryProvider inventoryProvider, + GameSession session, + Character character, + int skillLevel, + Func canDrop = null) { var chance = resProcessor.Random.NextDouble(); if (chance > ItemDropRateSettings.InitDropChance) @@ -47,6 +54,23 @@ public bool TryDropItem(ResourceTaskProcessor resProcessor, GameData gameData, P { if (canDrop == null || canDrop(res)) { + // check for cooldown + var cooldownKey = character.Id + "_" + res.Id; + if (res.Cooldown > 0) + { + if (dropTimes.TryGetValue(cooldownKey, out var lastDrop)) + { + if (DateTime.UtcNow - lastDrop < TimeSpan.FromSeconds(res.Cooldown)) + { + return false; + } + } + else + { + dropTimes[cooldownKey] = DateTime.UtcNow; + } + } + resProcessor.IncrementItemStack(gameData, inventoryProvider, session, character, res.Id); return true; } diff --git a/src/RavenNest.DataModels/Achievement.cs b/src/RavenNest.DataModels/Achievement.cs new file mode 100644 index 00000000..83721a36 --- /dev/null +++ b/src/RavenNest.DataModels/Achievement.cs @@ -0,0 +1,8 @@ +namespace RavenNest.DataModels +{ + public partial class Achievement : Entity + { + private string name; public string Name { get => name; set => Set(ref name, value); } + private string description; public string Description { get => description; set => Set(ref description, value); } + } +} diff --git a/src/RavenNest.DataModels/AchievementReward.cs b/src/RavenNest.DataModels/AchievementReward.cs new file mode 100644 index 00000000..41bdb75f --- /dev/null +++ b/src/RavenNest.DataModels/AchievementReward.cs @@ -0,0 +1,11 @@ +using System; + +namespace RavenNest.DataModels +{ + public partial class AchievementReward : Entity + { + private Guid achievementId; public Guid AchievementId { get => achievementId; set => Set(ref achievementId, value); } + private int rewardType; public int RewardType { get => rewardType; set => Set(ref rewardType, value); } + private long rewardAmount; public long RewardAmount { get => rewardAmount; set => Set(ref rewardAmount, value); } + } +} diff --git a/src/RavenNest.DataModels/CharacterAchievement.cs b/src/RavenNest.DataModels/CharacterAchievement.cs new file mode 100644 index 00000000..b39b7727 --- /dev/null +++ b/src/RavenNest.DataModels/CharacterAchievement.cs @@ -0,0 +1,11 @@ +using System; + +namespace RavenNest.DataModels +{ + public partial class CharacterAchievement : Entity + { + private Guid achievementId; public Guid AchievementId { get => achievementId; set => Set(ref achievementId, value); } + private Guid characterId; public Guid CharacterId { get => characterId; set => Set(ref characterId, value); } + private DateTime achieved; public DateTime Achieved { get => achieved; set => Set(ref achieved, value); } + } +} diff --git a/src/RavenNest.DataModels/ResourceItemDrop.cs b/src/RavenNest.DataModels/ResourceItemDrop.cs index a71e86cc..e50008a9 100644 --- a/src/RavenNest.DataModels/ResourceItemDrop.cs +++ b/src/RavenNest.DataModels/ResourceItemDrop.cs @@ -9,5 +9,6 @@ public partial class ResourceItemDrop : Entity private double dropChance; public double DropChance { get => dropChance; set => Set(ref dropChance, value); } private int levelRequirement; public int LevelRequirement { get => levelRequirement; set => Set(ref levelRequirement, value); } private int? skill; public int? Skill { get => skill; set => Set(ref skill, value); } + private double? cooldown; public double? Cooldown { get => cooldown; set => Set(ref cooldown, value); } } } diff --git a/src/RavenNest.DataModels/UserAchievement.cs b/src/RavenNest.DataModels/UserAchievement.cs new file mode 100644 index 00000000..44b1aa87 --- /dev/null +++ b/src/RavenNest.DataModels/UserAchievement.cs @@ -0,0 +1,11 @@ +using System; + +namespace RavenNest.DataModels +{ + public partial class UserAchievement : Entity + { + private Guid achievementId; public Guid AchievementId { get => achievementId; set => Set(ref achievementId, value); } + private Guid userId; public Guid UserId { get => userId; set => Set(ref userId, value); } + private DateTime achieved; public DateTime Achieved { get => achieved; set => Set(ref achieved, value); } + } +}