-
Notifications
You must be signed in to change notification settings - Fork 4
/
ItemBaseCollectionUtils.cs
286 lines (273 loc) · 11.9 KB
/
ItemBaseCollectionUtils.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
using System;
using System.Collections.Generic;
using System.Linq;
namespace FortressCraft.Community.Utilities
{
/// <summary>
/// Extension Methods and Helpers for the ItemBase Class
/// </summary>
public static partial class ItemBaseUtil
{
/// <summary>
/// Gets the amount of items and cubes in any type of Enumerable ItemBase
/// </summary>
/// <param name="items">The list of items to get the total count from</param>
/// <returns>The amount of Items and Cubes</returns>
public static Int32 GetItemCount(this IEnumerable<ItemBase> items)
{
return items.Sum(itemBase => itemBase.GetAmount());
}
/// <summary>
/// Gets the amount of items in any type of Enumerable ItemBase
/// </summary>
/// <param name="items">The list of items to get the total count from</param>
/// <param name="itemId">The unique id of the item to count</param>
/// <returns>The amount of Items</returns>
public static Int32 GetItemCount(this IEnumerable<ItemBase> items, Int32 itemId)
{
return items.Where(item => item.mnItemID == itemId).Sum(item => item.GetAmount());
}
/// <summary>
/// Gets the amount of cubes in any type of Enumerable ItemBase
/// </summary>
/// <param name="items"></param>
/// <param name="cubeId"></param>
/// <param name="cubeValue"></param>
/// <returns>The amount of Cubes</returns>
public static Int32 GetItemCount(this IEnumerable<ItemBase> items, UInt16 cubeId, UInt16 cubeValue)
{
return items.Where(item =>
{
var cube = item.As<ItemCubeStack>();
if (cube == null)
return false;
return cube.mCubeType == cubeId && cube.mCubeValue == cubeValue;
}).Sum(item => item.GetAmount());
}
/// <summary>
/// Gets the amount of cubes OR items from any Enumerable ItemBase, based off of an ItemBase
/// </summary>
/// <param name="items">The list of items to get the total count from</param>
/// <param name="restraints">The ItemBase which to restrain the Count to</param>
/// <returns>The amount of Cubes or Items</returns>
public static Int32 GetItemCount(this IEnumerable<ItemBase> items, ItemBase restraints)
{
if (restraints.mType != ItemType.ItemCubeStack)
return items.GetItemCount(restraints.mnItemID);
var cube = restraints.As<ItemCubeStack>();
return items.GetItemCount(cube.mCubeType, cube.mCubeValue);
}
/// <summary>
/// Adds an ItemBase to a list, consolidating stacks - obeys list storage capacity by returning excess items
/// </summary>
/// <param name="item">The item to add to the list</param>
/// <param name="targetlist">The list to transfer it to</param>
/// <param name="returnpartialstack">If true returns partial stack when insufficient stack size found</param>
/// <param name="storagecapacity">The list's storage capacity</param>
/// <returns>The remaining items that do not fit in the list</returns>
public static ItemBase AddListItem(this ItemBase item, IEnumerable<ItemBase> targetlist, bool returnpartialstack, int storagecapacity = int.MaxValue)
{
List<ItemBase> workingtarget = targetlist.ToList();
int remainder = 0;
int listcount = workingtarget.GetItemCount();
int itemcount = item.GetAmount();
int newtotal = listcount + itemcount;
ItemBase returnitem = null;
if (newtotal > storagecapacity)
{
remainder = newtotal - storagecapacity;
itemcount -= remainder;
item.SetAmount(itemcount);
returnitem = NewInstance(item);
returnitem.SetAmount(remainder);
}
for (int index = 0; index < workingtarget.Count; index++)
{
if (workingtarget[index].IsStackAndSame(item))
{
workingtarget[index].IncrementStack(itemcount);
break;
}
else
{
workingtarget.Add(item);
break;
}
}
targetlist = workingtarget;
return returnitem;
}
/// <summary>
/// Deduct an item from an item list by example
/// </summary>
/// <param name="item">The example item to attempt to remove from the list</param>
/// <param name="sourcelist">The list to take the item from</param>
/// <param name="returnpartialstack">If true returns partial stack when insufficient stack size found</param>
/// <returns>The ItemBase object or null if unavailable</returns>
public static ItemBase RemoveListItem(this ItemBase item, IEnumerable<ItemBase> sourcelist, bool returnpartialstack)
{
List<ItemBase> workingsource = sourcelist.ToList();
if (item.IsStack())
{
int itemcount = item.GetAmount();
int listitemcount;
for (int index = 0; index < workingsource.Count; index++)
{
ItemBase i = workingsource[index];
listitemcount = i.GetAmount();
if (i.Compare(item) && listitemcount > itemcount)
{
i.DecrementStack(itemcount);
sourcelist = workingsource;
return item;
}
else if (i.Compare(item) && listitemcount == itemcount)
{
workingsource.Remove(i);
sourcelist = workingsource;
return item;
}
else if (returnpartialstack)
{
item.SetAmount(listitemcount);
sourcelist = workingsource;
return item;
}
}
}
else
for (int index = 0; index < workingsource.Count; index++)
{
ItemBase i = workingsource[index];
if (i.Compare(item))
{
workingsource.Remove(i);
sourcelist = workingsource;
return i;
}
}
sourcelist = workingsource;
return null;
}
/// <summary>
/// Moves specified amount of any items from one list to another obeying target storage capacity.
/// </summary>
/// <param name="sourcelist">Source list of items</param>
/// <param name="targetlist">Target list of items</param>
/// <param name="amount">Quantity of items to move</param>
/// <param name="StorageCapacity">Storage capacity of target item list</param>
/// <param name="takefirstitem">Moves only the first item found</param>
/// <param name="whiteblacklist">A list of items to server as a whitelist or blacklist for transferring</param>
/// <param name="iswhitelist">True if whitelist otherwise treat as a blacklist</param>
public static void MoveItems(IEnumerable<ItemBase> sourcelist, IEnumerable<ItemBase> targetlist, int amount = 1, int StorageCapacity = int.MaxValue, bool takefirstitem = false, IEnumerable<ItemBase> whiteblacklist = null, bool iswhitelist = true)
{
int listcount;
int freespace;
List<ItemBase> workingsource = sourcelist.ToList();
List<ItemBase> workingtarget = targetlist.ToList();
List<ItemBase> filter = new List<ItemBase>();
if (whiteblacklist != null)
filter = whiteblacklist.ToList();
int filtercount = filter.Count;
bool matchfound = false;
if (amount <= 0)
{
return;
}
for (int index = 0; index < workingsource.Count; index++)
{
listcount = workingsource[index].GetAmount();
freespace = StorageCapacity - workingtarget.GetItemCount();
ItemBase i = workingsource[index];
if (filtercount != 0)
{
for (int index2 = 0; index2 < filtercount; index2++)
{
ItemBase j = filter[index2];
matchfound = (i.Compare(j));
if (matchfound)
break;
}
//XOR to skip the continue otherwise white/black list violation so go to next item
if (matchfound ^ iswhitelist)
continue;
}
if (i.IsStack())
{
if (listcount > amount)
{
if (amount > freespace)
{
AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
i.DecrementStack(freespace);
sourcelist = workingsource;
targetlist = workingtarget;
return;
}
else
{
AddListItem(NewInstance(i).SetAmount(amount), workingtarget, false);
i.DecrementStack(amount);
sourcelist = workingsource;
targetlist = workingtarget;
return;
}
}
else if (listcount == amount)
{
if (amount > freespace)
{
AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
workingsource.Remove(i);
sourcelist = workingsource;
targetlist = workingtarget;
return;
}
else
{
AddListItem(NewInstance(i).SetAmount(amount), workingtarget, false);
workingsource.Remove(i);
sourcelist = workingsource;
targetlist = workingtarget;
return;
}
}
else
{
if (listcount > freespace)
{
AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
workingsource.Remove(i);
amount -= listcount;
}
else
{
AddListItem(NewInstance(i).SetAmount(listcount), workingtarget, false);
workingsource.Remove(i);
amount -= listcount;
}
}
}
else
{
if (freespace > 0)
{
AddListItem(NewInstance(i), workingtarget, false);
workingsource.Remove(i);
amount--;
}
else
{
sourcelist = workingsource;
targetlist = workingtarget;
return;
}
}
if (takefirstitem)
break;
}
sourcelist = workingsource;
targetlist = workingtarget;
}
}
}