diff --git a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs
index 0f98463d5..b038b6376 100644
--- a/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs
+++ b/TLM/TLM/Patch/_BuildingDecoration/LoadPathsPatch.cs
@@ -4,11 +4,13 @@ namespace TrafficManager.Patches._BuildingDecoration {
using TrafficManager.Util;
using System;
using System.Reflection.Emit;
+ using JetBrains.Annotations;
//public static void LoadPaths(BuildingInfo info, ushort buildingID, ref Building data, float elevation)
[HarmonyPatch(typeof(BuildingDecoration), nameof(BuildingDecoration.LoadPaths))]
+ [UsedImplicitly]
public class LoadPathsPatch {
- ///Called after intersection is built
+ ///Called after intersection is built
internal static void AfterIntersectionBuilt(BuildingInfo info) {
if (!Shortcuts.InSimulationThread())
return; // only rendering
@@ -18,21 +20,24 @@ internal static void AfterIntersectionBuilt(BuildingInfo info) {
}
// code from: https://github.com/Strdate/SmartIntersections/blob/master/SmartIntersections/Patch/LoadPathsPatch.cs
+ [UsedImplicitly]
public static IEnumerable Transpiler(ILGenerator il, IEnumerable instructions) {
- var fTempNodeBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempNodeBuffer))
- ?? throw new Exception("cound not find NetManager.m_tempNodeBuffer");
- var mClear = AccessTools.DeclaredMethod(fTempNodeBuffer.FieldType, nameof(FastList.Clear))
- ?? throw new Exception("cound not find m_tempNodeBuffer.Clear");
+ var fTempSegmentBuffer = AccessTools.DeclaredField(typeof(NetManager), nameof(NetManager.m_tempSegmentBuffer))
+ ?? throw new Exception("Could not find NetManager.m_tempSegmentBuffer");
+ var mSize = AccessTools.DeclaredField(fTempSegmentBuffer.FieldType, nameof(FastList.m_size))
+ ?? throw new Exception("Could not find m_tempSegmentBuffer.m_size");
var mAfterIntersectionBuilt = AccessTools.DeclaredMethod(
typeof(LoadPathsPatch), nameof(AfterIntersectionBuilt))
- ?? throw new Exception("cound not find AfterIntersectionBuilt()");
+ ?? throw new Exception("Could not find AfterIntersectionBuilt()");
List codes = TranspilerUtil.ToCodeList(instructions);
- bool comp(int i) =>
- codes[i].opcode == OpCodes.Ldfld && codes[i].operand == fTempNodeBuffer &&
- codes[i + 1].opcode == OpCodes.Callvirt && codes[i + 1].operand == mClear;
- int index = TranspilerUtil.SearchGeneric(codes, comp, index: 0, counter: 2);
- index -= 1; // index to insert instructions.
+
+ bool predicate(int i) =>
+ codes[i].opcode == OpCodes.Blt &&
+ codes[i - 1].opcode == OpCodes.Ldfld && codes[i - 1].operand == mSize &&
+ codes[i - 2].opcode == OpCodes.Ldfld && codes[i - 2].operand == fTempSegmentBuffer;
+ int index = TranspilerUtil.SearchGeneric(codes, predicate, index: 0, counter: 1);
+ index += 1; // index to insert instructions. (end of the loop)
var newInstructions = new[] {
new CodeInstruction(OpCodes.Ldarg_0), // load argument info
diff --git a/TLM/TLM/Util/PlaceIntersectionUtil.cs b/TLM/TLM/Util/PlaceIntersectionUtil.cs
index 24b40e989..4e378127b 100644
--- a/TLM/TLM/Util/PlaceIntersectionUtil.cs
+++ b/TLM/TLM/Util/PlaceIntersectionUtil.cs
@@ -2,6 +2,7 @@ namespace TrafficManager.Util {
using System.Collections.Generic;
using System.Linq;
using CSUtil.Commons;
+ using Manager.Impl;
using TrafficManager.State.Asset;
using TrafficManager.Util;
using TrafficManager.Lifecycle;
@@ -9,8 +10,10 @@ namespace TrafficManager.Util {
public static class PlaceIntersectionUtil {
///maps old netowkr ids to new network ids
+ /// source segment id array created by on asset serialization
/// segment list provided by LoadPaths.
- public static void MapSegments(
+ /// segment map to fill in with pairs (old;new)
+ private static void FillSegmentsMap(
SegmentNetworkIDs[] oldSegments,
ushort[] newSegmentIds,
Dictionary map) {
@@ -34,8 +37,9 @@ public static void MapSegments(
///
/// segment list provided by LoadPaths.
public static void ApplyTrafficRules(BuildingInfo intersectionInfo, ushort[] newSegmentIds) {
- /*************************
- * Prepration: */
+ /****************/
+ /* Preparation: */
+ /****************/
Log._Debug($"PlaceIntersectionUtil.ApplyTrafficRules({intersectionInfo?.ToString() ?? "null"})");
@@ -64,34 +68,22 @@ public static void ApplyTrafficRules(BuildingInfo intersectionInfo, ushort[] new
var pathNetworkIDs = assetData.PathNetworkIDs;
if (pathNetworkIDs == null) return;
- /*************************
- * Apply traffic rules: */
+ /***********************/
+ /* Create segment map: */
+ /***********************/
+ Shortcuts.AssertNotNull(newSegmentIds, "newSegmentIds");
+ FillSegmentsMap(oldSegments: pathNetworkIDs, newSegmentIds: newSegmentIds, map: map);
- MapSegments(oldSegments: pathNetworkIDs, newSegmentIds: newSegmentIds, map: map);
+ // Note to previous solution:
+ // Node/segment calculation shouldn't be performed at this state!
+ // Forcing it here may trigger another 'fake' LoadPaths call breaking other mods attached to that method!
- foreach (var item in map)
- CalculateNetwork(item.Value);
-
- assetData.Record.Transfer(map);
+ /*****************************************/
+ /* Queue traffic rules transfer process: */
+ /*****************************************/
+ UtilityManager.Instance.QueueTransferRecordable(assetData.Record, map);
OnPlaceIntersection?.Invoke(intersectionInfo, map);
}
-
- ///
- /// early calculate networks so that we are able to set traffic rules without delay.
- ///
- public static void CalculateNetwork(InstanceID instanceId) {
- switch (instanceId.Type) {
- case InstanceType.NetNode:
- ushort nodeId = instanceId.NetNode;
- nodeId.ToNode().CalculateNode(nodeId);
- break;
- case InstanceType.NetSegment:
- ushort segmentId = instanceId.NetSegment;
- segmentId.ToSegment().CalculateSegment(segmentId);
- break;
- }
- }
-
}
}