diff --git a/src/main/java/de/ellpeck/prettypipes/Registry.java b/src/main/java/de/ellpeck/prettypipes/Registry.java index 2a49f1a..7de1fcd 100644 --- a/src/main/java/de/ellpeck/prettypipes/Registry.java +++ b/src/main/java/de/ellpeck/prettypipes/Registry.java @@ -4,6 +4,7 @@ import de.ellpeck.prettypipes.entities.PipeFrameEntity; import de.ellpeck.prettypipes.entities.PipeFrameRenderer; import de.ellpeck.prettypipes.items.*; import de.ellpeck.prettypipes.misc.ItemEquality; +import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ModuleClearingRecipe; import de.ellpeck.prettypipes.packets.*; import de.ellpeck.prettypipes.pipe.IPipeConnectable; @@ -81,7 +82,7 @@ import java.util.Comparator; import java.util.Locale; import java.util.function.BiFunction; -import static net.neoforged.fml.common.EventBusSubscriber.*; +import static net.neoforged.fml.common.EventBusSubscriber.Bus; @EventBusSubscriber(bus = Bus.MOD) public final class Registry { @@ -195,6 +196,11 @@ public final class Registry { event.register(Registries.RECIPE_SERIALIZER, h -> { h.register(ResourceLocation.fromNamespaceAndPath(PrettyPipes.ID, "module_clearing"), ModuleClearingRecipe.SERIALIZER); }); + + 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); + }); } @SubscribeEvent diff --git a/src/main/java/de/ellpeck/prettypipes/Utility.java b/src/main/java/de/ellpeck/prettypipes/Utility.java index 857f94a..1c7cd64 100644 --- a/src/main/java/de/ellpeck/prettypipes/Utility.java +++ b/src/main/java/de/ellpeck/prettypipes/Utility.java @@ -1,5 +1,7 @@ package de.ellpeck.prettypipes; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.ChatFormatting; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.resources.language.I18n; @@ -23,6 +25,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.neoforged.neoforge.common.util.INBTSerializable; import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.items.ItemStackHandler; import net.neoforged.neoforge.items.wrapper.SidedInvWrapper; import org.apache.commons.lang3.tuple.Pair; @@ -30,10 +33,21 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.function.Function; +import java.util.stream.IntStream; @SuppressWarnings("ALL") public final class Utility { + public static final Codec ITEM_STACK_HANDLER_CODEC = RecordCodecBuilder.create(builder -> builder.group( + Codec.INT.fieldOf("size").forGetter(h -> h.getSlots()), + Codec.list(ItemStack.CODEC).fieldOf("items").forGetter(h -> IntStream.range(0, h.getSlots()).mapToObj(h::getStackInSlot).toList()) + ).apply(builder, (size, items) -> { + var ret = new ItemStackHandler(size); + for (var i = 0; i < items.size(); i++) + ret.setStackInSlot(i, items.get(i)); + return ret; + })); + public static T getBlockEntity(Class type, BlockGetter world, BlockPos pos) { var tile = world.getBlockEntity(pos); return type.isInstance(tile) ? (T) tile : null; diff --git a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java index 0ffb569..f388a9a 100644 --- a/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java +++ b/src/main/java/de/ellpeck/prettypipes/items/ModuleItem.java @@ -26,8 +26,8 @@ public abstract class ModuleItem extends Item implements IModule { private final String name; - public ModuleItem(String name) { - super(new Properties().stacksTo(16)); + public ModuleItem(String name, Item.Properties properties) { + super(properties.stacksTo(16)); this.name = name; } diff --git a/src/main/java/de/ellpeck/prettypipes/misc/ItemEquality.java b/src/main/java/de/ellpeck/prettypipes/misc/ItemEquality.java index 27f4c2b..eda607a 100644 --- a/src/main/java/de/ellpeck/prettypipes/misc/ItemEquality.java +++ b/src/main/java/de/ellpeck/prettypipes/misc/ItemEquality.java @@ -10,7 +10,7 @@ import java.util.function.Supplier; public class ItemEquality { public static final ItemEquality DAMAGE = new ItemEquality((stack, filter) -> stack.getDamageValue() == filter.getDamageValue(), false, Type.DAMAGE); - public static final ItemEquality NBT = new ItemEquality((stack, filter) -> Objects.equals(stack.getTag(), filter.getTag()) && stack.areAttachmentsCompatible(filter), false, Type.NBT); + public static final ItemEquality NBT = new ItemEquality((stack, filter) -> Objects.equals(stack.getComponents(), filter.getComponents()), false, Type.NBT); public static final ItemEquality MOD = new ItemEquality((stack, filter) -> stack.getItem().getCreatorModId(stack).equals(filter.getItem().getCreatorModId(filter)), true, Type.MOD); public final Type type; diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java index 4211e7a..03d468b 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlockEntity.java @@ -141,7 +141,7 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC this.loadWithComponents(nbt, provider); var items = this.getItems(); items.clear(); - items.addAll(Utility.deserializeAll(nbt.getList("items", Tag.TAG_COMPOUND), IPipeItem::load)); + items.addAll(Utility.deserializeAll(nbt.getList("items", Tag.TAG_COMPOUND), d -> IPipeItem.load(provider, d))); } @Override diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleContainer.java b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleContainer.java index f158abb..369585b 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleContainer.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/modules/craft/CraftingModuleContainer.java @@ -19,9 +19,10 @@ public class CraftingModuleContainer extends AbstractPipeContainer getAllCraftables(ItemStack module, PipeBlockEntity tile) { List ret = new ArrayList<>(); - var output = this.getOutput(module); + var output = module.get(Contents.TYPE).output; for (var i = 0; i < output.getSlots(); i++) { var stack = output.getStackInSlot(i); if (!stack.isEmpty()) @@ -141,15 +141,14 @@ public class CraftingModuleItem extends ModuleItem { var network = PipeNetwork.get(tile.getLevel()); var items = network.getOrderedNetworkItems(tile.getBlockPos()); var equalityTypes = ItemFilter.getEqualityTypes(tile); - var input = this.getInput(module); + var content = module.get(Contents.TYPE); var craftable = 0; - var output = this.getOutput(module); - for (var i = 0; i < output.getSlots(); i++) { - var out = output.getStackInSlot(i); + for (var i = 0; i < content.output.getSlots(); i++) { + var out = content.output.getStackInSlot(i); if (!out.isEmpty() && ItemEquality.compareItems(out, stack, equalityTypes)) { // figure out how many crafting operations we can actually do with the input items we have in the network - var availableCrafts = CraftingTerminalBlockEntity.getAvailableCrafts(tile, input.getSlots(), input::getStackInSlot, k -> true, s -> items, unavailableConsumer, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes); + var availableCrafts = CraftingTerminalBlockEntity.getAvailableCrafts(tile, content.input.getSlots(), content.input::getStackInSlot, k -> true, s -> items, unavailableConsumer, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes); if (availableCrafts > 0) craftable += out.getCount() * availableCrafts; } @@ -174,7 +173,7 @@ public class CraftingModuleItem extends ModuleItem { var craftableCrafts = Mth.ceil(craftableAmount / (float) resultAmount); var toCraft = Math.min(craftableCrafts, requiredCrafts); - var input = this.getInput(module); + var input = module.get(Contents.TYPE).input; for (var i = 0; i < input.getSlots(); i++) { var in = input.getStackInSlot(i); if (in.isEmpty()) @@ -195,30 +194,8 @@ public class CraftingModuleItem extends ModuleItem { return remain; } - public ItemStackHandler getInput(ItemStack module) { - var handler = new ItemStackHandler(this.inputSlots); - if (module.hasTag()) - handler.deserializeNBT(module.getTag().getCompound("input")); - return handler; - } - - public ItemStackHandler getOutput(ItemStack module) { - var handler = new ItemStackHandler(this.outputSlots); - if (module.hasTag()) - handler.deserializeNBT(module.getTag().getCompound("output")); - return handler; - } - - public void save(ItemStackHandler input, ItemStackHandler output, ItemStack module) { - var tag = module.getOrCreateTag(); - if (input != null) - tag.put("input", input.serializeNBT()); - if (output != null) - tag.put("output", output.serializeNBT()); - } - private int getResultAmountPerCraft(ItemStack module, ItemStack stack, ItemEquality... equalityTypes) { - var output = this.getOutput(module); + var output = module.get(Contents.TYPE).output; var resultAmount = 0; for (var i = 0; i < output.getSlots(); i++) { var out = output.getStackInSlot(i); @@ -233,4 +210,15 @@ public class CraftingModuleItem extends ModuleItem { deps.push(module); return deps; } + + public record Contents(ItemStackHandler input, ItemStackHandler output) { + + public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( + Utility.ITEM_STACK_HANDLER_CODEC.fieldOf("input").forGetter(d -> d.input), + Utility.ITEM_STACK_HANDLER_CODEC.fieldOf("output").forGetter(d -> d.output) + ).apply(i, Contents::new)); + public static final DataComponentType TYPE = DataComponentType.builder().persistent(Contents.CODEC).cacheEncoding().build(); + + } + }