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.PipeFrameRenderer;
import de.ellpeck.prettypipes.items.*;
import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.misc.ModuleClearingRecipe;
@ -199,7 +200,11 @@ public final class Registry {
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, "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.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntArrayTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
@ -156,6 +158,15 @@ public final class Utility {
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 {
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 net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component;
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.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.context.UseOnContext;
import java.util.List;
@ -38,10 +40,9 @@ public class PipeFrameItem extends Item {
var world = context.getLevel();
HangingEntity hangingentity = new PipeFrameEntity(Registry.pipeFrameEntity, world, blockpos1, direction);
var compoundTag = itemstack.getTag();
if (compoundTag != null) {
EntityType.updateCustomEntityTag(world, playerentity, hangingentity, compoundTag);
}
var customdata = itemstack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
if (!customdata.isEmpty())
EntityType.updateCustomEntityTag(world, playerentity, hangingentity, customdata);
if (hangingentity.survives()) {
if (!world.isClientSide) {

View file

@ -1,11 +1,13 @@
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.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import net.minecraft.client.gui.components.AbstractWidget;
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.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
@ -66,18 +68,13 @@ public class DirectionSelector {
if (!this.modified)
return;
this.modified = false;
var tag = new CompoundTag();
if (this.direction != null)
tag.putString("direction", this.direction.getName());
this.stack.getOrCreateTag().put("direction_selector", tag);
this.stack.set(Data.TYPE, new Data(this.direction.getName()));
}
public void load() {
if (this.stack.hasTag()) {
var tag = this.stack.getTag().getCompound("direction_selector");
this.direction = Direction.byName(tag.getString("direction"));
}
var data = this.stack.get(Data.TYPE);
if (data != null)
this.direction = Direction.byName(data.direction);
}
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
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;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
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.screens.Screen;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.network.chat.Component;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
@ -24,18 +26,26 @@ import java.util.ArrayList;
import java.util.List;
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 PipeBlockEntity pipe;
public boolean isWhitelist;
public boolean canPopulateFromInventories;
public boolean canModifyWhitelist = true;
private boolean modified;
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.pipe = pipe;
this.load();
@ -43,8 +53,8 @@ public class ItemFilter extends ItemStackHandler {
public List<Slot> getSlots(int x, int y) {
List<Slot> slots = new ArrayList<>();
for (var i = 0; i < this.getSlots(); i++)
slots.add(new FilterSlot(this, i, x + i % 9 * 18, y + i / 9 * 18, true));
for (var i = 0; i < this.content.getSlots(); i++)
slots.add(new FilterSlot(this.content, i, x + i % 9 * 18, y + i / 9 * 18, true));
return slots;
}
@ -85,7 +95,7 @@ public class ItemFilter extends ItemStackHandler {
copy.setCount(1);
// try inserting into ourselves and any filter increase modifiers
for (var filter : filters) {
if (ItemHandlerHelper.insertItem(filter, copy, false).isEmpty()) {
if (ItemHandlerHelper.insertItem(filter.content, copy, false).isEmpty()) {
changed = true;
filter.save();
break;
@ -105,9 +115,9 @@ public class ItemFilter extends ItemStackHandler {
private boolean isFiltered(ItemStack stack, Direction direction) {
var types = ItemFilter.getEqualityTypes(this.pipe);
// also check if any filter increase modules have the item we need
for (ItemStackHandler handler : this.pipe.getFilters(direction)) {
for (var i = 0; i < handler.getSlots(); i++) {
var filter = handler.getStackInSlot(i);
for (ItemFilter handler : this.pipe.getFilters(direction)) {
for (var i = 0; i < handler.content.getSlots(); i++) {
var filter = handler.content.getStackInSlot(i);
if (filter.isEmpty())
continue;
if (ItemEquality.compareItems(stack, filter, types))
@ -119,35 +129,20 @@ public class ItemFilter extends ItemStackHandler {
public void save() {
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.modified = false;
}
}
public void load() {
if (this.stack.hasTag())
this.deserializeNBT(this.stack.getTag().getCompound("filter"));
}
@Override
public CompoundTag serializeNBT(HolderLookup.Provider provider) {
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;
var content = this.stack.get(Data.TYPE);
if (content != null) {
this.content.setSize(content.items.getSlots());
for (var i = 0; i < this.content.getSlots(); i++)
this.content.setStackInSlot(i, content.items.getStackInSlot(i));
this.isWhitelist = content.whitelist;
}
}
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;
import de.ellpeck.prettypipes.Utility;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
@ -45,8 +46,8 @@ public class NetworkEdge extends DefaultWeightedEdge implements INBTSerializable
public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) {
this.pipes.clear();
var list = nbt.getList("pipes", Tag.TAG_COMPOUND);
for (var i = 0; i < list.size(); i++)
this.pipes.add(NbtUtils.readBlockPos(list.getCompound(i)));
for (var tag : list)
this.pipes.add(Utility.readBlockPos(tag));
}
}

View file

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

View file

@ -65,12 +65,12 @@ public class PipeNetwork extends SavedData implements GraphListener<BlockPos, Ne
public PipeNetwork(CompoundTag nbt, HolderLookup.Provider provider) {
this();
var nodes = nbt.getList("nodes", Tag.TAG_COMPOUND);
for (var i = 0; i < nodes.size(); i++)
this.graph.addVertex(NbtUtils.readBlockPos(nodes.getCompound(i)));
for (var node : nodes)
this.graph.addVertex(Utility.readBlockPos(node));
var edges = nbt.getList("edges", Tag.TAG_COMPOUND);
for (var i = 0; i < edges.size(); 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);
for (var lock : Utility.deserializeAll(nbt.getList("locks", Tag.TAG_COMPOUND), t -> new NetworkLock(provider, t)))
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) -> {
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) -> {
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) -> {
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();
if (mc.level == null)
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);
if (pipe != null)
pipe.getItems().add(item);

View file

@ -12,18 +12,18 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
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 StreamCodec<RegistryFriendlyByteBuf, PacketRequest> CODEC = StreamCodec.composite(
BlockPos.STREAM_CODEC, PacketRequest::pos,
ItemStack.STREAM_CODEC, PacketRequest::stack,
ByteBufCodecs.INT, PacketRequest::nbtHash,
ByteBufCodecs.INT, PacketRequest::componentsHash,
ByteBufCodecs.INT, PacketRequest::amount,
PacketRequest::new);
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
@ -35,7 +35,7 @@ public record PacketRequest(BlockPos pos, ItemStack stack, int nbtHash, int amou
var player = ctx.player();
var tile = Utility.getBlockEntity(ItemTerminalBlockEntity.class, player.level(), message.pos);
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;
public HighPriorityModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
this.priority = tier.forTier(50, 100, 200);
}

View file

@ -11,7 +11,7 @@ public class LowPriorityModuleItem extends ModuleItem {
private final int priority;
public LowPriorityModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
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 RedstoneModuleItem() {
super("redstone_module");
super("redstone_module", new Properties());
}
@Override
@ -25,4 +25,5 @@ public class RedstoneModuleItem extends ModuleItem {
public boolean hasContainer(ItemStack module, PipeBlockEntity tile) {
return false;
}
}

View file

@ -1,9 +1,12 @@
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.ModuleItem;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.world.item.ItemStack;
import java.util.List;
@ -13,7 +16,7 @@ public class SortingModuleItem extends ModuleItem {
private final Type type;
public SortingModuleItem(String name, Type type) {
super(name);
super(name, new Properties());
this.type = type;
}
@ -32,8 +35,9 @@ public class SortingModuleItem extends ModuleItem {
switch (this.type) {
case ROUND_ROBIN:
// store an ever-increasing index and choose destinations based on that
var next = module.hasTag() ? module.getTag().getInt("last") + 1 : 0;
module.getOrCreateTag().putInt("last", next);
var prevData = module.get(Data.TYPE);
var next = prevData != null ? prevData.last + 1 : 0;
module.set(Data.TYPE, new Data(next));
return next % nodes.size();
case RANDOM:
return tile.getLevel().random.nextInt(nodes.size());
@ -45,4 +49,12 @@ public class SortingModuleItem extends ModuleItem {
ROUND_ROBIN,
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;
public SpeedModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
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) {
return this.speedIncrease;
}
}

View file

@ -23,7 +23,7 @@ public class ExtractionModuleItem extends ModuleItem {
public final int filterSlots;
public ExtractionModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
this.maxExtraction = tier.forTier(1, 8, 64);
this.speed = tier.forTier(20, 15, 10);
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 FilterIncreaseModuleItem() {
super("filter_increase_modifier");
super("filter_increase_modifier", new Properties());
}
@Override

View file

@ -14,7 +14,7 @@ public class FilterModuleGui extends AbstractPipeGui<FilterModuleContainer> {
@Override
protected void 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))
this.addRenderableWidget(widget);
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;
public FilterModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
this.filterSlots = tier.forTier(5, 9, 18);
this.canPopulateFromInventories = tier.forTier(false, false, true);
}

View file

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

View file

@ -1,12 +1,14 @@
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.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
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.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
@ -17,7 +19,7 @@ public class FilterModifierModuleItem extends ModuleItem {
public final ItemEquality.Type type;
public FilterModifierModuleItem(String name, ItemEquality.Type type) {
super(name);
super(name, new Properties());
this.type = type;
}
@ -45,15 +47,21 @@ public class FilterModifierModuleItem extends ModuleItem {
}
public static ResourceLocation getFilterTag(ItemStack stack) {
if (!stack.hasTag())
return null;
var tag = stack.getTag().getString("filter_tag");
if (Strings.isNullOrEmpty(tag))
return null;
return new ResourceLocation(tag);
var data = stack.get(Data.TYPE);
return data != null && data.filterTag != null ? ResourceLocation.parse(data.filterTag) : null;
}
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 RetrievalModuleItem(String name, ModuleTier tier) {
super(name);
super(name, new Properties());
this.maxExtraction = tier.forTier(1, 8, 16);
this.speed = tier.forTier(40, 20, 10);
this.filterSlots = tier.forTier(3, 6, 9);
@ -41,8 +41,8 @@ public class RetrievalModuleItem extends ModuleItem {
var equalityTypes = ItemFilter.getEqualityTypes(tile);
// loop through filters to see which items to pull
Arrays.stream(directions).flatMap(d -> tile.getFilters(d).stream()).distinct().forEach(f -> {
for (var i = 0; i < f.getSlots(); i++) {
var filtered = f.getStackInSlot(i);
for (var i = 0; i < f.content.getSlots(); i++) {
var filtered = f.content.getStackInSlot(i);
if (filtered.isEmpty())
continue;
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.setResponder(s -> {
if (s.isEmpty())
@ -43,7 +44,7 @@ public class StackSizeModuleGui extends AbstractPipeGui<StackSizeModuleContainer
var amount = Integer.parseInt(s);
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 -> {
PacketButton.sendAndExecute(this.menu.tile.getBlockPos(), ButtonResult.STACK_SIZE_MODULE_BUTTON, List.of());
b.setMessage(buttonText.get());

View file

@ -1,5 +1,7 @@
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.items.IModule;
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.pipe.PipeBlockEntity;
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.Player;
import net.minecraft.world.item.ItemStack;
@ -15,37 +18,15 @@ import net.neoforged.neoforge.items.IItemHandler;
public class StackSizeModuleItem extends ModuleItem {
public StackSizeModuleItem() {
super("stack_size_module");
}
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);
super("stack_size_module", new Properties());
}
@Override
public int getMaxInsertionAmount(ItemStack module, PipeBlockEntity tile, ItemStack stack, IItemHandler destination) {
var types = ItemFilter.getEqualityTypes(tile);
var max = StackSizeModuleItem.getMaxStackSizeForModule(module);
if (StackSizeModuleItem.getLimitToMaxStackSize(module))
var data = module.getOrDefault(Data.TYPE, Data.DEFAULT);
var max = data.maxStackSize;
if (data.limitToMaxStackSize)
max = Math.min(max, stack.getMaxStackSize());
var amount = 0;
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);
}
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");
this.updateItems();
// 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);
return item != null ? item.getLocations() : Collections.emptyList();
}, 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++) {
var stack = tile.getRequestedCraftItem(i);
var count = tile.isGhostItem(i) ? 0 : stack.getCount();
if (!ItemHandlerHelper.canItemStacksStack(stack, remain))
if (!ItemStack.isSameItemSameComponents(stack, remain))
continue;
// ensure that a single non-stackable item can still enter a ghost slot
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);
network.startProfile("terminal_request_item");
this.updateItems();
if (nbtHash != 0) {
if (componentsHash != 0) {
var filter = stack;
stack = this.networkItems.values().stream()
.map(NetworkItem::asStack)
// don't compare with nbt equality here or the whole hashing thing is pointless
.filter(s -> ItemEquality.compareItems(s, filter) && s.hasTag() && s.getTag().hashCode() == nbtHash)
// don't compare with nbt equality here or the data hashing thing is pointless
.filter(s -> ItemEquality.compareItems(s, filter) && !s.isComponentsPatchEmpty() && s.getComponents().hashCode() == componentsHash)
.findFirst().orElse(filter);
stack.setCount(filter.getCount());
}