using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Kai")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e6ccd529a2c0b9080eb8a65b3b184a8ecc3dc335")]
[assembly: AssemblyProduct("ValuablesDropItems")]
[assembly: AssemblyTitle("ValuablesDropItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.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]
[Microsoft.CodeAnalysis.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]
[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 ValuableItemDrop
{
public enum ItemConfigType
{
GroupedWeights,
ItemWeights
}
public enum ItemSizeGroup
{
None,
Small,
Medium,
Big
}
public class ItemGroupManager : MonoBehaviour
{
[CompilerGenerated]
private sealed class <BuildConfigDelayed>d__22 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ItemGroupManager <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <BuildConfigDelayed>d__22(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
ItemGroupManager itemGroupManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
if ((Object)(object)StatsManager.instance == (Object)null || StatsManager.instance.itemDictionary == null || StatsManager.instance.itemDictionary.Count == 0)
{
<>2__current = null;
<>1__state = 1;
return true;
}
itemGroupManager.BuildConfig();
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const int MinWeight = 0;
private const int MaxWeight = 10;
private ConfigEntry<ItemConfigType> _configType;
internal static ConfigEntry<float> SpawnHeightOffset;
internal static ConfigEntry<bool> EnableDebugLog;
private readonly Dictionary<string, ConfigEntry<int>> _smallWeights = new Dictionary<string, ConfigEntry<int>>();
private readonly Dictionary<string, ConfigEntry<int>> _mediumWeights = new Dictionary<string, ConfigEntry<int>>();
private readonly Dictionary<string, ConfigEntry<int>> _bigWeights = new Dictionary<string, ConfigEntry<int>>();
private const int MinChance = 0;
private const int MaxChance = 100;
internal static ConfigEntry<int> SmallRollChance;
internal static ConfigEntry<int> MediumRollChance;
internal static ConfigEntry<int> BigRollChance;
private bool _built;
public static ItemGroupManager Instance { get; private set; }
private void Awake()
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Expected O, but got Unknown
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)this);
return;
}
Instance = this;
_configType = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<ItemConfigType>("General", "ConfigType", ItemConfigType.GroupedWeights, "Config layout: GroupedWeights / ItemWeights");
SpawnHeightOffset = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<float>("Drop", "SpawnHeightOffset", 0.5f, "Vertical spawn offset in meters. Increase this if dropped items clip into the ground.");
SmallRollChance = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Drop", "SmallRollChance", 25, new ConfigDescription("Chance (0-100) to roll an item when a Small valuable is destroyed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
MediumRollChance = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Drop", "MediumRollChance", 60, new ConfigDescription("Chance (0-100) to roll an item when a Medium valuable is destroyed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
BigRollChance = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Drop", "BigRollChance", 100, new ConfigDescription("Chance (0-100) to roll an item when a Big valuable is destroyed.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
EnableDebugLog = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<bool>("Debug", "EnableDebugLog", false, "Enable debug logs for valuable drop processing.");
}
private void Start()
{
((MonoBehaviour)this).StartCoroutine(BuildConfigDelayed());
}
public static int GetRollChance(ItemSizeGroup group)
{
return group switch
{
ItemSizeGroup.Small => Mathf.Clamp(SmallRollChance?.Value ?? 100, 0, 100),
ItemSizeGroup.Medium => Mathf.Clamp(MediumRollChance?.Value ?? 100, 0, 100),
ItemSizeGroup.Big => Mathf.Clamp(BigRollChance?.Value ?? 100, 0, 100),
_ => 0,
};
}
public static bool ShouldRoll(ItemSizeGroup group)
{
int rollChance = GetRollChance(group);
if (rollChance <= 0)
{
return false;
}
if (rollChance >= 100)
{
return true;
}
int num = Random.Range(0, 100);
ValuablesDropItems.LogDebug($"[ValuableDrop] RollChance group={group}, chance={rollChance}, roll={num}");
return num < rollChance;
}
[IteratorStateMachine(typeof(<BuildConfigDelayed>d__22))]
private IEnumerator BuildConfigDelayed()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <BuildConfigDelayed>d__22(0)
{
<>4__this = this
};
}
private void BuildConfig()
{
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Expected O, but got Unknown
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Expected O, but got Unknown
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Expected O, but got Unknown
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0208: Expected O, but got Unknown
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: Expected O, but got Unknown
if (_built)
{
return;
}
_built = true;
IOrderedEnumerable<KeyValuePair<string, Item>> orderedEnumerable = from x in StatsManager.instance.itemDictionary
orderby x.Value.itemType, x.Key
select x;
foreach (KeyValuePair<string, Item> item in orderedEnumerable)
{
string key = item.Key;
string displayName = GetDisplayName(key);
switch (_configType.Value)
{
case ItemConfigType.GroupedWeights:
_smallWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Small", displayName, GetDefaultWeight(item.Value, ItemSizeGroup.Small), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
_mediumWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Medium", displayName, GetDefaultWeight(item.Value, ItemSizeGroup.Medium), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
_bigWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>("Big", displayName, GetDefaultWeight(item.Value, ItemSizeGroup.Big), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
break;
case ItemConfigType.ItemWeights:
_smallWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>(displayName, "Small", GetDefaultWeight(item.Value, ItemSizeGroup.Small), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
_mediumWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>(displayName, "Medium", GetDefaultWeight(item.Value, ItemSizeGroup.Medium), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
_bigWeights[key] = ((BaseUnityPlugin)ValuablesDropItems.Instance).Config.Bind<int>(displayName, "Big", GetDefaultWeight(item.Value, ItemSizeGroup.Big), new ConfigDescription("Weight 0-10 (0 = disabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
break;
}
}
ValuablesDropItems.Logger.LogInfo((object)$"Generated weighted item configs: {StatsManager.instance.itemDictionary.Count}");
}
private string GetDisplayName(string key)
{
if (key.StartsWith("ItemUpgrade"))
{
key = key.Substring("ItemUpgrade".Length);
}
else if (key.StartsWith("Item Upgrade"))
{
key = key.Substring("Item Upgrade".Length);
}
else if (key.StartsWith("Item"))
{
key = key.Substring("Item".Length);
}
return key.Replace(" ", "").Trim();
}
public int GetWeight(string itemKey, ItemSizeGroup group)
{
ConfigEntry<int> value = null;
switch (group)
{
case ItemSizeGroup.Small:
_smallWeights.TryGetValue(itemKey, out value);
break;
case ItemSizeGroup.Medium:
_mediumWeights.TryGetValue(itemKey, out value);
break;
case ItemSizeGroup.Big:
_bigWeights.TryGetValue(itemKey, out value);
break;
}
if (value == null)
{
return 0;
}
return Mathf.Clamp(value.Value, 0, 10);
}
public List<(string Key, Item Item, int Weight)> GetWeightedCandidates(ItemSizeGroup group)
{
List<(string, Item, int)> list = new List<(string, Item, int)>();
if ((Object)(object)StatsManager.instance == (Object)null || StatsManager.instance.itemDictionary == null)
{
return list;
}
foreach (KeyValuePair<string, Item> item in StatsManager.instance.itemDictionary)
{
string key = item.Key;
Item value = item.Value;
if (!((Object)(object)value == (Object)null) && !value.disabled && value.prefab != null && !string.IsNullOrEmpty(value.prefab.ResourcePath))
{
int weight = GetWeight(key, group);
if (weight > 0)
{
list.Add((key, value, weight));
}
}
}
return list;
}
public Item? RollItem(ItemSizeGroup group)
{
List<(string, Item, int)> weightedCandidates = GetWeightedCandidates(group);
if (weightedCandidates.Count == 0)
{
return null;
}
int num = 0;
foreach (var item in weightedCandidates)
{
num += item.Item3;
}
if (num <= 0)
{
return null;
}
int num2 = Random.Range(0, num);
foreach (var item2 in weightedCandidates)
{
if (num2 < item2.Item3)
{
return item2.Item2;
}
num2 -= item2.Item3;
}
return weightedCandidates[weightedCandidates.Count - 1].Item2;
}
private int GetDefaultWeight(Item item, ItemSizeGroup group)
{
//IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected I4, but got Unknown
//IL_009f: 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)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Expected I4, but got Unknown
//IL_010e: 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_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Expected I4, but got Unknown
if ((Object)(object)item == (Object)null)
{
return 0;
}
if (IsExcludedByDefault(item))
{
return 0;
}
switch (group)
{
case ItemSizeGroup.Small:
{
itemType itemType3 = item.itemType;
return (int)itemType3 switch
{
7 => 5,
13 => 4,
8 => 3,
6 => 2,
9 => 2,
11 => 1,
10 => 1,
0 => 1,
1 => 1,
_ => 0,
};
}
case ItemSizeGroup.Medium:
{
itemType itemType2 = item.itemType;
return (int)itemType2 switch
{
7 => 3,
13 => 3,
8 => 3,
6 => 4,
9 => 4,
11 => 3,
10 => 2,
0 => 2,
1 => 2,
_ => 0,
};
}
case ItemSizeGroup.Big:
{
itemType itemType = item.itemType;
return (int)itemType switch
{
7 => 1,
13 => 2,
8 => 2,
6 => 3,
9 => 4,
11 => 3,
10 => 3,
0 => 4,
1 => 4,
_ => 0,
};
}
default:
return 0;
}
}
private bool IsExcludedByDefault(Item item)
{
//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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected I4, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
itemType itemType = item.itemType;
switch (itemType - 2)
{
default:
if ((int)itemType != 12)
{
break;
}
return true;
case 1:
return true;
case 0:
return true;
case 3:
return true;
case 2:
break;
}
return false;
}
}
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "DestroyObject")]
internal class ValuableDropPatch
{
private static void Postfix(PhysGrabObjectImpactDetector __instance, bool effects)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
ValuablesDropItems.LogDebug("[ValuableDrop] DestroyObject triggered");
if (!SemiFunc.IsMasterClientOrSingleplayer())
{
ValuablesDropItems.LogDebug("[ValuableDrop] Skip: not host");
return;
}
if (!effects)
{
ValuablesDropItems.LogDebug("[ValuableDrop] Skip: effects=false");
return;
}
ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>();
if ((Object)(object)component == (Object)null)
{
ValuablesDropItems.LogDebug("[ValuableDrop] Skip: ValuableObject null");
return;
}
if ((Object)(object)ItemGroupManager.Instance == (Object)null)
{
ValuablesDropItems.LogDebug("[ValuableDrop] Skip: ItemGroupManager.Instance null");
return;
}
ItemSizeGroup itemSizeGroup = ConvertVolumeType(component.volumeType);
ValuablesDropItems.LogDebug($"[ValuableDrop] Group: {itemSizeGroup}");
if (itemSizeGroup == ItemSizeGroup.None)
{
ValuablesDropItems.LogDebug("[ValuableDrop] Skip: group none");
return;
}
if (!ItemGroupManager.ShouldRoll(itemSizeGroup))
{
ValuablesDropItems.LogDebug($"[ValuableDrop] Skip: chance failed for group {itemSizeGroup}");
return;
}
Item val = ItemGroupManager.Instance.RollItem(itemSizeGroup);
if ((Object)(object)val == (Object)null)
{
ValuablesDropItems.LogDebug("[ValuableDrop] No item rolled");
return;
}
ValuablesDropItems.LogDebug("[ValuableDrop] Selected item: " + ((Object)val).name);
SpawnItem(val, ((Component)component).transform.position);
}
private static ItemSizeGroup ConvertVolumeType(Type volumeType)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected I4, but got Unknown
switch ((int)volumeType)
{
case 0:
case 1:
return ItemSizeGroup.Small;
case 2:
return ItemSizeGroup.Medium;
case 3:
case 4:
case 5:
case 6:
return ItemSizeGroup.Big;
default:
return ItemSizeGroup.None;
}
}
private static void SpawnItem(Item item, Vector3 pos)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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)
//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_002a: 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_0059: 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_0042: 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)
float num = 0.5f;
if (ItemGroupManager.SpawnHeightOffset != null)
{
num = ItemGroupManager.SpawnHeightOffset.Value;
}
Vector3 val = pos + Vector3.up * num;
Quaternion identity = Quaternion.identity;
GameObject val2 = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(item.prefab.Prefab, val, identity) : PhotonNetwork.InstantiateRoomObject(item.prefab.ResourcePath, val, identity, (byte)0, (object[])null));
if ((Object)(object)val2 == (Object)null)
{
ValuablesDropItems.LogDebug("[ValuableDrop] Spawn failed");
return;
}
ItemAttributes component = val2.GetComponent<ItemAttributes>();
if (!((Object)(object)component != (Object)null) || !((Object)(object)PunManager.instance != (Object)null))
{
return;
}
int num2 = -1;
if (SemiFunc.IsMultiplayer())
{
PhotonView component2 = ((Component)component).GetComponent<PhotonView>();
if ((Object)(object)component2 != (Object)null)
{
num2 = component2.ViewID;
}
}
PunManager.instance.SetItemName(((Object)item).name, component, num2);
}
}
[BepInPlugin("Kai.ValuablesDropItems", "ValuablesDropItems", "1.0")]
public class ValuablesDropItems : BaseUnityPlugin
{
internal static ValuablesDropItems Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
((Component)this).gameObject.AddComponent<ItemGroupManager>();
Patch();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
}
internal void Patch()
{
//IL_0019: 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: Expected O, but got Unknown
//IL_0025: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
}
public static void LogDebug(string message)
{
if (ItemGroupManager.EnableDebugLog != null && ItemGroupManager.EnableDebugLog.Value)
{
Logger.LogInfo((object)message);
}
}
}
}