it compiles??

This commit is contained in:
Ell 2024-09-15 19:12:35 +02:00
parent 3e70470e83
commit 375f5522f9
28 changed files with 179 additions and 131 deletions

View file

@ -3,6 +3,7 @@ package de.ellpeck.prettypipes;
import de.ellpeck.prettypipes.entities.PipeFrameEntity; import de.ellpeck.prettypipes.entities.PipeFrameEntity;
import de.ellpeck.prettypipes.entities.PipeFrameRenderer; import de.ellpeck.prettypipes.entities.PipeFrameRenderer;
import de.ellpeck.prettypipes.items.*; import de.ellpeck.prettypipes.items.*;
import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.ItemEquality; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.misc.ModuleClearingRecipe; import de.ellpeck.prettypipes.misc.ModuleClearingRecipe;
@ -199,7 +200,11 @@ public final class Registry {
event.register(Registries.DATA_COMPONENT_TYPE, h -> { event.register(Registries.DATA_COMPONENT_TYPE, h -> {
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "crafting_module_contents"), CraftingModuleItem.Contents.TYPE); h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "crafting_module_contents"), CraftingModuleItem.Contents.TYPE);
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "item_filter_contents"), ItemFilter.TYPE); h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "item_filter_data"), ItemFilter.Data.TYPE);
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "stack_size_module_data"), StackSizeModuleItem.Data.TYPE);
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "direction_selector_data"), DirectionSelector.Data.TYPE);
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "filter_modifier_data"), FilterModifierModuleItem.Data.TYPE);
h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "sorting_module_data"), SortingModuleItem.Data.TYPE);
}); });
} }

View file

@ -9,7 +9,9 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntArrayTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style; import net.minecraft.network.chat.Style;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
@ -156,6 +158,15 @@ public final class Utility {
return new SidedInvWrapper(inventory, direction); return new SidedInvWrapper(inventory, direction);
} }
public static BlockPos readBlockPos(Tag tag) {
if (tag instanceof IntArrayTag i) {
int[] arr = i.getAsIntArray();
if (arr.length == 3)
return new BlockPos(arr[0], arr[1], arr[2]);
}
return null;
}
public interface IMergeItemStack { public interface IMergeItemStack {
boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection); boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection);

View file

@ -5,6 +5,7 @@ import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.entities.PipeFrameEntity; import de.ellpeck.prettypipes.entities.PipeFrameEntity;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
@ -14,6 +15,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.context.UseOnContext;
import java.util.List; import java.util.List;
@ -38,10 +40,9 @@ public class PipeFrameItem extends Item {
var world = context.getLevel(); var world = context.getLevel();
HangingEntity hangingentity = new PipeFrameEntity(Registry.pipeFrameEntity, world, blockpos1, direction); HangingEntity hangingentity = new PipeFrameEntity(Registry.pipeFrameEntity, world, blockpos1, direction);
var compoundTag = itemstack.getTag(); var customdata = itemstack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
if (compoundTag != null) { if (!customdata.isEmpty())
EntityType.updateCustomEntityTag(world, playerentity, hangingentity, compoundTag); EntityType.updateCustomEntityTag(world, playerentity, hangingentity, customdata);
}
if (hangingentity.survives()) { if (hangingentity.survives()) {
if (!world.isClientSide) { if (!world.isClientSide) {

View file

@ -1,11 +1,13 @@
package de.ellpeck.prettypipes.misc; package de.ellpeck.prettypipes.misc;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.core.component.DataComponentType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
@ -66,18 +68,13 @@ public class DirectionSelector {
if (!this.modified) if (!this.modified)
return; return;
this.modified = false; this.modified = false;
this.stack.set(Data.TYPE, new Data(this.direction.getName()));
var tag = new CompoundTag();
if (this.direction != null)
tag.putString("direction", this.direction.getName());
this.stack.getOrCreateTag().put("direction_selector", tag);
} }
public void load() { public void load() {
if (this.stack.hasTag()) { var data = this.stack.get(Data.TYPE);
var tag = this.stack.getTag().getCompound("direction_selector"); if (data != null)
this.direction = Direction.byName(tag.getString("direction")); this.direction = Direction.byName(data.direction);
}
} }
public Direction[] directions() { public Direction[] directions() {
@ -105,4 +102,13 @@ public class DirectionSelector {
} }
public record Data(String direction) {
public static final Codec<DirectionSelector.Data> CODEC = RecordCodecBuilder.create(i -> i.group(
Codec.STRING.fieldOf("direction").forGetter(f -> f.direction)
).apply(i, DirectionSelector.Data::new));
public static final DataComponentType<DirectionSelector.Data> TYPE = DataComponentType.<DirectionSelector.Data>builder().persistent(DirectionSelector.Data.CODEC).cacheEncoding().build();
}
} }

View file

@ -15,6 +15,7 @@ public record EquatableItemStack(ItemStack stack, ItemEquality... equalityTypes)
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(this.stack.getItem(), this.stack.getTag()); return Objects.hash(this.stack.getItem(), this.stack.getComponents());
} }
} }

View file

@ -1,6 +1,9 @@
package de.ellpeck.prettypipes.misc; package de.ellpeck.prettypipes.misc;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleItem; import de.ellpeck.prettypipes.pipe.modules.modifier.FilterModifierModuleItem;
@ -10,8 +13,7 @@ import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Tooltip; import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup; import net.minecraft.core.component.DataComponentType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.Slot; import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -24,18 +26,26 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
public class ItemFilter extends ItemStackHandler { public class ItemFilter {
public final ItemStackHandler content;
public boolean isWhitelist;
public boolean canPopulateFromInventories;
public boolean canModifyWhitelist = true;
private final ItemStack stack; private final ItemStack stack;
private final PipeBlockEntity pipe; private final PipeBlockEntity pipe;
public boolean isWhitelist;
public boolean canPopulateFromInventories;
public boolean canModifyWhitelist = true;
private boolean modified; private boolean modified;
public ItemFilter(int size, ItemStack stack, PipeBlockEntity pipe) { public ItemFilter(int size, ItemStack stack, PipeBlockEntity pipe) {
super(size); this.content = new ItemStackHandler(size) {
@Override
protected void onContentsChanged(int slot) {
ItemFilter.this.modified = true;
}
};
this.stack = stack; this.stack = stack;
this.pipe = pipe; this.pipe = pipe;
this.load(); this.load();
@ -43,8 +53,8 @@ public class ItemFilter extends ItemStackHandler {
public List<Slot> getSlots(int x, int y) { public List<Slot> getSlots(int x, int y) {
List<Slot> slots = new ArrayList<>(); List<Slot> slots = new ArrayList<>();
for (var i = 0; i < this.getSlots(); i++) for (var i = 0; i < this.content.getSlots(); i++)
slots.add(new FilterSlot(this, i, x + i % 9 * 18, y + i / 9 * 18, true)); slots.add(new FilterSlot(this.content, i, x + i % 9 * 18, y + i / 9 * 18, true));
return slots; return slots;
} }
@ -85,7 +95,7 @@ public class ItemFilter extends ItemStackHandler {
copy.setCount(1); copy.setCount(1);
// try inserting into ourselves and any filter increase modifiers // try inserting into ourselves and any filter increase modifiers
for (var filter : filters) { for (var filter : filters) {
if (ItemHandlerHelper.insertItem(filter, copy, false).isEmpty()) { if (ItemHandlerHelper.insertItem(filter.content, copy, false).isEmpty()) {
changed = true; changed = true;
filter.save(); filter.save();
break; break;
@ -105,9 +115,9 @@ public class ItemFilter extends ItemStackHandler {
private boolean isFiltered(ItemStack stack, Direction direction) { private boolean isFiltered(ItemStack stack, Direction direction) {
var types = ItemFilter.getEqualityTypes(this.pipe); var types = ItemFilter.getEqualityTypes(this.pipe);
// also check if any filter increase modules have the item we need // also check if any filter increase modules have the item we need
for (ItemStackHandler handler : this.pipe.getFilters(direction)) { for (ItemFilter handler : this.pipe.getFilters(direction)) {
for (var i = 0; i < handler.getSlots(); i++) { for (var i = 0; i < handler.content.getSlots(); i++) {
var filter = handler.getStackInSlot(i); var filter = handler.content.getStackInSlot(i);
if (filter.isEmpty()) if (filter.isEmpty())
continue; continue;
if (ItemEquality.compareItems(stack, filter, types)) if (ItemEquality.compareItems(stack, filter, types))
@ -119,35 +129,20 @@ public class ItemFilter extends ItemStackHandler {
public void save() { public void save() {
if (this.modified) { if (this.modified) {
this.stack.getOrCreateTag().put("filter", this.serializeNBT()); this.stack.set(Data.TYPE, new Data(this.content, this.isWhitelist));
this.pipe.setChanged(); this.pipe.setChanged();
this.modified = false; this.modified = false;
} }
} }
public void load() { public void load() {
if (this.stack.hasTag()) var content = this.stack.get(Data.TYPE);
this.deserializeNBT(this.stack.getTag().getCompound("filter")); if (content != null) {
} this.content.setSize(content.items.getSlots());
for (var i = 0; i < this.content.getSlots(); i++)
@Override this.content.setStackInSlot(i, content.items.getStackInSlot(i));
public CompoundTag serializeNBT(HolderLookup.Provider provider) { this.isWhitelist = content.whitelist;
var nbt = super.serializeNBT(provider); }
if (this.canModifyWhitelist)
nbt.putBoolean("whitelist", this.isWhitelist);
return nbt;
}
@Override
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
super.deserializeNBT(provider, nbt);
if (this.canModifyWhitelist)
this.isWhitelist = nbt.getBoolean("whitelist");
}
@Override
protected void onContentsChanged(int slot) {
this.modified = true;
} }
public static ItemEquality[] getEqualityTypes(PipeBlockEntity pipe) { public static ItemEquality[] getEqualityTypes(PipeBlockEntity pipe) {
@ -166,4 +161,14 @@ public class ItemFilter extends ItemStackHandler {
} }
public record Data(ItemStackHandler items, boolean whitelist) {
public static final Codec<Data> CODEC = RecordCodecBuilder.create(i -> i.group(
Utility.ITEM_STACK_HANDLER_CODEC.fieldOf("items").forGetter(f -> f.items),
Codec.BOOL.fieldOf("whitelist").forGetter(f -> f.whitelist)
).apply(i, Data::new));
public static final DataComponentType<Data> TYPE = DataComponentType.<Data>builder().persistent(Data.CODEC).cacheEncoding().build();
}
} }

View file

@ -1,5 +1,6 @@
package de.ellpeck.prettypipes.network; package de.ellpeck.prettypipes.network;
import de.ellpeck.prettypipes.Utility;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -45,8 +46,8 @@ public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) { public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
this.pipes.clear(); this.pipes.clear();
var list = nbt.getList("pipes", Tag.TAG_COMPOUND); var list = nbt.getList("pipes", Tag.TAG_COMPOUND);
for (var i = 0; i < list.size(); i++) for (var tag : list)
this.pipes.add(NbtUtils.readBlockPos(list.getCompound(i))); this.pipes.add(Utility.readBlockPos(tag));
} }
} }

View file

@ -275,8 +275,8 @@ public class PipeItem implements IPipeItem {
this.z = nbt.getFloat("z"); this.z = nbt.getFloat("z");
this.path.clear(); this.path.clear();
var list = nbt.getList("path", Tag.TAG_COMPOUND); var list = nbt.getList("path", Tag.TAG_COMPOUND);
for (var i = 0; i < list.size(); i++) for (var tag : list)
this.path.add(NbtUtils.readBlockPos(list.getCompound(i))); this.path.add(Utility.readBlockPos(tag));
} }
@Override @Override
@ -288,9 +288,9 @@ public class PipeItem implements IPipeItem {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void render(PipeBlockEntity tile, PoseStack matrixStack, Random random, float partialTicks, int light, int overlay, MultiBufferSource source) { public void render(PipeBlockEntity tile, PoseStack matrixStack, Random random, float partialTicks, int light, int overlay, MultiBufferSource source) {
matrixStack.translate( matrixStack.translate(
Mth.lerp(partialTicks, this.lastX, this.x), Mth.lerp(partialTicks, this.lastX, this.x),
Mth.lerp(partialTicks, this.lastY, this.y), Mth.lerp(partialTicks, this.lastY, this.y),
Mth.lerp(partialTicks, this.lastZ, this.z)); Mth.lerp(partialTicks, this.lastZ, this.z));
if (this.stack.getItem() instanceof BlockItem) { if (this.stack.getItem() instanceof BlockItem) {
var scale = 0.7F; var scale = 0.7F;
@ -309,9 +309,9 @@ public class PipeItem implements IPipeItem {
matrixStack.pushPose(); matrixStack.pushPose();
if (amount > 1) { if (amount > 1) {
matrixStack.translate( matrixStack.translate(
(random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F,
(random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F, (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F,
(random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F); (random.nextFloat() * 2.0F - 1.0F) * 0.25F * 0.5F);
} }
Minecraft.getInstance().getItemRenderer().renderStatic(this.stack, ItemDisplayContext.GROUND, light, overlay, matrixStack, source, tile.getLevel(), 0); Minecraft.getInstance().getItemRenderer().renderStatic(this.stack, ItemDisplayContext.GROUND, light, overlay, matrixStack, source, tile.getLevel(), 0);
matrixStack.popPose(); matrixStack.popPose();

View file

@ -65,12 +65,12 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
public PipeNetwork(CompoundTag nbt, HolderLookup.Provider provider) { public PipeNetwork(CompoundTag nbt, HolderLookup.Provider provider) {
this(); this();
var nodes = nbt.getList("nodes", Tag.TAG_COMPOUND); var nodes = nbt.getList("nodes", Tag.TAG_COMPOUND);
for (var i = 0; i < nodes.size(); i++) for (var node : nodes)
this.graph.addVertex(NbtUtils.readBlockPos(nodes.getCompound(i))); this.graph.addVertex(Utility.readBlockPos(node));
var edges = nbt.getList("edges", Tag.TAG_COMPOUND); var edges = nbt.getList("edges", Tag.TAG_COMPOUND);
for (var i = 0; i < edges.size(); i++) for (var i = 0; i < edges.size(); i++)
this.addEdge(new NetworkEdge(provider, edges.getCompound(i))); this.addEdge(new NetworkEdge(provider, edges.getCompound(i)));
for (var item : Utility.deserializeAll(nbt.getList("items", Tag.TAG_COMPOUND), IPipeItem::load)) for (var item : Utility.deserializeAll(nbt.getList("items", Tag.TAG_COMPOUND), i -> IPipeItem.load(provider, i)))
this.pipeItems.put(item.getCurrentPipe(), item); this.pipeItems.put(item.getCurrentPipe(), item);
for (var lock : Utility.deserializeAll(nbt.getList("locks", Tag.TAG_COMPOUND), t -> new NetworkLock(provider, t))) for (var lock : Utility.deserializeAll(nbt.getList("locks", Tag.TAG_COMPOUND), t -> new NetworkLock(provider, t)))
this.createNetworkLock(lock); this.createNetworkLock(lock);

View file

@ -92,11 +92,13 @@ public record PacketButton(BlockPos pos, int result, List<Integer> data) impleme
}), }),
STACK_SIZE_MODULE_BUTTON((pos, data, player) -> { STACK_SIZE_MODULE_BUTTON((pos, data, player) -> {
var container = (AbstractPipeContainer<?>) player.containerMenu; var container = (AbstractPipeContainer<?>) player.containerMenu;
StackSizeModuleItem.setLimitToMaxStackSize(container.moduleStack, !StackSizeModuleItem.getLimitToMaxStackSize(container.moduleStack)); var moduleData = container.moduleStack.getOrDefault(StackSizeModuleItem.Data.TYPE, StackSizeModuleItem.Data.DEFAULT);
container.moduleStack.set(StackSizeModuleItem.Data.TYPE, new StackSizeModuleItem.Data(moduleData.maxStackSize(), !moduleData.limitToMaxStackSize()));
}), }),
STACK_SIZE_AMOUNT((pos, data, player) -> { STACK_SIZE_AMOUNT((pos, data, player) -> {
var container = (AbstractPipeContainer<?>) player.containerMenu; var container = (AbstractPipeContainer<?>) player.containerMenu;
StackSizeModuleItem.setMaxStackSize(container.moduleStack, data.getFirst()); var moduleData = container.moduleStack.getOrDefault(StackSizeModuleItem.Data.TYPE, StackSizeModuleItem.Data.DEFAULT);
container.moduleStack.set(StackSizeModuleItem.Data.TYPE, new StackSizeModuleItem.Data(data.getFirst(), moduleData.limitToMaxStackSize()));
}), }),
CRAFT_TERMINAL_REQUEST((pos, data, player) -> { CRAFT_TERMINAL_REQUEST((pos, data, player) -> {
var tile = Utility.getBlockEntity(CraftingTerminalBlockEntity.class, player.level(), pos); var tile = Utility.getBlockEntity(CraftingTerminalBlockEntity.class, player.level(), pos);

View file

@ -31,7 +31,7 @@ public record PacketItemEnterPipe(BlockPos tilePos, CompoundTag item) implements
var mc = Minecraft.getInstance(); var mc = Minecraft.getInstance();
if (mc.level == null) if (mc.level == null)
return; return;
var item = IPipeItem.load(message.item); var item = IPipeItem.load(mc.level.registryAccess(), message.item);
var pipe = Utility.getBlockEntity(PipeBlockEntity.class, mc.level, message.tilePos); var pipe = Utility.getBlockEntity(PipeBlockEntity.class, mc.level, message.tilePos);
if (pipe != null) if (pipe != null)
pipe.getItems().add(item); pipe.getItems().add(item);

View file

@ -12,18 +12,18 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext;
public record PacketRequest(BlockPos pos, ItemStack stack, int nbtHash, int amount) implements CustomPacketPayload { public record PacketRequest(BlockPos pos, ItemStack stack, int componentsHash, int amount) implements CustomPacketPayload {
public static final Type<PacketRequest> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "request")); public static final Type<PacketRequest> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "request"));
public static final StreamCodec<RegistryFriendlyByteBuf, PacketRequest> CODEC = StreamCodec.composite( public static final StreamCodec<RegistryFriendlyByteBuf, PacketRequest> CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, PacketRequest::pos, BlockPos.STREAM_CODEC, PacketRequest::pos,
ItemStack.STREAM_CODEC, PacketRequest::stack, ItemStack.STREAM_CODEC, PacketRequest::stack,
ByteBufCodecs.INT, PacketRequest::nbtHash, ByteBufCodecs.INT, PacketRequest::componentsHash,
ByteBufCodecs.INT, PacketRequest::amount, ByteBufCodecs.INT, PacketRequest::amount,
PacketRequest::new); PacketRequest::new);
public PacketRequest(BlockPos pos, ItemStack stack, int amount) { public PacketRequest(BlockPos pos, ItemStack stack, int amount) {
this(pos, stack, stack.hasTag() ? stack.getTag().hashCode() : 0, amount); this(pos, stack, !stack.isComponentsPatchEmpty() ? stack.getComponents().hashCode() : 0, amount);
} }
@Override @Override
@ -35,7 +35,7 @@ public record PacketRequest(BlockPos pos, ItemStack stack, int nbtHash, int amou
var player = ctx.player(); var player = ctx.player();
var tile = Utility.getBlockEntity(ItemTerminalBlockEntity.class, player.level(), message.pos); var tile = Utility.getBlockEntity(ItemTerminalBlockEntity.class, player.level(), message.pos);
message.stack.setCount(message.amount); message.stack.setCount(message.amount);
tile.requestItem(player, message.stack, message.nbtHash); tile.requestItem(player, message.stack, message.componentsHash);
} }

View file

@ -11,7 +11,7 @@ public class HighPriorityModuleItem extends ModuleItem {
private final int priority; private final int priority;
public HighPriorityModuleItem(String name, ModuleTier tier) { public HighPriorityModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.priority = tier.forTier(50, 100, 200); this.priority = tier.forTier(50, 100, 200);
} }

View file

@ -11,7 +11,7 @@ public class LowPriorityModuleItem extends ModuleItem {
private final int priority; private final int priority;
public LowPriorityModuleItem(String name, ModuleTier tier) { public LowPriorityModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.priority = tier.forTier(-50, -100, -200); this.priority = tier.forTier(-50, -100, -200);
} }

View file

@ -8,7 +8,7 @@ import net.minecraft.world.item.ItemStack;
public class RedstoneModuleItem extends ModuleItem { public class RedstoneModuleItem extends ModuleItem {
public RedstoneModuleItem() { public RedstoneModuleItem() {
super("redstone_module"); super("redstone_module", new Properties());
} }
@Override @Override
@ -25,4 +25,5 @@ public class RedstoneModuleItem extends ModuleItem {
public boolean hasContainer(ItemStack module, PipeBlockEntity tile) { public boolean hasContainer(ItemStack module, PipeBlockEntity tile) {
return false; return false;
} }
} }

View file

@ -1,9 +1,12 @@
package de.ellpeck.prettypipes.pipe.modules; package de.ellpeck.prettypipes.pipe.modules;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import java.util.List; import java.util.List;
@ -13,7 +16,7 @@ public class SortingModuleItem extends ModuleItem {
private final Type type; private final Type type;
public SortingModuleItem(String name, Type type) { public SortingModuleItem(String name, Type type) {
super(name); super(name, new Properties());
this.type = type; this.type = type;
} }
@ -32,8 +35,9 @@ public class SortingModuleItem extends ModuleItem {
switch (this.type) { switch (this.type) {
case ROUND_ROBIN: case ROUND_ROBIN:
// store an ever-increasing index and choose destinations based on that // store an ever-increasing index and choose destinations based on that
var next = module.hasTag() ? module.getTag().getInt("last") + 1 : 0; var prevData = module.get(Data.TYPE);
module.getOrCreateTag().putInt("last", next); var next = prevData != null ? prevData.last + 1 : 0;
module.set(Data.TYPE, new Data(next));
return next % nodes.size(); return next % nodes.size();
case RANDOM: case RANDOM:
return tile.getLevel().random.nextInt(nodes.size()); return tile.getLevel().random.nextInt(nodes.size());
@ -45,4 +49,12 @@ public class SortingModuleItem extends ModuleItem {
ROUND_ROBIN, ROUND_ROBIN,
RANDOM RANDOM
} }
public record Data(int last) {
public static final Codec<Data> CODEC = RecordCodecBuilder.create(i -> i.group(Codec.INT.fieldOf("last").forGetter(f -> f.last)).apply(i, Data::new));
public static final DataComponentType<Data> TYPE = DataComponentType.<Data>builder().persistent(Data.CODEC).cacheEncoding().build();
}
} }

View file

@ -11,7 +11,7 @@ public class SpeedModuleItem extends ModuleItem {
private final float speedIncrease; private final float speedIncrease;
public SpeedModuleItem(String name, ModuleTier tier) { public SpeedModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.speedIncrease = tier.forTier(0.05F, 0.1F, 0.2F); this.speedIncrease = tier.forTier(0.05F, 0.1F, 0.2F);
} }
@ -29,4 +29,5 @@ public class SpeedModuleItem extends ModuleItem {
public float getItemSpeedIncrease(ItemStack module, PipeBlockEntity tile) { public float getItemSpeedIncrease(ItemStack module, PipeBlockEntity tile) {
return this.speedIncrease; return this.speedIncrease;
} }
} }

View file

@ -23,7 +23,7 @@ public class ExtractionModuleItem extends ModuleItem {
public final int filterSlots; public final int filterSlots;
public ExtractionModuleItem(String name, ModuleTier tier) { public ExtractionModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.maxExtraction = tier.forTier(1, 8, 64); this.maxExtraction = tier.forTier(1, 8, 64);
this.speed = tier.forTier(20, 15, 10); this.speed = tier.forTier(20, 15, 10);
this.filterSlots = tier.forTier(3, 6, 9); this.filterSlots = tier.forTier(3, 6, 9);

View file

@ -13,7 +13,7 @@ import net.minecraft.world.item.ItemStack;
public class FilterIncreaseModuleItem extends ModuleItem { public class FilterIncreaseModuleItem extends ModuleItem {
public FilterIncreaseModuleItem() { public FilterIncreaseModuleItem() {
super("filter_increase_modifier"); super("filter_increase_modifier", new Properties());
} }
@Override @Override

View file

@ -14,7 +14,7 @@ public class FilterModuleGui extends AbstractPipeGui<FilterModuleContainer> {
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
var buttonsY = this.topPos + 17 + 32 + 18 * Mth.ceil(this.menu.filter.getSlots() / 9F) + 2; var buttonsY = this.topPos + 17 + 32 + 18 * Mth.ceil(this.menu.filter.content.getSlots() / 9F) + 2;
for (var widget : this.menu.filter.getButtons(this, this.leftPos + this.imageWidth - 7, buttonsY, true)) for (var widget : this.menu.filter.getButtons(this, this.leftPos + this.imageWidth - 7, buttonsY, true))
this.addRenderableWidget(widget); this.addRenderableWidget(widget);
this.addRenderableWidget(this.menu.directionSelector.getButton(this.leftPos + 7, buttonsY)); this.addRenderableWidget(this.menu.directionSelector.getButton(this.leftPos + 7, buttonsY));

View file

@ -20,7 +20,7 @@ public class FilterModuleItem extends ModuleItem {
private final boolean canPopulateFromInventories; private final boolean canPopulateFromInventories;
public FilterModuleItem(String name, ModuleTier tier) { public FilterModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.filterSlots = tier.forTier(5, 9, 18); this.filterSlots = tier.forTier(5, 9, 18);
this.canPopulateFromInventories = tier.forTier(false, false, true); this.canPopulateFromInventories = tier.forTier(false, false, true);
} }

View file

@ -21,8 +21,8 @@ public class FilterModifierModuleContainer extends AbstractPipeContainer<FilterM
public List<ResourceLocation> getTags() { public List<ResourceLocation> getTags() {
Set<ResourceLocation> unsortedTags = new HashSet<>(); Set<ResourceLocation> unsortedTags = new HashSet<>();
for (var filter : this.tile.getFilters(null)) { for (var filter : this.tile.getFilters(null)) {
for (var i = 0; i < filter.getSlots(); i++) { for (var i = 0; i < filter.content.getSlots(); i++) {
var stack = filter.getStackInSlot(i); var stack = filter.content.getStackInSlot(i);
stack.getTags().forEach(t -> unsortedTags.add(t.location())); stack.getTags().forEach(t -> unsortedTags.add(t.location()));
} }
} }

View file

@ -1,12 +1,14 @@
package de.ellpeck.prettypipes.pipe.modules.modifier; package de.ellpeck.prettypipes.pipe.modules.modifier;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEquality; import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import joptsimple.internal.Strings; import net.minecraft.core.component.DataComponentType;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -17,7 +19,7 @@ public class FilterModifierModuleItem extends ModuleItem {
public final ItemEquality.Type type; public final ItemEquality.Type type;
public FilterModifierModuleItem(String name, ItemEquality.Type type) { public FilterModifierModuleItem(String name, ItemEquality.Type type) {
super(name); super(name, new Properties());
this.type = type; this.type = type;
} }
@ -45,15 +47,21 @@ public class FilterModifierModuleItem extends ModuleItem {
} }
public static ResourceLocation getFilterTag(ItemStack stack) { public static ResourceLocation getFilterTag(ItemStack stack) {
if (!stack.hasTag()) var data = stack.get(Data.TYPE);
return null; return data != null && data.filterTag != null ? ResourceLocation.parse(data.filterTag) : null;
var tag = stack.getTag().getString("filter_tag");
if (Strings.isNullOrEmpty(tag))
return null;
return new ResourceLocation(tag);
} }
public static void setFilterTag(ItemStack stack, ResourceLocation tag) { public static void setFilterTag(ItemStack stack, ResourceLocation tag) {
stack.getOrCreateTag().putString("filter_tag", tag.toString()); stack.set(Data.TYPE, new Data(tag.toString()));
} }
public record Data(String filterTag) {
public static final Codec<Data> CODEC = RecordCodecBuilder.create(i -> i.group(
Codec.STRING.fieldOf("filter_tag").forGetter(f -> f.filterTag)
).apply(i, Data::new));
public static final DataComponentType<Data> TYPE = DataComponentType.<Data>builder().persistent(Data.CODEC).cacheEncoding().build();
}
} }

View file

@ -25,7 +25,7 @@ public class RetrievalModuleItem extends ModuleItem {
public final int filterSlots; public final int filterSlots;
public RetrievalModuleItem(String name, ModuleTier tier) { public RetrievalModuleItem(String name, ModuleTier tier) {
super(name); super(name, new Properties());
this.maxExtraction = tier.forTier(1, 8, 16); this.maxExtraction = tier.forTier(1, 8, 16);
this.speed = tier.forTier(40, 20, 10); this.speed = tier.forTier(40, 20, 10);
this.filterSlots = tier.forTier(3, 6, 9); this.filterSlots = tier.forTier(3, 6, 9);
@ -41,8 +41,8 @@ public class RetrievalModuleItem extends ModuleItem {
var equalityTypes = ItemFilter.getEqualityTypes(tile); var equalityTypes = ItemFilter.getEqualityTypes(tile);
// loop through filters to see which items to pull // loop through filters to see which items to pull
Arrays.stream(directions).flatMap(d -> tile.getFilters(d).stream()).distinct().forEach(f -> { Arrays.stream(directions).flatMap(d -> tile.getFilters(d).stream()).distinct().forEach(f -> {
for (var i = 0; i < f.getSlots(); i++) { for (var i = 0; i < f.content.getSlots(); i++) {
var filtered = f.getStackInSlot(i); var filtered = f.content.getStackInSlot(i);
if (filtered.isEmpty()) if (filtered.isEmpty())
continue; continue;
var copy = filtered.copy(); var copy = filtered.copy();

View file

@ -35,7 +35,8 @@ public class StackSizeModuleGui extends AbstractPipeGui<StackSizeModuleContainer
} }
}); });
textField.setValue(String.valueOf(StackSizeModuleItem.getMaxStackSizeForModule(this.menu.moduleStack))); var data = this.menu.moduleStack.getOrDefault(StackSizeModuleItem.Data.TYPE, StackSizeModuleItem.Data.DEFAULT);
textField.setValue(String.valueOf(data.maxStackSize()));
textField.setMaxLength(4); textField.setMaxLength(4);
textField.setResponder(s -> { textField.setResponder(s -> {
if (s.isEmpty()) if (s.isEmpty())
@ -43,7 +44,7 @@ public class StackSizeModuleGui extends AbstractPipeGui<StackSizeModuleContainer
var amount = Integer.parseInt(s); var amount = Integer.parseInt(s);
PacketButton.sendAndExecute(this.menu.tile.getBlockPos(), ButtonResult.STACK_SIZE_AMOUNT, List.of(amount)); PacketButton.sendAndExecute(this.menu.tile.getBlockPos(), ButtonResult.STACK_SIZE_AMOUNT, List.of(amount));
}); });
Supplier<Component> buttonText = () -> Component.translatable("info." + PrettyPipes.ID + ".limit_to_max_" + (StackSizeModuleItem.getLimitToMaxStackSize(this.menu.moduleStack) ? "on" : "off")); Supplier<Component> buttonText = () -> Component.translatable("info." + PrettyPipes.ID + ".limit_to_max_" + (data.limitToMaxStackSize() ? "on" : "off"));
this.addRenderableWidget(Button.builder(buttonText.get(), b -> { this.addRenderableWidget(Button.builder(buttonText.get(), b -> {
PacketButton.sendAndExecute(this.menu.tile.getBlockPos(), ButtonResult.STACK_SIZE_MODULE_BUTTON, List.of()); PacketButton.sendAndExecute(this.menu.tile.getBlockPos(), ButtonResult.STACK_SIZE_MODULE_BUTTON, List.of());
b.setMessage(buttonText.get()); b.setMessage(buttonText.get());

View file

@ -1,5 +1,7 @@
package de.ellpeck.prettypipes.pipe.modules.stacksize; package de.ellpeck.prettypipes.pipe.modules.stacksize;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem; import de.ellpeck.prettypipes.items.ModuleItem;
@ -7,6 +9,7 @@ import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@ -15,37 +18,15 @@ import net.neoforged.neoforge.items.IItemHandler;
public class StackSizeModuleItem extends ModuleItem { public class StackSizeModuleItem extends ModuleItem {
public StackSizeModuleItem() { public StackSizeModuleItem() {
super("stack_size_module"); super("stack_size_module", new Properties());
}
public static int getMaxStackSizeForModule(ItemStack module) {
if (module.hasTag()) {
var amount = module.getTag().getInt("max_stack_size");
if (amount > 0)
return amount;
}
return 64;
}
public static void setMaxStackSize(ItemStack module, int amount) {
module.getOrCreateTag().putInt("max_stack_size", amount);
}
public static boolean getLimitToMaxStackSize(ItemStack module) {
if (module.hasTag())
return module.getTag().getBoolean("limit_to_max_stack_size");
return false;
}
public static void setLimitToMaxStackSize(ItemStack module, boolean yes) {
module.getOrCreateTag().putBoolean("limit_to_max_stack_size", yes);
} }
@Override @Override
public int getMaxInsertionAmount(ItemStack module, PipeBlockEntity tile, ItemStack stack, IItemHandler destination) { public int getMaxInsertionAmount(ItemStack module, PipeBlockEntity tile, ItemStack stack, IItemHandler destination) {
var types = ItemFilter.getEqualityTypes(tile); var types = ItemFilter.getEqualityTypes(tile);
var max = StackSizeModuleItem.getMaxStackSizeForModule(module); var data = module.getOrDefault(Data.TYPE, Data.DEFAULT);
if (StackSizeModuleItem.getLimitToMaxStackSize(module)) var max = data.maxStackSize;
if (data.limitToMaxStackSize)
max = Math.min(max, stack.getMaxStackSize()); max = Math.min(max, stack.getMaxStackSize());
var amount = 0; var amount = 0;
for (var i = 0; i < destination.getSlots(); i++) { for (var i = 0; i < destination.getSlots(); i++) {
@ -76,4 +57,16 @@ public class StackSizeModuleItem extends ModuleItem {
return new StackSizeModuleContainer(Registry.stackSizeModuleContainer, windowId, player, tile.getBlockPos(), moduleIndex); return new StackSizeModuleContainer(Registry.stackSizeModuleContainer, windowId, player, tile.getBlockPos(), moduleIndex);
} }
public record Data(int maxStackSize, boolean limitToMaxStackSize) {
public static final Data DEFAULT = new Data(64, false);
public static final Codec<StackSizeModuleItem.Data> CODEC = RecordCodecBuilder.create(i -> i.group(
Codec.INT.fieldOf("max_stack_size").forGetter(f -> f.maxStackSize),
Codec.BOOL.fieldOf("limit_to_max_stack_size").forGetter(f -> f.limitToMaxStackSize)
).apply(i, StackSizeModuleItem.Data::new));
public static final DataComponentType<StackSizeModuleItem.Data> TYPE = DataComponentType.<StackSizeModuleItem.Data>builder().persistent(StackSizeModuleItem.Data.CODEC).cacheEncoding().build();
}
} }

View file

@ -113,7 +113,7 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity {
network.startProfile("terminal_request_crafting"); network.startProfile("terminal_request_crafting");
this.updateItems(); this.updateItems();
// get the amount of crafts that we can do // get the amount of crafts that we can do
var lowestAvailable = CraftingTerminalBlockEntity.getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> ItemHandlerHelper.copyStackWithSize(this.getRequestedCraftItem(i), 1), this::isGhostItem, s -> { var lowestAvailable = CraftingTerminalBlockEntity.getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> this.getRequestedCraftItem(i).copyWithCount(1), this::isGhostItem, s -> {
var item = this.networkItems.get(s); var item = this.networkItems.get(s);
return item != null ? item.getLocations() : Collections.emptyList(); return item != null ? item.getLocations() : Collections.emptyList();
}, ItemTerminalBlockEntity.onItemUnavailable(player, force), new Stack<>(), ItemEquality.NBT); }, ItemTerminalBlockEntity.onItemUnavailable(player, force), new Stack<>(), ItemEquality.NBT);
@ -173,7 +173,7 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity {
for (var i = 0; i < tile.craftItems.getSlots(); i++) { for (var i = 0; i < tile.craftItems.getSlots(); i++) {
var stack = tile.getRequestedCraftItem(i); var stack = tile.getRequestedCraftItem(i);
var count = tile.isGhostItem(i) ? 0 : stack.getCount(); var count = tile.isGhostItem(i) ? 0 : stack.getCount();
if (!ItemHandlerHelper.canItemStacksStack(stack, remain)) if (!ItemStack.isSameItemSameComponents(stack, remain))
continue; continue;
// ensure that a single non-stackable item can still enter a ghost slot // ensure that a single non-stackable item can still enter a ghost slot
if (!stack.isStackable() && count >= 1) if (!stack.isStackable() && count >= 1)

View file

@ -147,16 +147,16 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
} }
} }
public void requestItem(Player player, ItemStack stack, int nbtHash) { public void requestItem(Player player, ItemStack stack, int componentsHash) {
var network = PipeNetwork.get(this.level); var network = PipeNetwork.get(this.level);
network.startProfile("terminal_request_item"); network.startProfile("terminal_request_item");
this.updateItems(); this.updateItems();
if (nbtHash != 0) { if (componentsHash != 0) {
var filter = stack; var filter = stack;
stack = this.networkItems.values().stream() stack = this.networkItems.values().stream()
.map(NetworkItem::asStack) .map(NetworkItem::asStack)
// don't compare with nbt equality here or the whole hashing thing is pointless // don't compare with nbt equality here or the data hashing thing is pointless
.filter(s -> ItemEquality.compareItems(s, filter) && s.hasTag() && s.getTag().hashCode() == nbtHash) .filter(s -> ItemEquality.compareItems(s, filter) && !s.isComponentsPatchEmpty() && s.getComponents().hashCode() == componentsHash)
.findFirst().orElse(filter); .findFirst().orElse(filter);
stack.setCount(filter.getCount()); stack.setCount(filter.getCount());
} }