Decompiled source of ThisIsValheim v0.1.0

ThisIsValheim.dll

Decompiled 16 hours ago
using System;
using System.Collections;
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.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ThisIsValheim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e67f65fcfb9136b09a058395c34e6bc40eccb3d2")]
[assembly: AssemblyProduct("ThisIsValheim")]
[assembly: AssemblyTitle("ThisIsValheim")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace ThisIsValheim
{
	[BepInPlugin("rauschekuh.thisisvalheim", "This Is Valheim!", "0.1.0")]
	public class ThisIsValheimPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRpc
		{
			private static void Postfix()
			{
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null && instance != registeredOn)
				{
					registeredOn = instance;
					instance.Register<ZDOID>("ThisIsValheim_Kick", (Action<long, ZDOID>)RPC_Kick);
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "AddHitPoint")]
		private static class NoticeKick
		{
			private static void Postfix(Attack __instance, GameObject go)
			{
				try
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)go == (Object)null) && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)__instance.m_character != (Object)(object)localPlayer) && IsKick(__instance.m_attackAnimation))
					{
						Door componentInParent = go.GetComponentInParent<Door>();
						if ((Object)(object)componentInParent != (Object)null)
						{
							TryKick(componentInParent, localPlayer);
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[ThisIsValheim] kick check failed: " + ex));
				}
			}
		}

		public const string GUID = "rauschekuh.thisisvalheim";

		public const string NAME = "This Is Valheim!";

		public const string VERSION = "0.1.0";

		private const string KickRpc = "ThisIsValheim_Kick";

		private const float SwingWindow = 1.5f;

		private const float KickCooldown = 0.6f;

		private const float SoundHeight = 1f;

		private const float EffectLifetime = 6f;

		private const string DefaultEffects = "sfx_battering_ram_impact,sfx_wood_break,vfx_SawDust,fx_hit_camshake";

		private static ThisIsValheimPlugin instance;

		private static ZRoutedRpc registeredOn;

		private static EffectList effects;

		private static bool resolved;

		private static readonly Dictionary<Door, Coroutine> swinging = new Dictionary<Door, Coroutine>();

		private static readonly Dictionary<Door, float> kicked = new Dictionary<Door, float>();

		private static ConfigEntry<float> swingSpeed;

		private static ConfigEntry<bool> lockedDoors;

		private static ConfigEntry<string> effectPrefabs;

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			instance = this;
			swingSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Kick", "SwingSpeed", 4f, new ConfigDescription("How many times faster than normal a kicked door swings open.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			lockedDoors = ((BaseUnityPlugin)this).Config.Bind<bool>("Kick", "LockedDoors", false, "Whether a door that wants a key can be kicked open without it. Off keeps the crypts shut until you have found the key, the way the game intends.");
			effectPrefabs = ((BaseUnityPlugin)this).Config.Bind<string>("Effects", "Prefabs", "sfx_battering_ram_impact,sfx_wood_break,vfx_SawDust,fx_hit_camshake", "The game's own effect prefabs that go off at the door, by name, separated by commas. Drop one to lose that layer, or put fx_GP_Activation in for the sound a Forsaken power makes when you call on it. An empty list makes the kick silent.");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "rauschekuh.thisisvalheim");
		}

		private static bool IsKick(string animation)
		{
			if (!string.IsNullOrEmpty(animation))
			{
				return animation.IndexOf("kick", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static bool TryKick(Door door, Player player)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			ZNetView nview = door.m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)door.m_animator == (Object)null || Recent(door))
			{
				return false;
			}
			if (nview.GetZDO().GetInt(ZDOVars.s_state, 0) != 0 || !door.CanInteract())
			{
				return false;
			}
			if (door.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)door).transform.position, 0f, false, false))
			{
				return false;
			}
			if ((Object)(object)door.m_keyItem != (Object)null && !lockedDoors.Value)
			{
				return false;
			}
			kicked[door] = Time.time;
			Broadcast(nview.GetZDO().m_uid);
			Vector3 val = ((Component)player).transform.position - ((Component)door).transform.position;
			door.Open(((Vector3)(ref val)).normalized);
			if ((Object)(object)Game.instance != (Object)null)
			{
				Game.instance.IncrementPlayerStat((PlayerStatType)74, 1f, false);
			}
			return true;
		}

		private static bool Recent(Door door)
		{
			float time = Time.time;
			if (kicked.TryGetValue(door, out var value) && time - value < 0.6f)
			{
				return true;
			}
			if (kicked.Count > 8)
			{
				List<Door> list = new List<Door>();
				foreach (KeyValuePair<Door, float> item in kicked)
				{
					if ((Object)(object)item.Key == (Object)null || time - item.Value >= 0.6f)
					{
						list.Add(item.Key);
					}
				}
				foreach (Door item2 in list)
				{
					kicked.Remove(item2);
				}
			}
			return false;
		}

		private static void Broadcast(ZDOID door)
		{
			//IL_002a: 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)
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "ThisIsValheim_Kick", new object[1] { door });
			}
			else
			{
				RPC_Kick(0L, door);
			}
		}

		private static void RPC_Kick(long sender, ZDOID id)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated())
			{
				return;
			}
			try
			{
				if (!((Object)(object)ZNetScene.instance == (Object)null))
				{
					GameObject val = ZNetScene.instance.FindInstance(id);
					Door val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Door>() : null);
					if (!((Object)(object)val2 == (Object)null))
					{
						Bang(((Component)val2).transform.position + Vector3.up * 1f);
						Swing(val2);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[ThisIsValheim] kick effects failed: " + ex));
			}
		}

		private static void Bang(Vector3 pos)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			EffectList val = Effects();
			if (val != null)
			{
				bool forceDisableInit = ZNetView.m_forceDisableInit;
				ZNetView.m_forceDisableInit = true;
				GameObject[] spawned;
				try
				{
					spawned = val.Create(pos, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
				finally
				{
					ZNetView.m_forceDisableInit = forceDisableInit;
				}
				Sweep(spawned);
			}
		}

		private static void Sweep(GameObject[] spawned)
		{
			foreach (GameObject val in spawned)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponentInChildren<TimedDestruction>(true) == (Object)null)
				{
					Object.Destroy((Object)(object)val, 6f);
				}
			}
		}

		private static EffectList Effects()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			if (resolved)
			{
				return effects;
			}
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			resolved = true;
			List<string> list = new List<string>();
			string[] array = effectPrefabs.Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0)
				{
					list.Add(text);
				}
			}
			if (list.Count == 0)
			{
				return null;
			}
			List<EffectData> list2 = new List<EffectData>();
			List<string> list3 = new List<string>();
			foreach (string item in list)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(item);
				if ((Object)(object)prefab != (Object)null)
				{
					list2.Add(new EffectData
					{
						m_prefab = prefab,
						m_enabled = true
					});
				}
				else
				{
					list3.Add(item);
				}
			}
			if (list3.Count > 0)
			{
				GameObject[] array2 = Resources.FindObjectsOfTypeAll<GameObject>();
				foreach (GameObject val in array2)
				{
					int num = list3.IndexOf(((Object)val).name);
					if (num >= 0)
					{
						list2.Add(new EffectData
						{
							m_prefab = val,
							m_enabled = true
						});
						list3.RemoveAt(num);
						if (list3.Count == 0)
						{
							break;
						}
					}
				}
			}
			foreach (string item2 in list3)
			{
				Debug.LogWarning((object)("[ThisIsValheim] no effect prefab called " + item2));
			}
			if (list2.Count == 0)
			{
				Debug.LogWarning((object)"[ThisIsValheim] nothing left to play, kicks will be quiet");
				return null;
			}
			effects = new EffectList
			{
				m_effectPrefabs = list2.ToArray()
			};
			return effects;
		}

		private static void Swing(Door door)
		{
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)door.m_animator == (Object)null))
			{
				if (swinging.TryGetValue(door, out var value))
				{
					((MonoBehaviour)instance).StopCoroutine(value);
				}
				swinging[door] = ((MonoBehaviour)instance).StartCoroutine(SwingRoutine(door, door.m_animator));
			}
		}

		private static IEnumerator SwingRoutine(Door door, Animator animator)
		{
			animator.speed = Mathf.Max(1f, swingSpeed.Value);
			yield return (object)new WaitForSeconds(1.5f);
			if ((Object)(object)animator != (Object)null)
			{
				animator.speed = 1f;
			}
			swinging.Remove(door);
		}
	}
}