Sequenced Gearshift

- Added Sequenced Gearshifts
- Fixed custom swords breaking blocks when held in creative mode
- Fixed belts cancelling flight when touched
- Fixed Entities being blocked by contraption boundaries when moved on belts
- Fixed Flexpeater going funky when edited while active
- Fixed Links not firing when placed into a powered location
This commit is contained in:
simibubi 2020-03-11 21:40:55 +01:00
parent 8c793b8d28
commit 14e053fafd
39 changed files with 1155 additions and 29 deletions

View File

@ -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()),

View File

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

View File

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

View File

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

View File

@ -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<StepContext, Integer> 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<StepContext, Integer> 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<StepContext, Integer> 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;
}

View File

@ -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<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
public void modifyDrops(final Collection<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool,
BlockState state) {
}
public void spawnParticles(IWorld world, BlockPos pos, ItemStack tool, BlockState state) {

View File

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

View File

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

View File

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

View File

@ -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<SequencedGearshiftTileEntity> {
private ListNBT instructions;
public ConfigureSequencedGearshiftPacket(BlockPos pos, Vector<Instruction> 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();
}
}

View File

@ -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<Instruction> instructions) {
ListNBT list = new ListNBT();
instructions.forEach(i -> list.add(i.serialize()));
return list;
}
public static Vector<Instruction> deserializeAll(ListNBT list) {
if (list.isEmpty())
return createDefault();
Vector<Instruction> instructions = new Vector<>(5);
list.forEach(inbt -> instructions.add(deserialize((CompoundNBT) inbt)));
return instructions;
}
public static Vector<Instruction> createDefault() {
Vector<Instruction> 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;
}
}

View File

@ -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<String> getOptions() {
List<String> options = new ArrayList<>();
for (InstructionSpeedModifiers entry : values())
options.add(Lang.translate(entry.translationKey));
return options;
}
}

View File

@ -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<SequencedGearshiftTileEntity> {
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<Block, BlockState> 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;
}
}

View File

@ -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<Instruction> instructions;
private BlockPos pos;
private Vector<Vector<ScrollInput>> 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<ScrollInput> 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<ScrollInput> 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<ScrollInput> 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);
}
}
}
}

View File

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

View File

@ -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<String> getOptions() {
List<String> 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;
}
}

View File

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

View File

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

View File

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

View File

@ -60,7 +60,8 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
public void transmit(boolean signal) {
transmittedSignal = signal;
link.notifySignalChange();
if (link != null)
link.notifySignalChange();
}
@Override

View File

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

View File

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

View File

@ -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.",

View File

@ -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": []
}
]
}
]
}

View File

@ -0,0 +1,6 @@
{
"parent": "create:block/sequenced_gearshift/idle",
"textures": {
"4": "create:block/sequenced_gearshift_1"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "create:block/sequenced_gearshift/idle",
"textures": {
"4": "create:block/sequenced_gearshift_2"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "create:block/sequenced_gearshift/idle",
"textures": {
"4": "create:block/sequenced_gearshift_3"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "create:block/sequenced_gearshift/idle",
"textures": {
"4": "create:block/sequenced_gearshift_4"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "create:block/sequenced_gearshift/idle",
"textures": {
"4": "create:block/sequenced_gearshift_5"
}
}

View File

@ -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]
}
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "create:sequenced_gearshift"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@ -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"
}
]
}