-
-
Notifications
You must be signed in to change notification settings - Fork 392
/
Copy pathTrackedItem.cs
110 lines (89 loc) · 3.08 KB
/
TrackedItem.cs
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
using System;
using System.Diagnostics.CodeAnalysis;
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
*********/
/// <inheritdoc />
public Item Sample { get; }
/// <inheritdoc />
public string Type { get; }
/// <inheritdoc />
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 = item.TypeDefinitionId;
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;
}
/// <inheritdoc />
public void Reduce(int count)
{
if (count <= 0)
return;
this.Item.Stack -= count;
this.Count -= count;
this.Delegate();
}
/// <inheritdoc />
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>
[return: NotNullIfNotNull("original")]
private Item? GetNewStack(Item? original, int stackSize = 1)
{
if (original == null)
return null;
Item stack = original.getOne();
stack.Stack = stackSize;
return stack;
}
}