Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of UltimateLethal CrewMorale v0.1.6
UltimateLethal.CrewMorale.dll
Decompiled 5 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("UltimateLethal.CrewMorale")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("UltimateLethal.CrewMorale")] [assembly: AssemblyTitle("UltimateLethal.CrewMorale")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace UltimateLethal.CrewMorale { [BepInPlugin("ultimatelethal.crewmorale", "Ultimate Lethal Crew Morale", "0.1.6")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class CrewMoralePlugin : BaseUnityPlugin { public const string Guid = "ultimatelethal.crewmorale"; public const string Name = "Ultimate Lethal Crew Morale"; public const string Version = "0.1.6"; internal static CrewMoralePlugin Instance; internal static ConfigEntry<float> StartingMorale; internal static ConfigEntry<float> MinimumMorale; internal static ConfigEntry<float> MaximumMorale; internal static ConfigEntry<float> DecorationPriceScaleCredits; internal static ConfigEntry<float> DecorationPriceExponent; internal static ConfigEntry<float> DecorationMaxMoraleEach; internal static ConfigEntry<float> DecorationBonusCap; internal static ConfigEntry<float> DeathPenalty; internal static ConfigEntry<float> ReunionReward; internal static ConfigEntry<float> QuotaFulfilledReward; internal static ConfigEntry<float> FullCrewShipRecoveryPerSecond; internal static ConfigEntry<float> OrbitRecoveryPerSecond; internal static ConfigEntry<float> EmptyShipDecayPerSecond; internal static ConfigEntry<float> HighMoraleSanityGainMultiplier; internal static ConfigEntry<float> LowMoraleSanityGainMultiplier; internal static ConfigEntry<float> HighMoraleRecoveryMultiplier; internal static ConfigEntry<float> LowMoraleRecoveryMultiplier; internal static ConfigEntry<bool> ShowHud; internal static ConfigEntry<float> HudX; internal static ConfigEntry<float> HudY; internal static ConfigEntry<float> HudWidth; internal static ConfigEntry<float> HudHeight; internal static ConfigEntry<float> SanityHudRaisePixels; private Harmony _harmony; private float _nextStateTick; private bool _wasFullLivingCrewInShip; private bool _wasLanded; private bool _someoneLeftShipThisExpedition; private bool _expeditionHadDeath; private bool _reunionAwardedThisExpedition; private int _expeditionStartingCrewCount; private readonly HashSet<PlayerControllerB> _expeditionRoster = new HashSet<PlayerControllerB>(); private readonly HashSet<PlayerControllerB> _countedDeadPlayers = new HashSet<PlayerControllerB>(); private bool _quotaStateInitialized; private bool _quotaWasFulfilled; private float _previousDecorationBonus = -1f; private float _eventUntil; private string _eventTitle = ""; private string _eventDetail = ""; private GUIStyle _labelStyle; private GUIStyle _smallStyle; private GUIStyle _eventTitleStyle; private GUIStyle _eventDetailStyle; private Texture2D _pixel; internal static float Morale { get; private set; } = 55f; internal static float DecorationBaseline { get; private set; } = 0f; internal static int DecorationCount { get; private set; } = 0; private void Awake() { //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown Instance = this; StartingMorale = ((BaseUnityPlugin)this).Config.Bind<float>("Morale", "StartingMorale", 55f, "Morale at the beginning of a session."); MinimumMorale = ((BaseUnityPlugin)this).Config.Bind<float>("Morale", "MinimumMorale", 0f, "Minimum morale."); MaximumMorale = ((BaseUnityPlugin)this).Config.Bind<float>("Morale", "MaximumMorale", 100f, "Maximum morale."); DecorationPriceScaleCredits = ((BaseUnityPlugin)this).Config.Bind<float>("Decorations", "PriceScaleCredits", 200f, "Price divisor used by the decoration morale curve."); DecorationPriceExponent = ((BaseUnityPlugin)this).Config.Bind<float>("Decorations", "PriceExponent", 1.15f, "Exponent used by the decoration morale curve. Values above 1 make expensive decorations more efficient."); DecorationMaxMoraleEach = ((BaseUnityPlugin)this).Config.Bind<float>("Decorations", "MaxMoralePerDecoration", 10f, "Maximum morale a single decoration can contribute regardless of price."); DecorationBonusCap = ((BaseUnityPlugin)this).Config.Bind<float>("Decorations", "DecorationBonusCap", 20f, "Maximum total baseline morale supplied by all decorations."); DeathPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "DeathPenalty", 18f, "Immediate morale loss per crew death."); ReunionReward = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "PerfectReunionReward", 10f, "Morale gained when everyone who started the expedition returns to the ship alive after someone has left it."); QuotaFulfilledReward = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "QuotaFulfilledReward", 15f, "Morale gained once when the current quota becomes fulfilled."); FullCrewShipRecoveryPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "FullCrewShipRecoveryPerSecond", 0.00833333f, "Passive morale recovery while the full living crew is together inside the ship (+0.5 morale/minute)."); OrbitRecoveryPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "OrbitRecoveryPerSecond", 0.0166667f, "Additional passive morale recovery while the ship is safely in orbit (+1 morale/minute)."); EmptyShipDecayPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Events", "EmptyShipDecayPerSecond", 0.03f, "Morale decay while nobody living is in the ship."); MigrateLegacyBalanceValues(); HighMoraleSanityGainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Sanity", "HighMoraleSanityGainMultiplier", 0.6f, "At 100 morale, positive insanity gain is multiplied by this."); LowMoraleSanityGainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Sanity", "LowMoraleSanityGainMultiplier", 1.3f, "At 0 morale, positive insanity gain is multiplied by this."); HighMoraleRecoveryMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Sanity", "HighMoraleRecoveryMultiplier", 1.45f, "At 100 morale, negative insanity change (recovery) is multiplied by this."); LowMoraleRecoveryMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Sanity", "LowMoraleRecoveryMultiplier", 0.65f, "At 0 morale, negative insanity change (recovery) is multiplied by this."); ShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowMoraleBar", true, "Show Crew Morale while the local player is in the ship."); HudX = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "X", 0.5f, "Horizontal screen anchor (0 to 1)."); HudY = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Y", 0.105f, "Vertical screen anchor (0 to 1)."); HudWidth = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Width", 260f, "Morale bar width in pixels."); HudHeight = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Height", 14f, "Morale bar height in pixels."); SanityHudRaisePixels = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "SanityHudRaisePixels", 360f, "Moves InsanityMod's bottom-right sanity ring upward by this many pixels."); Morale = Clamp(StartingMorale.Value); _harmony = new Harmony("ultimatelethal.crewmorale"); _harmony.PatchAll(); TryPatchInsanityMod(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Starting morale: {2:0}", "Ultimate Lethal Crew Morale", "0.1.6", Morale)); } private void MigrateLegacyBalanceValues() { if (Mathf.Approximately(DeathPenalty.Value, 12f)) { DeathPenalty.Value = 18f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated legacy DeathPenalty 12 -> 18."); } if (Mathf.Approximately(FullCrewShipRecoveryPerSecond.Value, 0.2f) || Mathf.Approximately(FullCrewShipRecoveryPerSecond.Value, 0.07f) || Mathf.Approximately(FullCrewShipRecoveryPerSecond.Value, 0.03f)) { FullCrewShipRecoveryPerSecond.Value = 0.00833333f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated legacy full-crew passive recovery -> +0.5 morale/minute."); } if (Mathf.Approximately(OrbitRecoveryPerSecond.Value, 0.35f) || Mathf.Approximately(OrbitRecoveryPerSecond.Value, 0.12f) || Mathf.Approximately(OrbitRecoveryPerSecond.Value, 0.05f)) { OrbitRecoveryPerSecond.Value = 0.0166667f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated legacy orbit passive recovery -> +1 morale/minute."); } } private void Start() { _expeditionRoster.Clear(); _countedDeadPlayers.Clear(); } private void Update() { if (!(Time.unscaledTime < _nextStateTick)) { float num = 0.25f; _nextStateTick = Time.unscaledTime + num; AdjustInsanityHudPosition(); if (!((Object)(object)StartOfRound.Instance == (Object)null)) { RefreshDecorationBaseline(); ApplyWorldState(num); } } } private static void AdjustInsanityHudPosition() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("InsanityHud_Root"); if ((Object)(object)val == (Object)null) { return; } RectTransform component = val.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float num = 130f + Mathf.Max(0f, SanityHudRaisePixels?.Value ?? 360f); Vector2 anchoredPosition = component.anchoredPosition; if (Mathf.Abs(anchoredPosition.y - num) > 0.1f) { component.anchoredPosition = new Vector2(anchoredPosition.x, num); } } } private void ApplyWorldState(float dt) { StartOfRound instance = StartOfRound.Instance; bool flag = (Object)(object)instance != (Object)null && instance.shipHasLanded; if (flag && !_wasLanded) { CaptureExpeditionRoster(); _expeditionStartingCrewCount = _expeditionRoster.Count; _someoneLeftShipThisExpedition = false; _expeditionHadDeath = false; _reunionAwardedThisExpedition = false; } int num = DetectNewExpeditionDeaths(); if (num > 0) { _expeditionHadDeath = true; float num2 = DeathPenalty.Value * (float)num; ChangeMorale(0f - num2, "crew death"); ShowEvent("CREW MEMBER LOST", $"-{num2:0.#} MORALE"); } int num3 = CountLivingExpeditionPlayers(); int num4 = CountLivingExpeditionPlayersInShip(); bool flag2 = num3 > 0 && num4 == num3; if (flag && num3 > 0 && num4 < num3) { _someoneLeftShipThisExpedition = true; } if (flag && _someoneLeftShipThisExpedition && !_expeditionHadDeath && !_reunionAwardedThisExpedition && _expeditionStartingCrewCount > 0 && num3 == _expeditionStartingCrewCount && flag2) { ChangeMorale(ReunionReward.Value, "perfect crew reunion"); ShowEvent("CREW REUNITED", $"+{ReunionReward.Value:0.#} MORALE"); _reunionAwardedThisExpedition = true; } UpdateQuotaReward(); bool num5 = IsInOrbit(); float num6 = 0f; if (flag2) { num6 += FullCrewShipRecoveryPerSecond.Value; } if (num5) { num6 += OrbitRecoveryPerSecond.Value; } if (num6 > 0f) { MoveTowardMorale(DecorationBaseline, num6 * dt); } else if (num3 > 0 && num4 == 0 && EmptyShipDecayPerSecond.Value > 0f) { ChangeMorale((0f - EmptyShipDecayPerSecond.Value) * dt, "empty ship"); } _wasFullLivingCrewInShip = flag2; _wasLanded = flag; } private void UpdateQuotaReward() { try { TimeOfDay val = Object.FindObjectOfType<TimeOfDay>(); if ((Object)(object)val == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(TimeOfDay), "quotaFulfilled"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(TimeOfDay), "profitQuota"); if (fieldInfo == null || fieldInfo2 == null) { return; } int num = Convert.ToInt32(fieldInfo.GetValue(val)); int num2 = Mathf.Max(1, Convert.ToInt32(fieldInfo2.GetValue(val))); bool flag = num >= num2; if (!_quotaStateInitialized) { _quotaStateInitialized = true; _quotaWasFulfilled = flag; return; } if (flag && !_quotaWasFulfilled) { ChangeMorale(QuotaFulfilledReward.Value, "quota fulfilled"); ShowEvent("QUOTA FULFILLED", $"+{QuotaFulfilledReward.Value:0.#} MORALE"); } _quotaWasFulfilled = flag; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Quota morale check failed: " + ex.Message)); } } private void ShowEvent(string title, string detail, float seconds = 4f) { _eventTitle = title ?? ""; _eventDetail = detail ?? ""; _eventUntil = Time.unscaledTime + seconds; } internal static void ChangeMorale(float amount, string reason = null) { float morale = Morale; Morale = Clamp(Morale + amount); if ((Object)(object)Instance != (Object)null && Mathf.Abs(Morale - morale) >= 0.01f && reason != null) { ((BaseUnityPlugin)Instance).Logger.LogDebug((object)$"Morale {morale:0.0} -> {Morale:0.0} ({reason})"); } } private static void MoveTowardMorale(float target, float maxDelta) { target = Clamp(target); Morale = Mathf.MoveTowards(Morale, target, Mathf.Max(0f, maxDelta)); } private static float Clamp(float value) { return Mathf.Clamp(value, MinimumMorale?.Value ?? 0f, MaximumMorale?.Value ?? 100f); } private void RefreshDecorationBaseline() { try { StartOfRound instance = StartOfRound.Instance; if (instance?.unlockablesList?.unlockables == null) { return; } int num = 0; float num2 = 0f; foreach (UnlockableItem unlockable in instance.unlockablesList.unlockables) { if (unlockable != null && unlockable.unlockableType == 1 && !unlockable.alreadyUnlocked && unlockable.hasBeenUnlockedByPlayer && !unlockable.inStorage) { int num3 = 0; if ((Object)(object)unlockable.shopSelectionNode != (Object)null) { num3 = Mathf.Max(0, unlockable.shopSelectionNode.itemCost); } float num4 = Mathf.Max(1f, DecorationPriceScaleCredits.Value); float num5 = Mathf.Max(0.01f, DecorationPriceExponent.Value); float num6 = Mathf.Pow(Mathf.Max(0f, (float)num3) / num4, num5); num6 = Mathf.Clamp(num6, 0f, DecorationMaxMoraleEach.Value); num2 += num6; num++; } } DecorationCount = num; float num7 = Mathf.Min(DecorationBonusCap.Value, num2); DecorationBaseline = Clamp(StartingMorale.Value + num7); if (_previousDecorationBonus >= 0f && Mathf.Abs(num7 - _previousDecorationBonus) >= 0.1f) { float num8 = num7 - _previousDecorationBonus; if (num8 > 0f) { ShowEvent("SHIP DECOR IMPROVED", $"+{num8:0.##} MORALE • DECOR {num7:0.##}/{DecorationBonusCap.Value:0}"); } else { ShowEvent("DECORATION REMOVED", $"{num8:0.##} MORALE • DECOR {num7:0.##}/{DecorationBonusCap.Value:0}"); } } _previousDecorationBonus = num7; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Decoration scan failed: " + ex.Message)); } } private void CaptureExpeditionRoster() { _expeditionRoster.Clear(); _countedDeadPlayers.Clear(); PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead) { _expeditionRoster.Add(val); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Captured expedition roster: {_expeditionRoster.Count} crew member(s)."); } private int DetectNewExpeditionDeaths() { int num = 0; foreach (PlayerControllerB item in _expeditionRoster) { if (!((Object)(object)item == (Object)null) && item.isPlayerDead && !_countedDeadPlayers.Contains(item)) { _countedDeadPlayers.Add(item); num++; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Crew death detected from expedition roster. Counted deaths: {_countedDeadPlayers.Count}/{_expeditionRoster.Count}"); } } return num; } private int CountLivingExpeditionPlayers() { int num = 0; foreach (PlayerControllerB item in _expeditionRoster) { if ((Object)(object)item != (Object)null && !item.isPlayerDead) { num++; } } return num; } private int CountLivingExpeditionPlayersInShip() { int num = 0; foreach (PlayerControllerB item in _expeditionRoster) { if (!((Object)(object)item == (Object)null) && !item.isPlayerDead && IsPlayerInShip(item)) { num++; } } return num; } private static int CountLivingPlayers() { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return 0; } int num = 0; PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead) { num++; } } return num; } private static int CountDeadPlayers() { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return 0; } int num = 0; PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && val.isPlayerDead) { num++; } } return num; } private static int CountLivingPlayersInShip() { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return 0; } int num = 0; PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead && IsPlayerInShip(val)) { num++; } } return num; } internal static bool IsPlayerInShip(PlayerControllerB player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (player.isInHangarShipRoom) { return true; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } Vector3 position = ((Component)player).transform.position; Bounds bounds; if ((Object)(object)instance.shipInnerRoomBounds != (Object)null) { bounds = instance.shipInnerRoomBounds.bounds; if (((Bounds)(ref bounds)).Contains(position)) { return true; } } if ((Object)(object)instance.shipBounds != (Object)null) { bounds = instance.shipBounds.bounds; if (((Bounds)(ref bounds)).Contains(position)) { return true; } } return false; } private static bool IsInOrbit() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (instance.inShipPhase) { return !instance.shipHasLanded; } return false; } private void TryPatchInsanityMod() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("InsanityMod.InsanityCalculator"); Type type2 = AccessTools.TypeByName("InsanityMod.Managers.InsanityModifiers"); Type type3 = AccessTools.TypeByName("InsanityMod.Managers.InsanityManager"); int num = 0; MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "TickDelta", (Type[])null, (Type[])null) : null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(InsanityIntegration), "ScaleTickDelta", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "ComputeBonusRate", (Type[])null, (Type[])null) : null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(InsanityIntegration), "ScaleBonusRate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } MethodInfo methodInfo3 = ((type3 != null) ? AccessTools.Method(type3, "AddInsanity", (Type[])null, (Type[])null) : null); if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(InsanityIntegration), "ScaleSpike", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } ((BaseUnityPlugin)this).Logger.LogInfo((object)((num > 0) ? $"InsanityMod integration active ({num}/3 hooks)." : "InsanityMod not detected; morale will run without sanity integration.")); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not patch InsanityMod: {arg}"); } } private void OnGUI() { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) if (!ShowHud.Value) { return; } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && IsPlayerInShip(val) && !((Object)(object)HUDManager.Instance == (Object)null)) { EnsureGui(); float num = Mathf.Max(280f, HudWidth.Value); float num2 = Mathf.Max(12f, HudHeight.Value); float num3 = (float)Screen.width * HudX.Value - num * 0.5f; float num4 = (float)Screen.height * HudY.Value; float num5 = Mathf.Max(0f, DecorationBaseline - StartingMorale.Value); string arg = MoraleStatus(Morale); float num6 = InsanityIntegration.GainMultiplier(); float num7 = InsanityIntegration.RecoveryMultiplier(); GUI.Label(new Rect(num3, num4 - 37f, num, 18f), $"CREW MORALE {Morale:0.#} / 100 • {arg}", _labelStyle); GUI.Label(new Rect(num3, num4 - 19f, num, 16f), $"DECOR +{num5:0.##}/{DecorationBonusCap.Value:0} • SANITY ×{num6:0.00} GAIN / ×{num7:0.00} RECOVERY", _smallStyle); Rect val2 = new Rect(num3, num4, num, num2); GUI.color = new Color(0f, 0f, 0f, 0.76f); GUI.DrawTexture(val2, (Texture)(object)_pixel); float num8 = Mathf.InverseLerp(MinimumMorale.Value, MaximumMorale.Value, Morale); Rect val3 = new Rect(num3 + 2f, num4 + 2f, Mathf.Max(0f, (num - 4f) * num8), Mathf.Max(1f, num2 - 4f)); if (Morale >= 80f) { GUI.color = new Color(0.35f, 0.95f, 0.55f, 0.96f); } else if (Morale >= 60f) { GUI.color = new Color(0.25f, 0.88f, 0.72f, 0.96f); } else if (Morale >= 40f) { GUI.color = new Color(0.2f, 0.75f, 0.95f, 0.96f); } else if (Morale >= 20f) { GUI.color = new Color(0.95f, 0.58f, 0.2f, 0.96f); } else { GUI.color = new Color(0.95f, 0.25f, 0.2f, 0.96f); } GUI.DrawTexture(val3, (Texture)(object)_pixel); GUI.color = Color.white; if (Time.unscaledTime < _eventUntil) { float num9 = num4 + num2 + 10f; GUI.Label(new Rect(num3, num9, num, 22f), _eventTitle, _eventTitleStyle); GUI.Label(new Rect(num3, num9 + 21f, num, 18f), _eventDetail, _eventDetailStyle); } } } private static string MoraleStatus(float morale) { if (morale >= 85f) { return "THRIVING"; } if (morale >= 70f) { return "CONFIDENT"; } if (morale >= 50f) { return "STABLE"; } if (morale >= 35f) { return "UNEASY"; } if (morale >= 20f) { return "SHAKEN"; } return "BROKEN"; } private void EnsureGui() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown if ((Object)(object)_pixel == (Object)null) { _pixel = new Texture2D(1, 1); _pixel.SetPixel(0, 0, Color.white); _pixel.Apply(); } if (_labelStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 13, fontStyle = (FontStyle)1 }; val.normal.textColor = Color.white; _labelStyle = val; } if (_smallStyle == null) { GUIStyle val2 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 10, fontStyle = (FontStyle)0 }; val2.normal.textColor = new Color(0.88f, 0.92f, 0.95f, 1f); _smallStyle = val2; } if (_eventTitleStyle == null) { GUIStyle val3 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 16, fontStyle = (FontStyle)1 }; val3.normal.textColor = Color.white; _eventTitleStyle = val3; } if (_eventDetailStyle == null) { GUIStyle val4 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 12, fontStyle = (FontStyle)1 }; val4.normal.textColor = new Color(0.9f, 0.95f, 1f, 1f); _eventDetailStyle = val4; } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)_pixel != (Object)null) { Object.Destroy((Object)(object)_pixel); } } } internal static class InsanityIntegration { internal static float Morale01 => Mathf.Clamp01(CrewMoralePlugin.Morale / 100f); internal static float GainMultiplier() { return Mathf.Lerp(CrewMoralePlugin.LowMoraleSanityGainMultiplier.Value, CrewMoralePlugin.HighMoraleSanityGainMultiplier.Value, Morale01); } internal static float RecoveryMultiplier() { return Mathf.Lerp(CrewMoralePlugin.LowMoraleRecoveryMultiplier.Value, CrewMoralePlugin.HighMoraleRecoveryMultiplier.Value, Morale01); } public static void ScaleTickDelta(ref float __result) { __result *= ((__result >= 0f) ? GainMultiplier() : RecoveryMultiplier()); } public static void ScaleBonusRate(ref float __result) { __result *= ((__result >= 0f) ? GainMultiplier() : RecoveryMultiplier()); } public static void ScaleSpike(ref float amount) { if (amount > 0f) { amount *= GainMultiplier(); } else if (amount < 0f) { amount *= RecoveryMultiplier(); } } } [HarmonyPatch(typeof(StartOfRound), "Start")] internal static class RoundStartPatch { [HarmonyPostfix] private static void Postfix() { CrewMoralePlugin.ChangeMorale(CrewMoralePlugin.StartingMorale.Value - CrewMoralePlugin.Morale, "round/session init"); } } }