Constructs, Pistons and Blocks

- Added Mechanical Pistons
- Added Chassis blocks for multiblock movement
- Improved memory usage of kinetic renders
- Added Mechanical Harvester
- Added Mechanical Drill
- Visual hints for the Belt connector
- Added Crushing Wheel Model
- Added Encased Belt
- Added Redstone Contact
- Fixed Invalid Schematics crashing on shift-right-click
- Added a variety of building materials
- Updated textures of kinetic blocks to be rotation independent
- Fixed axes rotating with fixed shaded sides
This commit is contained in:
simibubi 2019-08-17 00:57:36 +02:00
parent 71f928ae9d
commit 4cfd7a1bb9
217 changed files with 5088 additions and 210 deletions

View file

@ -13,14 +13,14 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
version = 'mc1.14.4_v0.0.5'
version = 'mc1.14.4_v0.1.0'
group = 'com.simibubi.create'
archivesBaseName = 'create'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft {
mappings channel: 'snapshot', version: '20190806-1.14.3'
mappings channel: 'snapshot', version: '20190816-1.14.3'
runs {
client {
@ -58,7 +58,7 @@ minecraft {
}
dependencies {
minecraft 'net.minecraftforge:forge:1.14.4-28.0.45'
minecraft 'net.minecraftforge:forge:1.14.4-28.0.49'
}
jar {

View file

@ -1,16 +1,26 @@
package com.simibubi.create;
import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.foundation.block.RenderUtilityAxisBlock;
import com.simibubi.create.foundation.block.RenderUtilityBlock;
import com.simibubi.create.modules.kinetics.base.HalfAxisBlock;
import com.simibubi.create.modules.kinetics.generators.MotorBlock;
import com.simibubi.create.modules.kinetics.receivers.TurntableBlock;
import com.simibubi.create.modules.kinetics.relays.AxisBlock;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelBlock;
import com.simibubi.create.modules.kinetics.relays.BeltBlock;
import com.simibubi.create.modules.kinetics.relays.CogWheelBlock;
import com.simibubi.create.modules.kinetics.relays.GearboxBlock;
import com.simibubi.create.modules.kinetics.relays.GearshifterBlock;
import com.simibubi.create.modules.contraptions.base.HalfAxisBlock;
import com.simibubi.create.modules.contraptions.generators.MotorBlock;
import com.simibubi.create.modules.contraptions.receivers.CrushingWheelBlock;
import com.simibubi.create.modules.contraptions.receivers.DrillBlock;
import com.simibubi.create.modules.contraptions.receivers.HarvesterBlock;
import com.simibubi.create.modules.contraptions.receivers.TurntableBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonHeadBlock;
import com.simibubi.create.modules.contraptions.receivers.constructs.PistonPoleBlock;
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
import com.simibubi.create.modules.contraptions.relays.AxisBlock;
import com.simibubi.create.modules.contraptions.relays.AxisTunnelBlock;
import com.simibubi.create.modules.contraptions.relays.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.CogWheelBlock;
import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
import com.simibubi.create.modules.contraptions.relays.GearboxBlock;
import com.simibubi.create.modules.contraptions.relays.GearshifterBlock;
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
@ -22,6 +32,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.Block.Properties;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.RotatedPillarBlock;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraftforge.registries.IForgeRegistry;
@ -40,20 +51,63 @@ public enum AllBlocks {
GEAR(new CogWheelBlock(false)),
LARGE_GEAR(new CogWheelBlock(true)),
AXIS_TUNNEL(new AxisTunnelBlock()),
ENCASED_BELT(new EncasedBeltBlock()),
GEARSHIFTER(new GearshifterBlock()),
GEARBOX(new GearboxBlock()),
BELT(new BeltBlock()),
BELT_PULLEY(new RenderUtilityAxisBlock()),
BELT_ANIMATION(new RenderUtilityBlock()),
MOTOR(new MotorBlock()),
TURNTABLE(new TurntableBlock()),
HALF_AXIS(new HalfAxisBlock()),
GEARBOX(new GearboxBlock()),
MOTOR(new MotorBlock()),
CRUSHING_WHEEL(new CrushingWheelBlock()),
MECHANICAL_PISTON(new MechanicalPistonBlock(false)),
STICKY_MECHANICAL_PISTON(new MechanicalPistonBlock(true)),
MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()),
PISTON_POLE(new PistonPoleBlock()),
CONSTRUCT(new ChassisBlock(ChassisBlock.Type.NORMAL)),
STICKY_CONSTRUCT(new ChassisBlock(ChassisBlock.Type.STICKY)),
RELOCATION_CONSTRUCT(new ChassisBlock(ChassisBlock.Type.RELOCATING)),
DRILL(new DrillBlock()),
HARVESTER(new HarvesterBlock()),
CONTACT(new ContactBlock()),
// Symmetry
SYMMETRY_PLANE(new PlaneSymmetryBlock()),
SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()),
SYMMETRY_TRIPLEPLANE(new TriplePlaneSymmetryBlock()),
// Palettes
ANDESITE_BRICKS(new Block(Properties.from(Blocks.ANDESITE))),
DIORITE_BRICKS(new Block(Properties.from(Blocks.DIORITE))),
GRANITE_BRICKS(new Block(Properties.from(Blocks.GRANITE))),
GABBRO(new Block(Properties.from(Blocks.ANDESITE))),
POLISHED_GABBRO(new Block(Properties.from(GABBRO.block))),
GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
PAVED_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
INDENTED_GABBRO(new Block(Properties.from(GABBRO.block))),
SLIGHTLY_MOSSY_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
MOSSY_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
LIMESTONE(new Block(Properties.from(Blocks.SANDSTONE))),
POLISHED_LIMESTONE(new Block(Properties.from(LIMESTONE.block))),
LIMESTONE_BRICKS(new Block(Properties.from(LIMESTONE.block))),
LIMESTONE_PILLAR(new RotatedPillarBlock(Properties.from(LIMESTONE.block))),
QUARTZIORITE(new Block(Properties.from(Blocks.QUARTZ_BLOCK))),
QUARTZIORITE_BRICKS(new Block(Properties.from(QUARTZIORITE.block))),
POLISHED_QUARTZIORITE(new Block(Properties.from(QUARTZIORITE.block))),
DOLOMITE(new Block(Properties.from(Blocks.GRANITE))),
DOLOMITE_BRICKS(new Block(Properties.from(DOLOMITE.block))),
POLISHED_DOLOMITE(new Block(Properties.from(DOLOMITE.block))),
DOLOMITE_PILLAR(new RotatedPillarBlock(Properties.from(DOLOMITE.block))),
;
public Block block;

View file

@ -1,10 +1,10 @@
package com.simibubi.create;
import com.simibubi.create.modules.contraptions.relays.BeltItem;
import com.simibubi.create.modules.curiosities.item.TreeFertilizerItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;
import com.simibubi.create.modules.kinetics.relays.BeltItem;
import com.simibubi.create.modules.schematics.item.BlueprintAndQuillItem;
import com.simibubi.create.modules.schematics.item.BlueprintItem;
import com.simibubi.create.modules.symmetry.SymmetryWandItem;

View file

@ -2,19 +2,23 @@ package com.simibubi.create;
import java.util.function.Supplier;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.kinetics.generators.MotorTileEntity;
import com.simibubi.create.modules.kinetics.generators.MotorTileEntityRenderer;
import com.simibubi.create.modules.kinetics.receivers.TurntableTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntityRenderer;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntityRenderer;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntityRenderer;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.generators.MotorTileEntity;
import com.simibubi.create.modules.contraptions.generators.MotorTileEntityRenderer;
import com.simibubi.create.modules.contraptions.receivers.CrushingWheelTileEntity;
import com.simibubi.create.modules.contraptions.receivers.DrillTileEntity;
import com.simibubi.create.modules.contraptions.receivers.TurntableTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.AxisTileEntity;
import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntity;
import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
import com.simibubi.create.modules.contraptions.relays.BeltTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity;
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer;
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity;
@ -41,15 +45,16 @@ public enum AllTileEntities {
// Kinetics
AXIS(AxisTileEntity::new, AllBlocks.AXIS, AllBlocks.GEAR, AllBlocks.LARGE_GEAR, AllBlocks.AXIS_TUNNEL),
MOTOR(MotorTileEntity::new, AllBlocks.MOTOR),
GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE),
AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL),
GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER),
BELT(BeltTileEntity::new, AllBlocks.BELT),
AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL, AllBlocks.ENCASED_BELT),
GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER), BELT(BeltTileEntity::new, AllBlocks.BELT),
MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON),
DRILL(DrillTileEntity::new, AllBlocks.DRILL),
CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL),
;
private Supplier<? extends TileEntity> supplier;
public TileEntityType<?> type;
private AllBlocks[] blocks;
@ -66,7 +71,7 @@ public enum AllTileEntities {
Block[] blocks = new Block[tileEntity.blocks.length];
for (int i = 0; i < blocks.length; i++)
blocks[i] = tileEntity.blocks[i].block;
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, tileEntity.name().toLowerCase());
tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null)
.setRegistryName(resourceLocation);
@ -84,6 +89,9 @@ public enum AllTileEntities {
bind(GearboxTileEntity.class, new GearboxTileEntityRenderer());
bind(GearshifterTileEntity.class, new GearshifterTileEntityRenderer());
bind(BeltTileEntity.class, new BeltTileEntityRenderer());
bind(MechanicalPistonTileEntity.class, new MechanicalPistonTileEntityRenderer());
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
}
@OnlyIn(Dist.CLIENT)

View file

@ -0,0 +1,12 @@
package com.simibubi.create.foundation.block;
import net.minecraft.block.RotatedPillarBlock;
import net.minecraft.block.material.Material;
public class RenderUtilityAxisBlock extends RotatedPillarBlock implements IRenderUtilityBlock {
public RenderUtilityAxisBlock() {
super(Properties.create(Material.AIR));
}
}

View file

@ -1,16 +1,14 @@
package com.simibubi.create.foundation.utility;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public abstract class BufferManipulator {
protected static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
protected ByteBuffer original;
protected ByteBuffer mutable;
@ -24,42 +22,72 @@ public abstract class BufferManipulator {
mutable.put(this.original);
mutable.rewind();
}
protected void forEachVertex(ByteBuffer buffer, Consumer<Integer> consumer) {
final int formatLength = DefaultVertexFormats.BLOCK.getSize();
for (int i = 0; i < buffer.limit() / formatLength; i++) {
final int position = i * formatLength;
consumer.accept(position);
}
protected int vertexCount(ByteBuffer buffer) {
return buffer.limit() / FORMAT_LENGTH;
}
protected Vec3d getPos(ByteBuffer buffer, int vertex) {
return new Vec3d(buffer.getFloat(vertex), buffer.getFloat(vertex + 4), buffer.getFloat(vertex + 8));
}
protected void putPos(ByteBuffer buffer, int vertex, Vec3d pos) {
buffer.putFloat(vertex, (float) pos.x);
buffer.putFloat(vertex + 4, (float) pos.y);
buffer.putFloat(vertex + 8, (float) pos.z);
}
protected Vec3d rotatePos(Vec3d pos, float angle, Axis axis) {
return rotatePos(pos, MathHelper.sin(angle), MathHelper.cos(angle), axis);
}
protected Vec3d rotatePos(Vec3d pos, float sin, float cos, Axis axis) {
final float x = (float) pos.x;
final float y = (float) pos.y;
final float z = (float) pos.z;
if (axis == Axis.X)
return new Vec3d(x, y * cos - z * sin, z * cos + y * sin);
if (axis == Axis.Y)
return new Vec3d(x * cos + z * sin, y, z * cos - x * sin);
if (axis == Axis.Z)
return new Vec3d(x * cos - y * sin, y * cos + x * sin, z);
return pos;
protected int getBufferPosition(int vertexIndex) {
return vertexIndex * FORMAT_LENGTH;
}
protected float getX(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index));
}
protected float getY(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 4);
}
protected float getZ(ByteBuffer buffer, int index) {
return buffer.getFloat(getBufferPosition(index) + 8);
}
protected byte getR(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 12);
}
protected byte getG(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 13);
}
protected byte getB(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 14);
}
protected byte getA(ByteBuffer buffer, int index) {
return buffer.get(getBufferPosition(index) + 15);
}
protected void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
int pos = getBufferPosition(index);
buffer.putFloat(pos, x);
buffer.putFloat(pos + 4, y);
buffer.putFloat(pos + 8, z);
}
protected float rotateX(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? x * cos + z * sin : axis == Axis.Z ? x * cos - y * sin : x;
}
protected float rotateY(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? y : axis == Axis.Z ? y * cos + x * sin : y * cos - z * sin;
}
protected float rotateZ(float x, float y, float z, float sin, float cos, Axis axis) {
return axis == Axis.Y ? z * cos - x * sin : axis == Axis.Z ? z : z * cos + y * sin;
}
protected void putLight(ByteBuffer buffer, int index, int packedLight) {
buffer.putInt(getBufferPosition(index) + 24, packedLight);
}
protected void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
int bufferPosition = getBufferPosition(index);
buffer.put(bufferPosition + 12, r);
buffer.put(bufferPosition + 13, g);
buffer.put(bufferPosition + 14, b);
buffer.put(bufferPosition + 15, a);
}
}

View file

@ -1,14 +1,15 @@
package com.simibubi.create.modules.kinetics;
package com.simibubi.create.modules.contraptions;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.IRotate;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity;
import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity;
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
import net.minecraft.block.BlockState;
import net.minecraft.state.IProperty;
@ -37,7 +38,7 @@ public class RotationPropagator {
final BlockPos diff = to.getPos().subtract(from.getPos());
final Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ());
final World world = from.getWorld();
IProperty<Axis> axisProperty = BlockStateProperties.AXIS;
boolean connectedByAxis = definitionFrom.isAxisTowards(world, from.getPos(), stateFrom, direction)
&& definitionTo.isAxisTowards(world, to.getPos(), stateTo, direction.getOpposite());
@ -58,6 +59,14 @@ public class RotationPropagator {
return getAxisModifier(from, direction) * getAxisModifier(to, direction.getOpposite());
}
// Attached Encased Belts
if (AllBlocks.ENCASED_BELT.typeOf(stateFrom) && AllBlocks.ENCASED_BELT.typeOf(stateTo)) {
boolean connected = stateFrom.get(EncasedBeltBlock.CONNECTED) && stateTo.get(EncasedBeltBlock.CONNECTED)
&& stateFrom.get(EncasedBeltBlock.CONNECTED_FACE) == direction
&& stateTo.get(EncasedBeltBlock.CONNECTED_FACE) == direction.getOpposite();
return connected ? 1 : 0;
}
// Gear <-> Large Gear
if (isLargeToSmallGear(stateFrom, stateTo, diff))
return -2f;
@ -133,12 +142,14 @@ public class RotationPropagator {
continue;
if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) {
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
addedTE.onSpeedChanged();
addedTE.notifyBlockUpdate();
continue;
}
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
addedTE.setSource(neighbourTE.getPos());
addedTE.onSpeedChanged();
addedTE.notifyBlockUpdate();
propagateNewSource(addedTE);
return;
@ -171,6 +182,7 @@ public class RotationPropagator {
neighbourTE.setSpeed(newSpeed);
neighbourTE.setSource(updateTE.getPos());
neighbourTE.onSpeedChanged();
neighbourTE.notifyBlockUpdate();
propagateNewSource(neighbourTE);
@ -254,6 +266,8 @@ public class RotationPropagator {
BlockState neighbourState = te.getWorld().getBlockState(neighbourPos);
if (!(neighbourState.getBlock() instanceof IRotate))
return null;
if (!neighbourState.hasTileEntity())
return null;
KineticTileEntity neighbour = (KineticTileEntity) te.getWorld().getTileEntity(neighbourPos);
if (getRotationSpeedModifier(te, neighbour) == 0)

View file

@ -0,0 +1,41 @@
package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
public abstract class DirectionalKineticBlock extends KineticBlock {
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public DirectionalKineticBlock(Properties properties) {
super(properties);
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING);
super.fillStateContainer(builder);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return getDefaultState().with(FACING, context.getFace());
}
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.foundation.block.IRenderUtilityBlock;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import com.simibubi.create.modules.kinetics.RotationPropagator;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -52,13 +52,10 @@ public abstract class KineticBlock extends Block implements IRotate {
@Override
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
@Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
// RotationPropagator.handleAdded(worldIn, pos);
}
@SuppressWarnings("deprecation")
@Override
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
super.updateNeighbors(stateIn, worldIn, pos, flags);
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
if (tileEntity == null)
return;

View file

@ -1,10 +1,10 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import java.util.Optional;
import java.util.Random;
import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.modules.kinetics.RotationPropagator;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
@ -31,6 +31,9 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
return true;
}
public void onSpeedChanged() {
}
@Override
public void onLoad() {
if (!hasWorld())
@ -126,6 +129,7 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
public void removeSource() {
this.source = Optional.empty();
setSpeed(0);
onSpeedChanged();
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import java.nio.ByteBuffer;
import java.util.HashMap;
@ -21,7 +21,6 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
@ -39,18 +38,23 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
super(original);
}
public ByteBuffer getTransformed(Vec3d translation, float angle, Axis axis, int packedLightCoords) {
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float angle, Axis axis,
int packedLightCoords) {
original.rewind();
mutable.rewind();
final float cos = MathHelper.cos(angle);
final float sin = MathHelper.sin(angle);
final Vec3d half = new Vec3d(.5f, .5f, .5f);
float cos = MathHelper.cos(angle);
float sin = MathHelper.sin(angle);
float x, y, z = 0;
forEachVertex(original, index -> {
final Vec3d vertex = getPos(original, index).subtract(half);
putPos(mutable, index, rotatePos(vertex, sin, cos, axis).add(translation).add(half));
mutable.putInt(index + 24, packedLightCoords);
});
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
x = getX(original, vertex) - .5f;
y = getY(original, vertex) - .5f;
z = getZ(original, vertex) - .5f;
putPos(mutable, vertex, rotateX(x, y, z, sin, cos, axis) + .5f + xIn,
rotateY(x, y, z, sin, cos, axis) + .5f + yIn, rotateZ(x, y, z, sin, cos, axis) + .5f + zIn);
putLight(mutable, vertex, packedLightCoords);
}
return mutable;
}
@ -67,20 +71,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
final BlockState state = getRenderedBlockState(te);
cacheIfMissing(state, BlockModelSpinner::new);
final Vec3d translation = new Vec3d(x, y, z);
final BlockPos pos = te.getPos();
final Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
float offset = getRotationOffsetForPosition(te, pos, axis);
float angle = (float) (((time * te.getSpeed() + offset) % 360) / 180 * (float) Math.PI);
renderFromCache(buffer, state, translation, pos, axis, angle);
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
}
protected void renderFromCache(BufferBuilder buffer, final BlockState state, final Vec3d translation,
final BlockPos pos, final Axis axis, float angle) {
protected void renderFromCache(BufferBuilder buffer, BlockState state, float x, float y, float z, BlockPos pos,
Axis axis, float angle) {
int packedLightmapCoords = state.getPackedLightmapCoords(getWorld(), pos);
buffer.putBulkData(((BlockModelSpinner) cachedBuffers.get(state)).getTransformed(translation, angle, axis,
buffer.putBulkData(((BlockModelSpinner) cachedBuffers.get(state)).getTransformed(x, y, z, angle, axis,
packedLightmapCoords));
}
@ -92,8 +95,9 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
BufferBuilder builder = new BufferBuilder(0);
Random random = new Random();
builder.setTranslation(0, 1, 0);
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
blockRenderer.renderModelFlat(getWorld(), originalModel, state, BlockPos.ZERO, builder, true, random, 42,
blockRenderer.renderModelFlat(getWorld(), originalModel, state, BlockPos.ZERO.down(), builder, true, random, 42,
EmptyModelData.INSTANCE);
builder.finishDrawing();
@ -114,5 +118,5 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return te.getBlockState();
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.base;
package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.kinetics.generators;
package com.simibubi.create.modules.contraptions.generators;
import com.simibubi.create.modules.kinetics.base.HorizontalKineticBlock;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.generators;
package com.simibubi.create.modules.contraptions.generators;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class MotorTileEntity extends KineticTileEntity {

View file

@ -1,8 +1,8 @@
package com.simibubi.create.modules.kinetics.generators;
package com.simibubi.create.modules.contraptions.generators;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;

View file

@ -0,0 +1,40 @@
package com.simibubi.create.modules.contraptions.receivers;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class CrushingWheelBlock extends RotatedPillarKineticBlock {
public CrushingWheelBlock() {
super(Properties.from(Blocks.DIORITE));
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new CrushingWheelTileEntity();
}
@Override
public Axis getRotationAxis(BlockState state) {
return state.get(AXIS);
}
@Override
public boolean isAxisTowards(World world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() == state.get(AXIS);
}
@Override
protected boolean hasStaticPart() {
return false;
}
}

View file

@ -0,0 +1,12 @@
package com.simibubi.create.modules.contraptions.receivers;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class CrushingWheelTileEntity extends KineticTileEntity {
public CrushingWheelTileEntity() {
super(AllTileEntities.CRUSHING_WHEEL.type);
}
}

View file

@ -0,0 +1,170 @@
package com.simibubi.create.modules.contraptions.receivers;
import java.util.List;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import com.simibubi.create.modules.contraptions.relays.AxisBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
public class DrillBlock extends DirectionalKineticBlock implements IHaveMovementBehavior {
protected static final VoxelShape CORE_SHAPE = makeCuboidShape(3, 3, 3, 13, 13, 13),
DRILL_SHAPE_X = VoxelShapes.or(CORE_SHAPE, AxisBlock.AXIS_X),
DRILL_SHAPE_Y = VoxelShapes.or(CORE_SHAPE, AxisBlock.AXIS_Y),
DRILL_SHAPE_Z = VoxelShapes.or(CORE_SHAPE, AxisBlock.AXIS_Z);
public static final BooleanProperty FIXATED = BooleanProperty.create("fixated");
public DrillBlock() {
super(Properties.from(Blocks.IRON_BLOCK));
setDefaultState(getDefaultState().with(FIXATED, true));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FIXATED);
super.fillStateContainer(builder);
}
@Override
public boolean hasTileEntity(BlockState state) {
return !state.get(FIXATED);
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new DrillTileEntity();
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
Axis axis = state.get(FACING).getAxis();
if (axis == Axis.X)
return DRILL_SHAPE_X;
if (axis == Axis.Y)
return DRILL_SHAPE_Y;
if (axis == Axis.Z)
return DRILL_SHAPE_Z;
return CORE_SHAPE;
}
@Override
public Axis getRotationAxis(BlockState state) {
return state.get(FACING).getAxis();
}
@Override
public boolean isAxisTowards(World world, BlockPos pos, BlockState state, Direction face) {
return !state.get(FIXATED) && face == state.get(FACING).getOpposite();
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return super.getStateForPlacement(context).with(FIXATED,
!canConnectTo(context.getWorld(), context.getPos(), context.getFace().getOpposite()));
}
private boolean canConnectTo(IWorld world, BlockPos pos, Direction direction) {
BlockPos offsetPos = pos.offset(direction);
BlockState blockStateAttached = world.getBlockState(offsetPos);
if (blockStateAttached.getBlock() instanceof IRotate && ((IRotate) blockStateAttached.getBlock())
.isAxisTowards(world.getWorld(), offsetPos, blockStateAttached, direction.getOpposite())) {
return true;
}
return false;
}
@Override
public PushReaction getPushReaction(BlockState state) {
return state.get(FIXATED) ? PushReaction.NORMAL : PushReaction.BLOCK;
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
if (facing == stateIn.get(FACING).getOpposite()) {
boolean connected = canConnectTo(worldIn, currentPos, facing);
boolean fixated = stateIn.get(FIXATED);
if (!fixated && !connected)
worldIn.getWorld().removeTileEntity(currentPos);
return stateIn.with(FIXATED, !connected);
}
if (facing != stateIn.get(FACING))
return stateIn;
DrillTileEntity te = (DrillTileEntity) worldIn.getTileEntity(currentPos);
if (te != null)
te.destroyNextTick();
return stateIn;
}
@Override
public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer) {
return state.get(FIXATED) && layer == BlockRenderLayer.SOLID;
}
@Override
protected boolean hasStaticPart() {
return false;
}
@Override
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
MechanicalPistonTileEntity piston) {
if (movement != block.get(FACING))
return false;
pos = pos.offset(movement);
BlockState stateVisited = world.getBlockState(pos);
if (stateVisited.getCollisionShape(world, pos).isEmpty())
return false;
if (stateVisited.getBlockHardness(world, pos) == -1)
return false;
world.playEvent(2001, pos, Block.getStateId(stateVisited));
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
world.setBlockState(pos, Blocks.AIR.getDefaultState());
for (ItemStack stack : drops) {
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
itemEntity.setMotion(
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
world.addEntity(itemEntity);
}
return false;
}
}

View file

@ -0,0 +1,98 @@
package com.simibubi.create.modules.contraptions.receivers;
import java.util.concurrent.atomic.AtomicInteger;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.AirBlock;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
public class DrillTileEntity extends KineticTileEntity implements ITickableTileEntity {
private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger();
private int ticksUntilNextProgress;
private int destroyProgress;
private int drillId = -NEXT_DRILL_ID.incrementAndGet();
public DrillTileEntity() {
super(AllTileEntities.DRILL.type);
}
@Override
public void onSpeedChanged() {
if (destroyProgress == -1)
destroyNextTick();
}
public void destroyNextTick() {
ticksUntilNextProgress = 1;
}
@Override
public CompoundNBT write(CompoundNBT compound) {
compound.putInt("Progress", destroyProgress);
compound.putInt("NextTick", ticksUntilNextProgress);
return super.write(compound);
}
@Override
public void read(CompoundNBT compound) {
destroyProgress = compound.getInt("Progress");
ticksUntilNextProgress = compound.getInt("NextTick");
super.read(compound);
}
@Override
public void remove() {
if (!world.isRemote && destroyProgress != 0) {
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
world.sendBlockBreakProgress(drillId, posToBreak, -1);
}
super.remove();
}
@Override
public void tick() {
if (world.isRemote)
return;
if (speed == 0)
return;
if (ticksUntilNextProgress < 0)
return;
if (ticksUntilNextProgress-- > 0)
return;
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
BlockState stateToBreak = world.getBlockState(posToBreak);
float blockHardness = stateToBreak.getBlockHardness(world, posToBreak);
if (stateToBreak.getMaterial().isLiquid() || stateToBreak.getBlock() instanceof AirBlock || blockHardness == -1) {
destroyProgress = 0;
world.sendBlockBreakProgress(drillId, posToBreak, -1);
return;
}
float breakSpeed = Math.abs(speed / 100f);
destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress);
if (destroyProgress >= 10) {
world.destroyBlock(posToBreak, true);
destroyProgress = 0;
ticksUntilNextProgress = -1;
world.sendBlockBreakProgress(drillId, posToBreak, -1);
return;
}
ticksUntilNextProgress = (int) (blockHardness / breakSpeed);
world.sendBlockBreakProgress(drillId, posToBreak, (int) destroyProgress);
}
}

View file

@ -0,0 +1,202 @@
package com.simibubi.create.modules.contraptions.receivers;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.CropsBlock;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.SugarCaneBlock;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.IProperty;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.IPlantable;
public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBehavior {
public static final VoxelShape SHAPE_SOUTH = makeCuboidShape(0, 4, 0, 16, 12, 6),
SHAPE_NORTH = makeCuboidShape(0, 4, 10, 16, 12, 16), SHAPE_WEST = makeCuboidShape(10, 4, 0, 16, 12, 16),
SHAPE_EAST = makeCuboidShape(0, 4, 0, 6, 12, 16);
public HarvesterBlock() {
super(Properties.from(Blocks.IRON_BLOCK));
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
Direction direction = state.get(HORIZONTAL_FACING);
if (direction == Direction.NORTH)
return SHAPE_NORTH;
if (direction == Direction.SOUTH)
return SHAPE_SOUTH;
if (direction == Direction.EAST)
return SHAPE_EAST;
if (direction == Direction.WEST)
return SHAPE_WEST;
return VoxelShapes.empty();
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(HORIZONTAL_FACING);
super.fillStateContainer(builder);
}
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
Direction direction = state.get(HORIZONTAL_FACING);
BlockPos offset = pos.offset(direction.getOpposite());
return Block.hasSolidSide(worldIn.getBlockState(offset), worldIn, offset, direction);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
Direction facing;
if (context.getFace().getAxis().isVertical())
facing = context.getPlacementHorizontalFacing().getOpposite();
else {
BlockState blockState = context.getWorld()
.getBlockState(context.getPos().offset(context.getFace().getOpposite()));
if (AllBlocks.HARVESTER.typeOf(blockState))
facing = blockState.get(HORIZONTAL_FACING);
else
facing = context.getFace();
}
return getDefaultState().with(HORIZONTAL_FACING, facing);
}
@Override
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
MechanicalPistonTileEntity piston) {
if (movement != block.get(HORIZONTAL_FACING))
return false;
BlockState stateVisited = world.getBlockState(pos);
boolean notCropButCuttable = false;
if (stateVisited.getBlock() == Blocks.SUGAR_CANE) {
notCropButCuttable = true;
pos = pos.up();
stateVisited = world.getBlockState(pos);
}
if (!isValidCrop(world, pos, stateVisited)) {
if (isValidOther(world, pos, stateVisited))
notCropButCuttable = true;
else
return false;
}
List<ItemStack> drops = Block.getDrops(stateVisited, (ServerWorld) world, pos, null);
world.playEvent(2001, pos, Block.getStateId(stateVisited));
world.setBlockState(pos, cutCrop(world, pos, stateVisited));
boolean seedSubtracted = notCropButCuttable;
for (ItemStack stack : drops) {
if (!seedSubtracted && stack.isItemEqual(new ItemStack(stateVisited.getBlock()))) {
stack.shrink(1);
seedSubtracted = true;
}
ItemEntity itemEntity = new ItemEntity(world, pos.getX() + .5f, pos.getY() + .25f, pos.getZ() + .5f, stack);
itemEntity.setMotion(
new Vec3d(movement.getDirectionVec()).add(0, 0.5f, 0).scale(world.rand.nextFloat() * .3f));
world.addEntity(itemEntity);
}
return false;
}
private boolean isValidCrop(World world, BlockPos pos, BlockState state) {
if (state.getBlock() instanceof CropsBlock) {
CropsBlock crop = (CropsBlock) state.getBlock();
if (!crop.isMaxAge(state))
return false;
return true;
}
if (state.getCollisionShape(world, pos).isEmpty()) {
for (IProperty<?> property : state.getProperties()) {
if (!(property instanceof IntegerProperty))
continue;
if (!property.getName().equals(BlockStateProperties.AGE_0_1.getName()))
continue;
if (((IntegerProperty) property).getAllowedValues().size() - 1 != state.get((IntegerProperty) property)
.intValue())
continue;
return true;
}
}
return false;
}
private boolean isValidOther(World world, BlockPos pos, BlockState state) {
if (state.getBlock() instanceof CropsBlock)
return false;
if (state.getBlock() instanceof SugarCaneBlock)
return true;
if (state.getCollisionShape(world, pos).isEmpty()) {
for (IProperty<?> property : state.getProperties()) {
if (!(property instanceof IntegerProperty))
continue;
if (!property.getName().equals(BlockStateProperties.AGE_0_1.getName()))
continue;
return false;
}
if (state.getBlock() instanceof IPlantable)
return true;
}
return false;
}
private BlockState cutCrop(World world, BlockPos pos, BlockState state) {
if (state.getBlock() instanceof CropsBlock) {
CropsBlock crop = (CropsBlock) state.getBlock();
return crop.withAge(0);
}
if (state.getBlock() == Blocks.SUGAR_CANE) {
return Blocks.AIR.getDefaultState();
}
if (state.getCollisionShape(world, pos).isEmpty()) {
for (IProperty<?> property : state.getProperties()) {
if (!(property instanceof IntegerProperty))
continue;
if (!property.getName().equals(BlockStateProperties.AGE_0_1.getName()))
continue;
return state.with((IntegerProperty) property, Integer.valueOf(0));
}
}
return Blocks.AIR.getDefaultState();
}
}

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.receivers;
package com.simibubi.create.modules.contraptions.receivers;
import com.simibubi.create.modules.kinetics.base.KineticBlock;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticBlock;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.receivers;
package com.simibubi.create.modules.contraptions.receivers;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.receivers;
package com.simibubi.create.modules.contraptions.receivers;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class TurntableTileEntity extends KineticTileEntity {

View file

@ -0,0 +1,37 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.RotatedPillarBlock;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.BlockPos;
public class ChassisBlock extends RotatedPillarBlock {
public Type type;
public enum Type {
NORMAL, STICKY, RELOCATING;
}
public ChassisBlock(Type type) {
super(Properties.from(Blocks.STRIPPED_SPRUCE_WOOD));
this.type = type;
}
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockPos placedOnPos = context.getPos().offset(context.getFace().getOpposite());
BlockState blockState = context.getWorld().getBlockState(placedOnPos);
if (blockState.getBlock() instanceof ChassisBlock)
return getDefaultState().with(AXIS, blockState.get(AXIS));
return super.getStateForPlacement(context);
}
}

View file

@ -0,0 +1,438 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD;
import static com.simibubi.create.AllBlocks.PISTON_POLE;
import static com.simibubi.create.AllBlocks.STICKY_MECHANICAL_PISTON;
import static net.minecraft.state.properties.BlockStateProperties.FACING;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import com.simibubi.create.AllBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.block.FallingBlock;
import net.minecraft.block.PistonBlock;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.FloatNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.PistonType;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class Construct {
public static final int MAX_EXTENSIONS = 20;
public static final int MAX_CHAINED_CHASSIS = 12;
public static final int MAX_CHAINED_BLOCKS = 8;
protected Map<BlockPos, BlockInfo> blocks;
protected List<BlockInfo> actors;
protected AxisAlignedBB collisionBoxFront;
protected AxisAlignedBB collisionBoxBack;
protected Set<BlockPos> cachedColliders;
protected Direction cachedColliderDirection;
protected int extensionLength;
protected int initialExtensionProgress;
public Construct() {
blocks = new HashMap<>();
actors = new ArrayList<>();
}
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
if (blocks == null)
return null;
if (cachedColliders == null || cachedColliderDirection != movementDirection) {
cachedColliders = new HashSet<>();
cachedColliderDirection = movementDirection;
for (BlockInfo info : blocks.values()) {
BlockPos offsetPos = info.pos.offset(movementDirection);
boolean hasNext = false;
for (BlockInfo otherInfo : blocks.values()) {
if (!otherInfo.pos.equals(offsetPos))
continue;
hasNext = true;
break;
}
if (!hasNext)
cachedColliders.add(info.pos);
}
}
return cachedColliders;
}
public static Construct getAttachedForPushing(World world, BlockPos pos, Direction direction) {
Construct construct = new Construct();
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 Construct getAttachedForPulling(World world, BlockPos pos, Direction direction) {
Construct construct = new Construct();
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) {
List<BlockInfo> poles = new ArrayList<>();
BlockPos actualStart = pos;
BlockState nextBlock = world.getBlockState(actualStart.offset(direction));
int extensionsInFront = 0;
boolean sticky = STICKY_MECHANICAL_PISTON.typeOf(world.getBlockState(pos));
while (PISTON_POLE.typeOf(nextBlock) && nextBlock.get(FACING).getAxis() == direction.getAxis()
|| MECHANICAL_PISTON_HEAD.typeOf(nextBlock) && nextBlock.get(FACING) == direction) {
actualStart = actualStart.offset(direction);
poles.add(new BlockInfo(actualStart, nextBlock.with(FACING, direction), null));
extensionsInFront++;
nextBlock = world.getBlockState(actualStart.offset(direction));
if (extensionsInFront > MAX_EXTENSIONS)
return false;
}
if (extensionsInFront == 0)
poles.add(
new BlockInfo(pos,
MECHANICAL_PISTON_HEAD.get().getDefaultState().with(FACING, direction).with(
BlockStateProperties.PISTON_TYPE, sticky ? PistonType.STICKY : PistonType.DEFAULT),
null));
else
poles.add(new BlockInfo(pos, PISTON_POLE.get().getDefaultState().with(FACING, direction), null));
BlockPos end = pos;
nextBlock = world.getBlockState(end.offset(direction.getOpposite()));
int extensionsInBack = 0;
while (PISTON_POLE.typeOf(nextBlock)) {
end = end.offset(direction.getOpposite());
poles.add(new BlockInfo(end, nextBlock.with(FACING, direction), null));
extensionsInBack++;
nextBlock = world.getBlockState(end.offset(direction.getOpposite()));
if (extensionsInFront + extensionsInBack > MAX_EXTENSIONS)
return false;
}
extensionLength = extensionsInBack + extensionsInFront;
initialExtensionProgress = extensionsInFront;
collisionBoxBack = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
for (BlockInfo pole : poles) {
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront);
blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
collisionBoxBack = collisionBoxBack.union(new AxisAlignedBB(polePos));
}
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 false;
BlockPos blockPos = pos.offset(direction).offset(direction, -offset);
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
collisionBoxFront = new AxisAlignedBB(blockPos);
} else {
for (int distance = 1; distance <= MAX_CHAINED_BLOCKS + 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 == MAX_CHAINED_BLOCKS + 1)
return false;
BlockPos blockPos = currentPos.offset(direction, -offset);
blocks.put(blockPos, new BlockInfo(blockPos, state, null));
if (collisionBoxFront == null)
collisionBoxFront = new AxisAlignedBB(blockPos);
else
collisionBoxFront = collisionBoxFront.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 {
collisionBoxFront = 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);
collisionBoxFront = collisionBoxFront.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<>();
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 ChassisBlock))
continue;
// Too many Blocks
if (!currentChassisPos.withinDistance(currentPos, MAX_CHAINED_BLOCKS + 2))
return null;
// Skip if pushed column ended already (Except for Relocating Chassis)
if (!AllBlocks.RELOCATION_CONSTRUCT.typeOf(chassisState) && !currentPos.equals(currentChassisPos)) {
boolean skip = false;
if (movementDirection != direction && !currentChassisPos.withinDistance(currentPos,
AllBlocks.STICKY_CONSTRUCT.typeOf(chassisState) ? 2 : 1))
continue;
for (BlockPos p = currentPos; !p.equals(currentChassisPos); p = p.offset(direction.getOpposite())) {
if (world.getBlockState(p).getMaterial().isReplaceable()
|| world.getBlockState(p).isAir(world, currentPos)) {
skip = true;
break;
}
}
if (skip)
continue;
}
// Ignore sand and co.
if (AllBlocks.RELOCATION_CONSTRUCT.typeOf(chassisState) && movementDirection != direction
&& state.getBlock() instanceof FallingBlock)
continue;
// Ignore replaceable Blocks and Air-like
if (state.getMaterial().isReplaceable() || state.isAir(world, currentPos))
continue;
if (state.getCollisionShape(world, currentPos).isEmpty())
continue;
// Structure is immobile
if (!canPush(world, currentPos, movementDirection))
return null;
blocks.add(new BlockInfo(currentPos.offset(direction, -offset), state, null));
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) {
return PistonBlock.canPush(world.getBlockState(pos), world, pos, direction, true, direction);
}
private static boolean canPull(World world, BlockPos pos, Direction direction) {
return PistonBlock.canPush(world.getBlockState(pos), world, pos, direction, true, 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<>(MAX_CHAINED_CHASSIS);
List<BlockInfo> chassis = new LinkedList<>();
search.add(pos.offset(direction));
while (!search.isEmpty()) {
if (chassis.size() > MAX_CHAINED_CHASSIS)
return null;
BlockPos current = search.remove(0);
if (visited.contains(current))
continue;
BlockState blockState = world.getBlockState(current);
if (!(blockState.getBlock() instanceof ChassisBlock))
continue;
if (blockState.get(BlockStateProperties.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 AxisAlignedBB getCollisionBoxFront() {
return collisionBoxFront;
}
public AxisAlignedBB getCollisionBoxBack() {
return collisionBoxBack;
}
public CompoundNBT writeNBT() {
CompoundNBT nbt = new CompoundNBT();
ListNBT blocks = new ListNBT();
for (BlockInfo block : this.blocks.values()) {
CompoundNBT c = new CompoundNBT();
c.put("Block", NBTUtil.writeBlockState(block.state));
c.put("Pos", NBTUtil.writeBlockPos(block.pos));
blocks.add(c);
}
if (collisionBoxFront != null) {
ListNBT bb = writeAABB(collisionBoxFront);
nbt.put("BoundsFront", bb);
}
if (collisionBoxBack != null) {
ListNBT bb = writeAABB(collisionBoxBack);
nbt.put("BoundsBack", bb);
}
nbt.put("Blocks", blocks);
nbt.putInt("ExtensionLength", extensionLength);
return nbt;
}
public ListNBT writeAABB(AxisAlignedBB bb) {
ListNBT bbtag = new ListNBT();
bbtag.add(new FloatNBT((float) bb.minX));
bbtag.add(new FloatNBT((float) bb.minY));
bbtag.add(new FloatNBT((float) bb.minZ));
bbtag.add(new FloatNBT((float) bb.maxX));
bbtag.add(new FloatNBT((float) bb.maxY));
bbtag.add(new FloatNBT((float) bb.maxZ));
return bbtag;
}
public AxisAlignedBB readAABB(ListNBT bbtag) {
if (bbtag == null || bbtag.isEmpty())
return null;
return new AxisAlignedBB(bbtag.getFloat(0), bbtag.getFloat(1), bbtag.getFloat(2), bbtag.getFloat(3),
bbtag.getFloat(4), bbtag.getFloat(5));
}
public static Construct fromNBT(CompoundNBT nbt) {
Construct construct = new Construct();
nbt.getList("Blocks", 10).forEach(c -> {
CompoundNBT comp = (CompoundNBT) c;
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
NBTUtil.readBlockState(comp.getCompound("Block")), null);
construct.blocks.put(info.pos, info);
});
construct.extensionLength = nbt.getInt("ExtensionLength");
if (nbt.contains("BoundsFront"))
construct.collisionBoxFront = construct.readAABB(nbt.getList("BoundsFront", 5));
if (nbt.contains("BoundsBack"))
construct.collisionBoxBack = construct.readAABB(nbt.getList("BoundsBack", 5));
// Find blocks with special movement behaviour
construct.blocks.values().forEach(block -> {
if (block.state.getBlock() instanceof IHaveMovementBehavior)
construct.actors.add(block);
});
return construct;
}
}

View file

@ -0,0 +1,114 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import net.minecraft.block.material.PushReaction;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.ReuseableStream;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
public class ConstructEntityHelper {
static List<AxisAlignedBB> renderedBBs = new LinkedList<>();
public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
float newOffset) {
World world = te.getWorld();
Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
Construct construct = te.movingConstruct;
if (world.isRemote) {
renderedBBs.clear();
if (construct.collisionBoxFront != null)
renderedBBs.add(construct.collisionBoxFront.offset(te.getConstructOffset(0)));
if (construct.collisionBoxBack != null)
renderedBBs.add(construct.collisionBoxBack.offset(te.getConstructOffset(0)));
}
if (construct.getCollisionBoxFront() != null) {
AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
if (world.isRemote) {
renderedBBs.add(constructBB);
}
for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
e -> e.getPushReaction() == PushReaction.NORMAL)) {
AxisAlignedBB entityBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset)).grow(.5f);
BlockPos min = new BlockPos(entityBB.minX, entityBB.minY, entityBB.minZ);// .add(-1, -1, -1);
BlockPos max = new BlockPos(entityBB.maxX, entityBB.maxY, entityBB.maxZ);// .add(1, 1, 1);
Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
.map(pos -> {
Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(0));
return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
vec.y, vec.z);
});
ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
// TODO: debug output
if (!world.isRemote) {
if (entity instanceof PlayerEntity)
((PlayerEntity) entity).sendStatusMessage(
new StringTextComponent("Potential Hits: " + potentialHits.createStream().count()),
true);
}
/////////////////
if (world.isRemote) {
for (Object shape : potentialHits.createStream().toArray())
renderedBBs.add(((VoxelShape) shape).getBoundingBox());
renderedBBs
.add(entity.getBoundingBox().offset(movementVec.scale(Math.signum(movementSpeed) * -.2f)));
}
Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed)
.add(entity.getMotion());
Vec3d allowedMovement = Entity.getAllowedMovement(movement,
entity.getBoundingBox().offset(movementVec.scale(Math.signum(movementSpeed) * -.2f)), world,
ISelectionContext.forEntity(entity), potentialHits);
if (!allowedMovement.equals(movement)) {
entity.setMotion(allowedMovement.subtract(movement.subtract(entity.getMotion())));
}
}
}
}
@SubscribeEvent
public static void onRenderWorld(RenderWorldLastEvent event) {
// for (AxisAlignedBB bb : renderedBBs) {
// TessellatorHelper.prepareForDrawing();
// GlStateManager.disableTexture();
// GlStateManager.lineWidth(3);
// WorldRenderer.drawSelectionBoundingBox(bb.grow(1 / 256f), .5f, 1, .5f, 1);
// GlStateManager.lineWidth(1);
// GlStateManager.enableTexture();
// TessellatorHelper.cleanUpAfterDrawing();
// }
}
}

View file

@ -0,0 +1,33 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.utility.BufferManipulator;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class ConstructVertexBuffer extends BufferManipulator {
public ConstructVertexBuffer(ByteBuffer original) {
super(original);
}
public ByteBuffer getTransformed(TileEntity te, float x, float y, float z, Vec3d offset) {
original.rewind();
mutable.rewind();
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
float xL = getX(original, vertex);
float yL = getY(original, vertex);
float zL = getZ(original, vertex);
putPos(mutable, vertex, xL + x, yL + y, zL + z);
BlockPos pos = new BlockPos(offset.x + xL, offset.y + yL, offset.z + zL);
putLight(mutable, vertex, te.getWorld().getCombinedLight(pos, 0));
}
return mutable;
}
}

View file

@ -0,0 +1,12 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IHaveMovementBehavior {
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement, MechanicalPistonTileEntity piston);
}

View file

@ -0,0 +1,196 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.base.KineticBlock;
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.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class MechanicalPistonBlock extends KineticBlock {
public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class);
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public static final BooleanProperty AXIS_ALONG_FIRST_COORDINATE = BooleanProperty.create("axis_along_first");
protected static final VoxelShape BASE_SHAPE_UP = makeCuboidShape(0, 0, 0, 16, 12, 16),
BASE_SHAPE_DOWN = makeCuboidShape(0, 4, 0, 16, 16, 16),
BASE_SHAPE_EAST = makeCuboidShape(0, 0, 0, 12, 16, 16),
BASE_SHAPE_WEST = makeCuboidShape(4, 0, 0, 16, 16, 16),
BASE_SHAPE_SOUTH = makeCuboidShape(0, 0, 0, 16, 16, 12),
BASE_SHAPE_NORTH = makeCuboidShape(0, 0, 4, 16, 16, 16),
EXTENDED_SHAPE_UP = VoxelShapes.or(BASE_SHAPE_UP, MechanicalPistonHeadBlock.AXIS_SHAPE_Y),
EXTENDED_SHAPE_DOWN = VoxelShapes.or(BASE_SHAPE_DOWN, MechanicalPistonHeadBlock.AXIS_SHAPE_Y),
EXTENDED_SHAPE_EAST = VoxelShapes.or(BASE_SHAPE_EAST, MechanicalPistonHeadBlock.AXIS_SHAPE_X),
EXTENDED_SHAPE_WEST = VoxelShapes.or(BASE_SHAPE_WEST, MechanicalPistonHeadBlock.AXIS_SHAPE_X),
EXTENDED_SHAPE_SOUTH = VoxelShapes.or(BASE_SHAPE_SOUTH, MechanicalPistonHeadBlock.AXIS_SHAPE_Z),
EXTENDED_SHAPE_NORTH = VoxelShapes.or(BASE_SHAPE_NORTH, MechanicalPistonHeadBlock.AXIS_SHAPE_Z);
protected boolean isSticky;
public MechanicalPistonBlock(boolean sticky) {
super(Properties.from(Blocks.PISTON));
setDefaultState(getDefaultState().with(FACING, Direction.NORTH).with(STATE, PistonState.RETRACTED));
isSticky = sticky;
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(STATE, FACING, AXIS_ALONG_FIRST_COORDINATE);
super.fillStateContainer(builder);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
Direction facing = context.getNearestLookingDirection().getOpposite();
if (context.isPlacerSneaking())
facing = facing.getOpposite();
Vec3d diff = context.getHitVec().subtract(new Vec3d(context.getPos()));
double firstCoord = facing.getAxis() == Axis.X ? diff.y : diff.x;
double secondCoord = facing.getAxis() == Axis.Z ? diff.y : diff.z;
boolean alongFirst = firstCoord + secondCoord < 1 ^ firstCoord < secondCoord;
return this.getDefaultState().with(FACING, facing).with(STATE, PistonState.RETRACTED)
.with(AXIS_ALONG_FIRST_COORDINATE, alongFirst);
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new MechanicalPistonTileEntity();
}
@Override
protected boolean hasStaticPart() {
return true;
}
@Override
public Axis getRotationAxis(BlockState state) {
Axis pistonAxis = state.get(FACING).getAxis();
boolean alongFirst = state.get(AXIS_ALONG_FIRST_COORDINATE);
if (pistonAxis == Axis.X)
return alongFirst ? Axis.Y : Axis.Z;
if (pistonAxis == Axis.Y)
return alongFirst ? Axis.X : Axis.Z;
if (pistonAxis == Axis.Z)
return alongFirst ? Axis.X : Axis.Y;
return super.getRotationAxis(state);
}
@Override
public boolean isAxisTowards(World world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() == getRotationAxis(state);
}
public enum PistonState implements IStringSerializable {
RETRACTED, MOVING, EXTENDED;
@Override
public String getName() {
return name().toLowerCase();
}
}
@Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
Direction direction = state.get(FACING);
BlockPos pistonHead = null;
BlockPos pistonBase = pos;
for (int offset = 1; offset < Construct.MAX_EXTENSIONS; offset++) {
BlockPos currentPos = pos.offset(direction, offset);
BlockState block = worldIn.getBlockState(currentPos);
if (AllBlocks.PISTON_POLE.typeOf(block)
&& direction.getAxis() == block.get(BlockStateProperties.FACING).getAxis())
continue;
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(block) && block.get(BlockStateProperties.FACING) == direction) {
pistonHead = currentPos;
}
break;
}
if (pistonHead != null && pistonBase != null) {
BlockPos.getAllInBox(pistonBase, pistonHead).filter(p -> !p.equals(pos))
.forEach(p -> worldIn.destroyBlock(p, !player.isCreative()));
}
for (int offset = 1; offset < Construct.MAX_EXTENSIONS; offset++) {
BlockPos currentPos = pos.offset(direction.getOpposite(), offset);
BlockState block = worldIn.getBlockState(currentPos);
if (AllBlocks.PISTON_POLE.typeOf(block)
&& direction.getAxis() == block.get(BlockStateProperties.FACING).getAxis()) {
worldIn.destroyBlock(currentPos, !player.isCreative());
continue;
}
break;
}
super.onBlockHarvested(worldIn, pos, state, player);
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
if (state.get(STATE) == PistonState.EXTENDED)
switch (state.get(FACING)) {
case DOWN:
return EXTENDED_SHAPE_DOWN;
case EAST:
return EXTENDED_SHAPE_EAST;
case NORTH:
return EXTENDED_SHAPE_NORTH;
case SOUTH:
return EXTENDED_SHAPE_SOUTH;
case UP:
return EXTENDED_SHAPE_UP;
case WEST:
return EXTENDED_SHAPE_WEST;
}
if (state.get(STATE) == PistonState.MOVING)
switch (state.get(FACING)) {
case DOWN:
return BASE_SHAPE_DOWN;
case EAST:
return BASE_SHAPE_EAST;
case NORTH:
return BASE_SHAPE_NORTH;
case SOUTH:
return BASE_SHAPE_SOUTH;
case UP:
return BASE_SHAPE_UP;
case WEST:
return BASE_SHAPE_WEST;
}
return VoxelShapes.fullCube();
}
}

View file

@ -0,0 +1,115 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.PistonType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class MechanicalPistonHeadBlock extends DirectionalBlock implements IWithoutBlockItem {
public static final EnumProperty<PistonType> TYPE = BlockStateProperties.PISTON_TYPE;
public static final VoxelShape AXIS_SHAPE_X = makeCuboidShape(0, 6, 6, 16, 10, 10),
AXIS_SHAPE_Y = makeCuboidShape(6, 0, 6, 10, 16, 10), AXIS_SHAPE_Z = makeCuboidShape(6, 6, 0, 10, 10, 16),
TOP_SHAPE_UP = makeCuboidShape(0, 12, 0, 16, 16, 16), TOP_SHAPE_DOWN = makeCuboidShape(0, 0, 0, 16, 4, 16),
TOP_SHAPE_EAST = makeCuboidShape(12, 0, 0, 16, 16, 16),
TOP_SHAPE_WEST = makeCuboidShape(0, 0, 0, 4, 16, 16),
TOP_SHAPE_SOUTH = makeCuboidShape(0, 0, 12, 16, 16, 16),
TOP_SHAPE_NORTH = makeCuboidShape(0, 0, 0, 16, 16, 4),
EXTENSION_SHAPE_UP = VoxelShapes.or(AXIS_SHAPE_Y, TOP_SHAPE_UP),
EXTENSION_SHAPE_DOWN = VoxelShapes.or(AXIS_SHAPE_Y, TOP_SHAPE_DOWN),
EXTENSION_SHAPE_EAST = VoxelShapes.or(AXIS_SHAPE_X, TOP_SHAPE_EAST),
EXTENSION_SHAPE_WEST = VoxelShapes.or(AXIS_SHAPE_X, TOP_SHAPE_WEST),
EXTENSION_SHAPE_SOUTH = VoxelShapes.or(AXIS_SHAPE_Z, TOP_SHAPE_SOUTH),
EXTENSION_SHAPE_NORTH = VoxelShapes.or(AXIS_SHAPE_Z, TOP_SHAPE_NORTH);
public MechanicalPistonHeadBlock() {
super(Properties.from(Blocks.PISTON_HEAD));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(TYPE, FACING);
super.fillStateContainer(builder);
}
@Override
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
PlayerEntity player) {
return new ItemStack(AllBlocks.PISTON_POLE.get());
}
@Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
Direction direction = state.get(FACING);
BlockPos pistonHead = pos;
BlockPos pistonBase = null;
for (int offset = 1; offset < Construct.MAX_EXTENSIONS; offset++) {
BlockPos currentPos = pos.offset(direction.getOpposite(), offset);
BlockState block = worldIn.getBlockState(currentPos);
if (AllBlocks.PISTON_POLE.typeOf(block)
&& direction.getAxis() == block.get(BlockStateProperties.FACING).getAxis())
continue;
if ((AllBlocks.MECHANICAL_PISTON.typeOf(block) || AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(block))
&& block.get(BlockStateProperties.FACING) == direction) {
pistonBase = currentPos;
}
break;
}
if (pistonHead != null && pistonBase != null) {
final BlockPos basePos = pistonBase;
BlockPos.getAllInBox(pistonBase, pistonHead).filter(p -> !p.equals(pos) && !p.equals(basePos))
.forEach(p -> worldIn.destroyBlock(p, !player.isCreative()));
worldIn.setBlockState(basePos,
worldIn.getBlockState(basePos).with(MechanicalPistonBlock.STATE, PistonState.RETRACTED));
}
super.onBlockHarvested(worldIn, pos, state, player);
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
switch (state.get(FACING)) {
case DOWN:
return EXTENSION_SHAPE_DOWN;
case EAST:
return EXTENSION_SHAPE_EAST;
case NORTH:
return EXTENSION_SHAPE_NORTH;
case SOUTH:
return EXTENSION_SHAPE_SOUTH;
case UP:
return EXTENSION_SHAPE_UP;
case WEST:
return EXTENSION_SHAPE_WEST;
}
return VoxelShapes.empty();
}
}

View file

@ -0,0 +1,287 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
public class MechanicalPistonTileEntity extends KineticTileEntity implements ITickableTileEntity {
protected static List<MechanicalPistonTileEntity> movingPistons = new ArrayList<>();
protected Construct movingConstruct;
protected float offset;
protected boolean running;
protected boolean assembleNextTick;
protected boolean hadCollisionWithOtherPiston;
public MechanicalPistonTileEntity() {
super(AllTileEntities.MECHANICAL_PISTON.type);
}
@Override
public boolean hasFastRenderer() {
return true;
}
@Override
public void onSpeedChanged() {
super.onSpeedChanged();
assembleNextTick = true;
}
@Override
public AxisAlignedBB getRenderBoundingBox() {
return INFINITE_EXTENT_AABB;
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.putBoolean("Running", running);
tag.putFloat("Offset", offset);
if (running)
tag.put("Construct", movingConstruct.writeNBT());
return super.write(tag);
}
@Override
public void read(CompoundNBT tag) {
running = tag.getBoolean("Running");
offset = tag.getFloat("Offset");
if (running)
movingConstruct = Construct.fromNBT(tag.getCompound("Construct"));
super.read(tag);
}
protected void onBlockVisited(float newOffset) {
Direction direction = getBlockState().get(BlockStateProperties.FACING);
for (BlockInfo block : movingConstruct.actors) {
IHaveMovementBehavior actor = (IHaveMovementBehavior) block.state.getBlock();
actor.visitPosition(world, block.pos.offset(direction, getModulatedOffset(newOffset)), block.state,
getMovementSpeed() > 0 ? direction : direction.getOpposite(), this);
}
}
public void assembleConstruct() {
Direction direction = getBlockState().get(BlockStateProperties.FACING);
// Collect Construct
movingConstruct = getMovementSpeed() < 0 ? Construct.getAttachedForPulling(getWorld(), getPos(), direction)
: Construct.getAttachedForPushing(getWorld(), getPos(), direction);
if (movingConstruct == null)
return;
// Check if not at limit already
float resultingOffset = movingConstruct.initialExtensionProgress + getMovementSpeed();
if (resultingOffset <= 0 || resultingOffset >= movingConstruct.extensionLength) {
movingConstruct = null;
return;
}
if (hasBlockCollisions(resultingOffset + .5f)) {
movingConstruct = null;
return;
}
// Run
running = true;
offset = movingConstruct.initialExtensionProgress;
movingPistons.add(this);
notifyBlockUpdate();
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
for (BlockInfo block : movingConstruct.blocks.values()) {
BlockPos startPos = block.pos.offset(direction, movingConstruct.initialExtensionProgress);
if (startPos.equals(pos))
continue;
getWorld().setBlockState(startPos, Blocks.AIR.getDefaultState(), 67);
}
onBlockVisited(offset);
}
public void disassembleConstruct() {
if (!running)
return;
Direction direction = getBlockState().get(BlockStateProperties.FACING);
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
for (BlockInfo block : movingConstruct.blocks.values()) {
BlockPos targetPos = block.pos.offset(direction, getModulatedOffset(offset));
BlockState state = block.state;
if (targetPos.equals(pos)) {
if (!AllBlocks.PISTON_POLE.typeOf(state))
getWorld().setBlockState(pos,
getBlockState().with(MechanicalPistonBlock.STATE, PistonState.RETRACTED), 3);
continue;
}
for (Direction face : Direction.values())
state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, targetPos,
targetPos.offset(face));
world.destroyBlock(targetPos, world.getBlockState(targetPos).getCollisionShape(world, targetPos).isEmpty());
getWorld().setBlockState(targetPos, state, 3);
}
running = false;
movingPistons.remove(this);
movingConstruct = null;
notifyBlockUpdate();
}
@Override
public void tick() {
if (!world.isRemote && assembleNextTick) {
assembleNextTick = false;
if (running) {
if (speed == 0)
disassembleConstruct();
return;
}
assembleConstruct();
return;
}
if (!running)
return;
float movementSpeed = getMovementSpeed();
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
float newOffset = offset + movementSpeed;
ConstructEntityHelper.moveEntities(this, movementSpeed, movementDirection, newOffset);
if (world.isRemote) {
offset = newOffset;
return;
}
if (getModulatedOffset(newOffset) != getModulatedOffset(offset)) {
onBlockVisited(newOffset);
}
float movement = .5f + (movementSpeed < 0 ? -1f : 0);
if (getModulatedOffset(newOffset + movement) != getModulatedOffset(offset + movement)) {
if (hasBlockCollisions(newOffset + movement)) {
disassembleConstruct();
if (hadCollisionWithOtherPiston)
hadCollisionWithOtherPiston = false;
else if (movementSpeed > 0)
assembleNextTick = true;
return;
}
}
offset = newOffset;
if (offset <= 0 || offset >= movingConstruct.extensionLength) {
disassembleConstruct();
return;
}
}
private boolean hasBlockCollisions(float newOffset) {
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
// Other moving Pistons
int maxPossibleRange = Construct.MAX_EXTENSIONS + Construct.MAX_CHAINED_BLOCKS + Construct.MAX_CHAINED_CHASSIS;
Iterator<MechanicalPistonTileEntity> iterator = movingPistons.iterator();
while (iterator.hasNext()) {
MechanicalPistonTileEntity otherPiston = iterator.next();
if (otherPiston == this)
continue;
if (!otherPiston.running || otherPiston.movingConstruct == null) {
iterator.remove();
continue;
}
if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
continue;
Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
getModulatedOffset(otherPiston.offset));
for (AxisAlignedBB thisBB : Arrays.asList(movingConstruct.collisionBoxFront,
movingConstruct.collisionBoxBack)) {
for (AxisAlignedBB otherBB : Arrays.asList(otherPiston.movingConstruct.collisionBoxFront,
otherPiston.movingConstruct.collisionBoxBack)) {
if (thisBB == null || otherBB == null)
continue;
if (thisBB.offset(relativePos).intersects(otherBB.offset(otherRelativePos))) {
hadCollisionWithOtherPiston = true;
return true;
}
if (otherMovementDirection == movementDirection.getOpposite()) {
if (thisBB.offset(relativePos.offset(movementDirection, getMovementSpeed() > 0 ? 1 : -1))
.intersects(otherBB.offset(otherRelativePos))) {
hadCollisionWithOtherPiston = true;
return true;
}
}
}
}
}
if (!running)
return false;
// Other Blocks in world
for (BlockPos pos : movingConstruct.getColliders(world,
getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
BlockPos colliderPos = pos.add(relativePos);
if (!world.isBlockPresent(colliderPos))
return true;
if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
&& !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
return true;
}
return false;
}
private int getModulatedOffset(float offset) {
return MathHelper.clamp((int) (offset + .5f), 0, movingConstruct.extensionLength);
}
public float getMovementSpeed() {
Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING);
int movementModifier = pistonDirection.getAxisDirection().getOffset()
* (pistonDirection.getAxis() == Axis.Z ? -1 : 1);
return getSpeed() * -movementModifier / 1024f;
}
public Vec3d getConstructOffset(float partialTicks) {
float interpolatedOffset = MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0,
movingConstruct.extensionLength);
return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(interpolatedOffset);
}
}

View file

@ -0,0 +1,84 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import org.lwjgl.opengl.GL11;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.simibubi.create.AllBlocks;
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.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
import net.minecraftforge.client.model.data.EmptyModelData;
public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer {
protected static Cache<Construct, ConstructVertexBuffer> cachedConstructs;
@Override
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
int destroyStage, BufferBuilder buffer) {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
// SPECIAL RENDER
MechanicalPistonTileEntity pistonTe = (MechanicalPistonTileEntity) te;
if (!pistonTe.running)
return;
cacheConstructIfMissing(pistonTe.movingConstruct);
renderConstructFromCache(pistonTe.movingConstruct, pistonTe, x, y, z, partialTicks, buffer);
}
protected void cacheConstructIfMissing(Construct c) {
if (cachedConstructs == null)
cachedConstructs = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();
if (cachedConstructs.getIfPresent(c) != null)
return;
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
Random random = new Random();
BufferBuilder builder = new BufferBuilder(0);
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
builder.setTranslation(0, 255, 0);
for (BlockInfo info : c.blocks.values()) {
IBakedModel originalModel = dispatcher.getModelForState(info.state);
blockRenderer.renderModel(getWorld(), originalModel, info.state, info.pos.down(255), builder, true, random,
42, EmptyModelData.INSTANCE);
}
builder.finishDrawing();
cachedConstructs.put(c, new ConstructVertexBuffer(builder.getByteBuffer()));
}
protected void renderConstructFromCache(Construct c, MechanicalPistonTileEntity te, double x, double y, double z,
float partialTicks, BufferBuilder buffer) {
final Vec3d offset = te.getConstructOffset(partialTicks);
buffer.putBulkData(cachedConstructs.getIfPresent(c).getTransformed(te,
(float) (x + offset.x - te.getPos().getX()), (float) (y + offset.y - te.getPos().getY()),
(float) (z + offset.z - te.getPos().getZ()), offset));
}
@Override
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return AllBlocks.AXIS.block.getDefaultState().with(BlockStateProperties.AXIS,
((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState()));
}
}

View file

@ -0,0 +1,112 @@
package com.simibubi.create.modules.contraptions.receivers.constructs;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock.PistonState;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class PistonPoleBlock extends DirectionalBlock {
public PistonPoleBlock() {
super(Properties.from(Blocks.PISTON_HEAD));
setDefaultState(getDefaultState().with(FACING, Direction.UP));
}
@Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
Axis axis = state.get(FACING).getAxis();
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
BlockPos pistonHead = null;
BlockPos pistonBase = null;
for (int modifier : new int[] { 1, -1 }) {
for (int offset = modifier; modifier * offset < Construct.MAX_EXTENSIONS; offset += modifier) {
BlockPos currentPos = pos.offset(direction, offset);
BlockState block = worldIn.getBlockState(currentPos);
if (AllBlocks.PISTON_POLE.typeOf(block) && axis == block.get(FACING).getAxis())
continue;
if ((AllBlocks.MECHANICAL_PISTON.typeOf(block) || AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(block))
&& block.get(BlockStateProperties.FACING).getAxis() == axis) {
pistonBase = currentPos;
}
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(block)
&& block.get(BlockStateProperties.FACING).getAxis() == axis) {
pistonHead = currentPos;
}
break;
}
}
if (pistonHead != null && pistonBase != null
&& worldIn.getBlockState(pistonHead).get(BlockStateProperties.FACING) == worldIn
.getBlockState(pistonBase).get(BlockStateProperties.FACING)) {
final BlockPos basePos = pistonBase;
BlockPos.getAllInBox(pistonBase, pistonHead).filter(p -> !p.equals(pos) && !p.equals(basePos))
.forEach(p -> worldIn.destroyBlock(p, !player.isCreative()));
worldIn.setBlockState(basePos,
worldIn.getBlockState(basePos).with(MechanicalPistonBlock.STATE, PistonState.RETRACTED));
}
super.onBlockHarvested(worldIn, pos, state, player);
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
switch (state.get(FACING).getAxis()) {
case X:
return MechanicalPistonHeadBlock.AXIS_SHAPE_X;
case Y:
return MechanicalPistonHeadBlock.AXIS_SHAPE_Y;
case Z:
return MechanicalPistonHeadBlock.AXIS_SHAPE_Z;
}
return VoxelShapes.empty();
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING);
super.fillStateContainer(builder);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return getDefaultState().with(FACING, context.getFace().getOpposite());
}
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
}

View file

@ -0,0 +1,128 @@
package com.simibubi.create.modules.contraptions.redstone;
import java.util.Random;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DirectionalBlock;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.TickPriority;
import net.minecraft.world.World;
public class ContactBlock extends DirectionalBlock implements IHaveMovementBehavior {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
public ContactBlock() {
super(Properties.from(Blocks.ANDESITE));
setDefaultState(getDefaultState().with(POWERED, false).with(FACING, Direction.UP));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(FACING, POWERED);
super.fillStateContainer(builder);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState state = getDefaultState().with(FACING, context.getNearestLookingDirection().getOpposite());
Direction placeDirection = context.getFace().getOpposite();
if (context.isPlacerSneaking() || hasValidContact(context.getWorld(), context.getPos(), placeDirection))
state = state.with(FACING, placeDirection);
if (hasValidContact(context.getWorld(), context.getPos(), state.get(FACING)))
state = state.with(POWERED, true);
return state;
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
if (facing != stateIn.get(FACING))
return stateIn;
boolean hasValidContact = hasValidContact(worldIn, currentPos, facing);
if (stateIn.get(POWERED) != hasValidContact) {
return stateIn.with(POWERED, hasValidContact);
}
return stateIn;
}
@SuppressWarnings("deprecation")
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.getBlock() == this && newState.getBlock() == this) {
if (state == newState.cycle(POWERED))
worldIn.notifyNeighborsOfStateChange(pos, this);
}
super.onReplaced(state, worldIn, pos, newState, isMoving);
}
@Override
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
boolean hasValidContact = hasValidContact(worldIn, pos, state.get(FACING));
if (state.get(POWERED) != hasValidContact)
worldIn.setBlockState(pos, state.with(POWERED, hasValidContact));
}
public static boolean hasValidContact(IWorld world, BlockPos pos, Direction direction) {
BlockState blockState = world.getBlockState(pos.offset(direction));
return AllBlocks.CONTACT.typeOf(blockState) && blockState.get(FACING) == direction.getOpposite();
}
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.with(FACING, rot.rotate(state.get(FACING)));
}
@Override
public BlockState mirror(BlockState state, Mirror mirrorIn) {
return state.rotate(mirrorIn.toRotation(state.get(FACING)));
}
@Override
public boolean canProvidePower(BlockState state) {
return state.get(POWERED);
}
@Override
public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) {
if (side == null)
return true;
return state.get(FACING) != side.getOpposite();
}
@Override
public int getWeakPower(BlockState state, IBlockReader blockAccess, BlockPos pos, Direction side) {
return state.get(POWERED) ? 15 : 0;
}
@Override
public boolean visitPosition(World world, BlockPos pos, BlockState block, Direction movement,
MechanicalPistonTileEntity piston) {
Direction direction = block.get(FACING);
if (!hasValidContact(world, pos, direction))
return false;
int ticksToStayActive = (int) Math.ceil(1 / Math.abs(piston.getMovementSpeed()));
world.setBlockState(pos.offset(direction), world.getBlockState(pos.offset(direction)).with(POWERED, true));
world.getPendingBlockTicks().scheduleTick(pos.offset(direction), this, ticksToStayActive, TickPriority.NORMAL);
return false;
}
}

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
@ -15,9 +15,9 @@ import net.minecraft.world.World;
public class AxisBlock extends RotatedPillarKineticBlock {
protected static final VoxelShape AXIS_X = makeCuboidShape(0, 5, 5, 16, 11, 11);
protected static final VoxelShape AXIS_Y = makeCuboidShape(5, 0, 5, 11, 16, 11);
protected static final VoxelShape AXIS_Z = makeCuboidShape(5, 5, 0, 11, 11, 16);
public static final VoxelShape AXIS_X = makeCuboidShape(0, 5, 5, 16, 11, 11);
public static final VoxelShape AXIS_Y = makeCuboidShape(5, 0, 5, 11, 16, 11);
public static final VoxelShape AXIS_Z = makeCuboidShape(5, 5, 0, 11, 11, 16);
public AxisBlock(Properties properties) {
super(properties);

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class AxisTileEntity extends KineticTileEntity {

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class AxisTunnelTileEntity extends KineticTileEntity {

View file

@ -1,8 +1,8 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;

View file

@ -1,18 +1,20 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.modules.kinetics.base.HorizontalKineticBlock;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity.TransportedEntityInfo;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity.TransportedEntityInfo;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer.Builder;
@ -23,6 +25,7 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.ISelectionContext;
@ -69,6 +72,12 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
setDefaultState(getDefaultState().with(SLOPE, Slope.HORIZONTAL).with(PART, Part.START));
}
@Override
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
PlayerEntity player) {
return new ItemStack(AllItems.BELT_CONNECTOR.item);
}
@Override
public void onLanded(IBlockReader worldIn, Entity entityIn) {
super.onLanded(worldIn, entityIn);

View file

@ -1,12 +1,12 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
@ -31,6 +31,11 @@ public class BeltItem extends Item {
@Override
public ActionResultType onItemUse(ItemUseContext context) {
if (context.isPlacerSneaking()) {
context.getItem().setTag(null);
return ActionResultType.SUCCESS;
}
World world = context.getWorld();
BlockPos pos = context.getPos();
boolean validAxis = validateAxis(world, pos);
@ -154,7 +159,7 @@ public class BeltItem extends Item {
te.setController(target);
}
private boolean canConnect(World world, BlockPos first, BlockPos second) {
public static boolean canConnect(World world, BlockPos first, BlockPos second) {
if (!world.isAreaLoaded(first, 1))
return false;
if (!world.isAreaLoaded(second, 1))
@ -177,16 +182,24 @@ public class BeltItem extends Item {
return false;
if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS))
return false;
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed();
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed();
if (speed1 != speed2 && speed1 != 0 && speed2 != 0)
return false;
BlockPos step = new BlockPos(Math.signum(diff.getX()), Math.signum(diff.getY()), Math.signum(diff.getZ()));
int limit = 1000;
for (BlockPos currentPos = first.add(step); !currentPos.equals(second)
&& limit-- > 0; currentPos = currentPos.add(step)) {
if (!world.getBlockState(currentPos).getMaterial().isReplaceable())
return false;
}
return true;
}
private boolean validateAxis(World world, BlockPos pos) {
public static boolean validateAxis(World world, BlockPos pos) {
if (!world.isAreaLoaded(pos, 1))
return false;
if (!AllBlocks.AXIS.typeOf(world.getBlockState(pos)))

View file

@ -0,0 +1,137 @@
package com.simibubi.create.modules.contraptions.relays;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.particles.RedstoneParticleData;
import net.minecraft.state.properties.BlockStateProperties;
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.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.RenderTickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT)
public class BeltItemHandler {
private static Random r = new Random();
@SubscribeEvent
public static void onRenderTick(RenderTickEvent event) {
if (event.phase == Phase.START)
return;
PlayerEntity player = Minecraft.getInstance().player;
World world = Minecraft.getInstance().world;
if (player == null || world == null)
return;
for (Hand hand : Hand.values()) {
ItemStack heldItem = player.getHeldItem(hand);
if (!AllItems.BELT_CONNECTOR.typeOf(heldItem))
continue;
if (!heldItem.hasTag())
continue;
CompoundNBT tag = heldItem.getTag();
if (!tag.contains("FirstPulley"))
continue;
BlockPos first = NBTUtil.readBlockPos(tag.getCompound("FirstPulley"));
if (!world.getBlockState(first).has(BlockStateProperties.AXIS))
continue;
Axis axis = world.getBlockState(first).get(BlockStateProperties.AXIS);
RayTraceResult rayTrace = Minecraft.getInstance().objectMouseOver;
if (rayTrace == null || !(rayTrace instanceof BlockRayTraceResult)) {
if (r.nextInt(50) == 0) {
world.addParticle(new RedstoneParticleData(.3f, .9f, .5f, 1),
first.getX() + .5f + randomOffset(.25f), first.getY() + .5f + randomOffset(.25f),
first.getZ() + .5f + randomOffset(.25f), 0, 0, 0);
}
return;
}
BlockPos selected = ((BlockRayTraceResult) rayTrace).getPos();
if (world.getBlockState(selected).getMaterial().isReplaceable())
return;
if (!AllBlocks.AXIS.typeOf(world.getBlockState(selected)))
selected = selected.offset(((BlockRayTraceResult) rayTrace).getFace());
if (!selected.withinDistance(first, BeltItem.MAX_PULLEY_DISTANCE))
return;
boolean canConnect = BeltItem.validateAxis(world, selected) && BeltItem.canConnect(world, first, selected);
Vec3d start = new Vec3d(first);
Vec3d end = new Vec3d(selected);
Vec3d actualDiff = end.subtract(start);
end = end.subtract(axis.getCoordinate(actualDiff.x, 0, 0), 0, axis.getCoordinate(0, 0, actualDiff.z));
Vec3d diff = end.subtract(start);
double x = Math.abs(diff.x);
double y = Math.abs(diff.y);
double z = Math.abs(diff.z);
Vec3d step = diff.normalize();
int sames = ((x == y) ? 1 : 0) + ((y == z) ? 1 : 0) + ((z == x) ? 1 : 0);
if (sames == 0) {
List<Vec3d> validDiffs = new LinkedList<>();
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
for (int k = -1; k <= 1; k++) {
if (axis.getCoordinate(i, j, k) != 0)
continue;
if (i == 0 && j == 0 && k == 0)
continue;
validDiffs.add(new Vec3d(i, j, k));
}
int closestIndex = 0;
float closest = Float.MAX_VALUE;
for (Vec3d validDiff : validDiffs) {
double distanceTo = step.distanceTo(validDiff);
if (distanceTo < closest) {
closest = (float) distanceTo;
closestIndex = validDiffs.indexOf(validDiff);
}
}
step = validDiffs.get(closestIndex);
}
for (float f = 0; f < actualDiff.length(); f += .25f) {
Vec3d position = start.add(step.scale(f));
if (r.nextInt(100) == 0) {
world.addParticle(new RedstoneParticleData(canConnect ? .3f : .9f, canConnect ? .9f : .3f, .5f, 1),
position.x + .5f, position.y + .5f, position.z + .5f, 0, 0, 0);
}
}
return;
}
}
private static float randomOffset(float range) {
return (r.nextFloat() - .5f) * 2 * range;
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import java.util.ArrayList;
import java.util.HashMap;
@ -7,9 +7,9 @@ import java.util.Map;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;

View file

@ -1,13 +1,13 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import java.nio.ByteBuffer;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.BufferManipulator;
import com.simibubi.create.modules.kinetics.base.IRotate;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
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.BlockState;
import net.minecraft.client.Minecraft;
@ -17,7 +17,6 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation;
public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
@ -28,19 +27,17 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
public BeltModelAnimator(ByteBuffer template) {
super(template);
if (beltTextures == null)
initSprites();
}
private void initSprites() {
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
originalTexture = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt"));
beltTextures = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt_animated"));
}
public ByteBuffer getTransformed(Vec3d translation, BeltTileEntity te) {
public ByteBuffer getTransformed(BeltTileEntity te, float x, float y, float z) {
original.rewind();
mutable.rewind();
@ -62,17 +59,19 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
}
final BlockState blockState = te.getBlockState();
final int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
final float texOffX = textureOffsetX;
final float texOffY = textureOffsetY;
forEachVertex(original, index -> {
Vec3d pos = getPos(original, index);
putPos(mutable, index, pos.add(translation));
mutable.putFloat(index + 16, original.getFloat(index + 16) + texOffX);
mutable.putFloat(index + 20, original.getFloat(index + 20) + texOffY);
mutable.putInt(index + 24, packedLightCoords);
});
int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
float texOffX = textureOffsetX;
float texOffY = textureOffsetY;
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
putPos(mutable, vertex, getX(original, vertex) + x, getY(original, vertex) + y,
getZ(original, vertex) + z);
putLight(mutable, vertex, packedLightCoords);
int bufferPosition = getBufferPosition(vertex);
mutable.putFloat(bufferPosition + 16, original.getFloat(bufferPosition + 16) + texOffX);
mutable.putFloat(bufferPosition + 20, original.getFloat(bufferPosition + 20) + texOffY);
}
return mutable;
}
@ -87,16 +86,16 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
cacheIfMissing(beltEntity.getBlockState(), BeltModelAnimator::new);
renderBeltFromCache(beltEntity, new Vec3d(x, y, z), buffer);
renderBeltFromCache(beltEntity, (float) x, (float) y, (float) z, buffer);
}
@Override
protected BlockState getRenderedBlockState(KineticTileEntity te) {
return AllBlocks.AXIS.get().getDefaultState().with(BlockStateProperties.AXIS,
return AllBlocks.BELT_PULLEY.get().getDefaultState().with(BlockStateProperties.AXIS,
((IRotate) AllBlocks.BELT.get()).getRotationAxis(te.getBlockState()));
}
public void renderBeltFromCache(BeltTileEntity te, Vec3d translation, BufferBuilder buffer) {
buffer.putBulkData(((BeltModelAnimator) cachedBuffers.get(te.getBlockState())).getTransformed(translation, te));
public void renderBeltFromCache(BeltTileEntity te, float x, float y, float z, BufferBuilder buffer) {
buffer.putBulkData(((BeltModelAnimator) cachedBuffers.get(te.getBlockState())).getTransformed(te, x, y, z));
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllBlocks;

View file

@ -0,0 +1,106 @@
package com.simibubi.create.modules.contraptions.relays;
import com.google.common.base.Predicates;
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.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
public class EncasedBeltBlock extends RotatedPillarKineticBlock {
public static final BooleanProperty CONNECTED = BooleanProperty.create("attached");
public static final DirectionProperty CONNECTED_FACE = DirectionProperty.create("attach_face",
Predicates.alwaysTrue());
public EncasedBeltBlock() {
super(Properties.from(Blocks.ANDESITE));
setDefaultState(getDefaultState().with(CONNECTED, false));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(CONNECTED, CONNECTED_FACE);
}
@Override
public boolean isSolid(BlockState state) {
return false;
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState state = getDefaultState().with(AXIS, context.getNearestLookingDirection().getAxis());
for (Direction face : Direction.values()) {
BlockState neighbour = context.getWorld().getBlockState(context.getPos().offset(face));
if (neighbour.getBlock() != this || neighbour.get(CONNECTED))
continue;
if (neighbour.get(AXIS) == face.getAxis())
continue;
if (state.get(AXIS) == face.getAxis())
continue;
return state.with(CONNECTED, true).with(CONNECTED_FACE, face);
}
return state;
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction face, BlockState neighbour, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
if (neighbour.getBlock() != this || !neighbour.get(CONNECTED))
return stateIn;
if (neighbour.get(CONNECTED_FACE) != face.getOpposite())
return stateIn;
if (neighbour.get(AXIS) == face.getAxis())
return stateIn;
return stateIn.with(CONNECTED, true).with(CONNECTED_FACE, face);
}
@SuppressWarnings("deprecation")
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
super.onReplaced(state, worldIn, pos, newState, isMoving);
if (!state.get(CONNECTED))
return;
BlockPos attached = pos.offset(state.get(CONNECTED_FACE));
BlockState attachedState = worldIn.getBlockState(attached);
if (attachedState.getBlock() == this)
worldIn.setBlockState(attached, attachedState.with(CONNECTED, false), 3);
}
@Override
public boolean isAxisTowards(World world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() == state.get(AXIS);
}
@Override
public Axis getRotationAxis(BlockState state) {
return state.get(AXIS);
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new AxisTunnelTileEntity();
}
@Override
protected boolean hasStaticPart() {
return true;
}
}

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class GearboxTileEntity extends KineticTileEntity {

View file

@ -1,8 +1,8 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
@ -11,7 +11,6 @@ import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation;
public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
@ -22,7 +21,6 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
final BlockPos pos = te.getPos();
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
final Vec3d translation = new Vec3d(x, y, z);
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
for (Direction direction : Direction.values()) {
@ -50,7 +48,7 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
angle += offset;
angle = angle / 180f * (float) Math.PI;
renderFromCache(buffer, state, translation, pos, axis, angle);
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
}
}

View file

@ -1,4 +1,7 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -46,6 +49,7 @@ public class GearshifterBlock extends AxisTunnelBlock {
boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos));
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
}
}

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class GearshifterTileEntity extends KineticTileEntity {

View file

@ -1,8 +1,8 @@
package com.simibubi.create.modules.kinetics.relays;
package com.simibubi.create.modules.contraptions.relays;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
@ -11,7 +11,6 @@ import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation;
public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
@ -22,7 +21,6 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
final BlockPos pos = te.getPos();
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
final Vec3d translation = new Vec3d(x, y, z);
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
for (Direction direction : Direction.values()) {
@ -44,7 +42,7 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
angle += offset;
angle = angle / 180f * (float) Math.PI;
renderFromCache(buffer, state, translation, pos, axis, angle);
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
}
}

View file

@ -144,9 +144,10 @@ public class BlueprintItem extends Item {
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
if (playerIn.isSneaking() && handIn == Hand.MAIN_HAND) {
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
displayBlueprintScreen();
});
if (playerIn.getHeldItem(handIn).hasTag())
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
displayBlueprintScreen();
});
return new ActionResult<ItemStack>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn));
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/andesite_bricks" }
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"axis=y": { "model": "create:block/belt_pulley" },
"axis=z": { "model": "create:block/belt_pulley", "x": 90 },
"axis=x": { "model": "create:block/belt_pulley", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,11 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/construct_normal"
},
"variants": {
"axis=y": { "model": "create:block/construct_normal" },
"axis=z": { "model": "create:block/construct_normal", "x": 90 },
"axis=x": { "model": "create:block/construct_normal", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,17 @@
{
"variants": {
"powered=false,facing=up": { "model": "create:block/contact" },
"powered=false,facing=down": { "model": "create:block/contact", "x": 180 },
"powered=false,facing=north": { "model": "create:block/contact", "x": 90 },
"powered=false,facing=south": { "model": "create:block/contact", "x": 90, "y": 180 },
"powered=false,facing=east": { "model": "create:block/contact", "x": 90, "y": 90 },
"powered=false,facing=west": { "model": "create:block/contact", "x": 90, "y": 270 },
"powered=true,facing=up": { "model": "create:block/contact_powered" },
"powered=true,facing=down": { "model": "create:block/contact_powered", "x": 180 },
"powered=true,facing=north": { "model": "create:block/contact_powered", "x": 90 },
"powered=true,facing=south": { "model": "create:block/contact_powered", "x": 90, "y": 180 },
"powered=true,facing=east": { "model": "create:block/contact_powered", "x": 90, "y": 90 },
"powered=true,facing=west": { "model": "create:block/contact_powered", "x": 90, "y": 270 }
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"axis=y": { "model": "create:block/crushing_wheel" },
"axis=z": { "model": "create:block/crushing_wheel", "x": 90 },
"axis=x": { "model": "create:block/crushing_wheel", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/diorite_bricks" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/dolomite" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/dolomite_bricks" }
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"axis=y": { "model": "create:block/palettes/dolomite_pillar" },
"axis=z": { "model": "create:block/palettes/dolomite_pillar", "x": 90 },
"axis=x": { "model": "create:block/palettes/dolomite_pillar", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,17 @@
{
"variants": {
"fixated=false,facing=up": { "model": "create:block/drill", "x": 90 },
"fixated=false,facing=down": { "model": "create:block/drill", "x": 270 },
"fixated=false,facing=north": { "model": "create:block/drill", "y": 180 },
"fixated=false,facing=south": { "model": "create:block/drill" },
"fixated=false,facing=east": { "model": "create:block/drill", "y": 270 },
"fixated=false,facing=west": { "model": "create:block/drill", "y": 90 },
"fixated=true,facing=up": { "model": "create:block/drill_fixated", "x": 90 },
"fixated=true,facing=down": { "model": "create:block/drill_fixated", "x": 270 },
"fixated=true,facing=north": { "model": "create:block/drill_fixated", "y": 180 },
"fixated=true,facing=south": { "model": "create:block/drill_fixated" },
"fixated=true,facing=east": { "model": "create:block/drill_fixated", "y": 270 },
"fixated=true,facing=west": { "model": "create:block/drill_fixated", "y": 90 }
}
}

View file

@ -0,0 +1,45 @@
{
"variants": {
"attached=false,attach_face=up,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=down,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=east,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=west,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=north,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=south,axis=y": { "model": "create:block/encased_belt", "x": 90 },
"attached=false,attach_face=up,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=down,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=east,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=west,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=north,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=south,axis=z": { "model": "create:block/encased_belt"},
"attached=false,attach_face=up,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=false,attach_face=down,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=false,attach_face=east,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=false,attach_face=west,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=false,attach_face=north,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=false,attach_face=south,axis=x": { "model": "create:block/encased_belt", "y": 90 },
"attached=true,attach_face=up,axis=y": { "model": "block/dirt" },
"attached=true,attach_face=down,axis=y": { "model": "block/dirt" },
"attached=true,attach_face=east,axis=y": { "model": "create:block/encased_belt_attached_vertical", "y": 270 },
"attached=true,attach_face=west,axis=y": { "model": "create:block/encased_belt_attached_vertical", "y": 90 },
"attached=true,attach_face=north,axis=y": { "model": "create:block/encased_belt_attached_vertical", "y": 180 },
"attached=true,attach_face=south,axis=y": { "model": "create:block/encased_belt_attached_vertical", "y": 0 },
"attached=true,attach_face=up,axis=z": { "model": "create:block/encased_belt_attached_horizontal", "x": 270, "y": 90 },
"attached=true,attach_face=down,axis=z": { "model": "create:block/encased_belt_attached_horizontal", "x": 90, "y": 90 },
"attached=true,attach_face=east,axis=z": { "model": "create:block/encased_belt_attached_horizontal", "x": 0, "y": 90 },
"attached=true,attach_face=west,axis=z": { "model": "create:block/encased_belt_attached_horizontal", "x": 180, "y": 90 },
"attached=true,attach_face=north,axis=z": { "model": "block/dirt"},
"attached=true,attach_face=south,axis=z": { "model": "block/dirt"},
"attached=true,attach_face=up,axis=x": { "model": "create:block/encased_belt_attached_horizontal", "x": 270 },
"attached=true,attach_face=down,axis=x": { "model": "create:block/encased_belt_attached_horizontal", "x": 90 },
"attached=true,attach_face=east,axis=x": { "model": "block/dirt" },
"attached=true,attach_face=west,axis=x": { "model": "block/dirt" },
"attached=true,attach_face=north,axis=x": { "model": "create:block/encased_belt_attached_horizontal", "x": 0 },
"attached=true,attach_face=south,axis=x": { "model": "create:block/encased_belt_attached_horizontal", "x": 180 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/gabbro" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/gabbro_bricks" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/granite_bricks" }
}
}

View file

@ -0,0 +1,8 @@
{
"variants": {
"facing=north": { "model": "create:block/harvester", "y": 180 },
"facing=south": { "model": "create:block/harvester" },
"facing=east": { "model": "create:block/harvester", "y": 270 },
"facing=west": { "model": "create:block/harvester", "y": 90 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/indented_gabbro" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/limestone" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/limestone_bricks" }
}
}

View file

@ -0,0 +1,7 @@
{
"variants": {
"axis=z": { "model": "create:block/palettes/limestone_pillar", "x": 90 },
"axis=y": { "model": "create:block/palettes/limestone_pillar" },
"axis=x": { "model": "create:block/palettes/limestone_pillar", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,50 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/mechanical_piston"
},
"variants": {
"axis_along_first=false,state=retracted,facing=south": { "model": "create:block/mechanical_piston", "x": 90, "y": 180 },
"axis_along_first=false,state=retracted,facing=north": { "model": "create:block/mechanical_piston", "x": 90 },
"axis_along_first=false,state=retracted,facing=west": { "model": "create:block/mechanical_piston/rotated", "x": 90, "y": 270 },
"axis_along_first=false,state=retracted,facing=up": { "model": "create:block/mechanical_piston" },
"axis_along_first=false,state=retracted,facing=down": { "model": "create:block/mechanical_piston", "x": 180 },
"axis_along_first=false,state=retracted,facing=east": { "model": "create:block/mechanical_piston/rotated", "x": 90, "y": 90 },
"axis_along_first=false,state=moving,facing=south": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 180 },
"axis_along_first=false,state=moving,facing=north": { "model": "create:block/mechanical_piston/base", "x": 90 },
"axis_along_first=false,state=moving,facing=west": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 270 },
"axis_along_first=false,state=moving,facing=up": { "model": "create:block/mechanical_piston/base" },
"axis_along_first=false,state=moving,facing=down": { "model": "create:block/mechanical_piston/base", "x": 180 },
"axis_along_first=false,state=moving,facing=east": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 90 },
"axis_along_first=false,state=extended,facing=south": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 180 },
"axis_along_first=false,state=extended,facing=north": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90 },
"axis_along_first=false,state=extended,facing=west": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 270 },
"axis_along_first=false,state=extended,facing=up": { "model": "create:block/mechanical_piston/base_with_extension" },
"axis_along_first=false,state=extended,facing=down": { "model": "create:block/mechanical_piston/base_with_extension", "x": 180 },
"axis_along_first=false,state=extended,facing=east": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 90 },
"axis_along_first=true,state=retracted,facing=south": { "model": "create:block/mechanical_piston/rotated", "x": 90, "y": 180 },
"axis_along_first=true,state=retracted,facing=north": { "model": "create:block/mechanical_piston/rotated", "x": 90 },
"axis_along_first=true,state=retracted,facing=west": { "model": "create:block/mechanical_piston", "x": 90, "y": 270 },
"axis_along_first=true,state=retracted,facing=up": { "model": "create:block/mechanical_piston/rotated" },
"axis_along_first=true,state=retracted,facing=down": { "model": "create:block/mechanical_piston/rotated", "x": 180 },
"axis_along_first=true,state=retracted,facing=east": { "model": "create:block/mechanical_piston", "x": 90, "y": 90 },
"axis_along_first=true,state=moving,facing=south": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 180 },
"axis_along_first=true,state=moving,facing=north": { "model": "create:block/mechanical_piston/base_rotated", "x": 90 },
"axis_along_first=true,state=moving,facing=west": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 270 },
"axis_along_first=true,state=moving,facing=up": { "model": "create:block/mechanical_piston/base_rotated" },
"axis_along_first=true,state=moving,facing=down": { "model": "create:block/mechanical_piston/base_rotated", "x": 180 },
"axis_along_first=true,state=moving,facing=east": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 90 },
"axis_along_first=true,state=extended,facing=south": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 180 },
"axis_along_first=true,state=extended,facing=north": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90 },
"axis_along_first=true,state=extended,facing=west": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 270 },
"axis_along_first=true,state=extended,facing=up": { "model": "create:block/mechanical_piston/base_with_extension_rotated" },
"axis_along_first=true,state=extended,facing=down": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 180 },
"axis_along_first=true,state=extended,facing=east": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,21 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/mechanical_piston_head"
},
"variants": {
"type=normal,facing=south": { "model": "create:block/mechanical_piston_head", "x": 90, "y": 180 },
"type=normal,facing=north": { "model": "create:block/mechanical_piston_head", "x": 90 },
"type=normal,facing=west": { "model": "create:block/mechanical_piston_head", "x": 90, "y": 270 },
"type=normal,facing=up": { "model": "create:block/mechanical_piston_head" },
"type=normal,facing=down": { "model": "create:block/mechanical_piston_head", "x": 180 },
"type=normal,facing=east": { "model": "create:block/mechanical_piston_head", "x": 90, "y": 90 },
"type=sticky,facing=south": { "model": "create:block/mechanical_piston_head_sticky", "x": 90, "y": 180 },
"type=sticky,facing=north": { "model": "create:block/mechanical_piston_head_sticky", "x": 90 },
"type=sticky,facing=west": { "model": "create:block/mechanical_piston_head_sticky", "x": 90, "y": 270 },
"type=sticky,facing=up": { "model": "create:block/mechanical_piston_head_sticky" },
"type=sticky,facing=down": { "model": "create:block/mechanical_piston_head_sticky", "x": 180 },
"type=sticky,facing=east": { "model": "create:block/mechanical_piston_head_sticky", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/mossy_gabbro_bricks" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/paved_gabbro_bricks" }
}
}

View file

@ -0,0 +1,10 @@
{
"variants": {
"facing=up": { "model": "create:block/mechanical_piston/pole" },
"facing=down": { "model": "create:block/mechanical_piston/pole" , "x": 180 },
"facing=south": { "model": "create:block/mechanical_piston/pole", "x": 90, "y": 180 },
"facing=north": { "model": "create:block/mechanical_piston/pole", "x": 90, "y": 0 },
"facing=east": { "model": "create:block/mechanical_piston/pole", "x": 90, "y": 90 },
"facing=west": { "model": "create:block/mechanical_piston/pole", "x": 90, "y": 270 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/polished_dolomite" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/polished_gabbro" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/polished_limestone" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/polished_quartziorite" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/quartziorite" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/quartziorite_bricks" }
}
}

View file

@ -0,0 +1,11 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/construct_relocating"
},
"variants": {
"axis=y": { "model": "create:block/construct_relocating" },
"axis=z": { "model": "create:block/construct_relocating", "x": 90 },
"axis=x": { "model": "create:block/construct_relocating", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "create:block/palettes/slightly_mossy_gabbro_bricks" }
}
}

View file

@ -0,0 +1,11 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/construct_sticky"
},
"variants": {
"axis=y": { "model": "create:block/construct_sticky" },
"axis=z": { "model": "create:block/construct_sticky", "x": 90 },
"axis=x": { "model": "create:block/construct_sticky", "x": 90, "y": 90 }
}
}

View file

@ -0,0 +1,50 @@
{
"forgemarker": 1,
"defaults": {
"model": "create:block/mechanical_piston_sticky"
},
"variants": {
"axis_along_first=false,state=retracted,facing=south": { "model": "create:block/mechanical_piston_sticky", "x": 90, "y": 180 },
"axis_along_first=false,state=retracted,facing=north": { "model": "create:block/mechanical_piston_sticky", "x": 90 },
"axis_along_first=false,state=retracted,facing=west": { "model": "create:block/mechanical_piston/rotated_sticky", "x": 90, "y": 270 },
"axis_along_first=false,state=retracted,facing=up": { "model": "create:block/mechanical_piston_sticky" },
"axis_along_first=false,state=retracted,facing=down": { "model": "create:block/mechanical_piston_sticky", "x": 180 },
"axis_along_first=false,state=retracted,facing=east": { "model": "create:block/mechanical_piston/rotated_sticky", "x": 90, "y": 90 },
"axis_along_first=false,state=moving,facing=south": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 180 },
"axis_along_first=false,state=moving,facing=north": { "model": "create:block/mechanical_piston/base", "x": 90 },
"axis_along_first=false,state=moving,facing=west": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 270 },
"axis_along_first=false,state=moving,facing=up": { "model": "create:block/mechanical_piston/base" },
"axis_along_first=false,state=moving,facing=down": { "model": "create:block/mechanical_piston/base", "x": 180 },
"axis_along_first=false,state=moving,facing=east": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 90 },
"axis_along_first=false,state=extended,facing=south": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 180 },
"axis_along_first=false,state=extended,facing=north": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90 },
"axis_along_first=false,state=extended,facing=west": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 270 },
"axis_along_first=false,state=extended,facing=up": { "model": "create:block/mechanical_piston/base_with_extension" },
"axis_along_first=false,state=extended,facing=down": { "model": "create:block/mechanical_piston/base_with_extension", "x": 180 },
"axis_along_first=false,state=extended,facing=east": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 90 },
"axis_along_first=true,state=retracted,facing=south": { "model": "create:block/mechanical_piston/rotated_sticky", "x": 90, "y": 180 },
"axis_along_first=true,state=retracted,facing=north": { "model": "create:block/mechanical_piston/rotated_sticky", "x": 90 },
"axis_along_first=true,state=retracted,facing=west": { "model": "create:block/mechanical_piston_sticky", "x": 90, "y": 270 },
"axis_along_first=true,state=retracted,facing=up": { "model": "create:block/mechanical_piston/rotated_sticky" },
"axis_along_first=true,state=retracted,facing=down": { "model": "create:block/mechanical_piston/rotated_sticky", "x": 180 },
"axis_along_first=true,state=retracted,facing=east": { "model": "create:block/mechanical_piston_sticky", "x": 90, "y": 90 },
"axis_along_first=true,state=moving,facing=south": { "model": "create:block/mechanical_piston/base_rotated", "x": 90, "y": 180 },
"axis_along_first=true,state=moving,facing=north": { "model": "create:block/mechanical_piston/base_rotated", "x": 90 },
"axis_along_first=true,state=moving,facing=west": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 270 },
"axis_along_first=true,state=moving,facing=up": { "model": "create:block/mechanical_piston/base_rotated" },
"axis_along_first=true,state=moving,facing=down": { "model": "create:block/mechanical_piston/base_rotated", "x": 180 },
"axis_along_first=true,state=moving,facing=east": { "model": "create:block/mechanical_piston/base", "x": 90, "y": 90 },
"axis_along_first=true,state=extended,facing=south": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90, "y": 180 },
"axis_along_first=true,state=extended,facing=north": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 90 },
"axis_along_first=true,state=extended,facing=west": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 270 },
"axis_along_first=true,state=extended,facing=up": { "model": "create:block/mechanical_piston/base_with_extension_rotated" },
"axis_along_first=true,state=extended,facing=down": { "model": "create:block/mechanical_piston/base_with_extension_rotated", "x": 180 },
"axis_along_first=true,state=extended,facing=east": { "model": "create:block/mechanical_piston/base_with_extension", "x": 90, "y": 90 }
}
}

View file

@ -9,17 +9,55 @@
"item.create.blueprint_and_quill": "Schematic and Quill",
"item.create.blueprint": "Schematic",
"item.create.belt_connector": "Mechanical Belt",
"block.create.gear": "Cogwheel",
"block.create.large_gear": "Large Cogwheel",
"block.create.turntable": "Turntable",
"block.create.gearbox": "Gearbox",
"block.create.gearshifter": "Gearshifter",
"block.create.axis_tunnel": "Encased Axis",
"block.create.axis": "Axis",
"block.create.encased_belt": "Encased Belt",
"block.create.axis_tunnel": "Encased Axis",
"block.create.motor": "Motor",
"block.create.belt": "Mechanical Belt",
"block.create.crushing_wheel": "Crushing Wheel",
"block.create.drill": "Mechanical Drill",
"block.create.harvester": "Mechanical Harvester",
"block.create.contact": "Redstone Contact",
"block.create.sticky_mechanical_piston": "Sticky Mechanical Piston",
"block.create.mechanical_piston": "Mechanical Piston",
"block.create.mechanical_piston_head": "Mechanical Piston Head",
"block.create.piston_pole": "Piston Extension Pole",
"block.create.construct": "Movement Chassis",
"block.create.sticky_construct": "Sticky Chassis",
"block.create.relocation_construct": "Relocation Chassis",
"block.create.andesite_bricks": "Andesite Bricks",
"block.create.diorite_bricks": "Diorite Bricks",
"block.create.granite_bricks": "Granite Bricks",
"block.create.gabbro": "Gabbro",
"block.create.polished_gabbro": "Polished Gabbro",
"block.create.gabbro_bricks": "Gabbro Bricks",
"block.create.paved_gabbro_bricks": "Paved Gabbro Bricks",
"block.create.indented_gabbro": "Indented Gabbro Tile",
"block.create.slightly_mossy_gabbro_bricks": "Mossy Gabbro Bricks",
"block.create.mossy_gabbro_bricks": "Overgrown Gabbro Bricks",
"block.create.limestone": "Limestone",
"block.create.polished_limestone": "Polished Limestone",
"block.create.limestone_bricks": "Limestone Bricks",
"block.create.limestone_pillar": "Limestone Pillar",
"block.create.quartziorite": "Quartziorite",
"block.create.quartziorite_bricks": "Quartziorite Bricks",
"block.create.polished_quartziorite": "Polished Quartziorite",
"block.create.dolomite": "Dolomite",
"block.create.dolomite_bricks": "Dolomite Bricks",
"block.create.polished_dolomite": "Polished Dolomite",
"block.create.dolomite_pillar": "Dolomite Pillar",
"block.create.schematicannon": "Schematicannon",
"block.create.schematic_table": "Schematic Table",
"block.create.creative_crate": "Schematicannon Creatifier",
"itemGroup.create": "Create"
}

View file

@ -11,6 +11,7 @@
"name": "Axis",
"from": [ 6.0, 0.0, 6.0 ],
"to": [ 10.0, 16.0, 10.0 ],
"shade": false,
"faces": {
"north": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
"east": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },

View file

@ -11,6 +11,7 @@
"name": "Axis",
"from": [ 6.0, 8.0, 6.0 ],
"to": [ 10.0, 16.0, 10.0 ],
"shade": false,
"faces": {
"north": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 8.0 ] },
"east": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 8.0 ] },

View file

@ -0,0 +1,54 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
"parent": "block/cube",
"textures": {
"particle": "block/stripped_spruce_log",
"0": "create:block/axis",
"1": "create:block/axis_top",
"2": "block/stripped_spruce_log",
"3": "block/stripped_spruce_log_top"
},
"elements": [
{
"name": "Axis",
"from": [ 6.0, 0.0, 6.0 ],
"to": [ 10.0, 16.0, 10.0 ],
"shade": false,
"faces": {
"north": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
"east": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
"south": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
"west": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
"up": { "texture": "#1", "uv": [ 6.0, 6.0, 10.0, 10.0 ] },
"down": { "texture": "#1", "uv": [ 6.0, 6.0, 10.0, 10.0 ] }
}
},
{
"name": "Pulley",
"from": [ 5.0, 2.0, 5.0 ],
"to": [ 11.0, 14.0, 11.0 ],
"faces": {
"north": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 14.0 ] },
"east": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 14.0 ] },
"south": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 14.0 ] },
"west": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 14.0 ] },
"up": { "texture": "#3", "uv": [ 5.0, 5.0, 11.0, 11.0 ] },
"down": { "texture": "#3", "uv": [ 5.0, 5.0, 11.0, 11.0 ] }
}
},
{
"name": "Pulley2",
"from": [ 5.0, 2.5000000074505806, 5.0 ],
"to": [ 11.0, 13.50000000745058, 11.0 ],
"rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": 45.0 },
"faces": {
"north": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 13.0 ] },
"east": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 13.0 ] },
"south": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 13.0 ] },
"west": { "texture": "#2", "uv": [ 5.0, 2.0, 11.0, 13.0 ] },
"up": { "texture": "#3", "uv": [ 5.0, 5.0, 11.0, 11.0 ] },
"down": { "texture": "#3", "uv": [ 5.0, 5.0, 11.0, 11.0 ] }
}
}
]
}

View file

@ -0,0 +1,60 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
"parent": "block/cube",
"textures": {
"particle": "create:block/construct_side",
"0": "create:block/construct_side",
"1": "block/stripped_spruce_log_top",
"2": "block/stripped_spruce_log"
},
"elements": [
{
"name": "Bottom",
"from": [ 0.0, 0.0, 0.0 ],
"to": [ 16.0, 3.0, 16.0 ],
"faces": {
"north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"east": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"west": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"down": { "texture": "#2", "uv": [ 0.0, 0.0, 16.0, 16.0 ] }
}
},
{
"name": "Top",
"from": [ 0.0, 13.0, 0.0 ],
"to": [ 16.0, 16.0, 16.0 ],
"faces": {
"north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"east": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"west": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 3.0 ] },
"up": { "texture": "#2", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"down": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] }
}
},
{
"name": "Core",
"from": [ 2.0, 3.0, 2.0 ],
"to": [ 14.0, 13.0, 14.0 ],
"faces": {
"north": { "texture": "#inner", "uv": [ 2.0, 0.0, 14.0, 10.0 ] },
"east": { "texture": "#inner", "uv": [ 2.0, 0.0, 14.0, 10.0 ] },
"south": { "texture": "#inner", "uv": [ 2.0, 0.0, 14.0, 10.0 ] },
"west": { "texture": "#inner", "uv": [ 2.0, 0.0, 14.0, 10.0 ] }
}
},
{
"name": "Coat",
"from": [ 0.0, 3.0, 0.0 ],
"to": [ 16.0, 13.0, 16.0 ],
"faces": {
"north": { "texture": "#0", "uv": [ 0.0, 3.0, 16.0, 13.0 ], "cullface": "north" },
"east": { "texture": "#0", "uv": [ 0.0, 3.0, 16.0, 13.0 ], "cullface": "east" },
"south": { "texture": "#0", "uv": [ 0.0, 3.0, 16.0, 13.0 ], "cullface": "south" },
"west": { "texture": "#0", "uv": [ 0.0, 3.0, 16.0, 13.0 ], "cullface": "west" }
}
}
]
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/construct",
"textures": {
"inner": "block/cobblestone"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/construct",
"textures": {
"inner": "block/purpur_pillar"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "create:block/construct",
"textures": {
"inner": "block/slime_block"
}
}

View file

@ -0,0 +1,82 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
"parent": "block/cube",
"textures": {
"particle": "create:block/contact_side",
"0": "create:block/brass_casing",
"1": "create:block/contact_side",
"2": "create:block/contact_front"
},
"elements": [
{
"name": "Center",
"from": [ 2.0, 1.0, 2.0 ],
"to": [ 14.0, 15.0, 14.0 ],
"faces": {
"up": { "texture": "#0", "uv": [ 2.0, 2.0, 14.0, 14.0 ] },
"down": { "texture": "#0", "uv": [ 2.0, 2.0, 14.0, 14.0 ] }
}
},
{
"name": "Side",
"from": [ 0.0, 0.0, 0.0 ],
"to": [ 2.0, 16.0, 16.0 ],
"faces": {
"north": { "texture": "#1", "uv": [ 14.0, 0.0, 16.0, 16.0 ] },
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 16.0 ] },
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 16.0 ] },
"down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 16.0 ] }
}
},
{
"name": "Side",
"from": [ 14.0, 0.0, 0.0 ],
"to": [ 16.0, 16.0, 16.0 ],
"faces": {
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 16.0 ] },
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"south": { "texture": "#1", "uv": [ 14.0, 0.0, 16.0, 16.0 ] },
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 16.0, 16.0 ] },
"up": { "texture": "#1", "uv": [ 14.0, 0.0, 16.0, 16.0 ] },
"down": { "texture": "#1", "uv": [ 14.0, 0.0, 16.0, 16.0 ] }
}
},
{
"name": "Short Side",
"from": [ 2.0, 0.0, 0.0 ],
"to": [ 14.0, 16.0, 2.0 ],
"faces": {
"north": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 16.0 ] },
"south": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 16.0 ] },
"up": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 2.0 ] },
"down": { "texture": "#1", "uv": [ 2.0, 14.0, 14.0, 16.0 ] }
}
},
{
"name": "Short Side",
"from": [ 2.0, 0.0, 14.0 ],
"to": [ 14.0, 16.0, 16.0 ],
"faces": {
"north": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 16.0 ] },
"south": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 16.0 ] },
"up": { "texture": "#1", "uv": [ 2.0, 14.0, 14.0, 16.0 ] },
"down": { "texture": "#1", "uv": [ 2.0, 0.0, 14.0, 2.0 ] }
}
},
{
"name": "Contact",
"from": [ 6.0, 15.0, 6.0 ],
"to": [ 10.0, 16.0, 10.0 ],
"shade": false,
"faces": {
"north": { "texture": "#2", "uv": [ 6.0, 10.0, 10.0, 11.0 ] },
"east": { "texture": "#2", "uv": [ 10.0, 6.0, 11.0, 10.0 ], "rotation": 90 },
"south": { "texture": "#2", "uv": [ 5.0, 6.0, 6.0, 10.0 ], "rotation": 90 },
"west": { "texture": "#2", "uv": [ 6.0, 5.0, 10.0, 6.0 ] },
"up": { "texture": "#2", "uv": [ 6.0, 6.0, 10.0, 10.0 ] }
}
}
]
}

View file

@ -0,0 +1,7 @@
{
"parent": "create:block/contact",
"textures": {
"particle": "create:block/contact_side_powered",
"1": "create:block/contact_side_powered"
}
}

Some files were not shown because too many files have changed in this diff Show more