some work on components

This commit is contained in:
Ell 2024-09-15 16:24:19 +02:00
parent bc710789c8
commit 3e70470e83
7 changed files with 55 additions and 45 deletions

View file

@ -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

View file

@ -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<ItemStackHandler> 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 extends BlockEntity> T getBlockEntity(Class<T> type, BlockGetter world, BlockPos pos) {
var tile = world.getBlockEntity(pos);
return type.isInstance(tile) ? (T) tile : null;

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -19,9 +19,10 @@ public class CraftingModuleContainer extends AbstractPipeContainer<CraftingModul
@Override
protected void addSlots() {
this.input = this.module.getInput(this.moduleStack);
var contents = this.moduleStack.get(CraftingModuleItem.Contents.TYPE);
this.input = contents.input();
for (var i = 0; i < this.input.getSlots(); i++) {
this.addSlot(new FilterSlot(this.input, i, (176 - this.module.inputSlots * 18) / 2 + 1 + i % 9 * 18, 17 + 32 + i / 9 * 18, false) {
this.addSlot(new FilterSlot(this.input, i, (176 - this.input.getSlots() * 18) / 2 + 1 + i % 9 * 18, 17 + 32 + i / 9 * 18, false) {
@Override
public void setChanged() {
super.setChanged();
@ -31,9 +32,9 @@ public class CraftingModuleContainer extends AbstractPipeContainer<CraftingModul
});
}
this.output = this.module.getOutput(this.moduleStack);
this.output = contents.output();
for (var i = 0; i < this.output.getSlots(); i++) {
this.addSlot(new FilterSlot(this.output, i, (176 - this.module.outputSlots * 18) / 2 + 1 + i % 9 * 18, 85 + i / 9 * 18, false) {
this.addSlot(new FilterSlot(this.output, i, (176 - this.output.getSlots() * 18) / 2 + 1 + i % 9 * 18, 85 + i / 9 * 18, false) {
@Override
public void setChanged() {
super.setChanged();
@ -47,6 +48,7 @@ public class CraftingModuleContainer extends AbstractPipeContainer<CraftingModul
public void removed(Player playerIn) {
super.removed(playerIn);
if (this.modified)
this.module.save(this.input, this.output, this.moduleStack);
this.moduleStack.set(CraftingModuleItem.Contents.TYPE, new CraftingModuleItem.Contents(this.input, this.output));
}
}

View file

@ -1,6 +1,9 @@
package de.ellpeck.prettypipes.pipe.modules.craft;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.items.IModule;
import de.ellpeck.prettypipes.items.ModuleItem;
import de.ellpeck.prettypipes.items.ModuleTier;
@ -14,6 +17,7 @@ import de.ellpeck.prettypipes.terminal.CraftingTerminalBlockEntity;
import de.ellpeck.prettypipes.terminal.ItemTerminalBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
@ -29,14 +33,10 @@ import java.util.function.Consumer;
public class CraftingModuleItem extends ModuleItem {
public final int inputSlots;
public final int outputSlots;
private final int speed;
public CraftingModuleItem(String name, ModuleTier tier) {
super(name);
this.inputSlots = tier.forTier(1, 4, 9);
this.outputSlots = tier.forTier(1, 2, 4);
super(name, new Properties().component(Contents.TYPE, new Contents(new ItemStackHandler(tier.forTier(1, 4, 9)), new ItemStackHandler(tier.forTier(1, 2, 4)))));
this.speed = tier.forTier(20, 10, 5);
}
@ -127,7 +127,7 @@ public class CraftingModuleItem extends ModuleItem {
@Override
public List<ItemStack> getAllCraftables(ItemStack module, PipeBlockEntity tile) {
List<ItemStack> 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<Contents> 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<Contents> TYPE = DataComponentType.<Contents>builder().persistent(Contents.CODEC).cacheEncoding().build();
}
}