Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MasterRings v1.2.1
MasterRings.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace GoblinHeim.MasterRings; internal sealed class MasterRingRuntimeCache : MonoBehaviour { internal bool KindInitialized; internal bool Greydwarf; internal bool Skeleton; internal float BoundValidUntil; internal bool Bound; internal float AuraValidUntil; internal bool Aura; internal float LichRingValidUntil; internal bool LichRing; } public class SE_MasterRingBiome : StatusEffect { public override void ModifyRunStaminaDrain(float baseDrain, ref float drain, Vector3 dir) { drain *= 0.9f; float finalCost = drain; Character character = base.m_character; StaminaDiagnostics.Log("Run", baseDrain, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifyJumpStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Jump", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifyAttackStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Attack", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifyBlockStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Block", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifyDodgeStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Dodge", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifySwimStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Swim", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifyHomeItemStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("HomeItem", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } public override void ModifySneakStaminaUsage(float baseStaminaUse, ref float staminaUse) { staminaUse *= 0.9f; float finalCost = staminaUse; Character character = base.m_character; StaminaDiagnostics.Log("Sneak", baseStaminaUse, finalCost, (Player)(object)((character is Player) ? character : null)); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("goblinheim.masterrings", "Master Rings", "1.2.1")] public class MasterRingsPlugin : BaseUnityPlugin { public const string PluginGuid = "goblinheim.masterrings"; public const string PluginName = "Master Rings"; public const string PluginVersion = "1.2.1"; internal const string Meadows = "MR_MeadowsLordRing"; internal const string Sylvian = "MR_SylvianRing"; internal const string Dreadful = "MR_DreadfulRing"; internal const string Wind = "MR_WindMasterRing"; internal const string Lich = "MR_LichKingRing"; internal const string BoundSkeletonZdoKey = "MR_BoundSkeleton"; internal const string BoundSkeletonExpiryZdoKey = "MR_BoundSkeletonExpiry"; internal const string LichSkeletonZdoKey = "MR_LichSkeleton"; internal const string LichSkeletonDamageZdoKey = "MR_LichSkeletonDamage"; internal const string SylvianAuraZdoKey = "MR_SylvianAura"; internal const string LichEquippedZdoKey = "MR_LichEquipped"; internal static readonly HashSet<string> MasterRingPrefabs = new HashSet<string>(StringComparer.Ordinal) { "MR_MeadowsLordRing", "MR_SylvianRing", "MR_DreadfulRing", "MR_WindMasterRing", "MR_LichKingRing" }; internal static MasterRingsPlugin Instance; internal static readonly Dictionary<int, float> BoundSkeletons = new Dictionary<int, float>(); internal static readonly Dictionary<int, Character> BoundSkeletonCharacters = new Dictionary<int, Character>(); private static readonly Dictionary<string, Sprite> SpriteCache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private static Player cachedLocalPlayer; private static string cachedLocalRing; private static bool localRingCacheValid; private static bool cachedLocalConstructedOrPath; private static string cachedLocalSurface = "Unknown"; private static string appliedLanguage; private float nextSkeletonScan; private float nextBoundExpiryScan; private float nextBoundDiscoveryScan; private float nextBiomeEffectCheck; private float nextExclusivityCheck; private float nextNecromancyCleanup; internal static readonly Dictionary<string, StatusEffect> BiomeEffects = new Dictionary<string, StatusEffect>(); internal static bool DiagnosticsEnabled = true; private static readonly FieldInfo CharacterNViewField = AccessTools.Field(typeof(Character), "m_nview"); private static Type cachedViewType; private static MethodInfo getZdoMethod; private static Type cachedZdoType; private static MethodInfo zdoSetBool; private static MethodInfo zdoSetLong; private static MethodInfo zdoSetFloat; private static MethodInfo zdoGetBool; private static MethodInfo zdoGetLong; private static MethodInfo zdoGetFloat; private static readonly Dictionary<string, string> French = new Dictionary<string, string> { { "mr_meadows_name", "Anneau du Seigneur des Prairies" }, { "mr_meadows_item", "Il régnait sans partage sur la Prairie" }, { "mr_meadows_effect_name", "Seigneur des Prairies" }, { "mr_meadows_effect", "Bonus actifs dans la Prairie:\n+10% de vitesse\n-10% de consommation d'endurance\n+20% de dégâts aux animaux\n+20 à la fabrication" }, { "mr_sylvian_name", "Anneau Sylvestre" }, { "mr_sylvian_item", "La forêt refleurira" }, { "mr_sylvian_effect_name", "Forêt noire" }, { "mr_sylvian_effect", "Bonus actifs dans la Forêt noire:\n+10% de vitesse\n-10% de consommation d'endurance\n+20 à l'agriculture" }, { "mr_sylvian_perm_name", "Anneau Sylvestre" }, { "mr_sylvian_perm", "Vous faites parti de la forêt." }, { "mr_dread_name", "Anneau d'Effroi" }, { "mr_dread_item", "Un royaume de vase et de boue" }, { "mr_dread_effect_name", "Marais" }, { "mr_dread_effect", "Bonus actifs dans les Marais:\n+10% de vitesse\n-10% de consommation d'endurance" }, { "mr_dread_perm_name", "Anneau d'Effroi" }, { "mr_dread_perm", "Insensible à l'humidité\nNécromancien" }, { "mr_wind_name", "Anneau du Maître des Vents" }, { "mr_wind_item", "Le dernier souffle de la Reine des Dragons" }, { "mr_wind_effect_name", "Montagne" }, { "mr_wind_effect", "Bonus actifs dans la Montagne:\n+10% de vitesse\n-10% de consommation d'endurance" }, { "mr_wind_perm_name", "Maître des Vents" }, { "mr_wind_perm", "Le vent arrive toujours en poupe quand vous naviguez" }, { "mr_lich_name", "Anneau du Roi-Liche" }, { "mr_lich_item", "Le vent souffle sur les plaines" }, { "mr_lich_perm_name", "Anneau du Roi-Liche" }, { "mr_lich_perm", "Très résistant au feu\nNécromancien" }, { "mr_lich_effect_name", "Plaines" }, { "mr_lich_effect", "Bonus actifs dans les plaines :\n+10% de vitesse\n-10% de consommation d'endurance\nInsensible au ralentissement du goudron" } }; private static readonly Dictionary<string, string> English = new Dictionary<string, string> { { "mr_meadows_name", "Meadows Lord Ring" }, { "mr_meadows_item", "He ruled the Meadows without equal" }, { "mr_meadows_effect_name", "Lord of the Meadows" }, { "mr_meadows_effect", "Active bonuses in the Meadows:\n+10% movement speed\n-10% stamina consumption\n+20% damage to animals\n+20 Crafting" }, { "mr_sylvian_name", "Sylvian Ring" }, { "mr_sylvian_item", "The forest will bloom again" }, { "mr_sylvian_effect_name", "Black Forest" }, { "mr_sylvian_effect", "Active bonuses in the Black Forest:\n+10% movement speed\n-10% stamina consumption\n+20 Farming" }, { "mr_sylvian_perm_name", "Sylvian Ring" }, { "mr_sylvian_perm", "You are part of the forest." }, { "mr_dread_name", "Dreadful Ring" }, { "mr_dread_item", "A kingdom of slime and mud" }, { "mr_dread_effect_name", "Swamp" }, { "mr_dread_effect", "Active bonuses in the Swamp:\n+10% movement speed\n-10% stamina consumption" }, { "mr_dread_perm_name", "Dreadful Ring" }, { "mr_dread_perm", "Unaffected by wetness\nNecromancer" }, { "mr_wind_name", "Wind Master Ring" }, { "mr_wind_item", "The Dragon Queen's last breath" }, { "mr_wind_effect_name", "Mountain" }, { "mr_wind_effect", "Active bonuses in the Mountains:\n+10% movement speed\n-10% stamina consumption" }, { "mr_wind_perm_name", "Master of Winds" }, { "mr_wind_perm", "The wind is always at your back when sailing" }, { "mr_lich_name", "Lich King Ring" }, { "mr_lich_item", "The wind blows across the plains" }, { "mr_lich_perm_name", "Lich King Ring" }, { "mr_lich_perm", "Very resistant to fire\nNecromancer" }, { "mr_lich_effect_name", "Plains" }, { "mr_lich_effect", "Active bonuses in the Plains:\n+10% movement speed\n-10% stamina consumption\nImmune to tar slowdown" } }; private void Awake() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown Instance = this; DiagnosticsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "Enabled", false, "Enable detailed diagnostic messages for troubleshooting.").Value; PrefabManager.OnVanillaPrefabsAvailable += RegisterRings; Harmony val = new Harmony("goblinheim.masterrings"); val.PatchAll(); DreadfulWetImmunityPatch.Install(val); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Master Rings 1.2.1 loaded"); } internal static void DiagnosticLog(string message) { if ((DiagnosticsEnabled || message == null || !message.StartsWith("[DIAG]", StringComparison.Ordinal)) && (Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterRings; } private void RegisterRings() { //IL_003e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0078: Expected O, but got Unknown //IL_0078: Expected O, but got Unknown //IL_0078: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00df: Expected O, but got Unknown //IL_00df: Expected O, but got Unknown //IL_00df: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0149: Expected O, but got Unknown //IL_0149: Expected O, but got Unknown //IL_0149: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01a3: Expected O, but got Unknown //IL_01a3: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_0209: Expected O, but got Unknown //IL_0209: Expected O, but got Unknown //IL_0209: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= RegisterRings; try { CreateRing("MR_MeadowsLordRing", "MeadowsLordRing.png", "MeadowsEffect.png", "$mr_meadows_name", "$mr_meadows_item", "$mr_meadows_effect_name", "$mr_meadows_effect", 1, new RequirementConfig("TrophyEikthyr", 1, 0, true), new RequirementConfig("Tin", 4, 0, true), new RequirementConfig("Copper", 2, 0, true), new RequirementConfig("Amber", 2, 0, true)); CreateRing("MR_SylvianRing", "SylvianRing.png", "BlackForestEffect.png", "$mr_sylvian_name", "$mr_sylvian_item", "$mr_sylvian_effect_name", "$mr_sylvian_effect", 2, new RequirementConfig("TrophyTheElder", 1, 0, true), new RequirementConfig("Root", 4, 0, true), new RequirementConfig("Thistle", 1, 0, true), new RequirementConfig("Acorn", 4, 0, true)); CreateRing("MR_DreadfulRing", "DreadfulRing.png", "SwampEffect.png", "$mr_dread_name", "$mr_dread_item", "$mr_dread_effect_name", "$mr_dread_effect", 3, new RequirementConfig("TrophyBonemass", 1, 0, true), new RequirementConfig("Ruby", 4, 0, true), new RequirementConfig("Obsidian", 10, 0, true), new RequirementConfig("BoneFragments", 10, 0, true), (DamageType)256); CreateRing("MR_WindMasterRing", "WindMasterRing.png", "MountainEffect.png", "$mr_wind_name", "$mr_wind_item", "$mr_wind_effect_name", "$mr_wind_effect", 4, new RequirementConfig("TrophyDragonQueen", 1, 0, true), new RequirementConfig("AmberPearl", 1, 0, true), new RequirementConfig("SerpentScale", 12, 0, true), null, (DamageType)64); CreateRing("MR_LichKingRing", "LichKingRing.png", "PlainsEffect.png", "$mr_lich_name", "$mr_lich_item", "$mr_lich_effect_name", "$mr_lich_effect", 5, new RequirementConfig("TrophyGoblinKing", 1, 0, true), new RequirementConfig("GoblinTotem", 1, 0, true), new RequirementConfig("BlackMarble", 10, 0, true), new RequirementConfig("Wisp", 4, 0, true), (DamageType)32); ApplyLocalization(); LogRegistrationDiagnostics(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"All five Master Rings registered. Recipe IDs: TrophyGoblinKing, GoblinTotem, BlackMarble, Wisp; Lich Workbench level 5."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void LogRegistrationDiagnostics() { if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject prefab = ZNetScene.instance.GetPrefab("AmberPearl"); ItemDrop val = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent<ItemDrop>()); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Trade invariant: vanilla AmberPearl value=" + (((Object)(object)val == (Object)null) ? "missing" : val.m_itemData.m_shared.m_value.ToString()))); string[] array = new string[5] { "MR_MeadowsLordRing", "MR_SylvianRing", "MR_DreadfulRing", "MR_WindMasterRing", "MR_LichKingRing" }; foreach (string text in array) { GameObject prefab2 = ZNetScene.instance.GetPrefab(text); ItemDrop val2 = (((Object)(object)prefab2 == (Object)null) ? null : prefab2.GetComponent<ItemDrop>()); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Trade invariant: " + text + " value=" + (((Object)(object)val2 == (Object)null) ? "missing" : val2.m_itemData.m_shared.m_value.ToString()))); } string[] array2 = new string[5] { "TrophyGoblinKing", "GoblinTotem", "BlackMarble", "Wisp", "Skeleton" }; foreach (string text2 in array2) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Prefab check: " + text2 + "=" + (((Object)(object)ZNetScene.instance.GetPrefab(text2) == (Object)null) ? "MISSING" : "OK"))); } } } private void CreateRing(string prefabName, string iconFile, string effectIconFile, string name, string desc, string effectName, string effectDesc, int stationLevel, RequirementConfig r1, RequirementConfig r2, RequirementConfig r3, RequirementConfig r4 = null, DamageType? resistance = null) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Expected O, but got Unknown //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Expected O, but got Unknown //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, "AmberPearl"); ItemDrop component = val.GetComponent<ItemDrop>(); MethodInfo method = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); component.m_itemData.m_shared = (SharedData)method.Invoke(component.m_itemData.m_shared, null); component.m_itemData.m_shared.m_name = name; component.m_itemData.m_shared.m_description = desc; component.m_itemData.m_shared.m_itemType = (ItemType)18; component.m_itemData.m_shared.m_weight = 0.1f; component.m_itemData.m_shared.m_maxStackSize = 1; component.m_itemData.m_shared.m_value = 0; Sprite val2 = LoadEmbeddedIcon(iconFile); if ((Object)(object)val2 != (Object)null) { component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } StatusEffect val3 = (StatusEffect)(object)ScriptableObject.CreateInstance<SE_MasterRingBiome>(); ((Object)val3).name = "SE_" + prefabName + "_Biome"; val3.m_name = effectName; val3.m_tooltip = effectDesc; Sprite val4 = LoadEmbeddedIcon(effectIconFile); val3.m_icon = (((Object)(object)val4 != (Object)null) ? val4 : val2); CustomStatusEffect val5 = new CustomStatusEffect(val3, false); ItemManager.Instance.AddStatusEffect(val5); BiomeEffects[prefabName] = val5.StatusEffect; switch (prefabName) { case "MR_SylvianRing": case "MR_DreadfulRing": case "MR_WindMasterRing": case "MR_LichKingRing": { SE_Stats val6 = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val6).name = "SE_" + prefabName + "_Permanent"; ((StatusEffect)val6).m_name = prefabName switch { "MR_WindMasterRing" => "$mr_wind_perm_name", "MR_DreadfulRing" => "$mr_dread_perm_name", "MR_SylvianRing" => "$mr_sylvian_perm_name", _ => "$mr_lich_perm_name", }; ((StatusEffect)val6).m_tooltip = prefabName switch { "MR_WindMasterRing" => "$mr_wind_perm", "MR_DreadfulRing" => "$mr_dread_perm", "MR_SylvianRing" => "$mr_sylvian_perm", _ => "$mr_lich_perm", }; ((StatusEffect)val6).m_icon = val2; val6.m_mods = new List<DamageModPair>(); switch (prefabName) { case "MR_DreadfulRing": val6.m_mods.Add(new DamageModPair { m_type = (DamageType)256, m_modifier = (DamageModifier)5 }); break; case "MR_WindMasterRing": val6.m_mods.Add(new DamageModPair { m_type = (DamageType)64, m_modifier = (DamageModifier)5 }); break; case "MR_LichKingRing": val6.m_mods.Add(new DamageModPair { m_type = (DamageType)32, m_modifier = (DamageModifier)5 }); break; } CustomStatusEffect val7 = new CustomStatusEffect((StatusEffect)(object)val6, false); ItemManager.Instance.AddStatusEffect(val7); component.m_itemData.m_shared.m_equipStatusEffect = val7.StatusEffect; break; } } ItemManager.Instance.AddItem(new CustomItem(val, false)); DiagnosticLog(string.Concat("MasterRing item registered: ", prefabName, ", value=", component.m_itemData.m_shared.m_value, ", type=", component.m_itemData.m_shared.m_itemType, ", world model source=AmberPearl")); List<RequirementConfig> list = new List<RequirementConfig>(); list.Add(r1); list.Add(r2); list.Add(r3); List<RequirementConfig> list2 = list; if (r4 != null) { list2.Add(r4); } ItemManager instance = ItemManager.Instance; RecipeConfig val8 = new RecipeConfig(); val8.Name = "Recipe_" + prefabName; val8.Item = prefabName; val8.Amount = 1; val8.CraftingStation = "piece_workbench"; val8.MinStationLevel = stationLevel; val8.Requirements = list2.ToArray(); instance.AddRecipe(new CustomRecipe(val8)); } private Sprite LoadEmbeddedIcon(string file) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (Application.isBatchMode) { return null; } if (SpriteCache.TryGetValue(file, out var value)) { return value; } string value2 = ".icons." + file; string text = null; string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith(value2, StringComparison.OrdinalIgnoreCase)) { text = text2; break; } } if (text == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Missing embedded icon: " + file)); return null; } using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(val, memoryStream.ToArray(), true); ((Object)val).name = file; ((Texture)val).filterMode = (FilterMode)(!file.EndsWith("Effect.png", StringComparison.OrdinalIgnoreCase)); Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); SpriteCache[file] = val2; return val2; } internal static string PrefabNameOf(GameObject go) { if ((Object)(object)go == (Object)null) { return string.Empty; } string text = ((Object)go).name ?? string.Empty; if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - "(Clone)".Length); } return text; } internal static void InvalidateLocalEquipmentCache(Player p) { if ((Object)(object)p == (Object)null || (Object)(object)p == (Object)(object)Player.m_localPlayer) { localRingCacheValid = false; } } internal static string EquippedMasterRing(Player p) { if ((Object)(object)p == (Object)null) { return null; } if ((Object)(object)p != (Object)(object)Player.m_localPlayer) { return RingPrefabOf(MasterRingExclusivity.FindEquippedRing(p)); } if (!localRingCacheValid || (Object)(object)cachedLocalPlayer != (Object)(object)p) { cachedLocalPlayer = p; cachedLocalRing = RingPrefabOf(MasterRingExclusivity.FindEquippedRing(p)); localRingCacheValid = true; } return cachedLocalRing; } internal static bool HasRing(Player p, string prefab) { return string.Equals(EquippedMasterRing(p), prefab, StringComparison.Ordinal); } internal static string RingPrefabOf(ItemData item) { if (item != null && !((Object)(object)item.m_dropPrefab == (Object)null)) { return PrefabNameOf(item.m_dropPrefab); } return string.Empty; } internal static bool IsMasterRing(ItemData item) { return MasterRingPrefabs.Contains(RingPrefabOf(item)); } internal static Biome Biome(Player p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)p == (Object)null)) { return p.GetCurrentBiome(); } return (Biome)0; } internal static bool CorrectBiome(Player p, string ring) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 Biome val = Biome(p); if ((!(ring == "MR_MeadowsLordRing") || (int)val != 1) && (!(ring == "MR_SylvianRing") || (int)val != 8) && (!(ring == "MR_DreadfulRing") || (int)val != 2) && (!(ring == "MR_WindMasterRing") || (int)val != 4)) { if (ring == "MR_LichKingRing") { return (int)val == 16; } return false; } return true; } internal static string EquippedBiomeRing(Player p) { string text = EquippedMasterRing(p); if (text == null || !CorrectBiome(p, text)) { return null; } return text; } internal static bool OnConstructedOrPath(Player p) { if ((Object)(object)p == (Object)(object)Player.m_localPlayer) { return cachedLocalConstructedOrPath; } return ComputeConstructedOrPath(p); } private static bool ComputeConstructedOrPath(Player p) { string surface; return ComputeConstructedOrPath(p, out surface); } private static bool ComputeConstructedOrPath(Player p, out string surface) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) surface = "Unknown"; if ((Object)(object)p == (Object)null) { return false; } Collider val = ((Character)p).GetLastGroundCollider(); Vector3 val2 = ((Component)p).transform.position; RaycastHit val3 = default(RaycastHit); if ((Object)(object)val == (Object)null && Physics.Raycast(((Component)p).transform.position + Vector3.up * 0.4f, Vector3.down, ref val3, 1.4f, -5, (QueryTriggerInteraction)1)) { val = ((RaycastHit)(ref val3)).collider; val2 = ((RaycastHit)(ref val3)).point; } if ((Object)(object)val == (Object)null) { return false; } Piece componentInParent = ((Component)val).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent != (Object)null) { surface = "Built:" + PrefabNameOf(((Component)componentInParent).gameObject); return true; } Heightmap val4 = ((Component)val).GetComponent<Heightmap>(); if ((Object)(object)val4 == (Object)null) { val4 = ((Component)val).GetComponentInParent<Heightmap>(); } if ((Object)(object)val4 == (Object)null) { surface = "Natural:" + ((Object)val).name; return false; } float num = 0f; float num2 = 0f; int num3 = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { Color paintMask = val4.GetPaintMask(val2 + new Vector3((float)j, 0f, (float)i)); num += paintMask.r; num2 += paintMask.b; num3++; } } num /= (float)num3; num2 /= (float)num3; if (num2 > 0.4f) { surface = "Paved"; return true; } if (num > 0.4f) { surface = "DirtPath"; return true; } surface = "Natural"; return false; } private static MasterRingRuntimeCache CacheOf(Character c) { if ((Object)(object)c == (Object)null) { return null; } MasterRingRuntimeCache masterRingRuntimeCache = ((Component)c).GetComponent<MasterRingRuntimeCache>(); if ((Object)(object)masterRingRuntimeCache == (Object)null) { masterRingRuntimeCache = ((Component)c).gameObject.AddComponent<MasterRingRuntimeCache>(); } if (!masterRingRuntimeCache.KindInitialized) { string text = PrefabNameOf(((Component)c).gameObject).ToLowerInvariant(); masterRingRuntimeCache.Greydwarf = text.Contains("greydwarf") || text.Contains("greyling"); masterRingRuntimeCache.Skeleton = !text.Contains("brenna") && text.Contains("skeleton"); masterRingRuntimeCache.KindInitialized = true; } return masterRingRuntimeCache; } internal static bool IsGreydwarf(Character c) { MasterRingRuntimeCache masterRingRuntimeCache = CacheOf(c); if ((Object)(object)masterRingRuntimeCache != (Object)null) { return masterRingRuntimeCache.Greydwarf; } return false; } internal static bool IsMeadowsAnimal(Character c) { if ((Object)(object)c == (Object)null) { return false; } string text = PrefabNameOf(((Component)c).gameObject).ToLowerInvariant(); if (!text.Contains("deer") && !text.Contains("boar") && !text.Contains("neck")) { return text.Contains("greyling"); } return true; } internal static bool IsSkeleton(Character c) { MasterRingRuntimeCache masterRingRuntimeCache = CacheOf(c); if ((Object)(object)masterRingRuntimeCache != (Object)null) { return masterRingRuntimeCache.Skeleton; } return false; } private static void CacheZdoMethods(object zdo) { if (zdo != null && !(cachedZdoType == zdo.GetType())) { cachedZdoType = zdo.GetType(); zdoSetBool = AccessTools.Method(cachedZdoType, "Set", new Type[2] { typeof(string), typeof(bool) }, (Type[])null); zdoSetLong = AccessTools.Method(cachedZdoType, "Set", new Type[2] { typeof(string), typeof(long) }, (Type[])null); zdoSetFloat = AccessTools.Method(cachedZdoType, "Set", new Type[2] { typeof(string), typeof(float) }, (Type[])null); zdoGetBool = AccessTools.Method(cachedZdoType, "GetBool", new Type[2] { typeof(string), typeof(bool) }, (Type[])null); zdoGetLong = AccessTools.Method(cachedZdoType, "GetLong", new Type[2] { typeof(string), typeof(long) }, (Type[])null); zdoGetFloat = AccessTools.Method(cachedZdoType, "GetFloat", new Type[2] { typeof(string), typeof(float) }, (Type[])null); } } internal static object CharacterZdo(Character c) { if ((Object)(object)c == (Object)null) { return null; } try { object obj = ((CharacterNViewField == null) ? null : CharacterNViewField.GetValue(c)); if (obj == null) { return null; } if (cachedViewType != obj.GetType()) { cachedViewType = obj.GetType(); getZdoMethod = AccessTools.Method(cachedViewType, "GetZDO", Type.EmptyTypes, (Type[])null); } return (getZdoMethod == null) ? null : getZdoMethod.Invoke(obj, null); } catch { return null; } } internal static void SetZdo(object zdo, string key, bool value) { CacheZdoMethods(zdo); if (zdoSetBool != null) { zdoSetBool.Invoke(zdo, new object[2] { key, value }); } } internal static void SetZdo(object zdo, string key, long value) { CacheZdoMethods(zdo); if (zdoSetLong != null) { zdoSetLong.Invoke(zdo, new object[2] { key, value }); } } internal static void SetZdo(object zdo, string key, float value) { CacheZdoMethods(zdo); if (zdoSetFloat != null) { zdoSetFloat.Invoke(zdo, new object[2] { key, value }); } } internal static bool GetZdoBool(object zdo, string key, bool fallback) { CacheZdoMethods(zdo); if (!(zdoGetBool == null)) { return (bool)zdoGetBool.Invoke(zdo, new object[2] { key, fallback }); } return fallback; } internal static long GetZdoLong(object zdo, string key, long fallback) { CacheZdoMethods(zdo); if (!(zdoGetLong == null)) { return (long)zdoGetLong.Invoke(zdo, new object[2] { key, fallback }); } return fallback; } internal static float GetZdoFloat(object zdo, string key, float fallback) { CacheZdoMethods(zdo); if (!(zdoGetFloat == null)) { return (float)zdoGetFloat.Invoke(zdo, new object[2] { key, fallback }); } return fallback; } internal static bool IsPlayerOrTamed(Character c) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c == (Object)null) { return false; } if (c is Player) { return true; } if ((int)c.GetFaction() == 0) { return true; } if (IsGreydwarf(c) && GreydwarfPeacePatch.SylvianAuraCovers(c)) { return true; } return c.IsTamed(); } internal static void SetBoundSkeletonNetworkFlag(Character c, bool value) { object zdo = CharacterZdo(c); SetZdo(zdo, "MR_BoundSkeleton", value); } internal static bool IsBoundSkeleton(Character c) { if ((Object)(object)c == (Object)null || !IsSkeleton(c)) { return false; } if (BoundSkeletons.ContainsKey(((Object)c).GetInstanceID())) { return true; } MasterRingRuntimeCache masterRingRuntimeCache = CacheOf(c); if ((Object)(object)masterRingRuntimeCache != (Object)null && Time.time < masterRingRuntimeCache.BoundValidUntil) { return masterRingRuntimeCache.Bound; } object zdo = CharacterZdo(c); bool zdoBool = GetZdoBool(zdo, "MR_BoundSkeleton", fallback: false); if ((Object)(object)masterRingRuntimeCache != (Object)null) { masterRingRuntimeCache.Bound = zdoBool; masterRingRuntimeCache.BoundValidUntil = Time.time + 0.25f; } return zdoBool; } internal static bool IsLichSkeleton(Character c) { object zdo = CharacterZdo(c); if (IsSkeleton(c)) { return GetZdoBool(zdo, "MR_LichSkeleton", fallback: false); } return false; } internal static long NetworkNowTicks() { if (!((Object)(object)ZNet.instance != (Object)null)) { return DateTime.UtcNow.Ticks; } return ZNet.instance.GetTime().Ticks; } internal static void BindSkeleton(Character c, Player followPlayer, float duration, bool lichRaised, float lichDamage) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)c == (Object)null) { return; } c.m_faction = (Faction)0; object obj = CharacterZdo(c); long value = NetworkNowTicks() + TimeSpan.FromSeconds(duration).Ticks; if (obj != null) { SetZdo(obj, "MR_BoundSkeleton", value: true); SetZdo(obj, "MR_BoundSkeletonExpiry", value); SetZdo(obj, "MR_LichSkeleton", lichRaised); if (lichRaised) { SetZdo(obj, "MR_LichSkeletonDamage", lichDamage); } } BaseAI baseAI = c.GetBaseAI(); if ((Object)(object)baseAI != (Object)null && (Object)(object)followPlayer != (Object)null) { MethodInfo methodInfo = AccessTools.Method(((object)baseAI).GetType(), "SetFollowTarget", new Type[1] { typeof(GameObject) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(baseAI, new object[1] { ((Component)followPlayer).gameObject }); } } BoundSkeletons[((Object)c).GetInstanceID()] = Time.time + duration; BoundSkeletonCharacters[((Object)c).GetInstanceID()] = c; MasterRingRuntimeCache masterRingRuntimeCache = CacheOf(c); if ((Object)(object)masterRingRuntimeCache != (Object)null) { masterRingRuntimeCache.BoundValidUntil = 0f; } } internal static float LichSkeletonDamage(Character c) { object zdo = CharacterZdo(c); return GetZdoFloat(zdo, "MR_LichSkeletonDamage", 0f); } private static void SetBiomeStatusEffect(Player p, string ring, bool active) { if ((Object)(object)p == (Object)null || !BiomeEffects.ContainsKey(ring)) { return; } StatusEffect val = BiomeEffects[ring]; int num = val.NameHash(); SEMan sEMan = ((Character)p).GetSEMan(); if (sEMan == null) { return; } if (active) { if (sEMan.HaveStatusEffect(num)) { return; } MethodInfo[] methods = typeof(SEMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "AddStatusEffect") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType != typeof(int)) { continue; } object[] array = new object[parameters.Length]; array[0] = num; for (int j = 1; j < parameters.Length; j++) { if (parameters[j].ParameterType == typeof(bool)) { array[j] = false; } else if (parameters[j].ParameterType == typeof(int)) { array[j] = 0; } else if (parameters[j].ParameterType == typeof(float)) { array[j] = 0f; } else { array[j] = null; } } methodInfo.Invoke(sEMan, array); break; } } else if (sEMan.HaveStatusEffect(num)) { sEMan.RemoveStatusEffect(num, false); } } private static void PublishSylvianAura(Player p) { if (!((Object)(object)p == (Object)null)) { object zdo = CharacterZdo((Character)(object)p); SetZdo(zdo, "MR_SylvianAura", HasRing(p, "MR_SylvianRing")); } } private static void PublishLichEquipped(Player p) { object zdo = CharacterZdo((Character)(object)p); SetZdo(zdo, "MR_LichEquipped", HasRing(p, "MR_LichKingRing")); } internal static bool HasPublishedSylvianAura(Player p) { if ((Object)(object)p == (Object)null) { return false; } if ((Object)(object)p == (Object)(object)Player.m_localPlayer) { return HasRing(p, "MR_SylvianRing"); } MasterRingRuntimeCache masterRingRuntimeCache = CacheOf((Character)(object)p); if ((Object)(object)masterRingRuntimeCache != (Object)null && Time.time < masterRingRuntimeCache.AuraValidUntil) { return masterRingRuntimeCache.Aura; } bool zdoBool = GetZdoBool(CharacterZdo((Character)(object)p), "MR_SylvianAura", fallback: false); if ((Object)(object)masterRingRuntimeCache != (Object)null) { masterRingRuntimeCache.Aura = zdoBool; masterRingRuntimeCache.AuraValidUntil = Time.time + 0.2f; } return zdoBool; } internal static bool HasPublishedLichRing(Player p) { if ((Object)(object)p == (Object)null) { return false; } if ((Object)(object)p == (Object)(object)Player.m_localPlayer) { return HasRing(p, "MR_LichKingRing"); } MasterRingRuntimeCache masterRingRuntimeCache = CacheOf((Character)(object)p); if ((Object)(object)masterRingRuntimeCache != (Object)null && Time.time < masterRingRuntimeCache.LichRingValidUntil) { return masterRingRuntimeCache.LichRing; } bool zdoBool = GetZdoBool(CharacterZdo((Character)(object)p), "MR_LichEquipped", fallback: false); if ((Object)(object)masterRingRuntimeCache != (Object)null) { masterRingRuntimeCache.LichRing = zdoBool; masterRingRuntimeCache.LichRingValidUntil = Time.time + 0.2f; } return zdoBool; } private void UpdateBiomeEffects(Player p) { if (!((Object)(object)p == (Object)null)) { string text = EquippedBiomeRing(p); SetBiomeStatusEffect(p, "MR_MeadowsLordRing", text == "MR_MeadowsLordRing"); SetBiomeStatusEffect(p, "MR_SylvianRing", text == "MR_SylvianRing"); SetBiomeStatusEffect(p, "MR_DreadfulRing", text == "MR_DreadfulRing"); SetBiomeStatusEffect(p, "MR_WindMasterRing", text == "MR_WindMasterRing"); SetBiomeStatusEffect(p, "MR_LichKingRing", text == "MR_LichKingRing"); } } private void ProcessBoundSkeletonExpiry() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) long num = NetworkNowTicks(); List<int> list = new List<int>(BoundSkeletonCharacters.Keys); for (int i = 0; i < list.Count; i++) { int key = list[i]; if (!BoundSkeletonCharacters.TryGetValue(key, out var value) || (Object)(object)value == (Object)null || value.IsDead()) { BoundSkeletonCharacters.Remove(key); BoundSkeletons.Remove(key); continue; } object zdo = CharacterZdo(value); long zdoLong = GetZdoLong(zdo, "MR_BoundSkeletonExpiry", 0L); float value2; bool flag = BoundSkeletons.TryGetValue(key, out value2) && Time.time >= value2; if ((zdoLong <= 0 || num < zdoLong) && !flag) { continue; } BoundSkeletons.Remove(key); BoundSkeletonCharacters.Remove(key); MasterRingRuntimeCache masterRingRuntimeCache = CacheOf(value); if ((Object)(object)masterRingRuntimeCache != (Object)null) { masterRingRuntimeCache.Bound = false; masterRingRuntimeCache.BoundValidUntil = Time.time + 0.25f; } if (value.IsOwner() && !value.IsDead()) { bool flag2 = IsLichSkeleton(value); HitData val = new HitData(); val.m_damage.m_damage = 1000000f; val.m_point = ((Component)value).transform.position; value.Damage(val); if (flag2) { DiagnosticLog("Lich King: resurrected Skeleton expired after 30 seconds."); } } } } private void DiscoverBoundSkeletons() { foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && IsSkeleton(allCharacter) && IsBoundSkeleton(allCharacter)) { BoundSkeletonCharacters[((Object)allCharacter).GetInstanceID()] = allCharacter; } } } private void Update() { //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && Time.time >= nextBiomeEffectCheck) { nextBiomeEffectCheck = Time.time + 0.2f; if (Localization.instance != null && !string.Equals(appliedLanguage, Localization.instance.GetSelectedLanguage(), StringComparison.OrdinalIgnoreCase)) { ApplyLocalization(); } InvalidateLocalEquipmentCache(localPlayer); EquippedMasterRing(localPlayer); string text = EquippedBiomeRing(localPlayer); string surface; if (text == null) { surface = "Inactive"; cachedLocalConstructedOrPath = false; } else { cachedLocalConstructedOrPath = ComputeConstructedOrPath(localPlayer, out surface); } if (!string.Equals(cachedLocalSurface, surface, StringComparison.Ordinal)) { cachedLocalSurface = surface; DiagnosticLog("[DIAG] GroundDetection surface=" + surface + " speedBonus=" + !cachedLocalConstructedOrPath + " ring=" + (EquippedMasterRing(localPlayer) ?? "none") + " biome=" + Biome(localPlayer)); } PublishSylvianAura(localPlayer); PublishLichEquipped(localPlayer); UpdateBiomeEffects(localPlayer); } if (Time.time >= nextBoundDiscoveryScan) { nextBoundDiscoveryScan = Time.time + 1f; DiscoverBoundSkeletons(); } if (Time.time >= nextBoundExpiryScan) { nextBoundExpiryScan = Time.time + 0.25f; ProcessBoundSkeletonExpiry(); } if ((Object)(object)localPlayer != (Object)null && Time.time >= nextExclusivityCheck) { nextExclusivityCheck = Time.time + 0.5f; MasterRingExclusivity.Enforce(localPlayer); } if (Time.time >= nextNecromancyCleanup) { nextNecromancyCleanup = Time.time + 10f; LichNecromancy.CleanupExpired(); } if ((Object)(object)localPlayer == (Object)null || !HasRing(localPlayer, "MR_DreadfulRing") || Time.time < nextSkeletonScan) { return; } nextSkeletonScan = Time.time + 0.5f; foreach (Character allCharacter in Character.GetAllCharacters()) { if ((Object)(object)allCharacter == (Object)null) { continue; } Vector3 val = ((Component)allCharacter).transform.position - ((Component)localPlayer).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 400f || !IsSkeleton(allCharacter)) { continue; } ((Object)allCharacter).GetInstanceID(); if (!IsBoundSkeleton(allCharacter)) { try { BindSkeleton(allCharacter, localPlayer, 30f, lichRaised: false, 0f); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Skeleton bind failed: " + ex.Message)); } } } } internal static void ApplyLocalization() { if (Localization.instance == null) { return; } appliedLanguage = Localization.instance.GetSelectedLanguage(); Dictionary<string, string> dictionary = (string.Equals(appliedLanguage, "French", StringComparison.OrdinalIgnoreCase) ? French : English); MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "AddWord", new Type[2] { typeof(string), typeof(string) }, (Type[])null); if (methodInfo == null) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)"Localization.AddWord not found; Master Rings localization was not injected."); } return; } foreach (KeyValuePair<string, string> item in dictionary) { methodInfo.Invoke(Localization.instance, new object[2] { item.Key, item.Value }); } } } internal static class MasterRingExclusivity { private static readonly Dictionary<int, ItemData> LastRequested = new Dictionary<int, ItemData>(); private static readonly Dictionary<int, List<ItemData>> KnownEquipped = new Dictionary<int, List<ItemData>>(); private static bool changing; private static List<ItemData> GetCandidates(Player player) { List<ItemData> list = new List<ItemData>(); foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems()) { if (MasterRingsPlugin.IsMasterRing(equippedItem) && !list.Contains(equippedItem)) { list.Add(equippedItem); } } if (KnownEquipped.TryGetValue(((Object)player).GetInstanceID(), out var value)) { foreach (ItemData item in value) { if (item != null && ((Humanoid)player).IsItemEquiped(item) && MasterRingsPlugin.IsMasterRing(item) && !list.Contains(item)) { list.Add(item); } } } return list; } internal static ItemData FindEquippedRing(Player player) { if ((Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null) { return null; } List<ItemData> candidates = GetCandidates(player); if (candidates.Count == 0) { return null; } if (LastRequested.TryGetValue(((Object)player).GetInstanceID(), out var value) && candidates.Contains(value)) { return value; } return candidates[candidates.Count - 1]; } internal static void PrepareEquip(Player player, ItemData requested) { if (changing || (Object)(object)player == (Object)null || !MasterRingsPlugin.IsMasterRing(requested)) { return; } MasterRingsPlugin.InvalidateLocalEquipmentCache(player); LastRequested[((Object)player).GetInstanceID()] = requested; MasterRingsPlugin.DiagnosticLog("MasterRing equip requested: " + MasterRingsPlugin.RingPrefabOf(requested)); changing = true; try { List<ItemData> candidates = GetCandidates(player); foreach (ItemData item in candidates) { if (item != requested && MasterRingsPlugin.IsMasterRing(item)) { ((Humanoid)player).UnequipItem(item, false); MasterRingsPlugin.DiagnosticLog("MasterRing exclusivity: unequipped " + MasterRingsPlugin.RingPrefabOf(item)); } } } finally { changing = false; } } internal static void RecordEquipped(Player player, ItemData item, bool succeeded) { if (!succeeded || (Object)(object)player == (Object)null || !MasterRingsPlugin.IsMasterRing(item)) { return; } MasterRingsPlugin.InvalidateLocalEquipmentCache(player); if (string.Equals(MasterRingsPlugin.RingPrefabOf(item), "MR_DreadfulRing", StringComparison.Ordinal)) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null && sEMan.HaveStatusEffect(SEMan.s_statusEffectWet)) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectWet, false); } } if (!KnownEquipped.TryGetValue(((Object)player).GetInstanceID(), out var value)) { value = new List<ItemData>(); KnownEquipped[((Object)player).GetInstanceID()] = value; } if (!value.Contains(item)) { value.Add(item); } } internal static void RecordUnequipped(Player player, ItemData item) { if (!((Object)(object)player == (Object)null) && item != null) { MasterRingsPlugin.InvalidateLocalEquipmentCache(player); if (KnownEquipped.TryGetValue(((Object)player).GetInstanceID(), out var value)) { value.Remove(item); } } } internal static void Enforce(Player player) { if (changing || (Object)(object)player == (Object)null || ((Humanoid)player).GetInventory() == null) { return; } List<ItemData> candidates = GetCandidates(player); if (candidates.Count <= 1) { return; } ItemData value = null; LastRequested.TryGetValue(((Object)player).GetInstanceID(), out value); if (value == null || !candidates.Contains(value)) { value = candidates[candidates.Count - 1]; } changing = true; try { foreach (ItemData item in candidates) { if (item != value) { ((Humanoid)player).UnequipItem(item, false); MasterRingsPlugin.DiagnosticLog("MasterRing invalid state repaired: unequipped " + MasterRingsPlugin.RingPrefabOf(item)); } } } finally { changing = false; } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class MasterRingEquipPatch { private static void Prefix(Humanoid __instance, ItemData item) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val != (Object)null) { MasterRingExclusivity.PrepareEquip(val, item); } } private static void Postfix(Humanoid __instance, ItemData item, bool __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val != (Object)null) { MasterRingExclusivity.RecordEquipped(val, item, __result); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class MasterRingUnequipPatch { private static void Postfix(Humanoid __instance, ItemData item) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val != (Object)null) { MasterRingExclusivity.RecordUnequipped(val, item); } } } internal static class StaminaDiagnostics { private static readonly Dictionary<string, float> NextLog = new Dictionary<string, float>(); internal static void Log(string action, float baseCost, float finalCost, Player player) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !((Object)(object)MasterRingsPlugin.Instance == (Object)null) && (!NextLog.TryGetValue(action, out var value) || !(Time.time < value))) { NextLog[action] = Time.time + 2f; string text = MasterRingsPlugin.EquippedBiomeRing(player); MasterRingsPlugin.DiagnosticLog(string.Concat("[DIAG] STAMINA action=", action, " baseCost=", baseCost.ToString("0.###"), " finalCost=", finalCost.ToString("0.###"), " ring=", text ?? "none", " biome=", MasterRingsPlugin.Biome(player), " multiplier=0.90")); } } } [HarmonyPatch] internal static class JogSpeedPatch { private static float nextDiag; private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Player), "GetJogSpeedFactor", (Type[])null, (Type[])null); } private static void Postfix(Player __instance, ref float __result) { if (MasterRingsPlugin.EquippedBiomeRing(__instance) != null && !MasterRingsPlugin.OnConstructedOrPath(__instance)) { float num = __result; __result *= 1.1f; if (Time.time >= nextDiag && (Object)(object)MasterRingsPlugin.Instance != (Object)null) { nextDiag = Time.time + 2f; MasterRingsPlugin.DiagnosticLog("[DIAG] Jog speed factor " + num.ToString("0.###") + " -> " + __result.ToString("0.###") + " (x1.10)"); } } } } [HarmonyPatch] internal static class RunSpeedPatch { private static float nextDiag; private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Player), "GetRunSpeedFactor", (Type[])null, (Type[])null); } private static void Postfix(Player __instance, ref float __result) { if (MasterRingsPlugin.EquippedBiomeRing(__instance) != null && !MasterRingsPlugin.OnConstructedOrPath(__instance)) { float num = __result; __result *= 1.1f; if (Time.time >= nextDiag && (Object)(object)MasterRingsPlugin.Instance != (Object)null) { nextDiag = Time.time + 2f; MasterRingsPlugin.DiagnosticLog("[DIAG] Run speed factor " + num.ToString("0.###") + " -> " + __result.ToString("0.###") + " (x1.10)"); } } } } [HarmonyPatch(typeof(Skills), "GetSkillLevel")] internal static class SkillPatch { private static void Postfix(SkillType skillType, ref float __result) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { if ((int)skillType == 107 && MasterRingsPlugin.HasRing(localPlayer, "MR_MeadowsLordRing") && MasterRingsPlugin.CorrectBiome(localPlayer, "MR_MeadowsLordRing")) { __result += 20f; } if ((int)skillType == 106 && MasterRingsPlugin.HasRing(localPlayer, "MR_SylvianRing") && MasterRingsPlugin.CorrectBiome(localPlayer, "MR_SylvianRing")) { __result += 20f; } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class DamagePatch { private static bool Prefix(Character __instance, HitData hit) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (hit == null) { return true; } Character attacker = hit.GetAttacker(); if (MasterRingsPlugin.IsBoundSkeleton(attacker) && MasterRingsPlugin.IsPlayerOrTamed(__instance)) { return false; } if (MasterRingsPlugin.IsLichSkeleton(attacker)) { float num = MasterRingsPlugin.LichSkeletonDamage(attacker); if (num > 0f) { hit.m_damage = default(DamageTypes); hit.m_damage.m_damage = num; } } Player val = (Player)(object)((attacker is Player) ? attacker : null); if ((Object)(object)val != (Object)null && MasterRingsPlugin.HasRing(val, "MR_MeadowsLordRing") && MasterRingsPlugin.CorrectBiome(val, "MR_MeadowsLordRing") && MasterRingsPlugin.IsMeadowsAnimal(__instance)) { ((DamageTypes)(ref hit.m_damage)).Modify(1.2f); } return true; } } [HarmonyPatch] internal static class LichTarSlowdownPatch { private static float nextDiag; private static IEnumerable<MethodBase> TargetMethods() { MethodInfo baseMethod = AccessTools.Method(typeof(StatusEffect), "ModifySpeed", (Type[])null, (Type[])null); if (baseMethod != null) { yield return baseMethod; } MethodInfo statsMethod = AccessTools.Method(typeof(SE_Stats), "ModifySpeed", (Type[])null, (Type[])null); if (statsMethod != null) { yield return statsMethod; } } private static bool Prefix(StatusEffect __instance) { Character character = __instance.m_character; Player val = (Player)(object)((character is Player) ? character : null); if ((Object)(object)val == (Object)null || !MasterRingsPlugin.HasRing(val, "MR_LichKingRing") || !MasterRingsPlugin.CorrectBiome(val, "MR_LichKingRing")) { return true; } string text = (((Object)__instance).name ?? string.Empty).ToLowerInvariant(); string text2 = (__instance.m_name ?? string.Empty).ToLowerInvariant(); bool flag = text == "tared" || text2 == "$se_tared" || text.Contains("tared"); if (flag && Time.time >= nextDiag) { nextDiag = Time.time + 2f; MasterRingsPlugin.DiagnosticLog("[DIAG] TARED attempt LichKing=true biome=Plains result=slowdown-neutralized"); } return !flag; } } internal static class LichNecromancy { private sealed class DeathContext { internal Player Killer; internal float VictimMaxHealth; internal Vector3 DeathPoint; internal string VictimPrefab; internal float CapturedAt; } private static readonly Dictionary<int, DeathContext> LastDamage = new Dictionary<int, DeathContext>(); private static readonly HashSet<string> ResurrectionWhitelist = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Greyling", "Greydwarf", "Greydwarf_Elite", "Greydwarf_Shaman", "Draugr", "Draugr_Ranged", "Draugr_Elite", "Fenring", "Fenring_Cultist", "Goblin", "GoblinArcher", "GoblinShaman", "Dverger", "DvergerMage" }; internal static void RecordDamage(Character victim, HitData hit) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)victim == (Object)null) && hit != null) { int instanceID = ((Object)victim).GetInstanceID(); string text = MasterRingsPlugin.PrefabNameOf(((Component)victim).gameObject); Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (AbsoluteExclusion(text) || !ResurrectionWhitelist.Contains(text) || (Object)(object)val == (Object)null || !MasterRingsPlugin.HasPublishedLichRing(val)) { LastDamage.Remove(instanceID); return; } LastDamage[instanceID] = new DeathContext { Killer = val, VictimMaxHealth = victim.GetMaxHealth(), DeathPoint = ((Component)victim).transform.position, VictimPrefab = text, CapturedAt = Time.time }; } } internal static void CleanupExpired() { if (LastDamage.Count == 0) { return; } List<int> list = new List<int>(); foreach (KeyValuePair<int, DeathContext> item in LastDamage) { if (Time.time - item.Value.CapturedAt > 30f || (Object)(object)item.Value.Killer == (Object)null) { list.Add(item.Key); } } for (int i = 0; i < list.Count; i++) { LastDamage.Remove(list[i]); } } private static bool AbsoluteExclusion(string prefab) { string text = (prefab ?? string.Empty).ToLowerInvariant(); if (!text.Contains("skeleton") && !text.Contains("brenna") && !text.Contains("troll")) { return text.Contains("goblinbrute"); } return true; } private static float DamageForBiome(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if ((int)biome == 8) { return 35f; } if ((int)biome == 2) { return 55f; } if ((int)biome == 4) { return 75f; } if ((int)biome == 16) { return 95f; } if ((int)biome == 512) { return 115f; } return 15f; } internal static void TryRaise(Character victim) { //IL_014a: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)victim == (Object)null || victim.GetHealth() > 0f || !victim.IsOwner() || !LastDamage.TryGetValue(((Object)victim).GetInstanceID(), out var value)) { return; } LastDamage.Remove(((Object)victim).GetInstanceID()); bool flag = AbsoluteExclusion(value.VictimPrefab); bool flag2 = !flag && ResurrectionWhitelist.Contains(value.VictimPrefab); string text = (((Object)(object)value.Killer == (Object)null) ? "none" : value.Killer.GetPlayerName()); bool flag3 = (Object)(object)value.Killer != (Object)null && MasterRingsPlugin.HasPublishedLichRing(value.Killer); MasterRingsPlugin.DiagnosticLog("Lich King death: victim=" + value.VictimPrefab + ", whitelist=" + flag2 + ", excluded=" + flag + ", killer=" + text + ", ring=" + flag3); if (!flag2 || !flag3) { return; } object obj = MasterRingsPlugin.CharacterZdo(victim); if (obj == null || MasterRingsPlugin.GetZdoBool(obj, "MR_LichRaised", fallback: false)) { return; } MasterRingsPlugin.SetZdo(obj, "MR_LichRaised", value: true); Biome val = Heightmap.FindBiome(value.DeathPoint); float lichDamage = DamageForBiome(val); GameObject val2 = (((Object)(object)ZNetScene.instance == (Object)null) ? null : ZNetScene.instance.GetPrefab("Skeleton")); if ((Object)(object)val2 == (Object)null) { MasterRingsPlugin.DiagnosticLog("Lich King spawn failed: vanilla prefab Skeleton was not found."); return; } GameObject val3 = Object.Instantiate<GameObject>(val2, value.DeathPoint + Vector3.up * 0.1f, Quaternion.identity); Character val4 = (((Object)(object)val3 == (Object)null) ? null : val3.GetComponent<Character>()); if ((Object)(object)val4 == (Object)null) { MasterRingsPlugin.DiagnosticLog("Lich King spawn failed: spawned Skeleton has no Character component."); return; } float num = Mathf.Max(1f, value.VictimMaxHealth); val4.SetMaxHealth(num); val4.SetHealth(num); MasterRingsPlugin.BindSkeleton(val4, value.Killer, 30f, lichRaised: true, lichDamage); MasterRingsPlugin.DiagnosticLog(string.Concat("Lich King raised Skeleton: victim=", value.VictimPrefab, ", biome=", val, ", maxHP=", num.ToString("0.##"), ", damage=", lichDamage.ToString("0.##"), ", duration=30s")); } } [HarmonyPatch(typeof(Character), "ApplyDamage")] internal static class LichFatalHitCapturePatch { private static void Prefix(Character __instance, HitData hit) { LichNecromancy.RecordDamage(__instance, hit); } } [HarmonyPatch(typeof(Character), "CheckDeath")] internal static class LichDeathPatch { private static void Prefix(Character __instance) { LichNecromancy.TryRaise(__instance); } } internal static class DreadfulWetImmunityPatch { private static readonly Dictionary<int, float> NextDiagnostic = new Dictionary<int, float>(); internal static void Install(Harmony harmony) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown int num = 0; MethodInfo methodInfo = AccessTools.Method(typeof(DreadfulWetImmunityPatch), "Prefix", (Type[])null, (Type[])null); MethodInfo[] methods = typeof(SEMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name != "AddStatusEffect" || methodInfo2.ReturnType != typeof(StatusEffect)) { continue; } ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 0) { continue; } Type parameterType = parameters[0].ParameterType; if (!(parameterType != typeof(string)) || !(parameterType != typeof(int))) { try { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } catch (Exception ex) { MasterRingsPlugin.DiagnosticLog("Dreadful Wet immunity skipped incompatible overload: " + ex.Message); } } } MasterRingsPlugin.DiagnosticLog("Dreadful Wet immunity installed on " + num + " AddStatusEffect overload(s)."); } private static bool Prefix(object[] __args, Character ___m_character, ref StatusEffect __result) { if (__args == null || __args.Length == 0) { return true; } object obj = __args[0]; if (!((obj is int) ? ((int)obj == SEMan.s_statusEffectWet) : string.Equals(obj as string, "Wet", StringComparison.Ordinal))) { return true; } Player val = (Player)(object)((___m_character is Player) ? ___m_character : null); if ((Object)(object)val == (Object)null || !MasterRingsPlugin.HasRing(val, "MR_DreadfulRing")) { return true; } __result = null; int instanceID = ((Object)val).GetInstanceID(); if (!NextDiagnostic.TryGetValue(instanceID, out var value) || Time.time >= value) { NextDiagnostic[instanceID] = Time.time + 10f; MasterRingsPlugin.DiagnosticLog("[DIAG] WET attempt Dreadful=true result=blocked"); } return false; } } [HarmonyPatch] internal static class GreydwarfPeacePatch { private const float AuraRadius = 100f; private const float AuraRadiusSqr = 10000f; private static MethodBase TargetMethod() { MethodInfo[] methods = typeof(BaseAI).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "IsEnemy") && !(methodInfo.ReturnType != typeof(bool))) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Character) && parameters[1].ParameterType == typeof(Character)) { return methodInfo; } } } return null; } internal static bool SylvianAuraCovers(Character greydwarf) { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)greydwarf == (Object)null) { return false; } List<Player> allPlayers = Player.GetAllPlayers(); if (allPlayers == null) { return false; } Vector3 position = ((Component)greydwarf).transform.position; for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if (!((Object)(object)val == (Object)null) && MasterRingsPlugin.HasPublishedSylvianAura(val)) { Vector3 val2 = ((Component)val).transform.position - position; if (((Vector3)(ref val2)).sqrMagnitude <= 10000f) { return true; } } } return false; } private static void Postfix(Character a, Character b, ref bool __result) { if (!__result || (Object)(object)a == (Object)null || (Object)(object)b == (Object)null) { return; } bool flag = MasterRingsPlugin.IsGreydwarf(a); bool flag2 = !flag && MasterRingsPlugin.IsGreydwarf(b); Character val = (flag ? a : (flag2 ? b : null)); Character c = (((Object)(object)val == (Object)(object)a) ? b : a); if ((Object)(object)val != (Object)null && MasterRingsPlugin.IsPlayerOrTamed(c) && SylvianAuraCovers(val)) { __result = false; return; } Character val2 = (MasterRingsPlugin.IsBoundSkeleton(a) ? a : (MasterRingsPlugin.IsBoundSkeleton(b) ? b : null)); Character c2 = (((Object)(object)val2 == (Object)(object)a) ? b : a); if ((Object)(object)val2 != (Object)null && MasterRingsPlugin.IsPlayerOrTamed(c2)) { __result = false; } } } internal static class AlliedBuildingPeace { internal static bool IsAlly(Character character) { if ((Object)(object)character != (Object)null) { if (!MasterRingsPlugin.IsBoundSkeleton(character)) { if (MasterRingsPlugin.IsGreydwarf(character)) { return GreydwarfPeacePatch.SylvianAuraCovers(character); } return false; } return true; } return false; } internal static bool IsPlayerBuilding(Component component) { if ((Object)(object)component == (Object)null) { return false; } Piece componentInParent = component.GetComponentInParent<Piece>(); if ((Object)(object)componentInParent != (Object)null) { return componentInParent.IsPlacedByPlayer(); } return false; } internal static bool AllowDamage(WearNTear building, HitData hit) { if (hit == null || !IsAlly(hit.GetAttacker())) { return true; } return !IsPlayerBuilding((Component)(object)building); } } [HarmonyPatch(typeof(BaseAI), "CanSeeTarget", new Type[] { typeof(StaticTarget) })] internal static class AlliedBuildingSelectionPatch { private static bool Prefix(BaseAI __instance, StaticTarget __0, ref bool __result) { if (!AlliedBuildingPeace.IsAlly(((Component)__instance).GetComponent<Character>()) || !AlliedBuildingPeace.IsPlayerBuilding((Component)(object)__0)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] internal static class AlliedBuildingTargetPatch { private static void Prefix(MonsterAI __instance, ref StaticTarget ___m_targetStatic) { if (AlliedBuildingPeace.IsAlly(((Component)__instance).GetComponent<Character>()) && AlliedBuildingPeace.IsPlayerBuilding((Component)(object)___m_targetStatic)) { ___m_targetStatic = null; } } } [HarmonyPatch(typeof(WearNTear), "Damage")] internal static class AlliedBuildingDamagePatch { private static bool Prefix(WearNTear __instance, HitData hit) { return AlliedBuildingPeace.AllowDamage(__instance, hit); } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] internal static class AlliedBuildingNetworkDamagePatch { private static bool Prefix(WearNTear __instance, HitData hit) { return AlliedBuildingPeace.AllowDamage(__instance, hit); } } internal static class SylvianTreeGift { private static readonly Dictionary<int, string> Pending = new Dictionary<int, string>(); internal static string WantedSeedPrefab(TreeBase tree) { if ((Object)(object)tree == (Object)null) { return null; } string text = MasterRingsPlugin.PrefabNameOf(((Component)tree).gameObject).ToLowerInvariant(); if (text.Contains("beech")) { return "BeechSeeds"; } if (text.Contains("birch")) { return "BirchSeeds"; } if (text.Contains("oak")) { return "Acorn"; } if (text.Contains("fir")) { return "FirCone"; } if (text.Contains("pine")) { return "PineCone"; } return null; } internal static void BeginHit(TreeBase tree, HitData hit) { if ((Object)(object)tree == (Object)null) { return; } int instanceID = ((Object)tree).GetInstanceID(); Pending.Remove(instanceID); if (hit == null) { return; } string text = WantedSeedPrefab(tree); if (text != null) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (!((Object)(object)val == (Object)null) && MasterRingsPlugin.HasPublishedSylvianAura(val)) { Pending[instanceID] = text; } } } internal static void EndHit(TreeBase tree) { if ((Object)(object)tree != (Object)null) { Pending.Remove(((Object)tree).GetInstanceID()); } } internal static void OnSpawnLog(TreeBase tree) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tree == (Object)null) { return; } int instanceID = ((Object)tree).GetInstanceID(); if (!Pending.TryGetValue(instanceID, out var value)) { return; } Pending.Remove(instanceID); try { if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject prefab = ZNetScene.instance.GetPrefab(value); if ((Object)(object)prefab == (Object)null) { MasterRingsPlugin.DiagnosticLog("Sylvian seed prefab not found: " + value); return; } Vector3 val = ((Component)tree).transform.position + Vector3.up * 0.5f; Object.Instantiate<GameObject>(prefab, val, Quaternion.identity); MasterRingsPlugin.DiagnosticLog("Sylvian tree gift on SpawnLog: " + value + " from " + MasterRingsPlugin.PrefabNameOf(((Component)tree).gameObject)); } } catch (Exception ex) { MasterRingsPlugin.DiagnosticLog("Sylvian SpawnLog gift: " + ex.Message); } } } [HarmonyPatch(typeof(TreeBase), "RPC_Damage")] internal static class SylvianTreeHitPatch { private static void Prefix(TreeBase __instance, HitData __1) { SylvianTreeGift.BeginHit(__instance, __1); } private static void Postfix(TreeBase __instance) { SylvianTreeGift.EndHit(__instance); } } [HarmonyPatch(typeof(TreeBase), "SpawnLog")] internal static class SylvianTreeSpawnLogPatch { private static void Prefix(TreeBase __instance) { SylvianTreeGift.OnSpawnLog(__instance); } } [HarmonyPatch(typeof(EnvMan), "GetWindDir")] internal static class WindPatch { private static void Postfix(ref Vector3 __result) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) //IL_009b: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !MasterRingsPlugin.HasRing(localPlayer, "MR_WindMasterRing")) { return; } Ship controlledShip = localPlayer.GetControlledShip(); if (!((Object)(object)controlledShip == (Object)null)) { Vector3 forward = ((Component)controlledShip).transform.forward; forward.y = 0f; if (!(((Vector3)(ref forward)).sqrMagnitude < 0.01f)) { float num = Mathf.Sin(Time.time * 0.12f) * 20f + Mathf.Sin(Time.time * 0.047f) * 10f; __result = Quaternion.Euler(0f, num, 0f) * ((Vector3)(ref forward)).normalized; } } } }