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 NoDrainTotem v0.1.0
BepInEx/plugins/NoDrainTotem.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using NoDrainTotem.Components; using NoDrainTotem.Configuration; using NoDrainTotem.Content; using NoDrainTotem.Patches; using NoDrainTotem.Services; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NoDrainTotem { [BepInPlugin("nodraintotem.valheim", "No Drain Totem", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public sealed class NoDrainTotemPlugin : BaseUnityPlugin { public const string PluginGuid = "nodraintotem.valheim"; public const string PluginName = "No Drain Totem"; public const string PluginVersion = "0.1.0"; private const float RefreshIntervalSeconds = 1f; private Harmony _harmony; private TotemSettings _settings; private float _nextRefresh; private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown _settings = new TotemSettings(((BaseUnityPlugin)this).Config); NoDrainTotemArea.Configure(_settings); AuraBlessingService.Configure(_settings); _harmony = new Harmony("nodraintotem.valheim"); _harmony.CreateClassProcessor(typeof(SkillDrainPatches)).Patch(); PrefabManager.OnVanillaPrefabsAvailable += RegisterContent; } private void RegisterContent() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterContent; TotemPieceBuilder.Register(_settings); } private void Update() { if (!(Time.time < _nextRefresh)) { _nextRefresh = Time.time + 1f; AuraBlessingService.RefreshLocalPlayer(); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace NoDrainTotem.Services { internal static class AuraBlessingService { private static TotemSettings _settings; public static void Configure(TotemSettings settings) { _settings = settings; } public static void RefreshLocalPlayer() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && NoDrainTotemArea.IsInsideActiveAura(((Component)localPlayer).transform.position)) { SEMan sEMan = ((Character)localPlayer).GetSEMan(); sEMan.AddStatusEffect(NoDrainStatusEffect.NameHash, true, 0, 0f, (short)(-1)); StatusEffect statusEffect = sEMan.GetStatusEffect(NoDrainStatusEffect.NameHash); if ((Object)(object)statusEffect != (Object)null) { statusEffect.m_ttl = _settings.GraceDuration.Value; } } } public static bool IsProtected(Player player) { if ((Object)(object)player != (Object)null) { return ((Character)player).GetSEMan().HaveStatusEffect(NoDrainStatusEffect.NameHash); } return false; } } } namespace NoDrainTotem.Patches { [HarmonyPatch] internal static class SkillDrainPatches { [HarmonyPatch(typeof(Skills), "OnDeath")] [HarmonyPrefix] private static bool OnDeath(Skills __instance) { Player component = ((Component)__instance).GetComponent<Player>(); if (!AuraBlessingService.IsProtected(component)) { return true; } ((Character)component).Message((MessageType)1, "Totem's Grace protected your skills", 0, (Sprite)null, false); return false; } } } namespace NoDrainTotem.Content { internal static class NoDrainStatusEffect { public const string Name = "SE_NoDrainTotem"; public static readonly int NameHash = StringExtensionMethods.GetStableHashCode("SE_NoDrainTotem"); public static StatusEffect Create(Sprite icon, float durationSeconds) { StatusEffect obj = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)obj).name = "SE_NoDrainTotem"; obj.m_name = "Totem's Grace"; obj.m_tooltip = "Your skills will not drain if you die. Refreshed while inside an active No Drain Totem aura."; obj.m_icon = icon; obj.m_ttl = durationSeconds; return obj; } } internal static class TotemPieceBuilder { public const string PrefabName = "NoDrainTotem"; private const string WardPrefabName = "guard_stone"; private const string SegmentPrefabName = "NoDrainTotem_AuraSegment"; public static void Register(TotemSettings settings) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("NoDrainTotem", "guard_stone"); PrivateArea component = val.GetComponent<PrivateArea>(); NoDrainTotemArea totem = val.AddComponent<NoDrainTotemArea>(); CopyWardVisuals(component, totem); Object.DestroyImmediate((Object)(object)component); TotemTint.Apply(val); Piece component2 = val.GetComponent<Piece>(); Sprite icon = (component2.m_icon = TotemTint.ApplyToIcon(component2.m_icon)); ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(NoDrainStatusEffect.Create(icon, settings.GraceDuration.Value), false)); PieceManager.Instance.AddPiece(new CustomPiece(val, false, CreatePieceConfig(icon))); } private static void CopyWardVisuals(PrivateArea ward, NoDrainTotemArea totem) { totem.m_name = "No Drain Totem"; totem.m_enabledEffect = ward.m_enabledEffect; totem.m_areaMarker = ward.m_areaMarker; totem.m_model = ward.m_model; totem.m_hoverOffset = ward.m_hoverOffset; totem.m_activateEffect = ward.m_activateEffect; totem.m_deactivateEffect = ward.m_deactivateEffect; if ((Object)(object)ward.m_areaMarker != (Object)null && (Object)(object)ward.m_areaMarker.m_prefab != (Object)null) { GameObject val = PrefabManager.Instance.CreateClonedPrefab("NoDrainTotem_AuraSegment", ward.m_areaMarker.m_prefab); TotemTint.Apply(val); ward.m_areaMarker.m_prefab = val; } if ((Object)(object)ward.m_inRangeEffect != (Object)null) { Object.DestroyImmediate((Object)(object)ward.m_inRangeEffect); } } private static PieceConfig CreatePieceConfig(Sprite icon) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown PieceConfig val = new PieceConfig(); val.Name = "No Drain Totem"; val.Icon = icon; val.Description = "Projects an aura that protects the skills of players inside it from draining on death."; val.PieceTable = PieceTables.Hammer; val.Category = PieceCategories.Misc; val.CraftingStation = CraftingStations.Workbench; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("RoundLog", 10, 0, true), new RequirementConfig("TrophyDraugr", 1, 0, true), new RequirementConfig("Iron", 3, 0, true) }; return val; } } internal static class TotemTint { public static readonly Color Color = new Color(0.25f, 0.85f, 1f); private const float BaseColorBlend = 0.5f; public static void Apply(GameObject root) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { TintRenderer(componentsInChildren[i]); } Light[] componentsInChildren2 = root.GetComponentsInChildren<Light>(true); foreach (Light obj in componentsInChildren2) { obj.color = Recolor(obj.color); } ParticleSystem[] componentsInChildren3 = root.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { TintParticles(componentsInChildren3[i]); } } public static Sprite ApplyToIcon(Sprite source) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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) if ((Object)(object)source == (Object)null || (int)SystemInfo.graphicsDeviceType == 4) { return source; } Rect textureRect = source.textureRect; Texture2D val = ReadPixels((Texture)(object)source.texture, textureRect); Color[] pixels = val.GetPixels(); for (int i = 0; i < pixels.Length; i++) { pixels[i] = Recolor(pixels[i]); } val.SetPixels(pixels); val.Apply(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(source.pivot.x / ((Rect)(ref textureRect)).width, source.pivot.y / ((Rect)(ref textureRect)).height); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, ((Rect)(ref textureRect)).width, ((Rect)(ref textureRect)).height), val2, source.pixelsPerUnit); ((Object)obj).name = ((Object)source).name + "_NoDrainTotem"; return obj; } private static Texture2D ReadPixels(Texture source, Rect rect) { //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_0040: 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_005b: Expected O, but got Unknown RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); RenderTexture active = RenderTexture.active; Graphics.Blit(source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D((int)((Rect)(ref rect)).width, (int)((Rect)(ref rect)).height, (TextureFormat)4, false); val.ReadPixels(rect, 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); return val; } private static void TintRenderer(Renderer renderer) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //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_0049: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Material[] sharedMaterials = renderer.sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { if (!((Object)(object)sharedMaterials[i] == (Object)null)) { Material val = new Material(sharedMaterials[i]); if (val.HasProperty("_Color")) { val.color = Color.Lerp(val.color, Recolor(val.color), 0.5f); } if (val.HasProperty("_TintColor")) { val.SetColor("_TintColor", Recolor(val.GetColor("_TintColor"))); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", Recolor(val.GetColor("_EmissionColor"))); } sharedMaterials[i] = val; } } renderer.sharedMaterials = sharedMaterials; } private static void TintParticles(ParticleSystem particles) { //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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) MainModule main = particles.main; ((MainModule)(ref main)).startColor = Recolor(((MainModule)(ref main)).startColor); ColorOverLifetimeModule colorOverLifetime = particles.colorOverLifetime; if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled) { ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = Recolor(((ColorOverLifetimeModule)(ref colorOverLifetime)).color); } } private static MinMaxGradient Recolor(MinMaxGradient source) { //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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected I4, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //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_0046: 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) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) ParticleSystemGradientMode mode = ((MinMaxGradient)(ref source)).mode; switch ((int)mode) { case 0: return new MinMaxGradient(Recolor(((MinMaxGradient)(ref source)).color)); case 2: return new MinMaxGradient(Recolor(((MinMaxGradient)(ref source)).colorMin), Recolor(((MinMaxGradient)(ref source)).colorMax)); case 1: case 4: { MinMaxGradient result = default(MinMaxGradient); ((MinMaxGradient)(ref result))..ctor(Recolor(((MinMaxGradient)(ref source)).gradient)); ((MinMaxGradient)(ref result)).mode = ((MinMaxGradient)(ref source)).mode; return result; } case 3: return new MinMaxGradient(Recolor(((MinMaxGradient)(ref source)).gradientMin), Recolor(((MinMaxGradient)(ref source)).gradientMax)); default: return source; } } private static Gradient Recolor(Gradient source) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_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_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_0051: Expected O, but got Unknown GradientColorKey[] colorKeys = source.colorKeys; for (int i = 0; i < colorKeys.Length; i++) { colorKeys[i].color = Recolor(colorKeys[i].color); } Gradient val = new Gradient { mode = source.mode }; val.SetKeys(colorKeys, source.alphaKeys); return val; } private static Color Recolor(Color source) { //IL_002c: 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) float maxColorComponent = ((Color)(ref source)).maxColorComponent; return new Color(Color.r * maxColorComponent, Color.g * maxColorComponent, Color.b * maxColorComponent, source.a); } } } namespace NoDrainTotem.Configuration { internal sealed class TotemSettings { public ConfigEntry<float> AuraRadius { get; } public ConfigEntry<float> GraceDuration { get; } public TotemSettings(ConfigFile config) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_007c: 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_0089: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown AuraRadius = config.Bind<float>("Totem", "Aura radius", 20f, new ConfigDescription("Radius in meters of the No Drain Totem aura. Synced from the server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 64f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); GraceDuration = config.Bind<float>("Totem", "Grace duration", 10f, new ConfigDescription("Seconds Totem's Grace lasts after leaving an active aura. Synced from the server.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); } } } namespace NoDrainTotem.Components { public sealed class NoDrainTotemArea : MonoBehaviour, Hoverable, Interactable { public const string DisplayName = "No Drain Totem"; private const string EnabledKey = "nodraintotem_enabled"; private const string ToggleRpc = "NoDrainTotem_Toggle"; private static readonly List<NoDrainTotemArea> ActiveTotems = new List<NoDrainTotemArea>(); private static TotemSettings _settings; public string m_name = "No Drain Totem"; public GameObject m_enabledEffect; public CircleProjector m_areaMarker; public MeshRenderer m_model; public float m_hoverOffset; public EffectList m_activateEffect = new EffectList(); public EffectList m_deactivateEffect = new EffectList(); private ZNetView _nview; internal static void Configure(TotemSettings settings) { _settings = settings; } public static bool IsInsideActiveAura(Vector3 position) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) foreach (NoDrainTotemArea activeTotem in ActiveTotems) { if (activeTotem.IsEnabled() && activeTotem.Covers(position)) { return true; } } return false; } private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { ActiveTotems.Add(this); _nview.Register<bool>("NoDrainTotem_Toggle", (Action<long, bool>)RPC_SetEnabled); ((MonoBehaviour)this).InvokeRepeating("UpdateVisuals", 0f, 1f); } } private void OnDestroy() { ActiveTotems.Remove(this); } private void UpdateVisuals() { bool flag = IsEnabled(); if ((Object)(object)m_enabledEffect != (Object)null) { m_enabledEffect.SetActive(flag); } if ((Object)(object)m_areaMarker != (Object)null) { m_areaMarker.m_radius = Radius(); ((Component)m_areaMarker).gameObject.SetActive(flag); } if (!((Object)(object)m_model != (Object)null)) { return; } Material[] materials = ((Renderer)m_model).materials; foreach (Material val in materials) { if (flag) { val.EnableKeyword("_EMISSION"); } else { val.DisableKeyword("_EMISSION"); } } } public string GetHoverText() { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return ""; } string text = (IsEnabled() ? "$piece_guardstone_active" : "$piece_guardstone_inactive"); string text2 = (IsEnabled() ? "$piece_guardstone_deactivate" : "$piece_guardstone_activate"); return Localization.instance.Localize(m_name + " ( " + text + " )\n[<color=yellow><b>$KEY_Use</b></color>] " + text2); } public string GetHoverName() { return m_name; } public float GetHoverOffset() { return m_hoverOffset; } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || (Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } _nview.InvokeRPC("NoDrainTotem_Toggle", new object[1] { !IsEnabled() }); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private void RPC_SetEnabled(long sender, bool enabled) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (_nview.IsOwner() && IsEnabled() != enabled) { _nview.GetZDO().Set("nodraintotem_enabled", enabled); UpdateVisuals(); (enabled ? m_activateEffect : m_deactivateEffect).Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } } private bool IsEnabled() { if ((Object)(object)_nview != (Object)null && _nview.IsValid()) { return _nview.GetZDO().GetBool("nodraintotem_enabled", true); } return false; } private bool Covers(Vector3 position) { //IL_0000: 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) return Utils.DistanceXZ(position, ((Component)this).transform.position) <= Radius(); } private static float Radius() { return _settings.AuraRadius.Value; } } }