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 BigFriendlyButton v1.0.1
BigFriendlyButton.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BigFriendlyButton.Services; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; [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: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("BigFriendlyButton")] [assembly: AssemblyTitle("BigFriendlyButton")] [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 BigFriendlyButton { [BepInPlugin("Vippy.BigFriendlyButton", "BigFriendlyButton", "1.0.1")] public class BigFriendlyButtonPlugin : BaseUnityPlugin { internal const string Guid = "Vippy.BigFriendlyButton"; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; PressConfig.Init(((BaseUnityPlugin)this).Config); new Harmony("Vippy.BigFriendlyButton").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BigFriendlyButton v1.0.1 loaded"); } } internal static class PressConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> HostOnly; public static ConfigEntry<bool> PressToCancel; public static ConfigEntry<bool> SendEarly; public static ConfigEntry<int> AutoExtractAfter; public static ConfigEntry<bool> PreviewNoModButton; public static ConfigEntry<bool> ProgressBar; public static void Init(ConfigFile config) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown Enabled = config.Bind<bool>("Button", "Enabled", true, "Turn it off and extraction goes back to vanilla on the spot, the haul goes the second you hit the goal. Joining someone with Zehs button still works either way."); HostOnly = config.Bind<bool>("Button", "Only host can press", false, "Only the host can send the haul or call it off. Everyone elses button stays dark. Turns itself off while the host is dead so the haul can't get stuck."); PressToCancel = config.Bind<bool>("Button", "Press again to cancel", true, "Hit the button again before the extraction goes to call it off. Nothing on the pad goes anywhere."); SendEarly = config.Bind<bool>("Button", "Send early", false, "Lets a press send the haul before it reaches the goal. Whatever it was short gets added to the next extraction point's goal. On the last point of a level its just gone."); AutoExtractAfter = config.Bind<int>("Button", "Auto extract after", 0, new ConfigDescription("Seconds at the goal before it goes on its own. 0 = never, it waits for a press.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 300), Array.Empty<object>())); ProgressBar = config.Bind<bool>("Button", "Progress bar", true, "A bar on the stand that fills as you get closer to being able to press. Just your screen. With Enabled off it moves to the extraction screen and shows the haul against the goal."); PreviewNoModButton = config.Bind<bool>("Button", "Preview the no-mod button", false, "Host only. Shows you what people without the mod get (the flat box) instead of the shop button, so you can try it solo."); Enabled.SettingChanged += delegate { ExtractionButton.SettingsChanged(); }; SendEarly.SettingChanged += delegate { Presence.Publish(); }; HostOnly.SettingChanged += delegate { Presence.Publish(); }; PressToCancel.SettingChanged += delegate { Presence.Publish(); }; } } internal static class BuildInfo { public const string Version = "1.0.1"; } } namespace BigFriendlyButton.Services { internal sealed class CubePin : MonoBehaviour { private PhysGrabObject grab; private Vector3 position; private Quaternion rotation; public void Pin(PhysGrabObject cube, Vector3 at, Quaternion facing) { //IL_0008: 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_000f: 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) grab = cube; position = at; rotation = facing; cube.impactDetector.destroyDisable = true; } private void FixedUpdate() { //IL_0026: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) grab.OverrideKinematic(0.2f); grab.OverrideIndestructible(0.2f); if (!(((Component)this).transform.position == position) || !(((Component)this).transform.rotation == rotation)) { grab.rb.position = position; grab.rb.rotation = rotation; ((Component)this).transform.SetPositionAndRotation(position, rotation); } } } internal sealed class ExtractionButton : MonoBehaviour { internal static readonly Color ReadyColor = new Color(1f, 0.5f, 0f); internal static readonly Vector3 StandScale = new Vector3(0.7f, 0.7f, 0.7f); internal static readonly Vector3 StandOffset = new Vector3(0.065f, 0f, 0.402f); private const string CubeTag = "Vippy.BigFriendlyButton"; private static readonly Vector3 CubeScale = new Vector3(1f, 1f, 0.15f); private static readonly List<ExtractionButton> Placed = new List<ExtractionButton>(); private static readonly Dictionary<GameObject, ExtractionButton> SoloCubes = new Dictionary<GameObject, ExtractionButton>(); private ExtractionPoint point; private GameObject station; private StaticGrabObject shopGrab; private Light shopLight; private MeshRenderer shopVisual; private GameObject? cubeObject; private PhysGrabObject? cube; private NotValuableObject? cubeHealth; private ProgressBar? standBar; private ProgressBar? backBar; private bool barsTried; private bool? lit; private bool wantLit; private bool squishing; private bool? cubeShown; private readonly List<Renderer> hiddenRenderers = new List<Renderer>(); private readonly List<Collider> hiddenColliders = new List<Collider>(); private readonly List<Light> hiddenLights = new List<Light>(); private float nextCubeCheck; private bool screenReady; private bool confirming; private bool settingGoal; private int? fullGoal; private float sentAt; private float goalMetFor; private string? readyText; private string? activeText; private static readonly Vector3 CubeBodyOffset = new Vector3(0f, 0f, 0.4f); public static bool AnyPlaced => Placed.Count > 0; private static bool Previewing { get { if (PressConfig.PreviewNoModButton.Value) { return SemiFunc.IsMasterClientOrSingleplayer(); } return false; } } public bool HoldsSuccess { get { if (!confirming && SemiFunc.IsMasterClientOrSingleplayer()) { return Gate.Live; } return false; } } public bool SettingOwnGoal => settingGoal; private bool GoalMet { get { if (point.haulGoalFetched) { return point.haulGoal - point.haulCurrent <= 0; } return false; } } private Quaternion CubeFacing => ((Component)point).transform.rotation * Quaternion.Euler(0f, 180f, 0f); private Vector3 CubeSpot { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)shopGrab).transform.position; return new Vector3(position.x, station.transform.position.y, position.z) - CubeFacing * Vector3.Scale(CubeBodyOffset, CubeScale); } } private float HaulProgress { get { if (point.haulGoalFetched) { if (point.haulGoal <= 0) { return 1f; } return Mathf.Clamp01((float)point.haulCurrent / (float)point.haulGoal); } return 0f; } } public static void Attach(ExtractionPoint point, Transform station) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) ExtractionButton extractionButton = ((Component)point).gameObject.AddComponent<ExtractionButton>(); extractionButton.point = point; extractionButton.station = ((Component)station).gameObject; extractionButton.shopGrab = ((Component)station).GetComponentInChildren<StaticGrabObject>(true); extractionButton.shopLight = ((Component)extractionButton.shopGrab).GetComponentInChildren<Light>(true); extractionButton.shopVisual = ((Component)point.shopButton).GetComponent<MeshRenderer>(); station.localScale = StandScale; station.localPosition = StandOffset; extractionButton.station.SetActive(false); Placed.Add(extractionButton); } public static Transform? AnyShopStation() { if (Placed.Count > 0) { return Placed[0].station.transform; } ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(); foreach (ExtractionPoint val in array) { if (Object.op_Implicit((Object)(object)val.shopStation) && val.shopStation.childCount > 0) { return val.shopStation; } } return null; } public static ExtractionButton? For(StaticGrabObject grab) { foreach (ExtractionButton item in Placed) { if ((Object)(object)item.shopGrab == (Object)(object)grab) { return item; } } return null; } public static ExtractionButton? For(PhysGrabObject grab) { foreach (ExtractionButton item in Placed) { if ((Object)(object)item.cube == (Object)(object)grab) { return item; } } return null; } public static void Adopt(CosmeticWorldObject cube) { if (SoloCubes.TryGetValue(((Component)cube).gameObject, out ExtractionButton value)) { SoloCubes.Remove(((Component)cube).gameObject); } else if (!IsCube(((Component)cube).GetComponent<PhotonView>())) { return; } RoundDirector.instance.cosmeticWorldObjects.Remove(cube); cube.tutorialActive = false; ValuableDiscoverCustom val = default(ValuableDiscoverCustom); if (((Component)cube).TryGetComponent<ValuableDiscoverCustom>(ref val)) { val.discovered = true; if (Gate.Present) { val.customMap.Clear(); } } if (value == null) { value = OwnerOf(((Component)cube).GetComponent<PhotonView>().InstantiationData[4]); } value?.TakeCube(cube); } private static ExtractionButton? OwnerOf(object pointView) { foreach (ExtractionButton item in Placed) { if (pointView is int num && item.point.photonView.ViewID == num) { return item; } } return null; } public static void SettingsChanged() { Presence.Publish(); if (Gate.Live) { return; } foreach (ExtractionButton item in Placed) { item.HandBack(); } } public static bool IsCube(PhotonView view) { if (Object.op_Implicit((Object)(object)view)) { object[] instantiationData = view.InstantiationData; if (instantiationData != null && instantiationData.Length == 5 && instantiationData[3] is string text) { return text == "Vippy.BigFriendlyButton"; } } return false; } private static bool IsFinished(State state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if (state - 6 <= 1 || (int)state == 9) { return true; } return false; } private void OnDestroy() { Placed.Remove(this); } public void OnHaulChecked() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 bool flag = SemiFunc.IsMasterClientOrSingleplayer(); bool flag2 = point.settingState || (int)point.stateSetTo > 0; if (flag && !flag2) { RestoreGoal(); } if (!Presence.HostLive() || !Gate.Live) { HandBack(); ShowBars(HaulProgress, onStand: false); return; } bool previewing = Previewing; station.SetActive(!previewing); ShowCube(previewing); bool flag3 = ICanPress(); if (flag2) { ShowReady(on: false); bool pressable = flag3 && Presence.HostCancels(); SetPressable(pressable); SetLit(pressable); return; } bool goalMet = GoalMet; bool flag4 = Presence.HostSendsEarly(); SetPressable(flag3 && (goalMet || flag4)); SetLit(flag3 && (goalMet || flag4)); ShowReady(goalMet); ShowBars(PressProgress(flag3, flag4), onStand: true); if (flag) { EnsureCube(); bool canPress = !PressConfig.HostOnly.Value || HostIsDown() || !SemiFunc.IsMultiplayer(); ShowProgressOnCube(PressProgress(canPress, PressConfig.SendEarly.Value)); TickAutoExtract(goalMet); } } public void OnStateSet(State state) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0038: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 State currentState = point.currentState; bool flag = ((currentState - 3 <= 1 || (int)currentState == 8) ? true : false); bool flag2 = flag; if ((int)state == 3 || ((int)state == 5 && flag2 && GoalMet)) { PlayPress(); } if (!IsFinished(state)) { return; } ShowReady(on: false); point.shopButtonAnimation = false; point.shopButton.localScale = Vector3.one; squishing = false; SetLit(on: false); SetPressable(on: false); if (SemiFunc.IsMasterClientOrSingleplayer()) { if ((int)state == 6) { CommitShortfall(); } if ((int)state == 7) { DropCube(); } } } public void OnPress(PhysGrabber grabber, bool fromCube = false) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Phase? phase = PhaseOf(point.currentState); if (phase.HasValue && Gate.Live) { PressResult pressResult = PressRules.Decide(facts: new PressFacts(GoalMet, grabber.isLocal, Time.time - sentAt), phase: phase.Value, settings: Settings()); BigFriendlyButtonPlugin.Log.LogDebug((object)string.Format("[Press] {0} {1}: {2}", fromCube ? "cube" : "button", point.currentState, pressResult)); switch (pressResult) { case PressResult.Confirm: Confirm(); break; case PressResult.SendEarly: SendEarly(); break; case PressResult.Cancel: Cancel(); break; case PressResult.Deny: Deny(); break; } } } private void PlayPress() { //IL_0028: 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) if (station.activeSelf) { point.shopButton.localScale = new Vector3(1f, 0.1f, 1f); point.soundButton.Play(point.shopButton.position, 1f, 1f, 1f, 1f); point.shopButtonAnimationEval = 0f; point.shopButtonAnimation = true; squishing = true; } } public void OnShopAnimationTick() { if (squishing && !point.shopButtonAnimation) { squishing = false; lit = null; ApplyLit(); } } private static bool ICanPress() { if (SemiFunc.IsMasterClientOrSingleplayer() || !Presence.HostOnlyPresses()) { return true; } foreach (PlayerAvatar item in SemiFunc.PlayerGetAll()) { if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.photonView) && item.photonView.Owner != null && item.photonView.Owner.IsMasterClient) { return item.isDisabled; } } return true; } private static PressSettings Settings() { return new PressSettings(PressConfig.HostOnly.Value && !HostIsDown(), PressConfig.PressToCancel.Value, PressConfig.SendEarly.Value); } private static Phase? PhaseOf(State state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown switch (state - 2) { case 0: return Phase.Filling; case 1: case 2: case 6: return Phase.Leaving; case 3: return Phase.Settling; case 4: case 5: case 7: return Phase.Done; default: return null; } } private void SetPressable(bool on) { if (((Behaviour)shopGrab).enabled != on) { ((Behaviour)shopGrab).enabled = on; } } private void HandBack() { ShowReady(on: false); station.SetActive(false); ShowCube(show: true); if (SemiFunc.IsMasterClientOrSingleplayer()) { DropCube(); } } private void EnsureCube() { //IL_00c9: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (Time.time < nextCubeCheck) { return; } nextCubeCheck = Time.time + 1f; if (Object.op_Implicit((Object)(object)cubeObject) && !Previewing && (!SemiFunc.IsMultiplayer() || !AnyoneWithoutTheMod())) { DropCube(); } if (Object.op_Implicit((Object)(object)cubeObject)) { return; } bool flag = !SemiFunc.IsMultiplayer(); if (!Previewing && (flag || !AnyoneWithoutTheMod())) { return; } PrefabRef val = SmallestCube(); if (val != null) { if (flag) { cubeObject = Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)val).Prefab, CubeSpot, CubeFacing); cubeObject.transform.localScale = CubeScale; SoloCubes[cubeObject] = this; return; } cubeObject = PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)val).ResourcePath, CubeSpot, CubeFacing, (byte)0, new object[5] { CubeScale.x, CubeScale.y, CubeScale.z, "Vippy.BigFriendlyButton", point.photonView.ViewID }); } } private static bool AnyoneWithoutTheMod() { Player[] playerListOthers = PhotonNetwork.PlayerListOthers; for (int i = 0; i < playerListOthers.Length; i++) { if (!Presence.HasMod(playerListOthers[i])) { return true; } } return false; } private float PressProgress(bool canPress, bool sendEarly) { if (!canPress) { return 0f; } if (sendEarly) { return 1f; } return HaulProgress; } private static bool HostIsDown() { if (!SemiFunc.IsMultiplayer()) { return false; } PlayerAvatar instance = PlayerAvatar.instance; if (Object.op_Implicit((Object)(object)instance)) { return instance.isDisabled; } return true; } private void ShowBars(float progress, bool onStand) { //IL_0027: 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_0047: 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) if (!barsTried) { barsTried = true; Transform parent = station.transform.Find("Extraction Point Side Button"); standBar = ProgressBar.Build(parent, ProgressBar.StandCenter, Quaternion.identity); backBar = ProgressBar.Build(point.platform, ProgressBar.BackCenter, ProgressBar.BackFacing); } bool value = PressConfig.ProgressBar.Value; standBar?.SetVisible(value && onStand); backBar?.SetVisible(value && !onStand); ProgressBar progressBar = (onStand ? standBar : backBar); if (value) { progressBar?.Show(progress); } } private void ShowProgressOnCube(float progress) { if (!((Object)(object)cubeHealth == (Object)null)) { int num = Mathf.Max(1, Mathf.RoundToInt(progress * (float)cubeHealth.healthMax)); if (cubeHealth.healthCurrent != num) { cubeHealth.healthCurrent = num; } } } internal static PrefabRef? SmallestCube() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (CosmeticWorldObjectSetup cosmeticWorldObjectSetup in ValuableDirector.instance.cosmeticWorldObjectSetups) { if ((int)cosmeticWorldObjectSetup.rarity == 0) { return cosmeticWorldObjectSetup.prefab; } } return null; } private void TakeCube(CosmeticWorldObject cube) { //IL_005d: 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) this.cube = cube.physGrabObject; cubeHealth = cube.notValuableObject; cubeObject = ((Component)cube).gameObject; cubeShown = null; ShowCube(!station.activeSelf); if (SemiFunc.IsMasterClientOrSingleplayer()) { ((Component)cube).gameObject.AddComponent<CubePin>().Pin(this.cube, CubeSpot, CubeFacing); } } private void ShowCube(bool show) { if ((Object)(object)cubeObject == (Object)null || cubeShown == show) { return; } cubeShown = show; if (show) { foreach (Renderer hiddenRenderer in hiddenRenderers) { if (Object.op_Implicit((Object)(object)hiddenRenderer)) { hiddenRenderer.enabled = true; } } foreach (Collider hiddenCollider in hiddenColliders) { if (Object.op_Implicit((Object)(object)hiddenCollider)) { hiddenCollider.enabled = true; } } foreach (Light hiddenLight in hiddenLights) { if (Object.op_Implicit((Object)(object)hiddenLight)) { ((Behaviour)hiddenLight).enabled = true; } } hiddenRenderers.Clear(); hiddenColliders.Clear(); hiddenLights.Clear(); return; } Renderer[] componentsInChildren = cubeObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (val.enabled) { val.enabled = false; hiddenRenderers.Add(val); } } Collider[] componentsInChildren2 = cubeObject.GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren2) { if (val2.enabled) { val2.enabled = false; hiddenColliders.Add(val2); } } Light[] componentsInChildren3 = cubeObject.GetComponentsInChildren<Light>(true); foreach (Light val3 in componentsInChildren3) { if (((Behaviour)val3).enabled) { ((Behaviour)val3).enabled = false; hiddenLights.Add(val3); } } } private void DropCube() { if (Object.op_Implicit((Object)(object)cubeObject) && SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(cubeObject); } else if (Object.op_Implicit((Object)(object)cubeObject)) { Object.Destroy((Object)(object)cubeObject); } cubeObject = null; cube = null; cubeHealth = null; cubeShown = null; hiddenRenderers.Clear(); hiddenColliders.Clear(); hiddenLights.Clear(); } private void TickAutoExtract(bool ready) { int value = PressConfig.AutoExtractAfter.Value; if (!ready || value <= 0) { goalMetFor = 0f; return; } goalMetFor += Time.deltaTime; if (goalMetFor >= (float)value) { Confirm(); } } private void Confirm() { goalMetFor = 0f; sentAt = Time.time; confirming = true; point.StateSet((State)3); confirming = false; } private void SendEarly() { int valueOrDefault = fullGoal.GetValueOrDefault(); if (!fullGoal.HasValue) { valueOrDefault = point.haulGoal; fullGoal = valueOrDefault; } SetGoal(point.haulCurrent); Confirm(); } private void RestoreGoal() { int? num = fullGoal; if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); fullGoal = null; SetGoal(valueOrDefault); } } private void CommitShortfall() { int? num = fullGoal; if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); fullGoal = null; Shortfall.Add(PressRules.Owed(valueOrDefault, point.haulGoal)); } } private void SetGoal(int goal) { settingGoal = true; point.HaulGoalSet(goal); settingGoal = false; } private void Cancel() { goalMetFor = 0f; point.StateSet((State)5); } private void Deny() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 if ((int)point.currentState == 2) { point.StateSet((State)5); } } private void SetLit(bool on) { wantLit = on; if (!point.shopButtonAnimation) { ApplyLit(); } } private void ApplyLit() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (lit != wantLit) { lit = wantLit; ((Behaviour)shopLight).enabled = wantLit; ((Renderer)shopVisual).material.SetColor("_EmissionColor", wantLit ? ReadyColor : Color.black); } } private void ShowReady(bool on) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (on) { screenReady = true; if (readyText == null) { readyText = (Object.op_Implicit((Object)(object)point.localizedExtractionReady) ? point.localizedExtractionReady.GetLocalizedString() : "READY"); } TubeScreen.Show(point, readyText, ReadyColor); } else if (screenReady) { screenReady = false; if (activeText == null) { activeText = (Object.op_Implicit((Object)(object)point.localizedExtractionActive) ? point.localizedExtractionActive.GetLocalizedString() : "ACTIVE"); } TubeScreen.Show(point, activeText, Color.green, silent: true); } } } internal static class Gate { public const string ZehsGuid = "com.github.zehsteam.ExtractionPointConfirmButton"; private static readonly string[] OtherConfirmMods = new string[6] { "com.github.zehsteam.ExtractionPointConfirmButton", "DJDarkLucky.AddExtractionButton", "com.repo.extractionconfirm", "yourname.extractionconfirm", "zichen.extractiondelayconfirm", "wzc.repo.auto_extraction_confirm" }; private static bool checkedOthers; private static bool otherPresent; public static bool Present => !OtherConfirmModLoaded(); public static bool Live { get { if (PressConfig.Enabled.Value) { return Present; } return false; } } public static bool ZehsLoaded => Chainloader.PluginInfos.ContainsKey("com.github.zehsteam.ExtractionPointConfirmButton"); private static bool OtherConfirmModLoaded() { if (checkedOthers) { return otherPresent; } checkedOthers = true; string[] otherConfirmMods = OtherConfirmMods; foreach (string text in otherConfirmMods) { if (Chainloader.PluginInfos.ContainsKey(text)) { otherPresent = true; BigFriendlyButtonPlugin.Log.LogWarning((object)(text + " already adds a confirm button, BigFriendlyButton is turning itself off")); break; } } return otherPresent; } } internal static class Presence { private const string Key = "Vippy.BigFriendlyButton"; private const int Off = 0; private const int Live = 1; private const int SendEarly = 2; private const int HostOnly = 4; private const int Cancel = 8; private static Room? sentRoom; private static int sentValue; public static void Publish() { //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_004e: Expected O, but got Unknown //IL_0055: Expected O, but got Unknown if (PhotonNetwork.InRoom) { int num = Local(); if (sentRoom != PhotonNetwork.CurrentRoom || sentValue != num) { sentRoom = PhotonNetwork.CurrentRoom; sentValue = num; Player localPlayer = PhotonNetwork.LocalPlayer; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"Vippy.BigFriendlyButton", (object)num); localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } } public static bool HasMod(Player player) { if (((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"Vippy.BigFriendlyButton", out object value) && value is int num) { return (num & 1) != 0; } return false; } public static bool HostLive() { return (Host() & 1) != 0; } public static bool HostSendsEarly() { return (Host() & 2) != 0; } public static bool HostOnlyPresses() { return (Host() & 4) != 0; } public static bool HostCancels() { return (Host() & 8) != 0; } public static void SendToModded(PhotonView view, string rpc, bool includeSelf, object[] args) { Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { bool num; if (!val.IsLocal) { if (val.IsMasterClient) { goto IL_002c; } num = HasMod(val); } else { num = includeSelf; } if (!num) { continue; } goto IL_002c; IL_002c: view.RPC(rpc, val, args); } } private static int Local() { if (!Gate.Live || !ExtractionButton.AnyPlaced) { return 0; } return 1 | (PressConfig.SendEarly.Value ? 2 : 0) | (PressConfig.HostOnly.Value ? 4 : 0) | (PressConfig.PressToCancel.Value ? 8 : 0); } private static int Host() { if (SemiFunc.IsMasterClientOrSingleplayer()) { return Local(); } Player masterClient = PhotonNetwork.MasterClient; if (masterClient != null && ((Dictionary<object, object>)(object)masterClient.CustomProperties).TryGetValue((object)"Vippy.BigFriendlyButton", out object value) && value is int) { return (int)value; } return 0; } } internal enum Phase { Filling, Leaving, Settling, Done } internal enum PressResult { Ignore, Deny, Confirm, SendEarly, Cancel } internal readonly struct PressFacts { public readonly bool GoalMet; public readonly bool ByHost; public readonly float SecondsLeaving; public PressFacts(bool goalMet, bool byHost, float secondsLeaving) { GoalMet = goalMet; ByHost = byHost; SecondsLeaving = secondsLeaving; } } internal readonly struct PressSettings { public readonly bool HostOnly; public readonly bool CanCancel; public readonly bool CanSendEarly; public PressSettings(bool hostOnly, bool canCancel, bool canSendEarly) { HostOnly = hostOnly; CanCancel = canCancel; CanSendEarly = canSendEarly; } } internal static class PressRules { public const float CancelGrace = 1.25f; public static int Owed(int fullGoal, int sentGoal) { if (fullGoal <= sentGoal) { return 0; } return fullGoal - sentGoal; } public static PressResult Decide(Phase phase, PressFacts facts, PressSettings settings) { switch (phase) { case Phase.Settling: case Phase.Done: return PressResult.Ignore; case Phase.Leaving: if (facts.SecondsLeaving < 1.25f) { return PressResult.Ignore; } break; } if (settings.HostOnly && !facts.ByHost) { return PressResult.Deny; } if (phase == Phase.Leaving) { if (!settings.CanCancel) { return PressResult.Deny; } return PressResult.Cancel; } if (facts.GoalMet) { return PressResult.Confirm; } if (settings.CanSendEarly) { return PressResult.SendEarly; } return PressResult.Deny; } } internal sealed class ProgressBar { private const float BarScale = 1.65f; private const float MinFill = 0.05f; public static readonly Vector3 StandCenter = new Vector3(0f, 0.78f, -0.4635f); public static readonly Vector3 BackCenter = new Vector3(0f, 1.55f, -1.5f); public static readonly Quaternion BackFacing = Quaternion.Euler(0f, 180f, 0f); private readonly GameObject root; private readonly Transform fill; private readonly Material fillMaterial; private readonly Gradient gradient; private float shown = -1f; private ProgressBar(GameObject root, Transform fill, Material fillMaterial, Gradient gradient) { this.root = root; this.fill = fill; this.fillMaterial = fillMaterial; this.gradient = gradient; } public static ProgressBar? Build(Transform parent, Vector3 center, Quaternion facing) { //IL_0049: 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_005a: 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_0066: 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_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) PrefabRef val = ExtractionButton.SmallestCube(); CosmeticWorldObject val2 = default(CosmeticWorldObject); if (!Object.op_Implicit((Object)(object)parent) || val == null || !Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)val).Prefab) || !((PrefabRef<GameObject>)(object)val).Prefab.TryGetComponent<CosmeticWorldObject>(ref val2)) { return null; } Transform healthTransform = val2.health.healthTransform; Transform obj = Object.Instantiate<Transform>(healthTransform.parent, parent, false); obj.localRotation = facing; obj.localScale = Vector3.one * 1.65f; obj.localPosition = center - facing * new Vector3(0.14850001f, 0f, 0f); Transform val3 = obj.Find(((Object)healthTransform).name); return new ProgressBar(fillMaterial: ((Renderer)((Component)val3).GetComponentInChildren<MeshRenderer>()).material, root: ((Component)obj).gameObject, fill: val3, gradient: val2.healthGradient); } public void SetVisible(bool visible) { if (root.activeSelf != visible) { root.SetActive(visible); } } public void Show(float progress) { //IL_0049: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) shown = ((shown < 0f) ? progress : Mathf.Lerp(shown, progress, Time.deltaTime * 8f)); fill.localScale = new Vector3(Mathf.Max(0.05f, shown), fill.localScale.y, fill.localScale.z); Color val = gradient.Evaluate(shown); fillMaterial.SetColor("_Color", val); fillMaterial.SetColor("_EmissionColor", val); } } internal static class Shortfall { private static RoundDirector? level; private static int owed; public static void Add(int amount) { Sync(); owed += amount; } public static int Take() { Sync(); int result = owed; owed = 0; return result; } private static void Sync() { if (!((Object)(object)level == (Object)(object)RoundDirector.instance)) { level = RoundDirector.instance; owed = 0; } } } internal static class TubeScreen { public static void Show(ExtractionPoint point, string text, Color color, bool silent = false) { //IL_0061: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!(point.tubeScreenTextString == text)) { if (!silent) { point.soundActivate2.Play(((Component)point).transform.position, 1f, 1f, 1f, 1f); } point.tubeScreenTextString = text; point.tubeScreenChangeTimer = 0.2f; ((TMP_Text)point.tubeScreenText).isRightToLeftText = false; ((TMP_Text)point.tubeScreenText).color = Color.white; point.tubeScreenLight.color = Color.white; point.tubeScreenTextColor = color; } } } internal sealed class ZehsStandIn : MonoBehaviour { private const string PrefabId = "ConfirmButton"; private static readonly List<ZehsStandIn> Spawned = new List<ZehsStandIn>(); private ExtractionPoint? point; private GameObject body; private Transform visual; private MeshRenderer visualRenderer; private float pressEval = -1f; public static bool IsZehsButton(string prefabId) { if (prefabId == "ConfirmButton") { return !Gate.ZehsLoaded; } return false; } public static GameObject? Build(Vector3 position, Quaternion rotation) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) Transform val = ExtractionButton.AnyShopStation(); if ((Object)(object)val == (Object)null) { return null; } GameObject val2 = new GameObject("ConfirmButton"); val2.SetActive(false); val2.transform.SetPositionAndRotation(position, rotation); val2.AddComponent<PhotonView>(); ZehsStandIn zehsStandIn = val2.AddComponent<ZehsStandIn>(); Transform val3 = Object.Instantiate<Transform>(val, val2.transform, false); ((Component)val3).gameObject.SetActive(true); val3.localPosition = ExtractionButton.StandOffset; val3.localRotation = Quaternion.identity; val3.localScale = ExtractionButton.StandScale; StaticGrabObject componentInChildren = ((Component)val3).GetComponentInChildren<StaticGrabObject>(true); Transform val4 = ((Component)componentInChildren).transform.Find("Shop Button Visual"); if (!Object.op_Implicit((Object)(object)val4)) { val4 = ((Component)componentInChildren).transform; } zehsStandIn.body = ((Component)val3).gameObject; zehsStandIn.visual = val4; zehsStandIn.visualRenderer = ((Component)val4).GetComponent<MeshRenderer>(); Light[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = true; } ((Renderer)zehsStandIn.visualRenderer).material.SetColor("_EmissionColor", ExtractionButton.ReadyColor); return val2; } public static void OnStateSet(ExtractionPoint point, State state) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) foreach (ZehsStandIn item in Spawned) { if ((Object)(object)item.point == (Object)(object)point) { item.body.SetActive(ShowsIn(state)); } } } private static bool ShowsIn(State state) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 bool flag = (((int)state == 1 || state - 6 <= 1 || (int)state == 9) ? true : false); return !flag; } private void OnEnable() { Spawned.Add(this); } private void OnDisable() { Spawned.Remove(this); } [PunRPC] private void SyncExtractionPointRPC(int extractionPointViewID, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0000: 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_003b: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.MasterOnlyRPC(_info)) { PhotonView val = PhotonView.Find(extractionPointViewID); ExtractionPoint val2 = default(ExtractionPoint); if (Object.op_Implicit((Object)(object)val) && ((Component)val).TryGetComponent<ExtractionPoint>(ref val2)) { point = val2; State state = (((int)val2.stateSetTo != 0) ? val2.stateSetTo : val2.currentState); body.SetActive(ShowsIn(state)); } } } [PunRPC] private void OnClickRPC(PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0000: 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_0054: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.MasterOnlyRPC(_info) && !((Object)(object)point == (Object)null) && !(pressEval >= 0f)) { visual.localScale = new Vector3(1f, 0.1f, 1f); point.soundButton.Play(visual.position, 1f, 1f, 1f, 1f); pressEval = 0f; } } private void Update() { //IL_0060: 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_006b: 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) if (!(pressEval < 0f) && !((Object)(object)point == (Object)null)) { pressEval = Mathf.Clamp01(pressEval + Time.deltaTime * 2f); float num = point.buttonPressAnimationCurve.Evaluate(pressEval); ((Renderer)visualRenderer).material.SetColor("_EmissionColor", Color.Lerp(ExtractionButton.ReadyColor, Color.white, num)); visual.localScale = new Vector3(1f, Mathf.Clamp(num, 0.5f, 1f), 1f); if (pressEval >= 1f) { pressEval = -1f; } } } } } namespace BigFriendlyButton.Patches { [HarmonyPatch] internal static class CubePatches { [HarmonyPatch(typeof(CosmeticWorldObject), "Start")] [HarmonyPostfix] private static void Spawned(CosmeticWorldObject __instance) { ExtractionButton.Adopt(__instance); } [HarmonyPatch(typeof(CosmeticWorldObject), "HealthLogic")] [HarmonyPrefix] private static void NoHealing(CosmeticWorldObject __instance) { if ((Object)(object)ExtractionButton.For(__instance.physGrabObject) != (Object)null) { __instance.healTimer = 0f; } } [HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")] [HarmonyPrefix] private static void BeforeSoloGrab(PhysGrabObject __instance, out int __state) { __state = __instance.playerGrabbing.Count; } [HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")] [HarmonyPostfix] private static void AfterSoloGrab(PhysGrabObject __instance, int __state) { if (!SemiFunc.IsMultiplayer()) { PressIfNew(__instance, __state); } } [HarmonyPatch(typeof(PhysGrabObject), "GrabStartedRPC")] [HarmonyPrefix] private static void BeforeGrab(PhysGrabObject __instance, out int __state) { __state = __instance.playerGrabbing.Count; } [HarmonyPatch(typeof(PhysGrabObject), "GrabStartedRPC")] [HarmonyPostfix] private static void AfterGrab(PhysGrabObject __instance, int __state) { if (SemiFunc.IsMasterClient()) { PressIfNew(__instance, __state); } } private static void PressIfNew(PhysGrabObject grab, int countBefore) { if (grab.playerGrabbing.Count > countBefore) { ExtractionButton extractionButton = ExtractionButton.For(grab); PhysGrabber val = grab.playerGrabbing[grab.playerGrabbing.Count - 1]; if ((Object)(object)extractionButton != (Object)null && Object.op_Implicit((Object)(object)val)) { extractionButton.OnPress(val, fromCube: true); } } } } [HarmonyPatch(typeof(ExtractionPoint))] internal static class ExtractionPointPatch { [HarmonyPatch("Start")] [HarmonyPrefix] private static void KeepShopStation(ExtractionPoint __instance, out Transform? __state) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown __state = null; if (SemiFunc.RunIsLevel() && Gate.Present && Object.op_Implicit((Object)(object)__instance.shopStation)) { __state = __instance.shopStation; GameObject val = new GameObject("Shop Station"); val.transform.SetParent(((Component)__instance).transform, false); __instance.shopStation = val.transform; } } [HarmonyPatch("Start")] [HarmonyPostfix] private static void Placed(ExtractionPoint __instance, Transform? __state) { if ((Object)(object)__state != (Object)null) { ExtractionButton.Attach(__instance, __state); } Presence.Publish(); } [HarmonyPatch("OnShopClick")] [HarmonyPrefix] private static bool SkipShopClick(ExtractionPoint __instance) { ExtractionButton extractionButton = default(ExtractionButton); return !((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton); } [HarmonyPatch("ShopButtonAnimation")] [HarmonyPostfix] private static void ShopButtonAnimated(ExtractionPoint __instance) { ExtractionButton extractionButton = default(ExtractionButton); if (((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton)) { extractionButton.OnShopAnimationTick(); } } [HarmonyPatch("HaulChecker")] [HarmonyPostfix] private static void HaulChecked(ExtractionPoint __instance) { ExtractionButton extractionButton = default(ExtractionButton); if (((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton)) { extractionButton.OnHaulChecked(); } } [HarmonyPatch("StateSetRPC")] [HarmonyPostfix] private static void StateChanged(ExtractionPoint __instance, State state, PhotonMessageInfo _info) { //IL_0000: 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_0014: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.MasterOnlyRPC(_info)) { ExtractionButton extractionButton = default(ExtractionButton); if (((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton)) { extractionButton.OnStateSet(state); } ZehsStandIn.OnStateSet(__instance, state); } } [HarmonyPatch("HaulGoalSetRPC")] [HarmonyPostfix] private static void GoalChanged(ExtractionPoint __instance, PhotonMessageInfo _info) { //IL_0000: 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_000f: Invalid comparison between Unknown and I4 ExtractionButton extractionButton = default(ExtractionButton); if (SemiFunc.MasterOnlyRPC(_info) && (int)__instance.currentState == 2 && ((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton)) { __instance.SetHaulText(); } } [HarmonyPatch("StateSet")] [HarmonyPrefix] private static bool HoldSuccess(ExtractionPoint __instance, State newState) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)newState != 3 || (int)__instance.currentState != 2) { return true; } ExtractionButton extractionButton = default(ExtractionButton); if (((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton)) { return !extractionButton.HoldsSuccess; } return true; } [HarmonyPatch("HaulGoalSet")] [HarmonyPrefix] private static void AddShortfall(ExtractionPoint __instance, ref int value) { ExtractionButton extractionButton = default(ExtractionButton); if (SemiFunc.IsMasterClientOrSingleplayer() && ((Component)__instance).TryGetComponent<ExtractionButton>(ref extractionButton) && !extractionButton.SettingOwnGoal) { value += Shortfall.Take(); } } } [HarmonyPatch(typeof(MultiplayerPool), "Instantiate")] internal static class MultiplayerPoolPatch { private static bool Prefix(MultiplayerPool __instance, string prefabId, Vector3 position, Quaternion rotation, ref GameObject? __result) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (__instance.ResourceCache.ContainsKey(prefabId) || !ZehsStandIn.IsZehsButton(prefabId)) { return true; } __result = ZehsStandIn.Build(position, rotation); return (Object)(object)__result == (Object)null; } } [HarmonyPatch(typeof(StaticGrabObject))] internal static class StaticGrabObjectPatch { [HarmonyPatch("GrabStartedRPC")] [HarmonyPrefix] private static void BeforeNetworkGrab(StaticGrabObject __instance, int playerPhotonID, out int __state) { if ((Object)(object)ExtractionButton.For(__instance) != (Object)null) { PhotonView val = PhotonView.Find(playerPhotonID); PhysGrabber item = default(PhysGrabber); if (Object.op_Implicit((Object)(object)val) && ((Component)val).TryGetComponent<PhysGrabber>(ref item)) { __instance.playerGrabbing.Remove(item); } } __state = __instance.playerGrabbing.Count; } [HarmonyPatch("GrabStartedRPC")] [HarmonyPostfix] private static void AfterNetworkGrab(StaticGrabObject __instance, int __state) { if (SemiFunc.IsMasterClient()) { PressIfNew(__instance, __state); } } [HarmonyPatch("GrabStarted")] [HarmonyPrefix] private static void BeforeLocalGrab(StaticGrabObject __instance, out int __state) { __state = __instance.playerGrabbing.Count; } [HarmonyPatch("GrabStarted")] [HarmonyPostfix] private static void AfterLocalGrab(StaticGrabObject __instance, int __state) { if (!SemiFunc.IsMultiplayer()) { PressIfNew(__instance, __state); } } [HarmonyPatch("GrabLink")] [HarmonyPrefix] private static bool LinkModdedOnly(StaticGrabObject __instance, object[] __args) { if (!SemiFunc.IsMultiplayer() || (Object)(object)ExtractionButton.For(__instance) == (Object)null) { return true; } Presence.SendToModded(__instance.photonView, "GrabLinkRPC", includeSelf: true, __args); return false; } [HarmonyPatch("Start")] [HarmonyPrefix] private static bool SkipShopOwnership(StaticGrabObject __instance) { if (SemiFunc.RunIsShop()) { return true; } ExtractionPoint componentInParent = ((Component)__instance).GetComponentInParent<ExtractionPoint>(); if (!Object.op_Implicit((Object)(object)componentInParent) || (Object)(object)componentInParent.buttonGrabObject == (Object)(object)__instance) { return true; } __instance.photonView = ((Component)__instance).GetComponent<PhotonView>(); return false; } [HarmonyPatch(typeof(PhysGrabObjectGrabArea), "UpdateList")] [HarmonyPrefix] private static bool AreaModdedOnly(PhysGrabObjectGrabArea __instance, bool add, PhysGrabber grabber) { if (!SemiFunc.IsMultiplayer() || !Object.op_Implicit((Object)(object)grabber) || !Object.op_Implicit((Object)(object)__instance.staticGrabObject) || (Object)(object)ExtractionButton.For(__instance.staticGrabObject) == (Object)null) { return true; } string rpc = (add ? "AddToGrabbersList" : "RemoveFromGrabbersList"); Presence.SendToModded(__instance.photonView, rpc, includeSelf: false, new object[1] { grabber.photonView.ViewID }); return false; } private static void PressIfNew(StaticGrabObject grab, int countBefore) { if (grab.playerGrabbing.Count > countBefore) { ExtractionButton extractionButton = ExtractionButton.For(grab); PhysGrabber val = grab.playerGrabbing[grab.playerGrabbing.Count - 1]; if ((Object)(object)extractionButton != (Object)null && Object.op_Implicit((Object)(object)val)) { extractionButton.OnPress(val); } } } } }