plugins/Nero/Nero.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
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 Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NeroMod
{
	[BepInPlugin("com.tronn.nero", "Nero", "1.7.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class NeroPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.tronn.nero";

		public const string PluginName = "Nero";

		public const string PluginVersion = "1.7.2";

		internal static string PluginDir;

		private ConfigEntry<float> _scale;

		internal static ConfigEntry<bool> Invincible;

		internal static ConfigEntry<float> DamageMultiplier;

		internal static ConfigEntry<bool> MapPin;

		internal static ConfigEntry<bool> OwnerOnly;

		internal static ConfigEntry<string> OwnerName;

		internal static ConfigEntry<float> BallHeldX;

		internal static ConfigEntry<float> BallHeldY;

		internal static ConfigEntry<float> BallHeldZ;

		private static FieldInfo _cheatField;

		internal const string OwnerKey = "nero_owner";

		private Minimap _pinMap;

		private PinData _pin;

		private Character _nero;

		private float _scanTimer;

		private Sprite _pinIcon;

		private bool _pinIconTried;

		private static readonly FieldInfo PinsField = typeof(Minimap).GetField("m_pins", BindingFlags.Instance | BindingFlags.NonPublic);

		private Vector3 _ballPos;

		private bool _ballKnown;

		private void Awake()
		{
			//IL_0153: 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_0168: Expected O, but got Unknown
			PluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			_scale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Scale", 0.85f, "Visual scale of Nero relative to a vanilla Wolf (1.0 = wolf size).");
			Invincible = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Invincible", true, "Nero takes no damage from anything (mobs, falls, fire...). The only exception: a player hitting him directly while devcommands are enabled, so an admin can still remove him.");
			DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DamageMultiplier", 0.25f, "Multiplier on the damage Nero deals to enemies (1.0 = full vanilla Wolf damage).");
			MapPin = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MapPin", true, "Show Nero on the map and minimap, like a player marker, for every player running the mod. If Nero's area unloads, the pin stays at his last known spot.");
			OwnerOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Ownership", "OwnerOnly", true, "Only the player who claims Nero can command him. Nobody else can tame him.");
			OwnerName = ((BaseUnityPlugin)this).Config.Bind<string>("Ownership", "OwnerName", "Flyn", "Only this character name may claim and command Nero (case-insensitive). Empty = the first player to interact with him claims him. Everyone else can pet and feed him, but he only follows his owner.");
			BallHeldX = ((BaseUnityPlugin)this).Config.Bind<float>("Neroball", "HeldOffsetX", 0f, "Nudge the held ball sideways in the hand, meters. Needs a game restart.");
			BallHeldY = ((BaseUnityPlugin)this).Config.Bind<float>("Neroball", "HeldOffsetY", 0f, "Nudge the held ball up/down in the hand, meters. Needs a game restart.");
			BallHeldZ = ((BaseUnityPlugin)this).Config.Bind<float>("Neroball", "HeldOffsetZ", 0.08f, "Nudge the held ball forward out of the palm, meters (negative = back). Needs a game restart.");
			Harmony val = new Harmony("com.tronn.nero");
			val.PatchAll(Assembly.GetExecutingAssembly());
			Neroball.InstallPatch(val);
			CreatureManager.OnVanillaCreaturesAvailable += AddNero;
			PrefabManager.OnVanillaPrefabsAvailable += Neroball.AddItems;
		}

		internal static bool CheatsEnabled()
		{
			try
			{
				if (_cheatField == null)
				{
					_cheatField = typeof(Terminal).GetField("m_cheat", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
				return _cheatField != null && (bool)_cheatField.GetValue(null);
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsNero(Character c)
		{
			if ((Object)(object)c != (Object)null)
			{
				return c.m_name == "Nero";
			}
			return false;
		}

		internal static long GetOwner(Character c)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)c) ? ((Component)c).GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return 0L;
			}
			return val.GetZDO().GetLong("nero_owner", 0L);
		}

		internal static void ClaimIfUnowned(Character c, long playerId)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)c) ? ((Component)c).GetComponent<ZNetView>() : null);
			if (!((Object)(object)val == (Object)null) && val.IsValid() && playerId != 0L && val.GetZDO().GetLong("nero_owner", 0L) == 0L)
			{
				val.ClaimOwnership();
				val.GetZDO().Set("nero_owner", playerId);
				Debug.Log((object)("Nero claimed by player " + playerId));
			}
		}

		internal static bool IsBallUser(Player player, long claimedOwner)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (!OwnerOnly.Value)
			{
				return true;
			}
			string text = OwnerName.Value.Trim();
			if (text.Length > 0)
			{
				return string.Equals(player.GetPlayerName(), text, StringComparison.OrdinalIgnoreCase);
			}
			if (claimedOwner != 0L)
			{
				return player.GetPlayerID() == claimedOwner;
			}
			return true;
		}

		internal static bool AllowAdminRemoval(HitData hit)
		{
			Character val = ((hit != null) ? hit.GetAttacker() : null);
			if ((Object)(object)val != (Object)null && val.IsPlayer())
			{
				return CheatsEnabled();
			}
			return false;
		}

		internal static bool BlockDamage(Character victim, HitData hit)
		{
			if (IsNero(victim) && Invincible.Value)
			{
				return !AllowAdminRemoval(hit);
			}
			return false;
		}

		private void AddNero()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			CreatureManager.OnVanillaCreaturesAvailable -= AddNero;
			try
			{
				CustomCreature val = new CustomCreature("Nero", "Wolf", new CreatureConfig());
				GameObject prefab = val.Prefab;
				Character component = prefab.GetComponent<Character>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.m_name = "Nero";
					FieldInfo field = typeof(Character).GetField("m_tamed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(component, true);
					}
					else
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"Character.m_tamed field not found; Nero spawns wild");
					}
				}
				Procreation component2 = prefab.GetComponent<Procreation>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					Object.DestroyImmediate((Object)(object)component2);
				}
				ApplyNeroVisual(prefab);
				CreatureManager.Instance.AddCreature(val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Nero registered (console: spawn Nero)");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Nero setup failed: {arg}");
			}
		}

		private void Update()
		{
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				_pin = null;
				_pinMap = null;
				_nero = null;
				return;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				if (_pin != null)
				{
					instance.RemovePin(_pin);
					_pin = null;
				}
				_nero = null;
				return;
			}
			if (!MapPin.Value)
			{
				if (_pin != null)
				{
					instance.RemovePin(_pin);
					_pin = null;
				}
				return;
			}
			if ((Object)(object)instance != (Object)(object)_pinMap)
			{
				_pin = null;
				_pinMap = instance;
			}
			_scanTimer -= Time.deltaTime;
			if (_scanTimer <= 0f)
			{
				_scanTimer = 1f;
				RemoveStrayNeroPins(instance);
				if ((Object)(object)_nero == (Object)null)
				{
					foreach (Character allCharacter in Character.GetAllCharacters())
					{
						if (IsNero(allCharacter))
						{
							_nero = allCharacter;
							break;
						}
					}
				}
				_ballKnown = (Object)(object)_nero == (Object)null && Neroball.TryGetBallPosition(out _ballPos);
			}
			if ((Object)(object)_nero != (Object)null)
			{
				SetPin(instance, ((Component)_nero).transform.position);
			}
			else if (_ballKnown)
			{
				SetPin(instance, _ballPos);
			}
		}

		private void SetPin(Minimap map, Vector3 pos)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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 (_pin == null)
			{
				_pin = map.AddPin(pos, (PinType)3, "Nero", false, false, 0L, default(PlatformUserID));
				Sprite pinIcon = GetPinIcon();
				if ((Object)(object)pinIcon != (Object)null)
				{
					_pin.m_icon = pinIcon;
				}
			}
			else
			{
				_pin.m_pos = pos;
			}
		}

		private void RemoveStrayNeroPins(Minimap map)
		{
			if (!(PinsField?.GetValue(map) is List<PinData> list))
			{
				return;
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				PinData val = list[num];
				if (val != _pin && !val.m_save && val.m_name == "Nero")
				{
					map.RemovePin(val);
				}
			}
		}

		private Sprite GetPinIcon()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (_pinIconTried)
			{
				return _pinIcon;
			}
			_pinIconTried = true;
			Texture2D val = LoadTexture(Path.Combine(PluginDir, "nero_map_icon.png"), linear: false);
			if ((Object)(object)val != (Object)null)
			{
				((Texture)val).wrapMode = (TextureWrapMode)1;
				_pinIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"nero_map_icon.png missing - using default pin icon.");
			}
			return _pinIcon;
		}

		private void ApplyNeroVisual(GameObject prefab)
		{
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Expected O, but got Unknown
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Expected O, but got Unknown
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			string pluginDir = PluginDir;
			SkinnedMeshRenderer val = null;
			SkinnedMeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || val2.bones.Length > val.bones.Length)
				{
					val = val2;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"No SkinnedMeshRenderer found on Wolf clone");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Wolf body renderer: {((Object)val).name}, bones {val.bones.Length}");
			NeroMeshData neroMeshData = NeroMeshData.Load(Path.Combine(pluginDir, "nero_mesh.bin"));
			Transform[] bones = val.bones;
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			for (int j = 0; j < bones.Length; j++)
			{
				if (Object.op_Implicit((Object)(object)bones[j]))
				{
					dictionary[((Object)bones[j]).name] = j;
				}
			}
			int[] array = new int[neroMeshData.BoneNames.Length];
			for (int k = 0; k < neroMeshData.BoneNames.Length; k++)
			{
				array[k] = (dictionary.TryGetValue(neroMeshData.BoneNames[k], out var value) ? value : (-1));
			}
			BoneWeight[] array2 = (BoneWeight[])(object)new BoneWeight[neroMeshData.VertexCount];
			for (int l = 0; l < neroMeshData.VertexCount; l++)
			{
				List<KeyValuePair<int, float>> obj = neroMeshData.Weights[l];
				float num = 0f;
				List<KeyValuePair<int, float>> list = new List<KeyValuePair<int, float>>(4);
				foreach (KeyValuePair<int, float> item in obj)
				{
					int num2 = array[item.Key];
					if (num2 >= 0)
					{
						list.Add(new KeyValuePair<int, float>(num2, item.Value));
						num += item.Value;
					}
				}
				if (list.Count == 0 || num <= 0f)
				{
					list.Clear();
					list.Add(new KeyValuePair<int, float>(0, 1f));
					num = 1f;
				}
				list.Sort((KeyValuePair<int, float> a, KeyValuePair<int, float> b) => b.Value.CompareTo(a.Value));
				BoneWeight val3 = default(BoneWeight);
				if (list.Count > 0)
				{
					((BoneWeight)(ref val3)).boneIndex0 = list[0].Key;
					((BoneWeight)(ref val3)).weight0 = list[0].Value / num;
				}
				if (list.Count > 1)
				{
					((BoneWeight)(ref val3)).boneIndex1 = list[1].Key;
					((BoneWeight)(ref val3)).weight1 = list[1].Value / num;
				}
				if (list.Count > 2)
				{
					((BoneWeight)(ref val3)).boneIndex2 = list[2].Key;
					((BoneWeight)(ref val3)).weight2 = list[2].Value / num;
				}
				if (list.Count > 3)
				{
					((BoneWeight)(ref val3)).boneIndex3 = list[3].Key;
					((BoneWeight)(ref val3)).weight3 = list[3].Value / num;
				}
				array2[l] = val3;
			}
			Transform transform = prefab.transform;
			Matrix4x4[] bindposes = val.sharedMesh.bindposes;
			Matrix4x4 val4 = transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
			Matrix4x4[] array3 = (Matrix4x4[])(object)new Matrix4x4[bones.Length];
			for (int num3 = 0; num3 < bones.Length; num3++)
			{
				array3[num3] = bindposes[num3] * ((Matrix4x4)(ref val4)).inverse;
			}
			Mesh val5 = new Mesh
			{
				name = "NeroMesh",
				indexFormat = (IndexFormat)1,
				vertices = neroMeshData.Vertices,
				normals = neroMeshData.Normals,
				uv = neroMeshData.UVs,
				triangles = neroMeshData.Triangles,
				boneWeights = array2,
				bindposes = array3
			};
			val5.RecalculateBounds();
			Material val6 = new Material(((Renderer)val).sharedMaterial)
			{
				name = "NeroMat"
			};
			Texture2D val7 = LoadTexture(Path.Combine(pluginDir, "nero_albedo.png"), linear: false);
			if (Object.op_Implicit((Object)(object)val7) && val6.HasProperty("_MainTex"))
			{
				val6.SetTexture("_MainTex", (Texture)(object)val7);
			}
			Texture2D val8 = LoadTexture(Path.Combine(pluginDir, "nero_normal.png"), linear: true);
			if (Object.op_Implicit((Object)(object)val8) && val6.HasProperty("_BumpMap"))
			{
				val6.SetTexture("_BumpMap", (Texture)(object)val8);
			}
			val.sharedMesh = val5;
			((Renderer)val).sharedMaterials = (Material[])(object)new Material[1] { val6 };
			((Renderer)val).localBounds = new Bounds(new Vector3(0f, 0.6f, 0f), new Vector3(2.5f, 2.5f, 3.5f));
			Transform val9 = (((Object)(object)val.rootBone != (Object)null) ? FindVisualNode(prefab, val) : null);
			if ((Object)(object)val9 != (Object)null)
			{
				val9.localScale = Vector3.one * _scale.Value;
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Visual node not found; Nero stays wolf-sized");
			}
		}

		private static Transform FindVisualNode(GameObject prefab, SkinnedMeshRenderer r)
		{
			Transform val = prefab.transform.Find("Visual");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform val2 = r.rootBone;
			while ((Object)(object)val2 != (Object)null && (Object)(object)val2.parent != (Object)(object)prefab.transform)
			{
				val2 = val2.parent;
			}
			return val2;
		}

		private static Texture2D LoadTexture(string path, bool linear)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			if (!File.Exists(path))
			{
				return null;
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear);
			MethodInfo method = typeof(ImageConversion).GetMethod("LoadImage", new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			});
			if (method == null || !(bool)method.Invoke(null, new object[3]
			{
				val,
				File.ReadAllBytes(path),
				false
			}))
			{
				return null;
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(Tameable), "Interact")]
	internal static class NeroCommandPatch
	{
		private static bool Prefix(Tameable __instance, Humanoid user, bool hold, bool alt)
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!NeroPlugin.IsNero(component) || !NeroPlugin.OwnerOnly.Value)
			{
				return true;
			}
			Player val = (Player)(object)((user is Player) ? user : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			long playerID = val.GetPlayerID();
			long owner = NeroPlugin.GetOwner(component);
			string text = NeroPlugin.OwnerName.Value.Trim();
			bool flag = text.Length == 0 || string.Equals(val.GetPlayerName(), text, StringComparison.OrdinalIgnoreCase);
			if (owner == 0 && flag)
			{
				NeroPlugin.ClaimIfUnowned(component, playerID);
				return true;
			}
			if (owner == playerID && flag)
			{
				return true;
			}
			PetInstead(__instance, component, val);
			return false;
		}

		private static void PetInstead(Tameable tame, Character c, Player player)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? obj = AccessTools.Field(typeof(Tameable), "m_petEffect")?.GetValue(tame);
				object? obj2 = ((obj is EffectList) ? obj : null);
				if (obj2 != null)
				{
					((EffectList)obj2).Create(((Component)c).transform.position, ((Component)c).transform.rotation, (Transform)null, 1f, -1, default(ZDOID));
				}
			}
			catch
			{
			}
			((Character)player).Message((MessageType)2, "Nero loves the pets, but he only follows his owner.", 0, (Sprite)null, false);
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class NeroDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			if (NeroPlugin.BlockDamage(__instance, hit))
			{
				return false;
			}
			if (NeroPlugin.IsNero((hit != null) ? hit.GetAttacker() : null))
			{
				((DamageTypes)(ref hit.m_damage)).Modify(NeroPlugin.DamageMultiplier.Value);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class NeroRpcDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			return !NeroPlugin.BlockDamage(__instance, hit);
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	internal static class NeroApplyDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			return !NeroPlugin.BlockDamage(__instance, hit);
		}
	}
	internal static class Neroball
	{
		internal const string BallItemName = "Neroball";

		internal const string FullItemName = "NeroballFull";

		private const string ProjEmpty = "neroball_projectile";

		private const string ProjFull = "neroball_full_projectile";

		private const string KeyHasNero = "nero_inside";

		private const string KeyLevel = "nero_level";

		private const string KeyHealth = "nero_health";

		private const string KeyPetName = "nero_petname";

		private const string KeyOwner = "nero_ball_owner";

		private const string KeyFollow = "nero_follow";

		internal const string MasterItemName = "Masterball";

		private const string ProjMaster = "masterball_projectile";

		private const string KeyModerOut = "moder_released";

		private const string KeyModerLevel = "moder_level";

		private const float CaptureRadius = 2f;

		private static readonly FieldInfo OwnerField = AccessTools.Field(typeof(Projectile), "m_owner");

		private static readonly FieldInfo SpawnItemField = AccessTools.Field(typeof(Projectile), "m_spawnItem");

		private const string DoneMarker = "nbdone_";

		private static readonly Dictionary<string, AudioClip> _clips = new Dictionary<string, AudioClip>();

		private const float BallRadius = 0.08f;

		private static Mesh _ballMesh;

		internal static void AddItems()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0041: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00c6: 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)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_0112: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= AddItems;
			try
			{
				ItemConfig val = new ItemConfig();
				val.CraftingStation = "piece_workbench";
				val.Amount = 1;
				val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
				{
					new RequirementConfig
					{
						Item = "Stone",
						Amount = 1
					},
					new RequirementConfig
					{
						Item = "LeatherScraps",
						Amount = 1
					}
				};
				ItemConfig val2 = val;
				SetupBall(new CustomItem("Neroball", "BombOoze", val2), full: false);
				SetupBall(new CustomItem("NeroballFull", "BombOoze"), full: true);
				val = new ItemConfig();
				val.CraftingStation = "piece_workbench";
				val.Amount = 1;
				val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
				{
					new RequirementConfig
					{
						Item = "Stone",
						Amount = 5
					},
					new RequirementConfig
					{
						Item = "LeatherScraps",
						Amount = 5
					},
					new RequirementConfig
					{
						Item = "Coal",
						Amount = 2
					}
				};
				ItemConfig val3 = val;
				SetupMasterball(new CustomItem("Masterball", "BombOoze", val3));
				Debug.Log((object)"[Neroball] items registered (craft a Neroball or a Masterball at the workbench)");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[Neroball] item setup failed: {arg}");
			}
		}

		private static void SetupBall(CustomItem item, bool full)
		{
			SharedData shared = item.ItemDrop.m_itemData.m_shared;
			shared.m_name = (full ? "Neroball (old)" : "Neroball");
			shared.m_description = (full ? "An old-style filled ball. Throw it to let Nero out — it becomes a normal Neroball." : "Throw it at Nero to catch him; throw it again to let him out.\nA missed throw drops the ball — walk over and pick it back up.");
			FinishBall(item, master: false, "neroball_projectile");
		}

		private static void SetupMasterball(CustomItem item)
		{
			SharedData shared = item.ItemDrop.m_itemData.m_shared;
			shared.m_name = "Masterball";
			shared.m_description = "Moder sleeps inside. Throw it anywhere to unleash her — tamed, and loyal to you.\nThrow it at her to put her back in.";
			FinishBall(item, master: true, "masterball_projectile");
		}

		private static void FinishBall(CustomItem item, bool master, string projName)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			SharedData shared = item.ItemDrop.m_itemData.m_shared;
			shared.m_maxStackSize = 1;
			shared.m_weight = 0.5f;
			shared.m_damages = default(DamageTypes);
			shared.m_attack.m_attackStamina = 2f;
			shared.m_attack.m_projectileAccuracy = 1f;
			shared.m_attack.m_projectileAccuracyMin = 1f;
			shared.m_attack.m_attackHitNoise = 5f;
			Sprite val = BuildIcon(master);
			if ((Object)(object)val != (Object)null)
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { val };
			}
			ApplyBallVisual(item.ItemPrefab, master);
			OffsetHeldVisual(item.ItemPrefab, new Vector3(NeroPlugin.BallHeldX.Value, NeroPlugin.BallHeldY.Value, NeroPlugin.BallHeldZ.Value));
			GameObject val2 = PrefabManager.Instance.GetPrefab(projName);
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = PrefabManager.Instance.CreateClonedPrefab(projName, shared.m_attack.m_attackProjectile);
				Projectile component = val2.GetComponent<Projectile>();
				component.m_aoe = 0f;
				component.m_spawnOnHit = null;
				component.m_spawnOnHitChance = -1f;
				component.m_respawnItemOnHit = true;
				component.m_rotateVisual = 300f;
				ApplyBallVisual(val2, master);
				PrefabManager.Instance.AddPrefab(val2);
			}
			shared.m_attack.m_attackProjectile = val2;
			ItemManager.Instance.AddItem(item);
		}

		internal static void InstallPatch(Harmony harmony)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = null;
				MethodInfo[] methods = typeof(Projectile).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo2 in methods)
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (methodInfo2.Name == "OnHit" && parameters.Length >= 2 && parameters[0].ParameterType == typeof(Collider) && parameters[1].ParameterType == typeof(Vector3))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
				if (methodInfo == null)
				{
					Debug.LogError((object)"[Neroball] Projectile.OnHit(Collider, Vector3, ...) not found — capture disabled");
					return;
				}
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(Neroball), "OnHitPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Debug.Log((object)"[Neroball] Projectile.OnHit patch installed");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[Neroball] patch failed: {arg}");
			}
		}

		public static bool OnHitPrefix(Projectile __instance, ref Collider __0, Vector3 __1)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string name = ((Object)__instance).name;
				if (name.StartsWith("nbdone_"))
				{
					return false;
				}
				bool flag = name.StartsWith("masterball_projectile");
				if (!flag && !name.StartsWith("neroball_projectile") && !name.StartsWith("neroball_full_projectile"))
				{
					return true;
				}
				object? obj = OwnerField?.GetValue(__instance);
				Player thrower = (Player)((obj is Player) ? obj : null);
				if (flag)
				{
					if (MasterHit(__instance, thrower, __0, __1))
					{
						Consume(__instance);
						return false;
					}
					return true;
				}
				object? obj2 = SpawnItemField?.GetValue(__instance);
				ItemData val = (ItemData)((obj2 is ItemData) ? obj2 : null);
				if (HasNeroData(val) || ((Object)(object)val?.m_dropPrefab != (Object)null && ((Object)val.m_dropPrefab).name == "NeroballFull"))
				{
					Summon(__instance, thrower, __1);
					Consume(__instance);
					return false;
				}
				Character val2 = FindNero(__0, __1);
				if ((Object)(object)val2 != (Object)null && Capture(thrower, val2))
				{
					Consume(__instance);
					return false;
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[Neroball] OnHit error: {arg}");
			}
			return true;
		}

		private static bool HasNeroData(ItemData item)
		{
			if (item?.m_customData != null)
			{
				if (!item.m_customData.ContainsKey("nero_inside"))
				{
					return item.m_customData.ContainsKey("nero_level");
				}
				return true;
			}
			return false;
		}

		internal static bool TryGetBallPosition(out Vector3 pos)
		{
			//IL_0001: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			pos = default(Vector3);
			try
			{
				Player localPlayer = Player.m_localPlayer;
				Inventory val = ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
				if (val != null)
				{
					foreach (ItemData allItem in val.GetAllItems())
					{
						if (HasNeroData(allItem))
						{
							pos = ((Component)localPlayer).transform.position;
							return true;
						}
					}
				}
				ItemDrop[] array = Object.FindObjectsByType<ItemDrop>((FindObjectsSortMode)0);
				foreach (ItemDrop val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && HasNeroData(val2.m_itemData))
					{
						pos = ((Component)val2).transform.position;
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static void Consume(Projectile ball)
		{
			try
			{
				((Object)ball).name = "nbdone_" + ((Object)ball).name;
				ZNetView component = ((Component)ball).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.ClaimOwnership();
					ZNetScene.instance.Destroy(((Component)ball).gameObject);
				}
				else
				{
					Object.Destroy((Object)(object)((Component)ball).gameObject);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] projectile cleanup failed: " + ex.Message));
			}
		}

		private static bool IsModer(Character c)
		{
			if ((Object)(object)c != (Object)null && !c.IsDead())
			{
				return ((Object)((Component)c).gameObject).name.StartsWith("Dragon");
			}
			return false;
		}

		private static Character FindModer(Collider direct, Vector3 hitPoint)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			Character val = (((Object)(object)direct != (Object)null) ? ((Component)direct).GetComponentInParent<Character>() : null);
			if (IsModer(val))
			{
				return val;
			}
			Collider[] array = Physics.OverlapSphere(hitPoint, 6f);
			foreach (Collider val2 in array)
			{
				val = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInParent<Character>() : null);
				if (IsModer(val))
				{
					return val;
				}
			}
			return null;
		}

		private static bool MasterHit(Projectile ball, Player thrower, Collider direct, Vector3 hitPoint)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			object? obj = SpawnItemField?.GetValue(ball);
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			if (val?.m_customData == null || !val.m_customData.ContainsKey("moder_released"))
			{
				ReleaseModer(thrower, hitPoint, val);
				return true;
			}
			Character val2 = FindModer(direct, hitPoint);
			if ((Object)(object)val2 != (Object)null)
			{
				return CaptureModer(thrower, val2);
			}
			return false;
		}

		private static void ReleaseModer(Player thrower, Vector3 hitPoint, ItemData item)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			if (!NeroPlugin.IsBallUser(thrower, 0L))
			{
				if (thrower != null)
				{
					((Character)thrower).Message((MessageType)2, "The Masterball won't open for you.", 0, (Sprite)null, false);
				}
				GiveOrDrop(thrower, "Masterball", hitPoint, item?.m_customData);
				return;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (IsModer(allCharacter) && allCharacter.IsTamed())
				{
					if (thrower != null)
					{
						((Character)thrower).Message((MessageType)2, "Moder is already out!", 0, (Sprite)null, false);
					}
					GiveOrDrop(thrower, "Masterball", hitPoint, item?.m_customData);
					return;
				}
			}
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab("Dragon") : null);
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogError((object)"[Masterball] Dragon prefab missing — cannot summon Moder");
				GiveOrDrop(thrower, "Masterball", hitPoint, item?.m_customData);
				return;
			}
			int result = 1;
			if (item?.m_customData != null && item.m_customData.TryGetValue("moder_level", out var value))
			{
				int.TryParse(value, out result);
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, hitPoint + Vector3.up * 3f, Quaternion.identity);
			Character component = val2.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				if (result > 1)
				{
					component.SetLevel(result);
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_tamed");
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(component, true);
				}
				ZNetView component2 = val2.GetComponent<ZNetView>();
				if ((Object)(object)component2 != (Object)null && component2.IsValid())
				{
					ZDO zDO = component2.GetZDO();
					zDO.Set("tamed", true);
					if ((Object)(object)thrower != (Object)null)
					{
						zDO.Set("nero_owner", thrower.GetPlayerID());
					}
				}
			}
			Poof(hitPoint);
			PlaySummonSound(hitPoint);
			Dictionary<string, string> data = new Dictionary<string, string> { ["moder_released"] = "1" };
			GiveOrDrop(thrower, "Masterball", hitPoint, data);
			if (thrower != null)
			{
				((Character)thrower).Message((MessageType)2, "MODER! GO!", 0, (Sprite)null, false);
			}
			Debug.Log((object)"[Masterball] Moder unleashed");
		}

		private static bool CaptureModer(Player thrower, Character moder)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)moder).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			if (!NeroPlugin.IsBallUser(thrower, 0L))
			{
				if (thrower != null)
				{
					((Character)thrower).Message((MessageType)2, "The Masterball ignores your throw.", 0, (Sprite)null, false);
				}
				return false;
			}
			Dictionary<string, string> data = new Dictionary<string, string> { ["moder_level"] = moder.GetLevel().ToString() };
			Vector3 position = ((Component)moder).transform.position;
			Poof(position);
			PlayCaptureSound(position);
			component.ClaimOwnership();
			ZNetScene.instance.Destroy(((Component)moder).gameObject);
			GiveOrDrop(thrower, "Masterball", position, data);
			if (thrower != null)
			{
				((Character)thrower).Message((MessageType)2, "Moder returned to the Masterball!", 0, (Sprite)null, false);
			}
			Debug.Log((object)"[Masterball] Moder captured");
			return true;
		}

		private static Character FindNero(Collider direct, Vector3 hitPoint)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Character val = NeroFrom(direct);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Collider[] array = Physics.OverlapSphere(hitPoint, 2f);
			for (int i = 0; i < array.Length; i++)
			{
				val = NeroFrom(array[i]);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static Character NeroFrom(Collider col)
		{
			if ((Object)(object)col == (Object)null)
			{
				return null;
			}
			Character componentInParent = ((Component)col).GetComponentInParent<Character>();
			if (!((Object)(object)componentInParent != (Object)null) || !NeroPlugin.IsNero(componentInParent) || componentInParent.IsDead())
			{
				return null;
			}
			return componentInParent;
		}

		private static bool Capture(Player thrower, Character nero)
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)nero).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			long claimedOwner = component.GetZDO().GetLong("nero_owner", 0L);
			if (!NeroPlugin.IsBallUser(thrower, claimedOwner))
			{
				if (thrower != null)
				{
					((Character)thrower).Message((MessageType)2, "The ball bounces off — Nero only answers to his owner.", 0, (Sprite)null, false);
				}
				return false;
			}
			Tameable component2 = ((Component)nero).GetComponent<Tameable>();
			MonsterAI component3 = ((Component)nero).GetComponent<MonsterAI>();
			bool flag = (Object)(object)component3 != (Object)null && (Object)(object)component3.GetFollowTarget() != (Object)null;
			Dictionary<string, string> data = new Dictionary<string, string>
			{
				["nero_inside"] = "1",
				["nero_level"] = nero.GetLevel().ToString(),
				["nero_health"] = Mathf.CeilToInt(nero.GetHealth()).ToString(),
				["nero_petname"] = (((Object)(object)component2 != (Object)null) ? (component2.GetText() ?? "") : ""),
				["nero_ball_owner"] = claimedOwner.ToString(),
				["nero_follow"] = (flag ? "1" : "0")
			};
			Vector3 position = ((Component)nero).transform.position;
			Poof(position);
			PlayCaptureSound(position);
			component.ClaimOwnership();
			ZNetScene.instance.Destroy(((Component)nero).gameObject);
			GiveOrDrop(thrower, "Neroball", position, data);
			if (thrower != null)
			{
				((Character)thrower).Message((MessageType)2, "Nero returned to his Neroball!", 0, (Sprite)null, false);
			}
			Debug.Log((object)"[Neroball] Nero captured");
			return true;
		}

		private static void Summon(Projectile ball, Player thrower, Vector3 hitPoint)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			object? obj = SpawnItemField?.GetValue(ball);
			Dictionary<string, string> dictionary = ((ItemData)(((obj is ItemData) ? obj : null)?)).m_customData;
			int result = 1;
			int result2 = -1;
			string text = "";
			long result3 = 0L;
			bool flag = false;
			if (dictionary != null)
			{
				if (dictionary.TryGetValue("nero_level", out var value))
				{
					int.TryParse(value, out result);
				}
				if (dictionary.TryGetValue("nero_health", out value))
				{
					int.TryParse(value, out result2);
				}
				if (dictionary.TryGetValue("nero_petname", out value))
				{
					text = value;
				}
				if (dictionary.TryGetValue("nero_ball_owner", out value))
				{
					long.TryParse(value, out result3);
				}
				if (dictionary.TryGetValue("nero_follow", out value))
				{
					flag = value == "1";
				}
			}
			if (!NeroPlugin.IsBallUser(thrower, result3))
			{
				if (thrower != null)
				{
					((Character)thrower).Message((MessageType)2, "The ball won't open — Nero only comes out for his owner.", 0, (Sprite)null, false);
				}
				GiveOrDrop(thrower, "Neroball", hitPoint, dictionary);
				return;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (NeroPlugin.IsNero(allCharacter) && !allCharacter.IsDead())
				{
					if (thrower != null)
					{
						((Character)thrower).Message((MessageType)2, "Nero is already out!", 0, (Sprite)null, false);
					}
					GiveOrDrop(thrower, "Neroball", hitPoint, dictionary);
					return;
				}
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("Nero");
			if ((Object)(object)prefab == (Object)null)
			{
				Debug.LogError((object)"[Neroball] Nero prefab missing — cannot summon");
				GiveOrDrop(thrower, "Neroball", hitPoint, dictionary);
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, hitPoint + Vector3.up * 0.4f, Quaternion.identity);
			Character component = val.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				if (result > 1)
				{
					component.SetLevel(result);
				}
				if (result2 > 0)
				{
					component.SetHealth((float)result2);
				}
				Tameable component2 = val.GetComponent<Tameable>();
				if ((Object)(object)component2 != (Object)null && text.Length > 0)
				{
					component2.SetText(text);
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_tamed");
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(component, true);
				}
				if ((Object)(object)thrower != (Object)null)
				{
					result3 = thrower.GetPlayerID();
				}
				ZNetView component3 = val.GetComponent<ZNetView>();
				if ((Object)(object)component3 != (Object)null && component3.IsValid())
				{
					ZDO zDO = component3.GetZDO();
					zDO.Set("tamed", true);
					if (result3 != 0L)
					{
						zDO.Set("nero_owner", result3);
					}
					if (flag && (Object)(object)thrower != (Object)null)
					{
						zDO.Set("follow", thrower.GetPlayerName());
					}
				}
				if (flag && (Object)(object)thrower != (Object)null)
				{
					MonsterAI component4 = val.GetComponent<MonsterAI>();
					if ((Object)(object)component4 != (Object)null)
					{
						component4.SetFollowTarget(((Component)thrower).gameObject);
					}
				}
			}
			Poof(hitPoint);
			PlaySummonSound(hitPoint);
			GiveOrDrop(thrower, "Neroball", hitPoint, null);
			if (thrower != null)
			{
				((Character)thrower).Message((MessageType)2, "Nero! Go!", 0, (Sprite)null, false);
			}
			Debug.Log((object)"[Neroball] Nero summoned");
		}

		private static void GiveOrDrop(Player player, string prefabName, Vector3 pos, Dictionary<string, string> data)
		{
			//IL_002c: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				Debug.LogError((object)("[Neroball] prefab " + prefabName + " missing"));
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, pos + Vector3.up * 0.7f, Quaternion.identity);
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (data != null)
			{
				foreach (KeyValuePair<string, string> datum in data)
				{
					component.m_itemData.m_customData[datum.Key] = datum.Value;
				}
			}
			if (!((Object)(object)player != (Object)null))
			{
				return;
			}
			try
			{
				((Humanoid)player).Pickup(val, false, false);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] pickup failed, item dropped: " + ex.Message));
			}
		}

		private static void OffsetHeldVisual(GameObject prefab, Vector3 offset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (offset == Vector3.zero)
			{
				return;
			}
			try
			{
				Transform val = prefab.transform.Find("attach");
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)"[Neroball] no 'attach' child — held offset skipped");
					return;
				}
				bool flag = false;
				foreach (Transform item in val)
				{
					item.localPosition += offset;
					flag = true;
				}
				if (flag)
				{
					return;
				}
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null))
				{
					MeshRenderer component2 = ((Component)val).GetComponent<MeshRenderer>();
					GameObject val3 = new GameObject("ballPivot");
					val3.transform.SetParent(val, false);
					val3.transform.localPosition = offset;
					val3.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
					if ((Object)(object)component2 != (Object)null)
					{
						((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterials = ((Renderer)component2).sharedMaterials;
						Object.DestroyImmediate((Object)(object)component2);
					}
					Object.DestroyImmediate((Object)(object)component);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] held offset failed: " + ex.Message));
			}
		}

		private static void Poof(Vector3 pos)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ZNetScene instance = ZNetScene.instance;
				object obj = ((instance != null) ? instance.GetPrefab("vfx_odin_despawn") : null);
				if (obj == null)
				{
					ZNetScene instance2 = ZNetScene.instance;
					obj = ((instance2 != null) ? instance2.GetPrefab("vfx_spawn") : null);
				}
				GameObject val = (GameObject)obj;
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, pos + Vector3.up * 0.5f, Quaternion.identity);
				}
			}
			catch
			{
			}
		}

		private static void PlaySummonSound(Vector3 pos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			PlayBallSound("nero_summon.wav", pos);
		}

		private static void PlayCaptureSound(Vector3 pos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			PlayBallSound("nero_capture.wav", pos);
		}

		private static void PlayBallSound(string file, Vector3 pos)
		{
			//IL_0068: 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)
			//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			try
			{
				if (!_clips.TryGetValue(file, out var value))
				{
					string path = Path.Combine(NeroPlugin.PluginDir, file);
					value = (File.Exists(path) ? LoadWav(path) : null);
					if ((Object)(object)value == (Object)null)
					{
						Debug.Log((object)("[Neroball] " + file + " missing — staying silent"));
					}
					_clips[file] = value;
				}
				if ((Object)(object)value != (Object)null)
				{
					GameObject val = new GameObject("LNC_ballSound");
					val.transform.position = pos + Vector3.up * 0.5f;
					AudioSource obj = val.AddComponent<AudioSource>();
					obj.clip = value;
					obj.volume = 1f;
					obj.spatialBlend = 1f;
					obj.minDistance = 6f;
					obj.maxDistance = 80f;
					obj.rolloffMode = (AudioRolloffMode)1;
					obj.Play();
					Object.Destroy((Object)val, value.length + 0.5f);
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] " + file + " failed: " + ex.Message));
			}
		}

		private static AudioClip LoadWav(string path)
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			byte[] array = File.ReadAllBytes(path);
			if (array.Length < 44 || Encoding.ASCII.GetString(array, 0, 4) != "RIFF" || Encoding.ASCII.GetString(array, 8, 4) != "WAVE")
			{
				throw new IOException("not a RIFF WAVE file");
			}
			int i = 12;
			int num = 1;
			int num2 = 44100;
			int num3 = -1;
			int val = 0;
			int num4;
			for (; i + 8 <= array.Length; i += 8 + num4 + (num4 & 1))
			{
				string text = Encoding.ASCII.GetString(array, i, 4);
				num4 = BitConverter.ToInt32(array, i + 4);
				if (text == "fmt ")
				{
					if (BitConverter.ToInt16(array, i + 8) != 1 || BitConverter.ToInt16(array, i + 22) != 16)
					{
						throw new IOException("need 16-bit PCM wav");
					}
					num = BitConverter.ToInt16(array, i + 10);
					num2 = BitConverter.ToInt32(array, i + 12);
				}
				else if (text == "data")
				{
					num3 = i + 8;
					val = num4;
				}
			}
			if (num3 < 0)
			{
				throw new IOException("wav has no data chunk");
			}
			val = Math.Min(val, array.Length - num3);
			int samples = val / 2;
			float[] f = new float[samples];
			for (int j = 0; j < samples; j++)
			{
				f[j] = (float)BitConverter.ToInt16(array, num3 + j * 2) / 32768f;
			}
			int cursor = 0;
			return AudioClip.Create("NeroballSummon", samples / num, num, num2, false, (PCMReaderCallback)delegate(float[] chunk)
			{
				for (int k = 0; k < chunk.Length; k++)
				{
					chunk[k] = ((cursor < samples) ? f[cursor++] : 0f);
				}
			});
		}

		private static Mesh GetBallMesh()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			if ((Object)(object)_ballMesh != (Object)null)
			{
				return _ballMesh;
			}
			try
			{
				string path = Path.Combine(NeroPlugin.PluginDir, "neroball_mesh.bin");
				if (File.Exists(path))
				{
					using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
					if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "NBAL")
					{
						throw new IOException("bad neroball_mesh.bin magic");
					}
					binaryReader.ReadInt32();
					int num = binaryReader.ReadInt32();
					Vector3[] array = (Vector3[])(object)new Vector3[num];
					Vector3[] array2 = (Vector3[])(object)new Vector3[num];
					Vector2[] array3 = (Vector2[])(object)new Vector2[num];
					for (int i = 0; i < num; i++)
					{
						array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()) * 0.08f;
					}
					for (int j = 0; j < num; j++)
					{
						array2[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					}
					for (int k = 0; k < num; k++)
					{
						array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
					}
					int num2 = binaryReader.ReadInt32();
					int[] array4 = new int[num2 * 3];
					for (int l = 0; l < array4.Length; l++)
					{
						array4[l] = binaryReader.ReadInt32();
					}
					Vector3[] array5 = (Vector3[])(object)new Vector3[num * 2];
					Vector3[] array6 = (Vector3[])(object)new Vector3[num * 2];
					Vector2[] array7 = (Vector2[])(object)new Vector2[num * 2];
					for (int m = 0; m < num; m++)
					{
						array5[m] = array[m];
						array5[m + num] = array[m];
						array6[m] = array2[m];
						array6[m + num] = -array2[m];
						array7[m] = array3[m];
						array7[m + num] = array3[m];
					}
					int[] array8 = new int[array4.Length * 2];
					Array.Copy(array4, array8, array4.Length);
					for (int n = 0; n < array4.Length; n += 3)
					{
						array8[array4.Length + n] = array4[n] + num;
						array8[array4.Length + n + 1] = array4[n + 2] + num;
						array8[array4.Length + n + 2] = array4[n + 1] + num;
					}
					Mesh val = new Mesh
					{
						name = "NeroballMesh",
						indexFormat = (IndexFormat)1,
						vertices = array5,
						normals = array6,
						uv = array7,
						triangles = array8
					};
					val.RecalculateBounds();
					_ballMesh = val;
					Debug.Log((object)$"[Neroball] loaded neroball_mesh.bin ({num} verts, {num2} tris, double-sided)");
					return _ballMesh;
				}
				Debug.LogWarning((object)"[Neroball] neroball_mesh.bin missing — using procedural sphere");
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] mesh load failed (" + ex.Message + ") — using procedural sphere"));
			}
			_ballMesh = BuildSphere(0.08f);
			return _ballMesh;
		}

		private static void ApplyBallVisual(GameObject prefab, bool full)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			try
			{
				Mesh ballMesh = GetBallMesh();
				MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter obj in componentsInChildren)
				{
					obj.sharedMesh = ballMesh;
					((Component)obj).transform.localScale = Vector3.one;
					((Component)obj).transform.localRotation = Quaternion.identity;
				}
				MeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<MeshRenderer>(true);
				if (componentsInChildren2.Length != 0)
				{
					Material val = MakeBallMaterial(((Renderer)componentsInChildren2[0]).sharedMaterial, full);
					MeshRenderer[] array = componentsInChildren2;
					for (int i = 0; i < array.Length; i++)
					{
						((Renderer)array[i]).sharedMaterials = (Material[])(object)new Material[1] { val };
					}
				}
				ParticleSystem[] componentsInChildren3 = prefab.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren3.Length; i++)
				{
					EmissionModule emission = componentsInChildren3[i].emission;
					((EmissionModule)(ref emission)).enabled = false;
				}
				Light[] componentsInChildren4 = prefab.GetComponentsInChildren<Light>(true);
				for (int i = 0; i < componentsInChildren4.Length; i++)
				{
					((Behaviour)componentsInChildren4[i]).enabled = false;
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Neroball] visual swap failed (ball stays ooze-shaped): " + ex.Message));
			}
		}

		private static Material MakeBallMaterial(Material template, bool master)
		{
			//IL_001b: 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_0021: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Material val = (((Object)(object)template != (Object)null) ? new Material(template) : new Material(Shader.Find("Standard")));
			((Object)val).name = (master ? "MasterballMat" : "NeroballMat");
			Texture2D val2 = BuildBallTexture(master);
			if (val.HasProperty("_MainTex"))
			{
				val.SetTexture("_MainTex", (Texture)(object)val2);
			}
			if (val.HasProperty("_Color"))
			{
				val.color = Color.white;
			}
			if (val.HasProperty("_EmissionColor"))
			{
				val.SetColor("_EmissionColor", Color.black);
			}
			if (val.HasProperty("_BumpMap"))
			{
				val.SetTexture("_BumpMap", (Texture)null);
			}
			return val;
		}

		private static Mesh BuildSphere(float radius, int latSeg = 18, int lonSeg = 28)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			Vector3 val = default(Vector3);
			for (int i = 0; i <= latSeg; i++)
			{
				float num = (float)i / (float)latSeg;
				float num2 = (float)Math.PI * num;
				for (int j = 0; j <= lonSeg; j++)
				{
					float num3 = (float)j / (float)lonSeg;
					float num4 = (float)Math.PI * 2f * num3;
					((Vector3)(ref val))..ctor(Mathf.Sin(num2) * Mathf.Cos(num4), Mathf.Cos(num2), Mathf.Sin(num2) * Mathf.Sin(num4));
					list.Add(val * radius);
					list2.Add(val);
					list3.Add(new Vector2(num3, 1f - num));
				}
			}
			int num5 = lonSeg + 1;
			for (int k = 0; k < latSeg; k++)
			{
				for (int l = 0; l < lonSeg; l++)
				{
					int num6 = k * num5 + l;
					list4.Add(num6);
					list4.Add(num6 + 1);
					list4.Add(num6 + num5);
					list4.Add(num6 + 1);
					list4.Add(num6 + num5 + 1);
					list4.Add(num6 + num5);
				}
			}
			int num7 = list4.Count / 6 * 3;
			Vector3 val2 = list[list4[num7]];
			Vector3 val3 = list[list4[num7 + 1]];
			Vector3 val4 = list[list4[num7 + 2]];
			if (Vector3.Dot(Vector3.Cross(val3 - val2, val4 - val2), val2 + val3 + val4) < 0f)
			{
				for (int m = 0; m < list4.Count; m += 3)
				{
					int value = list4[m + 1];
					list4[m + 1] = list4[m + 2];
					list4[m + 2] = value;
				}
			}
			Mesh val5 = new Mesh
			{
				name = "NeroballMesh"
			};
			val5.SetVertices(list);
			val5.SetNormals(list2);
			val5.SetUVs(0, list3);
			val5.SetTriangles(list4, 0);
			val5.RecalculateBounds();
			return val5;
		}

		private static Texture2D BuildBallTexture(bool master)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00c2: 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_00bf: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			Color val = (master ? new Color(0.44f, 0.16f, 0.66f) : new Color(0.78f, 0.08f, 0.08f));
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.95f, 0.45f, 0.7f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.92f, 0.92f, 0.92f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.05f, 0.05f, 0.05f);
			Texture2D val5 = new Texture2D(256, 256, (TextureFormat)4, true, false);
			for (int i = 0; i < 256; i++)
			{
				float num = (float)i / 255f;
				for (int j = 0; j < 256; j++)
				{
					float num2 = (float)j / 255f;
					Color val6 = ((num > 0.53f) ? val : ((num < 0.47f) ? val3 : val4));
					if (master && num > 0.56f)
					{
						float num3 = Mathf.Min(Mathf.Abs(num2 - 0.3f), Mathf.Abs(num2 - 0.7f)) * 2.2f;
						float num4 = (num - 0.66f) * 4.5f;
						if (Mathf.Sqrt(num3 * num3 + num4 * num4) < 0.14f)
						{
							val6 = val2;
						}
					}
					float num5 = (num2 - 0.5f) * 2.2f;
					float num6 = (num - 0.5f) * 4.5f;
					float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
					if (num7 < 0.24f)
					{
						val6 = val4;
					}
					if (num7 < 0.15f)
					{
						val6 = val3;
					}
					val5.SetPixel(j, i, val6);
				}
			}
			val5.Apply(true);
			((Texture)val5).wrapMode = (TextureWrapMode)0;
			return val5;
		}

		private static Sprite BuildIcon(bool full)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Color val = (full ? new Color(0.5f, 0.2f, 0.72f) : new Color(0.85f, 0.12f, 0.12f));
				Color val2 = default(Color);
				((Color)(ref val2))..ctor(0.95f, 0.45f, 0.7f);
				Color val3 = default(Color);
				((Color)(ref val3))..ctor(0.95f, 0.95f, 0.95f);
				Color val4 = default(Color);
				((Color)(ref val4))..ctor(0.05f, 0.05f, 0.05f);
				Color val5 = default(Color);
				((Color)(ref val5))..ctor(0f, 0f, 0f, 0f);
				Texture2D val6 = new Texture2D(64, 64, (TextureFormat)4, false, false);
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						float num = (float)j - 31.5f;
						float num2 = (float)i - 31.5f;
						float num3 = Mathf.Sqrt(num * num + num2 * num2);
						Color val7 = ((num3 > 28f) ? val5 : ((num3 > 25.5f) ? val4 : ((!(Mathf.Abs(num2) < 3f)) ? ((num2 > 0f) ? val : val3) : val4)));
						if (full && num2 > 8f && num3 <= 25.5f)
						{
							float num4 = Mathf.Min(Mathf.Abs(num - 12f), Mathf.Abs(num + 12f));
							if (Mathf.Sqrt(num4 * num4 + (num2 - 15f) * (num2 - 15f)) < 5f)
							{
								val7 = val2;
							}
						}
						if (num3 < 9f)
						{
							val7 = val4;
						}
						if (num3 < 5.5f)
						{
							val7 = val3;
						}
						val6.SetPixel(j, i, val7);
					}
				}
				val6.Apply(false);
				((Texture)val6).wrapMode = (TextureWrapMode)1;
				return Sprite.Create(val6, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f);
			}
			catch
			{
				return null;
			}
		}
	}
	internal class NeroMeshData
	{
		public string[] BoneNames;

		public Vector3[] Vertices;

		public Vector3[] Normals;

		public Vector2[] UVs;

		public List<KeyValuePair<int, float>>[] Weights;

		public int[] Triangles;

		public int VertexCount => Vertices.Length;

		public static NeroMeshData Load(string path)
		{
			//IL_00b9: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			using BinaryReader binaryReader = new BinaryReader(File.OpenRead(path));
			if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "NERO")
			{
				throw new IOException("bad nero_mesh.bin magic");
			}
			binaryReader.ReadInt32();
			NeroMeshData neroMeshData = new NeroMeshData();
			int num = binaryReader.ReadInt32();
			neroMeshData.BoneNames = new string[num];
			for (int i = 0; i < num; i++)
			{
				int count = binaryReader.ReadInt32();
				neroMeshData.BoneNames[i] = Encoding.UTF8.GetString(binaryReader.ReadBytes(count));
			}
			int num2 = binaryReader.ReadInt32();
			neroMeshData.Vertices = (Vector3[])(object)new Vector3[num2];
			for (int j = 0; j < num2; j++)
			{
				neroMeshData.Vertices[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
			}
			neroMeshData.Normals = (Vector3[])(object)new Vector3[num2];
			for (int k = 0; k < num2; k++)
			{
				neroMeshData.Normals[k] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
			}
			neroMeshData.UVs = (Vector2[])(object)new Vector2[num2];
			for (int l = 0; l < num2; l++)
			{
				neroMeshData.UVs[l] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
			}
			neroMeshData.Weights = new List<KeyValuePair<int, float>>[num2];
			for (int m = 0; m < num2; m++)
			{
				int num3 = binaryReader.ReadSByte();
				List<KeyValuePair<int, float>> list = new List<KeyValuePair<int, float>>(num3);
				for (int n = 0; n < num3; n++)
				{
					int key = binaryReader.ReadInt32();
					float value = binaryReader.ReadSingle();
					list.Add(new KeyValuePair<int, float>(key, value));
				}
				neroMeshData.Weights[m] = list;
			}
			int num4 = binaryReader.ReadInt32();
			neroMeshData.Triangles = new int[num4 * 3];
			for (int num5 = 0; num5 < num4 * 3; num5++)
			{
				neroMeshData.Triangles[num5] = binaryReader.ReadInt32();
			}
			return neroMeshData;
		}
	}
}