using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SCTCommon;
using TMPro;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SCTBuilding.BigChest")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SCTBuilding.BigChest")]
[assembly: AssemblyTitle("SCTBuilding.BigChest")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SCTCommon
{
internal static class Il2CppUtil
{
public static bool IsPlayer(Driller driller)
{
if (driller != null)
{
return (Object)(object)((Il2CppObjectBase)driller).TryCast<Player>() != (Object)null;
}
return false;
}
public static string Guid(BasePlugin plugin)
{
return MetadataHelper.GetMetadata((object)plugin).GUID;
}
public static IEnumerable<PluginInfo> Plugins()
{
if (IL2CPPChainloader.Instance == null)
{
yield break;
}
foreach (PluginInfo value in ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.Values)
{
yield return value;
}
}
}
internal static class Safe
{
private static readonly ManualLogSource Log = Logger.CreateLogSource("SCT Safe");
private static readonly HashSet<string> Reported = new HashSet<string>();
public static void Run(string where, Action action)
{
try
{
action();
}
catch (Exception e)
{
Report(where, e);
}
}
public static bool Prefix(string where, Func<bool> prefix)
{
try
{
return prefix();
}
catch (Exception e)
{
Report(where, e);
return true;
}
}
private static void Report(string where, Exception e)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
if (Reported.Add(where + e.GetType().Name + e.Message))
{
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 4, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(where);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" : ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.GetType().Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" : ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (ignoré, le jeu continue)\n");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.StackTrace);
}
Log.LogError(val);
}
}
}
internal static class Vanilla
{
private const string Key = "sct.vanilla";
public static bool Active
{
get
{
object data = AppDomain.CurrentDomain.GetData("sct.vanilla");
bool flag = default(bool);
int num;
if (data is bool)
{
flag = (bool)data;
num = 1;
}
else
{
num = 0;
}
return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
}
}
public static void Set(bool active)
{
AppDomain.CurrentDomain.SetData("sct.vanilla", active);
}
}
internal static class Lang
{
public static bool IsFrench
{
get
{
try
{
Locale selectedLocale = LocalizationSettings.SelectedLocale;
return ((selectedLocale != null) ? selectedLocale.Identifier.Code : null)?.StartsWith("fr", StringComparison.OrdinalIgnoreCase) ?? false;
}
catch (Exception)
{
return false;
}
}
}
public static string Pick(string fr, string en)
{
if (!IsFrench)
{
return en;
}
return fr;
}
}
internal static class SaveSlotApi
{
private const string VersionKey = "sct.saveslot.version";
public const string Prefix = "sct_";
public static string Directory => GameInstance.SaveDirectory;
public static int Version
{
get
{
object data = AppDomain.CurrentDomain.GetData("sct.saveslot.version");
if (data is int)
{
return (int)data;
}
return 0;
}
}
public static string PathOf(string name)
{
return Path.Combine(Directory, "sct_" + name);
}
public static void BumpVersion()
{
AppDomain.CurrentDomain.SetData("sct.saveslot.version", Version + 1);
}
public static void Migrate(string oldPath, string name)
{
try
{
string text = PathOf(name);
if (File.Exists(oldPath) && !File.Exists(text))
{
File.Move(oldPath, text);
}
}
catch (Exception)
{
}
}
}
internal static class GameInstance
{
private const string IndexKey = "sct.instance.index";
private const string MutexKey = "sct.instance.mutex";
private const string ErrorKey = "sct.instance.error";
private const string MutexName = "SCT_SpaceCatDigger_Instance_";
public const int Max = 4;
public static int Index
{
get
{
object data = AppDomain.CurrentDomain.GetData("sct.instance.index");
if (data is int)
{
return (int)data;
}
int i = 0;
Mutex data2 = null;
for (; i < 4; i++)
{
bool createdNew;
Mutex mutex = new Mutex(initiallyOwned: false, "SCT_SpaceCatDigger_Instance_" + i, out createdNew);
if (createdNew)
{
data2 = mutex;
break;
}
mutex.Dispose();
}
AppDomain.CurrentDomain.SetData("sct.instance.mutex", data2);
AppDomain.CurrentDomain.SetData("sct.instance.index", i);
if (i > 0)
{
PrepareTestSaves(i);
}
return i;
}
}
public static bool IsTest => Index > 0;
public static string Suffix
{
get
{
if (!IsTest)
{
return "";
}
return "_test" + (Index + 1);
}
}
public static string SaveDirectory => DirectoryOf(Index);
public static string Error => AppDomain.CurrentDomain.GetData("sct.instance.error") as string;
private static string DirectoryOf(int index)
{
if (index <= 0)
{
return Application.persistentDataPath;
}
return Path.Combine(Application.persistentDataPath, "coop_test_" + (index + 1));
}
public static int OthersRunning()
{
int index = Index;
int num = 0;
for (int i = 0; i < 4; i++)
{
if (i != index && Mutex.TryOpenExisting("SCT_SpaceCatDigger_Instance_" + i, out Mutex result))
{
result.Dispose();
num++;
}
}
return num;
}
private static void PrepareTestSaves(int index)
{
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Expected O, but got Unknown
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
ManualLogSource val = Logger.CreateLogSource("SCT Instance");
bool flag = default(bool);
try
{
string persistentDataPath = Application.persistentDataPath;
string text = DirectoryOf(index);
Directory.CreateDirectory(text);
string[] files = Directory.GetFiles(text);
for (int i = 0; i < files.Length; i++)
{
File.Delete(files[i]);
}
files = Directory.GetFiles(persistentDataPath);
foreach (string text2 in files)
{
string fileName = Path.GetFileName(text2);
if (fileName == "persistent.save" || fileName.StartsWith("sct_", StringComparison.Ordinal))
{
File.Copy(text2, Path.Combine(text, fileName), overwrite: true);
}
}
string text3 = text + "/game.save";
string text4 = text + "/persistent.save";
SaveSystem.GameFileName = text3;
SaveSystem.PersistentFileName = text4;
if (SaveSystem.GameFileName != text3 || SaveSystem.PersistentFileName != text4)
{
throw new InvalidOperationException("chemins de sauvegarde du jeu non modifiables");
}
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Exemplaire n° ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(index + 1);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" du jeu sur ce PC : sauvegarde de test dans ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
}
val.LogInfo(val2);
}
catch (Exception ex)
{
AppDomain.CurrentDomain.SetData("sct.instance.error", ex.Message);
BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(97, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Exemplaire n° ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(index + 1);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" : sauvegarde de test impossible (");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("). CET EXEMPLAIRE ÉCRIT DANS LA VRAIE SAUVEGARDE.");
}
val.LogError(val3);
}
}
}
internal static class CraftCosts
{
private const string OwnerKey = "sct.craft.owner";
private const string ProvidersKey = "sct.craft.providers";
private const float MinFactor = 0.25f;
private const int MaxBuildId = 512;
private static readonly Dictionary<int, int[]> Originals = new Dictionary<int, int[]>();
private static float _appliedFactor = 1f;
private static bool _isOwner;
public static float Factor
{
get
{
float num = 1f;
if (AppDomain.CurrentDomain.GetData("sct.craft.providers") is Dictionary<string, Func<float>> dictionary)
{
foreach (Func<float> value in dictionary.Values)
{
try
{
num *= 1f - Mathf.Clamp(value(), 0f, 0.9f);
}
catch (Exception)
{
}
}
}
return Mathf.Max(0.25f, num);
}
}
public static void RegisterDiscount(string id, Func<float> discount)
{
lock (AppDomain.CurrentDomain)
{
Dictionary<string, Func<float>> dictionary = (AppDomain.CurrentDomain.GetData("sct.craft.providers") as Dictionary<string, Func<float>>) ?? new Dictionary<string, Func<float>>();
dictionary[id] = discount;
AppDomain.CurrentDomain.SetData("sct.craft.providers", dictionary);
}
}
public static void Install(Harmony harmony, string owner)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
lock (AppDomain.CurrentDomain)
{
if (AppDomain.CurrentDomain.GetData("sct.craft.owner") != null)
{
return;
}
AppDomain.CurrentDomain.SetData("sct.craft.owner", owner);
_isOwner = true;
}
HarmonyMethod val = new HarmonyMethod(typeof(CraftCosts), "SyncPrefix", (Type[])null);
string[] array = new string[3] { "Open", "RefreshCostItems", "TryPurchase" };
foreach (string text in array)
{
MethodInfo methodInfo = AccessTools.Method(typeof(CraftMenu), text, (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
}
private static void SyncPrefix()
{
Safe.Run("Coûts de craft", Sync);
}
public static void Sync()
{
//IL_002f: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
if (!_isOwner)
{
return;
}
Dictionary<BuildType, List<ResourceTypeQuantity>> craftingCosts = CraftMenu._craftingCosts;
if (craftingCosts == null)
{
return;
}
float factor = Factor;
bool flag = !Mathf.Approximately(factor, _appliedFactor);
for (int i = 0; i < 512; i++)
{
BuildType val = (BuildType)i;
if (!craftingCosts.ContainsKey(val))
{
continue;
}
List<ResourceTypeQuantity> val2 = craftingCosts[val];
if (!Originals.TryGetValue(i, out var value) || value.Length != val2.Count)
{
value = new int[val2.Count];
for (int j = 0; j < val2.Count; j++)
{
value[j] = val2[j].quantity;
}
Originals[i] = value;
flag = true;
}
if (flag)
{
for (int k = 0; k < val2.Count; k++)
{
ResourceTypeQuantity val3 = val2[k];
val3.quantity = ((factor >= 1f) ? value[k] : Mathf.Max(1, Mathf.CeilToInt((float)value[k] * factor)));
val2[k] = val3;
}
}
}
_appliedFactor = factor;
}
public static void AddRecipe(BuildType type, params (ResourceType Resource, int Quantity)[] ingredients)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: 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_0043: 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)
Dictionary<BuildType, List<ResourceTypeQuantity>> craftingCosts = CraftMenu._craftingCosts;
List<ResourceTypeQuantity> val = new List<ResourceTypeQuantity>();
for (int i = 0; i < ingredients.Length; i++)
{
var (resourceType, quantity) = ingredients[i];
val.Add(new ResourceTypeQuantity
{
resourceType = resourceType,
quantity = quantity
});
}
craftingCosts[type] = val;
}
}
internal static class PngLoader
{
public static Texture2D LoadTexture(byte[] png)
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
int width;
int height;
byte[] array = Decode(png, out width, out height);
Color[] array2 = (Color[])(object)new Color[width * height];
for (int i = 0; i < height; i++)
{
int num = (height - 1 - i) * width * 4;
int num2 = i * width;
int num3 = 0;
while (num3 < width)
{
array2[num2 + num3] = new Color((float)(int)array[num] / 255f, (float)(int)array[num + 1] / 255f, (float)(int)array[num + 2] / 255f, (float)(int)array[num + 3] / 255f);
num3++;
num += 4;
}
}
Texture2D val = new Texture2D(width, height, (TextureFormat)4, false)
{
filterMode = (FilterMode)0,
wrapMode = (TextureWrapMode)1
};
val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array2));
val.Apply(false);
return val;
}
public static byte[] Decode(byte[] png, out int width, out int height)
{
if (png.Length < 8 || png[0] != 137 || png[1] != 80 || png[2] != 78 || png[3] != 71)
{
throw new InvalidDataException("pas un PNG");
}
width = (height = 0);
int num = -1;
byte[] array = null;
byte[] array2 = null;
using MemoryStream memoryStream = new MemoryStream();
int num3;
int num4;
for (int num2 = 8; num2 + 8 <= png.Length; num2 = num4 + num3 + 4)
{
num3 = ReadInt(png, num2);
string text = Encoding.ASCII.GetString(png, num2 + 4, 4);
num4 = num2 + 8;
if (num3 < 0 || num4 + num3 > png.Length)
{
throw new InvalidDataException("PNG tronqué");
}
switch (text)
{
case "IHDR":
width = ReadInt(png, num4);
height = ReadInt(png, num4 + 4);
num = png[num4 + 9];
if (png[num4 + 8] == 8 && png[num4 + 12] == 0)
{
continue;
}
throw new NotSupportedException("PNG 8 bits non entrelacé attendu");
case "PLTE":
array = png.AsSpan(num4, num3).ToArray();
continue;
case "tRNS":
array2 = png.AsSpan(num4, num3).ToArray();
continue;
case "IDAT":
memoryStream.Write(png, num4, num3);
continue;
default:
continue;
case "IEND":
break;
}
break;
}
int num5 = num switch
{
0 => 1,
2 => 3,
3 => 1,
4 => 2,
6 => 4,
_ => throw new NotSupportedException($"type de couleur PNG {num}"),
};
if (width <= 0 || height <= 0)
{
throw new InvalidDataException("PNG sans en-tête");
}
if (num == 3 && array == null)
{
throw new InvalidDataException("PNG sans palette");
}
int num6 = width * num5;
byte[] array3 = new byte[(num6 + 1) * height];
memoryStream.Position = 0L;
using (ZLibStream zLibStream = new ZLibStream(memoryStream, CompressionMode.Decompress))
{
int num7;
for (int i = 0; i < array3.Length; i += num7)
{
num7 = zLibStream.Read(array3, i, array3.Length - i);
if (num7 <= 0)
{
throw new InvalidDataException("données PNG incomplètes");
}
}
}
byte[] array4 = new byte[num6 * height];
for (int j = 0; j < height; j++)
{
int num8 = array3[j * (num6 + 1)];
int num9 = j * (num6 + 1) + 1;
int num10 = j * num6;
int num11 = num10 - num6;
for (int k = 0; k < num6; k++)
{
int num12 = ((k >= num5) ? array4[num10 + k - num5] : 0);
int num13 = ((j > 0) ? array4[num11 + k] : 0);
int upLeft = ((j > 0 && k >= num5) ? array4[num11 + k - num5] : 0);
int num14 = num8 switch
{
0 => 0,
1 => num12,
2 => num13,
3 => (num12 + num13) / 2,
4 => Paeth(num12, num13, upLeft),
_ => throw new InvalidDataException($"filtre PNG {num8}"),
};
array4[num10 + k] = (byte)(array3[num9 + k] + num14);
}
}
if (num == 6)
{
return array4;
}
byte[] array5 = new byte[width * height * 4];
int num15 = 0;
int num16 = 0;
int num17 = 0;
while (num15 < width * height)
{
switch (num)
{
case 0:
array5[num17] = (array5[num17 + 1] = (array5[num17 + 2] = array4[num16]));
array5[num17 + 3] = byte.MaxValue;
break;
case 2:
array5[num17] = array4[num16];
array5[num17 + 1] = array4[num16 + 1];
array5[num17 + 2] = array4[num16 + 2];
array5[num17 + 3] = byte.MaxValue;
break;
case 3:
{
int num18 = array4[num16];
if (num18 * 3 + 2 >= array.Length)
{
throw new InvalidDataException("couleur hors palette");
}
array5[num17] = array[num18 * 3];
array5[num17 + 1] = array[num18 * 3 + 1];
array5[num17 + 2] = array[num18 * 3 + 2];
array5[num17 + 3] = ((array2 != null && num18 < array2.Length) ? array2[num18] : byte.MaxValue);
break;
}
case 4:
array5[num17] = (array5[num17 + 1] = (array5[num17 + 2] = array4[num16]));
array5[num17 + 3] = array4[num16 + 1];
break;
}
num15++;
num16 += num5;
num17 += 4;
}
return array5;
}
private static int ReadInt(byte[] bytes, int offset)
{
return (bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3];
}
private static int Paeth(int left, int up, int upLeft)
{
int num = left + up - upLeft;
int num2 = Math.Abs(num - left);
int num3 = Math.Abs(num - up);
int num4 = Math.Abs(num - upLeft);
if (num2 > num3 || num2 > num4)
{
if (num3 > num4)
{
return upLeft;
}
return up;
}
return left;
}
}
}
namespace SCTBuildings
{
internal class BuildingDefinition
{
public BuildType Type;
public BuildType Template;
public string NameFr;
public string NameEn;
public string DescriptionFr;
public string DescriptionEn;
public int MinTier = 1;
public (ResourceType Resource, int Quantity)[] Recipe;
public int Capacity;
public Color Tint = Color.white;
public Color IconColor = new Color(0.9f, 0.7f, 0.2f);
public Action<Build> OnSpawn;
public string Name => Lang.Pick(NameFr, NameEn);
public string Description => Lang.Pick(DescriptionFr, DescriptionEn);
}
public abstract class BuildingPlugin : BasePlugin
{
internal static BuildingDefinition Definition;
internal static ConfigEntry<bool> Enabled;
internal static ManualLogSource Logger;
public BuildType BuildingType => Definition.Type;
public string BuildingName => Definition.Name;
internal abstract BuildingDefinition CreateDefinition();
protected virtual void BindConfig()
{
}
public override void Load()
{
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected I4, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected I4, but got Unknown
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Expected O, but got Unknown
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Expected O, but got Unknown
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Expected I4, but got Unknown
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BasePlugin)this).Log;
Definition = CreateDefinition();
Enabled = ((BasePlugin)this).Config.Bind<bool>("Batiment", "Enabled", true, "Ajoute " + Definition.NameFr + " au menu de craft.");
BindConfig();
string text = Il2CppUtil.Guid((BasePlugin)(object)this);
BuildingStore.Name = $"building_{(int)Definition.Type}.json";
BuildingStore.OldPath = Path.Combine(Paths.BepInExRootPath, "SCTBuildings", $"{(int)Definition.Type}.json");
BuildingSprites.Load(((object)this).GetType().Assembly);
new Harmony(text).PatchAll(((object)this).GetType().Assembly);
CraftCosts.Install(new Harmony(text + ".craft"), text);
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Bâtiment ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Definition.NameFr);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" chargé (id ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>((int)Definition.Type);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", modèle ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<BuildType>(Definition.Template);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
}
log.LogInfo(val);
}
internal static bool Is(BuildType type)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (Definition != null)
{
return type == Definition.Type;
}
return false;
}
}
internal static class BuildingSprites
{
public static Sprite Icon;
public static Sprite World;
public static void Load(Assembly assembly)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
try
{
Icon = LoadPng(assembly, "sprites/icon.png", 24f);
World = LoadPng(assembly, "sprites/build.png", 48f);
}
catch (Exception ex)
{
ManualLogSource logger = BuildingPlugin.Logger;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sprites non chargés (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") : sprites temporaires utilisés");
}
logger.LogWarning(val);
}
if ((Object)(object)Icon == (Object)null)
{
Icon = Generated(BuildingPlugin.Definition.IconColor);
}
}
private static Sprite LoadPng(Assembly assembly, string resource, float pixelsPerUnit)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
using Stream stream = assembly.GetManifestResourceStream(resource);
if (stream == null)
{
return null;
}
byte[] array = new byte[stream.Length];
stream.Read(array, 0, array.Length);
Texture2D val = PngLoader.LoadTexture(array);
return Keep(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), pixelsPerUnit), val);
}
private static Sprite Generated(Color color)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_0119: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
{
filterMode = (FilterMode)0
};
Color[] array = (Color[])(object)new Color[1024];
Color val2 = Color.Lerp(color, Color.black, 0.55f);
Color val3 = Color.Lerp(color, Color.white, 0.45f);
for (int i = 0; i < 32; i++)
{
for (int j = 0; j < 32; j++)
{
int num = Math.Min(Math.Min(j, i), Math.Min(31 - j, 31 - i));
Color val4 = ((((j < 4 || j > 27) && (i < 4 || i > 27) && num < 2) || num < 2) ? Color.clear : ((num < 4) ? val2 : ((Math.Abs(i - 16) < 2 || Math.Abs(j - 16) < 2) ? val3 : color)));
array[j + i * 32] = val4;
}
}
val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
val.Apply(false);
return Keep(Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 32f), val);
}
private static Sprite Keep(Sprite sprite, Texture2D texture)
{
((Object)texture).hideFlags = (HideFlags)61;
((Object)sprite).hideFlags = (HideFlags)61;
return sprite;
}
}
internal static class BuildingRegistry
{
private static Build _prefab;
private static GameObject _holder;
public static Build Prefab => _prefab;
public static void Setup(BuildManager manager)
{
//IL_000e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Expected O, but got Unknown
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_0041: 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)
BuildingDefinition definition = BuildingPlugin.Definition;
List<BuildType> buildTypes = BuildMenu.BuildTypes;
if (!buildTypes.Contains(definition.Type))
{
buildTypes.Add(definition.Type);
}
if (!CraftMenu._craftingCosts.ContainsKey(definition.Type) && definition.Recipe != null)
{
CraftCosts.AddRecipe(definition.Type, definition.Recipe);
}
Build buildPrefab = manager.GetBuildPrefab(definition.Template);
if ((Object)(object)buildPrefab == (Object)null)
{
ManualLogSource logger = BuildingPlugin.Logger;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Modèle ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<BuildType>(definition.Template);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" introuvable : ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(definition.NameFr);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" désactivé");
}
logger.LogError(val);
return;
}
_holder = new GameObject("SCT " + definition.NameEn + " (modèle)");
_holder.SetActive(false);
_prefab = Object.Instantiate<Build>(buildPrefab, _holder.transform);
((Object)_prefab).name = definition.NameEn;
if ((Object)(object)BuildingSprites.World != (Object)null)
{
SpriteRenderer component = ((Component)_prefab).GetComponent<SpriteRenderer>();
if ((Object)(object)component != (Object)null)
{
component.sprite = BuildingSprites.World;
}
}
}
public static void Configure(Build build)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
BuildingDefinition definition = BuildingPlugin.Definition;
if (definition.Capacity > 0)
{
build.maxCapacity = definition.Capacity;
}
if ((Object)(object)BuildingSprites.World == (Object)null)
{
SpriteRenderer component = ((Component)build).GetComponent<SpriteRenderer>();
if ((Object)(object)component != (Object)null)
{
component.color = definition.Tint;
}
}
definition.OnSpawn?.Invoke(build);
}
}
[HarmonyPatch(typeof(BuildManager), "Awake")]
internal static class BuildingSetupPatch
{
private static void Postfix(BuildManager __instance)
{
Safe.Run("Bâtiment " + BuildingPlugin.Definition.NameFr + " (enregistrement)", delegate
{
BuildingRegistry.Setup(__instance);
});
}
}
[HarmonyPatch(typeof(BuildManager), "GetBuildPrefab")]
internal static class BuildingPrefabPatch
{
private static bool Prefix(BuildType buildType, ref Build __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (!BuildingPlugin.Is(buildType) || (Object)(object)BuildingRegistry.Prefab == (Object)null)
{
return true;
}
__result = BuildingRegistry.Prefab;
return false;
}
}
[HarmonyPatch(typeof(BuildManager), "SpawnBuild")]
internal static class BuildingSpawnPatch
{
private static void Postfix(BuildType buildType, Build __result)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (BuildingPlugin.Is(buildType) && (Object)(object)__result != (Object)null)
{
Safe.Run("Bâtiment " + BuildingPlugin.Definition.NameFr + " (pose)", delegate
{
BuildingRegistry.Configure(__result);
});
}
}
}
[HarmonyPatch(typeof(UpgradeManager), "IsBuildAvailable")]
[HarmonyPriority(800)]
internal static class BuildingAvailablePatch
{
private static void Postfix(UpgradeManager __instance, BuildType buildType, ref bool __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (BuildingPlugin.Is(buildType))
{
__result = BuildingPlugin.Enabled.Value && !Vanilla.Active && (Object)(object)BuildingRegistry.Prefab != (Object)null && __instance.Tier >= BuildingPlugin.Definition.MinTier;
}
}
}
[HarmonyPatch(typeof(SpriteManager), "GetBuildIconSprite")]
internal static class BuildingIconPatch
{
private static bool Prefix(BuildType key, ref Sprite __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if (!BuildingPlugin.Is(key))
{
return true;
}
__result = BuildingSprites.Icon;
return false;
}
}
[HarmonyPatch(typeof(SpriteManager), "GetBuildSprite")]
internal static class BuildingSpritePatch
{
private static bool Prefix(SpriteManager __instance, BuildType key, ref Sprite __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if (!BuildingPlugin.Is(key))
{
return true;
}
__result = BuildingSprites.World ?? __instance.GetBuildSprite(BuildingPlugin.Definition.Template);
return false;
}
}
[HarmonyPatch(typeof(CraftMenu), "UpdateSelectedCraftItem")]
internal static class BuildingDescriptionPatch
{
private static void Postfix(CraftMenu __instance, CraftItem craftItem)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)craftItem == (Object)null) && BuildingPlugin.Is(craftItem.buildType) && !((Object)(object)__instance.description == (Object)null))
{
BuildingDefinition definition = BuildingPlugin.Definition;
((TMP_Text)__instance.description).text = "<b>" + definition.Name + "</b>\n" + definition.Description;
}
}
}
[HarmonyPatch(typeof(BuildMenu), "Start")]
internal static class BuildingRadialPatch
{
private static void Prefix(BuildMenu __instance)
{
int count = BuildMenu.BuildTypes.Count;
if (__instance.numberOfSegments < count)
{
__instance.numberOfSegments = count;
}
}
}
[Serializable]
public class StoredBuild
{
public int x;
public int y;
public List<int> storage = new List<int>();
}
[Serializable]
public class BuildingSave
{
public List<StoredBuild> builds = new List<StoredBuild>();
public int inventory;
}
internal static class BuildingStore
{
public static string Name;
public static string OldPath;
private static bool _migrated;
public static BuildingSave State = new BuildingSave();
private static readonly JsonSerializerOptions Options = new JsonSerializerOptions
{
IncludeFields = true,
WriteIndented = true
};
public static string FilePath
{
get
{
if (!_migrated)
{
_migrated = true;
SaveSlotApi.Migrate(OldPath, Name);
}
return SaveSlotApi.PathOf(Name);
}
}
public static void Write()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
try
{
Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
File.WriteAllText(FilePath, JsonSerializer.Serialize(State, Options));
}
catch (Exception ex)
{
ManualLogSource logger = BuildingPlugin.Logger;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sauvegarde du bâtiment impossible : ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
logger.LogWarning(val);
}
}
public static BuildingSave Read()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
try
{
if (File.Exists(FilePath))
{
return JsonSerializer.Deserialize<BuildingSave>(File.ReadAllText(FilePath), Options) ?? new BuildingSave();
}
}
catch (Exception ex)
{
ManualLogSource logger = BuildingPlugin.Logger;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sauvegarde du bâtiment illisible : ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
logger.LogWarning(val);
}
return new BuildingSave();
}
public static void Delete()
{
State = new BuildingSave();
try
{
if (File.Exists(FilePath))
{
File.Delete(FilePath);
}
}
catch (Exception)
{
}
}
}
internal class SavedAside
{
public List<Build> Builds = new List<Build>();
public int Inventory;
}
[HarmonyPatch(typeof(SaveSystem), "SaveGame")]
internal static class BuildingSavePatch
{
private static void Prefix(out SavedAside __state)
{
SavedAside aside = new SavedAside();
Safe.Run("Bâtiment (sauvegarde)", delegate
{
SetAside(aside);
});
__state = aside;
}
private static void SetAside(SavedAside aside)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: 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_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Expected I4, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
BuildManager instance = BuildManager.Instance;
Player val = (((Object)(object)Game.Instance != (Object)null) ? Game.Instance.player : null);
if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null)
{
return;
}
BuildType type = BuildingPlugin.Definition.Type;
List<Build> builds = instance.builds;
List<StoredBuild> list = new List<StoredBuild>();
for (int num = builds.Count - 1; num >= 0; num--)
{
Build val2 = builds[num];
if (!((Object)(object)val2 == (Object)null) && BuildingPlugin.Is(val2.BuildType))
{
StoredBuild storedBuild = new StoredBuild();
Vector3Int position = val2.Position;
storedBuild.x = ((Vector3Int)(ref position)).x;
position = val2.Position;
storedBuild.y = ((Vector3Int)(ref position)).y;
StoredBuild storedBuild2 = storedBuild;
List<ResourceTypeQuantity> outputStorage = val2._outputStorage;
for (int i = 0; i < outputStorage.Count; i++)
{
storedBuild2.storage.Add((int)outputStorage[i].resourceType);
storedBuild2.storage.Add(outputStorage[i].quantity);
}
list.Add(storedBuild2);
aside.Builds.Add(val2);
builds.RemoveAt(num);
}
}
BuildDict builds2 = val._builds;
if (builds2 != null && ((Dictionary<BuildType, int>)(object)builds2).ContainsKey(type))
{
aside.Inventory = ((Dictionary<BuildType, int>)(object)builds2)[type];
((Dictionary<BuildType, int>)(object)builds2).Remove(type);
}
BuildingStore.State.builds = list;
BuildingStore.State.inventory = aside.Inventory;
BuildingStore.Write();
}
private static void Postfix(SavedAside __state)
{
if (__state == null)
{
return;
}
Safe.Run("Bâtiment (après sauvegarde)", delegate
{
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
BuildManager instance = BuildManager.Instance;
if ((Object)(object)instance != (Object)null)
{
foreach (Build build in __state.Builds)
{
instance.builds.Add(build);
}
}
Player val = (((Object)(object)Game.Instance != (Object)null) ? Game.Instance.player : null);
if ((Object)(object)val != (Object)null && __state.Inventory > 0)
{
((Dictionary<BuildType, int>)(object)val._builds)[BuildingPlugin.Definition.Type] = __state.Inventory;
}
});
}
}
[HarmonyPatch(typeof(SaveSystem), "LoadGame")]
internal static class BuildingLoadPatch
{
private static void Postfix()
{
Safe.Run("Bâtiment (chargement)", delegate
{
//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_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Invalid comparison between Unknown and I4
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
BuildManager instance = BuildManager.Instance;
if (!((Object)(object)instance == (Object)null))
{
BuildingSave buildingSave = (BuildingStore.State = BuildingStore.Read());
BuildType type = BuildingPlugin.Definition.Type;
Vector3Int val = default(Vector3Int);
bool flag = default(bool);
foreach (StoredBuild build in buildingSave.builds)
{
((Vector3Int)(ref val))..ctor(build.x, build.y, 0);
TileData tile = BlockManager.Instance.GetTile(val);
if (tile == null || (int)tile.tileType != 2)
{
ManualLogSource logger = BuildingPlugin.Logger;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(42, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(BuildingPlugin.Definition.NameFr);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" en ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(build.x);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(",");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(build.y);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" : case occupée, rendu à l'inventaire");
}
logger.LogWarning(val2);
buildingSave.inventory++;
}
else
{
Build val3 = instance.SpawnBuild(type, tile, val);
for (int i = 0; i + 1 < build.storage.Count; i += 2)
{
val3.AddResource((ResourceType)build.storage[i], build.storage[i + 1]);
}
}
}
Player val4 = (((Object)(object)Game.Instance != (Object)null) ? Game.Instance.player : null);
if ((Object)(object)val4 != (Object)null && buildingSave.inventory > 0)
{
((Dictionary<BuildType, int>)(object)val4._builds)[type] = (((Dictionary<BuildType, int>)(object)val4._builds).ContainsKey(type) ? ((Dictionary<BuildType, int>)(object)val4._builds)[type] : 0) + buildingSave.inventory;
}
}
});
}
}
[HarmonyPatch(typeof(SaveSystem), "DeleteGameFile")]
internal static class BuildingDeleteRunPatch
{
private static void Postfix()
{
BuildingStore.Delete();
}
}
[HarmonyPatch(typeof(SaveSystem), "DeleteSavedProgress")]
internal static class BuildingDeleteProgressPatch
{
private static void Postfix()
{
BuildingStore.Delete();
}
}
}
namespace SCTBuildings.BigChest
{
[BepInPlugin("sct.building.bigchest", "SCT Bâtiment - Grand coffre", "0.1.1")]
public class BigChestBuilding : BuildingPlugin
{
internal override BuildingDefinition CreateDefinition()
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
BuildingDefinition buildingDefinition = new BuildingDefinition();
buildingDefinition.Type = (BuildType)100;
buildingDefinition.Template = (BuildType)1;
buildingDefinition.NameFr = "Grand coffre";
buildingDefinition.NameEn = "Big chest";
buildingDefinition.DescriptionFr = "Un coffre quatre fois plus grand (1024 ressources).";
buildingDefinition.DescriptionEn = "A chest four times larger (1024 resources).";
buildingDefinition.MinTier = 1;
buildingDefinition.Recipe = new(ResourceType, int)[2]
{
((ResourceType)1, 16),
((ResourceType)3, 4)
};
buildingDefinition.Capacity = 1024;
buildingDefinition.Tint = new Color(1f, 0.82f, 0.4f);
buildingDefinition.IconColor = new Color(0.85f, 0.6f, 0.2f);
return buildingDefinition;
}
}
}