using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Movement;
using Pigeon.UI;
using TMPro;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Floppy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: AssemblyInformationalVersion("0.4.1")]
[assembly: AssemblyProduct("Floppy")]
[assembly: AssemblyTitle("Floppy")]
[assembly: AssemblyVersion("0.4.1.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 Horse.Floppy
{
internal static class ExchangeRules
{
private sealed class EquippedSlot
{
internal IUpgradable Gear;
internal sbyte X;
internal sbyte Y;
internal byte Rotation;
}
private static readonly FieldInfo UpgradeBufferField = AccessTools.Field(typeof(PlayerData), "upgradeBuffer");
private static readonly FieldInfo UpgradeDupeBufferField = AccessTools.Field(typeof(PlayerData), "upgradeDupeBuffer");
internal static bool CanSubmit(UpgradeInstance input, out string reason)
{
reason = null;
if ((Object)(object)((input != null) ? input.Upgrade : null) == (Object)null || !input.IsCollected || input.Upgrade.IsSkin())
{
reason = "Select a module from your inventory.";
}
else if (!input.RemoveAfterMission)
{
reason = "Only temporary Ouroboros modules are accepted.";
}
return reason == null;
}
internal static List<ResourceCost> Cost(UpgradeInstance input)
{
return new List<ResourceCost>(input.Upgrade.GetOuroborosCost());
}
internal static UpgradeInstance Prepare(UpgradeInstance input, int seed)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Invalid comparison between Unknown and I4
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
if (!CanSubmit(input, out var _) || input.Gear == null)
{
return null;
}
bool flag = (int)input.Gear.GearType == 5;
UpgradeFilterParams val = default(UpgradeFilterParams);
((UpgradeFilterParams)(ref val))..ctor(input.Upgrade.Rarity, flag ? null : input.Gear, (DuplicateMode)2, (UnlockFlags)0, false, false, false);
val.isTempMissionUpgrade = true;
PlayerData.FindRandomUpgrade(val, false, seed);
List<FilterResult> list = UpgradeBufferField?.GetValue(null) as List<FilterResult>;
List<FilterResult> list2 = UpgradeDupeBufferField?.GetValue(null) as List<FilterResult>;
if (list == null || list2 == null)
{
FloppyPlugin.Log.LogError((object)"Floppy could not read the game's eligible module pool.");
return null;
}
List<FilterResult> pool = new List<FilterResult>();
HashSet<Tuple<int, Upgrade>> seen = new HashSet<Tuple<int, Upgrade>>();
Add(list);
Add(list2);
if (pool.Count == 0)
{
return null;
}
FilterResult val2 = pool[new Random(seed).Next(pool.Count)];
UpgradeInstance obj = PlayerData.CreateUpgradeInstance(val2.gear, val2.info.Upgrade, false);
obj.RemoveAfterMission = true;
return obj;
void Add(List<FilterResult> source)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: 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)
//IL_0079: 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_00af: Unknown result type (might be due to invalid IL or missing references)
foreach (FilterResult item in source)
{
UpgradeInfo info = item.info;
Upgrade val3 = ((info != null) ? info.Upgrade : null);
if (item.gear != null && !((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)input.Upgrade) && val3.Rarity == input.Upgrade.Rarity && !val3.IsSkin() && IsAllowedGear(input.Gear, item.gear) && seen.Add(Tuple.Create<int, Upgrade>(item.gear.Info.ID, val3)))
{
pool.Add(item);
}
}
}
}
private static bool SameGear(IUpgradable first, IUpgradable second)
{
if (first != null && second != null)
{
return first.Info.ID == second.Info.ID;
}
return false;
}
private static bool IsAllowedGear(IUpgradable input, IUpgradable output)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
if (input == null || output == null)
{
return false;
}
if ((int)input.GearType != 5)
{
return SameGear(input, output);
}
Character second = (((Object)(object)Player.LocalPlayer != (Object)null) ? Player.LocalPlayer.Character : null);
if (!SameGear(output, (IUpgradable)(object)Global.Instance))
{
return SameGear(output, (IUpgradable)(object)second);
}
return true;
}
internal static bool Commit(UpgradeInstance input, UpgradeInstance output, out string reason)
{
//IL_023b: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: 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_007b: Unknown result type (might be due to invalid IL or missing references)
if (!CanSubmit(input, out reason))
{
return false;
}
if ((Object)(object)((output != null) ? output.Upgrade : null) == (Object)null || output.Gear == null || output.IsCollected || !output.RemoveAfterMission || !IsAllowedGear(input.Gear, output.Gear) || (Object)(object)output.Upgrade == (Object)(object)input.Upgrade || output.Upgrade.IsSkin() || output.Upgrade.Rarity != input.Upgrade.Rarity)
{
reason = "No eligible module of the same rarity could be selected.";
return false;
}
List<ResourceCost> list = Cost(input);
UpgradeInfo upgradeInfo = PlayerData.GetUpgradeInfo(output.Gear, output.Upgrade);
int totalInstancesCollected = upgradeInfo.TotalInstancesCollected;
List<EquippedSlot> list2 = new List<EquippedSlot>();
sbyte x = default(sbyte);
sbyte y = default(sbyte);
byte rotation = default(byte);
foreach (GearData value in PlayerData.Instance.collectedGear.Values)
{
if (input.GetPosition(value.Gear, ref x, ref y, ref rotation))
{
list2.Add(new EquippedSlot
{
Gear = value.Gear,
X = x,
Y = y,
Rotation = rotation
});
}
}
if (!PlayerData.Instance.TryRemoveResources(list))
{
reason = "Not enough currency for this exchange.";
return false;
}
try
{
input.UnequipFromAll();
if (!input.Destroy())
{
throw new InvalidOperationException("Input not removed");
}
PlayerData.CollectInstance(output, (UnlockFlags)0);
if (!output.IsCollected)
{
throw new InvalidOperationException("Reward not collected");
}
Reapply();
return true;
}
catch (Exception ex)
{
upgradeInfo.SetTotalInstancesCollected(totalInstancesCollected);
if (!input.IsCollected)
{
PlayerData.GetUpgradeInfo(input.Gear, input.Upgrade).Instances.Add(input);
}
if (output.IsCollected)
{
output.UnequipFromAll();
PlayerData.GetUpgradeInfo(output.Gear, output.Upgrade).Instances.Remove(output);
}
foreach (EquippedSlot item in list2)
{
input.Equip(item.Gear, item.X, item.Y, item.Rotation, true, false);
}
foreach (ResourceCost item2 in list)
{
PlayerData.Instance.AddResource(item2.resource, item2.count, false);
}
Reapply();
FloppyPlugin.Log.LogError((object)("Exchange rolled back: " + ex));
reason = "Exchange cancelled. Your module and payment were returned.";
return false;
}
}
private static void Reapply()
{
try
{
GearUtil.ReapplyUpgrades();
}
catch (Exception ex)
{
FloppyPlugin.Log.LogError((object)("Could not refresh equipment after exchange: " + ex));
}
}
}
internal static class FloppyAvailability
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__OnState;
public static HandleNamedMessageDelegate <1>__OnRequest;
public static Action<ulong> <2>__OnConnected;
public static Action<ulong> <3>__OnDisconnected;
}
private const string StateMessage = "horse.mycopunk.floppy.availability.v1";
private const string RequestMessage = "horse.mycopunk.floppy.availability-request.v1";
private static NetworkManager manager;
private static CustomMessagingManager messages;
private static bool remoteKnown;
private static bool remoteEnabled;
private static bool lastPreference;
private static float nextRequest;
internal static bool CanEdit
{
get
{
NetworkManager singleton = NetworkManager.Singleton;
if (!((Object)(object)singleton == (Object)null) && singleton.IsListening)
{
return singleton.IsServer;
}
return true;
}
}
internal static bool IsSynchronized
{
get
{
if (!CanEdit)
{
if ((Object)(object)manager == (Object)(object)NetworkManager.Singleton && messages != null)
{
return remoteKnown;
}
return false;
}
return true;
}
}
internal static bool Enabled
{
get
{
if (!CanEdit)
{
if (IsSynchronized)
{
return remoteEnabled;
}
return false;
}
return FloppyPlugin.Instance?.Enabled.Value ?? false;
}
}
internal static void SetEnabled(bool enabled)
{
if (CanEdit && !((Object)(object)FloppyPlugin.Instance == (Object)null))
{
FloppyPlugin.Instance.Enabled.Value = enabled;
((BaseUnityPlugin)FloppyPlugin.Instance).Config.Save();
lastPreference = enabled;
if ((Object)(object)manager != (Object)null && manager.IsServer)
{
Broadcast();
}
}
}
internal unsafe static void Tick(float now)
{
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
//IL_00e3: 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_00ee: Expected O, but got Unknown
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
NetworkManager singleton = NetworkManager.Singleton;
CustomMessagingManager val = (((Object)(object)singleton != (Object)null && singleton.IsListening) ? singleton.CustomMessagingManager : null);
if ((Object)(object)singleton == (Object)null || !singleton.IsListening || val == null)
{
if (messages != null || (Object)(object)manager != (Object)null)
{
Dispose();
}
return;
}
if ((Object)(object)manager != (Object)(object)singleton || messages != val)
{
Dispose();
manager = singleton;
messages = val;
remoteKnown = false;
nextRequest = now;
lastPreference = FloppyPlugin.Instance?.Enabled.Value ?? false;
CustomMessagingManager obj = messages;
object obj2 = <>O.<0>__OnState;
if (obj2 == null)
{
HandleNamedMessageDelegate val2 = OnState;
<>O.<0>__OnState = val2;
obj2 = (object)val2;
}
obj.RegisterNamedMessageHandler("horse.mycopunk.floppy.availability.v1", (HandleNamedMessageDelegate)obj2);
CustomMessagingManager obj3 = messages;
object obj4 = <>O.<1>__OnRequest;
if (obj4 == null)
{
HandleNamedMessageDelegate val3 = OnRequest;
<>O.<1>__OnRequest = val3;
obj4 = (object)val3;
}
obj3.RegisterNamedMessageHandler("horse.mycopunk.floppy.availability-request.v1", (HandleNamedMessageDelegate)obj4);
manager.OnClientConnectedCallback += OnConnected;
manager.OnClientDisconnectCallback += OnDisconnected;
if (manager.IsServer)
{
Broadcast();
}
}
bool flag = FloppyPlugin.Instance?.Enabled.Value ?? false;
if (manager.IsServer && flag != lastPreference)
{
lastPreference = flag;
Broadcast();
}
if (manager.IsServer || !manager.IsConnectedClient || remoteKnown || !(now >= nextRequest))
{
return;
}
nextRequest = now + 0.75f;
FastBufferWriter val4 = default(FastBufferWriter);
((FastBufferWriter)(ref val4))..ctor(1, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val4)).WriteByteSafe((byte)1);
messages.SendNamedMessage("horse.mycopunk.floppy.availability-request.v1", 0uL, val4, (NetworkDelivery)3);
}
finally
{
((IDisposable)(*(FastBufferWriter*)(&val4))/*cast due to .constrained prefix*/).Dispose();
}
}
private static void OnConnected(ulong clientId)
{
if (!((Object)(object)manager == (Object)null))
{
if (manager.IsServer)
{
SendState(clientId);
}
else if (clientId == manager.LocalClientId)
{
remoteKnown = false;
nextRequest = 0f;
}
}
}
private static void OnDisconnected(ulong clientId)
{
if ((Object)(object)manager != (Object)null && !manager.IsServer && clientId == manager.LocalClientId)
{
remoteKnown = false;
}
}
private static void OnRequest(ulong sender, FastBufferReader reader)
{
if (!((Object)(object)manager == (Object)null) && manager.IsServer && ((FastBufferReader)(ref reader)).TryBeginRead(1))
{
byte b = default(byte);
((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
if (b == 1)
{
SendState(sender);
}
}
}
private static void OnState(ulong sender, FastBufferReader reader)
{
if (!((Object)(object)manager == (Object)null) && !manager.IsServer && sender == 0L && ((FastBufferReader)(ref reader)).TryBeginRead(2))
{
byte b = default(byte);
((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
byte b2 = default(byte);
((FastBufferReader)(ref reader)).ReadByteSafe(ref b2);
if (b == 1 && b2 <= 1)
{
remoteEnabled = b2 == 1;
remoteKnown = true;
}
}
}
private unsafe static void SendState(ulong clientId)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
if (messages == null || (Object)(object)manager == (Object)null || !manager.IsServer)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(2, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteByteSafe((byte)1);
((FastBufferWriter)(ref val)).WriteByteSafe(Enabled ? ((byte)1) : ((byte)0));
messages.SendNamedMessage("horse.mycopunk.floppy.availability.v1", clientId, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
}
}
private unsafe static void Broadcast()
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if (messages == null || (Object)(object)manager == (Object)null || !manager.IsServer)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(2, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteByteSafe((byte)1);
((FastBufferWriter)(ref val)).WriteByteSafe(Enabled ? ((byte)1) : ((byte)0));
messages.SendNamedMessageToAll("horse.mycopunk.floppy.availability.v1", val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
}
}
internal static void Dispose()
{
if ((Object)(object)manager != (Object)null)
{
manager.OnClientConnectedCallback -= OnConnected;
manager.OnClientDisconnectCallback -= OnDisconnected;
}
if (messages != null)
{
messages.UnregisterNamedMessageHandler("horse.mycopunk.floppy.availability.v1");
messages.UnregisterNamedMessageHandler("horse.mycopunk.floppy.availability-request.v1");
}
manager = null;
messages = null;
remoteKnown = false;
remoteEnabled = false;
nextRequest = 0f;
}
}
internal sealed class FloppyDeferredShop : MonoBehaviour
{
private OuroStoreRoom shop;
private OuroObjective objective;
private OuroItemPositions positions;
private OuroRoom room;
private int seed;
private bool pending;
internal void Defer(OuroStoreRoom owner, OuroObjective source, OuroItemPositions itemPositions, OuroRoom sourceRoom, int shopSeed)
{
shop = owner;
objective = source;
positions = itemPositions;
room = sourceRoom;
seed = shopSeed;
pending = true;
((Component)owner).gameObject.SetActive(true);
}
internal void Clear()
{
pending = false;
}
internal static void DisposeAll()
{
FloppyDeferredShop[] array = Object.FindObjectsByType<FloppyDeferredShop>((FindObjectsInactive)1);
foreach (FloppyDeferredShop floppyDeferredShop in array)
{
bool num = floppyDeferredShop.pending;
floppyDeferredShop.pending = false;
if (num && (Object)(object)floppyDeferredShop.shop != (Object)null && (Object)(object)floppyDeferredShop.objective != (Object)null && !((ObjectiveBase)floppyDeferredShop.objective).HasEnded && (Object)(object)GameManager.Instance != (Object)null)
{
try
{
floppyDeferredShop.shop.Setup(floppyDeferredShop.objective, floppyDeferredShop.positions, floppyDeferredShop.room, floppyDeferredShop.seed);
}
catch (Exception ex)
{
ManualLogSource log = FloppyPlugin.Log;
if (log != null)
{
log.LogWarning((object)("Could not restore deferred shop: " + ex));
}
}
}
Object.Destroy((Object)(object)floppyDeferredShop);
}
}
private void Update()
{
if (pending && FloppyAvailability.IsSynchronized)
{
pending = false;
if ((Object)(object)shop != (Object)null && (Object)(object)objective != (Object)null)
{
shop.Setup(objective, positions, room, seed);
}
}
}
private void OnDisable()
{
pending = false;
}
}
internal static class FloppyExchangeDiagnostics
{
private static readonly FieldInfo GridStealerField = AccessTools.Field(typeof(OuroObjective), "gridStealerUpgrade");
internal static void LogState(string phase, UpgradeInstance input, UpgradeInstance output)
{
try
{
Player localPlayer = Player.LocalPlayer;
if ((Object)(object)localPlayer == (Object)null)
{
return;
}
OuroObjective val = (((Object)(object)MissionManager.Instance != (Object)null) ? MissionManager.Instance.GetObjective<OuroObjective>() : null);
Upgrade gridStealer = (Upgrade)(((Object)(object)val != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
HashSet<int> seen = new HashSet<int>();
StringBuilder grids = new StringBuilder();
Add((IUpgradable)(object)localPlayer.Character);
if (localPlayer.Gear != null)
{
IGear[] gear = localPlayer.Gear;
foreach (IGear val2 in gear)
{
if (val2 != null)
{
Add(((IUpgradable)val2).Prefab);
}
}
}
FloppyPlugin.Log.LogInfo((object)("Exchange " + phase + ": input=" + Describe(input) + "; reward=" + Describe(output) + "; autoApply=" + OuroObjective.AutoApplyUpgrades + "; grids=[" + grids?.ToString() + "]"));
void Add(IUpgradable val3)
{
if (val3 != null && val3.Info.HasUpgradeGrid && seen.Add(val3.Info.ID))
{
int value = default(int);
int value2 = default(int);
val3.Info.GetUpgradeGridSize(ref value, ref value2, false);
int num = 0;
if ((Object)(object)gridStealer != (Object)null)
{
EquippedUpgradeEnumerator val4 = default(EquippedUpgradeEnumerator);
((EquippedUpgradeEnumerator)(ref val4))..ctor(val3, true);
while (((EquippedUpgradeEnumerator)(ref val4)).MoveNext())
{
if (((EquippedUpgradeEnumerator)(ref val4)).Upgrade != null && (Object)(object)((EquippedUpgradeEnumerator)(ref val4)).Upgrade.Upgrade == (Object)(object)gridStealer)
{
num++;
}
}
}
if (grids.Length > 0)
{
grids.Append("; ");
}
grids.Append(val3.Info.APIName).Append('#').Append(val3.Info.ID)
.Append('=')
.Append(value)
.Append('x')
.Append(value2)
.Append("/gridStealers=")
.Append(num);
}
}
}
catch (Exception ex)
{
FloppyPlugin.Log.LogDebug((object)("Exchange grid diagnostics unavailable: " + ex.Message));
}
}
private static string Describe(UpgradeInstance module)
{
if (!((Object)(object)((module != null) ? module.Upgrade : null) == (Object)null))
{
string[] obj = new string[7]
{
module.InstanceID.ToString(),
"/",
module.Upgrade.NumberID.ToString(),
"/",
module.Upgrade.GetInstanceName(module),
"/gear=",
null
};
IUpgradable gear = module.Gear;
obj[6] = ((gear != null) ? new int?(gear.Info.ID) : ((int?)null)).ToString();
return string.Concat(obj);
}
return "none";
}
}
internal static class FloppyInventorySelection
{
private static FloppyStation owner;
private static Action<UpgradeInstance> selected;
private static readonly Action<UpgradeInstance> receive = Receive;
internal static bool Active
{
get
{
if ((Object)(object)owner != (Object)null && OuroGearWindow.OpenAsUpgradeSelect)
{
return OuroGearWindow.OnUpgradeSelected == receive;
}
return false;
}
}
internal static void Open(FloppyStation station, Action<UpgradeInstance> callback)
{
Cancel();
GameManager.Instance.OpenMenu(true);
owner = station;
selected = callback;
OuroGearWindow.OpenAsUpgradeSelect = true;
OuroGearWindow.OnUpgradeSelected = receive;
}
private static void Receive(UpgradeInstance upgrade)
{
if (Active)
{
Action<UpgradeInstance> action = selected;
Cancel();
action?.Invoke(upgrade);
}
}
internal static bool AllowNonStackable(UpgradeInstance upgrade)
{
if (!Active)
{
return upgrade.CanStack;
}
return true;
}
internal static void Cancel(FloppyStation station = null)
{
if (!((Object)(object)station != (Object)null) || !((Object)(object)owner != (Object)(object)station))
{
if (OuroGearWindow.OnUpgradeSelected == receive)
{
OuroGearWindow.OnUpgradeSelected = null;
OuroGearWindow.OpenAsUpgradeSelect = false;
}
owner = null;
selected = null;
}
}
}
[HarmonyPatch(typeof(OuroGearWindow), "AddUpgrade")]
internal static class FloppyInventoryStackFilter
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
MethodInfo getter = AccessTools.PropertyGetter(typeof(UpgradeInstance), "CanStack");
MethodInfo replacement = AccessTools.Method(typeof(FloppyInventorySelection), "AllowNonStackable", (Type[])null, (Type[])null);
int replaced = 0;
foreach (CodeInstruction instruction in instructions)
{
if (CodeInstructionExtensions.Calls(instruction, getter))
{
instruction.opcode = OpCodes.Call;
instruction.operand = replacement;
replaced++;
}
yield return instruction;
}
if (replaced != 1)
{
throw new InvalidOperationException("OuroGearWindow stack filter changed; Floppy patch was not applied.");
}
}
}
[HarmonyPatch(typeof(Menu), "OnClose")]
internal static class FloppyInventoryClose
{
private static void Postfix()
{
FloppyInventorySelection.Cancel();
}
}
[HarmonyPatch(typeof(MissionInfoWindow), "Setup")]
internal static class FloppyMissionTogglePatch
{
private static readonly FieldInfo ToggleField = AccessTools.Field(typeof(MissionInfoWindow), "toggleButton");
private static bool reportedError;
private static void Prefix(MissionInfoWindow __instance)
{
((Component)__instance).GetComponent<FloppyMissionToggle>()?.RestoreNativeLayout();
}
private static void Postfix(MissionInfoWindow __instance)
{
FloppyMissionToggle floppyMissionToggle = ((Component)__instance).GetComponent<FloppyMissionToggle>();
if ((Object)(object)FloppyPlugin.Instance == (Object)null || !(((MissionData)(ref __instance.Mission)).Mission is OuroMission))
{
floppyMissionToggle?.Hide();
return;
}
try
{
object? obj = ToggleField?.GetValue(__instance);
DefaultButton val = (DefaultButton)((obj is DefaultButton) ? obj : null);
if ((Object)(object)val == (Object)null)
{
throw new InvalidOperationException("The mission options toggle is unavailable.");
}
if ((Object)(object)floppyMissionToggle == (Object)null)
{
floppyMissionToggle = ((Component)__instance).gameObject.AddComponent<FloppyMissionToggle>();
}
floppyMissionToggle.Setup(__instance, val);
}
catch (Exception ex)
{
floppyMissionToggle?.Hide();
if (!reportedError)
{
reportedError = true;
FloppyPlugin.Log.LogError((object)("Could not add the Floppy mission option: " + ex));
}
}
}
}
internal sealed class FloppyMissionToggle : MonoBehaviour
{
private MissionInfoWindow window;
private DefaultButton nativeToggle;
private DefaultButton button;
private RectTransform nativeRect;
private RectTransform buttonRect;
private TextMeshProUGUI label;
private Image icon;
private CanvasGroup appearance;
private Vector2 nativePosition;
private bool hasNativePosition;
private bool visible;
private bool lastEnabled;
private bool lastCanEdit;
private bool lastAuthority;
private int lastLanguage = -1;
internal bool CanEdit
{
get
{
if ((Object)(object)FloppyPlugin.Instance != (Object)null && FloppyAvailability.CanEdit)
{
if (!((Object)(object)DropPod.Instance == (Object)null))
{
return !DropPod.Instance.IsLaunching;
}
return true;
}
return false;
}
}
internal void Setup(MissionInfoWindow owner, DefaultButton template)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_0026: 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)
window = owner;
nativeToggle = template;
nativeRect = (RectTransform)((Component)template).transform;
nativePosition = nativeRect.anchoredPosition;
hasNativePosition = true;
if ((Object)(object)button == (Object)null)
{
CreateButton(template);
}
visible = true;
PositionControls();
RefreshState(force: true);
((Component)button).gameObject.SetActive(true);
}
private void CreateButton(DefaultButton template)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Expected O, but got Unknown
button = Object.Instantiate<DefaultButton>(template, ((Component)template).transform.parent, false);
((Object)((Component)button).gameObject).name = "FloppyMissionToggle";
((Component)button).gameObject.SetActive(false);
buttonRect = (RectTransform)((Component)button).transform;
((Button)button).OnHoverEnter = new UnityEvent();
((Button)button).OnHoverExit = new UnityEvent();
((Button)button).OnClickDown = new UnityEvent();
((Button)button).OnClickUp = new UnityEvent();
((Button)button).OnClickUp.AddListener(new UnityAction(OnClick));
label = ((Component)button).GetComponentInChildren<TextMeshProUGUI>(true);
ref Image reference = ref icon;
Graphic secondaryGraphic = button.SecondaryGraphic;
reference = (Image)(object)((secondaryGraphic is Image) ? secondaryGraphic : null);
if ((Object)(object)label == (Object)null || (Object)(object)icon == (Object)null || (Object)(object)button.MainGraphic == (Object)null)
{
throw new InvalidOperationException("The mission options toggle has an unsupported layout.");
}
appearance = ((Component)button).gameObject.AddComponent<CanvasGroup>();
((Component)button).gameObject.AddComponent<FloppyMissionToggleHint>().Owner = this;
((Component)button).GetComponent<Graphic>().raycastTarget = true;
}
private void PositionControls()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
if (!visible || (Object)(object)nativeRect == (Object)null || (Object)(object)buttonRect == (Object)null)
{
return;
}
Transform parent = ((Transform)nativeRect).parent;
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if (!((Object)(object)val == (Object)null))
{
Rect rect = val.rect;
float num = ((Rect)(ref rect)).width * 0.25f;
buttonRect.anchoredPosition = new Vector2(0f - num, nativePosition.y);
if (((Component)nativeToggle).gameObject.activeSelf)
{
nativeRect.anchoredPosition = new Vector2(num, nativePosition.y);
}
}
}
internal void RestoreNativeLayout()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
if (hasNativePosition && (Object)(object)nativeRect != (Object)null)
{
nativeRect.anchoredPosition = nativePosition;
}
hasNativePosition = false;
}
internal void Hide()
{
visible = false;
RestoreNativeLayout();
if ((Object)(object)button != (Object)null)
{
((Component)button).gameObject.SetActive(false);
}
}
private void OnClick()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if (visible && ((Behaviour)this).isActiveAndEnabled && !((Object)(object)window == (Object)null) && ((Component)window).gameObject.activeInHierarchy && ((MissionData)(ref window.Mission)).Mission is OuroMission && CanEdit && (int)((Button)button).LastPressButton == 0)
{
FloppyAvailability.SetEnabled(!FloppyAvailability.Enabled);
RefreshState(force: true);
}
}
private void LateUpdate()
{
if (visible && !((Object)(object)button == (Object)null))
{
if ((Object)(object)FloppyPlugin.Instance == (Object)null)
{
Hide();
}
else
{
RefreshState(force: false);
}
}
}
private void OnRectTransformDimensionsChange()
{
PositionControls();
}
private void RefreshState(bool force)
{
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
bool enabled = FloppyAvailability.Enabled;
bool canEdit = CanEdit;
bool canEdit2 = FloppyAvailability.CanEdit;
int languageIndex = TextBlocks.LanguageIndex;
if (force || lastEnabled != enabled || lastCanEdit != canEdit || lastAuthority != canEdit2 || lastLanguage != languageIndex)
{
lastEnabled = enabled;
lastCanEdit = canEdit;
lastAuthority = canEdit2;
lastLanguage = languageIndex;
((TMP_Text)label).text = (canEdit2 ? "Floppy" : "Floppy · HOST");
((Button)button).IgnoreEvents = !canEdit;
appearance.alpha = (canEdit ? 1f : 0.55f);
icon.sprite = (enabled ? Global.Instance.CheckmarkIcon : Global.Instance.CrossIcon);
button.SetDefaultColor(enabled ? Global.Instance.RedUIColor : Global.Instance.WhiteUIColor);
RectOutline val = default(RectOutline);
float num = (((Component)button).TryGetComponent<RectOutline>(ref val) ? ((OutlineGraphic)val).thickness : 1.5f);
RectTransform rectTransform = button.MainGraphic.rectTransform;
Rect rect = ((RectTransform)((Transform)rectTransform).parent).rect;
float num2 = ((Rect)(ref rect)).width * 0.5f;
rect = rectTransform.rect;
float num3 = num2 - ((Rect)(ref rect)).width * 0.5f - num;
rectTransform.anchoredPosition = new Vector2(enabled ? num3 : (0f - num3), rectTransform.anchoredPosition.y);
if (((Button)button).Hovering && (Object)(object)HoverInfoDisplay.Instance != (Object)null)
{
HoverInfoDisplay.Instance.Refresh();
}
}
}
private void OnDestroy()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
RestoreNativeLayout();
if ((Object)(object)button != (Object)null)
{
((Button)button).OnClickUp.RemoveListener(new UnityAction(OnClick));
((Component)button).gameObject.SetActive(false);
Object.Destroy((Object)(object)((Component)button).gameObject);
}
}
internal static void DisposeAll()
{
FloppyMissionToggle[] array = Object.FindObjectsByType<FloppyMissionToggle>((FindObjectsInactive)1);
foreach (FloppyMissionToggle obj in array)
{
obj.Hide();
Object.Destroy((Object)(object)obj);
}
}
}
internal sealed class FloppyMissionToggleHint : HoverInfo
{
internal FloppyMissionToggle Owner;
public override string GetInfo(HoverInfoDisplay display)
{
if (!FloppyAvailability.CanEdit)
{
return "The lobby host chooses whether Floppy appears.";
}
if ((Object)(object)Owner == (Object)null || !Owner.CanEdit)
{
return "Deployment has already started.";
}
return "Replace Ouroboros shops with Floppy. Change this before starting or continuing a run.";
}
public override bool GetTitle(out string title, out Color color)
{
//IL_000d: 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)
title = "Floppy";
color = Global.Instance.WhiteUIColor;
return true;
}
public override bool CanChangeCursor(out CursorData cursor)
{
//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)
cursor = Global.Instance.GetPointCursor();
if ((Object)(object)Owner != (Object)null)
{
return Owner.CanEdit;
}
return false;
}
}
[BepInPlugin("horse.mycopunk.floppy", "Floppy", "0.4.1")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public sealed class FloppyPlugin : BaseUnityPlugin
{
public const string Guid = "horse.mycopunk.floppy";
internal static FloppyPlugin Instance;
internal static ManualLogSource Log;
internal ConfigEntry<bool> Enabled;
internal ConfigEntry<float> Volume;
private Harmony harmony;
private void Awake()
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Replace Ouroboros shops with Floppy.");
Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.6f, new ConfigDescription("Spatial retro PC sound volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
try
{
ModelAssets.Load();
PcAudio.Load();
harmony = new Harmony("horse.mycopunk.floppy");
harmony.PatchAll(typeof(FloppyPlugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Floppy loaded. Three exchanges per player per shop appearance.");
}
catch (Exception ex)
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
((BaseUnityPlugin)this).Logger.LogError((object)("Floppy could not load; vanilla shops remain available: " + ex));
}
}
private void OnDestroy()
{
FloppyMissionToggle.DisposeAll();
FloppyAvailability.Dispose();
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
FloppyInventorySelection.Cancel();
FloppyStation[] array = Object.FindObjectsByType<FloppyStation>((FindObjectsInactive)1);
foreach (FloppyStation obj2 in array)
{
((Component)obj2).gameObject.SetActive(false);
obj2.RestoreVanilla();
Object.Destroy((Object)(object)((Component)obj2).gameObject);
}
FloppyDeferredShop.DisposeAll();
ModelAssets.Dispose();
PcAudio.Dispose();
Instance = null;
}
private void Update()
{
FloppyAvailability.Tick(Time.unscaledTime);
}
}
[HarmonyPatch(typeof(OuroStoreRoom), "Setup")]
internal static class ReplaceShop
{
private static bool Prefix(OuroStoreRoom __instance, OuroObjective objective, OuroItemPositions itemPositions, OuroRoom room, int seed)
{
if ((Object)(object)FloppyPlugin.Instance == (Object)null || !ModelAssets.Ready)
{
return true;
}
FloppyStation floppyStation = ((Component)__instance).GetComponentInChildren<FloppyStation>(true);
FloppyDeferredShop floppyDeferredShop = ((Component)__instance).GetComponent<FloppyDeferredShop>();
if (!FloppyAvailability.IsSynchronized)
{
if ((Object)(object)floppyStation != (Object)null)
{
((Component)floppyStation).gameObject.SetActive(false);
}
if ((Object)(object)floppyDeferredShop == (Object)null)
{
floppyDeferredShop = ((Component)__instance).gameObject.AddComponent<FloppyDeferredShop>();
}
floppyDeferredShop.Defer(__instance, objective, itemPositions, room, seed);
return false;
}
floppyDeferredShop?.Clear();
if (!FloppyAvailability.Enabled)
{
if ((Object)(object)floppyStation != (Object)null)
{
((Component)floppyStation).gameObject.SetActive(false);
floppyStation.RestoreVanilla();
}
return true;
}
try
{
if ((Object)(object)floppyStation == (Object)null)
{
floppyStation = ModelAssets.Instantiate(((Component)__instance).transform).AddComponent<FloppyStation>();
}
floppyStation.Setup(__instance, objective, itemPositions, room, seed);
return false;
}
catch (Exception ex)
{
FloppyPlugin.Log.LogError((object)("Floppy setup failed; restoring vanilla shop: " + ex));
if ((Object)(object)floppyStation != (Object)null)
{
floppyStation.RestoreVanilla();
Object.Destroy((Object)(object)((Component)floppyStation).gameObject);
}
return true;
}
}
}
[HarmonyPatch(typeof(OuroObjective), "SpawnShop_ClientRpc")]
internal static class FloppyShopAnnouncement
{
private static void Prefix(ref bool playVoiceline)
{
if ((Object)(object)FloppyPlugin.Instance != (Object)null && ModelAssets.Ready && FloppyAvailability.IsSynchronized && FloppyAvailability.Enabled)
{
playVoiceline = false;
}
}
}
internal sealed class FloppyShopHint : HoverInfo
{
internal FloppyStation Owner;
private string shownText;
private UpgradeInstance shownModule;
private bool shownCanConfirm;
private InputAction cancelAction;
internal bool CancelPressed
{
get
{
if (cancelAction != null)
{
return cancelAction.WasPressedThisFrame();
}
return false;
}
}
public override bool CenterText => false;
public override object Context
{
get
{
if (!((Object)(object)Owner != (Object)null))
{
return this;
}
return ((object)Owner.SelectedModule) ?? ((object)Owner);
}
}
private void OnEnable()
{
//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 (cancelAction == null)
{
MenuActions menu = PlayerInput.Controls.Menu;
cancelAction = ((MenuActions)(ref menu)).Cancel.Clone();
}
cancelAction.Enable();
}
public override bool HasAnchor(out AnchorParams anchor)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
anchor = new AnchorParams
{
Pivot = new Vector2(0.5f, 1f),
Offset = new Vector2(0f, -110f),
GamepadOnly = false
};
return true;
}
public override string GetInfo(HoverInfoDisplay display)
{
if (!((Object)(object)Owner != (Object)null))
{
return "";
}
return Owner.HintText;
}
public override bool GetTitle(out string title, out Color color)
{
//IL_000d: 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)
title = "Floppy";
color = Global.Instance.WhiteUIColor;
return true;
}
public override bool GetSubtitle(out string subtitle, out Color color)
{
//IL_0042: 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)
UpgradeInstance val = (((Object)(object)Owner != (Object)null) ? Owner.SelectedModule : null);
subtitle = ((val != null) ? val.Upgrade.GetInstanceName(val) : null);
color = ((val != null) ? val.Upgrade.Color : Color.white);
return val != null;
}
public override Color GetOutlineColor(out Material material)
{
//IL_003f: 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)
UpgradeInstance val = (((Object)(object)Owner != (Object)null) ? Owner.SelectedModule : null);
material = FloppyUiMaterial.Resolve((val != null) ? val.UIMaterial : null);
if (val == null)
{
return Color.white;
}
return val.Upgrade.Color;
}
public override bool GetPrimaryBinding(out InputAction binding, out string label)
{
//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)
PlayerActions player = PlayerInput.Controls.Player;
binding = ((PlayerActions)(ref player)).Interact;
label = "Exchange";
if ((Object)(object)Owner != (Object)null)
{
return Owner.CanConfirmExchange;
}
return false;
}
public override bool GetSecondaryBinding(out InputAction binding, out string label)
{
binding = cancelAction;
label = "Cancel";
if ((Object)(object)Owner != (Object)null && Owner.CanCancelSelection)
{
return cancelAction != null;
}
return false;
}
public override bool HasUnlockAction(out UnlockActionParams data)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
data = default(UnlockActionParams);
if ((Object)(object)Owner == (Object)null || !Owner.CanConfirmExchange)
{
return false;
}
data.Duration = 0.65f;
data.Cost = ExchangeRules.Cost(Owner.SelectedModule);
PlayerActions player = PlayerInput.Controls.Player;
data.Action = ((PlayerActions)(ref player)).Interact;
data.UnlockLoop = WwiseEvent.op_Implicit(Global.Instance.UnlockLoop);
data.OnComplete = Confirm;
return true;
}
private void Confirm()
{
if ((Object)(object)Owner != (Object)null && Owner.CanConfirmExchange)
{
Owner.Interact(Player.LocalPlayer);
}
}
private void Update()
{
HoverInfoDisplay instance = HoverInfoDisplay.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
if (!((Object)(object)Owner != (Object)null) || !((Object)(object)Highlighter.Instance != (Object)null) || (object)Highlighter.Instance.SelectedTarget != Owner || !Highlighter.Instance.IsSelectedTargetInInteractRange || !PlayerInput.IsPlayerEnabled || PlayerInput.IsMenuEnabled || !PositionAnchor(instance))
{
if ((Object)(object)instance.SelectedInfo == (Object)(object)this && ((Component)instance).gameObject.activeSelf)
{
instance.Deactivate();
}
return;
}
string hintText = Owner.HintText;
UpgradeInstance selectedModule = Owner.SelectedModule;
bool canConfirmExchange = Owner.CanConfirmExchange;
if ((Object)(object)instance.SelectedInfo != (Object)(object)this || !((Component)instance).gameObject.activeSelf)
{
instance.ShowInfo((HoverInfo)(object)this);
}
else if (shownText != hintText || shownModule != selectedModule || shownCanConfirm != canConfirmExchange)
{
instance.Refresh();
}
shownText = hintText;
shownModule = selectedModule;
shownCanConfirm = canConfirmExchange;
}
private void LateUpdate()
{
HoverInfoDisplay instance = HoverInfoDisplay.Instance;
if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.SelectedInfo != (Object)(object)this) && ((Component)instance).gameObject.activeSelf && (!PlayerInput.IsPlayerEnabled || PlayerInput.IsMenuEnabled || !PositionAnchor(instance)))
{
instance.Deactivate();
}
}
private bool PositionAnchor(HoverInfoDisplay display)
{
//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)
Canvas componentInParent = ((Component)display).GetComponentInParent<Canvas>();
Camera val = (((Object)(object)componentInParent != (Object)null) ? componentInParent.worldCamera : null);
if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
{
val = PlayerLook.LocalUICamera;
}
if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
{
return false;
}
((Component)this).transform.position = val.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, Mathf.Max(1f, val.nearClipPlane + 1f)));
return true;
}
protected override void OnDisable()
{
InputAction obj = cancelAction;
if (obj != null)
{
obj.Disable();
}
HoverInfoDisplay instance = HoverInfoDisplay.Instance;
if ((Object)(object)instance != (Object)null && (Object)(object)instance.SelectedInfo == (Object)(object)this)
{
instance.Deactivate();
}
((HoverInfo)this).OnDisable();
}
private void OnDestroy()
{
InputAction obj = cancelAction;
if (obj != null)
{
obj.Dispose();
}
}
}
public sealed class FloppyStation : MonoBehaviour, IInteractable, ISelectable
{
private readonly FloppyVisitState visits = new FloppyVisitState();
private readonly List<GameObject> hiddenVanilla = new List<GameObject>();
private FloppyVisitState.Visit visit;
private OuroStoreRoom shop;
private OuroObjective objective;
private int seed;
private Transform tray;
private Transform carriage;
private Transform socket;
private PcSpeaker speaker;
private Renderer powerLed;
private Renderer readLed;
private GameObject preview;
private FloppyShopHint shopHint;
private UpgradeInstance pending;
private bool busy;
private bool reading;
private bool powered;
public bool HoldToInteract => false;
public bool IsInspectable => false;
public bool EndInteractOnFocusLoss => false;
public InputAction InteractBinding
{
get
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
PlayerActions player = PlayerInput.Controls.Player;
return ((PlayerActions)(ref player)).Interact;
}
}
public bool UsesInteractBinding => true;
public bool EnableInteractableHighlighting
{
get
{
if (pending == null)
{
return CanInteract(Player.LocalPlayer);
}
return false;
}
}
public bool DrawWithInteractableMaterial => true;
public float Health => 1f;
public float NormalizedHealth => 1f;
public float LastSelectedTime => 0f;
public float HoldToInteractDuration => 0.65f;
public bool ShowHighlightVisual => false;
public bool EnableHighlighting => visit != null;
public List<TargetMesh> Meshes => null;
public string InteractText => "Floppy";
internal UpgradeInstance SelectedModule => pending;
internal bool CanConfirmExchange
{
get
{
if (pending != null)
{
return CanInteract(Player.LocalPlayer);
}
return false;
}
}
internal string HintText => "Attempts: " + (visit?.Remaining ?? 3) + "/" + 3;
internal bool CanCancelSelection
{
get
{
if (pending != null)
{
return !busy;
}
return false;
}
}
public bool Exists()
{
return (Object)(object)this != (Object)null;
}
public void EndInteract(Player player)
{
}
internal void Setup(OuroStoreRoom owner, OuroObjective source, OuroItemPositions positions, OuroRoom room, int shopSeed)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Expected O, but got Unknown
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_029d: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: 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_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_027d: Unknown result type (might be due to invalid IL or missing references)
//IL_0328: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_0335: Unknown result type (might be due to invalid IL or missing references)
//IL_0364: Unknown result type (might be due to invalid IL or missing references)
//IL_0374: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
//IL_030b: Unknown result type (might be due to invalid IL or missing references)
//IL_030f: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_031c: Unknown result type (might be due to invalid IL or missing references)
//IL_0321: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0304: Unknown result type (might be due to invalid IL or missing references)
//IL_0309: Unknown result type (might be due to invalid IL or missing references)
//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0403: Unknown result type (might be due to invalid IL or missing references)
string key = ((object)((Object)source).GetEntityId()/*cast due to .constrained prefix*/).ToString() + ":" + shopSeed + ":" + (((Object)(object)room != (Object)null) ? ((object)((Object)room).GetEntityId()/*cast due to .constrained prefix*/).ToString() : (((Object)(object)positions != (Object)null) ? ((object)((Object)positions).GetEntityId()/*cast due to .constrained prefix*/).ToString() : "0"));
if (visits.CanKeep(key, ((Component)this).gameObject.activeInHierarchy, powered, busy))
{
return;
}
FloppyInventorySelection.Cancel(this);
((MonoBehaviour)this).StopAllCoroutines();
if ((Object)(object)speaker != (Object)null)
{
PcAudio.Stop(speaker);
}
ClearPreview();
pending = null;
busy = false;
reading = false;
shop = owner;
objective = source;
seed = shopSeed;
visit = visits.Enter(key);
if ((Object)(object)shopHint == (Object)null)
{
GameObject val = new GameObject("Floppy_ShopHint");
val.transform.SetParent(((Component)this).transform, false);
val.transform.localPosition = Vector3.up * 0.90110904f;
shopHint = val.AddComponent<FloppyShopHint>();
shopHint.Owner = this;
}
if ((Object)(object)tray == (Object)null)
{
tray = ((Component)this).transform.Find("Tray");
carriage = ((Component)this).transform.Find("RailCarriage");
socket = tray.Find("ModuleSocket");
speaker = ((Component)this).gameObject.AddComponent<PcSpeaker>();
Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
foreach (Renderer val2 in componentsInChildren)
{
if (((Object)val2).name == "PowerLED_Mesh")
{
powerLed = val2;
}
if (((Object)val2).name == "ReadLED_Mesh")
{
readLed = val2;
}
}
}
Vector3 val3 = default(Vector3);
Quaternion val4 = default(Quaternion);
if ((Object)(object)room != (Object)null)
{
val3 = ((Component)room).transform.position;
val4 = ((Component)room).transform.rotation;
}
else
{
if (!((Object)(object)positions != (Object)null) || ((TransformDataArray)(ref positions.Positions)).Length <= 0)
{
throw new InvalidOperationException("Shop has no item position.");
}
TransformData val5 = ((TransformDataArray)(ref positions.Positions))[0];
((TransformData)(ref val5)).GetGlobalPositionAndRotation(((Component)positions).transform, ref val3, ref val4);
}
RaycastHit val6 = default(RaycastHit);
if (Physics.Raycast(val3 + Vector3.up * 2f, Vector3.down, ref val6, 6f, 8193, (QueryTriggerInteraction)1))
{
Vector3 val7 = Vector3.ProjectOnPlane(val4 * Vector3.forward, ((RaycastHit)(ref val6)).normal);
if (((Vector3)(ref val7)).sqrMagnitude < 0.0001f)
{
val7 = Vector3.ProjectOnPlane(val4 * Vector3.up, ((RaycastHit)(ref val6)).normal);
}
val4 = Quaternion.LookRotation(val7, ((RaycastHit)(ref val6)).normal);
val3 = ((RaycastHit)(ref val6)).point;
}
((Component)this).transform.SetPositionAndRotation(val3, val4);
((Component)this).transform.localScale = Vector3.one;
HideVanilla(owner);
((Component)owner).gameObject.SetActive(true);
((Component)this).gameObject.SetActive(true);
tray.localPosition = Vector3.zero;
carriage.localPosition = Vector3.zero;
object? obj = AccessTools.Field(typeof(OuroStoreRoom), "waypointSprite")?.GetValue(owner);
Sprite val8 = (Sprite)((obj is Sprite) ? obj : null);
if ((Object)(object)val8 != (Object)null && (Object)(object)Highlighter.Instance != (Object)null)
{
Highlighter.Instance.AddWaypointPing(((Component)owner).transform, val8, new Color(0.2f, 0.85f, 0.62f)).localPosition = ((Component)owner).transform.InverseTransformPoint(val3 + Vector3.up * 1.1263863f);
}
((MonoBehaviour)this).StartCoroutine(PowerOn());
}
private void HideVanilla(OuroStoreRoom owner)
{
string[] array = new string[2] { "shelves", "upgrades" };
foreach (string text in array)
{
if (!(AccessTools.Field(typeof(OuroStoreRoom), text)?.GetValue(owner) is IEnumerable enumerable))
{
continue;
}
foreach (object item in enumerable)
{
object obj = ((item is GameObject) ? item : null);
if (obj == null)
{
object obj2 = ((item is Component) ? item : null);
obj = ((obj2 != null) ? ((Component)obj2).gameObject : null);
}
GameObject val = (GameObject)obj;
if ((Object)(object)val != (Object)null && val.activeSelf)
{
hiddenVanilla.Add(val);
val.SetActive(false);
}
}
}
}
internal void RestoreVanilla()
{
foreach (GameObject item in hiddenVanilla)
{
if ((Object)(object)item != (Object)null)
{
item.SetActive(true);
}
}
hiddenVanilla.Clear();
}
private IEnumerator PowerOn()
{
busy = true;
powered = !visit.IsExhausted;
if (powered)
{
Play("power_on");
yield return (object)new WaitForSeconds(1.6f);
speaker.StartIdle();
yield return Slide(0.76969725f);
}
busy = false;
}
public void Interact(Player player)
{
if (!CanInteract(player))
{
return;
}
if (pending != null)
{
if (!ExchangeRules.CanSubmit(pending, out var reason))
{
Notice(reason);
pending = null;
ClearPreview();
return;
}
if (!PlayerData.Instance.CanAffordCost(ExchangeRules.Cost(pending)))
{
Notice("Not enough currency for this exchange.");
return;
}
UpgradeInstance val = ExchangeRules.Prepare(pending, seed + visit.Used * 104729 + pending.InstanceID);
if (val == null)
{
Notice("No other module of this rarity is available for this gear.");
}
else
{
((MonoBehaviour)this).StartCoroutine(Exchange(pending, val));
}
}
else
{
FloppyInventorySelection.Open(this, Select);
}
}
private bool CanInteract(Player player)
{
if (!busy && powered && visit != null && !visit.IsExhausted && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.LocalPlayer && player.IsAlive && (Object)(object)objective != (Object)null && !((ObjectiveBase)objective).HasEnded)
{
return !objective.ContinuingToNextLevel;
}
return false;
}
private void Select(UpgradeInstance input)
{
if (CanInteract(Player.LocalPlayer))
{
if (!ExchangeRules.CanSubmit(input, out var reason))
{
Notice(reason);
return;
}
pending = input;
ShowModule(input);
}
}
private IEnumerator Exchange(UpgradeInstance input, UpgradeInstance output)
{
busy = true;
pending = null;
yield return (object)new WaitForSeconds(0.3f);
yield return Slide(0f);
reading = true;
Play("disk_read");
yield return (object)new WaitForSeconds(1.9f);
reading = false;
string reason = "Exchange cancelled: the stage has ended.";
if (CanFinish())
{
FloppyExchangeDiagnostics.LogState("before", input, output);
}
if (!CanFinish() || !ExchangeRules.Commit(input, output, out reason))
{
if (CanFinish())
{
FloppyExchangeDiagnostics.LogState("cancelled", input, output);
}
Notice(CanFinish() ? reason : "Exchange cancelled: the stage has ended.");
ClearPreview();
yield return Slide(0.76969725f);
busy = false;
yield break;
}
FloppyExchangeDiagnostics.LogState("after", input, output);
visit.RecordSuccess();
ShowModule(output);
Play("complete");
yield return Slide(0.76969725f);
Notice("Received: " + output.Upgrade.GetInstanceName(output) + ".");
yield return (object)new WaitForSeconds(1.8f);
ClearPreview();
if (visit.IsExhausted)
{
yield return Slide(0f);
speaker.StopIdle();
Play("power_off");
yield return (object)new WaitForSeconds(1.35f);
powered = false;
}
busy = false;
}
private bool CanFinish()
{
if ((Object)(object)objective != (Object)null && !((ObjectiveBase)objective).HasEnded && !objective.ContinuingToNextLevel && (Object)(object)Player.LocalPlayer != (Object)null)
{
return Player.LocalPlayer.IsAlive;
}
return false;
}
private IEnumerator Slide(float distance)
{
Play("tray");
float start = tray.localPosition.z;
for (float t = 0f; t < 0.75f; t += Time.deltaTime)
{
tray.localPosition = Vector3.forward * Mathf.Lerp(start, distance, Mathf.SmoothStep(0f, 1f, t / 0.75f));
carriage.localPosition = tray.localPosition * 0.5f;
yield return null;
}
tray.localPosition = Vector3.forward * distance;
carriage.localPosition = tray.localPosition * 0.5f;
}
private void ShowModule(UpgradeInstance module)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0043: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
ClearPreview();
Mesh upgradeEngramMesh = Global.Instance.UpgradeEngramMesh;
preview = new GameObject("Floppy_ModulePreview");
preview.transform.SetParent(socket, false);
preview.transform.localScale = Vector3.one * 0.5f;
Transform transform = preview.transform;
Bounds bounds = upgradeEngramMesh.bounds;
transform.localPosition = -((Bounds)(ref bounds)).center * 0.5f;
preview.AddComponent<MeshFilter>().sharedMesh = upgradeEngramMesh;
((Renderer)preview.AddComponent<MeshRenderer>()).sharedMaterial = Global.GetRarity(module.Upgrade.Rarity).collectableMat;
}
private void ClearPreview()
{
if ((Object)(object)preview != (Object)null)
{
Object.Destroy((Object)(object)preview);
}
preview = null;
}
private void Play(string name)
{
speaker.Play(name);
}
private void Notice(string text)
{
FloppyPlugin.Log.LogDebug((object)text);
}
internal void CancelSelection()
{
if (CanCancelSelection)
{
pending = null;
ClearPreview();
}
}
private void Update()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)shopHint != (Object)null && shopHint.CancelPressed)
{
CancelSelection();
}
SetLed(powerLed, (Color)(powered ? new Color(0.19f, 0.84f, 0.39f) : Color.black));
SetLed(readLed, (Color)((reading && Mathf.FloorToInt(Time.time * 15f) % 3 != 0) ? new Color(1f, 0.4f, 0.045f) : Color.black));
}
private static void SetLed(Renderer renderer, Color color)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_001d: 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_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)renderer == (Object)null))
{
MaterialPropertyBlock val = new MaterialPropertyBlock();
renderer.GetPropertyBlock(val);
val.SetColor("_EmissionColor", color * 2f);
val.SetFloat("_Emission", (((Color)(ref color)).maxColorComponent > 0f) ? 2f : 0f);
val.SetFloat("_UseEmission", (((Color)(ref color)).maxColorComponent > 0f) ? 1f : 0f);
val.SetColor("_ShadowColor", color);
val.SetColor("_BaseColor", color);
val.SetColor("_Color", color);
renderer.SetPropertyBlock(val);
}
}
private void OnDisable()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
FloppyInventorySelection.Cancel(this);
((MonoBehaviour)this).StopAllCoroutines();
ClearPreview();
if ((Object)(object)tray != (Object)null)
{
tray.localPosition = Vector3.zero;
}
if ((Object)(object)carriage != (Object)null)
{
carriage.localPosition = Vector3.zero;
}
pending = null;
reading = false;
busy = false;
powered = false;
if ((Object)(object)speaker != (Object)null)
{
PcAudio.Stop(speaker);
}
}
private void OnDestroy()
{
if ((Object)(object)shop != (Object)null && (Object)(object)Highlighter.Instance != (Object)null)
{
Highlighter.Instance.RemovePing(((Component)shop).transform);
}
}
GameObject ISelectable.get_gameObject()
{
return ((Component)this).gameObject;
}
Transform ISelectable.get_transform()
{
return ((Component)this).transform;
}
string ISelectable.get_name()
{
return ((Object)this).name;
}
}
internal static class FloppyUiMaterial
{
private static readonly string[] MaskProperties = new string[6] { "_Stencil", "_StencilOp", "_StencilComp", "_StencilReadMask", "_StencilWriteMask", "_ColorMask" };
internal static Material Resolve(Material material)
{
if ((Object)(object)material == (Object)null)
{
return null;
}
string[] maskProperties = MaskProperties;
foreach (string text in maskProperties)
{
if (!material.HasProperty(text))
{
return null;
}
}
return material;
}
}
internal sealed class FloppyVisitState
{
internal sealed class Visit
{
internal int Used { get; private set; }
internal int Remaining => 3 - Used;
internal bool IsExhausted => Used >= 3;
internal void RecordSuccess()
{
if (IsExhausted)
{
throw new InvalidOperationException("Floppy visit has no exchanges remaining.");
}
Used++;
}
}
internal const int Limit = 3;
private readonly Dictionary<string, Visit> visits = new Dictionary<string, Visit>();
internal string Key { get; private set; }
internal Visit Current { get; private set; }
internal bool CanKeep(string key, bool active, bool powered, bool busy)
{
if (Key == key && Current != null && active)
{
if (!(powered || busy))
{
return Current.IsExhausted;
}
return true;
}
return false;
}
internal Visit Enter(string key)
{
Key = key;
if (!visits.TryGetValue(key, out var value))
{
visits.Add(key, value = new Visit());
}
Current = value;
return value;
}
}
internal static class ModelAssets
{
private sealed class Part
{
internal string Assembly;
internal Mesh Mesh;
internal int Material;
}
private sealed class Surface
{
internal string Name;
internal Color Color;
internal float Emission;
}
private static readonly List<Part> parts = new List<Part>();
private static readonly List<Surface> surfaces = new List<Surface>();
private static Texture2D plastic;
private static Texture2D metal;
private static string loggedShader;
internal static bool Ready => parts.Count > 0;
internal static void Load()
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_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_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)
//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Expected O, but got Unknown
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Floppy.Model") ?? throw new InvalidDataException("Embedded Floppy model missing.");
using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8);
if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "FLOPPY01")
{
throw new InvalidDataException("Unknown Floppy mesh version.");
}
int num = Count(binaryReader, 64);
for (int i = 0; i < num; i++)
{
surfaces.Add(new Surface
{
Name = ReadString(binaryReader),
Color = new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
Emission = binaryReader.ReadSingle()
});
}
int num2 = Count(binaryReader, 64);
for (int j = 0; j < num2; j++)
{
string text = ReadString(binaryReader);
int num3 = binaryReader.ReadInt32();
if (num3 < 0 || num3 >= surfaces.Count)
{
throw new InvalidDataException("Bad material index.");
}
int num4 = Count(binaryReader, 300000);
if (num4 % 3 != 0)
{
throw new InvalidDataException("Incomplete triangle.");
}
Vector3[] array = (Vector3[])(object)new Vector3[num4];
Vector3[] array2 = (Vector3[])(object)new Vector3[num4];
Vector2[] array3 = (Vector2[])(object)new Vector2[num4];
int[] array4 = new int[num4];
for (int k = 0; k < num4; k++)
{
array[k] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
array2[k] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
array3[k] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
array4[k] = k;
}
Mesh val = new Mesh
{
name = "Floppy_" + text + "_" + j,
indexFormat = (IndexFormat)(num4 > 65535)
};
val.vertices = array;
val.normals = array2;
val.uv = array3;
val.triangles = array4;
val.RecalculateBounds();
val.UploadMeshData(true);
parts.Add(new Part
{
Assembly = text,
Mesh = val,
Material = num3
});
}
if (stream.Position != stream.Length)
{
throw new InvalidDataException("Trailing model data.");
}
plastic = LoadTexture("Plastic");
metal = LoadTexture("Metal");
}
private static int Count(BinaryReader reader, int maximum)
{
int num = reader.ReadInt32();
if (num < 0 || num > maximum)
{
throw new InvalidDataException("Invalid mesh count.");
}
return num;
}
private static string ReadString(BinaryReader reader)
{
return Encoding.UTF8.GetString(reader.ReadBytes(Count(reader, 1024)));
}
internal static GameObject Instantiate(Transform parent)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0024: 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_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Expected O, but got Unknown
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_0458: Unknown result type (might be due to invalid IL or missing references)
//IL_045d: Unknown result type (might be due to invalid IL or missing references)
//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
//IL_050d: Unknown result type (might be due to invalid IL or missing references)
//IL_0517: Unknown result type (might be due to invalid IL or missing references)
//IL_049b: Unknown result type (might be due to invalid IL or missing references)
//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Floppy");
val.SetActive(false);
val.transform.SetParent(parent, false);
try
{
Transform transform = new GameObject("Tray").transform;
transform.SetParent(val.transform, false);
Transform transform2 = new GameObject("RailCarriage").transform;
transform2.SetParent(val.transform, false);
((Component)transform).gameObject.layer = 12;
BoxCollider obj = ((Component)transform).gameObject.AddComponent<BoxCollider>();
((Collider)obj).isTrigger = true;
obj.center = ModelMetrics.TrayCenter;
obj.size = ModelMetrics.TraySize;
Shader val2 = FindShader("Shader Graphs/PastelObjUV") ?? FindShader("Shader Graphs/Pastel") ?? FindShader("Universal Render Pipeline/Unlit");
if ((Object)(object)val2 == (Object)null)
{
throw new InvalidOperationException("No supported loaded shader found.");
}
if (loggedShader != ((Object)val2).name)
{
loggedShader = ((Object)val2).name;
FloppyPlugin.Log.LogInfo((object)("Floppy surfaces: " + ((Object)val2).name + "; embedded Plastic/Metal 512x512; shop module scale 0.5."));
}
Material[] array = (Material[])(object)new Material[surfaces.Count];
for (int i = 0; i < array.Length; i++)
{
Surface surface = surfaces[i];
Material val3 = new Material(val2)
{
name = surface.Name
};
SetColor(val3, surface.Color);
if (val3.HasProperty("_ShadowColor"))
{
val3.SetColor("_ShadowColor", new Color(surface.Color.r * 0.72f, surface.Color.g * 0.72f, surface.Color.b * 0.72f, 1f));
}
bool flag = surface.Name.Contains("Steel");
Texture2D val4 = (flag ? metal : ((surface.Name.Contains("Ivory") || surface.Name.Contains("Bezel") || surface.Name.Contains("Rubber") || surface.Name.Contains("Badge")) ? plastic : Texture2D.whiteTexture));
if (val3.HasProperty("_MainTex"))
{
val3.SetTexture("_MainTex", (Texture)(object)val4);
}
if (val3.HasProperty("_BaseMap"))
{
val3.SetTexture("_BaseMap", (Texture)(object)val4);
}
if (val3.HasProperty("_SecondaryTex"))
{
val3.SetTexture("_SecondaryTex", (Texture)(object)val4);
}
if (val3.HasProperty("_MainTexTile"))
{
val3.SetFloat("_MainTexTile", 1f);
}
if (val3.HasProperty("_SecondaryTexTile"))
{
val3.SetFloat("_SecondaryTexTile", 1f);
}
if (val3.HasProperty("_MainBlend"))
{
val3.SetFloat("_MainBlend", 0f);
}
if (val3.HasProperty("_SunColorIntensity"))
{
val3.SetFloat("_SunColorIntensity", 0.5f);
}
if (val3.HasProperty("_Infection"))
{
val3.SetFloat("_Infection", 0f);
}
if (val3.HasProperty("_SpecularMap"))
{
val3.SetTexture("_SpecularMap", (Texture)(object)Texture2D.blackTexture);
}
if (val3.HasProperty("_Smoothness"))
{
val3.SetFloat("_Smoothness", 0.22f);
}
if (val3.HasProperty("_Metallic"))
{
val3.SetFloat("_Metallic", flag ? 0.65f : 0f);
}
if (val3.HasProperty("_Emission"))
{
val3.SetFloat("_Emission", surface.Emission);
}
if (val3.HasProperty("_UseEmission"))
{
val3.SetFloat("_UseEmission", (float)((surface.Emission > 0f) ? 1 : 0));
}
if (surface.Emission > 0f)
{
val3.EnableKeyword("_EMISSION");
if (val3.HasProperty("_EmissionColor"))
{
val3.SetColor("_EmissionColor", surface.Color * surface.Emission);
}
}
array[i] = val3;
}
val.AddComponent<ModelMaterialOwner>().Materials = array;
foreach (Part part in parts)
{
GameObject val5 = new GameObject(part.Assembly + "_Mesh");
val5.transform.SetParent((part.Assembly == "Tray") ? transform : ((part.Assembly == "RailCarriage") ? transform2 : val.transform), false);
val5.AddComponent<MeshFilter>().sharedMesh = part.Mesh;
((Renderer)val5.AddComponent<MeshRenderer>()).sharedMaterial = array[part.Material];
}
Transform transform3 = new GameObject("ModuleSocket").transform;
transform3.SetParent(transform, false);
transform3.localPosition = ModelMetrics.SocketCenter;
val.layer = 12;
BoxCollider obj2 = val.AddComponent<BoxCollider>();
obj2.center = ModelMetrics.CaseCenter;
obj2.size = ModelMetrics.CaseSize;
return val;
}
catch
{
Object.Destroy((Object)(object)val);
throw;
}
}
internal static void SetColor(Material material, Color color)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (material.HasProperty("_BaseColor"))
{
material.SetColor("_BaseColor", color);
}
if (material.HasProperty("_Color"))
{
material.SetColor("_Color", color);
}
}
private static Shader FindShader(string name)
{
Shader val = Shader.Find(name);
if (!((Object)(object)val != (Object)null) || !val.isSupported)
{
return null;
}
return val;
}
private static Texture2D LoadTexture(string name)
{
//IL_00c3: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Expected O, but got Unknown
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Floppy.Texture." + name) ?? throw new InvalidDataException("Embedded Floppy surface missing: " + name);
using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8);
if (Encoding.ASCII.GetString(binaryReader.ReadBytes(8)) != "FLPTEX01")
{
throw new InvalidDataException("Unknown Floppy surface format: " + name);
}
int num = binaryReader.ReadInt32();
int num2 = binaryReader.ReadInt32();
if (num <= 0 || num2 <= 0 || num > 1024 || num2 > 1024 || stream.Length - stream.Position != num * num2 * 3)
{
throw new InvalidDataException("Invalid Floppy surface dimensions: " + name);
}
byte[] array = binaryReader.ReadBytes(num * num2 * 3);
Texture2D val = new Texture2D(num, num2, (TextureFormat)3, true, false)
{
name = "Floppy_" + name,
wrapMode = (TextureWrapMode)0,
filterMode = (FilterMode)2,
anisoLevel = 2
};
try
{
val.SetPixelData<byte>(array, 0, 0);
val.Apply(true, true);
return val;
}
catch
{
Object.Destroy((Object)(object)val);
throw;
}
}
internal static void Dispose()
{
foreach (Part part in parts)
{
if ((Object)(object)part.Mesh != (Object)null)
{
Object.Destroy((Object)(object)part.Mesh);
}
}
parts.Clear();
surfaces.Clear();
if ((Object)(object)plastic != (Object)null)
{
Object.Destroy((Object)(object)plastic);
}
if ((Object)(object)metal != (Object)null)
{
Object.Destroy((Object)(object)metal);
}
plastic = (metal = null);
loggedShader = null;
}
}
internal sealed class ModelMaterialOwner : MonoBehaviour
{
internal Material[] Materials;
private void OnDestroy()
{
if (Materials == null)
{
return;
}
Material[] materials = Materials;
foreach (Material val in materials)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
}
}
internal static class ModelMetrics
{
internal const float BakedScale = 0.37546209f;
internal const float ModuleScale = 0.5f;
internal const float TrayTravel = 0.76969725f;
internal static readonly Vector3 SocketCenter = new Vector3(0f, 2.59f, 0.37f) * 0.37546209f;
internal static readonly Vector3 CaseCenter = new Vector3(0f, 2.41f, 0f) * 0.37546209f;
internal static readonly Vector3 CaseSize = new Vector3(2.45f, 4.82f, 2.8f) * 0.37546209f;
internal static readonly Vector3 TrayCenter = new Vector3(0f, 2.51f, 1.49f) * 0.37546209f;
internal static readonly Vector3 TraySize = new Vector3(1.96f, 1.74f, 0.15f) * 0.37546209f;
internal const float EmitterHeight = 0.90110904f;
internal const float WaypointHeight = 1.1263863f;
}
internal static class PcAudio
{
private static byte[] bank;
private static uint bankId;
private static bool loaded;
private static bool warned;
internal static void Load()
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Floppy.AudioBank") ?? throw new InvalidDataException("Embedded Floppy soundbank missing.");
using MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
bank = memoryStream.ToArray();
}
private unsafe static bool EnsureLoaded()
{
//IL_005f: 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)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Invalid comparison between Unknown and I4
if (loaded)
{
return true;
}
if (bank == null || !AkUnitySoundEngine.IsInitialized())
{
return false;
}
IntPtr hglobal = Marshal.AllocHGlobal(bank.Length + 15);
try
{
IntPtr intPtr = new IntPtr((hglobal.ToInt64() + 15) & -16);
Marshal.Copy(bank, 0, intPtr, bank.Length);
AKRESULT val = AkUnitySoundEngine.LoadBankMemoryCopy(intPtr, (uint)bank.Length, ref bankId);
loaded = (int)val == 1;
if (!loaded && !warned)
{
warned = true;
FloppyPlugin.Log.LogError((object)("Wwise rejected Floppy soundbank: " + ((object)(*(AKRESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
}
return loaded;
}
finally
{
Marshal.FreeHGlobal(hglobal);
}
}
internal static uint Post(string phase, GameObject emitter, EventCallback callback, object cookie)
{
if (!EnsureLoaded())
{
return 0u;
}
uint num = AkUnitySoundEngine.PostEvent("Play_Floppy_" + phase, emitter, 1u, callback, cookie);
if (num == 0 && !warned)
{
warned = true;
FloppyPlugin.Log.LogError((object)("Wwise could not post Floppy event: " + phase));
}
if (num != 0)
{
SetVolume(num);
}
return num;
}
internal static void SetVolume(uint id)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
if (id != 0 && (Object)(object)FloppyPlugin.Instance != (Object)null)
{
AkUnitySoundEngine.SetRTPCValueByPlayingID("User_Volume", FloppyPlugin.Instance.Volume.Value, id);
}
}
internal static void Stop(PcSpeaker speaker)
{
speaker.StopAll();
}
internal static void Dispose()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (loaded && AkUnitySoundEngine.IsInitialized())
{
AkUnitySoundEngine.UnloadBank(bankId, IntPtr.Zero);
}
loaded = false;
bank = null;
}
}
internal sealed class PcSpeaker : MonoBehaviour
{
private sealed class Playback
{
internal volatile uint Id;
internal volatile bool Ended;
}
private readonly ConcurrentDictionary<uint, Playback> playing = new ConcurrentDictionary<uint, Playback>();
private GameObject emitter;
private uint idle;
private float nextVolumeUpdate;
private EventCallback ended;
private void EnsureEmitter()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
if (!((Object)(object)emitter != (Object)null))
{
emitter = new GameObject("Floppy_Wwise_Emitter");
emitter.transform.SetParent(((Component)this).transform, false);
emitter.transform.localPosition = Vector3.up * 0.90110904f;
emitter.AddComponent<AkGameObj>();
ended = new EventCallback(OnEventEnded);
}
}
private uint PlayInternal(string phase)
{
EnsureEmitter();
Playback playback = new Playback();
uint num = (playback.Id = PcAudio.Post(phase, emitter, ended, playback));
if (num != 0 && !playback.Ended)
{
playing.TryAdd(num, playback);
}
return num;
}
internal void Play(string phase)
{
PlayInternal(phase);
}
internal void StartIdle()
{
StopIdle();
idle = PlayInternal("idle");
}
internal void StopIdle()
{
Stop(idle);
idle = 0u;
}
private void Stop(uint id)
{
if (id != 0 && playing.TryRemove(id, out var _))
{
AkUnitySoundEngine.StopPlayingID(id, 40);
}
}
private void OnEventEnded(object cookie, AkCallbackType type, AkCallbackInfo info)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
if ((int)type == 1 && cookie is Playback playback)
{
playback.Ended = true;
if (playback.Id != 0)
{
playing.TryRemove(playback.Id, out var _);
}
}
}
internal void StopAll()
{
foreach (uint key in playing.Keys)
{
Stop(key);
}
idle = 0u;
}
private void Update()
{
if (Time.unscaledTime < nextVolumeUpdate)
{
return;
}
nextVolumeUpdate = Time.unscaledTime + 0.25f;
foreach (uint key in playing.Keys)
{
PcAudio.SetVolume(key);
}
}
private void OnDisable()
{
StopAll();
}
private void OnDestroy()
{
StopAll();
if ((Object)(object)emitter != (Object)null)
{
Object.Destroy((Object)(object)emitter);
}
}
}
}