using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using BuildInSeatruckPlus.Buildables;
using BuildInSeatruckPlus.Patches;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Nautilus.Assets;
using Nautilus.Assets.Gadgets;
using Nautilus.Assets.PrefabTemplates;
using Nautilus.Crafting;
using Nautilus.Handlers;
using Nautilus.Json;
using Nautilus.Options.Attributes;
using UWE;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BuildInSeatruckPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+814d0593c0c38c63b2bb09a75cd9d28c3a1442d9")]
[assembly: AssemblyProduct("BuildInSeatruckPlus")]
[assembly: AssemblyTitle("BuildInSeatruckPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 BuildInSeatruckPlus
{
[Menu("Build In Seatruck Plus")]
public class Config : ConfigFile
{
[Keybind("Playback hotkey (in Seatruck / base)")]
public KeyCode Hotkey = (KeyCode)114;
[Slider("Long-press seconds", 0.1f, 2f, DefaultValue = 0.5f, Step = 0.05f, Format = "{0:F2}")]
public float LongPressSeconds = 0.5f;
[Toggle("Cheap recipe (1 Titanium) - restart required")]
public bool CheapRecipe;
[Toggle("Unlock buildables at start - restart required")]
public bool UnlockBuildables;
[Toggle("New jukeboxes start in shuffle mode")]
public bool DefaultShuffle = true;
[Toggle("Show 'Now playing' notifications")]
public bool ShowTrackName = true;
[Choice("Don't unload containers labeled this color (needs AutosortLockers)", new string[] { })]
public UnloaderSkipColor UnloaderSkipColorChoice = UnloaderSkipColor.Red;
}
public enum UnloaderSkipColor
{
Off,
Red,
Yellow,
Green,
Blue,
Magenta,
White
}
internal class HotkeyController : MonoBehaviour
{
private float _downTime = -1f;
private bool _longFired;
private void Update()
{
//IL_0032: 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_0066: Unknown result type (might be due to invalid IL or missing references)
Config config = Plugin.Config;
if (config == null || (Object)(object)Player.main == (Object)null)
{
return;
}
if (!PlayerInInterior())
{
_downTime = -1f;
_longFired = false;
return;
}
if (Input.GetKeyDown(config.Hotkey))
{
_downTime = Time.unscaledTime;
_longFired = false;
}
if (_downTime >= 0f && !_longFired && Input.GetKey(config.Hotkey) && Time.unscaledTime - _downTime >= config.LongPressSeconds)
{
_longFired = true;
TogglePlayStop();
}
if (Input.GetKeyUp(config.Hotkey))
{
if (_downTime >= 0f && !_longFired)
{
NextTrack();
}
_downTime = -1f;
_longFired = false;
}
}
private static bool PlayerInInterior()
{
if (!(Player.main.currentInterior is SeaTruckSegment))
{
return (Object)(object)Player.main.GetCurrentSub() != (Object)null;
}
return true;
}
private static JukeboxInstance ResolveInstance()
{
//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_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
IInteriorSpace currentInterior = Player.main.currentInterior;
ISpeakerHost host = Speaker.GetHost((MonoBehaviour)(object)((currentInterior is MonoBehaviour) ? currentInterior : null));
if (host == null && (Object)(object)Player.main.GetCurrentSub() != (Object)null)
{
host = Speaker.GetHost((MonoBehaviour)(object)Player.main.GetCurrentSub());
}
JukeboxInstance instance = Jukebox.instance;
Vector3 val = default(Vector3);
float num = default(float);
float num2 = default(float);
if ((Object)(object)instance != (Object)null && ((Behaviour)instance).isActiveAndEnabled && Jukebox.isStartingOrPlaying && Speaker.IsSameHost(Speaker.GetHost((MonoBehaviour)(object)instance), host) && instance.GetSoundPosition(ref val, ref num, ref num2))
{
return instance;
}
Vector3 position = ((Component)Player.main).transform.position;
JukeboxInstance val2 = null;
float num3 = float.MaxValue;
bool flag = false;
foreach (JukeboxInstance item in JukeboxInstance.all)
{
if (!((Object)(object)item == (Object)null) && ((Behaviour)item).isActiveAndEnabled && Speaker.IsSameHost(Speaker.GetHost((MonoBehaviour)(object)item), host))
{
bool soundPosition = item.GetSoundPosition(ref val, ref num2, ref num);
val = ((Component)item).transform.position - position;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
if ((Object)(object)val2 == (Object)null || (soundPosition && !flag) || (soundPosition == flag && sqrMagnitude < num3))
{
val2 = item;
num3 = sqrMagnitude;
flag = soundPosition;
}
}
}
if (!((Object)(object)val2 != (Object)null))
{
return instance;
}
return val2;
}
private void TogglePlayStop()
{
JukeboxInstance val = ResolveInstance();
if (!((Object)(object)val == (Object)null))
{
if (Jukebox.isStartingOrPlaying && (Object)(object)Jukebox.instance == (Object)(object)val)
{
Jukebox.Stop();
return;
}
val.shuffle = Plugin.Config.DefaultShuffle;
Jukebox.Play(val);
}
}
private void NextTrack()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
JukeboxInstance val = ResolveInstance();
if ((Object)(object)val == (Object)null)
{
return;
}
string next = Jukebox.GetNext(val, true);
if (string.IsNullOrEmpty(next))
{
return;
}
val.file = next;
Jukebox.Play(val);
if (Plugin.Config.ShowTrackName)
{
string label = Jukebox.GetInfo(next).label;
if (!string.IsNullOrEmpty(label))
{
ErrorMessage.AddMessage("Now playing: " + label);
}
}
}
}
[BepInPlugin("com.tristyn.buildinseatruckplus", "Build In Seatruck Plus", "1.0.8")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public const string GUID = "com.tristyn.buildinseatruckplus";
public const string NAME = "Build In Seatruck Plus";
public const string VERSION = "1.0.8";
public static ManualLogSource Log { get; private set; }
public static Config Config { get; private set; }
private void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Config = OptionsPanelHandler.RegisterModOptions<Config>();
MiniBuildables.Register();
Harmony val = new Harmony("com.tristyn.buildinseatruckplus");
val.PatchAll();
((MonoBehaviour)this).StartCoroutine(AutosortCompat.TryPatchWhenReady(val));
Log.LogInfo((object)"Build In Seatruck Plus 1.0.8 loaded.");
((Component)this).gameObject.AddComponent<HotkeyController>();
}
}
internal static class SeaTruckSegmentHelper
{
private static readonly int UseableLayer = LayerMask.NameToLayer("Useable");
public static bool isPlayerInSeaTruckSegment()
{
if ((Object)(object)Player.main != (Object)null)
{
return Player.main.currentInterior is SeaTruckSegment;
}
return false;
}
public static SeaTruckSegment getCurrentSeaTruckSegment()
{
if (!((Object)(object)Player.main != (Object)null))
{
return null;
}
IInteriorSpace currentInterior = Player.main.currentInterior;
return (SeaTruckSegment)(object)((currentInterior is SeaTruckSegment) ? currentInterior : null);
}
public static SeaTruckSegment getParentSeaTruckSegment(GameObject gameObject)
{
return gameObject.GetComponentInParent<SeaTruckSegment>();
}
public static SubRoot getCurrentSeaTruckSegmentSubRoot()
{
SeaTruckSegment currentSeaTruckSegment = getCurrentSeaTruckSegment();
if (!((Object)(object)currentSeaTruckSegment == (Object)null))
{
return ((Component)currentSeaTruckSegment).gameObject.GetComponent<SubRoot>();
}
return null;
}
public static void NeutralizeCollidersForDocking(GameObject go)
{
Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
((Component)componentsInChildren[i]).gameObject.layer = UseableLayer;
}
}
public static void NeutralizeBuiltColliders(GameObject root)
{
if (!((Object)(object)root == (Object)null))
{
Constructable[] componentsInChildren = root.GetComponentsInChildren<Constructable>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
NeutralizeCollidersForDocking(((Component)componentsInChildren[i]).gameObject);
}
}
}
}
}
namespace BuildInSeatruckPlus.Patches
{
internal static class AutosortCompat
{
private const string UnloaderTypeName = "AutosortLockers.AutosortUnloader";
private const string MethodName = "AccumulateUnloadTargets";
private static bool done;
internal static IEnumerator TryPatchWhenReady(Harmony harmony)
{
for (int attempt = 0; attempt < 10; attempt++)
{
if (done)
{
break;
}
if (TryPatch(harmony))
{
break;
}
yield return (object)new WaitForSeconds(1f);
}
}
private static bool TryPatch(Harmony harmony)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
if (done)
{
return true;
}
try
{
Type type = AccessTools.TypeByName("AutosortLockers.AutosortUnloader");
if (type == null)
{
return false;
}
MethodInfo methodInfo = AccessTools.Method(type, "AccumulateUnloadTargets", (Type[])null, (Type[])null);
if (methodInfo == null)
{
Plugin.Log.LogInfo((object)"AutosortLockers present but AccumulateUnloadTargets not found; planter-protection patch skipped.");
done = true;
return true;
}
HarmonyMethod val = new HarmonyMethod(typeof(AutosortCompat), "AccumulateUnloadTargets_Postfix", (Type[])null);
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
done = true;
Plugin.Log.LogInfo((object)"AutosortLockers detected — unloader patched to leave Seatruck planters alone.");
return true;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("AutosortLockers planter-protection patch failed (harmless): " + ex.Message));
done = true;
return true;
}
}
private static void AccumulateUnloadTargets_Postfix(object __instance)
{
try
{
List<ItemsContainer> value = Traverse.Create(__instance).Field("containerTargets").GetValue<List<ItemsContainer>>();
if (value == null || value.Count == 0)
{
return;
}
Planter[] planters = Object.FindObjectsOfType<Planter>();
if (planters.Length != 0)
{
value.RemoveAll((ItemsContainer ct) => ct != null && planters.Any((Planter p) => (Object)(object)p != (Object)null && (Object)(object)p.storageContainer != (Object)null && p.storageContainer.container == ct));
}
RemoveColorMarkedContainers(value);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("AutosortLockers protection postfix error (harmless): " + ex.Message));
}
}
private static void RemoveColorMarkedContainers(List<ItemsContainer> list)
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if (list == null || list.Count == 0)
{
return;
}
UnloaderSkipColor unloaderSkipColor = ((Plugin.Config != null) ? Plugin.Config.UnloaderSkipColorChoice : UnloaderSkipColor.Off);
if (unloaderSkipColor == UnloaderSkipColor.Off)
{
return;
}
ColoredLabel[] array = Object.FindObjectsOfType<ColoredLabel>();
if (array.Length == 0)
{
return;
}
HashSet<ItemsContainer> protectedContainers = new HashSet<ItemsContainer>();
ColoredLabel[] array2 = array;
foreach (ColoredLabel val in array2)
{
if ((Object)(object)val == (Object)null || (Object)(object)val.signInput == (Object)null)
{
continue;
}
Color[] colors = val.signInput.colors;
int colorIndex = val.signInput.colorIndex;
if (colors != null && colorIndex >= 0 && colorIndex < colors.Length && Classify(colors[colorIndex]) == unloaderSkipColor)
{
StorageContainer val2 = ResolveContainer(val);
if ((Object)(object)val2 != (Object)null && val2.container != null)
{
protectedContainers.Add(val2.container);
}
}
}
if (protectedContainers.Count > 0)
{
list.RemoveAll((ItemsContainer ct) => ct != null && protectedContainers.Contains(ct));
}
}
private static StorageContainer ResolveContainer(ColoredLabel cl)
{
//IL_0019: 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_0030: Unknown result type (might be due to invalid IL or missing references)
StorageContainer componentInParent = GetComponentExtensions.GetComponentInParent<StorageContainer>((Component)(object)cl, true);
if ((Object)(object)componentInParent != (Object)null)
{
return componentInParent;
}
Vector3 position = ((Component)cl).transform.position;
Transform parent = ((Component)cl).transform.parent;
int num = 0;
while (num < 4 && (Object)(object)parent != (Object)null)
{
StorageContainer val = NearestContainer(parent, position);
if ((Object)(object)val != (Object)null)
{
return val;
}
num++;
parent = parent.parent;
}
return null;
}
private static StorageContainer NearestContainer(Transform scope, Vector3 lp)
{
//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_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)
StorageContainer result = null;
float num = float.MaxValue;
StorageContainer[] componentsInChildren = ((Component)scope).GetComponentsInChildren<StorageContainer>(true);
foreach (StorageContainer val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && val.container != null)
{
Vector3 val2 = ((Component)val).transform.position - lp;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
if (sqrMagnitude < num)
{
num = sqrMagnitude;
result = val;
}
}
}
return result;
}
private static UnloaderSkipColor Classify(Color c)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
float num = default(float);
float num2 = default(float);
float num3 = default(float);
Color.RGBToHSV(c, ref num, ref num2, ref num3);
if (num3 < 0.15f)
{
return UnloaderSkipColor.Off;
}
if (num2 < 0.25f)
{
return UnloaderSkipColor.White;
}
float num4 = num * 360f;
if (num4 < 20f || num4 >= 330f)
{
return UnloaderSkipColor.Red;
}
if (num4 < 70f)
{
return UnloaderSkipColor.Yellow;
}
if (num4 < 170f)
{
return UnloaderSkipColor.Green;
}
if (num4 < 260f)
{
return UnloaderSkipColor.Blue;
}
return UnloaderSkipColor.Magenta;
}
}
[HarmonyPatch(typeof(Builder), "CheckAsSubModule")]
internal static class Builder_CheckAsSubModule_Patch
{
private static bool Prefix(out Collider hitCollider, ref bool __result)
{
//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)
//IL_005e: 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)
hitCollider = null;
if ((Object)(object)SeaTruckSegmentHelper.getCurrentSeaTruckSegment() == (Object)null)
{
return true;
}
Builder.placementTarget = null;
Transform aimTransform = Builder.GetAimTransform();
RaycastHit val = default(RaycastHit);
if (!Physics.Raycast(aimTransform.position, aimTransform.forward, ref val, Builder.placeMaxDistance, ((LayerMask)(ref Builder.placeLayerMask)).value, (QueryTriggerInteraction)1))
{
__result = false;
return false;
}
if (!Constructable.CheckFlags(Builder.allowedInBase, Builder.allowedInSub, Builder.allowedOutside, Builder.allowedUnderwater, ((RaycastHit)(ref val)).point))
{
__result = false;
return false;
}
hitCollider = ((RaycastHit)(ref val)).collider;
Builder.placementTarget = ((Component)hitCollider).gameObject;
Builder.SetPlaceOnSurface(val, ref Builder.placePosition, ref Builder.placeRotation);
__result = true;
return false;
}
}
[HarmonyPatch(typeof(Builder), "TryPlace")]
internal static class Builder_TryPlace_Patch
{
private static bool Prefix(ref bool __result)
{
//IL_002c: 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_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
SeaTruckSegment currentSeaTruckSegment = SeaTruckSegmentHelper.getCurrentSeaTruckSegment();
if ((Object)(object)currentSeaTruckSegment == (Object)null)
{
return true;
}
if ((Object)(object)Builder.prefab == (Object)null || !Builder.canPlace)
{
RuntimeManager.PlayOneShot("event:/bz/ui/item_error", default(Vector3));
__result = false;
return false;
}
RuntimeManager.PlayOneShot("event:/tools/builder/place", Builder.ghostModel.transform.position);
GameObject obj = Object.Instantiate<GameObject>(Builder.prefab);
SeaTruckSegment val = (((Object)(object)Builder.placementTarget != (Object)null) ? SeaTruckSegmentHelper.getParentSeaTruckSegment(Builder.placementTarget) : null);
SeaTruckSegment val2 = (((Object)(object)val != (Object)null) ? val : currentSeaTruckSegment);
obj.transform.parent = ((Component)val2).transform;
obj.transform.position = Builder.placePosition;
obj.transform.rotation = Builder.placeRotation;
Constructable componentInParent = obj.GetComponentInParent<Constructable>();
componentInParent.SetState(false, true);
if ((Object)(object)Builder.ghostModel != (Object)null)
{
Object.Destroy((Object)(object)Builder.ghostModel);
}
componentInParent.SetIsInside(true);
SkyEnvironmentChanged.Send(obj, (Component)(object)val2);
SeaTruckSegmentHelper.NeutralizeCollidersForDocking(obj);
Builder.ghostModel = null;
Builder.prefab = null;
Builder.canPlace = false;
__result = true;
return false;
}
}
[HarmonyPatch(typeof(Builder), "CheckTag")]
internal static class Builder_CheckTag_Patch
{
private static bool Prefix(Collider c, ref bool __result)
{
if ((Object)(object)c != (Object)null && (Object)(object)((Component)c).GetComponentInParent<MoonpoolExpansionManager>() != (Object)null)
{
__result = true;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(CanvasLink), "SetCanvasesEnabled")]
internal static class CanvasLink_SetCanvasesEnabled_Patch
{
private static readonly FieldInfo Field = AccessTools.Field(typeof(CanvasLink), "canvases");
private static bool Prefix(CanvasLink __instance, bool enabled)
{
return CanvasLinkToggle.Run(Field, __instance, enabled);
}
}
[HarmonyPatch(typeof(CanvasLink), "SetRectMasksEnabled")]
internal static class CanvasLink_SetRectMasksEnabled_Patch
{
private static readonly FieldInfo Field = AccessTools.Field(typeof(CanvasLink), "rectMasks");
private static bool Prefix(CanvasLink __instance, bool enabled)
{
return CanvasLinkToggle.Run(Field, __instance, enabled);
}
}
internal static class CanvasLinkToggle
{
public static bool Run(FieldInfo field, CanvasLink instance, bool enabled)
{
if (field.GetValue(instance) is Behaviour[] array)
{
Behaviour[] array2 = array;
foreach (Behaviour val in array2)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = enabled;
}
}
}
return false;
}
}
[HarmonyPatch(typeof(Constructable), "CheckFlags")]
internal static class Constructable_CheckFlags_Patch
{
private static bool Prefix(ref bool __result)
{
if ((Object)(object)SeaTruckSegmentHelper.getCurrentSeaTruckSegment() == (Object)null)
{
return true;
}
__result = true;
return false;
}
}
internal static class DockedAudio
{
internal static readonly List<MoonpoolExpansionManager> Moonpools = new List<MoonpoolExpansionManager>();
}
[HarmonyPatch(typeof(MoonpoolExpansionManager), "Start")]
internal static class MoonpoolExpansionManager_Start_Patch
{
private static void Postfix(MoonpoolExpansionManager __instance)
{
if (!DockedAudio.Moonpools.Contains(__instance))
{
DockedAudio.Moonpools.Add(__instance);
}
}
}
[HarmonyPatch(typeof(Speaker), "GetSpeakers")]
internal static class Speaker_GetSpeakers_Patch
{
private static bool _bridging;
private static readonly List<Speaker> _other = new List<Speaker>();
private static void Postfix(ISpeakerHost host, Vector3 position, float radius, List<Speaker> results)
{
//IL_00bb: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
if (_bridging || host == null)
{
return;
}
_bridging = true;
try
{
for (int num = DockedAudio.Moonpools.Count - 1; num >= 0; num--)
{
MoonpoolExpansionManager val = DockedAudio.Moonpools[num];
if ((Object)(object)val == (Object)null)
{
DockedAudio.Moonpools.RemoveAt(num);
continue;
}
SeaTruckSegment dockedHead = val.GetDockedHead();
SeaTruckSegment dockedTail = val.GetDockedTail();
if ((Object)(object)dockedHead == (Object)null && (Object)(object)dockedTail == (Object)null)
{
continue;
}
BaseRoot baseRoot = val.baseRoot;
int num2;
if (host is BaseRoot)
{
num2 = (((object)host == baseRoot) ? 1 : 0);
if (num2 != 0)
{
goto IL_00b5;
}
}
else
{
num2 = 0;
}
if (!(host is SeaTruckSegment))
{
goto IL_00b5;
}
int num3 = ((((Object)(object)dockedTail != (Object)null && Speaker.IsSameHost(host, (ISpeakerHost)(object)dockedTail)) || ((Object)(object)dockedHead != (Object)null && Speaker.IsSameHost(host, (ISpeakerHost)(object)dockedHead))) ? 1 : 0);
goto IL_00b6;
IL_00b6:
bool flag = (byte)num3 != 0;
if (num2 != 0)
{
Append((ISpeakerHost)(object)dockedTail, position, radius, results);
Append((ISpeakerHost)(object)dockedHead, position, radius, results);
}
else if (flag)
{
Append((ISpeakerHost)(object)baseRoot, position, radius, results);
}
continue;
IL_00b5:
num3 = 0;
goto IL_00b6;
}
}
finally
{
_bridging = false;
}
}
private static void Append(ISpeakerHost other, Vector3 position, float radius, List<Speaker> results)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (other == null)
{
return;
}
_other.Clear();
Speaker.GetSpeakers(other, position, radius, _other);
for (int i = 0; i < _other.Count; i++)
{
Speaker val = _other[i];
if ((Object)(object)val != (Object)null && !results.Contains(val))
{
results.Add(val);
}
}
}
}
[HarmonyPatch(typeof(Speaker), "IsSameHost")]
internal static class Speaker_IsSameHost_Patch
{
private static bool _reentry;
private static void Postfix(ISpeakerHost a, ISpeakerHost b, ref bool __result)
{
if (__result || _reentry || a == null || b == null)
{
return;
}
_reentry = true;
try
{
for (int num = DockedAudio.Moonpools.Count - 1; num >= 0; num--)
{
MoonpoolExpansionManager val = DockedAudio.Moonpools[num];
if ((Object)(object)val == (Object)null)
{
DockedAudio.Moonpools.RemoveAt(num);
}
else
{
SeaTruckSegment dockedHead = val.GetDockedHead();
SeaTruckSegment dockedTail = val.GetDockedTail();
if ((!((Object)(object)dockedHead == (Object)null) || !((Object)(object)dockedTail == (Object)null)) && InGroup(a, val, dockedHead, dockedTail) && InGroup(b, val, dockedHead, dockedTail))
{
__result = true;
break;
}
}
}
}
finally
{
_reentry = false;
}
}
private static bool InGroup(ISpeakerHost h, MoonpoolExpansionManager mp, SeaTruckSegment head, SeaTruckSegment tail)
{
if (h is BaseRoot && (object)h == mp.baseRoot)
{
return true;
}
if ((Object)(object)head != (Object)null && Speaker.IsSameHost(h, (ISpeakerHost)(object)head))
{
return true;
}
if ((Object)(object)tail != (Object)null && Speaker.IsSameHost(h, (ISpeakerHost)(object)tail))
{
return true;
}
return false;
}
}
[HarmonyPatch(typeof(SeaTruckMotor), "StartPiloting")]
internal static class SeaTruckMotor_StartPiloting_Patch
{
private static void Postfix(SeaTruckMotor __instance)
{
if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.truckSegment != (Object)null)
{
SeaTruckSegmentHelper.NeutralizeBuiltColliders(((Component)__instance.truckSegment).gameObject);
}
}
}
[HarmonyPatch(typeof(MoonpoolExpansionManager), "StartUndocking")]
internal static class MoonpoolExpansionManager_StartUndocking_Patch
{
private static void Postfix(MoonpoolExpansionManager __instance)
{
SeaTruckSegment dockedHead = __instance.GetDockedHead();
if ((Object)(object)dockedHead != (Object)null)
{
SeaTruckSegmentHelper.NeutralizeBuiltColliders(((Component)dockedHead).gameObject);
}
SeaTruckSegment dockedTail = __instance.GetDockedTail();
if ((Object)(object)dockedTail != (Object)null)
{
SeaTruckSegmentHelper.NeutralizeBuiltColliders(((Component)dockedTail).gameObject);
}
}
}
[HarmonyPatch(typeof(JukeboxInstance), "ConsumePower")]
internal static class JukeboxInstance_ConsumePower_Patch
{
private static void Prefix(JukeboxInstance __instance)
{
if (!((Object)(object)__instance._powerRelay != (Object)null))
{
PowerRelay componentInParent = ((Component)__instance).GetComponentInParent<PowerRelay>();
if ((Object)(object)componentInParent != (Object)null)
{
__instance._powerRelay = componentInParent;
Plugin.Log.LogInfo((object)("Re-resolved missing PowerRelay for " + ((Object)__instance).name + " -> " + ((Object)componentInParent).name + " (load-timing fix)."));
}
}
}
}
internal static class JukeboxSync
{
internal static bool InDisable;
private static int _frame = -1;
private static readonly Dictionary<JukeboxInstance, bool> _cache = new Dictionary<JukeboxInstance, bool>();
internal static bool IsMirror(JukeboxInstance ji)
{
if (Time.frameCount != _frame)
{
_frame = Time.frameCount;
_cache.Clear();
}
if (_cache.TryGetValue(ji, out var value))
{
return value;
}
bool flag = Compute(ji);
_cache[ji] = flag;
return flag;
}
private static bool Compute(JukeboxInstance ji)
{
JukeboxInstance instance = Jukebox.instance;
if ((Object)(object)instance == (Object)null || (Object)(object)instance == (Object)(object)ji)
{
return false;
}
if (!Jukebox.isStartingOrPlaying)
{
return false;
}
return Speaker.IsSameHost(Speaker.GetHost((MonoBehaviour)(object)ji), Speaker.GetHost((MonoBehaviour)(object)instance));
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class JukeboxInstance_isControlling_Patch
{
private static void Postfix(JukeboxInstance __instance, ref bool __result)
{
if (!__result && !JukeboxSync.InDisable && JukeboxSync.IsMirror(__instance))
{
__result = true;
}
}
}
[HarmonyPatch(typeof(JukeboxInstance), "UpdatePower")]
internal static class JukeboxInstance_UpdatePower_Patch
{
private static bool Prefix(JukeboxInstance __instance)
{
return !JukeboxSync.IsMirror(__instance);
}
}
[HarmonyPatch(typeof(JukeboxInstance), "OnDisable")]
internal static class JukeboxInstance_OnDisable_Patch
{
private static void Prefix()
{
JukeboxSync.InDisable = true;
}
private static void Finalizer()
{
JukeboxSync.InDisable = false;
}
}
[HarmonyPatch(typeof(JukeboxInstance), "UpdateUI")]
internal static class JukeboxInstance_UpdateUI_Patch
{
private static void Prefix(JukeboxInstance __instance)
{
//IL_0039: 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_0048: 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_005f: Unknown result type (might be due to invalid IL or missing references)
if (!JukeboxSync.IsMirror(__instance))
{
return;
}
JukeboxInstance instance = Jukebox.instance;
if (!((Object)(object)instance == (Object)null))
{
if (__instance.file != instance.file)
{
__instance.file = instance.file;
}
if (__instance.repeat != instance.repeat)
{
__instance.repeat = instance.repeat;
__instance.imageRepeat.sprite = __instance.spritesRepeat[instance.repeat];
}
if (__instance.shuffle != instance.shuffle)
{
__instance.shuffle = instance.shuffle;
__instance.imageShuffle.sprite = (instance.shuffle ? __instance.spriteShuffleOn : __instance.spriteShuffleOff);
}
}
}
}
internal static class PlanterDiagnostics
{
private const string Tag = "[PlantDiag]";
internal static bool IsSeatruckPlanter(Planter p)
{
if ((Object)(object)p != (Object)null)
{
return (Object)(object)((Component)p).GetComponentInParent<SeaTruckSegment>() != (Object)null;
}
return false;
}
internal static string PlanterId(Planter p)
{
UniqueIdentifier val = ((Component)p).GetComponent<UniqueIdentifier>() ?? ((Component)p).GetComponentInParent<UniqueIdentifier>();
if (!((Object)(object)val != (Object)null))
{
return "<no-uid>";
}
return val.Id;
}
internal static void Dump(Planter p, string phase)
{
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)p == (Object)null)
{
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("[PlantDiag]").Append(' ').Append(phase)
.Append(" planter=")
.Append(PlanterId(p));
SeaTruckSegment componentInParent = ((Component)p).GetComponentInParent<SeaTruckSegment>();
stringBuilder.Append(" seg=").Append(((Object)(object)componentInParent != (Object)null) ? ((Object)componentInParent).name : "<none>");
int value = (((Object)(object)p.grownPlantsRoot != (Object)null) ? p.grownPlantsRoot.childCount : (-1));
stringBuilder.Append(" grownModels=").Append(value);
Transform val = (((Object)(object)p.storageContainer != (Object)null && (Object)(object)p.storageContainer.storageRoot != (Object)null) ? ((Component)p.storageContainer.storageRoot).transform : null);
int value2 = (((Object)(object)val != (Object)null) ? val.childCount : (-1));
stringBuilder.Append(" storedItems=").Append(value2);
Plugin.Log.LogInfo((object)stringBuilder.ToString());
if (!((Object)(object)val != (Object)null))
{
return;
}
for (int i = 0; i < val.childCount; i++)
{
Transform child = val.GetChild(i);
StringBuilder stringBuilder2 = new StringBuilder();
stringBuilder2.Append("[PlantDiag]").Append(" item[").Append(i)
.Append("] ")
.Append(((Object)child).name);
Pickupable component = ((Component)child).GetComponent<Pickupable>();
stringBuilder2.Append(" tech=").Append(((Object)(object)component != (Object)null) ? ((object)component.GetTechType()/*cast due to .constrained prefix*/).ToString() : "<no-pickupable>");
Plantable component2 = ((Component)child).GetComponent<Plantable>();
if ((Object)(object)component2 != (Object)null)
{
stringBuilder2.Append(" slot=").Append(component2.planterSlotId).Append(" age=")
.Append(component2.plantAge.ToString("0.000"));
}
UniqueIdentifier component3 = ((Component)child).GetComponent<UniqueIdentifier>();
stringBuilder2.Append(" uid=").Append(((Object)(object)component3 != (Object)null) ? component3.Id : "<none>").Append(" active=")
.Append(((Component)child).gameObject.activeSelf);
Plugin.Log.LogInfo((object)stringBuilder2.ToString());
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[PlantDiag] dump failed: " + ex.Message));
}
}
internal static IEnumerator DumpDelayed(Planter p, string phase, float seconds)
{
yield return (object)new WaitForSeconds(seconds);
Dump(p, phase);
}
}
[HarmonyPatch(typeof(Planter), "OnProtoSerializeObjectTree")]
internal static class Planter_OnProtoSerializeObjectTree_Diag
{
private static void Postfix(Planter __instance)
{
if (PlanterDiagnostics.IsSeatruckPlanter(__instance))
{
PlanterDiagnostics.Dump(__instance, "SAVE");
}
}
}
[HarmonyPatch(typeof(Planter), "OnProtoDeserializeObjectTree")]
internal static class Planter_OnProtoDeserializeObjectTree_Diag
{
private static void Postfix(Planter __instance)
{
if (PlanterDiagnostics.IsSeatruckPlanter(__instance))
{
PlanterDiagnostics.Dump(__instance, "LOAD-start");
CoroutineHost.StartCoroutine(PlanterDiagnostics.DumpDelayed(__instance, "LOAD+5s", 5f));
}
}
}
[HarmonyPatch(typeof(Planter), "ReplaceItem")]
internal static class Planter_ReplaceItem_Diag
{
private static void Postfix(Planter __instance, Plantable seed, Plantable plant, bool __result)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
if (!PlanterDiagnostics.IsSeatruckPlanter(__instance))
{
return;
}
try
{
string arg = (((Object)(object)seed != (Object)null && (Object)(object)seed.pickupable != (Object)null) ? ((object)seed.pickupable.GetTechType()/*cast due to .constrained prefix*/).ToString() : "<null>");
string arg2 = (((Object)(object)plant != (Object)null && (Object)(object)plant.pickupable != (Object)null) ? ((object)plant.pickupable.GetTechType()/*cast due to .constrained prefix*/).ToString() : "<null>");
Plugin.Log.LogInfo((object)("[PlantDiag] REPLACE (seed->plant) planter=" + PlanterDiagnostics.PlanterId(__instance) + " " + $"seed={arg} plant={arg2} result={__result}"));
}
catch
{
}
}
}
[HarmonyPatch(typeof(Planter), "SetupRenderers")]
internal static class Planter_SetupRenderers_Patch
{
private static void Postfix(Planter __instance, GameObject gameObject)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)gameObject == (Object)null) && !((Object)(object)((Component)__instance).GetComponentInParent<SeaTruckSegment>() == (Object)null))
{
SeaTruckSegmentHelper.NeutralizeCollidersForDocking(gameObject);
}
}
}
[HarmonyPatch(typeof(PowerConsumer), "IsPowered")]
internal static class PowerConsumer_IsPowered_Patch
{
private static bool Prefix(PowerConsumer __instance, ref bool __result)
{
SeaTruckSegment parentSeaTruckSegment = SeaTruckSegmentHelper.getParentSeaTruckSegment(((Component)__instance).gameObject);
if ((Object)(object)parentSeaTruckSegment == (Object)null)
{
return true;
}
__result = ((IInteriorSpace)parentSeaTruckSegment).CanBreathe();
return false;
}
}
[HarmonyPatch(typeof(SeaTruckSegment), "CanEnter")]
internal static class SeaTruckSegment_CanEnter_Patch
{
private static bool Prefix(ref bool __result)
{
__result = true;
return false;
}
}
}
namespace BuildInSeatruckPlus.Buildables
{
internal static class MiniBuildables
{
public static TechType MiniJukebox { get; private set; }
public static TechType MiniSpeaker { get; private set; }
public static void Register()
{
//IL_0019: 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)
MiniJukebox = Make("MiniJukebox", "Mini Jukebox", "A compact jukebox that fits inside a Seatruck.", (TechType)1564, 0.25f);
MiniSpeaker = Make("MiniSpeaker", "Mini Speaker", "A compact speaker for tight interiors.", (TechType)1566, 0.5f);
}
private static TechType Make(string classId, string friendly, string description, TechType cloneOf, float scale)
{
//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_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: 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_0040: Expected O, but got Unknown
//IL_0040: 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_0048: Expected O, but got Unknown
//IL_0097: 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_008e: Expected O, but got Unknown
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
//IL_00b2: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
PrefabInfo val = PrefabInfo.WithTechType(classId, friendly, description, "English", false, (Assembly)null);
PrefabInfo val2 = ((PrefabInfo)(ref val)).WithIcon(SpriteManager.Get(cloneOf));
CustomPrefab val3 = new CustomPrefab(val2);
CloneTemplate val4 = new CloneTemplate(val2, cloneOf);
val4.ModifyPrefab = (Action<GameObject>)Delegate.Combine(val4.ModifyPrefab, (Action<GameObject>)delegate(GameObject go)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
Transform transform = go.transform;
transform.localScale *= scale;
ConstructableBounds[] componentsInChildren = go.GetComponentsInChildren<ConstructableBounds>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].bounds.extents = Vector3.one * 0.02f;
}
Plugin.Log.LogInfo((object)$"{classId}: scaled to {scale} with liberal bounds.");
});
val3.SetGameObject((PrefabTemplate)(object)val4);
RecipeData val5 = (RecipeData)((!Plugin.Config.CheapRecipe) ? (((object)CraftDataHandler.GetRecipeData(cloneOf)) ?? ((object)new RecipeData((Ingredient[])(object)new Ingredient[1]
{
new Ingredient((TechType)16, 1)
}))) : ((object)new RecipeData((Ingredient[])(object)new Ingredient[1]
{
new Ingredient((TechType)16, 1)
})));
GadgetExtensions.SetRecipe((ICustomPrefab)(object)val3, val5);
TechGroup val6 = default(TechGroup);
TechCategory val7 = default(TechCategory);
int num = default(int);
if (CraftData.GetBuilderIndex(cloneOf, ref val6, ref val7, ref num))
{
GadgetExtensions.SetPdaGroupCategory((ICustomPrefab)(object)val3, val6, val7);
}
if (!Plugin.Config.UnlockBuildables)
{
GadgetExtensions.SetUnlock((ICustomPrefab)(object)val3, (TechType)1564, 1);
}
val3.Register();
return ((PrefabInfo)(ref val2)).TechType;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}