Thinking about Pipes

- Survival mode players can now configure the fluid supplied by a creative fluid tank
- Pondering for Tanks, Creative Tanks and Hose Pulleys
This commit is contained in:
simibubi 2021-06-24 18:22:28 +02:00
parent 9a020dd02a
commit ab8b8e41da
15 changed files with 553 additions and 89 deletions

View File

@ -96,7 +96,8 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
fluid = flowingFluid.getFluid();
else {
affectedArea.expandTo(new MutableBoundingBox(currentPos, currentPos));
world.setBlockState(currentPos, emptied, 2 | 16);
if (!tileEntity.isVirtual())
world.setBlockState(currentPos, emptied, 2 | 16);
queue.dequeue();
if (queue.isEmpty()) {
isValid = checkValid(world, rootPos);
@ -136,7 +137,8 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
return true;
}
world.setBlockState(currentPos, emptied, 2 | 16);
if (!tileEntity.isVirtual())
world.setBlockState(currentPos, emptied, 2 | 16);
affectedArea.expandTo(new MutableBoundingBox(currentPos, currentPos));
queue.dequeue();

View File

@ -176,13 +176,16 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
BlockState blockState = world.getBlockState(currentPos);
if (blockState.contains(BlockStateProperties.WATERLOGGED) && fluid.isEquivalentTo(Fluids.WATER)) {
world.setBlockState(currentPos,
updatePostWaterlogging(blockState.with(BlockStateProperties.WATERLOGGED, true)), 2 | 16);
if (!tileEntity.isVirtual())
world.setBlockState(currentPos,
updatePostWaterlogging(blockState.with(BlockStateProperties.WATERLOGGED, true)),
2 | 16);
} else {
replaceBlock(world, currentPos, blockState);
world.setBlockState(currentPos, FluidHelper.convertToStill(fluid)
.getDefaultState()
.getBlockState(), 2 | 16);
if (!tileEntity.isVirtual())
world.setBlockState(currentPos, FluidHelper.convertToStill(fluid)
.getDefaultState()
.getBlockState(), 2 | 16);
}
ITickList<Fluid> pendingFluidTicks = world.getPendingFluidTicks();

View File

@ -114,7 +114,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
if (heldItem.isEmpty())
return ActionResultType.PASS;
if (!player.isCreative())
if (!player.isCreative() && !creative)
return ActionResultType.PASS;
FluidExchange exchange = null;

View File

@ -8,6 +8,7 @@ import com.google.gson.JsonSyntaxException;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.fluids.actors.GenericItemFilling;
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity;
import com.simibubi.create.content.contraptions.processing.EmptyingByBasin;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.utility.Pair;
@ -134,7 +135,7 @@ public class FluidHelper {
emptyingResult = EmptyingByBasin.emptyItem(worldIn, copyOfHeld, false);
tank.fill(fluidStack, FluidAction.EXECUTE);
if (!player.isCreative()) {
if (!player.isCreative() && !(te instanceof CreativeFluidTankTileEntity)) {
if (copyOfHeld.isEmpty())
player.setHeldItem(handIn, emptyingResult.getSecond());
else {
@ -169,7 +170,7 @@ public class FluidHelper {
if (world.isRemote)
return true;
if (player.isCreative())
if (player.isCreative() || te instanceof CreativeFluidTankTileEntity)
heldItem = heldItem.copy();
ItemStack out = GenericItemFilling.fillItem(world, requiredAmountForItem, heldItem, fluid.copy());

View File

@ -14,7 +14,6 @@ import com.simibubi.create.content.contraptions.components.crafter.ConnectedInpu
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem;
import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
import com.simibubi.create.content.contraptions.fluids.PumpTileEntity;
import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;

View File

@ -242,7 +242,7 @@ public class PonderIndex {
// Fluids
// ProgressTM
// [##### ####. ..... .....]
// [##### ##### ##### .....]
PonderRegistry.forComponents(AllBlocks.FLUID_PIPE)
.addStoryBoard("fluid_pipe/flow", PipeScenes::flow, PonderTag.FLUIDS)
@ -264,9 +264,9 @@ public class PonderIndex {
.addStoryBoard("fluid_tank/storage_creative", FluidTankScenes::creative, PonderTag.FLUIDS, PonderTag.CREATIVE)
.addStoryBoard("fluid_tank/sizes_creative", FluidTankScenes::sizes);
PonderRegistry.forComponents(AllBlocks.HOSE_PULLEY)
.addStoryBoard("debug/scene_1", HosePulleyScenes::intro, PonderTag.FLUIDS, PonderTag.KINETIC_APPLIANCES)
.addStoryBoard("debug/scene_1", HosePulleyScenes::level)
.addStoryBoard("debug/scene_1", HosePulleyScenes::infinite);
.addStoryBoard("hose_pulley/intro", HosePulleyScenes::intro, PonderTag.FLUIDS, PonderTag.KINETIC_APPLIANCES)
.addStoryBoard("hose_pulley/level", HosePulleyScenes::level)
.addStoryBoard("hose_pulley/infinite", HosePulleyScenes::infinite);
PonderRegistry.forComponents(AllBlocks.SPOUT)
.addStoryBoard("debug/scene_1", SpoutScenes::filling, PonderTag.FLUIDS)
.addStoryBoard("debug/scene_1", SpoutScenes::access);

View File

@ -5,6 +5,9 @@ import com.simibubi.create.AllFluids;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.fluids.FluidFX;
import com.simibubi.create.content.contraptions.fluids.actors.SpoutTileEntity;
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity;
import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity;
import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity;
import com.simibubi.create.foundation.fluid.FluidHelper;
@ -20,6 +23,7 @@ import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstructi
import com.simibubi.create.foundation.utility.Pointing;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.Direction;
@ -214,39 +218,209 @@ public class FluidTankScenes {
public static void sizes(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("fluid_tank_sizes", "Dimensions of a Fluid tank");
scene.configureBasePlate(0, 0, 5);
scene.world.showSection(util.select.layer(0), Direction.UP);
scene.configureBasePlate(0, 0, 6);
scene.showBasePlate();
scene.idle(5);
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
/*
* Fluid Tanks can be combined to increase the total capacity
*
* The base shape can be a square up to 3 blocks wide...
*
* ...and grow in height by more than 30 additional layers
*
* Using a Wrench, the tanks' window can be toggled
*/
Selection single = util.select.position(0, 3, 0);
Selection single2 = util.select.fromTo(1, 2, 1, 0, 2, 0);
Selection single3 = util.select.fromTo(2, 1, 0, 0, 1, 2);
ElementLink<WorldSectionElement> s1 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s1, util.vector.of(2, -2, 2), 0);
scene.idle(10);
scene.overlay.showText(60)
.text("Fluid Tanks can be combined to increase the total capacity")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.topOf(2, 1, 2));
scene.idle(40);
ElementLink<WorldSectionElement> s2 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s2, util.vector.of(2, -2, 3), 0);
scene.idle(5);
ElementLink<WorldSectionElement> s3 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s3, util.vector.of(3, -2, 3), 0);
scene.idle(5);
ElementLink<WorldSectionElement> s4 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s4, util.vector.of(3, -2, 2), 0);
scene.idle(10);
scene.world.moveSection(s1, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s2, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s3, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s4, util.vector.of(0, -100, 0), 0);
ElementLink<WorldSectionElement> d = scene.world.showIndependentSectionImmediately(single2);
scene.world.moveSection(d, util.vector.of(2, -1, 2), 0);
scene.effects.indicateSuccess(util.grid.at(2, 1, 2));
scene.effects.indicateSuccess(util.grid.at(3, 1, 2));
scene.effects.indicateSuccess(util.grid.at(2, 1, 3));
scene.effects.indicateSuccess(util.grid.at(3, 1, 3));
scene.world.hideIndependentSection(s1, Direction.DOWN);
scene.world.hideIndependentSection(s2, Direction.DOWN);
scene.world.hideIndependentSection(s3, Direction.DOWN);
scene.world.hideIndependentSection(s4, Direction.DOWN);
scene.idle(25);
scene.overlay.showText(60)
.text("Their base square can be up to 3 blocks wide...")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.topOf(2, 1, 2));
scene.idle(40);
s1 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s1, util.vector.of(2, -2, 4), 0);
scene.idle(3);
s2 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s2, util.vector.of(3, -2, 4), 0);
scene.idle(3);
s3 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s3, util.vector.of(4, -2, 4), 0);
scene.idle(3);
s4 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s4, util.vector.of(4, -2, 3), 0);
scene.idle(3);
ElementLink<WorldSectionElement> s5 = scene.world.showIndependentSection(single, Direction.DOWN);
scene.world.moveSection(s5, util.vector.of(4, -2, 2), 0);
scene.idle(10);
scene.world.moveSection(d, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s1, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s2, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s3, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s4, util.vector.of(0, -100, 0), 0);
scene.world.moveSection(s5, util.vector.of(0, -100, 0), 0);
ElementLink<WorldSectionElement> t = scene.world.showIndependentSectionImmediately(single3);
scene.world.moveSection(t, util.vector.of(2, 0, 2), 0);
for (int i = 2; i < 5; i++)
for (int j = 2; j < 5; j++)
scene.effects.indicateSuccess(util.grid.at(i, 1, j));
scene.world.hideIndependentSection(d, Direction.DOWN);
scene.world.hideIndependentSection(s1, Direction.DOWN);
scene.world.hideIndependentSection(s2, Direction.DOWN);
scene.world.hideIndependentSection(s3, Direction.DOWN);
scene.world.hideIndependentSection(s4, Direction.DOWN);
scene.world.hideIndependentSection(s5, Direction.DOWN);
scene.idle(25);
scene.world.hideIndependentSection(t, Direction.DOWN);
scene.idle(10);
Selection full1 = util.select.fromTo(5, 1, 0, 5, 6, 0);
Selection full2 = util.select.fromTo(4, 1, 1, 3, 6, 2);
Selection full3 = util.select.fromTo(0, 6, 5, 2, 1, 3);
scene.world.showSection(full1, Direction.DOWN);
scene.idle(5);
scene.world.showSection(full2, Direction.DOWN);
scene.idle(5);
scene.world.showSection(full3, Direction.DOWN);
scene.idle(10);
Vector3d blockSurface = util.vector.blockSurface(util.grid.at(3, 3, 1), Direction.WEST);
scene.overlay.showText(60)
.text("...and grow in height by more than 30 additional layers")
.attachKeyFrame()
.placeNearTarget()
.pointAt(blockSurface);
scene.idle(70);
scene.overlay.showControls(
new InputWindowElement(util.vector.blockSurface(util.grid.at(3, 3, 1), Direction.NORTH), Pointing.RIGHT)
.rightClick()
.withWrench(),
60);
scene.idle(7);
scene.world.modifyBlocks(full2, s -> s.with(FluidTankBlock.SHAPE, FluidTankBlock.Shape.PLAIN), false);
scene.idle(30);
scene.overlay.showText(60)
.text("Using a Wrench, a tanks' window can be toggled")
.attachKeyFrame()
.placeNearTarget()
.pointAt(blockSurface);
scene.idle(50);
}
public static void creative(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("creative_fluid_tank", "Creative Fluid Tanks");
scene.configureBasePlate(0, 0, 5);
scene.world.showSection(util.select.layer(0), Direction.UP);
scene.showBasePlate();
scene.idle(5);
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
/*
* Creative Fluid Tanks can be used to provide a bottomless supply of fluid
*
* Right-Click with a fluid containing item to configure it
*
* Pipe Networks can now endlessly draw the assigned fluid from this tank
*
* Any Fluids pipes push into a Creative Fluid Tank will be voided
*/
Selection largeCog = util.select.position(5, 0, 2);
Selection cTank = util.select.fromTo(3, 1, 1, 3, 2, 1);
Selection tank = util.select.fromTo(1, 1, 3, 1, 3, 3);
Selection pipes = util.select.fromTo(3, 1, 2, 2, 1, 3);
Selection cog = util.select.position(4, 1, 2);
BlockPos cTankPos = util.grid.at(3, 1, 1);
BlockPos pumpPos = util.grid.at(3, 1, 2);
ElementLink<WorldSectionElement> cTankLink = scene.world.showIndependentSection(cTank, Direction.DOWN);
scene.world.moveSection(cTankLink, util.vector.of(-1, 0, 1), 0);
scene.overlay.showText(70)
.text("Creative Fluid Tanks can be used to provide a bottomless supply of fluid")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.WEST));
scene.idle(80);
ItemStack bucket = new ItemStack(Items.LAVA_BUCKET);
scene.overlay.showControls(
new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH), Pointing.RIGHT)
.rightClick()
.withItem(bucket),
40);
scene.idle(7);
scene.world.modifyTileEntity(cTankPos, CreativeFluidTankTileEntity.class,
te -> ((CreativeSmartFluidTank) te.getTankInventory())
.setContainedFluid(new FluidStack(Fluids.FLOWING_LAVA, 1000)));
scene.idle(5);
scene.overlay.showText(50)
.text("Right-Click with a fluid containing item to configure it")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.WEST));
scene.idle(60);
scene.world.moveSection(cTankLink, util.vector.of(1, 0, -1), 6);
scene.idle(7);
scene.world.showSection(tank, Direction.DOWN);
scene.idle(5);
scene.world.showSection(largeCog, Direction.UP);
scene.world.showSection(cog, Direction.NORTH);
scene.world.showSection(pipes, Direction.NORTH);
scene.world.multiplyKineticSpeed(util.select.everywhere(), -1);
scene.world.propagatePipeChange(pumpPos);
scene.effects.rotationDirectionIndicator(pumpPos);
scene.idle(40);
scene.overlay.showText(70)
.text("Pipe Networks can now endlessly draw the assigned fluid from the tank")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(util.grid.at(3, 1, 2), Direction.WEST));
scene.idle(120);
scene.world.multiplyKineticSpeed(util.select.everywhere(), -1);
scene.world.propagatePipeChange(pumpPos);
scene.effects.rotationDirectionIndicator(pumpPos);
scene.idle(40);
scene.overlay.showText(70)
.text("Any Fluids pushed back into a Creative Fluid Tank will be voided")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(util.grid.at(3, 1, 2), Direction.WEST));
scene.idle(40);
}

View File

@ -1,73 +1,358 @@
package com.simibubi.create.foundation.ponder.content.fluid;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyFluidHandler;
import com.simibubi.create.content.contraptions.fluids.actors.HosePulleyTileEntity;
import com.simibubi.create.foundation.ponder.ElementLink;
import com.simibubi.create.foundation.ponder.SceneBuilder;
import com.simibubi.create.foundation.ponder.SceneBuildingUtil;
import com.simibubi.create.foundation.ponder.Selection;
import com.simibubi.create.foundation.ponder.content.PonderPalette;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
import net.minecraft.block.Blocks;
import net.minecraft.fluid.Fluids;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
public class HosePulleyScenes {
public static void intro(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("hose_pulley", "Source Filling and Draining using Hose Pulleys");
scene.configureBasePlate(0, 0, 5);
scene.world.showSection(util.select.layer(0), Direction.UP);
scene.configureBasePlate(0, 0, 3);
scene.setSceneOffsetY(-1);
scene.scaleSceneView(.9f);
scene.showBasePlate();
scene.idle(5);
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
/*
* Hose Pulleys can be used to fill or drain large bodies of Fluid
*
* With the Kinetic Input, the height of the pulleys' hose can be controlled
*
* The Pulley will retract when the input rotation is inverted
*
* Once the hose is in position, an attached pipe network can either provide fluid to the Hose Pulley...
*
* ...or pull from it, draining the pool instead
*
* Fill and Drain speed of the pulley depend entirely on the fluid networks' throughput
*/
Selection cogs = util.select.fromTo(3, 1, 2, 3, 2, 2);
Selection pipes = util.select.fromTo(3, 1, 1, 3, 5, 1)
.add(util.select.position(2, 5, 1));
BlockPos hosePos = util.grid.at(1, 5, 1);
Selection hose = util.select.position(1, 5, 1);
Selection crank = util.select.position(0, 5, 1);
ElementLink<WorldSectionElement> hoselink = scene.world.showIndependentSection(hose, Direction.UP);
scene.world.moveSection(hoselink, util.vector.of(0, -1, 0), 0);
scene.idle(10);
Vector3d shaftInput = util.vector.blockSurface(hosePos.down(), Direction.WEST);
scene.overlay.showText(70)
.text("Hose Pulleys can be used to fill or drain large bodies of Fluid")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.topOf(hosePos.down()));
scene.idle(80);
scene.overlay.showText(80)
.text("With the Kinetic Input, the height of the pulleys' hose can be controlled")
.attachKeyFrame()
.placeNearTarget()
.pointAt(shaftInput);
scene.idle(40);
scene.world.showSectionAndMerge(crank, Direction.EAST, hoselink);
scene.idle(20);
Selection kinetics = util.select.fromTo(1, 5, 1, 0, 5, 1);
scene.world.setKineticSpeed(kinetics, 32);
scene.idle(50);
scene.world.setKineticSpeed(kinetics, 0);
scene.overlay.showText(80)
.text("The Pulley retracts while the input rotation is inverted")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.centerOf(hosePos.down(3)));
scene.idle(30);
scene.world.setKineticSpeed(kinetics, -32);
scene.idle(16);
scene.world.setKineticSpeed(kinetics, 0);
scene.idle(10);
scene.rotateCameraY(70);
scene.idle(40);
scene.overlay.showText(60)
.text("On the opposite side, pipes can be connected")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(hosePos.down(), Direction.EAST));
scene.idle(70);
scene.rotateCameraY(-70);
scene.idle(10);
scene.world.showSectionAndMerge(cogs, Direction.NORTH, hoselink);
scene.world.showSectionAndMerge(pipes, Direction.WEST, hoselink);
scene.world.showSection(util.select.fromTo(0, 1, 0, 2, 2, 2), Direction.UP);
scene.idle(10);
scene.overlay.showText(70)
.text("Attached pipe networks can either provide fluid to the hose...")
.attachKeyFrame()
.pointAt(util.vector.centerOf(util.grid.at(3, 1, 1)));
scene.idle(40);
List<BlockPos> blocks = new LinkedList<>();
for (int y = 1; y < 3; y++) {
blocks.add(util.grid.at(1, y, 1));
blocks.add(util.grid.at(0, y, 1));
blocks.add(util.grid.at(1, y, 0));
blocks.add(util.grid.at(2, y, 1));
blocks.add(util.grid.at(1, y, 2));
blocks.add(util.grid.at(0, y, 0));
blocks.add(util.grid.at(2, y, 0));
blocks.add(util.grid.at(2, y, 2));
blocks.add(util.grid.at(0, y, 2));
}
for (BlockPos blockPos : blocks) {
scene.world.setBlock(blockPos, Blocks.WATER.getDefaultState(), false);
scene.idle(3);
}
scene.world.multiplyKineticSpeed(util.select.fromTo(3, 1, 2, 3, 2, 1), -1);
scene.world.modifyTileEntity(util.grid.at(1, 5, 1), HosePulleyTileEntity.class, te -> te
.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.ifPresent(
ifh -> ((HosePulleyFluidHandler) ifh).fill(new FluidStack(Fluids.WATER, 100), FluidAction.EXECUTE)));
scene.world.propagatePipeChange(util.grid.at(3, 2, 1));
scene.idle(40);
scene.world.setKineticSpeed(kinetics, 32);
scene.idle(16);
scene.world.setKineticSpeed(kinetics, 0);
scene.idle(5);
scene.overlay.showText(70)
.text("...or pull from it, draining the pool instead")
.attachKeyFrame()
.pointAt(util.vector.centerOf(util.grid.at(3, 1, 1)));
scene.idle(40);
Collections.reverse(blocks);
for (BlockPos blockPos : blocks) {
scene.world.destroyBlock(blockPos);
scene.idle(3);
}
scene.idle(20);
scene.overlay.showText(120)
.text("Fill and Drain speed of the pulley depends entirely on the fluid networks' throughput")
.placeNearTarget()
.colored(PonderPalette.MEDIUM)
.attachKeyFrame()
.pointAt(util.vector.centerOf(util.grid.at(3, 1, 1)));
scene.idle(40);
}
public static void level(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("hose_pulley_level", "Fill and Drain level of Hose Pulleys");
scene.configureBasePlate(0, 0, 5);
scene.world.showSection(util.select.layer(0), Direction.UP);
scene.configureBasePlate(0, 0, 3);
scene.setSceneOffsetY(-1.5f);
scene.scaleSceneView(.9f);
scene.showBasePlate();
List<BlockPos> blocks = new LinkedList<>();
for (int y = 1; y < 4; y++) {
blocks.add(util.grid.at(1, y, 1));
blocks.add(util.grid.at(0, y, 1));
blocks.add(util.grid.at(1, y, 0));
blocks.add(util.grid.at(2, y, 1));
blocks.add(util.grid.at(1, y, 2));
blocks.add(util.grid.at(0, y, 0));
blocks.add(util.grid.at(2, y, 0));
blocks.add(util.grid.at(2, y, 2));
blocks.add(util.grid.at(0, y, 2));
}
for (BlockPos blockPos : blocks)
scene.world.setBlock(blockPos, Blocks.WATER.getDefaultState(), false);
scene.idle(5);
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
/*
* While fully retracted, the Hose Pulley cannot operate
*
* Draining runs from top to bottom
*
* The surface level will end up just below where the hose ends
*
* Filling runs from bottom to top
*
* The filled pool will not grow beyond the layer above the hose end
*/
Selection water = util.select.fromTo(2, 1, 0, 0, 4, 2);
scene.world.showSection(water, Direction.UP);
scene.idle(10);
Selection cogs = util.select.fromTo(3, 1, 2, 3, 2, 2);
Selection pipes = util.select.fromTo(3, 1, 1, 3, 6, 1)
.add(util.select.position(2, 6, 1));
BlockPos hosePos = util.grid.at(1, 6, 1);
Selection hose = util.select.position(1, 6, 1);
Selection crank = util.select.position(0, 6, 1);
ElementLink<WorldSectionElement> hoselink = scene.world.showIndependentSection(hose, Direction.DOWN);
scene.world.moveSection(hoselink, util.vector.of(0, -1, 0), 0);
scene.idle(10);
scene.world.showSectionAndMerge(crank, Direction.EAST, hoselink);
scene.idle(20);
scene.overlay.showSelectionWithText(util.select.position(hosePos.down()), 50)
.text("While fully retracted, the Hose Pulley cannot operate")
.placeNearTarget()
.colored(PonderPalette.RED)
.attachKeyFrame()
.pointAt(util.vector.blockSurface(hosePos.down(), Direction.UP));
scene.idle(55);
Selection kinetics = util.select.fromTo(1, 6, 1, 0, 6, 1);
scene.world.setKineticSpeed(kinetics, 32);
scene.idle(50);
scene.world.setKineticSpeed(kinetics, 0);
scene.overlay.showText(40)
.text("Draining runs from top to bottom")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.centerOf(hosePos.down(3)));
scene.idle(10);
scene.world.showSectionAndMerge(cogs, Direction.NORTH, hoselink);
scene.world.showSectionAndMerge(pipes, Direction.WEST, hoselink);
scene.world.multiplyKineticSpeed(util.select.fromTo(3, 1, 2, 3, 2, 1), -1);
scene.world.modifyTileEntity(util.grid.at(1, 6, 1), HosePulleyTileEntity.class, te -> te
.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.ifPresent(
ifh -> ((HosePulleyFluidHandler) ifh).fill(new FluidStack(Fluids.WATER, 100), FluidAction.EXECUTE)));
scene.world.propagatePipeChange(util.grid.at(3, 2, 1));
Vector3d surface = util.vector.topOf(1, 3, 1)
.subtract(0, 2 / 8f, 0);
AxisAlignedBB bb = new AxisAlignedBB(surface, surface).grow(1.5, 0, 1.5);
scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, bb, bb, 3);
scene.idle(3);
scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, bb, bb.expand(0, -2, 0), 70);
scene.idle(20);
Collections.reverse(blocks);
int i = 0;
for (BlockPos blockPos : blocks) {
if (i++ == 18)
break;
scene.world.destroyBlock(blockPos);
scene.idle(3);
}
scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, bb, bb.offset(0, -2, 0), 60);
scene.overlay.showText(60)
.text("The surface level will end up just below where the hose ends")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.of(0, 2 - 1 / 8f, 1.5f));
scene.idle(30);
scene.idle(10);
scene.world.multiplyKineticSpeed(util.select.fromTo(3, 1, 2, 3, 2, 1), -1);
scene.world.propagatePipeChange(util.grid.at(3, 2, 1));
scene.idle(30);
scene.world.hideSection(water, Direction.SOUTH);
scene.idle(15);
for (BlockPos blockPos : blocks)
scene.world.destroyBlock(blockPos);
scene.world.showSection(water, Direction.UP);
scene.idle(15);
scene.world.setKineticSpeed(kinetics, -32);
scene.idle(16);
scene.world.setKineticSpeed(kinetics, 0);
scene.overlay.showText(40)
.text("Filling runs from bottom to top")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.centerOf(hosePos.down(3)));
scene.idle(10);
scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, bb, bb.offset(0, -3 + 2 / 8f, 0), 3);
scene.idle(3);
scene.overlay.chaseBoundingBoxOutline(PonderPalette.MEDIUM, bb, bb.expand(0, -3 + 2 / 8f, 0), 120);
scene.idle(20);
scene.world.setBlock(util.grid.at(1, 3, 1), Blocks.WATER.getDefaultState(), false);
scene.idle(3);
scene.world.setBlock(util.grid.at(1, 2, 1), Blocks.WATER.getDefaultState(), false);
scene.idle(3);
Collections.reverse(blocks);
for (BlockPos blockPos : blocks) {
scene.world.setBlock(blockPos, Blocks.WATER.getDefaultState(), false);
scene.idle(3);
}
scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, bb, bb, 100);
scene.overlay.showText(100)
.text("The filled pool will not grow beyond the layer above the hose end")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.of(0, 4 - 1 / 8f, 1.5f));
scene.idle(80);
}
public static void infinite(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("hose_pulley_infinite", "Passively Filling and Draining large bodies of Fluid");
scene.configureBasePlate(0, 0, 5);
scene.world.showSection(util.select.layer(0), Direction.UP);
scene.setSceneOffsetY(-.5f);
scene.scaleSceneView(.9f);
scene.showBasePlate();
scene.idle(5);
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
/*
* When deploying the Hose Pulley into a large enough ocean...
*
* It will simply provide/dispose fluids without affecting the source
*
* Pipe networks can limitlessly pull or push fluids to and from such pulleys
*
* After such a state is reached, your goggles will display an indicator when looking at it
*/
Selection tank = util.select.fromTo(4, 1, 1, 4, 3, 1);
Selection pipes = util.select.fromTo(3, 1, 1, 2, 3, 2);
Selection kinetics = util.select.fromTo(5, 1, 2, 4, 2, 2)
.add(util.select.position(5, 0, 2));
Selection hose = util.select.fromTo(1, 3, 2, 0, 3, 2);
BlockPos pumpPos = util.grid.at(3, 2, 2);
scene.world.showSection(hose, Direction.UP);
scene.idle(5);
scene.world.showSection(tank, Direction.DOWN);
scene.idle(10);
scene.world.showSection(pipes, Direction.NORTH);
scene.idle(5);
scene.world.showSection(kinetics, Direction.DOWN);
scene.idle(10);
scene.world.setKineticSpeed(hose, 32);
scene.idle(10);
Vector3d entryPoint = util.vector.topOf(1, 0, 2);
scene.overlay.showText(60)
.text("When deploying the Hose Pulley into a large enough ocean...")
.attachKeyFrame()
.placeNearTarget()
.pointAt(entryPoint);
scene.idle(40);
scene.world.setKineticSpeed(hose, 0);
scene.world.multiplyKineticSpeed(util.select.everywhere(), -1);
scene.world.propagatePipeChange(pumpPos);
scene.effects.rotationDirectionIndicator(pumpPos);
scene.idle(30);
Selection pulleyPos = util.select.position(1, 3, 2);
scene.overlay.showSelectionWithText(pulleyPos, 60)
.text("It will provide/dispose fluids without affecting the source")
.attachKeyFrame()
.colored(PonderPalette.BLUE)
.placeNearTarget()
.pointAt(util.vector.topOf(util.grid.at(1, 3, 2)));
scene.idle(80);
scene.overlay.showText(60)
.text("Pipe networks can limitlessly take fluids from/to such pulleys")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector.blockSurface(util.grid.at(3, 2, 2), Direction.WEST));
scene.idle(40);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.