Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/appeng/core/network/InitNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import appeng.core.network.serverbound.HotkeyPacket;
import appeng.core.network.serverbound.InventoryActionPacket;
import appeng.core.network.serverbound.MEInteractionPacket;
import appeng.core.network.serverbound.PullItemToPlayerPacket;
import appeng.core.network.serverbound.MouseWheelPacket;
import appeng.core.network.serverbound.PartLeftClickPacket;
import appeng.core.network.serverbound.QuickMovePatternPacket;
Expand Down Expand Up @@ -82,6 +83,7 @@ public static void init(RegisterPayloadHandlersEvent event) {
serverbound(registrar, SwapSlotsPacket.TYPE, SwapSlotsPacket.STREAM_CODEC);
serverbound(registrar, SwitchGuisPacket.TYPE, SwitchGuisPacket.STREAM_CODEC);
serverbound(registrar, UpdateHoldingCtrlPacket.TYPE, UpdateHoldingCtrlPacket.STREAM_CODEC);
serverbound(registrar, PullItemToPlayerPacket.TYPE, PullItemToPlayerPacket.STREAM_CODEC);

// Bidirectional
bidirectional(registrar, ConfigValuePacket.TYPE, ConfigValuePacket.STREAM_CODEC);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package appeng.core.network.serverbound;

import net.minecraft.core.NonNullList;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;

import appeng.core.network.CustomAppEngPayload;
import appeng.core.network.ServerboundPacket;
import appeng.menu.me.common.MEStorageMenu;

public record PullItemToPlayerPacket(int containerId, NonNullList<ItemStack> stacks, long toPull) implements ServerboundPacket {

public static final StreamCodec<RegistryFriendlyByteBuf, PullItemToPlayerPacket> STREAM_CODEC = StreamCodec.ofMember(
PullItemToPlayerPacket::write,
PullItemToPlayerPacket::decode);

public static final Type<PullItemToPlayerPacket> TYPE = CustomAppEngPayload.createType("me_pull");

@Override
public Type<PullItemToPlayerPacket> type() {
return TYPE;
}

public static PullItemToPlayerPacket decode(RegistryFriendlyByteBuf buffer) {
int containerId = buffer.readInt();
NonNullList<ItemStack> stacks = NonNullList.withSize(buffer.readInt(), ItemStack.EMPTY);
for (int i = 0; i < stacks.size(); i++) {
stacks.set(i, ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer));
}
long toPull = buffer.readVarLong();
return new PullItemToPlayerPacket(containerId, stacks, toPull);
}

public void write(RegistryFriendlyByteBuf data) {
data.writeInt(containerId);
data.writeInt(stacks.size());
for (ItemStack stack : stacks) {
ItemStack.OPTIONAL_STREAM_CODEC.encode(data, stack);
}
data.writeVarLong(toPull);
}

@Override
public void handleOnServer(ServerPlayer player) {
if (player.containerMenu instanceof MEStorageMenu aeMenu) {
// The open screen has changed since the client sent the packet
if (player.containerMenu.containerId != containerId) {
return;
}

aeMenu.transferMatchingStacksToPlayer(stacks, toPull);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void register(EmiRegistry registry) {
registry.addGenericExclusionArea(new EmiAeBaseScreenExclusionZones());
registry.addGenericStackProvider(new EmiAeBaseScreenStackProvider());
registry.addGenericDragDropHandler(new EmiAeBaseScreenDragDropHandler());
registry.addGenericStackPuller(new EmiAeBaseScreenStackPuller());

// Additional Workstations
registerWorkstations(registry);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package appeng.integration.modules.emi;

import java.util.List;

import net.minecraft.core.NonNullList;
import dev.emi.emi.api.EmiStackPuller;
import net.neoforged.neoforge.network.PacketDistributor;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.item.ItemStack;

import appeng.menu.me.common.MEStorageMenu;
import appeng.core.network.ServerboundPacket;
import appeng.core.network.serverbound.PullItemToPlayerPacket;

public class EmiAeBaseScreenStackPuller implements EmiStackPuller<AbstractContainerMenu> {

@Override
public boolean pullStack(AbstractContainerMenu menu, List<ItemStack> stacks, long toPull) {
if (!(menu instanceof MEStorageMenu aeMenu)) {
return false;
}

NonNullList<ItemStack> nonNullStacks = NonNullList.copyOf(stacks);

ServerboundPacket message = new PullItemToPlayerPacket(menu.containerId, nonNullStacks, toPull);
PacketDistributor.sendToServer(message);

return true;
}

}
37 changes: 37 additions & 0 deletions src/main/java/appeng/menu/me/common/MEStorageMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import org.jetbrains.annotations.Nullable;

import net.minecraft.core.NonNullList;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.MenuType;
Expand Down Expand Up @@ -636,6 +637,42 @@ private boolean moveOneStackToPlayer(AEItemKey what) {
return false;
}

public void transferMatchingStacksToPlayer(NonNullList<ItemStack> stacks, long toPull) {
for (ItemStack stack : stacks) {
AEItemKey key = AEItemKey.of(stack);

long potentialAmount = storage.extract(key, toPull, Actionable.SIMULATE, getActionSource());
if (potentialAmount <= 0) {
continue;
}

var destinationSlots = getQuickMoveDestinationSlots(key.toStack(), false);

for (var destinationSlot : destinationSlots) {
var amount = Math.min(toPull, getPlaceableAmount(destinationSlot, key));
if (amount <= 0) {
continue;
}

var extracted = StorageHelper.poweredExtraction(energySource, storage, key, amount, getActionSource());
if (extracted == 0) {
break; // No items available, try next matching type
}

var currentItem = destinationSlot.getItem();
if (!currentItem.isEmpty()) {
destinationSlot.setByPlayer(currentItem.copyWithCount(currentItem.getCount() + (int) extracted));
} else {
destinationSlot.setByPlayer(key.toStack((int) extracted));
}

toPull -= extracted;
}

if (toPull <= 0) return;
}
}

@Nullable
protected final AEKey getStackBySerial(long serial) {
return updateHelper.getBySerial(serial);
Expand Down
Loading