diff --git a/build.gradle b/build.gradle index e4fe988..8b939f6 100644 --- a/build.gradle +++ b/build.gradle @@ -87,6 +87,9 @@ repositories { maven { url = "https://dvs1.progwml6.com/files/maven" } + maven { + url = "https://www.cursemaven.com" + } } configurations { @@ -100,6 +103,10 @@ dependencies { compileOnly fg.deobf("mezz.jei:jei-1.16.2:7.3.2.25:api") runtimeOnly fg.deobf("mezz.jei:jei-1.16.2:7.3.2.25") + + // to test the rf requiring stuff + runtimeOnly fg.deobf("curse.maven:powah:3057732") + runtimeOnly fg.deobf("curse.maven:lollipop:3057731") } // Example for how to get properties into the manifest for reading by the runtime.. diff --git a/src/main/java/de/ellpeck/prettypipes/Registry.java b/src/main/java/de/ellpeck/prettypipes/Registry.java index 01a599d..e43ea69 100644 --- a/src/main/java/de/ellpeck/prettypipes/Registry.java +++ b/src/main/java/de/ellpeck/prettypipes/Registry.java @@ -24,6 +24,10 @@ import de.ellpeck.prettypipes.pipe.modules.retrieval.RetrievalModuleItem; import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleContainer; import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleGui; import de.ellpeck.prettypipes.pipe.modules.stacksize.StackSizeModuleItem; +import de.ellpeck.prettypipes.pressurizer.PressurizerBlock; +import de.ellpeck.prettypipes.pressurizer.PressurizerContainer; +import de.ellpeck.prettypipes.pressurizer.PressurizerGui; +import de.ellpeck.prettypipes.pressurizer.PressurizerTileEntity; import de.ellpeck.prettypipes.terminal.CraftingTerminalBlock; import de.ellpeck.prettypipes.terminal.CraftingTerminalTileEntity; import de.ellpeck.prettypipes.terminal.ItemTerminalBlock; @@ -98,6 +102,10 @@ public final class Registry { public static EntityType pipeFrameEntity; + public static Block pressurizerBlock; + public static TileEntityType pressurizerTileEntity; + public static ContainerType pressurizerContainer; + public static ContainerType extractionModuleContainer; public static ContainerType filterModuleContainer; public static ContainerType retrievalModuleContainer; @@ -108,7 +116,8 @@ public final class Registry { event.getRegistry().registerAll( pipeBlock = new PipeBlock().setRegistryName("pipe"), itemTerminalBlock = new ItemTerminalBlock().setRegistryName("item_terminal"), - craftingTerminalBlock = new CraftingTerminalBlock().setRegistryName("crafting_terminal") + craftingTerminalBlock = new CraftingTerminalBlock().setRegistryName("crafting_terminal"), + pressurizerBlock = new PressurizerBlock().setRegistryName("pressurizer") ); } @@ -139,7 +148,8 @@ public final class Registry { event.getRegistry().registerAll( pipeTileEntity = (TileEntityType) TileEntityType.Builder.create(PipeTileEntity::new, pipeBlock).build(null).setRegistryName("pipe"), itemTerminalTileEntity = (TileEntityType) TileEntityType.Builder.create(ItemTerminalTileEntity::new, itemTerminalBlock).build(null).setRegistryName("item_terminal"), - craftingTerminalTileEntity = (TileEntityType) TileEntityType.Builder.create(CraftingTerminalTileEntity::new, craftingTerminalBlock).build(null).setRegistryName("crafting_terminal") + craftingTerminalTileEntity = (TileEntityType) TileEntityType.Builder.create(CraftingTerminalTileEntity::new, craftingTerminalBlock).build(null).setRegistryName("crafting_terminal"), + pressurizerTileEntity = (TileEntityType) TileEntityType.Builder.create(PressurizerTileEntity::new, pressurizerBlock).build(null).setRegistryName("pressurizer") ); } @@ -156,6 +166,7 @@ public final class Registry { pipeContainer = (ContainerType) IForgeContainerType.create((windowId, inv, data) -> new MainPipeContainer(pipeContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pipe"), itemTerminalContainer = (ContainerType) IForgeContainerType.create((windowId, inv, data) -> new ItemTerminalContainer(itemTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("item_terminal"), craftingTerminalContainer = (ContainerType) IForgeContainerType.create((windowId, inv, data) -> new CraftingTerminalContainer(craftingTerminalContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("crafting_terminal"), + pressurizerContainer = (ContainerType) IForgeContainerType.create((windowId, inv, data) -> new PressurizerContainer(pressurizerContainer, windowId, inv.player, data.readBlockPos())).setRegistryName("pressurizer"), extractionModuleContainer = createPipeContainer("extraction_module"), filterModuleContainer = createPipeContainer("filter_module"), retrievalModuleContainer = createPipeContainer("retrieval_module"), @@ -203,6 +214,7 @@ public final class Registry { ScreenManager.registerFactory(pipeContainer, MainPipeGui::new); ScreenManager.registerFactory(itemTerminalContainer, ItemTerminalGui::new); + ScreenManager.registerFactory(pressurizerContainer, PressurizerGui::new); ScreenManager.registerFactory(craftingTerminalContainer, CraftingTerminalGui::new); ScreenManager.registerFactory(extractionModuleContainer, ExtractionModuleGui::new); ScreenManager.registerFactory(filterModuleContainer, FilterModuleGui::new); diff --git a/src/main/java/de/ellpeck/prettypipes/Utility.java b/src/main/java/de/ellpeck/prettypipes/Utility.java index 33fbf58..64e537b 100644 --- a/src/main/java/de/ellpeck/prettypipes/Utility.java +++ b/src/main/java/de/ellpeck/prettypipes/Utility.java @@ -5,17 +5,21 @@ import de.ellpeck.prettypipes.network.PipeItem; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.InventoryHelper; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Slot; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; +import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; import net.minecraft.util.text.*; import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.items.IItemHandler; import org.apache.commons.lang3.tuple.Pair; @@ -25,6 +29,7 @@ import java.util.Collection; import java.util.List; import java.util.function.Function; import java.util.stream.IntStream; +import java.util.stream.Stream; public final class Utility { @@ -107,6 +112,13 @@ public final class Utility { return list; } + public static void sendTileEntityToClients(TileEntity tile) { + ServerWorld world = (ServerWorld) tile.getWorld(); + Stream entities = world.getChunkProvider().chunkManager.getTrackingPlayers(new ChunkPos(tile.getPos()), false); + SUpdateTileEntityPacket packet = tile.getUpdatePacket(); + entities.forEach(e -> e.connection.sendPacket(packet)); + } + public static > List deserializeAll(ListNBT list, Function supplier) { List items = new ArrayList<>(); for (int i = 0; i < list.size(); i++) diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java index 57f212d..0911e9e 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeItem.java @@ -159,22 +159,22 @@ public class PipeItem implements INBTSerializable, ILiquidContainer PipeNetwork network = PipeNetwork.get(currPipe.getWorld()); if (tryReturn) { // first time: we try to return to our input chest - if (!this.retryOnObstruction && network.routeItemToLocation(currPipe.getPos(), this.destInventory, this.getStartPipe(), this.startInventory, speed -> this)) { + if (!this.retryOnObstruction && network.routeItemToLocation(currPipe.getPos(), this.destInventory, this.getStartPipe(), this.startInventory, this.stack, speed -> this)) { this.retryOnObstruction = true; return; } // second time: we arrived at our input chest, it is full, so we try to find a different goal location ItemStack remain = network.routeItem(currPipe.getPos(), this.destInventory, this.stack, (stack, speed) -> this, false); - if (remain.isEmpty()) - return; - this.stack = remain; + if (!remain.isEmpty()) + this.drop(currPipe.getWorld(), remain.copy()); + } else { + // if all re-routing attempts fail, we drop + this.drop(currPipe.getWorld(), this.stack); } - // if all re-routing attempts fail, we drop - this.drop(currPipe.getWorld()); } - public void drop(World world) { - ItemEntity item = new ItemEntity(world, this.x, this.y, this.z, this.stack.copy()); + public void drop(World world, ItemStack stack) { + ItemEntity item = new ItemEntity(world, this.x, this.y, this.z, stack.copy()); item.world.addEntity(item); } diff --git a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java index cb9849f..ba97f71 100644 --- a/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java +++ b/src/main/java/de/ellpeck/prettypipes/network/PipeNetwork.java @@ -44,6 +44,7 @@ import javax.annotation.Nullable; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -152,7 +153,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL if (dest == null || dest.getLeft().equals(startInventory)) continue; Function sup = speed -> itemSupplier.apply(dest.getRight(), speed); - if (this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest.getLeft(), sup)) { + if (this.routeItemToLocation(startPipePos, startInventory, pipe.getPos(), dest.getLeft(), dest.getRight(), sup)) { ItemStack remain = stack.copy(); remain.shrink(dest.getRight().getCount()); this.endProfile(); @@ -163,7 +164,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return stack; } - public boolean routeItemToLocation(BlockPos startPipePos, BlockPos startInventory, BlockPos destPipePos, BlockPos destInventory, Function itemSupplier) { + public boolean routeItemToLocation(BlockPos startPipePos, BlockPos startInventory, BlockPos destPipePos, BlockPos destInventory, ItemStack stack, Function itemSupplier) { if (!this.isNode(startPipePos) || !this.isNode(destPipePos)) return false; if (!this.world.isBlockLoaded(startPipePos) || !this.world.isBlockLoaded(destPipePos)) @@ -176,10 +177,9 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL this.endProfile(); if (path == null) return false; - PipeItem item = itemSupplier.apply(startPipe.getItemSpeed()); + PipeItem item = itemSupplier.apply(startPipe.getItemSpeed(stack)); item.setDestination(startInventory, destInventory, path); - if (!startPipe.getItems().contains(item)) - startPipe.getItems().add(item); + startPipe.addNewItem(item); PacketHandler.sendToAllLoaded(this.world, startPipePos, new PacketItemEnterPipe(startPipePos, item)); return true; } @@ -205,7 +205,7 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL // try to extract from that location's inventory and send the item IItemHandler handler = location.getItemHandler(this.world); ItemStack extracted = handler.extractItem(slot, remain.getCount(), true); - if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, speed -> new PipeItem(extracted, speed))) { + if (this.routeItemToLocation(location.pipePos, location.getPos(), destPipe, destInventory, extracted, speed -> new PipeItem(extracted, speed))) { handler.extractItem(slot, extracted.getCount(), false); remain.shrink(extracted.getCount()); if (remain.isEmpty()) @@ -297,6 +297,15 @@ public class PipeNetwork implements ICapabilitySerializable, GraphL return null; } + public List getNetworkNodes(BlockPos pos, Predicate predicate) { + if (!this.isNode(pos)) + return Collections.emptyList(); + return this.getOrderedNetworkNodes(pos).stream() + .map(this::getPipe) + .filter(predicate) + .collect(Collectors.toList()); + } + private List createAllEdges(BlockPos pos, BlockState state, boolean ignoreCurrBlocked) { this.startProfile("create_all_edges"); List edges = new ArrayList<>(); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java index 0672f53..65d3aaf 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeBlock.java @@ -225,7 +225,7 @@ public class PipeBlock extends ContainerBlock implements IPipeConnectable { if (tile != null) { Utility.dropInventory(tile, tile.modules); for (PipeItem item : tile.getItems()) - item.drop(worldIn); + item.drop(worldIn, item.stack); } PipeNetwork network = PipeNetwork.get(worldIn); network.removeNode(pos); diff --git a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java index c193444..8ec83b5 100644 --- a/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java +++ b/src/main/java/de/ellpeck/prettypipes/pipe/PipeTileEntity.java @@ -1,5 +1,6 @@ package de.ellpeck.prettypipes.pipe; +import com.google.common.base.Predicates; import de.ellpeck.prettypipes.PrettyPipes; import de.ellpeck.prettypipes.Registry; import de.ellpeck.prettypipes.Utility; @@ -7,6 +8,8 @@ import de.ellpeck.prettypipes.items.IModule; import de.ellpeck.prettypipes.network.PipeItem; import de.ellpeck.prettypipes.network.PipeNetwork; import de.ellpeck.prettypipes.pipe.containers.MainPipeContainer; +import de.ellpeck.prettypipes.pressurizer.PressurizerBlock; +import de.ellpeck.prettypipes.pressurizer.PressurizerTileEntity; import net.minecraft.block.BlockState; import net.minecraft.block.ChestBlock; import net.minecraft.entity.player.PlayerEntity; @@ -57,6 +60,7 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide } }; protected List items; + private PressurizerTileEntity pressurizer; private int lastItemAmount; private int priority; @@ -117,6 +121,13 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide PipeNetwork.get(this.world).clearDestinationCache(this.pos); } profiler.endSection(); + + if (this.world.getGameTime() % 40 == 0) { + profiler.startSection("caching_data"); + // figure out if we're pressurized + this.pressurizer = this.findPressurizer(); + profiler.endSection(); + } } profiler.startSection("ticking_items"); @@ -136,6 +147,14 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return this.items; } + public void addNewItem(PipeItem item) { + // an item might be re-routed from a previous location, but it should still count as a new item then + if (!this.getItems().contains(item)) + this.getItems().add(item); + if (this.pressurizer != null && !this.pressurizer.isRemoved()) + this.pressurizer.pressurizeItem(item.stack, false); + } + public boolean isConnected(Direction dir) { return this.getBlockState().get(PipeBlock.DIRECTIONS.get(dir)).isConnected(); } @@ -198,9 +217,10 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide return this.priority; } - public float getItemSpeed() { - float speed = (float) this.streamModules().mapToDouble(m -> m.getRight().getItemSpeedIncrease(m.getLeft(), this)).sum(); - return 0.05F + speed; + public float getItemSpeed(ItemStack stack) { + float moduleSpeed = (float) this.streamModules().mapToDouble(m -> m.getRight().getItemSpeedIncrease(m.getLeft(), this)).sum(); + float pressureSpeed = this.pressurizer != null && !this.pressurizer.isRemoved() && this.pressurizer.pressurizeItem(stack, true) ? 0.4F : 0; + return 0.05F + moduleSpeed + pressureSpeed; } public boolean canWork() { @@ -282,4 +302,15 @@ public class PipeTileEntity extends TileEntity implements INamedContainerProvide public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) { return new MainPipeContainer(Registry.pipeContainer, window, player, PipeTileEntity.this.pos); } + + private PressurizerTileEntity findPressurizer() { + for (PipeTileEntity node : PipeNetwork.get(this.world).getNetworkNodes(this.pos, p -> true)) { + for (Direction dir : Direction.values()) { + IPipeConnectable connectable = node.getPipeConnectable(dir); + if (connectable instanceof PressurizerBlock) + return Utility.getTileEntity(PressurizerTileEntity.class, this.world, node.pos.offset(dir)); + } + } + return null; + } } diff --git a/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerBlock.java b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerBlock.java new file mode 100644 index 0000000..b127862 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerBlock.java @@ -0,0 +1,64 @@ +package de.ellpeck.prettypipes.pressurizer; + +import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.pipe.ConnectionType; +import de.ellpeck.prettypipes.pipe.IPipeConnectable; +import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.ContainerBlock; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; + +import javax.annotation.Nullable; +import java.util.List; + +public class PressurizerBlock extends ContainerBlock implements IPipeConnectable { + public PressurizerBlock() { + super(Properties.create(Material.ROCK).hardnessAndResistance(3).sound(SoundType.STONE)); + } + + @Override + public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult result) { + PressurizerTileEntity tile = Utility.getTileEntity(PressurizerTileEntity.class, worldIn, pos); + if (tile == null) + return ActionResultType.PASS; + if (!worldIn.isRemote) + NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos); + return ActionResultType.SUCCESS; + } + + @Override + public ConnectionType getConnectionType(World world, BlockPos pipePos, Direction direction) { + return ConnectionType.CONNECTED; + } + + @Override + public TileEntity createNewTileEntity(IBlockReader worldIn) { + return new PressurizerTileEntity(); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + @Override + public void addInformation(ItemStack stack, @Nullable IBlockReader worldIn, List tooltip, ITooltipFlag flagIn) { + Utility.addTooltip(this.getRegistryName().getPath(), tooltip); + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerContainer.java b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerContainer.java new file mode 100644 index 0000000..49066d0 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerContainer.java @@ -0,0 +1,38 @@ +package de.ellpeck.prettypipes.pressurizer; + +import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.terminal.ItemTerminalTileEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nullable; + +public class PressurizerContainer extends Container { + public final PressurizerTileEntity tile; + + public PressurizerContainer(@Nullable ContainerType type, int id, PlayerEntity player, BlockPos pos) { + super(type, id); + this.tile = Utility.getTileEntity(PressurizerTileEntity.class, player.world, pos); + + for (int l = 0; l < 3; ++l) + for (int j1 = 0; j1 < 9; ++j1) + this.addSlot(new Slot(player.inventory, j1 + l * 9 + 9, 8 + j1 * 18, 55 + l * 18)); + for (int i1 = 0; i1 < 9; ++i1) + this.addSlot(new Slot(player.inventory, i1, 8 + i1 * 18, 113)); + } + + @Override + public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) { + return Utility.transferStackInSlot(this, this::mergeItemStack, player, slotIndex, stack -> null); + } + + @Override + public boolean canInteractWith(PlayerEntity playerIn) { + return true; + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerGui.java b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerGui.java new file mode 100644 index 0000000..f9a8769 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerGui.java @@ -0,0 +1,43 @@ +package de.ellpeck.prettypipes.pressurizer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import de.ellpeck.prettypipes.PrettyPipes; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; + +public class PressurizerGui extends ContainerScreen { + private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/pressurizer.png"); + + public PressurizerGui(PressurizerContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) { + super(screenContainer, inv, titleIn); + this.xSize = 176; + this.ySize = 137; + } + + @Override + public void render(MatrixStack matrix, int mouseX, int mouseY, float partialTicks) { + this.renderBackground(matrix); + super.render(matrix, mouseX, mouseY, partialTicks); + this.func_230459_a_(matrix, mouseX, mouseY); + if (mouseX >= this.guiLeft + 26 && mouseY >= this.guiTop + 22 && mouseX < this.guiLeft + 26 + 124 && mouseY < this.guiTop + 22 + 12) + this.renderTooltip(matrix, new TranslationTextComponent("info." + PrettyPipes.ID + ".energy", this.container.tile.getEnergy(), this.container.tile.getMaxEnergy()), mouseX, mouseY); + } + + @Override + protected void drawGuiContainerForegroundLayer(MatrixStack matrix, int mouseX, int mouseY) { + this.font.drawString(matrix, this.playerInventory.getDisplayName().getString(), 8, this.ySize - 96 + 2, 4210752); + this.font.drawString(matrix, this.title.getString(), 8, 6, 4210752); + } + + @Override + protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) { + this.getMinecraft().getTextureManager().bindTexture(TEXTURE); + this.blit(matrixStack, this.guiLeft, this.guiTop, 0, 0, 176, 137); + int energy = (int) (this.container.tile.getEnergyPercentage() * 124); + this.blit(matrixStack, this.guiLeft + 26, this.guiTop + 22, 0, 137, energy, 12); + } +} diff --git a/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerTileEntity.java b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerTileEntity.java new file mode 100644 index 0000000..1942a26 --- /dev/null +++ b/src/main/java/de/ellpeck/prettypipes/pressurizer/PressurizerTileEntity.java @@ -0,0 +1,135 @@ +package de.ellpeck.prettypipes.pressurizer; + +import de.ellpeck.prettypipes.PrettyPipes; +import de.ellpeck.prettypipes.Registry; +import de.ellpeck.prettypipes.Utility; +import de.ellpeck.prettypipes.terminal.containers.ItemTerminalContainer; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SUpdateTileEntityPacket; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.EnergyStorage; +import net.minecraftforge.energy.IEnergyStorage; + +import javax.annotation.Nullable; + +public class PressurizerTileEntity extends TileEntity implements INamedContainerProvider, ITickableTileEntity { + + private final ModifiableEnergyStorage storage = new ModifiableEnergyStorage(64000, 512, 0); + private int lastEnergy; + + public PressurizerTileEntity() { + super(Registry.pressurizerTileEntity); + } + + public boolean pressurizeItem(ItemStack stack, boolean simulate) { + int amount = 100 * stack.getCount(); + return this.storage.extractInternal(amount, simulate) >= amount; + } + + public float getEnergyPercentage() { + return this.getEnergy() / (float) this.getMaxEnergy(); + } + + public int getEnergy() { + return this.storage.getEnergyStored(); + } + + public int getMaxEnergy() { + return this.storage.getMaxEnergyStored(); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.putInt("energy", this.getEnergy()); + return super.write(compound); + } + + @Override + public void read(BlockState state, CompoundNBT nbt) { + this.storage.setEnergyStored(nbt.getInt("energy")); + super.read(state, nbt); + } + + @Override + public CompoundNBT getUpdateTag() { + return this.write(new CompoundNBT()); + } + + @Override + public void handleUpdateTag(BlockState state, CompoundNBT tag) { + this.read(state, tag); + } + + @Override + public SUpdateTileEntityPacket getUpdatePacket() { + return new SUpdateTileEntityPacket(this.pos, -1, this.write(new CompoundNBT())); + } + + @Override + public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { + this.read(this.getBlockState(), pkt.getNbtCompound()); + } + + @Override + public ITextComponent getDisplayName() { + return new TranslationTextComponent("container." + PrettyPipes.ID + ".pressurizer"); + } + + @Nullable + @Override + public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) { + return new PressurizerContainer(Registry.pressurizerContainer, window, player, this.pos); + } + + @Override + public LazyOptional getCapability(Capability cap, Direction side) { + if (cap == CapabilityEnergy.ENERGY) { + return LazyOptional.of(() -> (T) this.storage); + } else { + return LazyOptional.empty(); + } + } + + @Override + public void tick() { + if (this.world.isRemote) + return; + if (this.lastEnergy != this.storage.getEnergyStored() && this.world.getGameTime() % 10 == 0) { + this.lastEnergy = this.storage.getEnergyStored(); + Utility.sendTileEntityToClients(this); + } + } + + private static class ModifiableEnergyStorage extends EnergyStorage { + + public ModifiableEnergyStorage(int capacity, int maxReceive, int maxExtract) { + super(capacity, maxReceive, maxExtract); + } + + private void setEnergyStored(int energy) { + this.energy = energy; + } + + private int extractInternal(int maxExtract, boolean simulate) { + int energyExtracted = Math.min(this.energy, maxExtract); + if (!simulate) + this.energy -= energyExtracted; + return energyExtracted; + } + } +} diff --git a/src/main/resources/assets/prettypipes/blockstates/pressurizer.json b/src/main/resources/assets/prettypipes/blockstates/pressurizer.json new file mode 100644 index 0000000..cb58979 --- /dev/null +++ b/src/main/resources/assets/prettypipes/blockstates/pressurizer.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "prettypipes:block/pressurizer" + } + } +} diff --git a/src/main/resources/assets/prettypipes/lang/en_us.json b/src/main/resources/assets/prettypipes/lang/en_us.json index 6a5ff9a..4314a2a 100644 --- a/src/main/resources/assets/prettypipes/lang/en_us.json +++ b/src/main/resources/assets/prettypipes/lang/en_us.json @@ -35,13 +35,16 @@ "info.prettypipes.redstone_module": "Allows disabling the pipe with a redstone signal\nWorks for both extraction and retrieval", "info.prettypipes.item_terminal": "Allows viewing and requesting all items in a pipe network\nAlso has slots for putting items into the network", "info.prettypipes.crafting_terminal": "Allows requesting ingredients for crafting recipes\nSupports auto-filling from JEI if installed", + "info.prettypipes.pressurizer": "Drastically increases item speed in the entire pipe network\nRequires FE (or RF) for each item transferred", "block.prettypipes.pipe": "Pipe", "block.prettypipes.item_terminal": "Item Terminal", "block.prettypipes.crafting_terminal": "Crafting Terminal", + "block.prettypipes.pressurizer": "Pipe Pressurizer", "itemGroup.prettypipes": "Pretty Pipes", "container.prettypipes.pipe": "Pipe", "container.prettypipes.item_terminal": "Item Terminal", "container.prettypipes.crafting_terminal": "Crafting Terminal", + "container.prettypipes.pressurizer": "Pipe Pressurizer", "info.prettypipes.whitelist": "Allowed", "info.prettypipes.blacklist": "Disallowed", "info.prettypipes.shift": "Hold Shift for info", @@ -61,5 +64,6 @@ "info.prettypipes.ascending": "Ascending", "info.prettypipes.descending": "Descending", "info.prettypipes.sync_jei.on": "Sync JEI Search", - "info.prettypipes.sync_jei.off": "Don't Sync JEI Search" + "info.prettypipes.sync_jei.off": "Don't Sync JEI Search", + "info.prettypipes.energy": "%s / %s FE" } \ No newline at end of file diff --git a/src/main/resources/assets/prettypipes/models/block/pressurizer.json b/src/main/resources/assets/prettypipes/models/block/pressurizer.json new file mode 100644 index 0000000..d8fc2de --- /dev/null +++ b/src/main/resources/assets/prettypipes/models/block/pressurizer.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_column", + "textures": { + "end": "prettypipes:block/pressurizer_top", + "side": "prettypipes:block/pressurizer" + } +} diff --git a/src/main/resources/assets/prettypipes/models/item/pressurizer.json b/src/main/resources/assets/prettypipes/models/item/pressurizer.json new file mode 100644 index 0000000..d29af8c --- /dev/null +++ b/src/main/resources/assets/prettypipes/models/item/pressurizer.json @@ -0,0 +1,3 @@ +{ + "parent": "prettypipes:block/pressurizer" +} \ No newline at end of file diff --git a/src/main/resources/assets/prettypipes/textures/gui/pressurizer.png b/src/main/resources/assets/prettypipes/textures/gui/pressurizer.png new file mode 100644 index 0000000..d4c1a6b Binary files /dev/null and b/src/main/resources/assets/prettypipes/textures/gui/pressurizer.png differ