Contraption Ponder Push

- Scenes for Pulley, Piston, and Clockwork Bearing
This commit is contained in:
simibubi 2021-03-11 03:32:18 +01:00
parent c54d80a161
commit c73e3166cb
20 changed files with 712 additions and 14 deletions

View file

@ -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<ClockHands> operationMode;
private float prevForcedAngle;
public ClockworkBearingTileEntity(TileEntityType<? extends ClockworkBearingTileEntity> 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;
}
}

View file

@ -20,5 +20,7 @@ public interface IBearingTileEntity extends IControlContraption {
return bearingAxis != axis;
});
}
void setAngle(float forcedAngle);
}

View file

@ -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();
}
}

View file

@ -27,6 +27,7 @@ import net.minecraft.util.math.Vec3d;
public class PulleyTileEntity extends LinearActuatorTileEntity {
protected int initialOffset;
private float prevAnimatedOffset;
public PulleyTileEntity(TileEntityType<? extends PulleyTileEntity> 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;
}
}

View file

@ -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) {

View file

@ -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<WorldSectionElement> 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<WorldSectionElement> 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<WorldSectionElement> 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);
}
}
}

View file

@ -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<WorldSectionElement> 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<WorldSectionElement> 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<WorldSectionElement> 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<ParrotElement> 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<WorldSectionElement> 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");
}
}

View file

@ -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);

View file

@ -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<WorldSectionElement> 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<WorldSectionElement> 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<WorldSectionElement> 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<WorldSectionElement> 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<WorldSectionElement> 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");
}
}

View file

@ -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");
}

View file

@ -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));
}

View file

@ -35,6 +35,8 @@ public class DisplayWorldSectionInstruction extends FadeIntoSceneInstruction<Wor
@Override
protected void firstTick(PonderScene scene) {
super.firstTick(scene);
mergeOnto.ifPresent(wse -> element.setAnimatedOffset(wse.get()
.getAnimatedOffset(), true));
element.set(initialSelection);
element.setVisible(true);
}

View file

@ -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();
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.