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 TinySnail v1.9.0
plugins\TinySnail.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Autodesk.Fbx")] [assembly: IgnoresAccessChecksTo("Discord.Sdk")] [assembly: IgnoresAccessChecksTo("Domain_Reload")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")] [assembly: IgnoresAccessChecksTo("Klattersynth")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonChat")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")] [assembly: IgnoresAccessChecksTo("PhotonVoice.API")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization")] [assembly: IgnoresAccessChecksTo("Sirenix.Utilities")] [assembly: IgnoresAccessChecksTo("Unity.Addressables")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")] [assembly: IgnoresAccessChecksTo("Unity.Localization")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.MemoryProfiler")] [assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.ResourceManager")] [assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")] [assembly: IgnoresAccessChecksTo("Unity.Splines")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("websocket-sharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TinySnail")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.9.0.0")] [assembly: AssemblyInformationalVersion("1.9.0")] [assembly: AssemblyProduct("TinySnail")] [assembly: AssemblyTitle("TinySnail")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.9.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 TinySnail { internal static class DifficultyPresets { public readonly struct Preset { public readonly float BaseSpeed; public readonly float MaxSpeed; public readonly float RageDistance; public readonly float KillRadius; public readonly int CountBase; public readonly int CountMax; public readonly bool DoubleEachMinute; public readonly float DoublingIntervalSeconds; public Preset(float baseSpeed, float maxSpeed, float rage, float kill, int countBase, int countMax, bool doubling, float interval) { BaseSpeed = baseSpeed; MaxSpeed = maxSpeed; RageDistance = rage; KillRadius = kill; CountBase = countBase; CountMax = countMax; DoubleEachMinute = doubling; DoublingIntervalSeconds = interval; } } public const string Custom = "Custom"; public const string Cute = "Cute"; public const string Standard = "Standard"; public const string Inevitable = "Inevitable"; public const string Snailpocalypse = "Snailpocalypse"; public static bool TryGet(string name, out Preset preset) { switch (name) { case "Cute": preset = new Preset(0.18f, 0.45f, 3f, 0.35f, 1, 4, doubling: false, 60f); return true; case "Standard": preset = new Preset(0.3f, 1.2f, 5f, 0.5f, 1, 8, doubling: false, 60f); return true; case "Inevitable": preset = new Preset(0.45f, 2f, 8f, 0.6f, 1, 16, doubling: true, 90f); return true; case "Snailpocalypse": preset = new Preset(0.55f, 3f, 12f, 0.8f, 3, 64, doubling: true, 45f); return true; default: preset = default(Preset); return false; } } } [HarmonyPatch(typeof(ItemGun), "Shoot")] internal static class ItemGunShootPatch { [HarmonyPostfix] private static void Postfix(ItemGun __instance, bool __result) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) try { if (__result && !((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).transform == (Object)null)) { SnailSenses.ReportNoise(((Component)__instance).transform.position); } } catch (Exception arg) { Plugin.Log.LogError((object)$"ItemGun.Shoot postfix failed: {arg}"); } } } [HarmonyPatch(typeof(PlayerHealth), "Hurt")] internal static class PlayerHealthHurtPatch { [HarmonyPostfix] private static void Postfix(PlayerHealth __instance, int damage) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) try { if (damage >= 10 && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.playerAvatar == (Object)null)) { SnailSenses.ReportNoise(((Object)(object)__instance.playerAvatar.playerTransform != (Object)null) ? __instance.playerAvatar.playerTransform.position : ((Component)__instance).transform.position); } } catch (Exception arg) { Plugin.Log.LogError((object)$"PlayerHealth.Hurt postfix failed: {arg}"); } } } internal class HeartbeatPlayer : MonoBehaviour { private AudioSource? _src; private float _nextBeatTime; private void Awake() { _src = ((Component)this).gameObject.AddComponent<AudioSource>(); _src.clip = SnailAudio.HeartbeatClip; _src.spatialBlend = 0f; _src.loop = false; _src.priority = 200; } private void Update() { try { Tick(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Heartbeat tick error: {arg}"); ((Behaviour)this).enabled = false; } } private void Tick() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_src == (Object)null || !Plugin.AudioEnabled.Value || !Plugin.HeartbeatSound.Value) { return; } PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); if ((Object)(object)val == (Object)null || (Object)(object)val.playerTransform == (Object)null || val.deadSet || !SemiFunc.RunIsLevel()) { return; } float num = TinySnailSpawner.NearestSnailDistance(val.playerTransform.position); if (!float.IsPositiveInfinity(num) && !(num > 30f)) { float num2 = Mathf.Lerp(0.3f, 1.5f, Mathf.Clamp01(num / 30f)); float num3 = Mathf.Lerp(0.25f, 0.95f, 1f - Mathf.Clamp01(num / 15f)); if (!(Time.unscaledTime < _nextBeatTime)) { _nextBeatTime = Time.unscaledTime + num2; _src.PlayOneShot(SnailAudio.HeartbeatClip, num3 * Mathf.Clamp01(Plugin.HeartbeatVolume.Value)); } } } } internal class MaterialCleanup : MonoBehaviour { private void OnDestroy() { try { Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } } } } catch { } } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] internal static class LevelGeneratorPatch { [HarmonyPostfix] private static void Postfix() { try { if (!SemiFunc.RunIsLevel()) { TinySnailSpawner.DespawnAll(); SnailDistanceHUD.Despawn(); SnailReproductionManager.Despawn(); SnailSenses.Clear(); } else { SnailSenses.Clear(); SnailNetwork.EnsureSpawned(); SnailDistanceHUD.EnsureSpawned(); TinySnailSpawner.SpawnInitialPopulation(); SnailReproductionManager.EnsureSpawned(); } } catch (Exception arg) { Plugin.Log.LogError((object)$"LevelGenerator.GenerateDone postfix failed: {arg}"); } } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class RunManagerPatch { [HarmonyPrefix] private static void Prefix() { try { TinySnailSpawner.DespawnAll(); SnailReproductionManager.Despawn(); } catch (Exception arg) { Plugin.Log.LogError((object)$"RunManager.ChangeLevel prefix failed: {arg}"); } } } [HarmonyPatch(typeof(RunManager), "LeaveToMainMenu")] internal static class RunManagerLeavePatch { [HarmonyPrefix] private static void Prefix() { try { TinySnailSpawner.DespawnAll(); SnailDistanceHUD.Despawn(); SnailReproductionManager.Despawn(); SnailNetwork.Despawn(); } catch (Exception arg) { Plugin.Log.LogError((object)$"RunManager.LeaveToMainMenu prefix failed: {arg}"); } } } [BepInPlugin("TinySnail", "TinySnail", "1.9.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony? _harmony; internal static ConfigEntry<string> DifficultyPreset; internal static ConfigEntry<float> BaseSpeed; internal static ConfigEntry<float> MaxSpeed; internal static ConfigEntry<float> RageDistance; internal static ConfigEntry<float> KillRadius; internal static ConfigEntry<bool> InvestigateNoises; internal static ConfigEntry<bool> ScaredByFlashlight; internal static ConfigEntry<bool> StealValuables; internal static ConfigEntry<float> Scale; internal static ConfigEntry<bool> SlimeTrail; internal static ConfigEntry<bool> PermanentTrail; internal static ConfigEntry<float> DecalInterval; internal static ConfigEntry<float> SlimeGlowIntensity; internal static ConfigEntry<bool> GlowingEyes; internal static ConfigEntry<bool> WobbleAnimation; internal static ConfigEntry<bool> SnailKillable; internal static ConfigEntry<int> SnailHealth; internal static ConfigEntry<float> ImpactDamageThreshold; internal static ConfigEntry<bool> CrouchStompKills; internal static ConfigEntry<int> SnailCountBase; internal static ConfigEntry<int> SnailCountPerLevel; internal static ConfigEntry<int> SnailCountMax; internal static ConfigEntry<float> MinSpawnDistance; internal static ConfigEntry<float> MaxSpawnDistance; internal static ConfigEntry<bool> DoubleEachMinute; internal static ConfigEntry<float> DoublingIntervalSeconds; internal static ConfigEntry<float> NetworkUpdateRateHz; internal static ConfigEntry<bool> AudioEnabled; internal static ConfigEntry<bool> SlitherSound; internal static ConfigEntry<float> SlitherVolume; internal static ConfigEntry<float> SlitherAudibleRange; internal static ConfigEntry<bool> HeartbeatSound; internal static ConfigEntry<float> HeartbeatVolume; internal static ConfigEntry<bool> SquelchOnDeath; internal static ConfigEntry<bool> HUDEnabled; internal static ConfigEntry<bool> HUDShowDistance; internal static ConfigEntry<string> HUDPosition; internal static float SafeBaseSpeed { get { if (!TryGetActivePreset(out var p)) { return Mathf.Max(0f, BaseSpeed.Value); } return p.BaseSpeed; } } internal static float SafeMaxSpeed { get { if (!TryGetActivePreset(out var p)) { return Mathf.Max(SafeBaseSpeed, MaxSpeed.Value); } return p.MaxSpeed; } } internal static float SafeRageDistance { get { if (!TryGetActivePreset(out var p)) { return Mathf.Max(0f, RageDistance.Value); } return p.RageDistance; } } internal static float SafeKillRadius { get { if (!TryGetActivePreset(out var p)) { return Mathf.Max(0.05f, KillRadius.Value); } return p.KillRadius; } } internal static int SafeCountMax { get { if (!TryGetActivePreset(out var p)) { return Mathf.Clamp(SnailCountMax.Value, 1, 64); } return Mathf.Clamp(p.CountMax, 1, 64); } } internal static int SafeCountBase { get { if (!TryGetActivePreset(out var p)) { return Mathf.Clamp(SnailCountBase.Value, 1, SafeCountMax); } return Mathf.Clamp(p.CountBase, 1, SafeCountMax); } } internal static bool SafeDoubleEachMinute { get { if (!TryGetActivePreset(out var p)) { return DoubleEachMinute.Value; } return p.DoubleEachMinute; } } internal static float SafeDoublingInterval { get { if (!TryGetActivePreset(out var p)) { return Mathf.Max(5f, DoublingIntervalSeconds.Value); } return Mathf.Max(5f, p.DoublingIntervalSeconds); } } internal static float SafeScale => Mathf.Clamp(Scale.Value, 0.01f, 5f); internal static int SafeCountPerLevel => Mathf.Clamp(SnailCountPerLevel.Value, 0, 5); internal static float SafeMinSpawnDistance => Mathf.Max(1f, MinSpawnDistance.Value); internal static float SafeMaxSpawnDistance => Mathf.Max(SafeMinSpawnDistance, MaxSpawnDistance.Value); internal static int SafeSnailHealth => Mathf.Clamp(SnailHealth.Value, 1, 100); internal static float SafeImpactDamageThreshold => Mathf.Max(0.5f, ImpactDamageThreshold.Value); private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { BindConfig(); _harmony = new Harmony("TinySnail"); _harmony.PatchAll(); Log.LogInfo((object)("TinySnail v1.9.0 loaded. The snail is coming. Preset: " + DifficultyPreset.Value)); } catch (Exception arg) { Log.LogError((object)string.Format("{0} failed to initialize: {1}", "TinySnail", arg)); } } private void OnDestroy() { try { TinySnailSpawner.DespawnAll(); SnailDistanceHUD.Despawn(); SnailReproductionManager.Despawn(); SnailNetwork.Despawn(); SlimeDecalManager.Clear(); SnailSenses.Clear(); SlimeMaterials.Invalidate(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; Log.LogInfo((object)"TinySnail unloaded cleanly."); } catch (Exception arg) { Log.LogError((object)$"OnDestroy cleanup failed: {arg}"); } } private void BindConfig() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Expected O, but got Unknown //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Expected O, but got Unknown //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Expected O, but got Unknown //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Expected O, but got Unknown //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Expected O, but got Unknown //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Expected O, but got Unknown //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Expected O, but got Unknown //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Expected O, but got Unknown //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Expected O, but got Unknown //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Expected O, but got Unknown //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Expected O, but got Unknown //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Expected O, but got Unknown //IL_070e: Unknown result type (might be due to invalid IL or missing references) //IL_0718: Expected O, but got Unknown DifficultyPreset = ((BaseUnityPlugin)this).Config.Bind<string>("Difficulty", "Preset", "Standard", new ConfigDescription("One-knob difficulty. Cute / Standard / Inevitable / Snailpocalypse override BaseSpeed, MaxSpeed, RageDistance, KillRadius, CountBase, CountMax, DoubleEachMinute, and DoublingIntervalSeconds. Set to 'Custom' to use the individual config values below instead.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "Custom", "Cute", "Standard", "Inevitable", "Snailpocalypse" }), Array.Empty<object>())); BaseSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "BaseSpeed", 0.3f, new ConfigDescription("Cruising speed in units/sec. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); MaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "MaxSpeed", 1.2f, new ConfigDescription("Top speed when right on top of you. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); RageDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "RageDistance", 5f, new ConfigDescription("Within this distance the snail accelerates. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>())); KillRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Behavior", "KillRadius", 0.5f, new ConfigDescription("Touch radius. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 5f), Array.Empty<object>())); InvestigateNoises = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "InvestigateNoises", true, "Gunshots and player damage attract the snail for ~10s."); ScaredByFlashlight = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "ScaredByFlashlight", true, "Shine a flashlight directly at the snail for >0.5s — it retracts and freezes for 3s."); StealValuables = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "StealValuables", true, "The snail crawls over loose valuables and carries them off. Grab it or kill it to get the item back."); Scale = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "Scale", 0.12f, new ConfigDescription("Overall snail size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>())); SlimeTrail = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "SlimeTrail", true, "Short-lived slime trail TrailRenderer behind the snail."); PermanentTrail = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "PermanentTrail", true, "Drop sticky slime decals on the floor wherever the snail has been."); DecalInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "DecalInterval", 0.6f, new ConfigDescription("Seconds between decal drops (per snail).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); SlimeGlowIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "SlimeGlowIntensity", 1f, new ConfigDescription("Multiplier on the emissive intensity of all slime visuals. REPO's bloom makes higher values glow brighter. 0 = matte slime.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>())); GlowingEyes = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "GlowingEyes", true, "Emissive red eyes + a small point light."); WobbleAnimation = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "WobbleAnimation", true, "Shell wobble and antenna sway while crawling."); SnailKillable = ((BaseUnityPlugin)this).Config.Bind<bool>("Killable", "Enabled", true, "The snail can be killed by impacts and crouch-stomps."); SnailHealth = ((BaseUnityPlugin)this).Config.Bind<int>("Killable", "Health", 1, new ConfigDescription("Hit points. 1 = one-shot.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ImpactDamageThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Killable", "ImpactDamageThreshold", 3f, new ConfigDescription("Minimum relative velocity (m/s) for a thrown valuable to damage the snail.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); CrouchStompKills = ((BaseUnityPlugin)this).Config.Bind<bool>("Killable", "CrouchStompKills", true, "When a crouching player gets within KillRadius, they stomp the snail instead of dying."); SnailCountBase = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "CountBase", 1, new ConfigDescription("Base number of snails per level. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>())); SnailCountPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "CountPerLevel", 0, new ConfigDescription("Extra snails per completed level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); SnailCountMax = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "CountMax", 32, new ConfigDescription("Hard cap on snails per level. (Custom preset only.)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 64), Array.Empty<object>())); MinSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "MinSpawnDistance", 20f, new ConfigDescription("Minimum spawn distance from local player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>())); MaxSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "MaxSpawnDistance", 80f, new ConfigDescription("Maximum spawn distance from local player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f), Array.Empty<object>())); DoubleEachMinute = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "DoubleEachMinute", false, "OFF by default — default mode is one snail per level. Turn on for escalating doubling: every minute the snail count doubles (1->2->4->8...)."); DoublingIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "DoublingIntervalSeconds", 60f, new ConfigDescription("Interval between doublings, in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), Array.Empty<object>())); NetworkUpdateRateHz = ((BaseUnityPlugin)this).Config.Bind<float>("Networking", "UpdateRateHz", 15f, new ConfigDescription("Master client snail pose broadcasts per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); AudioEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "Enabled", true, "Master audio toggle. If false, no procedural audio is generated."); SlitherSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "SlitherSound", true, "Looping 3D slither sound on the snail."); SlitherVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "SlitherVolume", 0.5f, new ConfigDescription("Slither loop max volume (at minDistance).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SlitherAudibleRange = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "SlitherAudibleRange", 15f, new ConfigDescription("Distance in units beyond which the slither is inaudible.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>())); HeartbeatSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "HeartbeatSound", true, "2D heartbeat thump that speeds up as the snail closes in."); HeartbeatVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "HeartbeatVolume", 0.7f, new ConfigDescription("Heartbeat volume scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SquelchOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "SquelchOnDeath", true, "Play a wet squelch when the snail dies."); HUDEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "Enabled", true, "Show the proximity 'heat meter' on screen during gameplay."); HUDShowDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowDistance", false, "Also show a small numeric distance under the heat word."); HUDPosition = ((BaseUnityPlugin)this).Config.Bind<string>("HUD", "Position", "TopRight", new ConfigDescription("HUD screen position.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "TopLeft", "TopRight", "BottomLeft", "BottomRight", "BottomCenter" }), Array.Empty<object>())); } private static bool TryGetActivePreset(out DifficultyPresets.Preset p) { return DifficultyPresets.TryGet(DifficultyPreset.Value, out p); } } internal static class SlimeDecalManager { private static readonly Queue<GameObject> _decals = new Queue<GameObject>(); private static GameObject? _root; private static Mesh? _quadMesh; private const int MaxDecals = 600; private static readonly int GroundMask = -37; public static void Initialize() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_root == (Object)null) { _root = new GameObject("TinySnailDecals"); Object.DontDestroyOnLoad((Object)(object)_root); } } public static void Clear() { while (_decals.Count > 0) { GameObject val = _decals.Dequeue(); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } public static void DropAt(Vector3 worldPos, float scale) { //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_001d: 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_0027: 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_004c: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00fb: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.PermanentTrail.Value) { return; } Initialize(); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(worldPos + Vector3.up * 1f, Vector3.down, ref val, 5f, GroundMask, (QueryTriggerInteraction)1)) { return; } GameObject val2 = new GameObject("SlimeDecal"); val2.transform.SetParent(_root.transform, false); val2.transform.position = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.01f; val2.transform.rotation = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val)).normal) * Quaternion.Euler(0f, Random.Range(0f, 360f), 0f); float num = Random.Range(0.95f, 1.45f); float num2 = Mathf.Clamp(scale * 10f, 0.18f, 1.6f) * num; val2.transform.localScale = new Vector3(num2, num2, num2); val2.AddComponent<MeshFilter>().sharedMesh = GetQuadMesh(); MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterial = SlimeMaterials.Decal; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; _decals.Enqueue(val2); while (_decals.Count > 600) { GameObject val3 = _decals.Dequeue(); if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)val3); } } } private static Mesh GetQuadMesh() { //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_0024: Expected O, but got Unknown //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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0077: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_quadMesh != (Object)null) { return _quadMesh; } Mesh val = new Mesh { name = "TinySnailDecalQuad" }; val.vertices = (Vector3[])(object)new Vector3[4] { new Vector3(-0.5f, 0f, -0.5f), new Vector3(0.5f, 0f, -0.5f), new Vector3(0.5f, 0f, 0.5f), new Vector3(-0.5f, 0f, 0.5f) }; val.uv = (Vector2[])(object)new Vector2[4] { new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f) }; val.triangles = new int[6] { 0, 2, 1, 0, 3, 2 }; val.RecalculateNormals(); val.RecalculateBounds(); _quadMesh = val; return val; } } internal static class SlimeMaterials { private static Material? _decal; private static Material? _trail; private static Material? _particle; public static Material Decal => _decal ?? (_decal = BuildEmissive("TinySnail_SlimeDecal", new Color(0.7f, 1f, 0.55f, 0.95f), new Color(0.55f, 1f, 0.3f), 1.4f)); public static Material Trail => _trail ?? (_trail = BuildEmissive("TinySnail_SlimeTrail", new Color(0.8f, 1f, 0.65f, 1f), new Color(0.6f, 1f, 0.35f), 1.8f)); public static Material Particle => _particle ?? (_particle = BuildEmissive("TinySnail_SlimeParticle", new Color(0.8f, 1f, 0.65f, 1f), new Color(0.6f, 1f, 0.35f), 1.6f)); private static Material BuildEmissive(string name, Color baseTint, Color emissionTint, float emissionBoost) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003f: 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_0109: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(Shader.Find("Standard") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Transparent")) { name = name }; val.mainTexture = (Texture)(object)SnailTextures.SlimeBlob; val.color = baseTint; if (val.HasProperty("_Mode")) { val.SetFloat("_Mode", 3f); val.SetOverrideTag("RenderType", "Transparent"); val.SetInt("_SrcBlend", 5); val.SetInt("_DstBlend", 10); val.SetInt("_ZWrite", 0); val.DisableKeyword("_ALPHATEST_ON"); val.DisableKeyword("_ALPHABLEND_ON"); val.EnableKeyword("_ALPHAPREMULTIPLY_ON"); val.renderQueue = 3000; } if (val.HasProperty("_EmissionColor")) { val.EnableKeyword("_EMISSION"); float num = Mathf.Max(0.1f, emissionBoost) * Mathf.Clamp(Plugin.SlimeGlowIntensity.Value, 0f, 8f); val.SetColor("_EmissionColor", emissionTint * num); val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1; } return val; } public static void Invalidate() { if ((Object)(object)_decal != (Object)null) { Object.Destroy((Object)(object)_decal); } if ((Object)(object)_trail != (Object)null) { Object.Destroy((Object)(object)_trail); } if ((Object)(object)_particle != (Object)null) { Object.Destroy((Object)(object)_particle); } _decal = null; _trail = null; _particle = null; } } internal static class SnailAssetBundle { private static bool _attemptedLoad; private static AssetBundle? _bundle; private static GameObject? _prefab; public static bool TryGetPrefab(out GameObject prefab) { EnsureLoaded(); if ((Object)(object)_prefab != (Object)null) { prefab = _prefab; return true; } prefab = null; return false; } private static void EnsureLoaded() { if (_attemptedLoad) { return; } _attemptedLoad = true; try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (string.IsNullOrEmpty(directoryName)) { return; } string text = Path.Combine(directoryName, "assets", "tinysnail.bundle"); if (!File.Exists(text)) { Plugin.Log.LogInfo((object)("No asset bundle at " + text + "; using procedural snail.")); return; } _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { Plugin.Log.LogWarning((object)("Asset bundle at " + text + " failed to load.")); return; } _prefab = _bundle.LoadAsset<GameObject>("TinySnail"); if ((Object)(object)_prefab == (Object)null) { Plugin.Log.LogWarning((object)"Asset bundle loaded but no 'TinySnail' prefab inside."); } else { Plugin.Log.LogInfo((object)"Loaded snail prefab from asset bundle."); } } catch (Exception arg) { Plugin.Log.LogError((object)$"Asset bundle load failed: {arg}"); } } } internal static class SnailAudio { private static AudioClip? _slither; private static AudioClip? _heartbeat; public static AudioClip SlitherClip => _slither ?? (_slither = BuildSlitherLoop()); public static AudioClip HeartbeatClip => _heartbeat ?? (_heartbeat = BuildHeartbeat()); private static AudioClip BuildSlitherLoop() { int num = 44100; float[] array = new float[num]; Random random = new Random(3054); float num2 = 0f; for (int i = 0; i < num; i++) { float num3 = (float)(random.NextDouble() * 2.0 - 1.0); float num4 = 0.1f; num2 += num4 * (num3 - num2); float num5 = (float)i / 22050f; float num6 = 0.6f + 0.4f * Mathf.Sin(num5 * MathF.PI * 2f * 0.7f); float num7 = 0.1f * Mathf.Sin(num5 * MathF.PI * 2f * 220f); array[i] = (num2 * 0.9f + num7) * num6 * 0.35f; } int num8 = 4410; for (int j = 0; j < num8; j++) { float num9 = (float)j / (float)num8; array[j] = array[j] * num9 + array[num - num8 + j] * (1f - num9); } AudioClip obj = AudioClip.Create("TinySnail_Slither", num, 1, 22050, false); obj.SetData(array, 0); return obj; } private static AudioClip BuildHeartbeat() { int num = 5512; float[] array = new float[num]; for (int i = 0; i < num; i++) { float num2 = (float)i / 22050f; float num3 = Mathf.Exp((0f - num2) * 35f); float num4 = ((num2 > 0.1f) ? Mathf.Exp((0f - (num2 - 0.1f)) * 28f) : 0f); float num5 = Mathf.Sin(num2 * MathF.PI * 2f * 60f); float num6 = Mathf.Sin(num2 * MathF.PI * 2f * 48f); array[i] = (num3 * num5 + num4 * num6 * 0.75f) * 0.55f; } AudioClip obj = AudioClip.Create("TinySnail_Heartbeat", num, 1, 22050, false); obj.SetData(array, 0); return obj; } public static void PlaySquelchAt(Vector3 worldPos, float volume = 0.7f) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (Plugin.AudioEnabled.Value) { int num = 3969; float[] array = new float[num]; Random random = new Random(); float num2 = 0f; for (int i = 0; i < num; i++) { float num3 = (float)i / 22050f; float num4 = Mathf.Lerp(1f, 0.3f, num3 / 0.18f); float num5 = (float)(random.NextDouble() * 2.0 - 1.0); num2 += 0.2f * (num5 - num2); float num6 = Mathf.Exp((0f - num3) * 18f); array[i] = num2 * num6 * num4; } AudioClip obj = AudioClip.Create("squelch", num, 1, 22050, false); obj.SetData(array, 0); AudioSource.PlayClipAtPoint(obj, worldPos, volume); } } public static void AttachSlither(GameObject snail) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Plugin.AudioEnabled.Value && Plugin.SlitherSound.Value) { GameObject val = new GameObject("Slither"); val.transform.SetParent(snail.transform, false); AudioSource obj = val.AddComponent<AudioSource>(); obj.clip = SlitherClip; obj.loop = true; obj.spatialBlend = 1f; obj.rolloffMode = (AudioRolloffMode)1; obj.minDistance = 1.5f; obj.maxDistance = Mathf.Max(5f, Plugin.SlitherAudibleRange.Value); obj.volume = Mathf.Clamp01(Plugin.SlitherVolume.Value); obj.priority = 192; obj.Play(); } } } internal static class SnailDeathEffects { public static void PlayAt(Vector3 worldPos, float snailScale) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0028: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0076: 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_00ba: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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) try { if (Plugin.SquelchOnDeath.Value) { SnailAudio.PlaySquelchAt(worldPos); } GameObject val = new GameObject("SnailDeathBurst"); val.transform.position = worldPos + Vector3.up * 0.1f; Object.DontDestroyOnLoad((Object)(object)val); ParticleSystem val2 = val.AddComponent<ParticleSystem>(); MainModule main = val2.main; ((MainModule)(ref main)).duration = 0.3f; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.6f, 1.2f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.6f, 1.6f); ((MainModule)(ref main)).startSize = new MinMaxCurve(Mathf.Max(0.05f, snailScale * 1.5f), Mathf.Max(0.1f, snailScale * 3f)); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.85f, 1f, 0.7f, 1f), new Color(0.55f, 1f, 0.3f, 1f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.8f); ((MainModule)(ref main)).maxParticles = 40; ((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)2; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)30) }); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = Mathf.Max(0.04f, snailScale * 0.5f); ParticleSystemRenderer component = ((Component)val2).GetComponent<ParticleSystemRenderer>(); ((Renderer)component).material = SlimeMaterials.Particle; component.renderMode = (ParticleSystemRenderMode)0; Object.Destroy((Object)(object)val, 4f); } catch (Exception arg) { Plugin.Log.LogError((object)$"Death burst failed: {arg}"); } } } internal class SnailDistanceHUD : MonoBehaviour { private static SnailDistanceHUD? _instance; private Canvas? _canvas; private Text? _label; private Text? _distanceText; private Image? _bar; private Image? _bg; private Image? _icon; private float _pulseTime; private static readonly (float maxDist, string word, Color color)[] Tiers = new(float, string, Color)[7] { (2f, "SCORCHING", new Color(1f, 0.1f, 0.1f)), (5f, "Burning", new Color(1f, 0.35f, 0.1f)), (10f, "Hot", new Color(1f, 0.6f, 0.15f)), (18f, "Warm", new Color(1f, 0.85f, 0.25f)), (30f, "Tepid", new Color(0.7f, 0.95f, 0.45f)), (50f, "Cool", new Color(0.45f, 0.85f, 0.95f)), (float.PositiveInfinity, "Ice cold", new Color(0.6f, 0.75f, 1f)) }; public static void EnsureSpawned() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_instance != (Object)null) && Plugin.HUDEnabled.Value) { GameObject val = new GameObject("TinySnailHUD"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<SnailDistanceHUD>(); val.AddComponent<HeartbeatPlayer>(); } } public static void Despawn() { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } } private void Awake() { try { BuildUI(); } catch (Exception arg) { Plugin.Log.LogError((object)$"HUD build failed: {arg}"); Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void BuildUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00b2: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Expected O, but got Unknown //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Expected O, but got Unknown //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Canvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 100; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 0.5f; val.AddComponent<GraphicRaycaster>(); GameObject val2 = new GameObject("Panel"); val2.transform.SetParent(val.transform, false); RectTransform obj2 = val2.AddComponent<RectTransform>(); SetAnchor(obj2, Plugin.HUDPosition.Value); obj2.sizeDelta = new Vector2(230f, 80f); _bg = val2.AddComponent<Image>(); _bg.sprite = SnailTextures.HudPanel; _bg.type = (Type)1; ((Graphic)_bg).color = new Color(0.05f, 0.05f, 0.08f, 0.78f); ((Graphic)_bg).raycastTarget = false; GameObject val3 = new GameObject("Icon"); val3.transform.SetParent(val2.transform, false); RectTransform obj3 = val3.AddComponent<RectTransform>(); obj3.anchorMin = new Vector2(0f, 0.5f); obj3.anchorMax = new Vector2(0f, 0.5f); obj3.pivot = new Vector2(0.5f, 0.5f); obj3.sizeDelta = new Vector2(42f, 42f); obj3.anchoredPosition = new Vector2(30f, 12f); _icon = val3.AddComponent<Image>(); _icon.sprite = SnailTextures.SnailIcon; ((Graphic)_icon).raycastTarget = false; GameObject val4 = new GameObject("Label"); val4.transform.SetParent(val2.transform, false); RectTransform obj4 = val4.AddComponent<RectTransform>(); obj4.anchorMin = new Vector2(0f, 0.45f); obj4.anchorMax = new Vector2(1f, 1f); obj4.offsetMin = new Vector2(58f, 0f); obj4.offsetMax = new Vector2(-12f, -4f); _label = val4.AddComponent<Text>(); _label.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); _label.fontSize = 24; _label.alignment = (TextAnchor)3; ((Graphic)_label).color = new Color(0.65f, 0.8f, 1f); _label.text = "Ice cold"; ((Graphic)_label).raycastTarget = false; _label.fontStyle = (FontStyle)1; GameObject val5 = new GameObject("Distance"); val5.transform.SetParent(val2.transform, false); RectTransform obj5 = val5.AddComponent<RectTransform>(); obj5.anchorMin = new Vector2(0f, 0.4f); obj5.anchorMax = new Vector2(1f, 0.55f); obj5.offsetMin = new Vector2(58f, 0f); obj5.offsetMax = new Vector2(-12f, 0f); _distanceText = val5.AddComponent<Text>(); _distanceText.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); _distanceText.fontSize = 13; _distanceText.alignment = (TextAnchor)3; ((Graphic)_distanceText).color = new Color(1f, 1f, 1f, 0.55f); ((Graphic)_distanceText).raycastTarget = false; ((Component)_distanceText).gameObject.SetActive(Plugin.HUDShowDistance.Value); GameObject val6 = new GameObject("BarBg"); val6.transform.SetParent(val2.transform, false); RectTransform obj6 = val6.AddComponent<RectTransform>(); obj6.anchorMin = new Vector2(0f, 0f); obj6.anchorMax = new Vector2(1f, 0.18f); obj6.offsetMin = new Vector2(58f, 8f); obj6.offsetMax = new Vector2(-12f, -2f); Image obj7 = val6.AddComponent<Image>(); obj7.sprite = SnailTextures.HudPanel; obj7.type = (Type)1; ((Graphic)obj7).color = new Color(1f, 1f, 1f, 0.1f); ((Graphic)obj7).raycastTarget = false; GameObject val7 = new GameObject("Bar"); val7.transform.SetParent(val6.transform, false); RectTransform obj8 = val7.AddComponent<RectTransform>(); obj8.anchorMin = new Vector2(0f, 0f); obj8.anchorMax = new Vector2(0f, 1f); obj8.offsetMin = new Vector2(2f, 2f); obj8.offsetMax = new Vector2(0f, -2f); _bar = val7.AddComponent<Image>(); _bar.sprite = SnailTextures.HudPanel; _bar.type = (Type)1; ((Graphic)_bar).color = new Color(0.5f, 0.7f, 1f); ((Graphic)_bar).raycastTarget = false; } private static void SetAnchor(RectTransform rt, string pos) { //IL_015d: 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_016b: 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) Vector2 val = default(Vector2); Vector2 pivot = default(Vector2); Vector2 anchoredPosition = default(Vector2); switch (pos) { case "TopLeft": ((Vector2)(ref val))..ctor(0f, 1f); ((Vector2)(ref pivot))..ctor(0f, 1f); ((Vector2)(ref anchoredPosition))..ctor(20f, -20f); break; case "BottomLeft": ((Vector2)(ref val))..ctor(0f, 0f); ((Vector2)(ref pivot))..ctor(0f, 0f); ((Vector2)(ref anchoredPosition))..ctor(20f, 20f); break; case "BottomRight": ((Vector2)(ref val))..ctor(1f, 0f); ((Vector2)(ref pivot))..ctor(1f, 0f); ((Vector2)(ref anchoredPosition))..ctor(-20f, 20f); break; case "BottomCenter": ((Vector2)(ref val))..ctor(0.5f, 0f); ((Vector2)(ref pivot))..ctor(0.5f, 0f); ((Vector2)(ref anchoredPosition))..ctor(0f, 20f); break; default: ((Vector2)(ref val))..ctor(1f, 1f); ((Vector2)(ref pivot))..ctor(1f, 1f); ((Vector2)(ref anchoredPosition))..ctor(-20f, -20f); break; } rt.anchorMin = val; rt.anchorMax = val; rt.pivot = pivot; rt.anchoredPosition = anchoredPosition; } private void Update() { try { UpdateInternal(); } catch (Exception arg) { Plugin.Log.LogError((object)$"HUD update error: {arg}"); ((Behaviour)this).enabled = false; } } private void UpdateInternal() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_label == (Object)null || (Object)(object)_bar == (Object)null || (Object)(object)_bg == (Object)null || (Object)(object)_icon == (Object)null) { return; } PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); if (!SemiFunc.RunIsLevel() || !((Object)(object)val != (Object)null) || !((Object)(object)val.playerTransform != (Object)null) || val.deadSet || (Object)(object)val == (Object)null || (Object)(object)val.playerTransform == (Object)null) { if (((Behaviour)_bg).enabled) { SetVisible(v: false); } return; } if (!((Behaviour)_bg).enabled) { SetVisible(v: true); } if ((Object)(object)_distanceText != (Object)null) { ((Behaviour)_distanceText).enabled = Plugin.HUDShowDistance.Value; } float num = TinySnailSpawner.NearestSnailDistance(val.playerTransform.position); if (float.IsPositiveInfinity(num)) { ApplyTier(Tiers[^1], 0f); if ((Object)(object)_distanceText != (Object)null) { _distanceText.text = ""; } return; } (float, string, Color) tier = PickTier(num); float num2 = Mathf.Clamp01(1f - num / 50f); num2 = Mathf.Pow(num2, 1.4f); ApplyTier(tier, num2); if (num < 5f) { _pulseTime += Time.deltaTime * Mathf.Lerp(2.5f, 8f, Mathf.Clamp01(1f - num / 5f)); float num3 = (Mathf.Sin(_pulseTime) + 1f) * 0.5f; ((Graphic)_bg).color = Color.Lerp(new Color(tier.Item3.r * 0.3f, 0.05f, 0.05f, 0.78f), new Color(tier.Item3.r * 0.6f, 0.1f, 0.1f, 0.92f), num3); } else { ((Graphic)_bg).color = new Color(0.05f, 0.05f, 0.08f, 0.78f); } if ((Object)(object)_distanceText != (Object)null && ((Behaviour)_distanceText).enabled) { _distanceText.text = $"{num:0.0} m"; } } private void SetVisible(bool v) { if ((Object)(object)_bg != (Object)null) { ((Behaviour)_bg).enabled = v; } if ((Object)(object)_label != (Object)null) { ((Behaviour)_label).enabled = v; } if ((Object)(object)_bar != (Object)null) { ((Behaviour)_bar).enabled = v; } if ((Object)(object)_icon != (Object)null) { ((Behaviour)_icon).enabled = v; } if ((Object)(object)_distanceText != (Object)null) { ((Behaviour)_distanceText).enabled = v && Plugin.HUDShowDistance.Value; } } private void ApplyTier((float maxDist, string word, Color color) tier, float heat) { //IL_0018: 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_003e: 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) _label.text = tier.word; ((Graphic)_label).color = tier.color; ((Graphic)_bar).color = tier.color; ((RectTransform)((Component)_bar).transform).anchorMax = new Vector2(heat, 1f); } private static (float maxDist, string word, Color color) PickTier(float dist) { (float, string, Color)[] tiers = Tiers; for (int i = 0; i < tiers.Length; i++) { (float, string, Color) result = tiers[i]; if (dist < result.Item1) { return result; } } return Tiers[^1]; } } internal class SnailItemTheft : MonoBehaviour { private PhysGrabObject? _carried; private Rigidbody? _carriedRb; private bool _originalKinematic; private float _nextScanTime; private const float ScanInterval = 0.4f; private const float CarryStickRadius = 0.6f; private const float CarryLoseDistance = 4f; private void Update() { try { Tick(); } catch (Exception arg) { Plugin.Log.LogError((object)$"SnailItemTheft tick error: {arg}"); } } private void Tick() { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) if (!Plugin.StealValuables.Value) { Drop(); return; } if ((Object)(object)_carried != (Object)null) { if ((Object)(object)_carried.rb == (Object)null || !((Component)_carried).gameObject.activeInHierarchy) { Drop(); } else if (IsBeingGrabbedByPlayer(_carried)) { Drop(); } else { if (!(Vector3.Distance(((Component)_carried).transform.position, ((Component)this).transform.position) > 4f)) { Vector3 val = ((Component)this).transform.position + Vector3.up * (((Component)this).transform.lossyScale.y * 0.6f); ((Component)_carried).transform.position = Vector3.Lerp(((Component)_carried).transform.position, val, Time.deltaTime * 8f); return; } Drop(); } } TinySnailBehavior component = ((Component)this).GetComponent<TinySnailBehavior>(); if ((Object)(object)component == (Object)null || !component.IsMasterSim || Time.time < _nextScanTime) { return; } _nextScanTime = Time.time + 0.4f; Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 0.6f); foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null)) { PhysGrabObject componentInParent = ((Component)val2).GetComponentInParent<PhysGrabObject>(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.rb == (Object)null) && !IsBeingGrabbedByPlayer(componentInParent) && !(componentInParent.rb.mass > 4f) && !((Object)(object)((Component)componentInParent).GetComponent<SnailTheftMarker>() != (Object)null)) { Pickup(componentInParent); break; } } } } private static bool IsBeingGrabbedByPlayer(PhysGrabObject pgo) { try { return SemiFunc.PhysGrabObjectIsGrabbed(pgo); } catch { return false; } } private void Pickup(PhysGrabObject pgo) { _carried = pgo; _carriedRb = pgo.rb; if ((Object)(object)_carriedRb != (Object)null) { _originalKinematic = _carriedRb.isKinematic; _carriedRb.isKinematic = true; } if ((Object)(object)((Component)pgo).gameObject.GetComponent<SnailTheftMarker>() == (Object)null) { ((Component)pgo).gameObject.AddComponent<SnailTheftMarker>(); } Plugin.Log.LogInfo((object)("Snail stole " + ((Object)pgo).name + ".")); } private void Drop() { if (!((Object)(object)_carried == (Object)null)) { if ((Object)(object)_carriedRb != (Object)null) { _carriedRb.isKinematic = _originalKinematic; } SnailTheftMarker component = ((Component)_carried).gameObject.GetComponent<SnailTheftMarker>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } _carried = null; _carriedRb = null; } } private void OnDestroy() { Drop(); } } internal class SnailTheftMarker : MonoBehaviour { } internal class SnailNetwork : MonoBehaviour { public const byte EvtSpawn = 180; public const byte EvtDespawn = 181; public const byte EvtPose = 182; public const byte EvtDespawnAll = 183; private static SnailNetwork? _instance; private readonly Dictionary<int, GameObject> _snails = new Dictionary<int, GameObject>(); private int _nextSnailId = 1; private float _nextPoseBroadcast; private bool _eventsSubscribed; public static SnailNetwork? Instance => _instance; public bool IsMaster => SafeIsMaster(); public IReadOnlyDictionary<int, GameObject> Snails => _snails; public int Count => _snails.Count; public static void EnsureSpawned() { //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_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("TinySnailNetwork"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<SnailNetwork>(); } } public static void Despawn() { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } } private static bool SafeIsMaster() { try { return SemiFunc.IsMasterClientOrSingleplayer(); } catch { return true; } } private static bool SafeIsMultiplayer() { try { return SemiFunc.IsMultiplayer(); } catch { return false; } } private void Awake() { TrySubscribeToPhoton(); } private void TrySubscribeToPhoton() { if (_eventsSubscribed) { return; } try { if (PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += OnEventReceived; _eventsSubscribed = true; Plugin.Log.LogInfo((object)"SnailNetwork subscribed to Photon events."); } } catch (Exception arg) { Plugin.Log.LogError((object)$"SnailNetwork Photon subscribe failed: {arg}"); } } private void OnDestroy() { try { if (_eventsSubscribed && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= OnEventReceived; } } catch { } foreach (GameObject value in _snails.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } _snails.Clear(); if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } public GameObject? MasterSpawn(Vector3 worldPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!IsMaster) { return null; } int id = _nextSnailId++; GameObject? obj = BuildSnail(id, worldPos); if ((Object)(object)obj != (Object)null && SafeIsMultiplayer()) { BroadcastSpawn(id, worldPos); } return obj; } public void MasterDespawnAll() { if (!IsMaster) { return; } foreach (GameObject value in _snails.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } _snails.Clear(); if (SafeIsMultiplayer()) { BroadcastDespawnAll(); } } private void Update() { try { TickNetwork(); } catch (Exception arg) { Plugin.Log.LogError((object)$"SnailNetwork tick error: {arg}"); } } private void TickNetwork() { if (!_eventsSubscribed) { TrySubscribeToPhoton(); } if (IsMaster && SafeIsMultiplayer() && _snails.Count != 0 && !(Time.unscaledTime < _nextPoseBroadcast)) { float num = Mathf.Clamp(Plugin.NetworkUpdateRateHz.Value, 1f, 30f); _nextPoseBroadcast = Time.unscaledTime + 1f / num; BroadcastPoses(); } } private static void BroadcastSpawn(int id, Vector3 pos) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0038: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) try { byte[] array = new byte[16]; WriteInt32(array, 0, id); WriteSingle(array, 4, pos.x); WriteSingle(array, 8, pos.y); WriteSingle(array, 12, pos.z); RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)180, (object)array, val, SendOptions.SendReliable); } catch (Exception arg) { Plugin.Log.LogError((object)$"BroadcastSpawn failed: {arg}"); } } private static void BroadcastDespawnAll() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) try { RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)183, (object)Array.Empty<byte>(), val, SendOptions.SendReliable); } catch (Exception arg) { Plugin.Log.LogError((object)$"BroadcastDespawnAll failed: {arg}"); } } private void BroadcastPoses() { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0155: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) try { int num = 0; foreach (KeyValuePair<int, GameObject> snail in _snails) { if ((Object)(object)snail.Value != (Object)null) { num++; } } if (num == 0) { return; } num = Mathf.Min(num, 200); byte[] array = new byte[1 + num * 20]; array[0] = (byte)num; int num2 = 1; int num3 = 0; foreach (KeyValuePair<int, GameObject> snail2 in _snails) { if (num3 < num) { if (!((Object)(object)snail2.Value == (Object)null)) { Transform transform = snail2.Value.transform; WriteInt32(array, num2, snail2.Key); num2 += 4; WriteSingle(array, num2, transform.position.x); num2 += 4; WriteSingle(array, num2, transform.position.y); num2 += 4; WriteSingle(array, num2, transform.position.z); num2 += 4; WriteSingle(array, num2, transform.eulerAngles.y); num2 += 4; num3++; } continue; } break; } RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)182, (object)array, val, SendOptions.SendUnreliable); } catch (Exception arg) { Plugin.Log.LogError((object)$"BroadcastPoses failed: {arg}"); } } private void OnEventReceived(EventData ev) { try { switch (ev.Code) { case 180: ApplySpawn((byte[])ev.CustomData); break; case 181: ApplyDespawn((byte[])ev.CustomData); break; case 182: ApplyPose((byte[])ev.CustomData); break; case 183: ApplyDespawnAll(); break; } } catch (Exception arg) { Plugin.Log.LogError((object)$"OnEventReceived failed: {arg}"); } } private void ApplySpawn(byte[] payload) { //IL_003a: 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) if (!IsMaster && payload != null && payload.Length >= 16) { int num = ReadInt32(payload, 0); Vector3 pos = default(Vector3); ((Vector3)(ref pos))..ctor(ReadSingle(payload, 4), ReadSingle(payload, 8), ReadSingle(payload, 12)); if (ValidatePayload(num, pos) && _snails.Count < Mathf.Max(1, Plugin.SafeCountMax * 2) && !_snails.ContainsKey(num)) { BuildSnail(num, pos); } } } private static bool ValidatePayload(int id, Vector3 pos) { //IL_000e: 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) //IL_0028: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (id <= 0 || id > 1000000) { return false; } if (!IsFinite(pos.x) || !IsFinite(pos.y) || !IsFinite(pos.z)) { return false; } if (Mathf.Abs(pos.x) > 10000f || Mathf.Abs(pos.y) > 10000f || Mathf.Abs(pos.z) > 10000f) { return false; } return true; } private static bool IsFinite(float v) { if (!float.IsNaN(v)) { return !float.IsInfinity(v); } return false; } private void ApplyDespawn(byte[] payload) { if (IsMaster || payload == null || payload.Length < 4) { return; } int key = ReadInt32(payload, 0); if (_snails.TryGetValue(key, out GameObject value)) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } _snails.Remove(key); } } private void ApplyPose(byte[] payload) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0127: Unknown result type (might be due to invalid IL or missing references) if (IsMaster || payload == null || payload.Length < 1) { return; } int num = payload[0]; if (num <= 0 || num > 200 || payload.Length < 1 + num * 20) { return; } int num2 = 1; Vector3 val = default(Vector3); for (int i = 0; i < num; i++) { int num3 = ReadInt32(payload, num2); num2 += 4; float num4 = ReadSingle(payload, num2); num2 += 4; float num5 = ReadSingle(payload, num2); num2 += 4; float num6 = ReadSingle(payload, num2); num2 += 4; float num7 = ReadSingle(payload, num2); num2 += 4; ((Vector3)(ref val))..ctor(num4, num5, num6); if (!ValidatePayload(num3, val)) { continue; } if (!IsFinite(num7)) { num7 = 0f; } if (!_snails.TryGetValue(num3, out GameObject value) || (Object)(object)value == (Object)null) { if (_snails.Count >= Mathf.Max(1, Plugin.SafeCountMax * 2)) { continue; } value = BuildSnail(num3, val); if ((Object)(object)value == (Object)null) { continue; } } Transform transform = value.transform; transform.position = Vector3.Lerp(transform.position, val, 0.5f); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0f, num7, 0f), 0.5f); } } private void ApplyDespawnAll() { if (IsMaster) { return; } foreach (GameObject value in _snails.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } _snails.Clear(); } private GameObject? BuildSnail(int id, Vector3 pos) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) GameObject result = null; try { var (val, parts) = TinySnailVisual.Build(Plugin.SafeScale); ((Object)val).name = $"TinySnail#{id}"; val.transform.position = pos; if (Plugin.SlimeTrail.Value) { TinySnailVisual.AttachSlimeTrail(val); TinySnailVisual.AttachSlimeDrips(val); } TinySnailBehavior tinySnailBehavior = val.AddComponent<TinySnailBehavior>(); tinySnailBehavior.Parts = parts; tinySnailBehavior.NetworkId = id; tinySnailBehavior.IsMasterSim = IsMaster; _snails[id] = val; result = val; } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to build snail #{id}: {arg}"); } return result; } public void MasterRemoveSnail(int id) { //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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!IsMaster) { return; } if (_snails.TryGetValue(id, out GameObject value)) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } _snails.Remove(id); } if (!SafeIsMultiplayer()) { return; } byte[] array = new byte[4]; WriteInt32(array, 0, id); try { RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)181, (object)array, val, SendOptions.SendReliable); } catch (Exception arg) { Plugin.Log.LogError((object)$"Despawn broadcast failed: {arg}"); } } public float NearestDistanceTo(Vector3 worldPos) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) float num = float.PositiveInfinity; foreach (KeyValuePair<int, GameObject> snail in _snails) { GameObject value = snail.Value; if (!((Object)(object)value == (Object)null)) { float num2 = Vector3.Distance(value.transform.position, worldPos); if (num2 < num) { num = num2; } } } return num; } private static void WriteInt32(byte[] buf, int off, int v) { buf[off] = (byte)((uint)v & 0xFFu); buf[off + 1] = (byte)((uint)(v >> 8) & 0xFFu); buf[off + 2] = (byte)((uint)(v >> 16) & 0xFFu); buf[off + 3] = (byte)((uint)(v >> 24) & 0xFFu); } private static int ReadInt32(byte[] buf, int off) { return buf[off] | (buf[off + 1] << 8) | (buf[off + 2] << 16) | (buf[off + 3] << 24); } private static void WriteSingle(byte[] buf, int off, float v) { byte[] bytes = BitConverter.GetBytes(v); buf[off] = bytes[0]; buf[off + 1] = bytes[1]; buf[off + 2] = bytes[2]; buf[off + 3] = bytes[3]; } private static float ReadSingle(byte[] buf, int off) { return BitConverter.ToSingle(buf, off); } } internal class SnailReproductionManager : MonoBehaviour { private static SnailReproductionManager? _instance; private float _levelStartTime; private int _doublingsApplied; public static void EnsureSpawned() { //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_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("TinySnailReproduction"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent<SnailReproductionManager>(); } } public static void Despawn() { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)_instance).gameObject); _instance = null; } } private void Awake() { _levelStartTime = Time.time; _doublingsApplied = 0; } private void OnDestroy() { if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } private void Update() { try { if (Plugin.SafeDoubleEachMinute && SemiFunc.RunIsLevel()) { float num = Time.time - _levelStartTime; float safeDoublingInterval = Plugin.SafeDoublingInterval; int num2 = Mathf.FloorToInt(num / safeDoublingInterval); num2 = Mathf.Min(num2, 12); while (_doublingsApplied < num2) { _doublingsApplied++; TinySnailSpawner.DoublePopulation(); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Reproduction manager error: {arg}"); ((Behaviour)this).enabled = false; } } } internal static class SnailSenses { private struct Noise { public Vector3 Position; public float ExpiresAt; } public const float InvestigateDurationSeconds = 10f; public const float HearingRange = 60f; private static readonly List<Noise> _noises = new List<Noise>(8); public static void ReportNoise(Vector3 worldPos) { //IL_001c: 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_005d: Unknown result type (might be due to invalid IL or missing references) if (Plugin.InvestigateNoises.Value) { _noises.Add(new Noise { Position = worldPos, ExpiresAt = Time.time + 10f }); if (_noises.Count > 32) { _noises.RemoveAt(0); } Plugin.Log.LogInfo((object)$"Noise heard at {worldPos}. Snails within {60f}u will investigate."); } } public static Vector3? NearestUnexpiredNoise(Vector3 snailPos) { //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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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) if (!Plugin.InvestigateNoises.Value) { return null; } for (int num = _noises.Count - 1; num >= 0; num--) { if (_noises[num].ExpiresAt < Time.time) { _noises.RemoveAt(num); } } if (_noises.Count == 0) { return null; } Vector3? result = null; float num2 = 3600f; foreach (Noise noise in _noises) { Vector3 val = noise.Position - snailPos; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num2) { num2 = sqrMagnitude; result = noise.Position; } } return result; } public static void Clear() { _noises.Clear(); } } internal static class SnailTextures { private static Texture2D? _shell; private static Texture2D? _body; private static Texture2D? _slimeBlob; private static Sprite? _hudPanel; private static Sprite? _snailIcon; public static Texture2D Shell => _shell ?? (_shell = BuildShell()); public static Texture2D Body => _body ?? (_body = BuildBody()); public static Texture2D SlimeBlob => _slimeBlob ?? (_slimeBlob = BuildSlimeBlob()); public static Sprite HudPanel => _hudPanel ?? (_hudPanel = BuildHudPanel()); public static Sprite SnailIcon => _snailIcon ?? (_snailIcon = BuildSnailIcon()); private static Texture2D BuildShell() { //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_001d: Expected O, but got Unknown //IL_0105: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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_013e: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: 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) Texture2D val = new Texture2D(256, 256, (TextureFormat)4, true) { name = "TinySnail_Shell" }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.95f, 0.84f, 0.62f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.55f, 0.36f, 0.18f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.3f, 0.18f, 0.08f); Color val5 = default(Color); ((Color)(ref val5))..ctor(1f, 0.92f, 0.78f); for (int i = 0; i < 256; i++) { for (int j = 0; j < 256; j++) { float num = (float)j / 256f; float num2 = (float)i / 256f; float num3 = num - 0.5f; float num4 = num2 - 0.5f; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4) * 2f; float num6 = Mathf.Repeat((Mathf.Atan2(num4, num3) / (MathF.PI * 2f) + Mathf.Log(Mathf.Max(num5, 0.001f)) * 0.7f) * 5f, 1f); Color val6 = ((!(num6 < 0.2f)) ? ((!(num6 < 0.55f)) ? val2 : val3) : val4); float num7 = Mathf.Clamp01((num6 - 0.18f) * 12f); val6 = Color.Lerp(val4, val6, num7); val6 = Color.Lerp(val6, val5, Mathf.Clamp01(0.4f - num5) * 0.55f); float num8 = (Mathf.PerlinNoise((float)j * 0.08f, (float)i * 0.08f) - 0.5f) * 0.06f; val6.r = Mathf.Clamp01(val6.r + num8); val6.g = Mathf.Clamp01(val6.g + num8); val6.b = Mathf.Clamp01(val6.b + num8); val.SetPixel(j, i, val6); } } val.Apply(true); ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; return val; } private static Texture2D BuildBody() { //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_001d: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, true) { name = "TinySnail_Body" }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.96f, 0.82f, 0.78f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.78f, 0.58f, 0.55f); Color val4 = default(Color); ((Color)(ref val4))..ctor(1f, 0.95f, 0.93f); for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = Mathf.PerlinNoise((float)j * 0.045f, (float)i * 0.045f); float num2 = Mathf.PerlinNoise((float)j * 0.18f + 100f, (float)i * 0.18f + 100f); Color val5 = val2; if (num > 0.68f) { val5 = Color.Lerp(val5, val3, (num - 0.68f) * 2.5f); } if ((float)i > 70.4f && num2 > 0.6f) { val5 = Color.Lerp(val5, val4, (num2 - 0.6f) * 1.5f); } val.SetPixel(j, i, val5); } } val.Apply(true); ((Texture)val).wrapMode = (TextureWrapMode)0; return val; } private static Texture2D BuildSlimeBlob() { //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_001d: Expected O, but got Unknown //IL_010c: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_0159: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, true) { name = "TinySnail_SlimeBlob" }; float num = 64f; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.95f, 1f, 0.65f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.55f, 1f, 0.3f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.3f, 0.85f, 0.2f); for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = Mathf.Clamp01(1f - num4 * 1.25f); float num6 = Mathf.Clamp01(1f - num4); float num7 = Mathf.Max(num5 * num5, num6 * num6 * num6 * 0.55f); float num8 = (Mathf.PerlinNoise((float)j * 0.12f, (float)i * 0.12f) - 0.5f) * 0.12f; num7 = Mathf.Clamp01(num7 + num8 * (1f - num4)); Color val5 = Color.Lerp(val3, val2, Mathf.Clamp01(num5 * 1.5f)); val5 = Color.Lerp(val4, val5, Mathf.Clamp01(num5 + num6 * 0.5f)); val.SetPixel(j, i, new Color(val5.r, val5.g, val5.b, num7)); } } val.Apply(true); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return val; } private static Sprite BuildHudPanel() { //IL_0006: 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_0017: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false) { name = "TinySnail_HudPanel" }; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = Mathf.Min(j, 63 - j); int num2 = Mathf.Min(i, 63 - i); float num5; if (num < 14 && num2 < 14) { float num3 = 14 - num; float num4 = 14 - num2; num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); } else { num5 = 0f; } float num6 = Mathf.Clamp01(1f - (num5 - 14f + 1f)); val.SetPixel(j, i, new Color(1f, 1f, 1f, num6)); } } val.Apply(); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; Vector4 val2 = default(Vector4); ((Vector4)(ref val2))..ctor(14f, 14f, 14f, 14f); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val2); } private static Sprite BuildSnailIcon() { //IL_0006: 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_0017: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0251: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_01a1: 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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false) { name = "TinySnail_Icon" }; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.55f, 0.36f, 0.18f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.78f, 0.58f, 0.32f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.95f, 0.82f, 0.58f); Color val5 = default(Color); ((Color)(ref val5))..ctor(0.96f, 0.82f, 0.78f); Color c = default(Color); ((Color)(ref c))..ctor(0.1f, 0.05f, 0.05f); Color val6 = default(Color); ((Color)(ref val6))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < 48; i++) { for (int j = 0; j < 48; j++) { val.SetPixel(j, i, val6); } } Vector2 val7 = default(Vector2); ((Vector2)(ref val7))..ctor(24f, 15.36f); for (int k = 0; k < 48; k++) { for (int l = 0; l < 48; l++) { float num = ((float)l - val7.x) / 21.599998f; float num2 = ((float)k - val7.y) / 8.64f; if (num * num + num2 * num2 < 1f) { val.SetPixel(l, k, val5); } } } Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(21.599998f, 26.400002f); for (int m = 0; m < 48; m++) { for (int n = 0; n < 48; n++) { float num3 = ((float)n - val8.x) / 14.400001f; float num4 = ((float)m - val8.y) / 14.400001f; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); if (!(num5 > 1f)) { Color val9 = ((num5 > 0.75f) ? val2 : ((!(num5 > 0.45f)) ? val4 : val3)); val.SetPixel(n, m, val9); } } } DrawLine(val, val5, 37, 18, 40, 29, 2); DrawLine(val, val5, 40, 18, 44, 26, 2); DrawDisc(val, c, 40, 31, 3); DrawDisc(val, c, 45, 27, 3); val.Apply(); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, 48f, 48f), new Vector2(0.5f, 0.5f), 100f); } private static void DrawDisc(Texture2D tex, Color c, int cx, int cy, int r) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) for (int i = cy - r; i <= cy + r; i++) { for (int j = cx - r; j <= cx + r; j++) { if (j >= 0 && i >= 0 && j < ((Texture)tex).width && i < ((Texture)tex).height) { int num = j - cx; int num2 = i - cy; if (num * num + num2 * num2 <= r * r) { tex.SetPixel(j, i, c); } } } } } private static void DrawLine(Texture2D tex, Color c, int x0, int y0, int x1, int y1, int thickness) { //IL_001c: 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) int num = Mathf.Max(Mathf.Abs(x1 - x0), Mathf.Abs(y1 - y0)); if (num == 0) { DrawDisc(tex, c, x0, y0, thickness); return; } for (int i = 0; i <= num; i++) { float num2 = (float)i / (float)num; int cx = (int)Mathf.Lerp((float)x0, (float)x1, num2); int cy = (int)Mathf.Lerp((float)y0, (float)y1, num2); DrawDisc(tex, c, cx, cy, thickness); } } } internal class TinySnailBehavior : MonoBehaviour { [CompilerGenerated] private sealed class <DeathPop>d__37 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public TinySnailBehavior <>4__this; private float <t>5__2; private Vector3 <startScale>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DeathPop>d__37(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_005a: 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) int num = <>1__state; TinySnailBehavior tinySnailBehavior = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <t>5__2 = 0f; <startScale>5__3 = ((Component)tinySnailBehavior).transform.localScale; break; case 1: <>1__state = -1; break; } if (<t>5__2 < 0.3f) { <t>5__2 += Time.deltaTime; ((Component)tinySnailBehavior).transform.localScale = Vector3.Lerp(<startScale>5__3, Vector3.zero, <t>5__2 / 0.3f); <>2__current = null; <>1__state = 1; return true; } if ((Object)(object)SnailNetwork.Instance != (Object)null && tinySnailBehavior.IsMasterSim) { SnailN