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 BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
[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("BallSaboteur")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BallSaboteur")]
[assembly: AssemblyTitle("BallSaboteur")]
[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 BallSaboteur
{
[BepInPlugin("sbg.ballsaboteur", "BallSaboteur", "0.1.1")]
public sealed class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(ItemCollection), "Initialize")]
private static class Patch_ItemCollection_Initialize
{
private static void Postfix(ItemCollection __instance)
{
EnsureCustomItemRegistered(__instance);
}
}
[HarmonyPatch(typeof(ItemCollection), "OnEnable")]
private static class Patch_ItemCollection_OnEnable
{
private static void Postfix(ItemCollection __instance)
{
EnsureCustomItemRegistered(__instance);
}
}
[HarmonyPatch(typeof(ItemCollection), "get_Count")]
private static class Patch_ItemCollection_Count
{
private static void Postfix(ref int __result)
{
if (customItemData != null)
{
__result++;
}
}
}
[HarmonyPatch(typeof(ItemCollection), "GetItemAtIndex")]
private static class Patch_ItemCollection_GetItemAtIndex
{
private static bool Prefix(ItemCollection __instance, int index, ref ItemData __result)
{
if (customItemData == null || itemCollectionItemsField == null)
{
return true;
}
if (!(itemCollectionItemsField.GetValue(__instance) is ItemData[] array))
{
return true;
}
if (index == array.Length)
{
__result = customItemData;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ItemPool), "GetWeightedRandomItem")]
private static class Patch_ItemPool_GetWeightedRandomItem
{
private static void Postfix(ref ItemType __result)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Invalid comparison between I4 and Unknown
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected I4, but got Unknown
if (!((Object)(object)Instance == (Object)null) && customItemData != null && (int)__result == (int)OrbitalLaserItemType && Random.value <= Instance.orbitalLaserReplacementChanceConfig.Value)
{
__result = (ItemType)(int)CustomItemType;
}
}
}
[HarmonyPatch(typeof(PlayerInventory), "TryUseItem")]
private static class Patch_PlayerInventory_TryUseItem
{
private static bool Prefix(PlayerInventory __instance, bool isAirhornReaction, ref bool shouldEatInput, ref bool __result)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (isAirhornReaction)
{
return true;
}
if (InvokeInventoryGetEffectiveSlot(__instance, __instance.EquippedItemIndex).itemType != CustomItemType)
{
return true;
}
__result = TryUseCustomItem(__instance, ref shouldEatInput);
return false;
}
}
[HarmonyPatch(typeof(PlayerInventory), "OnBUpdate")]
private static class Patch_PlayerInventory_OnBUpdate
{
private static void Postfix(PlayerInventory __instance)
{
UpdateCustomLockOnTargeting(__instance);
}
}
[HarmonyPatch(typeof(PlayerInventory), "UserCode_CmdActivateOrbitalLaser__Hittable__Vector3__ItemUseId")]
private static class Patch_PlayerInventory_CmdActivateOrbitalLaser
{
private static bool Prefix(ItemUseId itemUseId, Hittable target)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return !TryApplyCustomSabotageOnServer(itemUseId, target);
}
}
[HarmonyPatch(typeof(PlayerGolfer), "OnPlayerHitOwnBall")]
private static class Patch_PlayerGolfer_OnPlayerHitOwnBall
{
private static void Postfix(PlayerGolfer __instance)
{
MarkShotStarted(__instance);
}
}
[HarmonyPatch(typeof(NetworkClient), "RegisterMessageHandlers")]
private static class Patch_NetworkClient_RegisterMessageHandlers
{
private static void Postfix()
{
RegisterNetworkHandlers();
}
}
private struct BallSabotageStateMessage : NetworkMessage
{
public uint BallNetId;
public bool IsActive;
}
private sealed class ActiveSabotage
{
public uint BallNetId;
public GolfBall Ball;
public PlayerGolfer Owner;
public Vector3 StrokeStartPosition;
public bool WaitingForBallToStop;
}
private sealed class RuntimeBallMorph : MonoBehaviour
{
private GolfBall ball;
private SphereCollider sphereCollider;
private BoxCollider cubeCollider;
private GameObject cubeVisual;
private Renderer[] originalRenderers;
private void Awake()
{
ball = ((Component)this).GetComponent<GolfBall>();
sphereCollider = (((Object)(object)ball != (Object)null) ? ball.Collider : ((Component)this).GetComponent<SphereCollider>());
originalRenderers = ballRenderersField?.GetValue(ball) as Renderer[];
if (originalRenderers == null || originalRenderers.Length == 0)
{
originalRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
}
}
public void ApplyCube()
{
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)sphereCollider == (Object)null)
{
sphereCollider = ((Component)this).GetComponent<SphereCollider>();
}
if ((Object)(object)cubeCollider == (Object)null)
{
cubeCollider = ((Component)this).GetComponent<BoxCollider>();
if ((Object)(object)cubeCollider == (Object)null)
{
cubeCollider = ((Component)this).gameObject.AddComponent<BoxCollider>();
}
}
float num = (((Object)(object)sphereCollider != (Object)null) ? (sphereCollider.radius * 2f) : 0.45f);
cubeCollider.center = (((Object)(object)sphereCollider != (Object)null) ? sphereCollider.center : Vector3.zero);
cubeCollider.size = Vector3.one * num;
if ((Object)(object)sphereCollider != (Object)null)
{
((Collider)cubeCollider).sharedMaterial = ((Collider)sphereCollider).sharedMaterial;
((Collider)sphereCollider).enabled = false;
}
if ((Object)(object)cubeVisual == (Object)null)
{
cubeVisual = GameObject.CreatePrimitive((PrimitiveType)3);
((Object)cubeVisual).name = "BallSaboteurCubeVisual";
cubeVisual.transform.SetParent(((Component)this).transform, false);
Collider component = cubeVisual.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
}
cubeVisual.transform.localPosition = (((Object)(object)sphereCollider != (Object)null) ? sphereCollider.center : Vector3.zero);
cubeVisual.transform.localRotation = Quaternion.identity;
cubeVisual.transform.localScale = Vector3.one * num;
cubeVisual.SetActive(true);
if (originalRenderers == null)
{
return;
}
Renderer[] array = originalRenderers;
foreach (Renderer val in array)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = false;
}
}
}
public void RestoreSphere()
{
if ((Object)(object)sphereCollider != (Object)null)
{
((Collider)sphereCollider).enabled = true;
}
if ((Object)(object)cubeCollider != (Object)null)
{
((Collider)cubeCollider).enabled = false;
}
if ((Object)(object)cubeVisual != (Object)null)
{
cubeVisual.SetActive(false);
}
if (originalRenderers == null)
{
return;
}
Renderer[] array = originalRenderers;
foreach (Renderer val in array)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = true;
}
}
}
}
public const string ModGuid = "sbg.ballsaboteur";
public const string ModName = "BallSaboteur";
public const string ModVersion = "0.1.1";
internal const int CustomItemTypeRaw = 1001;
internal static readonly ItemType CustomItemType = (ItemType)1001;
private static readonly ItemType OrbitalLaserItemType = (ItemType)10;
internal static Plugin Instance;
internal static ManualLogSource Log;
private static readonly Dictionary<uint, ActiveSabotage> ActiveSabotages = new Dictionary<uint, ActiveSabotage>();
private static readonly Dictionary<uint, RuntimeBallMorph> BallMorphs = new Dictionary<uint, RuntimeBallMorph>();
private static FieldInfo itemCollectionMapField;
private static FieldInfo itemCollectionItemsField;
private static FieldInfo physicalItemTypeField;
private static FieldInfo itemDataTypeField;
private static FieldInfo itemDataPrefabField;
private static FieldInfo itemDataMaxUsesField;
private static FieldInfo itemDataCanUsageAffectBallsField;
private static FieldInfo ballRenderersField;
private static MethodInfo objectMemberwiseCloneMethod;
private static MethodInfo updateOrbitalLaserLockOnTargetMethod;
private static MethodInfo inventoryGetEffectiveSlotMethod;
private static MethodInfo inventoryCanUseEquippedItemMethod;
private static MethodInfo inventoryCancelItemUseMethod;
private static MethodInfo inventoryCancelItemFlourishMethod;
private static MethodInfo inventorySetItemUseTimestampMethod;
private static MethodInfo inventoryIncrementAndGetCurrentItemUseIdMethod;
private static MethodInfo inventoryCmdDecrementUseFromSlotAtMethod;
private static MethodInfo inventoryCmdActivateOrbitalLaserMethod;
private static MethodInfo inventorySetLockOnTargetMethod;
private static MethodInfo inventoryOnActivatedOrbitalLaserMethod;
private static MethodInfo inventoryCmdAddItemMethod;
private static Type onBUpdateDisplayClassType;
private static FieldInfo onBUpdateDisplayThisField;
private static FieldInfo onBUpdateDisplaySlotField;
private static ItemData customItemData;
private static GameObject customPickupPrefab;
private static bool networkSerializersRegistered;
private ConfigEntry<float> restoreDistanceMetersConfig;
private ConfigEntry<float> orbitalLaserReplacementChanceConfig;
private ConfigEntry<bool> debugGrantHotkeyEnabledConfig;
private ConfigEntry<bool> debugSelfSabotageHotkeyEnabledConfig;
private bool debugGrantPressedLastFrame;
private bool debugSelfSabotagePressedLastFrame;
private void Awake()
{
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
restoreDistanceMetersConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "RestoreDistanceMeters", 3f, "Minimum stroke distance before a sabotaged cube ball can restore once it stops.");
orbitalLaserReplacementChanceConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "OrbitalLaserReplacementChance", 0.35f, "Chance to convert a random Orbital Laser spawn into Ball Saboteur.");
debugGrantHotkeyEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableGrantHotkey", true, "When enabled, pressing F8 grants the local player one Ball Saboteur item.");
debugSelfSabotageHotkeyEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableSelfSabotageHotkey", true, "When enabled and hosting locally, pressing F9 sabotages the local player's own ball (bypasses self-target guard for testing).");
CacheReflection();
RegisterNetworkHandlers();
new Harmony("sbg.ballsaboteur").PatchAll();
Log.LogInfo((object)"BallSaboteur v0.1.1 loaded.");
}
private void Update()
{
UpdateDebugHotkey();
UpdateActiveSabotages();
}
private static void CacheReflection()
{
itemCollectionMapField = AccessTools.Field(typeof(ItemCollection), "allItemData");
itemCollectionItemsField = AccessTools.Field(typeof(ItemCollection), "items");
physicalItemTypeField = AccessTools.Field(typeof(PhysicalItem), "itemType");
itemDataTypeField = AccessTools.Field(typeof(ItemData), "<Type>k__BackingField");
itemDataPrefabField = AccessTools.Field(typeof(ItemData), "<Prefab>k__BackingField");
itemDataMaxUsesField = AccessTools.Field(typeof(ItemData), "<MaxUses>k__BackingField");
itemDataCanUsageAffectBallsField = AccessTools.Field(typeof(ItemData), "<CanUsageAffectBalls>k__BackingField");
ballRenderersField = AccessTools.Field(typeof(GolfBall), "renderers");
objectMemberwiseCloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
updateOrbitalLaserLockOnTargetMethod = AccessTools.Method(typeof(PlayerInventory), "<OnBUpdate>g__UpdateOrbitalLaserLockOnTarget|108_3", (Type[])null, (Type[])null);
inventoryGetEffectiveSlotMethod = AccessTools.Method(typeof(PlayerInventory), "GetEffectiveSlot", (Type[])null, (Type[])null);
inventoryCanUseEquippedItemMethod = AccessTools.Method(typeof(PlayerInventory), "CanUseEquippedItem", (Type[])null, (Type[])null);
inventoryCancelItemUseMethod = AccessTools.Method(typeof(PlayerInventory), "CancelItemUse", (Type[])null, (Type[])null);
inventoryCancelItemFlourishMethod = AccessTools.Method(typeof(PlayerInventory), "CancelItemFlourish", (Type[])null, (Type[])null);
inventorySetItemUseTimestampMethod = AccessTools.Method(typeof(PlayerInventory), "set_ItemUseTimestamp", (Type[])null, (Type[])null);
inventoryIncrementAndGetCurrentItemUseIdMethod = AccessTools.Method(typeof(PlayerInventory), "IncrementAndGetCurrentItemUseId", (Type[])null, (Type[])null);
inventoryCmdDecrementUseFromSlotAtMethod = AccessTools.Method(typeof(PlayerInventory), "CmdDecrementUseFromSlotAt", (Type[])null, (Type[])null);
inventoryCmdActivateOrbitalLaserMethod = AccessTools.Method(typeof(PlayerInventory), "CmdActivateOrbitalLaser", (Type[])null, (Type[])null);
inventorySetLockOnTargetMethod = AccessTools.Method(typeof(PlayerInventory), "SetLockOnTarget", (Type[])null, (Type[])null);
inventoryOnActivatedOrbitalLaserMethod = AccessTools.Method(typeof(PlayerInventory), "OnActivatedOrbitalLaser", (Type[])null, (Type[])null);
inventoryCmdAddItemMethod = AccessTools.Method(typeof(PlayerInventory), "CmdAddItem", (Type[])null, (Type[])null);
onBUpdateDisplayClassType = AccessTools.Inner(typeof(PlayerInventory), "<>c__DisplayClass108_0");
onBUpdateDisplayThisField = AccessTools.Field(onBUpdateDisplayClassType, "<>4__this");
onBUpdateDisplaySlotField = AccessTools.Field(onBUpdateDisplayClassType, "effectiveSlot");
}
private static void RegisterNetworkHandlers()
{
if (!networkSerializersRegistered)
{
Writer<BallSabotageStateMessage>.write = WriteBallSabotageState;
Reader<BallSabotageStateMessage>.read = ReadBallSabotageState;
networkSerializersRegistered = true;
}
NetworkClient.ReplaceHandler<BallSabotageStateMessage>((Action<BallSabotageStateMessage>)OnBallSabotageStateMessage, false);
}
private static void WriteBallSabotageState(NetworkWriter writer, BallSabotageStateMessage message)
{
NetworkWriterExtensions.WriteUInt(writer, message.BallNetId);
NetworkWriterExtensions.WriteBool(writer, message.IsActive);
}
private static BallSabotageStateMessage ReadBallSabotageState(NetworkReader reader)
{
BallSabotageStateMessage result = default(BallSabotageStateMessage);
result.BallNetId = NetworkReaderExtensions.ReadUInt(reader);
result.IsActive = NetworkReaderExtensions.ReadBool(reader);
return result;
}
private static void OnBallSabotageStateMessage(BallSabotageStateMessage message)
{
if (TryGetGolfBall(message.BallNetId, out var ball))
{
if (message.IsActive)
{
EnsureCubeApplied(ball);
}
else
{
EnsureSphereApplied(ball);
}
}
}
private void UpdateDebugHotkey()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
Keyboard current = Keyboard.current;
if (debugGrantHotkeyEnabledConfig.Value)
{
bool flag = current != null && ((ButtonControl)current.f8Key).isPressed;
if (flag && !debugGrantPressedLastFrame)
{
PlayerInventory localPlayerInventory = GameManager.LocalPlayerInventory;
if ((Object)(object)localPlayerInventory != (Object)null)
{
InvokeInventoryCmdAddItem(localPlayerInventory, CustomItemType);
Log.LogInfo((object)"Granted Ball Saboteur to local player.");
}
}
debugGrantPressedLastFrame = flag;
}
if (debugSelfSabotageHotkeyEnabledConfig.Value)
{
bool flag2 = current != null && ((ButtonControl)current.f9Key).isPressed;
if (flag2 && !debugSelfSabotagePressedLastFrame)
{
TryDebugSelfSabotage();
}
debugSelfSabotagePressedLastFrame = flag2;
}
}
private static void TryDebugSelfSabotage()
{
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)"Self-sabotage hotkey requires hosting locally (server authority).");
}
return;
}
PlayerInventory localPlayerInventory = GameManager.LocalPlayerInventory;
PlayerInfo val = (((Object)(object)localPlayerInventory != (Object)null) ? localPlayerInventory.PlayerInfo : null);
PlayerGolfer val2 = (((Object)(object)val != (Object)null) ? val.AsGolfer : null);
GolfBall val3 = (((Object)(object)val2 != (Object)null) ? val2.OwnBall : null);
if ((Object)(object)val3 == (Object)null || (Object)(object)((NetworkBehaviour)val3).netIdentity == (Object)null)
{
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogWarning((object)"Self-sabotage: local player has no owned ball yet.");
}
return;
}
uint netId = ((NetworkBehaviour)val3).netId;
ActiveSabotages[netId] = new ActiveSabotage
{
BallNetId = netId,
Ball = val3,
Owner = val2,
StrokeStartPosition = ((Component)val3).transform.position,
WaitingForBallToStop = false
};
EnsureCubeApplied(val3);
BroadcastSabotageState(netId, isActive: true);
ManualLogSource log3 = Log;
if (log3 != null)
{
log3.LogInfo((object)$"Self-sabotage applied to {((Object)val2).name} (ball net id {netId}).");
}
}
private void UpdateActiveSabotages()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || ActiveSabotages.Count == 0)
{
return;
}
List<uint> list = null;
foreach (KeyValuePair<uint, ActiveSabotage> activeSabotage in ActiveSabotages)
{
ActiveSabotage value = activeSabotage.Value;
if ((Object)(object)value.Ball == (Object)null || (Object)(object)value.Owner == (Object)null)
{
if (list == null)
{
list = new List<uint>();
}
list.Add(activeSabotage.Key);
}
else
{
if (!value.WaitingForBallToStop || value.Owner.IsSwinging || !value.Ball.IsStationary)
{
continue;
}
value.WaitingForBallToStop = false;
if (Vector3.Distance(value.StrokeStartPosition, ((Component)value.Ball).transform.position) >= restoreDistanceMetersConfig.Value)
{
if (list == null)
{
list = new List<uint>();
}
list.Add(activeSabotage.Key);
}
}
}
if (list == null)
{
return;
}
foreach (uint item in list)
{
RestoreSabotage(item);
}
}
private void RestoreSabotage(uint ballNetId)
{
if (ActiveSabotages.TryGetValue(ballNetId, out var value))
{
ActiveSabotages.Remove(ballNetId);
if ((Object)(object)value.Ball != (Object)null)
{
EnsureSphereApplied(value.Ball);
}
BroadcastSabotageState(ballNetId, isActive: false);
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)$"Restored sphere on ball net id {ballNetId}.");
}
}
}
internal static void EnsureCustomItemRegistered(ItemCollection collection)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)collection == (Object)null || itemCollectionMapField == null || !(itemCollectionMapField.GetValue(collection) is Dictionary<ItemType, ItemData> dictionary) || (customItemData != null && dictionary.ContainsKey(CustomItemType)))
{
return;
}
if (!dictionary.TryGetValue(OrbitalLaserItemType, out var value) || value == null)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)"Ball Saboteur could not find Orbital Laser data to clone.");
}
return;
}
EnsureCustomPickupPrefab(value);
if (!((Object)(object)customPickupPrefab == (Object)null))
{
customItemData = CloneItemData(value, customPickupPrefab);
dictionary[CustomItemType] = customItemData;
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogInfo((object)"Registered Ball Saboteur runtime item.");
}
}
}
private static void EnsureCustomPickupPrefab(ItemData orbitalLaserData)
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)customPickupPrefab != (Object)null)
{
return;
}
object? obj = itemDataPrefabField?.GetValue(orbitalLaserData);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
customPickupPrefab = Object.Instantiate<GameObject>(val);
((Object)customPickupPrefab).name = "BallSaboteurPickupRuntime";
((Object)customPickupPrefab).hideFlags = (HideFlags)61;
customPickupPrefab.SetActive(false);
Object.DontDestroyOnLoad((Object)(object)customPickupPrefab);
PhysicalItem component = customPickupPrefab.GetComponent<PhysicalItem>();
if ((Object)(object)component != (Object)null && physicalItemTypeField != null)
{
physicalItemTypeField.SetValue(component, CustomItemType);
}
}
}
private static ItemData CloneItemData(ItemData source, GameObject prefab)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
ItemData val = (ItemData)objectMemberwiseCloneMethod.Invoke(source, null);
itemDataTypeField?.SetValue(val, CustomItemType);
itemDataPrefabField?.SetValue(val, prefab);
itemDataMaxUsesField?.SetValue(val, 1);
itemDataCanUsageAffectBallsField?.SetValue(val, true);
return val;
}
internal static bool TryUseCustomItem(PlayerInventory inventory, ref bool shouldEatInput)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: 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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
shouldEatInput = true;
if ((Object)(object)inventory == (Object)null || !((NetworkBehaviour)inventory).isLocalPlayer)
{
return false;
}
InventorySlot equippedSlot = InvokeInventoryGetEffectiveSlot(inventory, inventory.EquippedItemIndex);
if (equippedSlot.itemType != CustomItemType)
{
return false;
}
ItemData equippedItemData = null;
bool shouldEatInput2 = true;
bool isFlourish = false;
if (!InvokeInventoryCanUseEquippedItem(inventory, altUse: false, isAirhornReaction: false, ref equippedSlot, ref equippedItemData, ref shouldEatInput2, ref isFlourish))
{
shouldEatInput = shouldEatInput2;
return false;
}
if (isFlourish)
{
shouldEatInput = false;
return false;
}
LockOnTarget lockOnTarget = inventory.LockOnTarget;
Entity val = (((Object)(object)lockOnTarget != (Object)null) ? lockOnTarget.AsEntity : null);
PlayerInfo val2 = (((Object)(object)val != (Object)null && val.IsPlayer) ? val.PlayerInfo : null);
PlayerInfo playerInfo = inventory.PlayerInfo;
if ((Object)(object)val2 == (Object)null || (Object)(object)playerInfo == (Object)null || (Object)(object)val2 == (Object)(object)playerInfo)
{
shouldEatInput = false;
return false;
}
PlayerGolfer asGolfer = val2.AsGolfer;
GolfBall val3 = (((Object)(object)asGolfer != (Object)null) ? asGolfer.OwnBall : null);
Hittable asHittable = val2.AsHittable;
if ((Object)(object)val3 == (Object)null || (Object)(object)asHittable == (Object)null)
{
shouldEatInput = false;
return false;
}
inventoryCancelItemUseMethod?.Invoke(inventory, null);
inventoryCancelItemFlourishMethod?.Invoke(inventory, null);
inventorySetItemUseTimestampMethod?.Invoke(inventory, new object[1] { Time.timeAsDouble });
playerInfo.CancelEmote(false);
ItemUseId val4 = InvokeInventoryIncrementAndGetCurrentItemUseId(inventory, CustomItemType);
inventoryCmdDecrementUseFromSlotAtMethod?.Invoke(inventory, new object[1] { inventory.EquippedItemIndex });
inventoryCmdActivateOrbitalLaserMethod?.Invoke(inventory, new object[3]
{
asHittable,
((Component)val3).transform.position,
val4
});
inventorySetLockOnTargetMethod?.Invoke(inventory, new object[1]);
try
{
inventoryOnActivatedOrbitalLaserMethod?.Invoke(inventory, null);
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogDebug((object)("Local Orbital Laser activation reuse failed: " + ex.Message));
}
}
shouldEatInput = false;
return true;
}
internal static void UpdateCustomLockOnTargeting(PlayerInventory inventory)
{
//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_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: 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)
if (!((Object)(object)inventory == (Object)null) && !(updateOrbitalLaserLockOnTargetMethod == null) && !(onBUpdateDisplayClassType == null))
{
InventorySlot val = InvokeInventoryGetEffectiveSlot(inventory, inventory.EquippedItemIndex);
if (val.itemType == CustomItemType)
{
object obj = Activator.CreateInstance(onBUpdateDisplayClassType);
onBUpdateDisplayThisField.SetValue(obj, inventory);
onBUpdateDisplaySlotField.SetValue(obj, val);
updateOrbitalLaserLockOnTargetMethod.Invoke(inventory, new object[1] { obj });
}
}
}
internal static bool TryApplyCustomSabotageOnServer(ItemUseId itemUseId, Hittable target)
{
//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_0006: 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_00de: Unknown result type (might be due to invalid IL or missing references)
if (itemUseId.itemType != CustomItemType)
{
return false;
}
if (!NetworkServer.active)
{
return true;
}
PlayerInfo val = (((Object)(object)target != (Object)null) ? ((Component)target).GetComponent<PlayerInfo>() : null);
if ((Object)(object)val == (Object)null && (Object)(object)target != (Object)null)
{
Entity component = ((Component)target).GetComponent<Entity>();
if ((Object)(object)component != (Object)null)
{
val = component.PlayerInfo;
}
}
PlayerGolfer val2 = (((Object)(object)val != (Object)null) ? val.AsGolfer : null);
GolfBall val3 = (((Object)(object)val2 != (Object)null) ? val2.OwnBall : null);
if ((Object)(object)val3 == (Object)null || (Object)(object)((NetworkBehaviour)val3).netIdentity == (Object)null)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)"Ball Saboteur activation had no valid target ball.");
}
return true;
}
uint netId = ((NetworkBehaviour)val3).netId;
ActiveSabotages[netId] = new ActiveSabotage
{
BallNetId = netId,
Ball = val3,
Owner = val2,
StrokeStartPosition = ((Component)val3).transform.position,
WaitingForBallToStop = false
};
EnsureCubeApplied(val3);
BroadcastSabotageState(netId, isActive: true);
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogInfo((object)("Applied Ball Saboteur to " + ((Object)val2).name + "."));
}
return true;
}
internal static void MarkShotStarted(PlayerGolfer golfer)
{
//IL_0038: 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_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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: 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 (!NetworkServer.active || (Object)(object)golfer == (Object)null)
{
return;
}
GolfBall ownBall = golfer.OwnBall;
if (!((Object)(object)ownBall == (Object)null) && ActiveSabotages.TryGetValue(((NetworkBehaviour)ownBall).netId, out var value))
{
value.StrokeStartPosition = ownBall.ServerLastStrokePosition;
if (value.StrokeStartPosition == Vector3.zero)
{
value.StrokeStartPosition = ((Component)ownBall).transform.position;
}
value.WaitingForBallToStop = true;
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)$"Shot started on sabotaged ball {((NetworkBehaviour)ownBall).netId} from {value.StrokeStartPosition}.");
}
}
}
private static void BroadcastSabotageState(uint ballNetId, bool isActive)
{
if (NetworkServer.active)
{
BallSabotageStateMessage ballSabotageStateMessage = default(BallSabotageStateMessage);
ballSabotageStateMessage.BallNetId = ballNetId;
ballSabotageStateMessage.IsActive = isActive;
NetworkServer.SendToAll<BallSabotageStateMessage>(ballSabotageStateMessage, 0, false);
}
}
private static bool TryGetGolfBall(uint ballNetId, out GolfBall ball)
{
ball = null;
if (!NetworkClient.spawned.TryGetValue(ballNetId, out var value) || (Object)(object)value == (Object)null)
{
return false;
}
ball = ((Component)value).GetComponent<GolfBall>();
return (Object)(object)ball != (Object)null;
}
private static InventorySlot InvokeInventoryGetEffectiveSlot(PlayerInventory inventory, int index)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: 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)
if (inventoryGetEffectiveSlotMethod == null)
{
return default(InventorySlot);
}
return (InventorySlot)inventoryGetEffectiveSlotMethod.Invoke(inventory, new object[1] { index });
}
private static bool InvokeInventoryCanUseEquippedItem(PlayerInventory inventory, bool altUse, bool isAirhornReaction, ref InventorySlot equippedSlot, ref ItemData equippedItemData, ref bool shouldEatInput, ref bool isFlourish)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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)
if (inventoryCanUseEquippedItemMethod == null)
{
return false;
}
object[] array = new object[6] { altUse, isAirhornReaction, equippedSlot, equippedItemData, shouldEatInput, isFlourish };
bool result = (bool)inventoryCanUseEquippedItemMethod.Invoke(inventory, array);
equippedSlot = (InventorySlot)array[2];
object obj = array[3];
equippedItemData = (ItemData)((obj is ItemData) ? obj : null);
shouldEatInput = (bool)array[4];
isFlourish = (bool)array[5];
return result;
}
private static ItemUseId InvokeInventoryIncrementAndGetCurrentItemUseId(PlayerInventory inventory, ItemType itemType)
{
//IL_0025: 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)
//IL_000f: 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)
if (inventoryIncrementAndGetCurrentItemUseIdMethod == null)
{
return default(ItemUseId);
}
return (ItemUseId)inventoryIncrementAndGetCurrentItemUseIdMethod.Invoke(inventory, new object[1] { itemType });
}
private static void InvokeInventoryCmdAddItem(PlayerInventory inventory, ItemType itemType)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
inventoryCmdAddItemMethod?.Invoke(inventory, new object[1] { itemType });
}
private static void EnsureCubeApplied(GolfBall ball)
{
if ((Object)(object)ball == (Object)null || (Object)(object)((NetworkBehaviour)ball).netIdentity == (Object)null)
{
return;
}
uint netId = ((NetworkBehaviour)ball).netId;
if (!BallMorphs.TryGetValue(netId, out var value) || (Object)(object)value == (Object)null)
{
value = ((Component)ball).GetComponent<RuntimeBallMorph>();
if ((Object)(object)value == (Object)null)
{
value = ((Component)ball).gameObject.AddComponent<RuntimeBallMorph>();
}
BallMorphs[netId] = value;
}
value.ApplyCube();
}
private static void EnsureSphereApplied(GolfBall ball)
{
if (!((Object)(object)ball == (Object)null) && !((Object)(object)((NetworkBehaviour)ball).netIdentity == (Object)null))
{
uint netId = ((NetworkBehaviour)ball).netId;
if (BallMorphs.TryGetValue(netId, out var value) && (Object)(object)value != (Object)null)
{
value.RestoreSphere();
}
BallMorphs.Remove(netId);
}
}
}
}