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 OreWeakSpots v0.9.3
plugins/OreWeakSpots/OreWeakSpots.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Networking; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace OreWeakSpots; public enum SpotColorOption { Blue, Gold } public enum CritSoundOption { Auto, File, Game, Mod, None } public enum CritNumberColorOption { Yellow, Red, Normal } [BepInPlugin("felih.OreWeakSpots", "Ore Weak Spots", "0.9.3")] public class Plugin : BaseUnityPlugin { public const string GUID = "felih.OreWeakSpots"; public const string NAME = "Ore Weak Spots"; public const string VERSION = "0.9.3"; public static ManualLogSource Log; public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> CritMultiplier; public static ConfigEntry<bool> CritUsesMidDamage; public static ConfigEntry<int> SpotCount; public static ConfigEntry<float> HitTolerance; public static ConfigEntry<float> SpotLifetime; public static ConfigEntry<float> MaxDistance; public static ConfigEntry<float> ActiveDuration; public static ConfigEntry<SpotColorOption> SpotColor; public static ConfigEntry<float> SpotSize; public static ConfigEntry<float> SoundVolume; public static ConfigEntry<CritSoundOption> CritSound; public static ConfigEntry<bool> AllRocks; public static ConfigEntry<string> OreNames; public static ConfigEntry<string> Excluded; public static ConfigEntry<float> MinSpacing; public static ConfigEntry<CritNumberColorOption> CritNumberColor; public static ConfigEntry<float> CritNumberScale; public static ConfigEntry<bool> DebugLog; private Harmony _harmony; private void Awake() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Expected O, but got Unknown //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Enabled", true, "Turns the mod on or off."); CritMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("1 - General", "CritMultiplier", 2f, new ConfigDescription("Pickaxe damage multiplier when you hit a weak spot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), new object[0])); CritUsesMidDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "CritUsesMidDamage", true, "Always use 2x mid damage: a crit ignores the game's random damage roll and uses the middle of your pickaxe skill's damage range before multiplying, so crits are never weak. Off = the crit multiplies whatever the game rolled."); AllRocks = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "AllRocks", true, "If on, weak spots appear on any rock, not only on ores."); OreNames = ((BaseUnityPlugin)this).Config.Bind<string>("1 - General", "OreNames", "copper,silver,obsidian,mudpile,meteorite,flametal,softtissue,giant,blackmarble,iron", "Parts of object names that count as ore (comma-separated). Used when AllRocks is off."); Excluded = ((BaseUnityPlugin)this).Config.Bind<string>("1 - General", "Exclude", "tin", "Parts of rock names that NEVER get weak spots, even with AllRocks on (comma-separated). Default: tin, which is too small."); SpotCount = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Weak spots", "Count", 4, new ConfigDescription("How many weak spots appear at the same time.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), new object[0])); MinSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Weak spots", "MinSpacing", 1.2f, new ConfigDescription("Minimum distance (meters) between two weak spots. On a rock that is too small, fewer spots appear instead of crowding together.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 5f), new object[0])); HitTolerance = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Weak spots", "HitTolerance", 0.6f, new ConfigDescription("Maximum distance (meters) between the hit and the spot for a crit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[0])); SpotLifetime = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Weak spots", "SpotLifetime", 5f, new ConfigDescription("Seconds each spot stays visible before it moves.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[0])); MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Weak spots", "MaxDistance", 8f, new ConfigDescription("Maximum distance (meters) from your eyes where a spot can appear. Spots spread over the whole ore surface within this distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), new object[0])); ActiveDuration = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Weak spots", "IdleTimeout", 3f, new ConfigDescription("Seconds without aiming at or hitting the ore before the spots disappear.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), new object[0])); SpotColor = ((BaseUnityPlugin)this).Config.Bind<SpotColorOption>("3 - Visuals", "Color", SpotColorOption.Gold, "Weak spot color."); SpotSize = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Visuals", "Size", 1f, new ConfigDescription("Scale of the glowing orbs (1 = about 16 cm).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), new object[0])); SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Visuals", "SoundVolume", 1f, new ConfigDescription("Crit sound volume (0 = off). Also follows the game's effects volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); CritSound = ((BaseUnityPlugin)this).Config.Bind<CritSoundOption>("3 - Visuals", "CritSound", CritSoundOption.Auto, "Auto = a file from the mod's SFX folder if there is one, otherwise the game sound. File = only .wav/.ogg files from BepInEx/plugins/OreWeakSpots/SFX (one at random). Game = Valheim's sound for hitting a staggered enemy. Mod = the mod's own chime. None = no sound."); CritNumberColor = ((BaseUnityPlugin)this).Config.Bind<CritNumberColorOption>("3 - Visuals", "CritNumberColor", CritNumberColorOption.Yellow, "Color of a crit's damage number. Normal = the game's default color."); CritNumberScale = ((BaseUnityPlugin)this).Config.Bind<float>("3 - Visuals", "CritNumberSize", 2f, new ConfigDescription("Size of a crit's damage number (2 = double, 1 = unchanged).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4f), new object[0])); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("9 - Debug", "DetailedLog", false, "Writes each hit, where the spots were placed and the distance from the hit to the spot to the BepInEx log (helps tuning)."); GameObject val = new GameObject("OreWeakSpots_Manager"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<WeakSpotManager>(); _harmony = new Harmony("felih.OreWeakSpots"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"Ore Weak Spots 0.9.3 loaded."); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } } [HarmonyPatch] internal static class DamagePatches { [HarmonyPatch(typeof(MineRock5), "Damage")] [HarmonyPrefix] private static void MineRock5Damage(MineRock5 __instance, HitData __0) { WeakSpotManager.OnPickaxeHit((Component)(object)__instance, __0); } [HarmonyPatch(typeof(MineRock), "Damage")] [HarmonyPrefix] private static void MineRockDamage(MineRock __instance, HitData __0) { WeakSpotManager.OnPickaxeHit((Component)(object)__instance, __0); } [HarmonyPatch(typeof(Destructible), "Damage")] [HarmonyPrefix] private static void DestructibleDamage(Destructible __instance, HitData __0) { WeakSpotManager.OnPickaxeHit((Component)(object)__instance, __0); } } [HarmonyPatch(typeof(Skills), "GetRandomSkillFactor")] internal static class SkillRollPatch { private static void Postfix(Skills __instance, SkillType __0, float __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) WeakSpotManager.NoteSkillRoll(__instance, __0, __result); } } [HarmonyPatch(typeof(DamageText), "AddInworldText")] internal static class CritNumberPatch { private static FieldInfo _worldTexts; private static FieldInfo _textField; private static void Postfix(DamageText __instance, Vector3 pos, string text) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) try { bool flag = WeakSpotManager.IsRecentCrit(pos); if (Plugin.DebugLog.Value && (flag || WeakSpotManager.IsRecentHit(pos))) { Plugin.Log.LogInfo((object)("On-screen number: " + text + (flag ? " (crit)" : ""))); } if (!flag) { return; } if (_worldTexts == null) { _worldTexts = AccessTools.Field(typeof(DamageText), "m_worldTexts"); } if (!(_worldTexts.GetValue(__instance) is IList { Count: not 0 } list)) { return; } object obj = list[list.Count - 1]; if (_textField == null) { _textField = AccessTools.Field(obj.GetType(), "m_textField"); } object value = _textField.GetValue(obj); if (value != null) { Type type = value.GetType(); if (Plugin.CritNumberColor.Value != CritNumberColorOption.Normal) { Color val = ((Plugin.CritNumberColor.Value == CritNumberColorOption.Red) ? new Color(1f, 0.18f, 0.12f) : new Color(1f, 0.82f, 0.1f)); type.GetProperty("color").SetValue(value, val, null); } PropertyInfo property = type.GetProperty("fontSize"); float num = (float)property.GetValue(value, null); property.SetValue(value, num * Plugin.CritNumberScale.Value, null); } } catch (Exception ex) { if (Plugin.DebugLog.Value) { Plugin.Log.LogWarning((object)("CritNumberPatch: " + ex.Message)); } } } } public class WeakSpotManager : MonoBehaviour { private static WeakSpotManager _inst; private Component _target; private float _lastSeenTime; private float _nextScan; private Vector3 _anchor; private readonly List<WeakSpot> _spots = new List<WeakSpot>(); private int _critFrame = -1; private Texture2D _glowTex; private Mesh _quadMesh; private Mesh _sphereMesh; private Shader _shader; private AudioClip _critClip; private static float _lastRoll = 1f; private static float _midRoll = 1f; private static float _rollTime = -100f; private static float _lastHitTime = -100f; private static Vector3 _lastHitPos; private static float _lastCritTime = -100f; private static Vector3 _lastCritPos; private readonly List<AudioClip> _fileClips = new List<AudioClip>(); private readonly List<AudioClip> _gameClips = new List<AudioClip>(); private AudioMixerGroup _mixerGroup; private bool _gameSoundSearched; private AudioSource _playerAudio; private Player _audioOwner; public static FieldInfo FindField(Type t, string name) { while (t != null) { FieldInfo field = t.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } t = t.BaseType; } return null; } private void Awake() { _inst = this; _glowTex = MakeGlowTexture(64); _quadMesh = MakeQuadMesh(); GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); _sphereMesh = val.GetComponent<MeshFilter>().sharedMesh; Object.Destroy((Object)(object)val); string[] array = new string[4] { "Sprites/Default", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Transparent", "UI/Default" }; for (int i = 0; i < array.Length; i++) { if (!((Object)(object)_shader == (Object)null)) { break; } _shader = Shader.Find(array[i]); if ((Object)(object)_shader != (Object)null) { Plugin.Log.LogInfo((object)("Shader in use: " + array[i])); } } if ((Object)(object)_shader == (Object)null) { Plugin.Log.LogWarning((object)"No transparent shader found; only the spot's light will be visible."); } _critClip = MakeCritClip(); ((MonoBehaviour)this).StartCoroutine(LoadSoundFiles()); } public static void OnPickaxeHit(Component rock, HitData hit) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_0081: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_inst == (Object)null || hit == null || (Object)(object)rock == (Object)null || !Plugin.Enabled.Value) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Character attacker = hit.GetAttacker(); string text = null; if ((Object)(object)attacker != (Object)(object)localPlayer) { text = "hit is not from the local player (" + (((Object)(object)attacker == (Object)null) ? "null" : ((Object)attacker).name) + ")"; } else if ((int)hit.m_skill != 12) { text = string.Concat("tool is not a pickaxe (", hit.m_skill, ")"); } else if (!IsOre(rock)) { text = "not in the ore list"; } if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Hit on " + OreId(rock) + " (" + ((object)rock).GetType().Name + "): " + ((text == null) ? "accepted" : ("ignored, " + text)))); } if (text == null) { _inst.HandleHit(rock, hit); } } } private static ZNetView NViewOf(Component rock) { ZNetView val = null; FieldInfo fieldInfo = FindField(((object)rock).GetType(), "m_nview"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(rock); val = (ZNetView)((value is ZNetView) ? value : null); } if ((Object)(object)val == (Object)null) { val = rock.GetComponentInParent<ZNetView>(); } return val; } private static Transform RootOf(Component rock) { ZNetView val = NViewOf(rock); if (!((Object)(object)val != (Object)null)) { return rock.transform.root; } return ((Component)val).transform; } private static string OreId(Component rock) { string text = ((Object)rock.gameObject).name; ZNetView val = NViewOf(rock); if ((Object)(object)val != (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { ZDO zDO = val.GetZDO(); if (zDO != null) { GameObject prefab = ZNetScene.instance.GetPrefab(zDO.GetPrefab()); if ((Object)(object)prefab != (Object)null) { text = ((Object)prefab).name; } } } FieldInfo fieldInfo = FindField(((object)rock).GetType(), "m_name"); if (fieldInfo != null) { string text2 = fieldInfo.GetValue(rock) as string; if (!string.IsNullOrEmpty(text2)) { text = text + " " + text2; } } return text; } private bool BelongsToTarget(Collider c) { Transform transform = ((Component)c).transform; if (!transform.IsChildOf(RootOf(_target))) { return transform.IsChildOf(_target.transform); } return true; } private static bool NameMatches(string name, string list) { string[] array = list.ToLowerInvariant().Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && name.Contains(text)) { return true; } } return false; } private static bool IsOre(Component rock) { string name = OreId(rock).ToLowerInvariant(); if (NameMatches(name, Plugin.Excluded.Value)) { return false; } if (!IsRock(rock)) { return false; } if (Plugin.AllRocks.Value) { return true; } if (NameMatches(name, Plugin.OreNames.Value)) { return true; } return DropsMoreThanStone(rock, 0); } private static bool IsRock(Component rock) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_002c: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 Destructible val = (Destructible)(object)((rock is Destructible) ? rock : null); if ((Object)(object)val == (Object)null) { return true; } DamageModifier pickaxe = val.m_damages.m_pickaxe; DamageModifier chop = val.m_damages.m_chop; bool flag = (int)pickaxe != 3 && (int)pickaxe != 4; bool result = (int)chop == 3 || (int)chop == 4; if (flag) { return result; } return false; } private static bool DropsMoreThanStone(Component rock, int depth) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) DropTable val = null; FieldInfo fieldInfo = FindField(((object)rock).GetType(), "m_dropItems"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(rock); val = (DropTable)((value is DropTable) ? value : null); } Destructible val2 = (Destructible)(object)((rock is Destructible) ? rock : null); if ((Object)(object)val2 != (Object)null) { DropOnDestroyed component = ((Component)val2).GetComponent<DropOnDestroyed>(); if ((Object)(object)component != (Object)null) { val = component.m_dropWhenDestroyed; } if ((val == null || val.m_drops == null || val.m_drops.Count == 0) && (Object)(object)val2.m_spawnWhenDestroyed != (Object)null && depth < 2) { Component component2 = (Component)(object)val2.m_spawnWhenDestroyed.GetComponent<MineRock5>(); if ((Object)(object)component2 == (Object)null) { component2 = (Component)(object)val2.m_spawnWhenDestroyed.GetComponent<MineRock>(); } if ((Object)(object)component2 != (Object)null) { return DropsMoreThanStone(component2, depth + 1); } } } if (val == null || val.m_drops == null) { return false; } for (int i = 0; i < val.m_drops.Count; i++) { GameObject item = val.m_drops[i].m_item; if ((Object)(object)item != (Object)null && ((Object)item).name != "Stone") { return true; } } return false; } private void SetTarget(Component rock, Vector3 anchor) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ClearSpots(); _target = rock; _anchor = anchor; _lastSeenTime = Time.time; if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Marking " + OreId(rock) + " (" + ((object)rock).GetType().Name + ") with " + Plugin.SpotCount.Value + " weak spots.")); } for (int i = 0; i < Plugin.SpotCount.Value; i++) { WeakSpot weakSpot = CreateSpot(); weakSpot.Relocate((float)i * 0.3f); _spots.Add(weakSpot); } } private void HandleHit(Component rock, HitData hit) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) _lastSeenTime = Time.time; NoteHit(hit); if (_critFrame == Time.frameCount && (Object)(object)_target == (Object)(object)rock) { ApplyCrit(hit); return; } if ((Object)(object)_target != (Object)(object)rock) { SetTarget(rock, hit.m_point); return; } WeakSpot weakSpot = null; float num = float.MaxValue; for (int i = 0; i < _spots.Count; i++) { WeakSpot weakSpot2 = _spots[i]; if (weakSpot2.IsHittable) { float num2 = Vector3.Distance(weakSpot2.Position, hit.m_point); if (num2 < num) { num = num2; weakSpot = weakSpot2; } } } if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Hit on " + ((Object)rock).name + ": distance to the nearest spot = " + ((weakSpot == null) ? "no spot" : (num.ToString("0.00") + " m")))); } if (weakSpot != null && num <= Plugin.HitTolerance.Value) { _critFrame = Time.frameCount; ApplyCrit(hit); PlayCritEffects(weakSpot.Position, weakSpot.Color); weakSpot.Relocate(0.5f); } } private void ApplyCrit(HitData hit) { float pickaxe = hit.m_damage.m_pickaxe; string text = ""; if (Plugin.CritUsesMidDamage.Value && Time.time - _rollTime < 1f && _lastRoll > 0.01f) { hit.m_damage.m_pickaxe = hit.m_damage.m_pickaxe / _lastRoll * _midRoll; text = ", roll " + _lastRoll.ToString("0.00") + " → mid " + _midRoll.ToString("0.00"); } ref DamageTypes damage = ref hit.m_damage; damage.m_pickaxe *= Plugin.CritMultiplier.Value; if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Crit: pickaxe damage " + pickaxe.ToString("0.0") + " → " + hit.m_damage.m_pickaxe.ToString("0.0") + " (x" + Plugin.CritMultiplier.Value.ToString("0.##") + text + ")")); } } public static void NoteSkillRoll(Skills skills, SkillType skill, float roll) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((int)skill == 12) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)skills != (Object)(object)((Character)localPlayer).GetSkills())) { float num = Mathf.Lerp(0.4f, 1f, skills.GetSkillFactor(skill)); _midRoll = (Mathf.Clamp01(num - 0.15f) + Mathf.Clamp01(num + 0.15f)) * 0.5f; _lastRoll = roll; _rollTime = Time.time; } } } private static void NoteHit(HitData hit) { //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) _lastHitTime = Time.time; _lastHitPos = hit.m_point; if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Hit damage: pickaxe " + hit.m_damage.m_pickaxe.ToString("0.0") + ", total " + ((DamageTypes)(ref hit.m_damage)).GetTotalDamage().ToString("0.0"))); } } public static bool IsRecentHit(Vector3 pos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001d: Unknown result type (might be due to invalid IL or missing references) if (Time.time - _lastHitTime < 1.5f) { Vector3 val = pos - _lastHitPos; return ((Vector3)(ref val)).sqrMagnitude < 16f; } return false; } private void Update() { //IL_0094: 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) if ((Object)(object)_target == (Object)null && _spots.Count > 0) { ClearSpots(); } Player localPlayer = Player.m_localPlayer; if (!Plugin.Enabled.Value || (Object)(object)localPlayer == (Object)null || !HoldingPickaxe(localPlayer)) { if ((Object)(object)_target != (Object)null) { ClearSpots(); } return; } if (Time.time >= _nextScan) { _nextScan = Time.time + 0.1f; ScanAimedOre(localPlayer); } if ((Object)(object)_target == (Object)null) { return; } bool flag = Vector3.Distance(((Component)localPlayer).transform.position, _anchor) > 10f; bool flag2 = Time.time - _lastSeenTime > Plugin.ActiveDuration.Value; if (flag || flag2) { ClearSpots(); return; } Camera main = Camera.main; for (int i = 0; i < _spots.Count; i++) { _spots[i].Tick(main); } } private static bool HoldingPickaxe(Player player) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon != null && currentWeapon.m_shared != null) { return (int)currentWeapon.m_shared.m_skillType == 12; } return false; } private void ScanAimedOre(Player player) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return; } Component componentInParent = (Component)(object)hoverObject.GetComponentInParent<MineRock5>(); if ((Object)(object)componentInParent == (Object)null) { componentInParent = (Component)(object)hoverObject.GetComponentInParent<MineRock>(); } if ((Object)(object)componentInParent == (Object)null) { componentInParent = (Component)(object)hoverObject.GetComponentInParent<Destructible>(); } if ((Object)(object)componentInParent == (Object)null || !IsOre(componentInParent)) { return; } Vector3 point; bool flag = AimPointOn(componentInParent, out point); if ((Object)(object)componentInParent != (Object)(object)_target) { SetTarget(componentInParent, flag ? point : hoverObject.transform.position); return; } _lastSeenTime = Time.time; if (flag) { _anchor = point; } } private bool AimPointOn(Component rock, out Vector3 point) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) point = Vector3.zero; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } RaycastHit[] array = Physics.RaycastAll(((Component)main).transform.position, ((Component)main).transform.forward, 30f, -1, (QueryTriggerInteraction)1); float num = float.MaxValue; Component target = _target; _target = rock; for (int i = 0; i < array.Length; i++) { if (((RaycastHit)(ref array[i])).distance < num && BelongsToTarget(((RaycastHit)(ref array[i])).collider)) { num = ((RaycastHit)(ref array[i])).distance; point = ((RaycastHit)(ref array[i])).point; } } _target = target; return num < float.MaxValue; } private void ClearSpots() { for (int i = 0; i < _spots.Count; i++) { _spots[i].Destroy(); } _spots.Clear(); _target = null; } private bool TargetBounds(out Bounds bounds) { //IL_0001: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool flag = false; Transform[] array = (Transform[])(object)new Transform[2] { RootOf(_target), _target.transform }; for (int i = 0; i < array.Length && (i != 1 || !((Object)(object)array[1] == (Object)(object)array[0])); i++) { Collider[] componentsInChildren = ((Component)array[i]).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger && ((Component)val).gameObject.activeInHierarchy) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } } return flag; } public bool FindSurfacePoint(WeakSpot self, out Vector3 pos, out Vector3 normal, out Collider col) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) pos = Vector3.zero; normal = Vector3.up; col = null; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)_target == (Object)null) { return false; } if (!TargetBounds(out var bounds)) { return false; } Vector3 eyePoint = ((Character)localPlayer).GetEyePoint(); float value = Plugin.MaxDistance.Value; float value2 = Plugin.MinSpacing.Value; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; string text = ""; for (int i = 0; i < 50; i++) { Vector3 val = ((Bounds)(ref bounds)).center + Vector3.Scale(Random.insideUnitSphere, ((Bounds)(ref bounds)).extents); Vector3 val2 = val - eyePoint; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude < 0.1f) { continue; } val2 /= magnitude; Vector3 val3 = val2; Vector3 size = ((Bounds)(ref bounds)).size; RaycastHit[] array = Physics.RaycastAll(eyePoint, val3, magnitude + ((Vector3)(ref size)).magnitude, -1, (QueryTriggerInteraction)1); if (array.Length == 0) { num++; continue; } Array.Sort(array, (RaycastHit h1, RaycastHit h2) => ((RaycastHit)(ref h1)).distance.CompareTo(((RaycastHit)(ref h2)).distance)); RaycastHit val4 = default(RaycastHit); bool flag = false; for (int num5 = 0; num5 < array.Length; num5++) { if (!((Component)((RaycastHit)(ref array[num5])).collider).transform.IsChildOf(((Component)localPlayer).transform)) { val4 = array[num5]; flag = true; break; } } if (!flag) { num++; continue; } if (!BelongsToTarget(((RaycastHit)(ref val4)).collider)) { num2++; text = ((Object)((RaycastHit)(ref val4)).collider).name + " (layer " + LayerMask.LayerToName(((Component)((RaycastHit)(ref val4)).collider).gameObject.layer) + ")"; continue; } if (((RaycastHit)(ref val4)).distance > value) { num3++; continue; } bool flag2 = false; for (int num6 = 0; num6 < _spots.Count; num6++) { WeakSpot weakSpot = _spots[num6]; if (weakSpot != self && weakSpot.IsPlaced && Vector3.Distance(weakSpot.Position, ((RaycastHit)(ref val4)).point) < value2) { flag2 = true; break; } } if (flag2) { num4++; continue; } pos = ((RaycastHit)(ref val4)).point; normal = ((RaycastHit)(ref val4)).normal; col = ((RaycastHit)(ref val4)).collider; if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Weak spot placed on " + ((Object)((RaycastHit)(ref val4)).collider).name + " a " + ((RaycastHit)(ref val4)).distance.ToString("0.0") + " m from the eyes.")); } return true; } if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("No place found for the weak spot: no hit=" + num + ", blocked=" + num2 + ((num2 > 0) ? (" by " + text) : "") + ", far=" + num3 + ", near another=" + num4)); } return false; } public Color CurrentColor() { //IL_0030: 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 (Plugin.SpotColor.Value != SpotColorOption.Blue) { return new Color(1f, 0.78f, 0.25f); } return new Color(0.35f, 0.75f, 1f); } private WeakSpot CreateSpot() { return new WeakSpot(this); } private static Mesh MakeQuadMesh() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh(); ((Object)val).name = "OreWeakSpots_Quad"; val.vertices = (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, -0.5f, 0f), new Vector3(0.5f, -0.5f, 0f), new Vector3(-0.5f, 0.5f, 0f), new Vector3(0.5f, 0.5f, 0f) }; val.uv = (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f) }; val.triangles = new int[6] { 0, 2, 1, 2, 3, 1 }; val.RecalculateNormals(); val.RecalculateBounds(); return val; } public GameObject MakeSphere(string name, Transform parent, float diameter) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001a: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localScale = Vector3.one * diameter; val.AddComponent<MeshFilter>().sharedMesh = _sphereMesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; if ((Object)(object)_shader != (Object)null && (Object)(object)_sphereMesh != (Object)null) { Material val3 = new Material(_shader); val3.mainTexture = (Texture)(object)Texture2D.whiteTexture; val3.renderQueue = 3101; ((Renderer)val2).material = val3; } else { ((Renderer)val2).enabled = false; } return val; } public GameObject MakeQuad(string name, Transform parent, float size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_001a: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localScale = Vector3.one * size; val.AddComponent<MeshFilter>().sharedMesh = _quadMesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; if ((Object)(object)_shader != (Object)null) { Material val3 = new Material(_shader); val3.mainTexture = (Texture)(object)_glowTex; val3.renderQueue = 3100; ((Renderer)val2).material = val3; } else { ((Renderer)val2).enabled = false; } return val; } public static bool IsRecentCrit(Vector3 pos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001d: Unknown result type (might be due to invalid IL or missing references) if (Time.time - _lastCritTime < 1.5f) { Vector3 val = pos - _lastCritPos; return ((Vector3)(ref val)).sqrMagnitude < 16f; } return false; } private void PlayCritEffects(Vector3 pos, Color color) { //IL_000a: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0021: 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) _lastCritTime = Time.time; _lastCritPos = pos; GameObject val = new GameObject("OreWeakSpots_Burst"); val.transform.position = pos; val.AddComponent<CritBurst>().Init(this, color); PlayCritSound(); } private void PlayCritSound() { float value = Plugin.SoundVolume.Value; CritSoundOption value2 = Plugin.CritSound.Value; if (value <= 0f || value2 == CritSoundOption.None) { return; } FindGameCritSound(); List<AudioClip> list = null; switch (value2) { case CritSoundOption.Auto: list = ((_fileClips.Count > 0) ? _fileClips : ((_gameClips.Count > 0) ? _gameClips : null)); break; case CritSoundOption.File: list = ((_fileClips.Count > 0) ? _fileClips : null); break; case CritSoundOption.Game: list = ((_gameClips.Count > 0) ? _gameClips : null); break; } AudioClip val = ((list != null) ? list[Random.Range(0, list.Count)] : _critClip); AudioSource playerAudio = GetPlayerAudio(); if (!((Object)(object)playerAudio == (Object)null) && !((Object)(object)val == (Object)null)) { playerAudio.pitch = Random.Range(0.95f, 1.05f); playerAudio.PlayOneShot(val, value); if (Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)("Crit sound: " + ((Object)val).name)); } } } private AudioSource GetPlayerAudio() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return null; } if ((Object)(object)_playerAudio != (Object)null && (Object)(object)_audioOwner == (Object)(object)localPlayer) { return _playerAudio; } GameObject val = new GameObject("OreWeakSpots_SFX"); val.transform.SetParent(((Component)localPlayer).transform, false); val.transform.localPosition = Vector3.up * 1.5f; _playerAudio = val.AddComponent<AudioSource>(); _playerAudio.playOnAwake = false; _playerAudio.loop = false; _playerAudio.spatialBlend = 0f; _playerAudio.outputAudioMixerGroup = (((Object)(object)_mixerGroup != (Object)null) ? _mixerGroup : FindAnyMixerGroup(localPlayer)); _audioOwner = localPlayer; return _playerAudio; } private static AudioMixerGroup FindAnyMixerGroup(Player p) { AudioSource[] componentsInChildren = ((Component)p).GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i].outputAudioMixerGroup != (Object)null) { return componentsInChildren[i].outputAudioMixerGroup; } } return null; } private void FindGameCritSound() { if (_gameSoundSearched || (Object)(object)ZNetScene.instance == (Object)null) { return; } _gameSoundSearched = true; string[] array = new string[6] { "Greydwarf", "Skeleton", "Draugr", "Troll", "Boar", "Deer" }; for (int i = 0; i < array.Length; i++) { if (_gameClips.Count != 0) { break; } GameObject prefab = ZNetScene.instance.GetPrefab(array[i]); if ((Object)(object)prefab == (Object)null) { continue; } Character component = prefab.GetComponent<Character>(); if ((Object)(object)component == (Object)null || component.m_critHitEffects == null || component.m_critHitEffects.m_effectPrefabs == null) { continue; } EffectData[] effectPrefabs = component.m_critHitEffects.m_effectPrefabs; for (int j = 0; j < effectPrefabs.Length; j++) { if ((Object)(object)effectPrefabs[j].m_prefab != (Object)null) { CollectClips(effectPrefabs[j].m_prefab); } } } Plugin.Log.LogInfo((object)("Game stagger sound: " + _gameClips.Count + " clip(s)" + (((Object)(object)_mixerGroup != (Object)null) ? (", channel " + ((Object)_mixerGroup).name) : ", no audio channel"))); } private void CollectClips(GameObject fx) { Component[] componentsInChildren = fx.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } FieldInfo fieldInfo = FindField(((object)val).GetType(), "m_audioClips"); if (fieldInfo != null && fieldInfo.GetValue(val) is AudioClip[] array) { for (int j = 0; j < array.Length; j++) { if ((Object)(object)array[j] != (Object)null && !_gameClips.Contains(array[j])) { _gameClips.Add(array[j]); } } } AudioSource val2 = (AudioSource)(object)((val is AudioSource) ? val : null); if ((Object)(object)val2 != (Object)null) { if ((Object)(object)val2.clip != (Object)null && !_gameClips.Contains(val2.clip)) { _gameClips.Add(val2.clip); } if ((Object)(object)_mixerGroup == (Object)null && (Object)(object)val2.outputAudioMixerGroup != (Object)null) { _mixerGroup = val2.outputAudioMixerGroup; } } } } private IEnumerator LoadSoundFiles() { string dir = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "SFX"); if (!Directory.Exists(dir)) { try { Directory.CreateDirectory(dir); yield break; } catch { yield break; } } string[] files = Directory.GetFiles(dir); for (int i = 0; i < files.Length; i++) { string ext = Path.GetExtension(files[i]).ToLowerInvariant(); AudioType type = (AudioType)((ext == ".wav") ? 20 : ((ext == ".ogg") ? 14 : 0)); if ((int)type == 0) { continue; } UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file:///" + files[i].Replace('\\', '/'), type); try { yield return req.SendWebRequest(); AudioClip clip = (((int)req.result == 1) ? DownloadHandlerAudioClip.GetContent(req) : null); if ((Object)(object)clip != (Object)null) { ((Object)clip).name = Path.GetFileNameWithoutExtension(files[i]); _fileClips.Add(clip); Plugin.Log.LogInfo((object)("Sound loaded: " + Path.GetFileName(files[i]))); } else { Plugin.Log.LogWarning((object)("Could not load sound " + files[i] + ": " + req.error)); } } finally { ((IDisposable)req)?.Dispose(); } } } private static Texture2D MakeGlowTexture(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; float num = (float)(size - 1) / 2f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)) / num; float num3 = Mathf.Clamp01(1f - num2 * 3f); float num4 = Mathf.Pow(Mathf.Clamp01(1f - num2), 2.2f); float num5 = Mathf.Clamp01(num4 * 0.8f + num3); val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(); return val; } private static AudioClip MakeCritClip() { int num = 44100; int num2 = (int)((float)num * 0.35f); float[] array = new float[num2]; for (int i = 0; i < num2; i++) { float num3 = (float)i / (float)num; float num4 = Mathf.Exp((0f - num3) * 14f); float num5 = Mathf.Clamp01(num3 * 400f); array[i] = num5 * num4 * (0.55f * Mathf.Sin((float)Math.PI * 3136f * num3) + 0.3f * Mathf.Sin((float)Math.PI * 4698f * num3) + 0.15f * Mathf.Sin((float)Math.PI * 6272f * num3)); } AudioClip val = AudioClip.Create("OreWeakSpots_Crit", num2, 1, num, false); val.SetData(array, 0); return val; } } public class WeakSpot { private const float FadeIn = 0.5f; private const float FadeOut = 0.7f; private readonly WeakSpotManager _mgr; private readonly GameObject _root; private readonly Transform _orb; private readonly Transform _halo; private readonly Material _orbMat; private readonly Material _haloMat; private readonly Light _light; private readonly float _orbSize; private readonly float _haloSize; private Collider _surface; private Vector3 _normal = Vector3.up; private float _bornAt; private float _lifetime; private bool _placed; private float _retryAt; public Color Color { get; private set; } public Vector3 Position => _orb.position; public bool IsPlaced => _placed; public bool IsHittable { get { if (_placed) { return Time.time >= _bornAt; } return false; } } public WeakSpot(WeakSpotManager mgr) { //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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown _mgr = mgr; _root = new GameObject("OreWeakSpot"); float value = Plugin.SpotSize.Value; _orbSize = 0.16f * value; _haloSize = 0.55f * value; GameObject val = mgr.MakeSphere("Orb", _root.transform, _orbSize); GameObject val2 = mgr.MakeQuad("Halo", _root.transform, _haloSize); _orb = val.transform; _halo = val2.transform; _orbMat = ((Renderer)val.GetComponent<MeshRenderer>()).material; _haloMat = ((Renderer)val2.GetComponent<MeshRenderer>()).material; _light = val.AddComponent<Light>(); _light.type = (LightType)2; _light.range = 1.3f; _light.shadows = (LightShadows)0; _root.SetActive(false); } public void Relocate(float delay) { _placed = false; _root.SetActive(false); _retryAt = Time.time + delay; } private void TryPlace() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!_mgr.FindSurfacePoint(this, out var pos, out var normal, out var col)) { _retryAt = Time.time + 0.5f; return; } _root.transform.position = pos; _root.transform.rotation = Quaternion.identity; _normal = normal; _surface = col; Color = _mgr.CurrentColor(); _lifetime = Plugin.SpotLifetime.Value * Random.Range(0.85f, 1.15f); _bornAt = Time.time; _placed = true; _root.SetActive(true); } public void Tick(Camera cam) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) if (!_placed) { if (Time.time >= _retryAt) { TryPlace(); } return; } if ((Object)(object)_surface == (Object)null || !_surface.enabled || !((Component)_surface).gameObject.activeInHierarchy) { Relocate(0.2f); return; } float num = Time.time - _bornAt; if (num > _lifetime) { Relocate(0.4f); return; } float num2 = Mathf.SmoothStep(0f, 1f, num / 0.5f); float num3 = Mathf.SmoothStep(0f, 1f, (_lifetime - num) / 0.7f); float num4 = num2 * num3; float num5 = 0.8f + 0.2f * Mathf.Sin(num * 6f); float num6 = Mathf.Lerp(0.3f, 1f, num4); float num7 = _orbSize * num6 * (0.95f + 0.05f * num5); _orb.localPosition = _normal * (num7 * 0.35f); _orb.localScale = Vector3.one * num7; _halo.localPosition = _orb.localPosition; _halo.localScale = Vector3.one * (_haloSize * num6 * num5); Color color = Color; _orbMat.color = new Color(Mathf.Lerp(color.r, 1f, 0.45f), Mathf.Lerp(color.g, 1f, 0.45f), Mathf.Lerp(color.b, 1f, 0.45f), num4); _haloMat.color = new Color(color.r, color.g, color.b, 0.55f * num4 * num5); _light.color = color; _light.intensity = 1.8f * num4 * num5; if ((Object)(object)cam != (Object)null) { _halo.rotation = ((Component)cam).transform.rotation; } } public void Destroy() { Object.Destroy((Object)(object)_root); Object.Destroy((Object)(object)_orbMat); Object.Destroy((Object)(object)_haloMat); } } public class CritBurst : MonoBehaviour { private const float Duration = 0.4f; private float _start; private Material _mat; private Light _light; private Color _color; private Transform _quad; public void Init(WeakSpotManager mgr, Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) _start = Time.time; _color = color; GameObject val = mgr.MakeQuad("Flash", ((Component)this).transform, 0.4f); _quad = val.transform; _mat = ((Renderer)val.GetComponent<MeshRenderer>()).material; _light = ((Component)this).gameObject.AddComponent<Light>(); _light.type = (LightType)2; _light.range = 3f; _light.color = color; _light.shadows = (LightShadows)0; } private void Update() { //IL_0040: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) float num = (Time.time - _start) / 0.4f; if (num >= 1f) { Object.Destroy((Object)(object)_mat); Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num2 = 1f - num; _quad.localScale = Vector3.one * Mathf.Lerp(0.4f, 1.6f, num); _mat.color = new Color(Mathf.Lerp(_color.r, 1f, 0.4f), Mathf.Lerp(_color.g, 1f, 0.4f), Mathf.Lerp(_color.b, 1f, 0.4f), num2); _light.intensity = 5f * num2; Camera main = Camera.main; if ((Object)(object)main != (Object)null) { ((Component)this).transform.rotation = ((Component)main).transform.rotation; } } }