using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using LethalProgression.Config;
using LethalProgression.GUI.HandSlot;
using LethalProgression.GUI.Skills;
using LethalProgression.GUI.XPBar;
using LethalProgression.LessShitConfig;
using LethalProgression.LessShitConfig.Attributes;
using LethalProgression.LessShitConfig.Internal;
using LethalProgression.LessShitConfig.Internal.ClassBuilders;
using LethalProgression.LessShitConfig.Sources;
using LethalProgression.Network;
using LethalProgression.Patches;
using LethalProgression.Saving;
using LethalProgression.Skills;
using LethalProgression.Skills.Upgrades;
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("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2-alpha.0.13+d9fc64ffc22a27e63ed4537cede1e50604e5a186")]
[assembly: AssemblyProduct("LethalProgression")]
[assembly: AssemblyTitle("LethalProgression")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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
{
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 int skillPoints;
public SkillList skillList = new SkillList();
public bool Initialized = false;
public bool loadedSave = false;
public void Start()
{
LethalPlugin.Log.LogInfo((object)"XP Network Behavior Made!");
teamLevel.OnValueChanged += OnTeamLevelChange;
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;
playerConnectClientEvent.InvokeServer();
}
public override void OnDestroy()
{
teamLevel.OnValueChanged -= OnTeamLevelChange;
teamLootLevel.OnValueChanged -= LethalPlugin.SkillsGUI.TeamLootButtonUpdate;
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.LogDebug((object)$"Received PlayerConnect message from {clientId}");
LessShitConfigSystem.ClearHostConfigs();
string text = LessShitConfigSystem.SerializeLocalConfigs();
LethalPlugin.Log.LogDebug((object)("Sending config -> " + text));
sendConfigServerMessage.SendClient(text, clientId);
}
public void LoadSharedData()
{
SaveSharedData? saveSharedData = ES3SaveManager.LoadSharedFile();
if (!saveSharedData.HasValue)
{
LethalPlugin.Log.LogDebug((object)"Shared data is null!");
return;
}
SaveSharedData value = saveSharedData.Value;
LethalPlugin.Log.LogDebug((object)"Loading Lobby shared data.");
teamXP.Value = value.xp;
teamLevel.Value = value.level;
teamTotalValue.Value = value.quota;
teamXPRequired.Value = CalculateXPRequirement();
LethalPlugin.Log.LogDebug((object)$"{value.level} current lvl, {value.xp} XP, {value.quota} Profit, {teamXPRequired.Value} teamXPRequired");
}
public IEnumerator LoadProfileData(string data)
{
LethalPlugin.Log.LogDebug((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 + GetDefaultStartingSkillPoints())
{
LethalPlugin.Log.LogDebug((object)$"Skill check is less than current level, adding {teamLevel.Value + GetDefaultStartingSkillPoints() - (skillCheck + skillPoints)} skill points.");
skillPoints += teamLevel.Value + GetDefaultStartingSkillPoints() - (skillCheck + skillPoints);
}
LethalPlugin.SkillsGUI.UpdateAllStats();
}
public int CalculateXPRequirement()
{
int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount;
int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota;
IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
int num = connectedPlayersAmount * active.personMultiplier;
int num2 = active.minXP + num;
int num3 = timesFulfilledQuota * active.quotaMultiplier;
num2 += (int)((float)num2 * ((float)num3 / 100f));
if (num2 > active.maxXP)
{
num2 = active.maxXP;
}
LethalPlugin.Log.LogInfo((object)$"{connectedPlayersAmount} players, {timesFulfilledQuota} quotas, {active.minXP} initial cost, {num} person value, {num3} quota value, {num2} total cost.");
return num2;
}
public int GetDefaultStartingSkillPoints()
{
IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
return active.startSkillPoints;
}
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.LogDebug((object)$"[{clientId}] Requested {change} to Team Loot Value, new value: {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)
{
LessShitConfigSystem.ApplyHostConfigs(serializedConfig);
if (!Initialized)
{
Initialized = true;
LP_NetworkManager.xpInstance = this;
skillList.InitializeSkills();
if (GameNetworkManager.Instance.isHostingGame)
{
LoadSharedData();
}
teamLootLevel.OnValueChanged += LethalPlugin.SkillsGUI.TeamLootButtonUpdate;
skillPoints = teamLevel.Value + GetDefaultStartingSkillPoints();
calculateAllPlayersHandSlotsClientEvent.InvokeServer();
evaluateXPRequirementClientEvent.InvokeServer();
}
}
public void RequestSavedData_C2SMessage(ulong steamID, ulong clientId)
{
string text = ES3SaveManager.LoadPlayerFile(steamID);
PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId);
sendProfileDataServerMessage.SendClient(text, playerController.actualClientId);
}
public void LoadProfileData_S2CMessage(string saveData)
{
LethalPlugin.Log.LogDebug((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.LogDebug((object)$"Received SaveData request for {saveProfileData.steamId} with data -> {JsonConvert.SerializeObject((object)saveProfileData.saveData)}");
ES3SaveManager.Save(saveProfileData.steamId, saveProfileData.saveData);
ES3SaveManager.SaveShared(teamXP.Value, teamLevel.Value, teamTotalValue.Value);
}
}
[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_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: 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("Henny.LethalProgressionPlus", "Lethal Progression+", "1.0.0")]
internal class LethalPlugin : BaseUnityPlugin
{
private const string modGUID = "Henny.LethalProgressionPlus";
private const string modName = "Lethal Progression+";
private const string modVersion = "1.0.0";
public static AssetBundle skillBundle;
internal static ManualLogSource Log;
internal static bool ReservedSlots;
public static LethalPlugin Instance { get; private set; }
public static XPBarGUI XPBarGUI { get; private set; }
public static SkillsGUI SkillsGUI { get; private set; }
public static SlotTemplate SlotTemplate { get; private set; }
private void Awake()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
Instance = this;
XPBarGUI = new XPBarGUI();
SkillsGUI = new SkillsGUI();
SlotTemplate = new SlotTemplate();
Harmony val = new Harmony("Henny.LethalProgressionPlus");
val.PatchAll();
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
skillBundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "skillmenu"));
if ((Object)(object)skillBundle == (Object)null)
{
Log.LogFatal((object)"Failed to load custom assets.");
return;
}
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"Lethal Progression initialised.");
LessShitConfigSystem.RegisterSection<IGeneralConfig>();
LessShitConfigSystem.RegisterSection<IBatteryLifeConfig>();
LessShitConfigSystem.RegisterSection<IHandSlotsConfig>();
LessShitConfigSystem.RegisterSection<IHealthRegenConfig>();
LessShitConfigSystem.RegisterSection<IMaxHealthConfig>();
LessShitConfigSystem.RegisterSection<IJumpHeightConfig>();
LessShitConfigSystem.RegisterSection<ILootValueConfig>();
LessShitConfigSystem.RegisterSection<ISprintSpeedConfig>();
LessShitConfigSystem.RegisterSection<IStaminaConfig>();
LessShitConfigSystem.RegisterSection<IStrengthConfig>();
LessShitConfigSystem.RegisterSection<IUIConfig>();
LessShitConfigSystem.RegisterSection<IOxygenConfig>();
LessShitConfigSystem.RegisterSection<IPowerConfig>();
LessShitConfigSystem.Bake(((BaseUnityPlugin)this).Config);
LessShitConfigSystem.SerializeLocalConfigs();
Log.LogInfo((object)"Lethal Progression Config loaded.");
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
string gUID = pluginInfo.Value.Metadata.GUID;
if (gUID.Contains("ReservedItem"))
{
ReservedSlots = true;
break;
}
if (gUID.Contains("mikestweaks") && (from entry in pluginInfo.Value.Instance.Config.GetConfigEntries()
where entry.Definition.Key == "ExtraItemSlots"
where int.TryParse(entry.GetSerializedValue(), out var result) && result > 0
select entry).Any())
{
ReservedSlots = true;
break;
}
}
SaveDataMigration.MigrateOldSaves();
}
public IDictionary<string, object> GetAllConfigEntries()
{
return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)((BaseUnityPlugin)this).Config).ToDictionary((KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.Definition.Key, (KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.BoxedValue);
}
}
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.Skills
{
internal abstract class Skill
{
protected readonly Action<int> _callback;
public int CurrentLevel { get; protected set; }
public abstract string ShortName { get; }
public abstract string Name { get; }
public abstract string Attribute { get; }
public abstract string Description { get; }
public abstract UpgradeType UpgradeType { get; }
public abstract int Cost { get; }
public abstract int MaxLevel { get; }
public abstract float Multiplier { get; }
public abstract bool IsTeamShared { get; }
public Skill(Action<int> callback = null)
{
CurrentLevel = 0;
_callback = callback;
}
public float GetTrueValue()
{
return Multiplier * (float)CurrentLevel;
}
public void SetLevel(int newLevel, bool triggerHostProfileSave = true)
{
int currentLevel = CurrentLevel;
CurrentLevel = newLevel;
_callback?.Invoke(newLevel - currentLevel);
if (triggerHostProfileSave)
{
ES3SaveManager.TriggerHostProfileSave();
}
}
public void AddLevel(int change)
{
CurrentLevel += change;
_callback?.Invoke(change);
ES3SaveManager.TriggerHostProfileSave();
}
}
internal class SkillList
{
public Dictionary<UpgradeType, Skill> skills = new Dictionary<UpgradeType, Skill>();
public bool IsSkillValid(UpgradeType upgrade)
{
return skills.ContainsKey(upgrade) && skills[upgrade].CurrentLevel > 0;
}
public Skill GetSkill(UpgradeType upgrade)
{
if (!IsSkillValid(upgrade))
{
return null;
}
return skills[upgrade];
}
public Dictionary<UpgradeType, Skill> GetSkills()
{
return skills;
}
public void InitializeSkills()
{
IHealthRegenConfig active = LessShitConfigSystem.GetActive<IHealthRegenConfig>();
IMaxHealthConfig active2 = LessShitConfigSystem.GetActive<IMaxHealthConfig>();
IStaminaConfig active3 = LessShitConfigSystem.GetActive<IStaminaConfig>();
IBatteryLifeConfig active4 = LessShitConfigSystem.GetActive<IBatteryLifeConfig>();
IHandSlotsConfig active5 = LessShitConfigSystem.GetActive<IHandSlotsConfig>();
ILootValueConfig active6 = LessShitConfigSystem.GetActive<ILootValueConfig>();
IStrengthConfig active7 = LessShitConfigSystem.GetActive<IStrengthConfig>();
IJumpHeightConfig active8 = LessShitConfigSystem.GetActive<IJumpHeightConfig>();
ISprintSpeedConfig active9 = LessShitConfigSystem.GetActive<ISprintSpeedConfig>();
IOxygenConfig active10 = LessShitConfigSystem.GetActive<IOxygenConfig>();
IPowerConfig active11 = LessShitConfigSystem.GetActive<IPowerConfig>();
if (active.isEnabled)
{
skills.Add(UpgradeType.HPRegen, new HPRegen());
}
if (active2.isEnabled)
{
skills.Add(UpgradeType.MaxHealth, new MaxHP());
}
if (active3.isEnabled)
{
skills.Add(UpgradeType.Stamina, new Stamina());
}
if (active4.isEnabled)
{
skills.Add(UpgradeType.Battery, new BatteryLife());
}
if (active5.isEnabled)
{
skills.Add(UpgradeType.HandSlot, new HandSlots());
}
if (active6.isEnabled)
{
skills.Add(UpgradeType.Value, new LootValue());
}
if (active7.isEnabled)
{
skills.Add(UpgradeType.Strength, new Strength());
}
if (active8.isEnabled)
{
skills.Add(UpgradeType.JumpHeight, new JumpHeight());
}
if (active9.isEnabled)
{
skills.Add(UpgradeType.SprintSpeed, new SprintSpeed());
}
if (active10.isEnabled)
{
skills.Add(UpgradeType.Oxygen, new OxygenSkill());
}
if (active11.isEnabled)
{
skills.Add(UpgradeType.Power, new Power());
}
}
}
internal interface ISkill
{
string ShortName { get; }
string Name { get; }
string Attribute { get; }
string Description { get; }
UpgradeType UpgradeType { get; }
int Cost { get; }
int MaxLevel { get; }
float Multiplier { get; }
bool IsTeamShared { get; }
int CurrentLevel { get; set; }
}
public enum UpgradeType
{
HPRegen,
Stamina,
Battery,
HandSlot,
Value,
JumpHeight,
SprintSpeed,
Strength,
MaxHealth,
Oxygen,
Power
}
}
namespace LethalProgression.Skills.Upgrades
{
internal class BatteryLife : Skill
{
public override string ShortName => "BAT";
public override string Name => "Battery Life";
public override string Attribute => "Battery Life";
public override string Description => "The company provides you with better batteries found from exotic moons. Don't forget to recharge them AT THE SHIP'S CHARGER.";
public override UpgradeType UpgradeType => UpgradeType.Battery;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IBatteryLifeConfig active = LessShitConfigSystem.GetActive<IBatteryLifeConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IBatteryLifeConfig active = LessShitConfigSystem.GetActive<IBatteryLifeConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static float GetUseItemBatteryUsage(float defaultBatteryUsage)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery))
{
return defaultBatteryUsage;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f;
float num2 = 1f / num;
return defaultBatteryUsage * num2;
}
public static List<CodeInstruction> UseItemBatteriesOpCode(List<CodeInstruction> codes)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
FieldInfo field = typeof(Item).GetField("batteryUsage");
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUseItemBatteryUsage")));
}
}
return codes;
}
public static float GetUpdateBatteryUsage(float defaultBatteryUsage)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery))
{
return defaultBatteryUsage;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f;
return defaultBatteryUsage * num;
}
public static List<CodeInstruction> BatteryDegradeUpdateOpCode(List<CodeInstruction> codes)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
FieldInfo field = typeof(Item).GetField("batteryUsage");
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUpdateBatteryUsage")));
}
}
return codes;
}
}
internal class HandSlots : Skill
{
public static int currentSlotCount = 4;
private static float _origSlotW = -1f;
private static float _origSlotH = -1f;
private static float _origCenterX = float.MinValue;
private static float _origBaseY = float.MinValue;
private static float _origBaseZ = float.MinValue;
public override string ShortName => "HND";
public override string Name => "Hand Slot";
public override string Attribute => "Hand Slots";
public override string Description => "The company finally gives you a better belt! Fit more stuff! (One slot every 100%.)";
public override UpgradeType UpgradeType => UpgradeType.HandSlot;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IHandSlotsConfig active = LessShitConfigSystem.GetActive<IHandSlotsConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IHandSlotsConfig active = LessShitConfigSystem.GetActive<IHandSlotsConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public HandSlots()
: base(HandSlotsUpdate)
{
}
public static void HandSlotsUpdate(int updateValue)
{
if (!LethalPlugin.ReservedSlots && 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_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_0213: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
//IL_0328: Unknown result type (might be due to invalid IL or missing references)
//IL_0348: Unknown result type (might be due to invalid IL or missing references)
//IL_0360: Unknown result type (might be due to invalid IL or missing references)
//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
//IL_03eb: 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 = LethalPlugin.SlotTemplate.GetTemplateSlot();
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);
}
int num6 = array.Length;
int num7 = Mathf.Max(1, Mathf.CeilToInt(Mathf.Sqrt((float)num6 / 5f)));
int num8 = 5 * num7;
if (_origSlotW < 0f)
{
_origSlotW = ((Graphic)array[0]).rectTransform.sizeDelta.x;
_origSlotH = ((Graphic)array[0]).rectTransform.sizeDelta.y;
_origCenterX = ((Component)array[0]).transform.localPosition.x + (((Component)array[3]).transform.localPosition.x + _origSlotW - ((Component)array[0]).transform.localPosition.x) / 2f;
_origBaseY = ((Component)array[0]).transform.localPosition.y;
_origBaseZ = ((Component)array[0]).transform.localPosition.z;
}
float num9 = _origSlotW / (float)num7;
float num10 = _origSlotH / (float)num7;
float num11 = _origCenterX - (float)num8 * num9 / 2f;
for (int k = 0; k < num6; k++)
{
int num12 = k / num8;
int num13 = k % num8;
((Graphic)array[k]).rectTransform.sizeDelta = new Vector2(num9, num10);
((Component)array[k]).transform.localPosition = new Vector3(num11 + (float)num13 * num9, _origBaseY - (float)num12 * num10, _origBaseZ);
}
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;
}
}
internal class HPRegen : Skill
{
public override string ShortName => "HPR";
public override string Name => "Health Regen";
public override string Attribute => "Health Regeneration";
public override string Description => "The company installs a basic healer into your suit, letting you regenerate health slowly. Only regenerate up to your max HP.";
public override UpgradeType UpgradeType => UpgradeType.HPRegen;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IHealthRegenConfig active = LessShitConfigSystem.GetActive<IHealthRegenConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IHealthRegenConfig active = LessShitConfigSystem.GetActive<IHealthRegenConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static List<CodeInstruction> DisableBaseGameHPRegen(List<CodeInstruction> codes)
{
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Expected O, but got Unknown
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen))
{
return codes;
}
FieldInfo field = typeof(PlayerControllerB).GetField("health");
for (int i = 0; i < codes.Count; i++)
{
if (!(codes[i].opcode != OpCodes.Ldfld) && !((FieldInfo)codes[i].operand != field) && !(codes[i + 1].opcode != OpCodes.Ldc_I4) && (int)codes[i + 1].operand == 20 && !(codes[i + 2].opcode != OpCodes.Bge_S))
{
codes.Insert(i + 2, new CodeInstruction(OpCodes.Pop, (object)null));
codes.Insert(i + 3, new CodeInstruction(OpCodes.Dup, (object)null));
}
}
return codes;
}
}
internal class JumpHeight : Skill
{
public override string ShortName => "JMP";
public override string Name => "Jump Height";
public override string Attribute => "Jump Height";
public override string Description => "The company installs you with jumping boots! (The company is not responsible for any broken knees.)";
public override UpgradeType UpgradeType => UpgradeType.JumpHeight;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IJumpHeightConfig active = LessShitConfigSystem.GetActive<IJumpHeightConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IJumpHeightConfig active = LessShitConfigSystem.GetActive<IJumpHeightConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static float GetJumpForce(float defaultJumpForce)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.JumpHeight))
{
return defaultJumpForce;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight].GetTrueValue() / 100f;
return defaultJumpForce * num;
}
public static List<CodeInstruction> PlayerJumpOpCode(List<CodeInstruction> codes)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
FieldInfo field = typeof(PlayerControllerB).GetField("jumpForce");
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(JumpHeight).GetMethod("GetJumpForce")));
}
}
return codes;
}
}
internal class LootValue : Skill
{
public override string ShortName => "VAL";
public override string Name => "Loot Value";
public override string Attribute => "Loot Value";
public override string Description => "The company gives you a better pair of eyes, allowing you to see the value in things.";
public override UpgradeType UpgradeType => UpgradeType.Value;
public override int Cost => 1;
public override int MaxLevel
{
get
{
ILootValueConfig active = LessShitConfigSystem.GetActive<ILootValueConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
ILootValueConfig active = LessShitConfigSystem.GetActive<ILootValueConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => true;
public LootValue()
: base(LootValueUpdate)
{
}
public static int GetNewScrapValueMultiplier(int defaultScrapValue)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value))
{
return defaultScrapValue;
}
float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].Multiplier;
float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier;
float num2 = 1f + num / 100f;
int num3 = (int)Math.Round((float)defaultScrapValue * num2);
LethalPlugin.Log.LogDebug((object)$"Current scrap value {defaultScrapValue} multiplied by {num2} to {num3}");
return num3;
}
public static void LootValueUpdate(int change)
{
if (LP_NetworkManager.xpInstance.skillList.skills.ContainsKey(UpgradeType.Value))
{
LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(change);
}
}
}
internal class MaxHP : Skill
{
public override string ShortName => "MHP";
public override string Name => "Max Health";
public override string Attribute => "Maximum Health";
public override string Description => "The company is trialling some new inhalents from exotic moons, giving you a health boost.";
public override UpgradeType UpgradeType => UpgradeType.MaxHealth;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IMaxHealthConfig active = LessShitConfigSystem.GetActive<IMaxHealthConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IMaxHealthConfig active = LessShitConfigSystem.GetActive<IMaxHealthConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static int GetNewMaxHealth(int defaultValue)
{
if ((Object)(object)LP_NetworkManager.xpInstance == (Object)null)
{
return defaultValue;
}
Skill skill = LP_NetworkManager.xpInstance.skillList.GetSkill(UpgradeType.MaxHealth);
if (skill == null)
{
return defaultValue;
}
return (int)Math.Floor((float)defaultValue * (1f + skill.GetTrueValue() / 100f));
}
public static List<CodeInstruction> UncapMaxHealth(List<CodeInstruction> codes)
{
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
MethodInfo method = typeof(Mathf).GetMethod("Clamp", new Type[3]
{
typeof(int),
typeof(int),
typeof(int)
});
for (int i = 0; i < codes.Count; i++)
{
if (CodeInstructionExtensions.Calls(codes[i], method) && codes[i - 2].opcode == OpCodes.Ldc_I4_0 && codes[i - 1].opcode == OpCodes.Ldc_I4_S)
{
codes.Insert(i, new CodeInstruction(OpCodes.Call, (object)typeof(MaxHP).GetMethod("GetNewMaxHealth")));
break;
}
}
return codes;
}
}
[HarmonyPatch]
internal class OxygenSkill : Skill
{
private static GameObject oxygenBar;
private static float oxygen = 0f;
private static float oxygenTimer = 0f;
private static bool inWater = false;
private static bool canDrown = true;
public override string ShortName => "OXY";
public override string Name => "Oxygen";
public override string Attribute => "Oxygen (s)";
public override string Description => "The company equips you with better lungs! Stay underwater longer.";
public override UpgradeType UpgradeType => UpgradeType.Oxygen;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IOxygenConfig active = LessShitConfigSystem.GetActive<IOxygenConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IOxygenConfig active = LessShitConfigSystem.GetActive<IOxygenConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
[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 (!((NetworkBehaviour)__instance).IsOwner || (Object)(object)LP_NetworkManager.xpInstance == (Object)null)
{
return;
}
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Oxygen))
{
if (Object.op_Implicit((Object)(object)oxygenBar))
{
oxygenBar.SetActive(false);
}
return;
}
if (__instance.isPlayerDead)
{
if (Object.op_Implicit((Object)(object)oxygenBar))
{
oxygenBar.SetActive(false);
}
return;
}
Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Oxygen];
if (skill.CurrentLevel == 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();
}
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;
}
}
private static void CreateOxygenBar()
{
oxygenBar = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("OxygenBar"));
oxygenBar.SetActive(false);
}
}
[HarmonyPatch]
internal class Power : Skill
{
public override string ShortName => "PWR";
public override string Name => "Power";
public override string Attribute => "Damage";
public override string Description => "Extra time at the Company gym pays off. You hit harder. (+% damage to enemies per level.)";
public override UpgradeType UpgradeType => UpgradeType.Power;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IPowerConfig active = LessShitConfigSystem.GetActive<IPowerConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IPowerConfig active = LessShitConfigSystem.GetActive<IPowerConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
[HarmonyPrefix]
[HarmonyPatch(typeof(EnemyAI), "HitEnemy")]
private static void PowerBoostHit(ref int force, PlayerControllerB playerWhoHit)
{
if (!((Object)(object)playerWhoHit == (Object)null) && !((Object)(object)playerWhoHit != (Object)(object)GameNetworkManager.Instance.localPlayerController) && !((Object)(object)LP_NetworkManager.xpInstance == (Object)null) && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Power))
{
float num = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Power].GetTrueValue() / 100f;
force = (int)Math.Ceiling((float)force * (1f + num));
}
}
}
internal class SprintSpeed : Skill
{
public override string ShortName => "SPD";
public override string Name => "Sprint Speed";
public override string Attribute => "Sprint Speed";
public override string Description => "The company empowers you with pure steroids, run, spaceman.";
public override UpgradeType UpgradeType => UpgradeType.SprintSpeed;
public override int Cost => 1;
public override int MaxLevel
{
get
{
ISprintSpeedConfig active = LessShitConfigSystem.GetActive<ISprintSpeedConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
ISprintSpeedConfig active = LessShitConfigSystem.GetActive<ISprintSpeedConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static float GetSprintSpeed(float defaultSprintSpeed)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.SprintSpeed))
{
return defaultSprintSpeed;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.SprintSpeed].GetTrueValue() / 100f;
return defaultSprintSpeed * num;
}
public static List<CodeInstruction> PlayerSprintSpeedOpCode(List<CodeInstruction> codes)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(2.25f))
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(SprintSpeed).GetMethod("GetSprintSpeed")));
}
}
return codes;
}
}
internal class Stamina : Skill
{
public override string ShortName => "STM";
public override string Name => "Stamina";
public override string Attribute => "Stamina";
public override string Description => "Hours on that company gym finally coming into play. Allows you to run for longer, but has to regenerate it slower.";
public override UpgradeType UpgradeType => UpgradeType.Stamina;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IStaminaConfig active = LessShitConfigSystem.GetActive<IStaminaConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IStaminaConfig active = LessShitConfigSystem.GetActive<IStaminaConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public static float GetJumpStaminaUsage(float defaultJumpStaminaUsage)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina))
{
return defaultJumpStaminaUsage;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f;
float num2 = 1f / num;
return defaultJumpStaminaUsage * num2;
}
public static List<CodeInstruction> PlayerJumpStaminaOpCode(List<CodeInstruction> codes)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(0.08f))
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetJumpStaminaUsage")));
}
}
return codes;
}
public static float GetSprintTime(float defaultStaminaTime)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina))
{
return defaultStaminaTime;
}
float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f;
return defaultStaminaTime * num;
}
public static List<CodeInstruction> PlayerSprintTimeOpCode(List<CodeInstruction> codes)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
FieldInfo field = typeof(PlayerControllerB).GetField("sprintTime");
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field)
{
codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetSprintTime")));
}
}
return codes;
}
}
[HarmonyPatch]
internal class Strength : Skill
{
public override string ShortName => "STR";
public override string Name => "Strength";
public override string Attribute => "Strength";
public override string Description => "More work at the Company's gym gives you pure muscles! You can carry better. (Reduces weight by a percentage.)";
public override UpgradeType UpgradeType => UpgradeType.Strength;
public override int Cost => 1;
public override int MaxLevel
{
get
{
IStrengthConfig active = LessShitConfigSystem.GetActive<IStrengthConfig>();
return active.maxLevel;
}
}
public override float Multiplier
{
get
{
IStrengthConfig active = LessShitConfigSystem.GetActive<IStrengthConfig>();
return active.multiplier;
}
}
public override bool IsTeamShared => false;
public Strength()
: base(StrengthUpdate)
{
}
public static void StrengthUpdate(int _change = 0)
{
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Strength))
{
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 static class ES3SaveManager
{
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 = default(SaveData);
saveData.steamId = num;
saveData.skillPoints = LP_NetworkManager.xpInstance.skillPoints;
saveData.skillAllocation = new Dictionary<UpgradeType, int>();
SaveData saveData2 = saveData;
foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills)
{
LethalPlugin.Log.LogDebug((object)$"Skill is {skill.Key} and value is {skill.Value.CurrentLevel}");
saveData2.skillAllocation.Add(skill.Key, skill.Value.CurrentLevel);
}
LethalPlugin.Log.LogDebug((object)$"Invoke saveProfileDataClientMessage({num}, {JsonConvert.SerializeObject((object)saveData2)})");
LP_NetworkManager.xpInstance.saveProfileDataClientMessage.SendServer(JsonConvert.SerializeObject((object)new SaveProfileData(num, saveData2)));
}
public static void DeleteSave()
{
string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
string[] keys = ES3.GetKeys(currentSaveFileName);
string[] array = keys;
foreach (string text in array)
{
if (text.StartsWith("LethalProgression_"))
{
LethalPlugin.Log.LogDebug((object)("Found key " + text + " to delete in " + currentSaveFileName));
ES3.DeleteKey(text, currentSaveFileName);
}
}
}
public static void Save(ulong steamId, SaveData data)
{
Save(steamId, data, null);
}
public static void Save(ulong steamId, SaveData data, string overrideSaveFile)
{
string text = overrideSaveFile;
if (overrideSaveFile == null)
{
text = GameNetworkManager.Instance.currentSaveFileName;
}
LethalPlugin.Log.LogDebug((object)$"Saving player {steamId} data to {text}");
ES3.Save<string>($"LethalProgression_{steamId}_Data", JsonConvert.SerializeObject((object)data), text);
}
public static void SaveShared(SaveSharedData data, string overrideSaveFile)
{
SaveShared(data.xp, data.level, data.quota, overrideSaveFile);
}
public static void SaveShared(int xp, int level, int quota)
{
SaveShared(xp, level, quota, null);
}
public static void SaveShared(int xp, int level, int quota, string overrideSaveFile)
{
string text = overrideSaveFile;
if (overrideSaveFile == null)
{
text = GameNetworkManager.Instance.currentSaveFileName;
}
LethalPlugin.Log.LogDebug((object)("Saving to save file " + text));
ES3.Save<string>("LethalProgression_shared_Data", JsonConvert.SerializeObject((object)new SaveSharedData(xp, level, quota)), text);
}
public static string LoadPlayerFile(ulong steamId)
{
string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
if (!ES3.KeyExists($"LethalProgression_{steamId}_Data", currentSaveFileName))
{
LethalPlugin.Log.LogDebug((object)$"Player file for {steamId} doesn't exist");
return null;
}
LethalPlugin.Log.LogDebug((object)$"Player file for {steamId} found");
return (string)ES3.Load($"LethalProgression_{steamId}_Data", currentSaveFileName);
}
public static SaveSharedData? LoadSharedFile()
{
string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
if (!ES3.KeyExists("LethalProgression_shared_Data", currentSaveFileName))
{
LethalPlugin.Log.LogDebug((object)"Shared file doesn't exist");
return null;
}
LethalPlugin.Log.LogDebug((object)"Shared file exists");
string text = (string)ES3.Load("LethalProgression_shared_Data", currentSaveFileName);
return JsonConvert.DeserializeObject<SaveSharedData>(text);
}
}
internal struct SaveData
{
public ulong steamId;
public int skillPoints;
public Dictionary<UpgradeType, int> skillAllocation;
public SaveData(ulong steamId, int skillPoints)
{
skillAllocation = new Dictionary<UpgradeType, int>();
this.steamId = steamId;
this.skillPoints = skillPoints;
}
public override readonly string ToString()
{
string text = "";
foreach (UpgradeType key in skillAllocation.Keys)
{
text += $" | {key}: {skillAllocation[key]}";
}
return $"skillPoints: {skillPoints} | Stats {text}";
}
}
internal static class SaveDataMigration
{
public static void MigrateOldSaves()
{
LethalPlugin.Log.LogInfo((object)"Checking for legacy save files to migrate.");
if (!Directory.Exists(Application.persistentDataPath + "/lethalprogression"))
{
LethalPlugin.Log.LogInfo((object)"No legacy save files found to migrate. ");
return;
}
List<string> list = new List<string>(Directory.EnumerateDirectories(Application.persistentDataPath + "/lethalprogression", "save*"));
if (list.Count == 0)
{
LethalPlugin.Log.LogInfo((object)"No legacy save files found to migrate. ");
return;
}
LethalPlugin.Log.LogInfo((object)$"Found {list.Count} saves to migrate.");
foreach (string item in list)
{
string text = item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1);
LethalPlugin.Log.LogInfo((object)("Found " + text + " in " + item + " to migrate."));
if (text.StartsWith("save"))
{
LethalPlugin.Log.LogWarning((object)("Found save: " + text + " - now migrating to ES3"));
MigrateSave(item);
}
}
}
public static void MigrateSave(string dir)
{
string text = dir.Substring(dir.LastIndexOf(Path.DirectorySeparatorChar) + 1);
text = text.Replace("save", "LCSaveFile");
List<string> list = new List<string>(Directory.EnumerateFiles(dir));
foreach (string item in list)
{
string text2 = item.Substring(item.LastIndexOf(Path.DirectorySeparatorChar) + 1);
text2 = text2.Replace(".json", "");
if (text2 == "shared")
{
LethalPlugin.Log.LogInfo((object)("Found shared data at " + item));
string text3 = File.ReadAllText(item);
SaveSharedData saveSharedData = JsonConvert.DeserializeObject<SaveSharedData>(text3);
LethalPlugin.Log.LogInfo((object)$"Old data: {saveSharedData}");
ES3SaveManager.SaveShared(saveSharedData, text);
}
else
{
LethalPlugin.Log.LogInfo((object)("Found player data at " + item));
string text4 = File.ReadAllText(item);
ulong.TryParse(text2, out var result);
LethalPlugin.Log.LogInfo((object)$"Parsed Steam ID: {result}");
SaveData saveData = JsonConvert.DeserializeObject<SaveData>(text4);
LethalPlugin.Log.LogInfo((object)$"Old data: {saveData}");
ES3SaveManager.Save(result, saveData, text);
}
File.Delete(item);
}
Directory.Delete(dir);
}
}
internal struct SaveSharedData
{
public int xp;
public int level;
public int quota;
public SaveSharedData(int xp, int level, int quota)
{
this.xp = xp;
this.level = level;
this.quota = quota;
}
}
}
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)
{
return;
}
IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
if (!active.disableEnemyXPGain)
{
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 GameNetworkManagerPatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
[HarmonyPriority(800)]
private static void DisconnectXPHandler()
{
if (LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value))
{
int currentLevel = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].CurrentLevel;
LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(-currentLevel);
}
HandSlots.currentSlotCount = 4;
LethalPlugin.SkillsGUI.CleanupGUI();
LethalPlugin.SkillsGUI.CloseSkillMenu();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameNetworkManager), "SaveGame")]
[HarmonyPriority(800)]
private static void SaveGamePrefix()
{
LethalPlugin.Log.LogDebug((object)"Invoked DoSave via SaveGame");
ES3SaveManager.TriggerHostProfileSave();
}
}
[HarmonyPatch]
internal class GrabbableObjectPatch
{
[HarmonyTranspiler]
[HarmonyPatch(typeof(GrabbableObject), "UseItemBatteries")]
private static IEnumerable<CodeInstruction> UseItemBatteriesTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
return BatteryLife.UseItemBatteriesOpCode(codes);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(GrabbableObject), "Update")]
private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
return BatteryLife.BatteryDegradeUpdateOpCode(codes);
}
}
[HarmonyPatch]
internal class HangarShipDoorPatch
{
}
[HarmonyPatch]
internal class HUDManagerPatch
{
private static GameObject _tempBar;
private static GameObject _bottomMiddle;
private static TextMeshProUGUI _tempText;
private static float _tempBarTime;
private static GameObject levelUpAsset;
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;
ILootValueConfig active = LessShitConfigSystem.GetActive<ILootValueConfig>();
int num = scrapValue;
if (active.isEnabled)
{
float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].Multiplier;
float num2 = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier;
float num3 = 1f + num2 / 100f;
num = (int)Math.Floor((float)scrapValue / num3);
}
LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num);
}
}
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/BottomMiddleXPStatus/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()
{
IUIConfig active = LessShitConfigSystem.GetActive<IUIConfig>();
if (!active.levelUpDisabled)
{
if (!Object.op_Implicit((Object)(object)levelText))
{
MakeLevelUp();
}
levelTextTime = 5f;
if (!levelText.gameObject.activeSelf)
{
((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(LevelUpCoroutine());
}
}
}
public static void MakeLevelUp()
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
levelUpAsset = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("LevelUp"));
IUIConfig active = LessShitConfigSystem.GetActive<IUIConfig>();
int num = active.levelUpPosition;
if (num < 0 || num > 1)
{
LethalPlugin.Log.LogWarning((object)$"[Invalid Config] Level Up Position value given {active.levelUpPosition} out of range (0-1)");
num = 1;
}
levelText = ((Component)levelUpAsset.transform.GetChild(num)).gameObject;
levelText.transform.GetChild(0).localScale = new Vector3(active.levelUpScale, active.levelUpScale, 1f);
levelText.transform.GetChild(1).localScale = new Vector3(active.levelUpScale, active.levelUpScale, 1f);
((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_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: 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_01ea: 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)
LethalPlugin.XPBarGUI.CreateAllObjectsIfRequired();
GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD");
GameObject val2 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle");
_bottomMiddle = Object.Instantiate<GameObject>(val2);
_bottomMiddle.transform.SetParent(val.transform, false);
((Object)_bottomMiddle).name = "BottomMiddleXPStatus";
foreach (Transform item in _bottomMiddle.transform)
{
Transform val3 = item;
Object.Destroy((Object)(object)((Component)val3).gameObject);
}
GameObject val4 = GameObject.Find("/Systems/UI/Canvas/QuickMenu/XpInfoContainer/XPBar");
_tempBar = Object.Instantiate<GameObject>(val4);
((Object)_tempBar).name = "XPUpdate";
_tempBar.SetActive(false);
_tempText = _tempBar.GetComponentInChildren<TextMeshProUGUI>();
_tempBar.transform.SetParent(_bottomMiddle.transform, false);
_tempBar.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
GameObject val5 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPLevel");
Object.Destroy((Object)(object)val5);
GameObject val6 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPProfit");
Object.Destroy((Object)(object)val6);
Vector3 localPosition = _bottomMiddle.transform.localPosition;
float x = _bottomMiddle.GetComponent<RectTransform>().sizeDelta.x;
float x2 = _tempBar.GetComponent<RectTransform>().sizeDelta.x;
LethalPlugin.Log.LogInfo((object)$"Move Bar {x} {x2}");
_tempBar.transform.Translate(0f, 0f, 0f);
_tempBar.transform.localPosition = new Vector3(x + 50f, localPosition.y - 30f, localPosition.z);
}
}
[HarmonyPatch]
internal class PlayerControllerBPatch
{
[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);
}
[HarmonyTranspiler]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static IEnumerable<CodeInstruction> PlayerJumpTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
return JumpHeight.PlayerJumpOpCode(codes);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")]
private static IEnumerable<CodeInstruction> Jump_performedTransplier(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
return Stamina.PlayerJumpStaminaOpCode(codes);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
codes = JumpHeight.PlayerJumpOpCode(codes);
return SprintSpeed.PlayerSprintSpeedOpCode(codes);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
private static IEnumerable<CodeInstruction> LateUpdateTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
codes = HPRegen.DisableBaseGameHPRegen(codes);
return Stamina.PlayerSprintTimeOpCode(codes);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
private static IEnumerable<CodeInstruction> DamagePlayerTranspiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> codes = new List<CodeInstruction>(instructions);
return MaxHP.UncapMaxHealth(codes);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
private static void HPRegenUpdate(PlayerControllerB __instance)
{
if (!((NetworkBehaviour)__instance).IsOwner || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject) || !__instance.isPlayerControlled || __instance.isPlayerDead)
{
return;
}
int newMaxHealth = MaxHP.GetNewMaxHealth(100);
if (__instance.health > newMaxHealth)
{
__instance.health = newMaxHealth;
HUDManager.Instance.UpdateHealthUI(__instance.health, false);
}
if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen))
{
return;
}
if (__instance.health < 20 && __instance.healthRegenerateTimer > 1f)
{
__instance.healthRegenerateTimer = 1f;
}
if (__instance.healthRegenerateTimer > 0f)
{
__instance.healthRegenerateTimer -= Time.deltaTime;
return;
}
if (__instance.health >= 20)
{
__instance.MakeCriticallyInjured(false);
}
if (__instance.health < newMaxHealth)
{
Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.HPRegen];
float num = 1f / skill.GetTrueValue();
if (__instance.health < 20 && num > 1f)
{
num = 1f;
}
__instance.healthRegenerateTimer = num;
__instance.health++;
HUDManager.Instance.UpdateHealthUI(__instance.health, false);
}
}
}
[HarmonyPatch]
internal class QuickMenuManagerPatch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
private static void OpenQuickMenu_Postfix(QuickMenuManager __instance)
{
if (__instance.isMenuOpen)
{
LethalPlugin.XPBarGUI.Show();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(QuickMenuManager), "Update")]
private static void QuickMenuManager_Postfix(QuickMenuManager __instance)
{
LethalPlugin.XPBarGUI.Update(__instance.mainButtonsPanel.activeSelf);
if (!LethalPlugin.SkillsGUI.isMenuOpen)
{
LethalPlugin.SkillsGUI.CloseSkillMenu();
return;
}
IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
if (active.enableUnspecInShip && !active.disableUnspec)
{
if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
{
LethalPlugin.SkillsGUI.SetUnspec(show: true);
}
else
{
LethalPlugin.SkillsGUI.SetUnspec(show: false);
}
}
if (active.enableUnspecInOrbit)
{
if (StartOfRound.Instance.inShipPhase)
{
LethalPlugin.SkillsGUI.SetUnspec(show: true);
}
else
{
LethalPlugin.SkillsGUI.SetUnspec(show: false);
}
}
if (active.disableUnspec)
{
LethalPlugin.SkillsGUI.SetUnspec(show: false);
}
LethalPlugin.SkillsGUI.OpenSkillMenu();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
private static void SkillMenuClose()
{
LethalPlugin.SkillsGUI.CloseSkillMenu();
}
}
[HarmonyPatch]
internal class RoundManagerPatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(RoundManager), "waitForScrapToSpawnToSync")]
[HarmonyPriority(0)]
public static void OnWaitForScrapToSpawnToSync(ref NetworkObjectReference[] spawnedScrap, ref int[] scrapValues)
{
List<int> list = new List<int>();
for (int i = 0; i < scrapValues.Length; i++)
{
list.Add(LootValue.GetNewScrapValueMultiplier(scrapValues[i]));
}
scrapValues = list.ToArray();
}
}
[HarmonyPatch]
internal class StartOfRoundPatch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")]
private static void ResetXPValues()
{
IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>();
if (active.keepProgress)
{
return;
}
LC_XP xpInstance = LP_NetworkManager.xpInstance;
ES3SaveManager.DeleteSave();
xpInstance.teamXPRequired.Value = xpInstance.CalculateXPRequirement();
foreach (Skill value in xpInstance.skillList.skills.Values)
{
value.SetLevel(0, triggerHostProfileSave: false);
}
LethalPlugin.SkillsGUI.UpdateAllStats();
ES3SaveManager.TriggerHostProfileSave();
xpInstance.SetSkillPoints(xpInstance.GetDefaultStartingSkillPoints());
xpInstance.teamXP.Value = 0;
xpInstance.teamTotalValue.Value = 0;
xpInstance.teamLevel.Value = 0;
xpInstance.teamLootLevel.Value = 0;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StartOfRound), "ReviveDeadPlayers")]
private static void ReviveDeadPlayersPostfix()
{
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
int num = (localPlayerController.health = MaxHP.GetNewMaxHealth(100));
HUDManager.Instance.UpdateHealthUI(num, false);
}
}
[HarmonyPatch]
internal class TimeOfDayPatch
{
[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.LessShitConfig
{
public static class LessShitConfigSystem
{
private static readonly IDictionary<ConfigDefinition, ConfigEntryData> entries = new Dictionary<ConfigDefinition, ConfigEntryData>();
private static readonly IDictionary<Type, ConfigSectionData> sections = new Dictionary<Type, ConfigSectionData>();
private static readonly IDictionary<Type, LocalConfigBase> localSections = new Dictionary<Type, LocalConfigBase>();
private static readonly IDictionary<Type, DictionaryOverlayConfigBase> activeSections = new Dictionary<Type, DictionaryOverlayConfigBase>();
private static readonly IDictionary<ConfigDefinition, object> hostConfigOverlay = new Dictionary<ConfigDefinition, object>();
public static object ActiveConfig { get; internal set; }
public static void RegisterSection<T>()
{
Type typeFromHandle = typeof(T);
LethalPlugin.Log.LogDebug((object)("RegisterSection: " + typeFromHandle.FullName));
if (sections.ContainsKey(typeFromHandle))
{
throw new ConfigRegistrationException("The config section defintion has already been registered: " + typeFromHandle.FullName);
}
ConfigSectionData configSectionData = new ConfigSectionData(typeFromHandle);
sections[typeFromHandle] = configSectionData;
foreach (ConfigEntryData entry in configSectionData.Entries)
{
entries[entry.Definition] = entry;
}
}
public static void Bake(ConfigFile configFile)
{
if (configFile == null)
{
throw new ArgumentNullException("config");
}
if (localSections.Count > 0)
{
throw new InvalidOperationException("Calling Bind multiple times is not allowed.");
}
foreach (ConfigEntryData value in entries.Values)
{
value.Bind(configFile);
}
foreach (KeyValuePair<Type, ConfigSectionData> section in sections)
{
LocalConfigSectionClassBuilder localConfigSectionClassBuilder = new LocalConfigSectionClassBuilder(section.Value, configFile);
foreach (ConfigEntryData entry in section.Value.Entries)
{
localConfigSectionClassBuilder.AddEntry(entry);
}
LocalConfigBase localConfigBase = localConfigSectionClassBuilder.Build();
localSections[section.Key] = localConfigBase;
DictionaryOverlayConfigSectionClassBuilder dictionaryOverlayConfigSectionClassBuilder = new DictionaryOverlayConfigSectionClassBuilder(section.Value, localConfigBase, hostConfigOverlay);
foreach (ConfigEntryData entry2 in section.Value.Entries)
{
dictionaryOverlayConfigSectionClassBuilder.AddEntry(entry2);
}
activeSections[section.Key] = dictionaryOverlayConfigSectionClassBuilder.Build();
}
}
internal static T GetActive<T>()
{
return (T)(object)activeSections[typeof(T)];
}
internal static string SerializeLocalConfigs()
{
IDictionary<string, IDictionary<string, string>> dictionary = new Dictionary<string, IDictionary<string, string>>();
foreach (ConfigEntryData value2 in entries.Values)
{
string section = value2.Definition.Section;
if (!(section == "UI"))
{
string key = value2.Definition.Key;
if (!dictionary.ContainsKey(section))
{
dictionary[section] = new Dictionary<string, string>();
}
object value = localSections[value2.Section.InterfaceType].GetValue(value2.Definition);
dictionary[section][key] = TomlTypeConverter.ConvertToString(value, value2.Property.PropertyType);
}
}
return JsonConvert.SerializeObject((object)dictionary);
}
internal static void ApplyHostConfigs(string configString)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
IDictionary<string, IDictionary<string, string>> dictionary = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, string>>>(configString);
foreach (KeyValuePair<string, IDictionary<string, string>> item in dictionary)
{
foreach (KeyValuePair<string, string> item2 in item.Value)
{
ConfigDefinition val = new ConfigDefinition(item.Key, item2.Key);
Type propertyType = entries[val].Property.PropertyType;
hostConfigOverlay[val] = TomlTypeConverter.ConvertToValue(item2.Value, propertyType);
LethalPlugin.Log.LogInfo((object)$"Applied host config override: {val} = {item2.Value}");
}
}
}
internal static void ClearHostConfigs()
{
hostConfigOverlay.Clear();
LethalPlugin.Log.LogInfo((object)"Cleared host config overrides");
}
}
}
namespace LethalProgression.LessShitConfig.Internal
{
public class ConfigEntryData
{
public readonly ConfigSectionData Section;
public readonly PropertyInfo Property;
public readonly ConfigDefinition Definition;
public readonly ConfigDescription Description;
public readonly object DefaultValue;
public ConfigEntryData(ConfigSectionData section, PropertyInfo property)
{
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Expected O, but got Unknown
if (!TomlTypeConverter.CanConvert(property.PropertyType))
{
throw new ConfigRegistrationException("There is no TOML converter registered for " + property.PropertyType.FullName + " entries: " + section.InterfaceType.FullName);
}
if (property.CanWrite)
{
throw new ConfigRegistrationException("Config section entries must not have property setter: (" + property.Name + " in " + section.InterfaceType.FullName + ")");
}
if (!property.CanRead)
{
throw new ConfigRegistrationException("Config section entries must have property getter: (" + property.Name + " in " + section.InterfaceType.FullName + ")");
}
ConfigNameAttribute customAttribute = property.GetCustomAttribute<ConfigNameAttribute>();
if (customAttribute == null)
{
throw new ConfigRegistrationException("Config section must have a named defined with Configname (" + property.Name + " in " + section.InterfaceType.FullName + ")");
}
ConfigDescriptionAttribute customAttribute2 = property.GetCustomAttribute<ConfigDescriptionAttribute>();
ConfigDefaultAttribute customAttribute3 = property.GetCustomAttribute<ConfigDefaultAttribute>(inherit: true);
LethalPlugin.Log.LogDebug((object)("Register Property: " + section.Name + " " + customAttribute.name));
Section = section;
Property = property;
Definition = new ConfigDefinition(section.Name, customAttribute.name);
Description = customAttribute2?.Description;
DefaultValue = ResolveDefaultValue(customAttribute3);
}
private object ResolveDefaultValue(ConfigDefaultAttribute defaultValue)
{
if (defaultValue != null)
{
return defaultValue.Value;
}
return Property.PropertyType.IsValueType ? Activator.CreateInstance(Property.PropertyType) : null;
}
public void Bind(ConfigFile file)
{
MethodInfo methodInfo = typeof(ConfigFile).GetMethod("Bind", new Type[3]
{
typeof(ConfigDefinition),
Type.MakeGenericMethodParameter(0),
typeof(ConfigDescription)
}).MakeGenericMethod(Property.PropertyType);
methodInfo.Invoke(file, new List<object> { Definition, DefaultValue, Description }.ToArray());
}
}
public class ConfigRegistrationException : Exception
{
public ConfigRegistrationException(string message)
: base(message)
{
}
}
public class ConfigSectionData
{
public readonly Type InterfaceType;
public readonly ICollection<ConfigEntryData> Entries;
public readonly string Name;
public ConfigDescription Description { get; private set; }
public ConfigSectionData(Type type)
{
if (!type.IsInterface)
{
throw new ConfigRegistrationException("Config section definitions must be interfaces: " + type.FullName);
}
ConfigSectionAttribute customAttribute = type.GetCustomAttribute<ConfigSectionAttribute>();
if (customAttribute == null)
{
throw new ConfigRegistrationException("Cannot register a config section without a ConfigSection attribute: " + type.FullName);
}
Name = customAttribute.section;
InterfaceType = type;
Entries = new List<ConfigEntryData>();
MemberInfo[] members = type.GetMembers();
foreach (MemberInfo memberInfo in members)
{
if (memberInfo.MemberType != MemberTypes.Property)
{
if (memberInfo.MemberType != MemberTypes.Method || !((MethodInfo)memberInfo).Name.StartsWith("get_"))
{
throw new ConfigRegistrationException($"Non-property members are not allowed in config section definitions: ({memberInfo.Name} is {memberInfo.MemberType})");
}
}
else
{
LethalPlugin.Log.LogDebug((object)("Register: " + type.Name + " = " + memberInfo.Name));
ConfigEntryData item = new ConfigEntryData(this, (PropertyInfo)memberInfo);
Entries.Add(item);
}
}
}
}
}
namespace LethalProgression.LessShitConfig.Internal.ClassBuilders
{
public abstract class ConfigSectionClassBuilder
{
protected static readonly MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName;
protected static readonly MethodInfo AbstractConfigBase_GetDefinitionMethod = typeof(AbstractConfigBase).GetMethod("GetDefinition", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
protected readonly TypeBuilder typeBuilder;
protected readonly ILGenerator constructorGenerator;
protected readonly ConfigSectionData sectionData;
protected abstract Type ConfigBaseType { get; }
protected abstract ConstructorInfo BaseConstructor { get; }
public ConfigSectionClassBuilder(ConfigSectionData section)
{
sectionData = section;
string text = "DynamicConfigClass_" + ConfigBaseType.Name + "_" + section.Name;
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(text), AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(text);
typeBuilder = moduleBuilder.DefineType(ConfigBaseType.Name + "_" + section.Name, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.BeforeFieldInit, ConfigBaseType, new Type[1] { section.InterfaceType });
Type[] parameterTypes = (from param in BaseConstructor.GetParameters()
select param.ParameterType).ToArray();
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, parameterTypes);
constructorGenerator = constructorBuilder.GetILGenerator();
AppendBaseConstructorOpcodes();
}
protected abstract void AppendBaseConstructorOpcodes();
public void AddEntry(ConfigEntryData entry)
{
PropertyInfo property = entry.Property;
Type propertyType = property.PropertyType;
string fieldName = "Definition_" + property.Name;
FieldBuilder field = typeBuilder.DefineField(fieldName, typeof(ConfigDefinition), FieldAttributes.Private);
MethodInfo methodInfo = ConfigBaseType.GetMethods().First((MethodInfo m) => m.Name == "GetValue" && m.IsGenericMethod);
constructorGenerator.Emit(OpCodes.Ldarg_0);
constructorGenerator.Emit(OpCodes.Ldarg_0);
constructorGenerator.Emit(OpCodes.Ldstr, entry.Definition.Key);
constructorGenerator.Emit(OpCodes.Callvirt, AbstractConfigBase_GetDefinitionMethod);
constructorGenerator.Emit(OpCodes.Stfld, field);
string name = "get_" + property.Name;
MethodBuilder methodBuilder = typeBuilder.DefineMethod(name, propertyMethodAttributes, propertyType, Type.EmptyTypes);
ILGenerator iLGenerator = methodBuilder.GetILGenerator();
iLGenerator.Emit(OpCodes.Ldarg_0);
iLGenerator.Emit(OpCodes.Ldarg_0);
iLGenerator.Emit(OpCodes.Ldfld, field);
iLGenerator.Emit(OpCodes.Callvirt, methodInfo.MakeGenericMethod(propertyType));
iLGenerator.Emit(OpCodes.Ret);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.None, propertyType, Type.EmptyTypes);
propertyBuilder.SetGetMethod(methodBuilder);
}
public AbstractConfigBase Build()
{
constructorGenerator.Emit(OpCodes.Ret);
Type type = typeBuilder.CreateType();
return ConstructGeneratedType(type);
}
protected abstract AbstractConfigBase ConstructGeneratedType(Type type);
}
public class DictionaryOverlayConfigSectionClassBuilder : ConfigSectionClassBuilder
{
private readonly AbstractConfigBase baseConfig;
private readonly IDictionary<ConfigDefinition, object> overlay;
protected override Type ConfigBaseType => typeof(DictionaryOverlayConfigBase);
protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[3]
{
typeof(string),
typeof(AbstractConfigBase),
typeof(Dictionary<ConfigDefinition, object>)
});
public DictionaryOverlayConfigSectionClassBuilder(ConfigSectionData section, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay)
: base(section)
{
this.baseConfig = baseConfig;
this.overlay = overlay;
}
protected override void AppendBaseConstructorOpcodes()
{
constructorGenerator.Emit(OpCodes.Ldarg_0);
constructorGenerator.Emit(OpCodes.Ldarg_1);
constructorGenerator.Emit(OpCodes.Ldarg_2);
constructorGenerator.Emit(OpCodes.Ldarg_3);
constructorGenerator.Emit(OpCodes.Call, BaseConstructor);
}
protected override AbstractConfigBase ConstructGeneratedType(Type type)
{
return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, baseConfig, overlay);
}
public new DictionaryOverlayConfigBase Build()
{
return (DictionaryOverlayConfigBase)base.Build();
}
}
public class LocalConfigSectionClassBuilder : ConfigSectionClassBuilder
{
private readonly ConfigFile configFile;
protected override Type ConfigBaseType => typeof(LocalConfigBase);
protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[2]
{
typeof(string),
typeof(ConfigFile)
});
public LocalConfigSectionClassBuilder(ConfigSectionData section, ConfigFile config)
: base(section)
{
configFile = config;
}
protected override void AppendBaseConstructorOpcodes()
{
constructorGenerator.Emit(OpCodes.Ldarg_0);
constructorGenerator.Emit(OpCodes.Ldarg_1);
constructorGenerator.Emit(OpCodes.Ldarg_2);
constructorGenerator.Emit(OpCodes.Call, BaseConstructor);
}
protected override AbstractConfigBase ConstructGeneratedType(Type type)
{
return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, configFile);
}
public new LocalConfigBase Build()
{
return (LocalConfigBase)base.Build();
}
}
}
namespace LethalProgression.LessShitConfig.Sources
{
public abstract class AbstractConfigBase
{
private string sectionName;
protected AbstractConfigBase(string sectionName)
{
this.sectionName = sectionName;
}
protected ConfigDefinition GetDefinition(string key)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
return new ConfigDefinition(sectionName, key);
}
public abstract object GetValue(ConfigDefinition definition);
public abstract T GetValue<T>(ConfigDefinition definition);
}
public abstract class DictionaryOverlayConfigBase : AbstractConfigBase
{
private readonly AbstractConfigBase baseConfig;
private readonly IDictionary<ConfigDefinition, object> overlay;
public DictionaryOverlayConfigBase(string sectionName, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay)
: base(sectionName)
{
this.baseConfig = baseConfig;
this.overlay = overlay;
}
public override object GetValue(ConfigDefinition definition)
{
if (overlay.TryGetValue(definition, out var value))
{
return value;
}
return baseConfig.GetValue(definition);
}
public override T GetValue<T>(ConfigDefinition definition)
{
if (overlay.TryGetValue(definition, out var value))
{
return (T)value;
}
return baseConfig.GetValue<T>(definition);
}
}
public abstract class LocalConfigBase : AbstractConfigBase
{
private readonly ConfigFile configFile;
public LocalConfigBase(string sectionName, ConfigFile config)
: base(sectionName)
{
configFile = config;
}
public override object GetValue(ConfigDefinition definition)
{
IDictionary<ConfigDefinition, ConfigEntryBase> dictionary = (IDictionary<ConfigDefinition, ConfigEntryBase>)configFile;
if (dictionary.TryGetValue(definition, out var value))
{
return value.BoxedValue;
}
throw new ArgumentException($"The config entry {definition} is not registered.", "definition");
}
public override T GetValue<T>(ConfigDefinition definition)
{
ConfigEntry<T> val = default(ConfigEntry<T>);
if (configFile.TryGetEntry<T>(definition, ref val))
{
return val.Value;
}
throw new ArgumentException($"The config entry {definition} is not registered.", "definition");
}
}
}
namespace LethalProgression.LessShitConfig.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
public class ConfigDefaultAttribute : Attribute
{
public object Value;
public ConfigDefaultAttribute(object value)
{
Value = value;
}
}
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigDescriptionAttribute : Attribute
{
public readonly ConfigDescription Description;
public ConfigDescriptionAttribute(string description)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
Description = new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>());
}
}
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigNameAttribute : Attribute
{
public readonly string name;
public ConfigNameAttribute(string name)
{
this.name = name;
}
}
[AttributeUsage(AttributeTargets.Interface)]
internal class ConfigSectionAttribute : Attribute
{
public readonly string section;
public ConfigSectionAttribute(string section)
{
this.section = section;
}
}
}
namespace LethalProgression.GUI.XPBar
{
internal class XPBarGUI
{
[CompilerGenerated]
private static class <>O
{
public static UnityAction <0>__OpenSkillTree;
}
private GameObject xpBar;
private GameObject xpInfoContainer;
private GameObject xpBarProgress;
private GameObject skillTreeButton;
private TextMeshProUGUI xpText;
private TextMeshProUGUI xpLevel;
private TextMeshProUGUI profit;
public void Show()
{
CreateAllObjectsIfRequired();
xpBar.SetActive(true);
xpBarProgress.SetActive(true);
}
public void Update(bool active)
{
CreateAllObjectsIfRequired();
LC_XP xpInstance = LP_NetworkManager.xpInstance;
xpInfoContainer.SetActive(active);
((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;
}
private void CreateContainer()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)xpInfoContainer))
{
GameObject val = GameObject.Find("/Systems/UI/Canvas/QuickMenu");
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);
}
}
private void CreateXPBar()
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Unknown result type (might be due