Please disclose if your mod was created primarily 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 Selective Pet Protection v0.2.2
SelectivePetProtection.dll
Decompiled 11 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace SelectivePetProtection { public enum ShieldState { None, Stun, Immortal } public static class ShieldColors { public static Dictionary<ShieldState, string> Colors = new Dictionary<ShieldState, string> { { ShieldState.None, "#FFFFFF" }, { ShieldState.Stun, "#95c9da" }, { ShieldState.Immortal, "#d8bf58" } }; public static void UpdateColors(string stunColor, string immortalColor) { Colors[ShieldState.Stun] = stunColor; Colors[ShieldState.Immortal] = immortalColor; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("magnus.SelectivePetProtection", "SelectivePetProtection", "0.2.2")] public class SelectivePetProtection : BaseUnityPlugin { internal const string ModName = "SelectivePetProtection"; internal const string ModVersion = "0.2.2"; internal const string Author = "magnus"; private const string ModGUID = "magnus.SelectivePetProtection"; public static ManualLogSource Log; public static bool isVikingNPCLoaded = false; private BaseUnityPlugin vikingNPCPlugin; public static Harmony harmony = new Harmony("mod.selective_pet_protection"); private ConfigEntry<int> stunRecoveryTimeConfig; private ConfigEntry<string> stunShieldColorConfig; private ConfigEntry<string> immortalShieldColorConfig; public static float stunRecoveryTime { get; internal set; } = 120f; public static string stunShieldColor { get; internal set; } = "#95c9da"; public static string immortalShieldColor { get; internal set; } = "#d8bf58"; public static ConfigEntry<KeyboardShortcut> ToggleProtectionShortcut { get; set; } private void Start() { Log = ((BaseUnityPlugin)this).Logger; foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { if (pluginInfo.Key == "RustyMods.VikingNPC") { isVikingNPCLoaded = true; vikingNPCPlugin = pluginInfo.Value.Instance; break; } } } private void Awake() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) stunRecoveryTimeConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "StunRecoveryTime", 120, "Time in seconds it takes for a pet to recover from being stunned after receiving a deadly hit"); stunRecoveryTime = stunRecoveryTimeConfig.Value; stunShieldColorConfig = ((BaseUnityPlugin)this).Config.Bind<string>("General", "StunShieldColor", "#95c9da", "Color as hex code of the shield icon that appears when a pet is protected and gets stunned when receiving a deadly hit (equivalent to essential in V+/PetProtection)"); stunShieldColor = stunShieldColorConfig.Value; immortalShieldColorConfig = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ImmortalShieldColor", "#d8bf58", "Color as hex code of the shield icon that appears when a pet is immortal (equivalent to immortal in V+/PetProtection)"); ShieldColors.UpdateColors(stunShieldColorConfig.Value, immortalShieldColorConfig.Value); harmony.PatchAll(); ToggleProtectionShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleProtectionShortcut", new KeyboardShortcut((KeyCode)116, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Toggle the protection of tamed creatures with the shield icon. Press Left Shift + T to toggle."); } } [HarmonyPatch(typeof(Player), "UpdateHover")] public static class Player_UpdateHover_Patch { public static void Postfix(ref Player __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = SelectivePetProtection.ToggleProtectionShortcut.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { return; } GameObject hovering = __instance.m_hovering; Interactable val = ((hovering != null) ? hovering.GetComponentInParent<Interactable>() : null); if (val == null) { return; } GameObject gameObject = __instance.m_hovering.gameObject; Character componentInParent = gameObject.GetComponentInParent<Character>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.IsTamed()) { ZDO zDO = componentInParent.m_nview.GetZDO(); string @string = zDO.GetString(ZDOVars.s_tamedName, ""); string text = StringExtensionMethods.RemoveRichTextTags(@string).Replace("\ud83d\udee1\ufe0f", ""); if (@string.Contains("<color=" + ShieldColors.Colors[ShieldState.Stun] + ">\ud83d\udee1\ufe0f")) { zDO.Set(ZDOVars.s_tamedName, text + "<color=" + ShieldColors.Colors[ShieldState.Immortal] + ">\ud83d\udee1\ufe0f</color>"); } else if (@string.Contains("<color=" + ShieldColors.Colors[ShieldState.Immortal] + ">\ud83d\udee1\ufe0f")) { zDO.Set(ZDOVars.s_tamedName, text); } else { zDO.Set(ZDOVars.s_tamedName, text + "<color=" + ShieldColors.Colors[ShieldState.Stun] + ">\ud83d\udee1\ufe0f</color>"); } componentInParent.m_name = zDO.GetString(ZDOVars.s_tamedName, ""); } } } [HarmonyPatch(typeof(Tameable), "RPC_SetName")] public static class Tameable_RPC_SetName_Patch { public static bool Prefix(ref Tameable __instance, ref string name) { if ((Object)(object)__instance.m_character == (Object)null) { return true; } ZDO zDO = __instance.m_character.m_nview.GetZDO(); string @string = zDO.GetString(ZDOVars.s_tamedName, ""); string text = StringExtensionMethods.RemoveRichTextTags(@string).Replace("\ud83d\udee1\ufe0f", ""); if (name.Equals("!stun")) { zDO.Set(ZDOVars.s_tamedName, text + "<color=" + ShieldColors.Colors[ShieldState.Stun] + ">\ud83d\udee1\ufe0f</color>"); return false; } if (name.Equals("!god")) { zDO.Set(ZDOVars.s_tamedName, text + "<color=" + ShieldColors.Colors[ShieldState.Immortal] + ">\ud83d\udee1\ufe0f</color>"); return false; } if (name.Equals("!none")) { zDO.Set(ZDOVars.s_tamedName, text); return false; } return true; } } [HarmonyPatch(typeof(Tameable), "SetName")] public static class Tameable_SetName_Patch { public static bool Prefix(ref Tameable __instance) { if ((Object)(object)__instance.m_character == (Object)null) { return true; } ZDO zDO = __instance.m_character.m_nview.GetZDO(); string @string = zDO.GetString(ZDOVars.s_tamedName, ""); if (@string.Contains("\ud83d\udee1\ufe0f")) { TextInput.instance.m_queuedSign = (TextReceiver)(object)__instance; TextInput.instance.Show("$hud_rename", StringExtensionMethods.RemoveRichTextTags(@string).Replace("\ud83d\udee1\ufe0f", ""), 10); return false; } return true; } } [HarmonyPatch(typeof(Tameable), "GetHoverName")] public static class Tameable_GetHoverName_Patch { public static void Postfix(ref Tameable __instance, ref string __result) { if (Object.op_Implicit((Object)(object)__instance.m_character)) { ZDO zDO = __instance.m_character.m_nview.GetZDO(); string @string = zDO.GetString(ZDOVars.s_tamedName, ""); if (@string.Contains("\ud83d\udee1\ufe0f</color>")) { __result = @string; } } } } [HarmonyPriority(0)] [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class Character_ApplyDamage_Patch { public static void Postfix(ref Character __instance, ref HitData hit, ref bool showDamageText, ref bool triggerEffects, ref DamageModifier mod) { ZDO zDO = __instance.m_nview.GetZDO(); string @string = zDO.GetString(ZDOVars.s_tamedName, ""); if (__instance.IsTamed() && zDO != null && @string.Contains("\ud83d\udee1\ufe0f") && __instance.GetHealth() <= 5f && ShouldIgnoreDamage(__instance, hit, zDO)) { if (@string.Contains(ShieldColors.Colors[ShieldState.Stun])) { __instance.SetHealth(__instance.GetMaxHealth()); __instance.m_animator.SetBool("sleeping", true); zDO.Set("sleeping", true); zDO.Set("isRecoveringFromStun", true); ((Component)__instance).GetComponent<MonsterAI>().m_sleeping = true; ((BaseAI)((Component)__instance).GetComponent<MonsterAI>()).SetAlerted(false); __instance.m_disableWhileSleeping = true; ((BaseAI)((Component)__instance).GetComponent<MonsterAI>()).m_nview.GetZDO().Set(ZDOVars.s_sleeping, true); } else { __instance.SetHealth(__instance.GetMaxHealth()); } } } private static bool ShouldIgnoreDamage(Character __instance, HitData hit, ZDO zdo) { if (hit == null) { return true; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null) { return true; } return true; } } [HarmonyPatch(typeof(MonsterAI), "UpdateSleep")] public static class MonsterAI_UpdateSleep_Patch { public static bool Prefix(MonsterAI __instance, ref float dt) { if (!((BaseAI)__instance).m_character.IsTamed()) { return true; } ZDO zDO = ((BaseAI)__instance).m_nview.GetZDO(); if (zDO == null || !zDO.GetBool("isRecoveringFromStun", false)) { return true; } if (__instance.m_sleepTimer != 0f) { __instance.m_sleepTimer = 0f; } float num = zDO.GetFloat("timeSinceStun", 0f) + dt; zDO.Set("timeSinceStun", num); if (num >= SelectivePetProtection.stunRecoveryTime) { zDO.Set("timeSinceStun", 0f); __instance.m_sleepTimer = 0.5f; ((BaseAI)__instance).m_character.m_animator.SetBool("sleeping", false); zDO.Set("sleeping", false); zDO.Set("isRecoveringFromStun", false); __instance.Wakeup(); } dt = 0f; return false; } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] public static class Tameable_GetHoverText_Patch { public static void Postfix(Tameable __instance, ref string __result) { if (Object.op_Implicit((Object)(object)__instance.m_character)) { if (__instance.m_character.IsTamed()) { __result += "\n[<color=yellow><b>Shift + T</b></color>] Toggle Protection"; } if (__instance.m_character.m_nview.GetZDO().GetBool("isRecoveringFromStun", false)) { __result = __result.Insert(__result.IndexOf(" )"), ", Recovering"); } } } } }