Skip to content

Commit

Permalink
Dismantle items directly into the player's inventory instead of dropp…
Browse files Browse the repository at this point in the history
…ing them (#6841)

* Dismantle items directly into inventory instead of dropping

Co-authored-by: Sebastian Hartte <shartte@users.noreply.github.com>
  • Loading branch information
62832 and shartte committed Jan 15, 2023
1 parent 0069817 commit 26f71f5
Show file tree
Hide file tree
Showing 27 changed files with 163 additions and 117 deletions.
6 changes: 6 additions & 0 deletions src/main/java/appeng/api/inventories/InternalInventory.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ static InternalInventory empty() {
return EmptyInternalInventory.INSTANCE;
}

default void clear() {
for (int i = 0; i < size(); i++) {
setItemDirect(i, ItemStack.EMPTY);
}
}

default boolean isEmpty() {
return !iterator().hasNext();
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/appeng/api/parts/IPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,9 @@ default void addPartDrop(List<ItemStack> drops, boolean wrenched) {
* Add additional drops to the drop list (the contents of the part, but not the part itself).
*
* @param wrenched control flag for wrenched vs broken
* @param remove remove the items being dropped from the inventory
*/
default void addAdditionalDrops(List<ItemStack> drops, boolean wrenched) {
default void addAdditionalDrops(List<ItemStack> drops, boolean wrenched, boolean remove) {
}

/**
Expand Down
21 changes: 9 additions & 12 deletions src/main/java/appeng/block/AEBaseEntityBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,20 +123,17 @@ public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, Block

@Override
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
if (newState.is(state.getBlock())) {
return; // Just a block state change
}

var te = this.getBlockEntity(level, pos);
if (te != null) {
var drops = new ArrayList<ItemStack>();
te.addAdditionalDrops(level, pos, drops);

// Cry ;_; ...
Platform.spawnDrops(level, pos, drops);
// Drop internal BE content
if (!level.isClientSide() && !newState.is(state.getBlock())) {
var be = this.getBlockEntity(level, pos);
if (be != null) {
var drops = new ArrayList<ItemStack>();
be.addAdditionalDrops(level, pos, drops, false);
Platform.spawnDrops(level, pos, drops);
}
}

// super will remove the BE, as it is not an instance of BlockContainer
// super will remove the TE, as it is not an instance of BlockContainer
super.onRemove(state, level, pos, newState, isMoving);
}

Expand Down
56 changes: 32 additions & 24 deletions src/main/java/appeng/blockentity/AEBaseBlockEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
import javax.annotation.Nullable;
import javax.annotation.OverridingMethodsMustInvokeSuper;

import com.google.common.collect.Lists;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.MustBeInvokedByOverriders;

Expand All @@ -44,6 +42,7 @@
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
Expand All @@ -70,7 +69,6 @@
import appeng.hooks.ticking.TickHandler;
import appeng.items.tools.MemoryCardItem;
import appeng.util.CustomNameUtil;
import appeng.util.Platform;
import appeng.util.SettingsFrom;
import appeng.util.helpers.ItemComparisonHelper;

Expand Down Expand Up @@ -339,11 +337,12 @@ public void importSettings(SettingsFrom mode, CompoundTag input, @Nullable Playe
/**
* returns the contents of the block entity but not the block itself, to drop into the world
*
* @param level level
* @param pos block position
* @param drops drops of block entity
* @param level level
* @param pos block position
* @param drops drops of block entity
* @param remove Remove the drops from the block entity so they don't drop again when it is broken.
*/
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
}

@Override
Expand Down Expand Up @@ -414,31 +413,40 @@ public Object getRenderAttachmentData() {
/**
* Called when a player uses a wrench on this block entity to disassemble it.
*/
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult) {
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult,
ItemStack wrench) {
var pos = hitResult.getBlockPos();
final BlockState blockState = level.getBlockState(pos);
final Block block = blockState.getBlock();

var itemDropCandidates = Platform.getBlockDrops(level, pos);
var op = new ItemStack(getBlockState().getBlock());

for (var ol : itemDropCandidates) {
if (ItemComparisonHelper.isEqualItemType(ol, op)) {
var tag = new CompoundTag();
exportSettings(SettingsFrom.DISMANTLE_ITEM, tag, player);
if (!tag.isEmpty()) {
ol.setTag(tag);
var state = level.getBlockState(pos);
var block = state.getBlock();

if (level instanceof ServerLevel serverLevel) {
// Drops of the block itself (without extra block entity inventory)
var drops = Block.getDrops(state, serverLevel, pos, this, player, wrench);

var op = new ItemStack(state.getBlock());
for (var ol : drops) {
if (ItemComparisonHelper.isEqualItemType(ol, op)) {
var tag = new CompoundTag();
exportSettings(SettingsFrom.DISMANTLE_ITEM, tag, player);
if (!tag.isEmpty()) {
ol.setTag(tag);
}
break;
}
}

// Add and remove extra block entity inventory
addAdditionalDrops(level, pos, drops, true);

for (var item : drops) {
player.getInventory().placeItemBackInInventory(item);
}
}

block.playerWillDestroy(level, pos, blockState, player);
block.playerWillDestroy(level, pos, state, player);
level.removeBlock(pos, false);
block.destroy(level, pos, getBlockState());

var itemsToDrop = Lists.newArrayList(itemDropCandidates);
Platform.spawnDrops(level, pos, itemsToDrop);

return InteractionResult.sidedSuccess(level.isClientSide());
}

Expand Down
21 changes: 15 additions & 6 deletions src/main/java/appeng/blockentity/AEBaseInvBlockEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,23 @@ public void saveAdditional(CompoundTag data) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
for (var stack : getInternalInventory()) {
// Wrapped fluid stacks are internal implementation details and should NEVER drop
if (GenericStack.isWrapped(stack)) {
continue;
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
var inv = getInternalInventory();
for (var stack : inv) {
var genericStack = GenericStack.unwrapItemStack(stack);
if (genericStack != null) {
genericStack.what().addDrops(
genericStack.amount(),
drops,
level,
pos);
} else {
drops.add(stack);
}
}

drops.add(stack);
if (remove) {
inv.clear();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,15 @@ public int getCraftingProgress() {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
super.addAdditionalDrops(level, pos, drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
super.addAdditionalDrops(level, pos, drops, remove);

for (var upgrade : upgrades) {
drops.add(upgrade);
}
if (remove) {
drops.clear();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ public Set<Direction> getGridConnectableSides(BlockOrientation orientation) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
this.logic.addDrops(drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
this.logic.addDrops(drops, remove);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,14 @@ private ConfigInventory getCellConfigInventory() {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
super.addAdditionalDrops(level, pos, drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
super.addAdditionalDrops(level, pos, drops, remove);

if (!this.cell.getStackInSlot(0).isEmpty()) {
drops.add(this.cell.getStackInSlot(0));
if (remove) {
this.cell.setItemDirect(0, ItemStack.EMPTY);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,15 @@ protected void onOrientationChanged(BlockOrientation orientation) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
super.addAdditionalDrops(level, pos, drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
super.addAdditionalDrops(level, pos, drops, remove);

for (var upgrade : upgrades) {
drops.add(upgrade);
}
if (remove) {
upgrades.clear();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ public void onMainNodeStateChanged(IGridNodeListener.State reason) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
this.logic.addDrops(drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
this.logic.addDrops(drops, remove);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,17 @@ public void onChangeInventory(InternalInventory inv, int slot) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
if (!this.getConfigSlot().isEmpty()) {
drops.add(this.getConfigSlot().getStackInSlot(0));
}

for (var key : this.inventory.getStoredItems()) {
drops.add(key.toStack());
}
if (remove) {
this.inventory.getStoredItems().clear();
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
Expand Down Expand Up @@ -154,8 +156,8 @@ public void markForUpdate() {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
this.getCableBus().addAdditionalDrops(drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
this.getCableBus().addAdditionalDrops(drops, remove);
}

@Override
Expand Down Expand Up @@ -299,10 +301,11 @@ public CableBusRenderState getRenderAttachmentData() {
}

@Override
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult) {
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult,
ItemStack wrench) {

if (!level.isClientSide) {
final List<ItemStack> is = new ArrayList<>();
var is = new ArrayList<ItemStack>();
final SelectedPart sp;

AppEng.instance().setPartInteractionPlayer(player);
Expand All @@ -315,24 +318,36 @@ public InteractionResult disassembleWithWrench(Player player, Level level, Block
// SelectedPart contains either a facade or a part. Never both.
if (sp.part != null) {
sp.part.addPartDrop(is, true);
sp.part.addAdditionalDrops(is, true);
cb.removePartFromSide(sp.side);
}

var pos = getBlockPos();
sp.part.addAdditionalDrops(is, true, remove);

// All facades will be dropped to the ground when the cable is removed,
// do it manually here, so they are moved to the player inv too
if (sp.side == null) {
var facades = getFacadeContainer();
for (var side : Direction.values()) {
var facade = facades.getFacade(side);
if (facade != null) {
is.add(facade.getItemStack());
facades.removeFacade(cb, side);
}
}
}

// A facade cannot exist without a cable part, no host cleanup needed.
if (sp.facade != null) {
cb.removePartFromSide(sp.side);
} else if (sp.facade != null) {
is.add(sp.facade.getItemStack());
cb.getFacadeContainer().removeFacade(cb, sp.side);
Platform.notifyBlocksOfNeighbors(level, pos);
Platform.notifyBlocksOfNeighbors(level, getBlockPos());
}

if (!is.isEmpty()) {
Platform.spawnDrops(level, pos, is);
for (var item : is) {
player.getInventory().placeItemBackInInventory(item);
}
}

// Play a break sound
level.playSound(player, getBlockPos(), SoundEvents.STONE_BREAK, SoundSource.BLOCKS, .7f, 1f);

return InteractionResult.sidedSuccess(level.isClientSide());

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,11 +391,14 @@ private boolean moveSlot(int x) {
* @param drops drops of block entity
*/
@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
super.addAdditionalDrops(level, pos, drops);
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
super.addAdditionalDrops(level, pos, drops, remove);

for (var upgrade : upgrades) {
drops.add(upgrade);
}
if (remove) {
drops.clear();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,14 @@ public void setLootTable(ResourceLocation lootTable, long lootTableSeed) {
}

@Override
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops, boolean remove) {
unpackLootTable(null);
super.addAdditionalDrops(level, pos, drops);
super.addAdditionalDrops(level, pos, drops, remove);
}

@Override
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult) {
public InteractionResult disassembleWithWrench(Player player, Level level, BlockHitResult hitResult,
ItemStack wrench) {
return InteractionResult.FAIL;
}
}
Loading

0 comments on commit 26f71f5

Please sign in to comment.