using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("InAirItems")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("InAirItems")]
[assembly: AssemblyTitle("InAirItems")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 InAirItems
{
[BepInPlugin("sbg.inairitems", "InAirItems", "0.2.1")]
public sealed class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(PlayerInventory), "TryUseSpringBoots")]
internal static class Patch_PlayerInventory_TryUseSpringBoots
{
private static void Postfix(PlayerInventory __instance, bool __result)
{
if (!__result || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isLocalPlayer)
{
return;
}
int equippedItemIndex = __instance.EquippedItemIndex;
int num = FindNextUsableSlot(__instance, equippedItemIndex);
if ((Object)(object)Instance != (Object)null && Instance.verboseLoggingConfig.Value)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)$"InAirItems: boots fired (currentIndex={equippedItemIndex}); next-usable-slot={num}.");
}
}
if (num >= 0 && num != equippedItemIndex && (Object)(object)Instance != (Object)null)
{
((MonoBehaviour)Instance).StartCoroutine(DeferredSelect(__instance, equippedItemIndex, num));
}
}
}
public const string ModGuid = "sbg.inairitems";
public const string ModName = "InAirItems";
public const string ModVersion = "0.2.1";
internal static ManualLogSource Log;
internal static Plugin Instance;
internal ConfigEntry<bool> verboseLoggingConfig;
private static MethodInfo getEffectiveSlotMethod;
private static FieldInfo equippedItemIndexBackingField;
private void Awake()
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
verboseLoggingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "VerboseLogging", false, "Emit diagnostic lines when boots fire, what next slot we tried to select, and whether vanilla TrySelectItemSlot accepted. Off by default; flip on if the auto-select still misbehaves.");
getEffectiveSlotMethod = AccessTools.Method(typeof(PlayerInventory), "GetEffectiveSlot", (Type[])null, (Type[])null);
equippedItemIndexBackingField = AccessTools.Field(typeof(PlayerInventory), "<EquippedItemIndex>k__BackingField");
new Harmony("sbg.inairitems").PatchAll();
Log.LogInfo((object)"InAirItems v0.2.1 loaded.");
}
private static IEnumerator DeferredSelect(PlayerInventory inventory, int bootsIndex, int nextIndex)
{
yield return null;
for (int attempt = 0; attempt < 3; attempt++)
{
if (!((Object)(object)inventory != (Object)null))
{
break;
}
if (inventory.EquippedItemIndex != bootsIndex)
{
LogVerbose($"InAirItems: equipped index changed to {inventory.EquippedItemIndex} before our select; skipping.");
yield break;
}
bool flag = inventory.TrySelectItemSlot(nextIndex);
LogVerbose($"InAirItems: TrySelectItemSlot({nextIndex}) attempt {attempt + 1} -> {flag}.");
if (flag)
{
yield break;
}
yield return null;
}
if ((Object)(object)inventory != (Object)null && inventory.EquippedItemIndex == bootsIndex && equippedItemIndexBackingField != null)
{
LogVerbose($"InAirItems: TrySelectItemSlot kept refusing; writing EquippedItemIndex = {nextIndex} directly.");
equippedItemIndexBackingField.SetValue(inventory, nextIndex);
PlayerInfo playerInfo = inventory.PlayerInfo;
if (playerInfo != null)
{
playerInfo.SetEquippedItemIndex(nextIndex);
}
}
}
private static int FindNextUsableSlot(PlayerInventory inventory, int startIndex)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Invalid comparison between Unknown and I4
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)GameManager.PlayerInventorySettings == (Object)null)
{
return -1;
}
int maxItems = GameManager.PlayerInventorySettings.MaxItems;
if (maxItems <= 0)
{
return -1;
}
for (int i = 1; i <= maxItems; i++)
{
int num = (startIndex + i) % maxItems;
if (num != startIndex)
{
InventorySlot val;
try
{
val = (InventorySlot)getEffectiveSlotMethod.Invoke(inventory, new object[1] { num });
}
catch
{
continue;
}
if ((int)val.itemType != 0 && (int)val.itemType != 5 && val.remainingUses > 0)
{
return num;
}
}
}
return -1;
}
private static void LogVerbose(string message)
{
if ((Object)(object)Instance != (Object)null && Instance.verboseLoggingConfig.Value)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)message);
}
}
}
}
}