Better Pistons Part I

- Started work on cascading chassis and better block models
This commit is contained in:
simibubi 2019-10-18 13:14:03 +02:00
parent 98f568f887
commit 835a4a638b
18 changed files with 734 additions and 298 deletions

View file

@ -20,7 +20,7 @@ archivesBaseName = 'create'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft { minecraft {
mappings channel: 'snapshot', version: '20191008-1.14.3' mappings channel: 'snapshot', version: '20191016-1.14.3'
runs { runs {
client { client {
@ -71,12 +71,12 @@ repositories {
} }
dependencies { dependencies {
minecraft 'net.minecraftforge:forge:1.14.4-28.1.40' minecraft 'net.minecraftforge:forge:1.14.4-28.1.56'
// compile against the JEI API but do not include it at runtime // compile against the JEI API but do not include it at runtime
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api") compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api")
// at runtime, use the full JEI jar // at runtime, use the full JEI jar
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.13") runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10")
} }
jar { jar {

View file

@ -115,6 +115,7 @@ public enum AllBlocks {
MECHANICAL_BEARING(new MechanicalBearingBlock()), MECHANICAL_BEARING(new MechanicalBearingBlock()),
MECHANICAL_BEARING_TOP(new ShaftHalfBlock()), MECHANICAL_BEARING_TOP(new ShaftHalfBlock()),
TRANSLATION_CHASSIS(new TranslationChassisBlock()), TRANSLATION_CHASSIS(new TranslationChassisBlock()),
TRANSLATION_CHASSIS_SECONDARY(new TranslationChassisBlock()),
ROTATION_CHASSIS(new RotationChassisBlock()), ROTATION_CHASSIS(new RotationChassisBlock()),
DRILL(new DrillBlock()), DRILL(new DrillBlock()),
HARVESTER(new HarvesterBlock()), HARVESTER(new HarvesterBlock()),

View file

@ -91,7 +91,11 @@ public enum AllTileEntities {
BELT(BeltTileEntity::new, AllBlocks.BELT), BELT(BeltTileEntity::new, AllBlocks.BELT),
MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON), MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON),
MECHANICAL_BEARING(MechanicalBearingTileEntity::new, AllBlocks.MECHANICAL_BEARING), MECHANICAL_BEARING(MechanicalBearingTileEntity::new, AllBlocks.MECHANICAL_BEARING),
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), DRILL(DrillTileEntity::new, AllBlocks.DRILL),
CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL), CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL),
CRUSHING_WHEEL_CONTROLLER(CrushingWheelControllerTileEntity::new, AllBlocks.CRUSHING_WHEEL_CONTROLLER), CRUSHING_WHEEL_CONTROLLER(CrushingWheelControllerTileEntity::new, AllBlocks.CRUSHING_WHEEL_CONTROLLER),
@ -130,7 +134,7 @@ public enum AllTileEntities {
this.supplier = supplier; this.supplier = supplier;
this.blocks = blocks; this.blocks = blocks;
} }
public boolean typeOf(TileEntity te) { public boolean typeOf(TileEntity te) {
return te.getType().equals(type); return te.getType().equals(type);
} }

View file

@ -0,0 +1,57 @@
package com.simibubi.create.foundation.utility;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.VoxelShape;
public class VoxelShaper {
private Map<Direction, VoxelShape> shapes;
public VoxelShape get(Direction direction) {
return shapes.get(direction);
}
public static VoxelShaper forHorizontalBlock(VoxelShape southShape) {
VoxelShaper voxelShaper = new VoxelShaper();
for (Direction facing : Direction.values()) {
if (facing.getAxis().isVertical())
continue;
voxelShaper.shapes.put(facing, rotatedCopy(southShape, (int) facing.getHorizontalAngle(), 0));
}
return voxelShaper;
}
public static VoxelShaper forDirectionalBlock(VoxelShape southShape) {
VoxelShaper voxelShaper = new VoxelShaper();
for (Direction facing : Direction.values()) {
int rotX = facing.getAxis().isVertical() ? 0 : (int) facing.getHorizontalAngle();
int rotY = facing.getAxis().isVertical() ? (facing == Direction.UP ? 90 : 270) : 0;
voxelShaper.shapes.put(facing, rotatedCopy(southShape, rotX, rotY));
}
return voxelShaper;
}
public VoxelShaper withVerticalShapes(VoxelShape upShape) {
shapes.put(Direction.UP, upShape);
shapes.put(Direction.DOWN, rotatedCopy(upShape, 180, 0));
return this;
}
public static VoxelShape rotatedCopy(VoxelShape shape, int rotX, int rotY) {
Vec3d v1 = new Vec3d(shape.getStart(Axis.X), shape.getStart(Axis.Y), shape.getStart(Axis.Z)).scale(16);
Vec3d v2 = new Vec3d(shape.getEnd(Axis.X), shape.getEnd(Axis.Y), shape.getEnd(Axis.Z)).scale(16);
v1 = VecHelper.rotate(v1, rotX, Axis.X);
v1 = VecHelper.rotate(v1, rotY, Axis.Y);
v2 = VecHelper.rotate(v2, rotX, Axis.X);
v2 = VecHelper.rotate(v2, rotY, Axis.Y);
return Block.makeCuboidShape(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
}
}

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.receivers.constructs; package com.simibubi.create.modules.contraptions.receivers.constructs;
import java.util.List;
import com.simibubi.create.foundation.block.IBlockWithScrollableValue; import com.simibubi.create.foundation.block.IBlockWithScrollableValue;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.IWithTileEntity;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -22,7 +24,7 @@ import net.minecraft.world.World;
public abstract class AbstractChassisBlock extends RotatedPillarBlock public abstract class AbstractChassisBlock extends RotatedPillarBlock
implements IWithTileEntity<ChassisTileEntity>, IBlockWithScrollableValue { implements IWithTileEntity<ChassisTileEntity>, IBlockWithScrollableValue {
private static final Vec3d valuePos = new Vec3d(15 / 16f, 9 / 16f, 9 / 16f); private static final Vec3d valuePos = new Vec3d(15 / 16f, 9 / 16f, 9 / 16f);
public AbstractChassisBlock(Properties properties) { public AbstractChassisBlock(Properties properties) {
@ -78,17 +80,29 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock
public String getValueName(BlockState state, IWorld world, BlockPos pos) { public String getValueName(BlockState state, IWorld world, BlockPos pos) {
return Lang.translate("generic.range"); return Lang.translate("generic.range");
} }
@Override @Override
public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) { public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) {
return valuePos; return valuePos;
} }
@Override @Override
public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) { public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) {
return null; return null;
} }
@Override
public List<ItemStack> getDrops(BlockState state, net.minecraft.world.storage.loot.LootContext.Builder builder) {
@SuppressWarnings("deprecation")
List<ItemStack> drops = super.getDrops(state, builder);
for (Direction face : Direction.values()) {
BooleanProperty glueableSide = getGlueableSide(state, face);
if (glueableSide != null && state.get(glueableSide))
drops.add(new ItemStack(Items.SLIME_BALL));
}
return drops;
}
@Override @Override
public boolean isValueOnAllSides() { public boolean isValueOnAllSides() {
return true; return true;

View file

@ -57,7 +57,7 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ITi
public AxisAlignedBB getRenderBoundingBox() { public AxisAlignedBB getRenderBoundingBox() {
return INFINITE_EXTENT_AABB; return INFINITE_EXTENT_AABB;
} }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public double getMaxRenderDistanceSquared() { public double getMaxRenderDistanceSquared() {
@ -102,9 +102,7 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ITi
Direction direction = getBlockState().get(BlockStateProperties.FACING); Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct // Collect Construct
movingConstruct = getMovementSpeed() < 0 movingConstruct = TranslationConstruct.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
? TranslationConstruct.getAttachedForPulling(getWorld(), getPos(), direction)
: TranslationConstruct.getAttachedForPushing(getWorld(), getPos(), direction);
if (movingConstruct == null) if (movingConstruct == null)
return; return;

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.receivers.constructs; package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -25,19 +27,39 @@ public class TranslationChassisBlock extends AbstractChassisBlock {
builder.add(STICKY_TOP, STICKY_BOTTOM); builder.add(STICKY_TOP, STICKY_BOTTOM);
super.fillStateContainer(builder); super.fillStateContainer(builder);
} }
@Override @Override
public BlockState getStateForPlacement(BlockItemUseContext context) { public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite()); BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite());
BlockState blockState = context.getWorld().getBlockState(placedOnPos); BlockState blockState = context.getWorld().getBlockState(placedOnPos);
if (blockState.getBlock() instanceof TranslationChassisBlock && !context.isPlacerSneaking()) if (isChassis(blockState) && !context.isPlacerSneaking())
return getDefaultState().with(AXIS, blockState.get(AXIS)); return getDefaultState().with(AXIS, blockState.get(AXIS));
if (!context.isPlacerSneaking())
return getDefaultState().with(AXIS, context.getNearestLookingDirection().getAxis());
return super.getStateForPlacement(context); return super.getStateForPlacement(context);
} }
@Override @Override
public BooleanProperty getGlueableSide(BlockState state, Direction face) { public BooleanProperty getGlueableSide(BlockState state, Direction face) {
if (face.getAxis() != state.get(AXIS))
return null;
return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM; return face.getAxisDirection() == AxisDirection.POSITIVE ? STICKY_TOP : STICKY_BOTTOM;
} }
@Override
public String getTranslationKey() {
Block block = AllBlocks.TRANSLATION_CHASSIS.get();
if (this == block)
return super.getTranslationKey();
return block.getTranslationKey();
}
public static boolean isChassis(BlockState state) {
return AllBlocks.TRANSLATION_CHASSIS.typeOf(state) || AllBlocks.TRANSLATION_CHASSIS_SECONDARY.typeOf(state);
}
public static boolean sameKind(BlockState state1, BlockState state2) {
return state1.getBlock() == state2.getBlock();
}
} }

View file

@ -3,7 +3,6 @@ package com.simibubi.create.modules.contraptions.receivers.constructs;
import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD;
import static com.simibubi.create.AllBlocks.PISTON_POLE; import static com.simibubi.create.AllBlocks.PISTON_POLE;
import static com.simibubi.create.AllBlocks.STICKY_MECHANICAL_PISTON; import static com.simibubi.create.AllBlocks.STICKY_MECHANICAL_PISTON;
import static com.simibubi.create.AllBlocks.TRANSLATION_CHASSIS;
import static com.simibubi.create.CreateConfig.parameters; import static com.simibubi.create.CreateConfig.parameters;
import static net.minecraft.state.properties.BlockStateProperties.AXIS; import static net.minecraft.state.properties.BlockStateProperties.AXIS;
import static net.minecraft.state.properties.BlockStateProperties.FACING; import static net.minecraft.state.properties.BlockStateProperties.FACING;
@ -54,12 +53,25 @@ public class TranslationConstruct {
protected int extensionLength; protected int extensionLength;
protected int initialExtensionProgress; protected int initialExtensionProgress;
protected Axis movementAxis; protected Direction orientation;
public TranslationConstruct() { public TranslationConstruct() {
blocks = new HashMap<>(); blocks = new HashMap<>();
actors = new ArrayList<>(); actors = new ArrayList<>();
} }
public static TranslationConstruct movePistonAt(World world, BlockPos pos, Direction direction, boolean retract) {
if (isFrozen())
return null;
TranslationConstruct construct = new TranslationConstruct();
construct.orientation = direction;
if (!construct.collectExtensions(world, pos, direction))
return null;
if (!construct.searchMovedStructure(world, pos.offset(direction, construct.initialExtensionProgress + 1),
retract ? direction.getOpposite() : direction))
return null;
return construct;
}
public Set<BlockPos> getColliders(World world, Direction movementDirection) { public Set<BlockPos> getColliders(World world, Direction movementDirection) {
if (blocks == null) if (blocks == null)
@ -85,38 +97,6 @@ public class TranslationConstruct {
return cachedColliders; return cachedColliders;
} }
public static TranslationConstruct getAttachedForPushing(World world, BlockPos pos, Direction direction) {
if (isFrozen())
return null;
TranslationConstruct construct = new TranslationConstruct();
if (!construct.collectExtensions(world, pos, direction))
return null;
if (!construct.collectAttached(world, pos.offset(direction, construct.initialExtensionProgress), direction,
direction, construct.initialExtensionProgress))
return null;
return construct;
}
public static TranslationConstruct getAttachedForPulling(World world, BlockPos pos, Direction direction) {
if (isFrozen())
return null;
TranslationConstruct construct = new TranslationConstruct();
if (!construct.collectExtensions(world, pos, direction))
return null;
if (STICKY_MECHANICAL_PISTON.typeOf(world.getBlockState(pos))) {
if (!construct.collectAttached(world, pos.offset(direction, construct.initialExtensionProgress), direction,
direction.getOpposite(), construct.initialExtensionProgress))
return null;
}
return construct;
}
private boolean collectExtensions(World world, BlockPos pos, Direction direction) { private boolean collectExtensions(World world, BlockPos pos, Direction direction) {
List<BlockInfo> poles = new ArrayList<>(); List<BlockInfo> poles = new ArrayList<>();
BlockPos actualStart = pos; BlockPos actualStart = pos;
@ -174,241 +154,6 @@ public class TranslationConstruct {
return true; return true;
} }
protected boolean collectAttached(World world, BlockPos pos, Direction direction, Direction movementDirection,
int offset) {
// Find chassis
List<BlockInfo> chassis = collectChassis(world, pos, direction, offset);
if (chassis == null)
return false;
// Get single row of blocks
if (chassis.isEmpty()) {
if (movementDirection != direction) {
BlockState state = world.getBlockState(pos.offset(direction));
if (state.getMaterial().isReplaceable() || state.isAir(world, pos.offset(direction)))
return true;
if (state.getCollisionShape(world, pos.offset(direction)).isEmpty())
return true;
if (!canPull(world, pos.offset(direction), movementDirection))
return true;
BlockPos blockPos = pos.offset(direction).offset(direction, -offset);
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
constructCollisionBox = new AxisAlignedBB(blockPos);
} else {
for (int distance = 1; distance <= parameters.maxChassisRange.get() + 1; distance++) {
BlockPos currentPos = pos.offset(direction, distance);
BlockState state = world.getBlockState(currentPos);
// Ignore replaceable Blocks and Air-like
if (state.getMaterial().isReplaceable() || state.isAir(world, currentPos))
break;
if (state.getCollisionShape(world, currentPos).isEmpty())
break;
// Row is immobile
if (!canPush(world, currentPos, direction))
return false;
// Too many blocks
if (distance == parameters.maxChassisRange.get() + 1)
return false;
BlockPos blockPos = currentPos.offset(direction, -offset);
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
if (constructCollisionBox == null)
constructCollisionBox = new AxisAlignedBB(blockPos);
else
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(blockPos));
// Don't collect in front of drills
if (AllBlocks.DRILL.typeOf(state) && state.get(FACING) == direction)
break;
}
}
}
// Get attached blocks by chassis
else {
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, -offset + 1));
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis,
movementDirection, offset);
if (attachedBlocksByChassis == null)
return false;
attachedBlocksByChassis.forEach(info -> {
blocks.put(info.pos, info);
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(info.pos));
});
}
// Find blocks with special movement behaviour
blocks.values().forEach(block -> {
if (block.state.getBlock() instanceof IHaveMovementBehavior)
actors.add(block);
});
return true;
}
private static List<BlockInfo> getAttachedBlocksByChassis(World world, Direction direction, List<BlockInfo> chassis,
Direction movementDirection, int offset) {
Axis axis = direction.getAxis();
List<BlockPos> frontier = new LinkedList<>();
Set<BlockPos> visited = new HashSet<>();
chassis.forEach(c -> frontier.add(c.pos.offset(direction, offset)));
BlockPos chassisPos = chassis.get(0).pos.offset(direction, offset);
int chassisCoord = direction.getAxis().getCoordinate(chassisPos.getX(), chassisPos.getY(), chassisPos.getZ());
Function<BlockPos, BlockPos> getChassisPos = pos -> new BlockPos(axis == Axis.X ? chassisCoord : pos.getX(),
axis == Axis.Y ? chassisCoord : pos.getY(), axis == Axis.Z ? chassisCoord : pos.getZ());
List<BlockInfo> blocks = new ArrayList<>();
boolean pushing = direction == movementDirection;
Search: while (!frontier.isEmpty()) {
BlockPos currentPos = frontier.remove(0);
BlockState state = world.getBlockState(currentPos);
if (visited.contains(currentPos))
continue;
visited.add(currentPos);
BlockPos currentChassisPos = getChassisPos.apply(currentPos);
BlockState chassisState = world.getBlockState(currentChassisPos);
// Not attached to a chassis
if (!(chassisState.getBlock() instanceof TranslationChassisBlock))
continue;
int chassisRange = ((ChassisTileEntity) world.getTileEntity(currentChassisPos)).getRange();
boolean chassisSticky = chassisState
.get(((AbstractChassisBlock) chassisState.getBlock()).getGlueableSide(chassisState, direction));
// Ignore replaceable Blocks and Air-like
if (state.getMaterial().isReplaceable() || state.isAir(world, currentPos))
continue;
if (state.getCollisionShape(world, currentPos).isEmpty())
continue;
// Too many Blocks
if (pushing && !currentChassisPos.withinDistance(currentPos, chassisRange + 1))
return null;
if (direction != movementDirection && !currentChassisPos.withinDistance(currentPos, chassisRange + 1))
continue;
// Skip if pushed column ended already
if (!currentPos.equals(currentChassisPos)) {
// Don't pull if not sticky
if (!chassisSticky && !pushing)
continue;
for (BlockPos p = currentPos; !p.equals(currentChassisPos); p = p.offset(direction.getOpposite())) {
BlockState blockState = world.getBlockState(p);
if (!chassisSticky
&& (blockState.getMaterial().isReplaceable() || blockState.isAir(world, currentPos))) {
continue Search;
}
if (!pushing && chassisSticky && !canPush(world, p, movementDirection)) {
continue Search;
}
}
}
// Ignore sand and co.
if (chassisSticky && movementDirection != direction && state.getBlock() instanceof FallingBlock)
continue;
// Structure is immobile
if (pushing && !canPush(world, currentPos, movementDirection))
return null;
if (!pushing && !canPull(world, currentPos, movementDirection))
continue;
CompoundNBT nbt = new CompoundNBT();
nbt.putInt("Range", chassisRange);
blocks.add(new BlockInfo(currentPos.offset(direction, -offset), state,
TRANSLATION_CHASSIS.typeOf(state) ? nbt : null));
// Expand search
for (Direction facing : Direction.values()) {
if (currentChassisPos.equals(currentPos) && facing == direction.getOpposite())
continue;
if (AllBlocks.DRILL.typeOf(state) && facing == direction)
continue;
frontier.add(currentPos.offset(facing));
}
}
return blocks;
}
private static boolean canPush(World world, BlockPos pos, Direction direction) {
BlockState blockState = world.getBlockState(pos);
if (TRANSLATION_CHASSIS.typeOf(blockState))
return true;
if (blockState.getBlock() instanceof ShulkerBoxBlock)
return false;
return PistonBlock.canPush(blockState, world, pos, direction, true, direction);
}
private static boolean canPull(World world, BlockPos pos, Direction direction) {
return canPush(world, pos, direction.getOpposite());
}
private static List<BlockInfo> collectChassis(World world, BlockPos pos, Direction direction, int offset2) {
List<BlockPos> search = new LinkedList<>();
Set<BlockPos> visited = new HashSet<>();
List<BlockInfo> chassis = new LinkedList<>();
search.add(pos.offset(direction));
while (!search.isEmpty()) {
if (chassis.size() > parameters.maxChassisForTranslation.get())
return null;
BlockPos current = search.remove(0);
if (visited.contains(current))
continue;
BlockState blockState = world.getBlockState(current);
if (!(blockState.getBlock() instanceof TranslationChassisBlock))
continue;
if (blockState.get(AXIS) != direction.getAxis())
continue;
visited.add(current);
chassis.add(new BlockInfo(current.offset(direction, -offset2), blockState, null));
for (Direction offset : Direction.values()) {
if (offset.getAxis() == direction.getAxis())
continue;
search.add(current.offset(offset));
}
}
return chassis;
}
/////////////////////////
public static TranslationConstruct moveConstructAt(World world, BlockPos pos, Direction direction) {
if (isFrozen())
return null;
TranslationConstruct construct = new TranslationConstruct();
construct.movementAxis = direction.getAxis();
// collect piston extensions
if (!construct.searchMovedStructure(world, pos, direction))
return null;
return construct;
}
private boolean searchMovedStructure(World world, BlockPos pos, Direction direction) { private boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
List<BlockPos> frontier = new ArrayList<>(); List<BlockPos> frontier = new ArrayList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
@ -420,15 +165,17 @@ public class TranslationConstruct {
if (!world.isAreaLoaded(currentPos, 1)) if (!world.isAreaLoaded(currentPos, 1))
return false; return false;
if (!world.isBlockPresent(currentPos)) if (!world.isBlockPresent(currentPos))
continue; break;
BlockState state = world.getBlockState(currentPos); BlockState state = world.getBlockState(currentPos);
if (state.getMaterial().isReplaceable()) if (state.getMaterial().isReplaceable())
break; break;
if (state.getCollisionShape(world, currentPos).isEmpty()) if (state.getCollisionShape(world, currentPos).isEmpty())
break; break;
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite())
break;
if (!canPush(world, currentPos, direction)) if (!canPush(world, currentPos, direction))
return false; return false;
frontier.add(currentPos);
} }
for (int limit = 1000; limit > 0; limit--) { for (int limit = 1000; limit > 0; limit--) {
@ -455,7 +202,7 @@ public class TranslationConstruct {
return true; return true;
if (!canPush(world, pos, direction)) if (!canPush(world, pos, direction))
return false; return false;
if (TRANSLATION_CHASSIS.typeOf(state) && !moveChassis(world, pos, direction, frontier, visited)) if (isChassis(state) && !moveChassis(world, pos, direction, frontier, visited))
return false; return false;
if (state.getBlock() instanceof SlimeBlock) if (state.getBlock() instanceof SlimeBlock)
for (Direction offset : Direction.values()) for (Direction offset : Direction.values())
@ -475,9 +222,6 @@ public class TranslationConstruct {
BlockInfo anchorChassis = cluster.get(0); BlockInfo anchorChassis = cluster.get(0);
Axis chassisAxis = anchorChassis.state.get(AXIS); Axis chassisAxis = anchorChassis.state.get(AXIS);
List<BlockPos> chassisFrontier = new LinkedList<>();
Set<BlockPos> chassisVisited = new HashSet<>();
cluster.forEach(c -> frontier.add(c.pos));
int chassisCoord = chassisAxis.getCoordinate(anchorChassis.pos.getX(), anchorChassis.pos.getY(), int chassisCoord = chassisAxis.getCoordinate(anchorChassis.pos.getX(), anchorChassis.pos.getY(),
anchorChassis.pos.getZ()); anchorChassis.pos.getZ());
@ -488,7 +232,11 @@ public class TranslationConstruct {
// Collect blocks on both sides // Collect blocks on both sides
for (AxisDirection axisDirection : AxisDirection.values()) { for (AxisDirection axisDirection : AxisDirection.values()) {
Direction chassisDirection = Direction.getFacingFromAxis(axisDirection, chassisAxis); Direction chassisDirection = Direction.getFacingFromAxis(axisDirection, chassisAxis);
List<BlockPos> chassisFrontier = new LinkedList<>();
Set<BlockPos> chassisVisited = new HashSet<>();
cluster.forEach(c -> chassisFrontier.add(c.pos));
boolean pushing = chassisDirection == movementDirection; boolean pushing = chassisDirection == movementDirection;
Search: while (!chassisFrontier.isEmpty()) { Search: while (!chassisFrontier.isEmpty()) {
@ -506,7 +254,10 @@ public class TranslationConstruct {
BlockState chassisState = world.getBlockState(currentChassisPos); BlockState chassisState = world.getBlockState(currentChassisPos);
// Not attached to a chassis // Not attached to a chassis
if (!AllBlocks.TRANSLATION_CHASSIS.typeOf(chassisState) || chassisState.get(AXIS) != chassisAxis) if (!isChassis(chassisState) || chassisState.get(AXIS) != chassisAxis)
continue;
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state)
&& state.get(FACING) == chassisDirection.getOpposite())
continue; continue;
int chassisRange = ((ChassisTileEntity) world.getTileEntity(currentChassisPos)).getRange(); int chassisRange = ((ChassisTileEntity) world.getTileEntity(currentChassisPos)).getRange();
@ -580,7 +331,8 @@ public class TranslationConstruct {
List<BlockPos> search = new LinkedList<>(); List<BlockPos> search = new LinkedList<>();
Set<BlockPos> visited = new HashSet<>(); Set<BlockPos> visited = new HashSet<>();
List<BlockInfo> chassis = new LinkedList<>(); List<BlockInfo> chassis = new LinkedList<>();
Axis axis = world.getBlockState(pos).get(AXIS); BlockState anchorChassis = world.getBlockState(pos);
Axis axis = anchorChassis.get(AXIS);
search.add(pos); search.add(pos);
while (!search.isEmpty()) { while (!search.isEmpty()) {
@ -594,7 +346,9 @@ public class TranslationConstruct {
return null; return null;
BlockState state = world.getBlockState(current); BlockState state = world.getBlockState(current);
if (!TRANSLATION_CHASSIS.typeOf(state)) if (!isChassis(state))
continue;
if (!TranslationChassisBlock.sameKind(anchorChassis, state))
continue; continue;
if (state.get(AXIS) != axis) if (state.get(AXIS) != axis)
continue; continue;
@ -619,14 +373,27 @@ public class TranslationConstruct {
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing; return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
return false; return false;
} }
private static boolean isChassis(BlockState state) {
return TranslationChassisBlock.isChassis(state);
}
private static boolean canPush(World world, BlockPos pos, Direction direction) {
BlockState blockState = world.getBlockState(pos);
if (isChassis(blockState))
return true;
if (blockState.getBlock() instanceof ShulkerBoxBlock)
return false;
return PistonBlock.canPush(blockState, world, pos, direction, true, direction);
}
private void add(BlockPos pos, BlockInfo block) { private void add(BlockPos pos, BlockInfo block) {
BlockPos localPos = pos.offset(Direction.getFacingFromAxisDirection(movementAxis, AxisDirection.POSITIVE), BlockPos localPos = pos.offset(orientation, -initialExtensionProgress);
-initialExtensionProgress); BlockInfo blockInfo = new BlockInfo(localPos, block.state, block.nbt);
blocks.put(localPos, block); blocks.put(localPos, blockInfo);
if (block.state.getBlock() instanceof IHaveMovementBehavior) if (block.state.getBlock() instanceof IHaveMovementBehavior)
actors.add(block); actors.add(blockInfo);
constructCollisionBox.union(new AxisAlignedBB(pos)); constructCollisionBox.union(new AxisAlignedBB(localPos));
} }
private static BlockInfo capture(World world, BlockPos pos) { private static BlockInfo capture(World world, BlockPos pos) {

View file

@ -0,0 +1,22 @@
{
"forge_marker": 1,
"defaults": {
"textures": {
"side": "create:block/translation_chassis_side_alt"
}
},
"variants": {
"axis=x,sticky_top=false,sticky_bottom=false": { "model": "create:block/translation_chassis", "x": 90, "y": 90 },
"axis=x,sticky_top=true,sticky_bottom=false": { "model": "create:block/translation_chassis_top_sticky", "x": 90, "y": 90 },
"axis=x,sticky_top=false,sticky_bottom=true": { "model": "create:block/translation_chassis_bottom_sticky", "x": 90, "y": 90 },
"axis=x,sticky_top=true,sticky_bottom=true": { "model": "create:block/translation_chassis_both_sticky", "x": 90, "y": 90 },
"axis=y,sticky_top=false,sticky_bottom=false": { "model": "create:block/translation_chassis" },
"axis=y,sticky_top=true,sticky_bottom=false": { "model": "create:block/translation_chassis_top_sticky" },
"axis=y,sticky_top=false,sticky_bottom=true": { "model": "create:block/translation_chassis_bottom_sticky" },
"axis=y,sticky_top=true,sticky_bottom=true": { "model": "create:block/translation_chassis_both_sticky" },
"axis=z,sticky_top=false,sticky_bottom=false": { "model": "create:block/translation_chassis", "x": 90, "y": 180 },
"axis=z,sticky_top=true,sticky_bottom=false": { "model": "create:block/translation_chassis_top_sticky", "x": 90, "y": 180 },
"axis=z,sticky_top=false,sticky_bottom=true": { "model": "create:block/translation_chassis_bottom_sticky", "x": 90, "y": 180 },
"axis=z,sticky_top=true,sticky_bottom=true": { "model": "create:block/translation_chassis_both_sticky", "x": 90, "y": 180 }
}
}

View file

@ -0,0 +1,137 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"textures": {
"gearbox_top": "create:block/gearbox_top",
"anvil": "minecraft:block/anvil",
"gearbox": "create:block/gearbox",
"axis_top": "create:block/axis_top",
"axis": "create:block/axis",
"andesite_casing_short": "create:block/andesite_casing_short"
},
"elements": [
{
"name": "Body",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 11 ],
"faces": {
"north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] },
"south": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] }
}
},
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Drill",
"from": [ 4, 4, 11 ],
"to": [ 12, 12, 13 ],
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 13 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 12 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 13, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 12, 5 ] }
}
},
{
"name": "Drill",
"from": [ 5, 5, 13 ],
"to": [ 11, 11, 15 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 11 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 10 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 11, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 10, 5 ] }
}
},
{
"name": "Drill",
"from": [ 6, 6, 15 ],
"to": [ 10, 10, 17 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 45.0 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 9 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 8 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 9, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 8, 5 ] }
}
},
{
"name": "Drill",
"from": [ 7, 7, 17 ],
"to": [ 9, 9, 19 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": -22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 7 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 6 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 7, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 6, 5 ] }
}
},
{
"name": "Shaft",
"from": [ 6, 6, 0 ],
"to": [ 10, 10, 11 ],
"faces": {
"north": { "texture": "#axis_top", "uv": [ 6, 6, 10, 10 ] },
"east": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ], "rotation": 90 },
"west": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ], "rotation": 270 },
"up": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ] },
"down": { "texture": "#axis", "uv": [ 6, 0, 10, 11 ] }
}
}
]
}

View file

@ -0,0 +1,123 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"textures": {
"gearbox_top": "create:block/gearbox_top",
"anvil": "minecraft:block/anvil",
"gearbox": "create:block/gearbox",
"andesite_casing_short": "create:block/andesite_casing_short"
},
"elements": [
{
"name": "Body",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 11 ],
"faces": {
"north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] },
"south": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] }
}
},
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Drill",
"from": [ 4, 4, 11 ],
"to": [ 12, 12, 13 ],
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 13 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 12 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 13, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 12, 5 ] }
}
},
{
"name": "Drill",
"from": [ 5, 5, 13 ],
"to": [ 11, 11, 15 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 11 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 10 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 11, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 10, 5 ] }
}
},
{
"name": "Drill",
"from": [ 6, 6, 15 ],
"to": [ 10, 10, 17 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 45.0 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 9 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 8 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 9, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 8, 5 ] }
}
},
{
"name": "Drill",
"from": [ 7, 7, 17 ],
"to": [ 9, 9, 19 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": -22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 7 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 6 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 7, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 6, 5 ] }
}
}
]
}

View file

@ -0,0 +1,81 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"textures": {
"gearbox_top": "create:block/gearbox_top",
"gearbox": "create:block/gearbox",
"stonecutter_saw": "minecraft:block/stonecutter_saw",
"andesite_casing_short": "create:block/andesite_casing_short",
"mechanical_saw_top": "create:block/mechanical_saw_top"
},
"elements": [
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 16, 16 ] },
"south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 16, 16 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 16 ] },
"down": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Inner",
"from": [ 2, 2, 1 ],
"to": [ 14, 12, 15 ],
"faces": {
"north": { "texture": "#gearbox", "uv": [ 2, 4, 14, 14 ] },
"south": { "texture": "#gearbox", "uv": [ 2, 4, 14, 14 ] },
"up": { "texture": "#mechanical_saw_top", "uv": [ 2, 1, 14, 15 ] },
"down": { "texture": "#gearbox", "uv": [ 0, 0, 12, 14 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 12, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 14, 0, 16, 10 ] },
"east": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 10 ] },
"south": { "texture": "#gearbox_top", "uv": [ 0, 0, 2, 10 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 14 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ], "rotation": 270 }
}
},
{
"name": "Side2",
"from": [ 14, 2, 0 ],
"to": [ 16, 12, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 0, 2, 10 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 14 ] },
"south": { "texture": "#gearbox_top", "uv": [ 14, 0, 16, 10 ] },
"west": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 10 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ], "rotation": 270 }
}
},
{
"name": "Saw",
"from": [ 0, 11, 8 ],
"to": [ 16, 19, 8 ],
"faces": {
"north": { "texture": "#stonecutter_saw", "uv": [ 0, 8, 16, 16 ] },
"south": { "texture": "#stonecutter_saw", "uv": [ 0, 8, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 12, 3 ],
"to": [ 16, 13, 13 ],
"faces": {
"north": { "texture": "#mechanical_saw_top", "uv": [ 0, 12, 16, 13 ] },
"east": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 1, 13 ], "rotation": 90 },
"south": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 16, 4 ] },
"west": { "texture": "#mechanical_saw_top", "uv": [ 15, 3, 16, 13 ], "rotation": 270 },
"up": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 16, 13 ] }
}
}
]
}

View file

@ -0,0 +1,123 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"textures": {
"gearbox_top": "create:block/gearbox_top",
"anvil": "minecraft:block/anvil",
"gearbox": "create:block/gearbox",
"andesite_casing_short": "create:block/andesite_casing_short"
},
"elements": [
{
"name": "Body",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 11 ],
"faces": {
"north": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] },
"south": { "texture": "#gearbox", "uv": [ 2, 2, 14, 14 ] }
}
},
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 2, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 14, 4, 16, 16 ], "rotation": 270 },
"up": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] },
"down": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 12 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 90 },
"south": { "texture": "#gearbox_top", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 2, 4, 14, 16 ], "rotation": 270 }
}
},
{
"name": "Drill",
"from": [ 4, 4, 11 ],
"to": [ 12, 12, 13 ],
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 13 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 11, 11 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 12 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 13, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 12, 5 ] }
}
},
{
"name": "Drill",
"from": [ 5, 5, 13 ],
"to": [ 11, 11, 15 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 11 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 9, 9 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 10 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 11, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 10, 5 ] }
}
},
{
"name": "Drill",
"from": [ 6, 6, 15 ],
"to": [ 10, 10, 17 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": 45.0 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 9 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 7, 7 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 8 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 9, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 8, 5 ] }
}
},
{
"name": "Drill",
"from": [ 7, 7, 17 ],
"to": [ 9, 9, 19 ],
"rotation": { "origin": [ 8, 8, 8 ], "axis": "z", "angle": -22.5 },
"faces": {
"north": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"east": { "texture": "#anvil", "uv": [ 10, 5, 12, 7 ] },
"south": { "texture": "#anvil", "uv": [ 3, 3, 5, 5 ] },
"west": { "texture": "#anvil", "uv": [ 8, 4, 10, 6 ] },
"up": { "texture": "#anvil", "uv": [ 5, 5, 7, 7 ] },
"down": { "texture": "#anvil", "uv": [ 4, 3, 6, 5 ] }
}
}
]
}

View file

@ -0,0 +1,81 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"textures": {
"gearbox_top": "create:block/gearbox_top",
"gearbox": "create:block/gearbox",
"stonecutter_saw": "minecraft:block/stonecutter_saw",
"andesite_casing_short": "create:block/andesite_casing_short",
"mechanical_saw_top": "create:block/mechanical_saw_top"
},
"elements": [
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 16, 16 ] },
"south": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 14, 16, 16 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 16 ] },
"down": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Inner",
"from": [ 2, 2, 1 ],
"to": [ 14, 12, 15 ],
"faces": {
"north": { "texture": "#gearbox", "uv": [ 2, 4, 14, 14 ] },
"south": { "texture": "#gearbox", "uv": [ 2, 4, 14, 14 ] },
"up": { "texture": "#mechanical_saw_top", "uv": [ 2, 1, 14, 15 ] },
"down": { "texture": "#gearbox", "uv": [ 0, 0, 12, 14 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 12, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 14, 0, 16, 10 ] },
"east": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 10 ] },
"south": { "texture": "#gearbox_top", "uv": [ 0, 0, 2, 10 ] },
"west": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 14 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 2 ], "rotation": 270 }
}
},
{
"name": "Side2",
"from": [ 14, 2, 0 ],
"to": [ 16, 12, 16 ],
"faces": {
"north": { "texture": "#gearbox_top", "uv": [ 0, 0, 2, 10 ] },
"east": { "texture": "#andesite_casing_short", "uv": [ 0, 4, 16, 14 ] },
"south": { "texture": "#gearbox_top", "uv": [ 14, 0, 16, 10 ] },
"west": { "texture": "#gearbox_top", "uv": [ 0, 0, 16, 10 ] },
"up": { "texture": "#gearbox_top", "uv": [ 0, 14, 16, 16 ], "rotation": 270 }
}
},
{
"name": "Saw",
"from": [ 0, 11, 8 ],
"to": [ 16, 19, 8 ],
"faces": {
"north": { "texture": "#stonecutter_saw", "uv": [ 0, 8, 16, 16 ] },
"south": { "texture": "#stonecutter_saw", "uv": [ 0, 8, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 12, 3 ],
"to": [ 16, 13, 13 ],
"faces": {
"north": { "texture": "#mechanical_saw_top", "uv": [ 0, 12, 16, 13 ] },
"east": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 1, 13 ], "rotation": 90 },
"south": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 16, 4 ] },
"west": { "texture": "#mechanical_saw_top", "uv": [ 15, 3, 16, 13 ], "rotation": 270 },
"up": { "texture": "#mechanical_saw_top", "uv": [ 0, 3, 16, 13 ] }
}
}
]
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/translation_chassis",
"textures": {
"side": "create:block/translation_chassis_side_alt"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B