added direction selector system

This commit is contained in:
Ell 2022-06-30 16:00:33 +02:00
parent 5909820693
commit 3451451c4f
41 changed files with 348 additions and 195 deletions

View file

@ -86,7 +86,7 @@ public final class Registry {
public static final CreativeModeTab TAB = new CreativeModeTab(PrettyPipes.ID) { public static final CreativeModeTab TAB = new CreativeModeTab(PrettyPipes.ID) {
@Override @Override
public ItemStack makeIcon() { public ItemStack makeIcon() {
return new ItemStack(wrenchItem); return new ItemStack(Registry.wrenchItem);
} }
}; };
@ -127,10 +127,10 @@ public final class Registry {
@SubscribeEvent @SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) { public static void registerBlocks(RegistryEvent.Register<Block> event) {
event.getRegistry().registerAll( event.getRegistry().registerAll(
pipeBlock = new PipeBlock().setRegistryName("pipe"), Registry.pipeBlock = new PipeBlock().setRegistryName("pipe"),
itemTerminalBlock = new ItemTerminalBlock().setRegistryName("item_terminal"), Registry.itemTerminalBlock = new ItemTerminalBlock().setRegistryName("item_terminal"),
craftingTerminalBlock = new CraftingTerminalBlock().setRegistryName("crafting_terminal"), Registry.craftingTerminalBlock = new CraftingTerminalBlock().setRegistryName("crafting_terminal"),
pressurizerBlock = new PressurizerBlock().setRegistryName("pressurizer") Registry.pressurizerBlock = new PressurizerBlock().setRegistryName("pressurizer")
); );
} }
@ -138,59 +138,59 @@ public final class Registry {
public static void registerItems(RegistryEvent.Register<Item> event) { public static void registerItems(RegistryEvent.Register<Item> event) {
var registry = event.getRegistry(); var registry = event.getRegistry();
registry.registerAll( registry.registerAll(
wrenchItem = new WrenchItem().setRegistryName("wrench"), Registry.wrenchItem = new WrenchItem().setRegistryName("wrench"),
new Item(new Item.Properties().tab(TAB)).setRegistryName("blank_module"), new Item(new Item.Properties().tab(Registry.TAB)).setRegistryName("blank_module"),
pipeFrameItem = new PipeFrameItem().setRegistryName("pipe_frame") Registry.pipeFrameItem = new PipeFrameItem().setRegistryName("pipe_frame")
); );
registry.registerAll(createTieredModule("extraction_module", ExtractionModuleItem::new)); registry.registerAll(Registry.createTieredModule("extraction_module", ExtractionModuleItem::new));
registry.registerAll(createTieredModule("filter_module", FilterModuleItem::new)); registry.registerAll(Registry.createTieredModule("filter_module", FilterModuleItem::new));
registry.registerAll(createTieredModule("speed_module", SpeedModuleItem::new)); registry.registerAll(Registry.createTieredModule("speed_module", SpeedModuleItem::new));
registry.registerAll(createTieredModule("low_priority_module", LowPriorityModuleItem::new)); registry.registerAll(Registry.createTieredModule("low_priority_module", LowPriorityModuleItem::new));
registry.registerAll(createTieredModule("high_priority_module", HighPriorityModuleItem::new)); registry.registerAll(Registry.createTieredModule("high_priority_module", HighPriorityModuleItem::new));
registry.registerAll(createTieredModule("retrieval_module", RetrievalModuleItem::new)); registry.registerAll(Registry.createTieredModule("retrieval_module", RetrievalModuleItem::new));
registry.register(new StackSizeModuleItem("stack_size_module")); registry.register(new StackSizeModuleItem("stack_size_module"));
registry.registerAll(Arrays.stream(ItemEquality.Type.values()).map(t -> new FilterModifierModuleItem(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new)); registry.registerAll(Arrays.stream(ItemEquality.Type.values()).map(t -> new FilterModifierModuleItem(t.name().toLowerCase(Locale.ROOT) + "_filter_modifier", t)).toArray(Item[]::new));
registry.register(new RedstoneModuleItem("redstone_module")); registry.register(new RedstoneModuleItem("redstone_module"));
registry.register(new FilterIncreaseModuleItem("filter_increase_modifier")); registry.register(new FilterIncreaseModuleItem("filter_increase_modifier"));
registry.registerAll(createTieredModule("crafting_module", CraftingModuleItem::new)); registry.registerAll(Registry.createTieredModule("crafting_module", CraftingModuleItem::new));
registry.registerAll(Arrays.stream(SortingModuleItem.Type.values()).map(t -> new SortingModuleItem(t.name().toLowerCase(Locale.ROOT) + "_sorting_modifier", t)).toArray(Item[]::new)); registry.registerAll(Arrays.stream(SortingModuleItem.Type.values()).map(t -> new SortingModuleItem(t.name().toLowerCase(Locale.ROOT) + "_sorting_modifier", t)).toArray(Item[]::new));
ForgeRegistries.BLOCKS.getValues().stream() ForgeRegistries.BLOCKS.getValues().stream()
.filter(b -> b.getRegistryName().getNamespace().equals(PrettyPipes.ID)) .filter(b -> b.getRegistryName().getNamespace().equals(PrettyPipes.ID))
.forEach(b -> registry.register(new BlockItem(b, new Item.Properties().tab(TAB)).setRegistryName(b.getRegistryName()))); .forEach(b -> registry.register(new BlockItem(b, new Item.Properties().tab(Registry.TAB)).setRegistryName(b.getRegistryName())));
} }
@SubscribeEvent @SubscribeEvent
public static void registerBlockEntities(RegistryEvent.Register<BlockEntityType<?>> event) { public static void registerBlockEntities(RegistryEvent.Register<BlockEntityType<?>> event) {
event.getRegistry().registerAll( event.getRegistry().registerAll(
pipeBlockEntity = (BlockEntityType<PipeBlockEntity>) BlockEntityType.Builder.of(PipeBlockEntity::new, pipeBlock).build(null).setRegistryName("pipe"), Registry.pipeBlockEntity = (BlockEntityType<PipeBlockEntity>) BlockEntityType.Builder.of(PipeBlockEntity::new, Registry.pipeBlock).build(null).setRegistryName("pipe"),
itemTerminalBlockEntity = (BlockEntityType<ItemTerminalBlockEntity>) BlockEntityType.Builder.of(ItemTerminalBlockEntity::new, itemTerminalBlock).build(null).setRegistryName("item_terminal"), Registry.itemTerminalBlockEntity = (BlockEntityType<ItemTerminalBlockEntity>) BlockEntityType.Builder.of(ItemTerminalBlockEntity::new, Registry.itemTerminalBlock).build(null).setRegistryName("item_terminal"),
craftingTerminalBlockEntity = (BlockEntityType<CraftingTerminalBlockEntity>) BlockEntityType.Builder.of(CraftingTerminalBlockEntity::new, craftingTerminalBlock).build(null).setRegistryName("crafting_terminal"), Registry.craftingTerminalBlockEntity = (BlockEntityType<CraftingTerminalBlockEntity>) BlockEntityType.Builder.of(CraftingTerminalBlockEntity::new, Registry.craftingTerminalBlock).build(null).setRegistryName("crafting_terminal"),
pressurizerBlockEntity = (BlockEntityType<PressurizerBlockEntity>) BlockEntityType.Builder.of(PressurizerBlockEntity::new, pressurizerBlock).build(null).setRegistryName("pressurizer") Registry.pressurizerBlockEntity = (BlockEntityType<PressurizerBlockEntity>) BlockEntityType.Builder.of(PressurizerBlockEntity::new, Registry.pressurizerBlock).build(null).setRegistryName("pressurizer")
); );
} }
@SubscribeEvent @SubscribeEvent
public static void registerEntities(RegistryEvent.Register<EntityType<?>> event) { public static void registerEntities(RegistryEvent.Register<EntityType<?>> event) {
event.getRegistry().registerAll( event.getRegistry().registerAll(
pipeFrameEntity = (EntityType<PipeFrameEntity>) EntityType.Builder.<PipeFrameEntity>of(PipeFrameEntity::new, MobCategory.MISC).build("pipe_frame").setRegistryName("pipe_frame") Registry.pipeFrameEntity = (EntityType<PipeFrameEntity>) EntityType.Builder.<PipeFrameEntity>of(PipeFrameEntity::new, MobCategory.MISC).build("pipe_frame").setRegistryName("pipe_frame")
); );
} }
@SubscribeEvent @SubscribeEvent
public static void registerContainers(RegistryEvent.Register<MenuType<?>> event) { public static void registerContainers(RegistryEvent.Register<MenuType<?>> event) {
event.getRegistry().registerAll( event.getRegistry().registerAll(
pipeContainer = (MenuType<MainPipeContainer>) IForgeMenuType.create((windowId, inv, data) -> new MainPipeContainer(pipeContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pipe"), Registry.pipeContainer = (MenuType<MainPipeContainer>) IForgeMenuType.create((windowId, inv, data) -> new MainPipeContainer(Registry.pipeContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pipe"),
itemTerminalContainer = (MenuType<ItemTerminalContainer>) IForgeMenuType.create((windowId, inv, data) -> new ItemTerminalContainer(itemTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("item_terminal"), Registry.itemTerminalContainer = (MenuType<ItemTerminalContainer>) IForgeMenuType.create((windowId, inv, data) -> new ItemTerminalContainer(Registry.itemTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("item_terminal"),
craftingTerminalContainer = (MenuType<CraftingTerminalContainer>) IForgeMenuType.create((windowId, inv, data) -> new CraftingTerminalContainer(craftingTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("crafting_terminal"), Registry.craftingTerminalContainer = (MenuType<CraftingTerminalContainer>) IForgeMenuType.create((windowId, inv, data) -> new CraftingTerminalContainer(Registry.craftingTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("crafting_terminal"),
pressurizerContainer = (MenuType<PressurizerContainer>) IForgeMenuType.create((windowId, inv, data) -> new PressurizerContainer(pressurizerContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pressurizer"), Registry.pressurizerContainer = (MenuType<PressurizerContainer>) IForgeMenuType.create((windowId, inv, data) -> new PressurizerContainer(Registry.pressurizerContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pressurizer"),
extractionModuleContainer = createPipeContainer("extraction_module"), Registry.extractionModuleContainer = Registry.createPipeContainer("extraction_module"),
filterModuleContainer = createPipeContainer("filter_module"), Registry.filterModuleContainer = Registry.createPipeContainer("filter_module"),
retrievalModuleContainer = createPipeContainer("retrieval_module"), Registry.retrievalModuleContainer = Registry.createPipeContainer("retrieval_module"),
stackSizeModuleContainer = createPipeContainer("stack_size_module"), Registry.stackSizeModuleContainer = Registry.createPipeContainer("stack_size_module"),
filterIncreaseModuleContainer = createPipeContainer("filter_increase_module"), Registry.filterIncreaseModuleContainer = Registry.createPipeContainer("filter_increase_module"),
craftingModuleContainer = createPipeContainer("crafting_module"), Registry.craftingModuleContainer = Registry.createPipeContainer("crafting_module"),
filterModifierModuleContainer = createPipeContainer("filter_modifier_module") Registry.filterModifierModuleContainer = Registry.createPipeContainer("filter_modifier_module")
); );
} }
@ -217,21 +217,21 @@ public final class Registry {
public static final class Client { public static final class Client {
public static void setup(FMLClientSetupEvent event) { public static void setup(FMLClientSetupEvent event) {
ItemBlockRenderTypes.setRenderLayer(pipeBlock, RenderType.cutout()); ItemBlockRenderTypes.setRenderLayer(Registry.pipeBlock, RenderType.cutout());
BlockEntityRenderers.register(pipeBlockEntity, PipeRenderer::new); BlockEntityRenderers.register(Registry.pipeBlockEntity, PipeRenderer::new);
EntityRenderers.register(pipeFrameEntity, PipeFrameRenderer::new); EntityRenderers.register(Registry.pipeFrameEntity, PipeFrameRenderer::new);
MenuScreens.register(pipeContainer, MainPipeGui::new); MenuScreens.register(Registry.pipeContainer, MainPipeGui::new);
MenuScreens.register(itemTerminalContainer, ItemTerminalGui::new); MenuScreens.register(Registry.itemTerminalContainer, ItemTerminalGui::new);
MenuScreens.register(pressurizerContainer, PressurizerGui::new); MenuScreens.register(Registry.pressurizerContainer, PressurizerGui::new);
MenuScreens.register(craftingTerminalContainer, CraftingTerminalGui::new); MenuScreens.register(Registry.craftingTerminalContainer, CraftingTerminalGui::new);
MenuScreens.register(extractionModuleContainer, ExtractionModuleGui::new); MenuScreens.register(Registry.extractionModuleContainer, ExtractionModuleGui::new);
MenuScreens.register(filterModuleContainer, FilterModuleGui::new); MenuScreens.register(Registry.filterModuleContainer, FilterModuleGui::new);
MenuScreens.register(retrievalModuleContainer, RetrievalModuleGui::new); MenuScreens.register(Registry.retrievalModuleContainer, RetrievalModuleGui::new);
MenuScreens.register(stackSizeModuleContainer, StackSizeModuleGui::new); MenuScreens.register(Registry.stackSizeModuleContainer, StackSizeModuleGui::new);
MenuScreens.register(filterIncreaseModuleContainer, FilterIncreaseModuleGui::new); MenuScreens.register(Registry.filterIncreaseModuleContainer, FilterIncreaseModuleGui::new);
MenuScreens.register(craftingModuleContainer, CraftingModuleGui::new); MenuScreens.register(Registry.craftingModuleContainer, CraftingModuleGui::new);
MenuScreens.register(filterModifierModuleContainer, FilterModifierModuleGui::new); MenuScreens.register(Registry.filterModifierModuleContainer, FilterModifierModuleGui::new);
} }
} }
} }

View file

@ -42,7 +42,7 @@ public class PipeFrameEntity extends ItemFrame implements IEntityAdditionalSpawn
@Override @Override
protected void defineSynchedData() { protected void defineSynchedData() {
super.defineSynchedData(); super.defineSynchedData();
this.entityData.define(AMOUNT, -1); this.entityData.define(PipeFrameEntity.AMOUNT, -1);
} }
@Override @Override
@ -53,7 +53,7 @@ public class PipeFrameEntity extends ItemFrame implements IEntityAdditionalSpawn
if (this.tickCount % 40 != 0) if (this.tickCount % 40 != 0)
return; return;
var network = PipeNetwork.get(this.level); var network = PipeNetwork.get(this.level);
var attached = getAttachedPipe(this.level, this.pos, this.direction); var attached = PipeFrameEntity.getAttachedPipe(this.level, this.pos, this.direction);
if (attached != null) { if (attached != null) {
var node = network.getNodeFromPipe(attached); var node = network.getNodeFromPipe(attached);
if (node != null) { if (node != null) {
@ -61,17 +61,17 @@ public class PipeFrameEntity extends ItemFrame implements IEntityAdditionalSpawn
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
var items = network.getOrderedNetworkItems(node); var items = network.getOrderedNetworkItems(node);
var amount = items.stream().mapToInt(i -> i.getItemAmount(this.level, stack)).sum(); var amount = items.stream().mapToInt(i -> i.getItemAmount(this.level, stack)).sum();
this.entityData.set(AMOUNT, amount); this.entityData.set(PipeFrameEntity.AMOUNT, amount);
return; return;
} }
} }
} }
this.entityData.set(AMOUNT, -1); this.entityData.set(PipeFrameEntity.AMOUNT, -1);
} }
@Override @Override
public boolean survives() { public boolean survives() {
return super.survives() && canPlace(this.level, this.pos, this.direction); return super.survives() && PipeFrameEntity.canPlace(this.level, this.pos, this.direction);
} }
private static BlockPos getAttachedPipe(Level world, BlockPos pos, Direction direction) { private static BlockPos getAttachedPipe(Level world, BlockPos pos, Direction direction) {
@ -85,11 +85,11 @@ public class PipeFrameEntity extends ItemFrame implements IEntityAdditionalSpawn
} }
public static boolean canPlace(Level world, BlockPos pos, Direction direction) { public static boolean canPlace(Level world, BlockPos pos, Direction direction) {
return getAttachedPipe(world, pos, direction) != null; return PipeFrameEntity.getAttachedPipe(world, pos, direction) != null;
} }
public int getAmount() { public int getAmount() {
return this.entityData.get(AMOUNT); return this.entityData.get(PipeFrameEntity.AMOUNT);
} }
@Override @Override

View file

@ -1,9 +1,11 @@
package de.ellpeck.prettypipes.items; package de.ellpeck.prettypipes.items;
import de.ellpeck.prettypipes.misc.DirectionSelector;
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.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
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;
@ -17,9 +19,9 @@ public interface IModule {
void tick(ItemStack module, PipeBlockEntity tile); void tick(ItemStack module, PipeBlockEntity tile);
boolean canNetworkSee(ItemStack module, PipeBlockEntity tile); boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler);
boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack); boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination);
int getMaxInsertionAmount(ItemStack module, PipeBlockEntity tile, ItemStack stack, IItemHandler destination); int getMaxInsertionAmount(ItemStack module, PipeBlockEntity tile, ItemStack stack, IItemHandler destination);
@ -44,4 +46,6 @@ public interface IModule {
Integer getCustomNextNode(ItemStack module, PipeBlockEntity tile, List<BlockPos> nodes, int index); Integer getCustomNextNode(ItemStack module, PipeBlockEntity tile, List<BlockPos> nodes, int index);
ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile); ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile);
DirectionSelector getDirectionSelector(ItemStack module, PipeBlockEntity tile);
} }

View file

@ -2,10 +2,12 @@ package de.ellpeck.prettypipes.items;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.Utility; import de.ellpeck.prettypipes.Utility;
import de.ellpeck.prettypipes.misc.DirectionSelector;
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.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
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;
@ -45,12 +47,12 @@ public abstract class ModuleItem extends Item implements IModule {
} }
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return true; return true;
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return true; return true;
} }
@ -103,4 +105,9 @@ public abstract class ModuleItem extends Item implements IModule {
public ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile) { public ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile) {
return null; return null;
} }
@Override
public DirectionSelector getDirectionSelector(ItemStack module, PipeBlockEntity tile) {
return null;
}
} }

View file

@ -0,0 +1,104 @@
package de.ellpeck.prettypipes.misc;
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.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.gui.widget.ExtendedButton;
public class DirectionSelector {
public Direction direction;
private boolean modified;
private final ItemStack stack;
private final PipeBlockEntity pipe;
public DirectionSelector(ItemStack stack, PipeBlockEntity pipe) {
this.stack = stack;
this.pipe = pipe;
this.load();
}
@OnlyIn(Dist.CLIENT)
public AbstractWidget getButton(int x, int y) {
return new ExtendedButton(x, y, 100, 20, new TranslatableComponent("info." + PrettyPipes.ID + ".populate"), button ->
PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.DIRECTION_SELECTOR)) {
@Override
public Component getMessage() {
var pipe = DirectionSelector.this.pipe;
var dir = DirectionSelector.this.direction;
MutableComponent msg = new TranslatableComponent("dir." + PrettyPipes.ID + "." + (dir != null ? dir.getName() : "none"));
if (dir != null) {
var blockName = pipe.getItemHandler(dir) != null ? pipe.getLevel().getBlockState(pipe.getBlockPos().relative(dir)).getBlock().getName() : null;
if (blockName != null)
msg = msg.append(" (").append(blockName).append(")");
}
return msg;
}
};
}
public void onButtonPacket() {
var dir = this.getValidDirection(this.direction != null ? this.direction : Direction.UP);
if (this.direction != dir) {
this.direction = dir;
this.modified = true;
}
}
public void save() {
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);
}
public void load() {
if (this.stack.hasTag()) {
var tag = this.stack.getTag().getCompound("direction_selector");
this.direction = Direction.byName(tag.getString("direction"));
}
// default to the first direction with a container
// don't mark as modified here because we don't want to save this automatic direction
if (this.direction == null || !this.isDirectionValid(this.direction))
this.direction = this.getValidDirection(Direction.UP);
}
private boolean isDirectionValid(Direction dir) {
if (this.pipe.getItemHandler(dir) == null)
return false;
return this.pipe.streamModules()
.filter(p -> p.getLeft() != this.stack)
.map(p -> p.getRight().getDirectionSelector(p.getLeft(), this.pipe))
.noneMatch(p -> p != null && p.direction == dir);
}
private Direction getValidDirection(Direction dir) {
for (var i = 0; i < 6; i++) {
dir = Direction.from3DDataValue(dir.get3DDataValue() + 1);
if (this.isDirectionValid(dir))
return dir;
}
return null;
}
public interface IDirectionContainer {
DirectionSelector getSelector();
}
}

View file

@ -48,17 +48,22 @@ public class ItemFilter extends ItemStackHandler {
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public List<AbstractWidget> getButtons(Screen gui, int x, int y) { public List<AbstractWidget> getButtons(Screen gui, int x, int y, boolean rightAligned) {
List<AbstractWidget> buttons = new ArrayList<>(); List<AbstractWidget> buttons = new ArrayList<>();
if (this.canModifyWhitelist) { if (this.canModifyWhitelist) {
var whitelistText = (Supplier<TranslatableComponent>) () -> new TranslatableComponent("info." + PrettyPipes.ID + "." + (this.isWhitelist ? "whitelist" : "blacklist")); var whitelistText = (Supplier<String>) () -> "info." + PrettyPipes.ID + "." + (this.isWhitelist ? "whitelist" : "blacklist");
buttons.add(new Button(x, y, 70, 20, whitelistText.get(), button -> { buttons.add(new Button(x - 20 * (rightAligned ? 1 : 0), y, 20, 20, new TranslatableComponent(whitelistText.get()), button -> {
PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.FILTER_CHANGE, 0); PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.FILTER_CHANGE, 0);
button.setMessage(whitelistText.get()); button.setMessage(new TranslatableComponent(whitelistText.get()));
})); }) {
@Override
public void renderToolTip(PoseStack matrix, int x, int y) {
gui.renderTooltip(matrix, new TranslatableComponent(whitelistText.get() + ".description").withStyle(ChatFormatting.GRAY), x, y);
}
});
} }
if (this.canPopulateFromInventories) { if (this.canPopulateFromInventories) {
buttons.add(new Button(x + 72, y, 70, 20, new TranslatableComponent("info." + PrettyPipes.ID + ".populate"), button -> PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.FILTER_CHANGE, 1)) { buttons.add(new Button(x + 22 * (rightAligned ? -1 : 1), y, 20, 20, new TranslatableComponent("info." + PrettyPipes.ID + ".populate"), button -> PacketButton.sendAndExecute(this.pipe.getBlockPos(), PacketButton.ButtonResult.FILTER_CHANGE, 1)) {
@Override @Override
public void renderToolTip(PoseStack matrix, int x, int y) { public void renderToolTip(PoseStack matrix, int x, int y) {
gui.renderTooltip(matrix, new TranslatableComponent("info." + PrettyPipes.ID + ".populate.description").withStyle(ChatFormatting.GRAY), x, y); gui.renderTooltip(matrix, new TranslatableComponent("info." + PrettyPipes.ID + ".populate.description").withStyle(ChatFormatting.GRAY), x, y);
@ -107,7 +112,7 @@ public class ItemFilter extends ItemStackHandler {
} }
private boolean isFiltered(ItemStack stack) { private boolean isFiltered(ItemStack stack) {
var types = 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()) { for (ItemStackHandler handler : this.pipe.getFilters()) {
for (var i = 0; i < handler.getSlots(); i++) { for (var i = 0; i < handler.getSlots(); i++) {
@ -164,6 +169,7 @@ public class ItemFilter extends ItemStackHandler {
ItemFilter getFilter(); ItemFilter getFilter();
default void onFilterPopulated() {} default void onFilterPopulated() {
}
} }
} }

View file

@ -16,6 +16,6 @@ public enum ItemOrder {
} }
public ItemOrder next() { public ItemOrder next() {
return values()[(this.ordinal() + 1) % values().length]; return ItemOrder.values()[(this.ordinal() + 1) % ItemOrder.values().length];
} }
} }

View file

@ -4,6 +4,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import de.ellpeck.prettypipes.terminal.containers.ItemTerminalGui; import de.ellpeck.prettypipes.terminal.containers.ItemTerminalGui;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
@ -41,7 +42,7 @@ public class ItemTerminalWidget extends AbstractWidget {
this.setBlitOffset(100); this.setBlitOffset(100);
renderer.blitOffset = 100; renderer.blitOffset = 100;
if (this.selected) if (this.selected)
fill(matrix, this.x, this.y, this.x + 16, this.y + 16, -2130706433); GuiComponent.fill(matrix, this.x, this.y, this.x + 16, this.y + 16, -2130706433);
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
renderer.renderGuiItem(this.stack, this.x, this.y); renderer.renderGuiItem(this.stack, this.x, this.y);
var amount = !this.craftable ? this.stack.getCount() : 0; var amount = !this.craftable ? this.stack.getCount() : 0;

View file

@ -20,30 +20,30 @@ public class PlayerPrefs {
public boolean syncJei = true; public boolean syncJei = true;
public void save() { public void save() {
var file = getFile(); var file = PlayerPrefs.getFile();
if (file.exists()) if (file.exists())
file.delete(); file.delete();
try (var writer = new FileWriter(file)) { try (var writer = new FileWriter(file)) {
GSON.toJson(this, writer); PlayerPrefs.GSON.toJson(this, writer);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static PlayerPrefs get() { public static PlayerPrefs get() {
if (instance == null) { if (PlayerPrefs.instance == null) {
var file = getFile(); var file = PlayerPrefs.getFile();
if (file.exists()) { if (file.exists()) {
try (var reader = new FileReader(file)) { try (var reader = new FileReader(file)) {
instance = GSON.fromJson(reader, PlayerPrefs.class); PlayerPrefs.instance = PlayerPrefs.GSON.fromJson(reader, PlayerPrefs.class);
return instance; return PlayerPrefs.instance;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
instance = new PlayerPrefs(); PlayerPrefs.instance = new PlayerPrefs();
} }
return instance; return PlayerPrefs.instance;
} }
private static File getFile() { private static File getFile() {

View file

@ -102,6 +102,6 @@ public class NetworkLocation implements INBTSerializable<CompoundTag> {
@Override @Override
public void deserializeNBT(CompoundTag nbt) { public void deserializeNBT(CompoundTag nbt) {
this.pipePos = NbtUtils.readBlockPos(nbt.getCompound("pipe_pos")); this.pipePos = NbtUtils.readBlockPos(nbt.getCompound("pipe_pos"));
this.direction = Direction.values()[(nbt.getInt("direction"))]; this.direction = Direction.values()[nbt.getInt("direction")];
} }
} }

View file

@ -60,7 +60,7 @@ public class PipeItem implements IPipeItem {
} }
public PipeItem(ItemStack stack, float speed) { public PipeItem(ItemStack stack, float speed) {
this(TYPE, stack, speed); this(PipeItem.TYPE, stack, speed);
} }
public PipeItem(ResourceLocation type, CompoundTag nbt) { public PipeItem(ResourceLocation type, CompoundTag nbt) {
@ -78,7 +78,7 @@ public class PipeItem implements IPipeItem {
public void setDestination(BlockPos startInventory, BlockPos destInventory, GraphPath<BlockPos, NetworkEdge> path) { public void setDestination(BlockPos startInventory, BlockPos destInventory, GraphPath<BlockPos, NetworkEdge> path) {
this.startInventory = startInventory; this.startInventory = startInventory;
this.destInventory = destInventory; this.destInventory = destInventory;
this.path = compilePath(path); this.path = PipeItem.compilePath(path);
this.currGoalPos = this.getStartPipe(); this.currGoalPos = this.getStartPipe();
this.currentTile = 0; this.currentTile = 0;
@ -126,7 +126,7 @@ public class PipeItem implements IPipeItem {
currPipe = next; currPipe = next;
} }
} else { } else {
var dist = (this.currGoalPos).distToLowCornerSqr(this.x - 0.5F, this.y - 0.5F, this.z - 0.5F); var dist = this.currGoalPos.distToLowCornerSqr(this.x - 0.5F, this.y - 0.5F, this.z - 0.5F);
if (dist < currSpeed * currSpeed) { if (dist < currSpeed * currSpeed) {
// we're past the start of the pipe, so move to the center of the next pipe // we're past the start of the pipe, so move to the center of the next pipe
BlockPos nextPos; BlockPos nextPos;

View file

@ -324,11 +324,9 @@ public class PipeNetwork implements ICapabilitySerializable<CompoundTag>, GraphL
if (!this.world.isLoaded(dest)) if (!this.world.isLoaded(dest))
continue; continue;
var pipe = this.getPipe(dest); var pipe = this.getPipe(dest);
if (!pipe.canNetworkSee())
continue;
for (var dir : Direction.values()) { for (var dir : Direction.values()) {
var handler = pipe.getItemHandler(dir); var handler = pipe.getItemHandler(dir);
if (handler == null) if (handler == null || !pipe.canNetworkSee(dir, handler))
continue; continue;
// check if this handler already exists (double-connected pipes, double chests etc.) // check if this handler already exists (double-connected pipes, double chests etc.)
if (info.stream().anyMatch(l -> handler.equals(l.getItemHandler(this.world)))) if (info.stream().anyMatch(l -> handler.equals(l.getItemHandler(this.world))))

View file

@ -26,6 +26,8 @@ import org.apache.logging.log4j.util.TriConsumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Supplier; import java.util.function.Supplier;
import static de.ellpeck.prettypipes.misc.DirectionSelector.IDirectionContainer;
public class PacketButton { public class PacketButton {
private BlockPos pos; private BlockPos pos;
@ -121,6 +123,10 @@ public class PacketButton {
TAG_FILTER((pos, data, player) -> { TAG_FILTER((pos, data, player) -> {
var container = (FilterModifierModuleContainer) player.containerMenu; var container = (FilterModifierModuleContainer) player.containerMenu;
FilterModifierModuleItem.setFilterTag(container.moduleStack, container.getTags().get(data[0])); FilterModifierModuleItem.setFilterTag(container.moduleStack, container.getTags().get(data[0]));
}),
DIRECTION_SELECTOR((pos, data, player) -> {
if (player.containerMenu instanceof IDirectionContainer filtered)
filtered.getSelector().onButtonPacket();
}); });
public final TriConsumer<BlockPos, int[], Player> action; public final TriConsumer<BlockPos, int[], Player> action;

View file

@ -53,8 +53,8 @@ public class PacketCraftingModuleTransfer {
public void run() { public void run() {
Player player = ctx.get().getSender(); Player player = ctx.get().getSender();
if (player.containerMenu instanceof CraftingModuleContainer container) { if (player.containerMenu instanceof CraftingModuleContainer container) {
copy(container.input, message.inputs); PacketCraftingModuleTransfer.copy(container.input, message.inputs);
copy(container.output, message.outputs); PacketCraftingModuleTransfer.copy(container.output, message.outputs);
container.modified = true; container.modified = true;
container.broadcastChanges(); container.broadcastChanges();
} }

View file

@ -93,7 +93,7 @@ public class PacketGhostSlot {
private final TagKey<Item> tag; private final TagKey<Item> tag;
public Entry(List<ItemStack> stacks) { public Entry(List<ItemStack> stacks) {
var tag = getTagForStacks(stacks); var tag = Entry.getTagForStacks(stacks);
if (tag != null) { if (tag != null) {
this.stacks = null; this.stacks = null;
this.tag = tag; this.tag = tag;

View file

@ -16,24 +16,24 @@ public final class PacketHandler {
private static SimpleChannel network; private static SimpleChannel network;
public static void setup() { public static void setup() {
network = NetworkRegistry.newSimpleChannel(new ResourceLocation(PrettyPipes.ID, "network"), () -> VERSION, VERSION::equals, VERSION::equals); PacketHandler.network = NetworkRegistry.newSimpleChannel(new ResourceLocation(PrettyPipes.ID, "network"), () -> PacketHandler.VERSION, PacketHandler.VERSION::equals, PacketHandler.VERSION::equals);
network.registerMessage(0, PacketItemEnterPipe.class, PacketItemEnterPipe::toBytes, PacketItemEnterPipe::fromBytes, PacketItemEnterPipe::onMessage); PacketHandler.network.registerMessage(0, PacketItemEnterPipe.class, PacketItemEnterPipe::toBytes, PacketItemEnterPipe::fromBytes, PacketItemEnterPipe::onMessage);
network.registerMessage(1, PacketButton.class, PacketButton::toBytes, PacketButton::fromBytes, PacketButton::onMessage); PacketHandler.network.registerMessage(1, PacketButton.class, PacketButton::toBytes, PacketButton::fromBytes, PacketButton::onMessage);
network.registerMessage(2, PacketNetworkItems.class, PacketNetworkItems::toBytes, PacketNetworkItems::fromBytes, PacketNetworkItems::onMessage); PacketHandler.network.registerMessage(2, PacketNetworkItems.class, PacketNetworkItems::toBytes, PacketNetworkItems::fromBytes, PacketNetworkItems::onMessage);
network.registerMessage(3, PacketRequest.class, PacketRequest::toBytes, PacketRequest::fromBytes, PacketRequest::onMessage); PacketHandler.network.registerMessage(3, PacketRequest.class, PacketRequest::toBytes, PacketRequest::fromBytes, PacketRequest::onMessage);
network.registerMessage(4, PacketGhostSlot.class, PacketGhostSlot::toBytes, PacketGhostSlot::fromBytes, PacketGhostSlot::onMessage); PacketHandler.network.registerMessage(4, PacketGhostSlot.class, PacketGhostSlot::toBytes, PacketGhostSlot::fromBytes, PacketGhostSlot::onMessage);
network.registerMessage(5, PacketCraftingModuleTransfer.class, PacketCraftingModuleTransfer::toBytes, PacketCraftingModuleTransfer::fromBytes, PacketCraftingModuleTransfer::onMessage); PacketHandler.network.registerMessage(5, PacketCraftingModuleTransfer.class, PacketCraftingModuleTransfer::toBytes, PacketCraftingModuleTransfer::fromBytes, PacketCraftingModuleTransfer::onMessage);
} }
public static void sendToAllLoaded(Level world, BlockPos pos, Object message) { public static void sendToAllLoaded(Level world, BlockPos pos, Object message) {
network.send(PacketDistributor.TRACKING_CHUNK.with(() -> world.getChunkAt(pos)), message); PacketHandler.network.send(PacketDistributor.TRACKING_CHUNK.with(() -> world.getChunkAt(pos)), message);
} }
public static void sendTo(Player player, Object message) { public static void sendTo(Player player, Object message) {
network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), message); PacketHandler.network.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), message);
} }
public static void sendToServer(Object message) { public static void sendToServer(Object message) {
network.send(PacketDistributor.SERVER.noArg(), message); PacketHandler.network.send(PacketDistributor.SERVER.noArg(), message);
} }
} }

View file

@ -46,7 +46,7 @@ public interface IPipeItem extends INBTSerializable<CompoundTag> {
static IPipeItem load(CompoundTag nbt) { static IPipeItem load(CompoundTag nbt) {
var type = new ResourceLocation(nbt.getString("type")); var type = new ResourceLocation(nbt.getString("type"));
var func = TYPES.get(type); var func = IPipeItem.TYPES.get(type);
return func != null ? func.apply(type, nbt) : null; return func != null ? func.apply(type, nbt) : null;
} }
} }

View file

@ -50,26 +50,26 @@ public class PipeBlock extends BaseEntityBlock {
public static final Map<Direction, EnumProperty<ConnectionType>> DIRECTIONS = new HashMap<>(); public static final Map<Direction, EnumProperty<ConnectionType>> DIRECTIONS = new HashMap<>();
private static final Map<Pair<BlockState, BlockState>, VoxelShape> SHAPE_CACHE = new HashMap<>(); private static final Map<Pair<BlockState, BlockState>, VoxelShape> SHAPE_CACHE = new HashMap<>();
private static final Map<Pair<BlockState, BlockState>, VoxelShape> COLL_SHAPE_CACHE = new HashMap<>(); private static final Map<Pair<BlockState, BlockState>, VoxelShape> COLL_SHAPE_CACHE = new HashMap<>();
private static final VoxelShape CENTER_SHAPE = box(5, 5, 5, 11, 11, 11); private static final VoxelShape CENTER_SHAPE = Block.box(5, 5, 5, 11, 11, 11);
public static final Map<Direction, VoxelShape> DIR_SHAPES = ImmutableMap.<Direction, VoxelShape>builder() public static final Map<Direction, VoxelShape> DIR_SHAPES = ImmutableMap.<Direction, VoxelShape>builder()
.put(Direction.UP, box(5, 10, 5, 11, 16, 11)) .put(Direction.UP, Block.box(5, 10, 5, 11, 16, 11))
.put(Direction.DOWN, box(5, 0, 5, 11, 6, 11)) .put(Direction.DOWN, Block.box(5, 0, 5, 11, 6, 11))
.put(Direction.NORTH, box(5, 5, 0, 11, 11, 6)) .put(Direction.NORTH, Block.box(5, 5, 0, 11, 11, 6))
.put(Direction.SOUTH, box(5, 5, 10, 11, 11, 16)) .put(Direction.SOUTH, Block.box(5, 5, 10, 11, 11, 16))
.put(Direction.EAST, box(10, 5, 5, 16, 11, 11)) .put(Direction.EAST, Block.box(10, 5, 5, 16, 11, 11))
.put(Direction.WEST, box(0, 5, 5, 6, 11, 11)) .put(Direction.WEST, Block.box(0, 5, 5, 6, 11, 11))
.build(); .build();
static { static {
for (var dir : Direction.values()) for (var dir : Direction.values())
DIRECTIONS.put(dir, EnumProperty.create(dir.getName(), ConnectionType.class)); PipeBlock.DIRECTIONS.put(dir, EnumProperty.create(dir.getName(), ConnectionType.class));
} }
public PipeBlock() { public PipeBlock() {
super(Block.Properties.of(Material.STONE).strength(2).sound(SoundType.STONE).noOcclusion()); super(Block.Properties.of(Material.STONE).strength(2).sound(SoundType.STONE).noOcclusion());
var state = this.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, false); var state = this.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, false);
for (var prop : DIRECTIONS.values()) for (var prop : PipeBlock.DIRECTIONS.values())
state = state.setValue(prop, ConnectionType.DISCONNECTED); state = state.setValue(prop, ConnectionType.DISCONNECTED);
this.registerDefaultState(state); this.registerDefaultState(state);
} }
@ -100,7 +100,7 @@ public class PipeBlock extends BaseEntityBlock {
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(DIRECTIONS.values().toArray(new EnumProperty[0])); builder.add(PipeBlock.DIRECTIONS.values().toArray(new EnumProperty[0]));
builder.add(BlockStateProperties.WATERLOGGED); builder.add(BlockStateProperties.WATERLOGGED);
} }
@ -114,7 +114,7 @@ public class PipeBlock extends BaseEntityBlock {
var newState = this.createState(worldIn, pos, state); var newState = this.createState(worldIn, pos, state);
if (newState != state) { if (newState != state) {
worldIn.setBlockAndUpdate(pos, newState); worldIn.setBlockAndUpdate(pos, newState);
onStateChanged(worldIn, pos, newState); PipeBlock.onStateChanged(worldIn, pos, newState);
} }
} }
@ -133,17 +133,17 @@ public class PipeBlock extends BaseEntityBlock {
@Override @Override
public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
onStateChanged(worldIn, pos, state); PipeBlock.onStateChanged(worldIn, pos, state);
} }
@Override @Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return this.cacheAndGetShape(state, worldIn, pos, s -> s.getShape(worldIn, pos, context), SHAPE_CACHE, null); return this.cacheAndGetShape(state, worldIn, pos, s -> s.getShape(worldIn, pos, context), PipeBlock.SHAPE_CACHE, null);
} }
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { public VoxelShape getCollisionShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return this.cacheAndGetShape(state, worldIn, pos, s -> s.getCollisionShape(worldIn, pos, context), COLL_SHAPE_CACHE, s -> { return this.cacheAndGetShape(state, worldIn, pos, s -> s.getCollisionShape(worldIn, pos, context), PipeBlock.COLL_SHAPE_CACHE, s -> {
// make the shape a bit higher so we can jump up onto a higher block // make the shape a bit higher so we can jump up onto a higher block
var newShape = new MutableObject<VoxelShape>(Shapes.empty()); var newShape = new MutableObject<VoxelShape>(Shapes.empty());
s.forAllBoxes((x1, y1, z1, x2, y2, z2) -> newShape.setValue(Shapes.join(Shapes.create(x1, y1, z1, x2, y2 + 3 / 16F, z2), newShape.getValue(), BooleanOp.OR))); s.forAllBoxes((x1, y1, z1, x2, y2, z2) -> newShape.setValue(Shapes.join(Shapes.create(x1, y1, z1, x2, y2 + 3 / 16F, z2), newShape.getValue(), BooleanOp.OR)));
@ -166,10 +166,10 @@ public class PipeBlock extends BaseEntityBlock {
var key = Pair.of(state, cover); var key = Pair.of(state, cover);
var shape = cache.get(key); var shape = cache.get(key);
if (shape == null) { if (shape == null) {
shape = CENTER_SHAPE; shape = PipeBlock.CENTER_SHAPE;
for (var entry : DIRECTIONS.entrySet()) { for (var entry : PipeBlock.DIRECTIONS.entrySet()) {
if (state.getValue(entry.getValue()).isConnected()) if (state.getValue(entry.getValue()).isConnected())
shape = Shapes.or(shape, DIR_SHAPES.get(entry.getKey())); shape = Shapes.or(shape, PipeBlock.DIR_SHAPES.get(entry.getKey()));
} }
if (shapeModifier != null) if (shapeModifier != null)
shape = shapeModifier.apply(shape); shape = shapeModifier.apply(shape);
@ -187,7 +187,7 @@ public class PipeBlock extends BaseEntityBlock {
state = state.setValue(BlockStateProperties.WATERLOGGED, true); state = state.setValue(BlockStateProperties.WATERLOGGED, true);
for (var dir : Direction.values()) { for (var dir : Direction.values()) {
var prop = DIRECTIONS.get(dir); var prop = PipeBlock.DIRECTIONS.get(dir);
var type = this.getConnectionType(world, pos, dir, state); var type = this.getConnectionType(world, pos, dir, state);
// don't reconnect on blocked faces // don't reconnect on blocked faces
if (type.isConnected() && curr.getValue(prop) == ConnectionType.BLOCKED) if (type.isConnected() && curr.getValue(prop) == ConnectionType.BLOCKED)
@ -215,8 +215,8 @@ public class PipeBlock extends BaseEntityBlock {
if (blockHandler != null) if (blockHandler != null)
return ConnectionType.CONNECTED; return ConnectionType.CONNECTED;
var offState = world.getBlockState(offset); var offState = world.getBlockState(offset);
if (hasLegsTo(world, offState, offset, direction)) { if (PipeBlock.hasLegsTo(world, offState, offset, direction)) {
if (DIRECTIONS.values().stream().noneMatch(d -> state.getValue(d) == ConnectionType.LEGS)) if (PipeBlock.DIRECTIONS.values().stream().noneMatch(d -> state.getValue(d) == ConnectionType.LEGS))
return ConnectionType.LEGS; return ConnectionType.LEGS;
} }
return ConnectionType.DISCONNECTED; return ConnectionType.DISCONNECTED;
@ -226,7 +226,7 @@ public class PipeBlock extends BaseEntityBlock {
if (state.getBlock() instanceof WallBlock || state.getBlock() instanceof FenceBlock) if (state.getBlock() instanceof WallBlock || state.getBlock() instanceof FenceBlock)
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (state.getMaterial() == Material.STONE || state.getMaterial() == Material.METAL) if (state.getMaterial() == Material.STONE || state.getMaterial() == Material.METAL)
return canSupportCenter(world, pos, direction.getOpposite()); return Block.canSupportCenter(world, pos, direction.getOpposite());
return false; return false;
} }
@ -240,7 +240,7 @@ public class PipeBlock extends BaseEntityBlock {
var connections = 0; var connections = 0;
var force = false; var force = false;
for (var dir : Direction.values()) { for (var dir : Direction.values()) {
var value = newState.getValue(DIRECTIONS.get(dir)); var value = newState.getValue(PipeBlock.DIRECTIONS.get(dir));
if (!value.isConnected()) if (!value.isConnected())
continue; continue;
connections++; connections++;
@ -271,7 +271,7 @@ public class PipeBlock extends BaseEntityBlock {
@Override @Override
public void playerWillDestroy(Level worldIn, BlockPos pos, BlockState state, Player player) { public void playerWillDestroy(Level worldIn, BlockPos pos, BlockState state, Player player) {
dropItems(worldIn, pos, player); PipeBlock.dropItems(worldIn, pos, player);
super.playerWillDestroy(worldIn, pos, state, player); super.playerWillDestroy(worldIn, pos, state, player);
} }
@ -302,7 +302,7 @@ public class PipeBlock extends BaseEntityBlock {
@org.jetbrains.annotations.Nullable @org.jetbrains.annotations.Nullable
@Override @Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return createTickerHelper(type, Registry.pipeBlockEntity, PipeBlockEntity::tick); return BaseEntityBlock.createTickerHelper(type, Registry.pipeBlockEntity, PipeBlockEntity::tick);
} }
public static void dropItems(Level worldIn, BlockPos pos, Player player) { public static void dropItems(Level worldIn, BlockPos pos, Player player) {

View file

@ -188,11 +188,9 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
public Pair<BlockPos, ItemStack> getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) { public Pair<BlockPos, ItemStack> getAvailableDestination(ItemStack stack, boolean force, boolean preventOversending) {
if (!this.canWork()) if (!this.canWork())
return null; return null;
if (!force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack)))
return null;
for (var dir : Direction.values()) { for (var dir : Direction.values()) {
var handler = this.getItemHandler(dir); var handler = this.getItemHandler(dir);
if (handler == null) if (handler == null || !force && this.streamModules().anyMatch(m -> !m.getRight().canAcceptItem(m.getLeft(), this, stack, dir, handler)))
continue; continue;
var remain = ItemHandlerHelper.insertItem(handler, stack, true); var remain = ItemHandlerHelper.insertItem(handler, stack, true);
// did we insert anything? // did we insert anything?
@ -315,13 +313,9 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
return null; return null;
} }
public boolean isConnectedInventory(Direction dir) {
return this.getItemHandler(dir) != null;
}
public boolean canHaveModules() { public boolean canHaveModules() {
for (var dir : Direction.values()) { for (var dir : Direction.values()) {
if (this.isConnectedInventory(dir)) if (this.getItemHandler(dir) != null)
return true; return true;
var connectable = this.getPipeConnectable(dir); var connectable = this.getPipeConnectable(dir);
if (connectable != null && connectable.allowsModules(this.worldPosition, dir)) if (connectable != null && connectable.allowsModules(this.worldPosition, dir))
@ -330,8 +324,8 @@ public class PipeBlockEntity extends BlockEntity implements MenuProvider, IPipeC
return false; return false;
} }
public boolean canNetworkSee() { public boolean canNetworkSee(Direction direction, IItemHandler handler) {
return this.streamModules().allMatch(m -> m.getRight().canNetworkSee(m.getLeft(), this)); return this.streamModules().allMatch(m -> m.getRight().canNetworkSee(m.getLeft(), this, direction, handler));
} }
public Stream<Pair<ItemStack, IModule>> streamModules() { public Stream<Pair<ItemStack, IModule>> streamModules() {

View file

@ -79,7 +79,7 @@ public abstract class AbstractPipeGui<T extends AbstractPipeContainer<?>> extend
@Override @Override
protected void renderBg(PoseStack matrix, float partialTicks, int mouseX, int mouseY) { protected void renderBg(PoseStack matrix, float partialTicks, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, AbstractPipeGui.TEXTURE);
this.blit(matrix, this.leftPos, this.topPos + 32, 0, 0, 176, 171); this.blit(matrix, this.leftPos, this.topPos + 32, 0, 0, 176, 171);
for (var tab : this.tabs) for (var tab : this.tabs)
@ -143,7 +143,7 @@ public abstract class AbstractPipeGui<T extends AbstractPipeContainer<?>> extend
AbstractPipeGui.this.itemRenderer.renderGuiItem(this.moduleStack, this.x + 6, this.y + itemOffset); AbstractPipeGui.this.itemRenderer.renderGuiItem(this.moduleStack, this.x + 6, this.y + itemOffset);
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, AbstractPipeGui.TEXTURE);
} }
private void drawForeground(PoseStack matrix, int mouseX, int mouseY) { private void drawForeground(PoseStack matrix, int mouseX, int mouseY) {

View file

@ -17,7 +17,7 @@ public class CraftingModuleGui extends AbstractPipeGui<CraftingModuleContainer>
protected void renderBg(PoseStack matrix, float partialTicks, int mouseX, int mouseY) { protected void renderBg(PoseStack matrix, float partialTicks, int mouseX, int mouseY) {
super.renderBg(matrix, partialTicks, mouseX, mouseY); super.renderBg(matrix, partialTicks, mouseX, mouseY);
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, AbstractPipeGui.TEXTURE);
this.blit(matrix, this.leftPos + 176 / 2 - 16 / 2, this.topPos + 32 + 18 * 2, 176, 80, 16, 16); this.blit(matrix, this.leftPos + 176 / 2 - 16 / 2, this.topPos + 32 + 18 * 2, 176, 80, 16, 16);
} }
} }

View file

@ -13,10 +13,12 @@ import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
import de.ellpeck.prettypipes.terminal.CraftingTerminalBlockEntity; import de.ellpeck.prettypipes.terminal.CraftingTerminalBlockEntity;
import de.ellpeck.prettypipes.terminal.ItemTerminalBlockEntity; import de.ellpeck.prettypipes.terminal.ItemTerminalBlockEntity;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
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;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
@ -54,12 +56,12 @@ public class CraftingModuleItem extends ModuleItem {
} }
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return false; return false;
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return false; return false;
} }
@ -147,7 +149,7 @@ public class CraftingModuleItem extends ModuleItem {
var out = output.getStackInSlot(i); var out = output.getStackInSlot(i);
if (!out.isEmpty() && ItemEquality.compareItems(out, stack, equalityTypes)) { 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 // 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, addDependency(dependencyChain, module), equalityTypes); var availableCrafts = CraftingTerminalBlockEntity.getAvailableCrafts(tile, input.getSlots(), input::getStackInSlot, k -> true, s -> items, unavailableConsumer, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes);
if (availableCrafts > 0) if (availableCrafts > 0)
craftable += out.getCount() * availableCrafts; craftable += out.getCount() * availableCrafts;
} }
@ -179,7 +181,7 @@ public class CraftingModuleItem extends ModuleItem {
continue; continue;
var copy = in.copy(); var copy = in.copy();
copy.setCount(in.getCount() * toCraft); copy.setCount(in.getCount() * toCraft);
var ret = ItemTerminalBlockEntity.requestItemLater(tile.getLevel(), tile.getBlockPos(), items, unavailableConsumer, copy, addDependency(dependencyChain, module), equalityTypes); var ret = ItemTerminalBlockEntity.requestItemLater(tile.getLevel(), tile.getBlockPos(), items, unavailableConsumer, copy, CraftingModuleItem.addDependency(dependencyChain, module), equalityTypes);
tile.craftIngredientRequests.addAll(ret.getLeft()); tile.craftIngredientRequests.addAll(ret.getLeft());
} }

View file

@ -1,5 +1,7 @@
package de.ellpeck.prettypipes.pipe.modules.extraction; package de.ellpeck.prettypipes.pipe.modules.extraction;
import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.DirectionSelector.IDirectionContainer;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer; import de.ellpeck.prettypipes.misc.ItemFilter.IFilteredContainer;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeContainer;
@ -9,9 +11,10 @@ import net.minecraft.world.inventory.MenuType;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class ExtractionModuleContainer extends AbstractPipeContainer<ExtractionModuleItem> implements IFilteredContainer { public class ExtractionModuleContainer extends AbstractPipeContainer<ExtractionModuleItem> implements IFilteredContainer, IDirectionContainer {
public ItemFilter filter; public ItemFilter filter;
public DirectionSelector directionSelector;
public ExtractionModuleContainer(@Nullable MenuType<?> type, int id, Player player, BlockPos pos, int moduleIndex) { public ExtractionModuleContainer(@Nullable MenuType<?> type, int id, Player player, BlockPos pos, int moduleIndex) {
super(type, id, player, pos, moduleIndex); super(type, id, player, pos, moduleIndex);
@ -20,6 +23,8 @@ public class ExtractionModuleContainer extends AbstractPipeContainer<ExtractionM
@Override @Override
protected void addSlots() { protected void addSlots() {
this.filter = this.module.getItemFilter(this.moduleStack, this.tile); this.filter = this.module.getItemFilter(this.moduleStack, this.tile);
this.directionSelector = this.module.getDirectionSelector(this.moduleStack, this.tile);
for (var slot : this.filter.getSlots((176 - this.module.filterSlots * 18) / 2 + 1, 17 + 32)) for (var slot : this.filter.getSlots((176 - this.module.filterSlots * 18) / 2 + 1, 17 + 32))
this.addSlot(slot); this.addSlot(slot);
} }
@ -28,10 +33,16 @@ public class ExtractionModuleContainer extends AbstractPipeContainer<ExtractionM
public void removed(Player playerIn) { public void removed(Player playerIn) {
super.removed(playerIn); super.removed(playerIn);
this.filter.save(); this.filter.save();
this.directionSelector.save();
} }
@Override @Override
public ItemFilter getFilter() { public ItemFilter getFilter() {
return this.filter; return this.filter;
} }
@Override
public DirectionSelector getSelector() {
return this.directionSelector;
}
} }

View file

@ -13,7 +13,8 @@ public class ExtractionModuleGui extends AbstractPipeGui<ExtractionModuleContain
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
for (var widget : this.menu.filter.getButtons(this, this.leftPos + 7, this.topPos + 17 + 32 + 20)) for (var widget : this.menu.filter.getButtons(this, this.leftPos + this.imageWidth - 7, this.topPos + 17 + 32 + 20, true))
this.addRenderableWidget(widget); this.addRenderableWidget(widget);
this.addRenderableWidget(this.menu.directionSelector.getButton(this.leftPos + 7, this.topPos + 17 + 32 + 20));
} }
} }

View file

@ -4,6 +4,7 @@ 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.items.ModuleTier; import de.ellpeck.prettypipes.items.ModuleTier;
import de.ellpeck.prettypipes.misc.DirectionSelector;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
import de.ellpeck.prettypipes.pipe.PipeBlockEntity; import de.ellpeck.prettypipes.pipe.PipeBlockEntity;
@ -12,6 +13,7 @@ import net.minecraft.core.Direction;
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;
import net.minecraftforge.items.IItemHandler;
public class ExtractionModuleItem extends ModuleItem { public class ExtractionModuleItem extends ModuleItem {
@ -33,35 +35,36 @@ public class ExtractionModuleItem extends ModuleItem {
if (!tile.shouldWorkNow(this.speed) || !tile.canWork()) if (!tile.shouldWorkNow(this.speed) || !tile.canWork())
return; return;
var filter = this.getItemFilter(module, tile); var filter = this.getItemFilter(module, tile);
var dirSelector = this.getDirectionSelector(module, tile);
if (dirSelector.direction == null)
return;
var handler = tile.getItemHandler(dirSelector.direction);
if (handler == null)
return;
var network = PipeNetwork.get(tile.getLevel()); var network = PipeNetwork.get(tile.getLevel());
for (var dir : Direction.values()) { for (var j = 0; j < handler.getSlots(); j++) {
var handler = tile.getItemHandler(dir); var stack = handler.extractItem(j, this.maxExtraction, true);
if (handler == null) if (stack.isEmpty())
continue; continue;
for (var j = 0; j < handler.getSlots(); j++) { if (!filter.isAllowed(stack))
var stack = handler.extractItem(j, this.maxExtraction, true); continue;
if (stack.isEmpty()) var remain = network.routeItem(tile.getBlockPos(), tile.getBlockPos().relative(dirSelector.direction), stack, this.preventOversending);
continue; if (remain.getCount() != stack.getCount()) {
if (!filter.isAllowed(stack)) handler.extractItem(j, stack.getCount() - remain.getCount(), false);
continue; return;
var remain = network.routeItem(tile.getBlockPos(), tile.getBlockPos().relative(dir), stack, this.preventOversending);
if (remain.getCount() != stack.getCount()) {
handler.extractItem(j, stack.getCount() - remain.getCount(), false);
return;
}
} }
} }
} }
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return false; return direction != this.getDirectionSelector(module, tile).direction;
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return false; return direction != this.getDirectionSelector(module, tile).direction;
} }
@Override @Override
@ -83,4 +86,9 @@ public class ExtractionModuleItem extends ModuleItem {
public ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile) { public ItemFilter getItemFilter(ItemStack module, PipeBlockEntity tile) {
return new ItemFilter(this.filterSlots, module, tile); return new ItemFilter(this.filterSlots, module, tile);
} }
@Override
public DirectionSelector getDirectionSelector(ItemStack module, PipeBlockEntity tile) {
return new DirectionSelector(module, tile);
}
} }

View file

@ -1,7 +1,6 @@
package de.ellpeck.prettypipes.pipe.modules.insertion; package de.ellpeck.prettypipes.pipe.modules.insertion;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeGui; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeGui;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
@ -15,7 +14,7 @@ public class FilterModuleGui extends AbstractPipeGui<FilterModuleContainer> {
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
for (var widget : this.menu.filter.getButtons(this, this.leftPos + 7, this.topPos + 17 + 32 + 18 * Mth.ceil(this.menu.filter.getSlots() / 9F) + 2)) for (var widget : this.menu.filter.getButtons(this, this.leftPos + 7, this.topPos + 17 + 32 + 18 * Mth.ceil(this.menu.filter.getSlots() / 9F) + 2, false))
this.addRenderableWidget(widget); this.addRenderableWidget(widget);
} }
} }

View file

@ -7,9 +7,11 @@ import de.ellpeck.prettypipes.items.ModuleTier;
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.Direction;
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;
import net.minecraftforge.items.IItemHandler;
public class FilterModuleItem extends ModuleItem { public class FilterModuleItem extends ModuleItem {
@ -23,7 +25,7 @@ public class FilterModuleItem extends ModuleItem {
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
var filter = this.getItemFilter(module, tile); var filter = this.getItemFilter(module, tile);
return filter.isAllowed(stack); return filter.isAllowed(stack);
} }

View file

@ -126,7 +126,7 @@ public class FilterModifierModuleGui extends AbstractPipeGui<FilterModifierModul
text = ChatFormatting.BOLD + text; text = ChatFormatting.BOLD + text;
FilterModifierModuleGui.this.font.draw(matrix, text, this.x, this.y, color); FilterModifierModuleGui.this.font.draw(matrix, text, this.x, this.y, color);
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, AbstractPipeGui.TEXTURE);
} }
private boolean onClicked(double mouseX, double mouseY, int button) { private boolean onClicked(double mouseX, double mouseY, int button) {

View file

@ -39,7 +39,7 @@ public class FilterModifierModuleItem extends ModuleItem {
public ItemEquality getEqualityType(ItemStack stack) { public ItemEquality getEqualityType(ItemStack stack) {
if (this.type == ItemEquality.Type.TAG) { if (this.type == ItemEquality.Type.TAG) {
return ItemEquality.tag(getFilterTag(stack)); return ItemEquality.tag(FilterModifierModuleItem.getFilterTag(stack));
} else { } else {
return this.type.getDefaultInstance(); return this.type.getDefaultInstance();
} }

View file

@ -1,7 +1,6 @@
package de.ellpeck.prettypipes.pipe.modules.retrieval; package de.ellpeck.prettypipes.pipe.modules.retrieval;
import de.ellpeck.prettypipes.pipe.containers.AbstractPipeGui; import de.ellpeck.prettypipes.pipe.containers.AbstractPipeGui;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Inventory;
@ -14,7 +13,7 @@ public class RetrievalModuleGui extends AbstractPipeGui<RetrievalModuleContainer
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
for (var widget : this.menu.filter.getButtons(this, this.leftPos + 7, this.topPos + 17 + 32 + 20)) for (var widget : this.menu.filter.getButtons(this, this.leftPos + 7, this.topPos + 17 + 32 + 20, false))
this.addRenderableWidget(widget); this.addRenderableWidget(widget);
} }
} }

View file

@ -4,16 +4,15 @@ 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.items.ModuleTier; import de.ellpeck.prettypipes.items.ModuleTier;
import de.ellpeck.prettypipes.misc.ItemEquality;
import de.ellpeck.prettypipes.misc.ItemFilter; import de.ellpeck.prettypipes.misc.ItemFilter;
import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.network.PipeNetwork;
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.BlockPos; import net.minecraft.core.Direction;
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;
import org.apache.commons.lang3.tuple.Pair; import net.minecraftforge.items.IItemHandler;
public class RetrievalModuleItem extends ModuleItem { public class RetrievalModuleItem extends ModuleItem {
@ -58,12 +57,12 @@ public class RetrievalModuleItem extends ModuleItem {
} }
@Override @Override
public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile) { public boolean canNetworkSee(ItemStack module, PipeBlockEntity tile, Direction direction, IItemHandler handler) {
return false; return false;
} }
@Override @Override
public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack) { public boolean canAcceptItem(ItemStack module, PipeBlockEntity tile, ItemStack stack, Direction direction, IItemHandler destination) {
return false; return false;
} }

View file

@ -43,8 +43,8 @@ public class StackSizeModuleItem extends ModuleItem {
@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 max = getMaxStackSize(module); var max = StackSizeModuleItem.getMaxStackSize(module);
if (getLimitToMaxStackSize(module)) if (StackSizeModuleItem.getLimitToMaxStackSize(module))
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++) {

View file

@ -63,7 +63,7 @@ public class PressurizerBlock extends BaseEntityBlock {
@org.jetbrains.annotations.Nullable @org.jetbrains.annotations.Nullable
@Override @Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return level.isClientSide ? null : createTickerHelper(type, Registry.pressurizerBlockEntity, PressurizerBlockEntity::tick); return level.isClientSide ? null : BaseEntityBlock.createTickerHelper(type, Registry.pressurizerBlockEntity, PressurizerBlockEntity::tick);
} }
@Override @Override

View file

@ -38,7 +38,7 @@ public class PressurizerGui extends AbstractContainerScreen<PressurizerContainer
@Override @Override
protected void renderBg(PoseStack matrixStack, float partialTicks, int x, int y) { protected void renderBg(PoseStack matrixStack, float partialTicks, int x, int y) {
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, PressurizerGui.TEXTURE);
this.blit(matrixStack, this.leftPos, this.topPos, 0, 0, 176, 137); this.blit(matrixStack, this.leftPos, this.topPos, 0, 0, 176, 137);
var energy = (int) (this.menu.tile.getEnergyPercentage() * 124); var energy = (int) (this.menu.tile.getEnergyPercentage() * 124);
this.blit(matrixStack, this.leftPos + 26, this.topPos + 22, 0, 137, energy, 12); this.blit(matrixStack, this.leftPos + 26, this.topPos + 22, 0, 137, energy, 12);

View file

@ -3,6 +3,7 @@ package de.ellpeck.prettypipes.terminal;
import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Registry;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker; import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
@ -18,6 +19,6 @@ public class CraftingTerminalBlock extends ItemTerminalBlock {
@org.jetbrains.annotations.Nullable @org.jetbrains.annotations.Nullable
@Override @Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return createTickerHelper(type, Registry.craftingTerminalBlockEntity, ItemTerminalBlockEntity::tick); return BaseEntityBlock.createTickerHelper(type, Registry.craftingTerminalBlockEntity, ItemTerminalBlockEntity::tick);
} }
} }

View file

@ -111,10 +111,10 @@ 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 = getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> ItemHandlerHelper.copyStackWithSize(this.getRequestedCraftItem(i), 1), this::isGhostItem, s -> { var lowestAvailable = CraftingTerminalBlockEntity.getAvailableCrafts(pipe, this.craftItems.getSlots(), i -> ItemHandlerHelper.copyStackWithSize(this.getRequestedCraftItem(i), 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();
}, onItemUnavailable(player, force), new Stack<>(), ItemEquality.NBT); }, ItemTerminalBlockEntity.onItemUnavailable(player, force), new Stack<>(), ItemEquality.NBT);
// if we're forcing, just pretend we have one available // if we're forcing, just pretend we have one available
if (lowestAvailable <= 0 && force) if (lowestAvailable <= 0 && force)
lowestAvailable = maxAmount; lowestAvailable = maxAmount;
@ -128,7 +128,7 @@ public class CraftingTerminalBlockEntity extends ItemTerminalBlockEntity {
continue; continue;
requested = requested.copy(); requested = requested.copy();
requested.setCount(lowestAvailable); requested.setCount(lowestAvailable);
this.requestItemImpl(requested, onItemUnavailable(player, force)); this.requestItemImpl(requested, ItemTerminalBlockEntity.onItemUnavailable(player, force));
} }
player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".sending_ingredients", lowestAvailable).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GREEN)), UUID.randomUUID()); player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".sending_ingredients", lowestAvailable).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GREEN)), UUID.randomUUID());
} else { } else {

View file

@ -82,7 +82,7 @@ public class ItemTerminalBlock extends BaseEntityBlock {
@org.jetbrains.annotations.Nullable @org.jetbrains.annotations.Nullable
@Override @Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return createTickerHelper(type, Registry.itemTerminalBlockEntity, ItemTerminalBlockEntity::tick); return BaseEntityBlock.createTickerHelper(type, Registry.itemTerminalBlockEntity, ItemTerminalBlockEntity::tick);
} }
} }

View file

@ -163,11 +163,11 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
.filter(s -> ItemEquality.compareItems(s, filter) && s.hasTag() && s.getTag().hashCode() == nbtHash) .filter(s -> ItemEquality.compareItems(s, filter) && s.hasTag() && s.getTag().hashCode() == nbtHash)
.findFirst().orElse(filter); .findFirst().orElse(filter);
} }
var requested = this.requestItemImpl(stack, onItemUnavailable(player, false)); var requested = this.requestItemImpl(stack, ItemTerminalBlockEntity.onItemUnavailable(player, false));
if (requested > 0) { if (requested > 0) {
player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".sending", requested, stack.getHoverName()).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GREEN)), UUID.randomUUID()); player.sendMessage(new TranslatableComponent("info." + PrettyPipes.ID + ".sending", requested, stack.getHoverName()).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GREEN)), UUID.randomUUID());
} else { } else {
onItemUnavailable(player, false).accept(stack); ItemTerminalBlockEntity.onItemUnavailable(player, false).accept(stack);
} }
network.endProfile(); network.endProfile();
} }
@ -175,7 +175,7 @@ public class ItemTerminalBlockEntity extends BlockEntity implements IPipeConnect
public int requestItemImpl(ItemStack stack, Consumer<ItemStack> unavailableConsumer) { public int requestItemImpl(ItemStack stack, Consumer<ItemStack> unavailableConsumer) {
var item = this.networkItems.get(new EquatableItemStack(stack, ItemEquality.NBT)); var item = this.networkItems.get(new EquatableItemStack(stack, ItemEquality.NBT));
Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations(); Collection<NetworkLocation> locations = item == null ? Collections.emptyList() : item.getLocations();
var ret = requestItemLater(this.level, this.getConnectedPipe().getBlockPos(), locations, unavailableConsumer, stack, new Stack<>(), ItemEquality.NBT); var ret = ItemTerminalBlockEntity.requestItemLater(this.level, this.getConnectedPipe().getBlockPos(), locations, unavailableConsumer, stack, new Stack<>(), ItemEquality.NBT);
this.existingRequests.addAll(ret.getLeft()); this.existingRequests.addAll(ret.getLeft());
return stack.getCount() - ret.getRight().getCount(); return stack.getCount() - ret.getRight().getCount();
} }

View file

@ -6,6 +6,7 @@ import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.packets.PacketButton; import de.ellpeck.prettypipes.packets.PacketButton;
import de.ellpeck.prettypipes.packets.PacketHandler; import de.ellpeck.prettypipes.packets.PacketHandler;
import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -25,9 +26,9 @@ public class CraftingTerminalGui extends ItemTerminalGui {
protected void init() { protected void init() {
super.init(); super.init();
this.requestButton = this.addRenderableWidget(new Button(this.leftPos + 8, this.topPos + 100, 50, 20, new TranslatableComponent("info." + PrettyPipes.ID + ".request"), button -> { this.requestButton = this.addRenderableWidget(new Button(this.leftPos + 8, this.topPos + 100, 50, 20, new TranslatableComponent("info." + PrettyPipes.ID + ".request"), button -> {
var amount = requestModifier(); var amount = ItemTerminalGui.requestModifier();
// also allow holding backspace instead of alt for people whose alt key is inaccessible (linux?) // also allow holding backspace instead of alt for people whose alt key is inaccessible (linux?)
var force = hasAltDown() || InputConstants.isKeyDown(this.minecraft.getWindow().getWindow(), 259) ? 1 : 0; var force = Screen.hasAltDown() || InputConstants.isKeyDown(this.minecraft.getWindow().getWindow(), 259) ? 1 : 0;
PacketHandler.sendToServer(new PacketButton(this.menu.tile.getBlockPos(), PacketButton.ButtonResult.CRAFT_TERMINAL_REQUEST, amount, force)); PacketHandler.sendToServer(new PacketButton(this.menu.tile.getBlockPos(), PacketButton.ButtonResult.CRAFT_TERMINAL_REQUEST, amount, force));
})); }));
this.tick(); this.tick();
@ -70,7 +71,7 @@ public class CraftingTerminalGui extends ItemTerminalGui {
@Override @Override
protected ResourceLocation getTexture() { protected ResourceLocation getTexture() {
return TEXTURE; return CraftingTerminalGui.TEXTURE;
} }
@Override @Override

View file

@ -15,6 +15,7 @@ import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.Widget; import net.minecraft.client.gui.components.Widget;
import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
@ -72,7 +73,7 @@ public class ItemTerminalGui extends AbstractContainerScreen<ItemTerminalContain
this.updateWidgets(); this.updateWidgets();
this.plusButton = this.addRenderableWidget(new Button(this.leftPos + this.getXOffset() + 95 - 7 + 12, this.topPos + 103, 12, 12, new TextComponent("+"), button -> { this.plusButton = this.addRenderableWidget(new Button(this.leftPos + this.getXOffset() + 95 - 7 + 12, this.topPos + 103, 12, 12, new TextComponent("+"), button -> {
var modifier = requestModifier(); var modifier = ItemTerminalGui.requestModifier();
if (modifier > 1 && this.requestAmount == 1) { if (modifier > 1 && this.requestAmount == 1) {
this.requestAmount = modifier; this.requestAmount = modifier;
} else { } else {
@ -83,7 +84,7 @@ public class ItemTerminalGui extends AbstractContainerScreen<ItemTerminalContain
this.requestAmount = 384; this.requestAmount = 384;
})); }));
this.minusButton = this.addRenderableWidget(new Button(this.leftPos + this.getXOffset() + 95 - 7 - 24, this.topPos + 103, 12, 12, new TextComponent("-"), button -> { this.minusButton = this.addRenderableWidget(new Button(this.leftPos + this.getXOffset() + 95 - 7 - 24, this.topPos + 103, 12, 12, new TextComponent("-"), button -> {
this.requestAmount -= requestModifier(); this.requestAmount -= ItemTerminalGui.requestModifier();
if (this.requestAmount < 1) if (this.requestAmount < 1)
this.requestAmount = 1; this.requestAmount = 1;
})); }));
@ -325,7 +326,7 @@ public class ItemTerminalGui extends AbstractContainerScreen<ItemTerminalContain
this.hoveredCrafting = ItemStack.EMPTY; this.hoveredCrafting = ItemStack.EMPTY;
if (this.currentlyCrafting != null && !this.currentlyCrafting.isEmpty()) { if (this.currentlyCrafting != null && !this.currentlyCrafting.isEmpty()) {
RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, TEXTURE); RenderSystem.setShaderTexture(0, ItemTerminalGui.TEXTURE);
this.blit(matrix, this.leftPos + this.imageWidth, this.topPos + 4, 191, 0, 65, 89); this.blit(matrix, this.leftPos + this.imageWidth, this.topPos + 4, 191, 0, 65, 89);
var x = 0; var x = 0;
@ -349,7 +350,7 @@ public class ItemTerminalGui extends AbstractContainerScreen<ItemTerminalContain
} }
protected ResourceLocation getTexture() { protected ResourceLocation getTexture() {
return TEXTURE; return ItemTerminalGui.TEXTURE;
} }
@Override @Override
@ -377,9 +378,9 @@ public class ItemTerminalGui extends AbstractContainerScreen<ItemTerminalContain
} }
public static int requestModifier() { public static int requestModifier() {
if (hasControlDown()) { if (Screen.hasControlDown()) {
return 10; return 10;
} else if (hasShiftDown()) { } else if (Screen.hasShiftDown()) {
return 64; return 64;
} else { } else {
return 1; return 1;

View file

@ -62,11 +62,13 @@
"container.prettypipes.item_terminal": "Item Terminal", "container.prettypipes.item_terminal": "Item Terminal",
"container.prettypipes.crafting_terminal": "Crafting Terminal", "container.prettypipes.crafting_terminal": "Crafting Terminal",
"container.prettypipes.pressurizer": "Pipe Pressurizer", "container.prettypipes.pressurizer": "Pipe Pressurizer",
"info.prettypipes.whitelist": "Allowed", "info.prettypipes.whitelist": "\u00A72A",
"info.prettypipes.blacklist": "Disallowed", "info.prettypipes.blacklist": "\u00A74D",
"info.prettypipes.whitelist.description": "Items in filter slots are allowed",
"info.prettypipes.blacklist.description": "Items in filter slots are disallowed",
"info.prettypipes.shift": "Hold Shift for info", "info.prettypipes.shift": "Hold Shift for info",
"info.prettypipes.populate": "Populate", "info.prettypipes.populate": "P",
"info.prettypipes.populate.description": "Filters items from adjacent inventories", "info.prettypipes.populate.description": "Populate filter slots with items from adjacent inventories",
"info.prettypipes.max_stack_size": "Maximum item amount", "info.prettypipes.max_stack_size": "Maximum item amount",
"info.prettypipes.limit_to_max_on": "Limit to one stack", "info.prettypipes.limit_to_max_on": "Limit to one stack",
"info.prettypipes.limit_to_max_off": "Don't limit to one stack", "info.prettypipes.limit_to_max_off": "Don't limit to one stack",
@ -88,5 +90,12 @@
"info.prettypipes.cancel_all": "Cancel", "info.prettypipes.cancel_all": "Cancel",
"info.prettypipes.cancel_all.desc": "Stops waiting for current crafting outputs\nDoesn't remove inputs from blocks", "info.prettypipes.cancel_all.desc": "Stops waiting for current crafting outputs\nDoesn't remove inputs from blocks",
"info.prettypipes.no_pipe_connected": "The terminal needs to be connected to a pipe network", "info.prettypipes.no_pipe_connected": "The terminal needs to be connected to a pipe network",
"info.prettypipes.too_many_pipes_connected": "The terminal can only be connected to a single pipe at a time" "info.prettypipes.too_many_pipes_connected": "The terminal can only be connected to a single pipe at a time",
"dir.prettypipes.up": "Up",
"dir.prettypipes.down": "Down",
"dir.prettypipes.north": "North",
"dir.prettypipes.east": "East",
"dir.prettypipes.south": "South",
"dir.prettypipes.west": "West",
"dir.prettypipes.none": "No Side Valid"
} }