From c73e3166cbe433125f10bd43599896fccdcbce68 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 11 Mar 2021 03:32:18 +0100 Subject: [PATCH] Contraption Ponder Push - Scenes for Pulley, Piston, and Clockwork Bearing --- .../bearing/ClockworkBearingTileEntity.java | 13 +- .../bearing/IBearingTileEntity.java | 2 + .../pulley/PulleyRenderer.java | 6 +- .../pulley/PulleyTileEntity.java | 20 ++ .../create/foundation/ponder/PonderScene.java | 9 +- .../ponder/content/BearingScenes.java | 138 ++++++++- .../ponder/content/PistonScenes.java | 279 ++++++++++++++++++ .../ponder/content/PonderIndex.java | 22 ++ .../ponder/content/PulleyScenes.java | 221 ++++++++++++++ .../foundation/ponder/content/SharedText.java | 1 + .../AnimateTileEntityInstruction.java | 8 +- .../DisplayWorldSectionInstruction.java | 2 + .../MarkAsFinishedInstruction.java | 5 + .../resources/ponder/clockwork_bearing.nbt | Bin 0 -> 882 bytes .../ponder/mechanical_piston/anchor.nbt | Bin 0 -> 904 bytes .../ponder/mechanical_piston/modes.nbt | Bin 0 -> 878 bytes .../ponder/mechanical_piston/piston_pole.nbt | Bin 0 -> 782 bytes .../resources/ponder/rope_pulley/anchor.nbt | Bin 0 -> 742 bytes .../ponder/rope_pulley/attachment.nbt | Bin 0 -> 874 bytes .../resources/ponder/rope_pulley/modes.nbt | Bin 0 -> 679 bytes 20 files changed, 712 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/PistonScenes.java create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/PulleyScenes.java create mode 100644 src/main/resources/ponder/clockwork_bearing.nbt create mode 100644 src/main/resources/ponder/mechanical_piston/anchor.nbt create mode 100644 src/main/resources/ponder/mechanical_piston/modes.nbt create mode 100644 src/main/resources/ponder/mechanical_piston/piston_pole.nbt create mode 100644 src/main/resources/ponder/rope_pulley/anchor.nbt create mode 100644 src/main/resources/ponder/rope_pulley/attachment.nbt create mode 100644 src/main/resources/ponder/rope_pulley/modes.nbt diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index 49cba252a..197637276 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -28,7 +28,8 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; -public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions { +public class ClockworkBearingTileEntity extends KineticTileEntity + implements IBearingTileEntity, IDisplayAssemblyExceptions { protected ControlledContraptionEntity hourHand; protected ControlledContraptionEntity minuteHand; @@ -40,9 +41,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe protected boolean running; protected boolean assembleNextTick; protected AssemblyException lastException; - protected ScrollOptionBehaviour operationMode; + private float prevForcedAngle; + public ClockworkBearingTileEntity(TileEntityType type) { super(type); setLazyTickRate(3); @@ -67,6 +69,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe super.tick(); if (world.isRemote) { + prevForcedAngle = hourAngle; clientMinuteAngleDiff /= 2; clientHourAngleDiff /= 2; } @@ -341,6 +344,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe @Override public float getInterpolatedAngle(float partialTicks) { + if (isVirtual()) + return MathHelper.lerp(partialTicks, prevForcedAngle, hourAngle); if (hourHand == null || hourHand.isStalled()) partialTicks = 0; return MathHelper.lerp(partialTicks, hourAngle, hourAngle + getHourArmSpeed()); @@ -414,4 +419,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe public boolean shouldRenderAsTE() { return true; } + + public void setAngle(float forcedAngle) { + hourAngle = forcedAngle; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/IBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/IBearingTileEntity.java index f2f9a475d..e729feae4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/IBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/IBearingTileEntity.java @@ -20,5 +20,7 @@ public interface IBearingTileEntity extends IControlContraption { return bearingAxis != axis; }); } + + void setAngle(float forcedAngle); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java index 182e063bb..00d708294 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java @@ -41,9 +41,7 @@ public class PulleyRenderer extends AbstractPulleyRenderer { @Override protected float getOffset(KineticTileEntity te, float partialTicks) { PulleyTileEntity pulley = (PulleyTileEntity) te; - boolean running = pulley.running; - boolean moving = running && (pulley.movedContraption == null || !pulley.movedContraption.isStalled()); - float offset = pulley.getInterpolatedOffset(moving ? partialTicks : 0.5f); + float offset = pulley.getInterpolatedOffset(partialTicks); if (pulley.movedContraption != null) { AbstractContraptionEntity e = pulley.movedContraption; @@ -57,7 +55,7 @@ public class PulleyRenderer extends AbstractPulleyRenderer { @Override protected boolean isRunning(KineticTileEntity te) { - return ((PulleyTileEntity) te).running; + return ((PulleyTileEntity) te).running || te.isVirtual(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index 5fde955e9..f6dbbb33c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -27,6 +27,7 @@ import net.minecraft.util.math.Vec3d; public class PulleyTileEntity extends LinearActuatorTileEntity { protected int initialOffset; + private float prevAnimatedOffset; public PulleyTileEntity(TileEntityType type) { super(type); @@ -41,6 +42,13 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { public double getMaxRenderDistanceSquared() { return super.getMaxRenderDistanceSquared() + offset * offset; } + + @Override + public void tick() { + super.tick(); + if (isVirtual()) + prevAnimatedOffset = offset; + } @Override protected void assemble() throws AssemblyException { @@ -219,4 +227,16 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP); } + @Override + public float getInterpolatedOffset(float partialTicks) { + if (isVirtual()) + return MathHelper.lerp(partialTicks, prevAnimatedOffset, offset); + boolean moving = running && (movedContraption == null || !movedContraption.isStalled()); + return super.getInterpolatedOffset(moving ? partialTicks : 0.5f); + } + + public void animateOffset(float forcedOffset) { + offset = forcedOffset; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java index 1eee89b34..a622c8b8d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java @@ -80,6 +80,7 @@ public class PonderScene { int offsetZ; int size; + boolean stoppedCounting; int totalTime; int currentTime; @@ -189,6 +190,7 @@ public class PonderScene { elements.add(baseWorldSection); totalTime = 0; + stoppedCounting = false; activeSchedule.addAll(schedule); activeSchedule.forEach(i -> i.onScheduled(this)); } @@ -269,7 +271,12 @@ public class PonderScene { } public void addToSceneTime(int time) { - totalTime += time; + if (!stoppedCounting) + totalTime += time; + } + + public void stopCounting() { + stoppedCounting = true; } public void addElement(PonderElement e) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java index 9ba29fd57..a1526380d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java @@ -327,9 +327,10 @@ public class BearingScenes { scene.overlay.showText(60) .pointAt(util.vector.blockSurface(bearingPos, Direction.WEST)) .placeNearTarget() - .text("This behaviour can be modified using a Wrench"); + .sharedText("behaviour_modify_wrench"); scene.idle(70); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); scene.world.toggleRedstonePower(cogAndClutch); scene.effects.indicateRedstone(leverPos); scene.world.rotateSection(contraption, 0, -55, 0, 23); @@ -343,7 +344,6 @@ public class BearingScenes { scene.overlay.showText(120) .colored(PonderPalette.GREEN) .pointAt(util.vector.blockSurface(util.grid.at(3, 1, 3), Direction.UP)) - .placeNearTarget() .text("It can be configured never to revert to solid blocks, or only near the angle it started at"); } @@ -410,11 +410,143 @@ public class BearingScenes { scene.world.rotateSection(contraption, 0, 0, 360 * 2, 74 * 2); scene.world.rotateBearing(bearingPos, -360 * 2, 74 * 2); scene.world.rotateSection(subContraption, 0, 0, 360 * 2, 74 * 2); - + scene.markAsFinished(); scene.idle(74 * 2); scene.world.setKineticSpeed(largeCog, 0); scene.world.setKineticSpeed(beltAndBearing, 0); } + public static void clockwork(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("clockwork_bearing", "Animating Structures using Clockwork Bearings"); + + Selection kinetics = util.select.fromTo(3, 3, 4, 3, 1, 6); + Selection largeCog = util.select.position(2, 0, 6); + BlockPos bearingPos = util.grid.at(3, 3, 3); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + scene.world.showSection(kinetics, Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(bearingPos), Direction.DOWN); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.position(bearingPos.north()), 60) + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(bearingPos, Direction.WEST)) + .placeNearTarget() + .text("Clockwork Bearings attach to blocks in front of them"); + scene.idle(50); + + ElementLink plank = + scene.world.showIndependentSection(util.select.position(2, 3, 2), Direction.SOUTH); + scene.world.moveSection(plank, util.vector.of(1, 0, 0), 0); + scene.idle(20); + + scene.world.rotateSection(plank, 0, 0, 60, 25); + scene.world.rotateBearing(bearingPos, 60, 25); + scene.world.setKineticSpeed(kinetics, 8); + scene.world.setKineticSpeed(largeCog, -4); + + scene.idle(25); + scene.overlay.showText(80) + .pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH)) + .placeNearTarget() + .text("Upon receiving Rotational Force, the structure will be rotated according to the hour of the day"); + scene.idle(90); + + scene.overlay.showText(30) + .pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH)) + .placeNearTarget() + .text("3:00"); + scene.world.rotateSection(plank, 0, 0, 30, 12); + scene.world.rotateBearing(bearingPos, 30, 12); + scene.idle(42); + scene.overlay.showText(30) + .pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH)) + .placeNearTarget() + .text("4:00"); + scene.world.rotateSection(plank, 0, 0, 30, 12); + scene.world.rotateBearing(bearingPos, 30, 12); + scene.idle(42); + + InputWindowElement clickTheBearing = new InputWindowElement(util.vector.topOf(bearingPos), Pointing.DOWN); + InputWindowElement clickTheBearingSide = + new InputWindowElement(util.vector.blockSurface(bearingPos, Direction.WEST), Pointing.LEFT); + + scene.overlay.showControls(clickTheBearing.rightClick(), 60); + scene.idle(7); + scene.world.rotateSection(plank, 0, 0, -120, 0); + scene.world.rotateBearing(bearingPos, -120, 0); + scene.overlay.showText(60) + .pointAt(util.vector.blockSurface(bearingPos, Direction.WEST)) + .placeNearTarget() + .text("Right-Click the bearing to start or stop animating the structure"); + scene.idle(70); + + scene.world.hideIndependentSection(plank, Direction.NORTH); + scene.idle(15); + + ElementLink hourHand = + scene.world.showIndependentSection(util.select.fromTo(3, 3, 1, 3, 5, 2), Direction.SOUTH); + scene.world.configureCenterOfRotation(hourHand, util.vector.centerOf(bearingPos)); + scene.idle(15); + scene.overlay.showSelectionWithText(util.select.fromTo(3, 3, 1, 3, 4, 2), 80) + .placeNearTarget() + .sharedText("movement_anchors"); + scene.idle(90); + + scene.overlay.showControls(clickTheBearingSide.rightClick(), 20); + scene.idle(7); + scene.world.rotateSection(hourHand, 0, 0, 120, 50); + scene.world.rotateBearing(bearingPos, 120, 50); + scene.idle(60); + + scene.overlay.showSelectionWithText(util.select.position(bearingPos.north(3)), 80) + .placeNearTarget() + .colored(PonderPalette.BLUE) + .text("In front of the Hour Hand, a second structure can be added"); + scene.idle(90); + scene.overlay.showControls(clickTheBearingSide.rightClick(), 20); + scene.idle(7); + scene.world.rotateSection(hourHand, 0, 0, -120, 0); + scene.world.rotateBearing(bearingPos, -120, 0); + scene.idle(10); + + ElementLink minuteHand = + scene.world.showIndependentSection(util.select.fromTo(3, 3, 0, 3, 6, 0), Direction.SOUTH); + scene.world.configureCenterOfRotation(minuteHand, util.vector.centerOf(bearingPos)); + scene.idle(30); + + scene.overlay.showOutline(PonderPalette.BLUE, minuteHand, util.select.fromTo(3, 3, 0, 3, 6, 0), 85); + scene.overlay.showSelectionWithText(util.select.fromTo(3, 3, 1, 3, 4, 2), 80) + .placeNearTarget() + .colored(PonderPalette.GREEN) + .text("Ensure the two Structures are not attached to each other through super glue or similar"); + scene.idle(90); + + scene.overlay.showControls(clickTheBearingSide.rightClick(), 20); + scene.idle(7); + + scene.world.rotateSection(hourHand, 0, 0, 120, 50); + scene.world.rotateSection(minuteHand, 0, 0, 180, 75); + scene.world.rotateBearing(bearingPos, 120, 50); + scene.idle(90); + scene.world.rotateSection(minuteHand, 0, 0, 6, 3); + + scene.overlay.showText(80) + .placeNearTarget() + .pointAt(util.vector.blockSurface(bearingPos.north(3), Direction.NORTH)) + .colored(PonderPalette.GREEN) + .text("The Second Structure will now rotate as the Minute Hand"); + scene.markAsFinished(); + + for (int i = 0; i < 40; i++) { + scene.idle(23); + scene.world.rotateSection(minuteHand, 0, 0, 6, 3); + if (i == 29) + scene.world.rotateSection(hourHand, 0, 0, 30, 20); + } + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PistonScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PistonScenes.java new file mode 100644 index 000000000..28706d1fa --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PistonScenes.java @@ -0,0 +1,279 @@ +package com.simibubi.create.foundation.ponder.content; + +import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonHeadBlock; +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.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.ParrotElement; +import com.simibubi.create.foundation.ponder.elements.ParrotElement.FaceCursorPose; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.block.DoublePlantBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.state.properties.DoubleBlockHalf; +import net.minecraft.state.properties.PistonType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; + +public class PistonScenes { + + public static void movement(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_piston", "Moving Structures using Mechanical Pistons"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0) + .add(util.select.position(0, 1, 2)), Direction.UP); + + Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2); + BlockPos piston = util.grid.at(3, 1, 2); + BlockPos leverPos = util.grid.at(3, 2, 4); + BlockPos shaft = util.grid.at(3, 1, 3); + + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(piston), Direction.DOWN); + ElementLink contraption = + scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN); + scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0); + scene.idle(20); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east()), Direction.DOWN, contraption); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east(2)), Direction.DOWN, contraption); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .west()), Direction.DOWN, contraption); + scene.idle(15); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + scene.overlay.showText(55) + .pointAt(util.vector.topOf(piston)) + .placeNearTarget() + .text("Mechanical Pistons can move blocks in front of them"); + scene.idle(65); + + scene.overlay.showText(45) + .pointAt(util.vector.blockSurface(shaft, Direction.SOUTH)) + .placeNearTarget() + .text("Speed and direction of movement depend on the Rotational Input"); + scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.AIR.getDefaultState(), false); + scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.OAK_PLANKS.getDefaultState(), false); + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40); + scene.idle(60); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(piston, Direction.WEST), Pointing.DOWN).rightClick() + .withItem(new ItemStack(Items.SLIME_BALL)), + 30); + scene.idle(7); + scene.world.modifyBlock(piston.north(), s -> s.with(MechanicalPistonHeadBlock.TYPE, PistonType.STICKY), false); + scene.effects.superGlue(piston, Direction.WEST, true); + + scene.idle(33); + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + + scene.idle(25); + scene.overlay.showText(60) + .pointAt(util.vector.topOf(piston)) + .placeNearTarget() + .text("Sticky Mechanical Pistons can pull the attached blocks back"); + scene.idle(20); + scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.OAK_PLANKS.getDefaultState(), false); + scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.AIR.getDefaultState(), false); + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40); + + scene.idle(50); + scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.AIR.getDefaultState(), false); + ElementLink chassis = + scene.world.showIndependentSection(util.select.fromTo(2, 2, 0, 2, 3, 2), Direction.DOWN); + scene.world.moveSection(chassis, util.vector.of(0, -1, 1), 0); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(1, 2, 0), Direction.EAST, chassis); + scene.idle(15); + scene.effects.superGlue(piston.west() + .north(), Direction.WEST, true); + scene.overlay.showText(80) + .pointAt(util.vector.topOf(piston.west())) + .placeNearTarget() + .sharedText("movement_anchors"); + + scene.idle(90); + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + scene.world.moveSection(chassis, util.vector.of(-2, 0, 0), 40); + } + + public static void poles(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("piston_pole", "Piston Extension Poles"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f); + + Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2); + BlockPos piston = util.grid.at(3, 1, 2); + + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(piston), Direction.DOWN); + ElementLink contraption = + scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN); + scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0); + scene.idle(20); + + BlockPos leverPos = util.grid.at(3, 2, 4); + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.setKineticSpeed(kinetics, 16); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.position(piston), 50) + .colored(PonderPalette.RED) + .placeNearTarget() + .text("Without attached Poles, a Mechanical Piston cannot move"); + scene.idle(60); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.setKineticSpeed(kinetics, 0); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east()), Direction.DOWN, contraption); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east(2)), Direction.DOWN, contraption); + scene.idle(10); + + scene.overlay.showOutline(PonderPalette.RED, new Object(), util.select.fromTo(piston.east(), piston.east(2)), + 100); + scene.overlay.showSelectionWithText(util.select.fromTo(piston.west(), piston.west(2)), 100) + .text("The Length of pole added at its back determines the Extension Range") + .placeNearTarget() + .colored(PonderPalette.GREEN); + scene.idle(110); + + scene.world.showSectionAndMerge(util.select.position(piston.north() + .west()), Direction.EAST, contraption); + scene.idle(10); + ElementLink birb = + scene.special.createBirb(util.vector.topOf(piston.west()), FaceCursorPose::new); + scene.idle(15); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.setKineticSpeed(kinetics, 16); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + scene.special.moveParrot(birb, util.vector.of(-2, 0, 0), 40); + + } + + public static void movementModes(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_piston_modes", "Movement Modes of the Mechanical Piston"); + scene.configureBasePlate(0, 0, 5); + Selection rose = util.select.fromTo(0, 2, 2, 0, 1, 2); + scene.world.showSection(util.select.layer(0) + .add(rose), Direction.UP); + + Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2); + BlockPos piston = util.grid.at(3, 1, 2); + BlockPos leverPos = util.grid.at(3, 2, 4); + BlockPos shaft = util.grid.at(3, 1, 3); + + scene.idle(5); + scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(piston), Direction.DOWN); + ElementLink contraption = + scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN); + scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0); + scene.idle(20); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east()), Direction.DOWN, contraption); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .east(2)), Direction.DOWN, contraption); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .west()), Direction.DOWN, contraption); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(piston.north() + .west() + .up()), Direction.DOWN, contraption); + scene.idle(15); + scene.effects.superGlue(piston.west(), Direction.UP, true); + scene.idle(10); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + scene.idle(40); + + scene.world.destroyBlock(util.grid.at(0, 1, 2)); + scene.world.destroyBlock(util.grid.at(0, 2, 2)); + scene.idle(10); + scene.overlay.showSelectionWithText(rose, 70) + .text("Whenever Pistons stop moving, the moved structure reverts to blocks") + .colored(PonderPalette.RED); + scene.idle(80); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40); + scene.world.hideSection(rose, Direction.UP); + scene.idle(50); + + scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.ROSE_BUSH.getDefaultState(), false); + scene.world.setBlock(util.grid.at(0, 2, 2), Blocks.ROSE_BUSH.getDefaultState() + .with(DoublePlantBlock.HALF, DoubleBlockHalf.UPPER), false); + scene.world.showIndependentSection(rose, Direction.DOWN); + scene.overlay.showCenteredScrollInput(piston, Direction.UP, 60); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(piston), Pointing.DOWN).scroll() + .withWrench(), 60); + scene.overlay.showText(70) + .pointAt(util.vector.topOf(piston)) + .placeNearTarget() + .sharedText("behaviour_modify_wrench"); + scene.idle(80); + + scene.effects.indicateRedstone(leverPos); + scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down())); + scene.world.modifyKineticSpeed(kinetics, f -> -f); + scene.effects.rotationDirectionIndicator(shaft); + scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40); + scene.idle(50); + scene.overlay.showText(120) + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(util.grid.at(0, 1, 2), Direction.WEST)) + .placeNearTarget() + .text("It can be configured never to revert to solid blocks, or only at the location it started at"); + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java index 2bbdb6088..67b6c5e68 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -77,6 +77,24 @@ public class PonderIndex { .addStoryBoard("funnels/transposer", FunnelScenes::transposer); PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/brass", FunnelScenes::brass); + // Mechanical Piston + PonderRegistry.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON) + .addStoryBoard("mechanical_piston/anchor", PistonScenes::movement, PonderTag.KINETIC_APPLIANCES, + PonderTag.MOVEMENT_ANCHOR); + PonderRegistry + .forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON, + AllBlocks.PISTON_EXTENSION_POLE) + .addStoryBoard("mechanical_piston/piston_pole", PistonScenes::poles); + PonderRegistry.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON) + .addStoryBoard("mechanical_piston/modes", PistonScenes::movementModes); + + // Windmill Bearing + PonderRegistry.forComponents(AllBlocks.ROPE_PULLEY) + .addStoryBoard("rope_pulley/anchor", PulleyScenes::movement, PonderTag.KINETIC_APPLIANCES, + PonderTag.MOVEMENT_ANCHOR) + .addStoryBoard("rope_pulley/modes", PulleyScenes::movementModes) + .addStoryBoard("rope_pulley/attachment", PulleyScenes::attachment); + // Windmill Bearing PonderRegistry.forComponents(AllBlocks.WINDMILL_BEARING) .addStoryBoard("windmill_bearing/source", BearingScenes::windmillsAsSource, PonderTag.KINETIC_SOURCES) @@ -91,6 +109,10 @@ public class PonderIndex { .addStoryBoard("mechanical_bearing/stabilized", BearingScenes::stabilizedBearings, PonderTag.CONTRAPTION_ACTOR); + // Clockwork Bearing + PonderRegistry.addStoryBoard(AllBlocks.CLOCKWORK_BEARING, "clockwork_bearing", BearingScenes::clockwork, + PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR); + // Gantries PonderRegistry.addStoryBoard(AllBlocks.GANTRY_SHAFT, "gantry/intro", GantryScenes::introForShaft, PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PulleyScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PulleyScenes.java new file mode 100644 index 000000000..b4712e67c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PulleyScenes.java @@ -0,0 +1,221 @@ +package com.simibubi.create.foundation.ponder.content; + +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.elements.InputWindowElement; +import com.simibubi.create.foundation.ponder.elements.WorldSectionElement; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; + +public class PulleyScenes { + + public static void movement(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("rope_pulley", "Moving Structures using Rope Pulleys"); + scene.configureBasePlate(0, 0, 8); + + Selection reversable = util.select.fromTo(2, 3, 4, 2, 4, 2); + BlockPos leverPos = util.grid.at(1, 2, 4); + BlockPos pulleyPos = util.grid.at(2, 4, 2); + Selection redstoneStuff = util.select.fromTo(leverPos, leverPos.east()); + + scene.world.showSection(util.select.layer(0), Direction.UP); + ElementLink plank = + scene.world.showIndependentSection(util.select.position(2, 1, 2), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 4, 3, 2, 1, 4), Direction.DOWN); + scene.idle(10); + + scene.world.showSection(util.select.position(pulleyPos), Direction.SOUTH); + scene.idle(20); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, 2, 40); + + scene.idle(45); + scene.overlay.showText(60) + .pointAt(util.vector.blockSurface(pulleyPos, Direction.WEST)) + .text("Rope Pulleys can move blocks vertically when given Rotational Force") + .placeNearTarget(); + scene.idle(70); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, -2, 40); + scene.world.moveSection(plank, util.vector.of(0, 2, 0), 40); + scene.idle(60); + + scene.overlay.showText(60) + .pointAt(util.vector.blockSurface(pulleyPos, Direction.SOUTH)) + .text("Direction and Speed of movement depend on the Rotational Input") + .placeNearTarget(); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, 2, 40); + scene.world.moveSection(plank, util.vector.of(0, -2, 0), 40); + scene.idle(50); + + scene.world.hideIndependentSection(plank, Direction.NORTH); + scene.idle(15); + ElementLink chassis = + scene.world.showIndependentSection(util.select.fromTo(2, 1, 1, 0, 2, 1), Direction.SOUTH); + scene.world.moveSection(chassis, util.vector.of(1, 0, 1), 0); + scene.idle(5); + scene.world.showSectionAndMerge(util.select.position(2, 1, 0), Direction.SOUTH, chassis); + scene.idle(15); + scene.effects.superGlue(util.grid.at(3, 1, 1), Direction.SOUTH, true); + scene.overlay.showText(80) + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.NORTH)) + .placeNearTarget() + .sharedText("movement_anchors"); + scene.idle(90); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, -2, 40); + scene.world.moveSection(chassis, util.vector.of(0, 2, 0), 40); + scene.idle(50); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, 2, 40); + scene.world.moveSection(chassis, util.vector.of(0, -2, 0), 40); + scene.idle(50); + } + + public static void movementModes(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("rope_pulley_modes", "Movement Modes of the Rope Pulley"); + scene.configureBasePlate(0, 0, 8); + + Selection reversable = util.select.fromTo(2, 3, 4, 2, 4, 2); + BlockPos leverPos = util.grid.at(1, 2, 4); + BlockPos pulleyPos = util.grid.at(2, 4, 2); + Selection redstoneStuff = util.select.fromTo(leverPos, leverPos.east()); + BlockPos flowerPos = util.grid.at(2, 1, 2); + + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.showSection(util.select.position(flowerPos), Direction.UP); + scene.idle(5); + scene.world.showSection(util.select.fromTo(1, 4, 3, 2, 1, 4), Direction.DOWN); + scene.idle(10); + + scene.world.showSection(util.select.position(pulleyPos), Direction.SOUTH); + ElementLink glass = + scene.world.showIndependentSection(util.select.position(pulleyPos.down()), Direction.UP); + scene.idle(20); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, 2, 40); + scene.world.moveSection(glass, util.vector.of(0, -2, 0), 40); + scene.idle(40); + + scene.world.destroyBlock(flowerPos); + scene.idle(10); + scene.overlay.showSelectionWithText(util.select.position(flowerPos), 70) + .text("Whenever Pulleys stop moving, the moved structure reverts to blocks") + .placeNearTarget() + .colored(PonderPalette.RED); + scene.idle(80); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, -2, 40); + scene.world.moveSection(glass, util.vector.of(0, 2, 0), 40); + scene.world.hideSection(util.select.position(flowerPos), Direction.DOWN); + scene.idle(40); + + scene.world.setBlock(flowerPos, Blocks.BLUE_ORCHID.getDefaultState(), false); + scene.world.showSection(util.select.position(flowerPos), Direction.DOWN); + scene.overlay.showCenteredScrollInput(pulleyPos, Direction.UP, 60); + scene.overlay.showControls(new InputWindowElement(util.vector.topOf(pulleyPos), Pointing.DOWN).scroll() + .withWrench(), 60); + scene.overlay.showText(70) + .pointAt(util.vector.topOf(pulleyPos)) + .placeNearTarget() + .sharedText("behaviour_modify_wrench"); + scene.idle(80); + + scene.world.toggleRedstonePower(redstoneStuff); + scene.effects.indicateRedstone(leverPos); + scene.world.modifyKineticSpeed(reversable, f -> -f); + scene.effects.rotationDirectionIndicator(pulleyPos.south()); + scene.world.movePulley(pulleyPos, 2, 40); + scene.world.moveSection(glass, util.vector.of(0, -2, 0), 40); + scene.idle(50); + scene.overlay.showText(120) + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(flowerPos, Direction.WEST)) + .placeNearTarget() + .text("It can be configured never to revert to solid blocks, or only at the location it started at"); + } + + public static void attachment(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("rope_pulley_attachment", "Moving Pulleys as part of a Contraption"); + scene.configureBasePlate(0, 0, 8); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + Selection kinetics = util.select.fromTo(4, 3, 2, 4, 1, 5); + Selection largeCog = util.select.position(3, 0, 5); + + scene.world.showSection(kinetics, Direction.DOWN); + ElementLink poles = + scene.world.showIndependentSection(util.select.fromTo(4, 4, 2, 6, 4, 2), Direction.DOWN); + scene.world.moveSection(poles, util.vector.of(0, -1, 0), 0); + scene.idle(10); + + BlockPos pulleyPos = util.grid.at(3, 3, 2); + ElementLink pulley = + scene.world.showIndependentSection(util.select.position(pulleyPos), Direction.EAST); + scene.idle(10); + scene.world.showSectionAndMerge(util.select.fromTo(3, 1, 1, 3, 1, 2) + .add(util.select.position(3, 2, 1)), Direction.SOUTH, pulley); + + scene.idle(10); + scene.overlay.showText(50) + .pointAt(util.vector.blockSurface(pulleyPos, Direction.WEST)) + .placeNearTarget() + .text("Whenever Pulleys are themselves being moved by a Contraption..."); + scene.idle(60); + + scene.world.setKineticSpeed(largeCog, -16); + scene.world.setKineticSpeed(kinetics, 32); + scene.effects.rotationDirectionIndicator(util.grid.at(4, 1, 5)); + scene.world.moveSection(poles, util.vector.of(-2, 0, 0), 40); + scene.world.moveSection(pulley, util.vector.of(-2, 0, 0), 40); + scene.idle(40); + + scene.overlay.showSelectionWithText(util.select.fromTo(1, 1, 1, 1, 1, 2), 50) + .colored(PonderPalette.GREEN) + .placeNearTarget() + .text("...its attached structure will be dragged with it"); + scene.idle(60); + scene.overlay.showText(80) + .colored(PonderPalette.RED) + .pointAt(util.vector.topOf(pulleyPos.west(2))) + .placeNearTarget() + .text("Mind that pulleys are only movable while stopped"); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java b/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java index c7e2ed679..73d233ba2 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/SharedText.java @@ -16,6 +16,7 @@ public class SharedText { add("rpm32", "32 RPM"); add("movement_anchors", "With the help of Chassis or Super Glue, larger structures can be moved."); + add("behaviour_modify_wrench", "This behaviour can be modified using a Wrench"); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java index 99e1e8f2b..fd788e53d 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/AnimateTileEntityInstruction.java @@ -4,7 +4,7 @@ import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Function; -import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.IBearingTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderWorld; @@ -24,14 +24,14 @@ public class AnimateTileEntityInstruction extends TickingInstruction { public static AnimateTileEntityInstruction bearing(BlockPos location, float totalDelta, int ticks) { return new AnimateTileEntityInstruction(location, totalDelta, ticks, - (w, f) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)), - (w) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0)) + (w, f) -> castIfPresent(w, location, IBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)), + (w) -> castIfPresent(w, location, IBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0)) .orElse(0f)); } public static AnimateTileEntityInstruction pulley(BlockPos location, float totalDelta, int ticks) { return new AnimateTileEntityInstruction(location, totalDelta, ticks, - (w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.offset = f), + (w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.animateOffset(f)), (w) -> castIfPresent(w, location, PulleyTileEntity.class).map(pulley -> pulley.offset) .orElse(0f)); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java index b0c50333c..d9f5c70fc 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/DisplayWorldSectionInstruction.java @@ -35,6 +35,8 @@ public class DisplayWorldSectionInstruction extends FadeIntoSceneInstruction element.setAnimatedOffset(wse.get() + .getAnimatedOffset(), true)); element.set(initialSelection); element.setVisible(true); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java index a7f2e15b2..ef15e46dd 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/instructions/MarkAsFinishedInstruction.java @@ -14,5 +14,10 @@ public class MarkAsFinishedInstruction extends PonderInstruction { public void tick(PonderScene scene) { scene.setFinished(true); } + + @Override + public void onScheduled(PonderScene scene) { + scene.stopCounting(); + } } diff --git a/src/main/resources/ponder/clockwork_bearing.nbt b/src/main/resources/ponder/clockwork_bearing.nbt new file mode 100644 index 0000000000000000000000000000000000000000..43b4c4f9331c19a3ec7a5bb6a95906a7d5c0fa2c GIT binary patch literal 882 zcmV-&1C9J2iwFP!000000JT=zZreBz9bM@7lC%NZ0!2}v4}IM)$lId3zy{b&igsJH zeGzDBA`78Ofu!R&AGY7uk!;FZRd(6L5g^dA&YU@;xsYRk5yYmr!w3MX`^eoR7^1X= zEzm%9jbJbpD!n#idiZSwQK^hG3SfN&5in!9#f?Q96ZT+&4kq&8i9L9j2anSn?%@f0 zFkPO=gD3XjVIDl8TU(fLM_iFdE+UUy?Bj_&c$f!|)7{2IJ(%z(7#Dl&k<-{Cr~7zf z4<6>h<1{mmd@+xF?c<3(cvvsb7$P~f5llX&S_$!)i$(QfIE1js;7O{HkZ0+P8&jAb zWwp8%V|){4w4C)-8UeHfd|M98J z$Tnaw`b#ZzgAd^7!$QhJ=J10&Sj&6q8?Qt9htid;@$)d47g;9oFl;9 zqiAx@bzXH*zMLV7`*A&WC9s2~{veHcFDElWSq zrkYAUS#t3JDb3^IwDioGlG>H#izvh@QCEqbVRA!ITvg|;Ke*+eQJX?Z+LHf+@7H)} IoS_c@0IqSk<^TWy literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_piston/anchor.nbt b/src/main/resources/ponder/mechanical_piston/anchor.nbt new file mode 100644 index 0000000000000000000000000000000000000000..7bbee5cc9b26aca8678ccaf5a149b4d2570bb317 GIT binary patch literal 904 zcmV;319$u%iwFP!000000L4~KZ`(!?9q~h=2W$KnnzpYvrrG z5NmQo5nApNyQ|1f5Wv4G_vD|nzoIu~D3LNlQ_9A0TLJ_j?aX^K?=6Qr0O*6K(|70s zKyi2J_KIg80u&}SDQYOLK6KByj3#~iRm`tg$7#ek(B4;P16QXdrpe`4;J6kzo&}Cm*3_}+%dzmwvG8jXj%$JAS>UWJweZ5V z@M05=Yk}ig;8d4qp|fY9^CleE0>^8`8GtL!jSE}DNJ-9LF+MF8f&iQ}h94q@6nPkp znbxUpsjT@Hxp#tC-@jgo=z~AZ5#!H`s<)ppZJu64n446J0Q$!=%cY>H1wXytH;M_( zDS!WPe@S?dOw$9R#O$139$=MtAmnMPjTEPnqu&2Os_mW-iC$2>%wtNWVs@Th7!;Zk zo}oz0xF~Y~-JzVSh^A-f&3r!pi=Kbb!XZ8Xr04I1)qBloh>8S!=sq8fG@7GD^}Q1` zGpQy%1jj6AQED!Ky(%Q|hBS^Tr0c`h&vA_L&?waU=&I1c`7NH$|G5JH=rQ3fSB_y} zb?1BBj%JOuYHFC+gsadOp$J*k6-@HK6cAK5@bq`(~ssF* z_b8^9Gmge!ah}``z&l|X!d^yQM~aQi;cT253?nH>7D}oj?q5e}A!p&@P};UC*(A(4 z6BA9X4NjHJQ5C1z0Jb&hI=Kwbr7A7|nWbhS~&`u-#0)rGEq1Eto>arAWe2sg)48C=F9Q zbD5JTLaL1M74oBX%7iNKYut-l$3OxEu4^Gl zn+vffMvP4-D>VbfWl-ZLk-2~L-&l!=v)uz&$B+bxzv@>a=74Y!wi-dbxfxP(`jHF3m(^k z$Ftz6MrRFArv=mGaV&UT3m(sc$0>cPW1JR@a|@;#P7UL((C%2|%dyDUIv&r0XPHuq ze7P3+TF2vB@OTzH)$lCNg=Z1xbv&*GkJrjG09TwDAN*mC7=K&5*?hyaIl722H<=Ux z^bh4Ymx4M1{QPOxC?+%~``!KBNFhD!C6jEAX^rDEKHI~}a8JmSOdBaqBuBmbnLOG) zrcLx>tG9Vfrc|g~M;8W#CWAL95|b8^2hbhLiHfK*b^e&o=YP@sCoSyL{DI~Z;_AI; z)SyHHK6HN@jWn8rh4;N8|NIu^Gu-0qT7P~dt0@28rAPNbo}~X>ew!I zB*>Ibvyr(?!s#jr^~2C@Ncej7!&C8hspCbdW4Njj`86HA|1%Z$)3GuibsfP9O#O1} zx5T4~88k4y1qND<>P8F3X<#0-`0O<5Y?Cm(oN+V;i|?tQ0`QL67-45j(Tfxtnf+;+ z84M#SD7<7;As*czw2;$q@lm#1-MU##IQ3&vH8@c+M^${t1>^zQ%)lQpu5UOW*Q^v- zm81>Z?ug2RdZ0H&ZGuWncPu~B+W@xNMW#c>rAWe2rnG79vbsk$HrkjHOmUec7?&i( zQP4x@a!L1~D!Y{YZc_AeIYmY0o>7xF>+kx<{hX+3pEH#d$x5avBEKKkR>^fImPS%M zGs`I_nhxOkY{~p|Rpi4IS$y|>mc&m=;*t%kYdp;9zHjn+DdQvXd6AhV!^4}>Q&MAi zHqq${!%3ds)sUPjcV_m(eL{MK>f{DILP-AUlyi>+ zAWUKs&?Fx{(z)O=n(01%dEO&lCUxnw9v<Op%$ESI2$-l zgH4^|T5voI4z=L8g{G>F+me@S(F@n27n?Yq1&3O2*6p(Bg=f)=O&rgHLoGPvpcZwe z7Iogl@hmvBk<%xhxG+BPM;X9)^~?4N)8_apg3KgR1f+K)(@YB7?c~L`fl*9oj{bv# zL8Jg5hVeWZGOZ!K;MYSa9fv}mCE7@FCOPQAcT}`{ib3=;)W>X$uDDQlj;{;|jSeRu zVl&NCc1ZXAT!=)(D1B=bDarXchbEf6%+qi)ly+4vSVoL6qGBEGZp70j~7z_{xH@~spmeFT1Tk4&afdus+93H`B_`p!zr-w z{o|~`PYZBCgYvcsGrX4ST#5)lAeU18-JW#-V3hzncdL@aC8+$$dd&ynUfXhvp$*A@w z@kFsbl7dN3c`DBEJiGyyuuAPTB#x`nfHD~+*0KwvQ(8ui{XKpA~?u8Nwc@Pe`Qn9K~XcR2( zNbgRJ&ej>-3PyHk)$WEEeegROV)SEbyzZUSPc?t=K8pzHw4u>S$1wKKeWt}5UPEqHn9Qx3F$ul0tdU8B9 zVAi3wPLRNdoueqisG}t+bvQNZ-IHiG`}H0C!+r8`wen&*PgHO=P7>pMEjMtLn+HX1 zWSU_&8w-Jxij14RwtSv_>-^lPs8JLDRfvy@5LG(b?2rm(P9hKXvRCI{L_^8pJ)lNy0&0Dclta&Fx9>w_J*+bvnEo zN^ysy@vpYjyG_@q|Hsi-Z{@2sYtbjjxInGZyh*m3z)txH;qizf2_^68gM1Kc?1pJV zp^{OFczBIaNt$=(ucK9~DIaz-!IPn)#J1mc!w3W%2Zd-~FNE|?1d4^s%0EbGbMIe496uHUl zZdAvPY`5F?#8dHBJVTjm;%ww*TMKP1McIvKzVDmyjO{5Q6B6n28Ym&8d3NxL@ku5m z1z}24f+o$FkmQuh{7g^r&+7@Hwba(BAC$z}Faw>(&?XqM2^^cy1BZIxL>@SH1b5&B zBQ`Eh=z&8$a3T*JJ3@~@T(Qh4No9O{7+dEnR)dE`0r$n#w| z)B`6P#hDT+P7NiypK~QS|H}AzGm)kwEDQ1|SAdp>`GRR(>Jio^f?>6VTR{v*5%-S- zZY7ML%w`%)V;YnAa}7|CmEYrI{Ha$TzSISJ2LajnbS^|G=H!+j(h7Rg2~x6#tUl)) zuF&fnLnic!Nz$^t`8}F+>WHPC*!zT0a`67rfY7BBA3)5_qP4tN?(@n#y?3PFN?{repn~xrl3sh$2}h!U%eB9VRhWM`!SQ|22Mces(I z+o!R6YCNEsJX|zGn(2s?(Aj8rH`ojtdvAm*a%}b;n|Q?LkzBkmZ|&;0`0}>>`tWO}%!*c-ff`_~8jhYMy=c4< zvu7PPz8^zUl|{kfAt@+`VmtV|OPo<$&ga;nPN7`)2zxg53oN|(JMm)O9W~ZI6xbi AKL7v# literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/rope_pulley/modes.nbt b/src/main/resources/ponder/rope_pulley/modes.nbt new file mode 100644 index 0000000000000000000000000000000000000000..6da97dd80b1a9756f2a5123526196a7380eaf56d GIT binary patch literal 679 zcmV;Y0$BYYiwFP!000000L@lSZ__{!9edYt;tEkADskptw1CtC2YM;cK>4^tTYHjN z-P+df29uuhtGM%@xS}vl?IxIwyS<=pWUb?U^LF0M?AQ^&0Ju)CkO4q-_2>$!c>sOP zOlnfpP>lif&Sf57=!pJ29RMqG-5A{r27xxhU~RF9@hljxh4CGDm;(=Y;Aw`}!Q)vl zZ64o&hdJF68=I1mOvqGFKM?^k0cW#HpFTSyW&? zq*gGVXSf~&xD+< zB=*5i6L=IWBqawbFK|@Mq{O);&b(EJ+&MnCE9&t7+Qq%vMV($25=R$lh9-@-h5mUR z`cqqt^HyyJEgeVqN5_7xV`$Uiwd%F^KXvTZIwmNTo~C27O~OG}D*Tp&@cyRaS(grW zODgWs(P&EQ!?yMx{B<dZl$U(tUhf-OLGXuLh7~Y-r97cgx0lfv;1&l zS<-Twl#B1F2Jh;|z}6;PHajH&l*}g+Olo&5L`}w|P?JjXq?{tkyKv3#$Q2fOiK>g| zp95_R<2k)HM!AZoRCeuXjYW*WOChCYyB@7pZy;WxHnt2%{D!J}LA@46oT1Wbo>6W6 NfIsi3r^aOq004?8QJVk& literal 0 HcmV?d00001