forked from Pathoschild/StardewMods
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrackedItem.cs
More file actions
113 lines (93 loc) · 3.87 KB
/
TrackedItem.cs
File metadata and controls
113 lines (93 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
using System;
using Pathoschild.Stardew.Common;
using StardewValley;
namespace Pathoschild.Stardew.Automate
{
/// <summary>An item stack which notifies callbacks when it's reduced.</summary>
public class TrackedItem : ITrackedStack
{
/*********
** Fields
*********/
/// <summary>The item stack.</summary>
private readonly Item Item;
/// <summary>The callback invoked when the stack size is reduced (including reduced to zero).</summary>
protected readonly Action<Item> OnReduced;
/// <summary>The callback invoked when the stack is empty.</summary>
protected readonly Action<Item> OnEmpty;
/// <summary>The last stack size handlers were notified of.</summary>
private int LastCount;
/*********
** Accessors
*********/
/// <summary>A sample item for comparison.</summary>
/// <remarks>This should be equivalent to the underlying item (except in stack size), but *not* a reference to it.</remarks>
public Item Sample { get; }
/// <summary>The underlying item type.</summary>
public ItemType Type { get; }
/// <summary>The number of items in the stack.</summary>
public int Count { get; private set; }
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="item">The item stack.</param>
/// <param name="onReduced">The callback invoked when the stack size is reduced (including reduced to zero).</param>
/// <param name="onEmpty">The callback invoked when the stack is empty.</param>
public TrackedItem(Item item, Action<Item> onReduced = null, Action<Item> onEmpty = null)
{
this.Item = item ?? throw new InvalidOperationException("Can't track a null item stack.");
this.Type = (ItemType)item.GetItemType();
this.Sample = this.GetNewStack(item);
this.OnReduced = onReduced;
this.OnEmpty = onEmpty;
this.Count = item.Stack; // we can't trust Item.Stack to reduce correctly (e.g. Hat.Stack always return 1), so we need to track it ourselves
this.LastCount = this.Count;
}
/// <summary>Remove the specified number of this item from the stack.</summary>
/// <param name="count">The number to consume.</param>
public void Reduce(int count)
{
if (count <= 0)
return;
this.Item.Stack -= count;
this.Count -= count;
this.Delegate();
}
/// <summary>Remove the specified number of this item from the stack and return a new stack matching the count.</summary>
/// <param name="count">The number to get.</param>
public Item Take(int count)
{
if (count <= 0)
return null;
this.Reduce(count);
return this.GetNewStack(this.Item, count);
}
/*********
** Private methods
*********/
/// <summary>Notify handlers.</summary>
private void Delegate()
{
// skip if not reduced
if (this.Count >= this.LastCount)
return;
this.LastCount = this.Count;
// notify handlers
this.OnReduced?.Invoke(this.Item);
if (this.Count <= 0)
this.OnEmpty?.Invoke(this.Item);
}
/// <summary>Create a new stack of the given item.</summary>
/// <param name="original">The item stack to clone.</param>
/// <param name="stackSize">The new stack size.</param>
private Item GetNewStack(Item original, int stackSize = 1)
{
if (original == null)
return null;
Item stack = original.getOne();
stack.Stack = stackSize;
return stack;
}
}
}