using System;
using System.Collections;
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;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BeltGoBrrrrr")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BeltGoBrrrrr")]
[assembly: AssemblyTitle("BeltGoBrrrrr")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 BeltGoBrrrrr
{
[BepInPlugin("com.acesgaminguk.beltgobrrrrr", "Belt Go Brrrrr", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<string> CustomerUnloadSpeed;
internal static ConfigEntry<int> CustomUnloadSpeed;
private Harmony? _harmony;
private void Awake()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected O, but got Unknown
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("# General #", "Enabled", true, "Enable Belt Go Brrrrr.");
CustomerUnloadSpeed = ((BaseUnityPlugin)this).Config.Bind<string>("# Checkout #", "Customer Unload Speed", "Instant", new ConfigDescription("Controls how quickly customers place items onto the checkout. Presets ignore the custom slider. Custom uses the Unload Speed slider only.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[5] { "Vanilla", "2x", "5x", "Custom", "Instant" }), Array.Empty<object>()));
CustomUnloadSpeed = ((BaseUnityPlugin)this).Config.Bind<int>("# Checkout #", "Unload Speed (Custom Only)", 100, new ConfigDescription("Only active when Customer Unload Speed is set to Custom. Ignored by Vanilla, 2x, 5x, and Instant. 0% = vanilla speed, 100% = instant.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)string.Format("{0} v{1} Initializing...", "Belt Go Brrrrr", ((BaseUnityPlugin)this).Info.Metadata.Version));
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)"Author: AcesGamingUK");
((BaseUnityPlugin)this).Logger.LogMessage((object)"GitHub: https://github.com/AcesGamingUK/Belt-Go-Brrrrr");
((BaseUnityPlugin)this).Logger.LogMessage((object)("Enabled: " + Enabled.Value));
((BaseUnityPlugin)this).Logger.LogMessage((object)("Customer unload speed: " + CustomerUnloadSpeed.Value));
((BaseUnityPlugin)this).Logger.LogMessage((object)("Custom unload speed: " + CustomUnloadSpeed.Value + "%"));
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
((BaseUnityPlugin)this).Logger.LogMessage((object)"Belt Go Brrrrr Initialized successfully!");
((BaseUnityPlugin)this).Logger.LogWarning((object)"=============================================");
_harmony = new Harmony("com.acesgaminguk.beltgobrrrrr");
_harmony.PatchAll();
}
private void OnDestroy()
{
Harmony? harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
[HarmonyPatch]
internal static class NPCInfoPlaceProductsCoroutinePatch
{
private static readonly FieldInfo ProductsIdCarryingField = AccessTools.Field(typeof(NPC_Info), "productsIDCarrying");
private static readonly FieldInfo ProductsCarryingPriceField = AccessTools.Field(typeof(NPC_Info), "productsCarryingPrice");
private static readonly FieldInfo ProductCheckoutPrefabField = AccessTools.Field(typeof(NPC_Info), "productCheckoutPrefab");
private static readonly FieldInfo CurrentCheckoutIndexField = AccessTools.Field(typeof(NPC_Info), "currentCheckoutIndex");
private static readonly FieldInfo ProductsIdInCheckoutField = AccessTools.Field(typeof(NPC_Info), "productsIDInCheckout");
private static readonly FieldInfo ProductItemPlaceWaitField = AccessTools.Field(typeof(NPC_Info), "productItemPlaceWait");
private static MethodBase TargetMethod()
{
MethodInfo methodInfo = AccessTools.Method(typeof(NPC_Info), "PlaceProductsCoroutine", new Type[1] { typeof(GameObject) }, (Type[])null);
if (methodInfo == null)
{
throw new MissingMethodException("NPC_Info.PlaceProductsCoroutine(GameObject) was not found.");
}
return methodInfo;
}
private static bool Prefix(NPC_Info __instance, GameObject checkoutOBJ, ref IEnumerator __result)
{
if (!Plugin.Enabled.Value || Plugin.CustomerUnloadSpeed.Value == "Vanilla")
{
return true;
}
__result = PlaceProductsCoroutine(__instance, checkoutOBJ);
return false;
}
private static IEnumerator PlaceProductsCoroutine(NPC_Info npc, GameObject checkoutOBJ)
{
if ((Object)(object)checkoutOBJ == (Object)null)
{
yield break;
}
List<int> productsIDCarrying = GetField<List<int>>(ProductsIdCarryingField, npc);
List<float> productsCarryingPrice = GetField<List<float>>(ProductsCarryingPriceField, npc);
GameObject productCheckoutPrefab = GetField<GameObject>(ProductCheckoutPrefabField, npc);
List<int> productsIDInCheckout = GetField<List<int>>(ProductsIdInCheckoutField, npc);
if (productsIDCarrying == null || productsCarryingPrice == null || (Object)(object)productCheckoutPrefab == (Object)null || productsIDInCheckout == null)
{
Plugin.Log.LogError((object)"Could not read NPC_Info checkout fields. Game update may have changed NPC_Info.");
yield break;
}
int field = GetField<int>(CurrentCheckoutIndexField, npc);
float field2 = GetField<float>(ProductItemPlaceWaitField, npc);
float delay = GetPlacementDelay(field2);
if (field < 0 || field >= checkoutOBJ.transform.childCount)
{
Plugin.Log.LogWarning((object)("Invalid checkout index while placing products: " + field));
yield break;
}
Transform checkoutTransform = checkoutOBJ.transform.GetChild(field);
GameObject checkoutLane = ((Component)checkoutTransform).gameObject;
Data_Container checkoutData = checkoutLane.GetComponent<Data_Container>();
if ((Object)(object)checkoutData == (Object)null)
{
Plugin.Log.LogWarning((object)"Checkout lane did not have Data_Container.");
yield break;
}
Transform checkoutItemPosition = checkoutTransform.Find("CheckoutItemPosition");
if ((Object)(object)checkoutItemPosition == (Object)null)
{
Plugin.Log.LogWarning((object)"Could not find CheckoutItemPosition on checkout lane.");
yield break;
}
while (productsIDCarrying.Count > 0 && productsCarryingPrice.Count > 0)
{
if (delay > 0f)
{
yield return (object)new WaitForSeconds(delay);
}
int num = productsIDCarrying[0];
float networkproductCarryingPrice = productsCarryingPrice[0];
productsIDCarrying.RemoveAt(0);
productsCarryingPrice.RemoveAt(0);
GameObject val = Object.Instantiate<GameObject>(productCheckoutPrefab);
ProductCheckoutSpawn component = val.GetComponent<ProductCheckoutSpawn>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val);
continue;
}
component.NetworkproductID = num;
component.NetworkcheckoutOBJ = checkoutLane;
component.NetworkNPCOBJ = ((Component)npc).gameObject;
component.NetworkproductCarryingPrice = networkproductCarryingPrice;
component.internalDataContainerListIndex = productsIDInCheckout.Count;
productsIDInCheckout.Add(num);
Vector3 val2 = CalculateCheckoutLocalPosition(productsIDInCheckout);
val.transform.position = checkoutItemPosition.TransformPoint(val2);
val.transform.rotation = checkoutTransform.rotation;
checkoutData.internalProductListForEmployees.Add(val);
NetworkServer.Spawn(val, (NetworkConnection)null);
}
yield return null;
}
private static float GetPlacementDelay(float originalDelay)
{
originalDelay = Mathf.Max(0f, originalDelay);
switch (Plugin.CustomerUnloadSpeed.Value)
{
case "2x":
return originalDelay / 2f;
case "5x":
return originalDelay / 5f;
case "Custom":
{
int num = Mathf.Clamp(Plugin.CustomUnloadSpeed.Value, 0, 100);
if (num >= 100)
{
return 0f;
}
return originalDelay * (1f - (float)num / 100f);
}
case "Instant":
return 0f;
default:
return originalDelay;
}
}
private static Vector3 CalculateCheckoutLocalPosition(List<int> productsIDInCheckout)
{
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
float num2 = 0f;
float num3 = 0f;
foreach (int item in productsIDInCheckout)
{
float num4 = 0.1f;
try
{
ProductData val = ProductListing.Instance.productsData[item];
num4 = (val.hasTrueCollider ? val.trueColliderSize.x : val.colliderSize.x);
}
catch
{
}
if (productsIDInCheckout.Count == 1)
{
num2 = num4 / 2f;
break;
}
num2 += num4 / 2f + num3 / 2f + 0.01f;
if (num2 + num4 / 2f > 0.5f)
{
num++;
num2 = num4 / 2f;
if (num > 6)
{
num = 0;
}
}
num3 = num4;
}
return new Vector3(num2, 0f, (float)num * 0.15f);
}
private static T? GetField<T>(FieldInfo field, object instance)
{
if (field == null)
{
return default(T);
}
object value = field.GetValue(instance);
if (value is T)
{
return (T)value;
}
return default(T);
}
}
internal static class PluginInfo
{
public const string Guid = "com.acesgaminguk.beltgobrrrrr";
public const string Name = "BeltGoBrrrrr";
public const string DisplayName = "Belt Go Brrrrr";
public const string Version = "1.0.0";
public const string Author = "AcesGamingUK";
public const string Website = "https://github.com/AcesGamingUK/Belt-Go-Brrrrr";
}
}