using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using InfernaleMod.Patches;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("InfernaleMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Multi purpose Mod for Lethal Company")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0")]
[assembly: AssemblyProduct("InfernaleMod")]
[assembly: AssemblyTitle("InfernaleMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace InfernaleMod
{
public class InfernaleModConfig
{
public static ConfigEntry<bool> ClockFormat;
public static ConfigEntry<bool> WeightUnit;
public static ConfigEntry<bool> ClockInShip;
public static ConfigEntry<bool> ShowHp;
public static ConfigEntry<int> ItemStorage;
public static ConfigEntry<bool> NoSellLimit;
public static ConfigEntry<bool> ShipLoot;
public static ConfigEntry<bool> SkipToMultiplayerMenu;
public static ConfigEntry<bool> TerminalWalkie;
public static ConfigEntry<bool> ClockVisibleInShip;
public static ConfigEntry<bool> InfiniteSprintAtCompanyBuilding;
public static ConfigEntry<bool> FadeOutChat;
public static ConfigEntry<bool> ReOpenLobby;
public static ConfigEntry<bool> QuickDrop;
public static ConfigEntry<bool> InvertHotbarScrollDirection;
public static ConfigEntry<bool> RestartLobby;
public static ConfigEntry<bool> ForceRestart;
public static void Init(ConfigFile config)
{
ItemStorage = config.Bind<int>("General", "ItemStorage", 45, "Sets the maximum amount of Items you can save in your ship.");
NoSellLimit = config.Bind<bool>("General", "NoSellLimit", false, "If set to true the item limit on the deposit desk at the company building will be removed.");
ShipLoot = config.Bind<bool>("General", "ShipLoot", false, "Set to true to enable the display to show all your scrap value on ship.");
SkipToMultiplayerMenu = config.Bind<bool>("Miscellaneous", "ForceOnlineMode", false, "If set to true the game will skip the Online/LAN screen on startup forcing into Online mode.");
ReOpenLobby = config.Bind<bool>("Miscellaneous", "ReOpenLobby", false, "If set to true the lobby will be joinable between the rounds while the ship is in the orbit. Also the invite buttom will work if set to true.");
RestartLobby = config.Bind<bool>("Miscellaneous", "RestartLobby", false, "If set to true the lobby can be restarted by typing /restart into the chat (only the Host).");
ForceRestart = config.Bind<bool>("Miscellaneous", "ForceRestart", false, "If set to true the confirmation step when restarting will be skipped.");
ClockFormat = config.Bind<bool>("HUD", "ClockFormat", false, "If set to true changes the ingame clock to appear in the 24h format instead of AM/PM.");
WeightUnit = config.Bind<bool>("HUD", "WeightUnit", false, "If set to true changes the weight unit to appear and calculated in kg instead of lb.");
FadeOutChat = config.Bind<bool>("HUD", "FadeOutChat", false, "If set to true the chat window will be hidden after a short period of time and will only be visible if there is a new message or you open the chat.");
ShowHp = config.Bind<bool>("HUD", "ShowHp", false, "If set to true in the top left will be shown your current HP as a number.");
ClockVisibleInShip = config.Bind<bool>("HUD", "ClockVisibleInShip", false, "If set to true changes the ingame clock to also appear inside the ship while on a mission.");
TerminalWalkie = config.Bind<bool>("QOL", "TerminalWalkie", false, "If set to true you will be able to use the walkie-talkie on the terminal without pressing any key. The walkie-talkie needs to be activated before.");
InfiniteSprintAtCompanyBuilding = config.Bind<bool>("QOL", "InfiniteSprintAtCompanyBuilding", false, "If set to true there will be no stamina drain while landed at the company building.");
QuickDrop = config.Bind<bool>("QOL", "QuickDrop", false, "If set to true you will be able to fast drop your items by spamming the drop button (G)");
InvertHotbarScrollDirection = config.Bind<bool>("QOL", "InvertHotbarScrollDirection", false, "If set to true the scroll direction of the hotbar will be fixed.");
}
}
public class InfernaleModConfigLog
{
public static void LogConfigSettings()
{
int value = InfernaleModConfig.ItemStorage.Value;
bool value2 = InfernaleModConfig.SkipToMultiplayerMenu.Value;
bool value3 = InfernaleModConfig.ClockFormat.Value;
bool value4 = InfernaleModConfig.WeightUnit.Value;
bool value5 = InfernaleModConfig.ShipLoot.Value;
bool value6 = InfernaleModConfig.NoSellLimit.Value;
bool value7 = InfernaleModConfig.TerminalWalkie.Value;
bool value8 = InfernaleModConfig.InfiniteSprintAtCompanyBuilding.Value;
bool value9 = InfernaleModConfig.FadeOutChat.Value;
bool value10 = InfernaleModConfig.ReOpenLobby.Value;
bool value11 = InfernaleModConfig.ShowHp.Value;
bool value12 = InfernaleModConfig.QuickDrop.Value;
bool value13 = InfernaleModConfig.InvertHotbarScrollDirection.Value;
bool value14 = InfernaleModConfig.RestartLobby.Value;
bool value15 = InfernaleModConfig.ForceRestart.Value;
if (value2)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The game will be forced into Online-mode.");
}
if (value10)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: Your lobbies will be joinable between each mission.");
}
if (value3)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The ingame clock will now be shown in the 24h format.");
}
if (value > 45 || value < 45)
{
InfernaleMod.Log.LogInfo((object)("Patch applied: The custom item storage has been set to " + value + "."));
}
if (value4)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The weight unit will now be shown and calculated as kg.");
}
if (value5)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The ship loot counter has been enabled.");
}
if (value7)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The walkie-talkie will now be used, if activated, when entering the terminal.");
}
if (value6)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The item limit on the deposit desk at the company building has been removed.");
}
if (value8)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: Infite stamina at the company building has been enabled.");
}
if (value9)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The chat window will be hidden until there are new messages.");
}
if (value11)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: Your current HP will be shown as a number.");
}
if (value12)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: You are now able to quick drop items.");
}
if (value13)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The scroll direction of the hotbar will now be inverted.");
}
if (value14)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The lobby can be restarted by chat commands.");
}
if (value14 && value15)
{
InfernaleMod.Log.LogInfo((object)"Patch applied: The lobby will be force restarted when typing /restart.");
}
}
}
[BepInPlugin("InfernaleMod", "InfernaleMod", "0.4.0")]
public class InfernaleMod : BaseUnityPlugin
{
private readonly Harmony harmony = new Harmony("InfernaleMod");
private static InfernaleMod Instance;
internal static ManualLogSource Log;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
Log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin InfernaleMod 0.4.0 is loaded!");
InfernaleModConfig.Init(((BaseUnityPlugin)this).Config);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Config file has been created or updated!");
InfernaleModConfigLog.LogConfigSettings();
harmony.PatchAll(typeof(InfernaleMod));
harmony.PatchAll(typeof(ForceOnlineMode_Patch));
harmony.PatchAll(typeof(ReOpenLobby));
harmony.PatchAll(typeof(RestartLobby_Patch));
harmony.PatchAll(typeof(ItemStorage_Patch));
harmony.PatchAll(typeof(ShipLoot_Patch));
harmony.PatchAll(typeof(NoSellLimit_Patch));
harmony.PatchAll(typeof(ClockFormat_Patch));
harmony.PatchAll(typeof(WeightUnit_Patch));
harmony.PatchAll(typeof(ClockVisibleInShip_Patch));
harmony.PatchAll(typeof(FadeOutChat_Patch));
harmony.PatchAll(typeof(ShopHp_Patch));
harmony.PatchAll(typeof(TerminalWalkie_Patch));
harmony.PatchAll(typeof(InfiniteSprintAtCompanyBuilding_Patch));
harmony.PatchAll(typeof(QuickDrop_Patch));
harmony.PatchAll(typeof(InvertHotbarScroll_Patch));
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "InfernaleMod";
public const string PLUGIN_NAME = "InfernaleMod";
public const string PLUGIN_VERSION = "0.4.0";
}
}
namespace InfernaleMod.Patches
{
[HarmonyPatch(typeof(HUDManager))]
public class ClockFormat_Patch
{
[HarmonyPatch("SetClock")]
[HarmonyPrefix]
public static bool ClockFormat(HUDManager __instance, ref string __result, float timeNormalized, float numberOfHours, bool createNewLine = true)
{
bool value = InfernaleModConfig.ClockFormat.Value;
int num = (int)(timeNormalized * (60f * numberOfHours)) + 360;
int num2 = (int)Mathf.Floor((float)(num / 60));
num2 %= 24;
int num3 = num % 60;
string text;
if (value)
{
text = $"{num2:00}:{num3:00}";
}
else if (num2 >= 24)
{
text = "12:00\nAM";
}
else
{
string text2 = (createNewLine ? "\n" : " ");
string text3 = ((num2 < 12) ? "AM" : "PM");
if (num2 > 12)
{
num2 %= 12;
}
int num4 = num % 60;
text = $"{num2:00}:{num4:00}".TrimStart('0') + text2 + text3;
}
((TMP_Text)__instance.clockNumber).text = text;
__result = text;
return false;
}
}
[HarmonyPatch(typeof(HUDManager))]
public class ClockVisibleInShip_Patch
{
[HarmonyPatch("SetClockVisible")]
[HarmonyPostfix]
public static void ClockVisibleInShip(HUDManager __instance)
{
if (InfernaleModConfig.ClockVisibleInShip.Value && GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom && !GameNetworkManager.Instance.localPlayerController.inTerminalMenu)
{
__instance.Clock.targetAlpha = 1f;
}
}
}
[HarmonyPatch(typeof(HUDManager))]
public class FadeOutChat_Patch
{
[HarmonyPatch("OpenMenu_performed")]
[HarmonyPatch("SubmitChat_performed")]
[HarmonyPatch("AddChatMessage")]
[HarmonyPostfix]
public static void HidingChat(ref HUDManager __instance)
{
if (InfernaleModConfig.FadeOutChat.Value)
{
__instance.PingHUDElement(__instance.Chat, 5f, 1f, 0f);
}
}
}
[HarmonyPatch]
public class ForceOnlineMode_Patch
{
private static bool skippedPreInitScene;
private static bool skippedInitScene;
[HarmonyPatch(typeof(PreInitSceneScript), "Awake")]
[HarmonyPrefix]
public static bool InitializeGameManager()
{
if (InfernaleModConfig.SkipToMultiplayerMenu.Value && !skippedPreInitScene)
{
skippedPreInitScene = true;
InfernaleMod.Log.LogInfo((object)"Loading the GameManager while inside InitScene...");
SceneManager.LoadScene("InitScene");
return false;
}
return true;
}
[HarmonyPatch(typeof(InitializeGame), "Start")]
[HarmonyPrefix]
public static bool LoadMultiplayerMenuScene()
{
if (InfernaleModConfig.SkipToMultiplayerMenu.Value && !skippedInitScene)
{
skippedInitScene = true;
InfernaleMod.Log.LogInfo((object)"Skipping to MainMenu...");
SceneManager.LoadScene("MainMenu");
return false;
}
return true;
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
public class InfiniteSprintAtCompanyBuilding_Patch
{
[HarmonyPostfix]
[HarmonyPatch("Update")]
private static void InfiniteStaminaAtCompanyPatch(PlayerControllerB __instance, ref float ___sprintMeter)
{
if (InfernaleModConfig.InfiniteSprintAtCompanyBuilding.Value)
{
SelectableLevel val = StartOfRound.Instance?.currentLevel;
if ((Object)(object)val != (Object)null && val.levelID == 3)
{
___sprintMeter = 1f;
}
}
}
}
public static class InvertHotbarScroll_Patch
{
[HarmonyPatch(typeof(PlayerControllerB), "ScrollMouse_performed")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> InvertHotbarScrollDirection(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
if (InfernaleModConfig.InvertHotbarScrollDirection.Value)
{
for (int i = 1; i < list.Count; i++)
{
if (list[i].opcode == OpCodes.Ble_Un && list[i - 1].opcode == OpCodes.Ldc_R4 && (float)list[i - 1].operand == 0f)
{
list[i].opcode = OpCodes.Bge_Un;
break;
}
}
}
return list.AsEnumerable();
}
}
[HarmonyPatch(typeof(StartOfRound))]
public class ItemStorage_Patch
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
public static void ShipItemStorage(ref int ___maxShipItemCapacity)
{
int value = InfernaleModConfig.ItemStorage.Value;
if (value > 45 || value < 45)
{
___maxShipItemCapacity = value;
}
else
{
___maxShipItemCapacity = 45;
}
}
}
[HarmonyPatch(typeof(DepositItemsDesk))]
public class NoSellLimit_Patch
{
[HarmonyPatch("PlaceItemOnCounter")]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
if (InfernaleModConfig.NoSellLimit.Value)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(DepositItemsDesk), "deskObjectsContainer");
bool flag = false;
int num = -1;
int num2 = -1;
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 0; i < list.Count; i++)
{
CodeInstruction val = list[i];
if (!flag && val.opcode == OpCodes.Ldfld && (FieldInfo)val.operand == fieldInfo)
{
flag = true;
num = i - 1;
}
else if (flag && val.opcode == OpCodes.Bge)
{
num2 = i;
break;
}
}
if (num > -1 && num2 > -1)
{
list[num].opcode = OpCodes.Nop;
list.RemoveRange(num, num2 - num + 1);
}
return list.AsEnumerable();
}
return instructions;
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class QuickDrop_Patch
{
[HarmonyPatch("Discard_performed")]
[HarmonyPrefix]
private static void QuickDrop(PlayerControllerB __instance, ref bool ___isHoldingObject, ref GrabbableObject[] ___ItemSlots)
{
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
if (!InfernaleModConfig.QuickDrop.Value || ___isHoldingObject)
{
return;
}
MethodInfo method = typeof(PlayerControllerB).GetMethod("NextItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo method2 = typeof(PlayerControllerB).GetMethod("SwitchToItemSlot", BindingFlags.Instance | BindingFlags.NonPublic);
if (!(method != null) || !(method2 != null))
{
return;
}
int currentItemSlot = __instance.currentItemSlot;
object[] parameters = new object[1] { true };
for (int num = (int)method.Invoke(__instance, parameters); num != currentItemSlot; num = (num + 1) % ___ItemSlots.Length)
{
if ((Object)___ItemSlots[num] != (Object)null)
{
method2.Invoke(__instance, new object[2] { num, null });
break;
}
}
}
}
[HarmonyPatch]
internal class ReOpenLobby
{
private static QuickMenuManager _quickMenuManager;
[HarmonyPostfix]
[HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientConnectedCallback")]
private static void LogConnect()
{
InfernaleMod.Log.LogDebug((object)"A Player has connected to the lobby.");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameNetworkManager), "Singleton_OnClientDisconnectCallback")]
private static void LogDisconnect()
{
InfernaleMod.Log.LogDebug((object)"A Player has disconnected from the lobby.");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameNetworkManager), "ConnectionApproval")]
private static void FixConnectionApproval(GameNetworkManager __instance, ConnectionApprovalResponse response)
{
if (!response.Approved && !(response.Reason != "The Game has already started!") && __instance.gameHasStarted && StartOfRound.Instance.inShipPhase)
{
InfernaleMod.Log.LogDebug((object)"Approving incoming late connection.");
response.Reason = "";
response.Approved = true;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(QuickMenuManager), "InviteFriendsButton")]
private static void FixFriendInviteButton()
{
if (GameNetworkManager.Instance.gameHasStarted && StartOfRound.Instance.inShipPhase)
{
GameNetworkManager.Instance.InviteFriendsUI();
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameNetworkManager), "LeaveLobbyAtGameStart")]
private static bool PreventSteamLobbyLeaving(GameNetworkManager __instance)
{
InfernaleMod.Log.LogDebug((object)"Preventing the closing of the Steam lobby.");
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(StartOfRound), "StartGame")]
private static void CloseSteamLobby(StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsServer && __instance.inShipPhase)
{
InfernaleMod.Log.LogDebug((object)"Setting lobby to not joinable.");
GameNetworkManager.Instance.SetLobbyJoinable(false);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
private static IEnumerator ReopenSteamLobby(IEnumerator coroutine, StartOfRound __instance)
{
while (coroutine.MoveNext())
{
yield return coroutine.Current;
}
if (!((NetworkBehaviour)__instance).IsServer)
{
yield break;
}
yield return (object)new WaitForSeconds(0.5f);
yield return (object)new WaitUntil((Func<bool>)(() => !__instance.firingPlayersCutsceneRunning));
InfernaleMod.Log.LogDebug((object)"Reopening lobby, setting it to joinable.");
GameNetworkManager manager = GameNetworkManager.Instance;
if (manager.currentLobby.HasValue)
{
manager.SetLobbyJoinable(true);
if ((Object)(object)_quickMenuManager == (Object)null)
{
_quickMenuManager = Object.FindObjectOfType<QuickMenuManager>();
}
_quickMenuManager.inviteFriendsTextAlpha.alpha = 1f;
}
}
}
[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
public class RestartLobby_Patch
{
private static bool Prefix(HUDManager __instance, ref CallbackContext context)
{
if (!((CallbackContext)(ref context)).performed || string.IsNullOrEmpty(__instance.chatTextField.text))
{
return true;
}
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
if ((Object)(object)localPlayerController == (Object)null)
{
return true;
}
StartOfRound playersManager = localPlayerController.playersManager;
if ((Object)(object)playersManager == (Object)null)
{
return true;
}
string text = __instance.chatTextField.text;
if (ChatCommands.verify)
{
string text2 = text.ToUpper();
if (text2 == "CONFIRM" || text2 == "C")
{
ResetTextbox(__instance, localPlayerController);
if (!localPlayerController.isInHangarShipRoom || !playersManager.inShipPhase || playersManager.travellingToNewLevel)
{
ChatCommands.SendChatMessage("Cannot restart, ship must be in orbit.");
return false;
}
ChatCommands.AcceptRestart(playersManager);
return false;
}
if (text2 == "DENY" || text2 == "D")
{
ResetTextbox(__instance, localPlayerController);
ChatCommands.DeclineRestart();
return false;
}
return true;
}
if (InfernaleModConfig.RestartLobby.Value && text == "/restart")
{
ResetTextbox(__instance, localPlayerController);
if (!GameNetworkManager.Instance.isHostingGame)
{
ChatCommands.SendChatMessage("Only the host can restart.");
return false;
}
if (!localPlayerController.isInHangarShipRoom || !playersManager.inShipPhase || playersManager.travellingToNewLevel)
{
ChatCommands.SendChatMessage("Cannot restart, ship must be in orbit.");
return false;
}
if (ChatCommands.forceRestart)
{
ChatCommands.AcceptRestart(playersManager);
}
else
{
ChatCommands.ConfirmRestart();
}
return false;
}
return true;
}
private static void ResetTextbox(HUDManager manager, PlayerControllerB local)
{
local.isTypingChat = false;
manager.chatTextField.text = "";
EventSystem.current.SetSelectedGameObject((GameObject)null);
manager.PingHUDElement(manager.Chat, 2f, 1f, 0.2f);
((Behaviour)manager.typingIndicator).enabled = false;
}
}
public static class ChatCommands
{
public static bool verify;
public static bool forceRestart;
private static MethodInfo chat;
static ChatCommands()
{
verify = false;
forceRestart = false;
forceRestart = InfernaleModConfig.ForceRestart.Value;
chat = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
}
public static void SendChatMessage(string message)
{
chat?.Invoke(HUDManager.Instance, new object[2] { message, "" });
HUDManager.Instance.lastChatMessage = "";
}
public static void ConfirmRestart()
{
verify = true;
SendChatMessage("Are you sure? Type CONFIRM or DENY.");
}
public static void AcceptRestart(StartOfRound manager)
{
SendChatMessage("Restart confirmed.");
verify = false;
int[] array = new int[4]
{
manager.gameStats.daysSpent,
manager.gameStats.scrapValueCollected,
manager.gameStats.deaths,
manager.gameStats.allStepsTaken
};
manager.FirePlayersAfterDeadlineClientRpc(array, false);
}
public static void DeclineRestart()
{
SendChatMessage("Restart aborted.");
verify = false;
}
}
[HarmonyPatch(typeof(HUDManager))]
public class ShipLoot_Patch
{
private static GameObject _totalCounter;
private static TextMeshProUGUI _textMesh;
private static float _displayTimeLeft;
private const float DisplayTime = 3f;
[HarmonyPatch("PingScan_performed")]
[HarmonyPrefix]
public static void ShipLoot(HUDManager __instance)
{
if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || !InfernaleModConfig.ShipLoot.Value)
{
return;
}
bool flag = (bool)AccessTools.Method(typeof(HUDManager), "CanPlayerScan", (Type[])null, (Type[])null).Invoke(__instance, null);
float num = (float)AccessTools.Field(typeof(HUDManager), "playerPingingScan").GetValue(__instance);
if (!flag || num > -0.5f || (!StartOfRound.Instance.inShipPhase && !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom))
{
return;
}
if ((Object)(object)_totalCounter == (Object)null || (Object)(object)_textMesh == (Object)null)
{
CopyValueCounter();
if ((Object)(object)_totalCounter == (Object)null || (Object)(object)_textMesh == (Object)null)
{
InfernaleMod.Log.LogError((object)"Failed to initialize _totalCounter or _textMesh.");
return;
}
}
float num2 = CalculateLootValue();
((TMP_Text)_textMesh).text = $"SHIP: ${num2:F0}";
_displayTimeLeft = 3f;
if (!_totalCounter.activeSelf)
{
((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(ShipLootCoroutine());
}
}
private static IEnumerator ShipLootCoroutine()
{
if ((Object)(object)_totalCounter == (Object)null)
{
InfernaleMod.Log.LogError((object)"_totalCounter is null or destroyed in ShipLootCoroutine.");
yield break;
}
_totalCounter.SetActive(true);
while (_displayTimeLeft > 0f)
{
if ((Object)(object)_totalCounter == (Object)null)
{
InfernaleMod.Log.LogError((object)"_totalCounter is null or destroyed in ShipLootCoroutine.");
yield break;
}
float time = _displayTimeLeft;
_displayTimeLeft = 0f;
yield return (object)new WaitForSeconds(time);
}
if ((Object)(object)_totalCounter != (Object)null)
{
_totalCounter.SetActive(false);
}
}
private static float CalculateLootValue()
{
GameObject val = GameObject.Find("/Environment/HangarShip");
List<GrabbableObject> list = (from obj in val.GetComponentsInChildren<GrabbableObject>()
where ((Object)obj).name != "ClipboardManual" && ((Object)obj).name != "StickyNoteItem" && ((Object)obj).name != "Key(Clone)" && ((Object)obj).name != "Key"
select obj).ToList();
InfernaleMod.Log.LogDebug((object)"Calculating total ship scrap value.");
CollectionExtensions.Do<GrabbableObject>((IEnumerable<GrabbableObject>)list, (Action<GrabbableObject>)delegate(GrabbableObject scrap)
{
InfernaleMod.Log.LogDebug((object)$"{((Object)scrap).name} - ${scrap.scrapValue}");
});
return list.Sum((GrabbableObject scrap) => scrap.scrapValue);
}
private static void CopyValueCounter()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: 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)
GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter");
if (!Object.op_Implicit((Object)(object)val))
{
InfernaleMod.Log.LogError((object)"Failed to find ValueCounter object to copy!");
return;
}
_totalCounter = Object.Instantiate<GameObject>(val, val.transform.parent, false);
if ((Object)(object)_totalCounter == (Object)null)
{
InfernaleMod.Log.LogError((object)"Failed to instantiate _totalCounter.");
return;
}
_totalCounter.transform.Translate(0f, 1f, 0f);
Vector3 localPosition = _totalCounter.transform.localPosition;
_totalCounter.transform.localPosition = new Vector3(localPosition.x + 50f, -50f, localPosition.z);
_textMesh = _totalCounter.GetComponentInChildren<TextMeshProUGUI>();
if ((Object)(object)_textMesh == (Object)null)
{
InfernaleMod.Log.LogError((object)"Failed to get TextMeshProUGUI from _totalCounter.");
}
}
}
[HarmonyPatch(typeof(HUDManager))]
public class ShopHp_Patch
{
private static TextMeshProUGUI healthText = null;
private static readonly Color _healthyColor = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue));
private static readonly Color _criticalHealthColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)0, (byte)0, byte.MaxValue));
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void PostfixAwake(HUDManager __instance)
{
if (InfernaleModConfig.ShowHp.Value)
{
PlayerControllerB val = Object.FindObjectOfType<PlayerControllerB>();
if ((Object)(object)val != (Object)null)
{
int health = val.health;
HUDManager.Instance.UpdateHealthUI(health, true);
InfernaleMod.Log.LogInfo((object)"UpdatedHealth");
}
else
{
InfernaleMod.Log.LogError((object)"PlayerControllerB not found.");
}
}
}
[HarmonyPatch(typeof(HUDManager), "UpdateHealthUI")]
[HarmonyPostfix]
private static void PostfixUpdateHealthUI(HUDManager __instance, int health)
{
if ((Object)(object)healthText == (Object)null)
{
CreateHealthText(__instance, health);
}
UpdateHealthText(health);
if (health <= 0)
{
Object.Destroy((Object)(object)((Component)healthText).gameObject);
healthText = null;
}
}
private static void UpdateHealthText(int health)
{
((TMP_Text)healthText).text = health.ToString();
UpdateHealthTextColor(health);
}
private static void UpdateHealthTextColor(int health)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
double t = (double)health / 100.0;
((Graphic)healthText).color = ColorInterpolation(_criticalHealthColor, _healthyColor, t);
}
private static void CreateHealthText(HUDManager hudManager, int health)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_0088: 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_00b4: 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)
GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/TopLeftCorner");
if ((Object)(object)val == (Object)null)
{
InfernaleMod.Log.LogError((object)"'TopLeftCorner' not found.");
return;
}
GameObject val2 = new GameObject("PlayerHealthText");
val2.transform.SetParent(val.transform, false);
healthText = val2.AddComponent<TextMeshProUGUI>();
((TMP_Text)healthText).fontSize = 24f;
((TMP_Text)healthText).alignment = (TextAlignmentOptions)514;
RectTransform component = val2.GetComponent<RectTransform>();
component.anchorMin = new Vector2(0f, 1f);
component.anchorMax = new Vector2(0f, 1f);
component.pivot = new Vector2(0f, 1f);
component.anchoredPosition = new Vector2(-28f, -108f);
UpdateHealthText(health);
}
private static Color ParseColor(string rgb)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
string[] array = rgb.Split(new string[1] { ", " }, StringSplitOptions.RemoveEmptyEntries);
if (array.Length != 3)
{
return Color.white;
}
if (float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3))
{
return new Color(result / 255f, result2 / 255f, result3 / 255f);
}
return Color.white;
}
private static Color ColorInterpolation(Color startColor, Color endColor, double t)
{
//IL_0001: 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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Lerp(startColor.r, endColor.r, (float)t);
float num2 = Mathf.Lerp(startColor.g, endColor.g, (float)t);
float num3 = Mathf.Lerp(startColor.b, endColor.b, (float)t);
float num4 = Mathf.Lerp(startColor.a, endColor.a, (float)t);
return new Color(num, num2, num3, num4);
}
}
[HarmonyPatch(typeof(Terminal))]
public class TerminalWalkie_Patch
{
public static void SetWalkieMode(bool enabled)
{
if (!InfernaleModConfig.TerminalWalkie.Value)
{
return;
}
InfernaleMod.Log.LogInfo((object)"Terminal opened! Trying to find walkie talkie...");
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
InfernaleMod.Log.LogInfo((object)$"There are {localPlayerController.ItemSlots.Length} item slots to check.");
GrabbableObject val = null;
for (int i = 0; i < localPlayerController.ItemSlots.Length; i++)
{
if (localPlayerController.ItemSlots[i] is WalkieTalkie && (!enabled || localPlayerController.ItemSlots[i].isBeingUsed))
{
val = localPlayerController.ItemSlots[i];
break;
}
}
if ((Object)(object)val == (Object)null)
{
InfernaleMod.Log.LogInfo((object)"No active walkie-talkie found in the player inventory!");
return;
}
InfernaleMod.Log.LogInfo((object)"Found an active walkie-talkie! Activating transmission...");
val.UseItemOnClient(enabled);
}
[HarmonyPatch("BeginUsingTerminal")]
[HarmonyPostfix]
public static void OpenTerminal()
{
SetWalkieMode(enabled: true);
}
[HarmonyPatch("QuitTerminal")]
[HarmonyPostfix]
public static void CloseTerminal()
{
SetWalkieMode(enabled: false);
}
}
[HarmonyPatch(typeof(HUDManager))]
public class WeightUnit_Patch
{
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void WeightUnit(HUDManager __instance)
{
if ((Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
{
if (InfernaleModConfig.WeightUnit.Value)
{
float num = Mathf.RoundToInt(Mathf.Clamp(GameNetworkManager.Instance.localPlayerController.carryWeight - 1f, 0f, 100f) * 105f);
((TMP_Text)__instance.weightCounter).text = string.Format("{0} kg", Mathf.RoundToInt(num * 0.4536f), num);
}
else
{
float num2 = Mathf.RoundToInt(Mathf.Clamp(GameNetworkManager.Instance.localPlayerController.carryWeight - 1f, 0f, 100f) * 105f);
((TMP_Text)__instance.weightCounter).text = $"{num2} lb";
}
}
}
}
}