From 140cd9a85a5094175de87474066162722ecf0eb1 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 21 Mar 2021 17:38:33 +0100 Subject: [PATCH] Sailing craft - Front face of crafters now supports hoppers and co - Scenes for Sails and Mechanical Crafters - Fixed a couple strange quirks of Ponder text windows --- .../crafter/MechanicalCrafterTileEntity.java | 62 ++- .../create/foundation/ponder/PonderScene.java | 17 +- .../create/foundation/ponder/PonderUI.java | 8 +- .../foundation/ponder/SceneBuilder.java | 13 + .../ponder/content/BearingScenes.java | 94 +++- .../ponder/content/CrafterScenes.java | 453 ++++++++++++++++++ .../ponder/content/PonderIndex.java | 16 + .../foundation/ponder/content/PonderTag.java | 4 + .../ponder/elements/InputWindowElement.java | 2 +- .../ponder/elements/ParrotElement.java | 2 +- .../ponder/elements/TextWindowElement.java | 10 +- .../ponder/mechanical_crafter/connect.nbt | Bin 0 -> 1144 bytes .../ponder/mechanical_crafter/covers.nbt | Bin 0 -> 825 bytes .../ponder/mechanical_crafter/setup.nbt | Bin 0 -> 904 bytes src/main/resources/ponder/sail.nbt | Bin 0 -> 447 bytes 15 files changed, 634 insertions(+), 47 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java create mode 100644 src/main/resources/ponder/mechanical_crafter/connect.nbt create mode 100644 src/main/resources/ponder/mechanical_crafter/covers.nbt create mode 100644 src/main/resources/ponder/mechanical_crafter/setup.nbt create mode 100644 src/main/resources/ponder/sail.nbt diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java index 64dc60b2d..6303c90c6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterTileEntity.java @@ -37,7 +37,6 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; public class MechanicalCrafterTileEntity extends KineticTileEntity { @@ -46,7 +45,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { IDLE, ACCEPTING, ASSEMBLING, EXPORTING, WAITING, CRAFTING, INSERTING; } - static class Inventory extends SmartInventory { + public static class Inventory extends SmartInventory { private MechanicalCrafterTileEntity te; @@ -57,11 +56,11 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { whenContentsChanged(slot -> { if (getStackInSlot(slot).isEmpty()) return; - if(te.phase == Phase.IDLE) + if (te.phase == Phase.IDLE) te.checkCompletedRecipe(false); }); } - + @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { if (te.phase != Phase.IDLE) @@ -70,9 +69,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { return stack; return super.insertItem(slot, stack, simulate); } - + } - + protected Inventory inventory; protected GroupedItems groupedItems = new GroupedItems(); protected ConnectedInput input = new ConnectedInput(); @@ -87,13 +86,15 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { private InvManipulationBehaviour inserting; private EdgeInteractionBehaviour connectivity; + private ItemStack scriptedResult = ItemStack.EMPTY; + public MechanicalCrafterTileEntity(TileEntityType type) { super(type); setLazyTickRate(20); phase = Phase.IDLE; groupedItemsBeforeCraft = new GroupedItems(); inventory = new Inventory(this); - + // Does not get serialized due to active checking in tick wasPoweredBefore = true; } @@ -118,7 +119,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { public BlockFace getTargetFace(World world, BlockPos pos, BlockState state) { return new BlockFace(pos, MechanicalCrafterBlock.getTargetDirection(state)); } - + public Direction getTargetDirection() { return MechanicalCrafterBlock.getTargetDirection(getBlockState()); } @@ -145,7 +146,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { compound.putBoolean("Cover", covered); super.write(compound, clientPacket); - + if (clientPacket && reRender) { compound.putBoolean("Redraw", true); reRender = false; @@ -156,7 +157,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { protected void read(CompoundNBT compound, boolean clientPacket) { Phase phaseBefore = phase; GroupedItems before = this.groupedItems; - + inventory.deserializeNBT(compound.getCompound("Inventory")); input.read(compound.getCompound("ConnectedInput")); groupedItems = GroupedItems.read(compound.getCompound("GroupedItems")); @@ -169,7 +170,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown = compound.getInt("CountDown"); covered = compound.getBoolean("Cover"); super.read(compound, clientPacket); - + if (!clientPacket) return; if (compound.contains("Redraw")) @@ -205,10 +206,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (phase == Phase.ACCEPTING) return; + boolean onClient = world.isRemote; + boolean runLogic = !onClient || isVirtual(); + if (wasPoweredBefore != world.isBlockPowered(pos)) { wasPoweredBefore = world.isBlockPowered(pos); if (wasPoweredBefore) { - if (world.isRemote) + if (!runLogic) return; checkCompletedRecipe(true); } @@ -218,7 +222,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown -= getCountDownSpeed(); if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; if (RecipeGridHandler.getTargetingCrafter(this) != null) { phase = Phase.EXPORTING; @@ -226,9 +230,11 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { sendData(); return; } - ItemStack result = RecipeGridHandler.tryToApplyRecipe(world, groupedItems); - if (result != null) { + ItemStack result = + isVirtual() ? scriptedResult : RecipeGridHandler.tryToApplyRecipe(world, groupedItems); + + if (result != null) { List containers = new ArrayList<>(); groupedItems.grid.values() .forEach(stack -> { @@ -237,6 +243,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { .copy()); }); + if (isVirtual()) + groupedItemsBeforeCraft = groupedItems; + groupedItems = new GroupedItems(result); for (int i = 0; i < containers.size(); i++) { ItemStack stack = containers.get(i); @@ -260,7 +269,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; MechanicalCrafterTileEntity targetingCrafter = RecipeGridHandler.getTargetingCrafter(this); @@ -283,7 +292,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { if (phase == Phase.CRAFTING) { - if (world.isRemote) { + if (onClient) { Direction facing = getBlockState().get(MechanicalCrafterBlock.HORIZONTAL_FACING); float progress = countDown / 2000f; Vec3d facingVec = new Vec3d(facing.getDirectionVec()); @@ -319,7 +328,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { countDown -= getCountDownSpeed(); if (countDown < 0) { countDown = 0; - if (world.isRemote) + if (!runLogic) return; tryInsert(); return; @@ -327,7 +336,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { } if (phase == Phase.INSERTING) { - if (!world.isRemote && isTargetingBelt()) + if (runLogic && isTargetingBelt()) tryInsert(); return; } @@ -364,7 +373,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { stack.setCount(remainder.getCount()); continue; } - + inserted.add(pair); } @@ -410,7 +419,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { @Override public void lazyTick() { super.lazyTick(); - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; if (phase == Phase.IDLE && craftingItemPresent()) checkCompletedRecipe(false); @@ -431,7 +440,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { protected void checkCompletedRecipe(boolean poweredStart) { if (getSpeed() == 0) return; - if (world.isRemote) + if (world.isRemote && !isVirtual()) return; List chain = RecipeGridHandler.getAllCraftersOfChainIf(this, poweredStart ? MechanicalCrafterTileEntity::craftingItemPresent @@ -471,11 +480,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { @Override public LazyOptional getCapability(Capability cap, Direction side) { - if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { - if (getBlockState().get(HORIZONTAL_FACING) == side) - return LazyOptional.empty(); + if (isItemHandlerCap(cap)) return invSupplier.cast(); - } return super.getCapability(cap, side); } @@ -495,4 +501,8 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity { return true; } + public void setScriptedResult(ItemStack scriptedResult) { + this.scriptedResult = scriptedResult; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java index 679854274..68d4fa0b2 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderScene.java @@ -451,14 +451,13 @@ public class PonderScene { return ms; } - public void updateSceneRVE() { - Vec3d v = screenToScene(width / 2, height / 2, 500); + public void updateSceneRVE(float pt) { + Vec3d v = screenToScene(width / 2, height / 2, 500, pt); renderViewEntity.setPosition(v.x, v.y, v.z); } - public Vec3d screenToScene(double x, double y, int depth) { - refreshMatrix(); - float pt = AnimationTickHolder.getPartialTicks(); + public Vec3d screenToScene(double x, double y, int depth, float pt) { + refreshMatrix(pt); Vec3d vec = new Vec3d(x, y, depth); vec = vec.subtract(width / 2, height / 2, 200 + offset); @@ -479,17 +478,17 @@ public class PonderScene { return vec; } - public Vec2f sceneToScreen(Vec3d vec) { - refreshMatrix(); + public Vec2f sceneToScreen(Vec3d vec, float pt) { + refreshMatrix(pt); Vector4f vec4 = new Vector4f((float) vec.x, (float) vec.y, (float) vec.z, 1); vec4.transform(cachedMat); return new Vec2f(vec4.getX(), vec4.getY()); } - protected void refreshMatrix() { + protected void refreshMatrix(float pt) { if (cachedMat != null) return; - cachedMat = apply(new MatrixStack()).peek() + cachedMat = apply(new MatrixStack(), pt, false).peek() .getModel(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index 0b241cae0..8cc99fedd 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -305,8 +305,8 @@ public class PonderUI extends NavigatableSimiScreen { double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); SceneTransform t = activeScene.getTransform(); - Vec3d vec1 = t.screenToScene(mouseX, mouseY, 1000); - Vec3d vec2 = t.screenToScene(mouseX, mouseY, -100); + Vec3d vec1 = t.screenToScene(mouseX, mouseY, 1000, 0); + Vec3d vec2 = t.screenToScene(mouseX, mouseY, -100, 0); Pair pair = activeScene.rayTraceScene(vec1, vec2); hoveredTooltipItem = pair.getFirst(); hoveredBlockPos = pair.getSecond(); @@ -391,7 +391,7 @@ public class PonderUI extends NavigatableSimiScreen { ms.push(); story.transform.updateScreenParams(width, height, slide); story.transform.apply(ms, partialTicks, false); - story.transform.updateSceneRVE(); + story.transform.updateSceneRVE(partialTicks); story.renderScene(buffer, ms, partialTicks); buffer.draw(); @@ -698,7 +698,7 @@ public class PonderUI extends NavigatableSimiScreen { RenderSystem.pushMatrix(); PonderScene story = scenes.get(i); MatrixStack ms = new MatrixStack(); - story.renderOverlay(this, ms, partialTicks); + story.renderOverlay(this, ms, skipCooling > 0 ? 0 : identifyMode ? ponderPartialTicksPaused : partialTicks); RenderSystem.popMatrix(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java index 7c0f52c56..51d2925be 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/SceneBuilder.java @@ -10,6 +10,8 @@ import java.util.function.UnaryOperator; import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.content.contraptions.base.KineticBlock; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.crafter.ConnectedInputHandler; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData; @@ -777,6 +779,17 @@ public class SceneBuilder { modifyTileEntity(position, FunnelTileEntity.class, funnel -> funnel.flap(!outward)); } + public void setCraftingResult(BlockPos crafter, ItemStack output) { + modifyTileEntity(crafter, MechanicalCrafterTileEntity.class, mct -> mct.setScriptedResult(output)); + } + + public void connectCrafterInvs(BlockPos position1, BlockPos position2) { + addInstruction(s -> { + ConnectedInputHandler.toggleConnection(s.getWorld(), position1, position2); + s.forEach(WorldSectionElement.class, WorldSectionElement::queueRedraw); + }); + } + } public class DebugInstructions { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java index 59aac1a8d..eca104623 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/BearingScenes.java @@ -14,6 +14,9 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Pointing; import net.minecraft.entity.Entity; +import net.minecraft.item.DyeColor; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -25,7 +28,7 @@ public class BearingScenes { scene.title("windmill_source", "Generating Rotational Force using Windmill Bearings"); scene.configureBasePlate(1, 1, 5); scene.setSceneOffsetY(-1); - + scene.world.showSection(util.select.fromTo(1, 0, 1, 5, 0, 5), Direction.UP); scene.world.setBlock(util.grid.at(2, -1, 0), AllBlocks.SAIL.getDefaultState() .with(SailBlock.FACING, Direction.NORTH), false); @@ -280,7 +283,7 @@ public class BearingScenes { scene.title("bearing_modes", "Movement Modes of the Mechanical Bearing"); scene.configureBasePlate(1, 1, 6); scene.setSceneOffsetY(-1); - + Selection sideCog = util.select.position(util.grid.at(7, 0, 3)); Selection cogColumn = util.select.fromTo(6, 1, 3, 6, 4, 3); Selection cogAndClutch = util.select.fromTo(5, 3, 1, 5, 4, 2); @@ -566,4 +569,91 @@ public class BearingScenes { } } + public static void sail(SceneBuilder scene, SceneBuildingUtil util) { + sails(scene, util, false); + } + + public static void sailFrame(SceneBuilder scene, SceneBuildingUtil util) { + sails(scene, util, true); + } + + private static void sails(SceneBuilder scene, SceneBuildingUtil util, boolean frame) { + String plural = frame ? "Sail Frames" : "Sails"; + scene.title(frame ? "sail_frame" : "sail", "Assembling Windmills using " + plural); + scene.configureBasePlate(0, 0, 5); + scene.scaleSceneView(0.9f); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.idle(5); + + BlockPos bearingPos = util.grid.at(2, 1, 2); + scene.world.showSection(util.select.position(bearingPos), Direction.DOWN); + scene.idle(5); + ElementLink plank = + scene.world.showIndependentSection(util.select.position(bearingPos.up()), Direction.DOWN); + scene.idle(10); + + for (int i = 0; i < 3; i++) { + for (Direction d : Iterate.horizontalDirections) { + BlockPos location = bearingPos.up(i + 1) + .offset(d); + if (frame) + scene.world.modifyBlock(location, s -> AllBlocks.SAIL_FRAME.getDefaultState() + .with(SailBlock.FACING, s.get(SailBlock.FACING)), false); + scene.world.showSectionAndMerge(util.select.position(location), d.getOpposite(), plank); + scene.idle(2); + } + } + + scene.overlay.showText(70) + .text(plural + " are handy blocks to create Windmills with") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.WEST)) + .placeNearTarget() + .attachKeyFrame(); + scene.idle(80); + + scene.overlay.showSelectionWithText(util.select.position(bearingPos.up()), 80) + .colored(PonderPalette.GREEN) + .text("They will attach to blocks and each other without the need of Super Glue or Chassis Blocks") + .attachKeyFrame() + .placeNearTarget(); + scene.idle(40); + scene.world.configureCenterOfRotation(plank, util.vector.centerOf(bearingPos)); + + if (!frame) { + scene.world.rotateBearing(bearingPos, 180, 75); + scene.world.rotateSection(plank, 0, 180, 0, 75); + scene.idle(76); + scene.world.rotateBearing(bearingPos, 180, 0); + scene.world.rotateSection(plank, 0, 180, 0, 0); + scene.rotateCameraY(-30); + scene.idle(10); + InputWindowElement input = + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.NORTH), Pointing.RIGHT) + .withItem(new ItemStack(Items.BLUE_DYE)); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.setBlock(util.grid.at(2, 3, 1), AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() + .with(SailBlock.FACING, Direction.WEST), true); + scene.idle(10); + scene.overlay.showText(40) + .colored(PonderPalette.BLUE) + .text("Right Click with Dye to paint them") + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 1), Direction.WEST)) + .placeNearTarget(); + scene.idle(20); + scene.overlay.showControls(input, 30); + scene.idle(7); + scene.world.replaceBlocks(util.select.fromTo(2, 2, 1, 2, 4, 1), + AllBlocks.DYED_SAILS[DyeColor.BLUE.ordinal()].getDefaultState() + .with(SailBlock.FACING, Direction.WEST), + true); + scene.idle(20); + } + + scene.world.rotateBearing(bearingPos, 720, 300); + scene.world.rotateSection(plank, 0, 720, 0, 300); + + } + } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java b/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java new file mode 100644 index 000000000..e4823d247 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/CrafterScenes.java @@ -0,0 +1,453 @@ +package com.simibubi.create.foundation.ponder.content; + +import java.util.Collection; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock; +import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity; +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.EntityElement; +import com.simibubi.create.foundation.ponder.elements.InputWindowElement; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.Pointing; + +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Direction; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.items.ItemHandlerHelper; + +public class CrafterScenes { + + public static void setup(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter", "Setting up Mechanical Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + scene.world.modifyKineticSpeed(util.select.everywhere(), f -> 1.5f * f); + + Selection redstone = util.select.fromTo(3, 1, 0, 3, 1, 1); + Selection kinetics = util.select.fromTo(4, 1, 2, 4, 1, 5); + BlockPos depotPos = util.grid.at(0, 1, 2); + Selection crafters = util.select.fromTo(1, 1, 2, 3, 3, 2); + + scene.world.modifyBlocks(crafters, s -> s.with(MechanicalCrafterBlock.POINTING, Pointing.DOWN), false); + scene.world.setKineticSpeed(crafters, 0); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 3; x++) { + scene.world.showSection(util.select.position(y == 1 ? x + 1 : 3 - x, y + 1, 2), Direction.DOWN); + scene.idle(2); + } + } + + scene.overlay.showText(70) + .text("An array of Mechanical Crafters can be used to automate any Crafting Recipe") + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.WEST)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(80); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH), Pointing.RIGHT) + .rightClick() + .withWrench(), + 40); + scene.idle(7); + scene.world.cycleBlockProperty(util.grid.at(2, 3, 2), MechanicalCrafterBlock.POINTING); + scene.idle(10); + scene.overlay.showText(50) + .text("Using a Wrench, the Crafters' paths can be arranged") + .pointAt(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + BlockPos[] positions = new BlockPos[] { util.grid.at(3, 1, 2), util.grid.at(2, 1, 2), util.grid.at(1, 1, 2) }; + + for (BlockPos pos : positions) { + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(pos, Direction.NORTH), Pointing.RIGHT).rightClick() + .withWrench(), + 10); + scene.idle(7); + scene.world.cycleBlockProperty(pos, MechanicalCrafterBlock.POINTING); + scene.idle(15); + } + + scene.overlay.showText(100) + .text("For a valid setup, all paths have to converge into one exit at any side") + .pointAt(util.vector.blockSurface(util.grid.at(1, 1, 2), Direction.WEST) + .add(0, 0, -.5f)) + .colored(PonderPalette.GREEN) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + Collection> couples = + ImmutableList.of(Couple.create(util.grid.at(3, 3, 2), util.grid.at(3, 2, 2)), + Couple.create(util.grid.at(3, 2, 2), util.grid.at(3, 1, 2)), + Couple.create(util.grid.at(2, 3, 2), util.grid.at(1, 3, 2)), + Couple.create(util.grid.at(3, 1, 2), util.grid.at(2, 1, 2)), + Couple.create(util.grid.at(1, 3, 2), util.grid.at(1, 2, 2)), + Couple.create(util.grid.at(2, 2, 2), util.grid.at(2, 1, 2)), + Couple.create(util.grid.at(1, 2, 2), util.grid.at(1, 1, 2)), + Couple.create(util.grid.at(2, 1, 2), util.grid.at(1, 1, 2)), + Couple.create(util.grid.at(1, 1, 2), util.grid.at(0, 1, 2))); + + for (Couple c : couples) { + scene.idle(5); + Vec3d p1 = util.vector.blockSurface(c.getFirst(), Direction.NORTH) + .add(0, 0, -0.125); + Vec3d p2 = util.vector.blockSurface(c.getSecond(), Direction.NORTH) + .add(0, 0, -0.125); + AxisAlignedBB point = new AxisAlignedBB(p1, p1); + AxisAlignedBB line = new AxisAlignedBB(p1, p2); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, p1, point, 2); + scene.idle(1); + scene.overlay.chaseBoundingBoxOutline(PonderPalette.GREEN, p1, line, 30); + } + + scene.world.showSection(util.select.position(depotPos), Direction.EAST); + scene.idle(20); + scene.overlay.showText(60) + .text("The outputs will be placed into the inventory at the exit") + .pointAt(util.vector.blockSurface(util.grid.at(0, 1, 2), Direction.NORTH)) + .placeNearTarget(); + scene.idle(70); + + scene.rotateCameraY(60); + scene.idle(20); + scene.world.showSection(kinetics, Direction.NORTH); + scene.overlay.showText(60) + .text("Mechanical Crafters require Rotational Force to operate") + .pointAt(util.vector.blockSurface(util.grid.at(4, 1, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(8); + scene.world.setKineticSpeed(crafters, -48); + scene.world.multiplyKineticSpeed(util.select.position(3, 2, 2) + .add(util.select.position(2, 3, 2)) + .add(util.select.position(1, 2, 2)) + .add(util.select.position(2, 1, 2)), -1); + scene.idle(55); + scene.rotateCameraY(-60); + + scene.idle(40); + ItemStack planks = new ItemStack(Items.OAK_PLANKS); + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.NORTH), Pointing.RIGHT) + .rightClick() + .withItem(planks), + 40); + scene.idle(7); + Class type = MechanicalCrafterTileEntity.class; + scene.world.modifyTileEntity(util.grid.at(1, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + + scene.idle(10); + scene.overlay.showText(50) + .text("Right-Click the front to insert Items manually") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.NORTH)) + .attachKeyFrame() + .placeNearTarget(); + scene.idle(60); + + ItemStack alloy = AllItems.ANDESITE_ALLOY.asStack(); + ItemStack log = new ItemStack(Items.OAK_LOG); + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), AllBlocks.ANDESITE_CASING.asStack(4)); + + scene.world.modifyTileEntity(util.grid.at(2, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, alloy.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, log.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, alloy.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(3, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + + scene.overlay.showText(80) + .attachKeyFrame() + .text("Once every slot of a path contains an Item, the crafting process will begin") + .pointAt(util.vector.blockSurface(util.grid.at(1, 3, 2), Direction.WEST)) + .placeNearTarget(); + scene.idle(180); + + scene.world.removeItemsFromBelt(depotPos); + + ItemStack stick = new ItemStack(Items.STICK); + ItemStack iron = new ItemStack(Items.IRON_INGOT); + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), new ItemStack(Items.IRON_PICKAXE)); + + scene.world.modifyTileEntity(util.grid.at(1, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(3, 3, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, stick.copy(), false)); + scene.idle(2); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, stick.copy(), false)); + scene.world.showSection(redstone, Direction.SOUTH); + scene.idle(10); + + scene.overlay.showText(90) + .attachKeyFrame() + .colored(PonderPalette.RED) + .text("For recipes not fully occupying the crafter setup, the start can be forced using a Redstone Pulse") + .pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.NORTH)) + .placeNearTarget(); + scene.idle(100); + scene.effects.indicateRedstone(util.grid.at(3, 1, 0)); + scene.world.toggleRedstonePower(redstone); + scene.idle(20); + scene.world.toggleRedstonePower(redstone); + } + + public static void connect(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter_connect", "Connecting Inventories of Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + for (int y = 0; y < 3; y++) { + for (int x = 0; x < 2; x++) { + scene.world.showSection(util.select.position(y == 1 ? x + 1 : 2 - x, y + 1, 2), Direction.DOWN); + scene.idle(2); + } + } + + Class type = MechanicalCrafterTileEntity.class; + BlockPos depotPos = util.grid.at(0, 1, 2); + Selection funnel = util.select.fromTo(4, 1, 5, 4, 1, 2) + .add(util.select.fromTo(3, 2, 2, 3, 1, 2)); + Selection kinetics = util.select.position(3, 3, 2) + .add(util.select.fromTo(3, 3, 3, 3, 1, 3)); + scene.idle(5); + + scene.world.showSection(kinetics, Direction.NORTH); + scene.idle(5); + scene.world.showSection(util.select.position(depotPos), Direction.EAST); + scene.idle(10); + scene.world.showSection(funnel, Direction.WEST); + scene.rotateCameraY(60); + ItemStack planks = new ItemStack(Items.OAK_PLANKS); + scene.world.createItemOnBelt(util.grid.at(4, 1, 2), Direction.EAST, planks.copy()); + scene.idle(22); + + scene.world.modifyTileEntity(util.grid.at(2, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.world.removeItemsFromBelt(util.grid.at(3, 1, 2)); + scene.world.flapFunnel(util.grid.at(3, 2, 2), false); + + scene.overlay.showSelectionWithText(util.select.position(2, 2, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Items can be inserted to Crafters automatically"); + scene.idle(80); + + scene.rotateCameraY(-60 - 90 - 30); + scene.idle(40); + + Vec3d v = util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.WEST); + AxisAlignedBB bb = new AxisAlignedBB(v, v).grow(.125f, .5, .5); + v = v.add(0, 0, .5); + + scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, new Object(), bb, 45); + scene.overlay.showControls(new InputWindowElement(v, Pointing.LEFT).rightClick() + .withWrench(), 40); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 2, 2), util.grid.at(1, 2, 2)); + scene.idle(40); + scene.overlay.showSelectionWithText(util.select.fromTo(2, 2, 2, 1, 2, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .pointAt(v) + .text("Using the Wrench at their backs, Mechanical Crafter inputs can be combined"); + scene.idle(80); + scene.overlay.showControls(new InputWindowElement(v.add(0, 1, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 3, 2), util.grid.at(1, 3, 2)); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(v.add(0, -1, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(1, 1, 2)); + scene.idle(20); + scene.overlay.showControls(new InputWindowElement(v.add(.5, -.5, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(2, 2, 2)); + scene.idle(10); + scene.overlay.showControls(new InputWindowElement(v.add(.5, .5, 0), Pointing.LEFT).rightClick() + .withWrench(), 20); + scene.idle(7); + scene.world.connectCrafterInvs(util.grid.at(2, 2, 2), util.grid.at(2, 3, 2)); + scene.idle(20); + + scene.rotateCameraY(90 + 30); + scene.idle(40); + scene.overlay.showSelectionWithText(util.select.fromTo(1, 1, 2, 2, 3, 2), 70) + .attachKeyFrame() + .placeNearTarget() + .text("All connected Crafters can now be accessed by the same input location"); + scene.idle(60); + scene.overlay.showControls( + new InputWindowElement(util.vector.centerOf(util.grid.at(4, 2, 2)), Pointing.DOWN).withItem(planks), 40); + scene.idle(7); + scene.world.createItemOnBelt(util.grid.at(4, 1, 2), Direction.EAST, + ItemHandlerHelper.copyStackWithSize(planks, 16)); + scene.idle(22); + + scene.world.removeItemsFromBelt(util.grid.at(3, 1, 2)); + BlockPos[] positions = new BlockPos[] { util.grid.at(2, 3, 2), util.grid.at(1, 3, 2), util.grid.at(1, 2, 2), + util.grid.at(2, 1, 2), util.grid.at(1, 1, 2) }; + + scene.world.setCraftingResult(util.grid.at(1, 1, 2), new ItemStack(Items.OAK_DOOR, 3)); + for (BlockPos pos : positions) { + scene.world.modifyTileEntity(pos, type, mct -> mct.getInventory() + .insertItem(0, planks.copy(), false)); + scene.idle(1); + } + + } + + public static void covers(SceneBuilder scene, SceneBuildingUtil util) { + scene.title("mechanical_crafter_covers", "Covering slots of Mechanical Crafters"); + scene.configureBasePlate(0, 0, 5); + scene.world.showSection(util.select.layer(0), Direction.UP); + + scene.world.setBlock(util.grid.at(2, 2, 2), Blocks.AIR.getDefaultState(), false); + + Selection kinetics = util.select.fromTo(3, 1, 2, 3, 1, 5); + scene.world.setKineticSpeed(util.select.fromTo(1, 2, 2, 3, 1, 2), 0); + + scene.world.showSection(util.select.position(3, 2, 2), Direction.EAST); + scene.idle(5); + scene.world.showSection(util.select.position(2, 1, 2), Direction.DOWN); + scene.idle(5); + scene.world.showSection(util.select.position(1, 2, 2), Direction.WEST); + scene.idle(5); + + ItemStack iron = new ItemStack(Items.IRON_INGOT); + + Class type = MechanicalCrafterTileEntity.class; + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + scene.idle(5); + + Selection emptyCrafter = util.select.position(2, 2, 2); + scene.overlay.showSelectionWithText(emptyCrafter, 90) + .attachKeyFrame() + .colored(PonderPalette.RED) + .text("Some recipes will require additional Crafters to bridge gaps in the path") + .placeNearTarget(); + scene.idle(70); + scene.world.restoreBlocks(emptyCrafter); + scene.world.setCraftingResult(util.grid.at(2, 2, 2), new ItemStack(Items.BUCKET)); + scene.world.showSection(emptyCrafter, Direction.DOWN); + scene.idle(10); + scene.world.showSection(util.select.position(2, 3, 2), Direction.DOWN); + scene.world.showSection(kinetics, Direction.NORTH); + scene.idle(5); + scene.world.setKineticSpeed(util.select.fromTo(3, 1, 2, 1, 2, 2), -32); + scene.world.setKineticSpeed(util.select.position(3, 1, 2) + .add(emptyCrafter), 32); + + scene.idle(20); + + scene.overlay.showText(90) + .attachKeyFrame() + .colored(PonderPalette.GREEN) + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Using Slot Covers, Crafters can be set to act as an Empty Slot in the arrangement") + .placeNearTarget(); + scene.idle(100); + scene.overlay + .showControls(new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH) + .add(0.5, 0, 0), Pointing.RIGHT).withItem(AllItems.CRAFTER_SLOT_COVER.asStack()) + .rightClick(), + 50); + scene.idle(7); + scene.world.modifyTileNBT(emptyCrafter, type, compound -> compound.putBoolean("Cover", true)); + scene.idle(130); + + scene.overlay.showControls( + new InputWindowElement(util.vector.blockSurface(util.grid.at(2, 3, 2), Direction.WEST), Pointing.LEFT) + .withItem(new ItemStack(Items.BUCKET)), + 40); + scene.idle(50); + scene.world.showSection(util.select.position(4, 2, 2), Direction.DOWN); + + scene.world.connectCrafterInvs(util.grid.at(3, 2, 2), util.grid.at(2, 2, 2)); + scene.idle(5); + scene.world.connectCrafterInvs(util.grid.at(2, 1, 2), util.grid.at(2, 2, 2)); + scene.idle(5); + scene.world.connectCrafterInvs(util.grid.at(1, 2, 2), util.grid.at(2, 2, 2)); + scene.idle(10); + + scene.overlay.showSelectionWithText(util.select.fromTo(3, 2, 2, 1, 2, 2) + .add(util.select.position(2, 1, 2)), 80) + .attachKeyFrame() + .pointAt(util.vector.blockSurface(util.grid.at(2, 2, 2), Direction.NORTH)) + .text("Shared Inputs created with the Wrench at the back can also reach across covered Crafters") + .placeNearTarget(); + scene.idle(60); + + ElementLink ingot = + scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(3, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + ingot = scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(2, 1, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + ingot = scene.world.createItemEntity(util.vector.centerOf(4, 4, 2), util.vector.of(0, 0.2, 0), iron); + scene.idle(17); + scene.world.modifyEntity(ingot, Entity::remove); + scene.world.modifyTileEntity(util.grid.at(1, 2, 2), type, mct -> mct.getInventory() + .insertItem(0, iron.copy(), false)); + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java index 7d5877ff9..32c8a6445 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndex.java @@ -97,6 +97,13 @@ public class PonderIndex { PonderRegistry.addStoryBoard(AllBlocks.BLAZE_BURNER, "blaze_burner", ProcessingScenes::blazeBurner); PonderRegistry.addStoryBoard(AllBlocks.DEPOT, "depot", BeltScenes::depot); + // Crafters + PonderRegistry.forComponents(AllBlocks.MECHANICAL_CRAFTER) + .addStoryBoard("mechanical_crafter/setup", CrafterScenes::setup) + .addStoryBoard("mechanical_crafter/connect", CrafterScenes::connect); + PonderRegistry.forComponents(AllBlocks.MECHANICAL_CRAFTER, AllItems.CRAFTER_SLOT_COVER) + .addStoryBoard("mechanical_crafter/covers", CrafterScenes::covers); + // Chutes PonderRegistry.forComponents(AllBlocks.CHUTE) .addStoryBoard("chute/downward", ChuteScenes::downward, PonderTag.LOGISTICS) @@ -148,6 +155,10 @@ public class PonderIndex { .addStoryBoard("windmill_bearing/source", BearingScenes::windmillsAsSource, PonderTag.KINETIC_SOURCES) .addStoryBoard("windmill_bearing/structure", BearingScenes::windmillsAnyStructure, PonderTag.MOVEMENT_ANCHOR); + PonderRegistry.forComponents(AllBlocks.SAIL) + .addStoryBoard("sail", BearingScenes::sail); + PonderRegistry.forComponents(AllBlocks.SAIL_FRAME) + .addStoryBoard("sail", BearingScenes::sailFrame); // Mechanical Bearing PonderRegistry.forComponents(AllBlocks.MECHANICAL_BEARING) @@ -332,6 +343,11 @@ public class PonderIndex { .add(AllBlocks.CREATIVE_FLUID_TANK) .add(AllBlocks.CREATIVE_MOTOR); + PonderRegistry.tags.forTag(PonderTag.SAILS) + .add(AllBlocks.SAIL) + .add(AllBlocks.SAIL_FRAME) + .add(Blocks.WHITE_WOOL); + PonderRegistry.tags.forTag(PonderTag.REDSTONE) .add(AllBlocks.NIXIE_TUBE) .add(AllBlocks.REDSTONE_CONTACT) diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java index bf649665d..6eca976b0 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTag.java @@ -59,6 +59,10 @@ public class PonderTag implements IScreenRenderable { .defaultLang("Block Attachment Utility", "Tools and Components used to assemble structures moved as an animated Contraption"), + SAILS = new PonderTag("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"), + // FLUID_TRANSFER = new PonderTag("fluid_transfer").idAsIcon(), // // OPEN_INVENTORY = new PonderTag("open_inventory").item(AllBlocks.BASIN.get() diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java index 0932b7443..dfa195ead 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java @@ -93,7 +93,7 @@ public class InputWindowElement extends AnimatedOverlayElement { if (fade < 1 / 16f) return; Vec2f sceneToScreen = scene.getTransform() - .sceneToScreen(sceneSpace); + .sceneToScreen(sceneSpace, partialTicks); if (hasIcon) { width += 24; diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java index 99d8081aa..262a64dee 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/ParrotElement.java @@ -246,7 +246,7 @@ public class ParrotElement extends AnimatedSceneElement { double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth(); double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight(); return scene.getTransform() - .screenToScene(mouseX, mouseY, 300); + .screenToScene(mouseX, mouseY, 300, 0); } } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java index cb985822c..7c28c5e01 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java @@ -10,7 +10,6 @@ import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderUI; import com.simibubi.create.foundation.ponder.content.PonderPalette; import com.simibubi.create.foundation.utility.ColorHelper; -import com.simibubi.create.foundation.utility.FontHelper; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec2f; @@ -87,7 +86,7 @@ public class TextWindowElement extends AnimatedOverlayElement { if (fade < 1 / 16f) return; Vec2f sceneToScreen = vec != null ? scene.getTransform() - .sceneToScreen(vec) : new Vec2f(screen.width / 2, (screen.height - 200) / 2 + y - 8); + .sceneToScreen(vec, partialTicks) : new Vec2f(screen.width / 2, (screen.height - 200) / 2 + y - 8); float yDiff = (screen.height / 2 - sceneToScreen.y - 10) / 100f; int targetX = (int) (screen.width * MathHelper.lerp(yDiff * yDiff, 6f / 8, 5f / 8)); @@ -122,8 +121,11 @@ public class TextWindowElement extends AnimatedOverlayElement { RenderSystem.popMatrix(); } - FontHelper.drawSplitString(screen.getFontRenderer(), bakedText, targetX - 10, 3, textWidth, - ColorHelper.applyAlpha(brighterColor, fade)); + for (int i = 0; i < list.size(); i++) { + String s = list.get(i); + screen.getFontRenderer() + .drawString(s, targetX - 10, 3 + 9 * i, ColorHelper.applyAlpha(brighterColor, fade)); + } RenderSystem.popMatrix(); } diff --git a/src/main/resources/ponder/mechanical_crafter/connect.nbt b/src/main/resources/ponder/mechanical_crafter/connect.nbt new file mode 100644 index 0000000000000000000000000000000000000000..27dac0c32b5fc7555c8f8ca246612c305ab3361c GIT binary patch literal 1144 zcmV-;1c&<{iwFP!000000Nq*JZrer>U0y{>a*_fq(4wEvFNjm1N#ryU5ZDIX7HwaI z6*-a!Q(R(qWhH*{SLMC^g1)8chxApQrAS>UQChijD~JGLo7_D!bI#0gNY@GRi7ldA zum~aQbnvwCbbaDMA|n}rAnNdm+l^UpE$aBkH$JgaCW=k7!y=B5R6@REagDKNjZs=- zYT#HJIJO2(aTptLj5TY@IHm@UrGaB>;1q|c!LzBs^Clci1IO0DnMt9+v!%iFCLBux z$JW3p4qJm~TZ89KIF<&Ey%wiVtfVVFVn!ip1|0DEX$UEkb<(^T$#f)Nj(R=d7O}6e z!f}V^6Q?awVQiGbSR;k?5K{cUS1Fzyp%mr@DYhjvZfPeWyi>R9ivr}l z{k4+99&uY#L`k36=NIR%%0#bjFi5j4=D_Hh`xcVE94MDH2(GQCGb3V3XCtSx3$a|& zyUN_yyK_Sxgqv=e8)H{)+~wr^?yf5ND%e^~x1}62$jK!WI9uJo1rJp{u4(vXVx7aS z|BpxBip`P~?%_Wbzdb@J%nedlW2EWCZ zXn%hiyIaRBJ&nsFVNf+^Eyhvb({TTO9TkfT}NW&O#g~ho?t5j!He8r3aQzYAKCD zN>KC8BM<9~4uO0*pM=MQNJ1xI3A%xsiWQ&FSBQj-JK5L&+1;fNj!O1R&Qjp&-vwC8 zJ>&sP*-03e1CMwqixQb#;Zc7eXDHQ^#|mUH?G8?l#sYAEO1UH!B;nkgJq96h5EC)( zBlQ8}(JeLz8qe%4wL2{fib*c_W}}iAJ9}fUgc)O+$O?Q*nm}pbx_Xgt5C$Qs;-I2(_wM$x7nPely>EGqZLZAOxn;bMye9ynMPC zU9AuT%yp_$R8X!ETF04)PE?zIJPpAsgsL}9mj}MmT%*}BZ{sYnaT+$R1&(Kd!z^&> z<*dPRme@3LTnik}0*6`P)XTNVvuly(bvT{{4zs|SN@0;_&mzz3a6AhfW`R>LW|3!R zk>_sf-WTKiDv;KZ7|94r zcazEFhjI7JxZ`B8^;(KiK_O}!DhlznOk*&i_#JVIl8iPEP>+Q?@geB&f=8)7dvj4n z&5me9m7aXqd=bYOA8Cn7J+E@(cH_z9=LNJ5cYTVa`lmzNAOM$~Jc%R{hrJ<23D47r zXT3=BzDC)Gu$!OKloRr7=EDiWuc9gBSoFXmn*VpL-4nB9vM0+9Tpk( zPSPB88Z{-jG!pC?367VQU6Y6Rzoc%Xq#RRL^HQ*XA;qe?{4*&o@39o_5-Hrf+ZD|& zzfV$3<(QMgH&S@8^G@p_d(lTC_z-`aq zq6C#*Qa)Y-ZR74A4$-Q^Vg4B@xcfZfRXo@l9^Wo*okxAR?HV4q>e<(y;}PCHJ(@gL z>fv8|=m=q>;2CO-9aji!5WjaXy29k|w)CI7CIX}*bHPdo5Q(u literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/mechanical_crafter/setup.nbt b/src/main/resources/ponder/mechanical_crafter/setup.nbt new file mode 100644 index 0000000000000000000000000000000000000000..5b744378fd29fa0b2522cfd421067bdca67db524 GIT binary patch literal 904 zcmV;319$u%iwFP!000000Nq*5j?+jGF5B&l;~4=5R=fKOoVYS@0A>(GS`8zOSOJ%) z$F3w+oNlYTgMrgL6?b?NeqLg4*|M=cCODZE8itULtR!~zSM}A`RdzZdKp&V+-l7Kp z#o^Pz=;-w!Kw%P-poU`fp?8|fXsSc{a;pzsCUrfj86NoBaD&y1wvE$a<1E>@7C4>- z4zs|ihqDI9>9ASGaV>B>3mj&FQxDf7&#pzD*Wq{;ILrd4k-{R+o<*M5;dmA}%mSw# z%p%XsBG2n^JPRDwi4%e+PE7!A62o4kkk0SNm`M}D-qX3s=H}siG(zP8JE01v89^WX zfx(%s@V;m5EUD>MUP8EbAcerlU_1~6O>N_l8(uU6TCvXaGNs_WsNP>zXd%rqN~S3) zhkA>Dk|D+)%1bwn=%X%AJj-Ho=LFy%Pq;>4gTsFwdC)(Qb72l;F22(3oyfV0uyD6n zEIw84_A7UsEcPBNInOA>f+U6bSW#}OQ2Yb=3Kbdc9HGgjn)(nN@Qg=^dGq9~h`LVG zbsu&g#4*MvMxoaCO9k9Pyjc8q2EF4uK1EVqIlNIMwG`m*N`M(g6E2d7r^86`kwFzg ze;{5_FO}-exesTp6i$Z}-p`QY;iXD(cMGL(uS$x`sfsUKTorX?bV+g1g0>-eA)P-e zIy#wUDGsNJK$AolNpRYA3tHyEHn+MzZt;?GstRvQ;csqr*Nyhx7E0k>l@ym#6`!}b zDjGR{kE*B})HXhTIJF$VS5<6lgSrwaE~hF!Z*f&Ll5|M1!B2wGswctrW<+oEdBm%D zur)m1pZ#(kbxGW*c;Kqd7{A41XY=$}=CM)_|C?VJ-M^;Vo20=CoA#z;pI$o|Pth1G z+FKX^JK{5hzh)F|S=9UaBr!OQq#!ypskXRzZlQ(DhvkNHbM>1&EJ}KKtYn6&*ntk9 zH==xsG5A6%GYKHbWFky?MkV8kX;4--nq|n{oa|I8$777aAMsQpf$-Of2Ip;qcfG=k zy`@V zO2=GHhmuc+r*mVZ_zu3D$AlCF=4&}Oljd8Q(&GP#xClSTmSGtNIJX;*f1Z1!@HBbC eVV)?YHN0EgiT_2V6LJs1JNO@`1_t5x7ytl?0j^H~ literal 0 HcmV?d00001 diff --git a/src/main/resources/ponder/sail.nbt b/src/main/resources/ponder/sail.nbt new file mode 100644 index 0000000000000000000000000000000000000000..9b325ae4d6ba5651d410acdac9a291182c6336b2 GIT binary patch literal 447 zcmV;w0YLsAiwFP!000000G*ZLO2aS^$FEJgbrV5B&^PcM{3Zx~5fMedj;uX3EK5p~ zG4R2BKGSOEsA+e25NLb<|Bv+ULgoN7;7)!Z1AulFam}Da?WLFKpp6+!mdaEsHxDnD zGhmHz(XDr zjKJXpP9E2uCLj1OM(712^kR&|2pmq}#NdQpa6&J}IE=vINzNRYUit!xrv|Zx&UbPj z9$ok0xv7IP3;ApPrtmvIecWg*^;^ImJyq5y^&-@!OO}w!8qO<=!FIKkx?W4A7E2U1 z7z#MP6VBhFMjP_=K!>v4G_Zk***^(9pi0F11cwngeNBqP37o#B z&xtkMpWx|04G(E}LNjfILhrG?49XJty;vh$tfj`vidTQNeU}~=mC<2Tf+;G_eicre z?V`I;QduKbi$)2(a$$t$57snj+pDOA$*ZW^;mkM9&NwuXLtef`=XdVY=