using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Jewelcrafting; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using PvpOverhaul.API; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; using WarheimStuff.RaidSystem; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("WarheimStuff")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("WarheimStuff")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.1.0")] namespace WarheimStuff { [HarmonyPatch(typeof(Skills), "Awake")] [HarmonyAfter(new string[] { "org.bepinex.plugins.professions" })] public static class ProfessionsKeepLevelsPatch { private static readonly HashSet PatchedButtons = new HashSet(); private static Type _professionsType; private static Type _helperType; private static Type _skillElementType; private static FieldInfo _professionPanelElementsField; private static FieldInfo _allowUnselectField; private static FieldInfo _professionChangeCooldownField; private static FieldInfo _serverTimeField; private static MethodInfo _updateSelectPanelSelectionsMethod; private static MethodInfo _fromProfessionMethod; private static MethodInfo _getActiveProfessionsMethod; private static MethodInfo _storeActiveProfessionsMethod; private static MethodInfo _getInactiveProfessionsMethod; private static MethodInfo _storeInactiveProfessionsMethod; private static MethodInfo _getHumanFriendlyTimeMethod; private static bool _reflectionReady; private static void Postfix() { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown try { if (!PrepareReflection() || !(_professionPanelElementsField?.GetValue(null) is IDictionary { Count: not 0 } dictionary)) { return; } foreach (DictionaryEntry item in dictionary) { object professionObj = item.Key; object? value = item.Value; GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { continue; } Component component = val.GetComponent(_skillElementType); if ((Object)(object)component == (Object)null) { continue; } object? obj = AccessTools.Field(_skillElementType, "Select")?.GetValue(component); Button val2 = (Button)((obj is Button) ? obj : null); if (!((Object)(object)val2 == (Object)null) && PatchedButtons.Add(((Object)val2).GetInstanceID())) { ((UnityEventBase)val2.onClick).RemoveAllListeners(); ((UnityEvent)val2.onClick).AddListener((UnityAction)delegate { OnProfessionButtonClicked(professionObj); }); } } } catch (Exception arg) { Debug.LogError((object)$"[WarheimStuff] Failed to rewire Professions buttons: {arg}"); } } private static bool PrepareReflection() { if (_reflectionReady) { return true; } _professionsType = AccessTools.TypeByName("Professions.Professions"); _helperType = AccessTools.TypeByName("Professions.Helper"); _skillElementType = AccessTools.TypeByName("Skill_Element"); if (_professionsType == null || _helperType == null || _skillElementType == null) { return false; } _professionPanelElementsField = AccessTools.Field(_professionsType, "professionPanelElements"); _allowUnselectField = AccessTools.Field(_professionsType, "allowUnselect"); _professionChangeCooldownField = AccessTools.Field(_professionsType, "professionChangeCooldown"); _serverTimeField = AccessTools.Field(_professionsType, "serverTime"); _updateSelectPanelSelectionsMethod = AccessTools.Method(_professionsType, "UpdateSelectPanelSelections", (Type[])null, (Type[])null); _fromProfessionMethod = AccessTools.Method(_professionsType, "fromProfession", (Type[])null, (Type[])null); _getActiveProfessionsMethod = AccessTools.Method(_helperType, "getActiveProfessions", (Type[])null, (Type[])null); _storeActiveProfessionsMethod = AccessTools.Method(_helperType, "storeActiveProfessions", (Type[])null, (Type[])null); _getInactiveProfessionsMethod = AccessTools.Method(_helperType, "getInactiveProfessions", (Type[])null, (Type[])null); _storeInactiveProfessionsMethod = AccessTools.Method(_helperType, "storeInactiveProfessions", (Type[])null, (Type[])null); _getHumanFriendlyTimeMethod = AccessTools.Method(_helperType, "getHumanFriendlyTime", (Type[])null, (Type[])null); _reflectionReady = _professionPanelElementsField != null && _allowUnselectField != null && _professionChangeCooldownField != null && _serverTimeField != null && _updateSelectPanelSelectionsMethod != null && _fromProfessionMethod != null && _getActiveProfessionsMethod != null && _storeActiveProfessionsMethod != null && _getInactiveProfessionsMethod != null && _storeInactiveProfessionsMethod != null && _getHumanFriendlyTimeMethod != null; return _reflectionReady; } private static void OnProfessionButtonClicked(object professionObj) { try { if (!PrepareReflection() || (Object)(object)Player.m_localPlayer == (Object)null) { return; } object obj = _getActiveProfessionsMethod.Invoke(null, null); if (obj == null) { return; } Type type = obj.GetType(); MethodInfo method = type.GetMethod("Contains"); MethodInfo method2 = type.GetMethod("Add"); MethodInfo method3 = type.GetMethod("Remove"); if (method != null && (bool)method.Invoke(obj, new object[1] { professionObj })) { if (!CanUnselectNow()) { return; } method3?.Invoke(obj, new object[1] { professionObj }); _storeActiveProfessionsMethod.Invoke(null, new object[1] { obj }); Player.m_localPlayer.m_customData["Professions LastProfessionChange"] = GetServerUnixTime().ToString(); } else { RestoreOldInactiveLevelIfNeeded(professionObj); method2?.Invoke(obj, new object[1] { professionObj }); _storeActiveProfessionsMethod.Invoke(null, new object[1] { obj }); } _updateSelectPanelSelectionsMethod.Invoke(null, null); } catch (Exception arg) { Debug.LogError((object)$"[WarheimStuff] Error in profession click override: {arg}"); } } private static bool CanUnselectNow() { object value = _allowUnselectField.GetValue(null); object value2 = _professionChangeCooldownField.GetValue(null); object obj = value?.GetType().GetProperty("Value")?.GetValue(value); object obj2 = value2?.GetType().GetProperty("Value")?.GetValue(value2); bool flag = string.Equals(obj?.ToString(), "On", StringComparison.OrdinalIgnoreCase); float num = ((obj2 != null) ? Convert.ToSingle(obj2) : 0f); if (!flag) { return false; } if (num <= 0f) { return true; } if (!Player.m_localPlayer.m_customData.TryGetValue("Professions LastProfessionChange", out var value3)) { return true; } if (!int.TryParse(value3, out var result)) { return true; } int serverUnixTime = GetServerUnixTime(); int num2 = result + (int)(num * 3600f) - serverUnixTime; if (num2 > 0) { string text = (string)_getHumanFriendlyTimeMethod.Invoke(null, new object[1] { num2 }); ((Character)Player.m_localPlayer).Message((MessageType)2, "You can change your profession in " + text + ".", 0, (Sprite)null); return false; } return true; } private static int GetServerUnixTime() { DateTime dateTime = (DateTime)_serverTimeField.GetValue(null); return (int)((DateTimeOffset)dateTime).ToUnixTimeSeconds(); } private static Skill GetOrCreateSkill(Player player, SkillType skillType) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return null; } object value = Traverse.Create((object)player).Field("m_skills").GetValue(); if (value == null) { return null; } object value2 = Traverse.Create(value).Method("GetSkill", new object[1] { skillType }).GetValue(); return (Skill)((value2 is Skill) ? value2 : null); } private static void RestoreOldInactiveLevelIfNeeded(object professionObj) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) try { object obj = _getInactiveProfessionsMethod.Invoke(null, null); if (!(obj is IDictionary dictionary) || !dictionary.Contains(professionObj)) { return; } float num = 0f; object obj2 = dictionary[professionObj]; if (obj2 != null) { num = Convert.ToSingle(obj2); } if (num <= 0f) { return; } object obj3 = _fromProfessionMethod.Invoke(null, new object[1] { professionObj }); if (obj3 != null) { SkillType skillType = (SkillType)obj3; Skill orCreateSkill = GetOrCreateSkill(Player.m_localPlayer, skillType); if (orCreateSkill != null) { orCreateSkill.m_level = Mathf.Max(orCreateSkill.m_level, num); } dictionary.Remove(professionObj); _storeInactiveProfessionsMethod.Invoke(null, new object[1] { obj }); } } catch (Exception arg) { Debug.LogWarning((object)$"[WarheimStuff] Failed to restore old inactive profession level: {arg}"); } } } internal static class WarheimGems { public struct IncreasePercentPower { [MultiplicativePercentagePower] public float Power; } public struct ReductionPercentPower { [InverseMultiplicativePercentagePower] public float Power; } public struct ResiliencePower { [AdditivePower] public float Power; } [HarmonyPatch(typeof(Character), "GetMaxHealth")] private static class MalachiteHealthPatch { private static void Postfix(Character __instance, ref float __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { __result *= 1f + GetIncrease(val, "Vitalité de la malachite") / 100f; } } } [HarmonyPatch(typeof(Player), "GetMaxStamina")] private static class MalachiteStaminaPatch { private static void Postfix(Player __instance, ref float __result) { __result *= 1f + GetIncrease(__instance, "Endurance de la malachite") / 100f; } } [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class MalachiteDamagePatch { private static void Prefix(Character __instance, HitData hit) { if (hit != null) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && (Object)(object)val != (Object)(object)__instance) { hit.ApplyModifier(1f + GetIncrease(val, "Puissance de la malachite") / 100f); } } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class GemDamageReductionPatch { private static void Prefix(Character __instance, HitData hit) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && hit != null) { Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)(object)__instance)) { hit.m_damage.m_pierce *= RemainingDamage(GetReduction(val, "Égide perforante de l'ambre")); hit.m_damage.m_blunt *= RemainingDamage(GetReduction(val, "Égide contondante de l'ambre")); hit.m_damage.m_slash *= RemainingDamage(GetReduction(val, "Égide tranchante de l'ambre")); hit.m_damage.m_lightning *= RemainingDamage(GetReduction(val, "Protection foudroyante de l'alexandrite")); hit.m_damage.m_poison *= RemainingDamage(GetReduction(val, "Protection toxique de l'alexandrite")); hit.m_damage.m_fire *= RemainingDamage(GetReduction(val, "Protection ardente de l'alexandrite")); hit.m_damage.m_spirit *= RemainingDamage(GetReduction(val, "Protection spirituelle de l'alexandrite")); hit.m_damage.m_frost *= RemainingDamage(GetReduction(val, "Protection glaciale de l'alexandrite")); hit.ApplyModifier(RemainingDamage(GetReduction(val, "Rempart d'ambre"))); } } } } [HarmonyPatch(typeof(SEMan), "ModifyAttackStaminaUsage")] private static class AmberAttackStaminaPatch { private static void Postfix(Character ___m_character, ref float staminaUse) { Player val = (Player)(object)((___m_character is Player) ? ___m_character : null); if (val != null) { staminaUse *= RemainingDamage(GetReduction(val, "Assaut d'ambre")); } } } [HarmonyPatch(typeof(SEMan), "ModifyJumpStaminaUsage")] private static class AmberJumpStaminaPatch { private static void Postfix(Character ___m_character, ref float staminaUse) { Player val = (Player)(object)((___m_character is Player) ? ___m_character : null); if (val != null) { staminaUse *= RemainingDamage(GetReduction(val, "Bond d'ambre")); } } } [HarmonyPatch(typeof(PvpResilienceAPI), "GetLocalEquippedResilience")] private static class AzuriteResiliencePatch { private static void Postfix(Player player, ref float __result) { __result += GetResilience(player); } } private const string ComfortTweaksGuid = "xyz.alcan.comfortcalc"; private const string MalachiteAttackSpeed = "Vivacité de la malachite"; private const string MalachiteHealth = "Vitalité de la malachite"; private const string MalachiteStamina = "Endurance de la malachite"; private const string MalachiteDamage = "Puissance de la malachite"; private const string AmberPierceResistance = "Égide perforante de l'ambre"; private const string AmberBluntResistance = "Égide contondante de l'ambre"; private const string AmberSlashResistance = "Égide tranchante de l'ambre"; private const string AmberShieldReduction = "Rempart d'ambre"; private const string AmberAttackStamina = "Assaut d'ambre"; private const string AmberJumpStamina = "Bond d'ambre"; private const string AlexandriteLightningResistance = "Protection foudroyante de l'alexandrite"; private const string AlexandritePoisonResistance = "Protection toxique de l'alexandrite"; private const string AlexandriteFireResistance = "Protection ardente de l'alexandrite"; private const string AlexandriteSpiritResistance = "Protection spirituelle de l'alexandrite"; private const string AlexandriteFrostResistance = "Protection glaciale de l'alexandrite"; private const string AzuriteResilience = "Warheim Azurite Resilience"; private static readonly int ColorProperty = Shader.PropertyToID("_Color"); private static readonly int BaseColorProperty = Shader.PropertyToID("_BaseColor"); private static readonly int EmissionColorProperty = Shader.PropertyToID("_EmissionColor"); private static bool initialized; private const string GemConfiguration = "Vivacité de la malachite:\r\n slot: legs\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nVitalité de la malachite:\r\n slot: chest\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nEndurance de la malachite:\r\n slot: head\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nPuissance de la malachite:\r\n slot: [weapon, bow, crossbow, magic]\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nÉgide perforante de l'ambre:\r\n slot: chest\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nÉgide contondante de l'ambre:\r\n slot: legs\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nÉgide tranchante de l'ambre:\r\n slot: head\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nRempart d'ambre:\r\n slot: shield\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nAssaut d'ambre:\r\n slot: weapon\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nBond d'ambre:\r\n slot: cloak\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nProtection foudroyante de l'alexandrite:\r\n slot: chest\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection toxique de l'alexandrite:\r\n slot: head\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection ardente de l'alexandrite:\r\n slot: legs\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection spirituelle de l'alexandrite:\r\n slot: utility\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection glaciale de l'alexandrite:\r\n slot: cloak\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nWarheim Azurite Resilience:\r\n slot: [head, legs, chest, cloak, utility]\r\n gem: Azurite\r\n power: [1, 2, 3]\r\ngems:\r\n Meadows:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Black Forest:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Swamp:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Mountain:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Plains:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Mistlands:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Ash Lands:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Deep North:\r\n Malachite: 0.0125\r\n Amber: 0.0125\r\n Alexandrite: 0.0125\r\n Azurite: 0.0125\r\n"; public static void Initialize() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if (!initialized && API.IsLoaded()) { initialized = true; RegisterEffects(); RegisterGemFamily("Malachite", new Color(0.05f, 0.55f, 0.18f, 1f), new Color(1.35f, 0.03f, 0.02f, 1f)); RegisterGemFamily("Amber", new Color(0.015f, 0.012f, 0.008f, 1f), new Color(1.5f, 0.8f, 0.02f, 1f)); RegisterGemFamily("Alexandrite", new Color(0.92f, 0.96f, 1f, 1f), new Color(0.05f, 0.4f, 1.4f, 1f)); RegisterGemFamily("Azurite", new Color(0.38f, 0.05f, 0.58f, 1f), new Color(1.5f, 0.32f, 0.01f, 1f)); API.AddGemConfig("Vivacité de la malachite:\r\n slot: legs\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nVitalité de la malachite:\r\n slot: chest\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nEndurance de la malachite:\r\n slot: head\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nPuissance de la malachite:\r\n slot: [weapon, bow, crossbow, magic]\r\n gem: Malachite\r\n power: [1, 1.5, 2]\r\nÉgide perforante de l'ambre:\r\n slot: chest\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nÉgide contondante de l'ambre:\r\n slot: legs\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nÉgide tranchante de l'ambre:\r\n slot: head\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nRempart d'ambre:\r\n slot: shield\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nAssaut d'ambre:\r\n slot: weapon\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nBond d'ambre:\r\n slot: cloak\r\n gem: Amber\r\n power: [1, 1.5, 2]\r\nProtection foudroyante de l'alexandrite:\r\n slot: chest\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection toxique de l'alexandrite:\r\n slot: head\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection ardente de l'alexandrite:\r\n slot: legs\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection spirituelle de l'alexandrite:\r\n slot: utility\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nProtection glaciale de l'alexandrite:\r\n slot: cloak\r\n gem: Alexandrite\r\n power: [1, 1.5, 2]\r\nWarheim Azurite Resilience:\r\n slot: [head, legs, chest, cloak, utility]\r\n gem: Azurite\r\n power: [1, 2, 3]\r\ngems:\r\n Meadows:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Black Forest:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Swamp:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Mountain:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Plains:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Mistlands:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Ash Lands:\r\n Malachite: 0\r\n Amber: 0\r\n Alexandrite: 0\r\n Azurite: 0\r\n Deep North:\r\n Malachite: 0.0125\r\n Amber: 0.0125\r\n Alexandrite: 0.0125\r\n Azurite: 0.0125\r\n"); RegisterAttackSpeedModifier(); API.OnEffectRecalc += SyncLocalResilience; AddFrenchTranslations(); } } private static void RegisterAttackSpeedModifier() { if (!Chainloader.PluginInfos.TryGetValue("xyz.alcan.comfortcalc", out var value) || (Object)(object)value.Instance == (Object)null) { Debug.LogWarning((object)"[WarheimGems] ComfortTweaks n'est pas chargé, le bonus de vitesse d'attaque de la malachite est désactivé."); return; } Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("AnimationSpeedManager"); Type type2 = type?.GetNestedType("Handler", BindingFlags.Public); MethodInfo methodInfo = type?.GetMethod("Add", BindingFlags.Static | BindingFlags.Public); MethodInfo method = typeof(WarheimGems).GetMethod("ApplyMalachiteAttackSpeed", BindingFlags.Static | BindingFlags.NonPublic); if (type2 == null || methodInfo == null || method == null) { Debug.LogWarning((object)"[WarheimGems] AnimationSpeedManager est introuvable dans ComfortTweaks."); return; } Delegate obj = Delegate.CreateDelegate(type2, method); methodInfo.Invoke(null, new object[2] { obj, 400 }); } private static double ApplyMalachiteAttackSpeed(Character character, double speed) { Player val = (Player)(object)((character is Player) ? character : null); if (val == null || !((Character)val).InAttack()) { return speed; } return speed * (1.0 + (double)GetMalachiteAttackSpeed(val)); } private static void RegisterGemFamily(string gemName, Color baseColor, Color emissionColor) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) GameObject shard = API.AddShardFromTemplate(gemName, gemName, baseColor); Material val = CreateGemMaterial(gemName, shard, baseColor, emissionColor); if ((Object)(object)val != (Object)null) { GameObject val2 = API.AddUncutFromTemplate(gemName, gemName, val); API.AddUncutGem(val2, gemName, (ConfigEntry)null); API.AddDestructibleFromTemplate(gemName, gemName, val); API.AddTieredGemFromTemplate(gemName, gemName, val, baseColor); } else { GameObject val3 = API.AddUncutFromTemplate(gemName, gemName, baseColor); API.AddUncutGem(val3, gemName, (ConfigEntry)null); API.AddDestructibleFromTemplate(gemName, gemName, baseColor); API.AddTieredGemFromTemplate(gemName, gemName, baseColor); } } private static Material CreateGemMaterial(string gemName, GameObject shard, Color baseColor, Color emissionColor) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)shard == (Object)null) { return null; } Transform val = shard.transform.Find("attach/Custom_Color_Mesh"); MeshRenderer val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null); Material val3 = (((Object)(object)val2 != (Object)null) ? ((Renderer)val2).sharedMaterial : null); if ((Object)(object)val3 == (Object)null) { return null; } Material val4 = new Material(val3) { name = "Warheim_" + gemName + "_Gem_Material" }; if (val4.HasProperty(ColorProperty)) { val4.SetColor(ColorProperty, baseColor); } if (val4.HasProperty(BaseColorProperty)) { val4.SetColor(BaseColorProperty, baseColor); } if (val4.HasProperty(EmissionColorProperty)) { val4.EnableKeyword("_EMISSION"); val4.SetColor(EmissionColorProperty, emissionColor); } ((Renderer)val2).sharedMaterial = val4; return val4; } private static void RegisterEffects() { API.AddGemEffect("Vivacité de la malachite", "Increases attack speed.", "Attack speed is increased by $1%."); API.AddGemEffect("Vitalité de la malachite", "Increases maximum health.", "Maximum health is increased by $1%."); API.AddGemEffect("Endurance de la malachite", "Increases maximum stamina.", "Maximum stamina is increased by $1%."); API.AddGemEffect("Puissance de la malachite", "Increases weapon damage.", "All damage dealt by the socketed weapon is increased by $1%."); API.AddGemEffect("Égide perforante de l'ambre", "Reduces piercing damage taken.", "Piercing damage taken is reduced by $1%."); API.AddGemEffect("Égide contondante de l'ambre", "Reduces blunt damage taken.", "Blunt damage taken is reduced by $1%."); API.AddGemEffect("Égide tranchante de l'ambre", "Reduces slashing damage taken.", "Slashing damage taken is reduced by $1%."); API.AddGemEffect("Rempart d'ambre", "Reduces all damage taken while using a shield.", "All damage taken is reduced by $1%."); API.AddGemEffect("Assaut d'ambre", "Reduces melee attack stamina usage.", "Melee attack stamina usage is reduced by $1%."); API.AddGemEffect("Bond d'ambre", "Reduces jump stamina usage.", "Jump stamina usage is reduced by $1%."); API.AddGemEffect("Protection foudroyante de l'alexandrite", "Reduces lightning damage taken.", "Lightning damage taken is reduced by $1%."); API.AddGemEffect("Protection toxique de l'alexandrite", "Reduces poison damage taken.", "Poison damage taken is reduced by $1%."); API.AddGemEffect("Protection ardente de l'alexandrite", "Reduces fire damage taken.", "Fire damage taken is reduced by $1%."); API.AddGemEffect("Protection spirituelle de l'alexandrite", "Reduces spirit damage taken.", "Spirit damage taken is reduced by $1%."); API.AddGemEffect("Protection glaciale de l'alexandrite", "Reduces frost damage taken.", "Frost damage taken is reduced by $1%."); API.AddGemEffect("Warheim Azurite Resilience", "Increases PvP resilience.", "PvP resilience is increased by $1."); } private static float GetMalachiteAttackSpeed(Player player) { return GetIncrease(player, "Vivacité de la malachite") / 100f; } private static void SyncLocalResilience() { if ((Object)(object)Player.m_localPlayer != (Object)null) { PvpResilienceAPI.SyncLocalPlayerResilienceDelayed(Player.m_localPlayer); } } private static float GetIncrease(Player player, string effect) { return ((Object)(object)player != (Object)null) ? API.GetEffectPower(player, effect).Power : 0f; } private static float GetReduction(Player player, string effect) { return ((Object)(object)player != (Object)null) ? API.GetEffectPower(player, effect).Power : 0f; } private static float GetResilience(Player player) { return ((Object)(object)player != (Object)null) ? API.GetEffectPower(player, "Warheim Azurite Resilience").Power : 0f; } private static float RemainingDamage(float reduction) { return 1f - Mathf.Clamp(reduction, 0f, 100f) / 100f; } private static void AddFrenchTranslations() { Dictionary dictionary = new Dictionary(); AddGemTranslations(dictionary, "malachite", "Malachite", "Malachite simple", "Malachite avancée", "Malachite parfaite"); AddGemTranslations(dictionary, "amber", "Ambre", "Ambre simple", "Ambre avancé", "Ambre parfait"); AddGemTranslations(dictionary, "alexandrite", "Alexandrite", "Alexandrite simple", "Alexandrite avancée", "Alexandrite parfaite"); AddGemTranslations(dictionary, "azurite", "Azurite", "Azurite simple", "Azurite avancée", "Azurite parfaite"); AddEffectTranslation(dictionary, "Vivacité de la malachite", "Vivacité de la malachite", "Augmente la vitesse d'attaque.", "La vitesse d'attaque est augmentée de $1%."); AddEffectTranslation(dictionary, "Vitalité de la malachite", "Vitalité de la malachite", "Augmente la vie maximale.", "La vie maximale est augmentée de $1%."); AddEffectTranslation(dictionary, "Endurance de la malachite", "Endurance de la malachite", "Augmente l'endurance maximale.", "L'endurance maximale est augmentée de $1%."); AddEffectTranslation(dictionary, "Puissance de la malachite", "Puissance de la malachite", "Augmente les dégâts de l'arme.", "Tous les dégâts de l'arme sertie sont augmentés de $1%."); AddEffectTranslation(dictionary, "Égide perforante de l'ambre", "Égide perforante de l'ambre", "Réduit les dégâts perforants subis.", "Les dégâts perforants subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Égide contondante de l'ambre", "Égide contondante de l'ambre", "Réduit les dégâts contondants subis.", "Les dégâts contondants subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Égide tranchante de l'ambre", "Égide tranchante de l'ambre", "Réduit les dégâts tranchants subis.", "Les dégâts tranchants subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Rempart d'ambre", "Rempart d'ambre", "Réduit tous les dégâts subis avec un bouclier serti.", "Tous les dégâts subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Assaut d'ambre", "Assaut d'ambre", "Réduit le coût d'endurance des attaques de mêlée.", "Le coût d'endurance des attaques de mêlée est réduit de $1%."); AddEffectTranslation(dictionary, "Bond d'ambre", "Bond d'ambre", "Réduit le coût d'endurance des sauts.", "Le coût d'endurance des sauts est réduit de $1%."); AddEffectTranslation(dictionary, "Protection foudroyante de l'alexandrite", "Protection foudroyante de l'alexandrite", "Réduit les dégâts de foudre subis.", "Les dégâts de foudre subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Protection toxique de l'alexandrite", "Protection toxique de l'alexandrite", "Réduit les dégâts de poison subis.", "Les dégâts de poison subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Protection ardente de l'alexandrite", "Protection ardente de l'alexandrite", "Réduit les dégâts de feu subis.", "Les dégâts de feu subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Protection spirituelle de l'alexandrite", "Protection spirituelle de l'alexandrite", "Réduit les dégâts d'esprit subis.", "Les dégâts d'esprit subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Protection glaciale de l'alexandrite", "Protection glaciale de l'alexandrite", "Réduit les dégâts de givre subis.", "Les dégâts de givre subis sont réduits de $1%."); AddEffectTranslation(dictionary, "Warheim Azurite Resilience", "Résilience de l'azurite", "Augmente la résilience en combat JcJ.", "La résilience JcJ est augmentée de $1."); CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "French"; localization.AddTranslation(ref text, dictionary); } private static void AddGemTranslations(Dictionary translations, string key, string displayName, string simpleName, string advancedName, string perfectName) { string value = "Une gemme pouvant être sertie dans une pièce d'équipement."; string text = displayName.ToLowerInvariant(); string text2 = (("aeiouyh".IndexOf(text[0]) >= 0) ? ("d'" + text) : ("de " + text)); translations["jc_merged_gemstone_" + key] = displayName; translations["jc_shattered_" + key + "_crystal"] = "Éclat " + text2; translations["jc_shattered_" + key + "_crystal_description"] = value; translations["jc_uncut_" + key + "_stone"] = displayName + " brute"; translations["jc_uncut_" + key + "_stone_description"] = "Une gemme brute pouvant être taillée à la table du lapidaire."; translations["jc_" + key + "_socket"] = simpleName; translations["jc_" + key + "_socket_description"] = value; translations["jc_adv_" + key + "_socket"] = advancedName; translations["jc_adv_" + key + "_socket_description"] = value; translations["jc_perfect_" + key + "_socket"] = perfectName; translations["jc_perfect_" + key + "_socket_description"] = value; translations["jc_raw_" + key + "_gemstone"] = "Formation " + text2; } private static void AddEffectTranslation(Dictionary translations, string effect, string name, string description, string detailedDescription) { string text = "jc_effect_" + effect.Replace(" ", "_").ToLowerInvariant(); translations[text] = name; translations[text + "_desc"] = description; translations[text + "_desc_detail"] = detailedDescription; } } internal static class WarheimGemTweaks { private struct RestedCostState { public StatusEffect Rested; public float OriginalTtl; public float FixedCost; } [HarmonyPatch(typeof(Character), "Damage")] private static class OverexertionFixedRestedCostPatch { [HarmonyPrepare] private static bool Prepare() { return ResolveMembers(); } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(HitData hit, ref RestedCostState __state) { if (!API.IsLoaded() || !IsComfortTweaksEnabled() || hit == null) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { object obj = getEffectPowerMethod.Invoke(null, new object[2] { val, "Overexertion" }); float num = Convert.ToSingle(penaltyField.GetValue(obj)); StatusEffect statusEffect = ((Character)val).GetSEMan().GetStatusEffect(RestedHash); if (!((Object)(object)statusEffect == (Object)null) && !(num <= 0f)) { __state.Rested = statusEffect; __state.OriginalTtl = statusEffect.m_ttl; __state.FixedCost = GetFixedRestedCost(num); } } } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(RestedCostState __state) { if ((Object)(object)__state.Rested != (Object)null) { __state.Rested.m_ttl = __state.OriginalTtl - __state.FixedCost; } } } private const string OverexertionEffect = "Overexertion"; private const float SimpleRestedCost = 15f; private const float AdvancedRestedCost = 25f; private const float PerfectRestedCost = 45f; private static readonly int RestedHash = StringExtensionMethods.GetStableHashCode("Rested"); private static MethodInfo getEffectPowerMethod; private static FieldInfo penaltyField; private static FieldInfo comfortEnabledField; private static PropertyInfo comfortEnabledValueProperty; private static bool ResolveMembers() { Type type = AccessTools.TypeByName("ComfortTweaks.gems.Overexertion+Config"); Type type2 = AccessTools.TypeByName("ComfortTweaks.ComfortTweaks"); if (type == null || type2 == null) { return false; } penaltyField = AccessTools.Field(type, "Penalty"); comfortEnabledField = AccessTools.Field(type2, "isEnabled"); comfortEnabledValueProperty = comfortEnabledField?.FieldType.GetProperty("Value"); MethodInfo[] methods = typeof(API).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "GetEffectPower" && methodInfo.IsGenericMethodDefinition && methodInfo.GetParameters().Length == 2) { getEffectPowerMethod = methodInfo.MakeGenericMethod(type); break; } } return getEffectPowerMethod != null && penaltyField != null && comfortEnabledField != null && comfortEnabledValueProperty != null; } private static bool IsComfortTweaksEnabled() { object value = comfortEnabledField.GetValue(null); return value != null && (bool)comfortEnabledValueProperty.GetValue(value, null); } private static float GetFixedRestedCost(float penalty) { if (penalty <= 0f) { return 0f; } if (penalty < 1.5f) { return 15f; } if (penalty < 3f) { return 25f; } return 45f; } } public static class WarheimPdf { public class SE_WarheimPdfCooldown : StatusEffect { } private static class PdfCastBar { private static GameObject _root; private static Text _text; private static readonly Color Gold = new Color(1f, 0.78f, 0.35f, 1f); public static void Show() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { _root.SetActive(true); SetProgress(0f, 10f); return; } Hud instance = Hud.instance; object obj; if (instance == null) { obj = null; } else { GameObject rootObject = instance.m_rootObject; obj = ((rootObject != null) ? rootObject.GetComponentInParent() : null); } Canvas val = (Canvas)obj; if (!((Object)(object)val == (Object)null)) { _root = new GameObject("WarheimPdfCastText"); _root.transform.SetParent(((Component)val).transform, false); RectTransform val2 = _root.AddComponent(); val2.anchorMin = new Vector2(0.5f, 0f); val2.anchorMax = new Vector2(0.5f, 0f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = new Vector2(0f, 145f); val2.sizeDelta = new Vector2(520f, 40f); _text = _root.AddComponent(); _text.alignment = (TextAnchor)4; _text.font = Resources.GetBuiltinResource("Arial.ttf"); _text.fontSize = 22; _text.fontStyle = (FontStyle)1; ((Graphic)_text).color = Gold; Outline val3 = _root.AddComponent(); ((Shadow)val3).effectColor = Color.black; ((Shadow)val3).effectDistance = new Vector2(1.8f, -1.8f); SetProgress(0f, 10f); } } public static void SetProgress(float progress, float remaining) { if (!((Object)(object)_root == (Object)null) && !((Object)(object)_text == (Object)null)) { _text.text = $"Canalisation de la Pierre de Foyer... {remaining:0.0}s"; } } public static void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } } [HarmonyPatch(typeof(Humanoid), "UseItem")] private static class Humanoid_UseItem_PdfPatch { private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, bool fromInventoryGui) { if ((Object)(object)__instance == (Object)null || item == null || !IsPdf(item)) { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null) { return true; } TryUse(val, inventory, item); return false; } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class Player_OnSpawned_PdfCooldownPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ((MonoBehaviour)__instance).StartCoroutine(ReapplyCooldownAfterSpawn(__instance)); } } } private const string PdfSimplePrefab = "PdfSimple"; private const string PdfWarheimPrefab = "PdfWarheim"; private const string CooldownKey = "Warheim.Pdf.CooldownUntilUtc"; private const float PdfSimpleCooldownSeconds = 3600f; private const float PdfWarheimCooldownSeconds = 1800f; private const float CastDuration = 10f; private static bool _isCasting; private const string PdfSimpleCooldownSeName = "SE_WarheimPdfSimpleCooldown"; private const string PdfWarheimCooldownSeName = "SE_WarheimPdfWarheimCooldown"; private static Sprite _pdfSimpleIcon; private static Sprite _pdfWarheimIcon; private static StatusEffect _pdfSimpleCooldownSe; private static StatusEffect _pdfWarheimCooldownSe; private static AudioClip _castAudioClip; private static GameObject _castVfxPrefab; public static bool IsPdf(ItemData item) { string prefabName = GetPrefabName(item); return prefabName == "PdfSimple" || prefabName == "PdfWarheim"; } private static bool IsSimple(ItemData item) { return GetPrefabName(item) == "PdfSimple"; } private static bool IsWarheim(ItemData item) { return GetPrefabName(item) == "PdfWarheim"; } private static string GetPrefabName(ItemData item) { return ((Object)(object)item?.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : ""; } private static float GetCooldownSeconds(ItemData item) { return IsWarheim(item) ? 1800f : 3600f; } private static bool ShouldConsume(ItemData item) { return IsSimple(item); } public static bool TryUse(Player player, Inventory sourceInventory, ItemData item) { if ((Object)(object)player == (Object)null || item == null || !IsPdf(item)) { return false; } if (sourceInventory == null) { sourceInventory = ((Humanoid)player).GetInventory(); } if (_isCasting) { ((Character)player).Message((MessageType)2, "La Pierre de Foyer est déjà en cours d'utilisation.", 0, (Sprite)null); return true; } double cooldownRemainingSeconds = GetCooldownRemainingSeconds(player); if (cooldownRemainingSeconds > 0.0) { ((Character)player).Message((MessageType)2, "Pierre de Foyer en rechargement : " + FormatTime(cooldownRemainingSeconds), 0, (Sprite)null); return true; } if (!CanTeleport(player, showMessage: true)) { return true; } ((MonoBehaviour)player).StartCoroutine(CastAndTeleport(player, sourceInventory, item)); return true; } private static IEnumerator CastAndTeleport(Player player, Inventory sourceInventory, ItemData item) { _isCasting = true; AudioSource castAudio = StartCastSound(player); GameObject castVfx = StartCastVfx(player); player.StartEmote("sit", false); Vector3 startPosition = ((Component)player).transform.position; ((Character)player).Message((MessageType)2, "Canalisation de la Pierre de Foyer...", 0, (Sprite)null); float timer = 0f; PdfCastBar.Show(); while (timer < 10f) { if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { _isCasting = false; PdfCastBar.Hide(); StopCastSound(castAudio); StopCastVfx(castVfx); yield break; } if (IsTryingToMove() || Vector3.Distance(startPosition, ((Component)player).transform.position) > 0.75f) { ((Character)player).Message((MessageType)2, "Canalisation interrompue.", 0, (Sprite)null); _isCasting = false; PdfCastBar.Hide(); StopCastSound(castAudio); StopCastVfx(castVfx); yield break; } float progress = timer / 10f; PdfCastBar.SetProgress(progress, 10f - timer); timer += Time.deltaTime; yield return null; } PdfCastBar.Hide(); if (!CanTeleport(player, showMessage: true)) { _isCasting = false; PdfCastBar.Hide(); StopCastSound(castAudio); StopCastVfx(castVfx); yield break; } if (!TryGetBedSpawnPoint(player, out var spawnPoint)) { ((Character)player).Message((MessageType)2, "Aucun point de retour trouvé.", 0, (Sprite)null); _isCasting = false; PdfCastBar.Hide(); StopCastSound(castAudio); StopCastVfx(castVfx); yield break; } ((Character)player).TeleportTo(spawnPoint, ((Component)player).transform.rotation, true); float cooldown = GetCooldownSeconds(item); SetCooldown(player, cooldown, item); ApplyCooldownStatusEffect(player, cooldown); if (ShouldConsume(item)) { bool removed = sourceInventory != null && sourceInventory.RemoveItem(item, 1); if (!removed) { removed = ((Humanoid)player).GetInventory().RemoveItem(item, 1); } if (!removed) { Logger.LogWarning((object)("[WarheimPdf] Impossible de consommer " + GetPrefabName(item) + ". Inventaire source invalide ou item introuvable.")); } } ((Character)player).Message((MessageType)2, "La Pierre de Foyer vous ramène chez vous.", 0, (Sprite)null); StopCastSound(castAudio); StopCastVfx(castVfx); _isCasting = false; } private static bool IsTryingToMove() { return Input.GetKey((KeyCode)119) || Input.GetKey((KeyCode)97) || Input.GetKey((KeyCode)115) || Input.GetKey((KeyCode)100) || Input.GetKey((KeyCode)32) || Input.GetKey((KeyCode)306); } private static void ApplyCooldownStatusEffect(Player player, double durationSeconds) { if (!((Object)(object)player == (Object)null)) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_WarheimPdfSimpleCooldown"), false); sEMan.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_WarheimPdfWarheimCooldown"), false); string value; bool flag = player.m_customData.TryGetValue("Warheim.Pdf.Type", out value) && value == "Warheim"; SE_WarheimPdfCooldown sE_WarheimPdfCooldown = ScriptableObject.CreateInstance(); ((Object)sE_WarheimPdfCooldown).name = (flag ? "SE_WarheimPdfWarheimCooldown" : "SE_WarheimPdfSimpleCooldown"); ((StatusEffect)sE_WarheimPdfCooldown).m_name = (flag ? "Pierre de Foyer Warheim" : "Pierre de Foyer"); ((StatusEffect)sE_WarheimPdfCooldown).m_tooltip = "Recharge restante : " + FormatTime(durationSeconds); ((StatusEffect)sE_WarheimPdfCooldown).m_icon = (flag ? _pdfWarheimIcon : _pdfSimpleIcon); ((StatusEffect)sE_WarheimPdfCooldown).m_ttl = (float)durationSeconds; Logger.LogInfo((object)$"[WarheimPdf] Adding SE {((Object)sE_WarheimPdfCooldown).name}, icon={(Object)(object)((StatusEffect)sE_WarheimPdfCooldown).m_icon != (Object)null}, ttl={((StatusEffect)sE_WarheimPdfCooldown).m_ttl}"); sEMan.AddStatusEffect((StatusEffect)(object)sE_WarheimPdfCooldown, true, 0, 0f); } } } private static bool CanTeleport(Player player, bool showMessage) { if (!((Humanoid)player).IsTeleportable()) { if (showMessage) { ((Character)player).Message((MessageType)2, "Une force empêche la Pierre de Foyer de fonctionner.", 0, (Sprite)null); } return false; } if (HasBlockedStatusEffect(player)) { if (showMessage) { ((Character)player).Message((MessageType)2, "Impossible d'utiliser la Pierre de Foyer en combat.", 0, (Sprite)null); } return false; } return true; } private static bool HasBlockedStatusEffect(Player player) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return false; } return sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_PvpModes_Bounty")) || sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_Combat")) || sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_PvP")) || sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("PvpTweaks_SE_Combat")) || sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("PvpTweaks_SE_NoTeleport")); } private static bool TryGetBedSpawnPoint(Player player, out Vector3 point) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if (val == null) { return false; } if (val.HaveCustomSpawnPoint()) { point = val.GetCustomSpawnPoint(); return true; } point = val.GetHomePoint(); return point != Vector3.zero; } private static void SetCooldown(Player player, float seconds, ItemData item) { long num = DateTimeOffset.UtcNow.AddSeconds(seconds).ToUnixTimeSeconds(); player.m_customData["Warheim.Pdf.CooldownUntilUtc"] = num.ToString(); player.m_customData["Warheim.Pdf.Type"] = (IsWarheim(item) ? "Warheim" : "Simple"); } private static double GetCooldownRemainingSeconds(Player player) { if (!player.m_customData.TryGetValue("Warheim.Pdf.CooldownUntilUtc", out var value)) { return 0.0; } if (!long.TryParse(value, out var result)) { return 0.0; } long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); double num2 = result - num; if (num2 <= 0.0) { player.m_customData.Remove("Warheim.Pdf.CooldownUntilUtc"); return 0.0; } return num2; } private static string FormatTime(double seconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (timeSpan.TotalMinutes >= 1.0) { return $"{(int)timeSpan.TotalMinutes}m {timeSpan.Seconds}s"; } return $"{timeSpan.Seconds}s"; } public static void InitStatusEffects(AssetBundle bundle) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown _pdfSimpleIcon = bundle.LoadAsset("assets/pdf/pdfsimpleicon.png"); _pdfWarheimIcon = bundle.LoadAsset("assets/pdf/pdfwarheimicon.png"); _castVfxPrefab = bundle.LoadAsset("assets/pdf/vfx_pdf_cast.prefab"); Logger.LogInfo((object)$"PDF VFX loaded = {(Object)(object)_castVfxPrefab != (Object)null}"); _pdfSimpleCooldownSe = CreateCooldownSe("SE_WarheimPdfSimpleCooldown", "Pierre de Foyer en recharge", "Votre Pierre de Foyer simple se recharge.", _pdfSimpleIcon, 3600f); _pdfWarheimCooldownSe = CreateCooldownSe("SE_WarheimPdfWarheimCooldown", "Pierre de Foyer Warheim en recharge", "Votre Pierre de Foyer Warheim se recharge.", _pdfWarheimIcon, 1800f); _castAudioClip = bundle.LoadAsset("assets/pdf/pdf_cast_loop.mp3"); Logger.LogInfo((object)$"PDF SFX loaded = {(Object)(object)_castAudioClip != (Object)null}"); ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(_pdfSimpleCooldownSe, false)); ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(_pdfWarheimCooldownSe, false)); } private static GameObject StartCastVfx(Player player) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_castVfxPrefab == (Object)null) { Logger.LogWarning((object)"[WarheimPdf] Cast VFX prefab is null"); return null; } GameObject val = Object.Instantiate(_castVfxPrefab); val.transform.position = ((Component)player).transform.position + new Vector3(0f, 0.05f, 0f); val.transform.rotation = Quaternion.identity; val.transform.SetParent(((Component)player).transform, true); Logger.LogInfo((object)$"[WarheimPdf] Cast VFX spawned at {val.transform.position}"); return val; } private static void StopCastVfx(GameObject vfx) { if ((Object)(object)vfx != (Object)null) { Object.Destroy((Object)(object)vfx); } } private static AudioSource StartCastSound(Player player) { if ((Object)(object)_castAudioClip == (Object)null) { Logger.LogWarning((object)"[WarheimPdf] Cast SFX clip is null"); return null; } AudioSource val = ((Component)player).gameObject.AddComponent(); val.clip = _castAudioClip; val.loop = true; val.playOnAwake = false; val.spatialBlend = 0f; val.volume = 1f; val.Play(); Logger.LogInfo((object)"[WarheimPdf] Cast SFX started"); return val; } private static void StopCastSound(AudioSource source) { if (!((Object)(object)source == (Object)null)) { source.Stop(); Object.Destroy((Object)(object)source); } } private static StatusEffect CreateCooldownSe(string name, string displayName, string tooltip, Sprite icon, float duration) { SE_WarheimPdfCooldown sE_WarheimPdfCooldown = ScriptableObject.CreateInstance(); ((Object)sE_WarheimPdfCooldown).name = name; ((StatusEffect)sE_WarheimPdfCooldown).m_name = displayName; ((StatusEffect)sE_WarheimPdfCooldown).m_tooltip = tooltip; ((StatusEffect)sE_WarheimPdfCooldown).m_icon = icon; ((StatusEffect)sE_WarheimPdfCooldown).m_ttl = duration; return (StatusEffect)(object)sE_WarheimPdfCooldown; } private static IEnumerator ReapplyCooldownAfterSpawn(Player player) { yield return null; yield return (object)new WaitForSeconds(1f); double remaining = GetCooldownRemainingSeconds(player); if (!(remaining <= 0.0)) { ApplyCooldownStatusEffect(player, remaining); } } } [BepInPlugin("dzk.warheimstuff", "WarheimStuff", "1.2.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class WarheimStuff : BaseUnityPlugin { private static class ReaperSpearRotationPatch { public static void Postfix(VisEquipment __instance, object[] __args, GameObject __result) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__result == (Object)null) && __args != null && __args.Length >= 3 && __args[0] is int num && num == StringExtensionMethods.GetStableHashCode("JC_Reaper_Spear")) { object obj = __args[2]; Transform val = (Transform)((obj is Transform) ? obj : null); if (val != null && !((Object)(object)val != (Object)(object)__instance.m_rightHand)) { __result.transform.localRotation = Quaternion.Euler(0f, 180f, 0f) * __result.transform.localRotation; } } } } private readonly struct PvpItemDef { public readonly string Path; public readonly float Resilience; public PvpItemDef(string path, float resilience) { Path = path; Resilience = resilience; } } private enum WarheimRingType { DPS, Tank, Archer, Mage, Miner, Lumberjack, Leviathan } public class SE_WarheimRingDPS : StatusEffect { public float m_staminaRegenMultiplier = 1f; public float m_damageMultiplier = 1f; public void SetStaminaRegenMultiplier(float value) { m_staminaRegenMultiplier = value; } public void SetDamageMultiplier(float value) { m_damageMultiplier = value; } public override void ModifyStaminaRegen(ref float staminaRegen) { staminaRegen *= m_staminaRegenMultiplier; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { ((DamageTypes)(ref hitData.m_damage)).Modify(m_damageMultiplier); } } public class SE_WarheimRingTank : StatusEffect { public float m_healthPercentBonus; public float m_healthRegenMultiplier = 1f; public void SetHealthPercentBonus(float value) { m_healthPercentBonus = value; } public void SetHealthRegenMultiplier(float value) { m_healthRegenMultiplier = value; } public override void ModifyHealthRegen(ref float regenMultiplier) { regenMultiplier *= m_healthRegenMultiplier; } } public class SE_WarheimRingArcher : StatusEffect { public float m_staminaPercentBonus; public float m_moveSpeedMultiplier = 1f; public void SetStaminaPercentBonus(float value) { m_staminaPercentBonus = value; } public void SetMoveSpeedMultiplier(float value) { m_moveSpeedMultiplier = value; } public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir) { speed *= m_moveSpeedMultiplier; } } public class SE_WarheimRingMage : StatusEffect { public float m_eitrPercentBonus; public float m_eitrRegenMultiplier = 1f; public void SetEitrPercentBonus(float value) { m_eitrPercentBonus = value; } public void SetEitrRegenMultiplier(float value) { m_eitrRegenMultiplier = value; } public override void ModifyEitrRegen(ref float regen) { regen *= m_eitrRegenMultiplier; } } public class SE_WarheimRingMiner : StatusEffect { public float m_carryWeightBonus; public float m_pickaxeDamageMultiplier = 1f; public float m_healthPercentBonus; public void SetCarryWeightBonus(float value) { m_carryWeightBonus = value; } public void SetPickaxeDamageMultiplier(float value) { m_pickaxeDamageMultiplier = value; } public void SetHealthPercentBonus(float value) { m_healthPercentBonus = value; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { hitData.m_damage.m_pickaxe *= m_pickaxeDamageMultiplier; } public override void ModifyMaxCarryWeight(float baseLimit, ref float limit) { limit += m_carryWeightBonus; } } public class SE_WarheimRingLumberjack : StatusEffect { public float m_carryWeightBonus; public float m_chopDamageMultiplier = 1f; public float m_staminaPercentBonus; public void SetCarryWeightBonus(float value) { m_carryWeightBonus = value; } public void SetChopDamageMultiplier(float value) { m_chopDamageMultiplier = value; } public void SetStaminaPercentBonus(float value) { m_staminaPercentBonus = value; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { hitData.m_damage.m_chop *= m_chopDamageMultiplier; } public override void ModifyMaxCarryWeight(float baseLimit, ref float limit) { limit += m_carryWeightBonus; } } public class SE_WarheimRingLeviathan : StatusEffect { public float m_swimSkillBonus; public float m_swimSpeedMultiplier = 1f; public void SetSwimSkillBonus(float value) { m_swimSkillBonus = value; } public void SetSwimSpeedMultiplier(float value) { m_swimSpeedMultiplier = value; } public override void ModifySkillLevel(SkillType skill, ref float level) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 if ((int)skill == 103) { level += m_swimSkillBonus; } } } public class SE_WarheimRingElementalist : StatusEffect { public override void ModifyDamageMods(ref DamageModifiers modifiers) { ((DamageModifiers)(ref modifiers)).Apply(CreateElementalistDamageModifiers()); } } public class SE_CollierWarheimDPS : StatusEffect { public float m_damageMultiplier = 1f; public float m_staminaRegenMultiplier = 1f; public void SetDamageMultiplier(float value) { m_damageMultiplier = value; } public void SetStaminaRegenMultiplier(float value) { m_staminaRegenMultiplier = value; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { ((DamageTypes)(ref hitData.m_damage)).Modify(m_damageMultiplier); } public override void ModifyStaminaRegen(ref float staminaRegen) { staminaRegen *= m_staminaRegenMultiplier; } } public class SE_CollierWarheimBerserker : StatusEffect { public float m_damageDoneMultiplier = 1f; public float m_attackStaminaMultiplier = 1f; public float m_damageTakenMultiplier = 1f; public float m_moveSpeedMultiplier = 1f; public void SetBonuses(float damageDone, float attackStamina, float damageTaken, float moveSpeed) { m_damageDoneMultiplier = damageDone; m_attackStaminaMultiplier = attackStamina; m_damageTakenMultiplier = damageTaken; m_moveSpeedMultiplier = moveSpeed; } public override void ModifyAttack(SkillType skill, ref HitData hitData) { hitData.ApplyModifier(m_damageDoneMultiplier); } public override void OnDamaged(HitData hit, Character attacker) { hit.ApplyModifier(m_damageTakenMultiplier); } public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= m_attackStaminaMultiplier; } public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir) { speed *= m_moveSpeedMultiplier; } } public class SE_CollierWarheimMage : StatusEffect { public float m_eitr; public float m_skillup; public float m_regenModifier; public void SetEitr(float eitr) { m_eitr = eitr; } public void SetSkill(float skill) { m_skillup = skill; } public void SetRegenModifier(float regenModifier) { m_regenModifier = regenModifier; } public override void ModifyEitrRegen(ref float regen) { regen *= m_regenModifier; } public override void ModifySkillLevel(SkillType skill, ref float value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)skill == 10 || (int)skill == 9) { value += m_skillup; } } } public class SE_CollierWarheimTank : StatusEffect { public float m_healthPercentBonus; public float m_healthRegenMultiplier = 1f; public void SetHealthPercentBonus(float value) { m_healthPercentBonus = value; } public void SetHealthRegenMultiplier(float value) { m_healthRegenMultiplier = value; } public override void ModifyHealthRegen(ref float regenMultiplier) { regenMultiplier *= m_healthRegenMultiplier; } } public class SE_WarheimRingGladiator : StatusEffect { public float m_regenMultiplier = 1f; public void SetRegenMultiplier(float value) { m_regenMultiplier = value; } public override void ModifyHealthRegen(ref float regenMultiplier) { regenMultiplier *= m_regenMultiplier; } public override void ModifyStaminaRegen(ref float staminaRegen) { staminaRegen *= m_regenMultiplier; } public override void ModifyEitrRegen(ref float regen) { regen *= m_regenMultiplier; } } public class SE_CollierWarheimGladiator : StatusEffect { public float m_health; public float m_stamina; public float m_eitr; public void SetBonuses(float health, float stamina, float eitr) { m_health = health; m_stamina = stamina; m_eitr = eitr; } } [HarmonyPatch] public static class SwimmingReworkedLeviathanSpeedPatch { private static bool Prepare() { return Chainloader.PluginInfos.ContainsKey("dzk.SwimmingReworked"); } private static MethodBase TargetMethod() { if (!Chainloader.PluginInfos.TryGetValue("dzk.SwimmingReworked", out var value)) { return null; } Type type = ((object)value.Instance).GetType().Assembly.GetType("SwimmingReworked.SwimAPI"); return AccessTools.Method(type, "GetExternalSwimSpeedMultiplier", new Type[1] { typeof(Player) }, (Type[])null); } [HarmonyPostfix] private static void Postfix(Player __0, ref float __result) { if ((Object)(object)__0 == (Object)null) { return; } SEMan sEMan = ((Character)__0).GetSEMan(); if (sEMan == null) { return; } foreach (StatusEffect statusEffect in sEMan.GetStatusEffects()) { if (statusEffect is SE_WarheimRingLeviathan sE_WarheimRingLeviathan) { __result *= sE_WarheimRingLeviathan.m_swimSpeedMultiplier; break; } } } } [HarmonyPatch] public static class Patch_IsNeckItem { private static MethodBase TargetMethod() { if (!Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var value)) { return null; } Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("Jewelcrafting.Visual"); if (type == null) { return null; } return AccessTools.Method(type, "IsNeckItem", (Type[])null, (Type[])null); } private static void Postfix(ItemData item, ref bool __result) { if ((Object)(object)item?.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name.StartsWith("JC_Necklace_Warheim")) { __result = true; } } } [HarmonyPatch] public static class Patch_IsFingerItem { private static MethodBase TargetMethod() { if (!Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var value)) { return null; } Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("Jewelcrafting.Visual"); if (type == null) { return null; } return AccessTools.Method(type, "IsFingerItem", (Type[])null, (Type[])null); } private static void Postfix(ItemData item, ref bool __result) { object obj; if (item == null) { obj = null; } else { GameObject dropPrefab = item.m_dropPrefab; obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } string text = (string)obj; if (!string.IsNullOrEmpty(text) && text.StartsWith("JC_Ring_Warheim", StringComparison.Ordinal)) { __result = true; } } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] public static class FoodTotalsFromWarheimNecklacesPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float hp, ref float stamina, ref float eitr) { if ((Object)(object)__instance == (Object)null) { return; } SEMan value = Traverse.Create((object)__instance).Field("m_seman").GetValue(); if (value == null) { return; } List value2 = Traverse.Create((object)value).Field("m_statusEffects").GetValue>(); if (value2 == null) { return; } float num = 0f; float num2 = 0f; float num3 = 0f; float num4 = 0f; foreach (StatusEffect item in value2) { if (item is SE_CollierWarheimMage { m_eitr: not 0f } sE_CollierWarheimMage) { num += sE_CollierWarheimMage.m_eitr; } if (item is SE_CollierWarheimTank { m_healthPercentBonus: not 0f } sE_CollierWarheimTank) { num2 += sE_CollierWarheimTank.m_healthPercentBonus; } if (item is SE_CollierWarheimGladiator sE_CollierWarheimGladiator) { num3 += sE_CollierWarheimGladiator.m_health; num4 += sE_CollierWarheimGladiator.m_stamina; num += sE_CollierWarheimGladiator.m_eitr; } } if (num != 0f) { eitr += num; } if (num2 != 0f) { hp *= 1f + num2; } if (num3 != 0f) { hp += num3; } if (num4 != 0f) { stamina += num4; } } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] public static class FoodTotalsFromWarheimRingsPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float hp, ref float stamina, ref float eitr) { if ((Object)(object)__instance == (Object)null) { return; } SEMan sEMan = ((Character)__instance).GetSEMan(); if (sEMan == null) { return; } float num = 0f; float num2 = 0f; float num3 = 0f; foreach (StatusEffect statusEffect in sEMan.GetStatusEffects()) { if (statusEffect is SE_WarheimRingTank { m_healthPercentBonus: not 0f } sE_WarheimRingTank) { num += sE_WarheimRingTank.m_healthPercentBonus; } if (statusEffect is SE_WarheimRingArcher { m_staminaPercentBonus: not 0f } sE_WarheimRingArcher) { num2 += sE_WarheimRingArcher.m_staminaPercentBonus; } if (statusEffect is SE_WarheimRingMage { m_eitrPercentBonus: not 0f } sE_WarheimRingMage) { num3 += sE_WarheimRingMage.m_eitrPercentBonus; } if (statusEffect is SE_WarheimRingMiner { m_healthPercentBonus: not 0f } sE_WarheimRingMiner) { num += sE_WarheimRingMiner.m_healthPercentBonus; } if (statusEffect is SE_WarheimRingLumberjack { m_staminaPercentBonus: not 0f } sE_WarheimRingLumberjack) { num2 += sE_WarheimRingLumberjack.m_staminaPercentBonus; } } if (num != 0f) { hp += hp * num; } if (num2 != 0f) { stamina += stamina * num2; } if (num3 != 0f) { eitr += eitr * num3; } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public static class WarheimJewelryArmorPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { if ((Object)(object)__instance == (Object)null) { return; } Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory == null) { return; } foreach (ItemData equippedItem in inventory.GetEquippedItems()) { if (!((Object)(object)equippedItem?.m_dropPrefab == (Object)null)) { string name = ((Object)equippedItem.m_dropPrefab).name; if (name.StartsWith("JC_Ring_Warheim", StringComparison.Ordinal) || name.StartsWith("JC_Necklace_Warheim", StringComparison.Ordinal)) { __result += Mathf.Max(1f, (float)equippedItem.m_quality); } } } } } [HarmonyPatch] public static class WarheimJewelryArmorTooltipPatch { private static IEnumerable TargetMethods() { return AccessTools.GetDeclaredMethods(typeof(ItemData)).FindAll((MethodInfo m) => m.Name == "GetTooltip"); } [HarmonyPostfix] private static void Postfix(ItemData __instance, ref string __result) { if (!((Object)(object)__instance?.m_dropPrefab == (Object)null) && !string.IsNullOrEmpty(__result)) { string name = ((Object)__instance.m_dropPrefab).name; if ((name.StartsWith("JC_Ring_Warheim", StringComparison.Ordinal) || name.StartsWith("JC_Necklace_Warheim", StringComparison.Ordinal)) && !__result.Contains("Armure :")) { int num = Mathf.Max(1, __instance.m_quality); __result += $"\nArmure : {num}"; } } } } public const string PluginGUID = "dzk.warheimstuff"; public const string PluginName = "WarheimStuff"; public const string PluginVersion = "1.2.2"; public static AssetBundle WarheimBundle; private static readonly PvpItemDef[] PvpItems = new PvpItemDef[14] { new PvpItemDef("assets/pvpitems/pvpswordohs1.prefab", 25f), new PvpItemDef("assets/pvpitems/pvpaxeohs1.prefab", 25f), new PvpItemDef("assets/pvpitems/pvpaxeths1.prefab", 35f), new PvpItemDef("assets/pvpitems/pvpswordths1.prefab", 35f), new PvpItemDef("assets/pvpitems/pvpatgeirs1.prefab", 35f), new PvpItemDef("assets/pvpitems/pvpbucklers1.prefab", 25f), new PvpItemDef("assets/pvpitems/pvptowers1.prefab", 35f), new PvpItemDef("assets/pvpitems/pvpspears1.prefab", 25f), new PvpItemDef("assets/pvpitems/pvpbows1.prefab", 20f), new PvpItemDef("assets/pvpitems/pvpdaggerss1.prefab", 15f), new PvpItemDef("assets/pvpitems/pvpmaceohs1.prefab", 25f), new PvpItemDef("assets/pvpitems/pvpsledgeths1.prefab", 40f), new PvpItemDef("assets/pvpitems/pvpcrossbows1.prefab", 20f), new PvpItemDef("assets/pvpitems/pvpstaffs1.prefab", 30f) }; private readonly float[] _tierSmall = new float[5] { 2f, 4f, 6f, 8f, 10f }; private readonly float[] _tierMedium = new float[5] { 1f, 2f, 3f, 4f, 5f }; private readonly float[] _tierLarge = new float[5] { 5f, 10f, 15f, 20f, 25f }; private void Awake() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) LoadAssets(); InitializeWarheimGems(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsReady; PrefabManager.OnVanillaPrefabsAvailable += OnVanillaItemsReady; PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailableForColliers; new Harmony("dzk.warheimstuff").PatchAll(); WarheimRaids.Init(WarheimBundle, (MonoBehaviour)(object)this); ((MonoBehaviour)this).StartCoroutine(RaidManager.WaitAndRegisterRoutedRpc()); ((MonoBehaviour)this).StartCoroutine(RaidConfigHotReloadLoop()); InstallReaperSpearRotationPatch(); } private static void InstallReaperSpearRotationPatch() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(VisEquipment), "AttachItem", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(ReaperSpearRotationPatch), "Postfix", (Type[])null, (Type[])null); new Harmony("warheimstuff.reaperspear.rotation").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void InitializeWarheimGems() { if (!API.IsLoaded()) { return; } try { WarheimGems.Initialize(); } catch (Exception ex) { Debug.LogError((object)("[WarheimGems] Échec de l'initialisation : " + ex)); } } private IEnumerator RaidConfigHotReloadLoop() { string path = RaidConfigLoader.ConfigPath; DateTime lastWrite = (File.Exists(path) ? File.GetLastWriteTimeUtc(path) : DateTime.MinValue); while (true) { yield return (object)new WaitForSeconds(2f); if (File.Exists(path)) { DateTime currentWrite = File.GetLastWriteTimeUtc(path); if (!(currentWrite <= lastWrite)) { lastWrite = currentWrite; yield return (object)new WaitForSeconds(0.25f); WarheimRaids.Config = RaidConfigLoader.LoadOrCreateDefault(); Debug.Log((object)"[WarheimRaids] YAML rechargé à chaud."); } } } } private void OnVanillaPrefabsAvailableForColliers() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailableForColliers; ((MonoBehaviour)this).StartCoroutine(AddColliersWhenReady()); } private IEnumerator AddColliersWhenReady() { while ((Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Moder")) == (Object)null) { yield return null; } AddColliers(); } private void LoadAssets() { WarheimBundle = AssetUtils.LoadAssetBundleFromResources("customcoins"); } private void OnVanillaPrefabsReady() { AddWarheimCoin(); AddPvpItems(); AddPdfItems(); AddHelQuestItems(); } private void OnVanillaItemsReady() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsReady; PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaItemsReady; } private static ZNetView GetNView(Component component) { return ((Object)(object)component != (Object)null) ? component.GetComponent() : null; } private void AddHelQuestItems() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Expected O, but got Unknown //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Expected O, but got Unknown //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Expected O, but got Unknown GameObject val = WarheimBundle.LoadAsset("assets/helquest/helskewer.prefab"); ItemConfig val2 = new ItemConfig { CraftingStation = CraftingStations.Cauldron, MinStationLevel = 1, Amount = 1 }; val2.AddRequirement("HelMeat", 3, 0); val2.AddRequirement("HelBones", 1, 0); val2.AddRequirement("HelEye", 2, 0); CustomItem val3 = new CustomItem(val, true, val2); ItemManager.Instance.AddItem(val3); GameObject val4 = WarheimBundle.LoadAsset("assets/helquest/helsoup.prefab"); ItemConfig val5 = new ItemConfig { CraftingStation = CraftingStations.Cauldron, MinStationLevel = 1, Amount = 1 }; val5.AddRequirement("HelBlood", 3, 0); val5.AddRequirement("HelMeat", 2, 0); val5.AddRequirement("HelHeart", 1, 0); CustomItem val6 = new CustomItem(val4, true, val5); ItemManager.Instance.AddItem(val6); GameObject val7 = WarheimBundle.LoadAsset("assets/helquest/helsausage.prefab"); ItemConfig val8 = new ItemConfig { CraftingStation = CraftingStations.Cauldron, MinStationLevel = 1, Amount = 1 }; val8.AddRequirement("HelEntrails", 4, 0); val8.AddRequirement("HelMeat", 1, 0); val8.AddRequirement("HelHeart", 2, 0); CustomItem val9 = new CustomItem(val7, true, val8); ItemManager.Instance.AddItem(val9); GameObject val10 = WarheimBundle.LoadAsset("assets/helquest/helblood.prefab"); CustomItem val11 = new CustomItem(val10, true); ItemManager.Instance.AddItem(val11); GameObject val12 = WarheimBundle.LoadAsset("assets/helquest/helbones.prefab"); CustomItem val13 = new CustomItem(val12, true); ItemManager.Instance.AddItem(val13); GameObject val14 = WarheimBundle.LoadAsset("assets/helquest/helcrystal.prefab"); CustomItem val15 = new CustomItem(val14, true); ItemManager.Instance.AddItem(val15); GameObject val16 = WarheimBundle.LoadAsset("assets/helquest/helcuir.prefab"); CustomItem val17 = new CustomItem(val16, true); ItemManager.Instance.AddItem(val17); GameObject val18 = WarheimBundle.LoadAsset("assets/helquest/helentrails.prefab"); CustomItem val19 = new CustomItem(val18, true); ItemManager.Instance.AddItem(val19); GameObject val20 = WarheimBundle.LoadAsset("assets/helquest/heleye.prefab"); CustomItem val21 = new CustomItem(val20, true); ItemManager.Instance.AddItem(val21); GameObject val22 = WarheimBundle.LoadAsset("assets/helquest/helfang.prefab"); CustomItem val23 = new CustomItem(val22, true); ItemManager.Instance.AddItem(val23); GameObject val24 = WarheimBundle.LoadAsset("assets/helquest/helfil.prefab"); CustomItem val25 = new CustomItem(val24, true); ItemManager.Instance.AddItem(val25); GameObject val26 = WarheimBundle.LoadAsset("assets/helquest/helheart.prefab"); CustomItem val27 = new CustomItem(val26, true); ItemManager.Instance.AddItem(val27); GameObject val28 = WarheimBundle.LoadAsset("assets/helquest/helmeat.prefab"); CustomItem val29 = new CustomItem(val28, true); ItemManager.Instance.AddItem(val29); GameObject val30 = WarheimBundle.LoadAsset("assets/helquest/helscale.prefab"); CustomItem val31 = new CustomItem(val30, true); ItemManager.Instance.AddItem(val31); GameObject val32 = WarheimBundle.LoadAsset("assets/helquest/helskull.prefab"); CustomItem val33 = new CustomItem(val32, true); ItemManager.Instance.AddItem(val33); } private void AddWarheimCoin() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown GameObject val = WarheimBundle.LoadAsset("assets/custombb/warheimcoin.prefab"); CustomItem val2 = new CustomItem(val, true); ItemManager.Instance.AddItem(val2); GameObject val3 = WarheimBundle.LoadAsset("assets/custombb/goldbar.prefab"); CustomItem val4 = new CustomItem(val3, true); ItemManager.Instance.AddItem(val4); GameObject val5 = WarheimBundle.LoadAsset("assets/custombb/emeraldbar.prefab"); CustomItem val6 = new CustomItem(val5, true); ItemManager.Instance.AddItem(val6); } private void AddPdfItems() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown WarheimPdf.InitStatusEffects(WarheimBundle); GameObject val = WarheimBundle.LoadAsset("assets/pdf/pdfsimple.prefab"); ItemConfig val2 = new ItemConfig(); val2.AddRequirement("Stone", 10, 0); val2.AddRequirement("SurtlingCore", 1, 0); val2.CraftingStation = "piece_workbench"; val2.RepairStation = "piece_workbench"; CustomItem val3 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val3); GameObject val4 = WarheimBundle.LoadAsset("assets/pdf/pdfwarheim.prefab"); CustomItem val5 = new CustomItem(val4, true); ItemManager.Instance.AddItem(val5); } private void AddPvpItems() { PvpItemDef[] pvpItems = PvpItems; for (int i = 0; i < pvpItems.Length; i++) { PvpItemDef pvpItemDef = pvpItems[i]; AddPvpItem(pvpItemDef.Path, pvpItemDef.Resilience); } } private void AddPvpItem(string path, float resilience) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown GameObject val = WarheimBundle.LoadAsset(path); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("Missing prefab: " + path)); return; } ItemDrop component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Logger.LogWarning((object)("Prefab has no ItemDrop: " + path)); return; } PvpResilienceAPI.SetResilience(component.m_itemData, resilience); CustomItem val2 = new CustomItem(val, false); ItemManager.Instance.AddItem(val2); } private void AddColliers() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Expected O, but got Unknown //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Expected O, but got Unknown //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Expected O, but got Unknown GameObject val = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val); ((Object)val).name = "JC_Necklace_Warheim_Sailing"; ItemConfig val2 = new ItemConfig(); val2.Name = "Collier du Capitaine"; val2.Description = "Ce collier vous permettra de toujours avoir le vent dans le dos."; Sprite icon1 = WarheimBundle.LoadAsset("colliersailing_icon.png"); val2.Icon = icon1; val2.AddRequirement("WarheimCoin", 40, 20); val2.CraftingStation = "piece_workbench"; val2.RepairStation = "piece_workbench"; SharedData shared = val.GetComponent().m_itemData.m_shared; shared.m_armor = 1f; shared.m_armorPerLevel = 1f; StatusEffect val3 = WarheimBundle.LoadAsset("SE_SailingWarheim"); CustomStatusEffect val4 = new CustomStatusEffect(val3, false); ItemManager.Instance.AddStatusEffect(val4); shared.m_equipStatusEffect = val4.StatusEffect; CustomItem val5 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val5); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_Sailing"); ItemDrop val15 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val15 != (Object)null) { val15.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon1 }; } }; GameObject val6 = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val6); ((Object)val6).name = "JC_Necklace_Warheim_DPS"; ItemConfig val7 = new ItemConfig(); val7.Name = "Collier du Carnage"; val7.Description = "Ce collier augmente considérablement vos dégâts et votre régénération d'endurance."; Sprite icon2 = WarheimBundle.LoadAsset("collierdps_icon.png"); val7.Icon = icon2; val7.AddRequirement("WarheimCoin", 40, 20); val7.CraftingStation = "piece_workbench"; val7.RepairStation = "piece_workbench"; SharedData shared2 = val6.GetComponent().m_itemData.m_shared; shared2.m_icons = (Sprite[])(object)new Sprite[1] { icon2 }; shared2.m_armor = 1f; shared2.m_armorPerLevel = 1f; SE_CollierWarheimDPS sE_CollierWarheimDPS = ScriptableObject.CreateInstance(); ((Object)sE_CollierWarheimDPS).name = "SE_CollierWarheim_DPS"; ((StatusEffect)sE_CollierWarheimDPS).m_name = "Collier du Carnage"; ((StatusEffect)sE_CollierWarheimDPS).m_icon = icon2; ((StatusEffect)sE_CollierWarheimDPS).m_tooltip = "+15% de dégâts totaux et +10% de régénération d'endurance."; sE_CollierWarheimDPS.SetDamageMultiplier(1.15f); sE_CollierWarheimDPS.SetStaminaRegenMultiplier(1.1f); shared2.m_equipStatusEffect = (StatusEffect)(object)sE_CollierWarheimDPS; CustomItem val8 = new CustomItem(val6, false, val7); ItemManager.Instance.AddItem(val8); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_DPS"); ItemDrop val15 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val15 != (Object)null) { val15.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon2 }; } }; GameObject val9 = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val9); ((Object)val9).name = "JC_Necklace_Warheim_Mage"; ItemConfig val10 = new ItemConfig(); val10.Name = "Collier du Mage"; val10.Description = "Ce collier augmente vos capacités magiques."; Sprite icon3 = WarheimBundle.LoadAsset("colliermage_icon.png"); val10.Icon = icon3; val10.AddRequirement("WarheimCoin", 40, 20); val10.CraftingStation = "piece_workbench"; val10.RepairStation = "piece_workbench"; SharedData shared3 = val9.GetComponent().m_itemData.m_shared; shared3.m_icons = (Sprite[])(object)new Sprite[1] { icon3 }; shared3.m_armor = 1f; shared3.m_armorPerLevel = 1f; SE_CollierWarheimMage sE_CollierWarheimMage = ScriptableObject.CreateInstance(); ((Object)sE_CollierWarheimMage).name = "SE_CollierWarheim_Mage"; ((StatusEffect)sE_CollierWarheimMage).m_name = "Collier du Mage"; ((StatusEffect)sE_CollierWarheimMage).m_icon = icon3; ((StatusEffect)sE_CollierWarheimMage).m_tooltip = "+10% aux skills de magie, +30% de regen d'eitr, +50 d'eitr max."; sE_CollierWarheimMage.SetEitr(50f); sE_CollierWarheimMage.SetSkill(11f); sE_CollierWarheimMage.SetRegenModifier(1.3f); shared3.m_equipStatusEffect = (StatusEffect)(object)sE_CollierWarheimMage; CustomItem val11 = new CustomItem(val9, false, val10); ItemManager.Instance.AddItem(val11); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_Mage"); ItemDrop val15 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val15 != (Object)null) { val15.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon3 }; } }; GameObject val12 = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val12); ((Object)val12).name = "JC_Necklace_Warheim_Tank"; ItemConfig val13 = new ItemConfig(); val13.Name = "Collier du Gardien"; val13.Description = "Ce collier augmente vos capacités défensives."; Sprite icon4 = WarheimBundle.LoadAsset("colliertank_icon.png"); val13.Icon = icon4; val13.AddRequirement("WarheimCoin", 40, 20); val13.CraftingStation = "piece_workbench"; val13.RepairStation = "piece_workbench"; SharedData shared4 = val12.GetComponent().m_itemData.m_shared; shared4.m_icons = (Sprite[])(object)new Sprite[1] { icon4 }; shared4.m_armor = 1f; shared4.m_armorPerLevel = 1f; SE_CollierWarheimTank sE_CollierWarheimTank = ScriptableObject.CreateInstance(); ((Object)sE_CollierWarheimTank).name = "SE_CollierWarheim_Tank"; ((StatusEffect)sE_CollierWarheimTank).m_name = "Collier du Gardien"; ((StatusEffect)sE_CollierWarheimTank).m_icon = icon4; ((StatusEffect)sE_CollierWarheimTank).m_tooltip = "+10% de vie totale finale et +15% de régénération de vie."; sE_CollierWarheimTank.SetHealthPercentBonus(0.1f); sE_CollierWarheimTank.SetHealthRegenMultiplier(1.15f); shared4.m_equipStatusEffect = (StatusEffect)(object)sE_CollierWarheimTank; CustomItem val14 = new CustomItem(val12, false, val13); ItemManager.Instance.AddItem(val14); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_Tank"); ItemDrop val15 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val15 != (Object)null) { val15.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon4 }; } }; AddGladiatorJewelry(); AddBerserkerNecklace(); AddElementalistRing(); AddRings(); AddMinerRings(); AddLumberjackRings(); AddLeviathanRings(); ItemManager.OnItemsRegistered += ApplyAllWarheimJewelryArmor; } private void AddBerserkerNecklace() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown GameObject val = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val); ((Object)val).name = "JC_Necklace_Warheim_Berserker"; SharedData shared = val.GetComponent().m_itemData.m_shared; Sprite icon = WarheimBundle.LoadAsset("collierberserker_icon.png"); if ((Object)(object)icon == (Object)null && shared.m_icons != null && shared.m_icons.Length != 0) { icon = shared.m_icons[0]; } ItemConfig val2 = new ItemConfig { Name = "Collier du Forcené", Description = "Co collier est fait pour les vikings un peu barjos...", Icon = icon, CraftingStation = "piece_workbench", RepairStation = "piece_workbench" }; val2.AddRequirement("WarheimCoin", 40, 20); shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; shared.m_armor = 1f; shared.m_armorPerLevel = 1f; SE_CollierWarheimBerserker sE_CollierWarheimBerserker = ScriptableObject.CreateInstance(); ((Object)sE_CollierWarheimBerserker).name = "SE_CollierWarheim_Berserker"; ((StatusEffect)sE_CollierWarheimBerserker).m_name = "Collier du Forcené"; ((StatusEffect)sE_CollierWarheimBerserker).m_icon = icon; ((StatusEffect)sE_CollierWarheimBerserker).m_tooltip = "+50% de dégâts infligés, -50% de coût d'endurance des attaques, +25% de dégâts subis et -10% de vitesse de déplacement."; sE_CollierWarheimBerserker.SetBonuses(1.5f, 0.5f, 1.25f, 0.9f); shared.m_equipStatusEffect = (StatusEffect)(object)sE_CollierWarheimBerserker; CustomItem val3 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val3); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_Berserker"); ItemDrop val4 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; } }; } private void AddElementalistRing() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown GameObject val = API.CreateRingFromTemplate("Red", Color.red); API.MarkJewelry(val); ((Object)val).name = "JC_Ring_Warheim_ELEMENTALIST"; SharedData shared = val.GetComponent().m_itemData.m_shared; Sprite icon = WarheimBundle.LoadAsset("ring_elementalist.png"); if ((Object)(object)icon == (Object)null && shared.m_icons != null && shared.m_icons.Length != 0) { icon = shared.m_icons[0]; } ItemConfig val2 = new ItemConfig { Name = "Anneau de l'Élémentaliste", Description = "Votre maitrise des élèments est telle que maintenant, vous subirez moins les assauts des monstres costauds en magie.", Icon = icon, CraftingStation = "piece_workbench", RepairStation = "piece_workbench" }; val2.AddRequirement("WarheimCoin", 40, 20); shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; shared.m_armor = 1f; shared.m_armorPerLevel = 1f; shared.m_damageModifiers = CreateElementalistDamageModifiers(); SE_WarheimRingElementalist sE_WarheimRingElementalist = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingElementalist).name = "SE_WarheimRing_Elementalist"; ((StatusEffect)sE_WarheimRingElementalist).m_name = "Anneau de l'Élémentaliste"; ((StatusEffect)sE_WarheimRingElementalist).m_icon = icon; ((StatusEffect)sE_WarheimRingElementalist).m_tooltip = "Résistant au feu, au givre, à la foudre, au poison et à l'esprit."; shared.m_equipStatusEffect = (StatusEffect)(object)sE_WarheimRingElementalist; CustomItem val3 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val3); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Ring_Warheim_ELEMENTALIST"); ItemDrop val4 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; val4.m_itemData.m_shared.m_damageModifiers = CreateElementalistDamageModifiers(); } }; } private static List CreateElementalistDamageModifiers() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) return new List { new DamageModPair { m_type = (DamageType)32, m_modifier = (DamageModifier)1 }, new DamageModPair { m_type = (DamageType)64, m_modifier = (DamageModifier)1 }, new DamageModPair { m_type = (DamageType)128, m_modifier = (DamageModifier)1 }, new DamageModPair { m_type = (DamageType)256, m_modifier = (DamageModifier)1 }, new DamageModPair { m_type = (DamageType)512, m_modifier = (DamageModifier)1 } }; } private static void ApplyAllWarheimJewelryArmor() { if ((Object)(object)ObjectDB.instance == (Object)null) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { if (!((Object)(object)item == (Object)null)) { string name = ((Object)item).name; if (name.StartsWith("JC_Ring_Warheim") || name.StartsWith("JC_Necklace_Warheim")) { ItemDrop component = item.GetComponent(); ApplyJewelryArmor(component); } } } } private static void ApplyJewelryArmor(ItemDrop item) { if (item?.m_itemData?.m_shared != null) { item.m_itemData.m_shared.m_armor = 1f; item.m_itemData.m_shared.m_armorPerLevel = 1f; } } private void AddGladiatorJewelry() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown GameObject val = API.CreateRingFromTemplate("Red", Color.red); API.MarkJewelry(val); ((Object)val).name = "JC_Ring_Warheim_Pvp_S1"; ItemConfig val2 = new ItemConfig(); val2.Name = "Anneau du Gladiateur Saison 1"; val2.Description = "Cet anneau fut porté par les Vikings les plus brutaux de Warheim."; Sprite ringIcon = WarheimBundle.LoadAsset("assets/pvpitems/icons/rings1icon.png"); val2.Icon = ringIcon; SharedData shared = val.GetComponent().m_itemData.m_shared; shared.m_icons = (Sprite[])(object)new Sprite[1] { ringIcon }; shared.m_armor = 1f; shared.m_armorPerLevel = 1f; PvpResilienceAPI.SetResilience(val.GetComponent().m_itemData, 25f); SE_WarheimRingGladiator sE_WarheimRingGladiator = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingGladiator).name = "SE_WarheimRing_Gladiator_S1"; ((StatusEffect)sE_WarheimRingGladiator).m_name = "Anneau du Gladiateur Saison 1"; ((StatusEffect)sE_WarheimRingGladiator).m_icon = ringIcon; ((StatusEffect)sE_WarheimRingGladiator).m_tooltip = "Cet anneau vous octroye 25 de résilience ainsi que 15% de régénération de vie, endurance & eitr."; sE_WarheimRingGladiator.SetRegenMultiplier(1.15f); shared.m_equipStatusEffect = (StatusEffect)(object)sE_WarheimRingGladiator; CustomItem val3 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val3); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Ring_Warheim_Pvp_S1"); ItemDrop val7 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val7 != (Object)null) { val7.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { ringIcon }; val7.m_itemData.m_shared.m_armor = 1f; val7.m_itemData.m_shared.m_armorPerLevel = 1f; } }; GameObject val4 = API.CreateNecklaceFromTemplate("Red", Color.red); API.MarkJewelry(val4); ((Object)val4).name = "JC_Necklace_Warheim_Pvp_S1"; ItemConfig val5 = new ItemConfig(); val5.Name = "Collier du Gladiateur Saison 1"; val5.Description = "Ce collier, si vous le voulez autour du cou d'un Viking, ne signifie qu'une chose : Courez. Vite, et loin."; Sprite neckIcon = WarheimBundle.LoadAsset("assets/pvpitems/icons/necks1icon.png"); val5.Icon = neckIcon; SharedData shared2 = val4.GetComponent().m_itemData.m_shared; shared2.m_icons = (Sprite[])(object)new Sprite[1] { neckIcon }; shared2.m_armor = 1f; shared2.m_armorPerLevel = 1f; PvpResilienceAPI.SetResilience(val4.GetComponent().m_itemData, 35f); SE_CollierWarheimGladiator sE_CollierWarheimGladiator = ScriptableObject.CreateInstance(); ((Object)sE_CollierWarheimGladiator).name = "SE_CollierWarheim_Gladiator_S1"; ((StatusEffect)sE_CollierWarheimGladiator).m_name = "Collier du Gladiateur Saison 1"; ((StatusEffect)sE_CollierWarheimGladiator).m_icon = neckIcon; ((StatusEffect)sE_CollierWarheimGladiator).m_tooltip = "Ce collier augmente votre résilience de 35 ainsi que vos attributs de vie, endurance & eitr de 50."; sE_CollierWarheimGladiator.SetBonuses(50f, 50f, 50f); shared2.m_equipStatusEffect = (StatusEffect)(object)sE_CollierWarheimGladiator; CustomItem val6 = new CustomItem(val4, false, val5); ItemManager.Instance.AddItem(val6); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("JC_Necklace_Warheim_Pvp_S1"); ItemDrop val7 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val7 != (Object)null) { val7.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { neckIcon }; val7.m_itemData.m_shared.m_armor = 1f; val7.m_itemData.m_shared.m_armorPerLevel = 1f; } }; } private void AddRings() { AddRingSeries(WarheimRingType.DPS); AddRingSeries(WarheimRingType.Tank); AddRingSeries(WarheimRingType.Archer); AddRingSeries(WarheimRingType.Mage); } private void AddMinerRings() { AddRingSeries(WarheimRingType.Miner); } private void AddLumberjackRings() { AddRingSeries(WarheimRingType.Lumberjack); } private void AddLeviathanRings() { AddRingSeries(WarheimRingType.Leviathan); } private void AddRingSeries(WarheimRingType type) { for (int i = 1; i <= 5; i++) { AddSingleRing(type, i); } } private void AddSingleRing(WarheimRingType type, int tier) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown GameObject val = API.CreateRingFromTemplate("Red", Color.red); API.MarkJewelry(val); string typeName = type.ToString().ToUpperInvariant(); string name = $"JC_Ring_Warheim_{typeName}_T{tier}"; ((Object)val).name = name; string ringDisplayName = GetRingDisplayName(type, tier); string ringDescription = GetRingDescription(type, tier); Sprite icon = GetRingIcon(type, tier); if ((Object)(object)icon == (Object)null) { SharedData shared = val.GetComponent().m_itemData.m_shared; if (shared.m_icons != null && shared.m_icons.Length != 0) { icon = shared.m_icons[0]; } } ItemConfig val2 = new ItemConfig { Name = ringDisplayName, Description = ringDescription, Icon = icon, CraftingStation = "piece_workbench", RepairStation = "piece_workbench" }; int ringCost = GetRingCost(tier); val2.AddRequirement("WarheimCoin", ringCost, ringCost + 5); if (tier > 1) { string text = $"JC_Ring_Warheim_{typeName}_T{tier - 1}"; val2.AddRequirement(text, 1, 0); } SharedData shared2 = val.GetComponent().m_itemData.m_shared; shared2.m_armor = 1f; shared2.m_armorPerLevel = 1f; shared2.m_icons = (Sprite[])(object)new Sprite[1] { icon }; StatusEffect equipStatusEffect = CreateRingStatusEffect(type, tier, icon); shared2.m_equipStatusEffect = equipStatusEffect; CustomItem val3 = new CustomItem(val, false, val2); ItemManager.Instance.AddItem(val3); ItemManager.OnItemsRegistered += delegate { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab($"JC_Ring_Warheim_{typeName}_T{tier}"); ItemDrop val4 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val4 != (Object)null) { val4.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; } }; } private string GetRingDisplayName(WarheimRingType type, int tier) { if (1 == 0) { } string result = type switch { WarheimRingType.DPS => $"Anneau du Carnage T{tier}", WarheimRingType.Tank => $"Anneau du Gardien T{tier}", WarheimRingType.Archer => $"Anneau du Traqueur T{tier}", WarheimRingType.Mage => $"Anneau de l'Arcaniste T{tier}", WarheimRingType.Miner => $"Anneau du Mineur T{tier}", WarheimRingType.Lumberjack => $"Anneau du Bûcheron T{tier}", WarheimRingType.Leviathan => $"Anneau du Léviathan T{tier}", _ => $"Anneau Warheim T{tier}", }; if (1 == 0) { } return result; } private string GetRingDescription(WarheimRingType type, int tier) { int num = tier - 1; if (1 == 0) { } string result = type switch { WarheimRingType.DPS => "Cet anneau augmente vos capacités offensives en général.", WarheimRingType.Tank => "Cet anneau augmente vos capacités défensives.", WarheimRingType.Archer => "Cet anneau augmente vos capacités d'archer.", WarheimRingType.Mage => "Cet anneau augmente vos capacités de mage.", WarheimRingType.Miner => "Vous aimez donner des coups de pioches ? Moi aussi.", WarheimRingType.Lumberjack => "Et vas-y qu'j'te coupe la b...", WarheimRingType.Leviathan => "Tel un Silver dans l'eau.", _ => "Anneau Warheim.", }; if (1 == 0) { } return result; } private int GetRingCost(int tier) { return 5; } private Sprite GetRingIcon(WarheimRingType type, int tier) { string arg = type.ToString().ToLowerInvariant(); return WarheimBundle.LoadAsset($"ring_{arg}_t{tier}.png"); } private StatusEffect CreateRingStatusEffect(WarheimRingType type, int tier, Sprite icon) { int num = tier - 1; switch (type) { case WarheimRingType.DPS: { SE_WarheimRingDPS sE_WarheimRingDPS = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingDPS).name = $"SE_WarheimRing_DPS_T{tier}"; ((StatusEffect)sE_WarheimRingDPS).m_name = $"Anneau du Carnage T{tier}"; ((StatusEffect)sE_WarheimRingDPS).m_icon = icon; ((StatusEffect)sE_WarheimRingDPS).m_tooltip = $"+{_tierSmall[num]}% regen stamina, +{_tierMedium[num]}% dégâts totaux."; sE_WarheimRingDPS.SetStaminaRegenMultiplier(1f + _tierSmall[num] / 100f); sE_WarheimRingDPS.SetDamageMultiplier(1f + _tierMedium[num] / 100f); return (StatusEffect)(object)sE_WarheimRingDPS; } case WarheimRingType.Tank: { SE_WarheimRingTank sE_WarheimRingTank = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingTank).name = $"SE_WarheimRing_Tank_T{tier}"; ((StatusEffect)sE_WarheimRingTank).m_name = $"Anneau du Gardien T{tier}"; ((StatusEffect)sE_WarheimRingTank).m_icon = icon; ((StatusEffect)sE_WarheimRingTank).m_tooltip = $"+{_tierSmall[num]}% vie totale, +{_tierLarge[num]}% regen vie."; sE_WarheimRingTank.SetHealthPercentBonus(_tierSmall[num] / 100f); sE_WarheimRingTank.SetHealthRegenMultiplier(1f + _tierLarge[num] / 100f); return (StatusEffect)(object)sE_WarheimRingTank; } case WarheimRingType.Archer: { SE_WarheimRingArcher sE_WarheimRingArcher = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingArcher).name = $"SE_WarheimRing_Archer_T{tier}"; ((StatusEffect)sE_WarheimRingArcher).m_name = $"Anneau du Traqueur T{tier}"; ((StatusEffect)sE_WarheimRingArcher).m_icon = icon; ((StatusEffect)sE_WarheimRingArcher).m_tooltip = $"+{_tierSmall[num]}% stamina totale, +{_tierMedium[num]}% vitesse de déplacement."; sE_WarheimRingArcher.SetStaminaPercentBonus(_tierSmall[num] / 100f); sE_WarheimRingArcher.SetMoveSpeedMultiplier(1f + _tierMedium[num] / 100f); return (StatusEffect)(object)sE_WarheimRingArcher; } case WarheimRingType.Mage: { SE_WarheimRingMage sE_WarheimRingMage = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingMage).name = $"SE_WarheimRing_Mage_T{tier}"; ((StatusEffect)sE_WarheimRingMage).m_name = $"Anneau de l'Arcaniste T{tier}"; ((StatusEffect)sE_WarheimRingMage).m_icon = icon; ((StatusEffect)sE_WarheimRingMage).m_tooltip = $"+{_tierSmall[num]}% eitr total, +{_tierLarge[num]}% regen d'eitr."; sE_WarheimRingMage.SetEitrPercentBonus(_tierSmall[num] / 100f); sE_WarheimRingMage.SetEitrRegenMultiplier(1f + _tierLarge[num] / 100f); return (StatusEffect)(object)sE_WarheimRingMage; } case WarheimRingType.Miner: { SE_WarheimRingMiner sE_WarheimRingMiner = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingMiner).name = $"SE_WarheimRing_Miner_T{tier}"; ((StatusEffect)sE_WarheimRingMiner).m_name = $"Anneau du Mineur T{tier}"; ((StatusEffect)sE_WarheimRingMiner).m_icon = icon; ((StatusEffect)sE_WarheimRingMiner).m_tooltip = $"+{tier * 75} de limite de poids, +{tier * 2}% de dégâts de pioche et +{tier}% de vie totale."; sE_WarheimRingMiner.SetCarryWeightBonus((float)tier * 75f); sE_WarheimRingMiner.SetPickaxeDamageMultiplier(1f + (float)tier * 2f / 100f); sE_WarheimRingMiner.SetHealthPercentBonus((float)tier / 100f); return (StatusEffect)(object)sE_WarheimRingMiner; } case WarheimRingType.Lumberjack: { SE_WarheimRingLumberjack sE_WarheimRingLumberjack = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingLumberjack).name = $"SE_WarheimRing_Lumberjack_T{tier}"; ((StatusEffect)sE_WarheimRingLumberjack).m_name = $"Anneau du Bûcheron T{tier}"; ((StatusEffect)sE_WarheimRingLumberjack).m_icon = icon; ((StatusEffect)sE_WarheimRingLumberjack).m_tooltip = $"+{tier * 75} de limite de poids, +{tier * 2}% de dégâts de coupe et +{tier}% d'endurance totale."; sE_WarheimRingLumberjack.SetCarryWeightBonus((float)tier * 75f); sE_WarheimRingLumberjack.SetChopDamageMultiplier(1f + (float)tier * 2f / 100f); sE_WarheimRingLumberjack.SetStaminaPercentBonus((float)tier / 100f); return (StatusEffect)(object)sE_WarheimRingLumberjack; } case WarheimRingType.Leviathan: { SE_WarheimRingLeviathan sE_WarheimRingLeviathan = ScriptableObject.CreateInstance(); ((Object)sE_WarheimRingLeviathan).name = $"SE_WarheimRing_Leviathan_T{tier}"; ((StatusEffect)sE_WarheimRingLeviathan).m_name = $"Anneau du Léviathan T{tier}"; ((StatusEffect)sE_WarheimRingLeviathan).m_icon = icon; ((StatusEffect)sE_WarheimRingLeviathan).m_tooltip = $"+{tier * 5} au skill de nage et +{tier * 3}% de vitesse de nage."; sE_WarheimRingLeviathan.SetSwimSkillBonus((float)tier * 5f); sE_WarheimRingLeviathan.SetSwimSpeedMultiplier(1f + (float)tier * 3f / 100f); return (StatusEffect)(object)sE_WarheimRingLeviathan; } default: return null; } } } internal static class WeightPanelFix { [HarmonyPatch] private static class InventoryGui_Awake_Patch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(InventoryGui), "Awake", (Type[])null, (Type[])null); } private static void Postfix(InventoryGui __instance) { if (!((Object)(object)__instance?.m_weight == (Object)null) && (Object)(object)((Component)__instance.m_weight).GetComponent() == (Object)null) { ((Component)__instance.m_weight).gameObject.AddComponent(); } } } private sealed class WarheimWeightPanelOffset : MonoBehaviour { private TMP_Text _text; private void Awake() { _text = ((Component)this).GetComponent(); } private void OnEnable() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Canvas.willRenderCanvases += new WillRenderCanvases(Apply); } private void OnDisable() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Canvas.willRenderCanvases -= new WillRenderCanvases(Apply); } private void OnDestroy() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Canvas.willRenderCanvases -= new WillRenderCanvases(Apply); } private void Apply() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_text == (Object)null) { return; } Transform parent = _text.transform.parent; if (!((Object)(object)parent == (Object)null)) { RectTransform component = ((Component)parent).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.anchoredPosition = new Vector2(40f, component.anchoredPosition.y); } } } } private const float WeightPanelX = 40f; } } namespace WarheimStuff.RaidSystem { public class RaidAltar : MonoBehaviour, Hoverable, Interactable { private ZNetView _zNetView; private void Awake() { _zNetView = ((Component)this).GetComponent(); } public ZDOID GetAltarId() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_zNetView == (Object)null || !_zNetView.IsValid() || _zNetView.GetZDO() == null) { return ZDOID.None; } return _zNetView.GetZDO().m_uid; } public string GetHoverText() { return Localization.instance.Localize(GetPieceLocalizationKey() + "\n[$KEY_Use] Ouvrir les épreuves"); } public string GetHoverName() { return Localization.instance.Localize(GetPieceLocalizationKey()); } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || (Object)(object)user == (Object)null || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return false; } if ((Object)(object)_zNetView == (Object)null || !_zNetView.IsValid()) { return false; } RaidUI.Show(this); return true; } private void OnDestroy() { RaidUI.NotifyAltarUnavailable(this); } public bool UseItem(Humanoid user, ItemData item) { return false; } public ZNetView GetZNetView() { return _zNetView; } public string GetPrefabName() { return Utils.GetPrefabName(((Component)this).gameObject); } private string GetPieceLocalizationKey() { string prefabName = GetPrefabName(); return string.IsNullOrWhiteSpace(prefabName) ? "$piece_warheim_raids_raven_altar" : ("$piece_" + prefabName); } } [Serializable] public class RaidConfigRoot { public Dictionary altars { get; set; } = new Dictionary(); public Dictionary trials { get; set; } = new Dictionary(); } [Serializable] public class RaidAltarConfig { public string displayName { get; set; } = ""; public List allowedTrials { get; set; } = new List(); } [Serializable] public class RaidTrialConfig { public string displayName { get; set; } = ""; public string requiredItem { get; set; } = ""; public int requiredAmount { get; set; } = 1; public int maxPlayers { get; set; } = 5; public float playerRadius { get; set; } = 35f; public string spawnMode { get; set; } = "raycast_down"; public float spawnRadius { get; set; } = 18f; public float minSpawnDistance { get; set; } = 8f; public float yOffset { get; set; } = 0.2f; public float raycastHeight { get; set; } = 25f; public float nextWaveDelay { get; set; } = 8f; public float checkInterval { get; set; } = 2f; public float waveTimeout { get; set; } = 300f; public bool cleanupOnSuccess { get; set; } = true; public bool cleanupOnFail { get; set; } = true; public bool failIfTooManyPlayers { get; set; } = true; public bool failIfNoParticipantsNearby { get; set; } = true; public string description { get; set; } = ""; public string music { get; set; } = ""; public bool musicLoop { get; set; } = true; public float musicVolume { get; set; } = 1f; public List rewards { get; set; } = new List(); public List waves { get; set; } = new List(); } [Serializable] public class RaidWaveConfig { public float delay { get; set; } = 0f; public float spawnInterval { get; set; } = 0.5f; public List mobs { get; set; } = new List(); } [Serializable] public class RaidMobConfig { public string prefab { get; set; } = ""; public int amount { get; set; } = 1; public int stars { get; set; } = 0; } [Serializable] public class RaidRewardConfig { public string prefab { get; set; } = ""; public int amount { get; set; } = 1; } public static class RaidConfigLoader { private const string FolderName = "WarheimRaids"; private const string FileName = "WarheimRaids.yaml"; private const string DefaultYaml = "altars:\r\n warheim_raids_raven_altar:\r\n displayName: \"Corbeau des Épreuves\"\r\n allowedTrials:\r\n - test_trial\r\n warheim_raids_dragon_altar:\r\n displayName: \"Autel du Dragon\"\r\n allowedTrials:\r\n - test_trial\r\n warheim_raids_viking_altar:\r\n displayName: \"Autel Viking\"\r\n allowedTrials:\r\n - test_trial\r\n\r\ntrials:\r\n test_trial:\r\n displayName: \"Épreuve de test\"\r\n requiredItem: \"TrophyBoar\"\r\n requiredAmount: 1\r\n\r\n maxPlayers: 5\r\n playerRadius: 35\r\n\r\n spawnMode: \"raycast_down\"\r\n spawnRadius: 18\r\n minSpawnDistance: 8\r\n yOffset: 0.2\r\n raycastHeight: 25\r\n\r\n nextWaveDelay: 8\r\n checkInterval: 2\r\n waveTimeout: 300\r\n\r\n cleanupOnSuccess: true\r\n cleanupOnFail: true\r\n failIfTooManyPlayers: true\r\n failIfNoParticipantsNearby: true\r\n\r\n description: \"Une première épreuve simple pour tester le système.\"\r\n music: \"raid_test.ogg\"\r\n musicLoop: true\r\n musicVolume: 0.8\r\n\r\n rewards:\r\n - prefab: \"Coins\"\r\n amount: 50\r\n\r\n waves:\r\n - delay: 3\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Boar\"\r\n amount: 5\r\n stars: 0\r\n\r\n - delay: 5\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Neck\"\r\n amount: 5\r\n stars: 1\r\n\r\n - delay: 5\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Greydwarf\"\r\n amount: 6\r\n stars: 1\r\n"; public static string ConfigPath { get { string text = Path.Combine(Paths.ConfigPath, "WarheimRaids"); Directory.CreateDirectory(text); return Path.Combine(text, "WarheimRaids.yaml"); } } public static RaidConfigRoot LoadOrCreateDefault() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown string text = Path.Combine(Paths.ConfigPath, "WarheimRaids"); Directory.CreateDirectory(text); string text2 = Path.Combine(text, "WarheimRaids.yaml"); if (!File.Exists(text2)) { File.WriteAllText(text2, "altars:\r\n warheim_raids_raven_altar:\r\n displayName: \"Corbeau des Épreuves\"\r\n allowedTrials:\r\n - test_trial\r\n warheim_raids_dragon_altar:\r\n displayName: \"Autel du Dragon\"\r\n allowedTrials:\r\n - test_trial\r\n warheim_raids_viking_altar:\r\n displayName: \"Autel Viking\"\r\n allowedTrials:\r\n - test_trial\r\n\r\ntrials:\r\n test_trial:\r\n displayName: \"Épreuve de test\"\r\n requiredItem: \"TrophyBoar\"\r\n requiredAmount: 1\r\n\r\n maxPlayers: 5\r\n playerRadius: 35\r\n\r\n spawnMode: \"raycast_down\"\r\n spawnRadius: 18\r\n minSpawnDistance: 8\r\n yOffset: 0.2\r\n raycastHeight: 25\r\n\r\n nextWaveDelay: 8\r\n checkInterval: 2\r\n waveTimeout: 300\r\n\r\n cleanupOnSuccess: true\r\n cleanupOnFail: true\r\n failIfTooManyPlayers: true\r\n failIfNoParticipantsNearby: true\r\n\r\n description: \"Une première épreuve simple pour tester le système.\"\r\n music: \"raid_test.ogg\"\r\n musicLoop: true\r\n musicVolume: 0.8\r\n\r\n rewards:\r\n - prefab: \"Coins\"\r\n amount: 50\r\n\r\n waves:\r\n - delay: 3\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Boar\"\r\n amount: 5\r\n stars: 0\r\n\r\n - delay: 5\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Neck\"\r\n amount: 5\r\n stars: 1\r\n\r\n - delay: 5\r\n spawnInterval: 0.5\r\n mobs:\r\n - prefab: \"Greydwarf\"\r\n amount: 6\r\n stars: 1\r\n"); } try { string text3 = File.ReadAllText(text2); IDeserializer val = ((BuilderSkeleton)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).IgnoreUnmatchedProperties().Build(); RaidConfigRoot raidConfigRoot = val.Deserialize(text3) ?? new RaidConfigRoot(); EnsureBuiltInAltars(raidConfigRoot); Debug.Log((object)("[WarheimRaids] YAML chargé : " + text2)); return raidConfigRoot; } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Erreur chargement YAML : " + ex)); return new RaidConfigRoot(); } } private static void EnsureBuiltInAltars(RaidConfigRoot config) { if (config.altars == null) { Dictionary dictionary = (config.altars = new Dictionary()); } if (config.altars.TryGetValue("warheim_raids_raven_altar", out var value)) { AddBuiltInAltarIfMissing(config, "warheim_raids_dragon_altar", "Autel du Dragon", value); AddBuiltInAltarIfMissing(config, "warheim_raids_viking_altar", "Autel Viking", value); } } private static void AddBuiltInAltarIfMissing(RaidConfigRoot config, string prefabName, string displayName, RaidAltarConfig fallback) { if (!config.altars.ContainsKey(prefabName)) { config.altars[prefabName] = new RaidAltarConfig { displayName = displayName, allowedTrials = ((fallback.allowedTrials != null) ? new List(fallback.allowedTrials) : new List()) }; } } } public static class RaidManager { [HarmonyPatch(typeof(Game), "Start")] private static class Game_Start_RaidPatch { private static void Postfix() { RegisterRoutedRpc(ZRoutedRpc.instance); } } [HarmonyPatch(typeof(ZNet), "Shutdown")] private static class ZNet_Shutdown_RaidPatch { private static void Prefix() { ResetNetworkState(); } } [HarmonyPatch(typeof(Character), "OnDeath")] private static class Character_OnDeath_RaidPatch { private static void Postfix(Character __instance) { ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (!zDO.GetBool("WarheimRaid", false)) { return; } string text = zDO.GetString("WarheimRaidSession", ""); int num = zDO.GetInt("WarheimRaidWave", -1); string text2 = ((object)Unsafe.As(ref zDO.m_uid)/*cast due to .constrained prefix*/).ToString(); if (!string.IsNullOrWhiteSpace(text)) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(0L, "WarheimRaids_MobDeath", new object[3] { text, num, text2 }); } } } } private const int ProtocolVersion = 1; private const string StartRaidRpc = "WarheimRaids_StartRaid"; private const string RequestUiRpc = "WarheimRaids_RequestUi"; private const string ReceiveUiRpc = "WarheimRaids_ReceiveUi"; private const string MessageRpc = "WarheimRaids_Message"; private const string PlayMusicRpc = "WarheimRaids_PlayMusic"; private const string StopMusicRpc = "WarheimRaids_StopMusic"; private const string GiveRewardsRpc = "WarheimRaids_GiveRewards"; private const string MobDeathRpc = "WarheimRaids_MobDeath"; private static readonly Dictionary ActiveRaids = new Dictionary(); private static readonly Dictionary ActiveRaidsByKey = new Dictionary(); private static ZRoutedRpc _registeredRoutedRpc; private static int _networkSession; public static void Init() { Debug.Log((object)"[WarheimRaids] RaidManager initialisé."); RegisterRoutedRpc(); } private static void RegisterRoutedRpc(ZRoutedRpc routedRpc = null) { ZRoutedRpc val = routedRpc ?? ZRoutedRpc.instance; if (val != null && _registeredRoutedRpc != val) { val.Register("WarheimRaids_StartRaid", (Action)RPC_StartRaid); val.Register("WarheimRaids_RequestUi", (Action)RPC_RequestRaidUi); val.Register("WarheimRaids_ReceiveUi", (Action)RPC_ReceiveRaidUi); val.Register("WarheimRaids_Message", (Action)RPC_Message); val.Register("WarheimRaids_PlayMusic", (Action)RaidMusic.RPC_PlayMusic); val.Register("WarheimRaids_StopMusic", (Action)RaidMusic.RPC_StopMusic); val.Register("WarheimRaids_GiveRewards", (Action)RaidRewards.RPC_GiveRewards); val.Register("WarheimRaids_MobDeath", (Action)RPC_MobDeath); _registeredRoutedRpc = val; _networkSession++; Debug.Log((object)("[WarheimRaids] ZRoutedRpc enregistrés pour la session réseau " + _networkSession + ".")); } } public static void ResetNetworkState() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { foreach (RaidSession item in ActiveRaids.Values.Distinct().ToList()) { item?.Abort(null, broadcast: false); } } ActiveRaids.Clear(); ActiveRaidsByKey.Clear(); _registeredRoutedRpc = null; RaidUI.ResetSession(); RaidMusic.ResetSession(); Debug.Log((object)"[WarheimRaids] État de session réseau réinitialisé."); } public static void SendRaidMessage(string message) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "WarheimRaids_Message", new object[1] { message }); } } private static void RPC_Message(long sender, string message) { if (!IsServerSender(sender) || string.IsNullOrWhiteSpace(message)) { return; } string text = ((Localization.instance != null) ? Localization.instance.Localize(message) : message); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false); Debug.Log((object)("[WarheimRaids] Broadcast reçu : " + text)); return; } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null); } } public static bool HasActiveRaid(ZNetView altar) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)altar == (Object)null || !altar.IsValid()) { return false; } ZDO zDO = altar.GetZDO(); return zDO != null && ActiveRaids.ContainsKey(zDO.m_uid); } public static bool IsRaidActiveOnAltar(ZNetView altar) { if ((Object)(object)altar == (Object)null || !altar.IsValid()) { return false; } ZDO zDO = altar.GetZDO(); return zDO != null && zDO.GetBool("WarheimRaidActive", false); } public static bool RequestRaidUi(RaidAltar altar, int requestId, int attempt) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)altar == (Object)null || ZRoutedRpc.instance == null) { return false; } ZNetView zNetView = altar.GetZNetView(); if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid()) { return false; } ZPackage val = new ZPackage(); val.Write(1); val.Write(requestId); val.Write(altar.GetAltarId()); Debug.Log((object)("[WarheimRaids] Demande de configuration UI au serveur : requête=" + requestId + ", tentative=" + attempt + ".")); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "WarheimRaids_RequestUi", new object[1] { val }); return true; } private static void RPC_RequestRaidUi(long sender, ZPackage pkg) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } int num; int num2; ZDOID val; try { num = pkg.ReadInt(); num2 = pkg.ReadInt(); val = pkg.ReadZDOID(); } catch (Exception ex) { Debug.LogWarning((object)("[WarheimRaids] Requête UI invalide : " + ex.Message)); return; } if (num != 1) { Debug.LogWarning((object)("[WarheimRaids] Requête UI refusée : protocole " + num + ", attendu " + 1 + ".")); return; } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(val) : null); RaidAltarConfig altarConfig = null; bool flag = false; List> list; if (val2 == null) { Debug.LogWarning((object)"[WarheimRaids] Requête UI : ZDO de l'autel introuvable."); altarConfig = null; list = new List>(); } else { flag = IsRaidActiveOnServer(val, val2); list = (flag ? new List>() : GetAllowedTrialsFromServer(val2, out altarConfig)); } ZPackage val3 = new ZPackage(); val3.Write(1); val3.Write(num2); val3.Write(val); val3.Write(flag); val3.Write(altarConfig?.displayName ?? ""); val3.Write(list.Count); foreach (KeyValuePair item in list) { RaidTrialConfig value = item.Value; val3.Write(item.Key); val3.Write(value.displayName ?? ""); val3.Write(value.description ?? ""); val3.Write(value.requiredItem ?? ""); val3.Write(value.requiredAmount); val3.Write(value.maxPlayers); int num3 = value.rewards?.Count ?? 0; val3.Write(num3); if (value.rewards == null) { continue; } foreach (RaidRewardConfig reward in value.rewards) { val3.Write(reward.prefab ?? ""); val3.Write(reward.amount); } } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "WarheimRaids_ReceiveUi", new object[1] { val3 }); Debug.Log((object)("[WarheimRaids] Configuration UI serveur envoyée : requête=" + num2 + ", destinataire=" + sender + ", active=" + flag + ", épreuves=" + list.Count + ".")); } private static void RPC_ReceiveRaidUi(long sender, ZPackage pkg) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer == null || sender != serverPeer.m_uid) { Debug.LogWarning((object)"[WarheimRaids] Réponse UI ignorée : elle ne provient pas du serveur."); return; } } try { int num = pkg.ReadInt(); int requestId = pkg.ReadInt(); if (num != 1) { Debug.LogWarning((object)("[WarheimRaids] Réponse UI ignorée : protocole " + num + ", attendu " + 1 + ".")); return; } ZDOID altarId = pkg.ReadZDOID(); bool raidActive = pkg.ReadBool(); string altarDisplayName = pkg.ReadString(); int num2 = pkg.ReadInt(); List> list = new List>(); for (int i = 0; i < num2; i++) { string key = pkg.ReadString(); RaidTrialConfig raidTrialConfig = new RaidTrialConfig { displayName = pkg.ReadString(), description = pkg.ReadString(), requiredItem = pkg.ReadString(), requiredAmount = pkg.ReadInt(), maxPlayers = pkg.ReadInt(), rewards = new List() }; int num3 = pkg.ReadInt(); for (int j = 0; j < num3; j++) { raidTrialConfig.rewards.Add(new RaidRewardConfig { prefab = pkg.ReadString(), amount = pkg.ReadInt() }); } list.Add(new KeyValuePair(key, raidTrialConfig)); } RaidUI.ApplyServerTrials(requestId, altarId, raidActive, altarDisplayName, list); Debug.Log((object)("[WarheimRaids] Configuration UI reçue : requête=" + requestId + ", active=" + raidActive + ", épreuves=" + list.Count + ".")); } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Erreur lecture configuration UI serveur : " + ex)); } } private static List> GetAllowedTrialsFromServer(ZDO altarZdo, out RaidAltarConfig altarConfig) { altarConfig = null; if (altarZdo == null || WarheimRaids.Config?.altars == null || WarheimRaids.Config.trials == null) { return new List>(); } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(altarZdo.GetPrefab()) : null); string text = (((Object)(object)val != (Object)null) ? Utils.GetPrefabName(val) : ""); if (string.IsNullOrWhiteSpace(text)) { Debug.LogWarning((object)"[WarheimRaids] Impossible d'identifier le prefab de l'autel."); return new List>(); } if (!WarheimRaids.Config.altars.TryGetValue(text, out altarConfig)) { Debug.LogWarning((object)("[WarheimRaids] Autel absent du YAML serveur : " + text)); return new List>(); } List allowedTrialIds = altarConfig.allowedTrials; if (allowedTrialIds == null) { return new List>(); } if (allowedTrialIds.Contains("all")) { return WarheimRaids.Config.trials.ToList(); } return WarheimRaids.Config.trials.Where((KeyValuePair entry) => allowedTrialIds.Contains(entry.Key)).ToList(); } public static void TryStartRaid(RaidAltar altar, string trialId, RaidTrialConfig serverTrial) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)altar == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || ZRoutedRpc.instance == null || serverTrial == null) { return; } ZNetView zNetView = altar.GetZNetView(); if (!((Object)(object)zNetView == (Object)null) && zNetView.IsValid()) { List playersInRadius = GetPlayersInRadius(((Component)altar).transform.position, serverTrial.playerRadius); if (serverTrial.failIfTooManyPlayers && playersInRadius.Count > serverTrial.maxPlayers) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Trop de joueurs autour de l'autel.", 0, (Sprite)null); return; } if (!ConsumeOffering(Player.m_localPlayer, serverTrial)) { string itemDisplayName = GetItemDisplayName(serverTrial.requiredItem); ((Character)Player.m_localPlayer).Message((MessageType)2, "Offrande manquante : " + serverTrial.requiredAmount + "x " + itemDisplayName, 0, (Sprite)null); return; } ZPackage val = new ZPackage(); val.Write(1); val.Write(altar.GetAltarId()); val.Write(trialId); val.Write(Player.m_localPlayer.GetPlayerID()); Debug.Log((object)("[WarheimRaids] Demande serveur de lancement : " + trialId)); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "WarheimRaids_StartRaid", new object[1] { val }); } } private static void RPC_StartRaid(long sender, ZPackage pkg) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) int num; ZDOID altarId; string trialId; long item; try { num = pkg.ReadInt(); altarId = pkg.ReadZDOID(); trialId = pkg.ReadString(); item = pkg.ReadLong(); } catch (Exception ex) { Debug.LogWarning((object)("[WarheimRaids] Requête de lancement invalide : " + ex.Message)); return; } if (num != 1) { Debug.LogWarning((object)("[WarheimRaids] Requête de lancement refusée : protocole " + num + ", attendu " + 1 + ".")); } else { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } Debug.Log((object)("[WarheimRaids] RPC_StartRaid reçu côté serveur : " + trialId)); ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(altarId) : null); if (val == null) { Debug.LogWarning((object)"[WarheimRaids] Stop : ZDO autel introuvable."); return; } Vector3 position = val.GetPosition(); if (IsRaidActiveOnServer(altarId, val)) { SendMessageToPeer(sender, "Une épreuve est déjà lancée."); return; } RaidAltarConfig altarConfig; List> allowedTrialsFromServer = GetAllowedTrialsFromServer(val, out altarConfig); RaidTrialConfig value = allowedTrialsFromServer.FirstOrDefault((KeyValuePair entry) => entry.Key == trialId).Value; if (value == null) { Debug.LogWarning((object)("[WarheimRaids] Stop : épreuve absente ou interdite sur cet autel : " + trialId)); SendMessageToPeer(sender, "Cette épreuve n'est pas disponible sur cet autel."); return; } HashSet peerIdsInRadius = GetPeerIdsInRadius(position, value.playerRadius); peerIdsInRadius.Add(sender); Debug.Log((object)("[WarheimRaids] Peers dans le rayon de l'autel : " + peerIdsInRadius.Count + " / limite : " + value.maxPlayers)); if (!value.failIfTooManyPlayers || peerIdsInRadius.Count <= value.maxPlayers) { val.Set("WarheimRaidActive", true); RaidSession session = new RaidSession(altarId, position, trialId, value, new HashSet { item }, peerIdsInRadius, sender); ActiveRaids[altarId] = session; RegisterSession(((object)Unsafe.As(ref altarId)/*cast due to .constrained prefix*/).ToString(), session); session.OnFinished += delegate { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance2 = ZDOMan.instance; ZDO val2 = ((instance2 != null) ? instance2.GetZDO(altarId) : null); if (ActiveRaids.TryGetValue(altarId, out var value2) && value2 == session) { if (val2 != null) { val2.Set("WarheimRaidActive", false); } ActiveRaids.Remove(altarId); } Debug.Log((object)("[WarheimRaids] Session terminée : " + trialId)); }; Debug.Log((object)"[WarheimRaids] Session.Start()"); try { session.Start(); return; } catch (Exception ex2) { Debug.LogError((object)("[WarheimRaids] Erreur au démarrage de la session " + trialId + ": " + ex2)); val.Set("WarheimRaidActive", false); ActiveRaids.Remove(altarId); UnregisterSession(((object)Unsafe.As(ref altarId)/*cast due to .constrained prefix*/).ToString()); SendMessageToPeer(sender, "Impossible de lancer l'épreuve."); return; } } Debug.LogWarning((object)"[WarheimRaids] Stop : trop de joueurs autour de l'autel."); SendRaidMessageToPeers(new HashSet { sender }, "Trop de joueurs autour de l'autel."); } } public static void SendRaidMessageToPeers(HashSet peerIds, string message) { if (ZRoutedRpc.instance == null || peerIds == null || peerIds.Count == 0) { return; } foreach (long peerId in peerIds) { ZRoutedRpc.instance.InvokeRoutedRPC(peerId, "WarheimRaids_Message", new object[1] { message }); } } private static void SendMessageToPeer(long peerId, string message) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(peerId, "WarheimRaids_Message", new object[1] { message }); } } public static HashSet GetPeerIdsInRadius(Vector3 center, float radius) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); if ((Object)(object)ZNet.instance == (Object)null) { return hashSet; } foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null && connectedPeer.IsReady() && IsPeerInRadius(connectedPeer, center, radius)) { hashSet.Add(connectedPeer.m_uid); } } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && Vector3.Distance(((Component)localPlayer).transform.position, center) <= radius) { hashSet.Add(ZNet.GetUID()); } return hashSet; } private static bool ConsumeOffering(Player player, RaidTrialConfig trial) { if (string.IsNullOrWhiteSpace(trial.requiredItem) || trial.requiredAmount <= 0) { return true; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } int num = CountItemByPrefab(inventory, trial.requiredItem); Debug.Log((object)("[WarheimRaids] Inventaire : " + num + "x " + trial.requiredItem)); if (num < trial.requiredAmount) { return false; } return RemoveItemByPrefab(inventory, trial.requiredItem, trial.requiredAmount); } public static List GetPlayersInRadius(Vector3 center, float radius) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Character)allPlayer).IsDead() && Vector3.Distance(((Component)allPlayer).transform.position, center) <= radius) { list.Add(allPlayer); } } return list; } public static IEnumerator WaitAndRegisterRoutedRpc() { while (ZRoutedRpc.instance == null) { yield return null; } RegisterRoutedRpc(ZRoutedRpc.instance); } public static string GetItemDisplayName(string prefabName) { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(prefabName) : null); ItemDrop val2 = ((val != null) ? val.GetComponent() : null); if ((Object)(object)val2 == (Object)null) { return prefabName; } return Localization.instance.Localize(val2.m_itemData.m_shared.m_name); } private static int CountItemByPrefab(Inventory inventory, string prefabName) { return (from i in inventory.GetAllItems() where (Object)(object)i?.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == prefabName select i).Sum((ItemData i) => i.m_stack); } private static bool RemoveItemByPrefab(Inventory inventory, string prefabName, int amount) { int num = amount; foreach (ItemData item in inventory.GetAllItems().ToList()) { if (!((Object)(object)item?.m_dropPrefab == (Object)null) && !(((Object)item.m_dropPrefab).name != prefabName)) { int num2 = Mathf.Min(item.m_stack, num); item.m_stack -= num2; num -= num2; if (item.m_stack <= 0) { inventory.RemoveItem(item); } if (num <= 0) { return true; } } } return false; } public static void RegisterSession(string key, RaidSession session) { ActiveRaidsByKey[key] = session; } public static void UnregisterSession(string key) { ActiveRaidsByKey.Remove(key); } internal static bool IsServerSender(long sender) { if ((Object)(object)ZNet.instance == (Object)null) { return false; } if (ZNet.instance.IsServer()) { return sender == ZNet.GetUID(); } ZNetPeer serverPeer = ZNet.instance.GetServerPeer(); return serverPeer != null && sender == serverPeer.m_uid; } private unsafe static bool IsRaidActiveOnServer(ZDOID altarId, ZDO altarZdo) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (ActiveRaids.TryGetValue(altarId, out var value)) { if (value != null && !value.IsFinished) { if (!altarZdo.GetBool("WarheimRaidActive", false)) { altarZdo.Set("WarheimRaidActive", true); } return true; } ActiveRaids.Remove(altarId); UnregisterSession(((object)(*(ZDOID*)(&altarId))/*cast due to .constrained prefix*/).ToString()); } if (altarZdo.GetBool("WarheimRaidActive", false)) { altarZdo.Set("WarheimRaidActive", false); ZDOID val = altarId; Debug.LogWarning((object)("[WarheimRaids] Verrou d'autel orphelin réinitialisé : " + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString() + ".")); } return false; } private static bool IsPeerInRadius(ZNetPeer peer, Vector3 center, float radius) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (Vector3.Distance(peer.m_refPos, center) <= radius) { return true; } if (peer.m_characterID == ZDOID.None || ZDOMan.instance == null) { return false; } ZDO zDO = ZDOMan.instance.GetZDO(peer.m_characterID); return zDO != null && zDO.IsValid() && Vector3.Distance(zDO.GetPosition(), center) <= radius; } private static void RPC_MobDeath(long sender, string sessionKey, int waveIndex, string mobId) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && !string.IsNullOrWhiteSpace(sessionKey) && !string.IsNullOrWhiteSpace(mobId) && ActiveRaidsByKey.TryGetValue(sessionKey, out var value)) { value.NotifyMobDeath(sender, waveIndex, mobId); } } } public static class RaidMusic { private static AudioSource _source; private static UnityWebRequest _activeRequest; private static int _playRequestVersion; private static readonly string MusicFolder = Path.Combine(Paths.ConfigPath, "WarheimRaids", "Music"); public static void PlayForParticipants(HashSet participantPeerIds, RaidTrialConfig trial) { if (string.IsNullOrWhiteSpace(trial.music) || participantPeerIds == null || participantPeerIds.Count == 0 || ZRoutedRpc.instance == null) { return; } foreach (long participantPeerId in participantPeerIds) { ZRoutedRpc.instance.InvokeRoutedRPC(participantPeerId, "WarheimRaids_PlayMusic", new object[3] { trial.music, trial.musicLoop, trial.musicVolume }); } } public static void StopForParticipants(HashSet participantPeerIds) { if (participantPeerIds == null || participantPeerIds.Count == 0 || ZRoutedRpc.instance == null) { return; } foreach (long participantPeerId in participantPeerIds) { ZRoutedRpc.instance.InvokeRoutedRPC(participantPeerId, "WarheimRaids_StopMusic", Array.Empty()); } } private static ZNetView GetNView(Component component) { return ((Object)(object)component != (Object)null) ? component.GetComponent() : null; } public static void RegisterPlayerRPC(Player player) { ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.Register("WarheimRaids_PlayMusic", (Action)RPC_PlayMusic); component.Register("WarheimRaids_StopMusic", (Action)RPC_StopMusic); } } public static void RPC_PlayMusic(long sender, string fileName, bool loop, float volume) { if (RaidManager.IsServerSender(sender) && !string.IsNullOrWhiteSpace(fileName) && !((Object)(object)WarheimRaids.Instance == (Object)null)) { int requestVersion = ++_playRequestVersion; StopCurrentPlayback(); WarheimRaids.Instance.StartCoroutine(LoadAndPlay(fileName, loop, volume, requestVersion)); } } public static void RPC_StopMusic(long sender) { if (RaidManager.IsServerSender(sender)) { _playRequestVersion++; StopCurrentPlayback(); } } public static void ResetSession() { _playRequestVersion++; StopCurrentPlayback(); } private static void StopCurrentPlayback() { if ((Object)(object)_source != (Object)null) { _source.Stop(); Object.Destroy((Object)(object)((Component)_source).gameObject); _source = null; } if (_activeRequest != null) { _activeRequest.Abort(); _activeRequest.Dispose(); _activeRequest = null; } } private static IEnumerator LoadAndPlay(string fileName, bool loop, float volume, int requestVersion) { Directory.CreateDirectory(MusicFolder); string safeFileName = Path.GetFileName(fileName); if (!string.Equals(fileName, safeFileName, StringComparison.Ordinal)) { Debug.LogWarning((object)("[WarheimRaids] Nom de musique invalide : " + fileName)); yield break; } string path = Path.GetFullPath(Path.Combine(MusicFolder, safeFileName)); if (!File.Exists(path)) { Debug.LogWarning((object)("[WarheimRaids] Musique introuvable : " + path)); yield break; } FileInfo fileInfo = new FileInfo(path); if (fileInfo.Length <= 0) { Debug.LogWarning((object)("[WarheimRaids] Fichier audio vide : " + path)); yield break; } AudioType audioType = GetAudioType(path); if ((int)audioType == 0) { Debug.LogWarning((object)("[WarheimRaids] Extension audio non supportée : " + path)); yield break; } string url = new Uri(path).AbsoluteUri; UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(url, audioType); DownloadHandler downloadHandler = request.downloadHandler; DownloadHandlerAudioClip audioHandler = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); if (audioHandler == null) { Debug.LogWarning((object)("[WarheimRaids] DownloadHandler audio invalide : " + path)); request.Dispose(); yield break; } audioHandler.streamAudio = false; _activeRequest = request; yield return request.SendWebRequest(); if (requestVersion != _playRequestVersion) { ReleaseRequest(request); yield break; } if ((int)request.result != 1) { Debug.LogWarning((object)("[WarheimRaids] Erreur chargement musique " + safeFileName + " : " + request.error)); ReleaseRequest(request); yield break; } AudioClip clip = DownloadHandlerAudioClip.GetContent(request); if ((Object)(object)clip == (Object)null) { Debug.LogWarning((object)("[WarheimRaids] AudioClip nul après chargement : " + path)); ReleaseRequest(request); yield break; } ((Object)clip).name = Path.GetFileNameWithoutExtension(safeFileName); if ((int)clip.loadState == 0 && !clip.LoadAudioData()) { Debug.LogWarning((object)("[WarheimRaids] Impossible de charger les données audio : " + safeFileName)); ReleaseRequest(request); yield break; } while ((int)clip.loadState == 1) { yield return null; } if (requestVersion != _playRequestVersion) { ReleaseRequest(request); yield break; } if ((int)clip.loadState == 3) { Debug.LogWarning((object)("[WarheimRaids] Décodage audio échoué : " + safeFileName)); ReleaseRequest(request); yield break; } if ((Object)(object)_source != (Object)null) { Object.Destroy((Object)(object)((Component)_source).gameObject); } GameObject obj = new GameObject("WarheimRaidMusic"); Object.DontDestroyOnLoad((Object)(object)obj); _source = obj.AddComponent(); _source.clip = clip; _source.loop = loop; _source.volume = Mathf.Clamp01(volume); _source.spatialBlend = 0f; _source.Play(); ReleaseRequest(request); yield return null; if (requestVersion == _playRequestVersion && (Object)(object)_source != (Object)null && !_source.isPlaying) { Debug.LogWarning((object)("[WarheimRaids] FMOD n'a pas démarré la musique : " + safeFileName + " (état=" + ((object)clip.loadState/*cast due to .constrained prefix*/).ToString() + ", durée=" + clip.length + "s)")); } else { Debug.Log((object)("[WarheimRaids] Musique lancée : " + safeFileName)); } } private static AudioType GetAudioType(string path) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch { ".ogg" => 14, ".wav" => 20, ".mp3" => 13, _ => 0, }); } private static void ReleaseRequest(UnityWebRequest request) { if (request != null && _activeRequest == request) { _activeRequest = null; request.Dispose(); } } } public static class RaidRewards { public static void SendRewardsToParticipants(RaidTrialConfig trial, HashSet participantIds) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if (trial?.rewards == null || trial.rewards.Count == 0 || participantIds == null || participantIds.Count == 0 || ZRoutedRpc.instance == null) { return; } ZPackage val = new ZPackage(); val.Write(participantIds.Count); foreach (long participantId in participantIds) { val.Write(participantId); } val.Write(trial.rewards.Count); foreach (RaidRewardConfig reward in trial.rewards) { val.Write(reward.prefab); val.Write(reward.amount); } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "WarheimRaids_GiveRewards", new object[1] { val }); } } public static void RPC_GiveRewards(long sender, ZPackage pkg) { //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) if (!RaidManager.IsServerSender(sender) || (Object)(object)Player.m_localPlayer == (Object)null) { return; } long playerID = Player.m_localPlayer.GetPlayerID(); int num = pkg.ReadInt(); bool flag = false; for (int i = 0; i < num; i++) { long num2 = pkg.ReadLong(); if (num2 == playerID) { flag = true; } } int num3 = pkg.ReadInt(); if (!flag) { return; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); for (int j = 0; j < num3; j++) { string text = pkg.ReadString(); int num4 = pkg.ReadInt(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[WarheimRaids] Reward introuvable : " + text)); continue; } ItemData val2 = inventory.AddItem(text, num4, val.m_itemData.m_quality, val.m_itemData.m_variant, 0L, "", false); if (val2 == null) { Vector3 val3 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward + Vector3.up; Object.Instantiate(itemPrefab, val3, Quaternion.identity).GetComponent().m_itemData.m_stack = num4; } } ((Character)Player.m_localPlayer).Message((MessageType)2, "Récompenses reçues.", 0, (Sprite)null); } } public class RaidSession { private readonly ZDOID _altarId; private readonly Vector3 _altarPosition; private readonly string _trialId; private readonly RaidTrialConfig _trial; private readonly HashSet _participantIds = new HashSet(); private readonly List _spawnedMobs = new List(); private int _currentWaveIndex = -1; private bool _finished; private readonly Dictionary _mobSpawnTimes = new Dictionary(); private readonly List _spawnedMobZdos = new List(); private readonly HashSet _participantPeerIds = new HashSet(); private readonly long _simulationPeerId; private int _aliveMobs; private readonly HashSet _deadMobIds = new HashSet(); public bool IsFinished => _finished; private string SessionKey => ((object)_altarId/*cast due to .constrained prefix*/).ToString(); public event Action OnFinished; public RaidSession(ZDOID altarId, Vector3 altarPosition, string trialId, RaidTrialConfig trial, HashSet participantIds, HashSet participantPeerIds, long simulationPeerId) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) _altarId = altarId; _altarPosition = altarPosition; _trialId = trialId; _trial = trial; _participantIds = ((participantIds != null) ? new HashSet(participantIds) : new HashSet()); _participantPeerIds = ((participantPeerIds != null) ? new HashSet(participantPeerIds) : new HashSet()); _simulationPeerId = simulationPeerId; } public void Start() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!_finished) { if (_altarId == ZDOID.None || _trial == null || (Object)(object)WarheimRaids.Instance == (Object)null || !IsAltarAvailable()) { Finish(success: false, "Autel invalide."); return; } Broadcast("$warheim_raid_started"); RaidMusic.PlayForParticipants(_participantPeerIds, _trial); WarheimRaids.Instance.StartCoroutine(RunRaidSafely()); } } private IEnumerator RunRaidSafely() { IEnumerator raidRoutine = RunRaid(); while (true) { bool hasNext; object current; try { hasNext = raidRoutine.MoveNext(); current = (hasNext ? raidRoutine.Current : null); } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Exception dans la session " + _trialId + ": " + ex)); Finish(success: false, "$warheim_raid_failed"); yield break; } if (!hasNext) { break; } yield return current; } if (!_finished) { Finish(success: false, "$warheim_raid_failed"); } } private static string GetWaveSummary(RaidWaveConfig wave) { return string.Join(", ", wave.mobs.Select((RaidMobConfig m) => $"{m.amount}x {m.prefab}")); } private IEnumerator RunRaid() { yield return (object)new WaitForSeconds(1f); if (_trial.waves == null || _trial.waves.Count == 0) { Finish(success: false, "Aucune vague configurée."); yield break; } for (int i = 0; i < _trial.waves.Count; i++) { if (!IsAltarAvailable()) { Finish(success: false, "$warheim_raid_failed"); yield break; } _currentWaveIndex = i; RaidWaveConfig wave = _trial.waves[i]; if (wave == null || wave.mobs == null) { Finish(success: false, "$warheim_raid_failed"); yield break; } if (wave.delay > 0f) { yield return (object)new WaitForSeconds(wave.delay); } if (!IsAltarAvailable()) { Finish(success: false, "$warheim_raid_failed"); yield break; } Broadcast($"Vague {i + 1}/{_trial.waves.Count} : {GetWaveSummary(wave)}"); _aliveMobs = 0; _deadMobIds.Clear(); RaidManager.RegisterSession(SessionKey, this); yield return SpawnWave(wave); if (_finished) { yield break; } Broadcast($"Vague {i + 1} lancée !"); float timer = 0f; float announceTimer = 0f; while (!_finished) { if (!ValidateParticipants()) { Finish(success: false, "$warheim_raid_failed"); yield break; } CleanupDeadMobRefs(); int alive = (_aliveMobs = CountAliveTrackedMobs()); Debug.Log((object)("[WarheimRaids] Wave " + (_currentWaveIndex + 1) + " alive = " + alive)); if (alive <= 0) { break; } timer += _trial.checkInterval; announceTimer += _trial.checkInterval; if (announceTimer >= 15f) { announceTimer = 0f; float remaining = Mathf.Max(0f, _trial.waveTimeout - timer); Broadcast($"Vague {i + 1}/{_trial.waves.Count} — ennemis restants : {alive} — temps restant : {Mathf.CeilToInt(remaining)}s"); } if (_trial.waveTimeout > 0f && timer >= _trial.waveTimeout) { Finish(success: false, "Temps écoulé."); yield break; } yield return (object)new WaitForSeconds(_trial.checkInterval); } Broadcast($"Vague {i + 1} terminée."); if (i < _trial.waves.Count - 1) { yield return (object)new WaitForSeconds(_trial.nextWaveDelay); } } Finish(success: true, "$warheim_raid_success"); } private unsafe int CountAliveTrackedMobs() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (ZDOMan.instance == null) { return _spawnedMobs.Count((Character mob) => (Object)(object)mob != (Object)null && mob.GetHealth() > 0f); } foreach (ZDOID item in _spawnedMobZdos.ToList()) { if (_deadMobIds.Contains(((object)(*(ZDOID*)(&item))/*cast due to .constrained prefix*/).ToString())) { _spawnedMobZdos.Remove(item); continue; } ZDO zDO = ZDOMan.instance.GetZDO(item); if (zDO != null && zDO.IsValid()) { num++; } else { _spawnedMobZdos.Remove(item); } } return num; } private IEnumerator SpawnWave(RaidWaveConfig wave) { foreach (RaidMobConfig mob in wave.mobs) { for (int i = 0; i < mob.amount; i++) { Character character; try { character = RaidSpawnUtility.SpawnMob(_altarPosition, _altarId, _trial, mob, _trialId, _currentWaveIndex, _simulationPeerId); } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Erreur spawn de " + mob.prefab + " : " + ex)); Finish(success: false, "$warheim_raid_failed"); yield break; } Debug.Log((object)("[WarheimRaids] Mob spawned character = " + ((Object)(object)character != (Object)null))); if ((Object)(object)character == (Object)null) { Finish(success: false, "$warheim_raid_failed"); yield break; } _spawnedMobs.Add(character); _mobSpawnTimes[character] = Time.time; _aliveMobs++; ZNetView znv = ((Component)character).GetComponent(); if ((Object)(object)znv == (Object)null || !znv.IsValid()) { Finish(success: false, "$warheim_raid_failed"); yield break; } ZDOID mobId = znv.GetZDO().m_uid; if (!_spawnedMobZdos.Contains(mobId)) { _spawnedMobZdos.Add(mobId); } Debug.Log((object)("[WarheimRaids] Mob tracked. Alive = " + _aliveMobs)); if (wave.spawnInterval > 0f) { yield return (object)new WaitForSeconds(wave.spawnInterval); } } } } private bool ValidateParticipants() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!IsAltarAvailable()) { return false; } HashSet peerIdsInRadius = RaidManager.GetPeerIdsInRadius(_altarPosition, _trial.playerRadius); if (_trial.failIfTooManyPlayers && peerIdsInRadius.Count > _trial.maxPlayers) { Broadcast("$warheim_raid_too_many_players"); return false; } if (_trial.failIfNoParticipantsNearby && !_participantPeerIds.Overlaps(peerIdsInRadius)) { return false; } return true; } private void CleanupDeadMobRefs() { _spawnedMobs.RemoveAll(delegate(Character mob) { if ((Object)(object)mob == (Object)null) { return true; } if (!_mobSpawnTimes.TryGetValue(mob, out var value)) { return false; } return !(Time.time - value < 3f) && mob.GetHealth() <= 0f; }); } private static ZNetView GetNView(Component component) { return ((Object)(object)component != (Object)null) ? component.GetComponent() : null; } public void Abort(string message, bool broadcast) { if (!_finished) { Finish(success: false, broadcast ? message : null); } } public unsafe void NotifyMobDeath(long sender, int waveIndex, string mobId) { if (_finished || waveIndex != _currentWaveIndex || string.IsNullOrWhiteSpace(mobId) || (sender != _simulationPeerId && !_participantPeerIds.Contains(sender) && sender != ZNet.GetUID())) { return; } int num = _spawnedMobZdos.FindIndex((ZDOID id) => ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).ToString() == mobId); if (num >= 0 && _deadMobIds.Add(mobId)) { _spawnedMobZdos.RemoveAt(num); _spawnedMobs.RemoveAll(delegate(Character mob) { ZNetView nView = GetNView((Component)(object)mob); return (Object)(object)nView != (Object)null && nView.IsValid() && ((object)Unsafe.As(ref nView.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString() == mobId; }); _aliveMobs = CountAliveTrackedMobs(); Debug.Log((object)("[WarheimRaids] Mort confirmée : session=" + SessionKey + ", vague=" + waveIndex + ", mob=" + mobId + ".")); } } private bool IsAltarAvailable() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (_altarId == ZDOID.None || ZDOMan.instance == null) { return false; } ZDO zDO = ZDOMan.instance.GetZDO(_altarId); return zDO != null && zDO.IsValid(); } private void Finish(bool success, string message) { if (_finished) { return; } _finished = true; try { if (!string.IsNullOrWhiteSpace(message)) { Broadcast(message); } if (success && _trial != null) { RaidRewards.SendRewardsToParticipants(_trial, _participantIds); } } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Erreur pendant la finalisation de " + _trialId + ": " + ex)); } finally { try { if (_trial != null && ((success && _trial.cleanupOnSuccess) || (!success && _trial.cleanupOnFail))) { CleanupMobs(); } } catch (Exception ex2) { Debug.LogError((object)("[WarheimRaids] Erreur nettoyage des mobs de " + _trialId + ": " + ex2)); } try { RaidMusic.StopForParticipants(_participantPeerIds); } catch (Exception ex3) { Debug.LogWarning((object)("[WarheimRaids] Erreur arrêt musique : " + ex3.Message)); } RaidManager.UnregisterSession(SessionKey); try { this.OnFinished?.Invoke(); } catch (Exception ex4) { Debug.LogError((object)("[WarheimRaids] Erreur libération de la session " + _trialId + ": " + ex4)); } } } private unsafe void CleanupMobs() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) int num = 0; long uID = ZNet.GetUID(); if (ZDOMan.instance != null) { foreach (ZDOID item in _spawnedMobZdos.ToList()) { ZDO zDO = ZDOMan.instance.GetZDO(item); if (zDO == null || !zDO.IsValid()) { continue; } try { zDO.SetOwner(uID); ZDOMan.instance.DestroyZDO(zDO); if (ZDOMan.instance.GetZDO(item) == null) { num++; continue; } ZDOID val = item; Debug.LogWarning((object)("[WarheimRaids] Le ZDO existe encore après DestroyZDO : " + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString())); } catch (Exception ex) { ZDOID val = item; Debug.LogWarning((object)("[WarheimRaids] Impossible de détruire le ZDO " + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString() + " : " + ex.Message)); } } } foreach (Character spawnedMob in _spawnedMobs) { if (!((Object)(object)spawnedMob == (Object)null)) { Object.Destroy((Object)(object)((Component)spawnedMob).gameObject); } } Debug.Log((object)("[WarheimRaids] Nettoyage session " + _trialId + " : " + num + " ZDO détruit(s).")); _spawnedMobs.Clear(); _mobSpawnTimes.Clear(); _spawnedMobZdos.Clear(); } private void Broadcast(string message) { RaidManager.SendRaidMessageToPeers(_participantPeerIds, message); } } public static class RaidSpawnUtility { public unsafe static Character SpawnMob(Vector3 altarPosition, ZDOID altarId, RaidTrialConfig trial, RaidMobConfig mob, string trialId, int waveIndex, long simulationPeerId) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab(mob.prefab); if ((Object)(object)prefab == (Object)null) { Debug.LogWarning((object)("[WarheimRaids] Mob prefab introuvable : " + mob.prefab)); return null; } Vector3 spawnPosition = GetSpawnPosition(altarPosition, trial); Quaternion val = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f); GameObject val2 = Object.Instantiate(prefab, spawnPosition, val); Character component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return null; } if (mob.stars > 0) { component.SetLevel(mob.stars + 1); } ZNetView component2 = val2.GetComponent(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { ZDO zDO = component2.GetZDO(); zDO.Set("WarheimRaid", true); zDO.Set("WarheimRaidTrial", trialId); zDO.Set("WarheimRaidWave", waveIndex); zDO.Set("WarheimRaidAltar", ((object)(*(ZDOID*)(&altarId))/*cast due to .constrained prefix*/).ToString()); zDO.Set("WarheimRaidSession", ((object)(*(ZDOID*)(&altarId))/*cast due to .constrained prefix*/).ToString()); if (simulationPeerId != 0) { zDO.SetOwner(simulationPeerId); ZDOID uid = zDO.m_uid; Debug.Log((object)("[WarheimRaids] Propriétaire réseau du mob " + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString() + " = " + simulationPeerId)); } } return component; } private static Vector3 GetSpawnPosition(Vector3 center, RaidTrialConfig trial) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized; float num = Random.Range(trial.minSpawnDistance, trial.spawnRadius); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x + normalized.x * num, center.y + trial.raycastHeight, center.z + normalized.y * num); if (trial.spawnMode == "altar_y") { val.y = center.y + trial.yOffset; return val; } if (trial.spawnMode == "ground") { val.y = ZoneSystem.instance.GetGroundHeight(val) + trial.yOffset; return val; } if (trial.spawnMode == "raycast_down") { RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(val, Vector3.down, ref val2, trial.raycastHeight * 2f, LayerMask.GetMask(new string[3] { "piece", "Default", "terrain" }))) { val.y = ((RaycastHit)(ref val2)).point.y + trial.yOffset; return val; } val.y = center.y + trial.yOffset; return val; } val.y = center.y + trial.yOffset; return val; } } public static class RaidUI { [HarmonyPatch(typeof(TextInput), "IsVisible")] private static class RaidUI_TextInput_IsVisible_Patch { private static void Postfix(ref bool __result) { if (IsVisible()) { __result = true; } } } [HarmonyPatch(typeof(StoreGui), "IsVisible")] private static class RaidUI_StoreGui_IsVisible_Patch { private static void Postfix(ref bool __result) { if (IsVisible()) { __result = true; } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__26_0; internal void b__26_0() { if (!((Object)(object)_currentAltar == (Object)null) && !string.IsNullOrWhiteSpace(_selectedTrialId)) { Debug.Log((object)("[WarheimRaids] Lancement épreuve : " + _selectedTrialId)); RaidManager.TryStartRaid(_currentAltar, _selectedTrialId, _selectedTrial); if (!((Object)(object)_currentAltar == (Object)null) && !string.IsNullOrWhiteSpace(_selectedTrialId) && _selectedTrial != null) { Hide(); } } } } private const string PanelPath = "assets/raids/warheim_raids_panel.prefab"; private const string RowPath = "assets/raids/warheim_trial_row.prefab"; private const int UiRequestAttempts = 3; private const float UiRequestTimeout = 2f; private static GameObject _panel; private static GameObject _rowPrefab; private static Transform _trialListRoot; private static Transform _rewardListRoot; private static TMP_Text _titleText; private static TMP_Text _descriptionText; private static Button _closeButton; private static Button _startButton; private static RaidAltar _currentAltar; private static string _selectedTrialId; private static RaidTrialConfig _selectedTrial; private static Coroutine _requestCoroutine; private static int _requestSequence; private static int _pendingRequestId; private static int _requestGeneration; public static void Show(RaidAltar altar) { try { CancelPendingRequest(); _currentAltar = altar; if ((Object)(object)_panel == (Object)null) { CreatePanel(); } if (!((Object)(object)_panel == (Object)null)) { _panel.SetActive(true); ClearList(_trialListRoot); _selectedTrialId = null; _selectedTrial = null; _titleText.text = "Corbeau des Épreuves"; _descriptionText.text = "Chargement des épreuves depuis le serveur..."; ((Selectable)_startButton).interactable = false; ClearRewards(); BeginUiRequest(altar); if (ZInput.instance != null) { ZInput.instance.Reset(); } } } catch (Exception ex) { Debug.LogError((object)("[WarheimRaids] Erreur ouverture UI : " + ex)); Hide(); } } public static void ApplyServerTrials(int requestId, ZDOID altarId, bool raidActive, string altarDisplayName, List> trials) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (!IsVisible() || (Object)(object)_currentAltar == (Object)null) { return; } if (requestId != _pendingRequestId) { Debug.LogWarning((object)("[WarheimRaids] Réponse UI ignorée : requête=" + requestId + ", attendue=" + _pendingRequestId + ".")); return; } ZNetView zNetView = _currentAltar.GetZNetView(); if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid()) { return; } ZDOID altarId2 = _currentAltar.GetAltarId(); if (!((ZDOID)(ref altarId2)).Equals(altarId)) { Debug.LogWarning((object)"[WarheimRaids] Réponse UI ignorée : elle concerne un autre autel."); return; } CompletePendingRequest(); ClearList(_trialListRoot); _selectedTrialId = null; _selectedTrial = null; ((Selectable)_startButton).interactable = false; _titleText.text = (string.IsNullOrWhiteSpace(altarDisplayName) ? "Ouvrir les épreuves" : altarDisplayName); _descriptionText.text = "Faites votre choix."; ClearRewards(); if (raidActive) { _descriptionText.text = "Une épreuve est déjà lancée sur cet autel."; } else { FillTrials(trials ?? new List>()); } } public static void Hide() { CancelPendingRequest(); if ((Object)(object)_panel != (Object)null) { _panel.SetActive(false); } _currentAltar = null; _selectedTrialId = null; _selectedTrial = null; if (ZInput.instance != null) { ZInput.instance.Reset(); } } public static void ResetSession() { CancelPendingRequest(); if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); } _panel = null; _rowPrefab = null; _trialListRoot = null; _rewardListRoot = null; _titleText = null; _descriptionText = null; _closeButton = null; _startButton = null; _currentAltar = null; _selectedTrialId = null; _selectedTrial = null; _requestSequence = 0; _pendingRequestId = 0; } public static void NotifyAltarUnavailable(RaidAltar altar) { if ((Object)(object)_currentAltar == (Object)(object)altar) { Hide(); } } public static bool IsVisible() { return (Object)(object)_panel != (Object)null && _panel.activeSelf; } private static Transform FindDeepChild(Transform parent, string name) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown foreach (Transform item in parent) { Transform val = item; if (((Object)val).name == name) { return val; } Transform val2 = FindDeepChild(val, name); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static void CreatePanel() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown GameObject val = WarheimStuff.WarheimBundle.LoadAsset("assets/raids/warheim_raids_panel.prefab"); _rowPrefab = WarheimStuff.WarheimBundle.LoadAsset("assets/raids/warheim_trial_row.prefab"); if ((Object)(object)val == (Object)null) { Debug.LogError((object)"[WarheimRaids] UI panel introuvable : assets/raids/warheim_raids_panel.prefab"); return; } if ((Object)(object)_rowPrefab == (Object)null) { Debug.LogError((object)"[WarheimRaids] UI row introuvable : assets/raids/warheim_trial_row.prefab"); return; } _panel = Object.Instantiate(val); ((Object)_panel).name = "WarheimRaidUI"; _panel.transform.position = Vector3.zero; _panel.transform.localScale = Vector3.one; Debug.Log((object)("[WarheimRaids] UI instanciée : " + ((Object)_panel).name)); Debug.Log((object)("[WarheimRaids] UI activeSelf : " + _panel.activeSelf)); Debug.Log((object)("[WarheimRaids] UI parent : " + (((Object)(object)_panel.transform.parent != (Object)null) ? ((Object)_panel.transform.parent).name : "none"))); Canvas component = _panel.GetComponent(); if ((Object)(object)component != (Object)null) { component.renderMode = (RenderMode)0; component.sortingOrder = 1000; } else { Debug.LogError((object)"[WarheimRaids] Aucun Canvas sur warheim_raids_panel"); } _titleText = Find("Panel/TitleText"); _descriptionText = Find("Panel/DescriptionText"); _trialListRoot = _panel.transform.Find("Panel/Scroll View/Viewport/TrialListRoot"); _rewardListRoot = _panel.transform.Find("Panel/RewardListRoot"); _closeButton = Find