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 The Slime Gun v0.2.15
BepInEx\plugins\SlimeGun\SlimeGun.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using SlimeGun.Combat; using SlimeGun.Weapon; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SlimeGun")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Slime Gun weapon mod for R.E.P.O. - coats enemies in toxic goo and heals allies.")] [assembly: AssemblyFileVersion("0.2.15.0")] [assembly: AssemblyInformationalVersion("0.2.15")] [assembly: AssemblyProduct("SlimeGun")] [assembly: AssemblyTitle("SlimeGun")] [assembly: AssemblyVersion("0.2.15.0")] [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 SlimeGun { [BepInPlugin("com.amgru.slimegun", "SlimeGun", "0.2.15")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.amgru.slimegun"; public const string PluginName = "SlimeGun"; public const string PluginVersion = "0.2.15"; internal static ConfigEntry<bool> ModEnabled = null; internal static ConfigEntry<float> DamagePerTick = null; internal static ConfigEntry<float> HealPerTick = null; internal static ConfigEntry<float> SlowAmount = null; internal static ConfigEntry<float> SlimeDuration = null; internal static ConfigEntry<float> TickInterval = null; internal static ConfigEntry<float> TankCapacity = null; internal static ConfigEntry<float> TankDrainRate = null; internal static ConfigEntry<float> TankRechargeRate = null; internal static ConfigEntry<float> GlobSpeed = null; private Harmony? harmony; internal static string PluginDirectory { get; private set; } = string.Empty; private void Awake() { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enables or disables the Slime Gun."); DamagePerTick = ((BaseUnityPlugin)this).Config.Bind<float>("Slime", "DamagePerTick", 8f, "Damage dealt to enemies per tick while slimed."); HealPerTick = ((BaseUnityPlugin)this).Config.Bind<float>("Slime", "HealPerTick", 10f, "Health restored to friendly players per tick while slimed."); SlowAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Slime", "SlowAmount", 0.78f, "Fraction of movement speed removed while slimed. 0 = no slow, 1 = fully frozen."); SlimeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Slime", "Duration", 6f, "Base seconds the slime effect lasts before the built-in 2.5x lasting coat multiplier. Re-coating refreshes the timer."); TickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Slime", "TickInterval", 0.5f, "Seconds between each damage or heal tick."); TankCapacity = ((BaseUnityPlugin)this).Config.Bind<float>("Gun", "TankCapacity", 100f, "Maximum slime tank capacity."); TankDrainRate = ((BaseUnityPlugin)this).Config.Bind<float>("Gun", "DrainRate", 4f, "Slime units drained per second while firing."); TankRechargeRate = ((BaseUnityPlugin)this).Config.Bind<float>("Gun", "RechargeRate", 8f, "Slime units recharged per second when not firing."); GlobSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Gun", "GlobSpeed", 6f, "Initial speed of slime projectiles in m/s."); SlimeGunRuntime.Enabled = ModEnabled.Value; SlimeGunRuntime.PluginDirectory = PluginDirectory; harmony = new Harmony("com.amgru.slimegun"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded. Enabled={2}", "SlimeGun", "0.2.15", ModEnabled.Value)); } private void OnDestroy() { Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } } namespace SlimeGun.Patches { [HarmonyPatch(typeof(ItemGun), "Shoot")] internal static class ItemGunShootPatch { private static bool Prefix(ItemGun __instance) { if ((((Component)__instance).GetComponent<ItemAttributes>() ?? ((Component)__instance).GetComponentInChildren<ItemAttributes>(true) ?? ((Component)__instance).GetComponentInParent<ItemAttributes>())?.item?.itemName != "Slime Gun") { return true; } SlimeGunController.OnItemGunShoot(__instance); return false; } } [HarmonyPatch(typeof(ItemGun), "Update")] internal static class ItemGunUpdatePatch { private static void Postfix(ItemGun __instance) { if ((((Component)__instance).GetComponent<ItemAttributes>() ?? ((Component)__instance).GetComponentInChildren<ItemAttributes>(true) ?? ((Component)__instance).GetComponentInParent<ItemAttributes>())?.item?.itemName != "Slime Gun") { return; } Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { string name = ((object)val).GetType().Name; if ((name == "LineRenderer" || name == "TrailRenderer") && val.enabled) { val.enabled = false; } } Component[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<Component>(true); bool flag = default(bool); foreach (Component val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !(((object)val2).GetType().Name != "ParticleSystem")) { object obj = ((object)val2).GetType().GetProperty("isPlaying")?.GetValue(val2); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { ((object)val2).GetType().GetMethod("Stop", Type.EmptyTypes)?.Invoke(val2, null); } } } } } [HarmonyPatch(typeof(PhysGrabObject), "Update")] internal static class PhysGrabObjectUpdatePatch { private static void Postfix(PhysGrabObject __instance) { SlimeGunController.OnPhysGrabObjectUpdate(__instance); } } [HarmonyPatch(typeof(PlayerController), "Start")] internal static class PlayerControllerStartPatch { private static void Postfix(PlayerController __instance) { } } } namespace SlimeGun.Combat { internal static class SlimeCombat { private static readonly FieldInfo EnemyHasHealthField = AccessTools.Field(typeof(Enemy), "HasHealth"); private static readonly FieldInfo EnemyHealthField = AccessTools.Field(typeof(Enemy), "Health"); private static readonly FieldInfo EnemyHasRigidbodyField = AccessTools.Field(typeof(Enemy), "HasRigidbody"); private static readonly FieldInfo EnemyRigidbodyField = AccessTools.Field(typeof(Enemy), "Rigidbody"); private static readonly FieldInfo EnemyRbField = AccessTools.Field(typeof(EnemyRigidbody), "rb"); internal static Enemy? FindEnemy(Collider collider) { Enemy componentInParent = ((Component)collider).GetComponentInParent<Enemy>(); if ((Object)(object)componentInParent != (Object)null && Object.op_Implicit((Object)(object)componentInParent)) { return componentInParent; } EnemyRigidbody componentInParent2 = ((Component)collider).GetComponentInParent<EnemyRigidbody>(); if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.enemy != (Object)null && Object.op_Implicit((Object)(object)componentInParent2.enemy)) { return componentInParent2.enemy; } if (!((Object)(object)collider.attachedRigidbody != (Object)null)) { return null; } return ((Component)collider.attachedRigidbody).GetComponent<EnemyRigidbody>()?.enemy; } internal static PlayerController? FindPlayer(Collider collider) { PlayerController componentInParent = ((Component)collider).GetComponentInParent<PlayerController>(); if ((Object)(object)componentInParent != (Object)null && Object.op_Implicit((Object)(object)componentInParent)) { return componentInParent; } PlayerAvatar componentInParent2 = ((Component)collider).GetComponentInParent<PlayerAvatar>(); if ((Object)(object)componentInParent2 != (Object)null && Object.op_Implicit((Object)(object)componentInParent2)) { PlayerController val = ((Component)componentInParent2).GetComponent<PlayerController>() ?? ((Component)componentInParent2).GetComponentInParent<PlayerController>(); if ((Object)(object)val != (Object)null && Object.op_Implicit((Object)(object)val)) { return val; } } return null; } internal static void DamageEnemy(Enemy enemy, int damage, Vector3 hitPosition) { //IL_000e: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //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_0078: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } Vector3 val = ((Component)enemy).transform.position - hitPosition; Vector3 val2 = ((Vector3)(ref val)).normalized; if (((Vector3)(ref val2)).sqrMagnitude < 0.01f) { val2 = Vector3.forward; } object value = EnemyHasHealthField.GetValue(enemy); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { object? value2 = EnemyHealthField.GetValue(enemy); EnemyHealth val3 = (EnemyHealth)((value2 is EnemyHealth) ? value2 : null); if (val3 != null) { val3.Hurt(Mathf.Max(0, damage), val2); Debug.Log((object)$"[SlimeGun] Slime tick: {damage} damage to {((Object)enemy).name}."); return; } } Debug.Log((object)$"[SlimeGun] Would deal {damage} to {((Object)enemy).name} but no EnemyHealth hook available."); } internal static void HealPlayer(PlayerAvatar playerAvatar, int amount) { if (SemiFunc.IsMasterClientOrSingleplayer()) { PlayerHealth playerHealth = playerAvatar.playerHealth; if ((Object)(object)playerHealth != (Object)null && Object.op_Implicit((Object)(object)playerHealth)) { playerHealth.HealOther(Mathf.Max(0, amount), true); Debug.Log((object)$"[SlimeGun] Slime tick: healed {amount} HP on {((Object)playerAvatar).name}."); } else { Debug.Log((object)$"[SlimeGun] Would heal {amount} HP on {((Object)playerAvatar).name} but no PlayerHealth component was found."); } } } internal static Rigidbody? GetEnemyRigidbody(Enemy enemy) { object value = EnemyHasRigidbodyField.GetValue(enemy); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { object? value2 = EnemyRigidbodyField.GetValue(enemy); EnemyRigidbody val = (EnemyRigidbody)((value2 is EnemyRigidbody) ? value2 : null); if (val != null) { object? value3 = EnemyRbField.GetValue(val); Rigidbody val2 = (Rigidbody)((value3 is Rigidbody) ? value3 : null); if (val2 != null) { return val2; } } } return null; } } } namespace SlimeGun.Weapon { public sealed class SlimeEffect : MonoBehaviour { public enum TargetType { Enemy, Player } private struct MaterialTintState { public Material material; public Color originalColor; public Color originalEmission; public bool hadEmission; } private struct RendererTintState { public Renderer renderer; public MaterialPropertyBlock originalBlock; public MaterialPropertyBlock slimeBlock; } private struct FloatMemberState { public object target; public FieldInfo? field; public PropertyInfo? property; public float originalValue; } private TargetType targetType; private Enemy? enemy; private PlayerAvatar? playerAvatar; private EnemyRigidbody? enemyRigidbody; private Rigidbody? targetRigidbody; private float originalDrag; private GameObject? gooCoat; private readonly List<GameObject> gooPatches = new List<GameObject>(); private Component? navAgentComponent; private PropertyInfo? navAgentSpeedProp; private float originalNavSpeed; private float slowAmount; private float startedAt; private float duration; private float expiresAt; private float nextTickAt; private float tickInterval; private int damageOrHealPerTick; private bool visualOnly; private const float DissolveStartFraction = 0.6f; private const float DurationMultiplier = 2.5f; private const float EnemyDamageMultiplier = 3f; private const int MaxGooPatchCount = 42; private readonly List<MaterialTintState> tintedStates = new List<MaterialTintState>(); private readonly List<RendererTintState> rendererTintStates = new List<RendererTintState>(); private readonly List<FloatMemberState> slowedFloatStates = new List<FloatMemberState>(); private static readonly Color SlimeTint = new Color(0.12f, 0.95f, 0.16f, 1f); private static readonly Color SlimeEmission = new Color(0.08f, 2.8f, 0.12f); public static SlimeEffect ApplyToEnemy(Enemy enemy, float duration, float slow, int damage, float tickInterval) { SlimeEffect obj = ((Component)enemy).gameObject.GetComponent<SlimeEffect>() ?? ((Component)enemy).gameObject.AddComponent<SlimeEffect>(); obj.InitForEnemy(enemy, duration, slow, damage, tickInterval, visualOnlyEffect: false); return obj; } public static SlimeEffect ApplyVisualToEnemy(Enemy enemy, float duration, float slow, int damage, float tickInterval) { SlimeEffect obj = ((Component)enemy).gameObject.GetComponent<SlimeEffect>() ?? ((Component)enemy).gameObject.AddComponent<SlimeEffect>(); obj.InitForEnemy(enemy, duration, slow, damage, tickInterval, visualOnlyEffect: true); return obj; } public static SlimeEffect ApplyToPlayer(PlayerController player, float duration, float slow, int heal, float tickInterval) { SlimeEffect obj = ((Component)player).gameObject.GetComponent<SlimeEffect>() ?? ((Component)player).gameObject.AddComponent<SlimeEffect>(); obj.InitForPlayer(player, duration, slow, heal, tickInterval, visualOnlyEffect: false); return obj; } public static SlimeEffect ApplyVisualToPlayer(PlayerController player, float duration, float slow, int heal, float tickInterval) { SlimeEffect obj = ((Component)player).gameObject.GetComponent<SlimeEffect>() ?? ((Component)player).gameObject.AddComponent<SlimeEffect>(); obj.InitForPlayer(player, duration, slow, heal, tickInterval, visualOnlyEffect: true); return obj; } public static SlimeEffect ApplyVisualToPlayerAvatar(PlayerAvatar avatar, float duration, float slow, int heal, float tickInterval) { SlimeEffect obj = ((Component)avatar).gameObject.GetComponent<SlimeEffect>() ?? ((Component)avatar).gameObject.AddComponent<SlimeEffect>(); obj.InitForPlayerAvatar(avatar, duration, slow, heal, tickInterval, visualOnlyEffect: true); return obj; } public static SlimeEffect ApplyToPlayerAvatar(PlayerAvatar avatar, float duration, float slow, int heal, float tickInterval) { SlimeEffect obj = ((Component)avatar).gameObject.GetComponent<SlimeEffect>() ?? ((Component)avatar).gameObject.AddComponent<SlimeEffect>(); obj.InitForPlayerAvatar(avatar, duration, slow, heal, tickInterval, visualOnlyEffect: false); return obj; } private void InitForEnemy(Enemy e, float duration, float slow, int damage, float tick, bool visualOnlyEffect) { if (targetType == TargetType.Enemy && (Object)(object)enemy == (Object)(object)e && Time.time < expiresAt) { Refresh(duration * 2.5f, slow, Mathf.CeilToInt((float)damage * 3f), Mathf.Min(tick, 0.25f)); if ((visualOnlyEffect && !visualOnly) || visualOnly == visualOnlyEffect) { return; } } RestoreSlow(); ClearTint(); targetType = TargetType.Enemy; enemy = e; enemyRigidbody = ((Component)e).GetComponentInChildren<EnemyRigidbody>(); visualOnly = visualOnlyEffect; slowAmount = slow; damageOrHealPerTick = Mathf.CeilToInt((float)damage * 3f); tickInterval = Mathf.Min(tick, 0.25f); this.duration = duration * 2.5f; startedAt = Time.time; expiresAt = Time.time + this.duration; nextTickAt = Time.time + tickInterval; targetRigidbody = (visualOnly ? null : SlimeCombat.GetEnemyRigidbody(e)); if (!visualOnly) { TrySlowNavAgent(((Component)e).gameObject); ApplyBroadEnemySlow(((Component)e).gameObject); ApplyRigidbodyDrag(); } GameObject root = FindVisualRoot(((Component)e).gameObject); ApplyPatchyGooCoat(root); Debug.Log((object)$"[SlimeGun] SlimeEffect started on enemy {((Object)e).name}. slow={slow:0.00} dmg={damageOrHealPerTick} duration={this.duration:0.0}s"); } private void InitForPlayer(PlayerController pc, float duration, float slow, int heal, float tick, bool visualOnlyEffect) { if (targetType == TargetType.Player && (Object)(object)playerAvatar == (Object)(object)pc.playerAvatarScript && Time.time < expiresAt) { Refresh(duration * 2.5f, slow, heal, tick); if ((visualOnlyEffect && !visualOnly) || visualOnly == visualOnlyEffect) { return; } } RestoreSlow(); ClearTint(); targetType = TargetType.Player; playerAvatar = pc.playerAvatarScript; enemyRigidbody = null; visualOnly = visualOnlyEffect; slowAmount = slow; damageOrHealPerTick = heal; tickInterval = tick; this.duration = duration * 2.5f; startedAt = Time.time; expiresAt = Time.time + this.duration; nextTickAt = Time.time + tick; targetRigidbody = (visualOnly ? null : pc.rb); if (!visualOnly) { ApplyRigidbodyDrag(); } ApplyPatchyGooCoat(((Component)pc).gameObject); Debug.Log((object)$"[SlimeGun] SlimeEffect started on player {((Object)pc).name}. slow={slow:0.00} heal={heal} duration={this.duration:0.0}s"); } private void InitForPlayerAvatar(PlayerAvatar avatar, float duration, float slow, int heal, float tick, bool visualOnlyEffect) { if (targetType == TargetType.Player && (Object)(object)playerAvatar == (Object)(object)avatar && Time.time < expiresAt) { Refresh(duration * 2.5f, slow, heal, tick); if ((visualOnlyEffect && !visualOnly) || visualOnly == visualOnlyEffect) { return; } } RestoreSlow(); ClearTint(); targetType = TargetType.Player; playerAvatar = avatar; enemyRigidbody = null; targetRigidbody = null; visualOnly = visualOnlyEffect; slowAmount = slow; damageOrHealPerTick = heal; tickInterval = tick; this.duration = duration * 2.5f; startedAt = Time.time; expiresAt = Time.time + this.duration; nextTickAt = Time.time + tick; ApplyPatchyGooCoat(FindVisualRoot(((Component)avatar).gameObject)); Debug.Log((object)(visualOnly ? $"[SlimeGun] Visual slime coat started on player avatar {((Object)avatar).name}. duration={this.duration:0.0}s" : $"[SlimeGun] SlimeEffect started on player avatar {((Object)avatar).name}. heal={heal} duration={this.duration:0.0}s")); } private void Refresh(float refreshedDuration, float refreshedSlow, int refreshedTickAmount, float refreshedTickInterval) { slowAmount = Mathf.Max(slowAmount, refreshedSlow); damageOrHealPerTick = Mathf.Max(damageOrHealPerTick, refreshedTickAmount); tickInterval = Mathf.Min(tickInterval, refreshedTickInterval); duration = Mathf.Max(duration, refreshedDuration); expiresAt = Time.time + duration; } private void Update() { if (Time.time >= expiresAt) { Object.Destroy((Object)(object)this); return; } float num = Time.time - startedAt; float num2 = duration * 0.6f; if (num >= num2 && duration > 0f) { float num3 = (num - num2) / (duration * 0.39999998f); float alpha = Mathf.Clamp01(1f - num3); UpdateGooCoatAlpha(alpha); } if (!visualOnly && Time.time >= nextTickAt) { nextTickAt = Time.time + tickInterval; ApplyTick(); } } private void UpdateGooCoatAlpha(float alpha) { //IL_00a0: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject gooPatch in gooPatches) { if ((Object)(object)gooPatch == (Object)null || !Object.op_Implicit((Object)(object)gooPatch)) { continue; } Renderer component = gooPatch.GetComponent<Renderer>(); if ((Object)(object)component == (Object)null || !Object.op_Implicit((Object)(object)component)) { continue; } Material[] materials = component.materials; foreach (Material val in materials) { if (!((Object)(object)val == (Object)null)) { Color val2 = (Color)(val.HasProperty("_Color") ? val.GetColor("_Color") : new Color(0.08f, 1f, 0.14f, 0.62f)); val2.a = Mathf.Min(val2.a, alpha * 0.62f); if (val.HasProperty("_Color")) { val.SetColor("_Color", val2); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", val2); } } } } } private void FixedUpdate() { //IL_0057: 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) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (!visualOnly) { if (targetType == TargetType.Enemy) { ApplyEnemyMovementSuppression(); ReapplyBroadEnemySlow(); } if ((Object)(object)targetRigidbody != (Object)null && Object.op_Implicit((Object)(object)targetRigidbody)) { float num = Mathf.Clamp01(1f - slowAmount * 0.65f); Rigidbody? obj = targetRigidbody; obj.velocity *= num; Rigidbody? obj2 = targetRigidbody; obj2.angularVelocity *= num; } } } private void OnDestroy() { if (!visualOnly) { RestoreSlow(); } ClearTint(); } private void ApplyTick() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (targetType == TargetType.Enemy && (Object)(object)enemy != (Object)null && Object.op_Implicit((Object)(object)enemy)) { SlimeCombat.DamageEnemy(enemy, damageOrHealPerTick, ((Component)this).transform.position); } else if (targetType == TargetType.Player && (Object)(object)playerAvatar != (Object)null && Object.op_Implicit((Object)(object)playerAvatar)) { SlimeCombat.HealPlayer(playerAvatar, damageOrHealPerTick); } } private void TrySlowNavAgent(GameObject root) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(); foreach (Component val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().FullName != "UnityEngine.AI.NavMeshAgent") { continue; } PropertyInfo property = ((object)val).GetType().GetProperty("speed", BindingFlags.Instance | BindingFlags.Public); if (!(property == null)) { object value = property.GetValue(val); if (value is float) { float num = (originalNavSpeed = (float)value); property.SetValue(val, num * (1f - slowAmount)); navAgentComponent = val; navAgentSpeedProp = property; Debug.Log((object)$"[SlimeGun] NavMeshAgent speed slowed: {num:0.00} -> {num * (1f - slowAmount):0.00}"); } } break; } } private void ApplyRigidbodyDrag() { if (!((Object)(object)targetRigidbody == (Object)null) && Object.op_Implicit((Object)(object)targetRigidbody)) { originalDrag = targetRigidbody.drag; targetRigidbody.drag = originalDrag + slowAmount * 60f; } } private void ApplyEnemyMovementSuppression() { if (!((Object)(object)enemyRigidbody == (Object)null) && Object.op_Implicit((Object)(object)enemyRigidbody)) { enemyRigidbody.DisableFollowPosition(0.25f, Mathf.Lerp(18f, 42f, slowAmount)); enemyRigidbody.DisableFollowRotation(0.25f, Mathf.Lerp(16f, 38f, slowAmount)); } } private void RestoreSlow() { if ((Object)(object)navAgentComponent != (Object)null && navAgentSpeedProp != null && Object.op_Implicit((Object)(object)navAgentComponent)) { navAgentSpeedProp.SetValue(navAgentComponent, originalNavSpeed); } navAgentComponent = null; navAgentSpeedProp = null; RestoreBroadEnemySlow(); if ((Object)(object)targetRigidbody != (Object)null && Object.op_Implicit((Object)(object)targetRigidbody)) { targetRigidbody.drag = originalDrag; } targetRigidbody = null; enemyRigidbody = null; } private void ApplyBroadEnemySlow(GameObject root) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); if (type.Namespace != null && type.Namespace.StartsWith("UnityEngine", StringComparison.Ordinal)) { continue; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.FieldType != typeof(float)) && !fieldInfo.IsInitOnly && ShouldSlowMember(fieldInfo.Name)) { float num = (float)fieldInfo.GetValue(val); float num2 = SlowValue(fieldInfo.Name, num); if (!Mathf.Approximately(num, num2)) { slowedFloatStates.Add(new FloatMemberState { target = val, field = fieldInfo, originalValue = num }); fieldInfo.SetValue(val, num2); } } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.PropertyType != typeof(float) || !propertyInfo.CanRead || !propertyInfo.CanWrite || !ShouldSlowMember(propertyInfo.Name) || propertyInfo.GetIndexParameters().Length != 0) { continue; } float num3; try { num3 = (float)propertyInfo.GetValue(val, null); } catch { continue; } float num4 = SlowValue(propertyInfo.Name, num3); if (!Mathf.Approximately(num3, num4)) { slowedFloatStates.Add(new FloatMemberState { target = val, property = propertyInfo, originalValue = num3 }); try { propertyInfo.SetValue(val, num4, null); } catch { slowedFloatStates.RemoveAt(slowedFloatStates.Count - 1); } } } } } private void ReapplyBroadEnemySlow() { foreach (FloatMemberState slowedFloatState in slowedFloatStates) { object target = slowedFloatState.target; Object val = (Object)((target is Object) ? target : null); if (val == null || !Object.op_Implicit(val)) { continue; } float num = SlowValue(slowedFloatState.field?.Name ?? slowedFloatState.property?.Name ?? string.Empty, slowedFloatState.originalValue); slowedFloatState.field?.SetValue(slowedFloatState.target, num); if (slowedFloatState.property != null) { try { slowedFloatState.property.SetValue(slowedFloatState.target, num, null); } catch { } } } } private void RestoreBroadEnemySlow() { foreach (FloatMemberState slowedFloatState in slowedFloatStates) { object target = slowedFloatState.target; Object val = (Object)((target is Object) ? target : null); if (val == null || !Object.op_Implicit(val)) { continue; } slowedFloatState.field?.SetValue(slowedFloatState.target, slowedFloatState.originalValue); if (slowedFloatState.property != null) { try { slowedFloatState.property.SetValue(slowedFloatState.target, slowedFloatState.originalValue, null); } catch { } } } slowedFloatStates.Clear(); } private bool ShouldSlowMember(string name) { string text = name.ToLowerInvariant(); if (text.Contains("attack") || text.Contains("cooldown") || text.Contains("delay") || text.Contains("interval")) { return true; } if (!text.Contains("speed") && !text.Contains("acceleration") && !text.Contains("chase") && !text.Contains("move") && !text.Contains("turn")) { return text.Contains("rotate"); } return true; } private float SlowValue(string name, float original) { if (original <= 0f) { return original; } string text = name.ToLowerInvariant(); if (text.Contains("cooldown") || text.Contains("delay") || text.Contains("interval")) { return original / Mathf.Max(0.08f, 1f - slowAmount); } return original * Mathf.Clamp(1f - slowAmount, 0.04f, 1f); } private void ApplyTint(GameObject root) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0099: 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) //IL_00a3: 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_00b3: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_010f: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { if (!ShouldUseRendererForTint(val)) { continue; } num++; MaterialPropertyBlock val2 = new MaterialPropertyBlock(); val.GetPropertyBlock(val2); MaterialPropertyBlock slimeBlock = new MaterialPropertyBlock(); rendererTintStates.Add(new RendererTintState { renderer = val, originalBlock = val2, slimeBlock = slimeBlock }); Material[] materials = val.materials; foreach (Material val3 in materials) { if (!((Object)(object)val3 == (Object)null)) { num2++; Color materialColor = GetMaterialColor(val3, Color.white); Color originalEmission = (val3.HasProperty("_EmissionColor") ? val3.GetColor("_EmissionColor") : Color.black); tintedStates.Add(new MaterialTintState { material = val3, originalColor = materialColor, originalEmission = originalEmission, hadEmission = val3.IsKeywordEnabled("_EMISSION") }); ApplySlimeToMaterial(val3, materialColor, originalEmission, 1f); } } } Debug.Log((object)$"[SlimeGun] Goo visual tint targets on {((Object)root).name}: renderers={num}, materials={num2}"); } private void ReapplyTint(float alpha) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_00b3: 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_00d7: Unknown result type (might be due to invalid IL or missing references) foreach (MaterialTintState tintedState in tintedStates) { if (!((Object)(object)tintedState.material == (Object)null)) { ApplySlimeToMaterial(tintedState.material, tintedState.originalColor, tintedState.originalEmission, alpha); } } Color slimeTintedColor = GetSlimeTintedColor(Color.white, alpha); Color val = Color.Lerp(Color.black, SlimeEmission, alpha); foreach (RendererTintState rendererTintState in rendererTintStates) { if (!((Object)(object)rendererTintState.renderer == (Object)null) && Object.op_Implicit((Object)(object)rendererTintState.renderer)) { rendererTintState.slimeBlock.SetColor("_Color", slimeTintedColor); rendererTintState.slimeBlock.SetColor("_BaseColor", slimeTintedColor); rendererTintState.slimeBlock.SetColor("_EmissionColor", val); rendererTintState.renderer.SetPropertyBlock(rendererTintState.slimeBlock); } } } private static Color GetSlimeTintedColor(Color original, float alpha) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Color result = Color.Lerp(original, SlimeTint, 0.93f * alpha); result.a = original.a; return result; } private static void ApplySlimeToMaterial(Material mat, Color originalColor, Color originalEmission, float alpha) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Color slimeTintedColor = GetSlimeTintedColor(originalColor, alpha); if (mat.HasProperty("_Color")) { mat.SetColor("_Color", slimeTintedColor); } if (mat.HasProperty("_BaseColor")) { mat.SetColor("_BaseColor", slimeTintedColor); } mat.EnableKeyword("_EMISSION"); Color val = Color.Lerp(originalEmission, SlimeEmission, alpha); if (mat.HasProperty("_EmissionColor")) { mat.SetColor("_EmissionColor", val); } } private static Color GetMaterialColor(Material mat, Color fallback) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty("_Color")) { return mat.GetColor("_Color"); } if (mat.HasProperty("_BaseColor")) { return mat.GetColor("_BaseColor"); } return fallback; } private void ApplyPatchyGooCoat(GameObject root) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gooCoat != (Object)null) { Object.Destroy((Object)(object)gooCoat); } gooPatches.Clear(); gooCoat = new GameObject("SlimeGun_GooCoat"); gooCoat.transform.SetParent(root.transform, false); gooCoat.transform.localPosition = Vector3.zero; gooCoat.transform.localRotation = Quaternion.identity; gooCoat.transform.localScale = Vector3.one; Material goo = CreateGooMaterial(); List<Renderer> targetRenderers = GetTargetRenderers(root); if (targetRenderers.Count == 0) { return; } int num = 42; foreach (Renderer item2 in targetRenderers) { if (!((Object)(object)item2 == (Object)null) && Object.op_Implicit((Object)(object)item2)) { AddRendererMeshShell(gooCoat.transform, item2, goo); int patchCountForRenderer = GetPatchCountForRenderer(item2, num); for (int i = 0; i < patchCountForRenderer; i++) { GameObject item = AddAttachedGooPatch(item2, goo, i); gooPatches.Add(item); } num -= patchCountForRenderer; if (num <= 0) { break; } } } } private static int GetPatchCountForRenderer(Renderer renderer, int remainingBudget) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = renderer.bounds; return Mathf.Clamp(Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)) * 5.5f), 4, 10), 0, remainingBudget); } private void AddRendererMeshShell(Transform parent, Renderer source, Material goo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = source.bounds; float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (num <= 0.01f || num > 4.75f) { return; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((source is SkinnedMeshRenderer) ? source : null); if (val != null) { if (!((Object)(object)val.sharedMesh == (Object)null)) { AddSkinnedShell(parent, val, goo, 1.055f); AddSkinnedShell(parent, val, goo, 1.095f); } return; } MeshFilter component = ((Component)source).GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { AddStaticShell(parent, source, component.sharedMesh, goo, 1.055f); AddStaticShell(parent, source, component.sharedMesh, goo, 1.095f); } } private void AddSkinnedShell(Transform parent, SkinnedMeshRenderer source, Material goo, float scaleMultiplier) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) GameObject val = CreateShellObject(parent, ((Component)source).transform, scaleMultiplier); SkinnedMeshRenderer obj = val.AddComponent<SkinnedMeshRenderer>(); obj.sharedMesh = source.sharedMesh; obj.bones = source.bones; obj.rootBone = source.rootBone; ((Renderer)obj).localBounds = ((Renderer)source).localBounds; obj.updateWhenOffscreen = true; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).materials = MakeMaterialArray(Mathf.Max(1, ((Renderer)source).sharedMaterials.Length), goo); gooPatches.Add(val); } private void AddStaticShell(Transform parent, Renderer source, Mesh mesh, Material goo, float scaleMultiplier) { GameObject val = CreateShellObject(parent, ((Component)source).transform, scaleMultiplier); val.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer obj = val.AddComponent<MeshRenderer>(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).materials = MakeMaterialArray(Mathf.Max(1, source.sharedMaterials.Length), goo); gooPatches.Add(val); } private static GameObject CreateShellObject(Transform parent, Transform source, float scaleMultiplier) { //IL_0016: 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_002f: 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_003f: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown GameObject val = new GameObject($"goo_mesh_shell_{((Object)source).name}_{scaleMultiplier:0.000}"); val.transform.SetParent(parent, true); val.transform.SetPositionAndRotation(source.position, source.rotation); val.transform.localScale = source.lossyScale * scaleMultiplier; val.AddComponent<SlimeShellFollower>().Init(source, scaleMultiplier); return val; } private static Material[] MakeMaterialArray(int count, Material material) { Material[] array = (Material[])(object)new Material[count]; for (int i = 0; i < array.Length; i++) { array[i] = material; } return array; } private static GameObject AddAttachedGooPatch(Renderer target, Material goo, int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00e8: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_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_015f: 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) Bounds bounds = target.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; float num = Mathf.Clamp(Mathf.Max(extents.x, Mathf.Max(extents.y, extents.z)) * 0.2f, 0.045f, 0.24f); Vector3 val = (Vector3)((index % 6) switch { 0 => Vector3.up, 1 => Vector3.down, 2 => Vector3.right, 3 => Vector3.left, 4 => Vector3.forward, _ => Vector3.back, }); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Random.Range(0f - extents.x, extents.x) * 0.22f, Random.Range(0f - extents.y, extents.y) * 0.22f, Random.Range(0f - extents.z, extents.z) * 0.22f); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val.x * extents.x * 0.78f, val.y * extents.y * 0.78f, val.z * extents.z * 0.78f); GameObject obj = CreateGooSphere("goo_body_patch", ((Bounds)(ref bounds)).center + val3 + val2, Quaternion.LookRotation((((Vector3)(ref val)).sqrMagnitude > 0.01f) ? val : Vector3.forward, Vector3.up) * Random.rotation, new Vector3(num * Random.Range(1.15f, 1.9f), num * Random.Range(0.18f, 0.38f), num * Random.Range(0.8f, 1.35f)), goo); obj.transform.SetParent(((Component)target).transform, true); return obj; } private static GameObject CreateGooSphere(string name, Vector3 position, Quaternion rotation, Vector3 scale, Material goo) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = name; obj.transform.SetPositionAndRotation(position, rotation); obj.transform.localScale = scale; Collider val = default(Collider); if (obj.TryGetComponent<Collider>(ref val)) { Object.Destroy((Object)(object)val); } Renderer val2 = default(Renderer); if (obj.TryGetComponent<Renderer>(ref val2)) { val2.shadowCastingMode = (ShadowCastingMode)0; val2.receiveShadows = false; val2.material = goo; } return obj; } private static List<Renderer> GetTargetRenderers(GameObject root) { List<Renderer> list = new List<Renderer>(); Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (ShouldUseRendererForGoo(val)) { list.Add(val); } } return list; } private static bool ShouldUseRendererForGoo(Renderer renderer) { //IL_004d: 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_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_006c: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || !Object.op_Implicit((Object)(object)renderer) || !renderer.enabled || IsGooCoatRenderer(renderer)) { return false; } if (renderer is LineRenderer || renderer is TrailRenderer || ((object)renderer).GetType().Name.Contains("Particle")) { return false; } Bounds bounds = renderer.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0.0001f) { return false; } bounds = renderer.bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = renderer.bounds; float y = ((Bounds)(ref bounds)).size.y; bounds = renderer.bounds; if (Mathf.Max(x, Mathf.Max(y, ((Bounds)(ref bounds)).size.z)) > 4.75f) { return false; } Mesh rendererMesh = GetRendererMesh(renderer); if ((Object)(object)rendererMesh == (Object)null) { return false; } string text = GetTransformPath(((Component)renderer).transform).ToLowerInvariant(); if (text.Contains("collider") || text.Contains("hitbox") || text.Contains("hurtbox") || text.Contains("debug") || text.Contains("gizmo") || text.Contains("ui") || text.Contains("icon")) { return false; } if (IsSuspiciousUtilitySphere(renderer, rendererMesh, text)) { return false; } return true; } private static bool ShouldUseRendererForTint(Renderer renderer) { //IL_004d: 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_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_0115: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null || !Object.op_Implicit((Object)(object)renderer) || !renderer.enabled || IsGooCoatRenderer(renderer)) { return false; } if (renderer is LineRenderer || renderer is TrailRenderer || ((object)renderer).GetType().Name.Contains("Particle")) { return false; } Bounds bounds = renderer.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0.0001f) { return false; } string text = GetTransformPath(((Component)renderer).transform).ToLowerInvariant(); if (text.Contains("collider") || text.Contains("hitbox") || text.Contains("hurtbox") || text.Contains("debug") || text.Contains("gizmo") || text.Contains("ui") || text.Contains("icon")) { return false; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { return true; } bool result = false; Material[] array = sharedMaterials; foreach (Material val in array) { if (!((Object)(object)val == (Object)null) && (!val.HasProperty("_Color") || val.color.a > 0.18f)) { result = true; break; } } return result; } private static GameObject FindVisualRoot(GameObject effectRoot) { Transform val = effectRoot.transform; GameObject result = effectRoot; int num = CountGooRenderers(effectRoot); for (int i = 0; i < 5; i++) { if (!((Object)(object)val.parent != (Object)null)) { break; } val = val.parent; int num2 = CountGooRenderers(((Component)val).gameObject); if (num2 > num && num2 <= 24 && HasReasonableRendererBounds(((Component)val).gameObject)) { result = ((Component)val).gameObject; num = num2; } } return result; } private static int CountGooRenderers(GameObject root) { int num = 0; Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (ShouldUseRendererForGoo(componentsInChildren[i])) { num++; } } return num; } private static bool HasReasonableRendererBounds(GameObject root) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_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) bool flag = false; Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(root.transform.position, Vector3.zero); Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (ShouldUseRendererForGoo(val)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } if (!flag) { return false; } return Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)) <= 5.5f; } private static int CountTintableRenderers(GameObject root) { int num = 0; Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (ShouldUseRendererForTint(componentsInChildren[i])) { num++; } } return num; } private static Mesh? GetRendererMesh(Renderer renderer) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if (val != null) { return val.sharedMesh; } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if (component == null) { return null; } return component.sharedMesh; } private static bool IsSuspiciousUtilitySphere(Renderer renderer, Mesh mesh, string lowerName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0049: 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) Bounds bounds = renderer.bounds; float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); float num2 = Mathf.Max(0.001f, Mathf.Min(((Bounds)(ref bounds)).size.x, Mathf.Min(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z))); bool num3 = num / num2 < 1.28f; bool flag = lowerName.Contains("range") || lowerName.Contains("vision") || lowerName.Contains("sight") || lowerName.Contains("detect") || lowerName.Contains("trigger") || lowerName.Contains("area") || lowerName.Contains("scan") || lowerName.Contains("sphere"); if (num3 && num > 1.2f) { if (!flag) { return mesh.vertexCount < 900; } return true; } return false; } private static string GetTransformPath(Transform transform) { string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } private static void AddWorldGooShell(Transform parent, Material goo, Bounds bounds, float expand, string name) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = name; obj.transform.position = ((Bounds)(ref bounds)).center; obj.transform.rotation = Random.rotation; obj.transform.localScale = new Vector3(Mathf.Max(((Bounds)(ref bounds)).size.x * expand, 0.22f), Mathf.Max(((Bounds)(ref bounds)).size.y * expand, 0.22f), Mathf.Max(((Bounds)(ref bounds)).size.z * expand, 0.22f)); obj.transform.SetParent(parent, true); Collider val = default(Collider); if (obj.TryGetComponent<Collider>(ref val)) { Object.Destroy((Object)(object)val); } Renderer val2 = default(Renderer); if (obj.TryGetComponent<Renderer>(ref val2)) { val2.material = goo; } } private static void AddWorldGooBlobs(Transform parent, Material goo, Bounds bounds, int count) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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) float num = Mathf.Clamp(Mathf.Max(((Bounds)(ref bounds)).extents.x, Mathf.Max(((Bounds)(ref bounds)).extents.y, ((Bounds)(ref bounds)).extents.z)) * 0.22f, 0.075f, 0.42f); Collider val = default(Collider); Renderer val2 = default(Renderer); for (int i = 0; i < count; i++) { Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3 position = ((Bounds)(ref bounds)).center + new Vector3(Random.Range(0f - extents.x, extents.x), Random.Range(0f - extents.y, extents.y), Random.Range(0f - extents.z, extents.z)); int num2 = Random.Range(0, 3); float num3 = ((Random.value < 0.5f) ? (-1f) : 1f); switch (num2) { case 0: position.x = ((Bounds)(ref bounds)).center.x + extents.x * num3; break; case 1: position.y = ((Bounds)(ref bounds)).center.y + extents.y * num3; break; default: position.z = ((Bounds)(ref bounds)).center.z + extents.z * num3; break; } GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "goo_surface_blob"; obj.transform.position = position; obj.transform.rotation = Random.rotation; float num4 = Random.Range(num * 0.7f, num * 1.35f); obj.transform.localScale = new Vector3(num4 * Random.Range(0.8f, 1.6f), num4 * Random.Range(0.35f, 0.85f), num4 * Random.Range(0.8f, 1.6f)); obj.transform.SetParent(parent, true); if (obj.TryGetComponent<Collider>(ref val)) { Object.Destroy((Object)(object)val); } if (obj.TryGetComponent<Renderer>(ref val2)) { val2.material = goo; } } } private void ApplyGooCoat(GameObject root) { //IL_001a: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: 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_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: 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_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0239: 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_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gooCoat != (Object)null) { Object.Destroy((Object)(object)gooCoat); } Bounds renderBounds = GetRenderBounds(root); gooCoat = new GameObject("SlimeGun_GooCoat"); gooCoat.transform.SetParent(root.transform, false); gooCoat.transform.localPosition = root.transform.InverseTransformPoint(((Bounds)(ref renderBounds)).center); gooCoat.transform.localRotation = Quaternion.identity; gooCoat.transform.localScale = Vector3.one; Material material = CreateGooMaterial(); Vector3 lossyScale = root.transform.lossyScale; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(((Bounds)(ref renderBounds)).extents.x / Mathf.Max(0.001f, Mathf.Abs(lossyScale.x)), ((Bounds)(ref renderBounds)).extents.y / Mathf.Max(0.001f, Mathf.Abs(lossyScale.y)), ((Bounds)(ref renderBounds)).extents.z / Mathf.Max(0.001f, Mathf.Abs(lossyScale.z))); Collider val2 = default(Collider); Renderer val3 = default(Renderer); for (int i = 0; i < 5; i++) { float num = 1.08f + (float)i * 0.09f; GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "goo_body_shell"; obj.transform.SetParent(gooCoat.transform, false); obj.transform.localPosition = new Vector3(Random.Range(0f - val.x, val.x) * 0.08f, Random.Range(0f - val.y, val.y) * 0.06f, Random.Range(0f - val.z, val.z) * 0.08f); obj.transform.localScale = new Vector3(val.x * 2f * num, val.y * 2f * num, val.z * 2f * num); obj.transform.localRotation = Random.rotation; if (obj.TryGetComponent<Collider>(ref val2)) { Object.Destroy((Object)(object)val2); } if (obj.TryGetComponent<Renderer>(ref val3)) { val3.material = material; } } float num2 = Mathf.Clamp(Mathf.Max(new float[3] { val.x, val.y, val.z }) * 0.32f, 0.12f, 0.55f); Collider val4 = default(Collider); Renderer val5 = default(Renderer); for (int j = 0; j < 36; j++) { GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj2).name = "goo_surface_blob"; obj2.transform.SetParent(gooCoat.transform, false); Vector3 onUnitSphere = Random.onUnitSphere; obj2.transform.localPosition = new Vector3(onUnitSphere.x * val.x * Random.Range(0.82f, 1.18f), onUnitSphere.y * val.y * Random.Range(0.82f, 1.18f), onUnitSphere.z * val.z * Random.Range(0.82f, 1.18f)); obj2.transform.localScale = new Vector3(Random.Range(0.85f, 1.75f) * num2, Random.Range(0.24f, 0.56f) * num2, Random.Range(0.85f, 1.75f) * num2); obj2.transform.localRotation = Random.rotation; if (obj2.TryGetComponent<Collider>(ref val4)) { Object.Destroy((Object)(object)val4); } if (obj2.TryGetComponent<Renderer>(ref val5)) { val5.material = material; } } } private static Bounds GetRenderBounds(GameObject root) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(); bool flag = false; Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(root.transform.position, Vector3.one); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null) && Object.op_Implicit((Object)(object)val) && !IsGooCoatRenderer(val)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } if (!flag) { return new Bounds(root.transform.position, Vector3.one); } return bounds; } private static bool IsGooCoatRenderer(Renderer renderer) { Transform val = ((Component)renderer).transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name == "SlimeGun_GooCoat") { return true; } val = val.parent; } return false; } private static Material CreateGooMaterial() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0156: 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_0073: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Hidden/Internal-Colored"); Material val2 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(Shader.Find("Standard"))); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.06f, 1f, 0.16f, 0.34f); if (val2.HasProperty("_Color")) { val2.SetColor("_Color", val3); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", val3); } try { val2.SetFloat("_Mode", 3f); val2.SetInt("_SrcBlend", 5); val2.SetInt("_DstBlend", 10); val2.SetInt("_ZWrite", 0); val2.SetInt("_ZTest", 8); val2.SetInt("_Cull", 0); val2.DisableKeyword("_ALPHATEST_ON"); val2.EnableKeyword("_ALPHABLEND_ON"); val2.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val2.renderQueue = 4000; } catch { } try { val2.SetFloat("_Surface", 1f); val2.SetFloat("_Blend", 0f); val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); } catch { } if (val2.HasProperty("_EmissionColor")) { val2.EnableKeyword("_EMISSION"); val2.SetColor("_EmissionColor", new Color(0.035f, 1.4f, 0.06f)); } return val2; } private void ClearTint() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) foreach (MaterialTintState tintedState in tintedStates) { if (!((Object)(object)tintedState.material == (Object)null)) { if (tintedState.material.HasProperty("_Color")) { tintedState.material.SetColor("_Color", tintedState.originalColor); } if (tintedState.material.HasProperty("_BaseColor")) { tintedState.material.SetColor("_BaseColor", tintedState.originalColor); } if (tintedState.material.HasProperty("_EmissionColor")) { tintedState.material.SetColor("_EmissionColor", tintedState.originalEmission); } if (!tintedState.hadEmission) { tintedState.material.DisableKeyword("_EMISSION"); } } } tintedStates.Clear(); foreach (RendererTintState rendererTintState in rendererTintStates) { if ((Object)(object)rendererTintState.renderer != (Object)null && Object.op_Implicit((Object)(object)rendererTintState.renderer)) { rendererTintState.renderer.SetPropertyBlock(rendererTintState.originalBlock); } } rendererTintStates.Clear(); if ((Object)(object)gooCoat != (Object)null) { Object.Destroy((Object)(object)gooCoat); gooCoat = null; } foreach (GameObject gooPatch in gooPatches) { if ((Object)(object)gooPatch != (Object)null && Object.op_Implicit((Object)(object)gooPatch)) { Object.Destroy((Object)(object)gooPatch); } } gooPatches.Clear(); } } public sealed class SlimeGlob : MonoBehaviour { private readonly HashSet<int> hitInstanceIds = new HashSet<int>(); private float spawnTime; private float expiresAt; private float slowAmount; private float slowDuration; private float tickInterval; private int enemyDamagePerTick; private int playerHealPerTick; private SlimeGunNetworkProxy? networkProxy; private const float ContactRadius = 0.9f; internal void Initialize(float lifetime, float slowAmount, float slowDuration, float tickInterval, int enemyDamagePerTick, int playerHealPerTick, SlimeGunNetworkProxy? networkProxy) { spawnTime = Time.time; expiresAt = Time.time + lifetime; this.slowAmount = slowAmount; this.slowDuration = slowDuration; this.tickInterval = tickInterval; this.enemyDamagePerTick = enemyDamagePerTick; this.playerHealPerTick = playerHealPerTick; this.networkProxy = networkProxy; } private void Update() { if (Time.time >= expiresAt) { Object.Destroy((Object)(object)((Component)this).gameObject); } else if (Time.time - spawnTime >= 0.15f) { CheckOverlaps(); } } private void OnTriggerEnter(Collider other) { if (!(Time.time - spawnTime < 0.15f)) { TryApplyToCollider(other); } } private void CheckOverlaps() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 0.9f, -1, (QueryTriggerInteraction)2); foreach (Collider val in array) { if ((Object)(object)val != (Object)null && TryApplyToCollider(val)) { break; } } } private bool TryApplyToCollider(Collider other) { Enemy val = SlimeCombat.FindEnemy(other); if ((Object)(object)val != (Object)null && Object.op_Implicit((Object)(object)val) && hitInstanceIds.Add(((Object)val).GetInstanceID())) { if ((Object)(object)networkProxy != (Object)null && SemiFunc.IsMultiplayer()) { networkProxy.RequestEnemyHit(val, slowDuration, slowAmount, enemyDamagePerTick, tickInterval); SlimeEffect.ApplyVisualToEnemy(val, slowDuration, slowAmount, enemyDamagePerTick, tickInterval); } else { SlimeEffect.ApplyToEnemy(val, slowDuration, slowAmount, enemyDamagePerTick, tickInterval); } Debug.Log((object)("[SlimeGun] Glob hit enemy: " + ((Object)val).name)); Splat(); return true; } PlayerController val2 = SlimeCombat.FindPlayer(other); if ((Object)(object)val2 != (Object)null && Object.op_Implicit((Object)(object)val2) && hitInstanceIds.Add(((Object)val2).GetInstanceID())) { if ((Object)(object)networkProxy != (Object)null && SemiFunc.IsMultiplayer()) { networkProxy.RequestPlayerHit(val2, slowDuration, slowAmount, playerHealPerTick, tickInterval); SlimeEffect.ApplyVisualToPlayer(val2, slowDuration, slowAmount, playerHealPerTick, tickInterval); } else { SlimeEffect.ApplyToPlayer(val2, slowDuration, slowAmount, playerHealPerTick, tickInterval); } Debug.Log((object)("[SlimeGun] Glob hit player: " + ((Object)val2).name)); Splat(); return true; } return false; } private void Splat() { Object.Destroy((Object)(object)((Component)this).gameObject); } } public sealed class SlimeGunController : MonoBehaviour { private sealed class HeldGunState { public float SlimeTank; public float FireRequestedUntil; public float SprayAccumulator; public float Pressure; public float NextNetworkSprayAt; public bool Initialized; public Component? Battery; } private static readonly FieldInfo? PlayerAvatarIsLocalField = typeof(PlayerAvatar).GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? GrabbedPhysGrabObjectField = typeof(PhysGrabber).GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? HeldByLocalPlayerField = typeof(PhysGrabObject).GetField("heldByLocalPlayer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? ToggleImpulseField = typeof(ItemToggle).GetField("toggleImpulse", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly Dictionary<int, HeldGunState> HeldGunStates = new Dictionary<int, HeldGunState>(); private static readonly Dictionary<Type, FieldInfo?> BatteryLifeFields = new Dictionary<Type, FieldInfo>(); private static readonly Dictionary<Type, FieldInfo?> BatteryActiveFields = new Dictionary<Type, FieldInfo>(); private PlayerController? playerController; private float slimeTank; private float nextGlobAt; private bool inputUnavailableLogged; private const float GlobFireInterval = 0.05f; private const float TriggerRequestWindow = 0.18f; private const float PressureRisePerSecond = 7.5f; private const float PressureFallPerSecond = 5.5f; private const float SprayDropletsPerSecond = 70f; private const int MaxDropletsPerFrame = 6; private const float GlobLifetime = 0.75f; private const float GlobLaunchUpward = 0.1f; private const float SprayConeAngle = 2.25f; private static Material? _slimeMaterial; internal const string SlimeGunItemName = "Slime Gun"; private const string BarrelMarkerName = "SlimeGun Barrel Origin"; public float TankFraction { get { if (!(Plugin.TankCapacity.Value > 0f)) { return 0f; } return slimeTank / Plugin.TankCapacity.Value; } } internal static void OnItemGunShoot(ItemGun gun) { if (SlimeGunRuntime.Enabled && !((Object)(object)gun == (Object)null) && Object.op_Implicit((Object)(object)gun)) { PhysGrabObject val = ((Component)gun).GetComponent<PhysGrabObject>() ?? ((Component)gun).GetComponentInParent<PhysGrabObject>(); int key = (((Object)(object)val != (Object)null) ? ((Object)val).GetInstanceID() : ((Object)gun).GetInstanceID()); if (!HeldGunStates.TryGetValue(key, out HeldGunState value)) { value = new HeldGunState { SlimeTank = Plugin.TankCapacity.Value, Initialized = true }; HeldGunStates[key] = value; } value.FireRequestedUntil = Time.time + 0.18f; value.Pressure = Mathf.Max(value.Pressure, 0.25f); } } internal static void OnPhysGrabObjectUpdate(PhysGrabObject physGrabObject) { if (!SlimeGunRuntime.Enabled || (Object)(object)physGrabObject == (Object)null || !Object.op_Implicit((Object)(object)physGrabObject)) { return; } ItemAttributes val = ((Component)physGrabObject).GetComponent<ItemAttributes>() ?? ((Component)physGrabObject).GetComponentInChildren<ItemAttributes>(true) ?? ((Component)physGrabObject).GetComponentInParent<ItemAttributes>(); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.item == (Object)null) && !(val.item.itemName != "Slime Gun")) { int instanceID = ((Object)physGrabObject).GetInstanceID(); if (!HeldGunStates.TryGetValue(instanceID, out HeldGunState value)) { value = new HeldGunState(); HeldGunStates[instanceID] = value; } if (!value.Initialized) { value.SlimeTank = Plugin.TankCapacity.Value; value.Battery = FindBattery(((Component)physGrabObject).gameObject); SetBattery(value); value.Initialized = true; } if (!IsHeldByLocalPlayer(physGrabObject)) { UpdateSprayState(value, firing: false, null, null, null); SetBattery(value); return; } bool firing; bool num = TryGetItemUseHeld(physGrabObject, out firing) && firing; bool flag = Time.time < value.FireRequestedUntil; bool firing2 = num || flag; Transform val2 = FindDeep(((Component)physGrabObject).transform, "SlimeGun Barrel Origin") ?? ((Component)physGrabObject).transform; Transform aim = (((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.cameraGameObject != (Object)null) ? PlayerController.instance.cameraGameObject.transform : val2); SlimeGunNetworkProxy networkProxy = EnsureNetworkProxy(physGrabObject); UpdateSprayState(value, firing2, val2, aim, networkProxy); BroadcastRemoteSpray(value, firing2, val2, aim, networkProxy); SetBattery(value); } } private void Start() { playerController = ((Component)this).GetComponent<PlayerController>(); if ((Object)(object)playerController != (Object)null) { slimeTank = Plugin.TankCapacity.Value; Debug.Log((object)$"[SlimeGun] Controller attached to {((Object)playerController).name}. Tank={slimeTank:0.0}"); } } private void Update() { if (!SlimeGunRuntime.Enabled || (Object)(object)playerController == (Object)null) { return; } Transform barrel; Transform aim; bool firing; if (!IsLocalController()) { RechargeTank(); } else if (!TryGetHeldSlimeGun(out barrel, out aim) || !TryGetFireHeld(out firing)) { RechargeTank(); } else if (firing && slimeTank > 0f) { slimeTank = Mathf.Max(0f, slimeTank - Plugin.TankDrainRate.Value * Time.deltaTime); if (Time.time >= nextGlobAt) { nextGlobAt = Time.time + 0.05f; FireSprayBurst(barrel, aim); } } else { RechargeTank(); } } private bool IsLocalController() { if ((Object)(object)playerController == (Object)null || !Object.op_Implicit((Object)(object)playerController)) { return false; } if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance != (Object)(object)playerController) { return false; } PlayerAvatar playerAvatarScript = playerController.playerAvatarScript; if ((Object)(object)playerAvatarScript == (Object)null || !Object.op_Implicit((Object)(object)playerAvatarScript)) { return (Object)(object)PlayerController.instance == (Object)(object)playerController; } object obj = PlayerAvatarIsLocalField?.GetValue(playerAvatarScript); if (obj is bool) { return (bool)obj; } return (Object)(object)PlayerController.instance == (Object)(object)playerController; } private bool TryGetFireHeld(out bool firing) { try { firing = SemiFunc.InputHold((InputKey)2); return true; } catch (Exception ex) { firing = false; if (!inputUnavailableLogged) { inputUnavailableLogged = true; Debug.LogWarning((object)("[SlimeGun] Fire input is unavailable; slime firing is disabled for this player controller. " + ex.GetType().Name + ": " + ex.Message)); } return false; } } private static bool TryGetItemUseHeld(PhysGrabObject physGrabObject, out bool firing) { bool flag = false; try { flag = SemiFunc.InputHold((InputKey)2); } catch { flag = false; } ItemToggle val = ((Component)physGrabObject).GetComponent<ItemToggle>() ?? ((Component)physGrabObject).GetComponentInChildren<ItemToggle>(true) ?? ((Component)physGrabObject).GetComponentInParent<ItemToggle>(); bool flag2 = default(bool); int num; if ((Object)(object)val != (Object)null) { object obj2 = ToggleImpulseField?.GetValue(val); if (obj2 is bool) { flag2 = (bool)obj2; num = 1; } else { num = 0; } } else { num = 0; } bool flag3 = (byte)((uint)num & (flag2 ? 1u : 0u)) != 0; firing = flag || ((Object)(object)val != (Object)null && (val.toggleState || flag3)); return true; } private static bool IsHeldByLocalPlayer(PhysGrabObject physGrabObject) { object obj = HeldByLocalPlayerField?.GetValue(physGrabObject); if (obj is bool) { return (bool)obj; } PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)instance)) { return false; } object? obj2 = GrabbedPhysGrabObjectField?.GetValue(instance); PhysGrabObject val = (PhysGrabObject)((obj2 is PhysGrabObject) ? obj2 : null); if ((Object)(object)val != (Object)null) { return (Object)(object)val == (Object)(object)physGrabObject; } return false; } private bool TryGetHeldSlimeGun(out Transform barrel, out Transform aim) { barrel = null; aim = null; PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)instance)) { return false; } object? obj = GrabbedPhysGrabObjectField?.GetValue(instance); PhysGrabObject val = (PhysGrabObject)((obj is PhysGrabObject) ? obj : null); if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val)) { return false; } ItemAttributes val2 = ((Component)val).GetComponent<ItemAttributes>() ?? ((Component)val).GetComponentInChildren<ItemAttributes>(true) ?? ((Component)val).GetComponentInParent<ItemAttributes>(); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.item == (Object)null || val2.item.itemName != "Slime Gun") { return false; } barrel = FindDeep(((Component)val).transform, "SlimeGun Barrel Origin") ?? ((Component)val).transform; aim = (Transform)(((Object)(object)playerController.cameraGameObject != (Object)null) ? ((object)playerController.cameraGameObject.transform) : ((object)barrel)); return true; } private void RechargeTank() { slimeTank = Mathf.Min(Plugin.TankCapacity.Value, slimeTank + Plugin.TankRechargeRate.Value * Time.deltaTime); } private static void RechargeTank(HeldGunState state) { state.SlimeTank = Mathf.Min(Plugin.TankCapacity.Value, state.SlimeTank + Plugin.TankRechargeRate.Value * Time.deltaTime); } private static void UpdateSprayState(HeldGunState state, bool firing, Transform? barrel, Transform? aim, SlimeGunNetworkProxy? networkProxy) { float num = ((firing && state.SlimeTank > 0f) ? 1f : 0f); float num2 = ((num > state.Pressure) ? 7.5f : 5.5f); state.Pressure = Mathf.MoveTowards(state.Pressure, num, num2 * Time.deltaTime); if (state.Pressure <= 0.02f || (Object)(object)barrel == (Object)null || (Object)(object)aim == (Object)null || state.SlimeTank <= 0f) { state.SprayAccumulator = 0f; if (!firing) { RechargeTank(state); } return; } float num3 = Mathf.Min(Plugin.TankDrainRate.Value, 4f); state.SlimeTank = Mathf.Max(0f, state.SlimeTank - num3 * state.Pressure * Time.deltaTime); state.SprayAccumulator += Time.deltaTime * Mathf.Lerp(28f, 70f, state.Pressure); int num4 = Mathf.Min(6, Mathf.FloorToInt(state.SprayAccumulator)); if (num4 > 0) { state.SprayAccumulator -= num4; for (int i = 0; i < num4; i++) { FireGlob(barrel, aim, state.Pressure, networkProxy); } } } private static void BroadcastRemoteSpray(HeldGunState state, bool firing, Transform barrel, Transform aim, SlimeGunNetworkProxy? networkProxy) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (firing && !(state.Pressure <= 0.05f) && !((Object)(object)networkProxy == (Object)null) && !(Time.time < state.NextNetworkSprayAt)) { state.NextNetworkSprayAt = Time.time + 0.08f; networkProxy.BroadcastSpray(barrel.position, aim.forward, state.Pressure); } } private static SlimeGunNetworkProxy? EnsureNetworkProxy(PhysGrabObject physGrabObject) { PhotonView val = ((Component)physGrabObject).GetComponent<PhotonView>() ?? ((Component)physGrabObject).GetComponentInChildren<PhotonView>(true) ?? ((Component)physGrabObject).GetComponentInParent<PhotonView>(); if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val)) { return null; } SlimeGunNetworkProxy slimeGunNetworkProxy = ((Component)val).GetComponent<SlimeGunNetworkProxy>(); if ((Object)(object)slimeGunNetworkProxy == (Object)null || !Object.op_Implicit((Object)(object)slimeGunNetworkProxy)) { slimeGunNetworkProxy = ((Component)val).gameObject.AddComponent<SlimeGunNetworkProxy>(); } slimeGunNetworkProxy.SetPhotonView(val); return slimeGunNetworkProxy; } private static Component? FindBattery(GameObject root) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "ItemBattery") { TrySetBatteryActive(val, active: true); return val; } } return null; } private static void SetBattery(HeldGunState state) { if (!((Object)(object)state.Battery == (Object)null) && Object.op_Implicit((Object)(object)state.Battery)) { Type type = ((object)state.Battery).GetType(); if (!BatteryLifeFields.TryGetValue(type, out FieldInfo value)) { value = type.GetField("batteryLife", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); BatteryLifeFields[type] = value; } if (value != null) { value.SetValue(state.Battery, Mathf.Clamp(state.SlimeTank, 0f, Plugin.TankCapacity.Value)); } TrySetBatteryActive(state.Battery, active: true); } } private static void TrySetBatteryActive(Component battery, bool active) { Type type = ((object)battery).GetType(); if (!BatteryActiveFields.TryGetValue(type, out FieldInfo value)) { value = type.GetField("batteryActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); BatteryActiveFields[type] = value; } value?.SetValue(battery, active); } private static void FireSprayBurst(Transform barrel, Transform aim, float pressure = 1f) { for (int i = 0; i < 2; i++) { FireGlob(barrel, aim, pressure, null); } } private static void FireGlob(Transform barrel, Transform aim, float pressure, SlimeGunNetworkProxy? networkProxy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) Vector3 val = barrel.right * Random.Range(-0.024f, 0.024f); Vector3 val2 = barrel.up * Random.Range(-0.02f, 0.02f); GameObject obj = CreateGlobObject(barrel.position + val + val2); Vector3 val3 = Quaternion.Euler(Random.Range(-2.25f, 2.25f), Random.Range(-2.25f, 2.25f), Random.Range(-2f, 2f)) * aim.forward; Rigidbody val4 = default(Rigidbody); if (obj.TryGetComponent<Rigidbody>(ref val4)) { float num = Mathf.Max(Plugin.GlobSpeed.Value, 12f); float num2 = Mathf.Lerp(num * 0.7f, num * 1.15f, pressure); float num3 = Random.Range(num2 * 0.82f, num2); val4.velocity = ((Vector3)(ref val3)).normalized * num3 + Vector3.up * Random.Range(0f, 0.1f); } obj.AddComponent<SlimeGlob>().Initialize(0.75f, Plugin.SlowAmount.Value, Plugin.SlimeDuration.Value, Plugin.TickInterval.Value, Mathf.RoundToInt(Plugin.DamagePerTick.Value), Mathf.RoundToInt(Plugin.HealPerTick.Value), networkProxy); } internal static void SpawnRemoteVisualSpray(Vector3 barrelPosition, Vector3 aimForward, float pressure, int seed) { //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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) State state = Random.state; Random.InitState(seed); try { int num = Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp(2f, 6f, pressure)), 2, 6); Vector3 val = ((((Vector3)(ref aimForward)).sqrMagnitude > 0.01f) ? ((Vector3)(ref aimForward)).normalized : Vector3.forward); Rigidbody val3 = default(Rigidbody); for (int i = 0; i < num; i++) { GameObject obj = CreateGlobObject(barrelPosition); Vector3 val2 = Quaternion.Euler(Random.Range(-2.25f, 2.25f), Random.Range(-2.25f, 2.25f), Random.Range(-2f, 2f)) * val; if (obj.TryGetComponent<Rigidbody>(ref val3)) { float num2 = Mathf.Max(Plugin.GlobSpeed.Value, 12f); float num3 = Mathf.Lerp(num2 * 0.7f, num2 * 1.15f, pressure); val3.velocity = ((Vector3)(ref val2)).normalized * Random.Range(num3 * 0.82f, num3); } obj.AddComponent<SlimeVisualGlob>().Initialize(0.75f); } } finally { Random.state = state; } } private static GameObject CreateGlobObject(Vector3 position) { //IL_0017: 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) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)obj).name = "SlimeGlob"; obj.transform.position = position; obj.transform.localScale = new Vector3(Random.Range(0.075f, 0.135f), Random.Range(0.055f, 0.11f), Random.Range(0.075f, 0.135f)); Collider val = default(Collider); if (obj.TryGetComponent<Collider>(ref val)) { val.isTrigger = true; } Rigidbody obj2 = obj.AddComponent<Rigidbody>(); obj2.useGravity = true; obj2.collisionDetectionMode = (CollisionDetectionMode)2; obj2.useGravity = false; obj2.drag = 1.4f; obj2.angularDrag = 2f; Renderer val2 = default(Renderer); if (obj.TryGetComponent<Renderer>(ref val2)) { val2.material = GetOrCreateSlimeMaterial(); } return obj; } private static Material GetOrCreateSlimeMaterial() { if ((Object)(object)_slimeMaterial != (Object)null && Object.op_Implicit((Object)(object)_slimeMaterial)) { return _slimeMaterial; } _slimeMaterial = CreateSlimeMaterial(); return _slimeMaterial; } private static Material CreateSlimeMaterial() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); Material val2; try { val2 = new Material(val.GetComponent<Renderer>().sharedMaterial); } finally { Object.Destroy((Object)(object)val); } val2.color = new Color(0.18f, 0.95f, 0.12f, 1f); TrySetTransparent(val2); if (val2.HasProperty("_EmissionColor")) { val2.EnableKeyword("_EMISSION"); val2.SetColor("_EmissionColor", new Color(0.04f, 0.55f, 0.04f)); } return val2