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 ScalerCore v1.0.1
ScalerCore.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using ScalerCore.AprilFools; using ScalerCore.Compat; using ScalerCore.Handlers; using ScalerCore.Handlers.EnemyVisuals; using ScalerCore.Utilities; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.Rendering.PostProcessing; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Vippy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Scaling library API for R.E.P.O. shrink and grow mods. Handles physics, mass, audio, NavMesh, animation, colliders, and multiplayer sync. Compile-time reference only: ship the runtime through the ScalerCore Thunderstore dependency.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+d35a3d825cc7f5af8afd129a74679ae52afd0bb7")] [assembly: AssemblyProduct("ScalerCore")] [assembly: AssemblyTitle("ScalerCore")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/VirtualPixel/ScalerCore.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 ScalerCore { internal static class BuildInfo { public const string Version = "1.0.1"; } [HarmonyPatch(typeof(PhysGrabObject), "Start")] internal static class AttachToValuablePatch { private static void Postfix(PhysGrabObject __instance) { if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null)) { bool num = (Object)(object)((Component)__instance).GetComponent<ValuableObject>() != (Object)null; bool flag = (Object)(object)((Component)__instance).GetComponent<ItemAttributes>() != (Object)null; bool flag2 = (Object)(object)((Component)__instance).GetComponent<CosmeticWorldObject>() != (Object)null; bool flag3 = (Object)(object)((Component)__instance).GetComponent<PlayerDeathHead>() != (Object)null; bool flag4 = (Object)(object)((Component)__instance).GetComponent<ShopRadio>() != (Object)null; if (num || flag || flag2 || flag3 || flag4) { ((Component)__instance).gameObject.AddComponent<ScaleController>(); } } } } [HarmonyPatch(typeof(EnemyRigidbody), "Awake")] internal static class AttachToEnemyPatch { private static void Postfix(EnemyRigidbody __instance) { if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<ScaleController>(); } } } [HarmonyPatch(typeof(PlayerAvatar), "Start")] internal static class AttachToPlayerPatch { private static void Postfix(PlayerAvatar __instance) { if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<ScaleController>(); PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); if (component != null) { component.RefreshRpcMonoBehaviourCache(); } } } } [HarmonyPatch(typeof(PhysGrabHinge), "Awake")] internal static class AttachToDoorPatch { private static void Postfix(PhysGrabHinge __instance) { if (!((Object)(object)((Component)__instance).GetComponent<ScaleController>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<ScaleController>(); } } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class LevelChangePatch { private static void Postfix() { ScaleManager.CleanupAll(); MapCollapse.OnLevelChange(); } } [HarmonyPatch(typeof(RunManagerPUN), "UpdateLevelRPC")] internal static class LevelChangeNonHostPatch { private static void Postfix() { if (!SemiFunc.IsMasterClientOrSingleplayer()) { ScaleManager.CleanupAll(); MapCollapse.OnLevelChange(); } } } [HarmonyPatch(typeof(ParticleScriptExplosion), "Spawn")] internal static class EnemyExplosionScalePatch { private static ScaleController? EnemyController(ParticleScriptExplosion spawner) { EnemyParent componentInParent = ((Component)spawner).GetComponentInParent<EnemyParent>(); if ((Object)(object)componentInParent == (Object)null) { return null; } ScaleController componentInChildren = ((Component)componentInParent).GetComponentInChildren<ScaleController>(); if (!((Object)(object)componentInChildren != (Object)null) || !componentInChildren.IsScaled) { return null; } return componentInChildren; } private static void Prefix(ParticleScriptExplosion __instance, ref float size, ref int damage, ref int enemyDamage, ref float forceMulti) { ScaleController scaleController = EnemyController(__instance); if (!((Object)(object)scaleController == (Object)null)) { float factor = scaleController._options.Factor; size *= factor; damage = Mathf.RoundToInt((float)damage * factor); enemyDamage = Mathf.RoundToInt((float)enemyDamage * factor); forceMulti *= factor; Plugin.Log.LogDebug((object)$"[SC] enemy explosion scaled x{factor:F2} (size={size:F2} dmg={damage} force={forceMulti:F2})"); } } private static void Postfix(ParticleScriptExplosion __instance, ParticlePrefabExplosion __result) { ScaleController scaleController = EnemyController(__instance); if (!((Object)(object)scaleController == (Object)null) && !((Object)(object)__result == (Object)null)) { AudioPitchHelper.PitchOneShot((Component)(object)__result, scaleController._options.Factor, scaleController._options.AudioPresence); } } } [HarmonyPatch(typeof(PlayerTumble), "SetupDone")] internal static class PlayerTumbleLinkPatch { private static void Postfix(PlayerTumble __instance) { PlayerAvatar playerAvatar = __instance.playerAvatar; ScaleController scaleController = ((playerAvatar != null) ? ((Component)playerAvatar).GetComponent<ScaleController>() : null); if (!((Object)(object)scaleController == (Object)null)) { AttachLink(((Component)__instance).gameObject, scaleController); Collider[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { AttachLink(((Component)componentsInChildren[i]).gameObject, scaleController); } Plugin.Log.LogDebug((object)("[SC] PlayerShrinkLink (tumble) attached → " + ((Object)((Component)__instance).gameObject).name + " avatar=" + ((Object)((Component)scaleController).gameObject).name)); } } private static void AttachLink(GameObject go, ScaleController ctrl) { (go.GetComponent<PlayerShrinkLink>() ?? go.AddComponent<PlayerShrinkLink>()).Controller = ctrl; } } [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")] internal static class PlayerDeathExpandPatch { private static void Postfix(PlayerAvatar __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled && !component._invertedActive) { component.DispatchExpand(); } } } } [HarmonyPatch(typeof(PlayerHealth), "Hurt")] internal static class PlayerBonkPatch { private static void Prefix(PlayerHealth __instance, out int __state) { __state = __instance.health; } private static void Postfix(PlayerHealth __instance, int __state) { if (__instance.health >= __state) { return; } ScaleController scaleController = ((Component)__instance).GetComponentInParent<ScaleController>() ?? ((Component)__instance).GetComponentInChildren<ScaleController>(); if ((Object)(object)scaleController == (Object)null) { return; } if (scaleController.IsScaled) { if (!scaleController._invertedActive) { scaleController.RequestBonkExpand(); } } else if (scaleController._invertedActive) { scaleController.RequestInvertedReshrink(); } } } [HarmonyPatch(typeof(ItemEquippable), "RequestEquip")] internal static class ShrunkEquipBlockPatch { private static bool Prefix(ItemEquippable __instance) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if ((Object)(object)component == (Object)null) { return true; } bool flag = false; if (component.HandlerState is CartHandler.State state) { flag = state.AddedEquippable; } else if (component.HandlerState is ItemHandler.State state2) { flag = state2.AddedEquippable; } else if (component.HandlerState is VehicleHandler.State state3) { flag = state3.AddedEquippable; } if (!flag) { return true; } PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return true; } ScaleController component2 = ((Component)instance).GetComponent<ScaleController>(); if ((Object)(object)component2 != (Object)null && component2.IsScaled) { return false; } return true; } } [HarmonyPatch(typeof(PlayerCollisionGrounded), "Update")] internal static class GroundedWallJumpFix { private static void Postfix(PlayerCollisionGrounded __instance) { //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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!__instance.Grounded) { return; } PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return; } ScaleController component = ((Component)instance).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled) { float num = __instance.Collider.radius * 1.5f; if (!Physics.Raycast(((Component)__instance).transform.position, Vector3.down, num, LayerMask.op_Implicit(__instance.LayerMask), (QueryTriggerInteraction)1)) { __instance.Grounded = false; __instance.GroundedTimer = 0f; __instance.CollisionController.Grounded = false; } } } } [HarmonyPatch(typeof(PhysGrabber), "OverrideGrabDistance")] internal static class GrabDistanceScalePatch { private static void Prefix(ref float dist) { if ((Object)(object)PhysGrabber.instance?.playerAvatar == (Object)null) { return; } ScaleController component = ((Component)PhysGrabber.instance.playerAvatar).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled) { float factor = component._options.Factor; if (factor > 1f) { dist *= factor; } else { dist *= 0.7f; } } } } [HarmonyPatch(typeof(PhysGrabObject), "OverrideGrabVerticalPosition")] internal static class GrabVerticalPositionScalePatch { private static void Prefix(ref float pos) { PhysGrabber instance = PhysGrabber.instance; object obj; if (instance == null) { obj = null; } else { PlayerAvatar playerAvatar = instance.playerAvatar; obj = ((playerAvatar != null) ? ((Component)playerAvatar).GetComponent<ScaleController>() : null); } ScaleController scaleController = (ScaleController)obj; if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled) { float factor = scaleController._options.Factor; if (factor > 1f) { pos *= factor; } else { pos = 0f; } } } } [HarmonyPatch(typeof(PhysGrabber), "StartGrabbingPhysObject")] internal static class ForceGrabPointVerticalScalePatch { private static void Postfix(PhysGrabber __instance, PhysGrabObject ___grabbedPhysGrabObject) { //IL_0089: 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_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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar playerAvatar = __instance.playerAvatar; if ((Object)(object)playerAvatar == (Object)null) { return; } ScaleController component = ((Component)playerAvatar).GetComponent<ScaleController>(); if ((Object)(object)component == (Object)null || !component.IsScaled || (Object)(object)___grabbedPhysGrabObject == (Object)null) { return; } Transform forceGrabPoint = ___grabbedPhysGrabObject.forceGrabPoint; if (!((Object)(object)forceGrabPoint == (Object)null) && ((Component)forceGrabPoint).gameObject.activeSelf) { PlayerLocalCamera localCamera = playerAvatar.localCamera; Transform val = ((localCamera != null) ? localCamera.GetOverrideTransform() : null); if (!((Object)(object)val == (Object)null)) { float num = 0.3f * (1f - component._options.Factor); Vector3 val2 = val.up * num; Transform physGrabPointPuller = __instance.physGrabPointPuller; physGrabPointPuller.position += val2; Transform physGrabPointPlane = __instance.physGrabPointPlane; physGrabPointPlane.position += val2; } } } } [HarmonyPatch(typeof(PhysGrabCart), "CartSteer")] internal static class CartHandledDistancePatch { private static float ScalePullDist(float d, PhysGrabCart cart, PhysGrabber grabber) { ScaleController component = ((Component)cart).GetComponent<ScaleController>(); if ((Object)(object)component != (Object)null && component.IsScaled) { return d * Mathf.Lerp(component._options.Factor, 1f, 0.15f); } if ((Object)(object)grabber == (Object)null) { return d; } ScaleController component2 = ((Component)grabber.playerAvatar).GetComponent<ScaleController>(); if ((Object)(object)component2 != (Object)null && component2.IsScaled) { return d * Mathf.Lerp(1f, component2._options.Factor, 0.15f); } return d; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase originalMethod) { MethodInfo lerpMethod = AccessTools.Method(typeof(Mathf), "Lerp", new Type[3] { typeof(float), typeof(float), typeof(float) }, (Type[])null); MethodInfo scaleMethod = AccessTools.Method(typeof(CartHandledDistancePatch), "ScalePullDist", (Type[])null, (Type[])null); IList<LocalVariableInfo> localVariables = originalMethod.GetMethodBody().LocalVariables; int grabberIndex = -1; int num = 0; foreach (LocalVariableInfo item in localVariables) { if (item.LocalType == typeof(PhysGrabber)) { num++; if (num == 2) { grabberIndex = item.LocalIndex; break; } } } if (grabberIndex == -1) { Plugin.Log.LogWarning((object)"[SC] CartSteer transpiler: second PhysGrabber local not found. Cart pull-distance scaling is DISABLED this session; if this appears after a game update, report it."); foreach (CodeInstruction instruction in instructions) { yield return instruction; } yield break; } int injected = 0; foreach (CodeInstruction code in instructions) { yield return code; if (code.opcode == OpCodes.Call && (MethodInfo)code.operand == lerpMethod) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldloc, (object)grabberIndex); yield return new CodeInstruction(OpCodes.Call, (object)scaleMethod); injected++; } } if (injected == 0) { Plugin.Log.LogWarning((object)"[SC] CartSteer transpiler: no Mathf.Lerp callsites matched. Cart pull-distance scaling is DISABLED this session; if this appears after a game update, report it."); } } } [HarmonyPatch(typeof(CameraGlitch), "Update")] internal static class CameraGlitchScalePatch { private static void Postfix(CameraGlitch __instance) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return; } ScaleController component = ((Component)instance).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled) { float num = ((component.OriginalScale.x > 0f) ? (component._t.localScale.x / component.OriginalScale.x) : 1f); if (!(num >= 1f) && !(num <= 0f)) { Transform transform = ((Component)__instance).transform; transform.localScale /= num; } } } } [HarmonyPatch(typeof(PlayerAvatar), "Footstep")] internal static class FootstepPitchPatch { private static void Prefix(PlayerAvatar __instance) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if ((Object)(object)component != (Object)null && component.IsScaled) { ScaleController.FootstepPitchMult = component._options.FootstepPitchMultiplier; } } private static void Postfix() { ScaleController.FootstepPitchMult = 1f; } } [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) })] internal static class SoundPlayPitchPatch { private static void Postfix(AudioSource __result) { if (ScaleController.FootstepPitchMult != 1f && (Object)(object)__result != (Object)null) { __result.pitch *= ScaleController.FootstepPitchMult; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class DriverFullyMountedScalePatch { private static void Postfix(ItemVehicle __instance, ref bool __result) { if (!__result && __instance.seats != null && __instance.seats.Length != 0 && !((Object)(object)__instance.seats[0].seatedPlayer == (Object)null)) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if ((Object)(object)component != (Object)null && component.IsScaled) { __result = true; } } } } [HarmonyPatch(typeof(ValuableTeethBot), "Update")] internal static class TeethVoiceScalePatch { private static void Postfix(ValuableTeethBot __instance) { ScaleController scaleController = ((Component)__instance).GetComponent<ScaleController>() ?? ((Component)__instance).GetComponentInParent<ScaleController>(); if ((Object)(object)scaleController == (Object)null || !scaleController.IsScaled) { return; } float num = PlayerHandler.VoicePitchMult(scaleController._options.Factor); foreach (PhysGrabber item in __instance.physGrabObject.playerGrabbing) { if (item.playerAvatar.voiceChatFetched) { item.playerAvatar.voiceChat.OverridePitch(1.25f * num, 0.1f, 0.1f, 0.2f, 0.05f, 100f); } } } } [HarmonyPatch(typeof(ItemWalkieTalkie), "Update")] internal static class WalkieVoiceScalePatch { private static void Postfix(ItemWalkieTalkie __instance) { ScaleController scaleController = ((Component)__instance).GetComponent<ScaleController>() ?? ((Component)__instance).GetComponentInParent<ScaleController>(); if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled) { PlayerAvatar inThisWalkie = __instance.inThisWalkie; if (!((Object)(object)inThisWalkie == (Object)null) && inThisWalkie.voiceChatFetched && !inThisWalkie.isLocal) { float num = PlayerHandler.VoicePitchMult(scaleController._options.Factor); inThisWalkie.voiceChat.OverridePitch(1.5f * num, 0.1f, 0.1f, 0.1f, 0f, 0f); } } } } [HarmonyPatch(typeof(PlayerDeathHead), "Update")] internal static class DeathHeadVoiceScalePatch { private static void Postfix(PlayerDeathHead __instance) { if (__instance.spectated && !((Object)(object)__instance.playerAvatar == (Object)null) && __instance.playerAvatar.voiceChatFetched) { ScaleController scaleController = ((Component)__instance).GetComponent<ScaleController>() ?? ((Component)__instance).GetComponentInParent<ScaleController>(); if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled) { float num = PlayerHandler.VoicePitchMult(scaleController._options.Factor); float num2 = (__instance.spectatedLowEnergy ? 0.5f : 1f); __instance.playerAvatar.voiceChat.OverridePitch(num2 * num, 0.2f, 0.2f, 0.1f, 0f, 0f); } } } } public class PlayerShrinkLink : MonoBehaviour { public ScaleController Controller; } [BepInPlugin("Vippy.ScalerCore", "ScalerCore", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static Harmony Harmony = null; internal static ManualLogSource Log = null; internal static readonly bool DiagMass = Environment.GetEnvironmentVariable("SCALERCORE_DIAG") == "1"; internal static readonly bool DebugDraw = Environment.GetEnvironmentVariable("SCALERCORE_DEBUG") == "1" || File.Exists(Path.Combine(Paths.ConfigPath, "scalercore_debug")); private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Harmony = new Harmony("Vippy.ScalerCore"); Harmony.PatchAll(); ((Component)this).gameObject.AddComponent<MapCollapse>(); if (DebugDraw) { ((Component)this).gameObject.AddComponent<ExtractionVolumeDebug>(); } } } public class ScaleController : MonoBehaviourPunCallbacks { public static readonly HashSet<ScaleController> Scaled = new HashSet<ScaleController>(); internal static float FootstepPitchMult = 1f; public static bool AllowManualScale = true; public Transform? ScaleTarget; internal IScaleHandler? Handler; internal object? HandlerState; internal bool HandlerOwnsScale; internal PhysGrabObject? _physGrabObject; internal Transform _t; internal Rigidbody? _rb; internal float _originalMass; private RoomVolumeCheck? _roomVolumeCheck; private Vector3 _originalRoomVolumeSize; private Vector3 _originalCheckPosition; private bool _isItem; internal ItemEquippable? _itemEquippable; internal List<ItemHandler.ScaledField>? _scaledItemFields; internal bool _invertedActive; internal Vector3 _target; internal Vector3 _animScale; internal bool _transitioning; internal float _currentAnimSpeed = ScaleOptions.Default.Speed; private Coroutine? _playerBounceAnim; private float _shrinkTimer; internal ScaleOptions _options; internal float _bonkImmuneTimer; internal string _displayName = ""; internal PhotonView? _networkPV; internal AudioPitchHelper _audioPitch = new AudioPitchHelper(); private float _pgoVanillaMassOriginal; public static bool ChallengeMode { get; set; } public Vector3 OriginalScale { get; internal set; } public bool IsScaled { get; private set; } public ScaleOptions CurrentOptions => _options; public ScaleTargets TargetType { get { if (!(Handler is PlayerHandler)) { if (!(Handler is EnemyHandler)) { if (!(Handler is ItemHandler)) { if (!(Handler is VehicleHandler)) { return ScaleTargets.Valuables; } return ScaleTargets.Items; } return ScaleTargets.Items; } return ScaleTargets.Enemies; } return ScaleTargets.Players; } } internal bool PhysicallyCapped { get { if (Handler is EnemyHandler && _options.EnemyPhysicalFactorCap > 0f && _options.Factor > 1f) { return _options.Factor > _options.EnemyPhysicalFactorCap; } return false; } } internal float PhysicalFactor { get { if (!PhysicallyCapped) { return _options.Factor; } return Mathf.Max(1f, _options.EnemyPhysicalFactorCap); } } private void Awake() { //IL_0013: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) _t = ((Component)this).transform; OriginalScale = ((Component)this).transform.localScale; _target = OriginalScale; _animScale = OriginalScale; } private void Start() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) Handler = ScaleHandlerRegistry.Resolve(((Component)this).gameObject); Handler?.Setup(this); if ((Object)(object)ScaleTarget != (Object)null) { _t = ScaleTarget; OriginalScale = _t.localScale; _target = OriginalScale; _animScale = OriginalScale; } _rb = ((Component)this).GetComponent<Rigidbody>(); if ((Object)(object)_rb != (Object)null) { _originalMass = _rb.mass; } if ((Object)(object)_physGrabObject == (Object)null) { _physGrabObject = ((Component)this).GetComponent<PhysGrabObject>(); } _roomVolumeCheck = ((Component)this).GetComponent<RoomVolumeCheck>(); if ((Object)(object)_roomVolumeCheck != (Object)null) { _originalRoomVolumeSize = _roomVolumeCheck.currentSize; _originalCheckPosition = _roomVolumeCheck.CheckPosition; } EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); _displayName = (((Object)(object)componentInParent != (Object)null) ? ((Object)((Component)componentInParent).gameObject).name : ((Object)((Component)this).gameObject).name); _isItem = (Object)(object)((Component)this).GetComponent<ItemAttributes>() != (Object)null; _itemEquippable = ((Component)this).GetComponent<ItemEquippable>(); string text = ((Handler != null) ? Handler.GetType().Name.Replace("Handler", "").ToLower() : "base"); EnemyParent componentInParent2 = ((Component)this).GetComponentInParent<EnemyParent>(); if ((Object)(object)componentInParent2 != (Object)null) { int num = 0; ScaleController[] componentsInChildren = ((Component)componentInParent2).GetComponentsInChildren<ScaleController>(); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)(object)this) { num++; } } if (num > 0) { Plugin.Log.LogWarning((object)$"[SC] *** DUPLICATE: {_displayName} already has {num} other ScaleController(s) under same EnemyParent ***"); } } _networkPV = ((MonoBehaviourPun)this).photonView ?? ((Component)this).GetComponentInParent<PhotonView>(); PhotonView? networkPV = _networkPV; if (networkPV != null) { networkPV.RefreshRpcMonoBehaviourCache(); } EnemyHandler.State state = HandlerState as EnemyHandler.State; Plugin.Log.LogDebug((object)("[SC] Registered " + _displayName + " (" + text + ")" + $" scale={OriginalScale}" + " mass=" + (((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F2") : "none") + " animTarget=" + (((Object)(object)state?.AnimTarget != (Object)null) ? ((Object)((Component)state.AnimTarget).gameObject).name : "NONE") + " navAgent=" + (((Object)(object)state?.NavAgent != (Object)null) ? "yes" : "no"))); if (Handler is PlayerHandler && SemiFunc.RunIsLobbyMenu()) { ((MonoBehaviour)this).StartCoroutine(LobbyPitchDeferred()); } if (ChallengeMode && Handler is PlayerHandler && !SemiFunc.RunIsLobbyMenu()) { ((MonoBehaviour)this).StartCoroutine(ChallengeModeDeferred()); } } private void Update() { bool flag = SemiFunc.IsMasterClientOrSingleplayer(); if (flag) { if (IsScaled && _shrinkTimer > 0f) { _shrinkTimer -= Time.deltaTime; if (_shrinkTimer <= 0f) { DispatchExpand(); } } if (_bonkImmuneTimer > 0f) { _bonkImmuneTimer -= Time.deltaTime; } if (IsScaled && Handler != null) { Handler.OnUpdate(this); } } if (!flag && IsScaled && Handler is PlayerHandler) { Handler.OnUpdate(this); } if (IsScaled && Handler is ValuableHandler) { ValuableHandler.OnDiagnoseMass(this, flag); } } private bool IsItemInInventory() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 if ((Object)(object)_itemEquippable == (Object)null) { return false; } if (_itemEquippable.IsEquipped()) { return true; } return (int)_itemEquippable.currentState > 0; } private void LateUpdate() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0108: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) bool flag = IsItemInInventory(); bool flag2 = Handler is PlayerHandler; if (_transitioning && !flag2 && !flag) { float currentAnimSpeed = _currentAnimSpeed; Vector3 originalScale = OriginalScale; float num = currentAnimSpeed * ((Vector3)(ref originalScale)).magnitude; _animScale = Vector3.MoveTowards(_animScale, _target, num * Time.deltaTime); if (!HandlerOwnsScale) { _t.localScale = ClampPhysical(_animScale); } if (_animScale == _target) { _transitioning = false; Plugin.Log.LogDebug((object)$"[SC] LATE_ANIM DONE {_displayName} finalScale={_animScale}"); } } Handler?.OnLateUpdate(this); if (!flag2 && !HandlerOwnsScale && IsScaled && !_transitioning && !flag) { Vector3 val = ClampPhysical(_target); if (_t.localScale != val) { Plugin.Log.LogDebug((object)$"[SC] LATE_FORCE {_displayName} was={_t.localScale} forcing={val}"); } _t.localScale = val; } } private Vector3 ClampPhysical(Vector3 intended) { //IL_001a: 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_001d: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0065: 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) if (!PhysicallyCapped || OriginalScale.x <= 0f) { return intended; } Vector3 val = OriginalScale * Mathf.Max(1f, _options.EnemyPhysicalFactorCap); return new Vector3(Mathf.Min(intended.x, val.x), Mathf.Min(intended.y, val.y), Mathf.Min(intended.z, val.z)); } private void ScalePgoMassOriginal(float f) { if (!((Object)(object)_physGrabObject == (Object)null) && !_isItem && !_options.PreserveMass) { if (_pgoVanillaMassOriginal == 0f) { _pgoVanillaMassOriginal = ((_physGrabObject.massOriginal > 0f) ? _physGrabObject.massOriginal : _originalMass); } if (!(_pgoVanillaMassOriginal <= 0f)) { _physGrabObject.massOriginal = Mathf.Clamp(_pgoVanillaMassOriginal * f, 0.5f, _options.MassCap); } } } private void RestorePgoMassOriginal() { if ((Object)(object)_physGrabObject != (Object)null && _pgoVanillaMassOriginal > 0f) { _physGrabObject.massOriginal = _pgoVanillaMassOriginal; } _pgoVanillaMassOriginal = 0f; } public override void OnDisable() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviourPunCallbacks)this).OnDisable(); if (IsScaled && Handler is EnemyHandler) { Plugin.Log.LogDebug((object)("[SC] DISABLE (despawn) " + _displayName + " restoring scale")); _t.localScale = OriginalScale; _animScale = OriginalScale; _target = OriginalScale; _transitioning = false; IsScaled = false; _invertedActive = false; _shrinkTimer = 0f; Scaled.Remove(this); if ((Object)(object)_rb != (Object)null) { _rb.mass = _originalMass; } RestorePgoMassOriginal(); if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize; _roomVolumeCheck.CheckPosition = _originalCheckPosition; } Handler?.OnRestore(this, isBonk: false); _audioPitch.RestorePitch(); ItemHandler.OnRestoreFields(_scaledItemFields); _scaledItemFields = null; } } private void OnDestroy() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (IsScaled) { _t.localScale = OriginalScale; PlayerHandler.State obj = HandlerState as PlayerHandler.State; if (obj != null) { PlayerVoiceChat voiceChat = obj.PlayerAvatar.voiceChat; if (voiceChat != null) { voiceChat.OverridePitchCancel(); } } Handler?.OnDestroy(this); } Scaled.Remove(this); } public void DispatchShrink(ScaleOptions options) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } if (!ScaleManager.AllowDeadHeads && (Object)(object)((Component)this).GetComponent<PlayerDeathHead>() != (Object)null) { Plugin.Log.LogDebug((object)("[SC] DispatchShrink ignored: " + _displayName + " is a dead Semibot head and ScaleManager.AllowDeadHeads is off")); return; } Plugin.Log.LogDebug((object)$"[SC] DispatchShrink ENTER {_displayName} instanceID={((Object)this).GetInstanceID()} IsScaled={IsScaled} currentScale={_t.localScale} GO={((Object)((Component)this).gameObject).name}"); Stopwatch swApply = Stopwatch.StartNew(); if (IsScaled) { if (Mathf.Approximately(options.Factor, _options.Factor)) { DispatchExpand(); if (_invertedActive) { _bonkImmuneTimer = _options.BonkImmuneDuration; } return; } Plugin.Log.LogDebug((object)$"[SC] RESCALE {_displayName} {_options.Factor} → {options.Factor}"); _options = options; _shrinkTimer = _options.Duration; if (_shrinkTimer < 0f) { _shrinkTimer = 0f; } float factor = _options.Factor; Vector3 val = OriginalScale * factor; _bonkImmuneTimer = _options.BonkImmuneDuration; _currentAnimSpeed = _options.Speed; ApplyScale(val); if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor; _roomVolumeCheck.CheckPosition = _originalCheckPosition * factor; } if ((Object)(object)_rb != (Object)null && !_isItem && !_options.PreserveMass) { _rb.mass = Mathf.Clamp(_originalMass * factor, 0.5f, _options.MassCap); } ScalePgoMassOriginal(factor); SetForceGrabPoint(factor >= 1f); if (!_options.SuppressVoicePitch) { EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); _audioPitch.ApplyPitch((Component)(object)(((Object)(object)componentInParent != (Object)null) ? ((ScaleController)(object)componentInParent) : this), factor, _options.AudioPresence); } ItemHandler.OnRestoreFields(_scaledItemFields); _scaledItemFields = ItemHandler.OnShrinkFields(this, factor); if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_Shrink", (RpcTarget)1, new object[3] { val, PackOpts(), PackBools() }); } WarnIfSlow("rescale"); return; } if (options.Factor <= 0f) { options.Factor = ScaleOptions.Default.Factor; } if (options.Speed <= 0f) { options.Speed = ScaleOptions.Default.Speed; } _options = options; _invertedActive = _options.InvertedMode; IsScaled = true; _shrinkTimer = _options.Duration; if (_shrinkTimer < 0f) { _shrinkTimer = 0f; } _currentAnimSpeed = _options.Speed; Scaled.Add(this); float factor2 = _options.Factor; Vector3 val2 = OriginalScale * factor2; Vector3 val3 = OriginalScale - val2; float magnitude = ((Vector3)(ref val3)).magnitude; float speed = _options.Speed; val3 = OriginalScale; float num = speed * ((Vector3)(ref val3)).magnitude; float num2 = ((num > 0f) ? (magnitude / num * 1.1f) : 0.75f); _bonkImmuneTimer = Mathf.Max(num2, _options.BonkImmuneDuration); ApplyScale(val2); if (factor2 < 1f) { SetForceGrabPoint(active: false); } if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor2; _roomVolumeCheck.CheckPosition = _originalCheckPosition * factor2; } if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom) { Plugin.Log.LogDebug((object)$"[SC] RPC_Shrink SEND {_displayName} viewID={_networkPV.ViewID} isMine={_networkPV.IsMine} target={val2}"); _networkPV.RPC("RPC_Shrink", (RpcTarget)1, new object[3] { val2, PackOpts(), PackBools() }); } else { Plugin.Log.LogDebug((object)string.Format("[SC] RPC_Shrink SKIP {0} networkPV={1} inRoom={2}", _displayName, ((Object)(object)_networkPV == (Object)null) ? "null" : "set", PhotonNetwork.InRoom)); } PlayImpactEffect(); Plugin.Log.LogDebug((object)("[SC] SHRINK " + _displayName + $" factor={_options.Factor}" + $" scale {OriginalScale} → {val2}" + $" animTime={magnitude / ((num > 0f) ? num : 1f):F2}s" + $" bonkImmune={_bonkImmuneTimer:F2}s" + " shrinkDuration=" + ((_shrinkTimer > 0f) ? (_shrinkTimer.ToString("F0") + "s") : "infinite"))); if ((Object)(object)_rb != (Object)null) { float num3 = _originalMass * factor2; if (!_isItem && !_options.PreserveMass) { _rb.mass = Mathf.Clamp(num3, 0.5f, _options.MassCap); } bool flag = !_isItem && !_options.PreserveMass && num3 < 0.5f; if (Plugin.DiagMass) { Plugin.Log.LogDebug((object)("[SC-DIAG][HOST] SHRINK_APPLY " + _displayName + " " + $"mass {_originalMass:F3} → {_rb.mass:F3} wantRaw={num3:F3} cap={_options.MassCap:F2}" + (flag ? " *FLOOR_HIT*" : "") + (_isItem ? " (item, mass untouched)" : "") + (_options.PreserveMass ? " (PreserveMass, mass untouched)" : "") + (((Object)(object)_physGrabObject != (Object)null) ? $" pgo.massOrig={_physGrabObject.massOriginal:F3} pgo.timerAlter={_physGrabObject.timerAlterMass:F2}" : ""))); } } ScalePgoMassOriginal(factor2); Handler?.OnScale(this); if (factor2 < 1f && (Object)(object)_physGrabObject != (Object)null && Handler is ValuableHandler) { _physGrabObject.OverrideIndestructible(0.5f); } if (!_options.SuppressVoicePitch) { EnemyParent componentInParent2 = ((Component)this).GetComponentInParent<EnemyParent>(); _audioPitch.ApplyPitch((Component)(object)(((Object)(object)componentInParent2 != (Object)null) ? ((ScaleController)(object)componentInParent2) : this), _options.Factor, _options.AudioPresence); } _scaledItemFields = ItemHandler.OnShrinkFields(this, _options.Factor); ScaleMapIcon(factor2); WarnIfSlow("fresh"); void WarnIfSlow(string path) { swApply.Stop(); if (swApply.ElapsedMilliseconds >= 10) { Plugin.Log.LogWarning((object)$"[SC] slow scale apply ({path}): {swApply.ElapsedMilliseconds}ms on {_displayName}"); } } } public void DispatchExpand() { //IL_0025: 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_004e: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && IsScaled) { IsScaled = false; Scaled.Remove(this); float num = ((OriginalScale.x > 0f) ? (_t.localScale.x / OriginalScale.x) : 0f); Plugin.Log.LogDebug((object)("[SC] EXPAND (timer/shot) " + _displayName + $" currentSize={num * 100f:F0}%" + string.Format(" mass {0} → {1:F3}", ((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F3") : "N/A", _originalMass))); _currentAnimSpeed = ResolveExpandSpeed(); ApplyScale(OriginalScale); SetForceGrabPoint(active: true); if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>()); } PlayImpactEffect(); PlayCameraShake(); if ((Object)(object)_rb != (Object)null) { _rb.mass = _originalMass; } RestorePgoMassOriginal(); if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize; _roomVolumeCheck.CheckPosition = _originalCheckPosition; } Handler?.OnRestore(this, isBonk: false); if (!_options.SuppressVoicePitch) { _audioPitch.RestorePitch(); } ItemHandler.OnRestoreFields(_scaledItemFields); _scaledItemFields = null; ScaleMapIcon(1f); } } public void DispatchExpandNow() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !IsScaled || _options.IgnoreBonkExpand) { return; } if (_bonkImmuneTimer > 0f) { Plugin.Log.LogDebug((object)$"[SC] BONK BLOCKED {_displayName} immune={_bonkImmuneTimer:F2}s remaining"); return; } IsScaled = false; _shrinkTimer = 0f; Scaled.Remove(this); float num = ((OriginalScale.x > 0f) ? (_t.localScale.x / OriginalScale.x) : 0f); Plugin.Log.LogDebug((object)("[SC] EXPAND (bonk/instant) " + _displayName + $" currentSize={num * 100f:F0}%" + string.Format(" mass {0} → {1:F3}", ((Object)(object)_rb != (Object)null) ? _rb.mass.ToString("F3") : "N/A", _originalMass))); _currentAnimSpeed = ResolveExpandSpeed(); ApplyScale(OriginalScale); SetForceGrabPoint(active: true); if ((Object)(object)_networkPV != (Object)null && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_Expand", (RpcTarget)1, Array.Empty<object>()); } PlayImpactEffect(); PlayCameraShake(); if ((Object)(object)_rb != (Object)null) { _rb.mass = _originalMass; } RestorePgoMassOriginal(); if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize; _roomVolumeCheck.CheckPosition = _originalCheckPosition; } Handler?.OnRestore(this, isBonk: true); if (!_options.SuppressVoicePitch) { _audioPitch.RestorePitch(); } ItemHandler.OnRestoreFields(_scaledItemFields); _scaledItemFields = null; ScaleMapIcon(1f); } private void ApplyScale(Vector3 target) { //IL_0001: 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_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_0051: 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) _target = target; if (!PhysicallyCapped) { _animScale = _t.localScale; } _transitioning = true; if (Handler is PlayerHandler) { if (_playerBounceAnim != null) { ((MonoBehaviour)this).StopCoroutine(_playerBounceAnim); } _playerBounceAnim = ((MonoBehaviour)this).StartCoroutine(PlayerBounceAnim(_t.localScale, target)); } } private void PlayImpactEffect() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!_options.SuppressImpactFlash) { AssetManager instance = AssetManager.instance; if (instance != null) { instance.PhysImpactEffect(_t.position); } } } private void PlayCameraShake() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!_options.SuppressCameraShake) { SemiFunc.CameraShakeImpactDistance(_t.position, 2f, 0.1f, 1f, 8f); } } private float ResolveExpandSpeed() { if (!(_options.RestoreSpeed > 0f)) { return _options.Speed; } return _options.RestoreSpeed; } private void ScaleMapIcon(float factor) { //IL_0036: 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) MapCustom val = ((Component)this).GetComponent<MapCustom>(); if ((Object)(object)val == (Object)null) { val = ((Component)this).GetComponentInParent<MapCustom>(); } if ((Object)(object)val?.mapCustomEntity != (Object)null) { ((Component)val.mapCustomEntity).transform.localScale = Vector3.one * Mathf.Max(factor, 0.3f); } } private void SetForceGrabPoint(bool active) { if ((Object)(object)_physGrabObject != (Object)null && (Object)(object)_physGrabObject.forceGrabPoint != (Object)null) { ((Component)_physGrabObject.forceGrabPoint).gameObject.SetActive(active); } } private static float BackOutEase(float t) { return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f); } private IEnumerator PlayerBounceAnim(Vector3 from, Vector3 to) { //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_0016: Unknown result type (might be due to invalid IL or missing references) float duration = 0.4f; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; float num = BackOutEase(Mathf.Clamp01(elapsed / duration)); _t.localScale = Vector3.LerpUnclamped(from, to, num); yield return null; } _t.localScale = to; _transitioning = false; _playerBounceAnim = null; } private IEnumerator ChallengeModeDeferred() { while ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) { yield return null; } if (SemiFunc.IsMultiplayer()) { PlayerHandler.State playerState = HandlerState as PlayerHandler.State; while ((Object)(object)playerState?.PlayerAvatar.voiceChat == (Object)null) { yield return null; } } if (!IsScaled && SemiFunc.IsMasterClientOrSingleplayer()) { ScaleOptions options = ScaleOptions.Default; options.InvertedMode = true; options.Duration = 0f; DispatchShrink(options); } } private IEnumerator LobbyPitchDeferred() { for (int i = 0; i < 10; i++) { yield return null; } PlayerVoiceChat[] array = Object.FindObjectsOfType<PlayerVoiceChat>(); foreach (PlayerVoiceChat val in array) { if (ChallengeMode) { val.OverridePitch(1.3f, 0.2f, 0.5f, 9999f, 0f, 0f); } else { val.OverridePitchCancel(); } } } private float[] PackOpts() { return new float[10] { _options.Factor, _options.Speed, _options.MassCap, _options.SpeedFactor, _options.AnimSpeedMultiplier, _options.FootstepPitchMultiplier, _options.BonkImmuneDuration, _options.RestoreSpeed, _options.AudioPresence, _options.EnemyPhysicalFactorCap }; } private bool[] PackBools() { return new bool[7] { _options.PreserveMass, _options.InvertedMode, _options.SuppressImpactFlash, _options.SuppressVoicePitch, _options.IgnoreBonkExpand, _options.RejectExternalApply, _options.SuppressCameraShake }; } [PunRPC] private void RPC_Shrink(Vector3 target, float[] opts, bool[] flags, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_003a: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom && (info.Sender == null || info.Sender != PhotonNetwork.MasterClient)) { return; } Plugin.Log.LogDebug((object)string.Format("[SC] RPC_Shrink RECV {0} target={1} factor={2} speed={3} handler={4}", _displayName, target, opts[0], opts[1], Handler?.GetType().Name ?? "null")); _options.Factor = opts[0]; _options.Speed = opts[1]; _options.MassCap = opts[2]; _options.SpeedFactor = opts[3]; _options.AnimSpeedMultiplier = opts[4]; _options.FootstepPitchMultiplier = opts[5]; _options.BonkImmuneDuration = opts[6]; _options.RestoreSpeed = ((opts.Length > 7) ? opts[7] : 0f); _options.AudioPresence = ((opts.Length > 8) ? opts[8] : 1f); _options.EnemyPhysicalFactorCap = ((opts.Length > 9) ? opts[9] : 0f); _options.PreserveMass = flags[0]; _options.InvertedMode = flags[1]; _options.SuppressImpactFlash = flags.Length > 2 && flags[2]; _options.SuppressVoicePitch = flags.Length > 3 && flags[3]; _options.IgnoreBonkExpand = flags.Length > 4 && flags[4]; _options.RejectExternalApply = flags.Length > 5 && flags[5]; _options.SuppressCameraShake = flags.Length > 6 && flags[6]; _invertedActive = flags[1]; float factor = _options.Factor; IsScaled = true; _currentAnimSpeed = _options.Speed; Scaled.Add(this); if ((Object)(object)_rb != (Object)null && !_isItem && !_options.PreserveMass) { _rb.mass = Mathf.Clamp(_originalMass * factor, 0.5f, _options.MassCap); } ScalePgoMassOriginal(factor); if ((Object)(object)_rb != (Object)null && Handler is ValuableHandler) { float num = _originalMass * factor; bool flag = !_isItem && !_options.PreserveMass && num < 0.5f; if (Plugin.DiagMass) { Plugin.Log.LogDebug((object)("[SC-DIAG][CLIENT] RPC_SHRINK_APPLY " + _displayName + " " + $"mass {_originalMass:F3} → {_rb.mass:F3} wantRaw={num:F3} cap={_options.MassCap:F2}" + (flag ? " *FLOOR_HIT*" : "") + (((Object)(object)_physGrabObject != (Object)null) ? $" pgo.massOrig={_physGrabObject.massOriginal:F3}" : ""))); } } if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize * factor; _roomVolumeCheck.CheckPosition = _originalCheckPosition * factor; } ApplyScale(target); if (factor < 1f) { SetForceGrabPoint(active: false); } PlayImpactEffect(); if (!_options.SuppressVoicePitch) { EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); _audioPitch.ApplyPitch((Component)(object)(((Object)(object)componentInParent != (Object)null) ? ((ScaleController)(object)componentInParent) : this), factor, _options.AudioPresence); } _scaledItemFields = ItemHandler.OnShrinkFields(this, factor); Handler?.OnScale(this); if (factor < 1f && (Object)(object)_physGrabObject != (Object)null && Handler is ValuableHandler) { _physGrabObject.OverrideIndestructible(0.5f); } ScaleMapIcon(factor); } [PunRPC] private void RPC_Expand(PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0007: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!PhotonNetwork.InRoom || (info.Sender != null && info.Sender == PhotonNetwork.MasterClient)) { IsScaled = false; Scaled.Remove(this); if ((Object)(object)_rb != (Object)null) { _rb.mass = _originalMass; } RestorePgoMassOriginal(); if ((Object)(object)_roomVolumeCheck != (Object)null) { _roomVolumeCheck.currentSize = _originalRoomVolumeSize; _roomVolumeCheck.CheckPosition = _originalCheckPosition; } _currentAnimSpeed = ResolveExpandSpeed(); ApplyScale(OriginalScale); SetForceGrabPoint(active: true); PlayImpactEffect(); PlayCameraShake(); if (!_options.SuppressVoicePitch) { _audioPitch.RestorePitch(); } ItemHandler.OnRestoreFields(_scaledItemFields); _scaledItemFields = null; Handler?.OnRestore(this, isBonk: false); ScaleMapIcon(1f); } } [PunRPC] private void RPC_PlayerPitchCancel(PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0007: 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) if (PhotonNetwork.InRoom && (info.Sender == null || info.Sender != PhotonNetwork.MasterClient)) { return; } PlayerHandler.State state = HandlerState as PlayerHandler.State; if (state != null) { PlayerVoiceChat voiceChat = state.PlayerAvatar.voiceChat; if (voiceChat != null) { voiceChat.OverridePitchCancel(); } } if (state != null) { PlayerHandler.RestoreVoicePresence(state); } } private bool SenderOwnsView(PhotonMessageInfo info) { //IL_0009: 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) if (!PhotonNetwork.InRoom) { return true; } if (info.Sender != null && (Object)(object)_networkPV != (Object)null) { return info.Sender == _networkPV.Owner; } return false; } public void RequestBonkExpand() { if (IsScaled) { if (SemiFunc.IsMasterClientOrSingleplayer()) { DispatchExpandNow(); } else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_RequestExpand", (RpcTarget)2, new object[1] { true }); } } } public void RequestInvertedReshrink() { if (!IsScaled && _invertedActive && !(_bonkImmuneTimer > 0f)) { if (SemiFunc.IsMasterClientOrSingleplayer()) { DispatchShrink(_options); } else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_RequestInvertedReshrink", (RpcTarget)2, Array.Empty<object>()); } } } [PunRPC] private void RPC_RequestInvertedReshrink(PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && SenderOwnsView(info) && !IsScaled && _invertedActive) { ScaleOptions options = ScaleOptions.Default; options.InvertedMode = true; options.Duration = 0f; DispatchShrink(options); } } public void RequestManualShrink() { if (IsScaled) { return; } if (SemiFunc.IsMasterClientOrSingleplayer()) { if (AllowManualScale) { DispatchShrink(ScaleOptions.Default); } } else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_RequestShrink", (RpcTarget)2, Array.Empty<object>()); } } [PunRPC] private void RPC_RequestShrink(PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && SenderOwnsView(info) && AllowManualScale && !IsScaled) { DispatchShrink(ScaleOptions.Default); } } public void RequestManualExpand() { if (!IsScaled) { return; } if (SemiFunc.IsMasterClientOrSingleplayer()) { if (AllowManualScale) { DispatchExpand(); } } else if ((Object)(object)_networkPV != (Object)null && _networkPV.IsMine && PhotonNetwork.InRoom) { _networkPV.RPC("RPC_RequestExpand", (RpcTarget)2, new object[1] { false }); } } [PunRPC] private void RPC_RequestExpand(bool checkImmunity, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && SenderOwnsView(info) && IsScaled) { if (checkImmunity) { DispatchExpandNow(); } else if (AllowManualScale) { DispatchExpand(); } } } public static void CleanupAll() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) foreach (ScaleController item in Scaled) { if ((Object)(object)item == (Object)null) { continue; } item._audioPitch.RestorePitch(); ItemHandler.OnRestoreFields(item._scaledItemFields); item._scaledItemFields = null; PlayerHandler.State obj = item.HandlerState as PlayerHandler.State; if (obj != null) { PlayerVoiceChat voiceChat = obj.PlayerAvatar.voiceChat; if (voiceChat != null) { voiceChat.OverridePitchCancel(); } } item.Handler?.OnRestore(item, isBonk: false); item.IsScaled = false; item._invertedActive = false; item._transitioning = false; item._target = item.OriginalScale; item._animScale = item.OriginalScale; item._t.localScale = item.OriginalScale; } Scaled.Clear(); } public override void OnJoinedRoom() { PhotonView? networkPV = _networkPV; if (networkPV != null) { networkPV.RefreshRpcMonoBehaviourCache(); } } public override void OnPlayerEnteredRoom(Player newPlayer) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { if (ChallengeMode && Handler is PlayerHandler) { ((MonoBehaviour)this).StartCoroutine(LobbyPitchDeferred()); } if (IsScaled && !((Object)(object)_networkPV == (Object)null)) { _networkPV.RPC("RPC_Shrink", newPlayer, new object[3] { _target, PackOpts(), PackBools() }); } } } } public static class ScaleManager { public static bool AllowDeadHeads { get; set; } public static void Apply(GameObject target) { Apply(target, ScaleOptions.Default); } public static void Apply(GameObject target, ScaleOptions options) { ScaleController controller = GetController(target); if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller) && IsTargetAllowed(controller, options.AllowedTargets)) { controller.DispatchShrink(options); } } public static bool ApplyIfNotScaled(GameObject target) { return ApplyIfNotScaled(target, ScaleOptions.Default); } public static bool ApplyIfNotScaled(GameObject target, ScaleOptions options) { ScaleController controller = GetController(target); if ((Object)(object)controller == (Object)null || controller.IsScaled) { return false; } if (IsLockedFromExternal(controller)) { return false; } if (!IsTargetAllowed(controller, options.AllowedTargets)) { return false; } controller.DispatchShrink(options); return true; } public static void ForceApply(GameObject target, ScaleOptions options) { ScaleController controller = GetController(target); if (!((Object)(object)controller == (Object)null) && IsTargetAllowed(controller, options.AllowedTargets)) { controller.DispatchShrink(options); } } public static ScaleController? GetController(GameObject target) { ScaleController scaleController = target.GetComponent<ScaleController>(); if (scaleController == null) { PlayerShrinkLink component = target.GetComponent<PlayerShrinkLink>(); if (component == null) { return null; } scaleController = component.Controller; } return scaleController; } public static void Restore(GameObject target) { ScaleController controller = GetController(target); if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller)) { controller.DispatchExpand(); } } public static void RestoreImmediate(GameObject target) { ScaleController controller = GetController(target); if (!((Object)(object)controller == (Object)null) && !IsLockedFromExternal(controller)) { controller.DispatchExpandNow(); } } public static void ForceRestore(GameObject target) { ScaleController controller = GetController(target); if (!((Object)(object)controller == (Object)null)) { controller.DispatchExpand(); } } public static bool UpdateOptions(GameObject target, ScaleOptions options) { ScaleController controller = GetController(target); if ((Object)(object)controller == (Object)null || !controller.IsScaled) { return false; } if (IsLockedFromExternal(controller)) { return false; } controller._options = options; return true; } public static bool ForceUpdateOptions(GameObject target, ScaleOptions options) { ScaleController controller = GetController(target); if ((Object)(object)controller == (Object)null || !controller.IsScaled) { return false; } controller._options = options; return true; } public static bool IsScaled(GameObject target) { ScaleController controller = GetController(target); if ((Object)(object)controller != (Object)null) { return controller.IsScaled; } return false; } public static void CleanupAll() { ScaleController.CleanupAll(); } private static bool IsTargetAllowed(ScaleController ctrl, ScaleTargets allowed) { IScaleHandler handler = ctrl.Handler; if (!(handler is PlayerHandler)) { if (!(handler is EnemyHandler)) { if (handler is ItemHandler || handler is VehicleHandler) { return (allowed & ScaleTargets.Items) != 0; } return (allowed & ScaleTargets.Valuables) != 0; } return (allowed & ScaleTargets.Enemies) != 0; } return (allowed & ScaleTargets.Players) != 0; } private static bool IsLockedFromExternal(ScaleController ctrl) { if (ctrl.IsScaled) { return ctrl._options.RejectExternalApply; } return false; } } [Flags] public enum ScaleTargets { None = 0, Players = 1, Enemies = 2, Items = 4, Valuables = 8, All = 0xF } public struct ScaleOptions { public float Factor; public float Duration; public float Speed; public float RestoreSpeed; public float BonkImmuneDuration; public float MassCap; public float SpeedFactor; public float AnimSpeedMultiplier; public float FootstepPitchMultiplier; public float AudioPresence; public float EnemyPhysicalFactorCap; public ScaleTargets AllowedTargets; public bool InvertedMode; public bool SuppressValueDropExpand; public bool PreserveMass; public bool SuppressImpactFlash; public bool SuppressCameraShake; public bool SuppressVoicePitch; public bool IgnoreBonkExpand; public bool RejectExternalApply; public static ScaleOptions Growth => new ScaleOptions { Factor = 2f, Duration = 0f, Speed = 2f, RestoreSpeed = 0f, BonkImmuneDuration = 5f, MassCap = 500f, SpeedFactor = 1.25f, AnimSpeedMultiplier = 0.75f, FootstepPitchMultiplier = 0.55f, AudioPresence = 1f, EnemyPhysicalFactorCap = 1.4f, AllowedTargets = ScaleTargets.All, InvertedMode = false, SuppressValueDropExpand = false, PreserveMass = false, SuppressImpactFlash = false, SuppressCameraShake = false, SuppressVoicePitch = false, IgnoreBonkExpand = false, RejectExternalApply = false }; public static ScaleOptions Default => new ScaleOptions { Factor = 0.4f, Duration = 0f, Speed = 2f, RestoreSpeed = 0f, BonkImmuneDuration = 5f, MassCap = 50f, SpeedFactor = 0.75f, AnimSpeedMultiplier = 1.5f, FootstepPitchMultiplier = 1.5f, AudioPresence = 1f, EnemyPhysicalFactorCap = 0f, AllowedTargets = ScaleTargets.All, InvertedMode = false, SuppressValueDropExpand = false, PreserveMass = false, SuppressImpactFlash = false, SuppressCameraShake = false, SuppressVoicePitch = false, IgnoreBonkExpand = false, RejectExternalApply = false }; } } namespace ScalerCore.Utilities { internal class AudioPitchHelper { private const float GrowVolumeBoost = 0.25f; private const float GrowReverbBoost = 0.15f; private Sound[]? _pitchedSounds; private float[]? _soundOriginalPitch; private float[]? _soundOriginalLoopPitch; private float[]? _soundOriginalVolume; private float[]? _soundOriginalLoopVolume; private float[]? _soundOriginalReverb; private float[]? _soundOriginalFalloff; private static readonly Dictionary<Type, FieldInfo[]> _soundFieldCache = new Dictionary<Type, FieldInfo[]>(); private static float VolumeMult(float presence) { return 1f + 0.25f * Mathf.Clamp01(presence); } private static float ReverbMult(float presence) { return 1f + 0.15f * Mathf.Clamp01(presence); } private static float FalloffMult(float factor, float presence) { return Mathf.Lerp(1f, factor, Mathf.Clamp01(presence)); } internal static Sound[] GatherSounds(Component root) { HashSet<Sound> hashSet = new HashSet<Sound>(); List<Sound> list = new List<Sound>(); MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } Type type = ((object)val).GetType(); if (!_soundFieldCache.TryGetValue(type, out FieldInfo[] value)) { value = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where f.FieldType == typeof(Sound) select f).ToArray(); _soundFieldCache[type] = value; } FieldInfo[] array = value; for (int num = 0; num < array.Length; num++) { object? value2 = array[num].GetValue(val); Sound val2 = (Sound)((value2 is Sound) ? value2 : null); if (val2 != null && hashSet.Add(val2)) { list.Add(val2); } } } return list.ToArray(); } private static float PitchMult(float factor) { if (!(factor >= 1f)) { return Mathf.Clamp(1f + (1f - factor) * 0.5f, 1f, 2f); } return Mathf.Max(0.5f, 1f - (factor - 1f) * 0.35f); } internal static void PitchOneShot(Component root, float factor, float presence) { float num = PitchMult(factor); bool flag = factor > 1f; Sound[] array = GatherSounds(root); foreach (Sound val in array) { val.Pitch *= num; val.LoopPitch *= num; val.FalloffMultiplier *= FalloffMult(factor, presence); if (flag) { val.Volume = Mathf.Min(1f, val.Volume * VolumeMult(presence)); val.ReverbMix = Mathf.Min(1f, val.ReverbMix * ReverbMult(presence)); } } } internal void ApplyPitch(Component searchRoot, float factor, float presence) { if (_pitchedSounds != null) { RestorePitch(); } Stopwatch stopwatch = Stopwatch.StartNew(); float num = PitchMult(factor); bool flag = factor > 1f; _pitchedSounds = GatherSounds(searchRoot); _soundOriginalPitch = _pitchedSounds.Select((Sound s) => s.Pitch).ToArray(); _soundOriginalLoopPitch = _pitchedSounds.Select((Sound s) => s.LoopPitch).ToArray(); _soundOriginalVolume = _pitchedSounds.Select((Sound s) => s.Volume).ToArray(); _soundOriginalLoopVolume = _pitchedSounds.Select((Sound s) => s.LoopVolume).ToArray(); _soundOriginalReverb = _pitchedSounds.Select((Sound s) => s.ReverbMix).ToArray(); _soundOriginalFalloff = _pitchedSounds.Select((Sound s) => s.FalloffMultiplier).ToArray(); for (int num2 = 0; num2 < _pitchedSounds.Length; num2++) { Sound val = _pitchedSounds[num2]; val.Pitch = _soundOriginalPitch[num2] * num; float num3 = _soundOriginalLoopPitch[num2]; val.LoopPitch = num3 * num; val.FalloffMultiplier = _soundOriginalFalloff[num2] * FalloffMult(factor, presence); if (flag) { val.Volume = Mathf.Min(1f, _soundOriginalVolume[num2] * VolumeMult(presence)); val.LoopVolume = Mathf.Min(1f, _soundOriginalLoopVolume[num2] * VolumeMult(presence)); val.ReverbMix = Mathf.Min(1f, _soundOriginalReverb[num2] * ReverbMult(presence)); } if ((Object)(object)val.Source != (Object)null && val.Source.isPlaying) { AudioSource source = val.Source; source.pitch *= num; } } Plugin.Log.LogDebug((object)string.Format("[SC] sound treatment x{0:F2} pitch{1} on {2} Sound objects under {3}", num, flag ? ", grown presence" : "", _pitchedSounds.Length, ((Object)searchRoot.gameObject).name)); stopwatch.Stop(); if (stopwatch.ElapsedMilliseconds >= 5) { Plugin.Log.LogWarning((object)$"[SC] slow sound treatment: {stopwatch.ElapsedMilliseconds}ms for {_pitchedSounds.Length} sounds under {((Object)searchRoot.gameObject).name}"); } } internal void RestorePitch() { if (_pitchedSounds == null) { return; } for (int i = 0; i < _pitchedSounds.Length; i++) { Sound val = _pitchedSounds[i]; if (val != null) { val.Pitch = _soundOriginalPitch[i]; val.LoopPitch = _soundOriginalLoopPitch[i]; val.Volume = _soundOriginalVolume[i]; val.LoopVolume = _soundOriginalLoopVolume[i]; val.ReverbMix = _soundOriginalReverb[i]; val.FalloffMultiplier = _soundOriginalFalloff[i]; if ((Object)(object)val.Source != (Object)null && val.Source.isPlaying) { val.Source.pitch = _soundOriginalLoopPitch[i]; } } } _pitchedSounds = null; _soundOriginalPitch = null; _soundOriginalLoopPitch = null; _soundOriginalVolume = null; _soundOriginalLoopVolume = null; _soundOriginalReverb = null; _soundOriginalFalloff = null; } } public class ExtractionVolumeDebug : MonoBehaviour { private readonly List<(BoxCollider col, Color color)> _boxes = new List<(BoxCollider, Color)>(); private readonly List<RoomVolumeCheck> _checks = new List<RoomVolumeCheck>(); private bool _built; private float _checkTimer; private Material? _lineMat; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[8]; private static readonly Color ProbeIn = Color.red; private static readonly Color ProbeOut = new Color(0.2f, 1f, 0.4f, 1f); private void Update() { _checkTimer -= Time.deltaTime; if (_checkTimer > 0f) { return; } _checkTimer = 0.5f; if (SemiFunc.RunIsLevel() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated) { if (!_built) { RebuildVolumes(); } RefreshChecks(); } else if (_built || _checks.Count > 0) { Clear(); } } private void RebuildVolumes() { //IL_0054: 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_0059: 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) _boxes.Clear(); ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(); foreach (ExtractionPoint val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val.roomVolume == (Object)null) { continue; } RoomVolume componentInChildren = val.roomVolume.GetComponentInChildren<RoomVolume>(true); Color item = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.Color : Color.cyan); item.a = 1f; BoxCollider[] componentsInChildren = val.roomVolume.GetComponentsInChildren<BoxCollider>(true); foreach (BoxCollider val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { _boxes.Add((val2, item)); } } } _built = _boxes.Count > 0; if (_built) { Plugin.Log.LogInfo((object)$"[ExtractionDebug] showing {_boxes.Count} extraction volume collider(s)"); } } private void RefreshChecks() { _checks.Clear(); RoomVolumeCheck[] array = Object.FindObjectsOfType<RoomVolumeCheck>(); foreach (RoomVolumeCheck val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.valuableObject != (Object)null) { _checks.Add(val); } } } private void Clear() { _boxes.Clear(); _checks.Clear(); _built = false; } private void OnRenderObject() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00de: 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) if (_boxes.Count == 0 && _checks.Count == 0) { return; } GameDirector instance = GameDirector.instance; if ((Object)(object)instance == (Object)null || (Object)(object)Camera.current != (Object)(object)instance.MainCamera) { return; } EnsureMaterial(); _lineMat.SetPass(0); GL.PushMatrix(); GL.Begin(1); foreach (var (val, val2) in _boxes) { if (!((Object)(object)val == (Object)null)) { GL.Color(val2); EmitBoxFromCollider(val); } } foreach (RoomVolumeCheck check in _checks) { if (!((Object)(object)check == (Object)null)) { GL.Color(check.inExtractionPoint ? ProbeIn : ProbeOut); EmitProbeBox(check); } } GL.End(); GL.PopMatrix(); } private void EmitBoxFromCollider(BoxCollider col) { //IL_0008: 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_000f: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_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) Transform transform = ((Component)col).transform; Vector3 center = col.center; Vector3 val = col.size * 0.5f; for (int i = 0; i < 8; i++) { _corners[i] = transform.TransformPoint(center + Vector3.Scale(val, Signs(i))); } EmitEdges(); } private void EmitProbeBox(RoomVolumeCheck check) { //IL_0008: 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_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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)check).transform; Vector3 val = transform.position + transform.rotation * check.CheckPosition; Vector3 val2 = ((check.currentSize == Vector3.zero) ? transform.localScale : check.currentSize) * 0.5f; Quaternion rotation = transform.rotation; for (int i = 0; i < 8; i++) { _corners[i] = val + rotation * Vector3.Scale(val2, Signs(i)); } EmitEdges(); } private void EmitEdges() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; j++) { int num = i ^ (1 << j); if (num > i) { GL.Vertex(_corners[i]); GL.Vertex(_corners[num]); } } } } private static Vector3 Signs(int i) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) return new Vector3(((i & 1) == 0) ? (-1f) : 1f, ((i & 2) == 0) ? (-1f) : 1f, ((i & 4) == 0) ? (-1f) : 1f); } private void EnsureMaterial() { //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_002c: Expected O, but got Unknown if (!((Object)(object)_lineMat != (Object)null)) { _lineMat = new Material(Shader.Find("Hidden/Internal-Colored")) { hideFlags = (HideFlags)61 }; _lineMat.SetInt("_SrcBlend", 5); _lineMat.SetInt("_DstBlend", 10); _lineMat.SetInt("_Cull", 0); _lineMat.SetInt("_ZWrite", 0); _lineMat.SetInt("_ZTest", 8); } } } } namespace ScalerCore.Patches { [HarmonyPatch(typeof(PhysGrabObject), "OverrideMass")] internal static class DiagOverrideMassPatch { private static void Prefix(PhysGrabObject __instance, float value, float time) { if (Plugin.DiagMass) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled && component.TargetType == ScaleTargets.Valuables) { Plugin.Log.LogInfo((object)($"[SC-DIAG] PGO.OverrideMass({value:F3}, t={time:F2}s) on {((Object)((Component)__instance).gameObject).name}" + $" rbMassNow={__instance.rb.mass:F3} pgo.massOriginal={__instance.massOriginal:F3}" + $" pgo.alterMass={__instance.alterMassValue:F3} pgo.timerAlter={__instance.timerAlterMass:F2}" + " caller=" + DiagCaller.Resolve())); } } } } [HarmonyPatch(typeof(PhysGrabObject), "ResetMass")] internal static class DiagResetMassPatch { private static void Prefix(PhysGrabObject __instance) { if (Plugin.DiagMass) { ScaleController component = ((Component)__instance).GetComponent<ScaleController>(); if (!((Object)(object)component == (Object)null) && component.IsScaled && component.TargetType == ScaleTargets.Valuables) { Plugin.Log.LogInfo((object)("[SC-DIAG] PGO.ResetMass() on " + ((Object)((Component)__instance).gameObject).name + $" rbMassBefore={__instance.rb.mass:F3} → pgo.massOriginal={__instance.massOriginal:F3}" + " caller=" + DiagCaller.Resolve())); } } } } internal static class DiagCaller { public static string Resolve() { StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false); for (int i = 0; i < stackTrace.FrameCount; i++) { MethodBase method = stackTrace.GetFrame(i).GetMethod(); if (!(method == null)) { string text = method.DeclaringType?.Namespace ?? ""; string text2 = method.DeclaringType?.Name ?? "?"; if (!text.StartsWith("HarmonyLib") && !text.StartsWith("System.") && !text2.Contains("DiagOverrideMassPatch") && !text2.Contains("DiagResetMassPatch")) { return text2 + "." + method.Name; } } } return "<unknown>"; } } internal static class EnemyPatchHelpers { internal static bool TryGetScaled(EnemyNavMeshAgent agent, out ScaleController? ctrl) { EnemyParent componentInParent = ((Component)agent).GetComponentInParent<EnemyParent>(); ctrl = ((componentInParent != null) ? ((Component)componentInParent).GetComponentInChildren<ScaleController>() : null); if ((Object)(object)ctrl != (Object)null) { return ctrl.IsScaled; } return false; } } [HarmonyPatch(typeof(EnemyNavMeshAgent), "OverrideAgent")] internal static class NavOverrideSpeedPatch { private static void Prefix(EnemyNavMeshAgent __instance, ref float speed) { if (EnemyPatchHelpers.TryGetScaled(__instance, out ScaleController ctrl)) { speed *= ctrl._options.SpeedFactor; } } } [HarmonyPatch(typeof(EnemyNavMeshAgent), "UpdateAgent")] internal static class NavUpdateSpeedPatch { private static void Prefix(EnemyNavMeshAgent __instance, ref float speed) { if (EnemyPatchHelpers.TryGetScaled(__instance, out ScaleController ctrl)) { speed *= ctrl._options.SpeedFactor; } } } [HarmonyPatch(typeof(EnemyFloater), "UpdateState")] internal static class FloaterChargeMoveInPatch { private static void Postfix(EnemyFloater __instance) { //IL_0047: 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_0086: Unknown result type (might be due to invalid IL or missing references) Enemy enemy = __instance.enemy; object obj; if (enemy == null) { obj = null; } else { EnemyRigidbody rigidbody = enemy.Rigidbody; obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null); } ScaleController scaleController = (ScaleController)obj; if ((Object)(object)scaleController == (Object)null || !scaleController.IsScaled) { return; } PlayerAvatar targetPlayer = __instance.targetPlayer; if (Object.op_Implicit((Object)(object)targetPlayer) && !(Vector3.Distance(__instance.feetTransform.position, ((Component)targetPlayer).transform.position) <= scaleController._options.Factor * 4f)) { Enemy enemy2 = __instance.enemy; if (enemy2 != null) { enemy2.NavMeshAgent.SetDestination(((Component)targetPlayer).transform.position); } } } } [HarmonyPatch(typeof(HurtCollider), "PlayerHurt")] internal static class KnockbackPatch { private static void Prefix(HurtCollider __instance, out (bool playerKill, int playerDamage, int tumbleDamage, float force, float torque) __state) { __state = (playerKill: __instance.playerKill, playerDamage: __instance.playerDamage, tumbleDamage: __instance.playerTumbleImpactHurtDamage, force: __instance.playerTumbleForce, torque: __instance.playerTumbleTorque); ScaleController scaleController = null; if ((Object)(object)__instance.enemyHost != (Object)null) { EnemyRigidbody rigidbody = __instance.enemyHost.Rigidbody; scaleController = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null); } else { EnemyParent componentInParent = ((Component)__instance).GetComponentInParent<EnemyParent>(); if ((Object)(object)componentInParent != (Object)null) { scaleController = ((Component)componentInParent).GetComponentInChildren<ScaleController>(); } } if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled) { if (scaleController._options.Factor < 1f) { __instance.playerKill = false; } __instance.playerDamage = Mathf.RoundToInt((float)__instance.playerDamage * scaleController._options.Factor); __instance.playerTumbleImpactHurtDamage = Mathf.RoundToInt((float)__instance.playerTumbleImpactHurtDamage * scaleController._options.Factor); __instance.playerTumbleForce *= scaleController._options.Factor; __instance.playerTumbleTorque *= scaleController._options.Factor; } } private static void Postfix(HurtCollider __instance, (bool playerKill, int playerDamage, int tumbleDamage, float force, float torque) __state) { (__instance.playerKill, __instance.playerDamage, __instance.playerTumbleImpactHurtDamage, __instance.playerTumbleForce, __instance.playerTumbleTorque) = __state; } } [HarmonyPatch(typeof(EnemyHeartHuggerGasGuider), "Update")] internal static class HeartHuggerGasPullPatch { private static void Postfix(EnemyHeartHuggerGasGuider __instance) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_006f: 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) if (!((Object)(object)__instance.enemyHeartHugger == (Object)null)) { Enemy enemy = __instance.enemyHeartHugger.enemy; object obj; if (enemy == null) { obj = null; } else { EnemyRigidbody rigidbody = enemy.Rigidbody; obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null); } ScaleController scaleController = (ScaleController)obj; if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled) { Vector3 position = __instance.enemyHeartHugger.headCenterTransform.position; Vector3 val = ((Component)__instance).transform.position - position; ((Component)__instance).transform.position = position + val * scaleController._options.Factor; } } } } [HarmonyPatch(typeof(EnemyHealth), "Hurt")] internal static class EnemyBonkPatch { private static void Postfix(EnemyHealth __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { Enemy enemy = __instance.enemy; object obj; if (enemy == null) { obj = null; } else { EnemyRigidbody rigidbody = enemy.Rigidbody; obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null); } ScaleController scaleController = (ScaleController)obj; if (!((Object)(object)scaleController == (Object)null) && scaleController.IsScaled && !(scaleController._options.Factor >= 1f)) { scaleController.DispatchExpandNow(); } } } } [HarmonyPatch] internal static class EnemyVisionShrunkCrouchPatch { private static MethodBase TargetMethod() { Type type = typeof(EnemyVision).GetNestedTypes(BindingFlags.NonPublic).FirstOrDefault((Type t) => t.Name.StartsWith("<Vision>")); if (type == null) { Plugin.Log.LogWarning((object)"[SC] EnemyVisionShrunkCrouchPatch: could not find Vision coroutine state machine"); return null; } return AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { FieldInfo isCrouchingField = AccessTools.Field(typeof(PlayerAvatar), "isCrouching"); MethodInfo helper = AccessTools.Method(typeof(EnemyVisionShrunkCrouchPatch), "IsEffectivelyCrouching", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo == isCrouchingField) { yield return new CodeInstruction(OpCodes.Call, (object)helper); } else { yield return instruction; } } } internal static bool IsEffectivelyCrouching(PlayerAvatar pa) { if (pa.isCrouching) { return true; } ScaleController component = ((Component)pa).GetComponent<ScaleController>(); if ((Object)(object)component != (Object)null && component.IsScaled) { return component._options.Factor < 1f; } return false; } } [HarmonyPatch(typeof(EnemyBeamer), "OnVision")] internal static class BeamerMeleeRangePatch { private static float ScaleMeleeRange(float range, EnemyBeamer beamer) { Enemy enemy = beamer.enemy; object obj; if (enemy == null) { obj = null; } else { EnemyRigidbody rigidbody = enemy.Rigidbody; obj = ((rigidbody != null) ? ((Component)rigidbody).GetComponent<ScaleController>() : null); } ScaleController scaleController = (ScaleController)obj; if ((Object)(object)scaleController == (Object)null || !scaleController.IsScaled) { return range; } return range * scaleController._options.Factor; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo helper = AccessTools.Method(typeof(BeamerMeleeRangePatch), "ScaleMeleeRange", (Type[])null, (Type[])null); int swapped = 0; foreach (CodeInstruction code in instructions) { yield return code; if (code.opcode == OpCodes.Ldc_R4 && code.operand is float num && num == 2.5f) { yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)helper); swapped++; } } if (swapped != 1) { Plugin.Log.LogWarning((object)($"[SC] Beamer melee-range transpiler matched {swapped} constants (expected 1). " + "Scaled Beamers keep the vanilla melee trigger range this session; if this appears after a game update, report it.")); } } } } namespace ScalerCore.Handlers { internal class CartHandler : IScaleHandler { internal sealed class State { internal PhysGrabCart Cart; internal bool AddedEquippable; } public void Setup(ScaleController ctrl) { PhysGrabCart component = ((Component)ctrl).GetComponent<PhysGrabCart>(); if (!((Object)(object)component == (Object)null)) { ctrl.HandlerState = new State { Cart = component }; } } public void OnScale(ScaleController ctrl) { State state = (State)ctrl.HandlerState; if (state != null) { state.AddedEquippable = PocketHelper.InjectEquippable(ctrl); } } public void OnRestore(ScaleController ctrl, bool isBonk) { State state = (State)ctrl.HandlerState; if (state != null && state.AddedEquippable) { PocketHelper.RemoveEquippable(ctrl); state.AddedEquippable = false; } } public void OnUpdate(ScaleController ctrl) { } public voi