using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using CommonAPI.Systems.ModLocalization;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;
using xiaoye97;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SignalNexus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.13.0")]
[assembly: AssemblyInformationalVersion("0.2.13")]
[assembly: AssemblyProduct("SignalNexus")]
[assembly: AssemblyTitle("SignalNexus")]
[assembly: AssemblyVersion("0.2.13.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SignalNexus
{
internal static class NexusLookup
{
internal static bool TryGetEntity(PlanetFactory factory, int entityId, out EntityData entity)
{
//IL_0001: 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)
entity = default(EntityData);
if (factory == null || entityId <= 0 || entityId >= factory.entityCursor)
{
return false;
}
entity = factory.entityPool[entityId];
if (entity.id == entityId)
{
return entity.protoId == Plugin.ItemId;
}
return false;
}
internal static bool TryGetFromMonitor(PlanetFactory factory, int monitorId, out EntityData entity, out MonitorComponent monitor, out MarkerComponent marker)
{
//IL_0001: 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_004d: 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)
entity = default(EntityData);
monitor = default(MonitorComponent);
marker = null;
if (factory?.cargoTraffic?.monitorPool == null || monitorId <= 0 || monitorId >= factory.cargoTraffic.monitorCursor)
{
return false;
}
monitor = factory.cargoTraffic.monitorPool[monitorId];
if (monitor.id != monitorId || !TryGetEntity(factory, monitor.entityId, out entity) || entity.markerId <= 0)
{
return false;
}
marker = factory.digitalSystem.markers[entity.markerId];
return marker != null;
}
internal static void SyncMarkerFromMonitor(PlanetFactory factory, EntityData entity)
{
//IL_0000: 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)
//IL_001e: 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_0047: Unknown result type (might be due to invalid IL or missing references)
if (entity.monitorId > 0 && entity.markerId > 0)
{
ref MonitorComponent reference = ref factory.cargoTraffic.monitorPool[entity.monitorId];
MarkerComponent val = factory.digitalSystem.markers[entity.markerId];
if (reference.id == entity.monitorId && val != null)
{
val.SetDigitalSignalId(reference.digitalSignalId);
}
}
}
internal static void SyncMonitorFromMarker(PlanetFactory factory, MarkerComponent marker)
{
//IL_0016: 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_003d: Unknown result type (might be due to invalid IL or missing references)
if (factory != null && marker != null && TryGetEntity(factory, marker.entityId, out var entity) && entity.monitorId > 0)
{
ref MonitorComponent reference = ref factory.cargoTraffic.monitorPool[entity.monitorId];
if (reference.id == entity.monitorId)
{
((MonitorComponent)(ref reference)).SetDigitalSignalId(marker.digitalSignalId);
}
}
}
}
[HarmonyPatch(typeof(UIGame), "OnPlayerInspecteeChange")]
internal static class NexusInspectPatch
{
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool Prefix(UIGame __instance, EObjectType objType, int objId)
{
//IL_0012: 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_0056: 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)
Player mainPlayer = GameMain.mainPlayer;
PlanetFactory factory = ((mainPlayer != null) ? mainPlayer.factory : null);
if ((int)objType != 0 || !NexusLookup.TryGetEntity(factory, objId, out var entity) || entity.monitorId <= 0)
{
return true;
}
try
{
__instance.nodeWindow.nodeId = 0;
__instance.markerWindow.markerId = 0;
__instance.ShutAllFunctionWindow();
__instance.ShutPlayerInventory();
__instance.monitorWindow.monitorId = entity.monitorId;
Traverse obj = Traverse.Create((object)__instance);
obj.Field("inspectMarkerId").SetValue((object)0);
obj.Field("inspectNodeId").SetValue((object)0);
obj.Field("inspectMonitorId").SetValue((object)entity.monitorId);
__instance.OpenMonitorWindow();
Plugin.Log.LogInfo((object)$"Opened Signal Nexus {objId} directly in the combined monitor/beacon window.");
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Signal Nexus direct window routing failed: {arg}");
return true;
}
return false;
}
}
[HarmonyPatch(typeof(PlanetFactory), "CreateEntityLogicComponents")]
internal static class EntityComponentPatch
{
[HarmonyPostfix]
private static void Postfix(PlanetFactory __instance, int entityId)
{
//IL_000c: 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_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: 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_001e: 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)
if (NexusLookup.TryGetEntity(__instance, entityId, out var entity))
{
if (entity.monitorId <= 0 || entity.markerId <= 0 || entity.powerNodeId <= 0)
{
Plugin.Log.LogError((object)$"Signal Nexus entity {entityId} is missing components: monitor={entity.monitorId}, marker={entity.markerId}, node={entity.powerNodeId}.");
}
else
{
NexusLookup.SyncMarkerFromMonitor(__instance, entity);
}
}
}
}
[HarmonyPatch(typeof(UIMonitorWindow))]
internal static class MonitorWindowPatch
{
private const float HoloSectionHeight = 196f;
private static UIMarkerDesc _embeddedMarker;
private static Vector2 _originalMonitorSize;
private static Transform _originalParent;
private static Vector2 _originalAnchorMin;
private static Vector2 _originalAnchorMax;
private static Vector2 _originalPivot;
private static Vector2 _originalAnchoredPosition;
private static Vector2 _originalMarkerSize;
private static RectTransform _advancedRect;
private static Transform _originalAdvancedParent;
private static Vector2 _originalAdvancedAnchorMin;
private static Vector2 _originalAdvancedAnchorMax;
private static Vector2 _originalAdvancedPivot;
private static Vector2 _originalAdvancedPosition;
private static Vector2 _originalAdvancedSize;
private static CanvasGroup _rootCanvas;
private static float _originalRootAlpha;
private static bool _originalRootBlocksRaycasts;
private static bool _originalRootInteractable;
private static GameObject _holoHeader;
private static RectTransform _holoHeaderRect;
private static float _holoBaseX;
private static float _holoBaseY;
private static bool _embedded;
[HarmonyPostfix]
[HarmonyPatch("_OnOpen")]
private static void OpenPostfix(UIMonitorWindow __instance)
{
try
{
PlanetFactory factory = __instance.factory;
int value = Traverse.Create((object)__instance).Field<int>("_monitorId").Value;
if (!NexusLookup.TryGetFromMonitor(factory, value, out var _, out var _, out var marker))
{
Hide(__instance);
return;
}
EnsureEmbedded(__instance);
if ((Object)(object)_embeddedMarker == (Object)null)
{
Plugin.Log.LogWarning((object)"Signal Nexus could not find the Holo Beacon settings panel to embed.");
return;
}
((Component)_embeddedMarker).gameObject.SetActive(true);
_embeddedMarker.advancedSettingsGo.SetActive(true);
_embeddedMarker.SetData(factory, marker, true);
InvokeLifecycle(_embeddedMarker, "_OnOpen");
_embeddedMarker.advancedSettingsGo.SetActive(true);
_embeddedMarker.advancedCanvasGroup.alpha = 1f;
_embeddedMarker.advancedCanvasGroup.blocksRaycasts = true;
_embeddedMarker.advancedCanvasGroup.interactable = true;
_embeddedMarker.Refresh();
NexusLookup.SyncMonitorFromMarker(factory, marker);
ApplyLayout(__instance);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Signal Nexus isolated a combined-panel opening failure: {arg}");
}
}
[HarmonyFinalizer]
[HarmonyPatch("_OnOpen")]
private static Exception OpenFinalizer(UIMonitorWindow __instance, Exception __exception)
{
if (__exception == null)
{
return null;
}
if (!(__exception is NullReferenceException))
{
return __exception;
}
try
{
OpenPostfix(__instance);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Signal Nexus monitor-window recovery failed: {arg}");
}
Plugin.Log.LogWarning((object)string.Format("Signal Nexus suppressed DSP's null speaker-panel failure while opening monitor {0}.", Traverse.Create((object)__instance).Field<int>("_monitorId").Value));
return null;
}
[HarmonyPrefix]
[HarmonyPatch("_OnClose")]
private static void ClosePrefix(UIMonitorWindow __instance)
{
Hide(__instance);
}
[HarmonyPostfix]
[HarmonyPatch("_OnUpdate")]
private static void UpdatePostfix(UIMonitorWindow __instance)
{
if (_embedded && !((Object)(object)_embeddedMarker == (Object)null))
{
InvokeLifecycle(_embeddedMarker, "_OnUpdate");
ApplyLayout(__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch("AdaptSpeaker")]
private static void AdaptSpeakerPostfix(UIMonitorWindow __instance)
{
//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)
if (_embedded)
{
_originalMonitorSize = __instance.monitorWindowRect.sizeDelta;
ApplyLayout(__instance);
}
}
private static void EnsureEmbedded(UIMonitorWindow monitorWindow)
{
//IL_0044: 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_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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: 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_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_0097: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: 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_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_0109: 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_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_02b2: Unknown result type (might be due to invalid IL or missing references)
//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
//IL_030c: Unknown result type (might be due to invalid IL or missing references)
//IL_0325: Unknown result type (might be due to invalid IL or missing references)
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_034d: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
if (_embedded)
{
return;
}
UIMarkerDesc val = UIRoot.instance?.uiGame?.markerWindow?.markerDesc;
if ((Object)(object)val == (Object)null)
{
return;
}
RectTransform monitorWindowRect = monitorWindow.monitorWindowRect;
_originalMonitorSize = monitorWindowRect.sizeDelta;
_embeddedMarker = val;
RectTransform rectTrans = _embeddedMarker.rectTrans;
_originalParent = ((Transform)rectTrans).parent;
_originalAnchorMin = rectTrans.anchorMin;
_originalAnchorMax = rectTrans.anchorMax;
_originalPivot = rectTrans.pivot;
_originalAnchoredPosition = rectTrans.anchoredPosition;
_originalMarkerSize = rectTrans.sizeDelta;
Transform transform = ((Component)_embeddedMarker.advancedCanvasGroup).transform;
_advancedRect = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)_advancedRect == (Object)null)
{
return;
}
_originalAdvancedParent = ((Transform)_advancedRect).parent;
_originalAdvancedAnchorMin = _advancedRect.anchorMin;
_originalAdvancedAnchorMax = _advancedRect.anchorMax;
_originalAdvancedPivot = _advancedRect.pivot;
_originalAdvancedPosition = _advancedRect.anchoredPosition;
_originalAdvancedSize = _advancedRect.sizeDelta;
_rootCanvas = ((Component)rectTrans).GetComponent<CanvasGroup>() ?? ((Component)rectTrans).gameObject.AddComponent<CanvasGroup>();
_originalRootAlpha = _rootCanvas.alpha;
_originalRootBlocksRaycasts = _rootCanvas.blocksRaycasts;
_originalRootInteractable = _rootCanvas.interactable;
_rootCanvas.alpha = 0f;
_rootCanvas.blocksRaycasts = false;
_rootCanvas.interactable = false;
Text val2 = ((IEnumerable<Text>)((Component)monitorWindow).GetComponentsInChildren<Text>(true)).FirstOrDefault((Func<Text, bool>)((Text text) => (Object)(object)text != (Object)null && text.text != null && text.text.IndexOf("Alarm settings", StringComparison.OrdinalIgnoreCase) >= 0));
if ((Object)(object)val2 == (Object)null)
{
val2 = ((IEnumerable<Text>)((Component)monitorWindow).GetComponentsInChildren<Text>(true)).FirstOrDefault((Func<Text, bool>)((Text text) => (Object)(object)text != (Object)null && ((Object)((Component)text).gameObject).name.IndexOf("alarm", StringComparison.OrdinalIgnoreCase) >= 0));
}
if ((Object)(object)val2 != (Object)null)
{
_holoHeader = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.parent);
((Object)_holoHeader).name = "signal-nexus-holo-settings-header";
Transform transform2 = _holoHeader.transform;
_holoHeaderRect = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
RectTransform rectTransform = ((Graphic)val2).rectTransform;
((Transform)_holoHeaderRect).SetParent((Transform)(object)monitorWindowRect, true);
((Transform)_holoHeaderRect).position = ((Transform)rectTransform).position;
_holoBaseX = _holoHeaderRect.anchoredPosition.x;
_holoBaseY = _holoHeaderRect.anchoredPosition.y;
_holoHeader.GetComponent<Text>().text = Localization.Translate("SignalNexusHoloSettings");
}
((Transform)rectTrans).SetParent((Transform)(object)monitorWindowRect, false);
rectTrans.anchorMin = new Vector2(0f, 1f);
rectTrans.anchorMax = new Vector2(0f, 1f);
rectTrans.pivot = new Vector2(0f, 1f);
((Transform)rectTrans).localScale = Vector3.one;
((Transform)_advancedRect).SetParent((Transform)(object)monitorWindowRect, false);
_advancedRect.anchorMin = new Vector2(0f, 1f);
_advancedRect.anchorMax = new Vector2(0f, 1f);
_advancedRect.pivot = new Vector2(0f, 1f);
((Transform)_advancedRect).localScale = Vector3.one;
_embedded = true;
ApplyLayout(monitorWindow);
Plugin.Log.LogInfo((object)"Attached Holo Beacon settings beneath the Traffic Monitor alarm settings.");
}
private static void ApplyLayout(UIMonitorWindow monitorWindow)
{
//IL_0092: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: 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_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
if (_embedded && !((Object)(object)_advancedRect == (Object)null))
{
RectTransform monitorWindowRect = monitorWindow.monitorWindowRect;
float num = (((Object)(object)_holoHeaderRect != (Object)null) ? _holoBaseX : 20f);
float num2 = (((Object)(object)_holoHeaderRect != (Object)null) ? _holoBaseY : (-344f)) - 92f;
if ((Object)(object)_holoHeaderRect != (Object)null)
{
_holoHeader.SetActive(true);
_holoHeaderRect.anchoredPosition = new Vector2(num, num2);
}
_advancedRect.anchoredPosition = new Vector2(num + 10f, num2 - 22f);
RectTransform advancedRect = _advancedRect;
float x = _originalAdvancedSize.x;
Rect rect = monitorWindowRect.rect;
advancedRect.sizeDelta = new Vector2(Math.Max(x, ((Rect)(ref rect)).width - 78f), Math.Max(_originalAdvancedSize.y, 176f));
RectTransform rectTrans = _embeddedMarker.rectTrans;
rectTrans.anchoredPosition = _advancedRect.anchoredPosition;
rectTrans.sizeDelta = _advancedRect.sizeDelta;
monitorWindowRect.sizeDelta = new Vector2(_originalMonitorSize.x, _originalMonitorSize.y + 196f);
}
}
private static void Hide(UIMonitorWindow monitorWindow)
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_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_00df: 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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: 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_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: 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)
if (!((Object)(object)_embeddedMarker == (Object)null) && _embedded)
{
if (((Component)_embeddedMarker).gameObject.activeSelf)
{
InvokeLifecycle(_embeddedMarker, "_OnClose");
}
if ((Object)(object)_advancedRect != (Object)null)
{
((Transform)_advancedRect).SetParent(_originalAdvancedParent, false);
_advancedRect.anchorMin = _originalAdvancedAnchorMin;
_advancedRect.anchorMax = _originalAdvancedAnchorMax;
_advancedRect.pivot = _originalAdvancedPivot;
_advancedRect.anchoredPosition = _originalAdvancedPosition;
_advancedRect.sizeDelta = _originalAdvancedSize;
}
RectTransform rectTrans = _embeddedMarker.rectTrans;
((Transform)rectTrans).SetParent(_originalParent, false);
rectTrans.anchorMin = _originalAnchorMin;
rectTrans.anchorMax = _originalAnchorMax;
rectTrans.pivot = _originalPivot;
rectTrans.anchoredPosition = _originalAnchoredPosition;
rectTrans.sizeDelta = _originalMarkerSize;
if ((Object)(object)_rootCanvas != (Object)null)
{
_rootCanvas.alpha = _originalRootAlpha;
_rootCanvas.blocksRaycasts = _originalRootBlocksRaycasts;
_rootCanvas.interactable = _originalRootInteractable;
}
_embeddedMarker.advancedSettingsGo.SetActive(false);
((Component)_embeddedMarker).gameObject.SetActive(false);
if ((Object)(object)_holoHeader != (Object)null)
{
_holoHeader.SetActive(false);
}
if (_originalMonitorSize != Vector2.zero)
{
monitorWindow.monitorWindowRect.sizeDelta = _originalMonitorSize;
}
_embedded = false;
}
}
private static void InvokeLifecycle(object target, string method)
{
try
{
AccessTools.Method(target.GetType(), method, (Type[])null, (Type[])null)?.Invoke(target, null);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Signal Nexus UI lifecycle " + method + " failed: " + ex.GetBaseException().Message));
}
}
}
[HarmonyPatch(typeof(UIMonitorWindow), "TryOpenSpeakerPanel")]
internal static class MonitorSpeakerPatch
{
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool Prefix(UIMonitorWindow __instance)
{
try
{
OpenSafeSpeakerPanel(__instance);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Signal Nexus isolated a monitor/speaker opening failure: {arg}");
}
return false;
}
private static void OpenSafeSpeakerPanel(UIMonitorWindow __instance)
{
PlanetFactory factory = __instance.factory;
CargoTraffic val = __instance.cargoTraffic ?? factory?.cargoTraffic;
int value = Traverse.Create((object)__instance).Field<int>("_monitorId").Value;
if (factory == null || val?.monitorPool == null || value <= 0 || value >= val.monitorCursor)
{
return;
}
ref MonitorComponent reference = ref val.monitorPool[value];
if (reference.id != value)
{
return;
}
UISpeakerPanel speakerPanel = __instance.speakerPanel;
if ((Object)(object)speakerPanel == (Object)null)
{
Plugin.Log.LogWarning((object)$"Monitor {value} opened without a UISpeakerPanel; skipping only the speaker subpanel.");
return;
}
MethodInfo methodInfo = AccessTools.Method(typeof(UIMonitorWindow), "AdaptSpeaker", (Type[])null, (Type[])null);
Action action = ((methodInfo == null) ? null : ((Action)Delegate.CreateDelegate(typeof(Action), __instance, methodInfo)));
if (reference.alarmMode != 0)
{
if (reference.entityId <= 0 || reference.entityId >= factory.entityCursor)
{
return;
}
ref EntityData reference2 = ref factory.entityPool[reference.entityId];
if (reference2.id != reference.entityId)
{
return;
}
DigitalSystem digitalSystem = factory.digitalSystem;
int num = reference2.speakerId;
if (digitalSystem != null && (num <= 0 || digitalSystem.speakerPool == null || num >= digitalSystem.speakerCursor || digitalSystem.speakerPool[num].id != num))
{
num = (reference.speakerId = (reference2.speakerId = digitalSystem.NewSpeakerComponent(reference2.id)));
Plugin.Log.LogInfo((object)$"Repaired missing speaker component for monitor entity {reference2.id} (speaker {num}).");
}
if (num <= 0)
{
return;
}
reference.speakerId = num;
Traverse obj = Traverse.Create((object)speakerPanel);
obj.Field("factory").SetValue((object)factory);
obj.Field("digitalSystem").SetValue((object)digitalSystem);
obj.Field("player").SetValue((object)GameMain.mainPlayer);
speakerPanel.speakerId = num;
if (action != null)
{
speakerPanel.onWindowChange = (Action)Delegate.Remove(speakerPanel.onWindowChange, action);
speakerPanel.onWindowChange = (Action)Delegate.Combine(speakerPanel.onWindowChange, action);
}
((ManualBehaviour)speakerPanel)._Open();
}
else
{
if (action != null)
{
speakerPanel.onWindowChange = (Action)Delegate.Remove(speakerPanel.onWindowChange, action);
}
((ManualBehaviour)speakerPanel)._Close();
}
action?.Invoke();
}
}
[HarmonyPatch(typeof(UIMonitorWindow), "OnDigitalSignalIdEndEdit")]
internal static class MonitorIpPatch
{
[HarmonyPostfix]
private static void Postfix(UIMonitorWindow __instance)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
PlanetFactory value = Traverse.Create((object)__instance).Field<PlanetFactory>("factory").Value;
int value2 = Traverse.Create((object)__instance).Field<int>("_monitorId").Value;
if (NexusLookup.TryGetFromMonitor(value, value2, out var entity, out var _, out var _))
{
NexusLookup.SyncMarkerFromMonitor(value, entity);
}
}
}
[HarmonyPatch(typeof(UIMarkerDesc), "OnDigitalSignalIdEndEdit")]
internal static class MarkerIpPatch
{
[HarmonyPostfix]
private static void Postfix(UIMarkerDesc __instance)
{
PlanetFactory value = Traverse.Create((object)__instance).Field<PlanetFactory>("factory").Value;
MarkerComponent value2 = Traverse.Create((object)__instance).Field<MarkerComponent>("marker").Value;
NexusLookup.SyncMonitorFromMarker(value, value2);
}
}
[HarmonyPatch(typeof(UIMarkerTipIcons), "_OnLateUpdate")]
internal static class MarkerTipGuardPatch
{
[HarmonyPrefix]
private static void Prefix(UIMarkerTipIcons __instance)
{
Traverse val = Traverse.Create((object)__instance);
if (!((Object)(object)val.Field<UIMarkerTip>("markerTip").Value != (Object)null))
{
val.Field("hoverIdx").SetValue((object)(-1));
val.Field("showTipIdx").SetValue((object)(-1));
val.Field("timer").SetValue((object)0f);
}
}
}
[HarmonyPatch(typeof(BuildingParameters), "CopyFromFactoryObject")]
internal static class BuildingCopyPatch
{
[HarmonyPostfix]
private static void Postfix(ref BuildingParameters __instance, int objectId, PlanetFactory factory, bool __result)
{
//IL_000e: 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_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
if (!__result || !NexusLookup.TryGetEntity(factory, objectId, out var entity) || entity.markerId <= 0 || entity.monitorId <= 0)
{
return;
}
MarkerComponent val = factory.digitalSystem.markers[entity.markerId];
if (val == null)
{
return;
}
ref MonitorComponent reference = ref factory.cargoTraffic.monitorPool[entity.monitorId];
int[] array = new int[128];
array[0] = reference.targetBeltId;
array[1] = reference.offset;
array[2] = reference.targetCargoBytes;
array[3] = ((MonitorComponent)(ref reference)).curPeriodTickCount;
array[4] = reference.passOperator;
array[5] = reference.passColorId;
array[6] = reference.failColorId;
array[10] = reference.systemWarningMode;
array[12] = reference.alarmMode;
array[14] = reference.cargoFilter;
array[17] = reference.systemWarningSignalId;
array[21] = reference.digitalSignalId;
if (entity.speakerId > 0 && factory.digitalSystem.speakerPool != null && entity.speakerId < factory.digitalSystem.speakerCursor)
{
ref SpeakerComponent reference2 = ref factory.digitalSystem.speakerPool[entity.speakerId];
if (reference2.id == entity.speakerId)
{
array[7] = reference2.tone;
array[8] = reference2.volume;
array[9] = reference2.pitch;
array[11] = (reference2.repeat ? 1 : 0);
array[13] = Mathf.RoundToInt(reference2.length * 10000f);
array[18] = Mathf.RoundToInt(reference2.falloffRadius0 * 10f);
array[19] = Mathf.RoundToInt(reference2.falloffRadius1 * 10f);
}
}
__instance.type = (BuildingType)15;
__instance.mode0 = reference.spawnItemOperator;
__instance.parameters = array;
__instance.content = MarkerSettings.Encode(val);
}
}
[HarmonyPatch(typeof(BuildingParameters), "PasteToFactoryObject")]
internal static class BuildingPastePatch
{
[HarmonyPostfix]
private static void Postfix(BuildingParameters __instance, int objectId, PlanetFactory factory, bool __result)
{
//IL_000e: 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_0032: Unknown result type (might be due to invalid IL or missing references)
if (__result && NexusLookup.TryGetEntity(factory, objectId, out var entity) && entity.markerId > 0)
{
MarkerComponent val = factory.digitalSystem.markers[entity.markerId];
if (val != null)
{
MarkerSettings.TryApply(__instance.content, val, factory.entityPool);
}
}
}
}
[HarmonyPatch(typeof(BuildTool_Addon), "CreatePrebuilds")]
internal static class AddonPrebuildContentPatch
{
[HarmonyPostfix]
private static void Postfix(BuildTool_Addon __instance)
{
PlanetFactory factory = ((BuildTool)__instance).factory;
if (factory?.prebuildPool == null || ((BuildTool)__instance).buildPreviews == null)
{
return;
}
foreach (BuildPreview buildPreview in ((BuildTool)__instance).buildPreviews)
{
if (buildPreview?.item == null || ((Proto)buildPreview.item).ID != Plugin.ItemId || buildPreview.objId >= 0 || string.IsNullOrEmpty(buildPreview.content))
{
continue;
}
int num = -buildPreview.objId;
if (num > 0 && num < factory.prebuildCursor)
{
ref PrebuildData reference = ref factory.prebuildPool[num];
if (reference.id == num && reference.protoId == Plugin.ItemId)
{
reference.content = buildPreview.content;
Plugin.Log.LogInfo((object)$"Preserved Holo settings on copied Signal Nexus prebuild {num}.");
}
}
}
}
}
[HarmonyPatch(typeof(BuildingParameters), "ApplyPrebuildParametersToEntity")]
internal static class BuildingApplyPatch
{
[HarmonyPostfix]
private static void Postfix(int entityId, string content, PlanetFactory factory)
{
//IL_000b: 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_003f: Unknown result type (might be due to invalid IL or missing references)
if (NexusLookup.TryGetEntity(factory, entityId, out var entity) && entity.markerId > 0)
{
MarkerComponent val = factory.digitalSystem.markers[entity.markerId];
if (val == null || !MarkerSettings.TryApply(content, val, factory.entityPool))
{
NexusLookup.SyncMarkerFromMonitor(factory, entity);
}
}
}
}
internal static class MarkerSettings
{
private const string Prefix = "SIGNAL_NEXUS_1:";
internal static string Encode(MarkerComponent marker)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected I4, but got Unknown
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected I4, but got Unknown
using MemoryStream memoryStream = new MemoryStream();
using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write(marker.icon);
binaryWriter.Write(marker.word ?? string.Empty);
binaryWriter.Write((int)marker.visibility);
binaryWriter.Write((int)marker.detailLevel);
binaryWriter.Write(marker.offline);
binaryWriter.Write(marker.color);
binaryWriter.Write(marker.height);
binaryWriter.Write(marker.radius);
binaryWriter.Write(marker.digitalSignalId);
binaryWriter.Write(marker.dfAttractionFlags);
binaryWriter.Write(marker.name ?? string.Empty);
binaryWriter.Write(marker.tags ?? string.Empty);
}
return "SIGNAL_NEXUS_1:" + Convert.ToBase64String(memoryStream.ToArray());
}
internal static bool TryApply(string content, MarkerComponent marker, EntityData[] entities)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (string.IsNullOrEmpty(content) || !content.StartsWith("SIGNAL_NEXUS_1:", StringComparison.Ordinal))
{
return false;
}
try
{
using BinaryReader binaryReader = new BinaryReader(new MemoryStream(Convert.FromBase64String(content.Substring("SIGNAL_NEXUS_1:".Length))));
marker.icon = binaryReader.ReadInt32();
marker.word = binaryReader.ReadString();
marker.visibility = (EMarkerVisibility)binaryReader.ReadInt32();
marker.detailLevel = (EMarkerDetailLevel)binaryReader.ReadInt32();
marker.offline = binaryReader.ReadBoolean();
marker.color = binaryReader.ReadByte();
marker.SetHeight(entities, binaryReader.ReadSingle());
marker.SetRadius(binaryReader.ReadSingle());
marker.SetDigitalSignalId(binaryReader.ReadInt32());
marker.SetDFAttractionFlags(binaryReader.ReadInt32());
marker.name = binaryReader.ReadString();
marker.tags = binaryReader.ReadString();
return true;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not restore Signal Nexus beacon settings: " + ex.Message));
return false;
}
}
}
[BepInPlugin("codex.dsp.signal-nexus", "Signal Nexus", "0.2.13")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "codex.dsp.signal-nexus";
public const string PluginName = "Signal Nexus";
public const string PluginVersion = "0.2.13";
private const int PreferredItemId = 9600;
private const int PreferredRecipeId = 9600;
private const int PreferredModelId = 722;
internal static ManualLogSource Log;
internal static ItemProto TrafficMonitor;
internal static ItemProto HoloBeacon;
internal static ItemProto TeslaTower;
internal static ItemProto NexusItem;
internal static RecipeProto NexusRecipe;
internal static ModelProto NexusModel;
private Harmony _harmony;
public static int ItemId { get; private set; } = 9600;
public static int RecipeId { get; private set; } = 9600;
public static int ModelId { get; private set; } = 722;
private void Awake()
{
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
RegisterStrings();
LDBTool.PreAddDataAction = (Action)Delegate.Combine(LDBTool.PreAddDataAction, new Action(AddPrototypes));
LDBTool.PostAddDataAction = (Action)Delegate.Combine(LDBTool.PostAddDataAction, new Action(FinishPrototypes));
_harmony = new Harmony("codex.dsp.signal-nexus");
_harmony.PatchAll(typeof(EntityComponentPatch));
_harmony.PatchAll(typeof(NexusInspectPatch));
_harmony.PatchAll(typeof(MonitorWindowPatch));
_harmony.PatchAll(typeof(MonitorSpeakerPatch));
_harmony.PatchAll(typeof(MonitorIpPatch));
_harmony.PatchAll(typeof(MarkerIpPatch));
_harmony.PatchAll(typeof(MarkerTipGuardPatch));
_harmony.PatchAll(typeof(BuildingCopyPatch));
_harmony.PatchAll(typeof(BuildingPastePatch));
_harmony.PatchAll(typeof(AddonPrebuildContentPatch));
_harmony.PatchAll(typeof(BuildingApplyPatch));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Signal Nexus prototype and combined monitor/beacon UI patches registered.");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
LDBTool.PreAddDataAction = (Action)Delegate.Remove(LDBTool.PreAddDataAction, new Action(AddPrototypes));
LDBTool.PostAddDataAction = (Action)Delegate.Remove(LDBTool.PostAddDataAction, new Action(FinishPrototypes));
}
private static void RegisterStrings()
{
LocalizationModule.RegisterTranslation("SignalNexusName", "Signal Nexus", "信号枢纽", "Signal Nexus");
LocalizationModule.RegisterTranslation("SignalNexusDesc", "A belt traffic monitor, Holo Beacon and Tesla Tower integrated into one compact facility. Its shared IP drives the beacon colour from the monitor signal, while the built-in power node connects and powers nearby facilities.", "将传送带流速监测器、全息信标与电力感应塔集成为一体。共享 IP 会使用监测信号控制信标颜色,内置电力节点还能连接并供电给附近设施。", "A belt traffic monitor, Holo Beacon and Tesla Tower integrated into one compact facility.");
LocalizationModule.RegisterTranslation("SignalNexusRecipeDesc", "Combine three vanilla utility buildings into one Signal Nexus.", "将三种原版功能建筑组合成一个信号枢纽。", "Combine three vanilla utility buildings into one Signal Nexus.");
LocalizationModule.RegisterTranslation("SignalNexusHoloSettings", "Holo settings", "全息设置", "Holo settings");
}
private static void AddPrototypes()
{
//IL_037a: Unknown result type (might be due to invalid IL or missing references)
//IL_0380: Expected O, but got Unknown
//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
ItemId = FindFreeId(9600, from proto in ((ProtoSet<ItemProto>)(object)LDB.items).dataArray
where proto != null
select ((Proto)proto).ID);
RecipeId = FindFreeId(9600, from proto in ((ProtoSet<RecipeProto>)(object)LDB.recipes).dataArray
where proto != null
select ((Proto)proto).ID);
ModelId = FindFreeId(722, from proto in ((ProtoSet<ModelProto>)(object)LDB.models).dataArray
where proto != null
select ((Proto)proto).ID);
TrafficMonitor = FindItem("流速器", "Traffic Monitor");
HoloBeacon = FindItem("激光灯塔", "Holo Beacon");
TeslaTower = FindItem("电力感应塔", "Tesla Tower");
if (TrafficMonitor == null || HoloBeacon == null || TeslaTower == null)
{
Log.LogError((object)"Signal Nexus could not locate all three vanilla source prototypes.");
return;
}
int gridIndex = FindFreeCraftingGridIndex(TrafficMonitor, ItemId);
int buildIndex = FindFreeBuildIndex(TrafficMonitor.BuildIndex / 100, ItemId);
ModelProto val = ((ProtoSet<ModelProto>)(object)LDB.models).Select(TrafficMonitor.ModelIndex);
if (val == null)
{
Log.LogError((object)"Signal Nexus could not locate the Traffic Monitor model prototype.");
return;
}
NexusModel = ShallowClone<ModelProto>(val);
((Proto)NexusModel).ID = ModelId;
((Proto)NexusModel).Name = "SignalNexusModel";
NexusModel.prefabDesc = ShallowClone<PrefabDesc>(val.prefabDesc);
NexusModel.prefabDesc.modelIndex = ModelId;
Traverse.Create((object)NexusModel).Field("prewarmed").SetValue((object)false);
LDBTool.PreAddProto((Proto)(object)NexusModel);
NexusItem = ShallowClone<ItemProto>(TrafficMonitor);
((Proto)NexusItem).ID = ItemId;
((Proto)NexusItem).Name = "SignalNexusName";
((Proto)NexusItem).name = "Signal Nexus";
NexusItem.Description = "SignalNexusDesc";
NexusItem.description = "SignalNexusDesc";
NexusItem.ModelIndex = ModelId;
NexusItem.ModelCount = 1;
NexusItem.BuildIndex = buildIndex;
NexusItem.GridIndex = gridIndex;
NexusItem.StackSize = Math.Max(TrafficMonitor.StackSize, 50);
NexusItem.prefabDesc = NexusModel.prefabDesc;
NexusItem.handcraft = null;
NexusItem.maincraft = null;
NexusItem.handcrafts = new List<RecipeProto>();
NexusItem.recipes = new List<RecipeProto>();
NexusItem.makes = new List<RecipeProto>();
LDBTool.PreAddProto((Proto)(object)NexusItem);
RecipeProto val2 = new RecipeProto();
((Proto)val2).ID = RecipeId;
((Proto)val2).Name = "SignalNexusName";
((Proto)val2).name = "Signal Nexus";
val2.Description = "SignalNexusRecipeDesc";
val2.description = "SignalNexusRecipeDesc";
val2.Type = (ERecipeType)4;
val2.Handcraft = true;
val2.Explicit = false;
val2.TimeSpend = 120;
val2.Items = new int[3]
{
((Proto)TrafficMonitor).ID,
((Proto)HoloBeacon).ID,
((Proto)TeslaTower).ID
};
val2.ItemCounts = new int[3] { 1, 1, 1 };
val2.Results = new int[1] { ItemId };
val2.ResultCounts = new int[1] { 1 };
val2.GridIndex = NexusItem.GridIndex;
val2.preTech = HoloBeacon.preTech ?? TrafficMonitor.preTech;
NexusRecipe = val2;
LDBTool.PreAddProto((Proto)(object)NexusRecipe);
NexusItem.handcraft = NexusRecipe;
NexusItem.maincraft = NexusRecipe;
NexusItem.handcrafts.Add(NexusRecipe);
NexusItem.recipes.Add(NexusRecipe);
Log.LogInfo((object)$"Registered Signal Nexus item {ItemId}, recipe {RecipeId}, model {ModelId}; temporary grid {NexusItem.GridIndex}, build {NexusItem.BuildIndex}. Traffic Monitor remains untouched.");
}
private static int FindFreeId(int preferred, IEnumerable<int> occupiedIds)
{
HashSet<int> hashSet = new HashSet<int>(occupiedIds);
for (int i = preferred; i < preferred + 300; i++)
{
if (!hashSet.Contains(i))
{
return i;
}
}
throw new InvalidOperationException($"Signal Nexus could not find a free prototype ID in {preferred}-{preferred + 300 - 1}.");
}
private static void FinishPrototypes()
{
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
NexusItem = ((ProtoSet<ItemProto>)(object)LDB.items).Select(ItemId);
NexusRecipe = ((ProtoSet<RecipeProto>)(object)LDB.recipes).Select(RecipeId);
NexusModel = ((ProtoSet<ModelProto>)(object)LDB.models).Select(ModelId);
if (NexusItem != null && NexusRecipe != null && NexusModel != null && TrafficMonitor != null && HoloBeacon != null && TeslaTower != null)
{
int num = FindFreeCraftingGridIndex(TrafficMonitor, ItemId);
int num2 = FindFreeBuildIndex(TrafficMonitor.BuildIndex / 100, ItemId);
NexusItem.GridIndex = num;
NexusRecipe.GridIndex = num;
NexusItem.BuildIndex = num2;
LDBTool.SetBuildBar(num2 / 100, num2 % 100, ItemId);
PrefabDesc prefabDesc = TrafficMonitor.prefabDesc;
PrefabDesc prefabDesc2 = HoloBeacon.prefabDesc;
PrefabDesc prefabDesc3 = TeslaTower.prefabDesc;
PrefabDesc val = ShallowClone<PrefabDesc>(prefabDesc);
val.modelIndex = ModelId;
val.dragBuild = false;
val.isMonitor = true;
val.isSpeaker = true;
val.isMarker = true;
val.markerPointDefaultHeight = prefabDesc2.markerPointDefaultHeight;
val.markerPointDefaultRadius = prefabDesc2.markerPointDefaultRadius;
val.isPowerNode = true;
val.powerConnectDistance = prefabDesc3.powerConnectDistance;
val.powerCoverRadius = prefabDesc3.powerCoverRadius;
val.powerPoint = new Vector3(0f, Math.Max(1.7f, prefabDesc.roughHeight), 0f);
val.isPowerConsumer = true;
val.workEnergyPerTick = Math.Max(1L, prefabDesc.workEnergyPerTick + prefabDesc2.workEnergyPerTick);
val.idleEnergyPerTick = Math.Max(1L, prefabDesc.idleEnergyPerTick + prefabDesc2.idleEnergyPerTick);
TryBuildCompositeMeshes(val, prefabDesc, prefabDesc2);
NexusModel.prefabDesc = val;
NexusModel.meshBounds = (((Object)(object)val.mesh != (Object)null) ? val.mesh.bounds : NexusModel.meshBounds);
NexusItem.prefabDesc = val;
NexusItem.ModelIndex = ModelId;
Sprite value = CreateIcon();
Traverse.Create((object)NexusItem).Field("_iconSprite").SetValue((object)value);
Traverse.Create((object)NexusRecipe).Field("_iconSprite").SetValue((object)value);
NexusRecipe.IconPath = string.Empty;
Log.LogInfo((object)$"Signal Nexus ready at grid {num}, build {num2}: monitor + marker + {val.powerConnectDistance:0.#}m power connection / {val.powerCoverRadius:0.#}m coverage. Traffic Monitor grid {TrafficMonitor.GridIndex}, build {TrafficMonitor.BuildIndex}.");
}
}
private static ItemProto FindItem(params string[] names)
{
return ((IEnumerable<ItemProto>)((ProtoSet<ItemProto>)(object)LDB.items).dataArray).FirstOrDefault((Func<ItemProto, bool>)((ItemProto item) => item != null && names.Any((string name) => string.Equals(((Proto)item).Name, name, StringComparison.OrdinalIgnoreCase) || string.Equals(((Proto)item).name, name, StringComparison.OrdinalIgnoreCase))));
}
private static int FindFreeCraftingGridIndex(ItemProto template, int excludedItemId)
{
HashSet<int> hashSet = new HashSet<int>(from item in ((ProtoSet<ItemProto>)(object)LDB.items).dataArray
where item != null && ((Proto)item).ID != excludedItemId && item.Type == template.Type
select item.GridIndex);
int baseRow = Math.Max(1, Math.Min(8, (template.GridIndex - 2000) / 100));
int baseColumn = Math.Max(1, Math.Min(14, template.GridIndex % 100));
foreach (var item in from slot in Enumerable.Range(1, 8).SelectMany((int row) => from column in Enumerable.Range(1, 14)
select new { row, column })
orderby Math.Abs(slot.row - baseRow) + Math.Abs(slot.column - baseColumn), slot.row, slot.column
select slot)
{
int num = 2000 + item.row * 100 + item.column;
if (!hashSet.Contains(num))
{
return num;
}
}
return 2814;
}
private static int NextBuildIndex()
{
return (from x in ((ProtoSet<ItemProto>)(object)LDB.items).dataArray
where x != null
select x.BuildIndex).DefaultIfEmpty(700).Max() + 1;
}
private static int FindFreeBuildIndex(int preferredCategory, int excludedItemId = 0)
{
HashSet<int> hashSet = new HashSet<int>(from item in ((ProtoSet<ItemProto>)(object)LDB.items).dataArray
where item != null && ((Proto)item).ID != excludedItemId && item.BuildIndex > 0
select item.BuildIndex);
if (preferredCategory >= 1 && preferredCategory <= 15)
{
for (int num = 12; num >= 1; num--)
{
int num2 = preferredCategory * 100 + num;
if (!hashSet.Contains(num2))
{
return num2;
}
}
}
for (int num3 = 12; num3 >= 1; num3--)
{
for (int num4 = 12; num4 >= 1; num4--)
{
int num5 = num3 * 100 + num4;
if (!hashSet.Contains(num5))
{
return num5;
}
}
}
return NextBuildIndex();
}
internal static T ShallowClone<T>(T source) where T : class
{
if (source == null)
{
return null;
}
return (T)AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null).Invoke(source, null);
}
private static void TryBuildCompositeMeshes(PrefabDesc target, PrefabDesc traffic, PrefabDesc marker)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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_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_0099: 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_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: 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_0126: Expected O, but got Unknown
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
try
{
if (traffic.lodMeshes == null || marker.lodMeshes == null)
{
return;
}
int num = Math.Max(traffic.lodMeshes.Length, marker.lodMeshes.Length);
target.lodMeshes = (Mesh[])(object)new Mesh[num];
target.lodMaterials = new Material[num][];
target.lodBlueprintMaterials = new Material[num][];
target.lodSubmeshIgnores = new bool[num][];
Matrix4x4 transform = Matrix4x4.TRS(new Vector3(0f, Math.Max(0.75f, traffic.roughHeight * 0.55f), 0f), Quaternion.identity, Vector3.one * 0.34f);
for (int i = 0; i < num; i++)
{
Mesh val = traffic.lodMeshes[Math.Min(i, traffic.lodMeshes.Length - 1)];
Mesh val2 = marker.lodMeshes[Math.Min(i, marker.lodMeshes.Length - 1)];
if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
{
List<CombineInstance> list = new List<CombineInstance>();
AddSubmeshes(list, val, Matrix4x4.identity);
AddSubmeshes(list, val2, transform);
Mesh val3 = new Mesh
{
name = $"Signal Nexus LOD {i}"
};
val3.CombineMeshes(list.ToArray(), false, true);
val3.RecalculateBounds();
target.lodMeshes[i] = val3;
Material[] lodMaterials = GetLodMaterials(traffic.lodMaterials, i);
Material[] lodMaterials2 = GetLodMaterials(marker.lodMaterials, i);
target.lodMaterials[i] = lodMaterials.Concat(lodMaterials2).ToArray();
Material[] lodMaterials3 = GetLodMaterials(traffic.lodBlueprintMaterials, i, lodMaterials);
Material[] lodMaterials4 = GetLodMaterials(marker.lodBlueprintMaterials, i, lodMaterials2);
target.lodBlueprintMaterials[i] = lodMaterials3.Concat(lodMaterials4).ToArray();
target.lodSubmeshIgnores[i] = new bool[target.lodMaterials[i].Length];
}
}
target.mesh = ((IEnumerable<Mesh>)target.lodMeshes).FirstOrDefault((Func<Mesh, bool>)((Mesh x) => (Object)(object)x != (Object)null)) ?? traffic.mesh;
target.meshes = (Mesh[])((!((Object)(object)target.mesh != (Object)null)) ? ((Array)traffic.meshes) : ((Array)new Mesh[1] { target.mesh }));
target.materials = target.lodMaterials.FirstOrDefault((Material[] x) => x != null) ?? traffic.materials;
target.roughHeight = Math.Max(traffic.roughHeight, ((Matrix4x4)(ref transform)).MultiplyPoint3x4(Vector3.up * marker.roughHeight).y);
target.cullingHeight = Math.Max(traffic.cullingHeight, target.roughHeight);
Log.LogInfo((object)"Built the Traffic Monitor + roof Holo Beacon composite mesh.");
}
catch (Exception ex)
{
Log.LogWarning((object)("Composite mesh creation failed; using the Traffic Monitor body: " + ex.Message));
}
}
private static void AddSubmeshes(List<CombineInstance> output, Mesh mesh, Matrix4x4 transform)
{
//IL_0007: 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_0025: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < mesh.subMeshCount; i++)
{
CombineInstance item = default(CombineInstance);
((CombineInstance)(ref item)).mesh = mesh;
((CombineInstance)(ref item)).subMeshIndex = i;
((CombineInstance)(ref item)).transform = transform;
output.Add(item);
}
}
private static Material[] GetLodMaterials(Material[][] source, int lod, Material[] fallback = null)
{
if (source == null || source.Length == 0)
{
return fallback ?? Array.Empty<Material>();
}
return source[Math.Min(lod, source.Length - 1)] ?? fallback ?? Array.Empty<Material>();
}
private static Sprite CreateIcon()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: 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_0025: Expected O, but got Unknown
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: 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_00e8: 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_0128: 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_0168: 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_0187: 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)
//IL_0245: 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)
Texture2D val = new Texture2D(80, 80, (TextureFormat)5, false)
{
name = "Signal Nexus Icon",
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1
};
Color[] pixels = Enumerable.Repeat<Color>(new Color(0f, 0f, 0f, 0f), 6400).ToArray();
Color color = default(Color);
((Color)(ref color))..ctor(0.035f, 0.12f, 0.15f, 1f);
Color color2 = default(Color);
((Color)(ref color2))..ctor(0.15f, 0.9f, 1f, 1f);
Color color3 = default(Color);
((Color)(ref color3))..ctor(0.22f, 1f, 0.42f, 1f);
Color color4 = default(Color);
((Color)(ref color4))..ctor(0.9f, 1f, 1f, 1f);
Rect(13, 10, 66, 35, color);
Rect(10, 15, 69, 30, color);
Rect(17, 14, 62, 31, color2);
Rect(21, 18, 58, 27, new Color(0.02f, 0.2f, 0.24f, 1f));
for (int i = 24; i < 57; i += 7)
{
Rect(i, 19, i + 2, 26, color3);
}
Rect(35, 35, 44, 51, color4);
Disc(40, 57, 12, new Color(0.1f, 0.55f, 0.38f, 1f));
Disc(40, 57, 8, color3);
Disc(40, 57, 3, color4);
for (int j = 16; j <= 27; j += 6)
{
for (int k = 0; k < 360; k += 8)
{
float num = (float)k * (MathF.PI / 180f);
Pixel(40 + Mathf.RoundToInt(Mathf.Cos(num) * (float)j), 57 + Mathf.RoundToInt(Mathf.Sin(num) * (float)j * 0.45f), new Color(0.15f, 1f, 0.45f, 0.72f));
}
}
val.SetPixels(pixels);
val.Apply(false, true);
return Sprite.Create(val, new Rect(0f, 0f, 80f, 80f), new Vector2(0.5f, 0.5f), 100f);
void Disc(int cx, int cy, int radius, Color color5)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
for (int l = -radius; l <= radius; l++)
{
for (int m = -radius; m <= radius; m++)
{
if (m * m + l * l <= radius * radius)
{
Pixel(cx + m, cy + l, color5);
}
}
}
}
void Pixel(int x, int y, Color val2)
{
//IL_0016: 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 ((uint)x < 80u && (uint)y < 80u)
{
pixels[y * 80 + x] = val2;
}
}
void Rect(int x0, int y0, int x1, int y1, Color color5)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
for (int l = y0; l <= y1; l++)
{
for (int m = x0; m <= x1; m++)
{
Pixel(m, l, color5);
}
}
}
}
}
}