This commit is contained in:
Ell 2024-09-15 20:56:48 +02:00
parent 9f55e87972
commit 4a43c32342
46 changed files with 154 additions and 107 deletions

View file

@ -21,6 +21,7 @@ import net.neoforged.neoforge.network.handling.IPayloadContext;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public record PacketGhostSlot(BlockPos pos, List<Entry> stacks) implements CustomPacketPayload { public record PacketGhostSlot(BlockPos pos, List<Entry> stacks) implements CustomPacketPayload {
@ -43,28 +44,27 @@ public record PacketGhostSlot(BlockPos pos, List<Entry> stacks) implements Custo
tile.setGhostItems(message.stacks); tile.setGhostItems(message.stacks);
} }
public record Entry(List<ItemStack> stacks, TagKey<Item> tag) { public record Entry(Optional<List<ItemStack>> stacks, Optional<TagKey<Item>> tag) {
public static final StreamCodec<RegistryFriendlyByteBuf, Entry> CODEC = StreamCodec.composite( public static final StreamCodec<RegistryFriendlyByteBuf, Entry> CODEC = StreamCodec.composite(
ItemStack.OPTIONAL_LIST_STREAM_CODEC, Entry::stacks, ByteBufCodecs.optional(ItemStack.OPTIONAL_LIST_STREAM_CODEC), Entry::stacks,
ByteBufCodecs.fromCodec(TagKey.codec(Registries.ITEM)), Entry::tag, ByteBufCodecs.optional(ByteBufCodecs.fromCodec(TagKey.codec(Registries.ITEM))), Entry::tag,
Entry::new); Entry::new);
public static Entry fromStacks(Level level, List<ItemStack> stacks) { public static Entry fromStacks(Level level, List<ItemStack> stacks) {
var tag = Entry.getTagForStacks(level, stacks); var tag = Entry.getTagForStacks(level, stacks);
if (tag != null) { if (tag != null) {
return new Entry(null, tag); return new Entry(Optional.empty(), Optional.of(tag));
} else { } else {
return new Entry(stacks, null); return new Entry(Optional.of(stacks), Optional.empty());
} }
} }
public List<ItemStack> getStacks(Level level) { public List<ItemStack> getStacks(Level level) {
if (this.stacks != null) return this.stacks.orElseGet(() ->
return this.stacks; Streams.stream(level.registryAccess().registry(Registries.ITEM).orElseThrow().getTagOrEmpty(this.tag.orElseThrow()).iterator())
return Streams.stream(level.registryAccess().registry(Registries.ITEM).orElseThrow().getTagOrEmpty(this.tag).iterator())
.filter(h -> h.value() != null & h.value() != Items.AIR) .filter(h -> h.value() != null & h.value() != Items.AIR)
.map(h -> new ItemStack(h.value())).collect(Collectors.toList()); .map(h -> new ItemStack(h.value())).collect(Collectors.toList()));
} }
private static TagKey<Item> getTagForStacks(Level level, List<ItemStack> stacks) { private static TagKey<Item> getTagForStacks(Level level, List<ItemStack> stacks) {

View file

@ -9,7 +9,10 @@ import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.*; import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -28,7 +31,7 @@ public class CraftingTerminalContainer extends ItemTerminalContainer {
@Override @Override
protected void addOwnSlots(Player player) { protected void addOwnSlots(Player player) {
this.craftInventory = new WrappedCraftingInventory(this.getTile().craftItems, this, 3, 3); this.craftInventory = new WrappedCraftingInventory(this.getTile().craftItems, this);
this.craftResult = new ResultContainer() { this.craftResult = new ResultContainer() {
@Override @Override
public void setChanged() { public void setChanged() {
@ -46,14 +49,7 @@ public class CraftingTerminalContainer extends ItemTerminalContainer {
@Override @Override
public void slotsChanged(Container inventoryIn) { public void slotsChanged(Container inventoryIn) {
super.slotsChanged(inventoryIn); super.slotsChanged(inventoryIn);
if (!this.player.level().isClientSide) { CraftingTerminalContainer.slotChangedCraftingGrid(this, this.player.level(), this.player, this.craftInventory, this.craftResult, null);
var ret = ItemStack.EMPTY;
var optional = this.player.level().getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, this.craftInventory.asCraftInput(), this.player.level());
if (optional.isPresent())
ret = optional.get().value().assemble(this.craftInventory.asCraftInput(), this.player.level().registryAccess());
this.craftResult.setItem(0, ret);
((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(this.containerId, 0, 0, ret));
}
} }
@Override @Override
@ -80,4 +76,28 @@ public class CraftingTerminalContainer extends ItemTerminalContainer {
return (CraftingTerminalBlockEntity) this.tile; return (CraftingTerminalBlockEntity) this.tile;
} }
// copied from CraftingMenu
protected static void slotChangedCraftingGrid(AbstractContainerMenu menu, Level level, Player player, CraftingContainer craftSlots, ResultContainer resultSlots, @Nullable RecipeHolder<CraftingRecipe> recipe) {
if (!level.isClientSide) {
var craftinginput = craftSlots.asCraftInput();
var serverplayer = (ServerPlayer) player;
var itemstack = ItemStack.EMPTY;
var optional = level.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftinginput, level, recipe);
if (optional.isPresent()) {
var recipeholder = optional.get();
var craftingrecipe = recipeholder.value();
if (resultSlots.setRecipeUsed(level, serverplayer, recipeholder)) {
var itemstack1 = craftingrecipe.assemble(craftinginput, level.registryAccess());
if (itemstack1.isItemEnabled(level.enabledFeatures())) {
itemstack = itemstack1;
}
}
}
resultSlots.setItem(0, itemstack);
menu.setRemoteSlot(0, itemstack);
serverplayer.connection.send(new ClientboundContainerSetSlotPacket(menu.containerId, menu.incrementStateId(), 0, itemstack));
}
}
} }

View file

@ -1,17 +1,20 @@
package de.ellpeck.prettypipes.terminal.containers; package de.ellpeck.prettypipes.terminal.containers;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.StackedContents; import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.inventory.TransientCraftingContainer; import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.ItemStackHandler; import net.neoforged.neoforge.items.ItemStackHandler;
public class WrappedCraftingInventory extends TransientCraftingContainer { import java.util.List;
import java.util.stream.IntStream;
public class WrappedCraftingInventory implements CraftingContainer {
private final ItemStackHandler items; private final ItemStackHandler items;
private final CraftingTerminalContainer eventHandler; private final CraftingTerminalContainer eventHandler;
public WrappedCraftingInventory(ItemStackHandler items, CraftingTerminalContainer eventHandlerIn, int width, int height) { public WrappedCraftingInventory(ItemStackHandler items, CraftingTerminalContainer eventHandlerIn) {
super(eventHandlerIn, width, height);
this.eventHandler = eventHandlerIn; this.eventHandler = eventHandlerIn;
this.items = items; this.items = items;
} }
@ -47,8 +50,7 @@ public class WrappedCraftingInventory extends TransientCraftingContainer {
var slotStack = this.items.getStackInSlot(index); var slotStack = this.items.getStackInSlot(index);
var ret = !slotStack.isEmpty() && count > 0 ? slotStack.split(count) : ItemStack.EMPTY; var ret = !slotStack.isEmpty() && count > 0 ? slotStack.split(count) : ItemStack.EMPTY;
if (!ret.isEmpty()) { if (!ret.isEmpty()) {
for (var player : this.eventHandler.getTile().getLookingPlayers()) this.eventHandler.slotsChanged(this);
player.containerMenu.slotsChanged(this);
} }
return ret; return ret;
} }
@ -56,8 +58,17 @@ public class WrappedCraftingInventory extends TransientCraftingContainer {
@Override @Override
public void setItem(int index, ItemStack stack) { public void setItem(int index, ItemStack stack) {
this.items.setStackInSlot(index, stack); this.items.setStackInSlot(index, stack);
for (var player : this.eventHandler.getTile().getLookingPlayers()) this.eventHandler.slotsChanged(this);
player.containerMenu.slotsChanged(this); }
@Override
public void setChanged() {
this.eventHandler.slotsChanged(this);
}
@Override
public boolean stillValid(Player player) {
return true;
} }
@Override @Override
@ -71,4 +82,20 @@ public class WrappedCraftingInventory extends TransientCraftingContainer {
for (var i = 0; i < this.items.getSlots(); i++) for (var i = 0; i < this.items.getSlots(); i++)
helper.accountStack(this.items.getStackInSlot(i)); helper.accountStack(this.items.getStackInSlot(i));
} }
@Override
public int getWidth() {
return 3;
}
@Override
public int getHeight() {
return 3;
}
@Override
public List<ItemStack> getItems() {
return IntStream.range(0, this.getContainerSize()).mapToObj(this::getItem).toList();
}
} }

View file

@ -20,6 +20,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:blank_module" "id": "prettypipes:blank_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:crafting_terminal" "id": "prettypipes:crafting_terminal"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:damage_filter_modifier" "id": "prettypipes:damage_filter_modifier"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:filter_increase_modifier" "id": "prettypipes:filter_increase_modifier"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_crafting_module" "id": "prettypipes:high_crafting_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_extraction_module" "id": "prettypipes:high_extraction_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_filter_module" "id": "prettypipes:high_filter_module"
} }
} }

View file

@ -14,6 +14,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_high_priority_module" "id": "prettypipes:high_high_priority_module"
} }
} }

View file

@ -7,13 +7,13 @@
], ],
"key": { "key": {
"C": { "C": {
"tag": "forge:cobblestone" "tag": "c:cobblestones"
}, },
"M": { "M": {
"item": "prettypipes:medium_low_priority_module" "item": "prettypipes:medium_low_priority_module"
} }
}, },
"result": { "result": {
"item": "prettypipes:high_low_priority_module" "id": "prettypipes:high_low_priority_module"
} }
} }

View file

@ -20,6 +20,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_retrieval_module" "id": "prettypipes:high_retrieval_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:high_speed_module" "id": "prettypipes:high_speed_module"
} }
} }

View file

@ -19,13 +19,13 @@
"item": "minecraft:iron_block" "item": "minecraft:iron_block"
}, },
"C": { "C": {
"tag": "forge:chests" "tag": "c:chests"
}, },
"D": { "D": {
"item": "minecraft:diamond" "item": "minecraft:diamond"
} }
}, },
"result": { "result": {
"item": "prettypipes:item_terminal" "id": "prettypipes:item_terminal"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_crafting_module" "id": "prettypipes:low_crafting_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_extraction_module" "id": "prettypipes:low_extraction_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_filter_module" "id": "prettypipes:low_filter_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_high_priority_module" "id": "prettypipes:low_high_priority_module"
} }
} }

View file

@ -10,13 +10,13 @@
"item": "minecraft:redstone" "item": "minecraft:redstone"
}, },
"C": { "C": {
"tag": "forge:cobblestone" "tag": "c:cobblestones"
}, },
"M": { "M": {
"item": "prettypipes:blank_module" "item": "prettypipes:blank_module"
} }
}, },
"result": { "result": {
"item": "prettypipes:low_low_priority_module" "id": "prettypipes:low_low_priority_module"
} }
} }

View file

@ -20,6 +20,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_retrieval_module" "id": "prettypipes:low_retrieval_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:low_speed_module" "id": "prettypipes:low_speed_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_crafting_module" "id": "prettypipes:medium_crafting_module"
} }
} }

View file

@ -14,6 +14,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_extraction_module" "id": "prettypipes:medium_extraction_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_filter_module" "id": "prettypipes:medium_filter_module"
} }
} }

View file

@ -14,6 +14,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_high_priority_module" "id": "prettypipes:medium_high_priority_module"
} }
} }

View file

@ -7,13 +7,13 @@
], ],
"key": { "key": {
"C": { "C": {
"tag": "forge:cobblestone" "tag": "c:cobblestones"
}, },
"M": { "M": {
"item": "prettypipes:low_low_priority_module" "item": "prettypipes:low_low_priority_module"
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_low_priority_module" "id": "prettypipes:medium_low_priority_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_retrieval_module" "id": "prettypipes:medium_retrieval_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:medium_speed_module" "id": "prettypipes:medium_speed_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:mod_filter_modifier" "id": "prettypipes:mod_filter_modifier"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:nbt_filter_modifier" "id": "prettypipes:nbt_filter_modifier"
} }
} }

View file

@ -13,14 +13,14 @@
"item": "minecraft:iron_bars" "item": "minecraft:iron_bars"
}, },
"G": { "G": {
"tag": "forge:glass" "tag": "c:glass_blocks"
}, },
"C": { "C": {
"item": "minecraft:copper_ingot" "item": "minecraft:copper_ingot"
} }
}, },
"result": { "result": {
"item": "prettypipes:pipe", "id": "prettypipes:pipe",
"count": 4 "count": 4
} }
} }

View file

@ -12,6 +12,6 @@
} }
], ],
"result": { "result": {
"item": "prettypipes:pipe_frame" "id": "prettypipes:pipe_frame"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:pressurizer" "id": "prettypipes:pressurizer"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:random_sorting_modifier" "id": "prettypipes:random_sorting_modifier"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:redstone_module" "id": "prettypipes:redstone_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:round_robin_sorting_modifier" "id": "prettypipes:round_robin_sorting_modifier"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:stack_size_module" "id": "prettypipes:stack_size_module"
} }
} }

View file

@ -17,6 +17,6 @@
} }
}, },
"result": { "result": {
"item": "prettypipes:tag_filter_modifier" "id": "prettypipes:tag_filter_modifier"
} }
} }

View file

@ -13,10 +13,10 @@
"item": "minecraft:iron_ingot" "item": "minecraft:iron_ingot"
}, },
"R": { "R": {
"tag": "forge:dyes/red" "tag": "c:dyes/red"
} }
}, },
"result": { "result": {
"item": "prettypipes:wrench" "id": "prettypipes:wrench"
} }
} }