using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.Localization.Components;
using UnityEngine.UI;
[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("HamiltonMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HamiltonMod")]
[assembly: AssemblyTitle("HamiltonMod")]
[assembly: AssemblyVersion("1.0.0.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 HamiltonMod
{
[BepInPlugin("codex.superbattlegolf.hamilton", "Hamilton", "0.1.17")]
public sealed class HamiltonPlugin : BaseUnityPlugin
{
private enum ShotOutcome
{
Normal,
Jam,
Backfire
}
[HarmonyPatch(typeof(PlayerInventory), "DecrementUseFromSlotAt")]
private static class KeepPistolLoadedPatch
{
private static bool Prefix(PlayerInventory __instance, int index)
{
return !IsReservedPistolSlot(__instance, index);
}
}
[HarmonyPatch(typeof(PlayerInventory), "RemoveIfOutOfUses")]
private static class PreventLoadedPistolRemovalPatch
{
private static bool Prefix(PlayerInventory __instance, int index)
{
return !IsReservedPistolSlot(__instance, index);
}
}
[HarmonyPatch(typeof(PlayerInventorySettings), "get_MaxItems")]
private static class MaxInventorySlotsPatch
{
private static void Postfix(ref int __result)
{
if (IsHamiltonEnabled())
{
__result = Mathf.Max(__result, 4);
}
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnStartServer")]
private static class ServerStartReservedPistolPatch
{
private static void Postfix(PlayerInventory __instance)
{
if (IsHamiltonEnabled() && NetworkServer.active)
{
EnsureReservedPistol(__instance);
}
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnStartClient")]
private static class ClientStartReservedPistolPatch
{
private static void Postfix(PlayerInventory __instance)
{
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnStartLocalPlayer")]
private static class LocalPlayerStartReservedPistolPatch
{
private static void Postfix(PlayerInventory __instance)
{
if (IsHamiltonEnabled() && NetworkServer.active)
{
EnsureReservedPistol(__instance);
}
}
}
[HarmonyPatch(typeof(PlayerInventory), "ServerTryAddItem")]
private static class ReservedSlotItemGrantPatch
{
private static bool Prefix(PlayerInventory __instance, ItemType itemToAdd, int remainingUses, ref bool __result)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
if (!IsHamiltonEnabled() || !NetworkServer.active)
{
return true;
}
if ((int)itemToAdd == 2)
{
EnsureReservedPistol(__instance);
__result = true;
return false;
}
EnsureReservedPistol(__instance);
return true;
}
}
[HarmonyPatch(typeof(PlayerInventory), "DropItem")]
private static class PreventDroppingReservedPistolPatch
{
private static bool Prefix(PlayerInventory __instance)
{
if (IsHamiltonEnabled())
{
return __instance.EquippedItemIndex != 0;
}
return true;
}
}
[HarmonyPatch(typeof(MatchSetupRules), "Initialize")]
private static class MatchSetupRulesInitializePatch
{
private static void Postfix()
{
instance?.TryInstallHamiltonRulesToggle();
}
}
[HarmonyPatch(typeof(MatchSetupRules), "OnStartClient")]
private static class MatchSetupRulesStartClientPatch
{
private static void Postfix()
{
instance?.TryInstallHamiltonRulesToggle();
}
}
[HarmonyPatch(typeof(ItemPool), "GetWeightedRandomItem")]
private static class RemovePistolFromItemPoolsPatch
{
private static bool Prefix(ItemPool __instance, ref ItemType __result)
{
if (!IsHamiltonEnabled())
{
return true;
}
return !TryGetWeightedRandomNonPistolItem(__instance, out __result);
}
}
[HarmonyPatch]
private static class DuelingPistolShotPatch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(PlayerInventory), "<ShootDuelingPistolRoutine>g__Shoot|164_0", (Type[])null, (Type[])null);
}
private static bool Prefix(PlayerInventory __instance)
{
if (!IsHamiltonEnabled() || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isLocalPlayer)
{
return true;
}
switch (RollShotOutcome())
{
case ShotOutcome.Jam:
QueueReloadJam(__instance);
return true;
case ShotOutcome.Backfire:
Backfire(__instance);
return false;
default:
return true;
}
}
private static void Postfix(PlayerInventory __instance)
{
if (IsHamiltonEnabled() && (Object)(object)__instance != (Object)null && ((NetworkBehaviour)__instance).isLocalPlayer)
{
ApplyReloadJam(__instance);
}
}
}
private const string PluginGuid = "codex.superbattlegolf.hamilton";
private const string PluginName = "Hamilton";
private const string PluginVersion = "0.1.17";
private const string LobbyEnabledStateKey = "codex_hamilton_enabled";
private const string LobbyEnabledVersionKey = "codex_hamilton_enabled_version";
private const string LobbyRequiredVersionKey = "codex_hamilton_required_version";
private const string LobbyMemberVersionKey = "codex_hamilton_member_version";
private const string ProGolfActiveStateKey = "codex_progolfplus_active";
private const float LobbyPollInterval = 1f;
private const float LocalMemberVersionPublishInterval = 2f;
private const float RulesUiRefreshInterval = 0.5f;
private const int ReservedPistolSlotIndex = 0;
private const int TotalInventorySlots = 4;
private static HamiltonPlugin instance;
private static FieldInfo inventorySlotsField;
private static FieldInfo itemPoolSpawnChancesField;
private static MethodInfo giveItemToLocalPlayerMethod;
private static FieldInfo itemUseTimestampField;
private static int syntheticItemUseIndex;
private static bool hasLobbyEnabledState;
private static bool lobbyEnabledState;
private static string lastObservedLobbyEnabledVersion = string.Empty;
private static float nextLobbyPollTime;
private static float nextLocalMemberVersionPublishTime;
private static bool allLobbyMembersCompatible = true;
private static string incompatibleLobbyMembers = string.Empty;
private static float nextCompatibilityWarningTime;
private static bool lastEffectiveEnabled;
private static bool proGolfPlusLobbyActive;
private static readonly Dictionary<Type, FieldInfo> spawnChanceItemFields = new Dictionary<Type, FieldInfo>();
private static readonly Dictionary<Type, FieldInfo> spawnChanceWeightFields = new Dictionary<Type, FieldInfo>();
private static readonly HashSet<PlayerInventory> pendingReloadJams = new HashSet<PlayerInventory>();
private Harmony harmony;
private ConfigEntry<bool> enabledConfig;
private ConfigEntry<float> grantCheckIntervalConfig;
private ConfigEntry<float> jamChanceConfig;
private ConfigEntry<float> jamReloadDelaySecondsConfig;
private ConfigEntry<float> backfireChanceConfig;
private ConfigEntry<bool> autoSelectPistolConfig;
private float nextGrantCheckTime;
private float nextRulesUiCheckTime;
private float nextRulesUiRefreshTime;
private DropdownOption hamiltonRulesDropdown;
private bool suppressHamiltonDropdownChanged;
private void Awake()
{
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Expected O, but got Unknown
instance = this;
enabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", false, "Enable Hamilton when Custom rules are selected.");
grantCheckIntervalConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "GrantCheckIntervalSeconds", 1f, "How often the mod checks whether the local player needs a pistol.");
jamChanceConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Chaos", "JamChance", 0.15f, "Chance from 0 to 1 that a pistol shot fires but reloads more slowly.");
jamReloadDelaySecondsConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Chaos", "JamReloadDelaySeconds", 1.5f, "Extra seconds added to the pistol reload when a jam happens.");
backfireChanceConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Chaos", "BackfireChance", 0.1f, "Chance from 0 to 1 that a pistol shot hits the shooter instead.");
autoSelectPistolConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoSelectPistol", false, "Automatically select the permanent pistol slot when the mod grants one.");
inventorySlotsField = AccessTools.Field(typeof(PlayerInventory), "slots");
itemUseTimestampField = AccessTools.Field(typeof(PlayerInventory), "<ItemUseTimestamp>k__BackingField");
itemPoolSpawnChancesField = AccessTools.Field(typeof(ItemPool), "spawnChances");
giveItemToLocalPlayerMethod = AccessTools.Method(typeof(PlayerInventory), "GiveItemToLocalPlayer", (Type[])null, (Type[])null);
harmony = new Harmony("codex.superbattlegolf.hamilton");
harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Hamilton 0.1.17 loaded.");
}
private void OnDestroy()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
if (instance == this)
{
instance = null;
}
}
private void Update()
{
PollSteamLobbyEnabledState();
TryInstallHamiltonRulesToggle();
RefreshHamiltonRulesToggleThrottled();
if (!IsHamiltonEnabled())
{
if (lastEffectiveEnabled && NetworkServer.active)
{
RemoveHamiltonPistolsFromAllPlayers();
}
lastEffectiveEnabled = false;
return;
}
lastEffectiveEnabled = true;
if (!(Time.unscaledTime < nextGrantCheckTime))
{
nextGrantCheckTime = Time.unscaledTime + Mathf.Max(0.25f, grantCheckIntervalConfig.Value);
TryEnsureLocalPlayerHasPistol();
}
}
private static bool IsHamiltonEnabled()
{
if (!IsHamiltonAllowedForCurrentPreset())
{
return false;
}
if (IsProGolfMatchUnderway())
{
return false;
}
if (NetworkServer.active && !allLobbyMembersCompatible)
{
return false;
}
if (hasLobbyEnabledState)
{
return lobbyEnabledState;
}
return instance?.enabledConfig.Value ?? false;
}
private static bool IsHamiltonAllowedForCurrentPreset()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
MatchSetupRules val = FindMatchSetupRules();
if ((Object)(object)val != (Object)null)
{
return (int)val.CurrentPreset == 2;
}
return false;
}
private static bool IsProGolfMatchUnderway()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Invalid comparison between Unknown and I4
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Invalid comparison between Unknown and I4
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
MatchSetupRules val = FindMatchSetupRules();
if ((Object)(object)val != (Object)null && (int)val.CurrentPreset == 1)
{
MatchState matchState = CourseManager.MatchState;
if ((int)matchState >= 1)
{
return (int)matchState < 6;
}
return false;
}
return proGolfPlusLobbyActive;
}
private void RefreshHamiltonRulesToggleThrottled()
{
if (!(Time.unscaledTime < nextRulesUiRefreshTime))
{
nextRulesUiRefreshTime = Time.unscaledTime + 0.5f;
RefreshHamiltonRulesToggle();
}
}
private static int DropdownValueFromEnabled(bool enabled)
{
return (!enabled) ? 1 : 0;
}
private static bool EnabledFromDropdownValue(int value)
{
return value == 0;
}
private static void PollSteamLobbyEnabledState()
{
//IL_005b: 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)
if (Time.unscaledTime < nextLobbyPollTime)
{
return;
}
nextLobbyPollTime = Time.unscaledTime + 1f;
Lobby lobby = default(Lobby);
if (!BNetworkManager.TryGetSteamLobby(ref lobby))
{
if (!NetworkServer.active && !NetworkClient.active)
{
hasLobbyEnabledState = false;
lastObservedLobbyEnabledVersion = string.Empty;
allLobbyMembersCompatible = true;
incompatibleLobbyMembers = string.Empty;
proGolfPlusLobbyActive = false;
}
return;
}
PublishLocalMemberVersion(lobby);
proGolfPlusLobbyActive = string.Equals(((Lobby)(ref lobby)).GetData("codex_progolfplus_active"), "1", StringComparison.Ordinal);
if (NetworkServer.active)
{
UpdateLobbyCompatibility(lobby);
}
string data = ((Lobby)(ref lobby)).GetData("codex_hamilton_enabled");
if (string.IsNullOrEmpty(data))
{
if (NetworkServer.active)
{
PublishSteamLobbyEnabledState(instance?.enabledConfig.Value ?? false);
}
return;
}
string data2 = ((Lobby)(ref lobby)).GetData("codex_hamilton_enabled_version");
bool flag = data == "1";
bool num = !hasLobbyEnabledState || lobbyEnabledState != flag || data2 != lastObservedLobbyEnabledVersion;
hasLobbyEnabledState = true;
lobbyEnabledState = flag;
lastObservedLobbyEnabledVersion = data2;
if (num)
{
if (NetworkServer.active)
{
ApplyServerEnabledState(flag);
}
instance?.RefreshHamiltonRulesToggle();
}
}
private static void PublishLocalMemberVersion(Lobby lobby)
{
if (SteamClient.IsValid && !(Time.unscaledTime < nextLocalMemberVersionPublishTime))
{
nextLocalMemberVersionPublishTime = Time.unscaledTime + 2f;
((Lobby)(ref lobby)).SetMemberData("codex_hamilton_member_version", "0.1.17");
}
}
private unsafe static void UpdateLobbyCompatibility(Lobby lobby)
{
//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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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_0088: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
return;
}
if (!string.Equals(((Lobby)(ref lobby)).GetData("codex_hamilton_required_version"), "0.1.17", StringComparison.Ordinal))
{
((Lobby)(ref lobby)).SetData("codex_hamilton_required_version", "0.1.17");
}
List<string> list = new List<string>();
foreach (Friend member in ((Lobby)(ref lobby)).Members)
{
Friend current = member;
string memberData = ((Lobby)(ref lobby)).GetMemberData(current, "codex_hamilton_member_version");
if (!string.Equals(memberData, "0.1.17", StringComparison.Ordinal))
{
string? text;
if (!string.IsNullOrEmpty(((Friend)(ref current)).Name))
{
text = ((Friend)(ref current)).Name;
}
else
{
SteamId id = current.Id;
text = ((object)(*(SteamId*)(&id))/*cast due to .constrained prefix*/).ToString();
}
string text2 = text;
list.Add(string.IsNullOrEmpty(memberData) ? (text2 + " (missing Hamilton 0.1.17)") : (text2 + " (Hamilton " + memberData + ", needs 0.1.17)"));
}
}
allLobbyMembersCompatible = list.Count == 0;
incompatibleLobbyMembers = string.Join(", ", list);
if (allLobbyMembersCompatible)
{
return;
}
if (hasLobbyEnabledState && lobbyEnabledState)
{
PublishSteamLobbyEnabledState(enabled: false);
}
if (Time.unscaledTime >= nextCompatibilityWarningTime)
{
nextCompatibilityWarningTime = Time.unscaledTime + 10f;
HamiltonPlugin hamiltonPlugin = instance;
if (hamiltonPlugin != null)
{
((BaseUnityPlugin)hamiltonPlugin).Logger.LogWarning((object)("Hamilton disabled until every lobby member is running Hamilton 0.1.17: " + incompatibleLobbyMembers));
}
}
}
private static void PublishSteamLobbyEnabledState(bool enabled)
{
if (enabled && !IsHamiltonAllowedForCurrentPreset())
{
enabled = false;
}
if (enabled && NetworkServer.active && !allLobbyMembersCompatible)
{
enabled = false;
HamiltonPlugin hamiltonPlugin = instance;
if (hamiltonPlugin != null)
{
((BaseUnityPlugin)hamiltonPlugin).Logger.LogWarning((object)("Hamilton cannot be enabled yet. Waiting for: " + incompatibleLobbyMembers));
}
}
hasLobbyEnabledState = true;
lobbyEnabledState = enabled;
lastObservedLobbyEnabledVersion = Time.unscaledTime.ToString("R");
Lobby val = default(Lobby);
if (BNetworkManager.TryGetSteamLobby(ref val))
{
((Lobby)(ref val)).SetData("codex_hamilton_enabled", enabled ? "1" : "0");
((Lobby)(ref val)).SetData("codex_hamilton_enabled_version", lastObservedLobbyEnabledVersion);
}
ApplyServerEnabledState(enabled);
instance?.RefreshHamiltonRulesToggle();
}
private static ulong GetPlayerGuid(PlayerInfo player)
{
if (!((Object)(object)((player != null) ? player.PlayerId : null) != (Object)null))
{
return 0uL;
}
return player.PlayerId.Guid;
}
private static void ApplyServerEnabledState(bool enabled)
{
if (!NetworkServer.active)
{
return;
}
PlayerInventory[] array = Object.FindObjectsByType<PlayerInventory>((FindObjectsSortMode)0);
foreach (PlayerInventory val in array)
{
if (!((Object)(object)val == (Object)null))
{
if (enabled)
{
EnsureReservedPistol(val);
}
else
{
RemoveReservedPistol(val);
}
}
}
}
private void TryInstallHamiltonRulesToggle()
{
if ((Object)(object)hamiltonRulesDropdown != (Object)null || Time.unscaledTime < nextRulesUiCheckTime)
{
return;
}
nextRulesUiCheckTime = Time.unscaledTime + 1f;
MatchSetupRules val = FindMatchSetupRules();
if ((Object)(object)val == (Object)null)
{
return;
}
DropdownOption val2 = (((Object)(object)val.hitOtherPlayers != (Object)null) ? val.hitOtherPlayers : val.homingShots);
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).transform == (Object)null) && !((Object)(object)((Component)val2).transform.parent == (Object)null))
{
GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.parent);
((Object)val3).name = "HamiltonRulesDropdown";
val3.transform.SetSiblingIndex(((Component)val2).transform.GetSiblingIndex() + 1);
LocalizeStringEvent[] componentsInChildren = val3.GetComponentsInChildren<LocalizeStringEvent>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
((Behaviour)componentsInChildren[i]).enabled = false;
}
hamiltonRulesDropdown = val3.GetComponent<DropdownOption>();
if ((Object)(object)hamiltonRulesDropdown == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not create Hamilton custom rules dropdown.");
Object.Destroy((Object)(object)val3);
return;
}
hamiltonRulesDropdown.SetOptions(new List<string> { "On", "Off" });
hamiltonRulesDropdown.Initialize((Action)OnHamiltonRulesDropdownChanged, DropdownValueFromEnabled(IsHamiltonEnabled()));
SetHamiltonRulesRowText();
RefreshHamiltonRulesToggle();
RebuildRulesLayout(((Component)val2).transform.parent);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Added Hamilton toggle to custom rules.");
}
}
private static MatchSetupRules FindMatchSetupRules()
{
if (SingletonNetworkBehaviour<MatchSetupRules>.HasInstance)
{
return SingletonNetworkBehaviour<MatchSetupRules>.Instance;
}
if (SingletonBehaviour<MatchSetupRules>.HasInstance)
{
return SingletonBehaviour<MatchSetupRules>.Instance;
}
return Object.FindFirstObjectByType<MatchSetupRules>((FindObjectsInactive)1);
}
private static void RebuildRulesLayout(Transform parent)
{
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if ((Object)(object)val == (Object)null)
{
val = ((Component)parent).GetComponent<RectTransform>();
}
if ((Object)(object)val != (Object)null)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(val);
}
}
private void SetHamiltonRulesRowText()
{
if ((Object)(object)hamiltonRulesDropdown == (Object)null)
{
return;
}
TMP_Text captionText = hamiltonRulesDropdown.captionText;
TMP_Text[] componentsInChildren = ((Component)hamiltonRulesDropdown).GetComponentsInChildren<TMP_Text>(true);
foreach (TMP_Text val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)captionText) && !val.text.Equals("On", StringComparison.OrdinalIgnoreCase) && !val.text.Equals("Off", StringComparison.OrdinalIgnoreCase))
{
val.text = GetHamiltonRulesLabel();
break;
}
}
}
private static string GetHamiltonRulesLabel()
{
if (NetworkServer.active && !allLobbyMembersCompatible)
{
return "Hamilton Needs Update";
}
return "Hamilton";
}
private void RefreshHamiltonRulesToggle()
{
if (!((Object)(object)hamiltonRulesDropdown == (Object)null))
{
suppressHamiltonDropdownChanged = true;
hamiltonRulesDropdown.valueWithoutNotify = DropdownValueFromEnabled(IsHamiltonEnabled());
suppressHamiltonDropdownChanged = false;
hamiltonRulesDropdown.Interactable = NetworkServer.active && allLobbyMembersCompatible && IsHamiltonAllowedForCurrentPreset();
SetHamiltonRulesRowText();
}
}
private void OnHamiltonRulesDropdownChanged()
{
if (!suppressHamiltonDropdownChanged && !((Object)(object)hamiltonRulesDropdown == (Object)null))
{
if (!NetworkServer.active)
{
RefreshHamiltonRulesToggle();
}
else
{
PublishSteamLobbyEnabledState(EnabledFromDropdownValue(hamiltonRulesDropdown.value));
}
}
}
private void TryEnsureLocalPlayerHasPistol()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
return;
}
PlayerInventory localPlayerInventory = GameManager.LocalPlayerInventory;
if ((Object)(object)localPlayerInventory == (Object)null || !((NetworkBehaviour)localPlayerInventory).isLocalPlayer)
{
return;
}
EnsureSlotCount(localPlayerInventory);
int index;
if (TryGetSlot(localPlayerInventory, 0, out var slot) && IsPistol(slot))
{
if (autoSelectPistolConfig.Value && localPlayerInventory.EquippedItemIndex != 0 && localPlayerInventory.CanSelectItemAt(0))
{
localPlayerInventory.TrySelectItemSlot(0);
}
}
else if (TryFindPistolSlot(localPlayerInventory, out index) && index != 0)
{
MovePistolToReservedSlot(localPlayerInventory, index);
}
else
{
giveItemToLocalPlayerMethod?.Invoke(localPlayerInventory, new object[1] { (object)(ItemType)2 });
((BaseUnityPlugin)this).Logger.LogInfo((object)"Granted local player a dueling pistol.");
}
}
private static bool TryFindPistolSlot(PlayerInventory inventory, out int index)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
index = -1;
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots == null)
{
return false;
}
for (int i = 0; i < slots.Count; i++)
{
if (IsPistol(slots[i]))
{
index = i;
return true;
}
}
return false;
}
private static bool TryGetSlot(PlayerInventory inventory, int index, out InventorySlot slot)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: 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_002c: Unknown result type (might be due to invalid IL or missing references)
slot = InventorySlot.Empty;
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots == null || index < 0 || index >= slots.Count)
{
return false;
}
slot = slots[index];
return true;
}
private static bool IsPistol(InventorySlot slot)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if ((int)slot.itemType == 2)
{
return slot.remainingUses > 0;
}
return false;
}
private static bool IsEmpty(InventorySlot slot)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
if ((int)slot.itemType != 0)
{
return slot.remainingUses <= 0;
}
return true;
}
private static bool IsReservedPistolSlot(PlayerInventory inventory, int index)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (IsHamiltonEnabled() && index == 0 && TryGetSlot(inventory, index, out var slot))
{
return IsPistol(slot);
}
return false;
}
private static SyncList<InventorySlot> GetSlots(PlayerInventory inventory)
{
return inventorySlotsField?.GetValue(inventory) as SyncList<InventorySlot>;
}
private static void EnsureSlotCount(PlayerInventory inventory)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots != null)
{
while (slots.Count < 4)
{
slots.Add(InventorySlot.Empty);
}
}
}
private static void MovePistolToReservedSlot(PlayerInventory inventory, int existingPistolIndex)
{
//IL_0020: 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_002a: 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_0044: 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)
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots != null && existingPistolIndex >= 0 && existingPistolIndex < slots.Count)
{
EnsureSlotCount(inventory);
InventorySlot val = slots[0];
slots[0] = new InventorySlot((ItemType)2, 1);
if (existingPistolIndex != 0)
{
slots[existingPistolIndex] = (IsEmpty(val) ? InventorySlot.Empty : val);
}
}
}
private static void EnsureReservedPistol(PlayerInventory inventory)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: 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_0052: 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)
if (!IsHamiltonEnabled())
{
return;
}
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots == null)
{
return;
}
EnsureSlotCount(inventory);
InventorySlot val = slots[0];
if (IsPistol(val))
{
return;
}
if (TryFindPistolSlot(inventory, out var index) && index != 0)
{
MovePistolToReservedSlot(inventory, index);
return;
}
if (!IsEmpty(val))
{
MoveReservedItemToFirstNormalSlot(slots, val);
}
slots[0] = new InventorySlot((ItemType)2, 1);
}
private static void RemoveReservedPistol(PlayerInventory inventory)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots != null && 0 < slots.Count && IsPistol(slots[0]))
{
slots[0] = InventorySlot.Empty;
}
}
private static void RemoveHamiltonPistolsFromAllPlayers()
{
PlayerInventory[] array = Object.FindObjectsByType<PlayerInventory>((FindObjectsSortMode)0);
for (int i = 0; i < array.Length; i++)
{
RemoveAllPistols(array[i]);
}
}
private static void RemoveAllPistols(PlayerInventory inventory)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
SyncList<InventorySlot> slots = GetSlots(inventory);
if (slots == null)
{
return;
}
for (int i = 0; i < slots.Count; i++)
{
if (IsPistol(slots[i]))
{
slots[i] = InventorySlot.Empty;
}
}
}
private static void MoveReservedItemToFirstNormalSlot(SyncList<InventorySlot> slots, InventorySlot reservedSlot)
{
//IL_0006: 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)
for (int i = 1; i < 4; i++)
{
if (IsEmpty(slots[i]))
{
slots[i] = reservedSlot;
break;
}
}
}
private static bool TryGetWeightedRandomNonPistolItem(ItemPool pool, out ItemType item)
{
//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_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Invalid comparison between Unknown and I4
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Invalid comparison between Unknown and I4
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Expected I4, but got Unknown
item = (ItemType)0;
if (!(itemPoolSpawnChancesField?.GetValue(pool) is Array { Length: not 0 } array))
{
return false;
}
float num = 0f;
foreach (object item2 in array)
{
if (TryGetSpawnChanceFields(item2, out var itemField, out var weightField))
{
ItemType val = (ItemType)itemField.GetValue(item2);
float num2 = (float)weightField.GetValue(item2);
if ((int)val != 2 && (int)val != 0 && num2 > 0f)
{
num += num2;
}
}
}
if (num <= 0f)
{
item = (ItemType)1;
return true;
}
float num3 = Random.value * num;
foreach (object item3 in array)
{
if (!TryGetSpawnChanceFields(item3, out var itemField2, out var weightField2))
{
continue;
}
ItemType val2 = (ItemType)itemField2.GetValue(item3);
float num4 = (float)weightField2.GetValue(item3);
if ((int)val2 != 2 && (int)val2 != 0 && !(num4 <= 0f))
{
num3 -= num4;
if (num3 <= 0f)
{
item = (ItemType)(int)val2;
return true;
}
}
}
item = (ItemType)1;
return true;
}
private static bool TryGetSpawnChanceFields(object spawnChance, out FieldInfo itemField, out FieldInfo weightField)
{
itemField = null;
weightField = null;
if (spawnChance == null)
{
return false;
}
Type type = spawnChance.GetType();
if (!spawnChanceItemFields.TryGetValue(type, out itemField))
{
itemField = AccessTools.Field(type, "item");
spawnChanceItemFields[type] = itemField;
}
if (!spawnChanceWeightFields.TryGetValue(type, out weightField))
{
weightField = AccessTools.Field(type, "spawnChanceWeight");
spawnChanceWeightFields[type] = weightField;
}
if (itemField != null)
{
return weightField != null;
}
return false;
}
private static ShotOutcome RollShotOutcome()
{
float num = Mathf.Clamp01(instance?.backfireChanceConfig.Value ?? 0f);
float num2 = Mathf.Clamp01(instance?.jamChanceConfig.Value ?? 0f);
float value = Random.value;
if (value < num)
{
return ShotOutcome.Backfire;
}
if (value < num + num2)
{
return ShotOutcome.Jam;
}
return ShotOutcome.Normal;
}
private static void Backfire(PlayerInventory inventory)
{
//IL_0043: 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_0057: 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_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
PlayerInfo playerInfo = inventory.PlayerInfo;
PlayerMovement val = ((playerInfo != null) ? playerInfo.Movement : null);
Hittable val2 = ((playerInfo != null) ? playerInfo.AsHittable : null);
if (!((Object)(object)playerInfo == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
{
Vector3 val3 = -((Component)playerInfo).transform.forward + Vector3.up * 0.35f;
Vector3 normalized = ((Vector3)(ref val3)).normalized;
Vector3 val4 = ((Component)val2).transform.InverseTransformPoint(inventory.GetDuelingPistolBarrelEndPosition());
Vector3 val5 = normalized * 12f;
ItemUseId val6 = CreateSyntheticItemUseId(playerInfo, (ItemType)2);
bool flag = default(bool);
val.TryKnockOut(playerInfo, (KnockoutType)4, false, val4, 0f, val5, false, val6, true, true, ref flag);
HamiltonPlugin hamiltonPlugin = instance;
if (hamiltonPlugin != null)
{
((BaseUnityPlugin)hamiltonPlugin).Logger.LogInfo((object)"Dueling pistol backfired.");
}
}
}
private static ItemUseId CreateSyntheticItemUseId(PlayerInfo player, ItemType itemType)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
return new ItemUseId(((Object)(object)((player != null) ? player.PlayerId : null) != (Object)null) ? player.PlayerId.Guid : 0, ++syntheticItemUseIndex, itemType);
}
private static void QueueReloadJam(PlayerInventory inventory)
{
if ((Object)(object)inventory != (Object)null)
{
pendingReloadJams.Add(inventory);
}
}
private static void ApplyReloadJam(PlayerInventory inventory)
{
if ((Object)(object)inventory == (Object)null || !pendingReloadJams.Remove(inventory))
{
return;
}
float num = Mathf.Max(0f, instance?.jamReloadDelaySecondsConfig.Value ?? 0f);
if (!(num <= 0f) && !(itemUseTimestampField == null))
{
itemUseTimestampField.SetValue(inventory, Time.timeAsDouble + (double)num);
HamiltonPlugin hamiltonPlugin = instance;
if (hamiltonPlugin != null)
{
((BaseUnityPlugin)hamiltonPlugin).Logger.LogInfo((object)$"Dueling pistol jammed; reload delayed by {num:0.##} seconds.");
}
}
}
}
}