Decompiled source of ValheimStarTrophies v1.1.0

StarTrophies.dll

Decompiled 2 weeks ago
using 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.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
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: AssemblyCompany("StarTrophies")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("StarTrophies")]
[assembly: AssemblyTitle("StarTrophies")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.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;
		}
	}
}
namespace StarTrophies
{
	[BepInPlugin("com.startrophies.valheim", "StarTrophies", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class StarTrophiesPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.startrophies.valheim";

		public const string PluginName = "StarTrophies";

		public const string PluginVersion = "2.0.0";

		public static readonly string[] NamePrefix = new string[2] { "★ ", "★★ " };

		public static readonly HashSet<string> KnownNonStarableTrophies = new HashSet<string> { "TrophyAbomination", "TrophyGolem", "TrophySerpent", "TrophyWraith", "TrophyLox", "TrophyDeathsquito" };

		public static ConfigEntry<float> ConfigValueMul1;

		public static ConfigEntry<float> ConfigValueMul2;

		public static ConfigEntry<float> ConfigScale1;

		public static ConfigEntry<float> ConfigScale2;

		private Harmony _harmony;

		private static bool _trophiesCreated = false;

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			BindConfig();
			_harmony = new Harmony("com.startrophies.valheim");
			_harmony.PatchAll();
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void BindConfig()
		{
			ConfigValueMul1 = ((BaseUnityPlugin)this).Config.Bind<float>("1 Star", "ValueMultiplier", 2f, "Множитель цены для 1★ трофеев");
			ConfigValueMul2 = ((BaseUnityPlugin)this).Config.Bind<float>("2 Stars", "ValueMultiplier", 4f, "Множитель цены для 2★ трофеев");
			ConfigScale1 = ((BaseUnityPlugin)this).Config.Bind<float>("1 Star", "SizeMultiplier", 1.15f, "Множитель размера модели на стойке/в мире для 1★");
			ConfigScale2 = ((BaseUnityPlugin)this).Config.Bind<float>("2 Stars", "SizeMultiplier", 1.4f, "Множитель размера модели на стойке/в мире для 2★");
		}

		private static void OnVanillaPrefabsAvailable()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			if (!_trophiesCreated)
			{
				CreateStarTrophies();
				_trophiesCreated = true;
			}
		}

		public static void CreateStarTrophies()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Invalid comparison between Unknown and I4
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Expected O, but got Unknown
			List<GameObject> list = new List<GameObject>();
			Dictionary<string, Object> prefabs = Cache.GetPrefabs(typeof(GameObject));
			if (prefabs != null)
			{
				foreach (KeyValuePair<string, Object> item in prefabs)
				{
					Object value = item.Value;
					GameObject val = (GameObject)(object)((value is GameObject) ? value : null);
					if (!((Object)(object)val == (Object)null))
					{
						ItemDrop component = val.GetComponent<ItemDrop>();
						if (!((Object)(object)component == (Object)null) && component.m_itemData != null && (int)component.m_itemData.m_shared.m_itemType == 13 && !KnownNonStarableTrophies.Contains(((Object)val).name))
						{
							list.Add(val);
						}
					}
				}
			}
			if (list.Count == 0 && (Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null)
			{
				foreach (GameObject item2 in ObjectDB.instance.m_items)
				{
					if (!((Object)(object)item2 == (Object)null))
					{
						ItemDrop component2 = item2.GetComponent<ItemDrop>();
						if (!((Object)(object)component2 == (Object)null) && component2.m_itemData != null && (int)component2.m_itemData.m_shared.m_itemType == 13 && !KnownNonStarableTrophies.Contains(((Object)item2).name))
						{
							list.Add(item2);
						}
					}
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			float[] array = new float[2] { ConfigValueMul1.Value, ConfigValueMul2.Value };
			float[] array2 = new float[2] { ConfigScale1.Value, ConfigScale2.Value };
			int num = 0;
			foreach (GameObject item3 in list)
			{
				ItemDrop component3 = item3.GetComponent<ItemDrop>();
				string name = component3.m_itemData.m_shared.m_name;
				string text = LocalizationManager.Instance.TryTranslate(name);
				if (string.IsNullOrEmpty(text))
				{
					text = (name.StartsWith("$") ? name.Substring(1) : name);
				}
				for (int i = 0; i < 2; i++)
				{
					string text2 = $"{((Object)item3).name}_Star{i + 1}";
					if ((Object)(object)PrefabManager.Instance.GetPrefab(text2) != (Object)null)
					{
						continue;
					}
					GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(text2, item3);
					if (!((Object)(object)val2 == (Object)null))
					{
						ItemDrop component4 = val2.GetComponent<ItemDrop>();
						if (!((Object)(object)component4 == (Object)null) && component4.m_itemData != null)
						{
							component4.m_itemData.m_dropPrefab = val2;
							val2.transform.localScale = item3.transform.localScale * array2[i];
							SharedData val3 = SharedDataCopy.ShallowCopy<SharedData>(component3.m_itemData.m_shared);
							val3.m_name = NamePrefix[i] + text;
							val3.m_value = Mathf.RoundToInt((float)val3.m_value * array[i]);
							val3.m_maxQuality = 3;
							val3.m_scaleByQuality = (array2[i] - 1f) / ((float)i + 1f);
							component4.m_itemData.m_quality = i + 2;
							component4.m_itemData.m_shared = val3;
							NativeStarColorizer.ApplyNativeStarColor(item3, val2, i);
							ItemManager.Instance.AddItem(new CustomItem(val2, true));
						}
					}
				}
				num++;
			}
			Logger.LogInfo((object)$"[StarTrophies] Нативные звездные трофеи успешно созданы для {num} видов ({num * 2} предметов).");
		}
	}
	public static class NativeStarColorizer
	{
		private static readonly string[] EmissionPropertyNames = new string[2] { "_EmissionColor", "_EmissiveColor" };

		public static void ApplyNativeStarColor(GameObject originalTrophy, GameObject cloneTrophy, int tier)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindMobByTrophy(originalTrophy);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			LevelEffects componentInChildren = val.GetComponentInChildren<LevelEffects>(true);
			if ((Object)(object)componentInChildren == (Object)null || componentInChildren.m_levelSetups == null || tier >= componentInChildren.m_levelSetups.Count)
			{
				return;
			}
			LevelSetup val2 = componentInChildren.m_levelSetups[tier];
			Renderer mainRender = componentInChildren.m_mainRender;
			Renderer val3 = FindMatchingRenderer(cloneTrophy, mainRender);
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			Material[] sharedMaterials = val3.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0 || (Object)(object)sharedMaterials[0] == (Object)null)
			{
				return;
			}
			Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
			for (int i = 0; i < sharedMaterials.Length; i++)
			{
				if ((Object)(object)sharedMaterials[i] == (Object)null)
				{
					continue;
				}
				Material val4 = new Material(sharedMaterials[i]);
				if (val4.HasProperty("_Hue"))
				{
					val4.SetFloat("_Hue", val2.m_hue);
				}
				if (val4.HasProperty("_Saturation"))
				{
					val4.SetFloat("_Saturation", val2.m_saturation);
				}
				if (val4.HasProperty("_Value"))
				{
					val4.SetFloat("_Value", val2.m_value);
				}
				if (val2.m_setEmissiveColor)
				{
					bool flag = false;
					string[] emissionPropertyNames = EmissionPropertyNames;
					foreach (string text in emissionPropertyNames)
					{
						if (val4.HasProperty(text))
						{
							val4.SetColor(text, val2.m_emissiveColor);
							flag = true;
						}
					}
					if (flag)
					{
						val4.EnableKeyword("_EMISSION");
					}
				}
				array[i] = val4;
			}
			val3.sharedMaterials = array;
		}

		private static GameObject FindMobByTrophy(GameObject trophyPrefab)
		{
			Dictionary<string, Object> prefabs = Cache.GetPrefabs(typeof(GameObject));
			if (prefabs != null)
			{
				foreach (KeyValuePair<string, Object> item in prefabs)
				{
					Object value = item.Value;
					GameObject val = (GameObject)(object)((value is GameObject) ? value : null);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					CharacterDrop component = val.GetComponent<CharacterDrop>();
					if ((Object)(object)component == (Object)null || component.m_drops == null)
					{
						continue;
					}
					foreach (Drop drop in component.m_drops)
					{
						if ((Object)(object)drop.m_prefab == (Object)(object)trophyPrefab)
						{
							return val;
						}
					}
				}
			}
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab == (Object)null)
					{
						continue;
					}
					CharacterDrop component2 = prefab.GetComponent<CharacterDrop>();
					if ((Object)(object)component2 == (Object)null || component2.m_drops == null)
					{
						continue;
					}
					foreach (Drop drop2 in component2.m_drops)
					{
						if ((Object)(object)drop2.m_prefab == (Object)(object)trophyPrefab)
						{
							return prefab;
						}
					}
				}
			}
			return null;
		}

		private static Renderer FindMatchingRenderer(GameObject trophyClone, Renderer mobRenderer)
		{
			Texture val = (((Object)(object)mobRenderer != (Object)null && (Object)(object)mobRenderer.sharedMaterial != (Object)null) ? mobRenderer.sharedMaterial.mainTexture : null);
			string text = (((Object)(object)mobRenderer != (Object)null && (Object)(object)mobRenderer.sharedMaterial != (Object)null) ? ((Object)mobRenderer.sharedMaterial).name.Replace(" (Instance)", "") : null);
			Renderer[] componentsInChildren = trophyClone.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				if (val2.sharedMaterials == null)
				{
					continue;
				}
				Material[] sharedMaterials = val2.sharedMaterials;
				foreach (Material val3 in sharedMaterials)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						if ((Object)(object)val != (Object)null && (Object)(object)val3.mainTexture == (Object)(object)val)
						{
							return val2;
						}
						if (text != null && ((Object)val3).name.StartsWith(text))
						{
							return val2;
						}
					}
				}
			}
			if (componentsInChildren.Length != 0)
			{
				return componentsInChildren[0];
			}
			return null;
		}
	}
	public static class SharedDataCopy
	{
		public static T ShallowCopy<T>(T source) where T : class
		{
			return (T)(typeof(T).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(source, null));
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	public static class CharacterDrop_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(CharacterDrop __instance, ref List<KeyValuePair<GameObject, int>> __result)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Invalid comparison between Unknown and I4
			if ((Object)(object)__instance == (Object)null || __result == null || __result.Count == 0)
			{
				return;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			int level = component.GetLevel();
			if (level <= 1)
			{
				return;
			}
			int num = level - 2;
			if (num < 0 || num > 1)
			{
				return;
			}
			for (int i = 0; i < __result.Count; i++)
			{
				KeyValuePair<GameObject, int> keyValuePair = __result[i];
				if ((Object)(object)keyValuePair.Key == (Object)null)
				{
					continue;
				}
				ItemDrop component2 = keyValuePair.Key.GetComponent<ItemDrop>();
				if (!((Object)(object)component2 != (Object)null) || component2.m_itemData == null || (int)component2.m_itemData.m_shared.m_itemType != 13)
				{
					continue;
				}
				string name = ((Object)keyValuePair.Key).name;
				if (!StarTrophiesPlugin.KnownNonStarableTrophies.Contains(name))
				{
					string text = $"{name}_Star{num + 1}";
					GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(text) : PrefabManager.Instance.GetPrefab(text));
					if ((Object)(object)val != (Object)null)
					{
						__result[i] = new KeyValuePair<GameObject, int>(val, keyValuePair.Value);
					}
				}
			}
		}
	}
}