We like to ponder

- Ponder scenes for: Pulse Timer, Chain Conveyor, Frogport
This commit is contained in:
simibubi 2025-01-09 21:41:15 +01:00
parent 8c7f7a5a23
commit b451ccd9d9
14 changed files with 1305 additions and 165 deletions

View file

@ -1,4 +1,4 @@
// 1.20.1 2025-01-08T09:46:32.7401287 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
// 1.20.1 2025-01-08T12:42:08.2186069 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json
c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json
@ -642,8 +642,8 @@ b0d8f08968763a5f74e5cd5644377a76a9f39753 assets/create/blockstates/yellow_toolbo
fe8c497aacc641c2f01cec90bba9f19e59cc2ed2 assets/create/blockstates/yellow_valve_handle.json
e819e93fdcbe9fd9c050a052d2718ff3b3539365 assets/create/blockstates/zinc_block.json
64121dcb216381c83b4fe28aa361ea07c24c9ad0 assets/create/blockstates/zinc_ore.json
739f9cbd71716d56d1561002e8668261cddf5b0c assets/create/lang/en_ud.json
20c3b2a59090bf209090579c2f37db818a06a26b assets/create/lang/en_us.json
c1d7b1f496afa2f971078caf90f20255292d760b assets/create/lang/en_ud.json
ce3c58e8401db1c42f3e1187bec1343fbf15009e assets/create/lang/en_us.json
a97e1060e00ae701a02e39cd4ef8054cf345fac4 assets/create/models/block/acacia_window.json
103e032c0b1a0a6a27c67da8c91179a564bd281c assets/create/models/block/acacia_window_pane_noside.json
fb00b627abda76ad4fea867ca57dbfadd24fffa3 assets/create/models/block/acacia_window_pane_noside_alt.json

View file

@ -2167,6 +2167,12 @@
"create.ponder.pulse_repeater.text_1": "ʎɐןǝp ɐ ɹǝʇɟɐ ǝsןnd ʇɹoɥs ɐ ʇıɯǝ sɹǝʇɐǝdǝᴚ ǝsןnԀ",
"create.ponder.pulse_repeater.text_2": "pǝɹnbıɟuoɔ ǝq uɐɔ ǝɯıʇ ǝbɹɐɥɔ ǝɥʇ 'ןǝuɐd ǝnןɐʌ ǝɥʇ buıs∩",
"create.ponder.pulse_repeater.text_3": "ɹnoɥ uɐ oʇ dn ǝbuɐɹ uɐɔ sʎɐןǝp pǝɹnbıɟuoƆ",
"create.ponder.pulse_timer.header": "ɹǝɯı⟘ ǝsןnԀ ǝɥʇ ɟo ʇndʇno ǝuoʇspǝᴚ",
"create.ponder.pulse_timer.text_1": "sǝsןnd ʇɹoɥs ʇıɯǝ ʎןpǝʇɐǝdǝɹ sɹǝɯı⟘ ǝsןnԀ",
"create.ponder.pulse_timer.text_2": "pǝɹnbıɟuoɔ ǝq uɐɔ ןɐʌɹǝʇuı ǝɯıʇ ǝɥʇ 'ןǝuɐd ǝnןɐʌ ǝɥʇ buıs∩",
"create.ponder.pulse_timer.text_3": "ɯǝɥʇ ʇǝsǝɹ puɐ ǝsnɐd ןןıʍ ǝpıs ʇnduı ǝɥʇ buıɹǝʍoԀ",
"create.ponder.pulse_timer.text_4": "ʇndʇno ǝɥʇ ʇɹǝʌuı oʇ ǝsɐq ʇınɔɹıɔ ǝɥʇ ʞɔıןɔ-ʇɥbıᴚ",
"create.ponder.pulse_timer.text_5": "ןɐubıs ǝuoʇspǝɹ ɐ ʇnoɥʇıʍ ʎןuo ǝʇɐʌıʇɔɐ ʇɐɥʇ sɯsıuɐɥɔǝɯ ɹǝbbıɹʇ sdןǝɥ sıɥ⟘",
"create.ponder.radial_chassis.header": "sıssɐɥƆ ןɐıpɐᴚ buısn sʞɔoןq buıɥɔɐʇʇⱯ",
"create.ponder.radial_chassis.text_1": "ʍoɹ ɐ uı sʞɔoןq sıssɐɥƆ ןɐɔıʇuǝpı oʇ ʇɔǝuuoɔ sıssɐɥƆ ןɐıpɐᴚ",
"create.ponder.radial_chassis.text_2": "ʇı ɥʇıʍ pǝbbɐɹp ǝɹɐ sɹǝɥʇo ǝɥʇ 'uoıʇdɐɹʇuoƆ ɐ ʎq pǝʌoɯ sı ǝuo uǝɥM",
@ -2322,6 +2328,8 @@
"create.ponder.tag.display_targets.description": "ʞuıꞀ ʎɐןdsıᗡ ɐ ɯoɹɟ pǝʌıǝɔǝɹ ɐʇɐp ǝɥʇ ʎɐןdsıp puɐ ssǝɔoɹd uɐɔ ɥɔıɥʍ sʞɔoןᗺ ɹo sʇuǝuodɯoƆ",
"create.ponder.tag.fluids": "sɹoʇɐןndıuɐW pınןℲ",
"create.ponder.tag.fluids.description": "spınןℲ ɟo ǝsn buıʞɐɯ puɐ buıʎɐןǝɹ dןǝɥ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.high_logistics": "sɔıʇsıboꞀ ɥbıH",
"create.ponder.tag.high_logistics.description": "ʎɹoʇɔɐɟ ɹnoʎ punoɹɐ sʇsǝnbǝɹ pǝʇɐɯoʇnɐ puɐ ǝbɐɹoʇs ɯǝʇı pǝʇnqıɹʇsıp buıbɐuɐɯ dןǝɥ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.kinetic_appliances": "sǝɔuɐıןddⱯ ɔıʇǝuıʞ",
"create.ponder.tag.kinetic_appliances.description": "ǝɔɹoℲ ןɐuoıʇɐʇoᴚ ɟo ǝsn ǝʞɐɯ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.kinetic_relays": "sʞɔoןᗺ ɔıʇǝuıʞ",
@ -2332,8 +2340,6 @@
"create.ponder.tag.logistics.description": "punoɹɐ sɯǝʇı buıʌoɯ dןǝɥ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.movement_anchor": "sɹoɥɔuⱯ ʇuǝɯǝʌoW",
"create.ponder.tag.movement_anchor.description": "sʎɐʍ ɟo ʎʇǝıɹɐʌ ɐ uı ǝɹnʇɔnɹʇs pǝɥɔɐʇʇɐ uɐ buıʇɐɯıuɐ 'suoıʇdɐɹʇuoɔ buıʌoɯ ɟo uoıʇɐǝɹɔ ǝɥʇ ʍoןןɐ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.recently_updated": "sǝbuɐɥƆ ʇuǝɔǝᴚ",
"create.ponder.tag.recently_updated.description": "ǝʇɐǝɹƆ ɟo suoısɹǝʌ ʇsǝʇɐן ǝɥʇ uı ʎןʇuɐɔıɟıubıs pǝbuɐɥɔ ɹo pǝppɐ uǝǝq ǝʌɐɥ ʇɐɥʇ sʇuǝuodɯoƆ",
"create.ponder.tag.redstone": "sʇuǝuodɯoƆ ɔıboꞀ",
"create.ponder.tag.redstone.description": "buıɹǝǝuıbuǝ ǝuoʇspǝɹ ɥʇıʍ dןǝɥ ɥɔıɥʍ sʇuǝuodɯoƆ",
"create.ponder.tag.threshold_switch_targets": "sǝɥɔʇıʍS pןoɥsǝɹɥ⟘ ɹoɟ sʇǝbɹɐ⟘",

View file

@ -2167,6 +2167,12 @@
"create.ponder.pulse_repeater.text_1": "Pulse Repeaters emit a short pulse after a delay",
"create.ponder.pulse_repeater.text_2": "Using the value panel, the charge time can be configured",
"create.ponder.pulse_repeater.text_3": "Configured delays can range up to an hour",
"create.ponder.pulse_timer.header": "Redstone output of the Pulse Timer",
"create.ponder.pulse_timer.text_1": "Pulse Timers repeatedly emit short pulses",
"create.ponder.pulse_timer.text_2": "Using the value panel, the time interval can be configured",
"create.ponder.pulse_timer.text_3": "Powering the input side will pause and reset them",
"create.ponder.pulse_timer.text_4": "Right-click the circuit base to invert the output",
"create.ponder.pulse_timer.text_5": "This helps trigger mechanisms that activate only without a redstone signal",
"create.ponder.radial_chassis.header": "Attaching blocks using Radial Chassis",
"create.ponder.radial_chassis.text_1": "Radial Chassis connect to identical Chassis blocks in a row",
"create.ponder.radial_chassis.text_2": "When one is moved by a Contraption, the others are dragged with it",
@ -2322,6 +2328,8 @@
"create.ponder.tag.display_targets.description": "Components or Blocks which can process and display the data received from a Display Link",
"create.ponder.tag.fluids": "Fluid Manipulators",
"create.ponder.tag.fluids.description": "Components which help relaying and making use of Fluids",
"create.ponder.tag.high_logistics": "High Logistics",
"create.ponder.tag.high_logistics.description": "Components which help managing distributed item storage and automated requests around your factory",
"create.ponder.tag.kinetic_appliances": "Kinetic Appliances",
"create.ponder.tag.kinetic_appliances.description": "Components which make use of Rotational Force",
"create.ponder.tag.kinetic_relays": "Kinetic Blocks",
@ -2332,8 +2340,6 @@
"create.ponder.tag.logistics.description": "Components which help moving items around",
"create.ponder.tag.movement_anchor": "Movement Anchors",
"create.ponder.tag.movement_anchor.description": "Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways",
"create.ponder.tag.recently_updated": "Recent Changes",
"create.ponder.tag.recently_updated.description": "Components that have been added or changed significantly in the latest versions of Create",
"create.ponder.tag.redstone": "Logic Components",
"create.ponder.tag.redstone.description": "Components which help with redstone engineering",
"create.ponder.tag.threshold_switch_targets": "Targets for Threshold Switches",

View file

@ -26,7 +26,7 @@ import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.engine_room.flywheel.api.backend.BackendManager;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.NBTHelper;
import net.createmod.catnip.utility.VecHelper;
@ -146,9 +146,8 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
if (level.isClientSide()) {
// We can use TickableVisuals if flywheel is enabled
if (!BackendManager.isBackendOn()) {
if (!VisualizationManager.supportsVisualization(level))
tickBoxVisuals();
}
}
if (!level.isClientSide()) {
@ -207,7 +206,7 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
anticipatePosition += serverSpeed * distancePerTick * 4;
anticipatePosition = Math.min(stats.chainLength, anticipatePosition);
if (level.isClientSide())
if (level.isClientSide() && !isVirtual())
continue;
for (Entry<BlockPos, ConnectedPort> portEntry : travelPorts.entrySet()) {
@ -376,6 +375,8 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
return false;
travellingPackages.computeIfAbsent(connection, $ -> new ArrayList<>())
.add(box);
if (level.isClientSide)
return true;
notifyUpdate();
return true;
}
@ -450,7 +451,7 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
ChainConveyorPackagePhysicsData physicsData = box.physicsData(level);
physicsData.setBE(this);
if (!physicsData.shouldTick())
if (!physicsData.shouldTick() && !isVirtual())
return;
physicsData.prevTargetPos = physicsData.targetPos;
@ -652,7 +653,7 @@ public class ChainConveyorBlockEntity extends KineticBlockEntity implements ITra
boolean connectedViaAxes, boolean connectedViaCogs) {
if (connections.contains(target.getBlockPos()
.subtract(worldPosition))) {
if (!(target instanceof ChainConveyorBlockEntity clbe))
if (!(target instanceof ChainConveyorBlockEntity))
return 0;
return 1;
}

View file

@ -15,7 +15,7 @@ import com.simibubi.create.content.kinetics.chainConveyor.ChainConveyorPackage.C
import com.simibubi.create.content.logistics.box.PackageItem;
import com.simibubi.create.foundation.render.RenderTypes;
import dev.engine_room.flywheel.api.backend.BackendManager;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.createmod.catnip.render.CachedBuffers;
import net.createmod.catnip.render.SuperByteBuffer;
@ -55,13 +55,14 @@ public class ChainConveyorRenderer extends KineticBlockEntityRenderer<ChainConve
renderChains(be, ms, buffer, light, overlay);
if (!BackendManager.isBackendOn()) {
for (ChainConveyorPackage box : be.loopingPackages)
if (VisualizationManager.supportsVisualization(be.getLevel()))
return;
for (ChainConveyorPackage box : be.loopingPackages)
renderBox(be, ms, buffer, overlay, pos, box, partialTicks);
for (Entry<BlockPos, List<ChainConveyorPackage>> entry : be.travellingPackages.entrySet())
for (ChainConveyorPackage box : entry.getValue())
renderBox(be, ms, buffer, overlay, pos, box, partialTicks);
for (Entry<BlockPos, List<ChainConveyorPackage>> entry : be.travellingPackages.entrySet())
for (ChainConveyorPackage box : entry.getValue())
renderBox(be, ms, buffer, overlay, pos, box, partialTicks);
}
}
private void renderBox(ChainConveyorBlockEntity be, PoseStack ms, MultiBufferSource buffer, int overlay,
@ -151,10 +152,9 @@ public class ChainConveyorRenderer extends KineticBlockEntityRenderer<ChainConve
Vec3 startOffset = stats.start()
.subtract(Vec3.atCenterOf(tilePos));
if (!BackendManager.isBackendOn()) {
if (!VisualizationManager.supportsVisualization(be.getLevel())) {
SuperByteBuffer guard =
CachedBuffers.partial(AllPartialModels.CHAIN_CONVEYOR_GUARD, be.getBlockState());
// guard.translate(startOffset.multiply(0, 1, 0));
guard.center();
guard.rotateYDegrees((float) yaw);

View file

@ -136,7 +136,7 @@ public class FrogportBlockEntity extends PackagePortBlockEntity implements IHave
float value = animationProgress.getValue();
if (currentlyDepositing) {
if (!level.isClientSide()) {
if (!level.isClientSide() || isVirtual()) {
if (value > 0.5 && animatedPackage != null) {
if (target == null
|| !target.depositImmediately() && !target.export(level, worldPosition, animatedPackage, false))

View file

@ -32,6 +32,8 @@ public class SmartBlockEntityRenderer<T extends SmartBlockEntity> extends SafeBl
protected void renderNameplateOnHover(T blockEntity, Component tag, float yOffset, PoseStack ms,
MultiBufferSource buffer, int light) {
Minecraft mc = Minecraft.getInstance();
if (blockEntity.isVirtual())
return;
if (mc.player.distanceToSqr(Vec3.atCenterOf(blockEntity.getBlockPos())) > 4096.0f)
return;
HitResult hitResult = mc.hitResult;

View file

@ -19,6 +19,7 @@ import com.simibubi.create.infrastructure.ponder.scenes.DisplayScenes;
import com.simibubi.create.infrastructure.ponder.scenes.EjectorScenes;
import com.simibubi.create.infrastructure.ponder.scenes.ElevatorScenes;
import com.simibubi.create.infrastructure.ponder.scenes.FanScenes;
import com.simibubi.create.infrastructure.ponder.scenes.FrogAndConveyorScenes;
import com.simibubi.create.infrastructure.ponder.scenes.FunnelScenes;
import com.simibubi.create.infrastructure.ponder.scenes.GantryScenes;
import com.simibubi.create.infrastructure.ponder.scenes.ItemVaultScenes;
@ -339,12 +340,20 @@ public class AllCreatePonderScenes {
.addStoryBoard("redstone_link", RedstoneScenes::redstoneLink);
HELPER.forComponents(AllBlocks.ROSE_QUARTZ_LAMP)
.addStoryBoard("rose_quartz_lamp", RedstoneScenes2::roseQuartzLamp);
HELPER.forComponents(AllBlocks.PULSE_TIMER)
.addStoryBoard("pulse_timer", RedstoneScenes2::pulseTimer);
HELPER.forComponents(AllBlocks.SMART_OBSERVER)
.addStoryBoard("smart_observer", DetectorScenes::smartObserver);
HELPER.forComponents(AllBlocks.THRESHOLD_SWITCH)
.addStoryBoard("threshold_switch", DetectorScenes::thresholdSwitch);
// Hilo
HELPER.forComponents(AllBlocks.CHAIN_CONVEYOR)
.addStoryBoard("chain_conveyor", FrogAndConveyorScenes::conveyor);
HELPER.forComponents(AllBlocks.PACKAGE_FROGPORT)
.addStoryBoard("package_frogport", FrogAndConveyorScenes::frogPort);
// Trains
HELPER.forComponents(TrackMaterial.allBlocks()
.stream()

View file

@ -25,6 +25,7 @@ public class AllCreatePonderTags {
KINETIC_APPLIANCES = loc("kinetic_appliances"),
FLUIDS = loc("fluids"),
LOGISTICS = loc("logistics"),
HIGH_LOGISTICS = loc("high_logistics"),
REDSTONE = loc("redstone"),
DECORATION = loc("decoration"),
CREATIVE = loc("creative"),
@ -34,73 +35,11 @@ public class AllCreatePonderTags {
SAILS = loc("windmill_sails"),
ARM_TARGETS = loc("arm_targets"),
TRAIN_RELATED = loc("train_related"),
RECENTLY_UPDATED = loc("recently_updated"),
// RECENTLY_UPDATED = loc("recently_updated"),
DISPLAY_SOURCES = loc("display_sources"),
DISPLAY_TARGETS = loc("display_targets"),
THRESHOLD_SWITCH_TARGETS = loc("threshold_switch_targets");
/*public static final PonderTag
KINETIC_RELAYS = create("kinetic_relays").item(AllBlocks.COGWHEEL.get())
.defaultLang("Kinetic Blocks", "Components which help relaying Rotational Force elsewhere"),
KINETIC_SOURCES = create("kinetic_sources").item(AllBlocks.WATER_WHEEL.get())
.defaultLang("Kinetic Sources", "Components which generate Rotational Force"),
KINETIC_APPLIANCES = create("kinetic_appliances").item(AllBlocks.MECHANICAL_PRESS.get())
.defaultLang("Kinetic Appliances", "Components which make use of Rotational Force"),
FLUIDS = create("fluids").item(AllBlocks.FLUID_PIPE.get())
.defaultLang("Fluid Manipulators", "Components which help relaying and making use of Fluids"),
LOGISTICS = create("logistics").item(Blocks.CHEST)
.defaultLang("Item Transportation", "Components which help moving items around"),
REDSTONE = create("redstone").item(Items.REDSTONE)
.defaultLang("Logic Components", "Components which help with redstone engineering"),
DECORATION = create("decoration").item(Items.ROSE_BUSH)
.defaultLang("Aesthetics", "Components used mostly for decorative purposes"),
CREATIVE = create("creative").item(AllBlocks.CREATIVE_CRATE.get())
.defaultLang("Creative Mode", "Components not usually available for Survival Mode"),
MOVEMENT_ANCHOR = create("movement_anchor").item(AllBlocks.MECHANICAL_PISTON.get())
.defaultLang("Movement Anchors",
"Components which allow the creation of moving contraptions, animating an attached structure in a variety of ways"),
CONTRAPTION_ACTOR = create("contraption_actor").item(AllBlocks.MECHANICAL_HARVESTER.get())
.defaultLang("Contraption Actors",
"Components which expose special behaviour when attached to a moving contraption"),
CONTRAPTION_ASSEMBLY = create("contraption_assembly").item(AllItems.SUPER_GLUE.get())
.defaultLang("Block Attachment Utility",
"Tools and Components used to assemble structures moved as an animated Contraption"),
SAILS = create("windmill_sails").item(AllBlocks.WINDMILL_BEARING.get(), true, true)
.defaultLang("Sails for Windmill Bearings",
"Blocks that count towards the strength of a Windmill Contraption when assembled. Each of these have equal efficiency in doing so."),
ARM_TARGETS = create("arm_targets").item(AllBlocks.MECHANICAL_ARM.get(), true, true)
.defaultLang("Targets for Mechanical Arms",
"Components which can be selected as inputs or outputs to the Mechanical Arm"),
TRAIN_RELATED = create("train_related").item(AllBlocks.TRACK.get())
.defaultLang("Railway Equipment",
"Components used in the construction or management of Train Contraptions"),
RECENTLY_UPDATED = create("recently_updated").item(AllBlocks.CLIPBOARD.get())
.defaultLang("Recent Changes",
"Components that have been added or changed significantly in the latest versions of Create"),
DISPLAY_SOURCES = create("display_sources").item(AllBlocks.DISPLAY_LINK.get(), true, true)
.defaultLang("Sources for Display Links",
"Components or Blocks which offer some data that can be read with a Display Link"),
DISPLAY_TARGETS = create("display_targets").item(AllBlocks.DISPLAY_LINK.get(), true, true)
.defaultLang("Targets for Display Links",
"Components or Blocks which can process and display the data received from a Display Link");*/
private static ResourceLocation loc(String id) {
return Create.asResource(id);
}
@ -146,6 +85,13 @@ public class AllCreatePonderTags {
.title("Item Transportation")
.description("Components which help moving items around")
.register();
helper.registerTag(HIGH_LOGISTICS)
.addToIndex()
.item(AllBlocks.STOCK_TICKER.get())
.title("High Logistics")
.description("Components which help managing distributed item storage and automated requests around your factory")
.register();
helper.registerTag(REDSTONE)
.addToIndex()
@ -208,12 +154,12 @@ public class AllCreatePonderTags {
.description("Components used in the construction or management of Train Contraptions")
.register();
helper.registerTag(RECENTLY_UPDATED)
.addToIndex()
.item(AllBlocks.CLIPBOARD.get())
.title("Recent Changes")
.description("Components that have been added or changed significantly in the latest versions of Create")
.register();
// helper.registerTag(RECENTLY_UPDATED)
// .addToIndex()
// .item(AllBlocks.CLIPBOARD.get())
// .title("Recent Changes")
// .description("Components that have been added or changed significantly in the latest versions of Create")
// .register();
helper.registerTag(DISPLAY_SOURCES)
.item(AllBlocks.DISPLAY_LINK.get())
@ -233,19 +179,7 @@ public class AllCreatePonderTags {
.description("Threshold Switches can read from these blocks, as well as most item and fluid containers.")
.register();
HELPER.addToTag(RECENTLY_UPDATED)
.add(AllBlocks.WATER_WHEEL)
.add(AllBlocks.LARGE_WATER_WHEEL)
.add(AllBlocks.COPPER_VALVE_HANDLE)
.add(AllBlocks.ELEVATOR_PULLEY)
.add(AllBlocks.CONTRAPTION_CONTROLS)
.add(AllBlocks.MECHANICAL_ROLLER)
.add(AllBlocks.MECHANICAL_PUMP)
.add(AllBlocks.SMART_OBSERVER)
.add(AllBlocks.THRESHOLD_SWITCH)
.add(AllItems.NETHERITE_BACKTANK)
.add(AllBlocks.COPYCAT_PANEL)
.add(AllBlocks.COPYCAT_STEP);
// HELPER.addToTag(RECENTLY_UPDATED);
HELPER.addToTag(KINETIC_RELAYS)
.add(AllBlocks.SHAFT)
@ -253,10 +187,12 @@ public class AllCreatePonderTags {
.add(AllBlocks.LARGE_COGWHEEL)
.add(AllItems.BELT_CONNECTOR)
.add(AllBlocks.GEARBOX)
.add(AllItems.VERTICAL_GEARBOX)
.add(AllBlocks.CLUTCH)
.add(AllBlocks.GEARSHIFT)
.add(AllBlocks.ENCASED_CHAIN_DRIVE)
.add(AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT)
.add(AllBlocks.CHAIN_CONVEYOR)
.add(AllBlocks.SEQUENCED_GEARSHIFT)
.add(AllBlocks.ROTATION_SPEED_CONTROLLER);
@ -391,6 +327,7 @@ public class AllCreatePonderTags {
.add(AllBlocks.REDSTONE_LINK)
.add(AllBlocks.PULSE_EXTENDER)
.add(AllBlocks.PULSE_REPEATER)
.add(AllBlocks.PULSE_TIMER)
.add(AllBlocks.POWERED_LATCH)
.add(AllBlocks.POWERED_TOGGLE_LATCH)
.add(AllBlocks.ROSE_QUARTZ_LAMP);
@ -417,6 +354,18 @@ public class AllCreatePonderTags {
.add(Blocks.SLIME_BLOCK)
.add(Blocks.HONEY_BLOCK);
HELPER.addToTag(HIGH_LOGISTICS)
.add(AllBlocks.PACKAGER)
.add(AllBlocks.PACKAGE_FROGPORT)
.add(AllBlocks.PACKAGE_POSTBOXES.get(DyeColor.WHITE))
.add(AllBlocks.STOCK_LINK)
.add(AllBlocks.STOCK_TICKER)
.add(AllBlocks.REDSTONE_REQUESTER)
.add(AllBlocks.TABLE_CLOTHS.get(DyeColor.WHITE))
.add(AllBlocks.FACTORY_GAUGE)
.add(AllBlocks.REPACKAGER)
.add(AllItems.PACKAGE_FILTER);
HELPER.addToTag(CONTRAPTION_ACTOR)
.add(AllBlocks.MECHANICAL_HARVESTER)
.add(AllBlocks.MECHANICAL_PLOUGH)
@ -452,6 +401,7 @@ public class AllCreatePonderTags {
.add(AllBlocks.STRESSOMETER)
.add(AllBlocks.SPEEDOMETER)
.add(AllBlocks.FLUID_TANK)
.add(AllBlocks.FACTORY_GAUGE)
.add(AllItems.BELT_CONNECTOR);
itemHelper.addToTag(DISPLAY_SOURCES)

View file

@ -0,0 +1,935 @@
package com.simibubi.create.infrastructure.ponder.scenes;
import java.util.Iterator;
import java.util.function.Supplier;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.kinetics.chainConveyor.ChainConveyorBlockEntity;
import com.simibubi.create.content.kinetics.chainConveyor.ChainConveyorPackage;
import com.simibubi.create.content.logistics.box.PackageItem;
import com.simibubi.create.content.logistics.box.PackageStyles;
import com.simibubi.create.content.logistics.packagePort.frogport.FrogportBlockEntity;
import com.simibubi.create.content.logistics.packager.PackagerBlockEntity;
import com.simibubi.create.foundation.ponder.CreateSceneBuilder;
import net.createmod.catnip.utility.Pointing;
import net.createmod.catnip.utility.math.AngleHelper;
import net.createmod.ponder.api.PonderPalette;
import net.createmod.ponder.api.element.ElementLink;
import net.createmod.ponder.api.element.ParrotElement;
import net.createmod.ponder.api.element.ParrotPose;
import net.createmod.ponder.api.element.WorldSectionElement;
import net.createmod.ponder.api.level.PonderLevel;
import net.createmod.ponder.api.scene.SceneBuilder;
import net.createmod.ponder.api.scene.SceneBuildingUtil;
import net.createmod.ponder.api.scene.Selection;
import net.createmod.ponder.foundation.element.ElementLinkImpl;
import net.createmod.ponder.foundation.element.ParrotElementImpl;
import net.createmod.ponder.foundation.instruction.CreateParrotInstruction;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class FrogAndConveyorScenes {
public static void conveyor(SceneBuilder builder, SceneBuildingUtil util) {
CreateSceneBuilder scene = new CreateSceneBuilder(builder);
scene.title("chain_conveyor", "Relaying rotational force using Chain Conveyors");
scene.configureBasePlate(0, 0, 9);
scene.scaleSceneView(.75f);
scene.setSceneOffsetY(-1);
scene.world()
.showSection(util.select()
.layer(0), Direction.UP);
Selection pole = util.select()
.fromTo(1, 1, 6, 1, 3, 6);
Selection cogs = util.select()
.position(8, 1, 2);
Selection cogs2 = util.select()
.fromTo(7, 1, 1, 7, 3, 1);
BlockPos conv1 = util.grid()
.at(7, 4, 1);
BlockPos conv2 = util.grid()
.at(1, 4, 7);
BlockPos conv3 = util.grid()
.at(1, 2, 4);
BlockPos conv4 = util.grid()
.at(7, 4, 7);
connection(builder, conv1, conv2, false);
connection(builder, conv1, conv3, false);
connection(builder, conv1, conv4, false);
Selection pole3 = util.select()
.position(1, 1, 4);
Selection pole4 = util.select()
.fromTo(7, 1, 7, 7, 3, 7);
Selection cogsBelow = util.select()
.fromTo(1, 2, 7, 1, 3, 7);
Selection cogsAbove = util.select()
.position(1, 5, 7);
Selection conv1S = util.select()
.position(conv1);
Selection conv2S = util.select()
.position(conv2);
Selection conv3S = util.select()
.position(conv3);
Selection conv4S = util.select()
.position(conv4);
scene.world()
.setKineticSpeed(conv2S, 0);
scene.idle(5);
scene.world()
.showSection(cogs, Direction.EAST);
scene.idle(5);
scene.world()
.showSection(cogs2, Direction.DOWN);
scene.idle(5);
scene.world()
.showSection(conv1S, Direction.DOWN);
ElementLink<WorldSectionElement> poleE = scene.world()
.showIndependentSection(pole, Direction.DOWN);
scene.world()
.moveSection(poleE, util.vector()
.of(0, 0, 1), 0);
scene.idle(5);
scene.world()
.showSection(conv2S, Direction.DOWN);
scene.idle(20);
ItemStack chainItem = new ItemStack(Items.CHAIN);
scene.overlay()
.showControls(util.vector()
.topOf(conv1), Pointing.DOWN, 117)
.rightClick()
.withItem(chainItem);
Vec3 c1 = util.vector()
.centerOf(conv1);
AABB bb1 = new AABB(c1, c1);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv1, bb1, 10);
scene.idle(1);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv1, bb1.inflate(1, 0.5, 1), 117);
scene.idle(16);
scene.overlay()
.showControls(util.vector()
.topOf(conv2), Pointing.DOWN, 100)
.rightClick()
.withItem(chainItem);
Vec3 c2 = util.vector()
.centerOf(conv2);
AABB bb2 = new AABB(c2, c2);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv2, bb2, 10);
scene.idle(1);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv2, bb2.inflate(1, 0.5, 1), 100);
scene.idle(10);
connection(builder, conv1, conv2, true);
scene.world()
.setKineticSpeed(conv2S, -32);
scene.overlay()
.showText(80)
.text("Right-click two conveyors with chains to connect them")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector()
.topOf(conv1.offset(-1, 0, -1)));
scene.idle(90);
scene.world()
.showSection(pole3, Direction.DOWN);
scene.idle(3);
scene.world()
.showSection(pole4, Direction.DOWN);
scene.idle(6);
scene.world()
.showSection(conv3S, Direction.DOWN);
scene.idle(3);
scene.world()
.showSection(conv4S, Direction.DOWN);
scene.idle(12);
connection(builder, conv1, conv3, true);
scene.idle(3);
connection(builder, conv1, conv4, true);
scene.idle(20);
scene.overlay()
.showText(60)
.text("These relay rotational power to each other very flexibly..")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector()
.topOf(conv3.offset(-1, 0, -1)));
scene.idle(50);
scene.world()
.hideIndependentSection(poleE, Direction.SOUTH);
scene.idle(20);
scene.world()
.showSection(cogsAbove, Direction.DOWN);
scene.idle(3);
scene.world()
.showSection(cogsBelow, Direction.UP);
scene.idle(12);
scene.effects()
.rotationDirectionIndicator(conv2.above());
scene.idle(3);
scene.effects()
.rotationDirectionIndicator(conv2.below(2));
scene.idle(10);
scene.overlay()
.showText(60)
.text("..and connect to shafts above or below them")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector()
.centerOf(util.grid()
.at(1, 2, 7)));
scene.idle(60);
scene.world()
.hideSection(cogsBelow, Direction.SOUTH);
scene.idle(15);
ElementLink<WorldSectionElement> poleE2 = scene.world()
.showIndependentSection(pole, Direction.EAST);
scene.world()
.moveSection(poleE2, util.vector()
.of(0, 0, 1), 0);
scene.idle(10);
scene.overlay()
.showText(80)
.text("Right-click holding a wrench to start travelling on the chain")
.attachKeyFrame()
.independent(30);
scene.idle(40);
ElementLink<ParrotElement> parrot = new ElementLinkImpl<>(ParrotElement.class);
Vec3 parrotStart = util.vector()
.centerOf(conv2)
.add(0, -1.45, 1);
ChainConveyorParrotElement element =
new ChainConveyorParrotElement(parrotStart, ParrotPose.FacePointOfInterestPose::new);
scene.addInstruction(new CreateParrotInstruction(0, Direction.DOWN, element));
scene.addInstruction(s -> s.linkElement(element, parrot));
scene.special()
.movePointOfInterest(util.grid()
.at(0, 3, 2));
scene.idle(20);
scene.special()
.moveParrot(parrot, util.vector()
.of(-1, 0, -1), 14);
scene.idle(14);
scene.special()
.movePointOfInterest(util.grid()
.at(7, 3, 0));
scene.special()
.moveParrot(parrot, util.vector()
.of(5.75, 0, -5.75), 90);
scene.idle(65);
scene.overlay()
.showText(60)
.text("At a junction, face towards a chain to follow it")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector()
.topOf(conv1));
scene.idle(25);
scene.special()
.movePointOfInterest(util.grid()
.at(9, 3, 1));
scene.special()
.moveParrot(parrot, util.vector()
.of(1, 0, -1), 14);
scene.idle(14);
scene.special()
.movePointOfInterest(util.grid()
.at(9, 3, 3));
scene.special()
.moveParrot(parrot, util.vector()
.of(0.5, 0, 0), 6);
scene.idle(6);
scene.special()
.movePointOfInterest(util.grid()
.at(8, 3, 10));
scene.special()
.moveParrot(parrot, util.vector()
.of(0.5, 0, 0.5), 14);
scene.idle(14);
scene.special()
.moveParrot(parrot, util.vector()
.of(0, 0, 7), 78);
scene.idle(78);
scene.special()
.hideElement(parrot, Direction.SOUTH);
}
private static void connection(SceneBuilder builder, BlockPos p1, BlockPos p2, boolean connect) {
builder.world()
.modifyBlockEntity(p1, ChainConveyorBlockEntity.class, be -> {
if (connect)
be.connections.add(p2.subtract(p1));
else
be.connections.remove(p2.subtract(p1));
});
builder.world()
.modifyBlockEntity(p2, ChainConveyorBlockEntity.class, be -> {
if (connect)
be.connections.add(p1.subtract(p2));
else
be.connections.remove(p1.subtract(p2));
});
}
public static class ChainConveyorParrotElement extends ParrotElementImpl {
private ItemEntity wrench;
public ChainConveyorParrotElement(Vec3 location, Supplier<? extends ParrotPose> pose) {
super(location, pose);
}
@Override
protected void renderLast(PonderLevel world, MultiBufferSource buffer, GuiGraphics graphics, float fade,
float pt) {
PoseStack poseStack = graphics.pose();
EntityRenderDispatcher entityrenderermanager = Minecraft.getInstance()
.getEntityRenderDispatcher();
if (entity == null) {
entity = pose.create(world);
entity.setYRot(entity.yRotO = 180);
}
if (wrench == null) {
wrench = new ItemEntity(world, 0, 0, 0, AllItems.WRENCH.asStack());
wrench.setYRot(wrench.yRotO = 180);
}
double lx = Mth.lerp(pt, entity.xo, entity.getX());
double ly = Mth.lerp(pt, entity.yo, entity.getY());
double lz = Mth.lerp(pt, entity.zo, entity.getZ());
float angle = AngleHelper.angleLerp(pt, entity.yRotO, entity.getYRot());
poseStack.pushPose();
poseStack.translate(location.x, location.y, location.z);
poseStack.translate(lx, ly, lz);
poseStack.mulPose(Axis.YP.rotationDegrees(angle));
poseStack.translate(0, 1.5f, 0);
poseStack.mulPose(Axis.ZP.rotationDegrees(Mth.sin((world.scene.getCurrentTime() + pt) * 0.2f) * 10));
poseStack.translate(0, -1.5f, 0);
poseStack.pushPose();
poseStack.mulPose(Axis.YP.rotationDegrees(90));
poseStack.mulPose(Axis.XP.rotationDegrees(90));
poseStack.mulPose(Axis.ZP.rotationDegrees(90));
poseStack.scale(1.5f, 1.5f, 1.5f);
poseStack.translate(-0.1, 0.2, -0.6);
BakedModel bakedmodel = Minecraft.getInstance()
.getItemRenderer()
.getModel(wrench.getItem(), world, (LivingEntity) null, 0);
Minecraft.getInstance()
.getItemRenderer()
.render(wrench.getItem(), ItemDisplayContext.GROUND, false, poseStack, buffer,
lightCoordsFromFade(fade), OverlayTexture.NO_OVERLAY, bakedmodel);
poseStack.popPose();
entity.flapSpeed = 2;
entityrenderermanager.render(entity, 0, 0, 0, 0, pt, poseStack, buffer, lightCoordsFromFade(fade));
poseStack.popPose();
}
}
public static void frogPort(SceneBuilder builder, SceneBuildingUtil util) {
CreateSceneBuilder scene = new CreateSceneBuilder(builder);
scene.title("package_frogport", "Transporting packages with Frogports");
scene.configureBasePlate(0, 0, 9);
scene.scaleSceneView(.75f);
scene.setSceneOffsetY(-1);
BlockPos conv1 = util.grid()
.at(1, 4, 7);
BlockPos conv2 = util.grid()
.at(7, 4, 7);
BlockPos conv3 = util.grid()
.at(7, 4, 1);
Selection conv1S = util.select()
.position(conv1);
Selection conv2S = util.select()
.position(conv2);
Selection conv3S = util.select()
.position(conv3);
Selection largeCog = util.select()
.position(2, 1, 8);
Selection shaftPole = util.select()
.fromTo(1, 1, 7, 1, 3, 7);
Selection pole2 = util.select()
.fromTo(7, 1, 7, 7, 3, 7);
Selection pole3 = util.select()
.fromTo(7, 1, 1, 7, 3, 1);
Selection largeCog2 = util.select()
.position(9, 0, 1);
Selection fromBelt = util.select()
.fromTo(9, 1, 0, 6, 1, 0)
.add(util.select()
.fromTo(5, 1, 0, 5, 1, 1));
BlockPos fromFunnel = util.grid()
.at(5, 2, 1);
Selection logistics = util.select()
.fromTo(2, 1, 2, 1, 1, 2);
Selection toBelt = util.select()
.fromTo(1, 1, 9, 0, 1, 9)
.add(util.select()
.fromTo(0, 1, 8, 0, 1, 6))
.add(util.select()
.fromTo(1, 1, 5, 0, 1, 5));
BlockPos toFunnel = util.grid()
.at(1, 2, 5);
BlockPos fromFrog = util.grid()
.at(5, 2, 2);
BlockPos toFrog = util.grid()
.at(2, 2, 5);
Selection fromFrogS = util.select()
.position(fromFrog);
Selection toFrogS = util.select()
.position(toFrog);
Selection casing = util.select()
.position(5, 1, 4);
Selection fromBarrel = util.select()
.position(5, 1, 3);
Selection toBarrel = util.select()
.position(3, 1, 5);
Selection fromPackager = util.select()
.fromTo(7, 1, 2, 5, 1, 2);
Selection sign = util.select()
.position(4, 1, 2);
BlockPos lever = util.grid()
.at(6, 1, 1);
Selection toPackager = util.select()
.fromTo(2, 1, 4, 0, 1, 4);
scene.world()
.showSection(util.select()
.layer(0)
.substract(largeCog2), Direction.UP);
scene.idle(10);
scene.world()
.showSection(largeCog, Direction.SOUTH);
scene.idle(2);
scene.world()
.showSection(shaftPole, Direction.DOWN);
scene.idle(2);
scene.world()
.showSection(pole2, Direction.DOWN);
scene.idle(2);
scene.world()
.showSection(pole3, Direction.DOWN);
scene.idle(5);
scene.world()
.showSection(conv1S, Direction.DOWN);
scene.world()
.showSection(conv2S, Direction.DOWN);
scene.world()
.showSection(conv3S, Direction.DOWN);
scene.idle(25);
Vec3 fromTarget = util.vector()
.of(6.78, 4.37, 3.5);
ItemStack frogItem = AllBlocks.PACKAGE_FROGPORT.asStack();
scene.overlay()
.showControls(fromTarget, Pointing.UP, 50)
.rightClick()
.withItem(frogItem);
scene.idle(5);
AABB bb1 = new AABB(fromTarget, fromTarget);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.WHITE, conv1, bb1, 10);
scene.idle(1);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.WHITE, conv1, bb1.inflate(0.025, 0.025, 0.025), 50);
scene.idle(26);
scene.overlay()
.showText(80)
.text("Right-click a Chain Conveyor and place the Frogport nearby")
.attachKeyFrame()
.placeNearTarget()
.pointAt(fromTarget);
scene.idle(40);
ElementLink<WorldSectionElement> fromFrogE = scene.world()
.showIndependentSection(fromFrogS, Direction.DOWN);
scene.world()
.moveSection(fromFrogE, util.vector()
.of(0, -1, 0), 0);
scene.idle(15);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv1, bb1.inflate(0.025, 0.025, 0.025), 50);
AABB bb2 = new AABB(fromFrog.below()).contract(0, 0.75, 0);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv2, bb2, 50);
scene.idle(10);
scene.overlay()
.showLine(PonderPalette.GREEN, util.vector()
.topOf(fromFrog.below()), fromTarget, 40);
scene.idle(45);
scene.overlay()
.showControls(util.vector()
.topOf(fromFrog.below()), Pointing.DOWN, 40)
.rightClick();
scene.idle(7);
scene.overlay()
.showOutlineWithText(util.select()
.position(fromFrog.below()), 70)
.attachKeyFrame()
.colored(PonderPalette.BLUE)
.text("They can be given a name in their inventory UI")
.pointAt(util.vector()
.topOf(fromFrog.below()))
.placeNearTarget();
scene.idle(80);
scene.world()
.moveSection(fromFrogE, util.vector()
.of(0, 1, 0), 10);
scene.idle(10);
ElementLink<WorldSectionElement> casingE = scene.world()
.showIndependentSection(casing, Direction.NORTH);
scene.world()
.moveSection(casingE, util.vector()
.of(0, 0, -2), 0);
scene.idle(5);
scene.world()
.showSection(largeCog2, Direction.UP);
scene.world()
.showSection(fromBelt, Direction.SOUTH);
scene.idle(5);
scene.world()
.showSection(util.select()
.position(fromFunnel), Direction.DOWN);
scene.idle(10);
ItemStack box = PackageStyles.getDefaultBox()
.copy();
PackageItem.addAddress(box, "Peter");
scene.world()
.createItemOnBelt(util.grid()
.at(5, 1, 0), Direction.NORTH, box);
scene.idle(5);
scene.world()
.multiplyKineticSpeed(util.select()
.fromTo(9, 0, 1, 5, 1, 0), 1 / 32f);
scene.idle(5);
scene.overlay()
.showText(75)
.colored(PonderPalette.BLUE)
.text("Albert")
.pointAt(util.vector()
.topOf(fromFrog))
.placeNearTarget();
scene.idle(5);
scene.overlay()
.showText(70)
.colored(PonderPalette.OUTPUT)
.text("Peter")
.pointAt(util.vector()
.centerOf(util.grid()
.at(5, 2, 0)))
.placeNearTarget();
scene.idle(30);
scene.overlay()
.showText(80)
.attachKeyFrame()
.text("If a package is addressed to a different name..")
.pointAt(util.vector()
.topOf(5, 0, 3))
.placeNearTarget();
scene.idle(60);
scene.world()
.multiplyKineticSpeed(util.select()
.fromTo(9, 0, 1, 5, 1, 0), 32f);
scene.idle(13);
scene.world()
.removeItemsFromBelt(util.grid()
.at(5, 1, 1));
scene.world()
.flapFunnel(fromFunnel, false);
scene.idle(15);
scene.world()
.modifyBlockEntity(fromFrog, FrogportBlockEntity.class, be -> be.startAnimation(box, true));
scene.idle(15);
scene.overlay()
.showText(60)
.text("..the Frogport will place the package on the conveyor")
.pointAt(fromTarget.add(0, 0, 1.5))
.placeNearTarget();
scene.idle(95);
scene.overlay()
.showText(60)
.attachKeyFrame()
.colored(PonderPalette.RED)
.text("Packages spin in place if they have no valid destination")
.pointAt(util.vector()
.of(6.5, 4.25, 7.5))
.placeNearTarget();
scene.idle(60);
scene.world()
.showSection(util.select()
.position(toFrog.below()), Direction.SOUTH);
scene.idle(5);
scene.world()
.showSection(toFrogS, Direction.DOWN);
scene.idle(15);
Vec3 toTarget = util.vector()
.of(3.5, 4.37, 6.78);
AABB bb3 = new AABB(toTarget, toTarget);
AABB bb4 = new AABB(toFrog).contract(0, 0.75, 0);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, conv3, bb3.inflate(0.025, 0.025, 0.025), 80);
scene.overlay()
.chaseBoundingBoxOutline(PonderPalette.GREEN, lever, bb4, 80);
scene.overlay()
.showLine(PonderPalette.GREEN, util.vector()
.topOf(toFrog), toTarget, 80);
scene.idle(10);
scene.overlay()
.showText(70)
.text("More Frogports can be added anywhere on the chain network")
.attachKeyFrame()
.placeNearTarget()
.pointAt(toTarget);
scene.idle(75);
scene.overlay()
.showText(70)
.colored(PonderPalette.BLUE)
.text("Peter")
.pointAt(util.vector()
.topOf(toFrog))
.placeNearTarget();
scene.idle(30);
scene.world()
.modifyBlockEntity(conv2, ChainConveyorBlockEntity.class, be -> boxTransfer(conv1, conv2, be));
scene.idle(50);
scene.overlay()
.showText(70)
.attachKeyFrame()
.text("Packages find their path to a matching frog on the chain network")
.pointAt(util.vector()
.topOf(toFrog))
.placeNearTarget();
scene.idle(40);
scene.world()
.showSection(toBelt, Direction.SOUTH);
scene.idle(10);
scene.world()
.showSection(util.select()
.position(toFunnel), Direction.DOWN);
scene.idle(15);
scene.world()
.createItemOnBelt(util.grid()
.at(1, 1, 5), Direction.EAST, box);
scene.idle(20);
scene.world()
.hideSection(util.select()
.fromTo(0, 1, 6, 0, 1, 9)
.add(util.select()
.position(1, 1, 9)),
Direction.SOUTH);
scene.world()
.setKineticSpeed(util.select()
.fromTo(1, 1, 5, 0, 1, 5), 0);
scene.overlay()
.showText(50)
.colored(PonderPalette.BLUE)
.text("Peter")
.pointAt(util.vector()
.topOf(toFrog))
.placeNearTarget();
scene.idle(5);
scene.overlay()
.showText(55)
.colored(PonderPalette.OUTPUT)
.text("Peter")
.pointAt(util.vector()
.centerOf(util.grid()
.at(0, 2, 5)))
.placeNearTarget();
scene.idle(60);
scene.world()
.hideSection(util.select()
.fromTo(1, 2, 5, 0, 1, 5), Direction.WEST);
scene.world()
.hideSection(util.select()
.fromTo(5, 2, 1, 5, 1, 0)
.add(util.select()
.fromTo(6, 1, 0, 9, 1, 0)),
Direction.NORTH);
scene.world()
.hideSection(util.select()
.position(9, 0, 1), Direction.DOWN);
scene.idle(15);
scene.world()
.hideIndependentSection(casingE, Direction.WEST);
scene.world()
.hideSection(util.select()
.position(2, 1, 5), Direction.WEST);
scene.idle(15);
ElementLink<WorldSectionElement> fromBarrelE = scene.world()
.showIndependentSection(fromBarrel, Direction.WEST);
scene.world()
.moveSection(fromBarrelE, util.vector()
.of(0, 0, -1), 0);
ElementLink<WorldSectionElement> toBarrelE = scene.world()
.showIndependentSection(toBarrel, Direction.WEST);
scene.world()
.moveSection(toBarrelE, util.vector()
.of(-1, 0, 0), 0);
scene.idle(20);
scene.overlay()
.showOutlineWithText(util.select()
.position(fromFrog.below())
.add(fromFrogS), 70)
.attachKeyFrame()
.colored(PonderPalette.BLUE)
.text("Frogports can directly interface with inventories below them")
.pointAt(util.vector()
.topOf(fromFrog.below()))
.placeNearTarget();
scene.idle(70);
scene.world()
.hideIndependentSection(fromBarrelE, Direction.WEST);
scene.world()
.hideIndependentSection(toBarrelE, Direction.EAST);
scene.idle(15);
scene.world()
.showIndependentSection(fromPackager, Direction.WEST);
ElementLink<WorldSectionElement> toPackagerE = scene.world()
.showIndependentSection(toPackager, Direction.WEST);
scene.world()
.moveSection(toPackagerE, util.vector()
.of(0, 0, 1), 0);
ElementLink<WorldSectionElement> leverE = scene.world()
.showIndependentSection(util.select()
.position(lever), Direction.DOWN);
scene.world()
.moveSection(leverE, util.vector()
.of(-1, 0, 0), 0);
scene.idle(15);
scene.overlay()
.showText(90)
.attachKeyFrame()
.text("This works with packagers, items can be packed and shipped directly")
.pointAt(util.vector()
.blockSurface(fromFrog.below(), Direction.WEST))
.placeNearTarget();
scene.idle(100);
scene.world()
.showSection(sign, Direction.EAST);
scene.idle(10);
scene.overlay()
.showText(80)
.colored(PonderPalette.BLUE)
.text("Albert")
.pointAt(util.vector()
.topOf(fromFrog))
.placeNearTarget();
scene.overlay()
.showText(80)
.colored(PonderPalette.BLUE)
.text("Peter")
.pointAt(util.vector()
.topOf(toFrog))
.placeNearTarget();
scene.idle(20);
scene.overlay()
.showOutlineWithText(util.select()
.position(fromFrog.below())
.add(util.select()
.position(fromFrog.below()
.west())),
70)
.colored(PonderPalette.OUTPUT)
.text("Addresses packages to 'Peter'")
.pointAt(util.vector()
.blockSurface(fromFrog.below()
.west(), Direction.NORTH))
.placeNearTarget();
scene.idle(80);
scene.overlay()
.showControls(util.vector()
.blockSurface(util.grid()
.at(6, 1, 2), Direction.UP)
.add(0.5, 0, 0), Pointing.DOWN, 40)
.withItem(new ItemStack(Items.DIAMOND));
scene.idle(25);
scene.addKeyframe();
scene.effects()
.indicateRedstone(util.grid()
.at(5, 1, 1));
scene.world()
.toggleRedstonePower(util.select()
.fromTo(5, 1, 2, 6, 1, 1));
scene.idle(5);
scene.world()
.modifyBlockEntity(util.grid()
.at(5, 1, 2), PackagerBlockEntity.class, be -> {
be.animationTicks = PackagerBlockEntity.CYCLE;
be.animationInward = false;
be.heldBox = box;
});
scene.idle(30);
scene.world()
.modifyBlockEntity(util.grid()
.at(5, 1, 2), PackagerBlockEntity.class, be -> {
be.heldBox = ItemStack.EMPTY;
});
scene.world()
.modifyBlockEntity(fromFrog, FrogportBlockEntity.class, be -> be.startAnimation(box, true));
scene.idle(40);
scene.world()
.modifyBlockEntity(conv2, ChainConveyorBlockEntity.class, be -> boxTransfer(conv1, conv2, be));
scene.idle(50);
scene.world()
.modifyBlockEntity(util.grid()
.at(2, 1, 4), PackagerBlockEntity.class, be -> {
be.animationTicks = PackagerBlockEntity.CYCLE;
be.animationInward = true;
be.previouslyUnwrapped = box;
});
scene.idle(20);
scene.overlay()
.showControls(util.vector()
.blockSurface(util.grid()
.at(0, 1, 5), Direction.UP)
.add(0.5, 0, 0), Pointing.DOWN, 40)
.withItem(new ItemStack(Items.DIAMOND));
scene.idle(60);
scene.overlay()
.showControls(util.vector()
.centerOf(util.grid()
.at(2, 2, 5)),
Pointing.RIGHT, 40)
.rightClick()
.withItem(AllBlocks.CLIPBOARD.asStack());
scene.idle(10);
scene.overlay()
.showText(90)
.attachKeyFrame()
.text("Right-click Frogports with a clipboard to collect their address")
.pointAt(util.vector()
.blockSurface(toFrog, Direction.WEST))
.placeNearTarget();
scene.idle(70);
scene.world()
.showSection(logistics, Direction.DOWN);
scene.idle(30);
scene.overlay()
.showText(120)
.text("Clipboards with collected names can help auto-complete address inputs in other UIs")
.pointAt(util.vector()
.topOf(util.grid()
.at(2, 1, 2)))
.placeNearTarget();
scene.idle(70);
}
public static void boxTransfer(BlockPos to, BlockPos from, ChainConveyorBlockEntity be) {
for (Iterator<ChainConveyorPackage> iterator = be.getLoopingPackages()
.iterator(); iterator.hasNext();) {
ChainConveyorPackage chainConveyorPackage = iterator.next();
chainConveyorPackage.chainPosition = 0;
be.addTravellingPackage(chainConveyorPackage, to.subtract(from));
iterator.remove();
}
}
}

View file

@ -2,8 +2,11 @@ package com.simibubi.create.infrastructure.ponder.scenes;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.redstone.RoseQuartzLampBlock;
import com.simibubi.create.content.redstone.diodes.BrassDiodeBlock;
import com.simibubi.create.content.redstone.diodes.PulseTimerBlockEntity;
import com.simibubi.create.content.redstone.nixieTube.NixieTubeBlockEntity;
import com.simibubi.create.foundation.ponder.CreateSceneBuilder;
import com.simibubi.create.foundation.ponder.CreateSceneBuilder.WorldInstructions;
import net.createmod.catnip.utility.Pointing;
import net.createmod.ponder.api.element.ElementLink;
@ -11,8 +14,10 @@ import net.createmod.ponder.api.element.WorldSectionElement;
import net.createmod.ponder.api.scene.SceneBuilder;
import net.createmod.ponder.api.scene.SceneBuildingUtil;
import net.createmod.ponder.api.scene.Selection;
import net.createmod.ponder.api.scene.SelectionUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.phys.Vec3;
public class RedstoneScenes2 {
@ -21,120 +26,184 @@ public class RedstoneScenes2 {
scene.title("rose_quartz_lamp", "Rose Quartz Lamps");
scene.configureBasePlate(0, 0, 7);
BlockPos centerLamp = util.grid().at(3, 1, 3);
Selection input = util.select().fromTo(3, 1, 1, 3, 1, 2);
Selection button = util.select().position(3, 1, 1);
Selection wire = util.select().position(3, 1, 2);
Selection output = util.select().fromTo(5, 1, 2, 5, 1, 1);
Selection comparator = util.select().fromTo(1, 1, 3, 0, 1, 3);
BlockPos centerLamp = util.grid()
.at(3, 1, 3);
Selection input = util.select()
.fromTo(3, 1, 1, 3, 1, 2);
Selection button = util.select()
.position(3, 1, 1);
Selection wire = util.select()
.position(3, 1, 2);
Selection output = util.select()
.fromTo(5, 1, 2, 5, 1, 1);
Selection comparator = util.select()
.fromTo(1, 1, 3, 0, 1, 3);
scene.showBasePlate();
scene.idle(15);
ElementLink<WorldSectionElement> rowElement =
scene.world().showIndependentSection(util.select().position(centerLamp), Direction.DOWN);
ElementLink<WorldSectionElement> rowElement = scene.world()
.showIndependentSection(util.select()
.position(centerLamp), Direction.DOWN);
scene.idle(5);
scene.world().showSection(input, Direction.SOUTH);
scene.world()
.showSection(input, Direction.SOUTH);
scene.idle(15);
scene.world().toggleRedstonePower(input);
scene.effects().indicateRedstone(util.grid().at(3, 1, 1));
scene.world().cycleBlockProperty(centerLamp, RoseQuartzLampBlock.POWERING);
scene.world()
.toggleRedstonePower(input);
scene.effects()
.indicateRedstone(util.grid()
.at(3, 1, 1));
scene.world()
.cycleBlockProperty(centerLamp, RoseQuartzLampBlock.POWERING);
scene.idle(15);
scene.overlay().showText(70)
.pointAt(util.vector().blockSurface(centerLamp, Direction.WEST))
scene.overlay()
.showText(70)
.pointAt(util.vector()
.blockSurface(centerLamp, Direction.WEST))
.placeNearTarget()
.attachKeyFrame()
.text("Rose Quartz Lamps activate on a Redstone signal");
scene.idle(5);
scene.world().toggleRedstonePower(button);
scene.world()
.toggleRedstonePower(button);
scene.idle(55);
scene.world().hideSection(input, Direction.EAST);
scene.world()
.hideSection(input, Direction.EAST);
scene.idle(10);
ElementLink<WorldSectionElement> outputElement = scene.world().showIndependentSection(output, Direction.EAST);
scene.world().moveSection(outputElement, util.vector().of(-2, 0, 0), 0);
ElementLink<WorldSectionElement> outputElement = scene.world()
.showIndependentSection(output, Direction.EAST);
scene.world()
.moveSection(outputElement, util.vector()
.of(-2, 0, 0), 0);
scene.idle(10);
scene.world().toggleRedstonePower(wire);
scene.world().toggleRedstonePower(output);
scene.world()
.toggleRedstonePower(wire);
scene.world()
.toggleRedstonePower(output);
scene.idle(5);
scene.overlay().showText(70)
.pointAt(util.vector().blockSurface(centerLamp, Direction.WEST))
scene.overlay()
.showText(70)
.pointAt(util.vector()
.blockSurface(centerLamp, Direction.WEST))
.placeNearTarget()
.text("They will continue to emit redstone power afterwards");
scene.idle(60);
scene.world().hideIndependentSection(outputElement, Direction.NORTH);
scene.world().showSectionAndMerge(util.select().position(centerLamp.west()), Direction.EAST, rowElement);
scene.world()
.hideIndependentSection(outputElement, Direction.NORTH);
scene.world()
.showSectionAndMerge(util.select()
.position(centerLamp.west()), Direction.EAST, rowElement);
scene.idle(3);
scene.world().showSectionAndMerge(util.select().position(centerLamp.east()), Direction.WEST, rowElement);
scene.world()
.showSectionAndMerge(util.select()
.position(centerLamp.east()), Direction.WEST, rowElement);
scene.idle(25);
scene.overlay().showText(50)
.pointAt(util.vector().blockSurface(util.grid().at(2, 1, 3), Direction.WEST))
scene.overlay()
.showText(50)
.pointAt(util.vector()
.blockSurface(util.grid()
.at(2, 1, 3), Direction.WEST))
.placeNearTarget()
.attachKeyFrame()
.text("When multiple lamps are arranged in a group...");
scene.idle(40);
ElementLink<WorldSectionElement> inputElement = scene.world().showIndependentSection(input, Direction.SOUTH);
scene.world().moveSection(inputElement, util.vector().of(1, 0, 0), 0);
ElementLink<WorldSectionElement> inputElement = scene.world()
.showIndependentSection(input, Direction.SOUTH);
scene.world()
.moveSection(inputElement, util.vector()
.of(1, 0, 0), 0);
scene.idle(15);
scene.world().toggleRedstonePower(input);
scene.effects().indicateRedstone(util.grid().at(4, 1, 1));
scene.world().cycleBlockProperty(centerLamp, RoseQuartzLampBlock.POWERING);
scene.world().cycleBlockProperty(centerLamp.east(), RoseQuartzLampBlock.POWERING);
scene.world()
.toggleRedstonePower(input);
scene.effects()
.indicateRedstone(util.grid()
.at(4, 1, 1));
scene.world()
.cycleBlockProperty(centerLamp, RoseQuartzLampBlock.POWERING);
scene.world()
.cycleBlockProperty(centerLamp.east(), RoseQuartzLampBlock.POWERING);
scene.idle(15);
scene.overlay().showText(80)
.pointAt(util.vector().blockSurface(util.grid().at(4, 1, 3), Direction.UP))
scene.overlay()
.showText(80)
.pointAt(util.vector()
.blockSurface(util.grid()
.at(4, 1, 3), Direction.UP))
.placeNearTarget()
.text("...activating a Lamp will focus the signal to it, deactivating all others");
scene.idle(5);
scene.world().toggleRedstonePower(button);
scene.world()
.toggleRedstonePower(button);
scene.idle(60);
scene.world().hideIndependentSection(inputElement, Direction.NORTH);
scene.world().moveSection(rowElement, util.vector().of(1, 0, 0), 10);
scene.idle(15);
scene.world().showSectionAndMerge(comparator, Direction.EAST, rowElement);
scene.idle(15);
scene.world().toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 13));
.hideIndependentSection(inputElement, Direction.NORTH);
scene.world()
.moveSection(rowElement, util.vector()
.of(1, 0, 0), 10);
scene.idle(15);
scene.world()
.showSectionAndMerge(comparator, Direction.EAST, rowElement);
scene.idle(15);
scene.world()
.toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 13));
scene.idle(25);
scene.overlay().showText(80)
.pointAt(util.vector().blockSurface(util.grid().at(1, 1, 3), Direction.WEST))
scene.overlay()
.showText(80)
.pointAt(util.vector()
.blockSurface(util.grid()
.at(1, 1, 3), Direction.WEST))
.placeNearTarget()
.attachKeyFrame()
.text("Comparators output based on the distance to a powered lamp");
scene.idle(90);
scene.overlay().showControls(util.vector().topOf(centerLamp.east(2)), Pointing.DOWN, 20).rightClick()
.withItem(AllItems.WRENCH.asStack());
scene.idle(6);
scene.world().cycleBlockProperty(centerLamp.east(), RoseQuartzLampBlock.POWERING);
scene.world().toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 0));
scene.idle(20);
scene.overlay().showControls(util.vector().topOf(centerLamp), Pointing.DOWN, 20).rightClick()
scene.overlay()
.showControls(util.vector()
.topOf(centerLamp.east(2)), Pointing.DOWN, 20)
.rightClick()
.withItem(AllItems.WRENCH.asStack());
scene.idle(6);
scene.world().cycleBlockProperty(centerLamp.west(), RoseQuartzLampBlock.POWERING);
scene.world().toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 15));
.cycleBlockProperty(centerLamp.east(), RoseQuartzLampBlock.POWERING);
scene.world()
.toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 0));
scene.idle(20);
scene.overlay().showText(80)
.pointAt(util.vector().blockSurface(util.grid().at(3, 1, 3), Direction.UP))
scene.overlay()
.showControls(util.vector()
.topOf(centerLamp), Pointing.DOWN, 20)
.rightClick()
.withItem(AllItems.WRENCH.asStack());
scene.idle(6);
scene.world()
.cycleBlockProperty(centerLamp.west(), RoseQuartzLampBlock.POWERING);
scene.world()
.toggleRedstonePower(comparator);
scene.world()
.modifyBlockEntityNBT(comparator, NixieTubeBlockEntity.class, nbt -> nbt.putInt("RedstoneStrength", 15));
scene.idle(20);
scene.overlay()
.showText(80)
.pointAt(util.vector()
.blockSurface(util.grid()
.at(3, 1, 3), Direction.UP))
.placeNearTarget()
.attachKeyFrame()
.text("The Lamps can also be toggled manually using a Wrench");
@ -142,4 +211,166 @@ public class RedstoneScenes2 {
}
public static void pulseTimer(SceneBuilder builder, SceneBuildingUtil util) {
CreateSceneBuilder scene = new CreateSceneBuilder(builder);
scene.title("pulse_timer", "Redstone output of the Pulse Timer");
scene.configureBasePlate(0, 0, 5);
WorldInstructions world = scene.world();
SelectionUtil select = util.select();
world.showSection(select.layer(0), Direction.UP);
BlockPos circuitPos = util.grid()
.at(2, 1, 2);
BlockPos leverPos = util.grid()
.at(4, 1, 2);
Vec3 circuitTop = util.vector()
.blockSurface(circuitPos, Direction.DOWN)
.add(0, 3 / 16f, 0);
world.modifyBlockEntityNBT(select.position(circuitPos), PulseTimerBlockEntity.class,
nbt -> nbt.putInt("ScrollValue", 30));
world.showSection(select.fromTo(1, 1, 2, 0, 1, 2), Direction.UP);
scene.idle(10);
world.showSection(select.position(circuitPos), Direction.DOWN);
scene.idle(8);
for (int i = 0; i < 1; i++) {
scene.idle(12);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(2);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
scene.idle(15);
}
scene.overlay()
.showText(60)
.text("Pulse Timers repeatedly emit short pulses")
.attachKeyFrame()
.placeNearTarget()
.pointAt(circuitTop);
scene.idle(13);
for (int i = 0; i < 3; i++) {
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(2);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
scene.idle(27);
}
scene.overlay()
.showRepeaterScrollInput(circuitPos, 60);
scene.overlay()
.showControls(circuitTop, Pointing.DOWN, 60)
.rightClick();
scene.idle(10);
scene.overlay()
.showText(60)
.text("Using the value panel, the time interval can be configured")
.attachKeyFrame()
.placeNearTarget()
.pointAt(circuitTop);
world.modifyBlockEntityNBT(select.position(circuitPos), PulseTimerBlockEntity.class,
nbt -> nbt.putInt("ScrollValue", 100));
scene.idle(70);
world.showSection(select.fromTo(3, 1, 2, 4, 1, 2), Direction.WEST);
scene.idle(20);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(2);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
scene.idle(10);
scene.effects()
.indicateRedstone(leverPos);
scene.world()
.toggleRedstonePower(util.select()
.fromTo(4, 1, 2, 2, 1, 2));
scene.idle(30);
scene.overlay()
.showText(60)
.text("Powering the input side will pause and reset them")
.attachKeyFrame()
.placeNearTarget()
.pointAt(util.vector()
.topOf(4, 0, 2));
scene.idle(70);
world.hideSection(select.fromTo(3, 1, 2, 4, 1, 2), Direction.EAST);
scene.idle(5);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERED);
world.hideSection(select.position(0, 1, 2), Direction.WEST);
scene.idle(10);
scene.overlay()
.showControls(circuitTop.add(-.375, 0, .375), Pointing.DOWN, 60)
.rightClick();
scene.idle(10);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.INVERTED);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.overlay()
.showText(60)
.text("Right-click the circuit base to invert the output")
.attachKeyFrame()
.placeNearTarget()
.pointAt(circuitTop.add(-.375, 0, .375));
scene.idle(70);
ElementLink<WorldSectionElement> link = world.showIndependentSection(select.position(0, 1, 4), Direction.EAST);
world.moveSection(link, util.vector()
.of(0, 0, -2), 0);
scene.idle(10);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(3);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
scene.idle(10);
scene.overlay()
.showText(80)
.text("This helps trigger mechanisms that activate only without a redstone signal")
.placeNearTarget()
.pointAt(util.vector()
.centerOf(0, 1, 2));
scene.idle(86);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(3);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
scene.idle(10);
scene.markAsFinished();
scene.idle(86);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.fromTo(1, 1, 2, 0, 1, 2));
scene.idle(3);
world.cycleBlockProperty(circuitPos, BrassDiodeBlock.POWERING);
world.toggleRedstonePower(select.position(1, 1, 2));
scene.idle(1);
world.toggleRedstonePower(select.position(0, 1, 2));
}
}