diff --git a/MxValheim/EventSystem/Patch.cs b/MxValheim/EventSystem/Patch.cs index fa4caf2..bed96b8 100644 --- a/MxValheim/EventSystem/Patch.cs +++ b/MxValheim/EventSystem/Patch.cs @@ -29,15 +29,6 @@ namespace MxValheim.EventSystem } } - [HarmonyPatch(typeof(RandEventSystem), nameof(RandEventSystem.Awake))] - public static class EventRadiusPatch - { - static void Postfix(RandEventSystem __instance) - { - - } - } - [HarmonyPatch(typeof(RandEventSystem), nameof(RandEventSystem.StartRandomEvent))] public static class DebugRaidFrequency { @@ -45,7 +36,30 @@ namespace MxValheim.EventSystem { if (ZRoutedRpc.instance != null) { - ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_MxKillMsg", "", "", "", "", -1); + //ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_MxKillMsg", "", "", "", "", -1); + } + } + + static void Postfix(RandEventSystem __instance) + { + RandomEvent activeEvent = RandEventSystem.instance.GetActiveEvent(); + if (activeEvent != null) + { + activeEvent.m_eventRange = 200f; + } + } + } + + [HarmonyPatch(typeof(RandEventSystem), nameof(RandEventSystem.FixedUpdate))] + public static class EventRadiusPatch + { + static void Postfix(RandEventSystem __instance) + { + RandomEvent currentEvent = __instance.GetCurrentRandomEvent(); + + if (currentEvent != null) + { + currentEvent.m_eventRange = 200f; } } } @@ -59,13 +73,7 @@ namespace MxValheim.EventSystem { __instance.m_eventIntervalMin = 10f; __instance.m_eventChance = 100f; - } - RandomEvent activeEvent = RandEventSystem.instance.GetActiveEvent(); - if (activeEvent != null) - { - activeEvent.m_eventRange = 200f; - activeEvent.m_duration = 10f; - } + } } } @@ -88,7 +96,7 @@ namespace MxValheim.EventSystem Vector3 playerPos = Player.m_localPlayer.transform.position; float distance = Vector3.Distance(playerPos, currentRaid.m_pos); - if (distance <= 96f) + if (distance <= 200f) { Heightmap.Biome currentBiome = EnvMan.instance.GetCurrentBiome(); Reward.GiveItemStatic("Coins", Reward.CalculateRewardCoin(Profiles.serverLevel, currentBiome, kill)); @@ -108,10 +116,11 @@ namespace MxValheim.EventSystem } if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot")) { - Reward.GiveEpicLootLowMats(); + Reward.GiveEpicLootDust(); + Reward.GiveEpicLootShard(); Reward.GiveEpicLootEssence(); Reward.GiveEpicLootRune(); - } + } } } } diff --git a/MxValheim/EventSystem/Reward.cs b/MxValheim/EventSystem/Reward.cs index 180756a..0cd9999 100644 --- a/MxValheim/EventSystem/Reward.cs +++ b/MxValheim/EventSystem/Reward.cs @@ -10,7 +10,7 @@ using UnityEngine; namespace MxValheim.EventSystem { internal class Reward - { + { public static int CalculateRewardCoin(int level, Heightmap.Biome biome, int kill) { Dictionary biomeBase = new Dictionary() @@ -46,16 +46,15 @@ namespace MxValheim.EventSystem return "Wood"; } - public static void GiveEpicLootLowMats() + public static void GiveEpicLootDust() { System.Random rand = new System.Random(); - int qty = rand.Next(5,10); + int qty = rand.Next(1, Profiles.serverLevel); - string[] rarity = { "Magic", "Rare", "Epic", "Legendary", "Mythic" }; - string[] type = { "Dust", "Shard", "Fragment" }; + string[] rarity = { "Rare", "Epic", "Legendary", "Mythic" }; - string itemName = $"{type[rand.Next(0, type.Length - 1)]}{rarity[rand.Next(0, rarity.Length - 1)]}"; + string itemName = $"Dust{rarity[rand.Next(0, rarity.Length - 1)]}"; Player player = Player.m_localPlayer; if (player == null) return; @@ -64,8 +63,30 @@ namespace MxValheim.EventSystem if (prefab != null) { player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); + } + else + { + Debug.LogWarning($"Item {itemName} not found in ObjectDB!"); + } + } - player.Message(MessageHud.MessageType.TopLeft, $"Received {qty}x {itemName}"); + public static void GiveEpicLootShard() + { + System.Random rand = new System.Random(); + + int qty = rand.Next(1, Profiles.serverLevel); + + string[] rarity = { "Rare", "Epic", "Legendary", "Mythic" }; + + string itemName = $"Shard{rarity[rand.Next(0, rarity.Length - 1)]}"; + + Player player = Player.m_localPlayer; + if (player == null) return; + + GameObject prefab = ObjectDB.instance.GetItemPrefab(itemName); + if (prefab != null) + { + player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); } else { @@ -77,9 +98,9 @@ namespace MxValheim.EventSystem { System.Random rand = new System.Random(); - int qty = rand.Next(1, 5); + int qty = rand.Next(1, Profiles.serverLevel); - string[] rarity = { "Magic", "Rare", "Epic", "Legendary", "Mythic" }; + string[] rarity = { "Rare", "Epic", "Legendary", "Mythic" }; string itemName = $"Essence{rarity[rand.Next(0, rarity.Length - 1)]}"; @@ -90,8 +111,6 @@ namespace MxValheim.EventSystem if (prefab != null) { player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); - - player.Message(MessageHud.MessageType.TopLeft, $"Received {qty}x {itemName}"); } else { @@ -103,9 +122,9 @@ namespace MxValheim.EventSystem { System.Random rand = new System.Random(); - int qty = 1; + int qty = rand.Next(1, 2); - string[] rarity = { "Magic", "Rare", "Epic" }; + string[] rarity = { "Rare", "Epic", "Legendary", "Mythic" }; string itemName = $"Runestone{rarity[rand.Next(0, rarity.Length - 1)]}"; @@ -116,8 +135,7 @@ namespace MxValheim.EventSystem if (prefab != null) { player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); - - player.Message(MessageHud.MessageType.TopLeft, $"Received {qty}x {itemName}"); + SendRewardMessage(player, prefab, itemName, qty); } else { @@ -136,8 +154,6 @@ namespace MxValheim.EventSystem if (prefab != null) { player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); - - player.Message(MessageHud.MessageType.TopLeft, $"Received {qty}x {itemName}"); } else { @@ -154,8 +170,10 @@ namespace MxValheim.EventSystem if (prefab != null) { player.GetInventory().AddItem(itemName, qty, 1, 0, 0, ""); - - player.Message(MessageHud.MessageType.TopLeft, $"Received {qty}x {itemName}"); + if (itemName == "Coins") + { + SendRewardMessage(player, prefab, itemName, qty); + } } else { @@ -163,6 +181,14 @@ namespace MxValheim.EventSystem } } - + public static void SendRewardMessage(Player player, GameObject prefab, string itemName, int qty) + { + if (ZRoutedRpc.instance != null) + { + ItemDrop item = prefab.GetComponent(); + string nameToken = item.m_itemData.m_shared.m_name; + ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "RPC_MxKillMsg", Player.m_localPlayer.GetHoverName(), qty.ToString(), Localization.instance.Localize(nameToken), itemName, -2); + } + } } } diff --git a/MxValheim/EventSystem/Watcher.cs b/MxValheim/EventSystem/Watcher.cs index bb0e1cf..bfc12b6 100644 --- a/MxValheim/EventSystem/Watcher.cs +++ b/MxValheim/EventSystem/Watcher.cs @@ -51,12 +51,18 @@ namespace MxValheim.EventSystem { string eventName = pkg.ReadString(); string eventPos = pkg.ReadString(); - - int evindex = MxValheimMod.ActiveEvents.FindIndex(e => e.Position.ToString() == eventPos); - - eventKill = 0; - - MxValheimMod.ActiveEvents.RemoveAt(evindex); + + int evindex = 0; + UnityEngine.Debug.Log($"RemoveEvent: ActiveEvents Count = {MxValheimMod.ActiveEvents.Count} ( {eventName} / {eventPos} )"); + if (MxValheimMod.ActiveEvents.Count > 0) + { + evindex = MxValheimMod.ActiveEvents.FindIndex(e => e.Position.ToString() == eventPos); + MxValheimMod.ActiveEvents.RemoveAt(evindex); + } 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. + MxValheimMod.ActiveEvents.Clear(); + } } } } diff --git a/MxValheim/KillFeed/Patch.cs b/MxValheim/KillFeed/Patch.cs index 4dd6619..b616985 100644 --- a/MxValheim/KillFeed/Patch.cs +++ b/MxValheim/KillFeed/Patch.cs @@ -16,6 +16,8 @@ namespace MxValheim.KillFeed { public class KillFeed_Patch { + public static string lastVictimName = ""; + public static string lastAttackerName = ""; public static Sprite LoadCustomSprite(string fileName) { string path = Path.Combine(BepInEx.Paths.PluginPath, "MxValheim", "Icons", fileName); @@ -74,6 +76,9 @@ namespace MxValheim.KillFeed int type = subRemainder % 10; // --- DECODING END --- + // Prevent the spam of multiple "same victim" kill to the feed + if (type == 2 && victim == lastVictimName && attacker == lastAttackerName) return; + // Inside OnReceiveKillMsg... Sprite biomeSprite = null; switch (biomeIndex) @@ -103,6 +108,7 @@ namespace MxValheim.KillFeed string type1Separator = Localization.instance.Localize("$killfeed_format_type1"); string type2Separator = Localization.instance.Localize("$killfeed_format_type2"); string type3Separator = Localization.instance.Localize("$killfeed_format_type3"); + string type4Separator = Localization.instance.Localize("$killfeed_format_type4"); string eventFormat = $"{victim}"; string finalMsg = ""; string attackerFormat = ""; @@ -145,13 +151,7 @@ namespace MxValheim.KillFeed finalMsg = (type == 1) ? $"{victimFormat}{type1Separator}{attackerFormat}{distanceFormat}" : // Player Death (type == 2) ? $"{attackerFormat}{type2Separator}{victimFormat}{distanceFormat}" : // Player Killed Something - $"{attackerFormat}{type2Separator}{victimFormat}{distanceFormat}"; // Failsafe - - if (encodedType == -1) - { - attacker = Player.m_localPlayer?.GetHoverName(); - finalMsg = $"{attacker.ToUpper()}{type3Separator}"; - } + $"{attackerFormat}{type2Separator}{victimFormat}{distanceFormat}"; // Failsafe Sprite weaponIcon = null; @@ -191,7 +191,30 @@ namespace MxValheim.KillFeed borderColor = new Color(0.0196f, 0.250f, 0.00750f); } - lock (_msgQueue) + if (encodedType == -1) + { + finalMsg = $"{type3Separator}{eventName}{type4Separator}"; + } + + if (encodedType == -2) + { + int qty = Convert.ToInt32(victim); + borderColor = new Color(0.0196f, 0.250f, 0.00750f); + finalMsg = $"{attacker.ToUpper()}{Localization.instance.Localize("$EventSystem_format_reward_Msg_GiveItem")}{qty} {victimInternalName}{Localization.instance.Localize("$EventSystem_format_reward_Msg_GiveItemEnd")}"; + GameObject itemObj = ObjectDB.instance.GetItemPrefab(weaponPrefab); + Sprite itemIcon = null; + if (itemObj != null) + { + ItemDrop item = itemObj.GetComponent(); + itemIcon = item?.m_itemData?.m_shared?.m_icons[0]; + } + biomeSprite = itemIcon; + } + + lastVictimName = victim; + lastAttackerName = attacker; + + lock (_msgQueue) { _msgQueue.Enqueue(finalMsg); _biomeIconQueue.Enqueue(biomeSprite); @@ -479,10 +502,8 @@ namespace MxValheim.KillFeed GameObject textObj = new GameObject("Text", typeof(RectTransform), typeof(Text)); textObj.transform.SetParent(panel.transform, false); _killText = textObj.GetComponent(); - // Important: Text needs to have its "Horizontal Overflow" set to Wrap or Overflow _killText.horizontalOverflow = HorizontalWrapMode.Overflow; - // Attempt to find Valheim's specific font, fallback to Arial if not found Font valheimFont = null; foreach (Font f in Resources.FindObjectsOfTypeAll()) { @@ -493,7 +514,6 @@ namespace MxValheim.KillFeed } } - // Corrected fallback for older Unity versions used in Valheim if (valheimFont == null) { valheimFont = Resources.GetBuiltinResource("Arial.ttf"); diff --git a/MxValheim/MxValheim.cs b/MxValheim/MxValheim.cs index bf8393e..904c983 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.7"; + private const string ModVersion = "1.6.8"; public static ConfigEntry Config_DebugRandomEventInterval; public static ConfigEntry Config_bowDrawSpeedBonusPerLevel; @@ -232,14 +232,15 @@ public class MxValheimMod : BaseUnityPlugin string timeString = clk.GetFormattedTime(); int day = EnvMan.instance.GetDay(); string pid = GetUserPlayerID(Player.m_localPlayer).ToString(); - RandomEvent activeEvent = RandEventSystem.instance.GetActiveEvent(); + RandomEvent activeEvent = RandEventSystem.instance.GetActiveEvent(); + string separator = $"]["; if (activeEvent == null) { - Clock.m_textComponent.text = $"{Localization.instance.Localize("$clock_string_rank")} {Profiles.serverLevel} | {Localization.instance.Localize("$clock_string_day")} {day} | {timeString}"; + 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} | {Localization.instance.Localize("$clock_string_kill")} {eventKill} | {Localization.instance.Localize("$clock_string_rank")} {Profiles.serverLevel} | {Localization.instance.Localize("$clock_string_day")} {day} | {timeString}"; - } + 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}"; + } } } diff --git a/MxValheim/Patch/Doors.cs b/MxValheim/Patch/Doors.cs index 48f8ff7..6816ecd 100644 --- a/MxValheim/Patch/Doors.cs +++ b/MxValheim/Patch/Doors.cs @@ -53,13 +53,13 @@ namespace MxValheim.Patch } } } - } + + } public void CloseNextDoor(Door door, ZNetView nview, string doorName) { if (door != null && nview != null && nview.IsValid()) { - nview.ClaimOwnership(); if (nview.GetZDO().GetInt("state") != 0) { Debug.Log($"AutoDoor: Closing door \"{doorName}\"."); diff --git a/MxValheim/Patch/HUD/Clock.cs b/MxValheim/Patch/HUD/Clock.cs index 339ee99..8c7cdeb 100644 --- a/MxValheim/Patch/HUD/Clock.cs +++ b/MxValheim/Patch/HUD/Clock.cs @@ -53,10 +53,9 @@ namespace MxValheim.Patch.HUD canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.sortingOrder = 999; - // --- CLOCK PANEL --- GameObject panelObj = new GameObject("TextBackground"); panelObj.transform.SetParent(m_canvasObject.transform, false); - panelObj.AddComponent().color = new Color(0, 0, 0, 0.5f); + panelObj.AddComponent().color = new Color(0, 0, 0, 0.8f); ContentSizeFitter fitter = panelObj.AddComponent(); fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize; @@ -71,36 +70,48 @@ namespace MxValheim.Patch.HUD panelRect.pivot = new Vector2(0.5f, 1.0f); panelRect.anchoredPosition = new Vector2(0, -5); - // --- TEXT --- GameObject textObj = new GameObject("ModdedText"); textObj.transform.SetParent(panelObj.transform, false); m_textComponent = textObj.AddComponent(); - m_textComponent.font = Resources.GetBuiltinResource("Arial.ttf"); + + Font valheimFont = null; + foreach (Font f in Resources.FindObjectsOfTypeAll()) + { + if (f.name == "AveriaSerifLibre-Bold") + { + valheimFont = f; + break; + } + } + + if (valheimFont == null) + { + valheimFont = Resources.GetBuiltinResource("Arial.ttf"); + } + + m_textComponent.font = valheimFont; m_textComponent.fontSize = 18; m_textComponent.color = Color.white; - // --- PROGRESS BAR CONTAINER --- - // This sits under the main rectangle GameObject barBgObj = new GameObject("BarBackground"); barBgObj.transform.SetParent(m_canvasObject.transform, false); - barBgObj.AddComponent().color = new Color(0.1f, 0.1f, 0.1f, 0.8f); // Dark background + barBgObj.AddComponent().color = new Color(0.1f, 0.1f, 0.1f, 0.8f); RectTransform barBgRect = barBgObj.GetComponent(); barBgRect.anchorMin = new Vector2(0.5f, 1.0f); barBgRect.anchorMax = new Vector2(0.5f, 1.0f); barBgRect.pivot = new Vector2(0.5f, 1.0f); - // Positioned below the clock panel (Clock is 35px high + 5px gap = -40) barBgRect.anchoredPosition = new Vector2(0, -45); - barBgRect.sizeDelta = new Vector2(180, 8); // Match width of clock, small height + barBgRect.sizeDelta = new Vector2(180, 8); // --- PROGRESS BAR FILL --- GameObject fillObj = new GameObject("BarFill"); fillObj.transform.SetParent(barBgObj.transform, false); - fillObj.AddComponent().color = Color.yellow; // Classic Valheim XP color + fillObj.AddComponent().color = Color.yellow; m_barFill = fillObj.GetComponent(); m_barFill.anchorMin = new Vector2(0, 0); - m_barFill.anchorMax = new Vector2(0.5f, 1); // This X value (0.5) will be updated via code + m_barFill.anchorMax = new Vector2(0.5f, 1); m_barFill.pivot = new Vector2(0, 0.5f); m_barFill.offsetMin = Vector2.zero; m_barFill.offsetMax = Vector2.zero;