Decompiled source of Horn of Heimdall v1.2.0

Horn_of_Heimdall_1.2.0/plugins/MyCoolMod/SuperHornMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("SuperHornMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("SuperHornMod")]
[assembly: AssemblyTitle("SuperHornMod")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace MyCoolMod;

public static class HornCreator
{
	public static Sprite HornIcon;

	public static void Init()
	{
		LoadIcon();
		PrefabManager.OnVanillaPrefabsAvailable += CreateHorn;
		ItemManager.OnItemsRegistered += OnItemsRegistered;
	}

	private static void LoadIcon()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		string path = Path.Combine(Paths.PluginPath, "MyCoolMod", "horn_icon.png");
		if (!File.Exists(path))
		{
			Debug.LogWarning((object)"[Рог Хеймдалля] horn_icon.png не найден, будет использована стандартная иконка.");
			return;
		}
		byte[] array = File.ReadAllBytes(path);
		Texture2D val = new Texture2D(2, 2);
		ImageConversion.LoadImage(val, array);
		HornIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		Debug.Log((object)"[Рог Хеймдалля] Иконка загружена.");
	}

	private static void CreateHorn()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= CreateHorn;
		ItemConfig val = new ItemConfig();
		val.Name = "Рог Хеймдалля";
		val.Description = "Древний рог стража Биврёста. Нажми G, чтобы протрубить!";
		val.CraftingStation = CraftingStations.Workbench;
		val.MinStationLevel = 1;
		val.AddRequirement(new RequirementConfig("Wood", 1, 0, true));
		if ((Object)(object)HornIcon != (Object)null)
		{
			val.Icons = (Sprite[])(object)new Sprite[1] { HornIcon };
		}
		CustomItem val2 = new CustomItem("SuperHorn", "Club", val);
		ItemManager.Instance.AddItem(val2);
		Debug.Log((object)"[Рог Хеймдалля] Предмет зарегистрирован!");
	}

	private static void OnItemsRegistered()
	{
		ItemManager.OnItemsRegistered -= OnItemsRegistered;
		ReplaceModel();
	}

	private static void ReplaceModel()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Expected O, but got Unknown
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("SuperHorn");
		GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab("TankardAnniversary");
		if ((Object)(object)itemPrefab == (Object)null || (Object)(object)itemPrefab2 == (Object)null)
		{
			Debug.LogWarning((object)"[Рог Хеймдалля] Замена модели не удалась — префабы не найдены.");
			return;
		}
		Transform val = itemPrefab.transform.Find("attach");
		Transform val2 = itemPrefab2.transform.Find("attach");
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
		{
			Debug.LogWarning((object)"[Рог Хеймдалля] Transform 'attach' не найден.");
			return;
		}
		foreach (Transform item in val)
		{
			Transform val3 = item;
			Object.Destroy((Object)(object)((Component)val3).gameObject);
		}
		GameObject val4 = Object.Instantiate<GameObject>(((Component)val2.GetChild(0)).gameObject, val);
		val4.transform.localPosition = Vector3.zero;
		val4.transform.localRotation = Quaternion.identity;
		val4.transform.localScale = Vector3.one;
		Debug.Log((object)"[Рог Хеймдалля] Модель заменена успешно.");
	}
}
[HarmonyPatch(typeof(Player), "LateUpdate")]
public static class HornHandAdjust
{
	private static bool logged;

	private static void Postfix(Player __instance)
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
		if (currentWeapon == null || (Object)(object)currentWeapon.m_dropPrefab == (Object)null || ((Object)currentWeapon.m_dropPrefab).name != "SuperHorn")
		{
			return;
		}
		VisEquipment component = ((Component)__instance).GetComponent<VisEquipment>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		GameObject value = Traverse.Create((object)component).Field("m_rightItemInstance").GetValue<GameObject>();
		if (!((Object)(object)value == (Object)null))
		{
			if (!logged)
			{
				LogHierarchy(value.transform, "");
				logged = true;
			}
			value.transform.localPosition = new Vector3(0f, 0.05f, 0.05f);
			value.transform.localRotation = Quaternion.Euler(-10f, 80f, -100f);
			for (int i = 0; i < value.transform.childCount; i++)
			{
				Transform child = value.transform.GetChild(i);
				child.localPosition = Vector3.zero;
				child.localRotation = Quaternion.Euler(0f, 0f, 90f);
			}
		}
	}

	private static void LogHierarchy(Transform t, string indent)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)$"[Рог Хеймдалля] {indent}{((Object)t).name} pos={t.localPosition} rot={t.localEulerAngles} scale={t.localScale}");
		for (int i = 0; i < t.childCount; i++)
		{
			LogHierarchy(t.GetChild(i), indent + "  ");
		}
	}
}
[HarmonyPatch]
public static class HornLogic
{
	private static float lastActivation;

	private static AudioClip hornClip;

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	[HarmonyPostfix]
	private static void LoadHorn()
	{
		if ((Object)(object)hornClip != (Object)null)
		{
			return;
		}
		string path = Path.Combine(Paths.PluginPath, "MyCoolMod", "horn.wav");
		if (!File.Exists(path))
		{
			Debug.LogError((object)"[Рог Хеймдалля] horn.wav не найден!");
			return;
		}
		hornClip = LoadWav(path);
		if ((Object)(object)hornClip != (Object)null)
		{
			Debug.Log((object)"[Рог Хеймдалля] horn.wav загружен успешно.");
		}
		else
		{
			Debug.LogError((object)"[Рог Хеймдалля] Не удалось загрузить WAV.");
		}
	}

	private static AudioClip LoadWav(string path)
	{
		byte[] array = File.ReadAllBytes(path);
		string @string = Encoding.ASCII.GetString(array);
		int num = @string.IndexOf("fmt ");
		int num2 = @string.IndexOf("data");
		if (num < 0 || num2 < 0)
		{
			Debug.LogError((object)"[Рог Хеймдалля] Неверная структура WAV.");
			return null;
		}
		int num3 = BitConverter.ToInt16(array, num + 10);
		int num4 = BitConverter.ToInt32(array, num + 12);
		int num5 = BitConverter.ToInt16(array, num + 22);
		if (num5 != 16)
		{
			Debug.LogError((object)"[Рог Хеймдалля] Поддерживается только 16-bit PCM.");
			return null;
		}
		int num6 = BitConverter.ToInt32(array, num2 + 4);
		int num7 = num2 + 8;
		int num8 = num6 / 2;
		float[] array2 = new float[num8];
		int num9 = 0;
		for (int i = num7; i < num7 + num6; i += 2)
		{
			short num10 = BitConverter.ToInt16(array, i);
			array2[num9++] = (float)num10 / 32768f;
		}
		AudioClip val = AudioClip.Create("HeimdallHorn", num8 / num3, num3, num4, false);
		val.SetData(array2, 0);
		return val;
	}

	[HarmonyPatch(typeof(Player), "Update")]
	[HarmonyPostfix]
	private static void HornInput(Player __instance)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		if (!Enum.TryParse<KeyCode>(MyMod.ActivationKey.Value, ignoreCase: true, out KeyCode result))
		{
			Debug.LogWarning((object)("[Рог Хеймдалля] Неизвестная клавиша: " + MyMod.ActivationKey.Value));
		}
		else
		{
			if (!Input.GetKeyDown(result))
			{
				return;
			}
			ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon();
			if (currentWeapon == null || !((Object)(object)currentWeapon.m_dropPrefab != (Object)null) || !(((Object)currentWeapon.m_dropPrefab).name == "SuperHorn"))
			{
				return;
			}
			if (Time.time - lastActivation >= MyMod.Cooldown.Value)
			{
				if (currentWeapon.m_durability < MyMod.DurabilityCost.Value)
				{
					((Character)__instance).Message((MessageType)2, "Рог слишком изношен!", 0, (Sprite)null);
					return;
				}
				lastActivation = Time.time;
				currentWeapon.m_durability -= MyMod.DurabilityCost.Value;
				((MonoBehaviour)__instance).StartCoroutine(ActivateHorn(__instance));
			}
			else
			{
				float num = MyMod.Cooldown.Value - (Time.time - lastActivation);
				((Character)__instance).Message((MessageType)2, $"Рог перезаряжается... ({num:F0} сек)", 0, (Sprite)null);
			}
		}
	}

	private static IEnumerator ActivateHorn(Player player)
	{
		player.StartEmote("cheer", true);
		yield return (object)new WaitForSeconds(0.35f);
		Vector3 pos = ((Component)player).transform.position + Vector3.up * 1.8f;
		SpawnHornSound(pos);
		SpawnWishboneFX(pos);
		ApplyBuff(player);
		((Character)player).Message((MessageType)2, "Рог Хеймдалля звучит!", 0, (Sprite)null);
	}

	private static void ApplyBuff(Player player)
	{
		SEMan sEMan = ((Character)player).GetSEMan();
		StatusEffect val = sEMan.GetStatusEffects().Find((StatusEffect se) => ((Object)se).name == "SE_HornBuff");
		if ((Object)(object)val != (Object)null)
		{
			sEMan.RemoveStatusEffect(val, false);
		}
		SE_HornBuff sE_HornBuff = ScriptableObject.CreateInstance<SE_HornBuff>();
		((Object)sE_HornBuff).name = "SE_HornBuff";
		sEMan.AddStatusEffect((StatusEffect)(object)sE_HornBuff, false, 0, 0f);
		Debug.Log((object)"[Рог Хеймдалля] Баф наложен.");
	}

	private static void SpawnHornSound(Vector3 pos)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hornClip == (Object)null)
		{
			Debug.LogWarning((object)"[Рог Хеймдалля] hornClip == null.");
			return;
		}
		GameObject val = new GameObject("HeimdallHornSound");
		val.transform.position = pos;
		AudioSource val2 = val.AddComponent<AudioSource>();
		val2.clip = hornClip;
		val2.spatialBlend = 1f;
		val2.minDistance = 40f;
		val2.maxDistance = MyMod.Radius.Value;
		val2.rolloffMode = (AudioRolloffMode)0;
		val2.dopplerLevel = 0f;
		val2.spread = 160f;
		val2.volume = 1f;
		val2.Play();
		Object.Destroy((Object)(object)val, hornClip.length + 1f);
	}

	private static void SpawnWishboneFX(Vector3 pos)
	{
		//IL_0032: 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)
		if ((Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		GameObject prefab = ZNetScene.instance.GetPrefab("vfx_WishbonePing");
		if (!((Object)(object)prefab == (Object)null))
		{
			GameObject val = Object.Instantiate<GameObject>(prefab, pos, Quaternion.identity);
			ZNetView component = val.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			Object.Destroy((Object)(object)val, 5f);
		}
	}
}
[BepInPlugin("com.rodogor.hornofheimdall", "Рог Хеймдалля", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class MyMod : BaseUnityPlugin
{
	public static ConfigEntry<string> ActivationKey;

	public static ConfigEntry<float> Cooldown;

	public static ConfigEntry<float> Radius;

	public static ConfigEntry<float> DurabilityCost;

	public static ConfigEntry<float> BuffDuration;

	public static Sprite HornBuffIcon;

	private void Awake()
	{
		ActivationKey = ((BaseUnityPlugin)this).Config.Bind<string>("Рог", "ActivationKey", "G", "Клавиша активации рога");
		Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Рог", "Cooldown", 60f, "Перезарядка в секундах");
		Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Рог", "Radius", 400f, "Радиус звука рога");
		DurabilityCost = ((BaseUnityPlugin)this).Config.Bind<float>("Рог", "DurabilityCost", 5f, "Расход прочности за использование");
		BuffDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Рог", "BuffDuration", 30f, "Длительность бафа в секундах");
		LoadBuffIcon();
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		HornCreator.Init();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Рог Хеймдалля загружен!");
	}

	private void LoadBuffIcon()
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		string text = Path.Combine(Paths.PluginPath, "MyCoolMod", "horn_buff_icon.png");
		Debug.Log((object)("[Рог Хеймдалля] Ищу иконку бафа: " + text));
		if (!File.Exists(text))
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			text = Path.Combine(directoryName, "horn_buff_icon.png");
			Debug.Log((object)("[Рог Хеймдалля] Пробую рядом с DLL: " + text));
		}
		if (!File.Exists(text))
		{
			Debug.LogWarning((object)"[Рог Хеймдалля] horn_buff_icon.png не найден!");
			return;
		}
		byte[] array = File.ReadAllBytes(text);
		Texture2D val = new Texture2D(2, 2);
		ImageConversion.LoadImage(val, array);
		HornBuffIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		Debug.Log((object)"[Рог Хеймдалля] Иконка бафа загружена.");
	}
}
public class SE_HornBuff : StatusEffect
{
	public override void Setup(Character character)
	{
		((StatusEffect)this).Setup(character);
		base.m_name = "Боевой рог";
		base.m_tooltip = "Духи войны наполняют тебя силой.\n+30% восстановление выносливости\n+10% скорость бега\n-30% расход выносливости при беге";
		base.m_icon = (((Object)(object)MyMod.HornBuffIcon != (Object)null) ? MyMod.HornBuffIcon : HornCreator.HornIcon);
		base.m_ttl = MyMod.BuffDuration.Value;
	}

	public override void ModifyStaminaRegen(ref float staminaRegen)
	{
		staminaRegen *= 1.3f;
	}

	public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir)
	{
		speed *= 1.1f;
	}

	public override void ModifyRunStaminaDrain(float baseDrain, ref float drain, Vector3 dir)
	{
		drain *= 0.7f;
	}
}