-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathInventoryComponent.java
More file actions
220 lines (192 loc) · 6.33 KB
/
Copy pathInventoryComponent.java
File metadata and controls
220 lines (192 loc) · 6.33 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
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
package io.github.cottonmc.component.item;
import io.github.cottonmc.component.api.ActionType;
import io.github.cottonmc.component.api.ComponentHelper;
import io.github.cottonmc.component.api.Observable;
import io.github.cottonmc.component.compat.vanilla.InventoryWrapper;
import io.github.cottonmc.component.serializer.StackSerializer;
import dev.onyxstudios.cca.api.v3.component.Component;
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public interface InventoryComponent extends Component, Observable {
/**
* @return How many slots are in this inventory.
*/
int size();
/**
* @return Whether this inventory is empty or not.
*/
default boolean isEmpty() {
for (ItemStack stack : getStacks()) {
if (!stack.isEmpty()) return false;
}
return true;
}
/**
* @return A copy of the list of all item stacks in this inventory.
*/
//TODO: is it really worth doing a deep copy here? It's a lot more expensive and I'm not a hundred percent sure it's worth it
List<ItemStack> getStacks();
/**
* DO NOT USE THIS FOR COMPONENT-TO-COMPONENT INTERACTION. ONLY EXISTS FOR INTEGRATION PURPOSES.
* @return The mutable list of all item stacks in this inventory.
*/
DefaultedList<ItemStack> getMutableStacks();
/**
* @param slot The slot to get the stack for.
* @return A copy of the item stack in the slot.
*/
ItemStack getStack(int slot);
/**
* @param slot The slot to insert into.
* @return Whether this slot can be inserted into.
*/
boolean canInsert(int slot); //TODO: take a stack argument?
/**
* @param slot The slot to extract from.
* @return Whether this slot can be extracted from.
*/
boolean canExtract(int slot); //TODO: take a stack argument?
/**
* Remove part of an item stack.
* @param slot The slot to take the stack from.
* @param amount The amount of items to extract.
* @param action The type of action to perform.
* @return The stack that was successfully removed.
*/
ItemStack removeStack(int slot, int amount, ActionType action);
/**
* Remove an entire item stack.
* @param slot The slot to take the stack from.
* @param action The type of action to perform.
* @return The stack that was successfully removed.
*/
ItemStack removeStack(int slot, ActionType action);
/**
* Set the stack in a slot, overriding the slot's previous contents.
* @param slot The slot to set the stack in.
* @param stack The stack to set.
*/
void setStack(int slot, ItemStack stack);
/**
* Insert a stack into a single slot.
* @param slot The slot to insert into.
* @param stack The stack to insert.
* @param action The type of action to perform.
* @return Any remainder that was not able to be inserted.
*/
ItemStack insertStack(int slot, ItemStack stack, ActionType action);
/**
* Insert a stack into the entire inventory, spilling over into other slots.
* @param stack The stack to insert.
* @param action The type of action to perform.
* @return Any remainder that was not able to be inserted.
*/
ItemStack insertStack(ItemStack stack, ActionType action);
/**
* Empty this inventory, removing all stacks.
*/
default void clear() {
for (int i = 0; i < size(); i++) {
removeStack(i, ActionType.PERFORM);
}
}
/**
* @param slot The slot to check the max size for.
* @return The maximum amount of items able to be held in this slot.
*/
default int getMaxStackSize(int slot) {
return 64;
}
/**
* @param slot The slot to check for.
* @param stack The stack to check for.
* @return Whether this stack may be inserted into this slot.
*/
default boolean isAcceptableStack(int slot, ItemStack stack) {
return !ComponentHelper.INVENTORY.hasComponent(stack);
}
/**
* @param item The item to check the total of.
* @return The total amount of the passed item in this inventory across all stacks.
*/
default int amountOf(Item item) {
return amountOf(Collections.singleton(item));
}
/**
* @param items The items to check the total of.
* @return The total amount of the passed items in this inventory across all stacks.
*/
default int amountOf(Set<Item> items) {
int amount = 0;
for (ItemStack stack : this.getStacks()) {
if (items.contains(stack.getItem())) {
amount += stack.getCount();
}
}
return amount;
}
/**
* @param item The item to check for.
* @return Whether there are any stacks of this item in this inventory.
*/
default boolean contains(Item item) {
return contains(Collections.singleton(item));
}
/**
* @param items The items to check for.
* @return Whether there are any stacks of these items in this inventory.
*/
default boolean contains(Set<Item> items) {
for (ItemStack stack : getStacks()) {
if (items.contains(stack.getItem()) && stack.getCount() > 0) {
return true;
}
}
return false;
}
/**
* Represent this component as a vanilla {@link Inventory} for use in containers and world interaction.
*/
default Inventory asInventory() {
return InventoryWrapper.of(this);
}
/**
* Represent this component as a vanilla {@link SidedInventory} for use with hoppers and sided world interaction. Only usable for block components.
* @param world The world this component is in.
* @param pos The position this component is at.
* @return A sided inventory wrapper of this component, or null if it's not attached to a block or has no sided behavior.
*/
@Nullable
default SidedInventory asLocalInventory(WorldAccess world, BlockPos pos) {
return null;
}
@Override
default void readFromNbt(NbtCompound tag) {
clear();
NbtList items = tag.getList("Items", NbtType.COMPOUND);
for (int i = 0; i < items.size(); i++) {
NbtCompound stackTag = (NbtCompound) items.get(i);
setStack(i, StackSerializer.fromTag(stackTag));
}
}
@Override
default void writeToNbt(NbtCompound tag) {
NbtList items = new NbtList();
for (ItemStack stack : getStacks()) {
items.add(StackSerializer.toTag(stack, new NbtCompound()));
}
tag.put("Items", items);
}
}