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.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using AssetBundleLoader;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ObjectLoader;
using SOD.Common.BepInEx;
using SOD.Common.Extensions;
using UnityEngine;
using UniverseLib;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CitiesV2")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7c267528a4ff8da9463e2b7def45b3e6b9de9486")]
[assembly: AssemblyProduct("CitiesV2")]
[assembly: AssemblyTitle("CitiesV2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
public class LoaderMethods : CitiesV2
{
public static void ReplaceFloorData(List<string> replacementFloors, string targetBuilding, int targetFloorSetting, int floorsAmount)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Expected O, but got Unknown
InteriorFloorSetting val = null;
string path = Path.Combine(CitiesV2.dir, "Floorplans\\");
Enumerator<BuildingPreset> enumerator = AssetLoader.Instance.allBuildingData.GetEnumerator();
bool flag = default(bool);
while (enumerator.MoveNext())
{
BuildingPreset current = enumerator.Current;
if (((Object)current).name.ToLower() == targetBuilding.ToLower())
{
val = current.floorLayouts[targetFloorSetting];
ManualLogSource log = PluginController<CitiesV2, IEmptyBindings>.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(37, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Found target building: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(targetBuilding);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" at setting: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(targetFloorSetting);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
}
log.LogInfo(val2);
break;
}
}
if (val == null)
{
return;
}
val.blueprints.Clear();
val.floorsWithThisSetting = floorsAmount;
foreach (string replacementFloor in replacementFloors)
{
val.blueprints.Add(new TextAsset(File.ReadAllText(Path.Combine(path, replacementFloor + ".json"))));
((Object)val.blueprints[replacementFloors.IndexOf(replacementFloor)]).name = replacementFloor;
CityData.Instance.floorData.Add(replacementFloor, JsonUtility.FromJson<FloorSaveData>(File.ReadAllText(Path.Combine(path, replacementFloor + ".json"))));
}
}
}
public class FloorLoaderConfig
{
public List<string>? floorNames { get; set; }
public string? targetBuilding { get; set; }
public int targetFloorConfig { get; set; }
public int floorsAmount { get; set; }
}
public class FloorLoader : CitiesV2
{
public static Dictionary<string, FloorSaveData> floorSaveDatas = new Dictionary<string, FloorSaveData>();
public static void Postfix()
{
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
bool flag2 = default(bool);
foreach (FloorLoaderConfig floorLoaderConfig in CitiesV2.floorLoaderConfigs)
{
string path = Path.Combine(CitiesV2.dir, "Floorplans\\");
bool flag = true;
foreach (string floorName in floorLoaderConfig.floorNames)
{
if (!File.Exists(Path.Combine(path, floorName + ".json")))
{
flag = false;
break;
}
}
if (flag)
{
LoaderMethods.ReplaceFloorData(floorLoaderConfig.floorNames, floorLoaderConfig.targetBuilding, floorLoaderConfig.targetFloorConfig, floorLoaderConfig.floorsAmount);
ManualLogSource log = PluginController<CitiesV2, IEmptyBindings>.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(50, 3, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Replaced floor data for ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(floorLoaderConfig.targetBuilding);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at setting ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(floorLoaderConfig.targetFloorConfig);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" with ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(floorLoaderConfig.floorNames.Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" floors.");
}
log.LogInfo(val);
}
}
}
}
[HarmonyPatch(typeof(Toolbox), "Start")]
public class BuildingLoader : CitiesV2
{
public static List<BuildingManifest> buildings = new List<BuildingManifest>();
public static List<AssetBundle> bundles = new List<AssetBundle>();
public static List<string> loaded = new List<string>();
public static void Postfix()
{
RoomLoader.LoadAll();
foreach (KeyValuePair<string, BuildingManifestBase> buildingManifest2 in CitiesV2.buildingManifests)
{
if (loaded.Contains(buildingManifest2.Key))
{
return;
}
BuildingManifest buildingManifest = LoadBuilding(buildingManifest2.Value, CitiesV2.dir, buildingManifest2.Key);
if (buildingManifest == null)
{
continue;
}
buildings.Add(buildingManifest);
PluginController<CitiesV2, IEmptyBindings>.Log.LogInfo((object)"Buildings have been cached");
foreach (Stairfix stairfix in buildingManifest2.Value.Stairfixes)
{
StairwellFix.toRun.Add(stairfix);
}
PluginController<CitiesV2, IEmptyBindings>.Log.LogInfo((object)"Stairfixes have been added.");
}
Enumerator<string, ScriptableObject> enumerator3 = Toolbox.Instance.resourcesCache[Il2CppType.Of<RoomConfiguration>()].Values.GetEnumerator();
while (enumerator3.MoveNext())
{
Enumerator<WallFrontage> enumerator4 = ((Il2CppObjectBase)enumerator3.Current).Cast<RoomConfiguration>().wallFrontage.GetEnumerator();
while (enumerator4.MoveNext())
{
WallFrontage current3 = enumerator4.Current;
current3.onlyIfBorderingOutside = true;
Enumerator<WallFrontageClass> enumerator5 = current3.insideFrontage.GetEnumerator();
while (enumerator5.MoveNext())
{
WallFrontageClass current4 = enumerator5.Current;
current3.outsideFrontage.Add(current4);
}
enumerator5 = current3.outsideFrontage.GetEnumerator();
while (enumerator5.MoveNext())
{
WallFrontageClass current5 = enumerator5.Current;
if (!current3.insideFrontage.Contains(current5))
{
current3.insideFrontage.Add(current5);
}
}
}
}
Enumerator<FurnitureCluster> enumerator6 = Toolbox.Instance.allFurnitureClusters.GetEnumerator();
while (enumerator6.MoveNext())
{
FurnitureCluster current6 = enumerator6.Current;
current6.limitToFloor = false;
current6.limitToFloorRange = false;
current6.allowedInOpenPlan = (AllowedOpenPlan)0;
}
enumerator3 = Toolbox.Instance.resourcesCache[Il2CppType.Of<FurnitureClass>()].Values.GetEnumerator();
while (enumerator3.MoveNext())
{
ScriptableObject current7 = enumerator3.Current;
((Il2CppObjectBase)current7).Cast<FurnitureClass>().limitToFloor = false;
((Il2CppObjectBase)current7).Cast<FurnitureClass>().limitToFloorRange = false;
((Il2CppObjectBase)current7).Cast<FurnitureClass>().requiresCeiling = false;
}
Enumerator<AddressPreset> enumerator7 = Toolbox.Instance.allAddressPresets.GetEnumerator();
while (enumerator7.MoveNext())
{
AddressPreset current8 = enumerator7.Current;
if (((Object)current8).name == "SyncClinic")
{
current8.baseScore = 1;
}
}
FloorLoader.Postfix();
FloorRegistration.Postfix();
PluginController<CitiesV2, IEmptyBindings>.Log.LogInfo((object)"Everything went according to plan");
}
public static BuildingManifest LoadBuilding(BuildingManifestBase manifest, string baseDir, string extraDir)
{
BuildingManifestBase manifest2 = manifest;
if (manifest2.hasBeenAdded)
{
return null;
}
Loader.TempChangePath(Path.Combine(baseDir, extraDir));
BuildingManifest buildingManifest = new BuildingManifest();
buildingManifest.preset = Loader.LoadFromJson<BuildingPreset>(Path.Combine(baseDir, extraDir, manifest2.BuildingPresetSO));
buildingManifest.assetBundle = BundleLoader.LoadBundle(Path.Combine(baseDir, extraDir, manifest2.BuildingAssetBundle), false, false);
bundles.Add(buildingManifest.assetBundle);
List<Object> list = buildingManifest.assetBundle.LoadAllAssets().ToList();
BuildingPreset preset = buildingManifest.preset;
buildingManifest.baseTexture = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingTexture)).Cast<Texture2D>();
buildingManifest.windowMap = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingWindowMap)).Cast<Texture2D>();
buildingManifest.addonMap = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingAddonMap)).Cast<Texture2D>();
buildingManifest.litMap = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingLitMap)).Cast<Texture2D>();
buildingManifest.unlitMap = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingUnlitMap)).Cast<Texture2D>();
buildingManifest.prefab = ((Il2CppObjectBase)list.Find((Object x) => x.name == manifest2.BuildingPrefab)).Cast<GameObject>();
buildingManifest.posOffset = manifest2.PosOffset;
preset.addonMap = buildingManifest.addonMap;
preset.windowMap = buildingManifest.windowMap;
preset.emissionMapLit = buildingManifest.litMap;
preset.emissionMapUnlit = buildingManifest.unlitMap;
preset.prefab = buildingManifest.prefab;
preset.tex = buildingManifest.baseTexture;
preset.captureMesh = ((Component)preset.prefab.transform.Find("Base")).GetComponent<MeshFilter>().sharedMesh;
Material material = ((Renderer)((Component)preset.prefab.transform.Find("Base")).GetComponent<MeshRenderer>()).material;
Material material2 = ((Renderer)((Component)((Il2CppObjectBase)Helpers.GetScriptableObject("OneFIfthAve", typeof(BuildingPreset))).Cast<BuildingPreset>().prefab.transform.Find("Base")).GetComponent<MeshRenderer>()).material;
material.shader = material2.shader;
((Object)preset.prefab).hideFlags = (HideFlags)32;
((Object)preset).hideFlags = (HideFlags)32;
preset.prefab.tag = "BuildingModel";
((Object)preset).name = ((SoCustomComparison)preset).presetName;
preset.CalculateMeshHeight();
IEnumerator enumerator = preset.prefab.transform.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
Transform val = ((Il2CppObjectBase)enumerator.Current).Cast<Transform>();
if (((Object)val).name.Contains("Base"))
{
((Component)val).tag = "BuildingModelLights";
((Component)val).gameObject.layer = 27;
}
}
}
finally
{
if (enumerator is IDisposable disposable)
{
disposable.Dispose();
}
}
if (File.Exists(Path.Combine(baseDir, extraDir, manifest2.CompiledWindowMap)))
{
preset.sortedWindows = WindowFloorPatch.Unpack(JsonSerializer.Deserialize<List<WindowFloorPatch>>(File.ReadAllText(Path.Combine(baseDir, extraDir, manifest2.CompiledWindowMap))));
}
if (preset.sortedWindows == null && (Object)(object)preset.windowMap != (Object)null)
{
preset.sortedWindows = new List<WindowUVFloor>();
preset.GenerateWindowData();
File.WriteAllText(Path.Combine(baseDir, extraDir, manifest2.CompiledWindowMap), JsonSerializer.Serialize(WindowFloorPatch.GeneratePatched(preset.sortedWindows), CitiesV2.serializerOptions));
}
if (File.Exists(Path.Combine(baseDir, extraDir, manifest2.CompiledAddonMap)))
{
preset.cableLinkPoints = EnumerableExtensions.ToListIl2Cpp<CableLinkPoint>((IEnumerable<CableLinkPoint>)JsonSerializer.Deserialize<List<CableLinkPoint>>(File.ReadAllText(Path.Combine(baseDir, extraDir, manifest2.CompiledAddonMap)), CitiesV2.serializerOptions));
}
if ((preset.cableLinkPoints == null || preset.cableLinkPoints.Count == 0) && (Object)(object)preset.addonMap != (Object)null)
{
preset.GenerateAddonData();
File.WriteAllText(Path.Combine(baseDir, extraDir, manifest2.CompiledAddonMap), JsonSerializer.Serialize(EnumerableExtensions.ToList<CableLinkPoint>(preset.cableLinkPoints), CitiesV2.serializerOptions));
}
Loader.RevertPath();
AssetLoader.Instance.allBuildingData.Add(preset);
return buildingManifest;
}
}
[Serializable]
public class WindowFloorPatch
{
[Serializable]
public class WindowBlockPatch
{
public float OriginPixelX { get; set; }
public float OriginPixelY { get; set; }
public float RectSizeX { get; set; }
public float RectSizeY { get; set; }
public float CentrePixelX { get; set; }
public float CentrePixelY { get; set; }
public float LocalMeshPositionLeftX { get; set; }
public float LocalMeshPositionLeftY { get; set; }
public float LocalMeshPositionLeftZ { get; set; }
public float LocalMeshPositionRightX { get; set; }
public float LocalMeshPositionRightY { get; set; }
public float LocalMeshPositionRightZ { get; set; }
public int Floor { get; set; }
public float SideX { get; set; }
public float SideY { get; set; }
public int Horizonal { get; set; }
}
public List<WindowBlockPatch> Back { get; set; }
public List<WindowBlockPatch> Front { get; set; }
public List<WindowBlockPatch> Left { get; set; }
public List<WindowBlockPatch> Right { get; set; }
public static List<WindowFloorPatch> GeneratePatched(List<WindowUVFloor> original)
{
List<WindowFloorPatch> list = new List<WindowFloorPatch>();
Enumerator<WindowUVFloor> enumerator = original.GetEnumerator();
while (enumerator.MoveNext())
{
WindowUVFloor current = enumerator.Current;
WindowFloorPatch windowFloorPatch = new WindowFloorPatch();
windowFloorPatch.Left = new List<WindowBlockPatch>();
windowFloorPatch.Right = new List<WindowBlockPatch>();
windowFloorPatch.Front = new List<WindowBlockPatch>();
windowFloorPatch.Back = new List<WindowBlockPatch>();
Enumerator<WindowUVBlock> enumerator2 = current.back.GetEnumerator();
while (enumerator2.MoveNext())
{
WindowUVBlock current2 = enumerator2.Current;
int floor = current2.floor;
current2.floor = floor + 1;
windowFloorPatch.Back.Add(GeneratePatched(current2));
}
enumerator2 = current.front.GetEnumerator();
while (enumerator2.MoveNext())
{
WindowUVBlock current3 = enumerator2.Current;
int floor = current3.floor;
current3.floor = floor + 1;
windowFloorPatch.Front.Add(GeneratePatched(current3));
}
enumerator2 = current.right.GetEnumerator();
while (enumerator2.MoveNext())
{
WindowUVBlock current4 = enumerator2.Current;
int floor = current4.floor;
current4.floor = floor + 1;
windowFloorPatch.Right.Add(GeneratePatched(current4));
}
enumerator2 = current.left.GetEnumerator();
while (enumerator2.MoveNext())
{
WindowUVBlock current5 = enumerator2.Current;
int floor = current5.floor;
current5.floor = floor + 1;
windowFloorPatch.Left.Add(GeneratePatched(current5));
}
list.Add(windowFloorPatch);
}
return list;
}
public static List<WindowUVFloor> Unpack(List<WindowFloorPatch> patched)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
List<WindowUVFloor> val = new List<WindowUVFloor>();
foreach (WindowFloorPatch item in patched)
{
WindowUVFloor val2 = new WindowUVFloor();
val2.left = new List<WindowUVBlock>();
val2.right = new List<WindowUVBlock>();
val2.front = new List<WindowUVBlock>();
val2.back = new List<WindowUVBlock>();
foreach (WindowBlockPatch item2 in item.Left)
{
val2.left.Add(Unpack(item2));
}
foreach (WindowBlockPatch item3 in item.Right)
{
val2.right.Add(Unpack(item3));
}
foreach (WindowBlockPatch item4 in item.Front)
{
val2.front.Add(Unpack(item4));
}
foreach (WindowBlockPatch item5 in item.Back)
{
val2.back.Add(Unpack(item5));
}
val.Add(val2);
}
return val;
}
public static WindowBlockPatch GeneratePatched(WindowUVBlock src)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: 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_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
return new WindowBlockPatch
{
OriginPixelX = src.originPixel.x,
OriginPixelY = src.originPixel.y,
RectSizeX = src.rectSize.x,
RectSizeY = src.rectSize.y,
CentrePixelX = src.centrePixel.x,
CentrePixelY = src.centrePixel.y,
LocalMeshPositionLeftX = src.localMeshPositionLeft.x,
LocalMeshPositionLeftY = src.localMeshPositionLeft.y,
LocalMeshPositionLeftZ = src.localMeshPositionLeft.z,
LocalMeshPositionRightX = src.localMeshPositionRight.x,
LocalMeshPositionRightY = src.localMeshPositionRight.y,
LocalMeshPositionRightZ = src.localMeshPositionRight.z,
Floor = src.floor,
SideX = src.side.x,
SideY = src.side.y,
Horizonal = src.horizonal
};
}
public static WindowUVBlock Unpack(WindowBlockPatch src)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: 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_0067: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
return new WindowUVBlock
{
originPixel = new Vector2(src.OriginPixelX, src.OriginPixelY),
rectSize = new Vector2(src.RectSizeX, src.RectSizeY),
centrePixel = new Vector2(src.CentrePixelX, src.CentrePixelY),
localMeshPositionLeft = new Vector3(src.LocalMeshPositionLeftX, src.LocalMeshPositionLeftY, src.LocalMeshPositionLeftZ),
localMeshPositionRight = new Vector3(src.LocalMeshPositionRightX, src.LocalMeshPositionRightY, src.LocalMeshPositionRightZ),
floor = src.Floor,
side = new Vector2(src.SideX, src.SideY),
horizonal = src.Horizonal
};
}
}
[Serializable]
public class BuildingManifestBase
{
[JsonIgnore]
public bool hasBeenAdded;
public string BuildingPresetSO { get; set; }
public string BuildingAssetBundle { get; set; }
public string BuildingPrefab { get; set; }
public string BuildingTexture { get; set; }
public string BuildingUnlitMap { get; set; }
public string BuildingLitMap { get; set; }
public string? BuildingWindowMap { get; set; }
public string? BuildingAddonMap { get; set; }
public float PosOffset { get; set; }
public string? CompiledWindowMap { get; set; }
public string? CompiledAddonMap { get; set; }
public List<Stairfix> Stairfixes { get; set; }
}
public class BuildingManifest
{
public BuildingPreset? preset;
public AssetBundle? assetBundle;
public GameObject? prefab;
public Texture2D? baseTexture;
public Texture2D? unlitMap;
public Texture2D? litMap;
public Texture2D? windowMap;
public Texture2D? addonMap;
public float posOffset;
public List<Stairfix>? Stairfixes;
public BuildingManifestBase? baseManifest;
}
[BepInPlugin("truedartt.citiesv2", "CitiesV2", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CitiesV2 : PluginController<CitiesV2>
{
public const string PluginGUID = "truedartt.citiesv2";
public const string PluginName = "CitiesV2";
public const string PluginVersion = "0.1.0";
protected static JsonSerializerOptions serializerOptions = new JsonSerializerOptions
{
AllowTrailingCommas = true,
WriteIndented = true,
MaxDepth = 256
};
protected static string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
protected static List<FloorLoaderConfig> floorLoaderConfigs = new List<FloorLoaderConfig>();
public static readonly Dictionary<string, BuildingManifestBase> buildingManifests = new Dictionary<string, BuildingManifestBase>();
public static readonly Dictionary<string, string> rooms = new Dictionary<string, string>();
public override void Load()
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Expected O, but got Unknown
PluginController<CitiesV2, IEmptyBindings>.Log.LogInfo((object)Path.Combine(dir, "LoaderConfigs.json"));
try
{
floorLoaderConfigs = JsonSerializer.Deserialize<List<FloorLoaderConfig>>(File.ReadAllText(Path.Combine(dir, "LoaderConfigs.json")), serializerOptions);
}
catch (Exception ex)
{
PluginController<CitiesV2, IEmptyBindings>.Log.LogError((object)ex);
}
try
{
buildingManifests.Add("DartTower", JsonSerializer.Deserialize<BuildingManifestBase>(File.ReadAllText(Path.Combine(dir, "DartTower", "DartTower_manifest.json"))));
}
catch (Exception ex2)
{
PluginController<CitiesV2, IEmptyBindings>.Log.LogError((object)ex2);
}
Loader.SetPath(dir);
rooms.Add("Terrace", Path.Combine(dir, "RoomConfigs"));
((PluginController<CitiesV2, IEmptyBindings>)(object)this).Harmony.PatchAll(Assembly.GetExecutingAssembly());
ManualLogSource log = PluginController<CitiesV2, IEmptyBindings>.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("CitiesV2");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
}
log.LogInfo(val);
}
}
public class FloorRegistration : CitiesV2
{
public static void Postfix()
{
PluginController<CitiesV2, IEmptyBindings>.Log.LogMessage((object)"Floor registration has begun.");
Dictionary<string, FloorSaveData> floorData = CityData.Instance.floorData;
foreach (BuildingManifest building in BuildingLoader.buildings)
{
Enumerator<InteriorFloorSetting> enumerator2 = building.preset.floorLayouts.GetEnumerator();
while (enumerator2.MoveNext())
{
InteriorFloorSetting current2 = enumerator2.Current;
Enumerator<TextAsset> enumerator3 = current2.blueprints.GetEnumerator();
while (enumerator3.MoveNext())
{
TextAsset current3 = enumerator3.Current;
if (!floorData.ContainsKey(((Object)current3).name))
{
floorData.Add(((Object)current3).name, Loader.LoadObject<FloorSaveData>(current3.text));
}
}
enumerator3 = current2.controlRoomVariants.GetEnumerator();
while (enumerator3.MoveNext())
{
TextAsset current4 = enumerator3.Current;
if (!floorData.ContainsKey(((Object)current4).name))
{
floorData.Add(((Object)current4).name, Loader.LoadObject<FloorSaveData>(current4.text));
}
}
}
enumerator2 = building.preset.basementLayouts.GetEnumerator();
while (enumerator2.MoveNext())
{
InteriorFloorSetting current5 = enumerator2.Current;
Enumerator<TextAsset> enumerator3 = current5.blueprints.GetEnumerator();
while (enumerator3.MoveNext())
{
TextAsset current6 = enumerator3.Current;
if (!floorData.ContainsKey(((Object)current6).name))
{
floorData.Add(((Object)current6).name, Loader.LoadObject<FloorSaveData>(current6.text));
}
}
enumerator3 = current5.controlRoomVariants.GetEnumerator();
while (enumerator3.MoveNext())
{
TextAsset current7 = enumerator3.Current;
if (!floorData.ContainsKey(((Object)current7).name))
{
floorData.Add(((Object)current7).name, Loader.LoadObject<FloorSaveData>(current7.text));
}
}
}
}
}
}
[HarmonyPatch(typeof(BuildingCreator), "Awake")]
public class BuildingRegistration : CitiesV2
{
public static void Postfix(BuildingCreator __instance)
{
foreach (BuildingManifest building in BuildingLoader.buildings)
{
__instance.buildingPresets.Add(building.preset);
}
}
}
public class RoomLoader : CitiesV2
{
public static List<string> loaded = new List<string>();
public static List<RoomConfiguration> roomConfigs = new List<RoomConfiguration>();
public static List<RoomTypePreset> presets = new List<RoomTypePreset>();
public static List<FiltersToAdd> filtersToAdd = new List<FiltersToAdd>();
public static void LoadAll()
{
foreach (KeyValuePair<string, string> room in CitiesV2.rooms)
{
if (loaded.Contains(room.Key))
{
break;
}
loaded.Add(room.Key);
LoadRoom(room.Key, room.Value);
}
}
public static void LoadRoom(string name, string dir)
{
_ = Toolbox.Instance.resourcesCache;
RoomConfiguration val = Loader.LoadFromJson<RoomConfiguration>(Path.Combine(dir, name, name + "_config.json"));
RoomClassPreset val2 = ScriptableObject.CreateInstance<RoomClassPreset>();
((SoCustomComparison)val2).presetName = name;
((Object)val2).name = name;
Toolbox.Instance.resourcesCache[Il2CppType.Of<RoomClassPreset>()].Add(((Object)val2).name, (ScriptableObject)(object)val2);
RoomTypePreset val4 = (val.roomType = Loader.LoadFromJson<RoomTypePreset>(Path.Combine(dir, name, name + "_preset.json")));
val.roomClass = val2;
val.openPlanRoom = val4;
val.debugRoom = val;
((Object)val4).name = name;
((Object)val).name = name;
val.steps = ((Il2CppObjectBase)Helpers.GetScriptableObject("Hallway", typeof(RoomConfiguration))).Cast<RoomConfiguration>().steps;
FiltersToAdd filtersToAdd = Loader.LoadFromJson<FiltersToAdd>(Path.Combine(dir, name, name + "_filters.json"));
foreach (RoomTypeFilter filter in filtersToAdd.Filters)
{
filter.roomClasses.Add(val2);
}
foreach (AddressPreset address in filtersToAdd.Addresses)
{
address.roomConfig.Add(val);
}
roomConfigs.Add(val);
presets.Add(val4);
if (filtersToAdd.MaterialGroups.Count == 0 && filtersToAdd.Clusters.Count == 0 && filtersToAdd.BasicFurniture.Count == 0)
{
return;
}
RoomTypeFilter val5 = ((Il2CppObjectBase)ScriptableObject.CreateInstance(Il2CppType.Of<RoomTypeFilter>())).Cast<RoomTypeFilter>();
((SoCustomComparison)val5).presetName = name;
((Object)val5).name = name;
val5.roomClasses.Add(val2);
Toolbox.Instance.resourcesCache[Il2CppType.Of<RoomTypeFilter>()].Add(((Object)val5).name, (ScriptableObject)(object)val5);
HashSet<FurniturePreset> val6 = new HashSet<FurniturePreset>();
foreach (FurniturePreset item in filtersToAdd.BasicFurniture)
{
item.allowedRoomFilters.Add(val5);
val6.Add(item);
}
foreach (MaterialGroupPreset materialGroup in filtersToAdd.MaterialGroups)
{
materialGroup.allowedRoomFilters.Add(val5);
}
foreach (FurnitureCluster cluster in filtersToAdd.Clusters)
{
cluster.allowedRoomFilters.Add(val5);
cluster.enableDebug = true;
}
RoomLoader.filtersToAdd.Add(filtersToAdd);
Toolbox.Instance.furnitureRoomTypeRef.Add(val2, val6);
}
}
[Serializable]
public class FiltersToAdd
{
public List<RoomTypeFilter> Filters { get; set; } = new List<RoomTypeFilter>();
public List<FurniturePreset> BasicFurniture { get; set; } = new List<FurniturePreset>();
public List<FurnitureCluster> Clusters { get; set; } = new List<FurnitureCluster>();
public List<MaterialGroupPreset> MaterialGroups { get; set; } = new List<MaterialGroupPreset>();
public List<AddressPreset> Addresses { get; set; } = new List<AddressPreset>();
}
[HarmonyPatch(typeof(Player), "PrepForStart")]
public class StairwellFix : CitiesV2
{
[Serializable]
public class NodePair
{
public Vector2Int nodeOne { get; set; }
public Vector2Int nodeTwo { get; set; }
}
public static List<Stairfix> toRun = new List<Stairfix>();
public static void Postfix()
{
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: Expected O, but got Unknown
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected O, but got Unknown
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Expected O, but got Unknown
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
PluginController<CitiesV2, IEmptyBindings>.Log.LogMessage((object)"Fixing Stair connections...");
bool flag = default(bool);
foreach (BuildingManifest building in BuildingLoader.buildings)
{
Enumerator<NewBuilding> enumerator2 = HighlanderSingleton<CityBuildings>.Instance.buildingDirectory.GetEnumerator();
while (enumerator2.MoveNext())
{
NewBuilding current2 = enumerator2.Current;
if ((SoCustomComparison)(object)current2.preset != (SoCustomComparison)(object)building.preset)
{
continue;
}
IEnumerator enumerator3 = ((Component)current2).gameObject.transform.GetEnumerator();
try
{
while (enumerator3.MoveNext())
{
Transform val = ((Il2CppObjectBase)enumerator3.Current).Cast<Transform>();
if (!(((Object)val).name != ((Object)building.preset.prefab).name + "(Clone)"))
{
ManualLogSource log = PluginController<CitiesV2, IEmptyBindings>.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("OG position ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Vector3>(val.position);
}
log.LogInfo(val2);
val.position = new Vector3(val.position.x, val.position.y + building.posOffset, val.position.z);
ManualLogSource log2 = PluginController<CitiesV2, IEmptyBindings>.Log;
val2 = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("NEW position ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Vector3>(val.position);
}
log2.LogInfo(val2);
}
}
}
finally
{
if (enumerator3 is IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
foreach (Stairfix item in toRun)
{
ManualLogSource log3 = PluginController<CitiesV2, IEmptyBindings>.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Fixing: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(item.floorPresetIndex);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(floorIndex) at ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(item.preset);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
}
log3.LogInfo(val2);
FixStairwell(item);
}
}
public static Vector2Int CalculatePos(Vector2Int pos, int rotation, int grid = 21)
{
//IL_002d: 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_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
rotation %= 4;
return (Vector2Int)(rotation switch
{
1 => new Vector2Int(grid - 1 - ((Vector2Int)(ref pos)).y, ((Vector2Int)(ref pos)).x),
2 => new Vector2Int(grid - 1 - ((Vector2Int)(ref pos)).x, grid - 1 - ((Vector2Int)(ref pos)).y),
3 => new Vector2Int(((Vector2Int)(ref pos)).y, grid - 1 - ((Vector2Int)(ref pos)).x),
_ => pos,
});
}
public static void FixStairwell(Stairfix stairfix)
{
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
List<NewBuilding> list = new List<NewBuilding>();
new List<NewFloor>();
BuildingPreset val = ((Il2CppObjectBase)Toolbox.Instance.resourcesCache[Il2CppType.Of<BuildingPreset>()][stairfix.preset]).Cast<BuildingPreset>();
List<string> list2 = new List<string>();
if (stairfix.isBasement)
{
Enumerator<TextAsset> enumerator = val.basementLayouts[stairfix.floorPresetIndex].blueprints.GetEnumerator();
while (enumerator.MoveNext())
{
TextAsset current = enumerator.Current;
list2.Add(((Object)current).name);
}
enumerator = val.basementLayouts[stairfix.floorPresetIndex].controlRoomVariants.GetEnumerator();
while (enumerator.MoveNext())
{
TextAsset current2 = enumerator.Current;
list2.Add(((Object)current2).name);
}
}
else
{
Enumerator<TextAsset> enumerator = val.floorLayouts[stairfix.floorPresetIndex].blueprints.GetEnumerator();
while (enumerator.MoveNext())
{
TextAsset current3 = enumerator.Current;
list2.Add(((Object)current3).name);
}
enumerator = val.floorLayouts[stairfix.floorPresetIndex].controlRoomVariants.GetEnumerator();
while (enumerator.MoveNext())
{
TextAsset current4 = enumerator.Current;
list2.Add(((Object)current4).name);
}
}
Enumerator<NewBuilding> enumerator2 = HighlanderSingleton<CityBuildings>.Instance.buildingDirectory.GetEnumerator();
while (enumerator2.MoveNext())
{
NewBuilding current5 = enumerator2.Current;
if (((Object)current5.preset).name == stairfix.preset)
{
list.Add(current5);
}
}
foreach (NewBuilding item in list)
{
int rotations = item.rotations;
List<NodePair> list3 = new List<NodePair>();
foreach (NodePair stairConnector in stairfix.stairConnectors)
{
list3.Add(new NodePair
{
nodeOne = CalculatePos(stairConnector.nodeOne, rotations),
nodeTwo = CalculatePos(stairConnector.nodeTwo, rotations)
});
}
Enumerator<int, NewFloor> enumerator5 = item.floors.Values.GetEnumerator();
while (enumerator5.MoveNext())
{
NewFloor current8 = enumerator5.Current;
if (!list2.Contains(current8.floorName))
{
continue;
}
Dictionary<NodePair, (NewNode, NewNode)> dictionary = new Dictionary<NodePair, (NewNode, NewNode)>();
foreach (NodePair item2 in list3)
{
dictionary.Add(item2, default((NewNode, NewNode)));
}
Enumerator<NewAddress> enumerator6 = current8.addresses.GetEnumerator();
while (enumerator6.MoveNext())
{
Enumerator<NewNode> enumerator7 = ((NewGameLocation)enumerator6.Current).nodes.GetEnumerator();
while (enumerator7.MoveNext())
{
NewNode current10 = enumerator7.Current;
foreach (NodePair item3 in list3)
{
if (item3.nodeOne == current10.floorCoord)
{
dictionary[item3] = (current10, dictionary[item3].Item2);
}
else if (item3.nodeTwo == current10.floorCoord)
{
dictionary[item3] = (dictionary[item3].Item1, current10);
}
}
}
}
foreach (var value in dictionary.Values)
{
value.Item1.AddAccessToOtherNode(value.Item2, true, true, (AccessType)4, true);
}
}
}
}
}
[Serializable]
public class Stairfix
{
public List<StairwellFix.NodePair> stairConnectors { get; set; }
public string preset { get; set; }
public int floorPresetIndex { get; set; }
public bool isBasement { get; set; }
}
[HarmonyPatch(typeof(Elevator), "UpdateCables")]
public class ElevatorFix
{
public static bool Prefix(Elevator __instance)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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)
if (__instance.top != null && (Object)(object)__instance.cable1 != (Object)null)
{
float num = __instance.top.position.y + PathFinder.Instance.tileSize.z - __instance.cable1.localPosition.y;
float num2 = __instance.bottom.position.y + PathFinder.Instance.tileSize.z - __instance.cable1.localPosition.y;
__instance.cable1.localScale = new Vector3(1f, num - num2 + 0.5f, 1f);
__instance.cable2.localScale = new Vector3(1f, num - num2 + 0.5f, 1f);
}
return false;
}
}