using 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: 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.4.0")]
[assembly: AssemblyInformationalVersion("1.7.4+3d28f3ca2c1d275816917312e8d6667f14060d79")]
[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 PluginInfo
{
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)
{
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("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)
{
}
}
}