diff --git a/MxValheim/EventSystem/Patch.cs b/MxValheim/EventSystem/Patch.cs index 9124cfb..e824cc4 100644 --- a/MxValheim/EventSystem/Patch.cs +++ b/MxValheim/EventSystem/Patch.cs @@ -87,11 +87,11 @@ namespace MxValheim.EventSystem RandomEvent currentRaid = ActiveEventField(__instance); if (string.IsNullOrEmpty(eventName) && currentRaid != null) { - int kill = 0; + int points = 0; ZPackage pkg = new ZPackage(); pkg.Write(currentRaid.m_name); pkg.Write($"{currentRaid.m_pos}"); - kill = Watcher.eventKill; + points = Watcher.eventPoints; ZRoutedRpc.instance.InvokeRoutedRPC(0, "RPC_ServerRemoveEvent", pkg); Vector3 playerPos = Player.m_localPlayer.transform.position; @@ -100,7 +100,7 @@ namespace MxValheim.EventSystem if (distance <= 200f) { Heightmap.Biome currentBiome = EnvMan.instance.GetCurrentBiome(); - Reward.GiveItemStatic("Coins", Reward.CalculateRewardCoin(Profiles.serverLevel, currentBiome, kill)); + Reward.GiveItemStatic("Coins", Reward.CalculateRewardCoin(Profiles.serverLevel, currentBiome, points)); System.Random rand = new System.Random(); Reward.GiveItemStatic("Feathers", rand.Next(5, 20)); float dayPercent = ((float)EnvMan.instance.GetDay() / 10); @@ -118,6 +118,7 @@ namespace MxValheim.EventSystem } if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { + Reward.GenRarity(); Reward.GiveEpicLootDust(); Reward.GiveEpicLootShard(); Reward.GiveEpicLootEssence(); @@ -178,6 +179,13 @@ namespace MxValheim.EventSystem ZPackage pkg = new ZPackage(); pkg.Write(activeEvent.m_name); pkg.Write($"{activeEvent.m_pos}"); + string internalName = __instance.gameObject.name; + int cloneIndex = internalName.IndexOf("(Clone)"); + if (cloneIndex != -1) + { + internalName = internalName.Substring(0, cloneIndex); + } + pkg.Write(Reward.EnemiesPointValue[internalName]); ActiveEventData entry = MxValheimMod.ActiveEvents.Find(e => e.Position == activeEvent.m_pos.ToString()); if (entry == null) { diff --git a/MxValheim/EventSystem/Reward.cs b/MxValheim/EventSystem/Reward.cs index ea7ba1c..a187246 100644 --- a/MxValheim/EventSystem/Reward.cs +++ b/MxValheim/EventSystem/Reward.cs @@ -12,8 +12,10 @@ using UnityEngine; namespace MxValheim.EventSystem { internal class Reward - { - public static int CalculateRewardCoin(int level, Heightmap.Biome biome, int kill) + { + private static string globalRarity = "Magic"; + + public static int CalculateRewardCoin(int level, Heightmap.Biome biome, int points) { Dictionary biomeBase = new Dictionary() { @@ -26,13 +28,21 @@ namespace MxValheim.EventSystem { 32, 70 }, }; - int rewardCoin = (biomeBase[((int)biome)] * level) + (biomeBase[((int)biome)] * kill); + int rewardCoin = (biomeBase[((int)biome)] * level) + points; return rewardCoin; - } + } + + public static void GenRarity() + { + string[] rarity = GetRarityList(Watcher.eventPoints); + + System.Random rand = new System.Random(); + globalRarity = rarity[rand.Next(0, rarity.Length - 1)]; + } public static string GetRewardPrefab(int level, string type) - { + { string[] foodList = { "OnionSoup", "CarrotSoup", "DeerStew", "Salad", "SerpentStew", "WolfMeatSkewer" }; string[] healList = { "MeadHealthMinor", "MeadHealthMedium", "MeadHealthMajor", "MeadHealthLingering" }; string[] metalList = { "CopperOre", "TinOre", "IronScrap", "SilverOre", "BlackMetalScrap", "FlametalOreNew" }; @@ -54,9 +64,9 @@ namespace MxValheim.EventSystem int qty = rand.Next(1, Profiles.serverLevel); - string[] rarity = GetRarityList(Watcher.eventKill); + string[] rarity = GetRarityList(Watcher.eventPoints); - string itemName = $"Dust{rarity[rand.Next(0, rarity.Length - 1)]}"; + string itemName = $"Dust{globalRarity}"; Player player = Player.m_localPlayer; if (player == null) return; @@ -64,7 +74,7 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); } else { @@ -78,9 +88,9 @@ namespace MxValheim.EventSystem int qty = rand.Next(1, Profiles.serverLevel); - string[] rarity = GetRarityList(Watcher.eventKill); + string[] rarity = GetRarityList(Watcher.eventPoints); - string itemName = $"Shard{rarity[rand.Next(0, rarity.Length - 1)]}"; + string itemName = $"Shard{globalRarity}"; Player player = Player.m_localPlayer; if (player == null) return; @@ -88,7 +98,7 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); } else { @@ -102,9 +112,9 @@ namespace MxValheim.EventSystem int qty = rand.Next(1, Profiles.serverLevel); - string[] rarity = GetRarityList(Watcher.eventKill); + string[] rarity = GetRarityList(Watcher.eventPoints); - string itemName = $"Essence{rarity[rand.Next(0, rarity.Length - 1)]}"; + string itemName = $"Essence{globalRarity}"; Player player = Player.m_localPlayer; if (player == null) return; @@ -112,7 +122,7 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); } else { @@ -126,9 +136,9 @@ namespace MxValheim.EventSystem int qty = rand.Next(1, 2); - string[] rarity = GetRarityList(Watcher.eventKill); + string[] rarity = GetRarityList(Watcher.eventPoints); - string itemName = $"Runestone{rarity[rand.Next(0, rarity.Length - 1)]}"; + string itemName = $"Runestone{globalRarity}"; Player player = Player.m_localPlayer; if (player == null) return; @@ -136,7 +146,7 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); SendRewardMessage(player, prefab, itemName, qty); } else @@ -155,7 +165,7 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); } else { @@ -171,11 +181,11 @@ namespace MxValheim.EventSystem GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); if (prefab != null) { - GiveItemInWorld(itemName, player, qty); + GiveItemSafe(itemName, player, qty); if (itemName == "Coins") { SendRewardMessage(player, prefab, itemName, qty); - } + } } else { @@ -183,6 +193,22 @@ namespace MxValheim.EventSystem } } + public static void GiveItemSafe(string itemName, Player player, int qty) + { + GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); + if (prefab == null) return; + + ItemDrop itemDrop = prefab.GetComponent(); + if (itemDrop == null) return; + + ItemDrop.ItemData result = player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); + + if (result == null) + { + GiveItemInWorld(itemName, player, qty); + } + } + public static void GiveItemInWorld(string itemName, Player player, int qty) { GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); @@ -224,28 +250,104 @@ namespace MxValheim.EventSystem } } - public static string[] GetRarityList(int victim) + public static string[] GetRarityList(int point) { string[] rarity = { }; - switch (victim) + switch (point) { - case < 1: + case < 100: rarity = ["Magic"]; break; - case >= 1 and < 5: + case >= 100 and < 500: rarity = ["Rare"]; break; - case >= 5 and <= 10: + case >= 500 and <= 1000: rarity = ["Epic"]; break; - case >= 11 and <= 20: + case >= 1001 and <= 2000: rarity = ["Epic", "Legendary"]; break; - case >= 21: + case >= 2001: rarity = ["Epic", "Legendary", "Mythic"]; break; } return rarity; } + + public static Dictionary EnemiesPointValue = new Dictionary + { + // --- Meadows --- + { "Boar", 10 }, + { "Neck", 10 }, + { "Greyling", 20 }, + + // --- Black Forest --- + { "Greydwarf", 20 }, + { "Greydwarf_Elite", 50 }, + { "Greydwarf_Shaman", 50 }, + { "Troll", 250 }, + { "Ghost", 100 }, + { "Skeleton", 60 }, + { "Skeleton_NoArcher", 60 }, // Melee only variant + + // --- Swamp --- + { "Blob", 50 }, + { "BlobElite", 80 }, // Oozer + { "Draugr", 100 }, + { "Draugr_Elite", 150 }, + { "Draugr_Ranged", 100 }, + { "Leech", 50 }, + { "Surtling", 80 }, + { "Wraith", 100 }, + { "Abomination", 300 }, + + // --- Mountains --- + { "Bat", 50 }, + { "Drake", 150 }, + { "Fenring", 150 }, + { "Fenring_Cultist", 150 }, + { "StoneGolem", 200 }, + { "Ulv", 200 }, + { "Wolf", 100 }, + + // --- Plains --- + { "Deathsquito", 50 }, + { "Fuling", 100 }, + { "FulingBerserker", 250 }, + { "FulingShaman", 150 }, + { "Lox", 300 }, + { "Growth", 50 }, + + // --- Mistlands --- + { "Gjall", 50 }, + { "Seeker", 100 }, + { "SeekerBrute", 300 }, // Seeker Soldier + { "SeekerBrood", 150 }, + { "Tick", 50 }, + { "Dverger", 200 }, + + // --- Ashlands --- + { "Asksvin", 50 }, + { "Charred_Melee", 100 }, // Charred Warrior + { "Charred_Archer", 100 }, // Charred Marksman + { "Charred_Mage", 100 }, // Charred Warlock + { "Charred_Twitcher", 100 }, + { "FallenValkyrie", 400 }, + { "Morgen", 300 }, + { "BonemawSerpent", 300 }, + { "Voltures", 100 }, + + // --- Ocean --- + { "Serpent", 500 }, + + // --- Bosses --- + { "Eikthyr", 100 }, + { "gd_king", 101 }, // The Elder + { "Bonemass", 102 }, + { "Dragon", 103 }, // Moder + { "GoblinKing", 104 }, // Yagluth + { "SeekerQueen", 105 }, + { "Fader", 106 } + }; } } diff --git a/MxValheim/EventSystem/Watcher.cs b/MxValheim/EventSystem/Watcher.cs index bfc12b6..8a4c9f9 100644 --- a/MxValheim/EventSystem/Watcher.cs +++ b/MxValheim/EventSystem/Watcher.cs @@ -10,7 +10,7 @@ namespace MxValheim.EventSystem { internal class Watcher { - public static int eventKill = 0; + public static int eventPoints = 0; public static void GetEventKill(long sender, ZPackage pkg) { @@ -19,22 +19,23 @@ namespace MxValheim.EventSystem int evindex = MxValheimMod.ActiveEvents.FindIndex(e => e.Position.ToString() == eventPos); - eventKill = MxValheimMod.ActiveEvents[evindex].Kills; + eventPoints = MxValheimMod.ActiveEvents[evindex].Points; } public static void SetEventKill(long sender, ZPackage pkg) { string eventName = pkg.ReadString(); string eventPos = pkg.ReadString(); + int killPoints = pkg.ReadInt(); int evindex = MxValheimMod.ActiveEvents.FindIndex(e => e.Position.ToString() == eventPos); - int evKill = MxValheimMod.ActiveEvents[evindex].Kills; + int evPoints = MxValheimMod.ActiveEvents[evindex].Points; MxValheimMod.ActiveEvents.RemoveAt(evindex); - int newKill = evKill+1; - eventKill = newKill; + int newPoints = eventPoints + killPoints; + eventPoints = newPoints; - MxValheimMod.ActiveEventData newData = new MxValheimMod.ActiveEventData(eventName, eventPos, newKill); + MxValheimMod.ActiveEventData newData = new MxValheimMod.ActiveEventData(eventName, eventPos, newPoints); MxValheimMod.ActiveEvents.Add(newData); } @@ -42,8 +43,9 @@ namespace MxValheim.EventSystem { string eventName = pkg.ReadString(); string eventPos = pkg.ReadString(); + int killPoints = pkg.ReadInt(); - MxValheimMod.ActiveEventData newData = new MxValheimMod.ActiveEventData(eventName, eventPos, 1); + MxValheimMod.ActiveEventData newData = new MxValheimMod.ActiveEventData(eventName, eventPos, killPoints); MxValheimMod.ActiveEvents.Add(newData); } @@ -58,10 +60,12 @@ namespace MxValheim.EventSystem { evindex = MxValheimMod.ActiveEvents.FindIndex(e => e.Position.ToString() == eventPos); MxValheimMod.ActiveEvents.RemoveAt(evindex); + eventPoints = 0; } else if (MxValheimMod.ActiveEvents.Count <= 0 && eventPos != null) { - // That's not the best wai to do it, but until i find a better one, it will prevent an event bugging eternaly. + // That's not the best way to do it, but until i find a better one, it will prevent an event bugging eternaly. MxValheimMod.ActiveEvents.Clear(); + eventPoints = 0; } } } diff --git a/MxValheim/MxValheim.cs b/MxValheim/MxValheim.cs index 40eb514..278730d 100644 --- a/MxValheim/MxValheim.cs +++ b/MxValheim/MxValheim.cs @@ -33,7 +33,7 @@ public class MxValheimMod : BaseUnityPlugin private const string ModGUID = "ovh.mxdev.mxvalheim"; private const string ModName = "MxValheim"; - private const string ModVersion = "1.6.11"; + private const string ModVersion = "1.6.12"; public static ConfigEntry Config_DebugRandomEventInterval; public static ConfigEntry Config_bowDrawSpeedBonusPerLevel; @@ -92,13 +92,13 @@ public class MxValheimMod : BaseUnityPlugin { public string Name; public string Position; - public int Kills; + public int Points; - public ActiveEventData(string name, string pos, int kills) + public ActiveEventData(string name, string pos, int points) { Name = name; Position = pos; - Kills = kills; + Points = points; } } @@ -239,7 +239,7 @@ public class MxValheimMod : BaseUnityPlugin Clock.m_textComponent.text = $"{Localization.instance.Localize("$clock_string_rank")} {Profiles.serverLevel} {separator} {Localization.instance.Localize("$clock_string_day")} {day} {separator} {timeString}"; } else { - Clock.m_textComponent.text = $"{eventName} {separator} {Localization.instance.Localize("$clock_string_kill")} {eventKill} {separator} {Localization.instance.Localize("$clock_string_rank")} {Profiles.serverLevel} {separator} {Localization.instance.Localize("$clock_string_day")} {day} {separator} {timeString}"; + Clock.m_textComponent.text = $"{eventName} {separator} {Localization.instance.Localize("$clock_string_kill")} {eventPoints} {separator} {Localization.instance.Localize("$clock_string_rank")} {Profiles.serverLevel} {separator} {Localization.instance.Localize("$clock_string_day")} {day} {separator} {timeString}"; } } } diff --git a/README.md b/README.md index 4cddc49..c2f2e44 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ Official **MxValheim Server** Mod. **This mod is created to be used Client/Server side. A lot of features are not working in solo mode.** +## Roadmap +- **1.6.12** Revamped EventSystem Reward System based on enemy difficulty. +- **1.6.13** Revamped Experience System based on enemy difficulty. +- **1.7.x** Stamina System Revamp +- **1.8.x** Random Mini Boss System +- **1.9.x** Biome Random Quest System + ## Dependencies - ![BepInEx for Valheim](https://thunderstore.io/c/valheim/p/denikson/BepInExPack_Valheim/) - ![Jotunn](https://thunderstore.io/c/valheim/p/ValheimModding/Jotunn/)