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 LethalProgression PatchFix keepProgress v1.7.4
LethalProgression.dll
Decompiled 2 years agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; 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 GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using LethalProgression.Config; using LethalProgression.GUI; using LethalProgression.Network; using LethalProgression.Patches; using LethalProgression.Properties; using LethalProgression.Saving; using LethalProgression.Skills; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Steamworks; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; 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: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("LethalProgression")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Leveling and skillpoints through a managed GUI! Patched and bugfixed until official copy updated.")] [assembly: AssemblyFileVersion("1.7.5.0")] [assembly: AssemblyInformationalVersion("1.7.5-alpha.0.2")] [assembly: AssemblyProduct("LethalProgression")] [assembly: AssemblyTitle("LethalProgression")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 LethalProgression { [HarmonyPatch] internal class LP_NetworkManager { public static LC_XP xpInstance; public static GameObject xpNetworkObject; [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Start")] public static void Init() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (!((Object)(object)xpNetworkObject != (Object)null)) { xpNetworkObject = (GameObject)LethalPlugin.skillBundle.LoadAsset("LP_XPHandler"); xpNetworkObject.AddComponent<LC_XP>(); NetworkManager.Singleton.AddNetworkPrefab(xpNetworkObject); } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Awake")] private static void SpawnNetworkHandler() { //IL_0024: 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) if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { GameObject val = Object.Instantiate<GameObject>(xpNetworkObject, Vector3.zero, Quaternion.identity); val.GetComponent<NetworkObject>().Spawn(false); xpInstance = val.GetComponent<LC_XP>(); LethalPlugin.Log.LogInfo((object)"XPHandler Initialized."); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Stoneman.LethalProgression", "Lethal Progression", "1.7.1")] internal class LethalPlugin : BaseUnityPlugin { private const string modGUID = "Stoneman.LethalProgression"; private const string modName = "Lethal Progression"; private const string modVersion = "1.7.1"; private const string modAuthor = "Stoneman"; public static AssetBundle skillBundle; internal static ManualLogSource Log; internal static bool ReservedSlots; internal static bool MikesTweaks; public static LethalPlugin Instance { get; private set; } private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown Instance = this; Harmony val = new Harmony("Stoneman.LethalProgression"); val.PatchAll(); skillBundle = AssetBundle.LoadFromMemory(Resources.skillmenu); Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Lethal Progression loaded."); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { if (pluginInfo.Value.Metadata.GUID.IndexOf("ReservedItem") >= 0) { ReservedSlots = true; } if (pluginInfo.Value.Metadata.GUID.IndexOf("mikestweaks") < 0) { continue; } ConfigEntryBase[] configEntries = pluginInfo.Value.Instance.Config.GetConfigEntries(); MikesTweaks = true; ConfigEntryBase[] array = configEntries; foreach (ConfigEntryBase val2 in array) { if (val2.Definition.Key == "ExtraItemSlots" && int.Parse(val2.GetSerializedValue()) > 0) { ReservedSlots = true; } } } SkillConfig.InitConfig(); } public void BindConfig<T>(string section, string key, T defaultValue, string description = "") { ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description); } public IDictionary<string, string> GetAllConfigEntries() { return ((BaseUnityPlugin)this).Config.GetConfigEntries().ToDictionary((ConfigEntryBase entry) => entry.Definition.Key, (ConfigEntryBase entry) => entry.GetSerializedValue()); } } internal class LC_XP : NetworkBehaviour { public LethalNetworkVariable<int> teamLevel = new LethalNetworkVariable<int>("teamLevel") { Value = 0 }; public LethalNetworkVariable<int> teamXP = new LethalNetworkVariable<int>("teamXP") { Value = 0 }; public LethalNetworkVariable<int> teamTotalValue = new LethalNetworkVariable<int>("teamTotalValue") { Value = 0 }; public LethalNetworkVariable<int> teamXPRequired = new LethalNetworkVariable<int>("teamXPRequired") { Value = 0 }; public LethalNetworkVariable<int> teamLootLevel = new LethalNetworkVariable<int>("teamLootLevel") { Value = 0 }; public LethalClientEvent playerConnectClientEvent = new LethalClientEvent("playerConnectEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent playerConnectServerEvent = new LethalServerEvent("playerConnectEvent", (Action<ulong>)null); public LethalClientEvent evaluateXPRequirementClientEvent = new LethalClientEvent("evaluateXPRequirementEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent evaluateXPRequirementServerEvent = new LethalServerEvent("evaluateXPRequirementEvent", (Action<ulong>)null); public LethalClientEvent calculateAllPlayersHandSlotsClientEvent = new LethalClientEvent("calculateAllPlayersHandSlotsEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent calculateAllPlayersHandSlotsServerEvent = new LethalServerEvent("calculateAllPlayersHandSlotsEvent", (Action<ulong>)null); public LethalServerMessage<string> sendConfigServerMessage = new LethalServerMessage<string>("sendConfigMessage", (Action<string, ulong>)null); public LethalClientMessage<string> sendConfigClientMessage = new LethalClientMessage<string>("sendConfigMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<ulong> requestProfileDataServerMessage = new LethalServerMessage<ulong>("requestProfileDataMessage", (Action<ulong, ulong>)null); public LethalClientMessage<ulong> requestProfileDataClientMessage = new LethalClientMessage<ulong>("requestProfileDataMessage", (Action<ulong>)null, (Action<ulong, ulong>)null); public LethalServerMessage<string> sendProfileDataServerMessage = new LethalServerMessage<string>("sendProfileDataMessage", (Action<string, ulong>)null); public LethalClientMessage<string> receiveProfileDataClientMessage = new LethalClientMessage<string>("sendProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<string> saveProfileDataServerMessage = new LethalServerMessage<string>("saveProfileDataMessage", (Action<string, ulong>)null); public LethalClientMessage<string> saveProfileDataClientMessage = new LethalClientMessage<string>("saveProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<int> updateTeamLootLevelServerMessage = new LethalServerMessage<int>("updateTeamLootLevelMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateTeamLootLevelClientMessage = new LethalClientMessage<int>("updateTeamLootLevelMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updateTeamXPServerMessage = new LethalServerMessage<int>("updateTeamXPMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateTeamXPClientMessage = new LethalClientMessage<int>("updateTeamXPMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updatePlayerSkillpointsServerMessage = new LethalServerMessage<int>("updatePlayerSkillPointsMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updatePlayerSkillpointsClientMessage = new LethalClientMessage<int>("updatePlayerSkillPointsMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updateSPHandSlotsServerMessage = new LethalServerMessage<int>("updateSPHandSlotsMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateSPHandSlotsClientMessage = new LethalClientMessage<int>("updateSPHandSlotsMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<PlayerHandSlotData> updatePlayerHandSlotsServerMessage = new LethalServerMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData, ulong>)null); public LethalClientMessage<PlayerHandSlotData> updatePlayerHandSlotsClientMessage = new LethalClientMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData>)null, (Action<PlayerHandSlotData, ulong>)null); public LethalServerMessage<PlayerJumpHeightData> updatePlayerJumpForceServerMessage = new LethalServerMessage<PlayerJumpHeightData>("updatePlayerJumpForceMessage", (Action<PlayerJumpHeightData, ulong>)null); public LethalClientMessage<PlayerJumpHeightData> updatePlayerJumpForceClientMessage = new LethalClientMessage<PlayerJumpHeightData>("updatePlayerJumpForceMessage", (Action<PlayerJumpHeightData>)null, (Action<PlayerJumpHeightData, ulong>)null); public int skillPoints; public SkillList skillList; public SkillsGUI guiObj; public bool Initialized = false; public bool loadedSave = false; public void Start() { LethalPlugin.Log.LogInfo((object)"XP Network Behavior Made!"); teamLevel.OnValueChanged += OnTeamLevelChange; teamXP.OnValueChanged += OnTeamXPChange; playerConnectServerEvent.OnReceived += PlayerConnect_C2SEvent; evaluateXPRequirementServerEvent.OnReceived += EvaluateXPRequirements_C2SEvent; calculateAllPlayersHandSlotsServerEvent.OnReceived += RefreshAllPlayerHandSlots_C2SEvent; sendConfigClientMessage.OnReceived += SendHostConfig_S2CMessage; receiveProfileDataClientMessage.OnReceived += LoadProfileData_S2CMessage; updatePlayerSkillpointsClientMessage.OnReceived += UpdateSkillPoints_S2CMessage; updatePlayerHandSlotsClientMessage.OnReceived += UpdatePlayerHandSlots_S2CMessage; updatePlayerJumpForceClientMessage.OnReceived += UpdatePlayerJumpHeight_S2CMessage; requestProfileDataServerMessage.OnReceived += RequestSavedData_C2SMessage; saveProfileDataServerMessage.OnReceived += SaveProfileData_C2SMessage; updateTeamLootLevelServerMessage.OnReceived += UpdateTeamLootLevel_C2SMessage; updateTeamXPServerMessage.OnReceived += UpdateTeamXP_C2SMessage; updateSPHandSlotsServerMessage.OnReceived += UpdateSPHandSlots_C2SMessage; updatePlayerJumpForceServerMessage.OnReceived += UpdatePlayerJumpHeight_C2SMessage; playerConnectClientEvent.InvokeServer(); } public override void OnDestroy() { teamLevel.OnValueChanged -= OnTeamLevelChange; teamXP.OnValueChanged -= OnTeamXPChange; teamLootLevel.OnValueChanged -= guiObj.TeamLootHudUpdate; playerConnectServerEvent.OnReceived -= PlayerConnect_C2SEvent; evaluateXPRequirementServerEvent.OnReceived -= EvaluateXPRequirements_C2SEvent; calculateAllPlayersHandSlotsServerEvent.OnReceived -= RefreshAllPlayerHandSlots_C2SEvent; sendConfigClientMessage.OnReceived -= SendHostConfig_S2CMessage; receiveProfileDataClientMessage.OnReceived -= LoadProfileData_S2CMessage; updatePlayerSkillpointsClientMessage.OnReceived -= UpdateSkillPoints_S2CMessage; updatePlayerHandSlotsClientMessage.OnReceived -= UpdatePlayerHandSlots_S2CMessage; requestProfileDataServerMessage.OnReceived -= RequestSavedData_C2SMessage; saveProfileDataServerMessage.OnReceived -= SaveProfileData_C2SMessage; updateTeamLootLevelServerMessage.OnReceived -= UpdateTeamLootLevel_C2SMessage; updateTeamXPServerMessage.OnReceived -= UpdateTeamXP_C2SMessage; updateSPHandSlotsServerMessage.OnReceived -= UpdateSPHandSlots_C2SMessage; ((NetworkBehaviour)this).OnDestroy(); } private void OnTeamLevelChange(int newLevel) { ((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowLevelUp)); } private void OnTeamXPChange(int newXP) { ((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowXPUpdate)); } public IEnumerator WaitUntilInitialisedThenAction(Action callback) { yield return (object)new WaitUntil((Func<bool>)(() => Initialized)); callback(); } public void PlayerConnect_C2SEvent(ulong clientId) { LethalPlugin.Log.LogInfo((object)$"Received PlayerConnect message from {clientId}"); IDictionary<string, string> allConfigEntries = LethalPlugin.Instance.GetAllConfigEntries(); string text = JsonConvert.SerializeObject((object)allConfigEntries); LethalPlugin.Log.LogInfo((object)("Sending config -> " + text)); sendConfigServerMessage.SendAllClients(text, true); } public void LoadSharedData() { SaveSharedData saveSharedData = SaveManager.LoadSharedFile(); if (saveSharedData == null) { LethalPlugin.Log.LogInfo((object)"Shared data is null!"); return; } LethalPlugin.Log.LogInfo((object)"Loading Lobby shared data."); teamXP.Value = saveSharedData.xp; teamLevel.Value = saveSharedData.level; teamTotalValue.Value = saveSharedData.quota; teamXPRequired.Value = CalculateXPRequirement(); LethalPlugin.Log.LogInfo((object)$"{saveSharedData.level} current lvl, {saveSharedData.xp} XP, {saveSharedData.quota} Profit, {teamXPRequired.Value} teamXPRequired"); } public IEnumerator LoadProfileData(string data) { LethalPlugin.Log.LogInfo((object)("Received player data from host -> " + data)); yield return (object)new WaitUntil((Func<bool>)(() => Initialized)); if (loadedSave) { LethalPlugin.Log.LogWarning((object)"Already loaded player data from host."); yield return null; } loadedSave = true; SaveData saveData = JsonConvert.DeserializeObject<SaveData>(data); skillPoints = saveData.skillPoints; LethalPlugin.Log.LogDebug((object)$"skillPoints -> {skillPoints}"); int skillCheck = 0; foreach (KeyValuePair<UpgradeType, int> skill in saveData.skillAllocation) { LethalPlugin.Log.LogDebug((object)$"{skill.Key} -> {skill.Value}"); skillList.skills[skill.Key].SetLevel(skill.Value, triggerHostProfileSave: false); skillCheck += skill.Value; LethalPlugin.Log.LogDebug((object)$"skillCheck -> {skillCheck}"); } if (skillCheck + skillPoints < teamLevel.Value + 5) { LethalPlugin.Log.LogInfo((object)$"Skill check is less than current level, adding {teamLevel.Value + 5 - (skillCheck + skillPoints)} skill points."); skillPoints += teamLevel.Value + 5 - (skillCheck + skillPoints); } LP_NetworkManager.xpInstance.guiObj.UpdateAllStats(); } public int CalculateXPRequirement() { int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount; int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota; int num = int.Parse(SkillConfig.hostConfig["XP Minimum"]); int num2 = int.Parse(SkillConfig.hostConfig["XP Maximum"]); int num3 = int.Parse(SkillConfig.hostConfig["Person Multiplier"]); int num4 = connectedPlayersAmount * num3; int num5 = num + num4; int num6 = int.Parse(SkillConfig.hostConfig["Quota Multiplier"]); int num7 = timesFulfilledQuota * num6; num5 += (int)((float)num5 * ((float)num7 / 100f)); if (num5 > num2) { num5 = num2; } LethalPlugin.Log.LogInfo((object)$"{connectedPlayersAmount} players, {timesFulfilledQuota} quotas, {num} initial cost, {num4} person value, {num7} quota value, {num5} total cost."); return num5; } public int GetXP() { return teamXP.Value; } public int GetLevel() { return teamLevel.Value; } public int GetProfit() { return teamTotalValue.Value; } public int GetSkillPoints() { return skillPoints; } public void SetSkillPoints(int num) { skillPoints = num; } public void EvaluateXPRequirements_C2SEvent(ulong clientId) { ((MonoBehaviour)this).StartCoroutine(XPRequirementCoroutine()); } public IEnumerator XPRequirementCoroutine() { yield return (object)new WaitForSeconds(0.5f); teamXPRequired.Value = CalculateXPRequirement(); } public void UpdateTeamXP_C2SMessage(int xpToAdd, ulong clientId) { LethalNetworkVariable<int> obj = teamXP; obj.Value += xpToAdd; LethalNetworkVariable<int> obj2 = teamTotalValue; obj2.Value += xpToAdd; int num = GetXP(); if (num >= teamXPRequired.Value) { int num2 = 0; while (num >= teamXPRequired.Value) { num2++; num -= teamXPRequired.Value; } teamXP.Value = num; LethalNetworkVariable<int> obj3 = teamLevel; obj3.Value += num2; updatePlayerSkillpointsServerMessage.SendAllClients(num2, true); } } public void UpdateSkillPoints_S2CMessage(int pointsToAdd) { skillPoints += pointsToAdd; } public void UpdateTeamLootLevel_C2SMessage(int change, ulong clientId) { int value = teamLootLevel.Value; if (value + change < 0) { teamLootLevel.Value = 0; } else { LethalNetworkVariable<int> obj = teamLootLevel; obj.Value += change; } LethalPlugin.Log.LogInfo((object)$"Changed team loot value by {change} turning into {teamLootLevel.Value}."); } public void UpdateSPHandSlots_C2SMessage(int slotChange, ulong clientId) { if (!LethalPlugin.ReservedSlots) { LethalPlugin.Log.LogInfo((object)$"C2S Received update for Player {clientId} to add {slotChange} slots"); updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(clientId, slotChange), true); } } public void UpdatePlayerHandSlots_S2CMessage(PlayerHandSlotData data) { LethalPlugin.Log.LogInfo((object)$"S2C Received update for Player {data.clientId} to add {data.additionalSlots} slots"); SetHandSlot(data.clientId, data.additionalSlots); } public void SetHandSlot(ulong playerID, int additionalSlots) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.playerClientId != playerID) { continue; } int num = 4 + additionalSlots; List<GrabbableObject> list = val.ItemSlots.ToList(); if (val.currentItemSlot > num - 1) { HandSlots.SwitchItemSlots(val, num - 1); } for (int j = 0; j < list.Count; j++) { if (j > num - 1 && (Object)(object)list[j] != (Object)null) { HandSlots.SwitchItemSlots(val, j); val.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true); } } val.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[num]; for (int k = 0; k < list.Count; k++) { if (!((Object)(object)list[k] == (Object)null)) { val.ItemSlots[k] = list[k]; } } LethalPlugin.Log.LogDebug((object)$"Player {playerID} has {val.ItemSlots.Length} slots after setting."); if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController) { LethalPlugin.Log.LogDebug((object)"Updating HUD slots."); HandSlots.UpdateHudSlots(); } break; } } public void RefreshAllPlayerHandSlots_C2SEvent(ulong clientId) { if (LethalPlugin.ReservedSlots || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot)) { return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (((Component)val).gameObject.activeSelf) { ulong playerClientId = val.playerClientId; int additionalSlots = val.ItemSlots.Length - 4; updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(playerClientId, additionalSlots), true); } } } public void SendHostConfig_S2CMessage(string serializedConfig) { IDictionary<string, string> dictionary = JsonConvert.DeserializeObject<IDictionary<string, string>>(serializedConfig); foreach (KeyValuePair<string, string> item in dictionary) { SkillConfig.hostConfig[item.Key] = item.Value; LethalPlugin.Log.LogInfo((object)("Loaded host config: " + item.Key + " = " + item.Value)); } if (!Initialized) { Initialized = true; LP_NetworkManager.xpInstance = this; skillList = new SkillList(); skillList.InitializeSkills(); if (GameNetworkManager.Instance.isHostingGame) { LoadSharedData(); } guiObj = new SkillsGUI(); teamLootLevel.OnValueChanged += guiObj.TeamLootHudUpdate; skillPoints = teamLevel.Value + 5; calculateAllPlayersHandSlotsClientEvent.InvokeServer(); evaluateXPRequirementClientEvent.InvokeServer(); } } public void RequestSavedData_C2SMessage(ulong steamID, ulong clientId) { string text = SaveManager.LoadPlayerFile(steamID); PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId); sendProfileDataServerMessage.SendClient(text, playerController.actualClientId); } public void LoadProfileData_S2CMessage(string saveData) { LethalPlugin.Log.LogInfo((object)("Received LoadProfileData_S2CMessage -> " + saveData)); if (saveData != null) { ((MonoBehaviour)this).StartCoroutine(LoadProfileData(saveData)); } } public void SaveProfileData_C2SMessage(string data, ulong clientId) { SaveProfileData saveProfileData = JsonConvert.DeserializeObject<SaveProfileData>(data); LethalPlugin.Log.LogInfo((object)$"Received SaveData request for {saveProfileData.steamId} with data -> {JsonConvert.SerializeObject((object)saveProfileData.saveData)}"); SaveManager.Save(saveProfileData.steamId, saveProfileData.saveData); SaveManager.SaveShared(teamXP.Value, teamLevel.Value, teamTotalValue.Value); } public void UpdatePlayerJumpHeight_C2SMessage(PlayerJumpHeightData playerData, ulong clientId) { LethalPlugin.Log.LogInfo((object)$"Received request for {clientId} [{playerData.clientId}] to set jump skill to {playerData.jumpSkillValue}"); updatePlayerJumpForceServerMessage.SendAllClients(playerData, true); } public void UpdatePlayerJumpHeight_S2CMessage(PlayerJumpHeightData playerData) { PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(playerData.clientId); Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight]; float num = (float)playerData.jumpSkillValue * skill.GetMultiplier() / 100f * 13f; playerController.jumpForce = 13f + num; LethalPlugin.Log.LogInfo((object)$"Updating client {playerData.clientId} jump height. Adding {num} resulting in {playerController.jumpForce} jump force"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalProgression"; public const string PLUGIN_NAME = "LethalProgression"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace LethalProgression.GUI { [HarmonyPatch] internal class GUIUpdate { public static bool isMenuOpen; public static SkillsGUI guiInstance; [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "Update")] private static void SkillMenuUpdate(QuickMenuManager __instance) { if (guiInstance == null || !Object.op_Implicit((Object)(object)guiInstance.mainPanel)) { return; } if (!isMenuOpen) { guiInstance.mainPanel.SetActive(false); return; } if (bool.Parse(SkillConfig.hostConfig["Unspec in Ship Only"]) && !bool.Parse(SkillConfig.hostConfig["Disable Unspec"])) { if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom) { guiInstance.SetUnspec(show: true); } else { guiInstance.SetUnspec(show: false); } } if (bool.Parse(SkillConfig.hostConfig["Unspec in Orbit Only"])) { if (StartOfRound.Instance.inShipPhase) { guiInstance.SetUnspec(show: true); } else { guiInstance.SetUnspec(show: false); } } if (bool.Parse(SkillConfig.hostConfig["Disable Unspec"])) { guiInstance.SetUnspec(show: false); } guiInstance.mainPanel.SetActive(true); GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); val.SetActive(false); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList"); val2.SetActive(false); RealTimeUpdateInfo(); } [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")] private static void SkillMenuClose(QuickMenuManager __instance) { isMenuOpen = false; } private static void RealTimeUpdateInfo() { GameObject gameObject = ((Component)guiInstance.mainPanel.transform.GetChild(2)).gameObject; gameObject = ((Component)gameObject.transform.GetChild(1)).gameObject; TextMeshProUGUI component = gameObject.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).text = LP_NetworkManager.xpInstance.GetSkillPoints().ToString(); } } internal class SkillsGUI { public GameObject mainPanel; public GameObject infoPanel; public Skill activeSkill; public GameObject templateSlot; public List<GameObject> skillButtonsList = new List<GameObject>(); public int shownSkills = 0; public SkillsGUI() { CreateSkillMenu(); GUIUpdate.guiInstance = this; } public void OpenSkillMenu() { GUIUpdate.isMenuOpen = true; mainPanel.SetActive(true); } public void CreateSkillMenu() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown mainPanel = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("SkillMenu")); ((Object)mainPanel).name = "SkillMenu"; mainPanel.SetActive(false); templateSlot = Object.Instantiate<GameObject>(GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory/Slot3")); ((Object)templateSlot).name = "TemplateSlot"; templateSlot.SetActive(false); infoPanel = ((Component)mainPanel.transform.GetChild(1)).gameObject; infoPanel.SetActive(false); GameObject gameObject = ((Component)mainPanel.transform.GetChild(4)).gameObject; gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(BackButton)); shownSkills = 0; if (LP_NetworkManager.xpInstance.skillList.skills == null) { return; } foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { LethalPlugin.Log.LogInfo((object)("Creating button for " + skill.Value.GetShortName())); GameObject val = SetupUpgradeButton(skill.Value); LethalPlugin.Log.LogInfo((object)"Setup passed!"); skillButtonsList.Add(val); LethalPlugin.Log.LogInfo((object)"Added to skill list.."); LoadSkillData(skill.Value, val); } TeamLootHudUpdate(0); } public void BackButton() { GUIUpdate.isMenuOpen = false; GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); val.SetActive(true); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList"); val2.SetActive(true); } public void SetUnspec(bool show) { GameObject gameObject = ((Component)infoPanel.transform.GetChild(6)).gameObject; GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(7)).gameObject; GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(8)).gameObject; gameObject.SetActive(show); gameObject2.SetActive(show); gameObject3.SetActive(show); if (!bool.Parse(SkillConfig.hostConfig["Disable Unspec"])) { GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(9)).gameObject; gameObject4.SetActive(!show); } if (bool.Parse(SkillConfig.hostConfig["Unspec in Orbit Only"])) { GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(9)).gameObject; ((TMP_Text)((Component)gameObject5.transform).GetComponent<TextMeshProUGUI>()).SetText("Return to orbit to unspec.", true); } } public GameObject SetupUpgradeButton(Skill skill) { //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown GameObject gameObject = ((Component)mainPanel.transform.GetChild(0)).gameObject; GameObject val = Object.Instantiate<GameObject>(gameObject); if (!Object.op_Implicit((Object)(object)gameObject)) { LethalPlugin.Log.LogError((object)"Couldn't find template button!"); return null; } ((Object)val).name = skill.GetShortName(); GameObject gameObject2 = ((Component)mainPanel.transform.GetChild(3)).gameObject; GameObject gameObject3 = ((Component)gameObject2.transform.GetChild(1)).gameObject; val.transform.SetParent(gameObject3.transform, false); shownSkills++; GameObject gameObject4 = ((Component)val.transform.GetChild(0)).gameObject; ((TMP_Text)gameObject4.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true); GameObject gameObject5 = ((Component)val.transform.GetChild(1)).gameObject; ((TMP_Text)gameObject5.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true); GameObject gameObject6 = ((Component)val.transform.GetChild(2)).gameObject; ((TMP_Text)gameObject6.GetComponent<TextMeshProUGUI>()).SetText("(" + skill.GetLevel() + " " + skill.GetAttribute() + ")", true); ((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true); val.SetActive(true); val.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { UpdateStatInfo(skill); }); return val; } public void LoadSkillData(Skill skill, GameObject skillButton) { if (!skill._teamShared) { GameObject gameObject = ((Component)skillButton.transform.GetChild(1)).gameObject; ((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true); GameObject gameObject2 = ((Component)skillButton.transform.GetChild(2)).gameObject; ((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText($"(+{(float)skill.GetLevel() * skill.GetMultiplier()}% {skill.GetAttribute()})", true); ((TMP_Text)skillButton.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true); } } public void UpdateAllStats() { foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { if (!skill.Value._teamShared) { GameObject skillButton = skillButtonsList.Find((GameObject x) => ((Object)x).name == skill.Value.GetShortName()); LoadSkillData(skill.Value, skillButton); } } } public void UpdateStatInfo(Skill skill) { //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected O, but got Unknown //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Expected O, but got Unknown //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Expected O, but got Unknown //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown if (!infoPanel.activeSelf) { infoPanel.SetActive(true); } TextMeshProUGUI component = ((Component)infoPanel.transform.GetChild(0)).gameObject.GetComponent<TextMeshProUGUI>(); TextMeshProUGUI component2 = ((Component)infoPanel.transform.GetChild(1)).gameObject.GetComponent<TextMeshProUGUI>(); TextMeshProUGUI component3 = ((Component)infoPanel.transform.GetChild(2)).gameObject.GetComponent<TextMeshProUGUI>(); activeSkill = skill; ((TMP_Text)component).SetText(skill.GetName(), true); if (skill.GetMaxLevel() == 99999) { ((TMP_Text)component2).SetText($"{skill.GetLevel()}", true); } else { ((TMP_Text)component2).SetText($"{skill.GetLevel()} / {skill.GetMaxLevel()}", true); } ((TMP_Text)component3).SetText(skill.GetDescription(), true); GameObject gameObject = ((Component)infoPanel.transform.GetChild(3)).gameObject; GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(4)).gameObject; GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(5)).gameObject; gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { AddSkillPoint(skill, 5); }); gameObject2.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { AddSkillPoint(skill, 2); }); gameObject3.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject3.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { AddSkillPoint(skill, 1); }); GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(6)).gameObject; GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(7)).gameObject; GameObject gameObject6 = ((Component)infoPanel.transform.GetChild(8)).gameObject; gameObject4.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { RemoveSkillPoint(skill, 5); }); gameObject5.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { RemoveSkillPoint(skill, 2); }); gameObject6.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { RemoveSkillPoint(skill, 1); }); } public void AddSkillPoint(Skill skill, int amt) { if (LP_NetworkManager.xpInstance.GetSkillPoints() <= 0) { return; } int skillPoints = LP_NetworkManager.xpInstance.GetSkillPoints(); if (skillPoints < amt) { amt = skillPoints; } if (skill.GetLevel() + amt > skill.GetMaxLevel()) { amt = skill.GetMaxLevel() - skill.GetLevel(); } LP_NetworkManager.xpInstance.SetSkillPoints(LP_NetworkManager.xpInstance.GetSkillPoints() - amt); skill.AddLevel(amt); UpdateStatInfo(skill); foreach (GameObject skillButtons in skillButtonsList) { if (((Object)skillButtons).name == skill.GetShortName()) { LoadSkillData(skill, skillButtons); } } } public void RemoveSkillPoint(Skill skill, int amt) { if (skill.GetLevel() == 0) { return; } int level = skill.GetLevel(); if (level < amt) { amt = level; } LP_NetworkManager.xpInstance.SetSkillPoints(LP_NetworkManager.xpInstance.GetSkillPoints() + amt); skill.AddLevel(-amt); UpdateStatInfo(skill); foreach (GameObject skillButtons in skillButtonsList) { if (((Object)skillButtons).name == skill.GetShortName()) { LoadSkillData(skill, skillButtons); } } } public void TeamLootHudUpdate(int newValue) { foreach (GameObject skillButtons in skillButtonsList) { if (((Object)skillButtons).name == "VAL") { Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value]; LoadSkillData(skill, skillButtons); GameObject gameObject = ((Component)skillButtons.transform.GetChild(0)).gameObject; ((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true); GameObject gameObject2 = ((Component)skillButtons.transform.GetChild(1)).gameObject; ((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText($"{skill.GetLevel()}", true); ((TMP_Text)skillButtons.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true); float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier(); float num = (float)newValue * multiplier; GameObject gameObject3 = ((Component)skillButtons.transform.GetChild(2)).gameObject; ((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText($"(+{num}% {skill.GetAttribute()})", true); LethalPlugin.Log.LogInfo((object)$"Setting team value hud to {num}"); } } } } } namespace LethalProgression.Skills { public enum UpgradeType { HPRegen, Stamina, Battery, HandSlot, Value, Oxygen, JumpHeight, SprintSpeed, Strength } internal class SkillList { public Dictionary<UpgradeType, Skill> skills = new Dictionary<UpgradeType, Skill>(); public void CreateSkill(UpgradeType upgrade, string name, string description, string shortname, string attribute, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false) { Skill value = new Skill(name, description, shortname, attribute, upgrade, cost, maxLevel, multiplier, callback, teamShared); skills.Add(upgrade, value); } public bool IsSkillListValid() { if (skills.Count == 0) { return false; } return true; } public bool IsSkillValid(UpgradeType upgrade) { if (!skills.ContainsKey(upgrade)) { LethalPlugin.Log.LogInfo((object)("Skill " + upgrade.ToString() + " is not in the skill list!")); return false; } return true; } public Skill GetSkill(UpgradeType upgrade) { if (!IsSkillValid(upgrade)) { return null; } return skills[upgrade]; } public Dictionary<UpgradeType, Skill> GetSkills() { return skills; } public void InitializeSkills() { if (bool.Parse(SkillConfig.hostConfig["Health Regen Enabled"])) { CreateSkill(UpgradeType.HPRegen, "Health Regen", "The company installs a basic healer into your suit, letting you regenerate health slowly. Only regenerate up to 100 HP.", "HPR", "Health Regeneration", 1, int.Parse(SkillConfig.hostConfig["Health Regen Max Level"]), float.Parse(SkillConfig.hostConfig["Health Regen Multiplier"], CultureInfo.InvariantCulture)); } if (bool.Parse(SkillConfig.hostConfig["Stamina Enabled"])) { CreateSkill(UpgradeType.Stamina, "Stamina", "Hours on that company gym finally coming into play. Allows you to run for longer, but has to regenerate it slower.", "STM", "Stamina", 1, int.Parse(SkillConfig.hostConfig["Stamina Max Level"]), float.Parse(SkillConfig.hostConfig["Stamina Multiplier"], CultureInfo.InvariantCulture), Stamina.StaminaUpdate); } if (bool.Parse(SkillConfig.hostConfig["Battery Life Enabled"])) { CreateSkill(UpgradeType.Battery, "Battery Life", "The company provides you with better batteries. Replace your batteries AT THE SHIP'S CHARGER to see an effect.", "BAT", "Battery Life", 1, int.Parse(SkillConfig.hostConfig["Battery Life Max Level"]), float.Parse(SkillConfig.hostConfig["Battery Life Multiplier"], CultureInfo.InvariantCulture)); } if (bool.Parse(SkillConfig.hostConfig["Hand Slots Enabled"]) && !LethalPlugin.ReservedSlots) { CreateSkill(UpgradeType.HandSlot, "Hand Slot", "The company finally gives you a better belt! Fit more stuff! (One slot every 100%.)", "HND", "Hand Slots", 1, int.Parse(SkillConfig.hostConfig["Hand Slots Max Level"]), float.Parse(SkillConfig.hostConfig["Hand Slots Multiplier"], CultureInfo.InvariantCulture), HandSlots.HandSlotsUpdate); } if (bool.Parse(SkillConfig.hostConfig["Loot Value Enabled"])) { CreateSkill(UpgradeType.Value, "Loot Value", "The company gives you a better pair of eyes, allowing you to see the value in things.", "VAL", "Loot Value", 1, int.Parse(SkillConfig.hostConfig["Loot Value Max Level"]), float.Parse(SkillConfig.hostConfig["Loot Value Multiplier"], CultureInfo.InvariantCulture), LootValue.LootValueUpdate, teamShared: true); } if (bool.Parse(SkillConfig.hostConfig["Oxygen Enabled"])) { CreateSkill(UpgradeType.Oxygen, "Oxygen", "The company installs you with oxygen tanks. You gain extra time in the water. (Start drowning when the bar is empty.)", "OXY", "Extra Oxygen", 1, int.Parse(SkillConfig.hostConfig["Oxygen Max Level"]), float.Parse(SkillConfig.hostConfig["Oxygen Multiplier"], CultureInfo.InvariantCulture)); } if (bool.Parse(SkillConfig.hostConfig["Strength Enabled"])) { CreateSkill(UpgradeType.Strength, "Strength", "More work at the Company's gym gives you pure muscles! You can carry better. (Reduces weight by a percentage.)", "STR", "Weight Reduction", 1, int.Parse(SkillConfig.hostConfig["Strength Max Level"]), float.Parse(SkillConfig.hostConfig["Strength Multiplier"], CultureInfo.InvariantCulture), Strength.StrengthUpdate); } if (bool.Parse(SkillConfig.hostConfig["Jump Height Enabled"])) { CreateSkill(UpgradeType.JumpHeight, "Jump Height", "The company installs you with jumping boots! (The company is not responsible for any broken knees.)", "JMP", "Jump Height", 1, int.Parse(SkillConfig.hostConfig["Jump Height Max Level"]), float.Parse(SkillConfig.hostConfig["Jump Height Multiplier"], CultureInfo.InvariantCulture), JumpHeight.JumpHeightUpdate); } if (!LethalPlugin.MikesTweaks && bool.Parse(SkillConfig.hostConfig["Sprint Speed Enabled"])) { CreateSkill(UpgradeType.SprintSpeed, "Sprint Speed", "The company empowers you with pure steroids, run, spaceman.", "SPD", "Sprint Speed", 1, int.Parse(SkillConfig.hostConfig["Sprint Speed Max Level"]), float.Parse(SkillConfig.hostConfig["Sprint Speed Multiplier"], CultureInfo.InvariantCulture), SprintSpeed.SprintSpeedUpdate); } } } internal class Skill { private readonly string _shortName; private readonly string _name; private readonly string _attribute; private readonly string _description; private readonly UpgradeType _upgradeType; private readonly int _cost; private readonly int _maxLevel; private readonly float _multiplier; private readonly Action<int> _callback; public bool _teamShared; private int _level; public Skill(string name, string description, string shortname, string attribute, UpgradeType upgradeType, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false) { _name = name; _shortName = shortname; _attribute = attribute; _description = description; _upgradeType = upgradeType; _cost = cost; _maxLevel = maxLevel; _multiplier = multiplier; _level = 0; _callback = callback; _teamShared = teamShared; } public string GetName() { return _name; } public string GetShortName() { return _shortName; } public string GetAttribute() { return _attribute; } public string GetDescription() { return _description; } public UpgradeType GetUpgradeType() { return _upgradeType; } public int GetCost() { return _cost; } public int GetMaxLevel() { return _maxLevel; } public int GetLevel() { return _level; } public float GetMultiplier() { return _multiplier; } public float GetTrueValue() { return _multiplier * (float)_level; } public void SetLevel(int newLevel, bool triggerHostProfileSave = true) { int level = _level; _level = newLevel; _callback?.Invoke(newLevel - level); if (triggerHostProfileSave) { SaveManager.TriggerHostProfileSave(); } } public void AddLevel(int change) { _level += change; _callback?.Invoke(change); SaveManager.TriggerHostProfileSave(); } } [HarmonyPatch] internal class BatteryLife { [HarmonyPrefix] [HarmonyPatch(typeof(GrabbableObject), "SyncBatteryServerRpc")] public static void BatteryUpdate(ref int charge) { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery) && charge == 100) { charge += (int)LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue(); } } } internal class HandSlots { public static int currentSlotCount = 4; public static void HandSlotsUpdate(int updateValue) { if (!LethalPlugin.ReservedSlots && LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot)) { LC_XP xpInstance = LP_NetworkManager.xpInstance; int num = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue(); int num2 = (int)Math.Floor((double)(num / 100)); ulong playerClientId = GameNetworkManager.Instance.localPlayerController.playerClientId; LethalPlugin.Log.LogInfo((object)$"Updating Player HandSlot {playerClientId}"); xpInstance.updateSPHandSlotsClientMessage.SendServer(num2); } } public static void UpdateHudSlots() { //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) LC_XP xpInstance = LP_NetworkManager.xpInstance; float num = xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue() / 100f; int num2 = 4 + (int)Math.Floor(num); int num3 = num2 - currentSlotCount; GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory"); List<string> list = new List<string> { "Slot0", "Slot1", "Slot2", "Slot3" }; for (int i = 0; i < val.transform.childCount; i++) { Transform child = val.transform.GetChild(i); if (!list.Contains(((Object)((Component)child).gameObject).name)) { Object.Destroy((Object)(object)((Component)child).gameObject); } } int num4 = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue(); int num5 = (int)Math.Floor((double)(num4 / 100)); Image[] array = (Image[])(object)new Image[num2]; array[0] = HUDManager.Instance.itemSlotIconFrames[0]; array[1] = HUDManager.Instance.itemSlotIconFrames[1]; array[2] = HUDManager.Instance.itemSlotIconFrames[2]; array[3] = HUDManager.Instance.itemSlotIconFrames[3]; Image[] array2 = (Image[])(object)new Image[num2]; array2[0] = HUDManager.Instance.itemSlotIcons[0]; array2[1] = HUDManager.Instance.itemSlotIcons[1]; array2[2] = HUDManager.Instance.itemSlotIcons[2]; array2[3] = HUDManager.Instance.itemSlotIcons[3]; GameObject val2 = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory/Slot3"); GameObject templateSlot = xpInstance.guiObj.templateSlot; GameObject val3 = val2; currentSlotCount = num2; for (int j = 0; j < (int)num; j++) { GameObject val4 = Object.Instantiate<GameObject>(templateSlot); ((Object)val4).name = $"Slot{3 + (j + 1)}"; val4.transform.SetParent(val.transform); Vector3 localPosition = val3.transform.localPosition; val4.transform.SetLocalPositionAndRotation(new Vector3(localPosition.x + 50f, localPosition.y, localPosition.z), val3.transform.localRotation); val3 = val4; array[3 + (j + 1)] = val4.GetComponent<Image>(); array2[3 + (j + 1)] = ((Component)val4.transform.GetChild(0)).GetComponent<Image>(); val4.SetActive(true); } for (int k = 0; k < array.Length; k++) { Vector3 localPosition2 = ((Component)array[k]).transform.localPosition; ((Component)array[k]).transform.SetLocalPositionAndRotation(new Vector3(localPosition2.x - (float)(num3 * 25), localPosition2.y, localPosition2.z), ((Component)array[k]).transform.localRotation); } HUDManager.Instance.itemSlotIconFrames = array; HUDManager.Instance.itemSlotIcons = array2; } public static bool IsItemSwitchPossible(PlayerControllerB player) { return (double)player.timeSinceSwitchingSlots >= 0.01 && !player.inTerminalMenu && !player.isGrabbingObjectAnimation && !player.inSpecialInteractAnimation && !player.throwingObject && !player.isTypingChat && !player.twoHanded && !player.activatingItem && !player.jetpackControls && !player.disablingJetpackControls; } public static bool SwitchItemSlots(PlayerControllerB player, int requestedSlot) { if (!IsItemSwitchPossible(player) || player.currentItemSlot == requestedSlot) { return false; } LethalPlugin.Log.LogDebug((object)$"Trying to switch to slot {requestedSlot}"); int num = player.currentItemSlot - requestedSlot; bool flag = num > 0; if (Math.Abs(num) == player.ItemSlots.Length - 1) { player.SwitchItemSlotsServerRpc(flag); } else { do { player.SwitchItemSlotsServerRpc(flag); num += ((!flag) ? 1 : (-1)); } while (num != 0); } ShipBuildModeManager.Instance.CancelBuildMode(true); player.playerBodyAnimator.SetBool("GrabValidated", false); LethalPlugin.Log.LogDebug((object)$"Switched to slot {requestedSlot}"); player.SwitchToItemSlot(requestedSlot, (GrabbableObject)null); if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { ((Component)player.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(player.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f); } return true; } } [HarmonyPatch] internal class HPRegen { [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] private static void HPRegenUpdate(PlayerControllerB __instance) { if (!((NetworkBehaviour)__instance).IsOwner || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject) || !__instance.isPlayerControlled || __instance.health >= 100 || __instance.isPlayerDead || !LP_NetworkManager.xpInstance.skillList.IsSkillListValid() || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen) || LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.HPRegen].GetLevel() == 0) { return; } if (__instance.healthRegenerateTimer <= 0f) { Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.HPRegen]; float trueValue = skill.GetTrueValue(); __instance.healthRegenerateTimer = 1f / trueValue; __instance.health++; if (__instance.health >= 20) { __instance.MakeCriticallyInjured(false); } HUDManager.Instance.UpdateHealthUI(__instance.health, false); } else { __instance.healthRegenerateTimer -= Time.deltaTime; } } } internal class JumpHeight { public static void JumpHeightUpdate(int updatedValue) { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.JumpHeight)) { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight]; PlayerJumpHeightData playerJumpHeightData = new PlayerJumpHeightData { clientId = localPlayerController.playerClientId, jumpSkillValue = skill.GetLevel() }; LethalPlugin.Log.LogInfo((object)$"Jump skill now {skill.GetLevel()}, sending to Server"); LP_NetworkManager.xpInstance.updatePlayerJumpForceClientMessage.SendServer(playerJumpHeightData); } } } [HarmonyPatch] internal class LootValue { [HarmonyPrefix] [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] private static void AddLootValue() { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value)) { float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier(); float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier; float num2 = num / 100f; try { RoundManager instance = RoundManager.Instance; instance.scrapValueMultiplier += num2; } catch { } LethalPlugin.Log.LogDebug((object)$"Added {num2} to scrap value multiplier, resulting in {RoundManager.Instance.scrapValueMultiplier}"); } } public static void LootValueUpdate(int change) { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value)) { LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(change); } } } [HarmonyPatch] internal class Oxygen { private static GameObject oxygenBar; private static float oxygen = 0f; private static float oxygenTimer = 0f; private static bool inWater = false; private static bool canDrown = true; [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "SetFaceUnderwaterClientRpc")] private static void EnteredWater(PlayerControllerB __instance) { inWater = true; } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "SetFaceOutOfWaterClientRpc")] private static void LeftWater(PlayerControllerB __instance) { inWater = false; } [HarmonyPrefix] [HarmonyPatch(typeof(PlayerControllerB), "SetFaceUnderwaterFilters")] private static void ShouldDrown(PlayerControllerB __instance) { if (!canDrown) { StartOfRound.Instance.drowningTimer = 99f; } } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] private static void OxygenUpdate(PlayerControllerB __instance) { if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillListValid() || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Oxygen)) { return; } if (__instance.isPlayerDead) { if (Object.op_Implicit((Object)(object)oxygenBar)) { oxygenBar.SetActive(false); } return; } if (LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Oxygen].GetLevel() == 0) { if (Object.op_Implicit((Object)(object)oxygenBar)) { oxygenBar.SetActive(false); } if (!canDrown) { canDrown = true; StartOfRound.Instance.drowningTimer = 1f; } return; } if (!Object.op_Implicit((Object)(object)oxygenBar)) { CreateOxygenBar(); } Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Oxygen]; float trueValue = skill.GetTrueValue(); if (inWater) { oxygenBar.SetActive(true); if (oxygenTimer <= 0f) { oxygenTimer = 0.1f; if (oxygen > 0f) { oxygen -= 0.1f; } else if (!canDrown) { canDrown = true; StartOfRound.Instance.drowningTimer = 1f; } } else { oxygenTimer -= Time.deltaTime; } } if (!inWater) { if (oxygenTimer <= 0f) { oxygenTimer = 0.1f; if (oxygen < trueValue) { oxygenBar.SetActive(true); oxygen += 0.1f; canDrown = false; } else { oxygenBar.SetActive(false); } } else { oxygenTimer -= Time.deltaTime; } } if (oxygen > trueValue) { oxygenBar.SetActive(false); oxygen = trueValue; } if (oxygenBar.activeSelf) { float fillAmount = oxygen / trueValue; ((Component)oxygenBar.transform.GetChild(0).GetChild(0)).GetComponent<Image>().fillAmount = fillAmount; } } public static void CreateOxygenBar() { oxygenBar = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("OxygenBar")); oxygenBar.SetActive(false); } } [HarmonyPatch] public static class SprintSpeed { public static float sprintSpeed = 2.25f; public static void SprintSpeedUpdate(int updatedValue) { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.SprintSpeed)) { Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.SprintSpeed]; PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; float num = (float)updatedValue * skill.GetMultiplier() / 100f * 2.25f; sprintSpeed += num; LethalPlugin.Log.LogInfo((object)$"{updatedValue} change, Adding {num} resulting in {sprintSpeed} run speed"); } } public static float GetSprintSpeed() { return sprintSpeed; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Update_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if (LethalPlugin.MikesTweaks) { return instructions; } List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 2.25f) { list[i] = new CodeInstruction(OpCodes.Call, (object)typeof(SprintSpeed).GetMethod("GetSprintSpeed")); } } return list.AsEnumerable(); } } internal class Stamina { public static void StaminaUpdate(int updatedValue) { if (LP_NetworkManager.xpInstance.skillList.IsSkillListValid() && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina)) { Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina]; PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; float num = (float)updatedValue * skill.GetMultiplier() / 100f * 11f; localPlayerController.sprintTime += num; LethalPlugin.Log.LogInfo((object)$"{updatedValue} change, Adding {num} resulting in {localPlayerController.sprintTime} stamina"); } } } [HarmonyPatch] internal class Strength { public static void StrengthUpdate(int change = 0) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillListValid() || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Strength) || LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetLevel() == 0) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; List<GrabbableObject> list = localPlayerController.ItemSlots.ToList(); LethalPlugin.Log.LogDebug((object)$"Carry weight was {localPlayerController.carryWeight}"); float trueValue = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetTrueValue(); float num = trueValue / 100f; float num2 = 0f; foreach (GrabbableObject item in list) { if (!((Object)(object)item == (Object)null)) { float num3 = item.itemProperties.weight - 1f; num3 *= 1f - num; num2 += num3; LethalPlugin.Log.LogDebug((object)$"Item weight was {item.itemProperties.weight - 1f} and is now {num3}"); LethalPlugin.Log.LogDebug((object)$"Adding carryweight.. now up to {num2}"); } } localPlayerController.carryWeight = Math.Clamp(1f + num2, 0f, 10f); LethalPlugin.Log.LogDebug((object)$"Player carry weight is now {localPlayerController.carryWeight}"); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")] private static void UpdateObjects() { StrengthUpdate(); } [HarmonyPostfix] [HarmonyPatch(typeof(GrabbableObject), "DiscardItem")] private static void UpdateByDiscard(GrabbableObject __instance) { if (((NetworkBehaviour)__instance).IsOwner) { StrengthUpdate(); } } } } namespace LethalProgression.Saving { internal class SaveData { public ulong steamId; public Dictionary<UpgradeType, int> skillAllocation = new Dictionary<UpgradeType, int>(); public int skillPoints { get; set; } } internal class SaveSharedData { public int xp { get; set; } public int level { get; set; } public int quota { get; set; } public SaveSharedData(int xp, int level, int quota) { this.xp = xp; this.level = level; this.quota = quota; } } internal static class SaveManager { public static int saveFileSlot; public static void TriggerHostProfileSave() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ulong num = SteamId.op_Implicit(SteamClient.SteamId); SaveData saveData = new SaveData { steamId = num, skillPoints = LP_NetworkManager.xpInstance.skillPoints }; foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { LethalPlugin.Log.LogInfo((object)$"Skill is {skill.Key} and value is {skill.Value.GetLevel()}"); saveData.skillAllocation.Add(skill.Key, skill.Value.GetLevel()); } LethalPlugin.Log.LogInfo((object)$"Invoke saveProfileDataClientMessage({num}, {JsonConvert.SerializeObject((object)saveData)})"); LP_NetworkManager.xpInstance.saveProfileDataClientMessage.SendServer(JsonConvert.SerializeObject((object)new SaveProfileData(num, saveData))); } public static void Save(ulong steamid, SaveData data) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; LethalPlugin.Log.LogInfo((object)$"Saving to slot {saveFileSlot + 1} in {GetSavePath()}"); if (!Directory.Exists(GetSavePath())) { Directory.CreateDirectory(GetSavePath()); } File.WriteAllText(GetSavePath() + steamid + ".json", JsonConvert.SerializeObject((object)data)); } public static void SaveShared(int xp, int level, int quota) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; LethalPlugin.Log.LogInfo((object)("Saving to slot " + saveFileSlot + 1)); if (!Directory.Exists(GetSavePath())) { Directory.CreateDirectory(GetSavePath()); } File.WriteAllText(GetSavePath() + "shared.json", JsonConvert.SerializeObject((object)new SaveSharedData(xp, level, quota))); } public static void DeleteSave(int _saveFileSlot) { saveFileSlot = _saveFileSlot; if (Directory.Exists(GetSavePath())) { Directory.Delete(Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1), recursive: true); } } public static string GetSavePath() { return Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1) + "/"; } public static string LoadPlayerFile(ulong steamId) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; if (!File.Exists(GetSavePath() + steamId + ".json")) { LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} doesn't exist"); return null; } LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} found"); return File.ReadAllText(GetSavePath() + steamId + ".json"); } public static SaveSharedData LoadSharedFile() { saveFileSlot = GameNetworkManager.Instance.saveFileNum; if (!File.Exists(GetSavePath() + "shared.json")) { LethalPlugin.Log.LogInfo((object)"Shared file doesn't exist"); return null; } LethalPlugin.Log.LogInfo((object)"Shared file exists"); string text = File.ReadAllText(GetSavePath() + "shared.json"); return JsonConvert.DeserializeObject<SaveSharedData>(text); } } [HarmonyPatch] internal class SavePatches : NetworkBehaviour { [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "SaveGame")] [HarmonyPriority(800)] private static void SaveGamePrefix() { LethalPlugin.Log.LogDebug((object)"Invoked DoSave via SaveGame"); SaveManager.TriggerHostProfileSave(); } [HarmonyPostfix] [HarmonyPatch(typeof(DeleteFileButton), "DeleteFile")] private static void DeleteSaveFile(DeleteFileButton __instance) { SaveManager.DeleteSave(__instance.fileToDelete); } } } namespace LethalProgression.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("LethalProgression.Properties.Resources", typeof(Resources).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] skillmenu { get { object @object = ResourceManager.GetObject("skillmenu", resourceCulture); return (byte[])@object; } } internal Resources() { } } } namespace LethalProgression.Patches { [HarmonyPatch] internal class EnemyAIPatch { private static Dictionary<string, int> _enemyReward = new Dictionary<string, int> { { "HoarderBug (EnemyType)", 30 }, { "BaboonBird (EnemyType)", 15 }, { "MouthDog (EnemyType)", 200 }, { "Centipede (EnemyType)", 30 }, { "Flowerman (EnemyType)", 200 }, { "SandSpider (EnemyType)", 50 }, { "Crawler (EnemyType)", 50 }, { "Puffer (EnemyType)", 15 } }; [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "KillEnemy")] private static void CalculateXPForEnemyDeath(EnemyAI __instance) { if (GameNetworkManager.Instance.isHostingGame) { string text = ((object)__instance.enemyType).ToString(); LethalPlugin.Log.LogInfo((object)("Enemy type: " + text)); int num = 30; if (_enemyReward.ContainsKey(text)) { num = _enemyReward[text]; } LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "HitEnemyServerRpc")] private static void HitEnemyTrigger(EnemyAI __instance, int force, int playerWhoHit) { LethalPlugin.Log.LogInfo((object)$"Player {playerWhoHit} hit enemy {((object)__instance).GetType()} with force {force}"); } } [HarmonyPatch] internal class HUDManagerPatch { private static GameObject _tempBar; private static TextMeshProUGUI _tempText; private static float _tempBarTime; private static GameObject levelText; private static float levelTextTime; [HarmonyPrefix] [HarmonyPatch(typeof(HUDManager), "AddNewScrapFoundToDisplay")] private static void GiveXPForScrap(GrabbableObject GObject) { if (GameNetworkManager.Instance.isHostingGame) { int scrapValue = GObject.scrapValue; LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(scrapValue); } } public static void ShowXPUpdate() { if (!Object.op_Implicit((Object)(object)_tempBar)) { MakeBar(); } LC_XP xpInstance = LP_NetworkManager.xpInstance; GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/XPUpdate/XPBarProgress"); val.GetComponent<Image>().fillAmount = (float)xpInstance.teamXP.Value / (float)xpInstance.CalculateXPRequirement(); ((TMP_Text)_tempText).text = xpInstance.teamXP.Value + " / " + (float)xpInstance.CalculateXPRequirement(); _tempBarTime = 2f; if (!_tempBar.activeSelf) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(XPBarCoroutine()); } } private static IEnumerator XPBarCoroutine() { _tempBar.SetActive(true); while (_tempBarTime > 0f) { float time = _tempBarTime; _tempBarTime = 0f; yield return (object)new WaitForSeconds(time); } _tempBar.SetActive(false); } public static void ShowLevelUp() { if (!Object.op_Implicit((Object)(object)levelText)) { MakeLevelUp(); } levelTextTime = 5f; if (!levelText.gameObject.activeSelf) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(LevelUpCoroutine()); } } public static void MakeLevelUp() { levelText = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("LevelUp")); ((TMP_Text)((Component)levelText.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "Level Up! Spend your skill points."; levelText.gameObject.SetActive(false); } private static IEnumerator LevelUpCoroutine() { levelText.gameObject.SetActive(true); while (levelTextTime > 0f) { float time = levelTextTime; levelTextTime = 0f; yield return (object)new WaitForSeconds(time); } levelText.gameObject.SetActive(false); } private static void MakeBar() { //IL_0077: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) QuickMenuManagerPatch.MakeNewXPBar(); GameObject val = GameObject.Find("/Systems/UI/Canvas/QuickMenu/XpInfoContainer/XPBar"); _tempBar = Object.Instantiate<GameObject>(val); ((Object)_tempBar).name = "XPUpdate"; _tempText = _tempBar.GetComponentInChildren<TextMeshProUGUI>(); GameObject val2 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle"); _tempBar.transform.SetParent(val2.transform, false); _tempBar.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f); GameObject val3 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/XPUpdate/XPLevel"); Object.Destroy((Object)(object)val3); GameObject val4 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/XPUpdate/XPProfit"); Object.Destroy((Object)(object)val4); _tempBar.transform.Translate(3.1f, -2.1f, 0f); Vector3 localPosition = _tempBar.transform.localPosition; _tempBar.transform.localPosition = new Vector3(localPosition.x, localPosition.y + 5f, localPosition.z); _tempBar.SetActive(false); } } [HarmonyPatch] internal class QuickMenuManagerPatch { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OpenSkillTree; } private static GameObject _xpBar; private static GameObject _xpInfoContainer; private static GameObject _xpBarProgress; private static TextMeshProUGUI _xpText; private static TextMeshProUGUI _xpLevel; private static TextMeshProUGUI _profit; private static GameObject skillTreeButton; [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] private static void QuickMenuXPBar(QuickMenuManager __instance) { if (__instance.isMenuOpen) { if (!Object.op_Implicit((Object)(object)_xpBar) || !Object.op_Implicit((Object)(object)_xpBarProgress)) { MakeNewXPBar(); } _xpBar.SetActive(true); _xpBarProgress.SetActive(true); } } [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "Update")] private static void XPMenuUpdate(QuickMenuManager __instance) { if (Object.op_Implicit((Object)(object)_xpInfoContainer) && Object.op_Implicit((Object)(object)_xpBar) && Object.op_Implicit((Object)(object)_xpBarProgress)) { LC_XP xpInstance = LP_NetworkManager.xpInstance; bool activeSelf = __instance.mainButtonsPanel.activeSelf; _xpInfoContainer.SetActive(activeSelf); ((TMP_Text)_xpText).text = xpInstance.GetXP() + " / " + xpInstance.teamXPRequired.Value; ((TMP_Text)_xpLevel).text = "Level: " + xpInstance.GetLevel(); ((TMP_Text)_profit).text = "You've made.. " + xpInstance.GetProfit() + "$"; _xpBarProgress.GetComponent<Image>().fillAmount = (float)xpInstance.GetXP() / (float)xpInstance.teamXPRequired.Value; } } public static void MakeNewXPBar() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("/Systems/UI/Canvas/QuickMenu"); GameObject val2 = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/Total"); if (!Object.op_Implicit((Object)(object)_xpInfoContainer)) { _xpInfoContainer = new GameObject("XpInfoContainer"); _xpInfoContainer.transform.SetParent(val.transform, false); _xpInfoContainer.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); _xpInfoContainer.transform.Translate(-1.7f, 0.9f, 0f); } if (!Object.op_Implicit((Object)(object)_xpBar)) { GameObject val3 = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpBox"); _xpBar = Object.Instantiate<GameObject>(val3); _xpBar.transform.SetParent(_xpInfoContainer.transform, false); ((Object)_xpBar).name = "XPBar"; _xpText = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((TMP_Text)_xpText).transform.SetParent(_xpBar.transform, false); ((TMP_Text)_xpText).transform.Translate(-0.75f, 0.21f, 0f); ((Object)_xpText).name = "XPText"; ((TMP_Text)_xpText).alignment = (TextAlignmentOptions)514; ((TMP_Text)_xpText).SetText("0/1000", true); ((Graphic)_xpText).color = new Color(1f, 0.6f, 0f, 1f); _xpLevel = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((TMP_Text)_xpLevel).transform.SetParent(_xpInfoContainer.transform, false); ((TMP_Text)_xpLevel).transform.position = new Vector3(_xpBar.transform.position.x, _xpBar.transform.position.y, _xpBar.transform.position.z); ((TMP_Text)_xpLevel).transform.Translate(-0.3f, 0.2f, 0f); ((Object)_xpLevel).name = "XPLevel"; ((TMP_Text)_xpLevel).alignment = (TextAlignmentOptions)514; ((TMP_Text)_xpLevel).SetText("Level: 0", true); ((Graphic)_xpLevel).color = new Color(1f, 0.6f, 0f, 1f); _profit = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((TMP_Text)_profit).transform.SetParent(_xpInfoContainer.transform, false); ((TMP_Text)_profit).transform.position = new Vector3(_xpBar.transform.position.x, _xpBar.transform.position.y, _xpBar.transform.position.z); ((TMP_Text)_profit).transform.Translate(-0.1f, -0.2f, 0f); ((Object)_profit).name = "XPProfit"; ((TMP_Text)_profit).alignment = (TextAlignmentOptions)514; ((TMP_Text)_profit).SetText("You've made.. 0$.", true); ((Graphic)_profit).color = new Color(1f, 0.6f, 0f, 1f); } if (!Object.op_Implicit((Object)(object)_xpBarProgress)) { GameObject val4 = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpMeter"); _xpBarProgress = Object.Instantiate<GameObject>(val4); _xpBarProgress.transform.SetParent(_xpBar.transform, false); _xpBarProgress.transform.SetAsFirstSibling(); _xpBarProgress.transform.localScale = new Vector3(0.597f, 5.21f, 1f); _xpBarProgress.transform.Translate(-0.8f, 0.2f, 0f); _xpBarProgress.transform.localPosition = new Vector3(0f, 0f, 0f); ((Object)_xpBarProgress).name = "XPBarProgress"; _xpBarProgress.GetComponent<Image>().fillAmount = 0f; } } [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] private static void SkillTreeAwake(QuickMenuManager __instance) { if (__instance.isMenuOpen && !Object.op_Implicit((Object)(object)skillTreeButton)) { MakeSkillTreeButton(); } } private static void MakeSkillTreeButton() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons/Resume"); skillTreeButton = Object.Instantiate<GameObject>(val); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); skillTreeButton.transform.SetParent(val2.transform, false); skillTreeButton.transform.position = new Vector3(0.55f + _xpBar.transform.position.x, 1.09f + _xpBar.transform.position.y, _xpBar.transform.position.z); ((Object)skillTreeButton).name = "Skills"; ((TMP_Text)skillTreeButton.GetComponentInChildren<TextMeshProUGUI>()).text = "> Skills"; Transform transform = ((TMP_Text)_xpText).transform; skillTreeButton.transform.localPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z); Transform transform2 = skillTreeButton.transform; transform2.position += new Vector3(-0.15f, 1.056f); ButtonClickedEvent val3 = new ButtonClickedEvent(); object obj = <>O.<0>__OpenSkillTree; if (obj == null) { UnityAction val4 = OpenSkillTree; <>O.<0>__OpenSkillTree = val4; obj = (object)val4; } ((UnityEvent)val3).AddListener((UnityAction)obj); skillTreeButton.GetComponent<Button>().onClick = val3; Button component = _xpBar.GetComponent<Button>(); if (component == null) { component = _xpBar.AddComponent<Button>(); component.onClick = val3; } component = _xpBarProgress.GetComponent<Button>(); if (component == null) { component = _xpBarProgress.AddComponent<Button>(); component.onClick = val3; } } private static void OpenSkillTree() { LP_NetworkManager.xpInstance.guiObj.OpenSkillMenu(); } } [HarmonyPatch] internal class StartOfRoundPatch { [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "ResetMiscValues")] private static void ResetMiscValues_PrePatch() { JumpHeight.JumpHeightUpdate(0); } [HarmonyPrefix] [HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")] private static void OnShipLandedMiscEvents_PrePatch() { JumpHeight.JumpHeightUpdate(0); } } [HarmonyPatch] internal class XPPatches : NetworkBehaviour { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")] private static void ResetXPValues(StartOfRound __instance) { if (bool.Parse(SkillConfig.hostConfig["Keep progress"])) { return; } LC_XP xpInstance = LP_NetworkManager.xpInstance; int saveFileSlot = GameNetworkManager.Instance.saveFileNum + 1; SaveManager.DeleteSave(saveFileSlot); xpInstance.teamXPRequired.Value = xpInstance.CalculateXPRequirement(); foreach (Skill value in xpInstance.skillList.skills.Values) { value.SetLevel(0); } xpInstance.SetSkillPoints(5); xpInstance.teamXP.Value = 0; xpInstance.teamTotalValue.Value = 0; xpInstance.teamLevel.Value = 0; xpInstance.teamLootLevel.Value = 0; } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] private static void DisconnectXPHandler() { if (LP_NetworkManager.xpInstance.skillList.GetSkill(UpgradeType.Value).GetLevel() != 0) { int level = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetLevel(); LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(-level); } SprintSpeed.sprintSpeed = 2.25f; HandSlots.currentSlotCount = 4; GUIUpdate.isMenuOpen = false; } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] private static void ConnectClientToPlayerObjectHandler() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ulong num = SteamId.op_Implicit(SteamClient.SteamId); LethalPlugin.Log.LogInfo((object)$"Player {num} has joined the game."); LP_NetworkManager.xpInstance.requestProfileDataClientMessage.SendServer(num); } [HarmonyPostfix] [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] private static void ProfitQuotaUpdate(TimeOfDay __instance) { if (GameNetworkManager.Instance.isHostingGame) { LP_NetworkManager.xpInstance.teamXPRequired.Value = LP_NetworkManager.xpInstance.CalculateXPRequirement(); } } } } namespace LethalProgression.Config { internal class SkillConfig { public static IDictionary<string, string> hostConfig = new Dictionary<string, string>(); public static void InitConfig() { LethalPlugin.Instance.BindConfig("General", "Person Multiplier", 35, "How much does XP cost to level up go up per person?"); LethalPlugin.Instance.BindConfig("General", "Quota Multiplier", 30, "How much more XP does it cost to level up go up per quota? (Percent)"); LethalPlugin.Instance.BindConfig("General", "XP Minimum", 40, "Minimum XP to level up."); LethalPlugin.Instance.BindConfig("General", "XP Maximum", 750, "Maximum XP to level up."); LethalPlugin.Instance.BindConfig("General", "Unspec in Ship Only", defaultValue: false, "Disallows unspecing stats if you're not currently on the ship."); LethalPlugin.Instance.BindConfig("General", "Unspec in Orbit Only", defaultValue: true, "Disallows unspecing stats if you're not currently in orbit."); LethalPlugin.Instance.BindConfig("General", "Disable Unspec", defaultValue: false, "Disallows unspecing altogether."); LethalPlugin.Instance.BindConfig("General", "Keep progress", defaultValue: false, "Keep your progress on reset"); LethalPlugin.Instance.BindConfig("Health", "Health Regen Enabled", defaultValue: true, "Enable the Health Regen skill?"); LethalPlugin.Instance.BindConfig("Health", "Health Regen Max Level", 20, "Maximum level for the health regen."); LethalPlugin.Instance.BindConfig("Health", "Health Regen Multiplier", 0.05f, "How much does the health regen skill increase per level?"); LethalPlugin.Instance.BindConfig("Stamina", "Stamina Enabled", defaultValue: true, "Enable the Stamina skill?"); LethalPlugin.Instance.BindConfig("Stamina", "Stamina Max Level", 99999, "Maximum level for the stamina."); LethalPlugin.Instance.BindConfig("Stamina", "Stamina Multiplier", 2f, "How much does the stamina skill increase per level?"); LethalPlugin.Instance.BindConfig("Battery", "Battery Life Enabled", defaultValue: true, "Enable the Battery Life skill?"); LethalPlugin.Instance.BindConfig("Battery", "Battery Life Max Level", 99999, "Maximum level for the battery life."); LethalPlugin.Instance.BindConfig("Battery", "Battery Life Multiplier", 5f, "How much does the battery life skill increase per level?"); LethalPlugin.Instance.BindConfig("Hand Slots", "Hand Slots Enabled", defaultValue: true, "Enable the Hand Slots skill?"); LethalPlugin.Instance.BindConfig("Hand Slots", "Hand Slots Max Level", 30, "Maximum level for the hand slots."); LethalPlugin.Instance.BindConfig("Hand Slots", "Hand Slots Multiplier", 10f, "How much does the hand slots skill increase per level?"); LethalPlugin.Instance.BindConfig("Loot Value", "Loot Value Enabled", defaultValue: true, "Enable the Loot Value skill?"); LethalPlugin.Instance.BindConfig("Loot Value", "Loot Value Max Level", 250, "Maximum level for the loot value."); LethalPlugin.Instance.BindConfig("Loot Value", "Loot Value Multiplier", 0.1f, "How much does the loot value skill increase per level?"); LethalPlugin.Instance.BindConfig("Oxygen", "Oxygen Enabled", defaultValue: true, "Enable the Oxygen skill?"); LethalPlugin.Instance.BindConfig("Oxygen", "Oxygen Max Level", 99999, "Maximum level for Oxygen."); LethalPlugin.Instance.BindConfig("Oxygen", "Oxygen Multiplier", 1f, "How much does the Oxygen skill increase per level?"); LethalPlugin.Instance.BindConfig("Jump Height", "Jump Height Enabled", defaultValue: true, "Enable the Jump Height skill?"); LethalPlugin.Instance.BindConfig("Jump Height", "Jump Height Max Level", 99999, "Maximum level for Jump Height."); LethalPlugin.Instance.BindConfig("Jump Height", "Jump Height Multiplier", 3f, "How much does the Jump Height skill increase per level?"); LethalPlugin.Instance.BindConfig("Sprint Speed", "Sprint Speed Enabled", defaultValue: true, "Enable the Sprint Speed skill?"); LethalPlugin.Instance.BindConfig("Sprint Speed", "Sprint Speed Max Level", 99999, "Maximum level for Sprint Speed."); LethalPlugin.Instance.BindConfig("Sprint Speed", "Sprint Speed Multiplier", 0.75f, "How much does the Sprint Speed skill increase per level?"); LethalPlugin.Instance.BindConfig("Strength", "Strength Enabled", defaultValue: true, "Enable the strength skill?"); LethalPlugin.Instance.BindConfig("Strength", "Strength Max Level", 75, "Maximum level for Strength."); LethalPlugin.Instance.BindConfig("Strength", "Strength Multiplier", 1f, "How much does the Strength skill increase per level?"); } } } namespace LethalProgression.Network { internal class PlayerHandSlotData { public ulong clientId { get; set; } public int additionalSlots { get; set; } public PlayerHandSlotData(ulong clientId, int additionalSlots) { this.clientId = clientId; this.additionalSlots = additionalSlots; } } internal class PlayerJumpHeightData { public ulong clientId; public int jumpSkillValue; } internal class SaveProfileData { public ulong steamId { get; set; } public SaveData saveData { get; set; } public SaveProfileData(ulong steamId, SaveData saveData) { this.steamId = steamId; this.saveData = saveData; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }