using System;
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.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using LethalLevelLoader;
using LethalLib.Compats;
using LethalLib.Extras;
using LethalLib.Modules;
using LethalLib.NetcodePatcher;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
[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-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: AssemblyCompany("Evaisa")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Content-addition API for Lethal Company")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+bc9d11fbc412aca87f9478eebaedb3c739b97c74")]
[assembly: AssemblyProduct("LethalLib")]
[assembly: AssemblyTitle("LethalLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvaisaDev/LethalLib")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[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 LethalLib
{
[BepInPlugin("evaisa.lethallib", "LethalLib", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
public const string ModGUID = "evaisa.lethallib";
public const string ModName = "LethalLib";
public const string ModVersion = "1.2.0";
public static AssetBundle MainAssets;
public static ManualLogSource logger;
public static ConfigFile config;
public static Plugin Instance;
public static ConfigEntry<bool> extendedLogging;
private void Awake()
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
config = ((BaseUnityPlugin)this).Config;
logger = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalLib loaded!!");
extendedLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging");
MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "lethallib"));
new ILHook((MethodBase)typeof(StackTrace).GetMethod("AddFrames", BindingFlags.Instance | BindingFlags.NonPublic), new Manipulator(IlHook));
Enemies.Init();
Items.Init();
Unlockables.Init();
MapObjects.Init();
Dungeon.Init();
Weathers.Init();
Player.Init();
Utilities.Init();
NetworkPrefabs.Init();
}
private void IlHook(ILContext il)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
ILCursor val = new ILCursor(il);
MethodInfo getFileLineNumberMethod = typeof(StackFrame).GetMethod("GetFileLineNumber", BindingFlags.Instance | BindingFlags.Public);
if (val.TryGotoNext(new Func<Instruction, bool>[1]
{
(Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)getFileLineNumberMethod)
}))
{
val.RemoveRange(2);
val.EmitDelegate<Func<StackFrame, string>>((Func<StackFrame, string>)GetLineOrIL);
}
}
private static string GetLineOrIL(StackFrame instance)
{
int fileLineNumber = instance.GetFileLineNumber();
if (fileLineNumber == -1 || fileLineNumber == 0)
{
return "IL_" + instance.GetILOffset().ToString("X4");
}
return fileLineNumber.ToString();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "LethalLib";
public const string PLUGIN_NAME = "LethalLib";
public const string PLUGIN_VERSION = "1.2.0";
}
}
namespace LethalLib.Modules
{
public class ContentLoader
{
public class CustomContent
{
private string id = "";
public string ID => id;
public CustomContent(string id)
{
this.id = id;
}
}
public class CustomItem : CustomContent
{
public Action<Item> registryCallback = delegate
{
};
public string contentPath = "";
internal Item item;
public Item Item => item;
public CustomItem(string id, string contentPath, Action<Item> registryCallback = null)
: base(id)
{
this.contentPath = contentPath;
if (registryCallback != null)
{
this.registryCallback = registryCallback;
}
}
}
public class ShopItem : CustomItem
{
public int initPrice;
public string buyNode1Path;
public string buyNode2Path;
public string itemInfoPath;
public void RemoveFromShop()
{
Items.RemoveShopItem(base.Item);
}
public void SetPrice(int price)
{
Items.UpdateShopItemPrice(base.Item, price);
}
public ShopItem(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, Action<Item> registryCallback = null)
: base(id, contentPath, registryCallback)
{
initPrice = price;
this.buyNode1Path = buyNode1Path;
this.buyNode2Path = buyNode2Path;
this.itemInfoPath = itemInfoPath;
}
}
public class ScrapItem : CustomItem
{
public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();
public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();
public int Rarity => 0;
public void RemoveFromLevels(Levels.LevelTypes levelFlags)
{
Items.RemoveScrapFromLevels(base.Item, levelFlags);
}
public ScrapItem(string id, string contentPath, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Action<Item> registryCallback = null)
: base(id, contentPath, registryCallback)
{
if (levelFlags != Levels.LevelTypes.None)
{
levelRarities.Add(levelFlags, rarity);
}
else if (levelOverrides != null)
{
foreach (string key in levelOverrides)
{
customLevelRarities.Add(key, rarity);
}
}
}
public ScrapItem(string id, string contentPath, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, Action<Item> registryCallback = null)
: base(id, contentPath, registryCallback)
{
if (levelRarities != null)
{
this.levelRarities = levelRarities;
}
if (customLevelRarities != null)
{
this.customLevelRarities = customLevelRarities;
}
}
}
public class Unlockable : CustomContent
{
public Action<UnlockableItem> registryCallback = delegate
{
};
internal UnlockableItem unlockable;
public string contentPath = "";
public int initPrice;
public string buyNode1Path;
public string buyNode2Path;
public string itemInfoPath;
public StoreType storeType;
public UnlockableItem UnlockableItem => unlockable;
public void RemoveFromShop()
{
Unlockables.DisableUnlockable(UnlockableItem);
}
public void SetPrice(int price)
{
Unlockables.UpdateUnlockablePrice(UnlockableItem, price);
}
public Unlockable(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, StoreType storeType = StoreType.None, Action<UnlockableItem> registryCallback = null)
: base(id)
{
this.contentPath = contentPath;
if (registryCallback != null)
{
this.registryCallback = registryCallback;
}
initPrice = price;
this.buyNode1Path = buyNode1Path;
this.buyNode2Path = buyNode2Path;
this.itemInfoPath = itemInfoPath;
this.storeType = storeType;
}
}
public class CustomEnemy : CustomContent
{
public Action<EnemyType> registryCallback = delegate
{
};
public string contentPath = "";
internal EnemyType enemy;
public string infoNodePath;
public string infoKeywordPath;
public int rarity;
public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;
public string[] levelOverrides;
public Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1);
public EnemyType Enemy => enemy;
public void RemoveFromLevels(Levels.LevelTypes levelFlags)
{
Enemies.RemoveEnemyFromLevels(Enemy, levelFlags);
}
public CustomEnemy(string id, string contentPath, int rarity = 0, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1), string[] levelOverrides = null, string infoNodePath = null, string infoKeywordPath = null, Action<EnemyType> registryCallback = null)
: base(id)
{
this.contentPath = contentPath;
if (registryCallback != null)
{
this.registryCallback = registryCallback;
}
this.infoNodePath = infoNodePath;
this.infoKeywordPath = infoKeywordPath;
this.rarity = rarity;
LevelTypes = levelFlags;
this.levelOverrides = levelOverrides;
this.spawnType = spawnType;
}
}
public class MapHazard : CustomContent
{
public Action<SpawnableMapObjectDef> registryCallback = delegate
{
};
public string contentPath = "";
internal SpawnableMapObjectDef hazard;
public Func<SelectableLevel, AnimationCurve> spawnRateFunction;
public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;
public string[] levelOverrides;
public SpawnableMapObjectDef Hazard => hazard;
public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
{
MapObjects.RemoveMapObject(Hazard, levelFlags, levelOverrides);
}
public MapHazard(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableMapObjectDef> registryCallback = null)
: base(id)
{
this.contentPath = contentPath;
if (registryCallback != null)
{
this.registryCallback = registryCallback;
}
LevelTypes = levelFlags;
this.levelOverrides = levelOverrides;
this.spawnRateFunction = spawnRateFunction;
}
}
public class OutsideObject : CustomContent
{
public Action<SpawnableOutsideObjectDef> registryCallback = delegate
{
};
public string contentPath = "";
internal SpawnableOutsideObjectDef mapObject;
public Func<SelectableLevel, AnimationCurve> spawnRateFunction;
public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None;
public string[] levelOverrides;
public SpawnableOutsideObjectDef MapObject => mapObject;
public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
{
MapObjects.RemoveOutsideObject(MapObject, levelFlags, levelOverrides);
}
public OutsideObject(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableOutsideObjectDef> registryCallback = null)
: base(id)
{
this.contentPath = contentPath;
if (registryCallback != null)
{
this.registryCallback = registryCallback;
}
LevelTypes = levelFlags;
this.levelOverrides = levelOverrides;
this.spawnRateFunction = spawnRateFunction;
}
}
public PluginInfo modInfo;
private AssetBundle modBundle;
public Action<CustomContent, GameObject> prefabCallback = delegate
{
};
public Dictionary<string, CustomContent> LoadedContent { get; } = new Dictionary<string, CustomContent>();
public string modName => modInfo.Metadata.Name;
public string modVersion => modInfo.Metadata.Version.ToString();
public string modGUID => modInfo.Metadata.GUID;
public ContentLoader(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
{
this.modInfo = modInfo;
this.modBundle = modBundle;
if (prefabCallback != null)
{
this.prefabCallback = prefabCallback;
}
}
public ContentLoader Create(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null)
{
return new ContentLoader(modInfo, modBundle, prefabCallback);
}
public void Register(CustomContent content)
{
if (LoadedContent.ContainsKey(content.ID))
{
Debug.LogError((object)("[LethalLib] " + modName + " tried to register content with ID " + content.ID + " but it already exists!"));
return;
}
if (content is CustomItem customItem)
{
Item val = (customItem.item = modBundle.LoadAsset<Item>(customItem.contentPath));
NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
Utilities.FixMixerGroups(val.spawnPrefab);
prefabCallback(customItem, val.spawnPrefab);
customItem.registryCallback(val);
if (content is ShopItem shopItem)
{
TerminalNode buyNode = null;
TerminalNode buyNode2 = null;
TerminalNode itemInfo = null;
if (shopItem.buyNode1Path != null)
{
buyNode = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode1Path);
}
if (shopItem.buyNode2Path != null)
{
buyNode2 = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode2Path);
}
if (shopItem.itemInfoPath != null)
{
itemInfo = modBundle.LoadAsset<TerminalNode>(shopItem.itemInfoPath);
}
Items.RegisterShopItem(val, buyNode, buyNode2, itemInfo, shopItem.initPrice);
}
else if (content is ScrapItem scrapItem)
{
Items.RegisterScrap(val, scrapItem.levelRarities, scrapItem.customLevelRarities);
}
else
{
Items.RegisterItem(val);
}
}
else if (content is Unlockable unlockable)
{
UnlockableItemDef unlockableItemDef = modBundle.LoadAsset<UnlockableItemDef>(unlockable.contentPath);
if ((Object)(object)unlockableItemDef.unlockable.prefabObject != (Object)null)
{
NetworkPrefabs.RegisterNetworkPrefab(unlockableItemDef.unlockable.prefabObject);
prefabCallback(content, unlockableItemDef.unlockable.prefabObject);
Utilities.FixMixerGroups(unlockableItemDef.unlockable.prefabObject);
}
unlockable.unlockable = unlockableItemDef.unlockable;
unlockable.registryCallback(unlockableItemDef.unlockable);
TerminalNode buyNode3 = null;
TerminalNode buyNode4 = null;
TerminalNode itemInfo2 = null;
if (unlockable.buyNode1Path != null)
{
buyNode3 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode1Path);
}
if (unlockable.buyNode2Path != null)
{
buyNode4 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode2Path);
}
if (unlockable.itemInfoPath != null)
{
itemInfo2 = modBundle.LoadAsset<TerminalNode>(unlockable.itemInfoPath);
}
Unlockables.RegisterUnlockable(unlockableItemDef, unlockable.storeType, buyNode3, buyNode4, itemInfo2, unlockable.initPrice);
}
else if (content is CustomEnemy customEnemy)
{
EnemyType val2 = modBundle.LoadAsset<EnemyType>(customEnemy.contentPath);
NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab);
Utilities.FixMixerGroups(val2.enemyPrefab);
customEnemy.enemy = val2;
prefabCallback(content, val2.enemyPrefab);
customEnemy.registryCallback(val2);
TerminalNode infoNode = null;
TerminalKeyword infoKeyword = null;
if (customEnemy.infoNodePath != null)
{
infoNode = modBundle.LoadAsset<TerminalNode>(customEnemy.infoNodePath);
}
if (customEnemy.infoKeywordPath != null)
{
infoKeyword = modBundle.LoadAsset<TerminalKeyword>(customEnemy.infoKeywordPath);
}
if (customEnemy.spawnType == (Enemies.SpawnType)(-1))
{
Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.levelOverrides, infoNode, infoKeyword);
}
else
{
Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.spawnType, customEnemy.levelOverrides, infoNode, infoKeyword);
}
}
else if (content is MapHazard mapHazard)
{
SpawnableMapObjectDef spawnableMapObjectDef = (mapHazard.hazard = modBundle.LoadAsset<SpawnableMapObjectDef>(mapHazard.contentPath));
NetworkPrefabs.RegisterNetworkPrefab(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
Utilities.FixMixerGroups(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
prefabCallback(content, spawnableMapObjectDef.spawnableMapObject.prefabToSpawn);
mapHazard.registryCallback(spawnableMapObjectDef);
MapObjects.RegisterMapObject(spawnableMapObjectDef, mapHazard.LevelTypes, mapHazard.levelOverrides, mapHazard.spawnRateFunction);
}
else if (content is OutsideObject outsideObject)
{
SpawnableOutsideObjectDef spawnableOutsideObjectDef = (outsideObject.mapObject = modBundle.LoadAsset<SpawnableOutsideObjectDef>(outsideObject.contentPath));
NetworkPrefabs.RegisterNetworkPrefab(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
Utilities.FixMixerGroups(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
prefabCallback(content, spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn);
outsideObject.registryCallback(spawnableOutsideObjectDef);
MapObjects.RegisterOutsideObject(spawnableOutsideObjectDef, outsideObject.LevelTypes, outsideObject.levelOverrides, outsideObject.spawnRateFunction);
}
LoadedContent.Add(content.ID, content);
}
public void RegisterAll(CustomContent[] content)
{
Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Length} content items!");
foreach (CustomContent content2 in content)
{
Register(content2);
}
}
public void RegisterAll(List<CustomContent> content)
{
Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Count} content items!");
foreach (CustomContent item in content)
{
Register(item);
}
}
}
public class Dungeon
{
public class CustomDungeonArchetype
{
public DungeonArchetype archeType;
public Levels.LevelTypes LevelTypes;
public int lineIndex = -1;
}
public class CustomGraphLine
{
public GraphLine graphLine;
public Levels.LevelTypes LevelTypes;
}
public class CustomDungeon
{
public int rarity;
public DungeonFlow dungeonFlow;
public Levels.LevelTypes LevelTypes;
public string[] levelOverrides;
public int dungeonIndex = -1;
public AudioClip firstTimeDungeonAudio;
}
[CompilerGenerated]
private static class <>O
{
public static hook_GenerateNewFloor <0>__RoundManager_GenerateNewFloor;
public static hook_Start <1>__RoundManager_Start;
}
public static List<CustomDungeonArchetype> customDungeonArchetypes = new List<CustomDungeonArchetype>();
public static List<CustomGraphLine> customGraphLines = new List<CustomGraphLine>();
public static Dictionary<string, TileSet> extraTileSets = new Dictionary<string, TileSet>();
public static Dictionary<string, GameObjectChance> extraRooms = new Dictionary<string, GameObjectChance>();
public static List<CustomDungeon> customDungeons = new List<CustomDungeon>();
public static void Init()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
object obj = <>O.<0>__RoundManager_GenerateNewFloor;
if (obj == null)
{
hook_GenerateNewFloor val = RoundManager_GenerateNewFloor;
<>O.<0>__RoundManager_GenerateNewFloor = val;
obj = (object)val;
}
RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj;
object obj2 = <>O.<1>__RoundManager_Start;
if (obj2 == null)
{
hook_Start val2 = RoundManager_Start;
<>O.<1>__RoundManager_Start = val2;
obj2 = (object)val2;
}
RoundManager.Start += (hook_Start)obj2;
}
private static void RoundManager_Start(orig_Start orig, RoundManager self)
{
orig.Invoke(self);
}
private static void RoundManager_GenerateNewFloor(orig_GenerateNewFloor orig, RoundManager self)
{
string name = ((Object)self.currentLevel).name;
if (Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
Levels.LevelTypes levelEnum = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name);
int index = 0;
self.dungeonGenerator.Generator.DungeonFlow.Lines.ForEach(delegate(GraphLine line)
{
foreach (CustomDungeonArchetype customDungeonArchetype in customDungeonArchetypes)
{
if (customDungeonArchetype.LevelTypes.HasFlag(levelEnum) && !line.DungeonArchetypes.Contains(customDungeonArchetype.archeType) && (customDungeonArchetype.lineIndex == -1 || customDungeonArchetype.lineIndex == index))
{
line.DungeonArchetypes.Add(customDungeonArchetype.archeType);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Added " + ((Object)customDungeonArchetype.archeType).name + " to " + name));
}
}
}
foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
{
string name2 = ((Object)dungeonArchetype).name;
if (extraTileSets.ContainsKey(name2))
{
TileSet val4 = extraTileSets[name2];
if (!dungeonArchetype.TileSets.Contains(val4))
{
dungeonArchetype.TileSets.Add(val4);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Added " + ((Object)val4).name + " to " + name));
}
}
}
foreach (TileSet tileSet in dungeonArchetype.TileSets)
{
string name3 = ((Object)tileSet).name;
if (extraRooms.ContainsKey(name3))
{
GameObjectChance item = extraRooms[name3];
if (!tileSet.TileWeights.Weights.Contains(item))
{
tileSet.TileWeights.Weights.Add(item);
}
}
}
}
index++;
});
foreach (CustomGraphLine customGraphLine in customGraphLines)
{
if (customGraphLine.LevelTypes.HasFlag(levelEnum) && !self.dungeonGenerator.Generator.DungeonFlow.Lines.Contains(customGraphLine.graphLine))
{
self.dungeonGenerator.Generator.DungeonFlow.Lines.Add(customGraphLine.graphLine);
}
}
}
orig.Invoke(self);
NetworkManager val = Object.FindObjectOfType<NetworkManager>();
RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
RandomMapObject[] array2 = array;
foreach (RandomMapObject val2 in array2)
{
for (int j = 0; j < val2.spawnablePrefabs.Count; j++)
{
string prefabName = ((Object)val2.spawnablePrefabs[j]).name;
NetworkPrefab val3 = ((IEnumerable<NetworkPrefab>)val.NetworkConfig.Prefabs.m_Prefabs).FirstOrDefault((Func<NetworkPrefab, bool>)((NetworkPrefab x) => ((Object)x.Prefab).name == prefabName));
if (val3 != null && (Object)(object)val3.Prefab != (Object)(object)val2.spawnablePrefabs[j])
{
val2.spawnablePrefabs[j] = val3.Prefab;
}
else if (val3 == null)
{
Plugin.logger.LogError((object)("DungeonGeneration - Could not find network prefab (" + prefabName + ")! Make sure your assigned prefab is registered with the network manager, or named identically to the vanilla prefab you are referencing."));
}
}
}
}
public static void AddArchetype(DungeonArchetype archetype, Levels.LevelTypes levelFlags, int lineIndex = -1)
{
CustomDungeonArchetype customDungeonArchetype = new CustomDungeonArchetype();
customDungeonArchetype.archeType = archetype;
customDungeonArchetype.LevelTypes = levelFlags;
customDungeonArchetype.lineIndex = lineIndex;
customDungeonArchetypes.Add(customDungeonArchetype);
}
public static void AddLine(GraphLine line, Levels.LevelTypes levelFlags)
{
CustomGraphLine customGraphLine = new CustomGraphLine();
customGraphLine.graphLine = line;
customGraphLine.LevelTypes = levelFlags;
customGraphLines.Add(customGraphLine);
}
public static void AddLine(DungeonGraphLineDef line, Levels.LevelTypes levelFlags)
{
AddLine(line.graphLine, levelFlags);
}
public static void AddTileSet(TileSet set, string archetypeName)
{
extraTileSets.Add(archetypeName, set);
}
public static void AddRoom(GameObjectChance room, string tileSetName)
{
extraRooms.Add(tileSetName, room);
}
public static void AddRoom(GameObjectChanceDef room, string tileSetName)
{
AddRoom(room.gameObjectChance, tileSetName);
}
public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags)
{
AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, dungeon.firstTimeDungeonAudio);
}
public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags, string[] levelOverrides)
{
AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, levelOverrides, dungeon.firstTimeDungeonAudio);
}
public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, AudioClip firstTimeDungeonAudio = null)
{
customDungeons.Add(new CustomDungeon
{
dungeonFlow = dungeon,
rarity = rarity,
LevelTypes = levelFlags,
firstTimeDungeonAudio = firstTimeDungeonAudio
});
}
public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, string[] levelOverrides = null, AudioClip firstTimeDungeonAudio = null)
{
customDungeons.Add(new CustomDungeon
{
dungeonFlow = dungeon,
rarity = rarity,
LevelTypes = levelFlags,
firstTimeDungeonAudio = firstTimeDungeonAudio,
levelOverrides = levelOverrides
});
}
}
public class Enemies
{
public struct EnemyAssetInfo
{
public EnemyType EnemyAsset;
public TerminalKeyword keyword;
}
public enum SpawnType
{
Default,
Daytime,
Outside
}
public class SpawnableEnemy
{
public EnemyType enemy;
public SpawnType spawnType;
public TerminalNode terminalNode;
public TerminalKeyword infoKeyword;
public string modName;
public int rarity;
public Levels.LevelTypes spawnLevels;
public string[] spawnLevelOverrides;
public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();
public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();
public SpawnableEnemy(EnemyType enemy, int rarity, Levels.LevelTypes spawnLevels, SpawnType spawnType, string[] spawnLevelOverrides = null)
{
this.enemy = enemy;
this.spawnLevels = spawnLevels;
this.spawnType = spawnType;
if (spawnLevelOverrides != null)
{
foreach (string levelName in spawnLevelOverrides)
{
customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
}
}
if (spawnLevels == Levels.LevelTypes.None)
{
return;
}
foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes)))
{
if (spawnLevels.HasFlag(value))
{
levelRarities.Add(value, rarity);
}
}
}
public SpawnableEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
{
this.enemy = enemy;
this.spawnType = spawnType;
if (levelRarities != null)
{
this.levelRarities = levelRarities;
}
if (customLevelRarities != null)
{
this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities);
}
}
}
[CompilerGenerated]
private static class <>O
{
public static hook_Awake <0>__RegisterLevelEnemies;
public static hook_Start <1>__Terminal_Start;
public static hook_Start <2>__QuickMenuManager_Start;
public static hook_Start <3>__RegisterLevelEnemiesforLLL_RoundManager_Start;
public static hook_Start <4>__RegisterLevelEnemiesforLE_Terminal_Start;
}
private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>();
private static bool addedToDebug = false;
public static Terminal terminal;
public static List<EnemyAssetInfo> enemyAssetInfos = new List<EnemyAssetInfo>();
public static List<SpawnableEnemy> spawnableEnemies = new List<SpawnableEnemy>();
public static void Init()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
object obj = <>O.<0>__RegisterLevelEnemies;
if (obj == null)
{
hook_Awake val = RegisterLevelEnemies;
<>O.<0>__RegisterLevelEnemies = val;
obj = (object)val;
}
StartOfRound.Awake += (hook_Awake)obj;
object obj2 = <>O.<1>__Terminal_Start;
if (obj2 == null)
{
hook_Start val2 = Terminal_Start;
<>O.<1>__Terminal_Start = val2;
obj2 = (object)val2;
}
Terminal.Start += (hook_Start)obj2;
object obj3 = <>O.<2>__QuickMenuManager_Start;
if (obj3 == null)
{
hook_Start val3 = QuickMenuManager_Start;
<>O.<2>__QuickMenuManager_Start = val3;
obj3 = (object)val3;
}
QuickMenuManager.Start += (hook_Start)obj3;
}
private static void QuickMenuManager_Start(orig_Start orig, QuickMenuManager self)
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
if (addedToDebug)
{
orig.Invoke(self);
return;
}
SelectableLevel testAllEnemiesLevel = self.testAllEnemiesLevel;
List<SpawnableEnemyWithRarity> enemies = testAllEnemiesLevel.Enemies;
List<SpawnableEnemyWithRarity> daytimeEnemies = testAllEnemiesLevel.DaytimeEnemies;
List<SpawnableEnemyWithRarity> outsideEnemies = testAllEnemiesLevel.OutsideEnemies;
foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
{
if (enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
{
continue;
}
SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(spawnableEnemy.enemy, spawnableEnemy.rarity);
switch (spawnableEnemy.spawnType)
{
case SpawnType.Default:
if (!enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
{
enemies.Add(item);
}
break;
case SpawnType.Daytime:
if (!daytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
{
daytimeEnemies.Add(item);
}
break;
case SpawnType.Outside:
if (!outsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy))
{
outsideEnemies.Add(item);
}
break;
}
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"Added {spawnableEnemy.enemy.enemyName} to DebugList [{spawnableEnemy.spawnType}]");
}
}
addedToDebug = true;
orig.Invoke(self);
}
private static void Terminal_Start(orig_Start orig, Terminal self)
{
//IL_0264: Unknown result type (might be due to invalid IL or missing references)
//IL_026e: Expected O, but got Unknown
terminal = self;
TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
List<string> list = new List<string>();
foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
{
if (list.Contains(spawnableEnemy.enemy.enemyName))
{
Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
continue;
}
if ((Object)(object)spawnableEnemy.terminalNode == (Object)null)
{
spawnableEnemy.terminalNode = ScriptableObject.CreateInstance<TerminalNode>();
spawnableEnemy.terminalNode.displayText = spawnableEnemy.enemy.enemyName + "\n\nDanger level: Unknown\n\n[No information about this creature was found.]\n\n";
spawnableEnemy.terminalNode.clearPreviousText = true;
spawnableEnemy.terminalNode.maxCharactersToType = 35;
spawnableEnemy.terminalNode.creatureName = spawnableEnemy.enemy.enemyName;
}
if (self.enemyFiles.Any((TerminalNode x) => x.creatureName == spawnableEnemy.terminalNode.creatureName))
{
Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added"));
continue;
}
TerminalKeyword keyword2 = (((Object)(object)spawnableEnemy.infoKeyword != (Object)null) ? spawnableEnemy.infoKeyword : TerminalUtils.CreateTerminalKeyword(spawnableEnemy.terminalNode.creatureName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val));
keyword2.defaultVerb = val;
List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
if (!list2.Any((TerminalKeyword x) => x.word == keyword2.word))
{
list2.Add(keyword2);
self.terminalNodes.allKeywords = list2.ToArray();
}
List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
if (!list3.Any((CompatibleNoun x) => x.noun.word == keyword2.word))
{
list3.Add(new CompatibleNoun(keyword2, spawnableEnemy.terminalNode));
}
val.compatibleNouns = list3.ToArray();
spawnableEnemy.terminalNode.creatureFileID = self.enemyFiles.Count;
self.enemyFiles.Add(spawnableEnemy.terminalNode);
ScanNodeProperties[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<ScanNodeProperties>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].creatureScanID = spawnableEnemy.terminalNode.creatureFileID;
}
EnemyAssetInfo enemyAssetInfo = default(EnemyAssetInfo);
enemyAssetInfo.EnemyAsset = spawnableEnemy.enemy;
enemyAssetInfo.keyword = keyword2;
EnemyAssetInfo item = enemyAssetInfo;
enemyAssetInfos.Add(item);
}
orig.Invoke(self);
}
private static void RegisterLevelEnemies(orig_Awake orig, StartOfRound self)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_006f: 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)
//IL_007a: Expected O, but got Unknown
orig.Invoke(self);
RegisterLethalLibEnemiesForAllLevels();
if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader"))
{
object obj = <>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start;
if (obj == null)
{
hook_Start val = RegisterLevelEnemiesforLLL_RoundManager_Start;
<>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start = val;
obj = (object)val;
}
RoundManager.Start += (hook_Start)obj;
}
if (Chainloader.PluginInfos.ContainsKey("LethalExpansion"))
{
object obj2 = <>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start;
if (obj2 == null)
{
hook_Start val2 = RegisterLevelEnemiesforLE_Terminal_Start;
<>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start = val2;
obj2 = (object)val2;
}
Terminal.Start += (hook_Start)obj2;
}
}
private static void RegisterLevelEnemiesforLLL_RoundManager_Start(orig_Start orig, RoundManager self)
{
orig.Invoke(self);
RegisterLethalLibEnemiesForAllLevels();
}
private static void RegisterLevelEnemiesforLE_Terminal_Start(orig_Start orig, Terminal self)
{
orig.Invoke(self);
RegisterLethalLibEnemiesForAllLevels();
}
private static void RegisterLethalLibEnemiesForAllLevels()
{
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
if (levelsAlreadyAddedTo.Contains(val))
{
continue;
}
foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies)
{
AddEnemyToLevel(spawnableEnemy, val);
}
levelsAlreadyAddedTo.Add(val);
}
}
private static void AddEnemyToLevel(SpawnableEnemy spawnableEnemy, SelectableLevel level)
{
//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Expected O, but got Unknown
SpawnableEnemy spawnableEnemy2 = spawnableEnemy;
string text = ((Object)level).name;
string lLLNameOfLevel = Levels.Compatibility.GetLLLNameOfLevel(text);
Levels.LevelTypes result = Levels.LevelTypes.None;
bool flag = false;
if (Enum.TryParse<Levels.LevelTypes>(text, ignoreCase: true, out result))
{
flag = true;
}
else
{
text = lLLNameOfLevel;
}
string chosenTag = string.Empty;
bool flag2 = spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All) || (spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.Keys != null && Levels.Compatibility.ContentIncludedToLevelViaTag(spawnableEnemy2.customLevelRarities.Keys.ToArray(), level, out chosenTag)) || (flag && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) || (!flag && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) || (flag && spawnableEnemy2.levelRarities.ContainsKey(result)) || (!flag && spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(lLLNameOfLevel));
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} for enemy: {spawnableEnemy2.enemy.enemyName}, isCurrentLevelFromVanilla: {flag}, Found valid: {flag2}");
}
if (!flag2)
{
return;
}
int num = 0;
if (spawnableEnemy2.levelRarities.ContainsKey(result))
{
num = spawnableEnemy2.levelRarities[result];
}
else if (spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(text))
{
num = spawnableEnemy2.customLevelRarities[text];
}
else if (spawnableEnemy2.customLevelRarities != null && chosenTag != string.Empty && spawnableEnemy2.customLevelRarities.ContainsKey(chosenTag))
{
num = spawnableEnemy2.customLevelRarities[chosenTag];
}
else if (flag && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla))
{
num = spawnableEnemy2.levelRarities[Levels.LevelTypes.Vanilla];
}
else if (!flag && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded))
{
num = spawnableEnemy2.levelRarities[Levels.LevelTypes.Modded];
}
else if (spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All))
{
num = spawnableEnemy2.levelRarities[Levels.LevelTypes.All];
}
SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(spawnableEnemy2.enemy, num);
switch (spawnableEnemy2.spawnType)
{
case SpawnType.Default:
if (!level.Enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
{
level.Enemies.Add(item);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} added {spawnableEnemy2.enemy.enemyName} with weight {num} and SpawnType [Inside/Default]");
}
}
break;
case SpawnType.Daytime:
if (!level.DaytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
{
level.DaytimeEnemies.Add(item);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} added {spawnableEnemy2.enemy.enemyName} with weight {num} andSpawnType [Daytime]");
}
}
break;
case SpawnType.Outside:
if (!level.OutsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy))
{
level.OutsideEnemies.Add(item);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} added {spawnableEnemy2.enemy.enemyName} with weight {num} and SpawnType [Outside]");
}
}
break;
}
}
public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword);
}
public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
EnemyType enemy2 = enemy;
EnemyNullCheck(enemy2);
SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType);
if (spawnableEnemy != null)
{
if (levelFlags != Levels.LevelTypes.None)
{
spawnableEnemy.levelRarities.Add(levelFlags, rarity);
}
if (spawnLevelOverrides != null)
{
foreach (string levelName in spawnLevelOverrides)
{
spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
}
}
}
else
{
spawnableEnemy = new SpawnableEnemy(enemy2, rarity, levelFlags, spawnType, spawnLevelOverrides);
spawnableEnemy.terminalNode = infoNode;
spawnableEnemy.infoKeyword = infoKeyword;
FinalizeRegisterEnemy(spawnableEnemy);
}
}
public static void RegisterEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
EnemyType enemy2 = enemy;
EnemyNullCheck(enemy2);
SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType);
if (spawnableEnemy != null)
{
if (levelRarities != null)
{
foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities)
{
spawnableEnemy.levelRarities.Add(levelRarity.Key, levelRarity.Value);
}
}
if (customLevelRarities == null)
{
return;
}
{
foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities)
{
spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value);
}
return;
}
}
spawnableEnemy = new SpawnableEnemy(enemy2, spawnType, levelRarities, customLevelRarities);
spawnableEnemy.terminalNode = infoNode;
spawnableEnemy.infoKeyword = infoKeyword;
FinalizeRegisterEnemy(spawnableEnemy);
}
private static void FinalizeRegisterEnemy(SpawnableEnemy spawnableEnemy)
{
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
spawnableEnemy.modName = name;
if (spawnableEnemy.enemy.enemyPrefab == null)
{
throw new NullReferenceException("Cannot register enemy '" + spawnableEnemy.enemy.enemyName + "', because enemy.enemyPrefab is null!");
}
EnemyAICollisionDetect[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<EnemyAICollisionDetect>();
EnemyAICollisionDetect[] array = componentsInChildren;
foreach (EnemyAICollisionDetect val in array)
{
if (val.mainScript == null)
{
Plugin.logger.LogWarning((object)("An Enemy AI Collision Detect Script on GameObject '" + ((Object)((Component)val).gameObject).name + "' of enemy '" + spawnableEnemy.enemy.enemyName + "' does not reference a 'Main Script', and could cause Null Reference Exceptions."));
}
}
spawnableEnemies.Add(spawnableEnemy);
}
private static void EnemyNullCheck(EnemyType enemy)
{
if (enemy == null)
{
throw new ArgumentNullException("enemy", "The first argument of RegisterEnemy was null!");
}
}
public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
EnemyNullCheck(enemy);
SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword);
}
public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
EnemyNullCheck(enemy);
SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
RegisterEnemy(enemy, rarity, levelFlags, spawnType, spawnLevelOverrides, infoNode, infoKeyword);
}
public static void RegisterEnemy(EnemyType enemy, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null)
{
EnemyNullCheck(enemy);
SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default));
RegisterEnemy(enemy, spawnType, levelRarities, customLevelRarities, infoNode, infoKeyword);
}
public static void RemoveEnemyFromLevels(EnemyType enemyType, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
{
EnemyType enemyType2 = enemyType;
if (!((Object)(object)StartOfRound.Instance != (Object)null))
{
return;
}
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
string name = ((Object)val).name;
if (!Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
name = Levels.Compatibility.GetLLLNameOfLevel(name);
}
bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
flag = true;
}
if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
{
continue;
}
Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
if (flag || levelFlags.HasFlag(levelTypes))
{
List<SpawnableEnemyWithRarity> enemies = val.Enemies;
List<SpawnableEnemyWithRarity> daytimeEnemies = val.DaytimeEnemies;
List<SpawnableEnemyWithRarity> outsideEnemies = val.OutsideEnemies;
enemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
daytimeEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
outsideEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Removed Enemy " + ((Object)enemyType2).name + " from Level " + name));
}
}
}
}
}
public class Items
{
public struct ItemSaveOrderData
{
public int itemId;
public string itemName;
public string assetName;
}
public struct BuyableItemAssetInfo
{
public Item itemAsset;
public TerminalKeyword keyword;
}
public class ScrapItem
{
public Item item;
public Item origItem;
public int rarity;
public Levels.LevelTypes spawnLevels;
public string[] spawnLevelOverrides;
public string modName = "Unknown";
public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();
public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();
public ScrapItem(Item item, int rarity, Levels.LevelTypes spawnLevels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null)
{
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
origItem = item;
if (!item.isScrap)
{
item = item.Clone<Item>();
item.isScrap = true;
if (item.maxValue == 0 && item.minValue == 0)
{
item.minValue = 40;
item.maxValue = 100;
}
else if (item.maxValue == 0)
{
item.maxValue = item.minValue * 2;
}
else if (item.minValue == 0)
{
item.minValue = item.maxValue / 2;
}
GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
{
val.GetComponent<GrabbableObject>().itemProperties = item;
}
if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null)
{
GameObject val2 = Object.Instantiate<GameObject>(scanNodePrefab, val.transform);
((Object)val2).name = "ScanNode";
val2.transform.localPosition = new Vector3(0f, 0f, 0f);
ScanNodeProperties component = val2.GetComponent<ScanNodeProperties>();
component.headerText = item.itemName;
}
item.spawnPrefab = val;
}
ReplaceInvalidReferences(item);
this.item = item;
if (spawnLevelOverrides != null)
{
foreach (string levelName in spawnLevelOverrides)
{
customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
}
}
if (spawnLevels == Levels.LevelTypes.None)
{
return;
}
foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes)))
{
if (spawnLevels.HasFlag(value))
{
levelRarities.Add(value, rarity);
}
}
}
public ScrapItem(Item item, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
{
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
origItem = item;
if (!item.isScrap)
{
item = item.Clone<Item>();
item.isScrap = true;
if (item.maxValue == 0 && item.minValue == 0)
{
item.minValue = 40;
item.maxValue = 100;
}
else if (item.maxValue == 0)
{
item.maxValue = item.minValue * 2;
}
else if (item.minValue == 0)
{
item.minValue = item.maxValue / 2;
}
GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
{
val.GetComponent<GrabbableObject>().itemProperties = item;
}
if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null)
{
GameObject val2 = Object.Instantiate<GameObject>(scanNodePrefab, val.transform);
((Object)val2).name = "ScanNode";
val2.transform.localPosition = new Vector3(0f, 0f, 0f);
ScanNodeProperties component = val2.GetComponent<ScanNodeProperties>();
component.headerText = item.itemName;
}
item.spawnPrefab = val;
}
ReplaceInvalidReferences(item);
this.item = item;
if (customLevelRarities != null)
{
this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities);
}
if (levelRarities != null)
{
this.levelRarities = levelRarities;
}
}
}
public class PlainItem
{
public Item item;
public string modName;
public PlainItem(Item item)
{
this.item = item;
}
}
public class ShopItem
{
public Item item;
public Item origItem;
public TerminalNode buyNode1;
public TerminalNode buyNode2;
public TerminalNode itemInfo;
public bool wasRemoved;
public int price;
public string modName;
public ShopItem(Item item, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0)
{
origItem = item;
this.item = item;
this.price = price;
if ((Object)(object)buyNode1 != (Object)null)
{
this.buyNode1 = buyNode1;
}
if ((Object)(object)buyNode2 != (Object)null)
{
this.buyNode2 = buyNode2;
}
if ((Object)(object)itemInfo != (Object)null)
{
this.itemInfo = itemInfo;
}
}
}
[CompilerGenerated]
private static class <>O
{
public static hook_Start <0>__StartOfRound_Start;
public static hook_Awake <1>__Terminal_Awake;
public static hook_TextPostProcess <2>__Terminal_TextPostProcess;
public static hook_Start <3>__RegisterLevelScrapforLLL_RoundManager_Start;
public static hook_Start <4>__RegisterLevelScrapforLE_Terminal_Start;
}
public static ConfigEntry<bool> useSavedataFix;
public static GameObject scanNodePrefab;
private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>();
public static List<Item> LethalLibItemList = new List<Item>();
public static List<ItemGroup> vanillaItemGroups = new List<ItemGroup>();
public static List<BuyableItemAssetInfo> buyableItemAssetInfos = new List<BuyableItemAssetInfo>();
public static Terminal terminal;
public static List<ScrapItem> scrapItems = new List<ScrapItem>();
public static List<ShopItem> shopItems = new List<ShopItem>();
public static List<PlainItem> plainItems = new List<PlainItem>();
public static void Init()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_0063: 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_006e: Expected O, but got Unknown
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
useSavedataFix = Plugin.config.Bind<bool>("Items", "EnableItemSaveFix", false, "Allow for LethalLib to store/reorder the item list, which should fix issues where items get reshuffled when loading an old save. This is experimental and may cause save corruptions occasionally.");
scanNodePrefab = Plugin.MainAssets.LoadAsset<GameObject>("Assets/Custom/ItemScanNode.prefab");
object obj = <>O.<0>__StartOfRound_Start;
if (obj == null)
{
hook_Start val = StartOfRound_Start;
<>O.<0>__StartOfRound_Start = val;
obj = (object)val;
}
StartOfRound.Start += (hook_Start)obj;
object obj2 = <>O.<1>__Terminal_Awake;
if (obj2 == null)
{
hook_Awake val2 = Terminal_Awake;
<>O.<1>__Terminal_Awake = val2;
obj2 = (object)val2;
}
Terminal.Awake += (hook_Awake)obj2;
object obj3 = <>O.<2>__Terminal_TextPostProcess;
if (obj3 == null)
{
hook_TextPostProcess val3 = Terminal_TextPostProcess;
<>O.<2>__Terminal_TextPostProcess = val3;
obj3 = (object)val3;
}
Terminal.TextPostProcess += (hook_TextPostProcess)obj3;
}
private static string Terminal_TextPostProcess(orig_TextPostProcess orig, Terminal self, string modifiedDisplayText, TerminalNode node)
{
List<Item> list = self.buyableItemsList.ToList();
List<Item> list2 = self.buyableItemsList.ToList();
list2.RemoveAll((Item x) => shopItems.FirstOrDefault((ShopItem item) => (Object)(object)item.origItem == (Object)(object)x || (Object)(object)item.item == (Object)(object)x)?.wasRemoved ?? false);
self.buyableItemsList = list2.ToArray();
string result = orig.Invoke(self, modifiedDisplayText, node);
self.buyableItemsList = list.ToArray();
return result;
}
private static void StartOfRound_Start(orig_Start orig, StartOfRound self)
{
if (useSavedataFix.Value && ((NetworkBehaviour)self).IsHost)
{
Plugin.logger.LogInfo((object)"Fixing Item savedata!!");
List<ItemSaveOrderData> itemList = new List<ItemSaveOrderData>();
StartOfRound.Instance.allItemsList.itemsList.ForEach(delegate(Item item)
{
itemList.Add(new ItemSaveOrderData
{
itemId = item.itemId,
itemName = item.itemName,
assetName = ((Object)item).name
});
});
if (ES3.KeyExists("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName))
{
itemList = ES3.Load<List<ItemSaveOrderData>>("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName);
}
List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
List<Item> list = new List<Item>();
foreach (ItemSaveOrderData item2 in itemList)
{
Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => x.itemId == item2.itemId && x.itemName == item2.itemName && item2.assetName == ((Object)x).name));
if ((Object)(object)val != (Object)null)
{
list.Add(val);
}
else
{
list.Add(ScriptableObject.CreateInstance<Item>());
}
}
foreach (Item item3 in itemsList)
{
if (!list.Contains(item3))
{
list.Add(item3);
}
}
StartOfRound.Instance.allItemsList.itemsList = list;
ES3.Save<List<ItemSaveOrderData>>("LethalLibAllItemsList", itemList, GameNetworkManager.Instance.currentSaveFileName);
}
orig.Invoke(self);
}
private static void RegisterLevelScrapforLLL_RoundManager_Start(orig_Start orig, RoundManager self)
{
orig.Invoke(self);
RegisterLethalLibScrapItemsForAllLevels();
}
private static void RegisterLevelScrapforLE_Terminal_Start(orig_Start orig, Terminal self)
{
orig.Invoke(self);
RegisterLethalLibScrapItemsForAllLevels();
}
private static void RegisterLethalLibScrapItemsForAllLevels()
{
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
if (levelsAlreadyAddedTo.Contains(val))
{
continue;
}
foreach (ScrapItem scrapItem in scrapItems)
{
AddScrapItemToLevel(scrapItem, val);
}
levelsAlreadyAddedTo.Add(val);
}
}
private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel level)
{
//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Expected O, but got Unknown
ScrapItem scrapItem2 = scrapItem;
string text = ((Object)level).name;
string lLLNameOfLevel = Levels.Compatibility.GetLLLNameOfLevel(text);
Levels.LevelTypes result = Levels.LevelTypes.None;
bool flag = false;
if (Enum.TryParse<Levels.LevelTypes>(text, ignoreCase: true, out result))
{
flag = true;
}
else
{
text = lLLNameOfLevel;
}
string chosenTag = string.Empty;
bool flag2 = scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All) || (scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.Keys != null && Levels.Compatibility.ContentIncludedToLevelViaTag(scrapItem2.customLevelRarities.Keys.ToArray(), level, out chosenTag)) || (flag && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) || (!flag && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) || (flag && scrapItem2.levelRarities.ContainsKey(result)) || (!flag && scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(lLLNameOfLevel));
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} for item: {scrapItem2.item.itemName}, isCurrentLevelFromVanilla: {flag}, Found valid: {flag2}");
}
if (!flag2)
{
return;
}
int num = 0;
if (scrapItem2.levelRarities.ContainsKey(result))
{
num = scrapItem2.levelRarities[result];
}
else if (scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(text))
{
num = scrapItem2.customLevelRarities[text];
}
else if (scrapItem2.customLevelRarities != null && chosenTag != string.Empty && scrapItem2.customLevelRarities.ContainsKey(chosenTag))
{
num = scrapItem2.customLevelRarities[chosenTag];
}
else if (flag && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla))
{
num = scrapItem2.levelRarities[Levels.LevelTypes.Vanilla];
}
else if (!flag && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded))
{
num = scrapItem2.levelRarities[Levels.LevelTypes.Modded];
}
else if (scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All))
{
num = scrapItem2.levelRarities[Levels.LevelTypes.All];
}
SpawnableItemWithRarity item = new SpawnableItemWithRarity(scrapItem2.item, num);
if (!level.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem2.item))
{
level.spawnableScrap.Add(item);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} added {((Object)scrapItem2.item).name} with rarity: {num}");
}
}
}
private static void RegisterScrapAsItem(StartOfRound startOfRound)
{
foreach (ScrapItem scrapItem in scrapItems)
{
if (startOfRound.allItemsList.itemsList.Contains(scrapItem.item))
{
continue;
}
if (Plugin.extendedLogging.Value)
{
if (scrapItem.modName != "LethalLib")
{
Plugin.logger.LogInfo((object)(scrapItem.modName + " registered scrap item: " + scrapItem.item.itemName));
}
else
{
Plugin.logger.LogInfo((object)("Registered scrap item: " + scrapItem.item.itemName));
}
}
LethalLibItemList.Add(scrapItem.item);
startOfRound.allItemsList.itemsList.Add(scrapItem.item);
}
}
private static void Terminal_Awake(orig_Awake orig, Terminal self)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
//IL_006e: 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_0079: Expected O, but got Unknown
//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
//IL_05b1: Expected O, but got Unknown
//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
//IL_05e9: Expected O, but got Unknown
//IL_0650: Unknown result type (might be due to invalid IL or missing references)
//IL_065a: Expected O, but got Unknown
//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
//IL_06f5: Expected O, but got Unknown
StartOfRound instance = StartOfRound.Instance;
RegisterLethalLibScrapItemsForAllLevels();
if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader"))
{
object obj = <>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start;
if (obj == null)
{
hook_Start val = RegisterLevelScrapforLLL_RoundManager_Start;
<>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start = val;
obj = (object)val;
}
RoundManager.Start += (hook_Start)obj;
}
if (Chainloader.PluginInfos.ContainsKey("LethalExpansion"))
{
object obj2 = <>O.<4>__RegisterLevelScrapforLE_Terminal_Start;
if (obj2 == null)
{
hook_Start val2 = RegisterLevelScrapforLE_Terminal_Start;
<>O.<4>__RegisterLevelScrapforLE_Terminal_Start = val2;
obj2 = (object)val2;
}
Terminal.Start += (hook_Start)obj2;
}
RegisterScrapAsItem(instance);
foreach (ShopItem shopItem in shopItems)
{
if (instance.allItemsList.itemsList.Contains(shopItem.item))
{
continue;
}
if (Plugin.extendedLogging.Value)
{
if (shopItem.modName != "LethalLib")
{
Plugin.logger.LogInfo((object)(shopItem.modName + " registered shop item: " + shopItem.item.itemName));
}
else
{
Plugin.logger.LogInfo((object)("Registered shop item: " + shopItem.item.itemName));
}
}
LethalLibItemList.Add(shopItem.item);
instance.allItemsList.itemsList.Add(shopItem.item);
}
foreach (PlainItem plainItem in plainItems)
{
if (instance.allItemsList.itemsList.Contains(plainItem.item))
{
continue;
}
if (Plugin.extendedLogging.Value)
{
if (plainItem.modName != "LethalLib")
{
Plugin.logger.LogInfo((object)(plainItem.modName + " registered item: " + plainItem.item.itemName));
}
else
{
Plugin.logger.LogInfo((object)("Registered item: " + plainItem.item.itemName));
}
}
LethalLibItemList.Add(plainItem.item);
instance.allItemsList.itemsList.Add(plainItem.item);
}
terminal = self;
List<Item> list = self.buyableItemsList.ToList();
TerminalKeyword val3 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
TerminalNode result = val3.compatibleNouns[0].result.terminalOptions[1].result;
TerminalKeyword val4 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
Plugin.logger.LogInfo((object)$"Adding {shopItems.Count} items to terminal");
foreach (ShopItem item in shopItems)
{
if (list.Any((Item x) => x.itemName == item.item.itemName) && !item.wasRemoved)
{
Plugin.logger.LogInfo((object)("Item " + item.item.itemName + " already exists in terminal, skipping"));
continue;
}
item.wasRemoved = false;
if (item.price == -1)
{
item.price = item.item.creditsWorth;
}
else
{
item.item.creditsWorth = item.price;
}
int num = -1;
if (!list.Any((Item x) => (Object)(object)x == (Object)(object)item.item))
{
list.Add(item.item);
}
else
{
num = list.IndexOf(item.item);
}
int buyItemIndex = ((num == -1) ? (list.Count - 1) : num);
string itemName = item.item.itemName;
char c = itemName[itemName.Length - 1];
string text = itemName;
TerminalNode val5 = item.buyNode2;
if ((Object)(object)val5 == (Object)null)
{
val5 = ScriptableObject.CreateInstance<TerminalNode>();
((Object)val5).name = itemName.Replace(" ", "-") + "BuyNode2";
val5.displayText = "Ordered [variableAmount] " + text + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n";
val5.clearPreviousText = true;
val5.maxCharactersToType = 15;
}
val5.buyItemIndex = buyItemIndex;
val5.isConfirmationNode = false;
val5.itemCost = item.price;
val5.playSyncedClip = 0;
TerminalNode val6 = item.buyNode1;
if ((Object)(object)val6 == (Object)null)
{
val6 = ScriptableObject.CreateInstance<TerminalNode>();
((Object)val6).name = itemName.Replace(" ", "-") + "BuyNode1";
val6.displayText = "You have requested to order " + text + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n";
val6.clearPreviousText = true;
val6.maxCharactersToType = 35;
}
val6.buyItemIndex = buyItemIndex;
val6.isConfirmationNode = true;
val6.overrideOptions = true;
val6.itemCost = item.price;
val6.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2]
{
new CompatibleNoun(self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "confirm"), val5),
new CompatibleNoun(self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "deny"), result)
};
TerminalKeyword val7 = TerminalUtils.CreateTerminalKeyword(itemName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val3);
List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList();
list2.Add(val7);
self.terminalNodes.allKeywords = list2.ToArray();
List<CompatibleNoun> list3 = val3.compatibleNouns.ToList();
list3.Add(new CompatibleNoun(val7, val6));
val3.compatibleNouns = list3.ToArray();
TerminalNode val8 = item.itemInfo;
if ((Object)(object)val8 == (Object)null)
{
val8 = ScriptableObject.CreateInstance<TerminalNode>();
((Object)val8).name = itemName.Replace(" ", "-") + "InfoNode";
val8.displayText = "[No information about this object was found.]\n\n";
val8.clearPreviousText = true;
val8.maxCharactersToType = 25;
}
self.terminalNodes.allKeywords = list2.ToArray();
List<CompatibleNoun> list4 = val4.compatibleNouns.ToList();
list4.Add(new CompatibleNoun(val7, val8));
val4.compatibleNouns = list4.ToArray();
BuyableItemAssetInfo buyableItemAssetInfo = default(BuyableItemAssetInfo);
buyableItemAssetInfo.itemAsset = item.item;
buyableItemAssetInfo.keyword = val7;
BuyableItemAssetInfo item2 = buyableItemAssetInfo;
buyableItemAssetInfos.Add(item2);
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"Added {itemName} to terminal (Item price: {val6.itemCost}, Item Index: {val6.buyItemIndex}, Terminal keyword: {val7.word})");
}
}
self.buyableItemsList = list.ToArray();
orig.Invoke(self);
}
public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags)
{
Item spawnableItem2 = spawnableItem;
ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
if (scrapItem != null)
{
if (levelFlags != Levels.LevelTypes.None)
{
scrapItem.levelRarities.Add(levelFlags, rarity);
}
return;
}
scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags);
ValidateItemProperties(scrapItem.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
scrapItem.modName = name;
scrapItems.Add(scrapItem);
}
public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
{
Item spawnableItem2 = spawnableItem;
ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
if (scrapItem != null)
{
if (levelFlags != Levels.LevelTypes.None)
{
scrapItem.levelRarities.Add(levelFlags, rarity);
}
if (levelOverrides != null)
{
foreach (string levelName in levelOverrides)
{
scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
}
}
}
else
{
scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags, levelOverrides);
ValidateItemProperties(scrapItem.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
scrapItem.modName = name;
scrapItems.Add(scrapItem);
}
}
public static void RegisterScrap(Item spawnableItem, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
{
Item spawnableItem2 = spawnableItem;
ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2);
if (scrapItem != null)
{
if (levelRarities != null)
{
foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities)
{
scrapItem.levelRarities.Add(levelRarity.Key, levelRarity.Value);
}
}
if (customLevelRarities == null)
{
return;
}
{
foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities)
{
scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value);
}
return;
}
}
scrapItem = new ScrapItem(spawnableItem2, levelRarities, customLevelRarities);
ValidateItemProperties(scrapItem.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
scrapItem.modName = name;
scrapItems.Add(scrapItem);
}
public static void RegisterShopItem(Item shopItem, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1)
{
ShopItem shopItem2 = new ShopItem(shopItem, buyNode1, buyNode2, itemInfo, price);
ValidateItemProperties(shopItem2.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
shopItem2.modName = name;
shopItems.Add(shopItem2);
}
public static void RegisterShopItem(Item shopItem, int price = -1)
{
ShopItem shopItem2 = new ShopItem(shopItem, null, null, null, price);
ValidateItemProperties(shopItem2.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
shopItem2.modName = name;
shopItems.Add(shopItem2);
}
public static void RegisterItem(Item plainItem)
{
PlainItem plainItem2 = new PlainItem(plainItem);
ValidateItemProperties(plainItem2.item);
Assembly callingAssembly = Assembly.GetCallingAssembly();
string name = callingAssembly.GetName().Name;
plainItem2.modName = name;
plainItems.Add(plainItem2);
}
private static void ValidateItemProperties(Item item)
{
if (!((Object)(object)item == (Object)null) && (item.weight < 1f || (double)item.weight > 3.75))
{
Plugin.logger.LogWarning((object)$"Item {item.itemName} has an invalid weight of {item.weight}, resetting to weight of 1, please check the lethal.wiki for the weight calculation and give it a valid number, anything below 1 or above 4 gets forced to be 1 or 4.");
item.weight = Mathf.Clamp(item.weight, 1f, 3.75f);
}
}
private static void ReplaceInvalidReferences(Item item)
{
List<ItemGroup> list = new List<ItemGroup>();
foreach (ItemGroup itemGroup in item.spawnPositionTypes)
{
if (!((Object)(object)itemGroup == (Object)null))
{
ItemGroup val = vanillaItemGroups.Where((ItemGroup x) => (Object)(object)x != (Object)null && ((Object)x).name == ((Object)itemGroup).name).FirstOrDefault();
if (!((Object)(object)val == (Object)null))
{
list.Add(val);
}
}
}
item.spawnPositionTypes = list;
}
public static void RemoveScrapFromLevels(Item scrapItem, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
{
Item scrapItem2 = scrapItem;
if ((Object)(object)StartOfRound.Instance == (Object)null)
{
return;
}
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
string name = ((Object)val).name;
if (!Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
name = Levels.Compatibility.GetLLLNameOfLevel(name);
}
bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
flag = true;
}
if (!Enum.IsDefined(typeof(Levels.LevelTypes), name) && !flag)
{
continue;
}
Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
if (!flag && !levelFlags.HasFlag(levelTypes))
{
continue;
}
ScrapItem actualItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)scrapItem2 || (Object)(object)x.item == (Object)(object)scrapItem2);
SpawnableItemWithRarity val2 = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)actualItem.item));
if (val2 != null)
{
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Removed Item " + ((Object)val2.spawnableItem).name + " from Level " + name));
}
val.spawnableScrap.Remove(val2);
}
}
}
public static void RemoveShopItem(Item shopItem)
{
Item shopItem2 = shopItem;
if (!((Object)(object)StartOfRound.Instance != (Object)null))
{
return;
}
ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2);
actualItem.wasRemoved = true;
List<TerminalKeyword> list = terminal.terminalNodes.allKeywords.ToList();
TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info");
TerminalKeyword val2 = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
List<CompatibleNoun> list2 = val2.compatibleNouns.ToList();
List<CompatibleNoun> list3 = val.compatibleNouns.ToList();
if (buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item))
{
BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item);
list.Remove(asset.keyword);
list2.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
list3.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
}
terminal.terminalNodes.allKeywords = list.ToArray();
val2.compatibleNouns = list2.ToArray();
val.compatibleNouns = list3.ToArray();
}
public static void UpdateShopItemPrice(Item shopItem, int price)
{
Item shopItem2 = shopItem;
if (!((Object)(object)StartOfRound.Instance != (Object)null))
{
return;
}
ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2);
actualItem.item.creditsWorth = price;
TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy");
TerminalNode result = val.compatibleNouns[0].result.terminalOptions[1].result;
List<CompatibleNoun> source = val.compatibleNouns.ToList();
if (!buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item))
{
return;
}
BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item);
if (!source.Any((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword))
{
return;
}
CompatibleNoun val2 = source.First((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword);
TerminalNode result2 = val2.result;
result2.itemCost = price;
if (result2.terminalOptions.Length == 0)
{
return;
}
CompatibleNoun[] terminalOptions = result2.terminalOptions;
foreach (CompatibleNoun val3 in terminalOptions)
{
if ((Object)(object)val3.result != (Object)null && val3.result.buyItemIndex != -1)
{
val3.result.itemCost = price;
}
}
}
}
public class Levels
{
[Flags]
public enum LevelTypes
{
None = 1,
ExperimentationLevel = 4,
AssuranceLevel = 8,
VowLevel = 0x10,
OffenseLevel = 0x20,
MarchLevel = 0x40,
RendLevel = 0x80,
DineLevel = 0x100,
TitanLevel = 0x200,
AdamanceLevel = 0x800,
ArtificeLevel = 0x1000,
EmbrionLevel = 0x2000,
Vanilla = 0x3BFC,
Modded = 0x400,
All = -1
}
internal static class Compatibility
{
private const string illegalCharacters = ".,?!@#$%^&*()_+-=';:'\"";
private static string GetNumberlessPlanetName(string planetName)
{
if (planetName != null)
{
return new string(planetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
}
return string.Empty;
}
private static string StripSpecialCharacters(string input)
{
string text = string.Empty;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ")
{
text += c;
}
}
return text;
}
internal static string GetLLLNameOfLevel(string levelName)
{
string text = StripSpecialCharacters(GetNumberlessPlanetName(levelName));
if (!text.EndsWith("Level", ignoreCase: true, CultureInfo.InvariantCulture))
{
text += "Level";
}
return text.ToLowerInvariant();
}
internal static Dictionary<string, int> LLLifyLevelRarityDictionary(Dictionary<string, int> keyValuePairs)
{
Dictionary<string, int> dictionary = new Dictionary<string, int>();
List<string> list = keyValuePairs.Keys.ToList();
List<int> list2 = keyValuePairs.Values.ToList();
for (int i = 0; i < keyValuePairs.Count; i++)
{
dictionary.Add(GetLLLNameOfLevel(list[i]), list2[i]);
}
return dictionary;
}
internal static bool ContentIncludedToLevelViaTag(string[] potentialTags, SelectableLevel level, out string chosenTag)
{
chosenTag = string.Empty;
List<string> list = LethalLevelLoaderCompat.TryGetLLLTagsFromLevels(level);
foreach (string item in list)
{
foreach (string text in potentialTags)
{
string text2 = text.Remove(text.Length - 5);
if (item == text2)
{
chosenTag = item;
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Level " + ((Object)level).name + " has valid tag " + text2));
}
return true;
}
}
}
return false;
}
}
}
public class MapObjects
{
public class RegisteredMapObject
{
[Obsolete("Use IndoorMapHazardType instead")]
public SpawnableMapObject mapObject;
public IndoorMapHazardType indoorMapHazardType;
public SpawnableOutsideObjectWithRarity outsideObject;
public Levels.LevelTypes levels;
public string[] spawnLevelOverrides;
public Func<SelectableLevel, AnimationCurve> spawnRateFunction;
}
[CompilerGenerated]
private static class <>O
{
public static hook_Awake <0>__StartOfRound_Awake;
public static hook_SpawnMapObjects <1>__RoundManager_SpawnMapObjects;
}
public static List<RegisteredMapObject> mapObjects = new List<RegisteredMapObject>();
internal static void Init()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
object obj = <>O.<0>__StartOfRound_Awake;
if (obj == null)
{
hook_Awake val = StartOfRound_Awake;
<>O.<0>__StartOfRound_Awake = val;
obj = (object)val;
}
StartOfRound.Awake += (hook_Awake)obj;
object obj2 = <>O.<1>__RoundManager_SpawnMapObjects;
if (obj2 == null)
{
hook_SpawnMapObjects val2 = RoundManager_SpawnMapObjects;
<>O.<1>__RoundManager_SpawnMapObjects = val2;
obj2 = (object)val2;
}
RoundManager.SpawnMapObjects += (hook_SpawnMapObjects)obj2;
}
private static void RoundManager_SpawnMapObjects(orig_SpawnMapObjects orig, RoundManager self)
{
RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>();
RandomMapObject[] array2 = array;
foreach (RandomMapObject val in array2)
{
foreach (RegisteredMapObject mapObject in mapObjects)
{
if ((Object)(object)mapObject.indoorMapHazardType != (Object)null && !val.spawnablePrefabs.Any((GameObject prefab) => (Object)(object)prefab == (Object)(object)mapObject.indoorMapHazardType.prefabToSpawn))
{
val.spawnablePrefabs.Add(mapObject.indoorMapHazardType.prefabToSpawn);
}
}
}
orig.Invoke(self);
}
private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
{
orig.Invoke(self);
foreach (RegisteredMapObject mapObject in mapObjects)
{
SelectableLevel[] levels = self.levels;
foreach (SelectableLevel level in levels)
{
AddMapObjectToLevel(mapObject, level);
}
}
}
private static void AddMapObjectToLevel(RegisteredMapObject mapObject, SelectableLevel level)
{
//IL_0214: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Expected O, but got Unknown
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0349: Unknown result type (might be due to invalid IL or missing references)
//IL_0361: Expected O, but got Unknown
RegisteredMapObject mapObject2 = mapObject;
string text = ((Object)level).name;
string lLLNameOfLevel = Levels.Compatibility.GetLLLNameOfLevel(text);
Levels.LevelTypes result = Levels.LevelTypes.None;
bool flag = false;
if (Enum.TryParse<Levels.LevelTypes>(text, ignoreCase: true, out result))
{
flag = true;
}
else
{
text = lLLNameOfLevel;
}
string chosenTag = string.Empty;
bool flag2 = mapObject2.levels.HasFlag(Levels.LevelTypes.All) || (mapObject2.spawnLevelOverrides != null && Levels.Compatibility.ContentIncludedToLevelViaTag(mapObject2.spawnLevelOverrides, level, out chosenTag)) || (flag && mapObject2.levels.HasFlag(Levels.LevelTypes.Vanilla)) || (!flag && mapObject2.levels.HasFlag(Levels.LevelTypes.Modded)) || (flag && mapObject2.levels.HasFlag(result)) || (!flag && mapObject2.spawnLevelOverrides != null && mapObject2.spawnLevelOverrides.Contains(lLLNameOfLevel));
string text2 = "invalid!";
if ((Object)(object)mapObject2.indoorMapHazardType != (Object)null)
{
text2 = ((Object)mapObject2.indoorMapHazardType.prefabToSpawn).name;
}
else if (mapObject2.outsideObject != null)
{
text2 = ((Object)mapObject2.outsideObject.spawnableObject.prefabToSpawn).name;
}
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)$"{text} for mapObject: {text2}, isCurrentLevelFromVanilla: {flag}, Found valid: {flag2}");
}
if (!flag2)
{
return;
}
if ((Object)(object)mapObject2.indoorMapHazardType != (Object)null)
{
if (level.indoorMapHazards.Any((IndoorMapHazard x) => (Object)(object)x.hazardType.prefabToSpawn == (Object)(object)mapObject2.indoorMapHazardType.prefabToSpawn))
{
List<IndoorMapHazard> list = level.indoorMapHazards.ToList();
list.RemoveAll((IndoorMapHazard x) => (Object)(object)x.hazardType.prefabToSpawn == (Object)(object)mapObject2.indoorMapHazardType.prefabToSpawn);
level.indoorMapHazards = list.ToArray();
}
IndoorMapHazard val = new IndoorMapHazard
{
hazardType = mapObject2.indoorMapHazardType,
numberToSpawn = AnimationCurve.Constant(0f, 1f, 0f)
};
if (mapObject2.spawnRateFunction != null)
{
val.numberToSpawn = mapObject2.spawnRateFunction(level);
}
List<IndoorMapHazard> list2 = level.indoorMapHazards.ToList();
list2.Add(val);
level.indoorMapHazards = list2.ToArray();
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Added " + ((Object)val.hazardType.prefabToSpawn).name + " to " + text));
}
}
else
{
if (mapObject2.outsideObject == null)
{
return;
}
if (level.spawnableOutsideObjects.Any((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject2.outsideObject.spawnableObject.prefabToSpawn))
{
List<SpawnableOutsideObjectWithRarity> list3 = level.spawnableOutsideObjects.ToList();
list3.RemoveAll((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject2.outsideObject.spawnableObject.prefabToSpawn);
level.spawnableOutsideObjects = list3.ToArray();
}
SpawnableOutsideObjectWithRarity val2 = new SpawnableOutsideObjectWithRarity(mapObject2.outsideObject.spawnableObject, AnimationCurve.Constant(0f, 1f, 0f))
{
spawnableObject = mapObject2.outsideObject.spawnableObject
};
if (mapObject2.spawnRateFunction != null)
{
val2.randomAmount = mapObject2.spawnRateFunction(level);
}
List<SpawnableOutsideObjectWithRarity> list4 = level.spawnableOutsideObjects.ToList();
list4.Add(val2);
level.spawnableOutsideObjects = list4.ToArray();
if (Plugin.extendedLogging.Value)
{
Plugin.logger.LogInfo((object)("Added " + ((Object)val2.spawnableObject.prefabToSpawn).name + " to " + text));
}
}
}
public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
RegisterMapObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
}
public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
RegisterMapObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
}
public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
mapObjects.Add(new RegisteredMapObject
{
mapObject = mapObject,
indoorMapHazardType = TurnMapObjectIntoIndoorMapHazard(mapObject),
levels = levels,
spawnRateFunction = spawnRateFunction
});
}
public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
mapObjects.Add(new RegisteredMapObject
{
mapObject = mapObject,
indoorMapHazardType = TurnMapObjectIntoIndoorMapHazard(mapObject),
levels = levels,
spawnRateFunction = spawnRateFunction,
spawnLevelOverrides = levelOverrides
});
}
public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
RegisterOutsideObject(mapObject.spawnableMapObject, levels, spawnRateFunction);
}
public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
RegisterOutsideObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction);
}
public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
mapObjects.Add(new RegisteredMapObject
{
outsideObject = mapObject,
levels = levels,
spawnRateFunction = spawnRateFunction
});
}
public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null)
{
mapObjects.Add(new RegisteredMapObject
{
outsideObject = mapObject,
levels = levels,
spawnRateFunction = spawnRateFunction,
spawnLevelOverrides = levelOverrides
});
}
public static void RemoveMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
{
RemoveMapObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
}
public static void RemoveMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
{
SpawnableMapObject mapObject2 = mapObject;
if (!((Object)(object)StartOfRound.Instance != (Object)null))
{
return;
}
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
string name = ((Object)val).name;
bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
flag = true;
}
if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
{
continue;
}
Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
if (flag || levelFlags.HasFlag(levelTypes))
{
val.indoorMapHazards = val.indoorMapHazards.Where((IndoorMapHazard x) => (Object)(object)x.hazardType.prefabToSpawn != (Object)(object)mapObject2.prefabToSpawn).ToArray();
}
}
}
public static void RemoveOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
{
RemoveOutsideObject(mapObject.spawnableMapObject, levelFlags, levelOverrides);
}
internal static IndoorMapHazardType TurnMapObjectIntoIndoorMapHazard(SpawnableMapObject mapObject)
{
IndoorMapHazardType val = ScriptableObject.CreateInstance<IndoorMapHazardType>();
val.prefabToSpawn = mapObject.prefabToSpawn;
val.requireDistanceBetweenSpawns = mapObject.requireDistanceBetweenSpawns;
val.disallowSpawningNearEntrances = mapObject.disallowSpawningNearEntrances;
val.spawnFacingAwayFromWall = mapObject.spawnFacingAwayFromWall;
val.spawnWithBackToWall = mapObject.spawnWithBackToWall;
val.spawnWithBackFlushAgainstWall = mapObject.spawnWithBackFlushAgainstWall;
val.spawnFacingWall = mapObject.spawnFacingWall;
return val;
}
public static void RemoveOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null)
{
SpawnableOutsideObjectWithRarity mapObject2 = mapObject;
if (!((Object)(object)StartOfRound.Instance != (Object)null))
{
return;
}
SelectableLevel[] levels = StartOfRound.Instance.levels;
foreach (SelectableLevel val in levels)
{
string name = ((Object)val).name;
bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
{
flag = true;
}
if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
{
continue;
}
Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
if (flag || levelFlags.HasFlag(levelTypes))
{
val.spawnableOutsideObjects = val.spawnableOutsideObjects.Where((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn != (Object)(object)mapObject2.spawnableObject.prefabToSpawn).ToArray();
}
}
}
}
public class NetworkPrefabs
{
[CompilerGenerated]
private static class <>O
{
public static hook_Start <0>__GameNetworkManager_Start;
}
private static List<GameObject> _networkPrefabs = new List<GameObject>();
internal static void Init()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
object obj = <>O.<0>__GameNetworkManager_Start;
if (obj == null)
{
hook_Start val = GameNetworkManager_Start;
<>O.<0>__GameNetworkManager_Start = val;
obj = (object)val;
}
GameNetworkManager.Start += (hook_Start)obj;
}
public static void RegisterNetworkPrefab(GameObject prefab)
{
if (prefab == null)
{
throw new ArgumentNullException("prefab", "The given argument for RegisterNetworkPrefab is null!");
}
if (!_networkPrefabs.Contains(prefab))
{
_networkPrefabs.Add(prefab);
}
}
public static GameObject CreateNetworkPrefab(string name)
{
GameObject val = PrefabUtils.CreatePrefab(name);
val.AddComponent<NetworkObject>();
byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + name));
val.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
RegisterNetworkPrefab(val);
return val;
}
public static GameObject CloneNetworkPrefab(GameObject prefabToClone, string newName = null)
{
GameObject val = PrefabUtils.ClonePrefab(prefabToClone, newName);
byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + ((Object)val).name));
val.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0);
RegisterNetworkPrefab(val);
return val;
}
private static void GameNetworkManager_Start(orig_Start orig, GameNetworkManager self)
{
orig.Invoke(self);
foreach (GameObject networkPrefab in _networkPrefabs)
{
if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab))
{
NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
}
}
}
}
public class Player
{
[CompilerGenerated]
private static class <>O
{
public static hook_Awake <0>__StartOfRound_Awake;
}
public static Dictionary<string, GameObject> ragdollRefs = new Dictionary<string, GameObject>();
public static Dictionary<string, int> ragdollIndexes = new Dictionary<string, int>();
public static void Init()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
object obj = <>O.<0>__StartOfRound_Awake;
if (obj == null)
{
hook_Awake val = StartOfRound_Awake;
<>O.<0>__StartOfRound_Awake = val;
obj = (object)val;
}
StartOfRound.Awake += (hook_Awake)obj;
}
private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self)
{
orig.Invoke(self);
foreach (KeyValuePair<string, GameObject> ragdollRef in ragdollRefs)
{
if (!self.playerRagdolls.Contains(ragdollRef.Value))
{
self.playerRagdolls.Add(ragdollRef.Value);
int value = self.playerRagdolls.Count - 1;
if (ragdollIndexes.ContainsKey(ragdollRef.Key))
{
ragdollIndexes[ragdollRef.Key] = value;
}
else
{
ragdollIndexes.Add(ragdollRef.Key, value);
}
}
}
}
public static int GetRagdollIndex(string id)
{
return ragdollIndexes[id];
}
public static GameObject GetRagdoll(string id)
{
return ragdollRefs[id];
}
public static void RegisterPlayerRagdoll(string id, GameObject ragdoll)
{
Plugin.logger.LogInfo((object)("Registering player ragdoll " + id));
ragdollRefs.Add(id, ragdoll);
}
}
public class PrefabUtils
{
internal static Lazy<GameObject> _prefab