using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Biodiversity.Util.Assetloading;
using FacilityMeltdown.API;
using FacilityMeltdown.Behaviours;
using FacilityMeltdown.Config;
using FacilityMeltdown.Equipment;
using FacilityMeltdown.Integrations;
using FacilityMeltdown.Lang;
using FacilityMeltdown.MeltdownSequence.Behaviours;
using FacilityMeltdown.NetcodePatcher;
using FacilityMeltdown.Patches;
using FacilityMeltdown.Util;
using FacilityMeltdown.Util.Attributes;
using FacilityMeltdown.Util.Config;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalLib.Modules;
using LethalSettings.UI;
using LethalSettings.UI.Components;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.Rendering.HighDefinition;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("FacilityMeltdown")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+751530cf52a095b3d3973cd6105ea15a6aac113d")]
[assembly: AssemblyProduct("FacilityMeltdown")]
[assembly: AssemblyTitle("FacilityMeltdown")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
static <Module>()
{
}
}
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 Biodiversity.Util.Assetloading
{
[AttributeUsage(AttributeTargets.Property)]
internal class LoadFromBundleAttribute : Attribute
{
public string BundleFile { get; private set; }
public LoadFromBundleAttribute(string bundleFile)
{
BundleFile = bundleFile;
base..ctor();
}
}
}
namespace FacilityMeltdown
{
[BepInPlugin("me.loaforc.facilitymeltdown", "FacilityMeltdown", "2.6.13")]
[CompatibleDependency("ainavt.lc.lethalconfig", typeof(LethalConfigIntergration))]
[CompatibleDependency("com.willis.lc.lethalsettings", typeof(LethalSettingsIntegration))]
[CompatibleDependency("BMX.LobbyCompatibility", typeof(LobbyCompatibilityIntegration))]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class MeltdownPlugin : BaseUnityPlugin
{
internal const string modGUID = "me.loaforc.facilitymeltdown";
internal const string modName = "FacilityMeltdown";
internal const string modVersion = "2.6.13";
internal static MeltdownPlugin instance;
internal static ManualLogSource logger;
internal static Harmony harmony = new Harmony("me.loaforc.facilitymeltdown");
internal static MeltdownAssets assets { get; private set; }
public static bool loadedFully { get; private set; } = false;
internal static MeltdownConfig config { get; set; }
internal static MeltdownClientConfig clientConfig { get; private set; }
private void Awake()
{
if (!((Object)(object)instance == (Object)null))
{
return;
}
instance = this;
logger = Logger.CreateLogSource("me.loaforc.facilitymeltdown");
if (RunLoadStep("Assets.Init", "Getting assets", delegate
{
assets = new MeltdownAssets();
}) && RunLoadStep("LangParser.Init", "Getting possible languages", LangParser.Init) && RunLoadStep("new MeltdownConfig()", "Setting up config", delegate
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
config = new MeltdownConfig(((BaseUnityPlugin)this).Config);
clientConfig = new MeltdownClientConfig(new ConfigFile(Utility.CombinePaths(new string[2]
{
Paths.ConfigPath,
"me.loaforc.facilitymeltdown.Client.cfg"
}), false, MetadataHelper.GetMetadata((object)this)));
logger.LogDebug((object)$"Test Config Value: {config.ApparatusValue}");
((BaseUnityPlugin)this).Config.ClearOrphans();
clientConfig.configFile.ClearOrphans();
}) && RunLoadStep("LangParser.SetLanguage", "Setting language", delegate
{
LangParser.SetLanguage(clientConfig.Language);
}) && RunLoadStep("RegisterPatches", "Integrating into LethalCompany", RegisterPatches) && RunLoadStep("RegisterNetworking", "Making sure everything is networked", RegisterNetworking))
{
if (!RunLoadStep("RegisterItems", "Adding the Geiger Counter", RegisterItems))
{
logger.LogWarning((object)"Failed to register the geiger counter.");
}
if (!RunLoadStep("CompatibleDependency.Init", "Checking for any soft dependencies", delegate
{
CompatibleDependencyAttribute.Init((BaseUnityPlugin)(object)this);
}))
{
logger.LogWarning((object)"Doing something with soft dependencies broke, meltdown itself should be fine.");
}
loadedFully = true;
logger.LogInfo((object)"FacilityMeltdown:2.6.13 by loaforc has loaded! have fun :3");
logger.LogInfo((object)" .-_; ;_-. ");
logger.LogInfo((object)" / / \\ \\ ");
logger.LogInfo((object)" | | | | ");
logger.LogInfo((object)" \\ \\.---./ / ");
logger.LogInfo((object)" .-\\\"\"~ .---. ~\"\"-.");
logger.LogInfo((object)" ,`.-~// .'`---`'. \\\\~-.`,");
logger.LogInfo((object)" ' ` | | \\(_)/ | | `' ");
logger.LogInfo((object)" , \\ \\ | | / / , ");
logger.LogInfo((object)" ;`'.,_\\ `-'-' /_,.'`; ");
logger.LogInfo((object)" '-._ _.-'^'-._ _.-' ");
}
}
private bool RunLoadStep(string stepName, string descrption, Action callback)
{
try
{
callback();
}
catch (Exception ex)
{
logger.LogError((object)("`" + stepName + "` caused an exception to be thrown, meltdown may or may not work, look for more errors."));
logger.LogError((object)ex);
return false;
}
logger.LogInfo((object)(stepName.PadRight(25) + " == " + descrption));
return true;
}
private void RegisterItems()
{
logger.LogInfo((object)"Registering Items");
Items.RegisterShopItem(assets.geigerCounterItemDef, (TerminalNode)null, (TerminalNode)null, assets.geigerCounterNode, 90);
}
private void OnDisable()
{
if (!loadedFully)
{
Harmony.UnpatchID("me.loaforc.facilitymeltdown");
logger.LogInfo((object)"Unpatching as something failed while loading.");
}
else if (Chainloader.PluginInfos.ContainsKey("den.meltdownchance") || Chainloader.PluginInfos.ContainsKey("PizzaProbability"))
{
logger.LogInfo((object)"You are using a mod that makes meltdown have a random chance of occuring.");
logger.LogInfo((object)"Keep in mind this goes against meltdown's core design, but your choice.");
logger.LogWarning((object)"However; BY DESIGN these mods need to mess with the internals of meltdown");
logger.LogWarning((object)"so I personally will be offering low to no support with these mods installed.");
}
}
private void RegisterNetworking()
{
Type[] array = new Type[2]
{
typeof(MeltdownHandler),
typeof(GeigerCounterItem)
};
Type[] array2 = array;
foreach (Type type in array2)
{
try
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array3 = methods;
foreach (MethodInfo methodInfo in array3)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
catch (Exception)
{
logger.LogWarning((object)"supressed an error from netcode patcher, probably fine but should still log that something happened.");
}
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private void RegisterPatches()
{
foreach (Type item in from t in Assembly.GetExecutingAssembly().GetLoadableTypes()
where t.IsClass && t.Namespace == "FacilityMeltdown.Patches"
select t)
{
logger.LogDebug((object)("Registering Patch handler: " + item.Name));
harmony.PatchAll(item);
}
}
}
internal static class ExtensionMethods
{
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int num = list.Count;
while (num > 1)
{
num--;
int index = rng.Next(num + 1);
T value = list[index];
list[index] = list[num];
list[num] = value;
}
}
public static float Remap(this float value, float from1, float to1, float from2, float to2)
{
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}
public static List<PlayerControllerB> GetConnectedPlayers(this StartOfRound startOfRound)
{
return startOfRound.allPlayerScripts.Where((PlayerControllerB player) => player.isPlayerControlled).ToList();
}
public static void SpawnEnemy(this EnemyVent vent, SpawnableEnemyWithRarity enemy)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = vent.floorNode.position;
float y = vent.floorNode.eulerAngles.y;
GameObject val = Object.Instantiate<GameObject>(enemy.enemyType.enemyPrefab, position, Quaternion.Euler(new Vector3(0f, y, 0f)));
EnemyAI component = val.GetComponent<EnemyAI>();
((NetworkBehaviour)component).NetworkObject.Spawn(true);
RoundManager.Instance.SpawnedEnemies.Add(component);
vent.OpenVentClientRpc();
vent.occupied = false;
}
internal static string Translate(this string text)
{
return LangParser.GetTranslation(text);
}
internal static void ClearOrphans(this ConfigFile config)
{
PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null);
dictionary.Clear();
config.Save();
}
internal static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
if (assembly == null)
{
throw new ArgumentNullException("assembly");
}
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
return ex.Types.Where((Type t) => t != null);
}
}
internal static (int hours, int minutes) GetCurrentTime(this TimeOfDay timeOfDay)
{
int num = Mathf.FloorToInt(timeOfDay.normalizedTimeOfDay * 60f * (float)timeOfDay.numberOfHours + 360f);
int item = Mathf.FloorToInt((float)(num / 60));
return (item, num % 60);
}
}
internal class MeltdownAssets : AssetBundleLoader<MeltdownAssets>
{
[LoadFromBundle("meltdownmusic.mp3")]
public AudioClip defaultMusic { get; private set; }
[LoadFromBundle("shockwave.mp3")]
public AudioClip shockwave { get; private set; }
[LoadFromBundle("FacilityExplosion.prefab")]
public GameObject facilityExplosionPrefab { get; private set; }
[LoadFromBundle("MeltdownHandler.prefab")]
public GameObject meltdownHandlerPrefab { get; private set; }
[LoadFromBundle("Shockwave.prefab")]
public GameObject shockwavePrefab { get; private set; }
[LoadFromBundle("GeigerCounterItemDef.asset")]
public Item geigerCounterItemDef { get; private set; }
[LoadFromBundle("GeigerCounterNode.asset")]
public TerminalNode geigerCounterNode { get; private set; }
[LoadFromBundle("HealthKeyword.asset")]
public TerminalKeyword healthKeyword { get; private set; }
[LoadFromBundle("ReactorKeyword.asset")]
public TerminalKeyword reactorKeyword { get; private set; }
[LoadFromBundle("ReactorHealthReport.asset")]
public TerminalNode reactorHealthNode { get; private set; }
public GameObject[] facilityEffects { get; private set; }
public AudioClip[] warnings { get; private set; }
public MeltdownAssets()
: base("facilitymeltdown")
{
}
protected override void FinishLoadingAssets(AssetBundle bundle)
{
warnings = (AudioClip[])(object)new AudioClip[4]
{
LoadAsset<AudioClip>(bundle, "warning1.mp3"),
LoadAsset<AudioClip>(bundle, "warning2.mp3"),
LoadAsset<AudioClip>(bundle, "warning3.mp3"),
LoadAsset<AudioClip>(bundle, "warning4.mp3")
};
facilityEffects = (GameObject[])(object)new GameObject[2]
{
LoadAsset<GameObject>(bundle, "Dust.prefab"),
LoadAsset<GameObject>(bundle, "Waterstream.prefab")
};
TerminalPatch.terminalKeywordsToRegister.Add(healthKeyword);
TerminalPatch.terminalKeywordsToRegister.Add(reactorKeyword);
TerminalPatch.terminalNodesToRegister.Add(reactorHealthNode);
}
}
}
namespace FacilityMeltdown.Util
{
internal abstract class AssetBundleLoader<T> where T : AssetBundleLoader<T>
{
public AssetBundleLoader(string filePath)
{
AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath));
MeltdownPlugin.logger.LogDebug((object)("[Assets] AssetBundle `" + filePath + "` contains these objects: \n" + string.Join("\n", val.GetAllAssetNames())));
Type typeFromHandle = typeof(T);
PropertyInfo[] properties = typeFromHandle.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
LoadFromBundleAttribute loadFromBundleAttribute = (LoadFromBundleAttribute)propertyInfo.GetCustomAttribute(typeof(LoadFromBundleAttribute));
if (loadFromBundleAttribute != null)
{
MeltdownPlugin.logger.LogDebug((object)("[Assets] Got LoadFromBundle attribute on `" + propertyInfo.Name + "`. Loading asset: `" + loadFromBundleAttribute.BundleFile + "` into the [roperty."));
propertyInfo.SetValue(this, LoadAsset<Object>(val, loadFromBundleAttribute.BundleFile.ToLower(CultureInfo.GetCultureInfo("en-GB"))));
}
}
GameObject[] array = val.LoadAllAssets<GameObject>();
foreach (GameObject val2 in array)
{
if (!((Object)(object)val2.GetComponent<NetworkObject>() == (Object)null) && !GameNetworkManagerPatch.networkPrefabsToRegister.Contains(val2))
{
GameNetworkManagerPatch.networkPrefabsToRegister.Add(val2);
}
}
FinishLoadingAssets(val);
}
protected virtual void FinishLoadingAssets(AssetBundle bundle)
{
}
protected AssetType LoadAsset<AssetType>(AssetBundle bundle, string path) where AssetType : Object
{
AssetType val = bundle.LoadAsset<AssetType>(path);
if ((Object)(object)val == (Object)null)
{
throw new ArgumentException(path + " is not valid in the assetbundle!");
}
return val;
}
}
}
namespace FacilityMeltdown.Util.Config
{
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigDescAttribute : Attribute
{
public string Description { get; private set; }
public ConfigDescAttribute(string desc)
{
Description = desc;
base..ctor();
}
}
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigGroupAttribute : Attribute
{
public string Group { get; private set; }
public ConfigGroupAttribute(string Group)
{
this.Group = Group;
base..ctor();
}
}
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigIgnoreAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property)]
internal class ConfigRangeAttribute : Attribute
{
internal float Min { get; private set; }
internal float Max { get; private set; }
internal ConfigRangeAttribute(float min, float max)
{
Min = min;
Max = max;
}
}
[Serializable]
internal abstract class LoafConfig<T> where T : LoafConfig<T>
{
internal List<(PropertyInfo, object)> configEntries = new List<(PropertyInfo, object)>();
internal ConfigFile configFile { get; private set; }
public LoafConfig(ConfigFile configFile)
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Expected O, but got Unknown
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Expected O, but got Unknown
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
if (configFile == null)
{
return;
}
this.configFile = configFile;
string header = "Misc";
Type typeFromHandle = typeof(T);
PropertyInfo[] properties = typeFromHandle.GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.GetCustomAttribute(typeof(ConfigIgnoreAttribute)) == null)
{
ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigGroupAttribute));
if (configGroupAttribute != null)
{
header = configGroupAttribute.Group.Replace(" ", "");
}
string text = "no description here :pensive:";
ConfigDescAttribute configDescAttribute = (ConfigDescAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigDescAttribute));
if (configDescAttribute != null)
{
text = configDescAttribute.Description;
}
ConfigDescription val = new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>());
ConfigRangeAttribute configRangeAttribute = (ConfigRangeAttribute)propertyInfo.GetCustomAttribute(typeof(ConfigRangeAttribute));
val = ((configRangeAttribute == null) ? new ConfigDescription(text, (AcceptableValueBase)null, Array.Empty<object>()) : ((!(propertyInfo.PropertyType == typeof(int))) ? new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<float>(configRangeAttribute.Min, configRangeAttribute.Max), Array.Empty<object>()) : new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<int>((int)configRangeAttribute.Min, (int)configRangeAttribute.Max), Array.Empty<object>())));
if (propertyInfo.PropertyType == typeof(float))
{
BindProperty<float>(propertyInfo, header, val);
}
if (propertyInfo.PropertyType == typeof(int))
{
BindProperty<int>(propertyInfo, header, val);
}
if (propertyInfo.PropertyType == typeof(string))
{
BindProperty<string>(propertyInfo, header, val);
}
if (propertyInfo.PropertyType == typeof(bool))
{
BindProperty<bool>(propertyInfo, header, val);
}
}
}
}
protected void BindProperty<V>(PropertyInfo property, string header, ConfigDescription description)
{
ConfigEntry<V> val = configFile.Bind<V>(header, property.Name, (V)property.GetValue(this), description);
configEntries.Add((property, val));
property.SetValue(this, val.Value);
}
}
internal abstract class LoafSyncedConfig<T> : LoafConfig<T> where T : LoafSyncedConfig<T>
{
internal static T Default { get; private set; }
internal LoafSyncedConfig(ConfigFile file)
: base(file)
{
if (Default == null)
{
Default = (T)this;
}
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
internal class RequiresRestartAttribute : Attribute
{
public bool RequiresRestart { get; private set; }
public RequiresRestartAttribute(bool requiresRestart = true)
{
RequiresRestart = requiresRestart;
base..ctor();
}
}
}
namespace FacilityMeltdown.Util.Attributes
{
internal class CompatibleDependencyAttribute : BepInDependency
{
public Type Handler;
public CompatibleDependencyAttribute(string guid, Type handlerType)
: base(guid, (DependencyFlags)2)
{
Handler = handlerType;
}
public static void Init(BaseUnityPlugin source)
{
IEnumerable<CompatibleDependencyAttribute> customAttributes = ((MemberInfo)((object)source).GetType()).GetCustomAttributes<CompatibleDependencyAttribute>();
foreach (CompatibleDependencyAttribute item in customAttributes)
{
if (Chainloader.PluginInfos.ContainsKey(((BepInDependency)item).DependencyGUID))
{
item.Handler.GetMethod("Initialize", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, null);
item.Handler = null;
}
}
}
}
}
namespace FacilityMeltdown.Patches
{
[HarmonyPatch(typeof(LungProp))]
internal class ApparaticePatch
{
[HarmonyPrefix]
[HarmonyPatch("EquipItem")]
internal static void BeginMeltdownSequence(LungProp __instance, ref bool ___isLungDocked)
{
if (!((NetworkBehaviour)__instance).IsHost || !___isLungDocked || MeltdownAPI.MeltdownStarted)
{
return;
}
try
{
if (MeltdownPlugin.config.OverrideApparatusValue)
{
((GrabbableObject)__instance).scrapValue = MeltdownPlugin.config.ApparatusValue;
}
GameObject val = Object.Instantiate<GameObject>(MeltdownPlugin.assets.meltdownHandlerPrefab);
val.GetComponent<NetworkObject>().Spawn(false);
}
catch (Exception ex)
{
MeltdownPlugin.logger.LogError((object)ex);
}
}
[HarmonyPrefix]
[HarmonyPatch("Start")]
internal static void AddRadiationSource(LungProp __instance)
{
MeltdownMoonMapper.EnsureMeltdownMoonMapper();
MeltdownInteriorMapper.EnsureMeltdownInteriorMapper();
try
{
RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
radiationSource.radiationAmount = 80f;
radiationSource.radiationDistance = 60f;
MeltdownMoonMapper.EnsureMeltdownMoonMapper();
if (MeltdownPlugin.config.OverrideApparatusValue)
{
((GrabbableObject)__instance).scrapValue = MeltdownPlugin.config.ApparatusValue;
}
MeltdownPlugin.logger.LogDebug((object)((GrabbableObject)__instance).scrapValue);
}
catch (Exception ex)
{
MeltdownPlugin.logger.LogError((object)ex);
}
}
}
[HarmonyPatch(typeof(BlobAI))]
internal class BlobAIPatch
{
[HarmonyPrefix]
[HarmonyPatch("Start")]
internal static void AddRadiationSource(BlobAI __instance)
{
RadiationSource radiationSource = ((Component)__instance).gameObject.AddComponent<RadiationSource>();
radiationSource.radiationAmount = 30f;
radiationSource.radiationDistance = 25f;
}
}
[HarmonyPatch(typeof(EntranceTeleport))]
internal static class EntranceTeleportPatch
{
[HarmonyPrefix]
[HarmonyPatch("FindExitPoint")]
private static bool dontAllowReneter(ref bool __result)
{
if ((Object)(object)MeltdownHandler.Instance != (Object)null && MeltdownHandler.Instance.HasExplosionOccured())
{
__result = false;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(GameNetworkManager))]
internal class GameNetworkManagerPatch
{
internal static List<GameObject> networkPrefabsToRegister = new List<GameObject>();
[HarmonyPatch("Start")]
[HarmonyPrefix]
private static void AddNetworkPrefabs()
{
foreach (GameObject item in networkPrefabsToRegister)
{
NetworkManager.Singleton.AddNetworkPrefab(item);
MeltdownPlugin.logger.LogDebug((object)("Registered " + ((Object)item).name + " as a network prefab."));
}
MeltdownPlugin.logger.LogInfo((object)$"Succesfully registered {networkPrefabsToRegister.Count} network prefabs.");
}
[HarmonyPostfix]
[HarmonyPatch("StartDisconnect")]
public static void PlayerLeave()
{
MeltdownPlugin.config = LoafSyncedConfig<MeltdownConfig>.Default;
}
}
[HarmonyPatch(typeof(GrabbableObject))]
public class GrabbableObjectPatch
{
[HarmonyPrefix]
[HarmonyPatch("Update")]
internal static void ApplyMinPeople(GrabbableObject __instance)
{
LungProp apparatus = (LungProp)(object)((__instance is LungProp) ? __instance : null);
if (apparatus == null)
{
return;
}
if (!apparatus.isLungDocked)
{
if (!((GrabbableObject)apparatus).grabbable)
{
((GrabbableObject)apparatus).customGrabTooltip = "";
((GrabbableObject)apparatus).grabbable = true;
}
return;
}
int num = StartOfRound.Instance.GetConnectedPlayers().Count((PlayerControllerB player) => Vector3.Distance(((Component)player).transform.position, ((Component)apparatus).transform.position) < 15f);
int num2 = Mathf.Min(MeltdownPlugin.config.MinPeopleToPullApparatus, StartOfRound.Instance.livingPlayers);
if (num < num2 && TimeOfDay.Instance.GetCurrentTime().hours < 21)
{
((GrabbableObject)apparatus).customGrabTooltip = $"[ NEEDS {num2} PEOPLE ]";
((GrabbableObject)apparatus).grabbable = false;
}
else
{
((GrabbableObject)apparatus).customGrabTooltip = "";
((GrabbableObject)apparatus).grabbable = true;
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal static class PlayerControllerPatch
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__OnRequestSync;
public static HandleNamedMessageDelegate <1>__OnReceiveSync;
}
private const string MESSAGE_REQUEST = "meltdown_OnRequestConfigSync";
private const string MESSAGE_RECIEVE = "meltdown_OnRecieveConfigSync";
private const int IntSize = 4;
[HarmonyPostfix]
[HarmonyPatch("ConnectClientToPlayerObject")]
private static void SyncConfig()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
if (NetworkManager.Singleton.IsHost)
{
CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
object obj = <>O.<0>__OnRequestSync;
if (obj == null)
{
HandleNamedMessageDelegate val = OnRequestSync;
<>O.<0>__OnRequestSync = val;
obj = (object)val;
}
customMessagingManager.RegisterNamedMessageHandler("meltdown_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
return;
}
CustomMessagingManager customMessagingManager2 = NetworkManager.Singleton.CustomMessagingManager;
object obj2 = <>O.<1>__OnReceiveSync;
if (obj2 == null)
{
HandleNamedMessageDelegate val2 = OnReceiveSync;
<>O.<1>__OnReceiveSync = val2;
obj2 = (object)val2;
}
customMessagingManager2.RegisterNamedMessageHandler("meltdown_OnRecieveConfigSync", (HandleNamedMessageDelegate)obj2);
RequestSync();
}
public static void RequestSync()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (NetworkManager.Singleton.IsHost)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1);
try
{
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
public static void OnRequestSync(ulong clientId, FastBufferReader _)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkManager.Singleton.IsHost)
{
return;
}
MeltdownPlugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject((object)MeltdownPlugin.config));
int num = bytes.Length;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num + 4, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteBytesSafe(bytes, -1, 0);
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("meltdown_OnRecieveConfigSync", clientId, val, (NetworkDelivery)3);
}
catch (Exception arg)
{
MeltdownPlugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
private static void OnReceiveSync(ulong _, FastBufferReader reader)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
if (!((FastBufferReader)(ref reader)).TryBeginRead(4))
{
MeltdownPlugin.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
return;
}
int num = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
{
MeltdownPlugin.logger.LogError((object)"Config sync error: Host could not sync.");
return;
}
byte[] bytes = new byte[num];
((FastBufferReader)(ref reader)).ReadBytesSafe(ref bytes, num, 0);
MeltdownPlugin.logger.LogDebug((object)Encoding.UTF8.GetString(bytes));
MeltdownPlugin.config = JsonConvert.DeserializeObject<MeltdownConfig>(Encoding.UTF8.GetString(bytes), new JsonSerializerSettings
{
ContractResolver = (IContractResolver)(object)new IncludePrivateSetterContractResolver()
});
MeltdownPlugin.logger.LogDebug((object)"Deserialized values are: ");
PropertyInfo[] properties = MeltdownPlugin.config.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
MeltdownPlugin.logger.LogDebug((object)$"{propertyInfo.Name} => {propertyInfo.GetValue(MeltdownPlugin.config)}");
}
MeltdownPlugin.logger.LogInfo((object)"Successfully synced config with host.");
}
}
internal class IncludePrivateSetterContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
JsonProperty val = ((DefaultContractResolver)this).CreateProperty(member, memberSerialization);
if (!val.Writable && member is PropertyInfo propertyInfo)
{
val.Writable = propertyInfo.GetSetMethod(nonPublic: true) != null;
}
return val;
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal static class StartOfRoundPatches
{
[HarmonyPrefix]
[HarmonyPatch("EndOfGame")]
internal static void UnloadMeltdownHandler()
{
if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
{
Object.Destroy((Object)(object)((Component)MeltdownHandler.Instance).gameObject);
}
if (Object.op_Implicit((Object)(object)MeltdownMoonMapper.Instance))
{
Object.Destroy((Object)(object)((Component)MeltdownMoonMapper.Instance).gameObject);
}
if (Object.op_Implicit((Object)(object)MeltdownInteriorMapper.Instance))
{
Object.Destroy((Object)(object)((Component)MeltdownInteriorMapper.Instance).gameObject);
}
}
}
[HarmonyPatch(typeof(Terminal))]
internal class TerminalPatch
{
internal class ReactorHealthReport
{
public float reactorInstability;
public float timeRemaining;
public float generatedAt = Time.time;
public string GetFlavourText()
{
if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.75f)
{
return "reactorscan.result.flavour.start";
}
if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.5f)
{
return "reactorscan.result.flavour.low";
}
if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.33f)
{
return "reactorscan.result.flavour.medium";
}
if (timeRemaining / (float)MeltdownPlugin.config.MeltdownTime > 0.15f)
{
return "reactorscan.result.flavour.high";
}
return "";
}
public string GetTeminalOutput()
{
string text = "reactorscan.result.unstable".Translate();
text = SubstituteVariables(text);
return text + "\n\n" + SubstituteVariables(GetFlavourText().Translate()) + "\n\n";
}
}
internal static float lastHealthCheck = 0f;
internal static ReactorHealthReport lastReport = null;
internal static List<TerminalKeyword> terminalKeywordsToRegister = new List<TerminalKeyword>();
internal static List<TerminalNode> terminalNodesToRegister = new List<TerminalNode>();
internal static string SubstituteVariables(string text)
{
StringBuilder stringBuilder = new StringBuilder(text);
stringBuilder.Replace("<cooldown>", MeltdownPlugin.config.ShipScanCooldown.ToString());
stringBuilder.Replace("<instability>", lastReport.reactorInstability.ToString());
stringBuilder.Replace("<time_left>", lastReport.timeRemaining.ToString());
return stringBuilder.ToString();
}
internal static string GetTextForNode()
{
if (Object.op_Implicit((Object)(object)MeltdownHandler.Instance))
{
string text = "reactorscan.error.overheat";
if (ReactorHealthCheckReady())
{
lastHealthCheck = Time.time;
lastReport = GetNewReactorHealthReport();
text = "reactorscan.success";
}
return SubstituteVariables(text.Translate()) + lastReport.GetTeminalOutput();
}
return "reactorscan.result.stable".Translate();
}
internal static bool ReactorHealthCheckReady()
{
return Time.time >= lastHealthCheck + MeltdownPlugin.config.ShipScanCooldown;
}
internal static ReactorHealthReport GetNewReactorHealthReport()
{
float num = ((float)MeltdownPlugin.config.MeltdownTime - MeltdownHandler.Instance.meltdownTimer) / (float)MeltdownPlugin.config.MeltdownTime * 100f;
num = Mathf.Round(num / MeltdownPlugin.config.ShipScanAccuracy) * MeltdownPlugin.config.ShipScanAccuracy;
float timeRemaining = (1f - num / 100f) * (float)MeltdownPlugin.config.MeltdownTime;
return new ReactorHealthReport
{
reactorInstability = num,
timeRemaining = timeRemaining
};
}
[HarmonyPostfix]
[HarmonyPatch("Awake")]
internal static void RegisterNodes(Terminal __instance)
{
__instance.terminalNodes.allKeywords = CollectionExtensions.AddRangeToArray<TerminalKeyword>(__instance.terminalNodes.allKeywords, terminalKeywordsToRegister.ToArray());
__instance.terminalNodes.terminalNodes.AddRange(terminalNodesToRegister);
}
[HarmonyPostfix]
[HarmonyPatch("TextPostProcess")]
internal static void ProcessReactorText(TerminalNode node, ref string __result)
{
if ((Object)(object)node == (Object)(object)MeltdownPlugin.assets.reactorHealthNode)
{
__result = "\n\n\n" + GetTextForNode();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StormyWeather), "GetMetalObjectsAfterDelay")]
internal static void CancelCoroutine(StormyWeather __instance, ref IEnumerator __result)
{
((MonoBehaviour)__instance).StopCoroutine(__result);
}
}
}
namespace FacilityMeltdown.MeltdownSequence
{
public static class MeltdownEffects
{
public static List<(Light light, Color originalColour)> SetupEmergencyLights()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < RoundManager.Instance.allPoweredLights.Count; i++)
{
RoundManager.Instance.allPoweredLights[i].color = MeltdownInteriorMapper.Instance.outsideEmergencyLightColour;
}
List<(Light, Color)> list = new List<(Light, Color)>();
for (int j = 0; j < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; j++)
{
list.Add((MeltdownMoonMapper.Instance.outsideEmergencyLights[j], MeltdownMoonMapper.Instance.outsideEmergencyLights[j].color));
}
return list;
}
public static IEnumerator RepeatUntilEndOfMeltdown(Func<IEnumerator> enumerator)
{
yield return (object)new WaitForSeconds(Random.Range(0f, 1f));
while (true)
{
MeltdownPlugin.logger.LogDebug((object)"looping effect");
yield return enumerator();
}
}
public static IEnumerator WithDelay(IEnumerator enumerator, float delay)
{
yield return (object)new WaitForSeconds(delay);
yield return enumerator;
}
public static IEnumerator WithDelay(Action callback, float delay)
{
yield return (object)new WaitForSeconds(delay);
callback();
}
public static IEnumerator WithRandomDelay(Func<IEnumerator> enumerator, float min, float max)
{
yield return WithDelay(enumerator(), Random.Range(min, max));
}
public static IEnumerator WithRandomDelay(Action callback, float min, float max)
{
yield return WithDelay(callback, Random.Range(min, max));
}
public static IEnumerator AtProgress(IEnumerator enumerator, float progress)
{
while (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
{
yield return null;
}
yield return enumerator;
}
public static IEnumerator AtProgress(Action callback, float progress)
{
while (MeltdownAPI.MeltdownStarted && MeltdownHandler.Instance.Progress > progress)
{
yield return null;
}
callback();
}
public static IEnumerator EmergencyLights(float onTime, float offTime, List<(Light light, Color originalColour)> originalLightColours)
{
MeltdownPlugin.logger.LogDebug((object)"Switching lights ON");
for (int i = 0; i < RoundManager.Instance.allPoweredLightsAnimators.Count; i++)
{
RoundManager.Instance.allPoweredLightsAnimators[i].SetBool("on", true);
}
for (int j = 0; j < MeltdownMoonMapper.Instance.outsideEmergencyLights.Count; j++)
{
MeltdownMoonMapper.Instance.outsideEmergencyLights[j].color = MeltdownMoonMapper.Instance.outsideEmergencyLightColour;
}
yield return (object)new WaitForSeconds(onTime);
MeltdownPlugin.logger.LogDebug((object)"Switching lights OFF");
for (int k = 0; k < RoundManager.Instance.allPoweredLightsAnimators.Count; k++)
{
RoundManager.Instance.allPoweredLightsAnimators[k].SetBool("on", false);
}
foreach (var (val, color) in originalLightColours)
{
val.color = color;
}
yield return (object)new WaitForSeconds(offTime);
}
public static void InsideParticleEffects()
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
if (MeltdownPlugin.clientConfig.ScreenShake)
{
RaycastHit val2 = default(RaycastHit);
for (int i = 0; i < Random.Range(5, 15); i++)
{
Vector3 val = GetRandomPositionInsideFacility() + Vector3.up;
if (Physics.Raycast(new Ray(val, Vector3.up), ref val2, 20f, 256))
{
GameObject val3 = MeltdownPlugin.assets.facilityEffects[Random.Range(0, MeltdownPlugin.assets.facilityEffects.Length)];
GameObject val4 = Object.Instantiate<GameObject>(val3);
val3.transform.position = ((RaycastHit)(ref val2)).point;
val4.transform.parent = ((Component)MeltdownHandler.Instance).transform;
}
}
}
if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
{
Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, GetRandomPositionNearPlayer(), Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform);
}
if (MeltdownPlugin.clientConfig.ScreenShake)
{
if (MeltdownHandler.Instance.Progress > 0.5f)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
}
else
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
}
}
}
public static IEnumerator WarningAnnouncer(AudioSource source)
{
source.volume = MeltdownPlugin.clientConfig.MusicVolume;
AudioClip clip = MeltdownPlugin.assets.warnings[Random.Range(0, MeltdownPlugin.assets.warnings.Length)];
source.clip = clip;
source.Play();
yield return (object)new WaitForSeconds(source.clip.length);
}
private static Vector3 PlacePositionInsideFacility(Vector3 position, float radius = 10f)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
return RoundManager.Instance.GetRandomNavMeshPositionInRadius(position, radius, default(NavMeshHit));
}
private static Vector3 GetRandomPositionNearPlayer(float radius = 15f)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
return PlacePositionInsideFacility(((Component)GameNetworkManager.Instance.localPlayerController).transform.position + Random.insideUnitSphere * radius);
}
private static Vector3 GetRandomPositionInsideFacility()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
return PlacePositionInsideFacility(RoundManager.Instance.insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position);
}
}
}
namespace FacilityMeltdown.MeltdownSequence.Behaviours
{
internal class FacilityExplosionHandler : MonoBehaviour
{
private PlayerControllerB player;
private float size;
private float time;
private LocalVolumetricFog internalFog;
private void Awake()
{
player = GameNetworkManager.Instance.localPlayerController;
internalFog = ((Component)this).GetComponent<LocalVolumetricFog>();
if ((Object)(object)internalFog == (Object)null)
{
MeltdownPlugin.logger.LogError((object)"Failed to get volumetric fog!");
}
if (MeltdownPlugin.clientConfig.ScreenShake)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
}
if (!player.isPlayerDead && player.isInsideFactory)
{
if (player.isInElevator)
{
MeltdownPlugin.logger.LogWarning((object)"Player is inside ship and facility at the same time!! Did you teleport out? Aborting kill");
}
else
{
KillPlayer();
}
}
}
private void Update()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: 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_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
time += Time.deltaTime * 10f;
size = TimeToSize(time);
((Component)this).transform.localScale = Vector3.one * size;
if ((Object)(object)internalFog != (Object)null)
{
internalFog.parameters.size = Vector3.one * size * 1.25f;
}
if (!ShouldIgnorePlayer() && PlayerIsInsideFireball())
{
player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0, default(Vector3));
}
}
private void KillPlayer()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
player.KillPlayer(Vector3.zero, false, (CauseOfDeath)3, 0, default(Vector3));
}
private bool PlayerIsInsideFireball()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
return Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < size;
}
private bool ShouldIgnorePlayer()
{
if (!player.isPlayerDead)
{
if (player.isInElevator)
{
return StartOfRound.Instance.shipIsLeaving;
}
return false;
}
return true;
}
private float TimeToSize(float time)
{
return Mathf.Log(time) + 3f + 2f * time;
}
}
public class MeltdownHandler : NetworkBehaviour
{
internal float meltdownTimer;
private bool meltdownStarted;
private GameObject explosion;
private GameObject shockwave;
[SerializeField]
private AudioSource meltdownMusic;
[SerializeField]
private AudioSource warningSource;
public float TimeLeftUntilMeltdown => meltdownTimer;
public float Progress => 1f - TimeLeftUntilMeltdown / (float)MeltdownPlugin.config.MeltdownTime;
private static PlayerControllerB Player => GameNetworkManager.Instance.localPlayerController;
internal static MeltdownHandler Instance { get; private set; }
private Vector3 effectOrigin => MeltdownMoonMapper.Instance.EffectOrigin;
[ClientRpc]
private void StartMeltdownClientRpc()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_02db: Unknown result type (might be due to invalid IL or missing references)
//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Invalid comparison between Unknown and I4
//IL_005f: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager == null || !networkManager.IsListening)
{
return;
}
if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams val = default(ClientRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3631067672u, val, (RpcDelivery)0);
((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3631067672u, val, (RpcDelivery)0);
}
if ((int)base.__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost) || (Object)(object)Instance != (Object)null)
{
return;
}
Instance = this;
Stopwatch stopwatch = new Stopwatch();
MeltdownPlugin.logger.LogInfo((object)"Beginning Meltdown Sequence! I'd run if I were you!");
stopwatch.Start();
MeltdownMoonMapper.EnsureMeltdownMoonMapper();
MeltdownInteriorMapper.EnsureMeltdownInteriorMapper();
if ((Object)(object)MeltdownInteriorMapper.Instance == (Object)null)
{
MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the interior mapper exists and it doesnt?!?");
}
if ((Object)(object)MeltdownMoonMapper.Instance == (Object)null)
{
MeltdownPlugin.logger.LogError((object)"WHAT. Just ensured that the moon mapper exists and it doesnt?!?");
}
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Ensuring data objects exist: {stopwatch.ElapsedMilliseconds}ms");
meltdownTimer = MeltdownPlugin.config.MeltdownTime;
stopwatch.Restart();
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Creating audio: {stopwatch.ElapsedMilliseconds}ms");
stopwatch.Restart();
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(delegate
{
HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.start"));
}, 5f));
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.WithDelay(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay(() => MeltdownEffects.WarningAnnouncer(warningSource), 10f, 15f)), 10f));
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay((Action)MeltdownEffects.InsideParticleEffects, 10f, 15f)));
if (MeltdownPlugin.config.EmergencyLights)
{
try
{
List<(Light, Color)> originalLightColours = MeltdownEffects.SetupEmergencyLights();
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.EmergencyLights(2f, 5f, originalLightColours)));
}
catch (Exception arg)
{
MeltdownPlugin.logger.LogError((object)$"Failed to set the emergency light colour: {arg}");
}
}
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.RepeatUntilEndOfMeltdown(() => MeltdownEffects.WithRandomDelay(delegate
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)shockwave != (Object)null)
{
Object.Destroy((Object)(object)shockwave);
}
shockwave = Object.Instantiate<GameObject>(MeltdownPlugin.assets.shockwavePrefab);
shockwave.transform.position = effectOrigin;
}, 25f, 35f)));
((MonoBehaviour)this).StartCoroutine(MeltdownEffects.AtProgress((Action)HUDManager.Instance.RadiationWarningHUD, 0.5f));
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Starting effects: {stopwatch.ElapsedMilliseconds}ms");
if (((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsServer)
{
SpawnEnemies();
}
stopwatch.Restart();
if (effectOrigin == Vector3.zero)
{
MeltdownPlugin.logger.LogError((object)"Effect Origin is Vector3.Zero! We couldn't find the effect origin");
HUDManager.Instance.DisplayGlobalNotification("Failed to find effect origin... Things will look broken.");
}
if (MeltdownPlugin.clientConfig.ScreenShake)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
}
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Getting effect origin: {stopwatch.ElapsedMilliseconds}ms");
stopwatch.Restart();
MeltdownAPI.OnMeltdownStart();
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"MeltdownAPI.OnMeltdownStart(): {stopwatch.ElapsedMilliseconds}ms");
meltdownStarted = true;
}
private void SpawnEnemies()
{
Stopwatch stopwatch = Stopwatch.StartNew();
List<string> disallowed = MeltdownPlugin.config.GetDisallowedEnemies();
List<SpawnableEnemyWithRarity> list = RoundManager.Instance.currentLevel.Enemies.Where((SpawnableEnemyWithRarity enemy) => !EnemyCannotBeSpawned(enemy.enemyType) && !disallowed.Contains(enemy.enemyType.enemyName)).ToList();
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Filtering enemies: {stopwatch.ElapsedMilliseconds}ms");
stopwatch.Restart();
List<EnemyVent> list2 = RoundManager.Instance.allEnemyVents.Where((EnemyVent vent) => !vent.occupied).ToList();
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Filtering vents: {stopwatch.ElapsedMilliseconds}ms");
stopwatch.Restart();
for (int i = 0; i < Mathf.Min(MeltdownPlugin.config.MonsterSpawnAmount, list2.Count); i++)
{
EnemyVent val = list2[Random.Range(0, list2.Count)];
list2.Remove(val);
SpawnableEnemyWithRarity val2 = list[Random.Range(0, list2.Count)];
RoundManager instance = RoundManager.Instance;
instance.currentEnemyPower += val2.enemyType.PowerLevel;
MeltdownPlugin.logger.LogInfo((object)("Spawning a " + val2.enemyType.enemyName + " during the meltdown sequence"));
val.SpawnEnemy(val2);
}
stopwatch.Stop();
MeltdownPlugin.logger.LogDebug((object)$"Spawning enemies: {stopwatch.ElapsedMilliseconds}ms");
}
public override void OnNetworkSpawn()
{
if (MeltdownPlugin.loadedFully && ((NetworkBehaviour)this).IsHost)
{
StartMeltdownClientRpc();
}
}
internal bool EnemyCannotBeSpawned(EnemyType type)
{
if (!type.spawningDisabled)
{
return type.numberSpawned >= type.MaxCount;
}
return true;
}
internal static DialogueSegment[] GetDialogue(string translation)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
JArray translationSet = LangParser.GetTranslationSet(translation);
DialogueSegment[] array = (DialogueSegment[])(object)new DialogueSegment[((JContainer)translationSet).Count];
for (int i = 0; i < ((JContainer)translationSet).Count; i++)
{
array[i] = new DialogueSegment
{
bodyText = ((string)translationSet[i]).Replace("<meltdown_time>", Math.Round((float)MeltdownPlugin.config.MeltdownTime / 60f).ToString()),
speakerText = "meltdown.dialogue.speaker".Translate()
};
}
return array;
}
private void OnDisable()
{
if (!((Object)(object)Instance != (Object)(object)this))
{
MeltdownPlugin.logger.LogInfo((object)"Cleaning up MeltdownHandler.");
Instance = null;
if ((Object)(object)explosion != (Object)null)
{
Object.Destroy((Object)(object)explosion);
}
if ((Object)(object)shockwave != (Object)null)
{
Object.Destroy((Object)(object)shockwave);
}
if (!meltdownStarted)
{
MeltdownPlugin.logger.LogError((object)"MeltdownHandler was disabled without starting a meltdown, a client most likely failed the MeltdownReadyCheck. If you are going to report this make sure to provide ALL client logs.");
}
}
}
private void Update()
{
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
if (!meltdownStarted || HasExplosionOccured())
{
return;
}
StartOfRound instance = StartOfRound.Instance;
meltdownMusic.volume = (float)MeltdownPlugin.clientConfig.MusicVolume / 100f;
if (!Player.isInsideFactory && !MeltdownPlugin.clientConfig.MusicPlaysOutside)
{
meltdownMusic.volume = 0f;
}
meltdownTimer -= Time.deltaTime;
if (meltdownTimer <= 3f && !instance.shipIsLeaving)
{
((MonoBehaviour)this).StartCoroutine(ShipTakeOff());
}
if (meltdownTimer <= 0f)
{
meltdownMusic.Stop();
GameObject val = MeltdownMoonMapper.Instance.explosionPrefab;
if ((Object)(object)val == (Object)null)
{
val = MeltdownPlugin.assets.facilityExplosionPrefab;
}
explosion = Object.Instantiate<GameObject>(val);
explosion.transform.position = effectOrigin;
FacilityExplosionHandler facilityExplosionHandler = default(FacilityExplosionHandler);
if (!explosion.TryGetComponent<FacilityExplosionHandler>(ref facilityExplosionHandler))
{
explosion.AddComponent<FacilityExplosionHandler>();
}
}
}
private IEnumerator ShipTakeOff()
{
StartOfRound shipManager = StartOfRound.Instance;
shipManager.shipLeftAutomatically = true;
shipManager.shipIsLeaving = true;
HUDManager.Instance.ReadDialogue(GetDialogue("meltdown.dialogue.shiptakeoff"));
yield return (object)new WaitForSeconds(3f);
yield return (object)new WaitForSeconds(3f);
((Behaviour)HUDManager.Instance.shipLeavingEarlyIcon).enabled = false;
StartMatchLever val = Object.FindObjectOfType<StartMatchLever>();
val.triggerScript.animationString = "SA_PushLeverBack";
val.leverHasBeenPulled = false;
val.triggerScript.interactable = false;
val.leverAnimatorObject.SetBool("pullLever", false);
shipManager.ShipLeave();
yield return (object)new WaitForSeconds(1.5f);
shipManager.SetSpectateCameraToGameOverMode(true, (PlayerControllerB)null);
if (GameNetworkManager.Instance.localPlayerController.isPlayerDead)
{
GameNetworkManager.Instance.localPlayerController.SetSpectatedPlayerEffects(true);
}
yield return (object)new WaitForSeconds(1f);
yield return (object)new WaitForSeconds(9.5f);
}
public bool HasExplosionOccured()
{
return (Object)(object)explosion != (Object)null;
}
protected override void __initializeVariables()
{
((NetworkBehaviour)this).__initializeVariables();
}
[RuntimeInitializeOnLoadMethod]
internal static void InitializeRPCS_MeltdownHandler()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
NetworkManager.__rpc_func_table.Add(3631067672u, new RpcReceiveHandler(__rpc_handler_3631067672));
}
private static void __rpc_handler_3631067672(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
target.__rpc_exec_stage = (__RpcExecStage)2;
((MeltdownHandler)(object)target).StartMeltdownClientRpc();
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
protected internal override string __getTypeName()
{
return "MeltdownHandler";
}
}
public class Shockwave : MonoBehaviour
{
private bool localPlayerCameraShake;
private float size;
private AudioSource sound;
private Renderer renderer;
private void Awake()
{
sound = ((Component)this).gameObject.AddComponent<AudioSource>();
sound.clip = MeltdownPlugin.assets.shockwave;
sound.spatialBlend = 0f;
sound.loop = false;
renderer = ((Component)this).GetComponent<Renderer>();
}
private void Update()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
size += Time.deltaTime * 50f;
((Component)this).transform.localScale = Vector3.one * size;
if (localPlayerController.isInsideFactory)
{
renderer.enabled = false;
return;
}
renderer.enabled = true;
if (PlayerIsInsideShockwave() && !localPlayerCameraShake && MeltdownPlugin.clientConfig.ScreenShake)
{
ScreenShake();
localPlayerCameraShake = true;
sound.Play();
}
}
private void ScreenShake()
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
}
internal bool PlayerIsInsideShockwave()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
return Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) <= size;
}
}
}
namespace FacilityMeltdown.Lang
{
internal static class LangParser
{
internal static Dictionary<string, string> languages { get; private set; }
internal static Dictionary<string, object> loadedLanguage { get; private set; }
internal static Dictionary<string, object> defaultLanguage { get; private set; }
internal static void Init()
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FacilityMeltdown.Lang.defs.json");
using StreamReader streamReader = new StreamReader(stream);
string text = streamReader.ReadToEnd();
languages = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
}
internal static Dictionary<string, object> LoadLanguage(string id)
{
using Stream stream = File.Open(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "lang", id + ".json"), FileMode.Open);
using StreamReader streamReader = new StreamReader(stream);
string text = streamReader.ReadToEnd();
return JsonConvert.DeserializeObject<Dictionary<string, object>>(text);
}
internal static void SetLanguage(string id)
{
MeltdownPlugin.logger.LogInfo((object)("Loading language: " + languages[id] + " (" + id + ")"));
loadedLanguage = LoadLanguage(id);
MeltdownPlugin.logger.LogInfo((object)("Loaded " + languages[id]));
}
internal static string GetTranslation(string translation)
{
if (loadedLanguage.TryGetValue(translation, out var value))
{
return (string)value;
}
if (defaultLanguage.TryGetValue(translation, out value))
{
MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation: " + translation));
return (string)value;
}
if (translation == "lang.missing")
{
MeltdownPlugin.logger.LogError((object)"LANG.MISSING IS MISSING!!!!! THIS IS BAD!! VERY BAD!!");
return "lang.missing; <translation_id>";
}
return GetTranslation("lang.missing").Replace("<translation_id>", translation);
}
internal static JArray GetTranslationSet(string translation)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
if (loadedLanguage.TryGetValue(translation, out var value))
{
MeltdownPlugin.logger.LogInfo((object)value.GetType());
return (JArray)((value is JArray) ? value : null);
}
if (defaultLanguage.TryGetValue(translation, out value))
{
MeltdownPlugin.logger.LogError((object)("Falling back to english. for translation (dialogue): " + translation));
return (JArray)((value is JArray) ? value : null);
}
JArray val = new JArray();
val.Add(JToken.op_Implicit(GetTranslation("lang.missing").Replace("<translation_id>", translation)));
return val;
}
}
}
namespace FacilityMeltdown.Integrations
{
internal class LethalConfigIntergration
{
public static bool Enabled { get; private set; }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static void Initialize()
{
Enabled = true;
LethalConfigManager.SetModDescription("Maybe taking the appartus isn't such a great idea...");
HandleConfig(MeltdownPlugin.config);
HandleConfig(MeltdownPlugin.clientConfig);
}
private static void HandleConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
{
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Expected O, but got Unknown
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Expected O, but got Unknown
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//IL_020e: Expected O, but got Unknown
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Expected O, but got Unknown
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Expected O, but got Unknown
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Expected O, but got Unknown
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Expected O, but got Unknown
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Expected O, but got Unknown
bool flag = true;
if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
{
flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
}
foreach (var configEntry in config.configEntries)
{
PropertyInfo property = configEntry.Item1;
object uncastedEntry = configEntry.Item2;
bool flag2 = flag;
RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
if (customAttribute != null)
{
flag2 = customAttribute.RequiresRestart;
}
ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
if (property.PropertyType == typeof(int))
{
if (customAttribute2 == null)
{
throw new NotImplementedException(property.Name + ": config entry of type: int, must have a range attribute, because i was too lazy lmao");
}
ConfigEntry<int> obj2 = (ConfigEntry<int>)uncastedEntry;
IntSliderOptions val = new IntSliderOptions();
((BaseRangeOptions<int>)val).Min = (int)customAttribute2.Min;
((BaseRangeOptions<int>)val).Max = (int)customAttribute2.Max;
((BaseOptions)val).RequiresRestart = flag2;
LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(obj2, val));
if (!flag2)
{
((ConfigEntry<int>)uncastedEntry).SettingChanged += delegate
{
property.SetValue(config, ((ConfigEntry<int>)uncastedEntry).Value);
};
}
}
if (property.PropertyType == typeof(float))
{
if (customAttribute2 == null)
{
throw new NotImplementedException(property.Name + ": config entry of type: float, must have a range attribute, because i was too lazy lmao");
}
ConfigEntry<float> obj3 = (ConfigEntry<float>)uncastedEntry;
FloatSliderOptions val2 = new FloatSliderOptions();
((BaseRangeOptions<float>)val2).Min = customAttribute2.Min;
((BaseRangeOptions<float>)val2).Max = customAttribute2.Max;
((BaseOptions)val2).RequiresRestart = flag2;
LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(obj3, val2));
if (!flag2)
{
((ConfigEntry<float>)uncastedEntry).SettingChanged += delegate
{
property.SetValue(config, ((ConfigEntry<float>)uncastedEntry).Value);
};
}
}
if (property.PropertyType == typeof(bool))
{
LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem((ConfigEntry<bool>)uncastedEntry, flag2));
if (!flag2)
{
((ConfigEntry<bool>)uncastedEntry).SettingChanged += delegate
{
property.SetValue(config, ((ConfigEntry<bool>)uncastedEntry).Value);
};
}
}
if (!(property.PropertyType == typeof(string)))
{
continue;
}
LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem((ConfigEntry<string>)uncastedEntry, flag2));
if (!flag2)
{
((ConfigEntry<string>)uncastedEntry).SettingChanged += delegate
{
property.SetValue(config, ((ConfigEntry<string>)uncastedEntry).Value);
};
}
}
}
}
internal class LethalSettingsIntegration
{
public static bool Enabled { get; private set; }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static void Initialize()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
Enabled = true;
VerticalComponent val = BuildConfig(MeltdownPlugin.clientConfig);
ModSettingsConfig val2 = new ModSettingsConfig();
val2.Name = "FacilityMeltdown";
val2.Id = "me.loaforc.facilitymeltdown";
val2.Version = "2.6.13";
val2.Description = "Maybe taking the appartus isn't such a great idea...";
val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[2]
{
(MenuComponent)BuildConfig(MeltdownPlugin.config),
(MenuComponent)val
};
ModMenu.RegisterMod(val2);
val2 = new ModSettingsConfig();
val2.Name = "FacilityMeltdown";
val2.Id = "me.loaforc.facilitymeltdown";
val2.Version = "2.6.13";
val2.Description = "Maybe taking the appartus isn't such a great idea... (GameSettings are hidden in game)";
val2.MenuComponents = (MenuComponent[])(object)new MenuComponent[1] { (MenuComponent)val };
ModMenu.RegisterMod(val2, false, true);
}
private static VerticalComponent BuildConfig<T>(LoafConfig<T> config) where T : LoafConfig<T>
{
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Expected O, but got Unknown
//IL_0101: 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_0112: Expected O, but got Unknown
//IL_013e: 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_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Expected O, but got Unknown
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: 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_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Expected O, but got Unknown
//IL_025a: Unknown result type (might be due to invalid IL or missing references)
//IL_025f: Unknown result type (might be due to invalid IL or missing references)
//IL_0271: Unknown result type (might be due to invalid IL or missing references)
//IL_0294: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Expected O, but got Unknown
//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0304: Unknown result type (might be due to invalid IL or missing references)
//IL_031c: Expected O, but got Unknown
bool flag = true;
if (config.GetType().GetCustomAttribute<RequiresRestartAttribute>() != null)
{
flag = config.GetType().GetCustomAttribute<RequiresRestartAttribute>().RequiresRestart;
}
List<MenuComponent> list = new List<MenuComponent>();
string text = "Misc";
foreach (var configEntry in config.configEntries)
{
PropertyInfo property = configEntry.Item1;
object uncastedEntry = configEntry.Item2;
bool requiresRestart = flag;
RequiresRestartAttribute customAttribute = property.GetCustomAttribute<RequiresRestartAttribute>();
if (customAttribute != null)
{
requiresRestart = customAttribute.RequiresRestart;
}
ConfigGroupAttribute configGroupAttribute = (ConfigGroupAttribute)property.GetCustomAttribute(typeof(ConfigGroupAttribute));
if (configGroupAttribute != null)
{
text = configGroupAttribute.Group;
list.Add((MenuComponent)new LabelComponent
{
Text = text
});
}
else if (text == "Misc")
{
list.Add((MenuComponent)new LabelComponent
{
Text = text
});
}
ConfigRangeAttribute customAttribute2 = property.GetCustomAttribute<ConfigRangeAttribute>();
if (property.PropertyType == typeof(int))
{
list.Add((MenuComponent)new SliderComponent
{
Value = (int)property.GetValue(config),
WholeNumbers = true,
MinValue = customAttribute2.Min,
MaxValue = customAttribute2.Max,
Text = property.Name,
OnValueChanged = delegate(SliderComponent self, float value)
{
((ConfigEntry<int>)uncastedEntry).Value = (int)value;
if (!requiresRestart)
{
property.SetValue(config, value);
}
}
});
}
if (property.PropertyType == typeof(float))
{
list.Add((MenuComponent)new SliderComponent
{
Value = (float)property.GetValue(config),
MinValue = customAttribute2.Min,
MaxValue = customAttribute2.Max,
Text = property.Name,
OnValueChanged = delegate(SliderComponent self, float value)
{
((ConfigEntry<float>)uncastedEntry).Value = value;
if (!requiresRestart)
{
property.SetValue(config, value);
}
}
});
}
if (property.PropertyType == typeof(bool))
{
list.Add((MenuComponent)new ToggleComponent
{
Text = property.Name,
Value = (bool)property.GetValue(config),
OnValueChanged = delegate(ToggleComponent self, bool value)
{
((ConfigEntry<bool>)uncastedEntry).Value = value;
if (!requiresRestart)
{
property.SetValue(config, value);
}
}
});
}
if (!(property.PropertyType == typeof(string)))
{
continue;
}
list.Add((MenuComponent)new InputComponent
{
Placeholder = property.Name,
Value = (string)property.GetValue(config),
OnValueChanged = delegate(InputComponent self, string value)
{
((ConfigEntry<string>)uncastedEntry).Value = value;
if (!requiresRestart)
{
property.SetValue(config, value);
}
}
});
}
return null;
}
}
public class LobbyCompatibilityIntegration
{
public static bool Enabled { get; private set; }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private static void Initialize()
{
Enabled = true;
PluginHelper.RegisterPlugin("me.loaforc.facilitymeltdown", Version.Parse("2.6.13"), (CompatibilityLevel)2, (VersionStrictness)3);
}
}
}
namespace FacilityMeltdown.Equipment
{
public class GeigerCounterItem : GrabbableObject
{
[Space(15f)]
[Header("Audio")]
public AudioSource generalAudioSource;
public AudioSource lowRadiation;
public AudioSource mediumRadiation;
public AudioSource highRadiation;
public AudioClip toggle;
public AudioClip outOfBattery;
public GameObject needle;
public float maxRotation = 25f;
public float maxDetection = 50f;
public override void ItemActivate(bool used, bool buttonDown = true)
{
((GrabbableObject)this).ItemActivate(used, buttonDown);
MeltdownPlugin.logger.LogInfo((object)"ACTIVATED GEIGER COUNTER");
SwitchPoweredState(used);
generalAudioSource.clip = toggle;
generalAudioSource.Play();
}
public override void UseUpBatteries()
{
((GrabbableObject)this).UseUpBatteries();
SwitchPoweredState(on: false);
generalAudioSource.clip = outOfBattery;
generalAudioSource.Play();
}
public void SwitchPoweredState(bool on)
{
MeltdownPlugin.logger.LogInfo((object)$"me when the on value is {on}. :rofl::rofl::rofl:");
if (base.isBeingUsed)
{
lowRadiation.Play();
mediumRadiation.Play();
highRadiation.Play();
}
else
{
lowRadiation.Stop();
mediumRadiation.Stop();
highRadiation.Stop();
}
}
public override void Update()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
((GrabbableObject)this).Update();
if (base.isBeingUsed)
{
float num = RadiationSource.CollectRadiationFromPoint(((Component)this).transform.position);
lowRadiation.volume = 0f;
mediumRadiation.volume = 0f;
highRadiation.volume = 0f;
if (num > maxDetection)
{
highRadiation.volume = 1f;
}
else if (num > maxDetection / 2f)
{
mediumRadiation.volume = 1f;
}
else
{
lowRadiation.volume = 1f;
}
float num2 = Mathf.Clamp01(num / maxDetection) * (maxRotation * 2f);
num2 -= maxRotation;
needle.transform.localEulerAngles = new Vector3(-90f, num2, 0f);
}
}
protected override void __initializeVariables()
{
((GrabbableObject)this).__initializeVariables();
}
[MethodImpl(MethodImplOptions.NoInlining)]
protected internal override string __getTypeName()
{
return "GeigerCounterItem";
}
}
}
namespace FacilityMeltdown.Config
{
[RequiresRestart(false)]
internal class MeltdownClientConfig : LoafConfig<MeltdownClientConfig>
{
[ConfigGroup("Audio")]
[ConfigDesc("What volume the music plays at. Also controls the volume of the random voicelines that play")]
[ConfigRange(0f, 100f)]
public int MusicVolume { get; private set; } = 100;
[ConfigDesc("Does the music play outside the facility?")]
public bool MusicPlaysOutside { get; private set; } = true;
[ConfigGroup("Visuals")]
[ConfigDesc("Whether or not to shake the screen during the meltdown sequence. Doesn't control other places of screen shake in the game.")]
public bool ScreenShake { get; private set; } = true;
[ConfigDesc("Should meltdown sequence contain particle effects? Doesn't include particle effects on the fireball.")]
public bool ParticleEffects { get; private set; } = true;
[ConfigIgnore]
[RequiresRestart(true)]
public string Language { get; private set; } = "en";
internal MeltdownClientConfig(ConfigFile file)
: base(file)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
BindProperty<string>(typeof(MeltdownClientConfig).GetProperty("Language"), "Language", new ConfigDescription("What language should FacilityMeltdown use? NOTE: This only affects facility meltdown and won't change the rest of the games langauge\nSome Languages may also need FontPatcher(https://thunderstore.io/c/lethal-company/p/LeKAKiD/FontPatcher/)\nLanguages Available: " + string.Join(", ", LangParser.languages.Keys), (AcceptableValueBase)null, Array.Empty<object>()));
}
}
internal class MeltdownConfig : LoafSyncedConfig<MeltdownConfig>
{
[ConfigGroup("GameBalance")]
[ConfigDesc("Whether or not FacilityMeltdown should override appartus value. Only disable for compatibility reasons.")]
public bool OverrideApparatusValue { get; private set; } = true;
[ConfigDesc("When overriding the apparatus value what should it's base value be?")]
[ConfigRange(80f, 500f)]
public int ApparatusValue { get; private set; } = 240;
[ConfigDesc("How many monsters should spawn during the meltdown sequence? Set to 0 to disable.")]
[ConfigRange(0f, 10f)]
public int MonsterSpawnAmount { get; private set; } = 5;
[ConfigDesc("Should the lights turn on periodically? Disabling this option makes them permanently off. (Matches Vanilla Behaviour)")]
public bool EmergencyLights { get; private set; } = true;
[ConfigDesc("How many people need to be nearby to the apparatus for it to be collectable? Will go UP TO the value, e.g. if it's set to 3 and there are only 2 people in the lobby, everyone will need to be there.\nThis value is ignored and anybody can grab it from 9PM")]
[ConfigRange(1f, 10f)]
public int MinPeopleToPullApparatus { get; private set; } = 2;
[ConfigDesc("What enemies to exclude from spawning in the meltdown sequence. Comma seperated list. Supports modded entities.")]
public string DisallowedEnemies { get; private set; } = "Centipede,Hoarding bug";
[ConfigDesc("How long until the ship's scanner can scan the reactor. (Doesn't affect the vanilla `scan` command)")]
[ConfigRange(0f, 20f)]
public float ShipScanCooldown { get; private set; } = 15f;
[ConfigDesc("How accurate is the ship's scanner when scanning the reactor. Higher values mean it is more uncertain, and lower values is more accurate. (Doesn't affect the vanilla `scan` command)")]
[ConfigRange(0f, 100f)]
public float ShipScanAccuracy { get; private set; } = 15f;
[ConfigGroup("UNSUPPORTED")]
[ConfigDesc("ABSOLUETLY NOT SUPPORTED OR RECOMMENDED! Change the length of the meltdown sequence. If this breaks I am not fixing it, you have been warned.")]
[ConfigRange(60f, 300f)]
public int MeltdownTime { get; private set; } = 120;
public MeltdownConfig(ConfigFile file)
: base(file)
{
}
public List<string> GetDisallowedEnemies()
{
return DisallowedEnemies.Split(',').ToList();
}
}
}
namespace FacilityMeltdown.Behaviours
{
public class MeltdownEvents : MonoBehaviour
{
[Serializable]
public class Marker
{
internal bool Triggered;
[field: SerializeField]
public float Progress { get; private set; } = 0.5f;
[field: SerializeField]
public UnityEvent OnMarker { get; private set; }
}
[SerializeField]
private UnityEvent OnMeltdownStart;
[SerializeField]
private List<Marker> markers = new List<Marker>();
private void OnEnable()
{
MeltdownAPI.OnMeltdownStart = (Action)Delegate.Combine(MeltdownAPI.OnMeltdownStart, new Action(OnMeltdownStart.Invoke));
}
private void OnDisable()
{
MeltdownAPI.OnMeltdownStart = (Action)Delegate.Remove(MeltdownAPI.OnMeltdownStart, new Action(OnMeltdownStart.Invoke));
}
private void Update()
{
if (!MeltdownAPI.MeltdownStarted)
{
return;
}
foreach (Marker marker in markers)
{
if (!marker.Triggered && !(marker.Progress > MeltdownHandler.Instance.Progress))
{
marker.OnMarker.Invoke();
marker.Triggered = true;
}
}
}
}
public class MeltdownInteriorMapper : MonoBehaviour
{
public static MeltdownInteriorMapper Instance { get; private set; }
[Tooltip("Colour to flash lights with, should probably just leave this at red. Only applies to inside lights.")]
[field: SerializeField]
public Color outsideEmergencyLightColour { get; private set; } = Color.red;
private void Awake()
{
Instance = this;
}
private void OnDisable()
{
if ((Object)(object)Instance != (Object)null)
{
Instance = null;
}
}
internal static void EnsureMeltdownInteriorMapper()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Instance != (Object)null) && !((Object)(object)Object.FindObjectOfType<MeltdownInteriorMapper>() != (Object)null))
{
MeltdownPlugin.logger.LogInfo((object)"Creating InteriorMapper!");
Instance = new GameObject("DefaultMeltdownInteriorMappings").AddComponent<MeltdownInteriorMapper>();
}
}
}
public class MeltdownMoonMapper : MonoBehaviour
{
[SerializeField]
[Tooltip("Lights to flash red during the meltdown sequence. Doesn't include inside lights.")]
public List<Light> outsideEmergencyLights = new List<Light>();
public static MeltdownMoonMapper Instance { get; private set; }
[Tooltip("Colour to flash lights with, should probably just leave this at red. Only applies to outside lights.")]
[field: SerializeField]
public Color outsideEmergencyLightColour { get; private set; } = Color.red;
[field: SerializeField]
public GameObject shockwavePrefab { get; private set; }
[field: SerializeField]
public GameObject explosionPrefab { get; private set; }
[field: SerializeField]
public Vector3 EffectOrigin { get; private set; }
private void Awake()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
if (EffectOrigin == Vector3.zero)
{
EffectOrigin = RoundManager.FindMainEntrancePosition(false, true);
}
}
private void OnDisable()
{
if ((Object)(object)Instance != (Object)null)
{
Instance = null;
}
}
internal static void EnsureMeltdownMoonMapper()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Instance != (Object)null) && !((Object)(object)Object.FindObjectOfType<MeltdownMoonMapper>() != (Object)null))
{
MeltdownPlugin.logger.LogInfo((object)"Creating MoonMapper!");
Instance = new GameObject("DefaultMeltdownMappings").AddComponent<MeltdownMoonMapper>();
Instance.outsideEmergencyLights = (from light in GameObject.Find("Environment").GetComponentsInChildren<Light>()
where CheckParentForDisallowed(((Component)light).transform)
select light).ToList();
}
}
private static bool CheckParentForDisallowed(Transform child)
{
if (((Object)((Component)child).gameObject).name == "Sun" || ((Object)((Component)child).gameObject).name == "ItemShipAnimContainer" || ((Object)((Component)child).gameObject).name == "MapPropsContainer")
{
return false;
}
if ((Object)(object)child.parent == (Object)null)
{
return true;
}
return CheckParentForDisallowed(child.parent);
}
}
public class RadiationSource : MonoBehaviour
{
[HideInInspector]
public static List<RadiationSource> radiators = new List<RadiationSource>();
[Range(0f, 100f)]
public float radiationAmount = 70f;
public bool isGlobal;
[Range(0f, 100f)]
public float radiationDistance = 50f;
[Header("Decay Settings")]
public bool doesDecay;
[Range(0f, 120f)]
public float decayTime = 120f;
public AnimationCurve radiationOutputVsDecay = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
{
new Keyframe(0f, 1f),
new Keyframe(0f, 1f)
});
private float existingTime;
public static float CollectRadiationFromPoint(Vector3 point)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
float num = 0f;
foreach (RadiationSource radiator in radiators)
{
num += radiator.GetRadiationFromPoint(point);
}
return num;
}
public float GetRadiationAtDistance(float distance)
{
if (distance > radiationDistance)
{
return 0f;
}
float num = Mathf.Clamp01((radiationDistance - distance) / radiationDistance);
if (isGlobal)
{
num = 1f;
}
return num * radiationAmount * GetDecayReduction();
}
public float GetDecayProgress()
{
if (!doesDecay)
{
return 0f;
}
return Mathf.Clamp01(existingTime / decayTime);
}
public float GetDecayReduction()
{
if (!doesDecay)
{
return 1f;
}
return radiationOutputVsDecay.Evaluate(GetDecayProgress());
}
public float GetRadiationFromPoint(Vector3 point)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
return GetRadiationAtDistance(Vector3.Distance(((Component)this).transform.position, point));
}
private void OnEnable()
{
radiators.Add(this);
MeltdownPlugin.logger.LogInfo((object)$"A new RadiationSource was created, there is now: {radiators.Count} radiators.");
}
private void OnDisable()
{
radiators.Remove(this);
}
private void Update()
{
existingTime += Time.deltaTime;
}
}
}
namespace FacilityMeltdown.API
{
public static class MeltdownAPI
{
internal static Action OnMeltdownStart = delegate
{
};
public static bool MeltdownStarted => (Object)(object)MeltdownHandler.Instance != (Object)null;
public static void StartMeltdown(string modGUID)
{
if (!MeltdownStarted)
{
MeltdownPlugin.logger.LogInfo((object)("A mod (" + modGUID + ") has begun a meltdown!"));
if (!((NetworkBehaviour)GameNetworkManager.Instance.localPlayerController).IsHost)
{
MeltdownPlugin.logger.LogWarning((object)"Local Player isn't host! Aborting!!");
return;
}
GameObject val = Object.Instantiate<GameObject>(MeltdownPlugin.assets.meltdownHandlerPrefab);
val.GetComponent<NetworkObject>().Spawn(false);
}
}
public static void RegisterMeltdownListener(Action callback)
{
OnMeltdownStart = (Action)Delegate.Combine(OnMeltdownStart, callback);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}
namespace FacilityMeltdown.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}