using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyVersion("0.1.2.0")]
namespace PickupNotificationAdjustment;
internal sealed class ReceiptLedger
{
private sealed class Credit
{
public int Key;
public int Amount;
public bool Actual;
public double Time;
}
private readonly List<Credit> credits = new List<Credit>();
public int Add(int key, int amount, bool actual, double now)
{
credits.RemoveAll((Credit c) => now - c.Time > 2.0);
if (amount <= 0)
{
return 0;
}
int num = amount;
foreach (Credit credit in credits)
{
if (credit.Key == key && credit.Actual != actual && credit.Amount != 0)
{
int num2 = Math.Min(num, credit.Amount);
num -= num2;
credit.Amount -= num2;
if (num == 0)
{
break;
}
}
}
credits.RemoveAll((Credit c) => c.Amount == 0);
if (num > 0)
{
credits.Add(new Credit
{
Key = key,
Amount = num,
Actual = actual,
Time = now
});
}
return num;
}
public void Clear()
{
credits.Clear();
}
}
internal sealed class DisplayQueue<T>
{
internal sealed class Visible
{
public T Value;
public double Remaining;
}
private readonly Queue<T> pending = new Queue<T>();
public readonly List<Visible> Active = new List<Visible>();
public int PendingCount => pending.Count;
public void Add(T value)
{
pending.Enqueue(value);
}
public void AddOrMerge(T value, Func<T, T, bool> sameItem, Action<T, T> merge, double lifetime)
{
foreach (Visible item in Active)
{
if (sameItem(item.Value, value))
{
merge.Invoke(item.Value, value);
item.Remaining = Math.Max(1.0, lifetime);
return;
}
}
foreach (T item2 in pending)
{
if (sameItem(item2, value))
{
merge.Invoke(item2, value);
return;
}
}
pending.Enqueue(value);
}
public void Advance(double delta, int limit, double lifetime)
{
for (int num = Active.Count - 1; num >= 0; num--)
{
Active[num].Remaining -= Math.Max(0.0, delta);
if (Active[num].Remaining <= 0.0)
{
Active.RemoveAt(num);
}
}
while (Active.Count < Math.Max(1, limit) && pending.Count > 0)
{
Active.Add(new Visible
{
Value = pending.Dequeue(),
Remaining = Math.Max(1.0, lifetime)
});
}
}
public void Clear()
{
pending.Clear();
Active.Clear();
}
}
public sealed class FeedView : MonoBehaviour
{
private sealed class Entry
{
public int ItemID;
public string Name;
public Sprite Icon;
public long Amount;
}
private sealed class Row
{
public RectTransform Rect;
public Text Label;
public Image Icon;
public CanvasGroup Group;
}
private readonly DisplayQueue<Entry> queue = new DisplayQueue<Entry>();
private readonly ReceiptLedger ledger = new ReceiptLedger();
private readonly List<Row> rows = new List<Row>();
private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];
private CharacterUI ui;
private Character character;
private RectTransform root;
private RectTransform parent;
private CanvasGroup group;
private Font font;
private QuickSlotPanel[] hotbars;
private float nextLayoutCheck;
private float hotbarTop = 150f;
private bool watchingSilver;
private int previousSilver;
private float silverDeadline;
private Ammunition watchedAmmo;
private int ammoBefore;
private int ammoExpected;
private float ammoDeadline;
internal void WatchAmmo(Ammunition ammo, int incoming)
{
CheckAmmo();
if ((Object)(object)watchedAmmo != (Object)(object)ammo)
{
ammoExpected = 0;
}
watchedAmmo = ammo;
ammoBefore = ((Item)ammo).RemainingAmount;
ammoExpected += Math.Min(incoming, Math.Max(0, ((Item)ammo).MaxStackAmount - ammoBefore));
ammoDeadline = Time.unscaledTime + 10f;
}
private void CheckAmmo()
{
if (Object.op_Implicit((Object)(object)watchedAmmo))
{
int remainingAmount = ((Item)watchedAmmo).RemainingAmount;
int num = Math.Min(ammoExpected, remainingAmount - ammoBefore);
ammoBefore = remainingAmount;
if (num > 0)
{
Receive(((Item)watchedAmmo).ItemID, ((Item)watchedAmmo).Name, ((Item)watchedAmmo).ItemIcon, num, actual: true);
ammoExpected -= num;
}
if (ammoExpected <= 0 || Time.unscaledTime >= ammoDeadline)
{
watchedAmmo = null;
}
}
}
internal void WatchSilver(Character c)
{
CheckSilver();
previousSilver = c.Inventory.ContainedSilver;
watchingSilver = true;
silverDeadline = Time.unscaledTime + 10f;
}
private void CheckSilver()
{
if (watchingSilver && Object.op_Implicit((Object)(object)character))
{
int containedSilver = character.Inventory.ContainedSilver;
int num = containedSilver - previousSilver;
previousSilver = containedSilver;
if (num > 0)
{
Currency silverPrefab = Currency.SilverPrefab;
Receive(((Item)silverPrefab).ItemID, ((Item)silverPrefab).Name, ((Item)silverPrefab).ItemIcon, num, actual: true);
watchingSilver = false;
}
if (Time.unscaledTime >= silverDeadline)
{
watchingSilver = false;
}
}
}
public void Initialize(CharacterUI owner)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Expected O, but got Unknown
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
ui = owner;
character = ui.TargetCharacter;
parent = (RectTransform)AccessTools.Field(typeof(CharacterUI), "m_gameplayPanelsHolder").GetValue(ui);
if (!Object.op_Implicit((Object)(object)parent))
{
ref RectTransform reference = ref parent;
Transform transform = ((Component)ui).transform;
reference = (RectTransform)(object)((transform is RectTransform) ? transform : null);
}
if (!Object.op_Implicit((Object)(object)parent))
{
throw new InvalidOperationException("Player UI has no RectTransform.");
}
Text val = (Object.op_Implicit((Object)(object)ui.SmallNotificationPanel) ? ((Component)ui.SmallNotificationPanel).GetComponentInChildren<Text>(true) : null);
font = (Object.op_Implicit((Object)(object)val) ? val.font : Resources.GetBuiltinResource<Font>("Arial.ttf"));
GameObject val2 = new GameObject("Pickup Notification Adjustment", new Type[2]
{
typeof(RectTransform),
typeof(CanvasGroup)
});
root = val2.GetComponent<RectTransform>();
((Transform)root).SetParent((Transform)(object)parent, false);
RectTransform obj = root;
Vector2 anchorMin = (root.anchorMax = new Vector2(1f, 0f));
obj.anchorMin = anchorMin;
root.pivot = new Vector2(1f, 0f);
group = val2.GetComponent<CanvasGroup>();
group.interactable = false;
group.blocksRaycasts = false;
hotbars = ((Component)ui).GetComponentsInChildren<QuickSlotPanel>(true);
((Transform)root).SetAsLastSibling();
}
internal void Receive(int id, string name, Sprite icon, int amount, bool actual)
{
int num = ledger.Add(id, amount, actual, Time.unscaledTime);
if (num <= 0)
{
return;
}
queue.AddOrMerge(new Entry
{
ItemID = id,
Name = (name ?? "Item"),
Icon = icon,
Amount = num
}, (Entry a, Entry b) => a.ItemID == b.ItemID, delegate(Entry a, Entry b)
{
a.Amount += b.Amount;
if (!Object.op_Implicit((Object)(object)a.Icon) && Object.op_Implicit((Object)(object)b.Icon))
{
a.Icon = b.Icon;
}
}, Plugin.Duration.Value);
}
private void LateUpdate()
{
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)ui) || !Object.op_Implicit((Object)(object)root))
{
return;
}
try
{
if (!Plugin.GameplayReady || (Object)(object)ui.TargetCharacter != (Object)(object)character)
{
queue.Clear();
ledger.Clear();
group.alpha = 0f;
watchingSilver = false;
watchedAmmo = null;
character = ui.TargetCharacter;
return;
}
CheckSilver();
CheckAmmo();
bool flag = ((Component)parent).gameObject.activeInHierarchy;
CanvasGroup[] componentsInParent = ((Component)parent).GetComponentsInParent<CanvasGroup>();
foreach (CanvasGroup val in componentsInParent)
{
if (val.alpha < 0.01f)
{
flag = false;
}
}
group.alpha = (flag ? 1 : 0);
if (!flag)
{
return;
}
queue.Advance(Time.unscaledDeltaTime, Plugin.Rows.Value, Plugin.Duration.Value);
UpdateLayout();
while (rows.Count < queue.Active.Count)
{
rows.Add(CreateRow());
}
float num = Math.Max(40, Plugin.FontSize.Value + 18);
for (int j = 0; j < rows.Count; j++)
{
Row row = rows[j];
bool flag2 = j < queue.Active.Count;
((Component)row.Rect).gameObject.SetActive(flag2);
if (flag2)
{
DisplayQueue<Entry>.Visible visible = queue.Active[j];
RectTransform rect = row.Rect;
Rect rect2 = root.rect;
rect.sizeDelta = new Vector2(((Rect)(ref rect2)).width, num - 3f);
row.Rect.anchoredPosition = new Vector2(0f, (float)(queue.Active.Count - 1 - j) * num);
row.Label.fontSize = Plugin.FontSize.Value;
row.Label.resizeTextMaxSize = Plugin.FontSize.Value;
row.Label.text = "+" + visible.Value.Amount + " " + visible.Value.Name;
row.Icon.sprite = visible.Value.Icon;
((Behaviour)row.Icon).enabled = Object.op_Implicit((Object)(object)visible.Value.Icon);
row.Group.alpha = Mathf.Clamp01((float)visible.Remaining / 0.5f);
}
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
private void UpdateLayout()
{
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//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_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
if (Time.unscaledTime >= nextLayoutCheck)
{
nextLayoutCheck = Time.unscaledTime + 0.5f;
hotbarTop = 150f;
bool flag = false;
if (hotbars != null)
{
QuickSlotPanel[] array = hotbars;
foreach (QuickSlotPanel val in array)
{
if (!Object.op_Implicit((Object)(object)val) || !((Component)val).gameObject.activeInHierarchy)
{
continue;
}
Transform transform = ((Component)val).transform;
RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if (!Object.op_Implicit((Object)(object)val2))
{
continue;
}
val2.GetWorldCorners(corners);
float y = ((Transform)parent).InverseTransformPoint(corners[1]).y;
Rect rect = parent.rect;
float num = y - ((Rect)(ref rect)).yMin;
if (!(num <= 0f))
{
Rect rect2 = parent.rect;
if (!(num > ((Rect)(ref rect2)).height * 0.55f))
{
hotbarTop = (flag ? Math.Max(hotbarTop, num) : num);
flag = true;
}
}
}
}
}
float value = Plugin.Width.Value;
Rect rect3 = parent.rect;
float num2 = Mathf.Min(value, Mathf.Max(160f, ((Rect)(ref rect3)).width - 24f));
Rect rect4 = parent.rect;
float num3 = Mathf.Max(0f, ((Rect)(ref rect4)).width - num2);
Rect rect5 = parent.rect;
float num4 = Mathf.Max(0f, ((Rect)(ref rect5)).height - (float)(Math.Max(40, Plugin.FontSize.Value + 18) * Plugin.Rows.Value));
root.sizeDelta = new Vector2(num2, 0f);
root.anchoredPosition = new Vector2(0f - Mathf.Clamp(Plugin.RightMargin.Value, 0f, num3), Mathf.Clamp(hotbarTop + 4f + Plugin.HeightOffset.Value, 0f, num4));
}
private Row CreateRow()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Expected O, but got Unknown
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Expected O, but got Unknown
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Pickup", new Type[3]
{
typeof(RectTransform),
typeof(CanvasGroup),
typeof(Image)
});
RectTransform component = val.GetComponent<RectTransform>();
((Transform)component).SetParent((Transform)(object)root, false);
Vector2 anchorMin = (component.anchorMax = new Vector2(1f, 0f));
component.anchorMin = anchorMin;
component.pivot = new Vector2(1f, 0f);
Image component2 = val.GetComponent<Image>();
((Graphic)component2).color = new Color(0.035f, 0.045f, 0.055f, 0.8f);
((Graphic)component2).raycastTarget = false;
GameObject val3 = new GameObject("Item icon", new Type[2]
{
typeof(RectTransform),
typeof(Image)
});
RectTransform component3 = val3.GetComponent<RectTransform>();
((Transform)component3).SetParent((Transform)(object)component, false);
Vector2 anchorMin2 = (component3.anchorMax = new Vector2(0f, 0.5f));
component3.anchorMin = anchorMin2;
component3.pivot = new Vector2(0f, 0.5f);
component3.anchoredPosition = new Vector2(5f, 0f);
component3.sizeDelta = new Vector2(32f, 32f);
Image component4 = val3.GetComponent<Image>();
((Graphic)component4).raycastTarget = false;
component4.preserveAspect = true;
GameObject val5 = new GameObject("Item name", new Type[2]
{
typeof(RectTransform),
typeof(Text)
});
RectTransform component5 = val5.GetComponent<RectTransform>();
((Transform)component5).SetParent((Transform)(object)component, false);
component5.anchorMin = Vector2.zero;
component5.anchorMax = Vector2.one;
component5.offsetMin = new Vector2(44f, 3f);
component5.offsetMax = new Vector2(-9f, -3f);
Text component6 = val5.GetComponent<Text>();
component6.font = font;
((Graphic)component6).color = new Color(0.95f, 0.93f, 0.86f);
component6.alignment = (TextAnchor)3;
component6.supportRichText = false;
((Graphic)component6).raycastTarget = false;
component6.resizeTextForBestFit = true;
component6.resizeTextMinSize = 12;
component6.resizeTextMaxSize = Plugin.FontSize.Value;
component6.horizontalOverflow = (HorizontalWrapMode)0;
component6.verticalOverflow = (VerticalWrapMode)0;
Row row = new Row();
row.Rect = component;
row.Label = component6;
row.Icon = component4;
row.Group = val.GetComponent<CanvasGroup>();
return row;
}
private void OnDestroy()
{
if (Object.op_Implicit((Object)(object)root))
{
Object.Destroy((Object)(object)((Component)root).gameObject);
}
}
}
[BepInPlugin("Outwardz.PickupNotificationAdjustment", "Pickup Notification Adjustment", "0.1.2")]
public sealed class Plugin : BaseUnityPlugin
{
public const string Id = "Outwardz.PickupNotificationAdjustment";
internal static Plugin Instance;
internal static ConfigEntry<bool> Enabled;
internal static ConfigEntry<int> Rows;
internal static ConfigEntry<int> FontSize;
internal static ConfigEntry<float> Duration;
internal static ConfigEntry<float> RightMargin;
internal static ConfigEntry<float> HeightOffset;
internal static ConfigEntry<float> Width;
private readonly Dictionary<CharacterUI, FeedView> feeds = new Dictionary<CharacterUI, FeedView>();
private Harmony harmony;
private bool loggedError;
internal static readonly FieldInfo InventoryOwner = AccessTools.Field(typeof(CharacterInventory), "m_character");
internal static bool GameplayReady
{
get
{
if (Object.op_Implicit((Object)(object)Instance) && Enabled.Value && Object.op_Implicit((Object)(object)NetworkLevelLoader.Instance) && NetworkLevelLoader.Instance.IsOverallLoadingDone)
{
return !NetworkLevelLoader.Instance.IsGameplayLoading;
}
return false;
}
}
private void Awake()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Expected O, but got Unknown
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Expected O, but got Unknown
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Expected O, but got Unknown
Instance = this;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show item pickups above the hotbar.");
Duration = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "Display seconds", 5f, new ConfigDescription("How long each pickup stays visible.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), new object[0]));
Rows = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "Visible items", 6, new ConfigDescription("Extra pickups wait their turn; they are not dropped.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0]));
FontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "Text size", 18, new ConfigDescription("Item-name text size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(12, 30), new object[0]));
Width = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Panel width", 350f, new ConfigDescription("Width in UI units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(220f, 650f), new object[0]));
RightMargin = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Right margin", 24f, new ConfigDescription("Distance from the right edge of your player screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[0]));
HeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Vertical offset", -66.197f, new ConfigDescription("Adjust the position above the hotbar. Negative moves down; positive moves up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-100f, 500f), new object[0]));
try
{
harmony = new Harmony("Outwardz.PickupNotificationAdjustment");
harmony.PatchAll(typeof(Plugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Pickup feed 0.1.2 ready. Grouped quantities; bottom-right layout; local-player receipts only.");
}
catch (Exception ex)
{
if (harmony != null)
{
harmony.UnpatchSelf();
}
Enabled.Value = false;
((BaseUnityPlugin)this).Logger.LogError((object)("Pickup feed could not start; original notifications remain enabled. " + ex));
}
}
internal static bool Local(Character c)
{
if (Object.op_Implicit((Object)(object)c) && c.IsLocalPlayer)
{
return Object.op_Implicit((Object)(object)c.CharacterUI);
}
return false;
}
internal static Character Owner(CharacterInventory inv)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
return (Character)InventoryOwner.GetValue(inv);
}
internal static bool Carried(Character c, ItemContainer box)
{
if (Local(c) && Object.op_Implicit((Object)(object)box))
{
if (!((Object)(object)box == (Object)(object)c.Inventory.Pouch))
{
if (c.Inventory.HasABag)
{
return (Object)(object)box == (Object)(object)c.Inventory.EquippedBag.Container;
}
return false;
}
return true;
}
return false;
}
internal static int Quantity(Item item)
{
if (!item.IsStackable)
{
return 1;
}
return Math.Max(1, item.RemainingAmount);
}
internal static void Report(Exception e)
{
if (Object.op_Implicit((Object)(object)Instance) && !Instance.loggedError)
{
Instance.loggedError = true;
((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Pickup display problem (gameplay unchanged): " + e));
}
}
internal static bool Receipt(Character c, Item item, int amount, bool actual)
{
if (!GameplayReady || !Local(c) || !Object.op_Implicit((Object)(object)item) || item is Skill || item is ItemContainer || amount <= 0)
{
return false;
}
try
{
FeedView feed = Instance.GetFeed(c);
feed.Receive(item.ItemID, item.Name, item.ItemIcon, amount, actual);
return true;
}
catch (Exception e)
{
Report(e);
return false;
}
}
internal FeedView GetFeed(Character c)
{
if (!feeds.TryGetValue(c.CharacterUI, out var value) || !Object.op_Implicit((Object)(object)value))
{
value = ((Component)c.CharacterUI).gameObject.AddComponent<FeedView>();
try
{
value.Initialize(c.CharacterUI);
}
catch
{
Object.Destroy((Object)(object)value);
throw;
}
feeds[c.CharacterUI] = value;
}
return value;
}
internal static void WatchCurrency(Character c)
{
if (!GameplayReady || !Local(c))
{
return;
}
try
{
Instance.GetFeed(c).WatchSilver(c);
}
catch (Exception e)
{
Report(e);
}
}
private void LateUpdate()
{
List<CharacterUI> list = new List<CharacterUI>();
foreach (KeyValuePair<CharacterUI, FeedView> feed in feeds)
{
if (!Object.op_Implicit((Object)(object)feed.Key) || !Object.op_Implicit((Object)(object)feed.Value))
{
list.Add(feed.Key);
}
}
foreach (CharacterUI item in list)
{
feeds.Remove(item);
}
}
private void OnDestroy()
{
if (harmony != null)
{
harmony.UnpatchSelf();
}
foreach (FeedView value in feeds.Values)
{
if (Object.op_Implicit((Object)(object)value))
{
Object.Destroy((Object)(object)value);
}
}
feeds.Clear();
Instance = null;
}
}
[HarmonyPatch(typeof(Item), "ChangeOwner", new Type[] { typeof(Character) })]
internal static class OwnershipHook
{
internal sealed class Capture
{
public Character Owner;
public int Amount;
}
private static void Prefix(Item __instance, Character __0, out Capture __state)
{
__state = null;
try
{
if (Plugin.GameplayReady && Plugin.Local(__0) && Object.op_Implicit((Object)(object)__instance) && !((Object)(object)((EffectSynchronizer)__instance).OwnerCharacter == (Object)(object)__0) && !(__instance is Skill) && !(__instance is ItemContainer))
{
__state = new Capture
{
Owner = __0,
Amount = Plugin.Quantity(__instance)
};
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
private static void Postfix(Item __instance, Capture __state)
{
try
{
if (__state != null && Object.op_Implicit((Object)(object)__instance) && (Object)(object)((EffectSynchronizer)__instance).OwnerCharacter == (Object)(object)__state.Owner)
{
Plugin.Receipt(__state.Owner, __instance, __state.Amount, actual: true);
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
}
[HarmonyPatch(typeof(CharacterInventory), "NotifyItemTake", new Type[]
{
typeof(Item),
typeof(int)
})]
internal static class NotificationHook
{
private static bool Prefix(CharacterInventory __instance, Item __0, int __1)
{
try
{
return !Plugin.Receipt(Plugin.Owner(__instance), __0, __1, actual: false);
}
catch (Exception e)
{
Plugin.Report(e);
return true;
}
}
}
[HarmonyPatch(typeof(CharacterInventory), "TakeItem", new Type[]
{
typeof(Item),
typeof(bool)
})]
internal static class AmmoHook
{
private static void Prefix(CharacterInventory __instance, Item __0, bool __1)
{
try
{
Character val = Plugin.Owner(__instance);
if (__0 is Currency)
{
Plugin.WatchCurrency(val);
}
Ammunition equippedAmmunition = __instance.GetEquippedAmmunition();
if (Plugin.GameplayReady && Plugin.Local(val) && __1 && Object.op_Implicit((Object)(object)__0) && Object.op_Implicit((Object)(object)equippedAmmunition) && !((Object)(object)__0 == (Object)(object)equippedAmmunition) && __0.ItemID == ((Item)equippedAmmunition).ItemID && !((Object)(object)((EffectSynchronizer)__0).OwnerCharacter == (Object)(object)val))
{
Plugin.Instance.GetFeed(val).WatchAmmo(equippedAmmunition, Plugin.Quantity(__0));
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
}
[HarmonyPatch(typeof(CharacterInventory), "AddMoney", new Type[]
{
typeof(int),
typeof(int),
typeof(bool)
})]
internal static class SilverHook
{
private static void Prefix(CharacterInventory __instance, int __1)
{
try
{
if (__1 > 0)
{
Plugin.WatchCurrency(Plugin.Owner(__instance));
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
}
[HarmonyPatch(typeof(CharacterInventory), "TakeAllContent", new Type[]
{
typeof(ItemContainer),
typeof(bool)
})]
internal static class TakeAllSilverHook
{
private static void Prefix(CharacterInventory __instance, ItemContainer __0)
{
try
{
if (Object.op_Implicit((Object)(object)__0) && __0.ContainedSilver > 0)
{
Plugin.WatchCurrency(Plugin.Owner(__instance));
}
}
catch (Exception e)
{
Plugin.Report(e);
}
}
}