mirror of
https://github.com/Ellpeck/PrettyPipes.git
synced 2024-11-24 04:38:33 +01:00
it compiles??
This commit is contained in:
parent
3e70470e83
commit
375f5522f9
28 changed files with 179 additions and 131 deletions
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue