1010import io .github .thebusybiscuit .slimefun4 .core .handlers .BlockBreakHandler ;
1111import io .github .thebusybiscuit .slimefun4 .implementation .Slimefun ;
1212import io .github .thebusybiscuit .slimefun4 .implementation .SlimefunItems ;
13+ import io .github .thebusybiscuit .slimefun4 .libraries .dough .inventory .InvUtils ;
1314import io .github .thebusybiscuit .slimefun4 .libraries .dough .items .CustomItemStack ;
15+ import io .github .thebusybiscuit .slimefun4 .libraries .dough .items .ItemUtils ;
1416import io .github .thebusybiscuit .slimefun4 .utils .ChestMenuUtils ;
17+ import io .github .thebusybiscuit .slimefun4 .utils .itemstack .ItemStackWrapper ;
1518import io .ncbpfluffybear .fluffymachines .objects .DoubleHologramOwner ;
1619import io .ncbpfluffybear .fluffymachines .objects .NonHopperableBlock ;
1720import io .ncbpfluffybear .fluffymachines .utils .Utils ;
2023import java .util .List ;
2124import java .util .Locale ;
2225import javax .annotation .Nonnull ;
26+ import javax .annotation .Nullable ;
27+
2328import me .mrCookieSlime .CSCoreLibPlugin .Configuration .Config ;
2429import me .mrCookieSlime .CSCoreLibPlugin .general .Inventory .ClickAction ;
2530import me .mrCookieSlime .Slimefun .Objects .handlers .BlockTicker ;
@@ -368,6 +373,74 @@ && matchMeta(Utils.unKeyItem(inv.getItemInSlot(DISPLAY_SLOT)), item)) {
368373 }
369374 }
370375
376+ // DirtyChestMenu#fits() does not check for nbt data...
377+ public boolean fits (DirtyChestMenu inv , @ Nonnull ItemStack item , int ... slots ) {
378+ int metaMismatches = 0 ;
379+ for (int slot : slots ) {
380+ ItemStack slotItem = inv .getItemInSlot (slot );
381+ // A small optimization for empty slots
382+ if (inv .getItemInSlot (slot ) == null ) {
383+ return true ;
384+ }
385+
386+ // Heavy but foolproof check
387+ if (!matchMeta (item , slotItem )) {
388+ metaMismatches ++;
389+ }
390+ }
391+
392+ if (metaMismatches == slots .length ) {
393+ return false ;
394+ }
395+
396+ // This still performs other config based checks to see if insertion is valid...
397+ return InvUtils .fits (inv .toInventory (), ItemStackWrapper .wrap (item ), slots );
398+ }
399+
400+ // DirtyChestMenu#pushItem() does not check for nbt data...
401+ @ Nullable
402+ public ItemStack pushItem (DirtyChestMenu inv , ItemStack item , int ... slots ) {
403+ if (item == null || item .getType () == Material .AIR ) {
404+ throw new IllegalArgumentException ("Cannot push null or AIR" );
405+ }
406+
407+ ItemStackWrapper wrapper = null ;
408+ int amount = item .getAmount ();
409+
410+ for (int slot : slots ) {
411+ if (amount <= 0 ) {
412+ break ;
413+ }
414+
415+ ItemStack stack = inv .getItemInSlot (slot );
416+
417+ if (stack == null ) {
418+ inv .replaceExistingItem (slot , item );
419+ return null ;
420+ } else {
421+ int maxStackSize = Math .min (stack .getMaxStackSize (), inv .toInventory ().getMaxStackSize ());
422+ if (stack .getAmount () < maxStackSize ) {
423+ if (wrapper == null ) {
424+ wrapper = ItemStackWrapper .wrap (item );
425+ }
426+
427+ // Patched with a meta check
428+ if (ItemUtils .canStack (wrapper , stack ) && matchMeta (wrapper , stack )) {
429+ amount -= (maxStackSize - stack .getAmount ());
430+ stack .setAmount (Math .min (stack .getAmount () + item .getAmount (), maxStackSize ));
431+ item .setAmount (amount );
432+ }
433+ }
434+ }
435+ }
436+
437+ if (amount > 0 ) {
438+ return new CustomItemStack (item , amount );
439+ } else {
440+ return null ;
441+ }
442+ }
443+
371444 void pushOutput (BlockMenu inv , Block b , int capacity ) {
372445 ItemStack displayItem = inv .getItemInSlot (DISPLAY_SLOT );
373446 if (displayItem != null && displayItem .getType () != Material .BARRIER ) {
@@ -380,21 +453,21 @@ void pushOutput(BlockMenu inv, Block b, int capacity) {
380453 ItemStack clone = new CustomItemStack (Utils .unKeyItem (displayItem ), displayItem .getMaxStackSize ());
381454
382455
383- if (inv . fits (clone , OUTPUT_SLOTS )) {
456+ if (fits (inv , clone , OUTPUT_SLOTS )) {
384457 int amount = clone .getMaxStackSize ();
385458
386459 setStored (b , stored - amount );
387- inv . pushItem (clone , OUTPUT_SLOTS );
460+ pushItem (inv , clone , OUTPUT_SLOTS );
388461 updateMenu (b , inv , false , capacity );
389462 }
390463
391464 } else if (stored != 0 ) { // Output remaining
392465
393466 ItemStack clone = new CustomItemStack (Utils .unKeyItem (displayItem ), stored );
394467
395- if (inv . fits (clone , OUTPUT_SLOTS )) {
468+ if (fits (inv , clone , OUTPUT_SLOTS )) {
396469 setStored (b , 0 );
397- inv . pushItem (clone , OUTPUT_SLOTS );
470+ pushItem (inv , clone , OUTPUT_SLOTS );
398471 updateMenu (b , inv , false , capacity );
399472 }
400473 }
@@ -435,7 +508,15 @@ private void storeItem(Block b, BlockMenu inv, int slot, ItemStack item, int cap
435508 */
436509 private boolean matchMeta (ItemStack item1 , ItemStack item2 ) {
437510 // It seems the meta comparisons are heavier than type checks
438- return item1 .getType ().equals (item2 .getType ()) && item1 .getItemMeta ().equals (item2 .getItemMeta ());
511+ if (!item1 .getType ().equals (item2 .getType ())) {
512+ return false ;
513+ }
514+
515+ if (!item1 .hasItemMeta () || !item2 .hasItemMeta ()) {
516+ return true ; // Match by type
517+ }
518+
519+ return item1 .getItemMeta ().equals (item2 .getItemMeta ());
439520 }
440521
441522 /**
0 commit comments