Skip to content

Commit f3f14f9

Browse files
committed
Allow bulk cell filters to be switched to other variants in the same chain + other tweaks
1 parent 754fbab commit f3f14f9

File tree

2 files changed

+124
-28
lines changed

2 files changed

+124
-28
lines changed

src/main/java/gripe/_90/megacells/item/cell/BulkCellInventory.java

+53-24
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ public class BulkCellInventory implements StorageCell {
3131
private final AEItemKey filterItem;
3232

3333
private final boolean compressionEnabled;
34-
private final CompressionChain compressionChain;
34+
private CompressionChain compressionChain;
3535
private BigInteger unitCount;
36-
private final BigInteger unitFactor;
37-
private final int compressionCutoff;
36+
private BigInteger unitFactor;
37+
private int compressionCutoff;
3838

39-
private final Map<Item, Long> availableStacks;
39+
private Map<Item, Long> availableStacks;
4040
private List<IPatternDetails> decompressionPatterns;
4141

4242
private boolean isPersisted = true;
@@ -47,17 +47,16 @@ public class BulkCellInventory implements StorageCell {
4747

4848
var cell = (BulkCellItem) stack.getItem();
4949
filterItem = (AEItemKey) cell.getConfigInventory(stack).getKey(0);
50+
compressionEnabled = cell.getUpgrades(stack).isInstalled(MEGAItems.COMPRESSION_CARD);
5051

5152
storedItem = (AEItemKey) stack.get(MEGAComponents.BULK_CELL_ITEM);
5253
unitCount = stack.getOrDefault(MEGAComponents.BULK_CELL_UNIT_COUNT, BigInteger.ZERO);
5354

5455
var determiningKey = storedItem != null ? storedItem : filterItem;
5556
var determiningItem = determiningKey != null ? determiningKey.getItem() : null;
5657
compressionChain = CompressionService.getChain(determiningItem);
57-
unitFactor = compressionChain.unitFactor(determiningItem);
5858

59-
// Check newly-calculated factor against what's already recorded in order to adjust for a compression chain that
60-
// has changed from the left of the item filtered to or stored
59+
unitFactor = compressionChain.unitFactor(determiningItem);
6160
var recordedFactor = stack.getOrDefault(MEGAComponents.BULK_CELL_UNIT_FACTOR, unitFactor);
6261

6362
if (!unitFactor.equals(recordedFactor)) {
@@ -70,12 +69,7 @@ public class BulkCellInventory implements StorageCell {
7069
int recordedCutoff = stack.getOrDefault(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF, maxCutoff);
7170
compressionCutoff = recordedCutoff < 0 ? maxCutoff : Math.min(recordedCutoff, maxCutoff);
7271

73-
if (hasCompressionChain()) {
74-
stack.set(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF, compressionCutoff);
75-
}
76-
7772
availableStacks = compressionChain.initStacks(unitCount, compressionCutoff, determiningItem);
78-
compressionEnabled = cell.getUpgrades(stack).isInstalled(MEGAItems.COMPRESSION_CARD);
7973
}
8074

8175
@Override
@@ -91,11 +85,11 @@ public CellState getStatus() {
9185
return CellState.NOT_EMPTY;
9286
}
9387

94-
public AEItemKey getStoredItem() {
88+
AEItemKey getStoredItem() {
9589
return storedItem;
9690
}
9791

98-
public long getStoredQuantity() {
92+
long getStoredQuantity() {
9993
return CompressionChain.clamp(unitCount.divide(unitFactor), Long.MAX_VALUE);
10094
}
10195

@@ -104,7 +98,26 @@ AEItemKey getFilterItem() {
10498
}
10599

106100
private boolean isFilterMismatched() {
107-
return storedItem != null && !storedItem.equals(filterItem);
101+
if (storedItem == null) {
102+
return false;
103+
}
104+
105+
if (storedItem.equals(filterItem)) {
106+
return false;
107+
}
108+
109+
if (filterItem == null) {
110+
return true;
111+
}
112+
113+
if (compressionChain.containsVariant(filterItem.getItem())) {
114+
storedItem = filterItem;
115+
unitFactor = compressionChain.unitFactor(storedItem.getItem());
116+
saveChanges();
117+
return false;
118+
}
119+
120+
return true;
108121
}
109122

110123
public boolean isCompressionEnabled() {
@@ -138,7 +151,7 @@ public long insert(AEKey what, long amount, Actionable mode, IActionSource sourc
138151
return 0;
139152
}
140153

141-
if (filterItem == null || isFilterMismatched()) {
154+
if (isFilterMismatched()) {
142155
return 0;
143156
}
144157

@@ -154,7 +167,7 @@ public long insert(AEKey what, long amount, Actionable mode, IActionSource sourc
154167
storedItem = filterItem;
155168
}
156169

157-
saveChanges(units);
170+
updateContents(units);
158171
}
159172

160173
return amount;
@@ -187,30 +200,39 @@ public long extract(AEKey what, long amount, Actionable mode, IActionSource sour
187200
if (currentUnitCount.compareTo(units) <= 0) {
188201
if (mode == Actionable.MODULATE) {
189202
storedItem = null;
190-
saveChanges(unitCount.negate());
203+
unitCount = BigInteger.ZERO;
204+
205+
var filter = filterItem != null ? filterItem.getItem() : null;
206+
compressionChain = CompressionService.getChain(filter);
207+
availableStacks = compressionChain.initStacks(unitCount, compressionCutoff, filter);
208+
209+
saveChanges();
191210
}
192211

193212
return CompressionChain.clamp(currentUnitCount.divide(factor), Long.MAX_VALUE);
194213
} else {
195214
if (mode == Actionable.MODULATE) {
196-
saveChanges(units.negate());
215+
updateContents(units.negate());
197216
}
198217

199218
return CompressionChain.clamp(units.divide(factor), Long.MAX_VALUE);
200219
}
201220
}
202221

203-
private void saveChanges(BigInteger unitsToAdd) {
222+
private void updateContents(BigInteger unitsToAdd) {
204223
unitCount = unitCount.add(unitsToAdd);
224+
saveChanges();
225+
compressionChain.updateStacks(availableStacks, unitsToAdd, compressionCutoff);
226+
}
227+
228+
private void saveChanges() {
205229
isPersisted = false;
206230

207231
if (container != null) {
208232
container.saveChanges();
209233
} else {
210234
persist();
211235
}
212-
213-
compressionChain.updateStacks(availableStacks, unitsToAdd, compressionCutoff);
214236
}
215237

216238
@Override
@@ -229,6 +251,12 @@ public void persist() {
229251
stack.set(MEGAComponents.BULK_CELL_UNIT_FACTOR, unitFactor);
230252
}
231253

254+
if (hasCompressionChain()) {
255+
stack.set(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF, compressionCutoff);
256+
} else {
257+
stack.remove(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF);
258+
}
259+
232260
isPersisted = true;
233261
}
234262

@@ -240,7 +268,8 @@ public void switchCompressionCutoff(boolean backwards) {
240268
var newCutoff = compressionCutoff;
241269
newCutoff += compressionChain.size() + (backwards ? 1 : -1);
242270
newCutoff %= compressionChain.size();
243-
stack.set(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF, newCutoff);
271+
compressionCutoff = newCutoff;
272+
stack.set(MEGAComponents.BULK_CELL_COMPRESSION_CUTOFF, compressionCutoff);
244273
}
245274

246275
public Item getCutoffItem() {
@@ -253,7 +282,7 @@ Item getHighestVariant() {
253282

254283
@Override
255284
public void getAvailableStacks(KeyCounter out) {
256-
if (!compressionEnabled && storedItem != null && !isFilterMismatched()) {
285+
if (!compressionEnabled && !isFilterMismatched() && storedItem != null) {
257286
out.add(storedItem, availableStacks.get(storedItem.getItem()));
258287
} else {
259288
availableStacks.forEach((item, amount) -> out.add(AEItemKey.of(item), amount));

src/test/java/gripe/_90/megacells/test/BulkCellInventoryTest.java

+71-4
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,14 @@ void testFilterMismatchWithCompression(MinecraftServer ignored) {
228228

229229
// ensure variant contents are recoverable even without a card
230230
assertThat(cell.extract(nugget, MAX, Actionable.MODULATE, SRC)).isOne();
231-
assertThat(cell.extract(ingot, MAX, Actionable.MODULATE, SRC)).isOne();
232-
assertThat(cell.extract(block, MAX, Actionable.MODULATE, SRC)).isOne();
233-
assertThat(cell.getStatus()).isEqualTo(CellState.EMPTY);
234231

235-
// ensure compression works with new filter item after emptying
236232
item.getUpgrades(stack).addItems(card);
237233
cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
234+
cell.extract(ingot, MAX, Actionable.MODULATE, SRC);
235+
cell.extract(block, MAX, Actionable.MODULATE, SRC);
236+
assertThat(cell.getStatus()).isEqualTo(CellState.EMPTY);
237+
238+
// ensure compression works with new filter item after emptying (without needing to recreate the cell inv
238239
nugget = AEItemKey.of(Items.GOLD_NUGGET);
239240
block = AEItemKey.of(Items.GOLD_BLOCK);
240241
assertThat(cell.insert(nugget, 1, Actionable.SIMULATE, SRC)).isOne();
@@ -272,4 +273,70 @@ void testCompressionCutoff(MinecraftServer ignored) {
272273
assertThat(cell.getAvailableStacks().get(block)).isOne();
273274
assertThat(cell.getAvailableStacks().get(ingot)).isOne();
274275
}
276+
277+
@Test
278+
void testFilterChangeWithinCompressionChain(MinecraftServer ignored) {
279+
var nugget = AEItemKey.of(Items.IRON_NUGGET);
280+
var ingot = AEItemKey.of(Items.IRON_INGOT);
281+
282+
var item = MEGAItems.BULK_ITEM_CELL.asItem();
283+
var stack = item.getDefaultInstance();
284+
item.getUpgrades(stack).addItems(MEGAItems.COMPRESSION_CARD.stack());
285+
item.getConfigInventory(stack).addFilter(ingot);
286+
287+
var cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
288+
var ingots = cell.insert(ingot, 2, Actionable.MODULATE, SRC);
289+
var nuggets = cell.insert(nugget, 3, Actionable.MODULATE, SRC);
290+
var units = cell.extract(nugget, MAX, Actionable.SIMULATE, SRC);
291+
292+
// first pass: switch filter to a smaller variant
293+
item.getConfigInventory(stack).clear();
294+
item.getConfigInventory(stack).addFilter(nugget);
295+
cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
296+
assertThat(cell.getStatus()).isNotEqualTo(CellState.FULL);
297+
assertThat(cell.insert(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
298+
assertThat(cell.insert(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
299+
assertThat(cell.getAvailableStacks().get(ingot)).isEqualTo(ingots * 2);
300+
assertThat(cell.getAvailableStacks().get(nugget)).isEqualTo(nuggets * 2);
301+
assertThat(cell.extract(nugget, MAX, Actionable.SIMULATE, SRC)).isEqualTo(units * 2);
302+
assertThat(cell.extract(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
303+
assertThat(cell.extract(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
304+
305+
// second pass: switch filter back to initial variant
306+
item.getConfigInventory(stack).clear();
307+
item.getConfigInventory(stack).addFilter(ingot);
308+
cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
309+
assertThat(cell.getStatus()).isNotEqualTo(CellState.FULL);
310+
assertThat(cell.insert(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
311+
assertThat(cell.insert(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
312+
assertThat(cell.getAvailableStacks().get(ingot)).isEqualTo(ingots * 2);
313+
assertThat(cell.getAvailableStacks().get(nugget)).isEqualTo(nuggets * 2);
314+
assertThat(cell.extract(nugget, MAX, Actionable.SIMULATE, SRC)).isEqualTo(units * 2);
315+
assertThat(cell.extract(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
316+
assertThat(cell.extract(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
317+
318+
// second pass: switch filter to even larger variant
319+
item.getConfigInventory(stack).clear();
320+
item.getConfigInventory(stack).addFilter(Items.IRON_BLOCK);
321+
cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
322+
assertThat(cell.getStatus()).isNotEqualTo(CellState.FULL);
323+
assertThat(cell.insert(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
324+
assertThat(cell.insert(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
325+
assertThat(cell.getAvailableStacks().get(ingot)).isEqualTo(ingots * 2);
326+
assertThat(cell.getAvailableStacks().get(nugget)).isEqualTo(nuggets * 2);
327+
assertThat(cell.extract(nugget, MAX, Actionable.SIMULATE, SRC)).isEqualTo(units * 2);
328+
assertThat(cell.extract(ingot, ingots, Actionable.MODULATE, SRC)).isEqualTo(ingots);
329+
assertThat(cell.extract(nugget, nuggets, Actionable.MODULATE, SRC)).isEqualTo(nuggets);
330+
331+
// fourth pass: switch filter to a non-variant altogether
332+
item.getConfigInventory(stack).clear();
333+
item.getConfigInventory(stack).addFilter(Items.GOLD_INGOT);
334+
cell = Objects.requireNonNull(StorageCells.getCellInventory(stack, null));
335+
assertThat(cell.getStatus()).isEqualTo(CellState.FULL);
336+
assertThat(cell.insert(ingot, ingots, Actionable.MODULATE, SRC)).isZero();
337+
assertThat(cell.insert(nugget, nuggets, Actionable.MODULATE, SRC)).isZero();
338+
assertThat(cell.getAvailableStacks().get(ingot)).isEqualTo(ingots);
339+
assertThat(cell.getAvailableStacks().get(nugget)).isEqualTo(nuggets);
340+
assertThat(cell.extract(nugget, MAX, Actionable.SIMULATE, SRC)).isEqualTo(nuggets);
341+
}
275342
}

0 commit comments

Comments
 (0)