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

View file

@ -1,16 +1,26 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.foundation.block.IWithoutBlockItem; 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.foundation.block.RenderUtilityBlock;
import com.simibubi.create.modules.kinetics.base.HalfAxisBlock; import com.simibubi.create.modules.contraptions.base.HalfAxisBlock;
import com.simibubi.create.modules.kinetics.generators.MotorBlock; import com.simibubi.create.modules.contraptions.generators.MotorBlock;
import com.simibubi.create.modules.kinetics.receivers.TurntableBlock; import com.simibubi.create.modules.contraptions.receivers.CrushingWheelBlock;
import com.simibubi.create.modules.kinetics.relays.AxisBlock; import com.simibubi.create.modules.contraptions.receivers.DrillBlock;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelBlock; import com.simibubi.create.modules.contraptions.receivers.HarvesterBlock;
import com.simibubi.create.modules.kinetics.relays.BeltBlock; import com.simibubi.create.modules.contraptions.receivers.TurntableBlock;
import com.simibubi.create.modules.kinetics.relays.CogWheelBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisBlock;
import com.simibubi.create.modules.kinetics.relays.GearboxBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock;
import com.simibubi.create.modules.kinetics.relays.GearshifterBlock; 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.CreativeCrateBlock;
import com.simibubi.create.modules.schematics.block.SchematicTableBlock; import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
import com.simibubi.create.modules.schematics.block.SchematicannonBlock; 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.Block.Properties;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.RotatedPillarBlock;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
@ -40,20 +51,63 @@ public enum AllBlocks {
GEAR(new CogWheelBlock(false)), GEAR(new CogWheelBlock(false)),
LARGE_GEAR(new CogWheelBlock(true)), LARGE_GEAR(new CogWheelBlock(true)),
AXIS_TUNNEL(new AxisTunnelBlock()), AXIS_TUNNEL(new AxisTunnelBlock()),
ENCASED_BELT(new EncasedBeltBlock()),
GEARSHIFTER(new GearshifterBlock()), GEARSHIFTER(new GearshifterBlock()),
GEARBOX(new GearboxBlock()),
BELT(new BeltBlock()), BELT(new BeltBlock()),
BELT_PULLEY(new RenderUtilityAxisBlock()),
BELT_ANIMATION(new RenderUtilityBlock()), BELT_ANIMATION(new RenderUtilityBlock()),
MOTOR(new MotorBlock()),
TURNTABLE(new TurntableBlock()), TURNTABLE(new TurntableBlock()),
HALF_AXIS(new HalfAxisBlock()), HALF_AXIS(new HalfAxisBlock()),
GEARBOX(new GearboxBlock()), CRUSHING_WHEEL(new CrushingWheelBlock()),
MOTOR(new MotorBlock()),
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
SYMMETRY_PLANE(new PlaneSymmetryBlock()), SYMMETRY_PLANE(new PlaneSymmetryBlock()),
SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()), SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()),
SYMMETRY_TRIPLEPLANE(new TriplePlaneSymmetryBlock()), 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; public Block block;

View file

@ -1,10 +1,10 @@
package com.simibubi.create; 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.item.TreeFertilizerItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer;
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel; 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.BlueprintAndQuillItem;
import com.simibubi.create.modules.schematics.item.BlueprintItem; import com.simibubi.create.modules.schematics.item.BlueprintItem;
import com.simibubi.create.modules.symmetry.SymmetryWandItem; import com.simibubi.create.modules.symmetry.SymmetryWandItem;

View file

@ -2,19 +2,23 @@ package com.simibubi.create;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.kinetics.generators.MotorTileEntity; import com.simibubi.create.modules.contraptions.generators.MotorTileEntity;
import com.simibubi.create.modules.kinetics.generators.MotorTileEntityRenderer; import com.simibubi.create.modules.contraptions.generators.MotorTileEntityRenderer;
import com.simibubi.create.modules.kinetics.receivers.TurntableTileEntity; import com.simibubi.create.modules.contraptions.receivers.CrushingWheelTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTileEntity; import com.simibubi.create.modules.contraptions.receivers.DrillTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntity; import com.simibubi.create.modules.contraptions.receivers.TurntableTileEntity;
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity; import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.AxisTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity; import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntityRenderer;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity; import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntityRenderer; 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.SchematicTableTileEntity;
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer; import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity; import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity;
@ -41,15 +45,16 @@ public enum AllTileEntities {
// Kinetics // Kinetics
AXIS(AxisTileEntity::new, AllBlocks.AXIS, AllBlocks.GEAR, AllBlocks.LARGE_GEAR, AllBlocks.AXIS_TUNNEL), AXIS(AxisTileEntity::new, AllBlocks.AXIS, AllBlocks.GEAR, AllBlocks.LARGE_GEAR, AllBlocks.AXIS_TUNNEL),
MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE), TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE),
AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL), AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL, AllBlocks.ENCASED_BELT),
GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER), GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER), BELT(BeltTileEntity::new, AllBlocks.BELT),
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; private Supplier<? extends TileEntity> supplier;
public TileEntityType<?> type; public TileEntityType<?> type;
private AllBlocks[] blocks; private AllBlocks[] blocks;
@ -66,7 +71,7 @@ public enum AllTileEntities {
Block[] blocks = new Block[tileEntity.blocks.length]; Block[] blocks = new Block[tileEntity.blocks.length];
for (int i = 0; i < blocks.length; i++) for (int i = 0; i < blocks.length; i++)
blocks[i] = tileEntity.blocks[i].block; blocks[i] = tileEntity.blocks[i].block;
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, tileEntity.name().toLowerCase()); ResourceLocation resourceLocation = new ResourceLocation(Create.ID, tileEntity.name().toLowerCase());
tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null) tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null)
.setRegistryName(resourceLocation); .setRegistryName(resourceLocation);
@ -84,6 +89,9 @@ public enum AllTileEntities {
bind(GearboxTileEntity.class, new GearboxTileEntityRenderer()); bind(GearboxTileEntity.class, new GearboxTileEntityRenderer());
bind(GearshifterTileEntity.class, new GearshifterTileEntityRenderer()); bind(GearshifterTileEntity.class, new GearshifterTileEntityRenderer());
bind(BeltTileEntity.class, new BeltTileEntityRenderer()); bind(BeltTileEntity.class, new BeltTileEntityRenderer());
bind(MechanicalPistonTileEntity.class, new MechanicalPistonTileEntityRenderer());
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
} }
@OnlyIn(Dist.CLIENT) @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; package com.simibubi.create.foundation.utility;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.function.Consumer;
import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public abstract class BufferManipulator { public abstract class BufferManipulator {
protected static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
protected ByteBuffer original; protected ByteBuffer original;
protected ByteBuffer mutable; protected ByteBuffer mutable;
@ -24,42 +22,72 @@ public abstract class BufferManipulator {
mutable.put(this.original); mutable.put(this.original);
mutable.rewind(); mutable.rewind();
} }
protected void forEachVertex(ByteBuffer buffer, Consumer<Integer> consumer) { protected int vertexCount(ByteBuffer buffer) {
final int formatLength = DefaultVertexFormats.BLOCK.getSize(); return buffer.limit() / FORMAT_LENGTH;
for (int i = 0; i < buffer.limit() / formatLength; i++) {
final int position = i * formatLength;
consumer.accept(position);
}
} }
protected Vec3d getPos(ByteBuffer buffer, int vertex) { protected int getBufferPosition(int vertexIndex) {
return new Vec3d(buffer.getFloat(vertex), buffer.getFloat(vertex + 4), buffer.getFloat(vertex + 8)); return vertexIndex * FORMAT_LENGTH;
}
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 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.LinkedList;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity; import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity; import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity;
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
@ -37,7 +38,7 @@ public class RotationPropagator {
final BlockPos diff = to.getPos().subtract(from.getPos()); final BlockPos diff = to.getPos().subtract(from.getPos());
final Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ()); final Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ());
final World world = from.getWorld(); final World world = from.getWorld();
IProperty<Axis> axisProperty = BlockStateProperties.AXIS; IProperty<Axis> axisProperty = BlockStateProperties.AXIS;
boolean connectedByAxis = definitionFrom.isAxisTowards(world, from.getPos(), stateFrom, direction) boolean connectedByAxis = definitionFrom.isAxisTowards(world, from.getPos(), stateFrom, direction)
&& definitionTo.isAxisTowards(world, to.getPos(), stateTo, direction.getOpposite()); && definitionTo.isAxisTowards(world, to.getPos(), stateTo, direction.getOpposite());
@ -58,6 +59,14 @@ public class RotationPropagator {
return getAxisModifier(from, direction) * getAxisModifier(to, direction.getOpposite()); 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 // Gear <-> Large Gear
if (isLargeToSmallGear(stateFrom, stateTo, diff)) if (isLargeToSmallGear(stateFrom, stateTo, diff))
return -2f; return -2f;
@ -133,12 +142,14 @@ public class RotationPropagator {
continue; continue;
if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) { if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) {
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier); addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
addedTE.onSpeedChanged();
addedTE.notifyBlockUpdate(); addedTE.notifyBlockUpdate();
continue; continue;
} }
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier); addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
addedTE.setSource(neighbourTE.getPos()); addedTE.setSource(neighbourTE.getPos());
addedTE.onSpeedChanged();
addedTE.notifyBlockUpdate(); addedTE.notifyBlockUpdate();
propagateNewSource(addedTE); propagateNewSource(addedTE);
return; return;
@ -171,6 +182,7 @@ public class RotationPropagator {
neighbourTE.setSpeed(newSpeed); neighbourTE.setSpeed(newSpeed);
neighbourTE.setSource(updateTE.getPos()); neighbourTE.setSource(updateTE.getPos());
neighbourTE.onSpeedChanged();
neighbourTE.notifyBlockUpdate(); neighbourTE.notifyBlockUpdate();
propagateNewSource(neighbourTE); propagateNewSource(neighbourTE);
@ -254,6 +266,8 @@ public class RotationPropagator {
BlockState neighbourState = te.getWorld().getBlockState(neighbourPos); BlockState neighbourState = te.getWorld().getBlockState(neighbourPos);
if (!(neighbourState.getBlock() instanceof IRotate)) if (!(neighbourState.getBlock() instanceof IRotate))
return null; return null;
if (!neighbourState.hasTileEntity())
return null;
KineticTileEntity neighbour = (KineticTileEntity) te.getWorld().getTileEntity(neighbourPos); KineticTileEntity neighbour = (KineticTileEntity) te.getWorld().getTileEntity(neighbourPos);
if (getRotationSpeedModifier(te, neighbour) == 0) 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; 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.Block;
import net.minecraft.block.BlockState; 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.block.BlockState;
import net.minecraft.util.Direction; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -52,13 +52,10 @@ public abstract class KineticBlock extends Block implements IRotate {
@Override @Override
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world); public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
@Override @SuppressWarnings("deprecation")
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
// RotationPropagator.handleAdded(worldIn, pos);
}
@Override @Override
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
super.updateNeighbors(stateIn, worldIn, pos, flags);
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos); KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
if (tileEntity == null) if (tileEntity == null)
return; 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.Optional;
import java.util.Random; import java.util.Random;
import com.simibubi.create.foundation.block.SyncedTileEntity; 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.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
@ -31,6 +31,9 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
return true; return true;
} }
public void onSpeedChanged() {
}
@Override @Override
public void onLoad() { public void onLoad() {
if (!hasWorld()) if (!hasWorld())
@ -126,6 +129,7 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
public void removeSource() { public void removeSource() {
this.source = Optional.empty(); this.source = Optional.empty();
setSpeed(0); 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.nio.ByteBuffer;
import java.util.HashMap; 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.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.model.animation.Animation; import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.client.model.animation.TileEntityRendererFast; import net.minecraftforge.client.model.animation.TileEntityRendererFast;
@ -39,18 +38,23 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
super(original); 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(); original.rewind();
mutable.rewind(); mutable.rewind();
final float cos = MathHelper.cos(angle); float cos = MathHelper.cos(angle);
final float sin = MathHelper.sin(angle); float sin = MathHelper.sin(angle);
final Vec3d half = new Vec3d(.5f, .5f, .5f); float x, y, z = 0;
forEachVertex(original, index -> { for (int vertex = 0; vertex < vertexCount(original); vertex++) {
final Vec3d vertex = getPos(original, index).subtract(half); x = getX(original, vertex) - .5f;
putPos(mutable, index, rotatePos(vertex, sin, cos, axis).add(translation).add(half)); y = getY(original, vertex) - .5f;
mutable.putInt(index + 24, packedLightCoords); 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; return mutable;
} }
@ -67,20 +71,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
final BlockState state = getRenderedBlockState(te); final BlockState state = getRenderedBlockState(te);
cacheIfMissing(state, BlockModelSpinner::new); cacheIfMissing(state, BlockModelSpinner::new);
final Vec3d translation = new Vec3d(x, y, z);
final BlockPos pos = te.getPos(); 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 time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
float offset = getRotationOffsetForPosition(te, pos, axis); float offset = getRotationOffsetForPosition(te, pos, axis);
float angle = (float) (((time * te.getSpeed() + offset) % 360) / 180 * (float) Math.PI); 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, protected void renderFromCache(BufferBuilder buffer, BlockState state, float x, float y, float z, BlockPos pos,
final BlockPos pos, final Axis axis, float angle) { Axis axis, float angle) {
int packedLightmapCoords = state.getPackedLightmapCoords(getWorld(), pos); 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)); packedLightmapCoords));
} }
@ -92,8 +95,9 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
BufferBuilder builder = new BufferBuilder(0); BufferBuilder builder = new BufferBuilder(0);
Random random = new Random(); Random random = new Random();
builder.setTranslation(0, 1, 0);
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); 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); EmptyModelData.INSTANCE);
builder.finishDrawing(); builder.finishDrawing();
@ -114,5 +118,5 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
protected BlockState getRenderedBlockState(KineticTileEntity te) { protected BlockState getRenderedBlockState(KineticTileEntity te) {
return te.getBlockState(); 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.Block;
import net.minecraft.block.BlockState; 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.BlockState;
import net.minecraft.block.material.Material; 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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class MotorTileEntity extends 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.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties; 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.contraptions.base.KineticBlock;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; 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.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist; 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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class TurntableTileEntity extends 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.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
@ -15,9 +15,9 @@ import net.minecraft.world.World;
public class AxisBlock extends RotatedPillarKineticBlock { public class AxisBlock extends RotatedPillarKineticBlock {
protected static final VoxelShape AXIS_X = makeCuboidShape(0, 5, 5, 16, 11, 11); public 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); public 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_Z = makeCuboidShape(5, 5, 0, 11, 11, 16);
public AxisBlock(Properties properties) { public AxisBlock(Properties properties) {
super(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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class AxisTileEntity extends 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.BlockState;
import net.minecraft.block.Blocks; 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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class AxisTunnelTileEntity extends 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.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties; 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.LinkedList;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.block.IWithoutBlockItem; import com.simibubi.create.foundation.block.IWithoutBlockItem;
import com.simibubi.create.modules.kinetics.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity.TransportedEntityInfo; import com.simibubi.create.modules.contraptions.relays.BeltTileEntity.TransportedEntityInfo;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty; import net.minecraft.state.EnumProperty;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer.Builder; 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.Direction.AxisDirection;
import net.minecraft.util.IStringSerializable; import net.minecraft.util.IStringSerializable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.ISelectionContext; 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)); 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 @Override
public void onLanded(IBlockReader worldIn, Entity entityIn) { public void onLanded(IBlockReader worldIn, Entity entityIn) {
super.onLanded(worldIn, 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.LinkedList;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@ -31,6 +31,11 @@ public class BeltItem extends Item {
@Override @Override
public ActionResultType onItemUse(ItemUseContext context) { public ActionResultType onItemUse(ItemUseContext context) {
if (context.isPlacerSneaking()) {
context.getItem().setTag(null);
return ActionResultType.SUCCESS;
}
World world = context.getWorld(); World world = context.getWorld();
BlockPos pos = context.getPos(); BlockPos pos = context.getPos();
boolean validAxis = validateAxis(world, pos); boolean validAxis = validateAxis(world, pos);
@ -154,7 +159,7 @@ public class BeltItem extends Item {
te.setController(target); 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)) if (!world.isAreaLoaded(first, 1))
return false; return false;
if (!world.isAreaLoaded(second, 1)) if (!world.isAreaLoaded(second, 1))
@ -177,16 +182,24 @@ public class BeltItem extends Item {
return false; return false;
if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS)) if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS))
return false; return false;
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed(); float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed();
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed(); float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed();
if (speed1 != speed2 && speed1 != 0 && speed2 != 0) if (speed1 != speed2 && speed1 != 0 && speed2 != 0)
return false; 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; return true;
} }
private boolean validateAxis(World world, BlockPos pos) { public static boolean validateAxis(World world, BlockPos pos) {
if (!world.isAreaLoaded(pos, 1)) if (!world.isAreaLoaded(pos, 1))
return false; return false;
if (!AllBlocks.AXIS.typeOf(world.getBlockState(pos))) 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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -7,9 +7,9 @@ import java.util.Map;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; 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 java.nio.ByteBuffer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.BufferManipulator; import com.simibubi.create.foundation.utility.BufferManipulator;
import com.simibubi.create.modules.kinetics.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; 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.state.properties.BlockStateProperties;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation; import net.minecraftforge.client.model.animation.Animation;
public class BeltTileEntityRenderer extends KineticTileEntityRenderer { public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
@ -28,19 +27,17 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
public BeltModelAnimator(ByteBuffer template) { public BeltModelAnimator(ByteBuffer template) {
super(template); super(template);
if (beltTextures == null) if (beltTextures == null)
initSprites(); initSprites();
} }
private void initSprites() { private void initSprites() {
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap(); AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
originalTexture = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt")); originalTexture = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt"));
beltTextures = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt_animated")); 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(); original.rewind();
mutable.rewind(); mutable.rewind();
@ -62,17 +59,19 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
} }
final BlockState blockState = te.getBlockState(); final BlockState blockState = te.getBlockState();
final int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos()); int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
final float texOffX = textureOffsetX; float texOffX = textureOffsetX;
final float texOffY = textureOffsetY; float texOffY = textureOffsetY;
forEachVertex(original, index -> { for (int vertex = 0; vertex < vertexCount(original); vertex++) {
Vec3d pos = getPos(original, index); putPos(mutable, vertex, getX(original, vertex) + x, getY(original, vertex) + y,
putPos(mutable, index, pos.add(translation)); getZ(original, vertex) + z);
mutable.putFloat(index + 16, original.getFloat(index + 16) + texOffX); putLight(mutable, vertex, packedLightCoords);
mutable.putFloat(index + 20, original.getFloat(index + 20) + texOffY);
mutable.putInt(index + 24, 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; return mutable;
} }
@ -87,16 +86,16 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer); super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
cacheIfMissing(beltEntity.getBlockState(), BeltModelAnimator::new); cacheIfMissing(beltEntity.getBlockState(), BeltModelAnimator::new);
renderBeltFromCache(beltEntity, new Vec3d(x, y, z), buffer); renderBeltFromCache(beltEntity, (float) x, (float) y, (float) z, buffer);
} }
@Override @Override
protected BlockState getRenderedBlockState(KineticTileEntity te) { 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())); ((IRotate) AllBlocks.BELT.get()).getRotationAxis(te.getBlockState()));
} }
public void renderBeltFromCache(BeltTileEntity te, Vec3d translation, BufferBuilder buffer) { public void renderBeltFromCache(BeltTileEntity te, float x, float y, float z, BufferBuilder buffer) {
buffer.putBulkData(((BeltModelAnimator) cachedBuffers.get(te.getBlockState())).getTransformed(translation, te)); 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; 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.BlockState;
import net.minecraft.block.Blocks; 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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class GearboxTileEntity extends 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.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; 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;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation; import net.minecraftforge.client.model.animation.Animation;
public class GearboxTileEntityRenderer extends KineticTileEntityRenderer { public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
@ -22,7 +21,6 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
final BlockPos pos = te.getPos(); final BlockPos pos = te.getPos();
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks); float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
final Vec3d translation = new Vec3d(x, y, z);
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState(); final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
@ -50,7 +48,7 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
angle += offset; angle += offset;
angle = angle / 180f * (float) Math.PI; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -46,6 +49,7 @@ public class GearshifterBlock extends AxisTunnelBlock {
boolean previouslyPowered = state.get(POWERED); boolean previouslyPowered = state.get(POWERED);
if (previouslyPowered != worldIn.isBlockPowered(pos)) { if (previouslyPowered != worldIn.isBlockPowered(pos)) {
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos));
worldIn.setBlockState(pos, state.cycle(POWERED), 2); 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.AllTileEntities;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
public class GearshifterTileEntity extends 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.AllBlocks;
import com.simibubi.create.modules.kinetics.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; 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;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.animation.Animation; import net.minecraftforge.client.model.animation.Animation;
public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer { public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
@ -22,7 +21,6 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS); final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
final BlockPos pos = te.getPos(); final BlockPos pos = te.getPos();
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks); float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
final Vec3d translation = new Vec3d(x, y, z);
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState(); final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
@ -44,7 +42,7 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
angle += offset; angle += offset;
angle = angle / 180f * (float) Math.PI; 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 @Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
if (playerIn.isSneaking() && handIn == Hand.MAIN_HAND) { if (playerIn.isSneaking() && handIn == Hand.MAIN_HAND) {
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { if (playerIn.getHeldItem(handIn).hasTag())
displayBlueprintScreen(); DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
}); displayBlueprintScreen();
});
return new ActionResult<ItemStack>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); 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_and_quill": "Schematic and Quill",
"item.create.blueprint": "Schematic", "item.create.blueprint": "Schematic",
"item.create.belt_connector": "Mechanical Belt", "item.create.belt_connector": "Mechanical Belt",
"block.create.gear": "Cogwheel", "block.create.gear": "Cogwheel",
"block.create.large_gear": "Large Cogwheel", "block.create.large_gear": "Large Cogwheel",
"block.create.turntable": "Turntable", "block.create.turntable": "Turntable",
"block.create.gearbox": "Gearbox", "block.create.gearbox": "Gearbox",
"block.create.gearshifter": "Gearshifter", "block.create.gearshifter": "Gearshifter",
"block.create.axis_tunnel": "Encased Axis",
"block.create.axis": "Axis", "block.create.axis": "Axis",
"block.create.encased_belt": "Encased Belt",
"block.create.axis_tunnel": "Encased Axis",
"block.create.motor": "Motor", "block.create.motor": "Motor",
"block.create.belt": "Mechanical Belt", "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.schematicannon": "Schematicannon",
"block.create.schematic_table": "Schematic Table", "block.create.schematic_table": "Schematic Table",
"block.create.creative_crate": "Schematicannon Creatifier", "block.create.creative_crate": "Schematicannon Creatifier",
"itemGroup.create": "Create" "itemGroup.create": "Create"
} }

View file

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