/
CapabilityContainerListener.java
117 lines (101 loc) · 4 KB
/
CapabilityContainerListener.java
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
package choonster.testmod3.capability;
import choonster.testmod3.TestMod3;
import choonster.testmod3.network.capability.MessageBulkUpdateContainerCapability;
import choonster.testmod3.network.capability.MessageUpdateContainerCapability;
import choonster.testmod3.util.CapabilityUtils;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nullable;
/**
* Syncs the capability handler instances for items in {@link Container}s.
*
* @param <HANDLER> The capability handler type to sync
* @author Choonster
*/
public abstract class CapabilityContainerListener<HANDLER> implements IContainerListener {
/**
* The player.
*/
private final EntityPlayerMP player;
/**
* The {@link Capability} instance to update.
*/
private final Capability<HANDLER> capability;
/**
* The {@link EnumFacing} to get the capability handler from.
*/
@Nullable
private final EnumFacing facing;
public CapabilityContainerListener(final EntityPlayerMP player, Capability<HANDLER> capability, @Nullable EnumFacing facing) {
this.player = player;
this.capability = capability;
this.facing = facing;
}
@Override
public final void updateCraftingInventory(final Container containerToSend, final NonNullList<ItemStack> itemsList) {
// Filter out any items from the list that shouldn't be synced
final NonNullList<ItemStack> syncableItemsList = NonNullList.withSize(itemsList.size(), ItemStack.EMPTY);
for (int index = 0; index < syncableItemsList.size(); index++) {
final ItemStack stack = syncableItemsList.get(index);
if (shouldSyncItem(stack)) {
syncableItemsList.set(index, stack);
} else {
syncableItemsList.set(index, ItemStack.EMPTY);
}
}
final MessageBulkUpdateContainerCapability<HANDLER, ?> message = createBulkUpdateMessage(containerToSend.windowId, syncableItemsList);
if (message.hasData()) { // Don't send the message if there's nothing to update
TestMod3.network.sendTo(message, player);
}
}
@Override
public final void sendSlotContents(final Container containerToSend, final int slotInd, final ItemStack stack) {
if (!shouldSyncItem(stack)) return;
final HANDLER handler = CapabilityUtils.getCapability(stack, capability, facing);
if (handler == null) return;
final MessageUpdateContainerCapability<HANDLER, ?> message = createSingleUpdateMessage(containerToSend.windowId, slotInd, handler);
if (message.hasData()) { // Don't send the message if there's nothing to update
TestMod3.network.sendTo(message, player);
}
}
@Override
public final void sendProgressBarUpdate(final Container containerIn, final int varToUpdate, final int newValue) {
// No-op
}
@Override
public final void sendAllWindowProperties(final Container containerIn, final IInventory inventory) {
// No-op
}
/**
* Should the {@link ItemStack}'s capability data be synced?
*
* @param stack The item
* @return Should the capability data be synced?
*/
protected boolean shouldSyncItem(final ItemStack stack) {
return true;
}
/**
* Create an instance of the bulk update message.
*
* @param windowID The window ID of the Container
* @param items The items list
* @return The bulk update message
*/
protected abstract MessageBulkUpdateContainerCapability<HANDLER, ?> createBulkUpdateMessage(final int windowID, final NonNullList<ItemStack> items);
/**
* Create an instance of the single update message.
*
* @param windowID The window ID of the Container
* @param slotNumber The slot's index in the Container
* @param handler The capability handler instance
* @return The single update message
*/
protected abstract MessageUpdateContainerCapability<HANDLER, ?> createSingleUpdateMessage(final int windowID, final int slotNumber, final HANDLER handler);
}