Decompiled source of BunkbedRevive v1.0.2

BunkbedRevive.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BunkbedRevive.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BunkbedRevive
{
	public class BunkbedController : MonoBehaviour
	{
		private static InteractTrigger interactTrigger;

		private static Sprite defaultIcon;

		private static Sprite disabledIcon;

		private static float nextReviveTime;

		private static readonly FieldInfo ThrowingObjectField = typeof(PlayerControllerB).GetField("throwingObject", BindingFlags.Instance | BindingFlags.NonPublic);

		public static BunkbedController Instance;

		public static int GetReviveCost()
		{
			return ModConfig.ReviveCost.Value;
		}

		public static bool HasDeadPlayers()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return false;
			}
			return StartOfRound.Instance.connectedPlayersAmount + 1 - StartOfRound.Instance.livingPlayers > 0;
		}

		private static void CreateTrigger()
		{
			//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_0045: 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_005f: 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_0071: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			GameObject val = new GameObject("ReviveBed", new Type[2]
			{
				typeof(BoxCollider),
				typeof(InteractTrigger)
			});
			val.transform.SetParent(((Component)Instance).transform);
			val.transform.localPosition = Vector3.zero;
			val.layer = LayerMask.NameToLayer("InteractableObject");
			val.tag = "InteractTrigger";
			BoxCollider component = val.GetComponent<BoxCollider>();
			component.center = Vector3.zero;
			component.size = new Vector3(2.5f, 3f, 1f);
			((Collider)component).enabled = true;
			interactTrigger = val.GetComponent<InteractTrigger>();
			interactTrigger.oneHandedItemAllowed = true;
			interactTrigger.twoHandedItemAllowed = true;
			interactTrigger.interactable = true;
			interactTrigger.holdInteraction = false;
			interactTrigger.timeToHold = 0.4f;
			interactTrigger.cooldownTime = 0.25f;
			interactTrigger.timeToHoldSpeedMultiplier = 1f;
			int reviveCost = GetReviveCost();
			interactTrigger.hoverTip = "Revive for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]";
			interactTrigger.hoverIcon = defaultIcon;
			interactTrigger.disabledHoverIcon = disabledIcon;
			interactTrigger.disabledHoverTip = "No dead players";
			interactTrigger.onCancelAnimation = new InteractEvent();
			interactTrigger.holdingInteractEvent = new InteractEventFloat();
			interactTrigger.onInteractEarly = new InteractEvent();
			interactTrigger.onInteract = new InteractEvent();
			interactTrigger.onStopInteract = new InteractEvent();
			((UnityEvent<PlayerControllerB>)(object)interactTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				OnInteract();
			});
			((UnityEvent<PlayerControllerB>)(object)interactTrigger.onStopInteract).AddListener((UnityAction<PlayerControllerB>)delegate
			{
				OnStopInteract();
			});
		}

		private static void GetIcons()
		{
			StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
			if ((Object)(object)val != (Object)null)
			{
				defaultIcon = val.triggerScript.hoverIcon;
				disabledIcon = val.triggerScript.disabledHoverIcon;
			}
		}

		private static RagdollGrabbableObject GetHeldBody()
		{
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)val == (Object)null || !val.isHoldingObject || (Object)(object)val.currentlyHeldObjectServer == (Object)null)
			{
				return null;
			}
			GrabbableObject currentlyHeldObjectServer = val.currentlyHeldObjectServer;
			return (RagdollGrabbableObject)(object)((currentlyHeldObjectServer is RagdollGrabbableObject) ? currentlyHeldObjectServer : null);
		}

		private static bool IsHeldBodyRevivable(RagdollGrabbableObject body)
		{
			if ((Object)(object)body == (Object)null || body.bodyID < 0)
			{
				return false;
			}
			PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts;
			if (array == null || body.bodyID >= array.Length)
			{
				return false;
			}
			PlayerControllerB val = array[body.bodyID];
			if ((Object)(object)val != (Object)null)
			{
				return val.isPlayerDead;
			}
			return false;
		}

		private void Awake()
		{
			Instance = this;
			GetIcons();
			CreateTrigger();
		}

		private void Update()
		{
			if (!((Object)(object)interactTrigger == (Object)null) && !((Object)(object)StartOfRound.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null))
			{
				RagdollGrabbableObject heldBody = GetHeldBody();
				bool flag = (Object)(object)heldBody != (Object)null && IsHeldBodyRevivable(heldBody);
				interactTrigger.interactable = flag;
				if (flag)
				{
					string text = (((Object)(object)heldBody.ragdoll != (Object)null) ? heldBody.ragdoll.playerScript.playerUsername : "Player");
					int reviveCost = GetReviveCost();
					interactTrigger.hoverTip = "Revive " + text + " for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]";
				}
			}
		}

		public static void OnInteract()
		{
			if (Time.unscaledTime < nextReviveTime)
			{
				return;
			}
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			RagdollGrabbableObject heldBody = GetHeldBody();
			if ((Object)(object)val == (Object)null || !IsHeldBodyRevivable(heldBody))
			{
				return;
			}
			int reviveCost = GetReviveCost();
			Terminal val2 = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val2 != (Object)null && val2.groupCredits < reviveCost)
			{
				BunkbedRevivePlugin.Log.LogMessage((object)"Not enough credits for revive");
				interactTrigger.StopInteraction();
				return;
			}
			nextReviveTime = Time.unscaledTime + 0.5f;
			if ((Object)(object)val2 != (Object)null)
			{
				val2.groupCredits -= reviveCost;
				val2.SyncGroupCreditsServerRpc(val2.groupCredits, val2.numberOfItemsInDropship);
			}
			int bodyID = heldBody.bodyID;
			string text = (((Object)(object)heldBody.ragdoll != (Object)null) ? heldBody.ragdoll.playerScript.playerUsername : "Player");
			BunkbedNetworking.RevivePlayerServerRpc(bodyID);
			GrabbableObject currentlyHeldObjectServer = val.currentlyHeldObjectServer;
			if ((Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)((NetworkBehaviour)currentlyHeldObjectServer).NetworkObject != (Object)null && ((NetworkBehaviour)currentlyHeldObjectServer).NetworkObject.IsSpawned)
			{
				val.DespawnHeldObject();
			}
			if ((Object)(object)BunkbedRevivePlugin.Instance != (Object)null)
			{
				((MonoBehaviour)BunkbedRevivePlugin.Instance).StartCoroutine(ClearStuckCarryState(val));
			}
			BunkbedRevivePlugin.Log.LogMessage((object)(text + " has been revived"));
		}

		private static void OnStopInteract()
		{
			int reviveCost = GetReviveCost();
			interactTrigger.hoverTip = "Revive for " + ((reviveCost <= 0) ? "free" : (reviveCost + " credits")) + " : [E]";
		}

		private static IEnumerator ClearStuckCarryState(PlayerControllerB player)
		{
			yield return (object)new WaitForSeconds(0.4f);
			if ((Object)(object)player == (Object)null)
			{
				yield break;
			}
			GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
			if ((Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)((NetworkBehaviour)currentlyHeldObjectServer).NetworkObject != (Object)null && ((NetworkBehaviour)currentlyHeldObjectServer).NetworkObject.IsSpawned)
			{
				yield break;
			}
			if ((Object)(object)currentlyHeldObjectServer != (Object)null)
			{
				for (int i = 0; i < player.ItemSlots.Length; i++)
				{
					if ((Object)(object)player.ItemSlots[i] == (Object)(object)currentlyHeldObjectServer)
					{
						player.ItemSlots[i] = null;
					}
				}
				if ((Object)(object)player.ItemOnlySlot == (Object)(object)currentlyHeldObjectServer)
				{
					player.ItemOnlySlot = null;
				}
			}
			bool flag = ThrowingObjectField != null && (bool)ThrowingObjectField.GetValue(player);
			player.currentlyHeldObjectServer = null;
			player.twoHanded = false;
			player.twoHandedAnimation = false;
			player.isHoldingObject = false;
			player.isGrabbingObjectAnimation = false;
			player.activatingItem = false;
			player.carryWeight = 1f;
			ResetThrowingFlag(player);
			BunkbedRevivePlugin.Log.LogInfo((object)$"Cleared carry state for {player.playerUsername} (throwingObject was {flag})");
			if ((Object)(object)HUDManager.Instance != (Object)null)
			{
				((Behaviour)HUDManager.Instance.holdingTwoHandedItem).enabled = false;
				HUDManager.Instance.ClearControlTips();
			}
		}

		private static void ResetThrowingFlag(PlayerControllerB player)
		{
			if (ThrowingObjectField != null && (bool)ThrowingObjectField.GetValue(player))
			{
				ThrowingObjectField.SetValue(player, false);
			}
		}

		public static void RevivePlayer(int playerId)
		{
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null || playerId < 0 || playerId >= instance.allPlayerScripts.Length)
			{
				return;
			}
			PlayerControllerB val = instance.allPlayerScripts[playerId];
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			bool isPlayerDead = val.isPlayerDead;
			val.ResetPlayerBloodObjects(isPlayerDead);
			if (isPlayerDead)
			{
				val.isPlayerDead = false;
				val.isPlayerControlled = true;
				val.isInElevator = true;
				val.isInHangarShipRoom = true;
				val.isInsideFactory = false;
				val.health = 100;
				val.criticallyInjured = false;
				val.bleedingHeavily = false;
				val.setPositionOfDeadPlayer = false;
				val.deadBody = null;
				val.isClimbingLadder = false;
				val.clampLooking = false;
				val.inVehicleAnimation = false;
				val.inSpecialInteractAnimation = false;
				val.freeRotationInInteractAnimation = false;
				val.disableSyncInAnimation = false;
				val.inAnimationWithEnemy = null;
				val.holdingWalkieTalkie = false;
				val.speakingToWalkieTalkie = false;
				val.parentedToElevatorLastFrame = false;
				val.overrideGameOverSpectatePivot = null;
				val.enemyWaitingForBodyRagdoll = null;
				val.hasBeenCriticallyInjured = false;
				((Behaviour)val.nightVisionRadar).enabled = false;
				val.disableMoveInput = false;
				val.disableLookInput = false;
				val.disableInteract = false;
				val.ResetZAndXRotation();
				((Collider)val.thisController).enabled = true;
				instance.SetPlayerObjectExtrapolate(false);
				Vector3 position = instance.playerSpawnPositions[playerId].position;
				val.TeleportPlayer(position, false, 0f, false, true);
				if ((Object)(object)val.playerBodyAnimator != (Object)null)
				{
					val.playerBodyAnimator.SetBool("Limp", false);
				}
				if (instance.livingPlayers < instance.connectedPlayersAmount + 1)
				{
					instance.livingPlayers++;
				}
			}
			instance.allPlayersDead = false;
			((Renderer)val.thisPlayerModel).enabled = true;
			((Renderer)val.thisPlayerModelLOD1).enabled = true;
			((Renderer)val.thisPlayerModelLOD2).enabled = true;
			if ((Object)(object)val.currentlyHeldObjectServer == (Object)null)
			{
				val.twoHanded = false;
				val.twoHandedAnimation = false;
				val.isHoldingObject = false;
				val.isGrabbingObjectAnimation = false;
				val.activatingItem = false;
				val.carryWeight = 1f;
				if (((NetworkBehaviour)val).IsOwner)
				{
					ResetThrowingFlag(val);
				}
			}
			if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				val.health = 100;
				val.hasBegunSpectating = false;
				val.hinderedMultiplier = 1f;
				val.isMovementHindered = 0;
				val.sourcesCausingSinking = 0;
				val.criticallyInjured = false;
				val.bleedingHeavily = false;
				val.isSinking = false;
				val.isUnderwater = false;
				val.sinkingValue = 0f;
				val.statusEffectAudio.Stop();
				val.DisableJetpackControlsLocally();
				if ((Object)(object)HUDManager.Instance != (Object)null)
				{
					HUDManager.Instance.gasHelmetAnimator.SetBool("gasEmitting", false);
					HUDManager.Instance.RemoveSpectateUI();
					HUDManager.Instance.gameOverAnimator.SetTrigger("revive");
					HUDManager.Instance.HideHUD(false);
					HUDManager.Instance.UpdateHealthUI(100, false);
					((Behaviour)HUDManager.Instance.audioListenerLowPass).enabled = false;
				}
				val.spectatedPlayerScript = null;
				instance.SetSpectateCameraToGameOverMode(false, val);
				TimeOfDay.Instance.DisableAllWeather(false);
				instance.UpdatePlayerVoiceEffects();
				val.reverbPreset = instance.shipReverb;
				if ((Object)(object)SoundManager.Instance != (Object)null)
				{
					SoundManager.Instance.earsRingingTimer = 0f;
					SoundManager.Instance.playerVoicePitchTargets[playerId] = 1f;
					SoundManager.Instance.SetPlayerPitch(1f, playerId);
				}
			}
		}
	}
	public static class BunkbedNetworking
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__HandleReviveRequest;

			public static HandleNamedMessageDelegate <1>__HandleReviveBroadcast;
		}

		private const string ReviveServerMsg = "BunkbedRevive.ReviveServer";

		private const string ReviveClientMsg = "BunkbedRevive.ReviveClient";

		public static void Init()
		{
			//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_003e: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null)
			{
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				object obj = <>O.<0>__HandleReviveRequest;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = HandleReviveRequest;
					<>O.<0>__HandleReviveRequest = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("BunkbedRevive.ReviveServer", (HandleNamedMessageDelegate)obj);
				CustomMessagingManager customMessagingManager2 = singleton.CustomMessagingManager;
				object obj2 = <>O.<1>__HandleReviveBroadcast;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = HandleReviveBroadcast;
					<>O.<1>__HandleReviveBroadcast = val2;
					obj2 = (object)val2;
				}
				customMessagingManager2.RegisterNamedMessageHandler("BunkbedRevive.ReviveClient", (HandleNamedMessageDelegate)obj2);
				BunkbedRevivePlugin.Log.LogInfo((object)"BunkbedRevive networking initialized");
			}
		}

		public static void Cleanup()
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.CustomMessagingManager != null)
			{
				singleton.CustomMessagingManager.UnregisterNamedMessageHandler("BunkbedRevive.ReviveServer");
				singleton.CustomMessagingManager.UnregisterNamedMessageHandler("BunkbedRevive.ReviveClient");
			}
		}

		public unsafe static void RevivePlayerServerRpc(int playerId)
		{
			//IL_0037: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			if (singleton.IsServer)
			{
				BroadcastRevive(playerId);
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref playerId, default(ForPrimitives));
				singleton.CustomMessagingManager.SendNamedMessage("BunkbedRevive.ReviveServer", 0uL, val, (NetworkDelivery)2);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static void HandleReviveRequest(ulong clientId, FastBufferReader reader)
		{
			//IL_001e: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && singleton.IsServer)
			{
				int playerId = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref playerId, default(ForPrimitives));
				BroadcastRevive(playerId);
			}
		}

		private unsafe static void BroadcastRevive(int playerId)
		{
			//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_0055: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			BunkbedController.RevivePlayer(playerId);
			List<ulong> remoteClientIds = GetRemoteClientIds();
			if (remoteClientIds.Count == 0)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref playerId, default(ForPrimitives));
				singleton.CustomMessagingManager.SendNamedMessage("BunkbedRevive.ReviveClient", (IReadOnlyList<ulong>)remoteClientIds, val, (NetworkDelivery)2);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static List<ulong> GetRemoteClientIds()
		{
			List<ulong> list = new List<ulong>();
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.ConnectedClientsList == null)
			{
				return list;
			}
			foreach (NetworkClient connectedClients in singleton.ConnectedClientsList)
			{
				if (connectedClients.ClientId != singleton.LocalClientId)
				{
					list.Add(connectedClients.ClientId);
				}
			}
			return list;
		}

		private static void HandleReviveBroadcast(ulong clientId, FastBufferReader reader)
		{
			//IL_001e: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null) && !singleton.IsServer)
			{
				int playerId = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref playerId, default(ForPrimitives));
				BunkbedController.RevivePlayer(playerId);
			}
		}
	}
	[BepInPlugin("com.user.BunkbedRevive", "BunkbedRevive", "1.0.2")]
	public sealed class BunkbedRevivePlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.user.BunkbedRevive";

		public const string PluginName = "BunkbedRevive";

		public const string PluginVersion = "1.0.2";

		private readonly Harmony harmony = new Harmony("com.user.BunkbedRevive");

		public static BunkbedRevivePlugin Instance;

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Init();
			harmony.PatchAll();
			Log.LogInfo((object)"BunkbedRevive v1.0.2 loaded!");
		}
	}
}
namespace BunkbedRevive.Patches
{
	[HarmonyPatch(typeof(RagdollGrabbableObject))]
	public class RagdollGrabbableObjectPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(RagdollGrabbableObject __instance)
		{
			((GrabbableObject)__instance).itemProperties.weight = ModConfig.BodyWeight.Value;
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(StartOfRound __instance)
		{
			BunkbedNetworking.Init();
			int bunkBedId = __instance.unlockablesList.unlockables.FindIndex((UnlockableItem unlockable) => unlockable.unlockableName.IndexOf("bunkbeds", StringComparison.CurrentCultureIgnoreCase) >= 0);
			if (bunkBedId >= 0)
			{
				PlaceableShipObject val = ((IEnumerable<PlaceableShipObject>)Object.FindObjectsOfType<PlaceableShipObject>()).FirstOrDefault((Func<PlaceableShipObject, bool>)((PlaceableShipObject placeable) => placeable.unlockableID == bunkBedId));
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject.GetComponent<BunkbedController>() == (Object)null)
				{
					((Component)val).gameObject.AddComponent<BunkbedController>();
					BunkbedRevivePlugin.Log.LogInfo((object)"BunkbedController added to bunk beds");
				}
			}
		}

		[HarmonyPatch("openingDoorsSequence")]
		[HarmonyPrefix]
		private static void OpeningDoorsSequencePatch()
		{
			BunkbedController.Instance = null;
		}

		[HarmonyPatch("EndOfGame")]
		[HarmonyPrefix]
		private static void EndOfGamePatch()
		{
			BunkbedNetworking.Cleanup();
			BunkbedController.Instance = null;
		}
	}
}
namespace BunkbedRevive.Configuration
{
	public static class ModConfig
	{
		public static ConfigEntry<int> ReviveCost;

		public static ConfigEntry<float> BodyWeight;

		public static void Init()
		{
			ReviveCost = ((BaseUnityPlugin)BunkbedRevivePlugin.Instance).Config.Bind<int>("Revive", "Cost", 25, "Number of credits to revive a dead player at the bunk beds");
			BodyWeight = ((BaseUnityPlugin)BunkbedRevivePlugin.Instance).Config.Bind<float>("Revive", "Body Weight", 1.1f, "Weight of dead bodies when carried");
		}
	}
}