Skip to content

Commit

Permalink
Fix configurator empty mode ignoring stack size (#7798) and also only…
Browse files Browse the repository at this point in the history
… allow emptying creative bins if the player is in creative
  • Loading branch information
pupnewfster committed Jun 8, 2023
1 parent 3fba9ac commit eedad76
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 20 deletions.
14 changes: 13 additions & 1 deletion src/main/java/mekanism/common/item/ItemConfigurator.java
Expand Up @@ -32,11 +32,14 @@
import mekanism.common.item.interfaces.IItemHUDProvider;
import mekanism.common.lib.radial.IRadialEnumModeItem;
import mekanism.common.lib.transmitter.TransmissionType;
import mekanism.common.tier.BinTier;
import mekanism.common.tile.TileEntityBin;
import mekanism.common.tile.base.TileEntityMekanism;
import mekanism.common.tile.component.config.ConfigInfo;
import mekanism.common.tile.component.config.DataType;
import mekanism.common.tile.interfaces.ISideConfiguration;
import mekanism.common.util.CapabilityUtils;
import mekanism.common.util.InventoryUtils;
import mekanism.common.util.MekanismUtils;
import mekanism.common.util.MekanismUtils.ResourceType;
import mekanism.common.util.StorageUtils;
Expand Down Expand Up @@ -141,6 +144,15 @@ public InteractionResult useOn(UseOnContext context) {
return InteractionResult.FAIL;
}
boolean creative = player.isCreative();
if (tile instanceof TileEntityBin bin && bin.getTier() == BinTier.CREATIVE) {
//If the tile is a creative bin only allow clearing it if the player is in creative
// and don't bother popping the stack out
if (creative) {
bin.getBinSlot().setEmpty();
return InteractionResult.SUCCESS;
}
return InteractionResult.FAIL;
}
IEnergyContainer energyContainer = creative ? null : StorageUtils.getEnergyContainer(stack, 0);
if (!creative && energyContainer == null) {
return InteractionResult.FAIL;
Expand All @@ -155,7 +167,7 @@ public InteractionResult useOn(UseOnContext context) {
}
energyContainer.extract(energyPerItemDump, Action.EXECUTE, AutomationType.MANUAL);
}
Block.popResource(world, pos, inventorySlot.getStack().copy());
InventoryUtils.dropStack(inventorySlot.getStack().copy(), slotStack -> Block.popResourceFromFace(world, pos, side, slotStack));
inventorySlot.setEmpty();
}
}
Expand Down
49 changes: 30 additions & 19 deletions src/main/java/mekanism/common/util/InventoryUtils.java
Expand Up @@ -4,6 +4,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import mekanism.api.Action;
import mekanism.api.AutomationType;
import mekanism.api.MekanismAPI;
Expand Down Expand Up @@ -51,31 +52,41 @@ public static void dropItemContents(ItemEntity entity, DamageSource source) {
ListTag storedContents = sustainedInventory.getInventory(stack);
for (IInventorySlot slot : ItemRecipeData.readContents(storedContents)) {
if (!slot.isEmpty()) {
ItemStack slotStack = slot.getStack();
int count = slotStack.getCount();
int max = slotStack.getMaxStackSize();
if (count > max) {
//If we have more than a stack of the item (such as we are a bin) or some other thing that allows for compressing
// stack counts, drop as many stacks as we need at their max size
while (count > max) {
entity.level.addFreshEntity(new ItemEntity(entity.level, entity.getX(), entity.getY(), entity.getZ(), StackUtils.size(slotStack, max)));
count -= max;
}
if (count > 0) {
//If we have anything left to drop afterward, do so
entity.level.addFreshEntity(new ItemEntity(entity.level, entity.getX(), entity.getY(), entity.getZ(), StackUtils.size(slotStack, count)));
}
} else {
//If we have a valid stack, we can just directly drop that instead without requiring any copies
// as while IInventorySlot#getStack says to not mutate the stack, our slot is a dummy slot
entity.level.addFreshEntity(new ItemEntity(entity.level, entity.getX(), entity.getY(), entity.getZ(), slotStack));
}
//Pass the stack directly as while IInventorySlot#getStack says to not mutate the stack, our slot is a dummy slot
// so even if we end up adding the entity using the source stack it is fine
dropStack(slot.getStack(), slotStack -> entity.level.addFreshEntity(new ItemEntity(entity.level, entity.getX(), entity.getY(), entity.getZ(), slotStack)));
}
}
}
}
}

/**
* Helper to drop a stack that may potentially be oversized.
*
* @param stack Item Stack to drop, may be passed directly to the dropper.
* @param dropper Called to drop the item.
*/
public static void dropStack(ItemStack stack, Consumer<ItemStack> dropper) {
int count = stack.getCount();
int max = stack.getMaxStackSize();
if (count > max) {
//If we have more than a stack of the item (such as we are a bin) or some other thing that allows for compressing
// stack counts, drop as many stacks as we need at their max size
while (count > max) {
dropper.accept(StackUtils.size(stack, max));
count -= max;
}
if (count > 0) {
//If we have anything left to drop afterward, do so
dropper.accept(StackUtils.size(stack, count));
}
} else {
//If we have a valid stack, we can just directly drop that instead without requiring any copies
dropper.accept(stack);
}
}

/**
* Like {@link ItemHandlerHelper#canItemStacksStack(ItemStack, ItemStack)} but empty stacks mean equal (either param). Thiakil: not sure why.
*
Expand Down

0 comments on commit eedad76

Please sign in to comment.