From 068b7c0c3742b9bf8bfd8a451b1dc4b0867e0e37 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 27 Feb 2020 18:09:41 +0100 Subject: [PATCH] Rotated Disassembly & Powered Latch - Chassis blocks now visualize their range blocks when selected with a wrench - Fixed Bearings and other actors selecting moved blocks as if they were being pushed in a direction - Fixed Radial chassis not connecting to each other consistently - Added Powered Latch and Powered Toggle Latch (Redstone circuits) - Window-logging now works with modded glass panes, that do not have the tag on their item, but the block only - Chassis can now be edited in bulk by holding down Ctrl - Chained block movement no longer marks blocks for movement if they are in front of a block breaker - Making a chassis sticky no longer uses up slime balls - Chassis can now be made sticky on all sides if a sticky side is clicked once again - Fixed linear chassis picking up blocks attached to other chassis' lines, even if not sticky - Fixed horizontal rotation and mirroring of chassis blocks and their sticky sides - Structures rotated in a Contraption now try to rotate themselves and their blocks toward the nearest axis-alinged direction when disassembled - Fans no longer shoot testing rays if the target block shape is completely filled or empty (trivial case) - Fans can now blow through iron bars again - Fixed crash when adjusting motors - Fixed missing icons in blockzapper & schematicannon interface - Reworked the drill model - Added more tags to #windowable - Leather horse armor no longer crushes into iron nuggets --- .../java/com/simibubi/create/AllBlocks.java | 4 + .../com/simibubi/create/ClientEvents.java | 2 + .../com/simibubi/create/CreateClient.java | 2 + src/main/java/com/simibubi/create/Events.java | 8 +- .../com/simibubi/create/ScreenResources.java | 12 +- .../scrollvalue/BulkScrollValueBehaviour.java | 23 ++ .../scrollvalue/ScrollValueBehaviour.java | 10 +- .../scrollvalue/ScrollValueHandler.java | 28 +- .../scrollvalue/ScrollValueRenderer.java | 35 +- .../contraptions/BlockMovementTraits.java | 50 +++ .../contraptions/ChassisRangeDisplay.java | 202 ++++++++++ .../components/contraptions/Contraption.java | 348 +++--------------- .../contraptions/ContraptionEntity.java | 7 +- .../contraptions/StructureTransform.java | 154 ++++++++ .../bearing/BearingContraption.java | 2 +- .../bearing/ClockworkContraption.java | 10 +- .../chassis/AbstractChassisBlock.java | 88 ++++- .../chassis/ChassisTileEntity.java | 202 +++++++++- .../mounted/CartAssemblerBlock.java | 6 +- .../mounted/MountedContraption.java | 12 +- .../piston/PistonContraption.java | 10 +- .../components/fan/AirCurrent.java | 19 + .../components/motor/MotorTileEntity.java | 5 +- .../logistics/block/diodes/LatchBlock.java | 91 +++++ .../block/diodes/ToggleLatchBlock.java | 80 ++++ .../create/blockstates/redstone_latch.json | 15 + .../create/blockstates/toggle_latch.json | 24 ++ .../resources/assets/create/lang/en_us.json | 2 + .../assets/create/models/block/drill.json | 238 ++++++++---- .../create/models/block/drill_base.json | 141 +++---- .../block/repeaters/redstone_latch.json | 7 + .../repeaters/redstone_latch_powered.json | 7 + .../models/block/repeaters/toggle_latch.json | 100 +++++ .../block/repeaters/toggle_latch_powered.json | 7 + .../toggle_latch_powered_powering.json | 7 + .../repeaters/toggle_latch_powering.json | 103 ++++++ .../assets/create/models/item/drill.json | 345 +++++++++++------ .../create/models/item/redstone_latch.json | 10 + .../create/models/item/toggle_latch.json | 10 + .../block/andesite_casing_very_short.png | Bin 0 -> 489 bytes .../create/textures/block/redstone_latch.png | Bin 0 -> 513 bytes .../textures/block/redstone_latch_powered.png | Bin 0 -> 510 bytes .../create/textures/block/toggle_latch.png | Bin 0 -> 510 bytes .../textures/block/toggle_latch_powered.png | Bin 0 -> 515 bytes .../block/toggle_latch_powered_powering.png | Bin 0 -> 504 bytes .../textures/block/toggle_latch_powering.png | Bin 0 -> 510 bytes .../loot_tables/blocks/redstone_latch.json | 19 + .../loot_tables/blocks/toggle_latch.json | 19 + .../crafting_shaped/redstone_latch.json | 32 ++ .../recipes/crafting_shaped/toggle_latch.json | 29 ++ .../create/recipes/crushing/blue_orchid.json | 1 - .../recipes/crushing/leather_horse_armor.json | 13 +- .../create/recipes/mixing/crushed_brass.json | 1 - .../create/recipes/pressing/lapis_block.json | 3 +- .../create/recipes/splashing/limestone.json | 14 + .../create/recipes/splashing/red_sand.json | 3 +- .../data/create/tags/blocks/windowable.json | 11 +- .../data/forge/tags/items/glass_panes.json | 12 +- wiki/Rotational Force in Create | 52 +++ 59 files changed, 1970 insertions(+), 665 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/BulkScrollValueBehaviour.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/diodes/ToggleLatchBlock.java create mode 100644 src/main/resources/assets/create/blockstates/redstone_latch.json create mode 100644 src/main/resources/assets/create/blockstates/toggle_latch.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/redstone_latch.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/redstone_latch_powered.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/toggle_latch.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered_powering.json create mode 100644 src/main/resources/assets/create/models/block/repeaters/toggle_latch_powering.json create mode 100644 src/main/resources/assets/create/models/item/redstone_latch.json create mode 100644 src/main/resources/assets/create/models/item/toggle_latch.json create mode 100644 src/main/resources/assets/create/textures/block/andesite_casing_very_short.png create mode 100644 src/main/resources/assets/create/textures/block/redstone_latch.png create mode 100644 src/main/resources/assets/create/textures/block/redstone_latch_powered.png create mode 100644 src/main/resources/assets/create/textures/block/toggle_latch.png create mode 100644 src/main/resources/assets/create/textures/block/toggle_latch_powered.png create mode 100644 src/main/resources/assets/create/textures/block/toggle_latch_powered_powering.png create mode 100644 src/main/resources/assets/create/textures/block/toggle_latch_powering.png create mode 100644 src/main/resources/data/create/loot_tables/blocks/redstone_latch.json create mode 100644 src/main/resources/data/create/loot_tables/blocks/toggle_latch.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/redstone_latch.json create mode 100644 src/main/resources/data/create/recipes/crafting_shaped/toggle_latch.json create mode 100644 src/main/resources/data/create/recipes/splashing/limestone.json create mode 100644 wiki/Rotational Force in Create diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 6b606d6f7..d02eafb3c 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -61,7 +61,9 @@ import com.simibubi.create.modules.logistics.block.StockswitchBlock; import com.simibubi.create.modules.logistics.block.belts.BeltObserverBlock; import com.simibubi.create.modules.logistics.block.belts.FunnelBlock; import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock; +import com.simibubi.create.modules.logistics.block.diodes.LatchBlock; import com.simibubi.create.modules.logistics.block.diodes.PulseRepeaterBlock; +import com.simibubi.create.modules.logistics.block.diodes.ToggleLatchBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorBlock; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock; @@ -184,6 +186,8 @@ public enum AllBlocks { PULSE_REPEATER(new PulseRepeaterBlock()), FLEXPEATER(new FlexpeaterBlock()), FLEXPULSEPEATER(new FlexpeaterBlock()), + REDSTONE_LATCH(new LatchBlock()), + TOGGLE_LATCH(new ToggleLatchBlock()), __CURIOSITIES__(), SYMMETRY_PLANE(new PlaneSymmetryBlock()), diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/ClientEvents.java index 81e38cbc2..bb9c0cadc 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/ClientEvents.java @@ -11,6 +11,7 @@ import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.modules.contraptions.KineticDebugger; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay; import com.simibubi.create.modules.contraptions.components.turntable.TurntableHandler; import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItemHandler; @@ -67,6 +68,7 @@ public class ClientEvents { CreateClient.schematicAndQuillHandler.render(); CreateClient.schematicHologram.render(); KineticDebugger.renderSourceOutline(); + ChassisRangeDisplay.renderOutlines(event.getPartialTicks()); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index e75f16efc..06882c481 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -11,6 +11,7 @@ import com.simibubi.create.foundation.block.render.SpriteShiftEntry; import com.simibubi.create.foundation.item.IHaveCustomItemModel; import com.simibubi.create.foundation.utility.SuperByteBufferCache; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionRenderer; import com.simibubi.create.modules.schematics.ClientSchematicLoader; import com.simibubi.create.modules.schematics.client.SchematicAndQuillHandler; @@ -81,6 +82,7 @@ public class CreateClient { schematicAndQuillHandler.tick(); schematicHandler.tick(); schematicHologram.tick(); + ChassisRangeDisplay.clientTick(); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/Events.java b/src/main/java/com/simibubi/create/Events.java index cc7de9bac..e58c67ee4 100644 --- a/src/main/java/com/simibubi/create/Events.java +++ b/src/main/java/com/simibubi/create/Events.java @@ -71,10 +71,12 @@ public class Events { ItemStack stack = event.getItemStack(); if (stack.isEmpty()) return; - if (!stack.getItem().isIn(Tags.Items.GLASS_PANES)) - return; if (!(stack.getItem() instanceof BlockItem)) return; + BlockItem item = (BlockItem) stack.getItem(); + if (!item.isIn(Tags.Items.GLASS_PANES) + && (item.getBlock() == null || !item.getBlock().isIn(Tags.Blocks.GLASS_PANES))) + return; BlockPos pos = event.getPos(); World world = event.getWorld(); @@ -89,7 +91,7 @@ public class Events { TileEntity te = world.getTileEntity(pos); if (te != null && te instanceof WindowInABlockTileEntity) { WindowInABlockTileEntity wte = (WindowInABlockTileEntity) te; - wte.setWindowBlock(((BlockItem) stack.getItem()).getBlock().getDefaultState()); + wte.setWindowBlock(item.getBlock().getDefaultState()); wte.updateWindowConnections(); if (blockState.getBlock() instanceof FourWayBlock) { diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index c6ec17a9d..e65f94bb2 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -124,30 +124,30 @@ public enum ScreenResources { I_MOVE_NEVER_PLACE(11, 1), I_DONT_REPLACE(0, 2), - I_REPLACE_SOLID(4, 2), + I_REPLACE_SOLID(1, 2), I_REPLACE_ANY(2, 2), I_REPLACE_EMPTY(3, 2), I_TOOL_DEPLOY(0, 3), I_SKIP_TILES(2, 3), - I_SKIP_MISSING(4, 3), + I_SKIP_MISSING(1, 3), I_TOOL_MOVE_XZ(0, 4), - I_TOOL_MOVE_Y(4, 4), + I_TOOL_MOVE_Y(1, 4), I_TOOL_ROTATE(2, 4), I_TOOL_MIRROR(3, 4), I_PLAY(0, 5), - I_PAUSE(4, 5), + I_PAUSE(1, 5), I_STOP(2, 5), I_PATTERN_SOLID(0, 6), - I_PATTERN_CHECKERED(4, 6), + I_PATTERN_CHECKERED(1, 6), I_PATTERN_CHECKERED_INVERSED(2, 6), I_PATTERN_CHANCE_25(3, 6), I_PATTERN_CHANCE_50(0, 7), - I_PATTERN_CHANCE_75(4, 7), + I_PATTERN_CHANCE_75(1, 7), I_FOLLOW_DIAGONAL(2, 7), I_FOLLOW_MATERIAL(3, 7), diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/BulkScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/BulkScrollValueBehaviour.java new file mode 100644 index 000000000..c1f188c7d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/BulkScrollValueBehaviour.java @@ -0,0 +1,23 @@ +package com.simibubi.create.foundation.behaviour.scrollvalue; + +import java.util.List; +import java.util.function.Function; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; + +public class BulkScrollValueBehaviour extends ScrollValueBehaviour { + + Function> groupGetter; + + public BulkScrollValueBehaviour(String label, SmartTileEntity te, ValueBoxTransform slot, + Function> groupGetter) { + super(label, te, slot); + this.groupGetter = groupGetter; + } + + List getBulk() { + return groupGetter.apply(tileEntity); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java index 1b0cac1ab..2eee0cc2b 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java @@ -26,11 +26,12 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { int min = 0; int max = 1; public int value; - int scrollableValue; + public int scrollableValue; int ticksUntilScrollPacket; boolean forceClientState; String label; Consumer callback; + Consumer clientCallback; Function formatter; Function unit; BiFunction step; @@ -42,6 +43,8 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { slotPositioning = slot; callback = i -> { }; + clientCallback = i -> { + }; textShift = Vec3d.ZERO; formatter = i -> Integer.toString(i); step = (i, b) -> 1; @@ -91,6 +94,11 @@ public class ScrollValueBehaviour extends TileEntityBehaviour { ticksUntilScrollPacket = -1; } + public ScrollValueBehaviour withClientCallback(Consumer valueCallback) { + clientCallback = valueCallback; + return this; + } + public ScrollValueBehaviour withCallback(Consumer valueCallback) { callback = valueCallback; return this; diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java index ef49c2671..7948cb0f9 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java @@ -1,7 +1,9 @@ package com.simibubi.create.foundation.behaviour.scrollvalue; import com.simibubi.create.AllItems; +import com.simibubi.create.AllKeys; import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import net.minecraft.client.Minecraft; @@ -40,13 +42,29 @@ public class ScrollValueHandler { if (!scrolling.testHit(objectMouseOver.getHitVec())) return false; - scrolling.ticksUntilScrollPacket = 10; - scrolling.scrollableValue = (int) MathHelper.clamp( - scrolling.scrollableValue - + Math.signum(delta) * scrolling.step.apply(scrolling.scrollableValue, delta > 0), - scrolling.min, scrolling.max); + if (scrolling instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) { + BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) scrolling; + for (SmartTileEntity smartTileEntity : bulkScrolling.getBulk()) { + ScrollValueBehaviour other = TileEntityBehaviour.get(smartTileEntity, ScrollValueBehaviour.TYPE); + if (other != null) + applyTo(delta, other); + } + + } else + applyTo(delta, scrolling); return true; } + protected static void applyTo(double delta, ScrollValueBehaviour scrolling) { + scrolling.ticksUntilScrollPacket = 10; + int valueBefore = scrolling.scrollableValue; + scrolling.scrollableValue = (int) MathHelper.clamp( + scrolling.scrollableValue + + Math.signum(delta) * scrolling.step.apply(scrolling.scrollableValue, delta > 0), + scrolling.min, scrolling.max); + if (valueBefore != scrolling.scrollableValue) + scrolling.clientCallback.accept(scrolling.scrollableValue); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java index 20edc2550..35b4263af 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java @@ -2,11 +2,13 @@ package com.simibubi.create.foundation.behaviour.scrollvalue; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllItems; +import com.simibubi.create.AllKeys; import com.simibubi.create.foundation.behaviour.ValueBox; import com.simibubi.create.foundation.behaviour.ValueBox.IconValueBox; import com.simibubi.create.foundation.behaviour.ValueBox.TextValueBox; import com.simibubi.create.foundation.behaviour.ValueBoxRenderer; import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.TessellatorHelper; @@ -14,6 +16,7 @@ import com.simibubi.create.foundation.utility.TessellatorHelper; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -36,22 +39,39 @@ public class ScrollValueRenderer { BlockRayTraceResult result = (BlockRayTraceResult) target; ClientWorld world = Minecraft.getInstance().world; BlockPos pos = result.getPos(); - BlockState state = world.getBlockState(pos); + Direction face = result.getFace(); ScrollValueBehaviour behaviour = TileEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE); if (behaviour == null) return; if (behaviour.needsWrench && !AllItems.WRENCH.typeOf(Minecraft.getInstance().player.getHeldItemMainhand())) return; + boolean highlight = behaviour.testHit(target.getHitVec()); TessellatorHelper.prepareForDrawing(); - GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); + if (behaviour instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) { + BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) behaviour; + for (SmartTileEntity smartTileEntity : bulkScrolling.getBulk()) { + GlStateManager.pushMatrix(); + ScrollValueBehaviour other = TileEntityBehaviour.get(smartTileEntity, ScrollValueBehaviour.TYPE); + if (other != null) + render(world, smartTileEntity.getPos(), face, other, highlight); + GlStateManager.popMatrix(); + } + } else + render(world, pos, face, behaviour, highlight); + TessellatorHelper.cleanUpAfterDrawing(); + } + protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour, + boolean highlight) { + GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); + BlockState state = world.getBlockState(pos); if (behaviour.slotPositioning instanceof Sided) - ((Sided) behaviour.slotPositioning).fromSide(result.getFace()); + ((Sided) behaviour.slotPositioning).fromSide(face); behaviour.slotPositioning.renderTransformed(state, () -> { - AxisAlignedBB bb = - new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.5f).contract(0, 0, -.5f).offset(0, 0, -.125f); + AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.5f).contract(0, 0, -.5f).offset(0, 0, + -.125f); String label = behaviour.label; ValueBox box; @@ -65,11 +85,8 @@ public class ScrollValueRenderer { box.scrollTooltip("[" + Lang.translate("action.scroll") + "]"); box.offsetLabel(behaviour.textShift.add(20, -10, 0)).withColors(0xbe970b, 0xffe75e); - ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec())); - + ValueBoxRenderer.renderBox(box, highlight); }); - - TessellatorHelper.cleanUpAfterDrawing(); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java new file mode 100644 index 000000000..36cfdd305 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/BlockMovementTraits.java @@ -0,0 +1,50 @@ +package com.simibubi.create.modules.contraptions.components.contraptions; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ShulkerBoxBlock; +import net.minecraft.block.material.PushReaction; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class BlockMovementTraits { + + public static boolean movementAllowed(World world, BlockPos pos) { + BlockState blockState = world.getBlockState(pos); + if (blockState.getBlock() instanceof AbstractChassisBlock) + return true; + if (blockState.getBlock() instanceof ShulkerBoxBlock) + return false; + if (blockState.getBlockHardness(world, pos) == -1) + return false; + if (blockState.getBlock() == Blocks.OBSIDIAN) + return false; + return blockState.getPushReaction() != PushReaction.BLOCK; + } + + public static boolean notSupportive(BlockState state, Direction facing) { + if (AllBlocks.DRILL.typeOf(state)) + return state.get(BlockStateProperties.FACING) == facing; + if (AllBlocks.SAW.typeOf(state)) + return state.get(BlockStateProperties.FACING) == facing; + if (AllBlocks.HARVESTER.typeOf(state)) + return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing; + return false; + } + + public static boolean movementIgnored(BlockState state) { + if (AllBlocks.MECHANICAL_PISTON.typeOf(state)) + return true; + if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(state)) + return true; + if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state)) + return true; + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java new file mode 100644 index 000000000..4986495d3 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ChassisRangeDisplay.java @@ -0,0 +1,202 @@ +package com.simibubi.create.modules.contraptions.components.contraptions; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.world.World; + +public class ChassisRangeDisplay { + + private static final VoxelShape BLOCK_OUTLINE = Block.makeCuboidShape(-.5f, -.5f, -.5f, 16.5f, 16.5f, 16.5f); + private static final int DISPLAY_TIME = 200; + private static GroupEntry lastHoveredGroup = null; + + private static class Entry { + VoxelShape shape; + ChassisTileEntity te; + int timer; + + public Entry(ChassisTileEntity te) { + this.te = te; + this.shape = createSelection(te); + timer = DISPLAY_TIME; + } + + protected VoxelShape createSelection(ChassisTileEntity chassis) { + List positions = chassis.getIncludedBlockPositions(null, true); + VoxelShape shape = VoxelShapes.empty(); + if (positions == null) + return shape; + for (BlockPos blockPos : positions) + shape = VoxelShapes.or(shape, + BLOCK_OUTLINE.withOffset(blockPos.getX(), blockPos.getY(), blockPos.getZ())); + return shape; + } + + } + + private static class GroupEntry extends Entry { + + List includedTEs; + + public GroupEntry(ChassisTileEntity te) { + super(te); + } + + @Override + protected VoxelShape createSelection(ChassisTileEntity chassis) { + VoxelShape shape = VoxelShapes.empty(); + includedTEs = te.collectChassisGroup(); + if (includedTEs == null) + return shape; + for (ChassisTileEntity chassisTileEntity : includedTEs) + shape = VoxelShapes.or(shape, super.createSelection(chassisTileEntity)); + return shape; + } + + } + + static Map entries = new HashMap<>(); + static List groupEntries = new ArrayList<>(); + + public static void clientTick() { + PlayerEntity player = Minecraft.getInstance().player; + World world = Minecraft.getInstance().world; + boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand()); + + for (Iterator iterator = entries.keySet().iterator(); iterator.hasNext();) + if (tickEntry(entries.get(iterator.next()), hasWrench)) + iterator.remove(); + + for (Iterator iterator = groupEntries.iterator(); iterator.hasNext();) { + GroupEntry group = iterator.next(); + if (tickEntry(group, hasWrench)) { + iterator.remove(); + if (group == lastHoveredGroup) + lastHoveredGroup = null; + } + } + + if (hasWrench) { + RayTraceResult over = Minecraft.getInstance().objectMouseOver; + if (!(over instanceof BlockRayTraceResult)) + return; + BlockRayTraceResult ray = (BlockRayTraceResult) over; + BlockPos pos = ray.getPos(); + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity == null || tileEntity.isRemoved()) + return; + if (tileEntity instanceof ChassisTileEntity) { + ChassisTileEntity chassisTileEntity = (ChassisTileEntity) tileEntity; + if (AllKeys.ctrlDown()) { + GroupEntry existingGroupForPos = getExistingGroupForPos(pos); + if (existingGroupForPos != null) { + for (ChassisTileEntity included : existingGroupForPos.includedTEs) + entries.remove(included.getPos()); + existingGroupForPos.timer = DISPLAY_TIME; + return; + } + } + if (!entries.containsKey(pos) || AllKeys.ctrlDown()) + display(chassisTileEntity); + else { + deselect(); + if (!AllKeys.ctrlDown()) + entries.get(pos).timer = DISPLAY_TIME; + } + } + } + } + + private static void deselect() { + for (Entry entry : entries.values()) + if (entry.timer > 10) + entry.timer = 10; + for (Entry entry : groupEntries) + if (entry.timer > 10) + entry.timer = 10; + } + + private static boolean tickEntry(Entry entry, boolean hasWrench) { + ChassisTileEntity chassisTileEntity = entry.te; + World teWorld = chassisTileEntity.getWorld(); + World world = Minecraft.getInstance().world; + + if (chassisTileEntity.isRemoved() || teWorld == null || teWorld != world + || !world.isBlockPresent(chassisTileEntity.getPos())) { + return true; + } + + if (!hasWrench && entry.timer > 20) { + entry.timer = 20; + return false; + } + + entry.timer--; + if (entry.timer == 0) + return true; + return false; + } + + public static void display(ChassisTileEntity chassis) { + deselect(); + if (AllKeys.ctrlDown()) { + groupEntries.clear(); + GroupEntry hoveredGroup = new GroupEntry(chassis); + for (ChassisTileEntity included : hoveredGroup.includedTEs) + entries.remove(included.getPos()); + groupEntries.add(hoveredGroup); + } else { + entries.put(chassis.getPos(), new Entry(chassis)); + } + } + + public static void renderOutlines(float partialTicks) { + GlStateManager.lineWidth(2); + TessellatorHelper.prepareForDrawing(); + GlStateManager.disableTexture(); + + for (Entry entry : entries.values()) { + float timer = entry.timer - partialTicks; + float alpha = timer > 20 ? 1 : timer / 20f; + WorldRenderer.drawShape(entry.shape, 0, 0, 0, 1, .7f, 0, alpha); + } + for (Entry entry : groupEntries) { + float timer = entry.timer - partialTicks; + float alpha = timer > 20 ? 1 : timer / 20f; + WorldRenderer.drawShape(entry.shape, 0, 0, 0, 1, .7f, 0, alpha); + } + + GlStateManager.enableTexture(); + TessellatorHelper.cleanUpAfterDrawing(); + GlStateManager.lineWidth(1); + } + + private static GroupEntry getExistingGroupForPos(BlockPos pos) { + for (GroupEntry groupEntry : groupEntries) + for (ChassisTileEntity chassis : groupEntry.includedTEs) + if (pos.equals(chassis.getPos())) + return groupEntry; + return null; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java index d0987bb09..6f3ef9fc6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/Contraption.java @@ -1,21 +1,18 @@ package com.simibubi.create.modules.contraptions.components.contraptions; -import static net.minecraft.state.properties.BlockStateProperties.AXIS; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiPredicate; -import java.util.function.Function; import java.util.stream.Collectors; +import javax.annotation.Nullable; + import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -24,26 +21,18 @@ import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; -import com.simibubi.create.modules.contraptions.components.contraptions.chassis.LinearChassisBlock; -import com.simibubi.create.modules.contraptions.components.contraptions.chassis.RadialChassisBlock; import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.block.FallingBlock; -import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.block.SlimeBlock; -import net.minecraft.block.material.PushReaction; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.NBTUtil; -import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; -import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -76,44 +65,6 @@ public abstract class Contraption { renderOrder = new ArrayList<>(); } - private static List getChassisClusterAt(World world, BlockPos pos) { - List search = new LinkedList<>(); - Set visited = new HashSet<>(); - List chassis = new LinkedList<>(); - BlockState anchorChassis = world.getBlockState(pos); - Axis axis = anchorChassis.get(AXIS); - search.add(pos); - - while (!search.isEmpty()) { - if (chassis.size() > AllConfigs.SERVER.kinetics.maxChassisForTranslation.get()) - return null; - - BlockPos current = search.remove(0); - if (visited.contains(current)) - continue; - if (!world.isAreaLoaded(current, 1)) - return null; - - BlockState state = world.getBlockState(current); - if (!isLinearChassis(state)) - continue; - if (!LinearChassisBlock.sameKind(anchorChassis, state)) - continue; - if (state.get(AXIS) != axis) - continue; - - visited.add(current); - chassis.add(new BlockInfo(current, world.getBlockState(current), getTileEntityNBT(world, current))); - - for (Direction offset : Direction.values()) { - if (offset.getAxis() == axis) - continue; - search.add(current.offset(offset)); - } - } - return chassis; - } - public Set getColliders(World world, Direction movementDirection) { if (blocks == null) return null; @@ -138,7 +89,7 @@ public abstract class Contraption { return cachedColliders; } - public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { + public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { List frontier = new ArrayList<>(); Set visited = new HashSet<>(); anchor = pos; @@ -147,29 +98,30 @@ public abstract class Contraption { constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO); frontier.add(pos); - if (!addToInitialFrontier(world, pos, direction, frontier)) + if (!addToInitialFrontier(world, pos, forcedDirection, frontier)) return false; for (int limit = 1000; limit > 0; limit--) { if (frontier.isEmpty()) return true; - if (!moveBlock(world, frontier.remove(0), direction, frontier, visited)) + if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) return false; } return false; } public void gatherStoredItems() { - List list = - storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList()); + List list = storage.values().stream().map(MountedStorage::getItemHandler) + .collect(Collectors.toList()); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); } - protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, List frontier) { + protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, + List frontier) { return true; } - protected boolean moveBlock(World world, BlockPos pos, Direction direction, List frontier, + protected boolean moveBlock(World world, BlockPos pos, Direction forcedDirection, List frontier, Set visited) { visited.add(pos); frontier.remove(pos); @@ -181,22 +133,21 @@ public abstract class Contraption { return true; if (state.getCollisionShape(world, pos).isEmpty()) return true; - if (!canPush(world, pos, direction)) + if (!BlockMovementTraits.movementAllowed(world, pos)) return false; - if (isLinearChassis(state) && !moveLinearChassis(world, pos, direction, frontier, visited)) - return false; - if (isRadialChassis(state) && !moveRadialChassis(world, pos, direction, frontier, visited)) + if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited)) return false; if (state.getBlock() instanceof SlimeBlock) for (Direction offset : Direction.values()) { BlockPos offsetPos = pos.offset(offset); - if (offset.getAxis() == direction.getAxis()) { - BlockState blockState = world.getBlockState(offsetPos); - if (AllBlocks.MECHANICAL_PISTON.typeOf(blockState) - || AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(blockState) - || AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(blockState)) - continue; + BlockState blockState = world.getBlockState(offsetPos); + if (BlockMovementTraits.movementIgnored(blockState)) + continue; + if (!BlockMovementTraits.movementAllowed(world, offsetPos)) { + if (offset == forcedDirection) + return false; + continue; } if (!visited.contains(offsetPos)) frontier.add(offsetPos); @@ -206,243 +157,23 @@ public abstract class Contraption { return true; } - private boolean moveLinearChassis(World world, BlockPos pos, Direction movementDirection, List frontier, + protected static boolean isChassis(BlockState state) { + return state.getBlock() instanceof AbstractChassisBlock; + } + + private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List frontier, Set visited) { - List cluster = getChassisClusterAt(world, pos); - - if (cluster == null) + TileEntity te = world.getTileEntity(pos); + if (!(te instanceof ChassisTileEntity)) return false; - if (cluster.isEmpty()) - return true; - - Set validChassis = new HashSet<>(cluster.size()); - cluster.forEach(info -> validChassis.add(info.pos)); - - BlockInfo anchorChassis = cluster.get(0); - Axis chassisAxis = anchorChassis.state.get(AXIS); - int chassisCoord = - chassisAxis.getCoordinate(anchorChassis.pos.getX(), anchorChassis.pos.getY(), anchorChassis.pos.getZ()); - - Function getChassisPos = - position -> new BlockPos(chassisAxis == Axis.X ? chassisCoord : position.getX(), - chassisAxis == Axis.Y ? chassisCoord : position.getY(), - chassisAxis == Axis.Z ? chassisCoord : position.getZ()); - - // Collect blocks on both sides - for (AxisDirection axisDirection : AxisDirection.values()) { - - Direction chassisDirection = Direction.getFacingFromAxis(axisDirection, chassisAxis); - List chassisFrontier = new LinkedList<>(); - Set chassisVisited = new HashSet<>(); - cluster.forEach(c -> chassisFrontier.add(c.pos)); - boolean pushing = chassisDirection == movementDirection; - - Search: while (!chassisFrontier.isEmpty()) { - BlockPos currentPos = chassisFrontier.remove(0); - if (!world.isAreaLoaded(currentPos, 1)) - return false; - if (!world.isBlockPresent(currentPos)) - continue; - if (chassisVisited.contains(currentPos)) - continue; - chassisVisited.add(currentPos); - - BlockState state = world.getBlockState(currentPos); - BlockPos currentChassisPos = getChassisPos.apply(currentPos); - BlockState chassisState = world.getBlockState(currentChassisPos); - - // Not attached to a chassis - if (!isLinearChassis(chassisState) || chassisState.get(AXIS) != chassisAxis) - continue; - if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) - && state.get(FACING) == chassisDirection.getOpposite()) - continue; - - int chassisRange = ((ChassisTileEntity) world.getTileEntity(currentChassisPos)).getRange(); - boolean chassisSticky = chassisState.get(((AbstractChassisBlock) chassisState.getBlock()) - .getGlueableSide(chassisState, chassisDirection)); - - // Ignore replaceable Blocks and Air-like - if (state.getMaterial().isReplaceable() || state.isAir(world, currentPos)) - continue; - if (state.getCollisionShape(world, currentPos).isEmpty()) - continue; - - // Too many Blocks - boolean notInRange = !currentChassisPos.withinDistance(currentPos, chassisRange + 1); - if (pushing && notInRange) - return false; - if (!pushing && notInRange) - continue; - - // Chassis not part of cluster - if (!validChassis.contains(currentChassisPos)) - continue; - - boolean isBaseChassis = currentPos.equals(currentChassisPos); - if (!isBaseChassis) { - // Don't pull if chassis not sticky - if (!chassisSticky && !pushing) - continue; - - // Skip if pushed column ended already - for (BlockPos posInbetween = currentPos; !posInbetween.equals(currentChassisPos); posInbetween = - posInbetween.offset(chassisDirection.getOpposite())) { - BlockState blockState = world.getBlockState(posInbetween); - - if (!chassisSticky && (blockState.getMaterial().isReplaceable())) - continue Search; - if (!pushing && chassisSticky && !canPush(world, posInbetween, movementDirection)) - continue Search; - } - } - - // Ignore sand and co. - if (chassisSticky && !pushing && state.getBlock() instanceof FallingBlock) - continue; - - // Structure is immobile - boolean cannotPush = !canPush(world, currentPos, movementDirection); - if (pushing && cannotPush) - return false; - if (!pushing && cannotPush) - continue; - - if (isBaseChassis) { - add(currentPos, capture(world, currentPos)); - visited.add(currentPos); - } else { - frontier.add(currentPos); - } - - // Expand search - for (Direction facing : Direction.values()) { - if (isBaseChassis && facing == chassisDirection.getOpposite()) - continue; - if (notSupportive(world, pos, facing)) - continue; - chassisFrontier.add(currentPos.offset(facing)); - } - } - } - + ChassisTileEntity chassis = (ChassisTileEntity) te; + chassis.addAttachedChasses(frontier, visited); + for (BlockPos blockPos : chassis.getIncludedBlockPositions(movementDirection, false)) + if (!visited.contains(blockPos)) + frontier.add(blockPos); return true; } - private boolean moveRadialChassis(World world, BlockPos pos, Direction movementDirection, List frontier, - Set visited) { - RadialChassisBlock def = (RadialChassisBlock) AllBlocks.ROTATION_CHASSIS.block; - - List chassisPositions = new ArrayList<>(); - BlockState chassisState = world.getBlockState(pos); - Axis axis = chassisState.get(RadialChassisBlock.AXIS); - chassisPositions.add(pos); - - // Collect chain of chassis - for (int offset : new int[] { -1, 1 }) { - for (int distance = 1; distance <= AllConfigs.SERVER.kinetics.maxChassisForRotation.get(); distance++) { - Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); - BlockPos currentPos = pos.offset(direction, distance * offset); - if (!world.isBlockPresent(currentPos)) - return false; - - BlockState state = world.getBlockState(currentPos); - if (!AllBlocks.ROTATION_CHASSIS.typeOf(state)) - break; - if (direction.getAxis() != state.get(BlockStateProperties.AXIS)) - break; - - chassisPositions.add(currentPos); - } - } - - // Add attached blocks to frontier - for (BlockPos chassisPos : chassisPositions) { - add(chassisPos, capture(world, chassisPos)); - visited.add(chassisPos); - - BlockPos currentPos = chassisPos; - BlockState state = world.getBlockState(currentPos); - TileEntity tileEntity = world.getTileEntity(currentPos); - - if (!(tileEntity instanceof ChassisTileEntity)) - return false; - - int chassisRange = ((ChassisTileEntity) tileEntity).getRange(); - - for (Direction facing : Direction.values()) { - if (facing.getAxis() == axis) - continue; - if (!state.get(def.getGlueableSide(state, facing))) - continue; - - BlockPos startPos = currentPos.offset(facing); - List localFrontier = new LinkedList<>(); - Set localVisited = new HashSet<>(); - localFrontier.add(startPos); - - while (!localFrontier.isEmpty()) { - BlockPos searchPos = localFrontier.remove(0); - BlockState searchedState = world.getBlockState(searchPos); - - if (localVisited.contains(searchPos)) - continue; - if (!searchPos.withinDistance(currentPos, chassisRange + .5f)) - continue; - if (searchedState.getMaterial().isReplaceable() || state.isAir(world, searchPos)) - continue; - if (searchedState.getCollisionShape(world, searchPos).isEmpty()) - continue; - - localVisited.add(searchPos); - if (!visited.contains(searchPos)) - frontier.add(searchPos); - - for (Direction offset : Direction.values()) { - if (offset.getAxis() == axis) - continue; - if (searchPos.equals(currentPos) && offset != facing) - continue; - - localFrontier.add(searchPos.offset(offset)); - } - } - } - } - - return true; - } - - private static boolean isLinearChassis(BlockState state) { - return LinearChassisBlock.isChassis(state); - } - - private static boolean isRadialChassis(BlockState state) { - return AllBlocks.ROTATION_CHASSIS.typeOf(state); - } - - private boolean notSupportive(World world, BlockPos pos, Direction facing) { - BlockState state = world.getBlockState(pos); - if (AllBlocks.DRILL.typeOf(state)) - return state.get(BlockStateProperties.FACING) == facing; - if (AllBlocks.HARVESTER.typeOf(state)) - return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing; - return false; - } - - protected static boolean canPush(World world, BlockPos pos, Direction direction) { - BlockState blockState = world.getBlockState(pos); - if (isLinearChassis(blockState) || isRadialChassis(blockState)) - return true; - if (blockState.getBlock() instanceof ShulkerBoxBlock) - return false; - if (blockState.getBlockHardness(world, pos) == -1) - return false; - if (blockState.getBlock() == Blocks.OBSIDIAN) - return false; - return blockState.getPushReaction() != PushReaction.BLOCK; - } - protected Pair capture(World world, BlockPos pos) { BlockState blockstate = world.getBlockState(pos); if (AllBlocks.SAW.typeOf(blockstate)) @@ -520,8 +251,8 @@ public abstract class Contraption { CompoundNBT comp = (CompoundNBT) c; storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), new MountedStorage(comp.getCompound("Data"))); }); - List list = - storage.values().stream().map(MountedStorage::getItemHandler).collect(Collectors.toList()); + List list = storage.values().stream().map(MountedStorage::getItemHandler) + .collect(Collectors.toList()); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); if (nbt.contains("BoundsFront")) @@ -582,8 +313,8 @@ public abstract class Contraption { return AllConfigs.SERVER.control.freezePistonConstructs.get(); } - public void disassemble(World world, BlockPos offset, float yaw, float pitch) { - disassemble(world, offset, yaw, pitch, (pos, state) -> false); + public void disassemble(World world, BlockPos offset, Vec3d rotation) { + disassemble(world, offset, rotation, (pos, state) -> false); } public void removeBlocksFromWorld(IWorld world, BlockPos offset) { @@ -600,12 +331,15 @@ public abstract class Contraption { } } - public void disassemble(World world, BlockPos offset, float yaw, float pitch, + public void disassemble(World world, BlockPos offset, Vec3d rotation, BiPredicate customPlacement) { stop(world); + + StructureTransform transform = new StructureTransform(offset, rotation); + for (BlockInfo block : blocks.values()) { - BlockPos targetPos = block.pos.add(offset); - BlockState state = block.state; + BlockPos targetPos = transform.apply(block.pos); + BlockState state = transform.apply(block.state); if (customPlacement.test(targetPos, state)) continue; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java index ea97ff630..ecd6e7087 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/ContraptionEntity.java @@ -43,8 +43,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected Vec3d motionBeforeStall; protected boolean stationary; - private static final DataParameter STALLED = - EntityDataManager.createKey(ContraptionEntity.class, DataSerializers.BOOLEAN); + private static final DataParameter STALLED = EntityDataManager.createKey(ContraptionEntity.class, + DataSerializers.BOOLEAN); public float prevYaw; public float prevPitch; @@ -365,7 +365,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public void disassemble() { if (getContraption() != null) - getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)), yaw, pitch); + getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)), + new Vec3d(getRoll(1), getYaw(1), getPitch(1))); remove(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java new file mode 100644 index 000000000..84e2a1021 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/StructureTransform.java @@ -0,0 +1,154 @@ +package com.simibubi.create.modules.contraptions.components.contraptions; + +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; + +import net.minecraft.block.BlockState; +import net.minecraft.block.SlabBlock; +import net.minecraft.block.StairsBlock; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.state.properties.Half; +import net.minecraft.state.properties.SlabType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.Rotation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +public class StructureTransform { + + // Assuming structures cannot be rotated around multiple axes at once + Rotation rotation; + int angle; + Axis rotationAxis; + BlockPos offset; + + public StructureTransform(BlockPos offset, Vec3d rotation) { + this.offset = offset; + if (rotation.x != 0) { + rotationAxis = Axis.X; + angle = (int) (Math.round(rotation.x / 90) * 90); + } + if (rotation.y != 0) { + rotationAxis = Axis.Y; + angle = (int) (Math.round(rotation.y / 90) * 90); + } + if (rotation.z != 0) { + rotationAxis = Axis.Z; + angle = (int) (Math.round(rotation.z / 90) * 90); + } + + angle %= 360; + if (angle < -90) + angle += 360; + + this.rotation = Rotation.NONE; + if (angle == -90 || angle == 270) + this.rotation = Rotation.CLOCKWISE_90; + if (angle == 90) + this.rotation = Rotation.COUNTERCLOCKWISE_90; + if (angle == 180) + this.rotation = Rotation.CLOCKWISE_180; + + } + + public BlockPos apply(BlockPos localPos) { + Vec3d vec = VecHelper.getCenterOf(localPos); + vec = VecHelper.rotateCentered(vec, angle, rotationAxis); + localPos = new BlockPos(vec); + return localPos.add(offset); + } + + /** + * Minecraft does not support blockstate rotation around axes other than y. Add + * specific cases here for blockstates, that should react to rotations around + * horizontal axes + */ + public BlockState apply(BlockState state) { + + if (rotationAxis == Axis.Y) + state = state.rotate(rotation); + else { + if (state.getBlock() instanceof AbstractChassisBlock) + return rotateChassis(state); + + if (state.getBlock() instanceof StairsBlock) { + if (state.get(StairsBlock.FACING).getAxis() != rotationAxis) { + for (int i = 0; i < rotation.ordinal(); i++) { + Direction direction = state.get(StairsBlock.FACING); + Half half = state.get(StairsBlock.HALF); + if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ half == Half.BOTTOM + ^ direction.getAxis() == Axis.Z) + state = state.cycle(StairsBlock.HALF); + else + state = state.with(StairsBlock.FACING, direction.getOpposite()); + } + } else { + if (rotation == Rotation.CLOCKWISE_180) { + state = state.cycle(StairsBlock.HALF); + } + } + return state; + } + + if (state.has(BlockStateProperties.FACING)) { + state = state.with(BlockStateProperties.FACING, + transformFacing(state.get(BlockStateProperties.FACING))); + + } else if (state.has(BlockStateProperties.AXIS)) { + state = state.with(BlockStateProperties.AXIS, transformAxis(state.get(BlockStateProperties.AXIS))); + + } else if (rotation == Rotation.CLOCKWISE_180) { + state = state.rotate(rotation); + if (state.has(SlabBlock.TYPE) && state.get(SlabBlock.TYPE) != SlabType.DOUBLE) + state = state.with(SlabBlock.TYPE, + state.get(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM); + } + + } + + return state; + } + + protected Axis transformAxis(Axis axisIn) { + Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn); + facing = transformFacing(facing); + Axis axis = facing.getAxis(); + return axis; + } + + protected Direction transformFacing(Direction facing) { + for (int i = 0; i < rotation.ordinal(); i++) + facing = facing.rotateAround(rotationAxis); + return facing; + } + + private BlockState rotateChassis(BlockState state) { + if (rotation == Rotation.NONE) + return state; + + BlockState rotated = state.with(BlockStateProperties.AXIS, transformAxis(state.get(BlockStateProperties.AXIS))); + AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock(); + + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = block.getGlueableSide(rotated, face); + if (glueableSide != null) + rotated = rotated.with(glueableSide, false); + } + + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = block.getGlueableSide(state, face); + if (glueableSide == null || !state.get(glueableSide)) + continue; + Direction rotatedFacing = transformFacing(face); + BooleanProperty rotatedGlueableSide = block.getGlueableSide(rotated, rotatedFacing); + if (rotatedGlueableSide != null) + rotated = rotated.with(rotatedGlueableSide, true); + } + + return rotated; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java index a0dda0e5d..1563729a8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/BearingContraption.java @@ -28,7 +28,7 @@ public class BearingContraption extends Contraption { return null; BearingContraption construct = new BearingContraption(); construct.facing = direction; - if (!construct.searchMovedStructure(world, pos.offset(direction), direction)) + if (!construct.searchMovedStructure(world, pos.offset(direction), null)) return null; construct.initActors(world); return construct; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java index 7205526cf..454b29ae6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/bearing/ClockworkContraption.java @@ -3,7 +3,6 @@ package com.simibubi.create.modules.contraptions.components.contraptions.bearing import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.function.BiPredicate; import org.apache.commons.lang3.tuple.Pair; @@ -11,7 +10,6 @@ import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; -import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -76,13 +74,7 @@ public class ClockworkContraption extends Contraption { @Override public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { - return super.searchMovedStructure(world, pos.offset(direction, offset + 1), direction); - } - - @Override - public void disassemble(World world, BlockPos offset, float yaw, float pitch, - BiPredicate customPlacement) { - super.disassemble(world, offset, yaw, pitch, customPlacement); + return super.searchMovedStructure(world, pos.offset(direction, offset + 1), null); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java index b1cf7e3b7..e2d13f6eb 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java @@ -1,20 +1,18 @@ package com.simibubi.create.modules.contraptions.components.contraptions.chassis; -import java.util.List; - import com.simibubi.create.AllSoundEvents; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.RotatedPillarBlock; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; import net.minecraft.particles.ParticleTypes; import net.minecraft.state.BooleanProperty; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Hand; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -45,12 +43,32 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock { if (!player.isAllowEdit()) return false; + ItemStack heldItem = player.getHeldItem(handIn); + boolean isSlimeBall = heldItem.getItem().isIn(Tags.Items.SLIMEBALLS); + BooleanProperty affectedSide = getGlueableSide(state, hit.getFace()); if (affectedSide == null) return false; - ItemStack heldItem = player.getHeldItem(handIn); - boolean isSlimeBall = heldItem.getItem().isIn(Tags.Items.SLIMEBALLS); + if (isSlimeBall && state.get(affectedSide)) { + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = getGlueableSide(state, face); + if (glueableSide != null && !state.get(glueableSide)) { + if (worldIn.isRemote) { + Vec3d vec = hit.getHitVec(); + worldIn.addParticle(ParticleTypes.ITEM_SLIME, vec.x, vec.y, vec.z, 0, 0, 0); + return true; + } + worldIn.playSound(null, pos, AllSoundEvents.SLIME_ADDED.get(), SoundCategory.BLOCKS, .5f, 1); + if (!player.isCreative()) + heldItem.shrink(1); + state = state.with(glueableSide, true); + } + } + if (!worldIn.isRemote) + worldIn.setBlockState(pos, state); + return true; + } if ((!heldItem.isEmpty() || !player.isSneaking()) && !isSlimeBall) return false; @@ -63,27 +81,61 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock { } worldIn.playSound(null, pos, AllSoundEvents.SLIME_ADDED.get(), SoundCategory.BLOCKS, .5f, 1); - if (isSlimeBall && !player.isCreative()) - heldItem.shrink(1); - if (!isSlimeBall && !player.isCreative()) - Block.spawnAsEntity(worldIn, pos.offset(hit.getFace()), new ItemStack(Items.SLIME_BALL)); - worldIn.setBlockState(pos, state.with(affectedSide, isSlimeBall)); return true; } - public abstract BooleanProperty getGlueableSide(BlockState state, Direction face); - @Override - public List getDrops(BlockState state, net.minecraft.world.storage.loot.LootContext.Builder builder) { + public BlockState rotate(BlockState state, Rotation rotation) { + if (rotation == Rotation.NONE) + return state; + @SuppressWarnings("deprecation") - List drops = super.getDrops(state, builder); + BlockState rotated = super.rotate(state, rotation); + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = getGlueableSide(rotated, face); + if (glueableSide != null) + rotated = rotated.with(glueableSide, false); + } + for (Direction face : Direction.values()) { BooleanProperty glueableSide = getGlueableSide(state, face); - if (glueableSide != null && state.get(glueableSide)) - drops.add(new ItemStack(Items.SLIME_BALL)); + if (glueableSide == null || !state.get(glueableSide)) + continue; + Direction rotatedFacing = rotation.rotate(face); + BooleanProperty rotatedGlueableSide = getGlueableSide(rotated, rotatedFacing); + if (rotatedGlueableSide != null) + rotated = rotated.with(rotatedGlueableSide, true); } - return drops; + + return rotated; } + @Override + public BlockState mirror(BlockState state, Mirror mirrorIn) { + if (mirrorIn == Mirror.NONE) + return state; + + BlockState mirrored = state; + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = getGlueableSide(mirrored, face); + if (glueableSide != null) + mirrored = mirrored.with(glueableSide, false); + } + + for (Direction face : Direction.values()) { + BooleanProperty glueableSide = getGlueableSide(state, face); + if (glueableSide == null || !state.get(glueableSide)) + continue; + Direction mirroredFacing = mirrorIn.mirror(face); + BooleanProperty mirroredGlueableSide = getGlueableSide(mirrored, mirroredFacing); + if (mirroredGlueableSide != null) + mirrored = mirrored.with(mirroredGlueableSide, true); + } + + return mirrored; + } + + public abstract BooleanProperty getGlueableSide(BlockState state, Direction face); + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java index 1aa202ca9..5659bab6e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java @@ -1,14 +1,35 @@ package com.simibubi.create.modules.contraptions.components.contraptions.chassis; -import java.util.List; +import static net.minecraft.state.properties.BlockStateProperties.AXIS; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.BulkScrollValueBehaviour; import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; +import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay; + +import net.minecraft.block.BlockState; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; public class ChassisTileEntity extends SmartTileEntity { @@ -21,9 +42,12 @@ public class ChassisTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) { int max = AllConfigs.SERVER.kinetics.maxChassisRange.get(); - range = new ScrollValueBehaviour(Lang.translate("generic.range"), this, new CenteredSideValueBoxTransform()); + range = new BulkScrollValueBehaviour(Lang.translate("generic.range"), this, new CenteredSideValueBoxTransform(), + te -> ((ChassisTileEntity) te).collectChassisGroup()); range.requiresWrench(); range.between(1, max); + range.withClientCallback( + i -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> ChassisRangeDisplay.display(this))); range.value = max / 2; behaviours.add(range); } @@ -39,4 +63,178 @@ public class ChassisTileEntity extends SmartTileEntity { return range.getValue(); } + public List getIncludedBlockPositions(Direction forcedMovement, boolean visualize) { + if (!(getBlockState().getBlock() instanceof AbstractChassisBlock)) + return Collections.emptyList(); + return isRadial() ? getIncludedBlockPositionsRadial(forcedMovement, visualize) + : getIncludedBlockPositionsLinear(forcedMovement, visualize); + } + + protected boolean isRadial() { + return world.getBlockState(pos).getBlock() instanceof RadialChassisBlock; + } + + public List collectChassisGroup() { + List frontier = new ArrayList<>(); + List collected = new ArrayList<>(); + Set visited = new HashSet<>(); + frontier.add(pos); + while (!frontier.isEmpty()) { + BlockPos current = frontier.remove(0); + if (visited.contains(current)) + continue; + visited.add(current); + TileEntity tileEntity = world.getTileEntity(current); + if (tileEntity instanceof ChassisTileEntity) { + ChassisTileEntity chassis = (ChassisTileEntity) tileEntity; + collected.add(chassis); + visited.add(current); + chassis.addAttachedChasses(frontier, visited); + } + } + return collected; + } + + public boolean addAttachedChasses(List frontier, Set visited) { + BlockState state = getBlockState(); + if (!(state.getBlock() instanceof AbstractChassisBlock)) + return false; + Axis axis = state.get(AbstractChassisBlock.AXIS); + if (isRadial()) { + + // Collect chain of radial chassis + for (int offset : new int[] { -1, 1 }) { + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + BlockPos currentPos = pos.offset(direction, offset); + if (!world.isBlockPresent(currentPos)) + return false; + + BlockState neighbourState = world.getBlockState(currentPos); + if (!AllBlocks.ROTATION_CHASSIS.typeOf(neighbourState)) + continue; + if (axis != neighbourState.get(BlockStateProperties.AXIS)) + continue; + if (!visited.contains(currentPos)) + frontier.add(currentPos); + } + + return true; + } + + // Collect group of connected linear chassis + for (Direction offset : Direction.values()) { + if (offset.getAxis() == axis) + continue; + BlockPos current = pos.offset(offset); + if (visited.contains(current)) + continue; + if (!world.isBlockPresent(current)) + return false; + + BlockState neighbourState = world.getBlockState(current); + if (!LinearChassisBlock.isChassis(neighbourState)) + continue; + if (!LinearChassisBlock.sameKind(state, neighbourState)) + continue; + if (neighbourState.get(AXIS) != axis) + continue; + + frontier.add(current); + } + + return true; + } + + private List getIncludedBlockPositionsLinear(Direction forcedMovement, boolean visualize) { + List positions = new ArrayList<>(); + BlockState state = getBlockState(); + AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock(); + Axis axis = state.get(AbstractChassisBlock.AXIS); + Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + int chassisRange = visualize ? range.scrollableValue : getRange(); + + for (int offset : new int[] { 1, -1 }) { + if (offset == -1) + facing = facing.getOpposite(); + boolean sticky = state.get(block.getGlueableSide(state, facing)); + for (int i = 1; i <= chassisRange; i++) { + BlockPos current = pos.offset(facing, i); + BlockState currentState = world.getBlockState(current); + + if (forcedMovement != facing && !visualize && !sticky) + break; + + // Ignore replaceable Blocks and Air-like + if (currentState.getMaterial().isReplaceable()) + break; + if (currentState.getCollisionShape(world, current).isEmpty()) + break; + if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(currentState)) + break; + if (AllBlocks.MECHANICAL_PISTON.typeOf(currentState)) + break; + if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(currentState)) + break; + + positions.add(current); + + if (BlockMovementTraits.notSupportive(currentState, facing)) + break; + } + } + + return positions; + } + + private List getIncludedBlockPositionsRadial(Direction forcedMovement, boolean visualize) { + List positions = new ArrayList<>(); + BlockState state = world.getBlockState(pos); + Axis axis = state.get(AbstractChassisBlock.AXIS); + AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock(); + int chassisRange = visualize ? range.scrollableValue : getRange(); + + for (Direction facing : Direction.values()) { + if (facing.getAxis() == axis) + continue; + if (!state.get(block.getGlueableSide(state, facing))) + continue; + + BlockPos startPos = pos.offset(facing); + List localFrontier = new LinkedList<>(); + Set localVisited = new HashSet<>(); + localFrontier.add(startPos); + + while (!localFrontier.isEmpty()) { + BlockPos searchPos = localFrontier.remove(0); + BlockState searchedState = world.getBlockState(searchPos); + + if (localVisited.contains(searchPos)) + continue; + if (!searchPos.withinDistance(pos, chassisRange + .5f)) + continue; + if (searchedState.getMaterial().isReplaceable()) + continue; + if (searchedState.getCollisionShape(world, searchPos).isEmpty()) + continue; + + localVisited.add(searchPos); + if (!searchPos.equals(pos)) + positions.add(searchPos); + + for (Direction offset : Direction.values()) { + if (offset.getAxis() == axis) + continue; + if (searchPos.equals(pos) && offset != facing) + continue; + if (BlockMovementTraits.notSupportive(searchedState, offset)) + continue; + + localFrontier.add(searchPos.offset(offset)); + } + } + } + + return positions; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java index fa74c19e8..52e3c9e58 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/CartAssemblerBlock.java @@ -30,8 +30,8 @@ import net.minecraft.world.World; public class CartAssemblerBlock extends AbstractRailBlock { - public static IProperty RAIL_SHAPE = - EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH); + public static IProperty RAIL_SHAPE = EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, + RailShape.NORTH_SOUTH); public static BooleanProperty POWERED = BlockStateProperties.POWERED; public CartAssemblerBlock() { @@ -72,7 +72,7 @@ public class CartAssemblerBlock extends AbstractRailBlock { if (!cart.getPassengers().isEmpty()) return; - Contraption contraption = MountedContraption.assembleMinecart(world, pos, cart); + Contraption contraption = MountedContraption.assembleMinecart(world, pos); if (contraption == null) return; float initialAngle = ContraptionEntity.yawFromVector(cart.getMotion()); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java index eee8cf6be..53730fa5b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/mounted/MountedContraption.java @@ -11,7 +11,6 @@ import com.simibubi.create.modules.contraptions.components.contraptions.AllContr import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import net.minecraft.block.BlockState; -import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntity; @@ -30,8 +29,8 @@ public class MountedContraption extends Contraption { protected AllContraptionTypes getType() { return AllContraptionTypes.MOUNTED; } - - public static Contraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) { + + public static Contraption assembleMinecart(World world, BlockPos pos) { if (isFrozen()) return null; @@ -40,8 +39,7 @@ public class MountedContraption extends Contraption { return null; Contraption contraption = new MountedContraption(); - Vec3d vec = cart.getMotion(); - if (!contraption.searchMovedStructure(world, pos, Direction.getFacingFromVector(vec.x, vec.y, vec.z))) + if (!contraption.searchMovedStructure(world, pos, null)) return null; Axis axis = state.get(RAIL_SHAPE) == RailShape.EAST_WEST ? Axis.X : Axis.Z; @@ -83,8 +81,8 @@ public class MountedContraption extends Contraption { } @Override - public void disassemble(World world, BlockPos offset, float yaw, float pitch) { - super.disassemble(world, offset, yaw, pitch, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state)); + public void disassemble(World world, BlockPos offset, Vec3d rotation) { + super.disassemble(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state)); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java index 6e1042955..5a817099f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/piston/PistonContraption.java @@ -14,6 +14,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.modules.contraptions.components.contraptions.AllContraptionTypes; +import com.simibubi.create.modules.contraptions.components.contraptions.BlockMovementTraits; import com.simibubi.create.modules.contraptions.components.contraptions.Contraption; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState; @@ -26,6 +27,7 @@ import net.minecraft.tileentity.TileEntity; 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.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -140,9 +142,11 @@ public class PistonContraption extends Contraption { break; if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite()) break; - if (!canPush(world, currentPos, direction)) + if (!BlockMovementTraits.movementAllowed(world, currentPos)) return retracting; frontier.add(currentPos); + if (BlockMovementTraits.notSupportive(state, orientation)) + break; } return true; } @@ -153,8 +157,8 @@ public class PistonContraption extends Contraption { } @Override - public void disassemble(World world, BlockPos offset, float yaw, float pitch) { - super.disassemble(world, offset, yaw, pitch, (pos, state) -> { + public void disassemble(World world, BlockPos offset, Vec3d rotation) { + super.disassemble(world, offset, rotation, (pos, state) -> { BlockPos pistonPos = anchor.offset(orientation, -1); BlockState pistonState = world.getBlockState(pistonPos); TileEntity te = world.getTileEntity(pistonPos); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/fan/AirCurrent.java b/src/main/java/com/simibubi/create/modules/contraptions/components/fan/AirCurrent.java index 904e4c1d3..3f6b2651b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/fan/AirCurrent.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/fan/AirCurrent.java @@ -14,6 +14,7 @@ import com.simibubi.create.modules.logistics.InWorldProcessing; import com.simibubi.create.modules.logistics.InWorldProcessing.Type; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.nbt.CompoundNBT; @@ -31,7 +32,9 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; +import net.minecraftforge.common.Tags; public class AirCurrent { @@ -155,7 +158,15 @@ public class AirCurrent { if (!world.isBlockPresent(currentPos)) break; BlockState state = world.getBlockState(currentPos); + if (shouldAlwaysPass(state)) + continue; VoxelShape voxelshape = state.getCollisionShape(world, currentPos, ISelectionContext.dummy()); + if (voxelshape.isEmpty()) + continue; + if (voxelshape == VoxelShapes.fullCube()) { + maxDistance = i - 1; + break; + } for (Vec3d offset : offsets) { Vec3d rayStart = VecHelper.getCenterOf(currentPos).subtract(directionVec.scale(.5f + 1 / 32f)) @@ -273,6 +284,14 @@ public class AirCurrent { } + private static boolean shouldAlwaysPass(BlockState state) { + if (state.isIn(Tags.Blocks.FENCES)) + return true; + if (state.getBlock() == Blocks.IRON_BARS) + return true; + return false; + } + public InWorldProcessing.Type getSegmentAt(float offset) { for (AirCurrentSegment airCurrentSegment : segments) { if (offset > airCurrentSegment.endOffset && pushing) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java index 8e47bc9cf..83ca9983e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java @@ -11,6 +11,8 @@ import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; +import net.minecraft.entity.player.PlayerEntity; + public class MotorTileEntity extends GeneratingKineticTileEntity { public static final int DEFAULT_SPEED = 16; @@ -47,7 +49,8 @@ public class MotorTileEntity extends GeneratingKineticTileEntity { } private int step(int current, boolean forward) { - if (world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ()).isSneaking()) + PlayerEntity closestPlayer = world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ()); + if (closestPlayer != null && closestPlayer.isSneaking()) return 1; int magnitude = Math.abs(current) - (forward == current > 0 ? 0 : 1); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java new file mode 100644 index 000000000..b66cba448 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/LatchBlock.java @@ -0,0 +1,91 @@ +package com.simibubi.create.modules.logistics.block.diodes; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.TickPriority; +import net.minecraft.world.World; + +public class LatchBlock extends ToggleLatchBlock { + + public static BooleanProperty POWERED_SIDE = BooleanProperty.create("powered_side"); + + public LatchBlock() { + setDefaultState(getDefaultState().with(POWERED_SIDE, false)); + } + + @Override + protected void fillStateContainer(Builder builder) { + super.fillStateContainer(builder.add(POWERED_SIDE)); + } + + @Override + protected void updateState(World worldIn, BlockPos pos, BlockState state) { + boolean back = state.get(POWERED); + boolean shouldBack = this.shouldBePowered(worldIn, pos, state); + boolean side = state.get(POWERED_SIDE); + boolean shouldSide = getPowerOnSides(worldIn, pos, state) > 0; + + TickPriority tickpriority = TickPriority.HIGH; + if (this.isFacingTowardsRepeater(worldIn, pos, state)) + tickpriority = TickPriority.EXTREMELY_HIGH; + else if (side || back) + tickpriority = TickPriority.VERY_HIGH; + + if (worldIn.getPendingBlockTicks().isTickPending(pos, this)) + return; + if (back != shouldBack || side != shouldSide) + worldIn.getPendingBlockTicks().scheduleTick(pos, this, this.getDelay(state), tickpriority); + } + + @Override + public void tick(BlockState state, World worldIn, BlockPos pos, Random random) { + boolean back = state.get(POWERED); + boolean shouldBack = this.shouldBePowered(worldIn, pos, state); + boolean side = state.get(POWERED_SIDE); + boolean shouldSide = getPowerOnSides(worldIn, pos, state) > 0; + BlockState stateIn = state; + + if (back != shouldBack) { + state = state.with(POWERED, shouldBack); + if (shouldBack) + state = state.with(POWERING, true); + else if (side) + state = state.with(POWERING, false); + } + + if (side != shouldSide) { + state = state.with(POWERED_SIDE, shouldSide); + if (shouldSide) + state = state.with(POWERING, false); + else if (back) + state = state.with(POWERING, true); + } + + if (state != stateIn) + worldIn.setBlockState(pos, state, 2); + } + + @Override + protected boolean activated(World worldIn, BlockPos pos, BlockState state) { + if (state.get(POWERED) != state.get(POWERED_SIDE)) + return false; + if (!worldIn.isRemote) + worldIn.setBlockState(pos, state.cycle(POWERING), 2); + return true; + } + + @Override + public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { + if (side == null) + return false; + return side.getAxis().isHorizontal(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ToggleLatchBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ToggleLatchBlock.java new file mode 100644 index 000000000..20b238593 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ToggleLatchBlock.java @@ -0,0 +1,80 @@ +package com.simibubi.create.modules.logistics.block.diodes; + +import java.util.Random; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.RedstoneDiodeBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; + +public class ToggleLatchBlock extends RedstoneDiodeBlock { + + public static BooleanProperty POWERING = BooleanProperty.create("powering"); + + public ToggleLatchBlock() { + super(Properties.from(Blocks.REPEATER)); + setDefaultState(getDefaultState().with(POWERING, false).with(POWERED, false)); + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(POWERED, POWERING, HORIZONTAL_FACING); + } + + @Override + public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { + return blockState.get(HORIZONTAL_FACING) == side ? this.getActiveSignal(blockAccess, pos, blockState) : 0; + } + + @Override + protected int getDelay(BlockState state) { + return 1; + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + if (!player.isAllowEdit()) + return false; + if (player.isSneaking()) + return false; + return activated(worldIn, pos, state); + } + + @Override + protected int getActiveSignal(IBlockReader worldIn, BlockPos pos, BlockState state) { + return state.get(POWERING) ? 15 : 0; + } + + @Override + public void tick(BlockState state, World worldIn, BlockPos pos, Random random) { + boolean poweredPreviously = state.get(POWERED); + super.tick(state, worldIn, pos, random); + BlockState newState = worldIn.getBlockState(pos); + if (newState.get(POWERED) && !poweredPreviously) + worldIn.setBlockState(pos, newState.cycle(POWERING), 2); + } + + protected boolean activated(World worldIn, BlockPos pos, BlockState state) { + if (!worldIn.isRemote) + worldIn.setBlockState(pos, state.cycle(POWERING), 2); + return true; + } + + @Override + public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { + if (side == null) + return false; + return side.getAxis() == state.get(HORIZONTAL_FACING).getAxis(); + } + +} diff --git a/src/main/resources/assets/create/blockstates/redstone_latch.json b/src/main/resources/assets/create/blockstates/redstone_latch.json new file mode 100644 index 000000000..2ca364252 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/redstone_latch.json @@ -0,0 +1,15 @@ +{ + "forge_marker": 1, + "variants": { + "powering": { + "true": { "model": "create:block/repeaters/redstone_latch_powered" }, + "false": { "model": "create:block/repeaters/redstone_latch" } + }, + "facing": { + "north": { "y": 180 }, + "east": { "y": 270 }, + "south": { "y": 0 }, + "west": { "y": 90 } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/blockstates/toggle_latch.json b/src/main/resources/assets/create/blockstates/toggle_latch.json new file mode 100644 index 000000000..11ec7dfe6 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/toggle_latch.json @@ -0,0 +1,24 @@ +{ + "forge_marker": 1, + "variants": { + "powered=false,powering=false,facing=north": { "model": "create:block/repeaters/toggle_latch", "y": 180 }, + "powered=false,powering=false,facing=east": { "model": "create:block/repeaters/toggle_latch", "y": 270 }, + "powered=false,powering=false,facing=south": { "model": "create:block/repeaters/toggle_latch", "y": 0 }, + "powered=false,powering=false,facing=west": { "model": "create:block/repeaters/toggle_latch", "y": 90 }, + + "powered=true,powering=false,facing=north": { "model": "create:block/repeaters/toggle_latch_powered", "y": 180 }, + "powered=true,powering=false,facing=east": { "model": "create:block/repeaters/toggle_latch_powered", "y": 270 }, + "powered=true,powering=false,facing=south": { "model": "create:block/repeaters/toggle_latch_powered", "y": 0 }, + "powered=true,powering=false,facing=west": { "model": "create:block/repeaters/toggle_latch_powered", "y": 90 }, + + "powered=false,powering=true,facing=north": { "model": "create:block/repeaters/toggle_latch_powering", "y": 180 }, + "powered=false,powering=true,facing=east": { "model": "create:block/repeaters/toggle_latch_powering", "y": 270 }, + "powered=false,powering=true,facing=south": { "model": "create:block/repeaters/toggle_latch_powering", "y": 0 }, + "powered=false,powering=true,facing=west": { "model": "create:block/repeaters/toggle_latch_powering", "y": 90 }, + + "powered=true,powering=true,facing=north": { "model": "create:block/repeaters/toggle_latch_powered_powering", "y": 180 }, + "powered=true,powering=true,facing=east": { "model": "create:block/repeaters/toggle_latch_powered_powering", "y": 270 }, + "powered=true,powering=true,facing=south": { "model": "create:block/repeaters/toggle_latch_powered_powering", "y": 0 }, + "powered=true,powering=true,facing=west": { "model": "create:block/repeaters/toggle_latch_powered_powering", "y": 90 } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index b5b66cb0a..5043fb297 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -138,6 +138,8 @@ "block.create.linked_transposer": "Linked Transposer", "block.create.pulse_repeater": "Pulse Repeater", "block.create.flexpulsepeater": "Adjustable Pulse Repeater", + "block.create.redstone_latch": "Powered Latch", + "block.create.toggle_latch": "Powered Toggle Latch", "block.create.flexpeater": "Adjustable Repeater", "block.create.entity_detector": "Belt Observer", "block.create.logistical_casing": "Logistical Casing", diff --git a/src/main/resources/assets/create/models/block/drill.json b/src/main/resources/assets/create/models/block/drill.json index b68f2ef3e..0659789ce 100644 --- a/src/main/resources/assets/create/models/block/drill.json +++ b/src/main/resources/assets/create/models/block/drill.json @@ -1,81 +1,161 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", - "textures": { - "gearbox_top": "create:block/gearbox_top", - "anvil": "create:block/noisy_iron_block", - "anvil2": "minecraft:block/anvil", - "gearbox": "create:block/gearbox", - "axis_top": "create:block/axis_top", - "axis": "create:block/axis", - "andesite_casing_short": "create:block/andesite_casing_short" - }, - "elements": [ - { - "name": "Drill", - "from": [ 4, 4, 11 ], - "to": [ 12, 12, 13 ], - "faces": { - "north": { "texture": "#anvil2", "uv": [ 3, 3, 11, 11 ] }, - "east": { "texture": "#anvil2", "uv": [ 10, 5, 12, 13 ] }, - "south": { "texture": "#anvil2", "uv": [ 3, 3, 11, 11 ] }, - "west": { "texture": "#anvil2", "uv": [ 8, 4, 10, 12 ] }, - "up": { "texture": "#anvil2", "uv": [ 5, 5, 13, 7 ] }, - "down": { "texture": "#anvil2", "uv": [ 4, 3, 12, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 5, 5, 13 ], - "to": [ 11, 11, 15 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 22.5 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 11 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 10 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 11, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 10, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 6, 6, 15 ], - "to": [ 10, 10, 17 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 45.0 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 9 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 8 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 9, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 8, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 7, 7, 17 ], - "to": [ 9, 9, 19 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": -22.5 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 7 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 6 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 7, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 6, 5 ] } - } - }, - { - "name": "Shaft", - "from": [ 6, 6, 0 ], - "to": [ 10, 10, 11 ], - "faces": { - "north": { "texture": "#axis_top", "uv": [ 6, 6, 10, 10 ] }, - "east": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ], "rotation": 90 }, - "west": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ], "rotation": 270 }, - "up": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ] }, - "down": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ] } - } - } - ] + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/axis_top", + "1": "create:block/axis", + "2": "block/anvil", + "7": "block/polished_andesite", + "10": "create:block/andesite_casing_very_short", + "particle": "block/anvil" + }, + "elements": [ + { + "name": "Axle", + "from": [6, 6, 0], + "to": [10, 10, 4], + "shade": false, + "faces": { + "north": {"uv": [6, 6, 10, 10], "texture": "#0"}, + "east": {"uv": [6, 12, 10, 16], "rotation": 90, "texture": "#1"}, + "west": {"uv": [6, 0, 10, 4], "rotation": 270, "texture": "#1"}, + "up": {"uv": [6, 12, 10, 16], "texture": "#1"}, + "down": {"uv": [6, 0, 10, 4], "rotation": 180, "texture": "#1"} + } + }, + { + "name": "Core", + "from": [5, 5, 9], + "to": [11, 11, 12], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 6], "texture": "#7"}, + "east": {"uv": [0, 2, 6, 5], "rotation": 270, "texture": "#10"}, + "south": {"uv": [5, 0, 11, 6], "texture": "#2"}, + "west": {"uv": [0, 2, 6, 5], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 2, 6, 5], "rotation": 180, "texture": "#10"}, + "down": {"uv": [0, 2, 6, 5], "texture": "#10"} + } + }, + { + "name": "Top", + "from": [6, 11, 9], + "to": [10, 13, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#10"}, + "east": {"uv": [0, 1, 4, 3], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "rotation": 90, "texture": "#10"}, + "west": {"uv": [0, 1, 4, 3], "texture": "#10"}, + "up": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#10"}, + "down": {"uv": [0, 0, 4, 4], "texture": "#10"} + } + }, + { + "name": "Bottom", + "from": [6, 3, 9], + "to": [10, 5, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#10"}, + "east": {"uv": [0, 1, 4, 3], "rotation": 180, "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "rotation": 90, "texture": "#10"}, + "west": {"uv": [0, 1, 4, 3], "rotation": 180, "texture": "#10"}, + "up": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "down": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Left", + "from": [3, 6, 9], + "to": [5, 10, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "west": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "up": {"uv": [0, 1, 4, 3], "rotation": 270, "texture": "#10"}, + "down": {"uv": [0, 1, 4, 3], "rotation": 270, "texture": "#10"} + } + }, + { + "name": "Right", + "from": [11, 6, 9], + "to": [13, 10, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "west": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "up": {"uv": [0, 1, 4, 3], "rotation": 90, "texture": "#10"}, + "down": {"uv": [0, 1, 4, 3], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Bit1", + "from": [5.5, 5.5, 12], + "to": [10.5, 10.5, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 5, 5], "texture": "#2"}, + "east": {"uv": [0, 0, 5, 2], "rotation": 90, "texture": "#2"}, + "south": {"uv": [1, 2, 6, 7], "texture": "#2"}, + "west": {"uv": [0, 0, 5, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 5, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 5, 2], "texture": "#2"} + } + }, + { + "name": "Bit2", + "from": [6, 6, 14], + "to": [10, 10, 16], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 4, 4], "texture": "#2"}, + "east": {"uv": [0, 0, 4, 2], "rotation": 90, "texture": "#2"}, + "south": {"uv": [0, 0, 4, 4], "texture": "#2"}, + "west": {"uv": [0, 0, 4, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 4, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 4, 2], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "Bit3", + "from": [6.5, 6.5, 16], + "to": [9.5, 9.5, 18], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 3, 3], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 3], "texture": "#2"}, + "south": {"uv": [0, 0, 3, 3], "texture": "#2"}, + "west": {"uv": [0, 0, 3, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 3, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 3, 2], "texture": "#2"} + } + }, + { + "name": "Bit4", + "from": [7, 7, 18], + "to": [9, 9, 20], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "south": {"uv": [5, 5, 7, 7], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#2"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "head", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/drill_base.json b/src/main/resources/assets/create/models/block/drill_base.json index 76b562376..5d425f7ab 100644 --- a/src/main/resources/assets/create/models/block/drill_base.json +++ b/src/main/resources/assets/create/models/block/drill_base.json @@ -1,69 +1,78 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", + "credit": "Made with Blockbench", + "parent": "block/block", "textures": { - "particle": "create:block/gearbox_top", - "gearbox_top": "create:block/gearbox_top", - "anvil": "minecraft:block/anvil", - "gearbox": "create:block/gearbox", - "andesite_casing_short": "create:block/andesite_casing_short" - }, - "elements": [ - { - "name": "Body", - "from": [ 2, 2, 1 ], - "to": [ 14, 14, 11 ], - "faces": { - "north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] }, - "south": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] } - } - }, - { - "name": "Bottom", - "from": [ 0, 0, 0 ], - "to": [ 16, 2, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Top", - "from": [ 0, 14, 0 ], - "to": [ 16, 16, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Side", - "from": [ 0, 2, 0 ], - "to": [ 2, 14, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 } - } - }, - { - "name": "Side", - "from": [ 14, 2, 0 ], - "to": [ 16, 14, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 }, - "south": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 } - } - } - ] + "10": "create:block/andesite_casing_very_short", + "particle": "block/anvil", + "gearbox_top": "create:block/gearbox_top", + "gearbox": "create:block/gearbox", + "andesite_casing_short": "create:block/andesite_casing_short" + }, + "elements": [ + { + "name": "Body", + "from": [2, 2, 1], + "to": [14, 14, 9], + "faces": { + "north": {"uv": [2, 2, 14, 14], "texture": "#gearbox"}, + "south": {"uv": [2, 2, 14, 14], "texture": "#gearbox"} + } + }, + { + "name": "Bottom", + "from": [0, 0, 0], + "to": [16, 2, 10], + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#gearbox_top"}, + "east": {"uv": [14, 6, 16, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#gearbox_top"}, + "west": {"uv": [14, 6, 16, 16], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 6, 16, 16], "texture": "#10"} + } + }, + { + "name": "Top", + "from": [0, 14, 0], + "to": [16, 16, 10], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#gearbox_top"}, + "east": {"uv": [0, 6, 2, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#gearbox_top"}, + "west": {"uv": [0, 6, 2, 16], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 6, 16, 16], "texture": "#10"}, + "down": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Side", + "from": [0, 2, 0], + "to": [2, 14, 10], + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "east": {"uv": [2, 4, 14, 16], "rotation": 90, "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "west": {"uv": [2, 6, 14, 16], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Side", + "from": [14, 2, 0], + "to": [16, 14, 10], + "faces": { + "north": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "east": {"uv": [2, 6, 14, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "west": {"uv": [2, 4, 14, 16], "rotation": 270, "texture": "#andesite_casing_short"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "casing", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/redstone_latch.json b/src/main/resources/assets/create/models/block/repeaters/redstone_latch.json new file mode 100644 index 000000000..fd504e5a4 --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/redstone_latch.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/repeaters/toggle_latch", + "textures": { + "3": "create:block/redstone_latch", + "particle": "create:block/redstone_latch" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/redstone_latch_powered.json b/src/main/resources/assets/create/models/block/repeaters/redstone_latch_powered.json new file mode 100644 index 000000000..2a66ce1cb --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/redstone_latch_powered.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/repeaters/toggle_latch_powering", + "textures": { + "3": "create:block/redstone_latch_powered", + "particle": "create:block/redstone_latch_powered" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/toggle_latch.json b/src/main/resources/assets/create/models/block/repeaters/toggle_latch.json new file mode 100644 index 000000000..83507382e --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/toggle_latch.json @@ -0,0 +1,100 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "3": "create:block/toggle_latch", + "torch": "minecraft:block/redstone_torch_off", + "smooth_stone": "minecraft:block/smooth_stone", + "particle": "minecraft:block/cobblestone", + "base": "minecraft:block/cobblestone", + "lever": "minecraft:block/lever" + }, + "elements": [ + { + "name": "Top", + "from": [3, 2, 4], + "to": [13, 3, 12], + "faces": { + "north": {"uv": [3, 4, 13, 5], "rotation": 180, "texture": "#3"}, + "east": {"uv": [12, 4, 13, 12], "rotation": 90, "texture": "#3"}, + "south": {"uv": [3, 11, 13, 12], "texture": "#3"}, + "west": {"uv": [3, 4, 4, 12], "rotation": 90, "texture": "#3"}, + "up": {"uv": [3, 4, 13, 12], "texture": "#3"} + } + }, + { + "name": "circuit", + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "east": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "west": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#3"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#smooth_stone"} + } + }, + { + "name": "Front Torch", + "from": [6, 2, 1], + "to": [10, 8, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [6, 5, 10, 11], "texture": "#torch"}, + "south": {"uv": [6, 5, 10, 11], "texture": "#torch"} + } + }, + { + "name": "Front Torch", + "from": [7, 2, 0], + "to": [9, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "east": {"uv": [6, 5, 10, 11], "texture": "#torch"}, + "west": {"uv": [6, 5, 10, 11], "texture": "#torch"} + } + }, + { + "name": "Front Torch Top", + "from": [7, 6, 1], + "to": [9, 7, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "up": {"uv": [7, 6, 9, 8], "texture": "#torch"} + } + }, + { + "from": [4, 2, 5], + "to": [12, 5, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]}, + "faces": { + "north": {"uv": [4, 0, 12, 3], "texture": "#base"}, + "east": {"uv": [5, 0, 11, 3], "texture": "#base"}, + "south": {"uv": [4, 0, 12, 3], "texture": "#base"}, + "west": {"uv": [5, 0, 11, 3], "texture": "#base"}, + "up": {"uv": [5, 4, 11, 12], "rotation": 90, "texture": "#base"}, + "down": {"uv": [5, 4, 11, 12], "rotation": 270, "texture": "#base", "cullface": "down"} + } + }, + { + "from": [11.24264, 4.75736, 7], + "to": [13.24264, 14.75736, 9], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 9, 8]}, + "faces": { + "north": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "east": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "south": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "west": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "up": {"uv": [7, 6, 9, 8], "rotation": 90, "texture": "#lever"} + } + } + ], + "groups": [0, 1, 2, 3, 4, + { + "name": "lever", + "origin": [8, 8, 8], + "children": [5, 6] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered.json b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered.json new file mode 100644 index 000000000..55d817a33 --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/repeaters/toggle_latch", + "textures": { + "3": "create:block/toggle_latch_powered", + "particle": "create:block/toggle_latch_powered" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered_powering.json b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered_powering.json new file mode 100644 index 000000000..a161e2dfd --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powered_powering.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/repeaters/toggle_latch_powering", + "textures": { + "3": "create:block/toggle_latch_powered_powering", + "particle": "create:block/toggle_latch_powered_powering" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powering.json b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powering.json new file mode 100644 index 000000000..565558b87 --- /dev/null +++ b/src/main/resources/assets/create/models/block/repeaters/toggle_latch_powering.json @@ -0,0 +1,103 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "ambientocclusion": false, + "textures": { + "3": "create:block/toggle_latch", + "5": "create:block/toggle_latch_powered_powering", + "torch": "minecraft:block/redstone_torch", + "smooth_stone": "minecraft:block/smooth_stone", + "particle": "minecraft:block/cobblestone", + "base": "minecraft:block/cobblestone", + "lever": "minecraft:block/lever" + }, + "elements": [ + { + "name": "Top", + "from": [3, 2, 4], + "to": [13, 3, 12], + "faces": { + "north": {"uv": [3, 4, 13, 5], "rotation": 180, "texture": "#5"}, + "east": {"uv": [12, 4, 13, 12], "rotation": 90, "texture": "#5"}, + "south": {"uv": [3, 11, 13, 12], "texture": "#5"}, + "west": {"uv": [3, 4, 4, 12], "rotation": 90, "texture": "#5"}, + "up": {"uv": [3, 4, 13, 12], "texture": "#5"}, + "down": {"uv": [0, 0, 10, 8], "texture": "#5"} + } + }, + { + "name": "circuit", + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "east": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "west": {"uv": [0, 0, 16, 2], "texture": "#smooth_stone"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#3"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#smooth_stone"} + } + }, + { + "name": "Front Torch", + "from": [6, 2, 1], + "to": [10, 8, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [6, 5, 10, 11], "texture": "#torch"}, + "south": {"uv": [6, 5, 10, 11], "texture": "#torch"} + } + }, + { + "name": "Front Torch", + "from": [7, 2, 0], + "to": [9, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "east": {"uv": [6, 5, 10, 11], "texture": "#torch"}, + "west": {"uv": [6, 5, 10, 11], "texture": "#torch"} + } + }, + { + "name": "Front Torch Top", + "from": [7, 6, 1], + "to": [9, 7, 3], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]}, + "faces": { + "up": {"uv": [7, 6, 9, 8], "texture": "#torch"} + } + }, + { + "from": [4, 2, 5], + "to": [12, 5, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]}, + "faces": { + "north": {"uv": [4, 0, 12, 3], "texture": "#base"}, + "east": {"uv": [5, 0, 11, 3], "texture": "#base"}, + "south": {"uv": [4, 0, 12, 3], "texture": "#base"}, + "west": {"uv": [5, 0, 11, 3], "texture": "#base"}, + "up": {"uv": [5, 4, 11, 12], "rotation": 90, "texture": "#base"}, + "down": {"uv": [5, 4, 11, 12], "rotation": 270, "texture": "#base", "cullface": "down"} + } + }, + { + "from": [7, 3, 7], + "to": [9, 13, 9], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 3, 8]}, + "faces": { + "north": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "east": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "south": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "west": {"uv": [7, 6, 9, 16], "texture": "#lever"}, + "up": {"uv": [7, 6, 9, 8], "rotation": 90, "texture": "#lever"} + } + } + ], + "groups": [0, 1, 2, 3, 4, + { + "name": "lever", + "origin": [8, 8, 8], + "children": [5, 6] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/drill.json b/src/main/resources/assets/create/models/item/drill.json index c5031bf2b..f4ee35562 100644 --- a/src/main/resources/assets/create/models/item/drill.json +++ b/src/main/resources/assets/create/models/item/drill.json @@ -1,125 +1,226 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)", - "textures": { - "gearbox_top": "create:block/gearbox_top", - "anvil": "create:block/noisy_iron_block", - "anvil2": "minecraft:block/anvil", - "gearbox": "create:block/gearbox", - "andesite_casing_short": "create:block/andesite_casing_short" - }, + "credit": "Made with Blockbench", "parent": "create:block/block", - "elements": [ - { - "name": "Body", - "from": [ 2, 2, 1 ], - "to": [ 14, 14, 11 ], - "faces": { - "north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] }, - "south": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] } - } - }, - { - "name": "Bottom", - "from": [ 0, 0, 0 ], - "to": [ 16, 2, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Top", - "from": [ 0, 14, 0 ], - "to": [ 16, 16, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 }, - "up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }, - "down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] } - } - }, - { - "name": "Side", - "from": [ 0, 2, 0 ], - "to": [ 2, 14, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 }, - "south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 } - } - }, - { - "name": "Side", - "from": [ 14, 2, 0 ], - "to": [ 16, 14, 12 ], - "faces": { - "north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] }, - "east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 }, - "south": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] }, - "west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 } - } - }, - { - "name": "Drill", - "from": [ 4, 4, 11 ], - "to": [ 12, 12, 13 ], - "faces": { - "north": { "texture": "#anvil2", "uv": [ 3, 3, 11, 11 ] }, - "east": { "texture": "#anvil2", "uv": [ 10, 5, 12, 13 ] }, - "south": { "texture": "#anvil2", "uv": [ 3, 3, 11, 11 ] }, - "west": { "texture": "#anvil2", "uv": [ 8, 4, 10, 12 ] }, - "up": { "texture": "#anvil2", "uv": [ 5, 5, 13, 7 ] }, - "down": { "texture": "#anvil2", "uv": [ 4, 3, 12, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 5, 5, 13 ], - "to": [ 11, 11, 15 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 22.5 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 11 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 10 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 11, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 10, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 6, 6, 15 ], - "to": [ 10, 10, 17 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 45.0 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 9 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 8 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 9, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 8, 5 ] } - } - }, - { - "name": "Drill", - "from": [ 7, 7, 17 ], - "to": [ 9, 9, 19 ], - "rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": -22.5 }, - "faces": { - "north": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] }, - "east": { "texture": "#anvil", "uv": [ 10, 5, 12, 7 ] }, - "south": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] }, - "west": { "texture": "#anvil", "uv": [ 8, 4, 10, 6 ] }, - "up": { "texture": "#anvil", "uv": [ 5, 5, 7, 7 ] }, - "down": { "texture": "#anvil", "uv": [ 4, 3, 6, 5 ] } - } - } - ] + "textures": { + "0": "create:block/axis_top", + "1": "create:block/axis", + "2": "block/anvil", + "7": "block/polished_andesite", + "10": "create:block/andesite_casing_very_short", + "particle": "block/anvil", + "gearbox_top": "create:block/gearbox_top", + "gearbox": "create:block/gearbox", + "andesite_casing_short": "create:block/andesite_casing_short" + }, + "elements": [ + { + "name": "Axle", + "from": [6, 6, 0], + "to": [10, 10, 4], + "shade": false, + "faces": { + "north": {"uv": [6, 6, 10, 10], "texture": "#0"}, + "east": {"uv": [6, 12, 10, 16], "rotation": 90, "texture": "#1"}, + "west": {"uv": [6, 0, 10, 4], "rotation": 270, "texture": "#1"}, + "up": {"uv": [6, 12, 10, 16], "texture": "#1"}, + "down": {"uv": [6, 0, 10, 4], "rotation": 180, "texture": "#1"} + } + }, + { + "name": "Core", + "from": [5, 5, 9], + "to": [11, 11, 12], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 6, 6], "texture": "#7"}, + "east": {"uv": [0, 2, 6, 5], "rotation": 270, "texture": "#10"}, + "south": {"uv": [5, 0, 11, 6], "texture": "#2"}, + "west": {"uv": [0, 2, 6, 5], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 2, 6, 5], "rotation": 180, "texture": "#10"}, + "down": {"uv": [0, 2, 6, 5], "texture": "#10"} + } + }, + { + "name": "Top", + "from": [6, 11, 9], + "to": [10, 13, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#10"}, + "east": {"uv": [0, 1, 4, 3], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "rotation": 90, "texture": "#10"}, + "west": {"uv": [0, 1, 4, 3], "texture": "#10"}, + "up": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#10"}, + "down": {"uv": [0, 0, 4, 4], "texture": "#10"} + } + }, + { + "name": "Bottom", + "from": [6, 3, 9], + "to": [10, 5, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#10"}, + "east": {"uv": [0, 1, 4, 3], "rotation": 180, "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "rotation": 90, "texture": "#10"}, + "west": {"uv": [0, 1, 4, 3], "rotation": 180, "texture": "#10"}, + "up": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "down": {"uv": [0, 0, 4, 4], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Left", + "from": [3, 6, 9], + "to": [5, 10, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "west": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "up": {"uv": [0, 1, 4, 3], "rotation": 270, "texture": "#10"}, + "down": {"uv": [0, 1, 4, 3], "rotation": 270, "texture": "#10"} + } + }, + { + "name": "Right", + "from": [11, 6, 9], + "to": [13, 10, 13], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "south": {"uv": [0, 0, 2, 4], "texture": "#10"}, + "west": {"uv": [0, 0, 4, 4], "texture": "#10"}, + "up": {"uv": [0, 1, 4, 3], "rotation": 90, "texture": "#10"}, + "down": {"uv": [0, 1, 4, 3], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Bit1", + "from": [5.5, 5.5, 12], + "to": [10.5, 10.5, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 5, 5], "texture": "#2"}, + "east": {"uv": [0, 0, 5, 2], "rotation": 90, "texture": "#2"}, + "south": {"uv": [1, 2, 6, 7], "texture": "#2"}, + "west": {"uv": [0, 0, 5, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 5, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 5, 2], "texture": "#2"} + } + }, + { + "name": "Bit2", + "from": [6, 6, 14], + "to": [10, 10, 16], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 4, 4], "texture": "#2"}, + "east": {"uv": [0, 0, 4, 2], "rotation": 90, "texture": "#2"}, + "south": {"uv": [0, 0, 4, 4], "texture": "#2"}, + "west": {"uv": [0, 0, 4, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 4, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 4, 2], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "Bit3", + "from": [6.5, 6.5, 16], + "to": [9.5, 9.5, 18], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 3, 3], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 3], "texture": "#2"}, + "south": {"uv": [0, 0, 3, 3], "texture": "#2"}, + "west": {"uv": [0, 0, 3, 2], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 3, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 3, 2], "texture": "#2"} + } + }, + { + "name": "Bit4", + "from": [7, 7, 18], + "to": [9, 9, 20], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 7]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "south": {"uv": [5, 5, 7, 7], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#2"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#2"} + } + }, + { + "name": "Body", + "from": [2, 2, 1], + "to": [14, 14, 9], + "faces": { + "north": {"uv": [2, 2, 14, 14], "texture": "#gearbox"}, + "south": {"uv": [2, 2, 14, 14], "texture": "#gearbox"} + } + }, + { + "name": "Bottom", + "from": [0, 0, 0], + "to": [16, 2, 10], + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#gearbox_top"}, + "east": {"uv": [14, 6, 16, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#gearbox_top"}, + "west": {"uv": [14, 6, 16, 16], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"}, + "down": {"uv": [0, 6, 16, 16], "texture": "#10"} + } + }, + { + "name": "Top", + "from": [0, 14, 0], + "to": [16, 16, 10], + "faces": { + "north": {"uv": [0, 0, 16, 2], "texture": "#gearbox_top"}, + "east": {"uv": [0, 6, 2, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [0, 0, 16, 2], "texture": "#gearbox_top"}, + "west": {"uv": [0, 6, 2, 16], "rotation": 90, "texture": "#10"}, + "up": {"uv": [0, 6, 16, 16], "texture": "#10"}, + "down": {"uv": [0, 4, 16, 16], "texture": "#andesite_casing_short"} + } + }, + { + "name": "Side", + "from": [0, 2, 0], + "to": [2, 14, 10], + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "east": {"uv": [2, 4, 14, 16], "rotation": 90, "texture": "#andesite_casing_short"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "west": {"uv": [2, 6, 14, 16], "rotation": 90, "texture": "#10"} + } + }, + { + "name": "Side", + "from": [14, 2, 0], + "to": [16, 14, 10], + "faces": { + "north": {"uv": [0, 2, 2, 14], "texture": "#gearbox_top"}, + "east": {"uv": [2, 6, 14, 16], "rotation": 90, "texture": "#10"}, + "south": {"uv": [14, 2, 16, 14], "texture": "#gearbox_top"}, + "west": {"uv": [2, 4, 14, 16], "rotation": 270, "texture": "#andesite_casing_short"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "head", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + }, + { + "name": "casing", + "origin": [8, 8, 8], + "children": [10, 11, 12, 13, 14] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/redstone_latch.json b/src/main/resources/assets/create/models/item/redstone_latch.json new file mode 100644 index 000000000..0d839e344 --- /dev/null +++ b/src/main/resources/assets/create/models/item/redstone_latch.json @@ -0,0 +1,10 @@ +{ + "parent": "create:block/repeaters/redstone_latch", + "display": { + "fixed": { + "rotation": [ 270, 0, 0 ], + "translation": [ 0, 0, -3], + "scale":[ 0.5, 0.5, 0.5 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/toggle_latch.json b/src/main/resources/assets/create/models/item/toggle_latch.json new file mode 100644 index 000000000..0794ca899 --- /dev/null +++ b/src/main/resources/assets/create/models/item/toggle_latch.json @@ -0,0 +1,10 @@ +{ + "parent": "create:block/repeaters/toggle_latch", + "display": { + "fixed": { + "rotation": [ 270, 0, 0 ], + "translation": [ 0, 0, -3], + "scale":[ 0.5, 0.5, 0.5 ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/andesite_casing_very_short.png b/src/main/resources/assets/create/textures/block/andesite_casing_very_short.png new file mode 100644 index 0000000000000000000000000000000000000000..692ef9d9f3ee6279ac4f344b3241191978b6d8d4 GIT binary patch literal 489 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940e(qDK~y+T%~4BE z!!Qs{oWzOiHfbwC)ddp24FZnAB`UF@5=Q`WDNe!;Sg>LRRH)FTZQ{g98lD*xAx^;4 zXf*R?#`Cd#b#vX1`c+-m4O3|X+p?^xXPeDIo;e zEkKgdhV04tBukYpOXm7zk$SGzG)-0%p_D4m81u?fBU`CL1U!s-|8b%#Tgb?LQ`a&5#ToM9{+td5k2u%d~``7zr2zOPfytvfP9bpbWA}P)`Y?@eT}z zW8p;D>G^&AnXKOu4M7+-7|7FW3L6QugZa3V<5SeY0mAR2QH($#j17&m{(KyL6Gnt? fU4WR@wJhrk{c;Pngplv900000NkvXXu0mjf#dgcA literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/redstone_latch.png b/src/main/resources/assets/create/textures/block/redstone_latch.png new file mode 100644 index 0000000000000000000000000000000000000000..0571c5fe27a600bd0ef2c7427ddc71e097c1a3c2 GIT binary patch literal 513 zcmV+c0{;DpP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940hUQbK~y+TZIVGt z0$~t_bKBfh%C!QME*-lR3Z27)_aH>+hZK|rT};CI1<|3O5P?W1=?{1aqML%0-PA&J zMR$9?oo$n7*d5-P_nn#V*ZQ%(Ot~Pi`ggy-qJ0i~a$L^#lML z^ag~DRzss26pn`B@O;qXMaS1}w!zXxO+Z??uTbevr;~?UMBb_7AgX{K#J7hBYqs{P z+5h^?<%LwL0*-_yyI0CvBMUqk+h0~cWJHYMtTpW4l&T`5uLiPmSxV{TIJT|@=G9d~ z%dr*w*mgeqs)a981siV61Z^&i!Wj?Ugfb&&#N(?_NRfFHUR;g|Z|_YMZuDy$5(+6Y zZvsY4o2A8=C?tu2C!+zBgvivTpLuL|0$lr}qfLZWwh%G60~A-aGJ$vJSE{*ZCZccaIC{o%D1bpl%~uBx^(V zY(Gm9yE`w|9&04oB~fF6@>N+7#&m`XzzgPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!2kdb!2!6DYwZ940h38YK~y+TWs=WI z0#Ovk$7ym>DaQ&-+SE>hLSG=n7ic4b&k=1Jgdl@JdX+YTxC&_(JRIY; zyKS9nSTr6bhvg$JR&;#5P7f|!)C8opry7;PbUOLGi|218i>Ly6;O8%|RPrC*H7&1c z&kt2Nm8yW1yp;BOUvj1nWIl6$ol(S$nc)p*GSVt_g2?Er!){6iN+FAdYv`dZb(F|n zVjnwm7e6D_B9N(qLswa#Z$?opW)pFN88(y2gS58{GJnE{?n?UetAj##09g_#GJk^j z*xj83RulsGd^+|WPo@riacyJyH^}wA`}*8Vdf1McoPiV&nZcCoX}0;+XHNO zEs#hcGnm2^Vjs(@f$Roa%S%Lx4P^d3aEtOBz>%07*qoM6N<$f&nkp A?f?J) literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/toggle_latch.png b/src/main/resources/assets/create/textures/block/toggle_latch.png new file mode 100644 index 0000000000000000000000000000000000000000..b41dd151b07f4a995e8b92dccb0bce8b54816806 GIT binary patch literal 510 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0h38YK~y+TZIaJQ z0#Ovkb()+s$gu*G2zr8W(K=kX4nm??k3kc5yT3pxPy zlv!O#sY0CqJ{=DU!5Jjzz;IZ~5Nm&QoL;Zn?dZb883-ZJ+c4=8*^)z3rdE2<7+?!m z%QlpmbkYB{dvQh}Klg-`i*z=#%H$pxiCffvrEliGa75w#^I~oPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0hmcdK~y+TZIZ!C z0#Ou(uhZnDL5>xeL{PhE5iVMX3!fmwo}?hmRfvT32rYVsK%|xQ5YbLSOohOa&>Yd3 zzU!GLi4J!T|2^kF=RbGujTB2o+qTt@IgTSB3=&x;n0%Sz41PEmCX$IiAibXkVB_JK zZL{4ps0PIoadLPTY4O5ibz5DqbkPb>Yfm*QLv=a@xXmt@N(RvdG+_UDd9mvm9mD(A z=k9J9gi2kYwc3j4S>@cFx#E!#KX++laQDR%k zZT!shKS#O+CJMShj);P>8i(P}CJTZ#D{7@uJEWj;)Ifp%fJfoI*MhNN{u)D)f(k8A zz}VAfb0aAX31Z;+bW94&Ab|qI;b}vz`_Xd-gMPm!iwI{R1wn4ZL`CiCL(`^SewG}@ z7A&4^NHbB9|8;VGMIyKKgam8qVrHS~dtfAPQT~;@nS(<9O{v#XF?*U_jsx@=Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0gXvSK~y+TWs*Tl z0$~t_*KKptAlC}aLr^#A5dMM?e}f49j_9;_${-N`N|!)9g>>#L-4ujW2wVxx6?J=N zXI-RT)?vPxcV^!CJ`--ubsWdo!t*?J;vkV-g2k_RUBpf&(@ZuKJLyb%*dOLE^1?EV z`E*XaH|UvEl-i&?B&ub}n~T2s^TBG(j%}e2)4s)Q_Pep+bu$=ox!_ zl*KATfxlix?GO@8Kpd9aAUFIPd6UU_JkpN{JCFkU8kVekE)u!BLcOgyfNq6GVw%Mi zy|3q*OG34Q?)DLd8pf3-?|>v;QSXY)I9^sOH15{i(oJbMjw3thzle}V{c43ElCB;e uJ8vC=s8=>fG@1?d0Mq}-2*VL1>o~uA@bd|brd{^{0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0h38YK~y+TWs<>4 z0#Ou(uhZnDL5>xei=d^e@CibEfi_Y29MPshXkihEPtZFA5s0gh)~%zRf|Lq@BcVB> zGktf?I7I!7hjY*Q&pH3O*Mw7bY}-~VxUMTs93=9aVDc*-7O~^eIFrr9PCAqBcl-H+ zyk;pi9Z!jOdL4smJksQ_e5A23gvUoEzO>U5pf(?yRL0Zk6!|?)ktz|Q3uwT(e14&m z|L~?%S*fQ+9U)Ze0zE72^m1GA<{r*+;eUIRl(lIk*Sy(8)mlQMuc3*n%LxMCG!h$n zmDEml7rXF-uZeB}WP&b`MS-!Nh7l}gas*b=%H{S7VMkVtCdh?=k3koP_%TEzRA|uz zIb*lCvRGjV@R#$b9YUfBh{JLl*^6THH-^QzXOtZMY$_B<9K&=`fm8gmrm)Z^gE8DcaVP(A&Fj9 zP6&dBo9p&-n;`0i4HET6T|B__KQh8_1f8|*AMEM#_3?;AQ2+n{07*qoM6N<$f@d<{ A3;+NC literal 0 HcmV?d00001 diff --git a/src/main/resources/data/create/loot_tables/blocks/redstone_latch.json b/src/main/resources/data/create/loot_tables/blocks/redstone_latch.json new file mode 100644 index 000000000..527015d65 --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/redstone_latch.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:redstone_latch" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/loot_tables/blocks/toggle_latch.json b/src/main/resources/data/create/loot_tables/blocks/toggle_latch.json new file mode 100644 index 000000000..3d2ba3f49 --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/toggle_latch.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:toggle_latch" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/redstone_latch.json b/src/main/resources/data/create/recipes/crafting_shaped/redstone_latch.json new file mode 100644 index 000000000..087f52d14 --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/redstone_latch.json @@ -0,0 +1,32 @@ +{ + "type": "crafting_shaped", + "pattern": [ + " T ", + "RCR", + "SSS" + ], + "key": { + "S": { + "item": "minecraft:stone" + }, + "C": { + "item": "minecraft:lever" + }, + "R": { + "item": "minecraft:redstone" + }, + "T": { + "item": "minecraft:redstone_torch" + } + }, + "result": { + "item": "create:redstone_latch", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "logistics" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/toggle_latch.json b/src/main/resources/data/create/recipes/crafting_shaped/toggle_latch.json new file mode 100644 index 000000000..eb470244a --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/toggle_latch.json @@ -0,0 +1,29 @@ +{ + "type": "crafting_shaped", + "pattern": [ + " T ", + " C ", + "SSS" + ], + "key": { + "S": { + "item": "minecraft:stone" + }, + "C": { + "item": "minecraft:lever" + }, + "T": { + "item": "minecraft:redstone_torch" + } + }, + "result": { + "item": "create:toggle_latch", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "logistics" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crushing/blue_orchid.json b/src/main/resources/data/create/recipes/crushing/blue_orchid.json index 2975bd13c..2946ca025 100644 --- a/src/main/resources/data/create/recipes/crushing/blue_orchid.json +++ b/src/main/resources/data/create/recipes/crushing/blue_orchid.json @@ -1,6 +1,5 @@ { "type": "create:crushing", - "group": "minecraft:misc", "ingredients": [ { "item": "minecraft:blue_orchid" diff --git a/src/main/resources/data/create/recipes/crushing/leather_horse_armor.json b/src/main/resources/data/create/recipes/crushing/leather_horse_armor.json index 571fc5923..eda689e4d 100644 --- a/src/main/resources/data/create/recipes/crushing/leather_horse_armor.json +++ b/src/main/resources/data/create/recipes/crushing/leather_horse_armor.json @@ -1,6 +1,5 @@ { "type": "create:crushing", - "group": "minecraft:misc", "ingredients": [ { "item": "minecraft:leather_horse_armor" @@ -9,22 +8,12 @@ "results": [ { "item": "minecraft:leather", - "count": 3 + "count": 2 }, { "item": "minecraft:leather", "count": 2, "chance": 0.5 - }, - { - "item": "minecraft:string", - "count": 2, - "chance": 0.25 - }, - { - "item": "minecraft:iron_nugget", - "count": 8, - "chance": 0.25 } ], "processingTime": 200 diff --git a/src/main/resources/data/create/recipes/mixing/crushed_brass.json b/src/main/resources/data/create/recipes/mixing/crushed_brass.json index a4a54694f..a97dcdc40 100644 --- a/src/main/resources/data/create/recipes/mixing/crushed_brass.json +++ b/src/main/resources/data/create/recipes/mixing/crushed_brass.json @@ -1,6 +1,5 @@ { "type": "create:mixing", - "group": "minecraft:misc", "ingredients": [ { "item": "create:crushed_copper" diff --git a/src/main/resources/data/create/recipes/pressing/lapis_block.json b/src/main/resources/data/create/recipes/pressing/lapis_block.json index d7014e528..62239dff0 100644 --- a/src/main/resources/data/create/recipes/pressing/lapis_block.json +++ b/src/main/resources/data/create/recipes/pressing/lapis_block.json @@ -11,6 +11,5 @@ "item": "create:lapis_plate", "count": 1 } - ], - "processingTime": 100 + ] } \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/splashing/limestone.json b/src/main/resources/data/create/recipes/splashing/limestone.json new file mode 100644 index 000000000..09dcce315 --- /dev/null +++ b/src/main/resources/data/create/recipes/splashing/limestone.json @@ -0,0 +1,14 @@ +{ + "type": "create:splashing", + "ingredients": [ + { + "item": "create:limestone" + } + ], + "results": [ + { + "item": "create:weathered_limestone", + "count": 1 + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/splashing/red_sand.json b/src/main/resources/data/create/recipes/splashing/red_sand.json index 40d00217d..6b66c4b36 100644 --- a/src/main/resources/data/create/recipes/splashing/red_sand.json +++ b/src/main/resources/data/create/recipes/splashing/red_sand.json @@ -17,6 +17,5 @@ "count": 1, "chance": 0.05 } - ], - "processingTime": 100 + ] } \ No newline at end of file diff --git a/src/main/resources/data/create/tags/blocks/windowable.json b/src/main/resources/data/create/tags/blocks/windowable.json index 94fd00594..1cbbf1a06 100644 --- a/src/main/resources/data/create/tags/blocks/windowable.json +++ b/src/main/resources/data/create/tags/blocks/windowable.json @@ -1,6 +1,15 @@ { "replace": false, "values": [ - "#minecraft:stairs", "#minecraft:slabs", "#minecraft:walls", "#minecraft:fences", "#forge:fences" + "#minecraft:stairs", + "#minecraft:wooden_stairs", + "#minecraft:wooden_slabs", + "#minecraft:slabs", + "#minecraft:walls", + "#minecraft:fences", + "#minecraft:wooden_fences", + "#forge:fences", + "#forge:fences/wooden", + "#forge:fences/nether_brick" ] } \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/items/glass_panes.json b/src/main/resources/data/forge/tags/items/glass_panes.json index 17dc53a1a..03cefac89 100644 --- a/src/main/resources/data/forge/tags/items/glass_panes.json +++ b/src/main/resources/data/forge/tags/items/glass_panes.json @@ -1,6 +1,16 @@ { "replace": false, "values": [ - "create:tiled_glass_pane" + "create:tiled_glass_pane", + "create:framed_glass_pane", + "create:horizontal_framed_glass_pane", + "create:vertical_framed_glass_pane", + "create:oak_glass_pane", + "create:spruce_glass_pane", + "create:birch_glass_pane", + "create:jungle_glass_pane", + "create:dark_oak_glass_pane", + "create:acacia_glass_pane", + "create:iron_glass_pane" ] } \ No newline at end of file diff --git a/wiki/Rotational Force in Create b/wiki/Rotational Force in Create new file mode 100644 index 000000000..1fafb47df --- /dev/null +++ b/wiki/Rotational Force in Create @@ -0,0 +1,52 @@ +Some of the most prominent machines and components require **Rotational Force** to operate. Sometimes the provided rotation speed and direction reflects their behaviour, and some components may have a more significant _cost_ than others. + +1. Generate & Convey +2. Changing Gear +3. Stress & Capacity + +## Generate & Convey +Using appropiate generators(link), you can start setting things in motion. These kinetic components will apply the speed they generate at to attached shafts, cogs, etc. Any component can be connected to any other, so long as their integrated shafts/cogs are linked together. + +(waterwheel powering something) (mechanical crafters powering each other) + +**Multiple generators** can be connected together in order achieve a greater Capacity score for the attached kinetic network. When attaching new generators to running components, it is important that the added generator rotates in the **same direction** as the component it is attached to. When connecting two kinetic blocks with **incompatible direction** of rotation, you'll notice that the blocks just break. However, trouble-shooting this will be quite straight-forward - all you need to do is to include a means of reversing the rotation between the generator and the rest: + +Relaying rotational power between two components is one of the most important tasks when creating with Create. There are a variety of options and multiple possible solutions for each situation. These are the components that allow you to move, spread and modify rotational behaviour most effectively: + +(mesh of these components showing off their behaviour) + +- **Shafts**, cheapest option for relaying in a straight line. +- **Cogwheels**, move sideways while keeping the same rotation axis; reverse the direction +- **Belts**, move sideways while while keeping the same rotation axis; cannot be vertical; do not reverse direction +- **Gearboxes**, relay between two different rotation axes in a compact fashion; reverse connections on the same axis +- **Encased Belts**, relay sideways and between different rotation axes; do not reverse direction + +Best is play around with each component and familiarizing yourself with its abilities. It is important to know the options when having to deal with complex connection tasks in a potentially less forgiving environment. + +## Changing Gear + +Some kinetic blocks have the ability to **speed up** or **slow down** connected components. Attach a large to a regular cogwheel diagonally: powering one of them at their shaft will result in the other rotating twice or half the speed respectively. +With this and other more compact blocks, you will have full control over the speed provided to your contraptions. This is especially important for machines that require a **minimum level of speed** to operate (e.g. the Mechanical Mixer). +Connecting faster components to other slower components **directly** will cause the faster network to overpower the rest, alinging the speed of everything that is now part of it. (That is, if the direction lines up) + +(image of something ridiculous) + +With this mechanic you can take things to the extreme and either rotate machines at the configurated maximum speed (256rpm by default) or slow them down to a fraction. But you may notice that speeding up brings a cost with it... + +## Stress & Capacity + +_In Create 0.2+, a bit of balance had been brought to rotational power: something to resemble torque in a highly simplified fashion._ + +Rotational generators have limited capacity for what they power. "Stress Impact" and "Stress Capacity" are the two opposing values in a kinetic network: **generators add capacity, machines and components add impact**. If the capacity is exhausted, all connected parts will simply stop moving, until capacity is increased or stress is relieved again. +**Stress Impact is tied to rotation speed**. Increasing the speed increases a components stress impact or capacity proportionally. + +(image of fans and water wheel) + +Consider the following example: +Assume one Water Wheel can provide just enough power in order to power four fans at the same speed. +* Doubling the speed of the fans using cogwheels will make the fans blow stronger, but the network will cease to function until the count of fans is halved, or the count of water wheels is doubled. +* Similarly, you would be able to power eight fans running at half the speed of the water wheel. + +By default, components used **only for relaying** rotational power, such as shafts and cogwheels, have **no stress impact** at all. This makes predicting the amount of generators required for your contraptions much simpler and prevents punishment for aesthetic detours between machines and generators. + +Optimizing stress impact and comparing net capacity of sources at base speed can become quite scientific. For those who are interested in seeing some actual numbers and more exhaustive information, it is recommended to look into crafting a pair of Goggles and a Stress Gauge. \ No newline at end of file