using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using EquinoxsDebuggingTools;
using EquinoxsModUtils.Additions;
using EquinoxsModUtils.Additions.ContentAdders;
using EquinoxsModUtils.Additions.Patches;
using FluffyUnderware.DevTools.Extensions;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EMUAdditions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EMUAdditions")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("163385b3-d393-47fc-8f18-a6b38a505f13")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EquinoxsModUtils
{
public static class EMUAdditions
{
public static class CustomData
{
private static Dictionary<string, object> customMachineData = new Dictionary<string, object>();
private static bool hasCustomMachineDataLoaded = false;
private static string dataFolder => EMUAdditionsPlugin.dataFolder;
public static void Add<T>(uint instanceId, string name, T value)
{
if (!hasCustomMachineDataLoaded)
{
EMUAdditionsPlugin.Log.LogError((object)"GetAll() called before custom data has loaded.");
EMUAdditionsPlugin.Log.LogInfo((object)"Try using the SaveStateLoaded event or hasSaveStateLoaded variable");
return;
}
EMUAdditionsPlugin.Log.LogWarning((object)$"EMUAdditions.CustomData.Add() is deprecated, switch to Update() - Calling mod: {Assembly.GetCallingAssembly()}");
if (!new List<string>
{
typeof(uint).ToString(),
typeof(int).ToString(),
typeof(float).ToString(),
typeof(double).ToString(),
typeof(bool).ToString(),
typeof(string).ToString(),
typeof(char).ToString()
}.Contains(typeof(T).ToString()))
{
EMUAdditionsPlugin.Log.LogError((object)$"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
}
string key = $"{instanceId}-{name}-{typeof(T)}";
if (!customMachineData.ContainsKey(key))
{
customMachineData.Add(key, value);
}
}
public static void Update<T>(uint instanceId, string name, T value)
{
if (!hasCustomMachineDataLoaded)
{
EMUAdditionsPlugin.Log.LogError((object)"GetAll() called before custom data has loaded.");
EMUAdditionsPlugin.Log.LogInfo((object)"Try using the SaveStateLoaded event or hasSaveStateLoaded variable");
return;
}
if (!new List<string>
{
typeof(uint).ToString(),
typeof(int).ToString(),
typeof(float).ToString(),
typeof(double).ToString(),
typeof(bool).ToString(),
typeof(string).ToString(),
typeof(char).ToString()
}.Contains(typeof(T).ToString()))
{
EMUAdditionsPlugin.Log.LogError((object)$"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
}
string key = $"{instanceId}-{name}-{typeof(T)}";
customMachineData[key] = value;
}
public static T Get<T>(uint instanceId, string name)
{
if (!hasCustomMachineDataLoaded)
{
EMUAdditionsPlugin.Log.LogError((object)"Get() called before custom data has loaded.");
EMUAdditionsPlugin.Log.LogInfo((object)"Try using the SaveStateLoaded event or hasSaveStateLoaded variable");
return default(T);
}
if (!new List<string>
{
typeof(uint).ToString(),
typeof(int).ToString(),
typeof(float).ToString(),
typeof(double).ToString(),
typeof(bool).ToString(),
typeof(string).ToString(),
typeof(char).ToString()
}.Contains(typeof(T).ToString()))
{
EMUAdditionsPlugin.Log.LogError((object)$"EMU cannot save custom data of type '{typeof(T)}', please use one of: uint, int, float, double, bool, string, char");
}
string text = $"{instanceId}-{name}-{typeof(T)}";
if (customMachineData.ContainsKey(text))
{
return (T)customMachineData[text];
}
EMUAdditionsPlugin.Log.LogError((object)("Could not find custom data with key '" + text + "'"));
return default(T);
}
public static Dictionary<string, object> GetAll(uint instanceId)
{
if (!hasCustomMachineDataLoaded)
{
EMUAdditionsPlugin.Log.LogError((object)"GetAll() called before custom data has loaded.");
EMUAdditionsPlugin.Log.LogInfo((object)"Try using the SaveStateLoaded event or hasSaveStateLoaded variable");
return null;
}
Dictionary<string, object> dictionary = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> customMachineDatum in customMachineData)
{
if (customMachineDatum.Key.StartsWith(instanceId.ToString()))
{
dictionary.Add(customMachineDatum.Key.Split(new char[1] { '-' })[1], customMachineDatum.Value);
}
}
return dictionary;
}
public static bool AnyExists(uint instanceId)
{
foreach (string key in customMachineData.Keys)
{
if (key.Split(new char[1] { '-' })[0] == instanceId.ToString())
{
return true;
}
}
return false;
}
public static bool FieldExists<T>(uint instanceId, string name)
{
string key = $"{instanceId}-{name}-{typeof(T)}";
return customMachineData.ContainsKey(key);
}
internal static void Save(string worldName)
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, object> customMachineDatum in customMachineData)
{
list.Add($"{customMachineDatum.Key}|{customMachineDatum.Value}");
}
Directory.CreateDirectory(dataFolder);
File.WriteAllLines(dataFolder + "/" + worldName + " CustomData.txt", list);
}
internal static void Load(string worldName)
{
string path = dataFolder + "/" + worldName + " CustomData.txt";
if (!File.Exists(path))
{
EMUAdditionsPlugin.LogWarning("No CustomData save file found for world '" + worldName + "'");
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { '|' });
string text = array2[1];
object obj = null;
string text2 = array2[0];
string text3 = text2.Split(new char[1] { '-' })[2];
switch (text3)
{
case "System.UInt32":
obj = uint.Parse(text);
break;
case "System.Int32":
obj = int.Parse(text);
break;
case "System.Single":
obj = float.Parse(text);
break;
case "System.Double":
obj = double.Parse(text);
break;
case "System.Boolean":
obj = bool.Parse(text);
break;
case "System.String":
obj = text;
break;
case "System.Char":
obj = char.Parse(text);
break;
default:
EMUAdditionsPlugin.LogError("Cannot load custom data (key: '" + text2 + "') with unhandled type: '" + text3 + "'");
continue;
}
customMachineData[text2] = obj;
}
hasCustomMachineDataLoaded = true;
EMUAdditionsPlugin.LogInfo("Loaded custom machine data");
}
}
public static void AddNewUnlock(NewUnlockDetails details, bool shouldLog = false)
{
if (!details.Validate())
{
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Unlock '" + details.displayName + "'");
return;
}
Unlock item = details.ConvertToUnlock();
UnlockAdder.unlocksToAdd.Add(item);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new Unlock '" + details.displayName + "' for adding to game");
}
}
public static void AddNewResource(NewResourceDetails details, bool shouldLog = false)
{
if (!details.Validate())
{
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Resource '" + details.name + "'");
return;
}
ResourceAdder.resourcesToAdd.Add(details);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new Resource '" + details.name + "' for adding to game");
}
}
public static void AddNewRecipe(NewRecipeDetails details, bool shouldLog = false)
{
if (!details.Validate())
{
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Recipe");
return;
}
RecipeAdder.recipesToAdd.Add(details);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new Recipe '" + details.GetUniqueName() + "' for adding to game");
}
}
public static void AddNewSchematicsSubHeader(string title, string parentTitle, int priority, bool shouldLog = false)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
if (string.IsNullOrEmpty(title))
{
EMUAdditionsPlugin.LogError("New SchematicsSubHeader title cannot be null or empty");
return;
}
if (string.IsNullOrEmpty(parentTitle))
{
EMUAdditionsPlugin.LogError("New SchematicsSubHeader '" + title + "' parentTitle cannot be null or empty");
return;
}
SchematicsSubHeader val = (SchematicsSubHeader)ScriptableObject.CreateInstance(typeof(SchematicsSubHeader));
val.title = title ?? "";
val.priority = priority;
SubHeaderAdder.subHeadersToAdd.Add(val);
SubHeaderAdder.parents.Add(parentTitle);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new SchematicsSubHeader '" + parentTitle + "/" + title + "' to be added to game");
}
}
public static void AddNewMachine<T, V>(MachineDefinition<T, V> definition, NewResourceDetails details, bool shouldLog = false) where T : struct, IMachineInstance<T, V> where V : MachineDefinition<T, V>
{
if (!details.Validate())
{
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Machine '" + details.name + "'");
return;
}
((ResourceInfo)definition).rawName = details.name;
MachineAdder.machinesToAdd.Add((ResourceInfo)(object)definition);
MachineAdder.details.Add(details);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new Machine '" + ((ResourceInfo)definition).displayName + "' for adding to game");
}
}
public static void AddNewEquipment<T>(Equipment equipment, NewResourceDetails details, bool shouldLog = false) where T : ScriptableObject
{
if (!details.Validate())
{
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Equipment '" + details.name + "'");
return;
}
T val = ScriptableObject.CreateInstance<T>();
EMU.SetPrivateField<Equipment>("_info", equipment, (object)val);
((ResourceInfo)equipment.info).rawName = details.name;
EquipmentAdder.equipmentToAdd.Add(equipment);
EquipmentAdder.details.Add(details);
if (shouldLog)
{
EMUAdditionsPlugin.LogInfo("Successfully registered new Equipment '" + details.name + "' for adding to game");
}
}
}
internal static class Testing
{
internal static bool doUnlockTest;
internal static bool doResourcePlusTest;
internal static bool doMachineTest;
internal static void DoTests()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
if (doUnlockTest)
{
EMUAdditions.AddNewUnlock(new NewUnlockDetails
{
displayName = "My New Unlock",
description = "Description of my new Unlock",
category = (TechCategory)0,
requiredTier = (ResearchTier)4,
coreTypeNeeded = (CoreType)0,
coreCountNeeded = 20,
treePosition = 10
});
}
if (doResourcePlusTest)
{
EMUAdditions.AddNewResource(new NewResourceDetails
{
parentName = "Limestone",
name = "Limestone 3",
description = "Limestone 3 Test",
headerTitle = "Intermediates",
subHeaderTitle = "Test Parts 2",
craftingMethod = (CraftingMethod)0,
craftTierRequired = 0,
fuelAmount = 100f,
sortPriority = 10,
unlockName = "Core Composer"
});
EMUAdditions.AddNewRecipe(new NewRecipeDetails
{
GUID = "com.equinox.EMUAdditions",
craftingMethod = (CraftingMethod)0,
craftTierRequired = 0,
duration = 0.1f,
ingredients = new List<RecipeResourceInfo>
{
new RecipeResourceInfo
{
name = "Limestone",
quantity = 2
}
},
outputs = new List<RecipeResourceInfo>
{
new RecipeResourceInfo
{
name = "Limestone 3",
quantity = 2
}
},
sortPriority = 10,
unlockName = "Core Composer"
});
EMUAdditions.AddNewSchematicsSubHeader("Test Parts 2", "Intermediates", 10);
}
if (doMachineTest)
{
NewResourceDetails details = new NewResourceDetails
{
name = "Void Chest",
description = "Voids all items inserted into it.",
craftingMethod = (CraftingMethod)0,
craftTierRequired = 0,
headerTitle = "Logistics",
subHeaderTitle = "Utility",
maxStackCount = 500,
sortPriority = 999,
unlockName = "Basic Logistics",
parentName = "Container"
};
EMUAdditions.AddNewMachine<ChestInstance, ChestDefinition>((MachineDefinition<ChestInstance, ChestDefinition>)(object)ScriptableObject.CreateInstance<ChestDefinition>(), details, shouldLog: true);
EMUAdditions.AddNewRecipe(new NewRecipeDetails
{
GUID = "com.equinox.EMUAdditions",
craftingMethod = (CraftingMethod)0,
craftTierRequired = 0,
duration = 0.1f,
ingredients = new List<RecipeResourceInfo>
{
new RecipeResourceInfo
{
name = "Iron Ingot",
quantity = 10
}
},
outputs = new List<RecipeResourceInfo>
{
new RecipeResourceInfo
{
name = "Void Chest",
quantity = 1
}
},
sortPriority = 10,
unlockName = "Basic Logistics"
});
}
}
}
[BepInPlugin("com.equinox.EMUAdditions", "EMUAdditions", "2.0.1")]
public class EMUAdditionsPlugin : BaseUnityPlugin
{
internal const string MyGUID = "com.equinox.EMUAdditions";
private const string PluginName = "EMUAdditions";
private const string VersionString = "2.0.1";
private static readonly Harmony Harmony = new Harmony("com.equinox.EMUAdditions");
internal static ManualLogSource Log = new ManualLogSource("EMUAdditions");
internal static Dictionary<string, string> customTranslations = new Dictionary<string, string>();
internal static string dataFolder = Application.persistentDataPath + "/EMUAdditions";
internal static Dictionary<string, int> idHistory = new Dictionary<string, int>();
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: EMUAdditions, VersionString: 2.0.1 is loading...");
Harmony.PatchAll();
LoadIdHistory();
UnlockAdder.LoadIdHistory();
RecipeAdder.LoadIdHistory();
SubHeaderAdder.LoadIdHistory();
ApplyPatches();
Events.GameDefinesLoaded += OnGameDefinesLoaded;
Events.SaveStateLoaded += OnSaveStateLoaded;
Events.TechTreeStateLoaded += OnTechTreeStateLoaded;
Events.GameSaved += OnGameSaved;
Testing.DoTests();
((BaseUnityPlugin)this).Logger.LogInfo((object)"PluginName: EMUAdditions, VersionString: 2.0.1 is loaded.");
}
private void OnGameDefinesLoaded()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
UnlockAdder.AddRegisteredUnlocks();
if (Testing.doUnlockTest)
{
Unlock unlockByName = Unlocks.GetUnlockByName("My New Unlock", false);
Unlock unlockByName2 = Unlocks.GetUnlockByName("Excavator Bit MKI", false);
Unlock unlockByName3 = Unlocks.GetUnlockByName("Basic Powder Bricks", false);
unlockByName.requiredTier = unlockByName2.requiredTier;
unlockByName.treePosition = unlockByName3.treePosition;
Resources.GetResourceInfoByName("Limestone", false);
unlockByName.sprite = Images.LoadSpriteFromFile("EMUAdditions.Images.VoidChest.png", false);
}
if (Testing.doMachineTest)
{
ChestDefinition val = (ChestDefinition)Resources.GetResourceInfoByName("Void Chest", false);
((BuilderInfo)val).inventorySizes = new List<Vector2Int>
{
new Vector2Int(1, 1)
};
((BuilderInfo)val).invSizeOutput = new Vector2Int(1, 1);
}
}
private void OnSaveStateLoaded(object sender, EventArgs e)
{
EMUAdditions.CustomData.Load(SaveState.instance.metadata.worldName);
RecipeAdder.FetchUnlocks();
ResourceAdder.FetchUnlocks();
MachineAdder.FetchUnlocks();
}
private void OnTechTreeStateLoaded()
{
TechTreeState.instance.RefreshKnownResources();
}
private void OnGameSaved(object sender, EventArgs e)
{
EMUAdditions.CustomData.Save(sender.ToString());
}
internal static void LogInfo(string message)
{
Log.LogInfo((object)message);
}
internal static void LogWarning(string message)
{
Log.LogWarning((object)message);
}
internal static void LogError(string message)
{
Log.LogError((object)message);
}
internal static bool IsTranslatableStringUnique(string input)
{
return !customTranslations.ContainsValue(input);
}
private void ApplyPatches()
{
Harmony.CreateAndPatchAll(typeof(FlowManagerPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(GameDefinesPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(LocsUtilityPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(TechActivatedSystemMessage), (string)null);
}
internal static void SaveIdHistory()
{
Directory.CreateDirectory(dataFolder);
List<string> list = new List<string>();
foreach (KeyValuePair<string, int> item in idHistory)
{
list.Add($"{item.Key}|{item.Value}");
}
File.WriteAllLines(dataFolder + "/Id History.txt", list);
}
private void LoadIdHistory()
{
string path = dataFolder + "/Id History.txt";
if (!File.Exists(path))
{
LogWarning("No Id History save file found");
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { '|' });
idHistory.Add(array2[0], int.Parse(array2[1]));
}
}
}
}
namespace EquinoxsModUtils.Additions
{
public class NewRecipeDetails
{
public string GUID;
public CraftingMethod craftingMethod;
public int craftTierRequired;
public float duration;
public List<RecipeResourceInfo> ingredients = new List<RecipeResourceInfo>();
public List<RecipeResourceInfo> outputs = new List<RecipeResourceInfo>();
public int sortPriority;
public string unlockName;
public string GetUniqueName()
{
return GUID + "-" + outputs[0].name;
}
public bool Validate()
{
if (outputs.Count == 0)
{
EMUAdditionsPlugin.LogError("New Recipe cannot have no outputs");
return false;
}
if (ingredients.Count == 0)
{
EMUAdditionsPlugin.LogError("New Recipe cannot have no ingredients '" + GetUniqueName() + "'");
return false;
}
if (string.IsNullOrEmpty(GUID))
{
EMUAdditionsPlugin.LogError("GUID cannot be null or empty for new Recipe '" + GetUniqueName() + "'");
return false;
}
return true;
}
public SchematicsRecipeData ConvertToRecipe()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
SchematicsRecipeData val = (SchematicsRecipeData)ScriptableObject.CreateInstance("SchematicsRecipeData");
val.craftingMethod = craftingMethod;
val.craftTierRequired = craftTierRequired;
val.duration = duration;
val.sortPriority = sortPriority;
val.ingQuantities = new int[ingredients.Count];
val.ingTypes = (ResourceInfo[])(object)new ResourceInfo[ingredients.Count];
val.outputQuantities = new int[outputs.Count];
val.outputTypes = (ResourceInfo[])(object)new ResourceInfo[outputs.Count];
((Object)val).name = GetUniqueName();
for (int i = 0; i < ingredients.Count; i++)
{
val.ingQuantities[i] = ingredients[i].quantity;
ResourceInfo resourceInfoByNameUnsafe = Resources.GetResourceInfoByNameUnsafe(ingredients[i].name, false);
val.ingTypes[i] = resourceInfoByNameUnsafe;
}
for (int j = 0; j < outputs.Count; j++)
{
val.outputQuantities[j] = outputs[j].quantity;
ResourceInfo resourceInfoByNameUnsafe2 = Resources.GetResourceInfoByNameUnsafe(outputs[j].name, false);
val.outputTypes[j] = resourceInfoByNameUnsafe2;
}
return val;
}
}
public struct RecipeResourceInfo
{
public string name;
public int quantity;
public RecipeResourceInfo(string _name, int _quantity)
{
name = _name;
quantity = _quantity;
}
}
public class NewResourceDetails
{
public string parentName;
public string name;
public string description;
public CraftingMethod craftingMethod;
public int craftTierRequired;
public float fuelAmount;
public string headerTitle;
public string subHeaderTitle;
public int maxStackCount = 500;
public Sprite sprite;
public int sortPriority;
public string unlockName;
internal bool Validate()
{
if (string.IsNullOrEmpty(parentName))
{
EMUAdditionsPlugin.LogError("parentName cannot be null or empty for NewResourceDetails '" + name + "'");
return false;
}
if (string.IsNullOrEmpty(name))
{
EMUAdditionsPlugin.LogError("name cannot be null or empty for NewResourceDetails");
return false;
}
if (string.IsNullOrEmpty(description))
{
EMUAdditionsPlugin.LogError("description cannot be null or empty for NewResourceDetails '" + name + "'");
return false;
}
return true;
}
internal ResourceInfo ConvertToResourceInfo()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
ResourceInfo obj = ScriptableObject.CreateInstance<ResourceInfo>();
obj.craftingMethod = craftingMethod;
obj.craftTierRequired = craftTierRequired;
obj.description = description;
obj.fuelAmount = fuelAmount;
obj.maxStackCount = maxStackCount;
obj.rawName = name;
obj.rawSprite = sprite;
obj.sortPriority = sortPriority;
return obj;
}
}
public class NewUnlockDetails
{
public string displayName;
public string description;
public TechCategory category;
public ResearchTier requiredTier;
public CoreType coreTypeNeeded;
public int coreCountNeeded;
public int treePosition;
public List<string> dependencyNames = new List<string>();
public Sprite sprite;
internal bool Validate()
{
if (dependencyNames.Count > 2)
{
EMUAdditionsPlugin.LogError("New Unlock '" + displayName + "' cannot have more than 2 dependencies");
return false;
}
if (!EMUAdditionsPlugin.IsTranslatableStringUnique(displayName))
{
EMUAdditionsPlugin.LogError("New Unlock displayName '" + displayName + "' is not unique");
return false;
}
if (!EMUAdditionsPlugin.IsTranslatableStringUnique(description))
{
EMUAdditionsPlugin.LogWarning("New Unlock " + displayName + "'s description is not unique");
}
return true;
}
internal Unlock ConvertToUnlock()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Expected O, but got Unknown
Unlock val = (Unlock)ScriptableObject.CreateInstance(typeof(Unlock));
val.category = category;
val.coresNeeded = new List<RequiredCores>
{
new RequiredCores
{
type = coreTypeNeeded,
number = coreCountNeeded
}
};
val.isCoreTech = false;
val.isDebugTech = false;
val.numScansNeeded = 0;
val.requiredTier = requiredTier;
val.priority = 0;
val.scanDuration = 1f;
val.sprite = sprite;
val.treePosition = treePosition;
string hashString = LocsUtility.GetHashString(displayName);
string hashString2 = LocsUtility.GetHashString(description);
val.displayNameHash = hashString;
val.descriptionHash = hashString2;
EMUAdditionsPlugin.customTranslations[hashString] = displayName;
EMUAdditionsPlugin.customTranslations[hashString2] = description;
UnlockAdder.unlockDependencies.Add(hashString, dependencyNames);
return val;
}
}
}
namespace EquinoxsModUtils.Additions.Patches
{
internal class FlowManagerPatch
{
[HarmonyPatch(typeof(FlowManager), "ClearGameState")]
[HarmonyPostfix]
private static void ResetContentAdders()
{
GameDefinesPatch.loadedCustomData = false;
}
}
internal class GameDefinesPatch
{
public static bool loadedCustomData = false;
public static bool isFirstLoad = true;
[HarmonyPatch(typeof(GameDefines), "GetMaxResId")]
[HarmonyPrefix]
private static void AddCustomData()
{
if (!loadedCustomData)
{
loadedCustomData = true;
SubHeaderAdder.AddRegisteredSubHeaders();
ResourceAdder.AddHistoricResources();
MachineAdder.AddHistoricMachines();
ResourceAdder.AddBrandNewResources();
MachineAdder.AddBrandNewMachines();
EquipmentAdder.AddHistoricEquipment();
EquipmentAdder.AddBrandNewEquipment();
ResourceAdder.FillMissingIds();
RecipeAdder.AddRegisteredRecipes();
EMU.SetPrivateStaticField<GameDefines>("_topResId", GameDefines.instance, (object)(-1));
isFirstLoad = false;
}
}
}
internal class LocsUtilityPatch
{
[HarmonyPatch(typeof(LocsUtility), "TranslateStringFromHash", new Type[]
{
typeof(string),
typeof(string),
typeof(Object)
})]
[HarmonyPrefix]
private static bool GetModdedTranslation(ref string __result, string hash)
{
if (string.IsNullOrEmpty(hash))
{
return true;
}
if (EMUAdditionsPlugin.customTranslations.ContainsKey(hash))
{
__result = EMUAdditionsPlugin.customTranslations[hash];
return false;
}
return true;
}
}
internal class TechActivatedSystemMessagePatch
{
[HarmonyPatch(typeof(TechActivatedSystemMessage), "ToString")]
[HarmonyPrefix]
private static void SetDefaultSprite(TechActivatedSystemMessage __instance)
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
if (!EDT.NullCheck((object)__instance.unlock.sprite, "Unlock Sprite", false))
{
EDT.NullCheck((object)UIManager.instance, "UIManager", false);
EDT.NullCheck((object)UIManager.instance.techTreeMenu, "techTreeMenu", false);
TechTreeNode nodeByUnlock = UIManager.instance.techTreeMenu.GridUI.GetNodeByUnlock(GameDefines.instance.unlocks[0]);
EDT.NullCheck((object)nodeByUnlock, "TechTreeNode", false);
Sprite val = (Sprite)EMU.GetPrivateField<TechTreeNode>("iconSprite", nodeByUnlock);
EDT.NullCheck((object)val, "defaultSprite", false);
__instance.unlock.sprite = val;
GameDefines.instance.unlocks[GameDefines.instance.unlocks.Count - 1] = __instance.unlock;
EMUAdditionsPlugin.LogInfo("Set Unlock '" + __instance.unlock.displayName + "' to default sprite");
}
}
}
}
namespace EquinoxsModUtils.Additions.ContentAdders
{
internal static class EquipmentAdder
{
internal static List<Equipment> equipmentToAdd = new List<Equipment>();
internal static List<NewResourceDetails> details = new List<NewResourceDetails>();
internal static Dictionary<string, int> idHistory => EMUAdditionsPlugin.idHistory;
internal static void AddHistoricEquipment()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
List<Equipment> list = equipmentToAdd.Where((Equipment equipment) => idHistory.ContainsKey("Equipment-" + ((ResourceInfo)equipment.info).displayName)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} historic new Equipments have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
Equipment val = list[i];
int index = equipmentToAdd.IndexOf(val);
NewResourceDetails newResourceDetails = details[index];
EquippableResourceInfo val2 = (EquippableResourceInfo)Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false);
EquippableResourceInfo info = val.info;
EMU.CloneObject<EquippableResourceInfo>(val2, ref info);
((ResourceInfo)info).rawName = newResourceDetails.name;
((UniqueIdScriptableObject)info).uniqueId = idHistory["Equipment-" + ((ResourceInfo)info).displayName];
AddEquipmentToGame(val);
EMUAdditionsPlugin.LogInfo($"Added historic new Equipment '{((ResourceInfo)info).rawName}' to the game with id {((UniqueIdScriptableObject)info).uniqueId}");
}
}
internal static void AddBrandNewEquipment()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
List<Equipment> list = equipmentToAdd.Where((Equipment equipment) => !idHistory.ContainsKey("Equipment-" + ((ResourceInfo)equipment.info).displayName)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} brand new Equipments have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
Equipment val = list[i];
int index = equipmentToAdd.IndexOf(val);
NewResourceDetails newResourceDetails = details[index];
EquippableResourceInfo val2 = (EquippableResourceInfo)Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false);
EquippableResourceInfo info = val.info;
EMU.CloneObject<EquippableResourceInfo>(val2, ref info);
((ResourceInfo)info).rawName = newResourceDetails.name;
((UniqueIdScriptableObject)info).uniqueId = GetNewEquipmentId();
idHistory.Add("Equipment-" + ((ResourceInfo)info).rawName, ((UniqueIdScriptableObject)info).uniqueId);
AddEquipmentToGame(val);
EMUAdditionsPlugin.LogInfo($"Added brand new Equipment '{((ResourceInfo)info).rawName}' to the game with id {((UniqueIdScriptableObject)info).uniqueId}");
}
EMUAdditionsPlugin.SaveIdHistory();
}
internal static void FetchUnlocks()
{
foreach (NewResourceDetails detail in details)
{
if (!string.IsNullOrEmpty(detail.name))
{
ResourceInfo resourceInfoByNameUnsafe = Resources.GetResourceInfoByNameUnsafe(detail.name, false);
if (!((Object)(object)resourceInfoByNameUnsafe.unlock != (Object)null))
{
resourceInfoByNameUnsafe.unlock = Unlocks.GetUnlockByName(detail.unlockName, false);
resourceInfoByNameUnsafe.unlock.GetUnlockState().unlockedResources.Add(resourceInfoByNameUnsafe);
}
}
}
}
private static void AddEquipmentToGame(Equipment equipment)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
int index = equipmentToAdd.IndexOf(equipment);
NewResourceDetails newResourceDetails = details[index];
EquippableResourceInfo val = (EquippableResourceInfo)Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false);
((ResourceInfo)equipment.info).craftingMethod = newResourceDetails.craftingMethod;
((ResourceInfo)equipment.info).craftTierRequired = newResourceDetails.craftTierRequired;
((ResourceInfo)equipment.info).description = newResourceDetails.description;
((ResourceInfo)equipment.info).maxStackCount = newResourceDetails.maxStackCount;
((ResourceInfo)equipment.info).rawName = newResourceDetails.name;
((ResourceInfo)equipment.info).rawSprite = newResourceDetails.sprite;
((ResourceInfo)equipment.info).sortPriority = newResourceDetails.sortPriority;
if (!string.IsNullOrEmpty(newResourceDetails.subHeaderTitle))
{
((ResourceInfo)equipment.info).headerType = Recipes.GetSchematicsSubHeaderByTitleUnsafe(newResourceDetails.headerTitle, newResourceDetails.subHeaderTitle, false);
}
if ((Object)(object)((ResourceInfo)equipment.info).sprite == (Object)null)
{
((ResourceInfo)equipment.info).rawSprite = ((ResourceInfo)val).sprite;
}
string hashString = LocsUtility.GetHashString(((ResourceInfo)equipment.info).displayName);
string hashString2 = LocsUtility.GetHashString(((ResourceInfo)equipment.info).description);
EMUAdditionsPlugin.customTranslations[hashString] = ((ResourceInfo)equipment.info).displayName;
EMUAdditionsPlugin.customTranslations[hashString2] = ((ResourceInfo)equipment.info).description;
GameDefines.instance.resources.Add((ResourceInfo)(object)equipment.info);
Resources.SafeResources.Add(((ResourceInfo)equipment.info).displayName);
Dictionary<ResourceInfo, Equipment> dictionary = (Dictionary<ResourceInfo, Equipment>)EMU.GetPrivateField<PlayerEquipment>("equipmentLookup", Player.instance.equipment);
dictionary.Add((ResourceInfo)(object)equipment.info, equipment);
EMU.SetPrivateField<PlayerEquipment>("equipmentLookup", Player.instance.equipment, (object)dictionary);
EMUAdditionsPlugin.LogInfo("Registered " + ((ResourceInfo)equipment.info).displayName + " with Player.instance.equipment");
ResourceAdder.addedIds.Add(((UniqueIdScriptableObject)equipment.info).uniqueId);
}
private static int GetNewEquipmentId()
{
int num = 0;
foreach (ResourceInfo resource in GameDefines.instance.resources)
{
if (((UniqueIdScriptableObject)resource).uniqueId > num)
{
num = ((UniqueIdScriptableObject)resource).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
}
internal static class MachineAdder
{
internal static List<ResourceInfo> machinesToAdd = new List<ResourceInfo>();
internal static List<NewResourceDetails> details = new List<NewResourceDetails>();
internal static Dictionary<string, int> idHistory => EMUAdditionsPlugin.idHistory;
internal static void AddHistoricMachines()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
List<ResourceInfo> list = machinesToAdd.Where((ResourceInfo machine) => idHistory.ContainsKey("Machine-" + machine.displayName)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} historic new Machines have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
ResourceInfo val = list[i];
int index = machinesToAdd.IndexOf(val);
NewResourceDetails newResourceDetails = details[index];
EMU.CloneObject<ResourceInfo>((ResourceInfo)(BuilderInfo)Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false), ref val);
val.rawName = newResourceDetails.name;
((UniqueIdScriptableObject)val).uniqueId = idHistory["Machine-" + val.displayName];
AddMachineToGame(val);
EMUAdditionsPlugin.LogInfo($"Added historic new Machine '{val.rawName}' to the game with id {((UniqueIdScriptableObject)val).uniqueId}");
}
}
internal static void AddBrandNewMachines()
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
List<ResourceInfo> list = machinesToAdd.Where((ResourceInfo machine) => !idHistory.ContainsKey("Machine-" + machine.displayName)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} brand new Machines have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
ResourceInfo val = list[i];
int index = machinesToAdd.IndexOf(val);
NewResourceDetails newResourceDetails = details[index];
EMU.CloneObject<ResourceInfo>((ResourceInfo)(BuilderInfo)Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false), ref val);
val.rawName = newResourceDetails.name;
((UniqueIdScriptableObject)val).uniqueId = GetNewMachineID();
idHistory.Add("Machine-" + val.displayName, ((UniqueIdScriptableObject)val).uniqueId);
AddMachineToGame(val);
EMUAdditionsPlugin.LogInfo($"Added brand new Machine '{newResourceDetails.name}' to the game with id '{((UniqueIdScriptableObject)val).uniqueId}'");
}
EMUAdditionsPlugin.SaveIdHistory();
}
internal static void FetchUnlocks()
{
foreach (NewResourceDetails detail in details)
{
if (!string.IsNullOrEmpty(detail.name))
{
ResourceInfo resourceInfoByName = Resources.GetResourceInfoByName(detail.name, false);
if (!((Object)(object)resourceInfoByName.unlock != (Object)null))
{
resourceInfoByName.unlock = Unlocks.GetUnlockByName(detail.unlockName, false);
resourceInfoByName.unlock.GetUnlockState().unlockedResources.Add(resourceInfoByName);
}
}
}
}
private static void AddMachineToGame(ResourceInfo machineDefinition)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Expected O, but got Unknown
int index = machinesToAdd.IndexOf(machineDefinition);
NewResourceDetails newResourceDetails = details[index];
ResourceInfo resourceInfoByNameUnsafe = Resources.GetResourceInfoByNameUnsafe(newResourceDetails.parentName, false);
machineDefinition.craftingMethod = newResourceDetails.craftingMethod;
machineDefinition.craftTierRequired = newResourceDetails.craftTierRequired;
machineDefinition.description = newResourceDetails.description;
machineDefinition.maxStackCount = newResourceDetails.maxStackCount;
machineDefinition.rawName = newResourceDetails.name;
machineDefinition.rawSprite = newResourceDetails.sprite;
machineDefinition.sortPriority = newResourceDetails.sortPriority;
if (!string.IsNullOrEmpty(newResourceDetails.subHeaderTitle))
{
machineDefinition.headerType = Recipes.GetSchematicsSubHeaderByTitleUnsafe(newResourceDetails.headerTitle, newResourceDetails.subHeaderTitle, false);
}
if ((Object)(object)machineDefinition.sprite == (Object)null)
{
machineDefinition.rawSprite = resourceInfoByNameUnsafe.sprite;
}
string hashString = LocsUtility.GetHashString(machineDefinition.displayName);
string hashString2 = LocsUtility.GetHashString(machineDefinition.description);
EMUAdditionsPlugin.customTranslations[hashString] = machineDefinition.displayName;
EMUAdditionsPlugin.customTranslations[hashString2] = machineDefinition.description;
GameDefines.instance.resources.Add(machineDefinition);
GameDefines.instance.buildableResources.Add((BuilderInfo)machineDefinition);
Resources.SafeResources.Add(machineDefinition.displayName);
ResourceAdder.addedIds.Add(((UniqueIdScriptableObject)machineDefinition).uniqueId);
}
private static int GetNewMachineID()
{
int num = 0;
foreach (ResourceInfo resource in GameDefines.instance.resources)
{
if (((UniqueIdScriptableObject)resource).uniqueId > num)
{
num = ((UniqueIdScriptableObject)resource).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
}
internal static class RecipeAdder
{
internal static List<NewRecipeDetails> recipesToAdd = new List<NewRecipeDetails>();
internal static Dictionary<string, int> idHistory = new Dictionary<string, int>();
private static List<SchematicsRecipeData> addedRecipes = new List<SchematicsRecipeData>();
private static string dataFolder => EMUAdditionsPlugin.dataFolder;
internal static void AddRegisteredRecipes()
{
EMUAdditionsPlugin.LogInfo($"{recipesToAdd.Count} new Recipes have been registered for adding");
foreach (NewRecipeDetails item in recipesToAdd.Where((NewRecipeDetails recipe) => idHistory.ContainsKey(recipe.GetUniqueName())).ToList())
{
SchematicsRecipeData recipe2 = item.ConvertToRecipe();
((UniqueIdScriptableObject)recipe2).uniqueId = idHistory[item.GetUniqueName()];
AddRecipeToGame(item, ref recipe2);
EMUAdditionsPlugin.LogInfo($"Added historic new Recipe '{item.GetUniqueName()}' to the game with id {((UniqueIdScriptableObject)recipe2).uniqueId}");
}
foreach (NewRecipeDetails item2 in recipesToAdd.Where((NewRecipeDetails recipe) => !idHistory.ContainsKey(recipe.GetUniqueName())).ToList())
{
SchematicsRecipeData recipe3 = item2.ConvertToRecipe();
((UniqueIdScriptableObject)recipe3).uniqueId = GetNewRecipeID();
idHistory.Add(item2.GetUniqueName(), ((UniqueIdScriptableObject)recipe3).uniqueId);
AddRecipeToGame(item2, ref recipe3);
EMUAdditionsPlugin.LogInfo($"Added brand new Recipe '{item2.GetUniqueName()}' to the game with id {((UniqueIdScriptableObject)recipe3).uniqueId}");
}
SaveIdHistory();
}
internal static void FetchUnlocks()
{
foreach (NewRecipeDetails item in recipesToAdd)
{
if (string.IsNullOrEmpty(item.unlockName))
{
continue;
}
List<int> list = new List<int>();
List<int> list2 = new List<int>();
foreach (RecipeResourceInfo ingredient in item.ingredients)
{
list.Add(Resources.GetResourceIDByName(ingredient.name, false));
}
foreach (RecipeResourceInfo output in item.outputs)
{
list2.Add(Resources.GetResourceIDByName(output.name, false));
}
SchematicsRecipeData val = Recipes.TryFindRecipe(list, list2, false);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.unlock != (Object)null))
{
val.unlock = Unlocks.GetUnlockByName(item.unlockName, false);
val.unlock.GetUnlockState().unlockedRecipes.Add(val);
TechTreeState.instance.knownRecipes.Remove(val);
TechTreeState.instance.knownRecipesArray[((UniqueIdScriptableObject)val).uniqueId] = false;
}
}
}
private static void AddRecipeToGame(NewRecipeDetails details, ref SchematicsRecipeData recipe)
{
GameDefines.instance.schematicsRecipeEntries.Add(recipe);
addedRecipes.Add(recipe);
}
private static int GetNewRecipeID()
{
int num = 0;
foreach (SchematicsRecipeData schematicsRecipeEntry in GameDefines.instance.schematicsRecipeEntries)
{
if (((UniqueIdScriptableObject)schematicsRecipeEntry).uniqueId > num)
{
num = ((UniqueIdScriptableObject)schematicsRecipeEntry).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
private static void SaveIdHistory()
{
Directory.CreateDirectory(dataFolder);
List<string> list = new List<string>();
foreach (KeyValuePair<string, int> item in idHistory)
{
list.Add($"{item.Key}|{item.Value}");
}
File.WriteAllLines(dataFolder + "/Recipe Id History.txt", list);
}
internal static void LoadIdHistory()
{
string path = dataFolder + "/Recipe Id History.txt";
if (!File.Exists(path))
{
EMUAdditionsPlugin.LogWarning("No Recipe Id History save file found");
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { '|' });
idHistory.Add(array2[0], int.Parse(array2[1]));
}
}
}
internal static class ResourceAdder
{
internal static List<NewResourceDetails> resourcesToAdd = new List<NewResourceDetails>();
internal static List<int> addedIds = new List<int>();
internal static Dictionary<string, int> idHistory => EMUAdditionsPlugin.idHistory;
internal static void AddHistoricResources()
{
List<NewResourceDetails> list = resourcesToAdd.Where((NewResourceDetails details) => idHistory.ContainsKey("Resource-" + details.name)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} historic new Resources have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
NewResourceDetails newResourceDetails = list[i];
ResourceInfo resource = newResourceDetails.ConvertToResourceInfo();
((UniqueIdScriptableObject)resource).uniqueId = idHistory["Resource-" + newResourceDetails.name];
AddResourceToGame(newResourceDetails, ref resource);
EMUAdditionsPlugin.LogInfo($"Added historic new Resource '{newResourceDetails.name}' to the game with id {((UniqueIdScriptableObject)resource).uniqueId}");
}
}
internal static void AddBrandNewResources()
{
List<NewResourceDetails> list = resourcesToAdd.Where((NewResourceDetails details) => !idHistory.ContainsKey("Resource-" + details.name)).ToList();
EMUAdditionsPlugin.LogInfo($"{list.Count} brand new Resources have been registered for adding");
for (int i = 0; i < list.Count; i++)
{
NewResourceDetails newResourceDetails = list[i];
ResourceInfo resource = newResourceDetails.ConvertToResourceInfo();
((UniqueIdScriptableObject)resource).uniqueId = GetNewResourceID();
idHistory.Add("Resource-" + newResourceDetails.name, ((UniqueIdScriptableObject)resource).uniqueId);
AddResourceToGame(newResourceDetails, ref resource);
EMUAdditionsPlugin.LogInfo($"Added brand new Resource '{newResourceDetails.name}' to the game with id {((UniqueIdScriptableObject)resource).uniqueId}");
}
EMUAdditionsPlugin.SaveIdHistory();
}
internal static void FillMissingIds()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
foreach (int value in idHistory.Values)
{
if (!addedIds.Contains(value))
{
EMUAdditionsPlugin.LogWarning($"Historic ResourceId {value} has not added been added this launch");
ResourceInfo resourceInfoByNameUnsafe = Resources.GetResourceInfoByNameUnsafe("SharkRepellant", false);
ResourceInfo val = (ResourceInfo)ScriptableObject.CreateInstance(typeof(ResourceInfo));
((Object)val).name = "EMU Hidden Resource";
val.redacted = true;
((UniqueIdScriptableObject)val).uniqueId = value;
val.rawConveyorResourcePrefab = resourceInfoByNameUnsafe.rawConveyorResourcePrefab;
val.headerType = resourceInfoByNameUnsafe.headerType;
GameDefines.instance.resources.Add(val);
}
}
}
internal static void FetchUnlocks()
{
foreach (NewResourceDetails item in resourcesToAdd)
{
if (!string.IsNullOrEmpty(item.unlockName))
{
ResourceInfo resourceInfoByName = Resources.GetResourceInfoByName(item.name, false);
if (!((Object)(object)resourceInfoByName.unlock != (Object)null))
{
resourceInfoByName.unlock = Unlocks.GetUnlockByName(item.unlockName, false);
resourceInfoByName.unlock.GetUnlockState().unlockedResources.Add(resourceInfoByName);
}
}
}
}
private static void AddResourceToGame(NewResourceDetails details, ref ResourceInfo resource)
{
ResourceInfo resourceInfoByNameUnsafe = Resources.GetResourceInfoByNameUnsafe(details.parentName, false);
if ((Object)(object)resourceInfoByNameUnsafe == (Object)null)
{
EMUAdditionsPlugin.LogError("Could not find parent Resource '" + details.parentName + "'");
EMUAdditionsPlugin.LogError("Abandoning attempt to add new Resource '" + details.name + "'");
return;
}
if (!string.IsNullOrEmpty(details.subHeaderTitle))
{
resource.headerType = Recipes.GetSchematicsSubHeaderByTitleUnsafe(details.headerTitle, details.subHeaderTitle, false);
}
if ((Object)(object)resource.headerType == (Object)null)
{
resource.headerType = resourceInfoByNameUnsafe.headerType;
}
if ((Object)(object)resource.sprite == (Object)null)
{
resource.rawSprite = resourceInfoByNameUnsafe.sprite;
}
resource.model3D = resourceInfoByNameUnsafe.model3D;
resource.rawConveyorResourcePrefab = resourceInfoByNameUnsafe.rawConveyorResourcePrefab;
string hashString = LocsUtility.GetHashString(details.name);
string hashString2 = LocsUtility.GetHashString(details.description);
EMUAdditionsPlugin.customTranslations[hashString] = details.name;
EMUAdditionsPlugin.customTranslations[hashString2] = details.description;
GameDefines.instance.resources.Add(resource);
Resources.SafeResources.Add(resource.displayName);
addedIds.Add(((UniqueIdScriptableObject)resource).uniqueId);
}
private static int GetNewResourceID()
{
int num = 0;
foreach (ResourceInfo resource in GameDefines.instance.resources)
{
if (((UniqueIdScriptableObject)resource).uniqueId > num)
{
num = ((UniqueIdScriptableObject)resource).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
}
internal static class SubHeaderAdder
{
internal static List<SchematicsSubHeader> subHeadersToAdd = new List<SchematicsSubHeader>();
internal static List<string> parents = new List<string>();
internal static Dictionary<string, int> idHistory = new Dictionary<string, int>();
private static string dataFolder => EMUAdditionsPlugin.dataFolder;
internal static void AddRegisteredSubHeaders()
{
EMUAdditionsPlugin.LogInfo($"{subHeadersToAdd.Count} new SchematicsSubHeaders have been registered for adding");
foreach (SchematicsSubHeader item in subHeadersToAdd.Where((SchematicsSubHeader subHeader) => idHistory.ContainsKey(subHeader.title)).ToList())
{
EMUAdditionsPlugin.LogInfo("Trying to add historic new SchematicsSubHeader '" + item.title + "'");
((UniqueIdScriptableObject)item).uniqueId = idHistory[item.title];
if (AddSubHeaderToGame(item))
{
EMUAdditionsPlugin.LogInfo($"Added historic new SchematicsSubHeader '{item.title}' to the game with id {((UniqueIdScriptableObject)item).uniqueId}");
}
}
foreach (SchematicsSubHeader item2 in subHeadersToAdd.Where((SchematicsSubHeader subHeader) => !idHistory.ContainsKey(subHeader.title)).ToList())
{
EMUAdditionsPlugin.LogInfo("Trying to add brand new SchematicsSubHeader '" + item2.title + "'");
((UniqueIdScriptableObject)item2).uniqueId = GetNewSubHeaderID();
idHistory.Add(item2.title, ((UniqueIdScriptableObject)item2).uniqueId);
if (AddSubHeaderToGame(item2))
{
EMUAdditionsPlugin.LogInfo($"Added brand new SchematicsSubHeader '{item2.title}' to the game with id {((UniqueIdScriptableObject)item2).uniqueId}");
}
}
SaveIdHistory();
}
private static bool AddSubHeaderToGame(SchematicsSubHeader subHeader)
{
int index = subHeadersToAdd.IndexOf(subHeader);
string text = parents[index];
subHeader.filterTag = Recipes.GetSchematicsHeaderByTitleUnsafe(text, false);
if ((Object)(object)subHeader.filterTag == (Object)null)
{
EMUAdditionsPlugin.LogError("Aborting attempt to add new SchematicsSubHeader '" + subHeader.title + "'");
return false;
}
string hashString = LocsUtility.GetHashString(subHeader.title);
EMUAdditionsPlugin.customTranslations[hashString] = subHeader.title;
GameDefines.instance.schematicsSubHeaderEntries.Add(subHeader);
return true;
}
private static int GetNewSubHeaderID()
{
int num = 0;
foreach (SchematicsSubHeader schematicsSubHeaderEntry in GameDefines.instance.schematicsSubHeaderEntries)
{
if (((UniqueIdScriptableObject)schematicsSubHeaderEntry).uniqueId > num)
{
num = ((UniqueIdScriptableObject)schematicsSubHeaderEntry).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
private static void SaveIdHistory()
{
Directory.CreateDirectory(dataFolder);
List<string> list = new List<string>();
foreach (KeyValuePair<string, int> item in idHistory)
{
list.Add($"{item.Key}|{item.Value}");
}
File.WriteAllLines(dataFolder + "/SubHeader Id History.txt", list);
}
internal static void LoadIdHistory()
{
string path = dataFolder + "/SubHeader Id History.txt";
if (!File.Exists(path))
{
EMUAdditionsPlugin.LogWarning("No SubHeader Id History save file found");
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { '|' });
idHistory.Add(array2[0], int.Parse(array2[1]));
}
}
}
internal static class UnlockAdder
{
internal static Dictionary<string, int> idHistory = new Dictionary<string, int>();
internal static Dictionary<string, List<string>> unlockDependencies = new Dictionary<string, List<string>>();
internal static List<Unlock> unlocksToAdd = new List<Unlock>();
private static List<string> newUnlockHashedNames = new List<string>();
private static string dataFolder => EMUAdditionsPlugin.dataFolder;
internal static void AddRegisteredUnlocks()
{
EMUAdditionsPlugin.LogInfo($"{unlocksToAdd.Count} new Unlocks have been registered for adding");
List<Unlock> list = unlocksToAdd.Where((Unlock unlock) => idHistory.ContainsKey(unlock.displayNameHash)).ToList();
for (int i = 0; i < list.Count; i++)
{
Unlock unlock2 = list[i];
if (EDT.NullCheck((object)unlock2, "New Unlock", false) && FindDependencies(ref unlock2))
{
((UniqueIdScriptableObject)unlock2).uniqueId = idHistory[unlock2.displayNameHash];
AddUnlockToGame(ref unlock2);
EMUAdditionsPlugin.LogInfo($"Added historic new Unlock '{EMUAdditionsPlugin.customTranslations[unlock2.displayNameHash]}' to the game with id {((UniqueIdScriptableObject)unlock2).uniqueId}");
}
}
List<Unlock> list2 = unlocksToAdd.Where((Unlock unlock) => !idHistory.ContainsKey(unlock.displayNameHash)).ToList();
for (int j = 0; j < list2.Count; j++)
{
Unlock unlock3 = list2[j];
if (EDT.NullCheck((object)unlock3, "New Unlock", false) && FindDependencies(ref unlock3))
{
((UniqueIdScriptableObject)unlock3).uniqueId = GetNewUnlockID();
idHistory.Add(unlock3.displayNameHash, ((UniqueIdScriptableObject)unlock3).uniqueId);
AddUnlockToGame(ref unlock3);
EMUAdditionsPlugin.LogInfo($"Added brand new Unlock '{EMUAdditionsPlugin.customTranslations[unlock3.displayNameHash]}' to the game with id {((UniqueIdScriptableObject)unlock3).uniqueId}");
}
}
SaveIdHistory();
}
internal static void CleanUnlockStates()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
EMUAdditionsPlugin.Log.LogInfo((object)"Cleaning Unlock States");
int num = 0;
while (num < TechTreeState.instance.unlockStates.Count())
{
UnlockState val = TechTreeState.instance.unlockStates[num];
if ((Object)(object)val.unlockRef == (Object)null || GameDefines.instance.unlocks.Contains(val.unlockRef))
{
num++;
continue;
}
ArrayExt.RemoveAt<UnlockState>(TechTreeState.instance.unlockStates, num);
GameState.instance.acknowledgedUnlocks.Remove(((UniqueIdScriptableObject)val.unlockRef).uniqueId);
EMUAdditionsPlugin.Log.LogInfo((object)$"Could not find Unlock for UnlockState #{num}. Removed.");
}
EMUAdditionsPlugin.Log.LogInfo((object)"Clearing duplicate unlock states");
List<UnlockState> list = new List<UnlockState>();
for (int i = 0; i < TechTreeState.instance.unlockStates.Count(); i++)
{
bool flag = true;
foreach (UnlockState item in list)
{
if (!((Object)(object)TechTreeState.instance.unlockStates[i].unlockRef == (Object)null) && !((Object)(object)item.unlockRef == (Object)null) && ((UniqueIdScriptableObject)TechTreeState.instance.unlockStates[i].unlockRef).uniqueId == ((UniqueIdScriptableObject)item.unlockRef).uniqueId)
{
flag = false;
break;
}
}
if (flag)
{
list.Add(TechTreeState.instance.unlockStates[i]);
}
}
int num2 = TechTreeState.instance.unlockStates.Count() - list.Count;
EMUAdditionsPlugin.Log.LogInfo((object)$"Found '{list.Count}' unique states");
EMUAdditionsPlugin.Log.LogInfo((object)$"Removing {num2} duplicates");
TechTreeState.instance.unlockStates = list.ToArray();
}
internal static void CleanTechProgress()
{
EMUAdditionsPlugin.Log.LogInfo((object)"Cleaning Tech Progress");
int num = 0;
while (num < SaveState.instance.techTree.researchProgress.Count)
{
TechProgress val = SaveState.instance.techTree.researchProgress[num];
if (val.techIndex >= TechTreeState.instance.unlockStates.Length)
{
SaveState.instance.techTree.researchProgress.RemoveAt(num);
EMUAdditionsPlugin.Log.LogInfo((object)$"Could not find UnlockState for TechProgress #{val.techIndex}. Removed.");
}
else
{
num++;
}
}
}
private static void AddUnlockToGame(ref Unlock unlock)
{
newUnlockHashedNames.Add(unlock.displayNameHash);
GameDefines.instance.unlocks.Add(unlock);
}
private static int GetNewUnlockID()
{
int num = 0;
for (int i = 0; i < GameDefines.instance.unlocks.Count; i++)
{
if (((UniqueIdScriptableObject)GameDefines.instance.unlocks[i]).uniqueId > num)
{
num = ((UniqueIdScriptableObject)GameDefines.instance.unlocks[i]).uniqueId;
}
}
foreach (int value in idHistory.Values)
{
if (value > num)
{
num = value;
}
}
return num + 1;
}
private static bool FindDependencies(ref Unlock unlock)
{
List<Unlock> list = new List<Unlock>();
foreach (string item in unlockDependencies[unlock.displayNameHash])
{
Unlock unlockByName = Unlocks.GetUnlockByName(item, false);
if ((Object)(object)unlockByName != (Object)null)
{
list.Add(unlockByName);
continue;
}
EMUAdditionsPlugin.LogError("Could not find dependency with name '" + item + "'. Abandoning attempt to add.");
EMUAdditionsPlugin.LogError("Try using a name from EMU.UnlockNames");
return false;
}
unlock.dependencies = list;
if (list.Count >= 1)
{
unlock.dependency1 = list[0];
}
if (list.Count == 2)
{
unlock.dependency2 = list[1];
}
return true;
}
internal static void SaveIdHistory()
{
Directory.CreateDirectory(dataFolder);
List<string> list = new List<string>();
foreach (KeyValuePair<string, int> item in idHistory)
{
list.Add($"{item.Key}|{item.Value}");
}
File.WriteAllLines(dataFolder + "/Unlock Id History.txt", list);
}
internal static void LoadIdHistory()
{
string path = dataFolder + "/Unlock Id History.txt";
if (!File.Exists(path))
{
EMUAdditionsPlugin.LogWarning("No Unlock Id History save file found");
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { '|' });
idHistory.Add(array2[0], int.Parse(array2[1]));
}
}
}
}