diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 8e09b208a..a4ab83f28 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -41,6 +41,7 @@ import com.simibubi.create.modules.contraptions.processing.BasinBlock; import com.simibubi.create.modules.contraptions.redstone.AnalogLeverBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerBlock; +import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelBlock; import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock; @@ -164,6 +165,7 @@ public enum AllBlocks { BRASS_CASING(new CasingBlock("crafter_top")), MECHANICAL_CRAFTER(new MechanicalCrafterBlock()), + SEQUENCED_GEARSHIFT(new SequencedGearshiftBlock()), FLYWHEEL(new FlywheelBlock()), FURNACE_ENGINE(new FurnaceEngineBlock()), ROTATION_SPEED_CONTROLLER(new SpeedControllerBlock()), diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index 7ddc8c3c4..00903d8df 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -12,6 +12,7 @@ import com.simibubi.create.foundation.packet.NbtPacket; import com.simibubi.create.foundation.packet.SimplePacketBase; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket; +import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket; import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket; import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket; import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket; @@ -34,6 +35,7 @@ public enum AllPackets { CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new), CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new), CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new), + CONFIGURE_SEQUENCER(ConfigureSequencedGearshiftPacket.class, ConfigureSequencedGearshiftPacket::new), PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new), UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new), CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new), diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 7d0df523d..f23f5cd83 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -50,6 +50,7 @@ import com.simibubi.create.modules.contraptions.redstone.AnalogLeverTileEntity; import com.simibubi.create.modules.contraptions.redstone.AnalogLeverTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerRenderer; import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerTileEntity; +import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelTileEntity; @@ -121,10 +122,7 @@ public enum AllTileEntities { MECHANICAL_BEARING(MechanicalBearingTileEntity::new, AllBlocks.MECHANICAL_BEARING), CLOCKWORK_BEARING(ClockworkBearingTileEntity::new, AllBlocks.CLOCKWORK_BEARING), ROPE_PULLEY(PulleyTileEntity::new, AllBlocks.ROPE_PULLEY), - CHASSIS( - ChassisTileEntity::new, - AllBlocks.ROTATION_CHASSIS, - AllBlocks.TRANSLATION_CHASSIS, + CHASSIS(ChassisTileEntity::new, AllBlocks.ROTATION_CHASSIS, AllBlocks.TRANSLATION_CHASSIS, AllBlocks.TRANSLATION_CHASSIS_SECONDARY), DRILL(DrillTileEntity::new, AllBlocks.DRILL), SAW(SawTileEntity::new, AllBlocks.SAW), @@ -139,6 +137,7 @@ public enum AllTileEntities { DEPLOYER(DeployerTileEntity::new, AllBlocks.DEPLOYER), BASIN(BasinTileEntity::new, AllBlocks.BASIN), MECHANICAL_CRAFTER(MechanicalCrafterTileEntity::new, AllBlocks.MECHANICAL_CRAFTER), + SEQUENCED_GEARSHIFT(SequencedGearshiftTileEntity::new, AllBlocks.SEQUENCED_GEARSHIFT), ROTATION_SPEED_CONTROLLER(SpeedControllerTileEntity::new, AllBlocks.ROTATION_SPEED_CONTROLLER), SPEED_GAUGE(SpeedGaugeTileEntity::new, AllBlocks.SPEED_GAUGE), STRESS_GAUGE(StressGaugeTileEntity::new, AllBlocks.STRESS_GAUGE), @@ -151,9 +150,7 @@ public enum AllTileEntities { EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR, AllBlocks.VERTICAL_EXTRACTOR), LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR, AllBlocks.VERTICAL_LINKED_EXTRACTOR), TRANSPOSER(TransposerTileEntity::new, AllBlocks.TRANSPOSER, AllBlocks.VERTICAL_TRANSPOSER), - LINKED_TRANSPOSER( - LinkedTransposerTileEntity::new, - AllBlocks.LINKED_TRANSPOSER, + LINKED_TRANSPOSER(LinkedTransposerTileEntity::new, AllBlocks.LINKED_TRANSPOSER, AllBlocks.VERTICAL_LINKED_TRANSPOSER), BELT_FUNNEL(FunnelTileEntity::new, AllBlocks.BELT_FUNNEL, AllBlocks.VERTICAL_FUNNEL), ENTITY_DETECTOR(BeltObserverTileEntity::new, AllBlocks.ENTITY_DETECTOR), @@ -206,6 +203,7 @@ public enum AllTileEntities { bind(GearboxTileEntity.class, new GearboxTileEntityRenderer()); bind(GearshiftTileEntity.class, new SplitShaftTileEntityRenderer()); bind(ClutchTileEntity.class, new SplitShaftTileEntityRenderer()); + bind(SequencedGearshiftTileEntity.class, new SplitShaftTileEntityRenderer()); bind(BeltTileEntity.class, new BeltTileEntityRenderer()); bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer()); bind(HandCrankTileEntity.class, new HandCrankTileEntityRenderer()); diff --git a/src/main/java/com/simibubi/create/ScreenResources.java b/src/main/java/com/simibubi/create/ScreenResources.java index a155a69ae..307b26599 100644 --- a/src/main/java/com/simibubi/create/ScreenResources.java +++ b/src/main/java/com/simibubi/create/ScreenResources.java @@ -41,6 +41,12 @@ public enum ScreenResources { FILTER("filter.png", 200, 100), ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86), + + SEQUENCER("sequencer.png", 156, 128), + SEQUENCER_INSTRUCTION("sequencer.png", 14, 47, 131, 18), + SEQUENCER_WAIT("sequencer.png", 14, 65, 131, 18), + SEQUENCER_END("sequencer.png", 14, 83, 131, 18), + SEQUENCER_EMPTY("sequencer.png", 14, 101, 131, 18), // Logistical Index INDEX_TOP("index.png", 41, 0, 174, 22), diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java index ccbacc6a3..c57a3ba95 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java @@ -1,8 +1,10 @@ package com.simibubi.create.foundation.gui.widgets; import java.util.function.Consumer; +import java.util.function.Function; import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour.StepContext; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.util.text.TextFormatting; @@ -18,6 +20,7 @@ public class ScrollInput extends AbstractSimiWidget { protected int min, max; protected int shiftStep; + Function step; public ScrollInput(int xIn, int yIn, int widthIn, int heightIn) { super(xIn, yIn, widthIn, heightIn); @@ -25,8 +28,13 @@ public class ScrollInput extends AbstractSimiWidget { min = 0; max = 1; shiftStep = 5; + step = standardStep(); } - + + public Function standardStep() { + return c -> c.shift ? shiftStep : 1; + } + public ScrollInput withRange(int min, int max) { this.min = min; this.max = max; @@ -44,6 +52,11 @@ public class ScrollInput extends AbstractSimiWidget { return this; } + public ScrollInput withStepFunction(Function step) { + this.step = step; + return this; + } + public ScrollInput writingTo(Label label) { this.displayLabel = label; writeToLabel(); @@ -62,7 +75,7 @@ public class ScrollInput extends AbstractSimiWidget { writeToLabel(); return this; } - + public ScrollInput withShiftStep(int step) { shiftStep = step; return this; @@ -73,18 +86,25 @@ public class ScrollInput extends AbstractSimiWidget { if (!isHovered) return false; + StepContext context = new StepContext(); + context.control = AllKeys.ctrlDown(); + context.shift = AllKeys.shiftDown(); + context.currentValue = state; + context.forward = delta > 0; + int priorState = state; boolean shifted = AllKeys.shiftDown(); - int step = (int) Math.signum(delta) * (shifted ? shiftStep : 1); + int step = (int) Math.signum(delta) * this.step.apply(context); + state += step; if (shifted) state -= state % shiftStep; clampState(); - + if (priorState != state) onChanged(); - + return priorState != state; } @@ -94,7 +114,7 @@ public class ScrollInput extends AbstractSimiWidget { if (state < min) state = min; } - + public void onChanged() { if (displayLabel != null) writeToLabel(); @@ -102,7 +122,7 @@ public class ScrollInput extends AbstractSimiWidget { onScroll.accept(state); updateTooltip(); } - + protected void writeToLabel() { displayLabel.text = "" + state; } diff --git a/src/main/java/com/simibubi/create/foundation/item/AbstractToolItem.java b/src/main/java/com/simibubi/create/foundation/item/AbstractToolItem.java index eb0c01d9f..b6f8effa9 100644 --- a/src/main/java/com/simibubi/create/foundation/item/AbstractToolItem.java +++ b/src/main/java/com/simibubi/create/foundation/item/AbstractToolItem.java @@ -112,7 +112,7 @@ public abstract class AbstractToolItem extends ToolItem { @Override public boolean canPlayerBreakBlockWhileHolding(BlockState state, World worldIn, BlockPos pos, PlayerEntity player) { - return !(hasType(SWORD) && !player.isCreative()); + return !hasType(SWORD) || !player.isCreative(); } @Override @@ -126,7 +126,8 @@ public abstract class AbstractToolItem extends ToolItem { return false; } - public void modifyDrops(final Collection drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) { + public void modifyDrops(final Collection drops, IWorld world, BlockPos pos, ItemStack tool, + BlockState state) { } public void spawnParticles(IWorld world, BlockPos pos, ItemStack tool, BlockState state) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index 7afedea6f..1cd01d438 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -67,7 +67,10 @@ public class RotationPropagator { // Axis <-> Axis if (connectedByAxis) { - return getAxisModifier(from, direction) * getAxisModifier(to, direction.getOpposite()); + float axisModifier = getAxisModifier(to, direction.getOpposite()); + if (axisModifier != 0) + axisModifier = 1 / axisModifier; + return getAxisModifier(from, direction) * axisModifier; } // Attached Encased Belts diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java index 939a2b83b..f23f2819f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/HorizontalAxisKineticBlock.java @@ -39,7 +39,7 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock { return this.getDefaultState().with(HORIZONTAL_AXIS, context.getPlacementHorizontalFacing().rotateY().getAxis()); } - public Axis getPreferredHorizontalAxis(BlockItemUseContext context) { + public static Axis getPreferredHorizontalAxis(BlockItemUseContext context) { Direction prefferedSide = null; for (Direction side : Direction.values()) { if (side.getAxis().isVertical()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/RotatedPillarKineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/RotatedPillarKineticBlock.java index d890c2eab..01c3177e1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/RotatedPillarKineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/RotatedPillarKineticBlock.java @@ -40,7 +40,7 @@ public abstract class RotatedPillarKineticBlock extends KineticBlock { } } - public Axis getPreferredAxis(BlockItemUseContext context) { + public static Axis getPreferredAxis(BlockItemUseContext context) { Axis prefferedAxis = null; for (Direction side : Direction.values()) { BlockState blockState = context.getWorld().getBlockState(context.getPos().offset(side)); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/ConfigureSequencedGearshiftPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/ConfigureSequencedGearshiftPacket.java new file mode 100644 index 000000000..6886b01d9 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/ConfigureSequencedGearshiftPacket.java @@ -0,0 +1,45 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.Vector; + +import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.util.Constants.NBT; + +public class ConfigureSequencedGearshiftPacket extends TileEntityConfigurationPacket { + + private ListNBT instructions; + + public ConfigureSequencedGearshiftPacket(BlockPos pos, Vector instructions) { + super(pos); + this.instructions = Instruction.serializeAll(instructions); + } + + public ConfigureSequencedGearshiftPacket(PacketBuffer buffer) { + super(buffer); + } + + @Override + protected void readSettings(PacketBuffer buffer) { + instructions = buffer.readCompoundTag().getList("data", NBT.TAG_COMPOUND); + } + + @Override + protected void writeSettings(PacketBuffer buffer) { + CompoundNBT tag = new CompoundNBT(); + tag.put("data", instructions); + buffer.writeCompoundTag(tag); + } + + @Override + protected void applySettings(SequencedGearshiftTileEntity te) { + te.run(-1); + te.instructions = Instruction.deserializeAll(instructions); + te.sendData(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/Instruction.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/Instruction.java new file mode 100644 index 000000000..1335ac686 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/Instruction.java @@ -0,0 +1,105 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.Vector; + +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; + +public class Instruction { + + SequencerInstructions instruction; + InstructionSpeedModifiers speedModifier; + int value; + + public Instruction(SequencerInstructions instruction) { + this(instruction, 1); + } + + public Instruction(SequencerInstructions instruction, int value) { + this.instruction = instruction; + speedModifier = InstructionSpeedModifiers.FORWARD; + this.value = value; + } + + int getDuration(float initialProgress, float speed) { + int offset = speed > 0 && speedModifier.value < 0 ? 1 : 2; + speed *= speedModifier.value; + speed = Math.abs(speed); + + double degreesPerTick = (speed * 360) / 60 / 20; + double metersPerTick = speed / 512; + switch (instruction) { + + case TURN_ANGLE: + return (int) ((1 - initialProgress) * value / degreesPerTick + 1); + + case TURN_DISTANCE: + return (int) ((1 - initialProgress) * value / metersPerTick + offset); + + case WAIT: + return (int) ((1 - initialProgress) * value + 1); + + case END: + default: + break; + + } + return 0; + } + + int getSpeedModifier() { + switch (instruction) { + + case TURN_ANGLE: + case TURN_DISTANCE: + return speedModifier.value; + + case END: + case WAIT: + default: + break; + + } + return 0; + } + + public static ListNBT serializeAll(Vector instructions) { + ListNBT list = new ListNBT(); + instructions.forEach(i -> list.add(i.serialize())); + return list; + } + + public static Vector deserializeAll(ListNBT list) { + if (list.isEmpty()) + return createDefault(); + Vector instructions = new Vector<>(5); + list.forEach(inbt -> instructions.add(deserialize((CompoundNBT) inbt))); + return instructions; + } + + public static Vector createDefault() { + Vector instructions = new Vector<>(5); + instructions.add(new Instruction(SequencerInstructions.TURN_ANGLE, 90)); + instructions.add(new Instruction(SequencerInstructions.END)); + return instructions; + } + + CompoundNBT serialize() { + CompoundNBT tag = new CompoundNBT(); + tag.putString("Type", NBTHelper.writeEnum(instruction)); + tag.putString("Modifier", NBTHelper.writeEnum(speedModifier)); + tag.putInt("Value", value); + return tag; + } + + static Instruction deserialize(CompoundNBT tag) { + Instruction instruction = + new Instruction(NBTHelper.readEnum(tag.getString("Type"), SequencerInstructions.class)); + instruction.speedModifier = NBTHelper.readEnum(tag.getString("Modifier"), InstructionSpeedModifiers.class); + instruction.value = tag.getInt("Value"); + return instruction; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java new file mode 100644 index 000000000..fae6ba089 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/InstructionSpeedModifiers.java @@ -0,0 +1,31 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.ArrayList; +import java.util.List; + +import com.simibubi.create.foundation.utility.Lang; + +public enum InstructionSpeedModifiers { + + FORWARD_FAST(2, ">>"), FORWARD(1, "->"), BACK(-1, "<-"), BACK_FAST(-2, "<<"), + + ; + + String translationKey; + int value; + String label; + + private InstructionSpeedModifiers(int modifier, String label) { + this.label = label; + translationKey = "gui.sequenced_gearshift.speed." + Lang.asId(name()); + value = modifier; + } + + static List getOptions() { + List options = new ArrayList<>(); + for (InstructionSpeedModifiers entry : values()) + options.add(Lang.translate(entry.translationKey)); + return options; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java new file mode 100644 index 000000000..2e3503b80 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java @@ -0,0 +1,139 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import com.simibubi.create.AllItems; +import com.simibubi.create.foundation.block.IWithTileEntity; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock; +import com.simibubi.create.modules.contraptions.base.KineticBlock; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.state.BooleanProperty; +import net.minecraft.state.IntegerProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +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.IWorldReader; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; + +public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock + implements IWithTileEntity { + + public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical"); + public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5); + + public SequencedGearshiftBlock() { + super(Properties.from(Blocks.ANDESITE)); + } + + @Override + protected void fillStateContainer(Builder builder) { + super.fillStateContainer(builder.add(STATE, VERTICAL)); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new SequencedGearshiftTileEntity(); + } + + @Override + public boolean shouldCheckWeakPower(BlockState state, IWorldReader world, BlockPos pos, Direction side) { + return false; + } + + @Override + public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, + boolean isMoving) { + if (worldIn.isRemote) + return; + + boolean previouslyPowered = state.get(STATE) != 0; + if (previouslyPowered != worldIn.isBlockPowered(pos)) + withTileEntityDo(worldIn, pos, SequencedGearshiftTileEntity::onRedstoneUpdate); + } + + @Override + public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { + if (state.get(VERTICAL)) + return face.getAxis().isVertical(); + return super.hasShaftTowards(world, pos, state, face); + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + ItemStack held = player.getHeldItemMainhand(); + if (AllItems.WRENCH.typeOf(held)) + return false; + if (held.getItem() instanceof BlockItem) { + BlockItem blockItem = (BlockItem) held.getItem(); + if (blockItem.getBlock() instanceof KineticBlock && hasShaftTowards(worldIn, pos, state, hit.getFace())) + return false; + } + + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { + displayScreen((SequencedGearshiftTileEntity) worldIn.getTileEntity(pos)); + }); + return true; + } + + @OnlyIn(value = Dist.CLIENT) + protected void displayScreen(SequencedGearshiftTileEntity te) { + ScreenOpener.open(new SequencedGearshiftScreen(te)); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + Axis preferredAxis = RotatedPillarKineticBlock.getPreferredAxis(context); + if (preferredAxis != null && !context.isPlacerSneaking()) + return withAxis(preferredAxis, context); + return withAxis(context.getNearestLookingDirection().getAxis(), context); + } + + @Override + public ActionResultType onWrenched(BlockState state, ItemUseContext context) { + Direction facing = context.getFace(); + if (facing.getAxis().isVertical() && !state.get(VERTICAL)) { + KineticTileEntity.switchToBlockState(context.getWorld(), context.getPos(), state.cycle(VERTICAL)); + return ActionResultType.SUCCESS; + } + return super.onWrenched(state, context); + } + + private BlockState withAxis(Axis axis, BlockItemUseContext context) { + BlockState state = getDefaultState().with(VERTICAL, axis.isVertical()); + if (axis.isVertical()) + return state.with(HORIZONTAL_AXIS, context.getPlacementHorizontalFacing().getAxis()); + return state.with(HORIZONTAL_AXIS, axis); + } + + @Override + public Axis getRotationAxis(BlockState state) { + if (state.get(VERTICAL)) + return Axis.Y; + return super.getRotationAxis(state); + } + + @Override + protected boolean hasStaticPart() { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java new file mode 100644 index 000000000..6ad295296 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java @@ -0,0 +1,195 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.Vector; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPackets; +import com.simibubi.create.ScreenResources; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.ScreenElementRenderer; +import com.simibubi.create.foundation.gui.widgets.ScrollInput; +import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; + +public class SequencedGearshiftScreen extends AbstractSimiScreen { + + private static final ItemStack renderedItem = new ItemStack(AllBlocks.SEQUENCED_GEARSHIFT.get()); + private static final ScreenResources background = ScreenResources.SEQUENCER; + + private final String title = Lang.translate("gui.sequenced_gearshift.title"); + private int lastModification; + private Vector instructions; + private BlockPos pos; + + private Vector> inputs; + + public SequencedGearshiftScreen(SequencedGearshiftTileEntity te) { + this.instructions = te.instructions; + this.pos = te.getPos(); + lastModification = -1; + } + + @Override + protected void init() { + setWindowSize(background.width + 50, background.height); + super.init(); + widgets.clear(); + + inputs = new Vector<>(5); + for (int row = 0; row < inputs.capacity(); row++) + inputs.add(new Vector<>(3)); + + for (int row = 0; row < instructions.size(); row++) + initInputsOfRow(row); + } + + public void initInputsOfRow(int row) { + int x = guiLeft + 28; + int y = guiTop + 29; + int rowHeight = 18; + + Vector rowInputs = inputs.get(row); + rowInputs.forEach(widgets::remove); + rowInputs.clear(); + int index = row; + Instruction instruction = instructions.get(row); + + ScrollInput type = + new SelectionScrollInput(x, y + rowHeight * row, 50, 14).forOptions(SequencerInstructions.getOptions()) + .calling(state -> instructionUpdated(index, state)).setState(instruction.instruction.ordinal()) + .titled(Lang.translate("gui.sequenced_gearshift.instruction")); + ScrollInput value = + new ScrollInput(x + 54, y + rowHeight * row, 30, 14).calling(state -> instruction.value = state); + ScrollInput direction = new SelectionScrollInput(x + 88, y + rowHeight * row, 18, 14) + .forOptions(InstructionSpeedModifiers.getOptions()) + .calling(state -> instruction.speedModifier = InstructionSpeedModifiers.values()[state]) + .titled(Lang.translate("gui.sequenced_gearshift.speed")); + + rowInputs.add(type); + rowInputs.add(value); + rowInputs.add(direction); + + widgets.addAll(rowInputs); + updateParamsOfRow(row); + } + + public void updateParamsOfRow(int row) { + Instruction instruction = instructions.get(row); + Vector rowInputs = inputs.get(row); + SequencerInstructions def = instruction.instruction; + boolean hasValue = def.hasValueParameter; + boolean hasModifier = def.hasSpeedParameter; + + ScrollInput value = rowInputs.get(1); + value.active = value.visible = hasValue; + if (hasValue) + value.withRange(1, def.maxValue + 1).titled(Lang.translate(def.parameterKey)).withShiftStep(def.shiftStep) + .setState(instruction.value).onChanged(); + if (def == SequencerInstructions.WAIT) { + value.withStepFunction(context -> { + int v = context.currentValue; + if (!context.forward) + v--; + if (v < 20) + return context.shift ? 20 : 1; + return context.shift ? 100 : 20; + }); + } else + value.withStepFunction(value.standardStep()); + + ScrollInput modifier = rowInputs.get(2); + modifier.active = modifier.visible = hasModifier; + if (hasModifier) + modifier.setState(instruction.speedModifier.ordinal()); + } + + @Override + protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + int hFontColor = 0xD3CBBE; + background.draw(this, guiLeft, guiTop); + + for (int row = 0; row < instructions.capacity(); row++) { + ScreenResources toDraw = ScreenResources.SEQUENCER_EMPTY; + int yOffset = toDraw.height * row; + + if (row < instructions.size()) { + Instruction instruction = instructions.get(row); + SequencerInstructions def = instruction.instruction; + def.background.draw(guiLeft + 14, guiTop + 29 + yOffset); + + label(32, 6 + yOffset, Lang.translate(def.translationKey)); + if (def.hasValueParameter) { + String text = def.formatValue(instruction.value); + int stringWidth = font.getStringWidth(text); + label(85 + (12 - stringWidth / 2), 6 + yOffset, text); + } + if (def.hasSpeedParameter) + label(120, 6 + yOffset, instruction.speedModifier.label); + + continue; + } + + toDraw.draw(guiLeft + 14, guiTop + 29 + yOffset); + } + + font.drawStringWithShadow(title, guiLeft - 3 + (background.width - font.getStringWidth(title)) / 2, guiTop + 10, + hFontColor); + ScreenElementRenderer.render3DItem(this::getRenderedBlock); + } + + private void label(int x, int y, String text) { + font.drawStringWithShadow(text, guiLeft + x, guiTop + 26 + y, 0xFFFFEE); + } + + @Override + public void tick() { + super.tick(); + + if (lastModification >= 0) + lastModification++; + + if (lastModification >= 20) { + lastModification = -1; + sendPacket(); + } + } + + public void sendPacket() { + AllPackets.channel.sendToServer(new ConfigureSequencedGearshiftPacket(pos, instructions)); + } + + @Override + public void removed() { + sendPacket(); + } + + public ItemStack getRenderedBlock() { + GlStateManager.translated(guiLeft + background.width + 20, guiTop + 50, 0); + GlStateManager.scaled(5, 5, 5); + return renderedItem; + } + + private void instructionUpdated(int index, int state) { + SequencerInstructions newValue = SequencerInstructions.values()[state]; + instructions.get(index).instruction = newValue; + updateParamsOfRow(index); + if (newValue == SequencerInstructions.END) { + for (int i = instructions.size() - 1; i > index; i--) { + instructions.remove(i); + Vector rowInputs = inputs.get(i); + rowInputs.forEach(widgets::remove); + rowInputs.clear(); + } + } else { + if (index + 1 < instructions.capacity() && index + 1 == instructions.size()) { + instructions.add(new Instruction(SequencerInstructions.END)); + initInputsOfRow(index + 1); + } + } + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java new file mode 100644 index 000000000..b50f20dbd --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftTileEntity.java @@ -0,0 +1,128 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.Vector; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.modules.contraptions.relays.encased.SplitShaftTileEntity; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Direction; +import net.minecraftforge.common.util.Constants.NBT; + +public class SequencedGearshiftTileEntity extends SplitShaftTileEntity { + + Vector instructions; + int currentInstruction; + int currentInstructionDuration; + int timer; + + public SequencedGearshiftTileEntity() { + super(AllTileEntities.SEQUENCED_GEARSHIFT.type); + instructions = Instruction.createDefault(); + currentInstruction = -1; + currentInstructionDuration = -1; + timer = 0; + } + + @Override + public void tick() { + super.tick(); + + if (isIdle()) + return; + if (world.isRemote) + return; + if (timer < currentInstructionDuration) { + timer++; + return; + } + run(currentInstruction + 1); + } + + @Override + public void onSpeedChanged(float previousSpeed) { + super.onSpeedChanged(previousSpeed); + if (isIdle()) + return; + float currentSpeed = Math.abs(speed); + if (Math.abs(previousSpeed) == currentSpeed) + return; + Instruction instruction = getInstruction(currentInstruction); + if (instruction == null) + return; + + // Update instruction time with regards to new speed + float initialProgress = timer / (float) currentInstructionDuration; + currentInstructionDuration = instruction.getDuration(initialProgress, getTheoreticalSpeed()); + timer = 0; + } + + public boolean isIdle() { + return currentInstruction == -1; + } + + public void onRedstoneUpdate() { + if (!isIdle()) + return; + if (!world.isBlockPowered(pos)) { + world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, 0), 3); + return; + } + run(0); + } + + protected void run(int instructionIndex) { + Instruction instruction = getInstruction(instructionIndex); + if (instruction == null || instruction.instruction == SequencerInstructions.END) { + if (getModifier() != 0) + detachKinetics(); + currentInstruction = -1; + currentInstructionDuration = -1; + timer = 0; + if (!world.isBlockPowered(pos)) + world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, 0), 3); + else + sendData(); + return; + } + + detachKinetics(); + currentInstructionDuration = instruction.getDuration(0, getTheoreticalSpeed()); + currentInstruction = instructionIndex; + timer = 0; + world.setBlockState(pos, getBlockState().with(SequencedGearshiftBlock.STATE, instructionIndex + 1), 3); + } + + public Instruction getInstruction(int instructionIndex) { + return instructionIndex >= 0 && instructionIndex < instructions.size() ? instructions.get(instructionIndex) + : null; + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.putInt("InstructionIndex", currentInstruction); + compound.putInt("InstructionDuration", currentInstructionDuration); + compound.putInt("Timer", timer); + compound.put("Instructions", Instruction.serializeAll(instructions)); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + currentInstruction = compound.getInt("InstructionIndex"); + currentInstructionDuration = compound.getInt("InstructionDuration"); + timer = compound.getInt("Timer"); + instructions = Instruction.deserializeAll(compound.getList("Instructions", NBT.TAG_COMPOUND)); + super.read(compound); + } + + @Override + public float getRotationSpeedModifier(Direction face) { + return (!hasSource() || face == getSourceFacing()) ? 1 : getModifier(); + } + + public int getModifier() { + return isIdle() ? 0 : instructions.get(currentInstruction).getSpeedModifier(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencerInstructions.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencerInstructions.java new file mode 100644 index 000000000..09278a04f --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencerInstructions.java @@ -0,0 +1,61 @@ +package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; + +import java.util.ArrayList; +import java.util.List; + +import com.simibubi.create.ScreenResources; +import com.simibubi.create.foundation.utility.Lang; + +public enum SequencerInstructions { + + TURN_ANGLE("angle", ScreenResources.SEQUENCER_INSTRUCTION, true, true, 360, 45), + TURN_DISTANCE("distance", ScreenResources.SEQUENCER_INSTRUCTION, true, true, 50, 5), + WAIT("duration", ScreenResources.SEQUENCER_WAIT, true, false, 600, 20), + END("", ScreenResources.SEQUENCER_END), + + ; + + String translationKey; + String parameterKey; + boolean hasValueParameter; + boolean hasSpeedParameter; + ScreenResources background; + int maxValue; + int shiftStep; + + private SequencerInstructions(String parameterName, ScreenResources background) { + this(parameterName, background, false, false, -1, -1); + } + + private SequencerInstructions(String parameterName, ScreenResources background, boolean hasValueParameter, + boolean hasSpeedParameter, int maxValue, int shiftStep) { + this.hasValueParameter = hasValueParameter; + this.hasSpeedParameter = hasSpeedParameter; + this.background = background; + this.maxValue = maxValue; + this.shiftStep = shiftStep; + translationKey = "gui.sequenced_gearshift.instruction." + Lang.asId(name()); + parameterKey = translationKey + "." + parameterName; + } + + static List getOptions() { + List options = new ArrayList<>(); + for (SequencerInstructions entry : values()) + options.add(Lang.translate(entry.translationKey)); + return options; + } + + String formatValue(int value) { + if (this == TURN_ANGLE) + return value + "°"; + if (this == TURN_DISTANCE) + return value + "m"; + if (this == WAIT) { + if (value >= 20) + return (value / 20) + "s"; + return value + "t"; + } + return "" + value; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java index b07e5aef8..3259bf037 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java @@ -153,8 +153,13 @@ public class BeltBlock extends HorizontalKineticBlock if (state.get(SLOPE) == Slope.VERTICAL) return; - if (entityIn instanceof PlayerEntity && entityIn.isSneaking()) - return; + if (entityIn instanceof PlayerEntity) { + PlayerEntity player = (PlayerEntity) entityIn; + if (player.isSneaking()) + return; + if (player.abilities.isFlying) + return; + } if (belt == null || belt.getSpeed() == 0) return; if (entityIn instanceof ItemEntity && entityIn.isAlive()) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java index 2aac23aad..3189c5e70 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java @@ -7,6 +7,7 @@ import static net.minecraft.util.Direction.AxisDirection.POSITIVE; import java.util.List; import com.simibubi.create.AllBlocks; +import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; @@ -14,6 +15,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.item.HangingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.potion.EffectInstance; import net.minecraft.potion.Effects; @@ -150,7 +152,7 @@ public class BeltMovementHandler { checkBB = checkBB.offset(checkDistance).grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z)); List list = world.getEntitiesWithinAABBExcludingEntity(entityIn, checkBB); - list.removeIf(e -> entityIn.isRidingOrBeingRiddenBy(e)); + list.removeIf(e -> shouldIgnoreBlocking(entityIn, e)); if (!list.isEmpty()) { entityIn.setMotion(0, 0, 0); info.ticksSinceLastCollision--; @@ -186,4 +188,12 @@ public class BeltMovementHandler { } } + public static boolean shouldIgnoreBlocking(Entity me, Entity other) { + if (other instanceof ContraptionEntity) + return true; + if (other instanceof HangingEntity) + return true; + return me.isRidingOrBeingRiddenBy(other); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntityRenderer.java index e2995ce43..4788aca94 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/encased/SplitShaftTileEntityRenderer.java @@ -3,11 +3,12 @@ package com.simibubi.create.modules.contraptions.relays.encased; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.SuperByteBuffer; +import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import net.minecraft.block.Block; import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; @@ -15,9 +16,10 @@ import net.minecraft.util.math.BlockPos; public class SplitShaftTileEntityRenderer extends KineticTileEntityRenderer { @Override - public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, - int destroyStage, BufferBuilder buffer) { - final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); + public void renderFast(KineticTileEntity te, double x, double y, double z, float partialTicks, int destroyStage, + BufferBuilder buffer) { + Block block = te.getBlockState().getBlock(); + final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState()); final BlockPos pos = te.getPos(); float time = AnimationTickHolder.getRenderTick(); @@ -37,8 +39,8 @@ public class SplitShaftTileEntityRenderer extends KineticTileEntityRenderer { angle += offset; angle = angle / 180f * (float) Math.PI; - SuperByteBuffer superByteBuffer = AllBlockPartials.SHAFT_HALF.renderOnDirectional(te.getBlockState(), - direction); + SuperByteBuffer superByteBuffer = + AllBlockPartials.SHAFT_HALF.renderOnDirectional(te.getBlockState(), direction); kineticRotationTransform(superByteBuffer, te, axis, angle, getWorld()); superByteBuffer.translate(x, y, z).renderInto(buffer); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java index 7a9a01693..a55bc7fcb 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java @@ -60,7 +60,8 @@ public class RedstoneLinkTileEntity extends SmartTileEntity { public void transmit(boolean signal) { transmittedSignal = signal; - link.notifySignalChange(); + if (link != null) + link.notifySignalChange(); } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java index 05ede33a1..df07b31e1 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java @@ -14,6 +14,7 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.MathHelper; public class FlexpeaterTileEntity extends SmartTileEntity { @@ -36,8 +37,15 @@ public class FlexpeaterTileEntity extends SmartTileEntity { maxState.withStepFunction(this::step); maxState.withFormatter(this::format); maxState.withUnit(this::getUnit); + maxState.withCallback(this::onMaxDelayChanged); + behaviours.add(maxState); } + + private void onMaxDelayChanged(int newMax) { + state = MathHelper.clamp(state, 0, newMax); + sendData(); + } @Override public void read(CompoundNBT compound) { diff --git a/src/main/resources/assets/create/blockstates/sequenced_gearshift.json b/src/main/resources/assets/create/blockstates/sequenced_gearshift.json new file mode 100644 index 000000000..17c2890c1 --- /dev/null +++ b/src/main/resources/assets/create/blockstates/sequenced_gearshift.json @@ -0,0 +1,31 @@ +{ + "variants": { + "vertical=false,axis=x,state=0" : { "model": "create:block/sequenced_gearshift/idle", "y": 90 }, + "vertical=false,axis=x,state=1" : { "model": "create:block/sequenced_gearshift/seq_1", "y": 90 }, + "vertical=false,axis=x,state=2" : { "model": "create:block/sequenced_gearshift/seq_2", "y": 90 }, + "vertical=false,axis=x,state=3" : { "model": "create:block/sequenced_gearshift/seq_3", "y": 90 }, + "vertical=false,axis=x,state=4" : { "model": "create:block/sequenced_gearshift/seq_4", "y": 90 }, + "vertical=false,axis=x,state=5" : { "model": "create:block/sequenced_gearshift/seq_5", "y": 90 }, + + "vertical=false,axis=z,state=0" : { "model": "create:block/sequenced_gearshift/idle" }, + "vertical=false,axis=z,state=1" : { "model": "create:block/sequenced_gearshift/seq_1" }, + "vertical=false,axis=z,state=2" : { "model": "create:block/sequenced_gearshift/seq_2" }, + "vertical=false,axis=z,state=3" : { "model": "create:block/sequenced_gearshift/seq_3" }, + "vertical=false,axis=z,state=4" : { "model": "create:block/sequenced_gearshift/seq_4" }, + "vertical=false,axis=z,state=5" : { "model": "create:block/sequenced_gearshift/seq_5" }, + + "vertical=true,axis=x,state=0" : { "model": "create:block/sequenced_gearshift/idle", "x": 90, "y": 90 }, + "vertical=true,axis=x,state=1" : { "model": "create:block/sequenced_gearshift/seq_1", "x": 90, "y": 90 }, + "vertical=true,axis=x,state=2" : { "model": "create:block/sequenced_gearshift/seq_2", "x": 90, "y": 90 }, + "vertical=true,axis=x,state=3" : { "model": "create:block/sequenced_gearshift/seq_3", "x": 90, "y": 90 }, + "vertical=true,axis=x,state=4" : { "model": "create:block/sequenced_gearshift/seq_4", "x": 90, "y": 90 }, + "vertical=true,axis=x,state=5" : { "model": "create:block/sequenced_gearshift/seq_5", "x": 90, "y": 90 }, + + "vertical=true,axis=z,state=0" : { "model": "create:block/sequenced_gearshift/idle", "x": 90 }, + "vertical=true,axis=z,state=1" : { "model": "create:block/sequenced_gearshift/seq_1", "x": 90 }, + "vertical=true,axis=z,state=2" : { "model": "create:block/sequenced_gearshift/seq_2", "x": 90 }, + "vertical=true,axis=z,state=3" : { "model": "create:block/sequenced_gearshift/seq_3", "x": 90 }, + "vertical=true,axis=z,state=4" : { "model": "create:block/sequenced_gearshift/seq_4", "x": 90 }, + "vertical=true,axis=z,state=5" : { "model": "create:block/sequenced_gearshift/seq_5", "x": 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 f6d638ee5..f93eff1e6 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -151,6 +151,7 @@ "block.create.logisticians_table": "Logisticians Table", "block.create.package_funnel": "Package Funnel", "block.create.belt_tunnel": "Conveyor Tunnel", + "block.create.sequenced_gearshift": "Sequenced Gearshift", "block.create.tiled_glass": "Tiled Glass", "block.create.framed_glass": "Large Glass Window", @@ -421,6 +422,21 @@ "create.gui.stockswitch.startAbove": "Start Signal above", "create.gui.stockswitch.stopAt": "Stop Signal at", "create.gui.stockswitch.stopBelow": "Stop Signal below", + + "create.gui.sequenced_gearshift.title": "Sequenced Gearshift", + "create.gui.sequenced_gearshift.instruction": "Instruction", + "create.gui.sequenced_gearshift.instruction.turn_angle": "Turn", + "create.gui.sequenced_gearshift.instruction.turn_angle.angle": "Angle", + "create.gui.sequenced_gearshift.instruction.turn_distance": "Piston", + "create.gui.sequenced_gearshift.instruction.turn_distance.distance": "Distance", + "create.gui.sequenced_gearshift.instruction.wait": "Wait", + "create.gui.sequenced_gearshift.instruction.wait.duration": "Duration", + "create.gui.sequenced_gearshift.instruction.end": "End", + "create.gui.sequenced_gearshift.speed": "Speed, Direction", + "create.gui.sequenced_gearshift.speed.forward": "Input speed, Forwards", + "create.gui.sequenced_gearshift.speed.forward_fast": "Double speed, Forwards", + "create.gui.sequenced_gearshift.speed.back": "Input speed, Reversed", + "create.gui.sequenced_gearshift.speed.back_fast": "Double speed, Reversed", "create.schematicAndQuill.dimensions": "Schematic Size: %1$sx%2$sx%3$s", "create.schematicAndQuill.firstPos": "First position set.", diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/idle.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/idle.json new file mode 100644 index 000000000..25b73b6ec --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/idle.json @@ -0,0 +1,110 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/brass_casing", + "1": "create:block/brass_gearbox", + "4": "create:block/sequenced_gearshift", + "particle": "create:block/brass_gearbox" + }, + "elements": [ + { + "name": "Core", + "from": [1, 1, 1], + "to": [15, 15, 15], + "faces": { + "north": {"uv": [1, 1, 15, 15], "texture": "#1"}, + "south": {"uv": [1, 1, 15, 15], "texture": "#1"}, + "up": {"uv": [1, 1, 15, 15], "texture": "#4"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#4"} + } + }, + { + "name": "Top", + "from": [0, 14, 0], + "to": [5, 16, 16], + "faces": { + "north": {"uv": [11, 0, 16, 2], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 16], "rotation": 90, "texture": "#4"}, + "south": {"uv": [0, 0, 5, 2], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 16], "rotation": 270, "texture": "#4"}, + "up": {"uv": [0, 0, 5, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + }, + { + "name": "Bottom", + "from": [0, 0, 0], + "to": [5, 2, 16], + "faces": { + "north": {"uv": [11, 14, 16, 16], "texture": "#0"}, + "east": {"uv": [2, 0, 0, 16], "rotation": 90, "texture": "#4"}, + "south": {"uv": [0, 14, 5, 16], "texture": "#0"}, + "west": {"uv": [2, 0, 0, 16], "rotation": 90, "texture": "#4"}, + "up": {"uv": [0, 16, 16, 0], "texture": "#0"}, + "down": {"uv": [0, 16, 5, 0], "texture": "#4"} + } + }, + { + "name": "Top", + "from": [11, 14, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [16, 0, 11, 2], "texture": "#0"}, + "east": {"uv": [0, 16, 2, 0], "rotation": 90, "texture": "#4"}, + "south": {"uv": [5, 0, 0, 2], "texture": "#0"}, + "west": {"uv": [0, 16, 2, 0], "rotation": 90, "texture": "#4"}, + "up": {"uv": [11, 0, 16, 16], "texture": "#4"}, + "down": {"uv": [16, 0, 0, 16], "texture": "#0"} + } + }, + { + "name": "Bottom", + "from": [11, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 14, 5, 16], "texture": "#0"}, + "east": {"uv": [2, 16, 0, 0], "rotation": 90, "texture": "#4"}, + "south": {"uv": [11, 14, 16, 16], "texture": "#0"}, + "west": {"uv": [2, 16, 0, 0], "rotation": 90, "texture": "#4"}, + "up": {"uv": [16, 16, 0, 0], "texture": "#0"}, + "down": {"uv": [11, 16, 16, 0], "texture": "#4"} + } + }, + { + "name": "SideWest", + "from": [0, 2, 0], + "to": [2, 14, 16], + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#0"}, + "east": {"uv": [0, 2, 16, 14], "texture": "#0"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#0"}, + "west": {"uv": [0, 2, 16, 14], "texture": "#0"} + } + }, + { + "name": "SideEast", + "from": [14, 2, 0], + "to": [16, 14, 16], + "faces": { + "north": {"uv": [0, 2, 2, 14], "texture": "#0"}, + "east": {"uv": [0, 2, 16, 14], "texture": "#0"}, + "south": {"uv": [14, 2, 16, 14], "texture": "#0"}, + "west": {"uv": [0, 2, 16, 14], "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "encased_shaft", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4, 5, 6, + { + "name": "shaft", + "origin": [8, 8, 8], + "children": [] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_1.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_1.json new file mode 100644 index 000000000..d9500154c --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_1.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/sequenced_gearshift/idle", + "textures": { + "4": "create:block/sequenced_gearshift_1" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_2.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_2.json new file mode 100644 index 000000000..3b3464707 --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_2.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/sequenced_gearshift/idle", + "textures": { + "4": "create:block/sequenced_gearshift_2" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_3.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_3.json new file mode 100644 index 000000000..5f65339f1 --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_3.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/sequenced_gearshift/idle", + "textures": { + "4": "create:block/sequenced_gearshift_3" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_4.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_4.json new file mode 100644 index 000000000..11d2776ad --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_4.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/sequenced_gearshift/idle", + "textures": { + "4": "create:block/sequenced_gearshift_4" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_5.json b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_5.json new file mode 100644 index 000000000..cbd98c912 --- /dev/null +++ b/src/main/resources/assets/create/models/block/sequenced_gearshift/seq_5.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/sequenced_gearshift/idle", + "textures": { + "4": "create:block/sequenced_gearshift_5" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/sequenced_gearshift.json b/src/main/resources/assets/create/models/item/sequenced_gearshift.json new file mode 100644 index 000000000..b87b557db --- /dev/null +++ b/src/main/resources/assets/create/models/item/sequenced_gearshift.json @@ -0,0 +1,125 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/brass_casing", + "1": "create:block/brass_gearbox", + "4": "create:block/sequenced_gearshift", + "particle": "create:block/axis", + "1_0": "create:block/axis", + "1_1": "create:block/axis_top" + }, + "elements": [ + { + "name": "Core", + "from": [1, 1, 1], + "to": [15, 15, 15], + "faces": { + "north": {"uv": [1, 1, 15, 15], "texture": "#1"}, + "south": {"uv": [1, 1, 15, 15], "texture": "#1"}, + "up": {"uv": [1, 1, 15, 15], "texture": "#4"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#4"} + } + }, + { + "name": "Top", + "from": [0, 14, 0], + "to": [5, 16, 16], + "faces": { + "north": {"uv": [11, 0, 16, 2], "texture": "#0"}, + "east": {"uv": [0, 0, 2, 16], "rotation": 90, "texture": "#4"}, + "south": {"uv": [0, 0, 5, 2], "texture": "#0"}, + "west": {"uv": [0, 0, 2, 16], "rotation": 270, "texture": "#4"}, + "up": {"uv": [0, 0, 5, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + }, + { + "name": "Bottom", + "from": [0, 0, 0], + "to": [5, 2, 16], + "faces": { + "north": {"uv": [11, 14, 16, 16], "texture": "#0"}, + "east": {"uv": [2, 0, 0, 16], "rotation": 90, "texture": "#4"}, + "south": {"uv": [0, 14, 5, 16], "texture": "#0"}, + "west": {"uv": [2, 0, 0, 16], "rotation": 90, "texture": "#4"}, + "up": {"uv": [0, 16, 16, 0], "texture": "#0"}, + "down": {"uv": [0, 16, 5, 0], "texture": "#4"} + } + }, + { + "name": "Top", + "from": [11, 14, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [16, 0, 11, 2], "texture": "#0"}, + "east": {"uv": [0, 16, 2, 0], "rotation": 90, "texture": "#4"}, + "south": {"uv": [5, 0, 0, 2], "texture": "#0"}, + "west": {"uv": [0, 16, 2, 0], "rotation": 90, "texture": "#4"}, + "up": {"uv": [11, 0, 16, 16], "texture": "#4"}, + "down": {"uv": [16, 0, 0, 16], "texture": "#0"} + } + }, + { + "name": "Bottom", + "from": [11, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 14, 5, 16], "texture": "#0"}, + "east": {"uv": [2, 16, 0, 0], "rotation": 90, "texture": "#4"}, + "south": {"uv": [11, 14, 16, 16], "texture": "#0"}, + "west": {"uv": [2, 16, 0, 0], "rotation": 90, "texture": "#4"}, + "up": {"uv": [16, 16, 0, 0], "texture": "#0"}, + "down": {"uv": [11, 16, 16, 0], "texture": "#4"} + } + }, + { + "name": "SideWest", + "from": [0, 2, 0], + "to": [2, 14, 16], + "faces": { + "north": {"uv": [14, 2, 16, 14], "texture": "#0"}, + "east": {"uv": [0, 2, 16, 14], "texture": "#0"}, + "south": {"uv": [0, 2, 2, 14], "texture": "#0"}, + "west": {"uv": [0, 2, 16, 14], "texture": "#0"} + } + }, + { + "name": "SideEast", + "from": [14, 2, 0], + "to": [16, 14, 16], + "faces": { + "north": {"uv": [0, 2, 2, 14], "texture": "#0"}, + "east": {"uv": [0, 2, 16, 14], "texture": "#0"}, + "south": {"uv": [14, 2, 16, 14], "texture": "#0"}, + "west": {"uv": [0, 2, 16, 14], "texture": "#0"} + } + }, + { + "name": "Axis", + "from": [6, 6, 0], + "to": [10, 10, 16], + "faces": { + "north": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#1_1"}, + "east": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#1_0"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#1_1"}, + "west": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#1_0"}, + "up": {"uv": [6, 0, 10, 16], "texture": "#1_0"}, + "down": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#1_0"} + } + } + ], + "groups": [ + { + "name": "encased_shaft", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4, 5, 6, + { + "name": "shaft", + "origin": [8, 8, 8], + "children": [7] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift.png new file mode 100644 index 000000000..cb48df541 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift.png differ diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift_1.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift_1.png new file mode 100644 index 000000000..972947432 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift_1.png differ diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift_2.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift_2.png new file mode 100644 index 000000000..0de7980a4 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift_2.png differ diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift_3.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift_3.png new file mode 100644 index 000000000..5e43c4250 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift_3.png differ diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift_4.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift_4.png new file mode 100644 index 000000000..e0ede7442 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift_4.png differ diff --git a/src/main/resources/assets/create/textures/block/sequenced_gearshift_5.png b/src/main/resources/assets/create/textures/block/sequenced_gearshift_5.png new file mode 100644 index 000000000..af1890182 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/sequenced_gearshift_5.png differ diff --git a/src/main/resources/assets/create/textures/gui/sequencer.png b/src/main/resources/assets/create/textures/gui/sequencer.png new file mode 100644 index 000000000..13a8cbd33 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/sequencer.png differ diff --git a/src/main/resources/data/create/loot_tables/blocks/sequenced_gearshift.json b/src/main/resources/data/create/loot_tables/blocks/sequenced_gearshift.json new file mode 100644 index 000000000..ee60996d2 --- /dev/null +++ b/src/main/resources/data/create/loot_tables/blocks/sequenced_gearshift.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:sequenced_gearshift" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/crafting_shaped/contraptions/sequenced_gearshift.json b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/sequenced_gearshift.json new file mode 100644 index 000000000..20d3df096 --- /dev/null +++ b/src/main/resources/data/create/recipes/crafting_shaped/contraptions/sequenced_gearshift.json @@ -0,0 +1,33 @@ +{ + "type": "crafting_shaped", + "type": "crafting_shaped", + "pattern": [ + " B ", + "SCS", + " I " + ], + "key": { + "S": { + "item": "create:cogwheel" + }, + "B": { + "item": "create:electron_tube" + }, + "C": { + "item": "create:brass_casing" + }, + "I": { + "item": "minecraft:clock" + } + }, + "result": { + "item": "create:sequenced_gearshift", + "count": 1 + }, + "conditions": [ + { + "type": "create:module", + "module": "contraptions" + } + ] +} \ No newline at end of file