Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Railroads v0.1.9
plugins/Railroads/Railroads.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Blackforge.Hot; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 Blackforge { public static class Bodies { private const float MissingFor = 3f; private static readonly Dictionary<ZDOID, float> missingSince = new Dictionary<ZDOID, float>(); private static float nextCheck; private static string ReportFile => Path.Combine(Paths.BepInExRootPath, "rail-bodies.txt"); public static void Reset() { missingSince.Clear(); nextCheck = 0f; } private static IEnumerable<ZDOID> Parts(ZDO loco) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return ((IEnumerable<ZDOID>)(object)new ZDOID[1] { loco.m_uid }).Concat(Train.WagonIds(loco)); } public static void Report() { //IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00f0: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); Player localPlayer = Player.m_localPlayer; Vector3 me = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.position : Vector3.zero); Vector3 val = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetReferencePosition() : me); stringBuilder.Append($"time {Time.time:0.0}, player at {Point(me)}, reference {Point(val)}, session {ZDOMan.GetSessionID()}, rail in sync {RailPlugin.InSync}\n"); foreach (ZDO item in Train.Trains().OrderBy(delegate(ZDO l) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = l.GetPosition() - me; return ((Vector3)(ref val2)).sqrMagnitude; })) { stringBuilder.Append($"train {item.m_uid}, {Train.WagonIds(item).Count} wagons\n"); foreach (ZDOID item2 in Parts(item)) { stringBuilder.Append(" ").Append(Describe(item2, me, val)).Append('\n'); } } File.WriteAllText(ReportFile, stringBuilder.ToString()); } public static string Describe(ZDOID id, Vector3 me, Vector3 center) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO == null) { return $"{id}: no saved data on this machine"; } Vector3 position = zDO.GetPosition(); Vector2s zone = ZoneSystem.GetZone(position); ZNetView val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zDO) : null); string arg = "no object"; if ((Object)(object)val != (Object)null) { Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); int num = componentsInChildren.Count((Renderer r) => r.enabled && ((Component)r).gameObject.activeInHierarchy); arg = $"object at {Point(((Component)val).transform.position)}, {Vector3.Distance(((Component)val).transform.position, position):0.0} m from saved, active {((Component)val).gameObject.activeInHierarchy}, valid {val.IsValid()}, renderers {num} of {componentsInChildren.Length} on"; } string text = ((zDO.GetPrefab() == Train.LocomotiveHash) ? "locomotive" : "wagon"); return string.Format("{0} {1}: owner {2}{3}, in use {4}, saved at {5}, ", text, id, zDO.GetOwner(), zDO.IsOwner() ? " me" : "", zDO.GetInt(ZDOVars.s_inUse, 0), Point(position)) + $"{Vector3.Distance(position, me):0} m from the player, zone {zone.x},{zone.y} active {ZNetScene.InActiveArea(position, center)} loaded {ZoneSystem.instance.IsZoneLoaded(position)}, " + $"created {zDO.Created}, {arg}"; } public static void Heal() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) if (Time.time < nextCheck || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsDedicated() || (Object)(object)Player.m_localPlayer == (Object)null) { return; } nextCheck = Time.time + 1f; Vector3 position = ((Component)Player.m_localPlayer).transform.position; Vector3 referencePosition = ZNet.instance.GetReferencePosition(); HashSet<ZDOID> seen = new HashSet<ZDOID>(); foreach (ZDO item in Train.Trains()) { foreach (ZDOID item2 in Parts(item)) { ZDO zDO = ZDOMan.instance.GetZDO(item2); if (zDO == null) { continue; } Vector3 position2 = zDO.GetPosition(); if (!ZNetScene.InActiveArea(position2, referencePosition) || !ZoneSystem.instance.IsZoneLoaded(position2) || (Object)(object)ZNetScene.instance.FindInstance(zDO) != (Object)null) { continue; } seen.Add(item2); if (!missingSince.TryGetValue(item2, out var value)) { missingSince[item2] = Time.time; } else if (!(Time.time - value < 3f)) { if (!zDO.Created) { RailPlugin.Log.LogInfo((object)$"rail: a train body waits for the scene for {Time.time - value:0} s: {Describe(item2, position, referencePosition)}"); missingSince[item2] = Time.time; } else { RailPlugin.Log.LogWarning((object)$"rail: a train body has no object for {Time.time - value:0} s, it is built again: {Describe(item2, position, referencePosition)}"); zDO.Created = false; missingSince[item2] = Time.time; } } } } foreach (ZDOID item3 in missingSince.Keys.Where((ZDOID id) => !seen.Contains(id)).ToList()) { missingSince.Remove(item3); } } private static string Point(Vector3 p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) return string.Format(CultureInfo.InvariantCulture, "{0:0.0} {1:0.0} {2:0.0}", p.x, p.y, p.z); } } public class RailCargo : MonoBehaviour { public static readonly float[] Stages = new float[4] { 0.01f, 25f, 50f, 75f }; public GameObject[] m_stages = (GameObject[])(object)new GameObject[0]; private Container m_container; private float m_next; private void Awake() { m_container = ((Component)this).GetComponent<Container>(); } private void Update() { if (Time.time < m_next || (Object)(object)m_container == (Object)null || m_container.GetInventory() == null) { return; } m_next = Time.time + 1f; float num = m_container.GetInventory().SlotsUsedPercentage(); for (int i = 0; i < m_stages.Length && i < Stages.Length; i++) { if (m_stages[i].activeSelf != num >= Stages[i]) { m_stages[i].SetActive(num >= Stages[i]); } } } } public static class Carry { private const float Reach = 8f; private static Transform ride; private static Vector3 spot; public static void Before() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).IsTeleporting()) { ride = null; return; } if (((Character)localPlayer).IsOnGround()) { Rigidbody lastGroundBody = ((Character)localPlayer).m_lastGroundBody; ride = (((Object)(object)lastGroundBody != (Object)null && ((Object)(object)((Component)lastGroundBody).GetComponent<RailBody>() != (Object)null || (Object)(object)((Component)lastGroundBody).GetComponent<FlatbedDeck>() != (Object)null)) ? ((Component)lastGroundBody).transform : null); } if (!((Object)(object)ride == (Object)null)) { Vector3 val = ride.position - ((Component)localPlayer).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > 64f)) { spot = ride.InverseTransformPoint(((Component)localPlayer).transform.position); return; } } ride = null; } public static void After() { //IL_0022: 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_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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0052: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)ride == (Object)null) && !((Object)(object)localPlayer == (Object)null)) { Vector3 val = ride.TransformPoint(spot) - ((Component)localPlayer).transform.position; if (!(val == Vector3.zero)) { Transform transform = ((Component)localPlayer).transform; transform.position += val; ((Character)localPlayer).m_body.position = ((Component)localPlayer).transform.position; } } } public static void Reset() { ride = null; } } public static class LocoLayout { public const float Lift = 0.9f; public static readonly Vector3 BigAxle = new Vector3(0f, 1.19f, -1.8f); public const float BigRadius = 0.85f; public const float Crank = 0.28f; public const float MainRod = 1.2f; public const float RodX = 0.9f; public const float MainX = 1f; public const float Eccentric = 0.12f; public const float EccentricRod = 1.5f; public const float ValveX = 1.16f; public const float ValveY = 1.3f; public const float CylinderFront = 0.5f; public static readonly Vector3 Seat = new Vector3(0f, 2.85f, -2.45f); public static readonly Vector3 Chimney = new Vector3(0f, 5.25f, 1.45f); public static readonly Vector3 Lever = new Vector3(0.72f, 2.46f, -1.45f); public static readonly Vector3 SpeedLever = new Vector3(-0.72f, 2.46f, -1.45f); public static readonly Vector3 Panel = new Vector3(0f, 3.45f, -0.925f); public static readonly Vector3 PanelSize = new Vector3(1f, 0.42f, 0.04f); public static readonly Vector3 Firebox = new Vector3(0f, 2.4f, 0.37f); public static readonly Vector3 FireDoor = new Vector3(0.8f, 2.53f, 0.37f); public static readonly Vector3 FireGlow = new Vector3(0.95f, 2.6f, 0.37f); public static readonly Vector3[] Cores = (Vector3[])(object)new Vector3[4] { new Vector3(0.6f, 2.42f, -0.43f), new Vector3(0.6f, 2.42f, 1.17f), new Vector3(-0.6f, 2.42f, -0.43f), new Vector3(-0.6f, 2.42f, 1.17f) }; } public class RailDrive : MonoBehaviour { private static readonly float[] Sides = new float[2] { 1f, -1f }; private static readonly float[] Phases = new float[2] { 0f, 90f }; public RailMotion m_motion; public int m_axle; public Transform[] m_mainRods = (Transform[])(object)new Transform[2]; public Transform[] m_crossheads = (Transform[])(object)new Transform[2]; public Transform[] m_eccentricRods = (Transform[])(object)new Transform[2]; public Transform[] m_valveRods = (Transform[])(object)new Transform[2]; public ParticleSystem[] m_steam = (ParticleSystem[])(object)new ParticleSystem[2]; private readonly int[] m_strokes = new int[2] { -1, -1 }; private void LateUpdate() { if (!((Object)(object)m_motion == (Object)null)) { float num = m_motion.Angle(m_axle); for (int i = 0; i < 2; i++) { Place(i, num + Phases[i]); } } } private static Vector3 Around(float angle, float radius) { //IL_0000: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) return LocoLayout.BigAxle + Quaternion.Euler(angle, 0f, 0f) * new Vector3(0f, 0f, radius); } private void Place(int i, float angle) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) float num = Sides[i]; Vector3 val = Around(angle, 0.28f); float num2 = val.y - LocoLayout.BigAxle.y; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, LocoLayout.BigAxle.y, val.z + Mathf.Sqrt(1.44f - num2 * num2)); Aim(m_mainRods[i], num * 1f, val, val2); Put(m_crossheads[i], num * 0.9f, val2); Vector3 val3 = Around(angle + 90f, 0.12f); float num3 = 1.3f - val3.y; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(0f, 1.3f, val3.z + Mathf.Sqrt(2.25f - num3 * num3)); Aim(m_eccentricRods[i], num * 1.16f, val3, val4); Put(m_valveRods[i], num * 1.16f, val4); int num4 = Mathf.FloorToInt(Mathf.Repeat(angle, 360f) / 180f); if (num4 != m_strokes[i]) { if (m_strokes[i] >= 0 && m_motion.Speed > 0.3f) { Puff(i, num); } m_strokes[i] = num4; } } private static void Put(Transform part, float x, Vector3 at) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) if ((Object)(object)part != (Object)null) { part.localPosition = new Vector3(x, at.y, at.z); } } private static void Aim(Transform rod, float x, Vector3 from, Vector3 to) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) if ((Object)(object)rod != (Object)null) { rod.localPosition = new Vector3(x, from.y, from.z); rod.localRotation = Quaternion.LookRotation(new Vector3(0f, to.y - from.y, to.z - from.z), Vector3.up); } } private void Puff(int i, float side) { //IL_0030: 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_0045: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00b1: 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) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) ParticleSystem val = m_steam[i]; if (!((Object)(object)val == (Object)null)) { float num = Mathf.Clamp01(m_motion.Speed / 10f); Vector3 val2 = ((Component)this).transform.rotation * new Vector3(side, -0.3f, 0.2f); int num2 = 3 + Mathf.RoundToInt(num * 4f); for (int j = 0; j < num2; j++) { EmitParams val3 = default(EmitParams); ((EmitParams)(ref val3)).position = ((Component)val).transform.position; ((EmitParams)(ref val3)).applyShapeToPosition = false; ((EmitParams)(ref val3)).velocity = val2 * Random.Range(0.8f, 1.6f) + Random.insideUnitSphere * 0.3f; EmitParams val4 = val3; val.Emit(val4, 1); } } } } public static class Flatbed { [HarmonyPatch(typeof(ZDOMan), "AddIfPortal")] private static class Added { private static void Postfix(ZDOMan __instance, ZDO zdo) { if (__instance == seeded) { Index(zdo); } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] private static class Destroyed { private static void Prefix(ZDOMan __instance, ZDOID uid) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (__instance == seeded) { Forget(uid); } } } [HarmonyPatch(typeof(Player), "PieceRayTest")] private static class AimAtDeck { private static void Postfix(Player __instance, ref bool __result, ref Vector3 point, ref Vector3 normal, ref Piece piece, ref Heightmap heightmap, ref Collider waterSurface, bool water) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_00c3: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) aim = 0L; aimAt = null; if (__result || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)GameCamera.instance == (Object)null) { return; } Transform transform = ((Component)GameCamera.instance).transform; int num = (water ? __instance.m_placeWaterRayMask : __instance.m_placeRayMask); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(transform.position, transform.forward, ref val, 50f, num)) { return; } Transform deck; long num2 = DeckOf(((RaycastHit)(ref val)).collider, out deck); if (num2 != 0L) { float num3 = __instance.m_maxPlaceDistance; Piece val2 = (((Object)(object)__instance.m_placementGhost != (Object)null) ? __instance.m_placementGhost.GetComponent<Piece>() : null); if ((Object)(object)val2 != (Object)null) { num3 += (float)val2.m_extraPlacementDistance; } if (!(Vector3.Distance(((Character)__instance).m_eye.position, ((RaycastHit)(ref val)).point) >= num3)) { point = ((RaycastHit)(ref val)).point; normal = ((RaycastHit)(ref val)).normal; piece = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>(); heightmap = null; waterSurface = null; aim = num2; aimAt = deck; __result = true; } } } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static class TurnWithDeck { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo euler = AccessTools.Method(typeof(Quaternion), "Euler", new Type[3] { typeof(float), typeof(float), typeof(float) }, (Type[])null); MethodInfo turn = AccessTools.Method(typeof(Flatbed), "GhostTurn", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, euler)) { instruction.operand = turn; } yield return instruction; } } private static void Prefix(Player __instance) { GameObject placementGhost = __instance.m_placementGhost; Piece val = (((Object)(object)placementGhost != (Object)null) ? placementGhost.GetComponent<Piece>() : null); bool flag = (Object)(object)val != (Object)null && aim != 0L && ((Settings.DeckSmelters && IsSmelter(placementGhost)) || (Settings.DeckFires && IsFire(placementGhost))); if (flag && val.m_notOnWood) { val.m_notOnWood = false; onWood = val; } else if (!flag && (Object)(object)onWood != (Object)null && (Object)(object)onWood == (Object)(object)val) { val.m_notOnWood = true; onWood = null; } } private static void Postfix(Player __instance) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) refusal = null; GameObject placementGhost = __instance.m_placementGhost; if (aim != 0L && !((Object)(object)aimAt == (Object)null) && !((Object)(object)placementGhost == (Object)null) && placementGhost.activeSelf) { refusal = Refusal(placementGhost); if (refusal != null) { __instance.m_placementStatus = (PlacementStatus)1; __instance.SetPlacementGhostValid(false); } } } } private enum Fit { Inside, Past, TooHigh } [HarmonyPatch(typeof(Player), "TryPlacePiece")] private static class SayWhy { private static void Postfix(Player __instance, bool __result) { if (!__result && refusal != null && aim != 0L) { ((Character)__instance).Message((MessageType)2, refusal, 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(Player), "PlacePiece")] private static class Placed { private static void Prefix(Player __instance, Vector3 pos) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0060: 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_008b: Unknown result type (might be due to invalid IL or missing references) placing = 0L; placingAt = null; if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && aim != 0L && !((Object)(object)aimAt == (Object)null) && refusal == null) { Vector3 val = aimAt.InverseTransformPoint(pos); if (!(Mathf.Abs(val.x) > 2f + Settings.DeckReachLeftRight + 0.01f) && !(Mathf.Abs(val.z) > 3f + Settings.DeckReachFrontBack + 0.01f) && !(val.y < 0.5f) && !(val.y > 1.5f + Settings.DeckHeight + 0.5f)) { placing = aim; placingAt = aimAt; } } } private static void Finalizer() { placing = 0L; placingAt = null; } } [HarmonyPatch(typeof(ZNetView), "Awake")] private static class Arrived { private static void Postfix(ZNetView __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) ZDO zdo = __instance.m_zdo; if (zdo == null) { return; } try { if (Flatbed.placing != 0L) { long placing = Flatbed.placing; Transform placingAt = Flatbed.placingAt; Flatbed.placing = 0L; Flatbed.placingAt = null; if ((Object)(object)placingAt != (Object)null && zdo.IsOwner() && (Object)(object)((Component)__instance).GetComponent<Piece>() != (Object)null) { zdo.Set("bf_deck", placing); zdo.Set("bf_deck_pos", placingAt.InverseTransformPoint(((Component)__instance).transform.position)); zdo.Set("bf_deck_rot", Quaternion.Inverse(placingAt.rotation) * ((Component)__instance).transform.rotation); } } if (zdo.GetLong(OnHash, 0L) != 0L) { Attach(__instance); } } catch (Exception arg) { if (!failed) { failed = true; RailPlugin.Log.LogWarning((object)$"rail flatbed: a piece could not be put on its deck: {arg}"); } } } } [HarmonyPatch(typeof(Player), "FindHoverObject")] private static class UseWhatRides { private static void Postfix(Player __instance, ref GameObject hover) { //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) if ((Object)(object)hover == (Object)null || (Object)(object)hover.GetComponent<FlatbedDeck>() == (Object)null) { return; } RaycastHit[] raycastHoverHits = __instance.m_raycastHoverHits; for (int i = 0; i < raycastHoverHits.Length; i++) { RaycastHit val = raycastHoverHits[i]; Collider collider = ((RaycastHit)(ref val)).collider; if ((Object)(object)collider != (Object)null && (Object)(object)collider.attachedRigidbody != (Object)null && (Object)(object)((Component)collider.attachedRigidbody).gameObject == (Object)(object)hover) { hover = ((Component)collider).gameObject; break; } } } } [HarmonyPatch(typeof(Player), "RemovePiece")] private static class Removing { private static void Prefix() { removing = true; } private static void Finalizer() { removing = false; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] private static class KeepLoaded { private static void Postfix(Player __instance, Piece piece, ref bool __result) { if (removing && __result && !((Object)(object)piece == (Object)null)) { RailFlatbed component = ((Component)piece).GetComponent<RailFlatbed>(); if ((Object)(object)component != (Object)null && Count(component.DeckKey) > 0) { ((Character)__instance).Message((MessageType)2, "Remove what is built on it first", 0, (Sprite)null, false); __result = false; } } } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] private static class NoHits { private static bool Prefix(WearNTear __instance) { return !Safe(__instance); } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] private static class Wearing { private static void Prefix(WearNTear __instance) { wearing = __instance; } private static void Finalizer() { wearing = null; } } [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] private static class NoWear { private static bool Prefix(WearNTear __instance, HitData hitData, ref bool __result) { if (hitData != null || !Safe(__instance) || ((Object)(object)wearing == (Object)(object)__instance && !__instance.HaveSupport())) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(WearNTear), "UpdateSupport")] private static class OnDeck { private static readonly Collider[] found = (Collider[])(object)new Collider[128]; private static bool Prefix(WearNTear __instance) { Transform parent = ((Component)__instance).transform.parent; FlatbedDeck flatbedDeck = (((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponent<FlatbedDeck>() : null); if ((Object)(object)flatbedDeck == (Object)null) { return true; } if ((Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner()) { return false; } float maxSupport = default(float); float num = default(float); float horizontalLoss = default(float); float verticalLoss = default(float); __instance.GetMaterialProperties(ref maxSupport, ref num, ref horizontalLoss, ref verticalLoss); Set(__instance, Support(__instance, flatbedDeck, maxSupport, horizontalLoss, verticalLoss)); return false; } private static void Set(WearNTear wear, float support) { if (!wear.m_support.Equals(support)) { wear.m_support = support; wear.m_nview.GetZDO().Set(ZDOVars.s_support, support); } } private static float Support(WearNTear wear, FlatbedDeck deck, float maxSupport, float horizontalLoss, float verticalLoss) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) ZDO val = Find(deck.Key); if (val == null || (Object)(object)ZNetScene.instance.FindInstance(val) == (Object)null) { return maxSupport; } if (wear.m_colliders == null) { wear.SetupColliders(); } Vector3 cOM = wear.GetCOM(); float num = 0f; Collider[] colliders = wear.m_colliders; Vector3 val6 = default(Vector3); foreach (Collider val2 in colliders) { if ((Object)(object)val2 == (Object)null || val2.isTrigger) { continue; } BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null); Quaternion val4; Vector3 val5; if (val3 != null) { Vector3 lossyScale = ((Component)val3).transform.lossyScale; val4 = ((Component)val3).transform.rotation; val5 = ((Component)val3).transform.TransformPoint(val3.center); ((Vector3)(ref val6))..ctor(lossyScale.x * val3.size.x, lossyScale.y * val3.size.y, lossyScale.z * val3.size.z); } else { val4 = Quaternion.identity; Bounds bounds = val2.bounds; val5 = ((Bounds)(ref bounds)).center; bounds = val2.bounds; val6 = ((Bounds)(ref bounds)).size; } val6 = (val6 + Vector3.one * 0.3f) * 0.5f; int num2 = Physics.OverlapBoxNonAlloc(val5, val6, found, val4, WearNTear.s_rayMask); for (int j = 0; j < num2; j++) { Collider val7 = found[j]; if (val7.isTrigger || Array.IndexOf(wear.m_colliders, val7) >= 0 || DeckOf(val7, out var _) != deck.Key) { continue; } WearNTear componentInParent = ((Component)val7).GetComponentInParent<WearNTear>(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent == (Object)(object)wear) { continue; } if ((Object)(object)((Component)componentInParent).GetComponent<RailFlatbed>() != (Object)null) { return maxSupport; } if (!componentInParent.m_supports) { continue; } float num3 = Mathf.Min(Vector3.Distance(cOM, componentInParent.GetCOM()), Vector3.Distance(cOM, ((Component)componentInParent).transform.position)) + 0.1f; float support = componentInParent.GetSupport(); num = Mathf.Max(num, support - horizontalLoss * num3 * support); Vector3 val8 = WearNTear.FindSupportPoint(cOM, componentInParent, val7); if (val8.y < cOM.y + 0.05f) { Vector3 val9 = val8 - cOM; Vector3 normalized = ((Vector3)(ref val9)).normalized; if (normalized.y < 0f) { float num4 = Mathf.Acos(1f - Mathf.Abs(normalized.y)) / (MathF.PI / 2f); float num5 = Mathf.Lerp(horizontalLoss, verticalLoss, num4); num = Mathf.Max(num, support - num5 * num3 * support); } } } } return Mathf.Min(num, maxSupport); } } public const string Prefab = "bf_wagon_flat"; public static readonly int Hash = StringExtensionMethods.GetStableHashCode("bf_wagon_flat"); public const string Key = "bf_deck_key"; public const string On = "bf_deck"; public const string Pos = "bf_deck_pos"; public const string Rot = "bf_deck_rot"; private static readonly int KeyHash = StringExtensionMethods.GetStableHashCode("bf_deck_key"); private static readonly int OnHash = StringExtensionMethods.GetStableHashCode("bf_deck"); private static readonly int PosHash = StringExtensionMethods.GetStableHashCode("bf_deck_pos"); private static readonly int RotHash = StringExtensionMethods.GetStableHashCode("bf_deck_rot"); public const float HalfWidth = 2f; public const float HalfLength = 3f; public const float Floor = 1.5f; public const float Cover = 0.02f; private const float Top = 0.5f; private const float Sunk = 0.35f; private const float SyncEvery = 8f; private static readonly Dictionary<long, HashSet<ZDOID>> riders = new Dictionary<long, HashSet<ZDOID>>(); private static readonly Dictionary<ZDOID, long> deckOf = new Dictionary<ZDOID, long>(); private static readonly Dictionary<long, ZDO> wagons = new Dictionary<long, ZDO>(); private static readonly Dictionary<long, (Vector3 position, Quaternion rotation, bool settled)> synced = new Dictionary<long, (Vector3, Quaternion, bool)>(); private static readonly Dictionary<Material, Material> still = new Dictionary<Material, Material>(); private static readonly List<ZDOID> gone = new List<ZDOID>(); private static ZDOMan seeded; private static long aim; private static Transform aimAt; private static string refusal; private static long placing; private static Transform placingAt; private static bool removing; private static bool failed; private static Piece onWood; private static WearNTear wearing; public static void Reset() { riders.Clear(); deckOf.Clear(); wagons.Clear(); synced.Clear(); seeded = null; aim = 0L; aimAt = null; refusal = null; placing = 0L; placingAt = null; FlatbedDeck.Clear(); } public static void Unload() { FlatbedDeck.Release(); Reset(); } public static void Restore() { if ((Object)(object)ZNetScene.instance == (Object)null) { return; } foreach (ZNetView item in ZNetScene.instance.m_instances.Values.ToList()) { if ((Object)(object)item != (Object)null && item.GetZDO() != null && item.GetZDO().GetLong(OnHash, 0L) != 0L) { Attach(item); } } } public static void Update() { ZDOMan instance = ZDOMan.instance; if (instance == null || seeded == instance) { return; } riders.Clear(); deckOf.Clear(); foreach (ZDO value in instance.m_objectsByID.Values) { Index(value); } seeded = instance; if (deckOf.Count > 0) { RailPlugin.Log.LogInfo((object)$"rail flatbeds: {deckOf.Count} pieces ride on {riders.Count} of them"); } } private static void Index(ZDO zdo) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) long num = zdo.GetLong(OnHash, 0L); if (deckOf.TryGetValue(zdo.m_uid, out var value)) { if (value == num) { return; } Forget(zdo.m_uid); } if (num != 0L) { deckOf[zdo.m_uid] = num; if (!riders.TryGetValue(num, out var value2)) { value2 = (riders[num] = new HashSet<ZDOID>()); } value2.Add(zdo.m_uid); } } private static void Forget(ZDOID id) { //IL_0005: 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_002b: Unknown result type (might be due to invalid IL or missing references) if (deckOf.TryGetValue(id, out var value)) { deckOf.Remove(id); if (riders.TryGetValue(value, out var value2) && value2.Remove(id) && value2.Count == 0) { riders.Remove(value); } } } public static int Count(long key) { //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_0034: 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_0082: Unknown result type (might be due to invalid IL or missing references) if (key == 0L || !riders.TryGetValue(key, out var value)) { return 0; } gone.Clear(); foreach (ZDOID item in value) { ZDO zDO = ZDOMan.instance.GetZDO(item); if (zDO == null || zDO.GetLong(OnHash, 0L) != key) { gone.Add(item); } } foreach (ZDOID item2 in gone) { Forget(item2); } if (!riders.TryGetValue(key, out value)) { return 0; } return value.Count; } public static long KeyOf(ZDO flatbed) { if (flatbed == null) { return 0L; } return flatbed.GetLong(KeyHash, 0L); } public static ZDO Find(long key) { if (key == 0L) { return null; } if (wagons.TryGetValue(key, out var value) && value.IsValid() && value.GetLong(KeyHash, 0L) == key) { return value; } wagons.Remove(key); foreach (ZDO wagon in Scan.Wagons) { if (wagon.GetPrefab() == Hash && wagon.GetLong(KeyHash, 0L) == key) { wagons[key] = wagon; return wagon; } } return null; } public static void GiveKey(ZDO flatbed) { if (flatbed != null && flatbed.IsOwner() && flatbed.GetLong(KeyHash, 0L) == 0L) { long num = BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0); flatbed.Set("bf_deck_key", (num == 0L) ? 1 : num); } } public static void ServerTick() { foreach (ZDO wagon in Scan.Wagons) { if (wagon.GetPrefab() == Hash) { GiveKey(wagon); } } } private static bool Moving(ZDOID wagon) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ZDO val = Train.Pulling(wagon); if (val != null) { return Mathf.Abs(val.GetFloat("bf_speed", 0f)) > 0.01f; } return false; } public static void Sync(ZDO flatbed, Vector3 position, Quaternion rotation, bool standing) { //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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) long num = flatbed.GetLong(KeyHash, 0L); if (num == 0L || !riders.TryGetValue(num, out var value) || value.Count == 0) { return; } Vector3 val; if (synced.TryGetValue(num, out (Vector3, Quaternion, bool) value2)) { val = value2.Item1 - position; if (!(((Vector3)(ref val)).sqrMagnitude > 64f) && (!standing || value2.Item3)) { if (!standing && value2.Item3) { synced[num] = (value2.Item1, value2.Item2, false); } return; } } long sessionID = ZDOMan.GetSessionID(); bool flag = true; gone.Clear(); foreach (ZDOID item in value) { ZDO zDO = ZDOMan.instance.GetZDO(item); if (zDO == null || zDO.GetLong(OnHash, 0L) != num) { gone.Add(item); continue; } Vector3 val2 = position + rotation * zDO.GetVec3(PosHash, Vector3.zero); Quaternion val3 = rotation * zDO.GetQuaternion(RotHash, Quaternion.identity); val = zDO.GetPosition() - val2; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && Quaternion.Angle(zDO.GetRotation(), val3) < 0.1f) { continue; } if (!zDO.IsOwner()) { if (zDO.GetInt(ZDOVars.s_inUse, 0) != 0) { flag = false; continue; } zDO.SetOwner(sessionID); } zDO.SetPosition(val2); zDO.SetRotation(val3); } foreach (ZDOID item2 in gone) { Forget(item2); } synced[num] = (position, rotation, standing && flag); } public static void Follow() { FlatbedDeck.FollowAll(); } private static void Attach(ZNetView view) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_008d: Unknown result type (might be due to invalid IL or missing references) //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) ZDO zDO = view.GetZDO(); long num = zDO.GetLong(OnHash, 0L); if (num != 0L) { Index(zDO); Vector3 vec = zDO.GetVec3(PosHash, Vector3.zero); Quaternion quaternion = zDO.GetQuaternion(RotHash, Quaternion.identity); FlatbedDeck flatbedDeck = FlatbedDeck.Get(num); if (!flatbedDeck.Place() && ((Component)flatbedDeck).transform.childCount == 0) { Quaternion val = ((Component)view).transform.rotation * Quaternion.Inverse(quaternion); ((Component)flatbedDeck).transform.SetPositionAndRotation(((Component)view).transform.position - val * vec, val); } ((Component)view).transform.SetParent(((Component)flatbedDeck).transform, false); ((Component)view).transform.localPosition = vec; ((Component)view).transform.localRotation = quaternion; WearNTear component = ((Component)view).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null) { component.m_staticPosition = false; } flatbedDeck.Burns(view); if (!ZNet.instance.IsDedicated()) { Still(view); } } } private static void Still(ZNetView view) { Renderer[] componentsInChildren = ((Component)view).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer)) { continue; } Material[] sharedMaterials = val.sharedMaterials; bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (!((Object)(object)val2 == (Object)null) && !((Object)val2).name.EndsWith(" moving") && (val2.HasProperty("_RippleDistance") || val2.HasProperty("_ValueNoise"))) { if (!still.TryGetValue(val2, out var value) || (Object)(object)value == (Object)null) { value = (still[val2] = Pieces.Moveable(val2)); } sharedMaterials[j] = value; flag = true; } } if (flag) { val.sharedMaterials = sharedMaterials; } } } private static long DeckOf(Collider collider, out Transform deck) { deck = null; Rigidbody val = (((Object)(object)collider != (Object)null) ? collider.attachedRigidbody : null); if ((Object)(object)val == (Object)null) { return 0L; } RailFlatbed component = ((Component)val).GetComponent<RailFlatbed>(); if ((Object)(object)component != (Object)null) { deck = ((Component)component).transform; return component.DeckKey; } FlatbedDeck component2 = ((Component)val).GetComponent<FlatbedDeck>(); if ((Object)(object)component2 != (Object)null) { deck = ((Component)component2).transform; return component2.Key; } return 0L; } public static Quaternion GhostTurn(float x, float y, float z) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) Quaternion val = Quaternion.Euler(x, y, z); if (!((Object)(object)aimAt != (Object)null)) { return val; } return aimAt.rotation * val; } private static string Refusal(GameObject ghost) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ghost.GetComponent<RailPiece>() != (Object)null) { return "Rail pieces do not go on a flatbed"; } if ((Object)(object)ghost.GetComponentInChildren<TeleportWorld>(true) != (Object)null) { return "Use the portal wagon"; } if ((Object)(object)ghost.GetComponentInChildren<Bed>(true) != (Object)null) { return "No beds on a train"; } if ((Object)(object)ghost.GetComponent<Rigidbody>() != (Object)null || (Object)(object)ghost.GetComponent<ZSyncTransform>() != (Object)null) { return "It does not ride on a train"; } ZDO val = Find(aim); if (val == null) { return "The flatbed is not ready, try again"; } if (Moving(val.m_uid)) { return "The train is moving"; } if (Count(aim) >= Settings.MaxDeckPieces) { return $"A flatbed carries at most {Settings.MaxDeckPieces} pieces"; } if (!Settings.DeckSmelters && IsSmelter(ghost)) { return "Smelters on a flatbed are off, the setting DeckSmelters"; } if (!Settings.DeckFires && IsFire(ghost)) { return "Fires on a flatbed are off, the setting DeckFires"; } return InBox(ghost, aimAt) switch { Fit.Inside => null, Fit.TooHigh => $"It reaches higher than {Settings.DeckHeight:0.##} m over the deck, the setting DeckHeight", _ => "It reaches past the deck", }; } private static bool IsSmelter(GameObject ghost) { if (!((Object)(object)ghost.GetComponentInChildren<Smelter>(true) != (Object)null)) { return (Object)(object)ghost.GetComponentInChildren<Incinerator>(true) != (Object)null; } return true; } private static bool IsFire(GameObject ghost) { //IL_0020: 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) if ((Object)(object)ghost.GetComponentInChildren<Fireplace>(true) == (Object)null) { return false; } EffectArea[] componentsInChildren = ghost.GetComponentsInChildren<EffectArea>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((componentsInChildren[i].m_type & 9) != 0) { return true; } } return false; } private static Fit InBox(GameObject ghost, Transform deck) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0052: 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_0098: 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_00a1: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00b8: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) Fit result = Fit.Inside; bool flag = false; Collider[] componentsInChildren = ghost.GetComponentsInChildren<Collider>(); Bounds bounds = default(Bounds); Vector3 val5 = default(Vector3); foreach (Collider val in componentsInChildren) { if (val.isTrigger || !val.enabled) { continue; } flag = true; Transform val2 = ((Component)val).transform; BoxCollider val3 = (BoxCollider)(object)((val is BoxCollider) ? val : null); if (val3 != null) { ((Bounds)(ref bounds))..ctor(val3.center, val3.size); } else { MeshCollider val4 = (MeshCollider)(object)((val is MeshCollider) ? val : null); if (val4 != null && (Object)(object)val4.sharedMesh != (Object)null) { bounds = val4.sharedMesh.bounds; } else { bounds = val.bounds; val2 = null; } } Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; for (int j = 0; j < 8; j++) { ((Vector3)(ref val5))..ctor(((j & 1) == 0) ? min.x : max.x, ((j & 2) == 0) ? min.y : max.y, ((j & 4) == 0) ? min.z : max.z); switch (Inside(deck.InverseTransformPoint(((Object)(object)val2 != (Object)null) ? val2.TransformPoint(val5) : val5))) { case Fit.Past: return Fit.Past; case Fit.TooHigh: result = Fit.TooHigh; break; } } } if (!flag) { return Inside(deck.InverseTransformPoint(ghost.transform.position)); } return result; } private static Fit Inside(Vector3 local) { //IL_0000: 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_0030: 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) if (Mathf.Abs(local.x) > 2f + Settings.DeckReachLeftRight || Mathf.Abs(local.z) > 3f + Settings.DeckReachFrontBack || local.y < 1.15f) { return Fit.Past; } if (!(local.y > 1.5f + Settings.DeckHeight + 0.5f)) { return Fit.Inside; } return Fit.TooHigh; } private static bool Safe(WearNTear wear) { if (Settings.DeckPiecesIndestructible && (Object)(object)wear.m_nview != (Object)null && wear.m_nview.IsValid()) { return wear.m_nview.GetZDO().GetLong(OnHash, 0L) != 0; } return false; } } public class RailFlatbed : MonoBehaviour, Hoverable, Interactable { private ZNetView m_nview; public long DeckKey { get { if (!((Object)(object)m_nview != (Object)null) || !m_nview.IsValid()) { return 0L; } return Flatbed.KeyOf(m_nview.GetZDO()); } } private void Start() { m_nview = ((Component)this).GetComponent<ZNetView>(); ((MonoBehaviour)this).InvokeRepeating("GiveKey", 0f, 1f); } private void GiveKey() { if ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) { Flatbed.GiveKey(m_nview.GetZDO()); } } public string GetHoverText() { return Localization.instance.Localize($"Flatbed wagon\n{Flatbed.Count(DeckKey)} of {Settings.MaxDeckPieces} pieces built on it\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Couple or uncouple"); } public string GetHoverName() { return "Flatbed wagon"; } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || !alt) { return false; } return Coupling.Toggle(((Component)this).GetComponent<ZNetView>(), user); } public bool UseItem(Humanoid user, ItemData item) { return false; } } public class FlatbedDeck : MonoBehaviour { private static readonly Dictionary<long, FlatbedDeck> all = new Dictionary<long, FlatbedDeck>(); private static readonly List<long> empty = new List<long>(); public long Key; private readonly List<EffectArea> burning = new List<EffectArea>(); private Vector3 burntAt; private Quaternion burntTurn; public void Burns(ZNetView view) { //IL_0011: 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) EffectArea[] componentsInChildren = ((Component)view).GetComponentsInChildren<EffectArea>(true); foreach (EffectArea val in componentsInChildren) { if ((val.m_type & 8) != 0 && !burning.Contains(val)) { burning.Add(val); } } } private void Rekindle() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0056: 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_002b: 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_00bd: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if (burning.Count == 0 || (((Component)this).transform.position == burntAt && ((Component)this).transform.rotation == burntTurn)) { return; } burntAt = ((Component)this).transform.position; burntTurn = ((Component)this).transform.rotation; for (int num = burning.Count - 1; num >= 0; num--) { EffectArea val = burning[num]; if ((Object)(object)val == (Object)null) { burning.RemoveAt(num); } else { int num2 = EffectArea.s_BurningAreas.IndexOf(val.burnCloseToArea); Collider component = ((Component)val).GetComponent<Collider>(); if (num2 >= 0 && !((Object)(object)component == (Object)null)) { Bounds key = Box(component); ((Bounds)(ref key)).Expand(new Vector3(0.25f, 0.25f, 0.25f)); val.burnCloseToArea = new KeyValuePair<Bounds, EffectArea>(key, val); EffectArea.s_BurningAreas[num2] = val.burnCloseToArea; } } } } private static Bounds Box(Collider shape) { //IL_0008: 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) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_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_0094: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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_00c7: 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_0101: 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_0107: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)shape).transform; Vector3 lossyScale = transform.lossyScale; SphereCollider val = (SphereCollider)(object)((shape is SphereCollider) ? shape : null); if (val != null) { float num = val.radius * Mathf.Max(new float[3] { Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z) }); return new Bounds(transform.TransformPoint(val.center), Vector3.one * num * 2f); } BoxCollider val2 = (BoxCollider)(object)((shape is BoxCollider) ? shape : null); Vector3 center; Vector3 val3; if (val2 != null) { center = val2.center; val3 = val2.size * 0.5f; } else { CapsuleCollider val4 = (CapsuleCollider)(object)((shape is CapsuleCollider) ? shape : null); if (val4 == null) { return shape.bounds; } center = val4.center; val3 = Vector3.one * val4.radius; ((Vector3)(ref val3))[val4.direction] = Mathf.Max(val4.height * 0.5f, val4.radius); } Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(transform.TransformPoint(center), Vector3.zero); for (int i = 0; i < 8; i++) { ((Bounds)(ref result)).Encapsulate(transform.TransformPoint(center + new Vector3(((i & 1) == 0) ? (0f - val3.x) : val3.x, ((i & 2) == 0) ? (0f - val3.y) : val3.y, ((i & 4) == 0) ? (0f - val3.z) : val3.z))); } return result; } public static FlatbedDeck Get(long key) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (all.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } GameObject val = new GameObject("bf_deck"); value = val.AddComponent<FlatbedDeck>(); value.Key = key; val.AddComponent<Rigidbody>().isKinematic = true; all[key] = value; return value; } public bool Place() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_004d: Unknown result type (might be due to invalid IL or missing references) ZDO val = Flatbed.Find(Key); if (val == null) { return false; } ZNetView val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(val) : null); if ((Object)(object)val2 != (Object)null) { ((Component)this).transform.SetPositionAndRotation(((Component)val2).transform.position, ((Component)val2).transform.rotation); } else { ((Component)this).transform.SetPositionAndRotation(val.GetPosition(), val.GetRotation()); } return true; } public static void FollowAll() { empty.Clear(); foreach (KeyValuePair<long, FlatbedDeck> item in all) { if ((Object)(object)item.Value == (Object)null) { empty.Add(item.Key); } else if (((Component)item.Value).transform.childCount == 0) { Object.Destroy((Object)(object)((Component)item.Value).gameObject); empty.Add(item.Key); } else { item.Value.Place(); item.Value.Rekindle(); } } foreach (long item2 in empty) { all.Remove(item2); } } public static void Release() { foreach (FlatbedDeck value in all.Values) { if (!((Object)(object)value == (Object)null)) { for (int num = ((Component)value).transform.childCount - 1; num >= 0; num--) { ((Component)value).transform.GetChild(num).SetParent((Transform)null, true); } Object.Destroy((Object)(object)((Component)value).gameObject); } } all.Clear(); } public static void Clear() { all.Clear(); } } public static class Follow { private class Copy { public TrackCursor cursor; public uint revision; public float receivedAt; } public static bool Enabled = true; private const float Pull = 2f; private const float Snap = 6f; private const float MaxAge = 0.5f; private static readonly Dictionary<ZDOID, Copy> copies = new Dictionary<ZDOID, Copy>(); public static void Reset() { copies.Clear(); } public static void Forget(ZDOID loco) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) copies.Remove(loco); } public static bool Step(ZDO loco, float dt) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) if (!Train.Load(loco, out var owner)) { copies.Remove(loco.m_uid); return false; } if (!copies.TryGetValue(loco.m_uid, out var value) || Graph.Find(value.cursor.line.Id) == null) { value = new Copy { cursor = owner, revision = loco.DataRevision, receivedAt = Time.time }; copies[loco.m_uid] = value; } if (loco.DataRevision != value.revision) { value.revision = loco.DataRevision; value.receivedAt = Time.time; } float num = loco.GetFloat("bf_speed", 0f); IReadOnlyList<LineId> route = Saved.Lines(loco, "bf_route"); IReadOnlyList<LineId> readOnlyList = Saved.Lines(loco, "bf_trail"); TrackCursor now = owner; float num2 = Mathf.Min(Time.time - value.receivedAt, 0.5f); IReadOnlyList<LineId> rear = ((loco.GetBool("bf_moving", false) && loco.GetLong("bf_driver", 0L) == 0L && loco.GetInt("bf_way", 1) < 0) ? route : readOnlyList); now.Walk(num * num2, (List<Step> steps, bool backward) => Choose(steps, backward, now, route, rear, owner.line)); Vector3 val = now.Position - value.cursor.Position; if (((Vector3)(ref val)).sqrMagnitude > 36f || Vector3.Dot(now.Forward, value.cursor.Forward) < 0f) { value.cursor = now; } else { float num3 = Vector3.Dot(val, value.cursor.Forward); float distance = num * dt + num3 * Mathf.Min(1f, 2f * dt); TrackCursor next = value.cursor; next.Walk(distance, (List<Step> steps, bool backward) => Choose(steps, backward, next, route, rear, owner.line)); value.cursor = next; } List<LineId> list = new List<LineId>(readOnlyList); if (value.cursor.line != owner.line) { if (list.Count > 0 && value.cursor.line.Matches(list[0])) { list.RemoveAt(0); } else { list.Insert(0, owner.line.Id); } } IReadOnlyList<LineId> ahead = (Train.GoesForward(loco) ? route : null); LineQueue rest; List<Train.Body> list2 = Train.Layout(loco, value.cursor, list, ahead, out rest); Train.Draw(list2); foreach (Train.Body item in list2.Skip(1)) { ZDO zDO = ZDOMan.instance.GetZDO(item.id); if (zDO != null && zDO.IsOwner()) { zDO.SetPosition(item.position); zDO.SetRotation(item.rotation); Train.Save(zDO, item.cursor); Mend.Mark(zDO); } } return true; } private static Step? Choose(List<Step> steps, bool backward, TrackCursor at, IReadOnlyList<LineId> route, IReadOnlyList<LineId> trail, Line ownerLine) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (backward) { LineQueue trail2 = new LineQueue(trail); return Train.FromTrail(steps, ref trail2, at.Forward); } foreach (Step step in steps) { if (step.line == ownerLine || route.Any((LineId id) => step.line.Matches(id))) { return step; } } return TrackCursor.Straightest(steps, at.Forward, 0); } } public readonly struct LineId : IEquatable<LineId> { public readonly Vector3 a; public readonly Vector3 b; public LineId(Vector3 a, Vector3 b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) this.a = a; this.b = b; } public bool Equals(LineId other) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) //IL_001c: 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) Vector3 val = a; if (((Vector3)(ref val)).Equals(other.a)) { val = b; return ((Vector3)(ref val)).Equals(other.b); } return false; } public override bool Equals(object other) { if (other is LineId other2) { return Equals(other2); } return false; } public override int GetHashCode() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) return (((object)a/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ ((object)b/*cast due to .constrained prefix*/).GetHashCode(); } public override string ToString() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return $"{a}-{b}"; } } public class Line { public readonly ZDOID piece; public readonly Vector3[] points; public readonly float[] along; public readonly LineId Id; internal List<Step> nextAtA = new List<Step>(); internal List<Step> nextAtB = new List<Step>(); public Vector3 A => points[0]; public Vector3 B => points[points.Length - 1]; public float Length => along[along.Length - 1]; public Line(ZDOID piece, Vector3[] points) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) this.piece = piece; this.points = points; along = new float[points.Length]; for (int i = 1; i < points.Length; i++) { along[i] = along[i - 1] + Vector3.Distance(points[i - 1], points[i]); } Id = new LineId(A, B); } public void At(float s, out Vector3 position, out Vector3 forward) { //IL_005b: 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_007f: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00ac: Unknown result type (might be due to invalid IL or missing references) s = Mathf.Clamp(s, 0f, Length); int i; for (i = 1; i < points.Length - 1 && along[i] < s; i++) { } float num = Mathf.Max(along[i] - along[i - 1], 1E-06f); position = Vector3.Lerp(points[i - 1], points[i], (s - along[i - 1]) / num); Vector3 val = points[i] - points[i - 1]; forward = ((Vector3)(ref val)).normalized; } public Vector3 Leaving(bool atB) { //IL_003b: 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_004e: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0024: 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_002c: Unknown result type (might be due to invalid IL or missing references) int num = points.Length; Vector3 val; if (!atB) { val = points[0] - points[1]; return ((Vector3)(ref val)).normalized; } val = points[num - 1] - points[num - 2]; return ((Vector3)(ref val)).normalized; } public bool Matches(LineId id) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_002f: 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_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) if (!Id.Equals(id)) { Vector3 val = A - id.a; if (((Vector3)(ref val)).sqrMagnitude < 0.09f) { val = B - id.b; return ((Vector3)(ref val)).sqrMagnitude < 0.09f; } return false; } return true; } } public struct Step { public Line line; public bool fromA; } public static class Scan { private enum Kind { Track, Locomotive, Wagon, Station } [HarmonyPatch(typeof(ZDOMan), "AddIfPortal")] private static class Added { private static void Postfix(ZDOMan __instance, ZDO zdo, int prefabHash) { //IL_0019: 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) if (__instance == seeded && KindOf(prefabHash, out var kind) && (!known.TryGetValue(zdo.m_uid, out (ZDO, Kind) value) || value.Item1 != zdo)) { known[zdo.m_uid] = (zdo, kind); dirty = true; } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] private static class Destroyed { private static void Prefix(ZDOMan __instance, ZDOID uid) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (__instance == seeded && known.Remove(uid)) { dirty = true; } } } [HarmonyPatch(typeof(ZDOMan), "Load")] private static class Loaded { private static void Postfix() { seeded = null; } } [HarmonyPatch(typeof(ZDOMan), "LoadChunks")] private static class LoadedChunks { private static void Postfix() { seeded = null; } } private static readonly Dictionary<ZDOID, (ZDO zdo, Kind kind)> known = new Dictionary<ZDOID, (ZDO, Kind)>(); private static Dictionary<int, Kind> kinds; private static ZDOMan seeded; private static bool dirty; private static List<ZDO> tracks = new List<ZDO>(); private static List<ZDO> locomotives = new List<ZDO>(); private static List<ZDO> wagons = new List<ZDO>(); private static List<ZDO> stations = new List<ZDO>(); public static int Pass; public static List<ZDO> Tracks { get { Update(); return tracks; } } public static List<ZDO> Locomotives { get { Update(); return locomotives; } } public static List<ZDO> Wagons { get { Update(); return wagons; } } public static List<ZDO> Stations { get { Update(); return stations; } } public static void Reset() { known.Clear(); seeded = null; tracks = new List<ZDO>(); locomotives = new List<ZDO>(); wagons = new List<ZDO>(); stations = new List<ZDO>(); dirty = false; Pass++; } public static void Update() { ZDOMan instance = ZDOMan.instance; if (instance != null) { if (seeded != instance) { Seed(instance); } if (dirty) { Split(); } } } private static bool KindOf(int prefab, out Kind kind) { if (kinds == null) { kinds = Pieces.Specs.Where((Pieces.Spec s) => s.model.StartsWith("track_")).ToDictionary((Pieces.Spec s) => StringExtensionMethods.GetStableHashCode(s.prefab), (Pieces.Spec s) => Kind.Track); kinds[Train.LocomotiveHash] = Kind.Locomotive; kinds[Train.WagonHash] = Kind.Wagon; kinds[Train.RestaurantHash] = Kind.Wagon; kinds[RailPortal.Hash] = Kind.Wagon; kinds[Flatbed.Hash] = Kind.Wagon; kinds[Station.Hash] = Kind.Station; } return kinds.TryGetValue(prefab, out kind); } private static void Seed(ZDOMan man) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Stopwatch stopwatch = Stopwatch.StartNew(); known.Clear(); foreach (ZDO value in man.m_objectsByID.Values) { if (KindOf(value.GetPrefab(), out var kind)) { known[value.m_uid] = (value, kind); } } seeded = man; Split(); RailPlugin.Log.LogInfo((object)$"rail objects: {known.Count} of {man.m_objectsByID.Count} in {stopwatch.ElapsedMilliseconds} ms"); } private static void Split() { dirty = false; List<ZDO> list = new List<ZDO>(); List<ZDO> list2 = new List<ZDO>(); List<ZDO> list3 = new List<ZDO>(); List<ZDO> list4 = new List<ZDO>(); foreach (var value in known.Values) { var (item, _) = value; switch (value.kind) { case Kind.Track: list.Add(item); break; case Kind.Locomotive: list2.Add(item); break; case Kind.Wagon: list3.Add(item); break; default: list4.Add(item); break; } } tracks = list; locomotives = list2; wagons = list3; stations = list4; Pass++; } } public static class Graph { private class Piece { public string model; public Vector3 position; public Quaternion rotation; public List<Line> lines; } public const float Join = 0.3f; private static readonly Dictionary<ZDOID, Piece> pieces = new Dictionary<ZDOID, Piece>(); private static readonly Dictionary<Vector3Int, List<(Line line, bool atB)>> ends = new Dictionary<Vector3Int, List<(Line, bool)>>(); private static readonly Dictionary<LineId, Line> byId = new Dictionary<LineId, Line>(); private static Dictionary<int, string> trackPrefabs; private static int builtFrom = -1; public static int Version; private static float nextBuild; private static readonly HashSet<string> Crossings = new HashSet<string> { "track_crossing", "track_junction_x" }; public static IEnumerable<Line> Lines => pieces.Values.SelectMany((Piece p) => p.lines); public static void Reset() { pieces.Clear(); ends.Clear(); byId.Clear(); builtFrom = -1; nextBuild = 0f; } public static void Update() { Scan.Update(); if (builtFrom != Scan.Pass || Time.time >= nextBuild) { Build(); } } public static void Rebuild() { Scan.Update(); Build(); } private static void Build() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) builtFrom = Scan.Pass; nextBuild = Time.time + 1f; if (trackPrefabs == null) { trackPrefabs = Pieces.Specs.Where((Pieces.Spec s) => s.model.StartsWith("track_")).ToDictionary((Pieces.Spec s) => StringExtensionMethods.GetStableHashCode(s.prefab), (Pieces.Spec s) => s.model); } HashSet<ZDOID> seen = new HashSet<ZDOID>(); bool flag = false; foreach (ZDO zdo in Scan.Tracks) { if (!zdo.IsValid() || !trackPrefabs.TryGetValue(zdo.GetPrefab(), out var value)) { continue; } seen.Add(zdo.m_uid); Vector3 position = zdo.GetPosition(); Quaternion rotation = zdo.GetRotation(); if (pieces.TryGetValue(zdo.m_uid, out var value2) && value2.position == position && value2.rotation == rotation) { continue; } Matrix4x4 world = Matrix4x4.TRS(position, rotation, Vector3.one); pieces[zdo.m_uid] = new Piece { model = value, position = position, rotation = rotation, lines = Models.Load(value).lines.Select((Vector3[] l) => new Line(zdo.m_uid, l.Select((Vector3 p) => ((Matrix4x4)(ref world)).MultiplyPoint3x4(p)).ToArray())).ToList() }; flag = true; } foreach (ZDOID item in pieces.Keys.Where((ZDOID id) => !seen.Contains(id)).ToList()) { pieces.Remove(item); flag = true; } if (!flag) { return; } ends.Clear(); byId.Clear(); foreach (Line line in Lines) { byId[line.Id] = line; AddEnd(line, atB: false); AddEnd(line, atB: true); } foreach (Line line2 in Lines) { line2.nextAtA = Search(line2, atB: false); line2.nextAtB = Search(line2, atB: true); } Version++; } private static Vector3Int Cell(Vector3 p) { //IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Vector3Int(Mathf.FloorToInt(p.x), Mathf.FloorToInt(p.y), Mathf.FloorToInt(p.z)); } private static void AddEnd(Line line, bool atB) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001c: 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) Vector3Int key = Cell(atB ? line.B : line.A); if (!ends.TryGetValue(key, out List<(Line, bool)> value)) { value = new List<(Line, bool)>(); ends[key] = value; } value.Add((line, atB)); } public static List<Step> Next(Line line, bool atB) { if (!atB) { return line.nextAtA; } return line.nextAtB; } private static List<Step> Search(Line line, bool atB) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0019: 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_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_0044: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00a1: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (atB ? line.B : line.A); Vector3 val