-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathItemStackHandler.java
More file actions
146 lines (126 loc) · 5.14 KB
/
ItemStackHandler.java
File metadata and controls
146 lines (126 loc) · 5.14 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
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
package cam72cam.mod.item;
import cam72cam.mod.serialization.*;
import javax.annotation.Nonnull;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
/** Standard IInventory implementation */
@TagMapped(ItemStackHandler.TagMapper.class)
public class ItemStackHandler implements IInventory {
public final net.minecraftforge.items.ItemStackHandler internal;
protected BiPredicate<Integer, ItemStack> checkSlot = (integer, itemStack) -> true;
private final List<Consumer<Integer>> onChanged = new ArrayList<>();
private Function<Integer, Integer> slotLimit = null;
public ItemStackHandler(int size) {
this.internal = new net.minecraftforge.items.ItemStackHandler(size) {
@Override
public void setStackInSlot(int slot, @Nonnull net.minecraft.item.ItemStack stack) {
if (checkSlot.test(slot, new ItemStack(stack))) {
super.setStackInSlot(slot, stack);
}
}
@Override
@Nonnull
public net.minecraft.item.ItemStack insertItem(int slot, @Nonnull net.minecraft.item.ItemStack stack, boolean simulate) {
return checkSlot.test(slot, new ItemStack(stack)) ? super.insertItem(slot, stack.copy(), simulate) : stack;
}
@Override
public int getSlotLimit(int slot) {
return slotLimit == null ? super.getSlotLimit(slot) : Math.min(super.getSlotLimit(slot), slotLimit.apply(slot));
}
@Override
protected void onContentsChanged(int slot) {
super.onContentsChanged(slot);
onChanged.forEach(f -> f.accept(slot));
}
};
}
public ItemStackHandler() {
this(1);
}
/** Get notified any time a stack changes (which slot) */
public void onChanged(Consumer<Integer> fn) {
onChanged.add(fn);
}
/** Set slot limiter */
public void setSlotLimit(Function<Integer, Integer> limiter) {
slotLimit = limiter;
}
/** Change the size of the inventory and return items that don't fit anymore */
public List<ItemStack> setSize(int inventorySize) {
if (inventorySize == getSlotCount()) {
return Collections.emptyList();
}
List<ItemStack> keep = new ArrayList<>();
List<ItemStack> extra = new ArrayList<>();
if (internal.getSlots() > inventorySize) {
for (int i = 0; i < internal.getSlots(); i++) {
(i < inventorySize ? keep : extra).add(get(i));
}
}
internal.setSize(inventorySize);
for (int i = 0; i < keep.size(); i++) {
internal.setStackInSlot(i, keep.get(i).internal);
}
return extra;
}
@Override
public int getSlotCount() {
return internal.getSlots();
}
@Override
public ItemStack get(int slot) {
return new ItemStack(internal.getStackInSlot(slot));
}
@Override
public void set(int slot, ItemStack stack) {
internal.setStackInSlot(slot, stack.internal);
}
@Override
public ItemStack insert(int slot, ItemStack stack, boolean simulate) {
return new ItemStack(internal.insertItem(slot, stack.internal, simulate));
}
@Override
public ItemStack extract(int slot, int amount, boolean simulate) {
return new ItemStack(internal.extractItem(slot, amount, simulate));
}
@Override
public int getLimit(int slot) {
return internal.getSlotLimit(slot);
}
public static class TagMapper implements cam72cam.mod.serialization.TagMapper<ItemStackHandler> {
@Override
public TagAccessor<ItemStackHandler> apply(Class<ItemStackHandler> type, String fieldName, TagField tag) throws SerializationException {
Constructor<ItemStackHandler> ctr;
try {
ctr = type.getDeclaredConstructor();
ctr.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new SerializationException("Unable to detect constructor for " + type, e);
}
return new TagAccessor<>(
(d, o) -> {
if (o == null) {
d.remove(fieldName);
return;
}
d.set(fieldName, new TagCompound(o.internal.serializeNBT()));
},
(d, w) -> {
try {
ItemStackHandler o = ctr.newInstance();
o.internal.deserializeNBT(d.get(fieldName).internal);
return o;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new SerializationException("Unable to construct item stack handler " + type, e);
}
}
);
}
}
}