11package com .cleanroommc .modularui .widgets .slot ;
22
33import com .cleanroommc .modularui .core .mixin .InventoryCraftingAccessor ;
4+ import com .cleanroommc .modularui .utils .Platform ;
45
6+ import net .minecraft .client .util .RecipeItemHelper ;
57import net .minecraft .inventory .Container ;
68import net .minecraft .inventory .InventoryCrafting ;
79import net .minecraft .item .ItemStack ;
1012import net .minecraftforge .items .IItemHandlerModifiable ;
1113import net .minecraftforge .items .ItemHandlerHelper ;
1214
15+ import org .jetbrains .annotations .NotNull ;
16+
17+ /**
18+ * A crafting inventory which wraps a {@link IItemHandlerModifiable}. This inventory creates a content list which is here used to detect
19+ * changes from the item handler. This is required as interacting with a slot will update the content, but will not notify the container
20+ * to check for new recipes.
21+ */
1322public class InventoryCraftingWrapper extends InventoryCrafting {
1423
15- private final IItemHandler delegate ;
24+ private final IItemHandlerModifiable delegate ;
25+ private final int size ;
1626 private final int startIndex ;
17- private final ItemStack [] snapshot ;
1827
1928 public InventoryCraftingWrapper (Container eventHandlerIn , int width , int height , IItemHandlerModifiable delegate , int startIndex ) {
2029 super (eventHandlerIn , width , height );
30+ this .size = width * height + 1 ;
31+ if (startIndex + this .size < delegate .getSlots ()) {
32+ throw new IllegalArgumentException ("Inventory does not have enough slots for given size. Requires " + (startIndex + this .size ) + " slots, but only has " + delegate .getSlots () + " slots!" );
33+ }
2134 this .delegate = delegate ;
2235 this .startIndex = startIndex ;
23- this .snapshot = new ItemStack [width * height ];
24- // save inventory snapshot
25- for (int i = 0 ; i < snapshot .length ; i ++) {
36+ for (int i = 0 ; i < this .size - 1 ; i ++) {
2637 ItemStack stack = this .delegate .getStackInSlot (i + this .startIndex );
2738 updateSnapshot (i , stack );
28- getBackingList ().set (i , stack .isEmpty () ? ItemStack .EMPTY : stack .copy ());
2939 }
3040 }
3141
3242 private NonNullList <ItemStack > getBackingList () {
3343 return ((InventoryCraftingAccessor ) this ).getStackList ();
3444 }
3545
36- public Container getEventHandler () {
46+ public Container getContainer () {
3747 return ((InventoryCraftingAccessor ) this ).getEventHandler ();
3848 }
3949
4050 private void updateSnapshot (int index , ItemStack stack ) {
41- this . snapshot [ index ] = stack . isEmpty () ? ItemStack . EMPTY : stack . copy ( );
51+ getBackingList (). set ( index , Platform . copyStack ( stack ) );
4252 }
4353
4454 public void detectChanges () {
4555 // detect changes from snapshot and notify container
46- for (int i = 0 ; i < snapshot .length ; i ++) {
47- ItemStack stack = snapshot [i ];
56+ boolean notify = false ;
57+ for (int i = 0 ; i < this .size - 1 ; i ++) {
58+ ItemStack stack = getBackingList ().get (i );
4859 ItemStack current = this .delegate .getStackInSlot (i + this .startIndex );
49- if (stack .isEmpty () != current .isEmpty () || (!stack .isEmpty () && !ItemHandlerHelper .canItemStacksStack (stack , current ))) {
50- setInventorySlotContents (i , current );
60+ if (Platform .isStackEmpty (current ) && current != Platform .EMPTY_STACK ) {
61+ current = Platform .EMPTY_STACK ;
62+ this .delegate .setStackInSlot (i + this .startIndex , Platform .EMPTY_STACK );
63+ }
64+ if (Platform .isStackEmpty (stack ) != Platform .isStackEmpty (current ) ||
65+ (!Platform .isStackEmpty (stack ) && !ItemHandlerHelper .canItemStacksStack (stack , current ))) {
5166 updateSnapshot (i , current );
67+ notify = true ;
5268 }
5369 }
70+ if (notify ) notifyContainer ();
5471 }
5572
5673 public IItemHandler getDelegate () {
@@ -60,4 +77,87 @@ public IItemHandler getDelegate() {
6077 public int getStartIndex () {
6178 return startIndex ;
6279 }
80+
81+ @ Override
82+ public int getSizeInventory () {
83+ return size ;
84+ }
85+
86+ @ Override
87+ public boolean isEmpty () {
88+ for (int i = 0 ; i < this .size ; i ++) {
89+ if (!Platform .isStackEmpty (getStackInSlot (i ))) {
90+ return false ;
91+ }
92+ }
93+ return true ;
94+ }
95+
96+ @ Override
97+ public @ NotNull ItemStack getStackInSlot (int index ) {
98+ index += this .startIndex ;
99+ return index >= 0 && index < this .size ? this .delegate .getStackInSlot (index ) : Platform .EMPTY_STACK ;
100+ }
101+
102+ @ Override
103+ public void setInventorySlotContents (int index , @ NotNull ItemStack stack ) {
104+ setSlot (index , stack , true );
105+ }
106+
107+ public void setSlot (int index , @ NotNull ItemStack stack , boolean notifyContainer ) {
108+ this .delegate .setStackInSlot (this .startIndex + index , stack );
109+ if (notifyContainer ) notifyContainer ();
110+ }
111+
112+ @ Override
113+ public @ NotNull ItemStack decrStackSize (int index , int count ) {
114+ return decrStackSize (index , count , true );
115+ }
116+
117+ public ItemStack decrStackSize (int index , int count , boolean notifyContainer ) {
118+ index += this .startIndex ;
119+ if (index < 0 || index >= this .size || count <= 0 ) return Platform .EMPTY_STACK ;
120+ ItemStack stack = getStackInSlot (index );
121+ if (Platform .isStackEmpty (stack )) return Platform .EMPTY_STACK ;
122+ stack .splitStack (count );
123+ if (Platform .isStackEmpty (stack )) {
124+ setSlot (index , Platform .EMPTY_STACK , false );
125+ }
126+ if (notifyContainer ) {
127+ notifyContainer ();
128+ }
129+ return stack ;
130+ }
131+
132+ @ Override
133+ public @ NotNull ItemStack removeStackFromSlot (int index ) {
134+ return removeStackFromSlot (index , true );
135+ }
136+
137+ public @ NotNull ItemStack removeStackFromSlot (int index , boolean notifyContainer ) {
138+ index += this .startIndex ;
139+ if (index < 0 || index >= this .size ) return Platform .EMPTY_STACK ;
140+ ItemStack stack = getStackInSlot (index );
141+ this .delegate .setStackInSlot (index , Platform .EMPTY_STACK );
142+ if (notifyContainer ) notifyContainer ();
143+ return stack ;
144+ }
145+
146+ @ Override
147+ public void clear () {
148+ for (int i = 0 ; i < this .size ; i ++) {
149+ setSlot (i , Platform .EMPTY_STACK , false );
150+ }
151+ }
152+
153+ @ Override
154+ public void fillStackedContents (@ NotNull RecipeItemHelper helper ) {
155+ for (int i = 0 ; i < this .size ; i ++) {
156+ helper .accountStack (getStackInSlot (i ));
157+ }
158+ }
159+
160+ public void notifyContainer () {
161+ getContainer ().onCraftMatrixChanged (this );
162+ }
63163}
0 commit comments