mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 12:33:57 +01:00
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:
parent
71f928ae9d
commit
4cfd7a1bb9
@ -13,14 +13,14 @@ apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
version = 'mc1.14.4_v0.0.5'
|
||||
version = 'mc1.14.4_v0.1.0'
|
||||
group = 'com.simibubi.create'
|
||||
archivesBaseName = 'create'
|
||||
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20190806-1.14.3'
|
||||
mappings channel: 'snapshot', version: '20190816-1.14.3'
|
||||
|
||||
runs {
|
||||
client {
|
||||
@ -58,7 +58,7 @@ minecraft {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.0.45'
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.0.49'
|
||||
}
|
||||
|
||||
jar {
|
||||
|
@ -1,16 +1,26 @@
|
||||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.foundation.block.IWithoutBlockItem;
|
||||
import com.simibubi.create.foundation.block.RenderUtilityAxisBlock;
|
||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||
import com.simibubi.create.modules.kinetics.base.HalfAxisBlock;
|
||||
import com.simibubi.create.modules.kinetics.generators.MotorBlock;
|
||||
import com.simibubi.create.modules.kinetics.receivers.TurntableBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.AxisBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.AxisTunnelBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.CogWheelBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearboxBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearshifterBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.HalfAxisBlock;
|
||||
import com.simibubi.create.modules.contraptions.generators.MotorBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.CrushingWheelBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.DrillBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.HarvesterBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.TurntableBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ChassisBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonHeadBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.PistonPoleBlock;
|
||||
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.AxisBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.AxisTunnelBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.CogWheelBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearboxBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearshifterBlock;
|
||||
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonBlock;
|
||||
@ -22,6 +32,7 @@ import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Block.Properties;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RotatedPillarBlock;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
@ -40,20 +51,63 @@ public enum AllBlocks {
|
||||
GEAR(new CogWheelBlock(false)),
|
||||
LARGE_GEAR(new CogWheelBlock(true)),
|
||||
AXIS_TUNNEL(new AxisTunnelBlock()),
|
||||
ENCASED_BELT(new EncasedBeltBlock()),
|
||||
GEARSHIFTER(new GearshifterBlock()),
|
||||
GEARBOX(new GearboxBlock()),
|
||||
BELT(new BeltBlock()),
|
||||
BELT_PULLEY(new RenderUtilityAxisBlock()),
|
||||
BELT_ANIMATION(new RenderUtilityBlock()),
|
||||
|
||||
MOTOR(new MotorBlock()),
|
||||
|
||||
TURNTABLE(new TurntableBlock()),
|
||||
HALF_AXIS(new HalfAxisBlock()),
|
||||
GEARBOX(new GearboxBlock()),
|
||||
MOTOR(new MotorBlock()),
|
||||
CRUSHING_WHEEL(new CrushingWheelBlock()),
|
||||
|
||||
MECHANICAL_PISTON(new MechanicalPistonBlock(false)),
|
||||
STICKY_MECHANICAL_PISTON(new MechanicalPistonBlock(true)),
|
||||
MECHANICAL_PISTON_HEAD(new MechanicalPistonHeadBlock()),
|
||||
PISTON_POLE(new PistonPoleBlock()),
|
||||
CONSTRUCT(new ChassisBlock(ChassisBlock.Type.NORMAL)),
|
||||
STICKY_CONSTRUCT(new ChassisBlock(ChassisBlock.Type.STICKY)),
|
||||
RELOCATION_CONSTRUCT(new ChassisBlock(ChassisBlock.Type.RELOCATING)),
|
||||
|
||||
DRILL(new DrillBlock()),
|
||||
HARVESTER(new HarvesterBlock()),
|
||||
CONTACT(new ContactBlock()),
|
||||
|
||||
// Symmetry
|
||||
SYMMETRY_PLANE(new PlaneSymmetryBlock()),
|
||||
SYMMETRY_CROSSPLANE(new CrossPlaneSymmetryBlock()),
|
||||
SYMMETRY_TRIPLEPLANE(new TriplePlaneSymmetryBlock()),
|
||||
|
||||
// Palettes
|
||||
ANDESITE_BRICKS(new Block(Properties.from(Blocks.ANDESITE))),
|
||||
DIORITE_BRICKS(new Block(Properties.from(Blocks.DIORITE))),
|
||||
GRANITE_BRICKS(new Block(Properties.from(Blocks.GRANITE))),
|
||||
|
||||
GABBRO(new Block(Properties.from(Blocks.ANDESITE))),
|
||||
POLISHED_GABBRO(new Block(Properties.from(GABBRO.block))),
|
||||
GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
|
||||
PAVED_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
|
||||
INDENTED_GABBRO(new Block(Properties.from(GABBRO.block))),
|
||||
SLIGHTLY_MOSSY_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
|
||||
MOSSY_GABBRO_BRICKS(new Block(Properties.from(GABBRO.block))),
|
||||
|
||||
LIMESTONE(new Block(Properties.from(Blocks.SANDSTONE))),
|
||||
POLISHED_LIMESTONE(new Block(Properties.from(LIMESTONE.block))),
|
||||
LIMESTONE_BRICKS(new Block(Properties.from(LIMESTONE.block))),
|
||||
LIMESTONE_PILLAR(new RotatedPillarBlock(Properties.from(LIMESTONE.block))),
|
||||
|
||||
QUARTZIORITE(new Block(Properties.from(Blocks.QUARTZ_BLOCK))),
|
||||
QUARTZIORITE_BRICKS(new Block(Properties.from(QUARTZIORITE.block))),
|
||||
POLISHED_QUARTZIORITE(new Block(Properties.from(QUARTZIORITE.block))),
|
||||
|
||||
DOLOMITE(new Block(Properties.from(Blocks.GRANITE))),
|
||||
DOLOMITE_BRICKS(new Block(Properties.from(DOLOMITE.block))),
|
||||
POLISHED_DOLOMITE(new Block(Properties.from(DOLOMITE.block))),
|
||||
DOLOMITE_PILLAR(new RotatedPillarBlock(Properties.from(DOLOMITE.block))),
|
||||
|
||||
;
|
||||
|
||||
public Block block;
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltItem;
|
||||
import com.simibubi.create.modules.curiosities.item.TreeFertilizerItem;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItem;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRenderer;
|
||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunModel;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltItem;
|
||||
import com.simibubi.create.modules.schematics.item.BlueprintAndQuillItem;
|
||||
import com.simibubi.create.modules.schematics.item.BlueprintItem;
|
||||
import com.simibubi.create.modules.symmetry.SymmetryWandItem;
|
||||
|
@ -2,19 +2,23 @@ package com.simibubi.create;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.kinetics.generators.MotorTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.generators.MotorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.kinetics.receivers.TurntableTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.AxisTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.AxisTunnelTileEntityRenderer;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltTileEntityRenderer;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntityRenderer;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.generators.MotorTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.generators.MotorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.CrushingWheelTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.DrillTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.TurntableTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.AxisTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.AxisTunnelTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity;
|
||||
@ -41,15 +45,16 @@ public enum AllTileEntities {
|
||||
|
||||
// Kinetics
|
||||
AXIS(AxisTileEntity::new, AllBlocks.AXIS, AllBlocks.GEAR, AllBlocks.LARGE_GEAR, AllBlocks.AXIS_TUNNEL),
|
||||
MOTOR(MotorTileEntity::new, AllBlocks.MOTOR),
|
||||
GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
|
||||
MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
|
||||
TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE),
|
||||
AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL),
|
||||
GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER),
|
||||
BELT(BeltTileEntity::new, AllBlocks.BELT),
|
||||
|
||||
AXIS_TUNNEL(AxisTunnelTileEntity::new, AllBlocks.AXIS_TUNNEL, AllBlocks.ENCASED_BELT),
|
||||
GEARSHIFTER(GearshifterTileEntity::new, AllBlocks.GEARSHIFTER), BELT(BeltTileEntity::new, AllBlocks.BELT),
|
||||
MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON),
|
||||
DRILL(DrillTileEntity::new, AllBlocks.DRILL),
|
||||
CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL),
|
||||
|
||||
;
|
||||
|
||||
|
||||
private Supplier<? extends TileEntity> supplier;
|
||||
public TileEntityType<?> type;
|
||||
private AllBlocks[] blocks;
|
||||
@ -66,7 +71,7 @@ public enum AllTileEntities {
|
||||
Block[] blocks = new Block[tileEntity.blocks.length];
|
||||
for (int i = 0; i < blocks.length; i++)
|
||||
blocks[i] = tileEntity.blocks[i].block;
|
||||
|
||||
|
||||
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, tileEntity.name().toLowerCase());
|
||||
tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, blocks).build(null)
|
||||
.setRegistryName(resourceLocation);
|
||||
@ -84,6 +89,9 @@ public enum AllTileEntities {
|
||||
bind(GearboxTileEntity.class, new GearboxTileEntityRenderer());
|
||||
bind(GearshifterTileEntity.class, new GearshifterTileEntityRenderer());
|
||||
bind(BeltTileEntity.class, new BeltTileEntityRenderer());
|
||||
bind(MechanicalPistonTileEntity.class, new MechanicalPistonTileEntityRenderer());
|
||||
bind(DrillTileEntity.class, new KineticTileEntityRenderer());
|
||||
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
@ -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));
|
||||
|
||||
}
|
||||
}
|
@ -1,16 +1,14 @@
|
||||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class BufferManipulator {
|
||||
|
||||
|
||||
protected static final int FORMAT_LENGTH = DefaultVertexFormats.BLOCK.getSize();
|
||||
protected ByteBuffer original;
|
||||
protected ByteBuffer mutable;
|
||||
|
||||
@ -24,42 +22,72 @@ public abstract class BufferManipulator {
|
||||
mutable.put(this.original);
|
||||
mutable.rewind();
|
||||
}
|
||||
|
||||
protected void forEachVertex(ByteBuffer buffer, Consumer<Integer> consumer) {
|
||||
final int formatLength = DefaultVertexFormats.BLOCK.getSize();
|
||||
for (int i = 0; i < buffer.limit() / formatLength; i++) {
|
||||
final int position = i * formatLength;
|
||||
consumer.accept(position);
|
||||
}
|
||||
|
||||
protected int vertexCount(ByteBuffer buffer) {
|
||||
return buffer.limit() / FORMAT_LENGTH;
|
||||
}
|
||||
|
||||
protected Vec3d getPos(ByteBuffer buffer, int vertex) {
|
||||
return new Vec3d(buffer.getFloat(vertex), buffer.getFloat(vertex + 4), buffer.getFloat(vertex + 8));
|
||||
}
|
||||
|
||||
protected void putPos(ByteBuffer buffer, int vertex, Vec3d pos) {
|
||||
buffer.putFloat(vertex, (float) pos.x);
|
||||
buffer.putFloat(vertex + 4, (float) pos.y);
|
||||
buffer.putFloat(vertex + 8, (float) pos.z);
|
||||
}
|
||||
|
||||
protected Vec3d rotatePos(Vec3d pos, float angle, Axis axis) {
|
||||
return rotatePos(pos, MathHelper.sin(angle), MathHelper.cos(angle), axis);
|
||||
}
|
||||
|
||||
protected Vec3d rotatePos(Vec3d pos, float sin, float cos, Axis axis) {
|
||||
final float x = (float) pos.x;
|
||||
final float y = (float) pos.y;
|
||||
final float z = (float) pos.z;
|
||||
|
||||
if (axis == Axis.X)
|
||||
return new Vec3d(x, y * cos - z * sin, z * cos + y * sin);
|
||||
if (axis == Axis.Y)
|
||||
return new Vec3d(x * cos + z * sin, y, z * cos - x * sin);
|
||||
if (axis == Axis.Z)
|
||||
return new Vec3d(x * cos - y * sin, y * cos + x * sin, z);
|
||||
|
||||
return pos;
|
||||
protected int getBufferPosition(int vertexIndex) {
|
||||
return vertexIndex * FORMAT_LENGTH;
|
||||
}
|
||||
|
||||
protected float getX(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index));
|
||||
}
|
||||
|
||||
protected float getY(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 4);
|
||||
}
|
||||
|
||||
protected float getZ(ByteBuffer buffer, int index) {
|
||||
return buffer.getFloat(getBufferPosition(index) + 8);
|
||||
}
|
||||
|
||||
protected byte getR(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 12);
|
||||
}
|
||||
|
||||
protected byte getG(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 13);
|
||||
}
|
||||
|
||||
protected byte getB(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 14);
|
||||
}
|
||||
|
||||
protected byte getA(ByteBuffer buffer, int index) {
|
||||
return buffer.get(getBufferPosition(index) + 15);
|
||||
}
|
||||
|
||||
protected void putPos(ByteBuffer buffer, int index, float x, float y, float z) {
|
||||
int pos = getBufferPosition(index);
|
||||
buffer.putFloat(pos, x);
|
||||
buffer.putFloat(pos + 4, y);
|
||||
buffer.putFloat(pos + 8, z);
|
||||
}
|
||||
|
||||
protected float rotateX(float x, float y, float z, float sin, float cos, Axis axis) {
|
||||
return axis == Axis.Y ? x * cos + z * sin : axis == Axis.Z ? x * cos - y * sin : x;
|
||||
}
|
||||
|
||||
protected float rotateY(float x, float y, float z, float sin, float cos, Axis axis) {
|
||||
return axis == Axis.Y ? y : axis == Axis.Z ? y * cos + x * sin : y * cos - z * sin;
|
||||
}
|
||||
|
||||
protected float rotateZ(float x, float y, float z, float sin, float cos, Axis axis) {
|
||||
return axis == Axis.Y ? z * cos - x * sin : axis == Axis.Z ? z : z * cos + y * sin;
|
||||
}
|
||||
|
||||
protected void putLight(ByteBuffer buffer, int index, int packedLight) {
|
||||
buffer.putInt(getBufferPosition(index) + 24, packedLight);
|
||||
}
|
||||
|
||||
protected void putColor(ByteBuffer buffer, int index, byte r, byte g, byte b, byte a) {
|
||||
int bufferPosition = getBufferPosition(index);
|
||||
buffer.put(bufferPosition + 12, r);
|
||||
buffer.put(bufferPosition + 13, g);
|
||||
buffer.put(bufferPosition + 14, b);
|
||||
buffer.put(bufferPosition + 15, a);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
package com.simibubi.create.modules.kinetics;
|
||||
package com.simibubi.create.modules.contraptions;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.IRotate;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearboxTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.GearshifterTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.EncasedBeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearboxTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.state.IProperty;
|
||||
@ -37,7 +38,7 @@ public class RotationPropagator {
|
||||
final BlockPos diff = to.getPos().subtract(from.getPos());
|
||||
final Direction direction = Direction.getFacingFromVector(diff.getX(), diff.getY(), diff.getZ());
|
||||
final World world = from.getWorld();
|
||||
|
||||
|
||||
IProperty<Axis> axisProperty = BlockStateProperties.AXIS;
|
||||
boolean connectedByAxis = definitionFrom.isAxisTowards(world, from.getPos(), stateFrom, direction)
|
||||
&& definitionTo.isAxisTowards(world, to.getPos(), stateTo, direction.getOpposite());
|
||||
@ -58,6 +59,14 @@ public class RotationPropagator {
|
||||
return getAxisModifier(from, direction) * getAxisModifier(to, direction.getOpposite());
|
||||
}
|
||||
|
||||
// Attached Encased Belts
|
||||
if (AllBlocks.ENCASED_BELT.typeOf(stateFrom) && AllBlocks.ENCASED_BELT.typeOf(stateTo)) {
|
||||
boolean connected = stateFrom.get(EncasedBeltBlock.CONNECTED) && stateTo.get(EncasedBeltBlock.CONNECTED)
|
||||
&& stateFrom.get(EncasedBeltBlock.CONNECTED_FACE) == direction
|
||||
&& stateTo.get(EncasedBeltBlock.CONNECTED_FACE) == direction.getOpposite();
|
||||
return connected ? 1 : 0;
|
||||
}
|
||||
|
||||
// Gear <-> Large Gear
|
||||
if (isLargeToSmallGear(stateFrom, stateTo, diff))
|
||||
return -2f;
|
||||
@ -133,12 +142,14 @@ public class RotationPropagator {
|
||||
continue;
|
||||
if (neighbourTE.hasSource() && neighbourTE.getSource().equals(addedTE.getPos())) {
|
||||
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
|
||||
addedTE.onSpeedChanged();
|
||||
addedTE.notifyBlockUpdate();
|
||||
continue;
|
||||
}
|
||||
|
||||
addedTE.setSpeed(neighbourTE.getSpeed() * speedModifier);
|
||||
addedTE.setSource(neighbourTE.getPos());
|
||||
addedTE.onSpeedChanged();
|
||||
addedTE.notifyBlockUpdate();
|
||||
propagateNewSource(addedTE);
|
||||
return;
|
||||
@ -171,6 +182,7 @@ public class RotationPropagator {
|
||||
|
||||
neighbourTE.setSpeed(newSpeed);
|
||||
neighbourTE.setSource(updateTE.getPos());
|
||||
neighbourTE.onSpeedChanged();
|
||||
neighbourTE.notifyBlockUpdate();
|
||||
propagateNewSource(neighbourTE);
|
||||
|
||||
@ -254,6 +266,8 @@ public class RotationPropagator {
|
||||
BlockState neighbourState = te.getWorld().getBlockState(neighbourPos);
|
||||
if (!(neighbourState.getBlock() instanceof IRotate))
|
||||
return null;
|
||||
if (!neighbourState.hasTileEntity())
|
||||
return null;
|
||||
|
||||
KineticTileEntity neighbour = (KineticTileEntity) te.getWorld().getTileEntity(neighbourPos);
|
||||
if (getRotationSpeedModifier(te, neighbour) == 0)
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Direction;
|
@ -1,6 +1,6 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.RotationPropagator;
|
||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
@ -52,13 +52,10 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||
@Override
|
||||
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
// RotationPropagator.handleAdded(worldIn, pos);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
|
||||
super.updateNeighbors(stateIn, worldIn, pos, flags);
|
||||
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
|
||||
if (tileEntity == null)
|
||||
return;
|
@ -1,10 +1,10 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.RotationPropagator;
|
||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
@ -31,6 +31,9 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onSpeedChanged() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (!hasWorld())
|
||||
@ -126,6 +129,7 @@ public abstract class KineticTileEntity extends SyncedTileEntity {
|
||||
public void removeSource() {
|
||||
this.source = Optional.empty();
|
||||
setSpeed(0);
|
||||
onSpeedChanged();
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
@ -21,7 +21,6 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
@ -39,18 +38,23 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(Vec3d translation, float angle, Axis axis, int packedLightCoords) {
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float angle, Axis axis,
|
||||
int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
final float cos = MathHelper.cos(angle);
|
||||
final float sin = MathHelper.sin(angle);
|
||||
final Vec3d half = new Vec3d(.5f, .5f, .5f);
|
||||
float cos = MathHelper.cos(angle);
|
||||
float sin = MathHelper.sin(angle);
|
||||
float x, y, z = 0;
|
||||
|
||||
forEachVertex(original, index -> {
|
||||
final Vec3d vertex = getPos(original, index).subtract(half);
|
||||
putPos(mutable, index, rotatePos(vertex, sin, cos, axis).add(translation).add(half));
|
||||
mutable.putInt(index + 24, packedLightCoords);
|
||||
});
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
x = getX(original, vertex) - .5f;
|
||||
y = getY(original, vertex) - .5f;
|
||||
z = getZ(original, vertex) - .5f;
|
||||
|
||||
putPos(mutable, vertex, rotateX(x, y, z, sin, cos, axis) + .5f + xIn,
|
||||
rotateY(x, y, z, sin, cos, axis) + .5f + yIn, rotateZ(x, y, z, sin, cos, axis) + .5f + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
@ -67,20 +71,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
cacheIfMissing(state, BlockModelSpinner::new);
|
||||
|
||||
final Vec3d translation = new Vec3d(x, y, z);
|
||||
final BlockPos pos = te.getPos();
|
||||
final Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = (float) (((time * te.getSpeed() + offset) % 360) / 180 * (float) Math.PI);
|
||||
|
||||
renderFromCache(buffer, state, translation, pos, axis, angle);
|
||||
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
}
|
||||
|
||||
protected void renderFromCache(BufferBuilder buffer, final BlockState state, final Vec3d translation,
|
||||
final BlockPos pos, final Axis axis, float angle) {
|
||||
protected void renderFromCache(BufferBuilder buffer, BlockState state, float x, float y, float z, BlockPos pos,
|
||||
Axis axis, float angle) {
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(getWorld(), pos);
|
||||
buffer.putBulkData(((BlockModelSpinner) cachedBuffers.get(state)).getTransformed(translation, angle, axis,
|
||||
buffer.putBulkData(((BlockModelSpinner) cachedBuffers.get(state)).getTransformed(x, y, z, angle, axis,
|
||||
packedLightmapCoords));
|
||||
}
|
||||
|
||||
@ -92,8 +95,9 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(getWorld(), originalModel, state, BlockPos.ZERO, builder, true, random, 42,
|
||||
blockRenderer.renderModelFlat(getWorld(), originalModel, state, BlockPos.ZERO.down(), builder, true, random, 42,
|
||||
EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
@ -114,5 +118,5 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
return te.getBlockState();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.base;
|
||||
package com.simibubi.create.modules.contraptions.base;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
@ -1,6 +1,6 @@
|
||||
package com.simibubi.create.modules.kinetics.generators;
|
||||
package com.simibubi.create.modules.contraptions.generators;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.Material;
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.generators;
|
||||
package com.simibubi.create.modules.contraptions.generators;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class MotorTileEntity extends KineticTileEntity {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.simibubi.create.modules.kinetics.generators;
|
||||
package com.simibubi.create.modules.contraptions.generators;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.receivers;
|
||||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.KineticBlock;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.receivers;
|
||||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.receivers;
|
||||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class TurntableTileEntity extends KineticTileEntity {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
@ -15,9 +15,9 @@ import net.minecraft.world.World;
|
||||
|
||||
public class AxisBlock extends RotatedPillarKineticBlock {
|
||||
|
||||
protected static final VoxelShape AXIS_X = makeCuboidShape(0, 5, 5, 16, 11, 11);
|
||||
protected static final VoxelShape AXIS_Y = makeCuboidShape(5, 0, 5, 11, 16, 11);
|
||||
protected static final VoxelShape AXIS_Z = makeCuboidShape(5, 5, 0, 11, 11, 16);
|
||||
public static final VoxelShape AXIS_X = makeCuboidShape(0, 5, 5, 16, 11, 11);
|
||||
public static final VoxelShape AXIS_Y = makeCuboidShape(5, 0, 5, 11, 16, 11);
|
||||
public static final VoxelShape AXIS_Z = makeCuboidShape(5, 5, 0, 11, 11, 16);
|
||||
|
||||
public AxisBlock(Properties properties) {
|
||||
super(properties);
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class AxisTileEntity extends KineticTileEntity {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class AxisTunnelTileEntity extends KineticTileEntity {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
@ -1,18 +1,20 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.block.IWithoutBlockItem;
|
||||
import com.simibubi.create.modules.kinetics.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltTileEntity.TransportedEntityInfo;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltTileEntity.TransportedEntityInfo;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
@ -23,6 +25,7 @@ import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
@ -69,6 +72,12 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
||||
setDefaultState(getDefaultState().with(SLOPE, Slope.HORIZONTAL).with(PART, Part.START));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
|
||||
PlayerEntity player) {
|
||||
return new ItemStack(AllItems.BELT_CONNECTOR.item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLanded(IBlockReader worldIn, Entity entityIn) {
|
||||
super.onLanded(worldIn, entityIn);
|
@ -1,12 +1,12 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.Item;
|
||||
@ -31,6 +31,11 @@ public class BeltItem extends Item {
|
||||
|
||||
@Override
|
||||
public ActionResultType onItemUse(ItemUseContext context) {
|
||||
if (context.isPlacerSneaking()) {
|
||||
context.getItem().setTag(null);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getPos();
|
||||
boolean validAxis = validateAxis(world, pos);
|
||||
@ -154,7 +159,7 @@ public class BeltItem extends Item {
|
||||
te.setController(target);
|
||||
}
|
||||
|
||||
private boolean canConnect(World world, BlockPos first, BlockPos second) {
|
||||
public static boolean canConnect(World world, BlockPos first, BlockPos second) {
|
||||
if (!world.isAreaLoaded(first, 1))
|
||||
return false;
|
||||
if (!world.isAreaLoaded(second, 1))
|
||||
@ -177,16 +182,24 @@ public class BeltItem extends Item {
|
||||
return false;
|
||||
if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS))
|
||||
return false;
|
||||
|
||||
|
||||
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed();
|
||||
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed();
|
||||
if (speed1 != speed2 && speed1 != 0 && speed2 != 0)
|
||||
return false;
|
||||
|
||||
BlockPos step = new BlockPos(Math.signum(diff.getX()), Math.signum(diff.getY()), Math.signum(diff.getZ()));
|
||||
int limit = 1000;
|
||||
for (BlockPos currentPos = first.add(step); !currentPos.equals(second)
|
||||
&& limit-- > 0; currentPos = currentPos.add(step)) {
|
||||
if (!world.getBlockState(currentPos).getMaterial().isReplaceable())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean validateAxis(World world, BlockPos pos) {
|
||||
public static boolean validateAxis(World world, BlockPos pos) {
|
||||
if (!world.isAreaLoaded(pos, 1))
|
||||
return false;
|
||||
if (!AllBlocks.AXIS.typeOf(world.getBlockState(pos)))
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -7,9 +7,9 @@ import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.kinetics.relays.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
@ -1,13 +1,13 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.modules.kinetics.base.IRotate;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@ -17,7 +17,6 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
|
||||
public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
@ -28,19 +27,17 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
|
||||
public BeltModelAnimator(ByteBuffer template) {
|
||||
super(template);
|
||||
|
||||
if (beltTextures == null)
|
||||
initSprites();
|
||||
}
|
||||
|
||||
private void initSprites() {
|
||||
AtlasTexture textureMap = Minecraft.getInstance().getTextureMap();
|
||||
|
||||
originalTexture = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt"));
|
||||
beltTextures = textureMap.getSprite(new ResourceLocation(Create.ID, "block/belt_animated"));
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(Vec3d translation, BeltTileEntity te) {
|
||||
public ByteBuffer getTransformed(BeltTileEntity te, float x, float y, float z) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
@ -62,17 +59,19 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
}
|
||||
|
||||
final BlockState blockState = te.getBlockState();
|
||||
final int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
|
||||
final float texOffX = textureOffsetX;
|
||||
final float texOffY = textureOffsetY;
|
||||
|
||||
forEachVertex(original, index -> {
|
||||
Vec3d pos = getPos(original, index);
|
||||
putPos(mutable, index, pos.add(translation));
|
||||
mutable.putFloat(index + 16, original.getFloat(index + 16) + texOffX);
|
||||
mutable.putFloat(index + 20, original.getFloat(index + 20) + texOffY);
|
||||
mutable.putInt(index + 24, packedLightCoords);
|
||||
});
|
||||
int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
|
||||
float texOffX = textureOffsetX;
|
||||
float texOffY = textureOffsetY;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putPos(mutable, vertex, getX(original, vertex) + x, getY(original, vertex) + y,
|
||||
getZ(original, vertex) + z);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
|
||||
int bufferPosition = getBufferPosition(vertex);
|
||||
mutable.putFloat(bufferPosition + 16, original.getFloat(bufferPosition + 16) + texOffX);
|
||||
mutable.putFloat(bufferPosition + 20, original.getFloat(bufferPosition + 20) + texOffY);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
@ -87,16 +86,16 @@ public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
cacheIfMissing(beltEntity.getBlockState(), BeltModelAnimator::new);
|
||||
renderBeltFromCache(beltEntity, new Vec3d(x, y, z), buffer);
|
||||
renderBeltFromCache(beltEntity, (float) x, (float) y, (float) z, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
return AllBlocks.AXIS.get().getDefaultState().with(BlockStateProperties.AXIS,
|
||||
return AllBlocks.BELT_PULLEY.get().getDefaultState().with(BlockStateProperties.AXIS,
|
||||
((IRotate) AllBlocks.BELT.get()).getRotationAxis(te.getBlockState()));
|
||||
}
|
||||
|
||||
public void renderBeltFromCache(BeltTileEntity te, Vec3d translation, BufferBuilder buffer) {
|
||||
buffer.putBulkData(((BeltModelAnimator) cachedBuffers.get(te.getBlockState())).getTransformed(translation, te));
|
||||
public void renderBeltFromCache(BeltTileEntity te, float x, float y, float z, BufferBuilder buffer) {
|
||||
buffer.putBulkData(((BeltModelAnimator) cachedBuffers.get(te.getBlockState())).getTransformed(te, x, y, z));
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.modules.kinetics.base.RotatedPillarKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class GearboxTileEntity extends KineticTileEntity {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@ -11,7 +11,6 @@ import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
|
||||
public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
@ -22,7 +21,6 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
|
||||
final Vec3d translation = new Vec3d(x, y, z);
|
||||
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
@ -50,7 +48,7 @@ public class GearboxTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
|
||||
renderFromCache(buffer, state, translation, pos, axis, angle);
|
||||
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
@ -46,6 +49,7 @@ public class GearshifterBlock extends AxisTunnelBlock {
|
||||
|
||||
boolean previouslyPowered = state.get(POWERED);
|
||||
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
||||
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos));
|
||||
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
|
||||
public class GearshifterTileEntity extends KineticTileEntity {
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.simibubi.create.modules.kinetics.relays;
|
||||
package com.simibubi.create.modules.contraptions.relays;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.kinetics.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@ -11,7 +11,6 @@ import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.client.model.animation.Animation;
|
||||
|
||||
public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
@ -22,7 +21,6 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
|
||||
final Vec3d translation = new Vec3d(x, y, z);
|
||||
final BlockState defaultState = AllBlocks.HALF_AXIS.get().getDefaultState();
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
@ -44,7 +42,7 @@ public class GearshifterTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
angle += offset;
|
||||
angle = angle / 180f * (float) Math.PI;
|
||||
|
||||
renderFromCache(buffer, state, translation, pos, axis, angle);
|
||||
renderFromCache(buffer, state, (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
}
|
||||
}
|
||||
|
@ -144,9 +144,10 @@ public class BlueprintItem extends Item {
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||
if (playerIn.isSneaking() && handIn == Hand.MAIN_HAND) {
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||
displayBlueprintScreen();
|
||||
});
|
||||
if (playerIn.getHeldItem(handIn).hasTag())
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||
displayBlueprintScreen();
|
||||
});
|
||||
return new ActionResult<ItemStack>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/andesite_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
11
src/main/resources/assets/create/blockstates/construct.json
Normal file
11
src/main/resources/assets/create/blockstates/construct.json
Normal 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 }
|
||||
}
|
||||
}
|
17
src/main/resources/assets/create/blockstates/contact.json
Normal file
17
src/main/resources/assets/create/blockstates/contact.json
Normal 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 }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/diorite_bricks" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/dolomite" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/dolomite_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
17
src/main/resources/assets/create/blockstates/drill.json
Normal file
17
src/main/resources/assets/create/blockstates/drill.json
Normal 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 }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
5
src/main/resources/assets/create/blockstates/gabbro.json
Normal file
5
src/main/resources/assets/create/blockstates/gabbro.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/gabbro" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/gabbro_bricks" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/granite_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/indented_gabbro" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/limestone" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/limestone_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/mossy_gabbro_bricks" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/paved_gabbro_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/polished_dolomite" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/polished_gabbro" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/polished_limestone" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/polished_quartziorite" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/quartziorite" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/quartziorite_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/palettes/slightly_mossy_gabbro_bricks" }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -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 }
|
||||
}
|
||||
}
|
@ -9,17 +9,55 @@
|
||||
"item.create.blueprint_and_quill": "Schematic and Quill",
|
||||
"item.create.blueprint": "Schematic",
|
||||
"item.create.belt_connector": "Mechanical Belt",
|
||||
|
||||
"block.create.gear": "Cogwheel",
|
||||
"block.create.large_gear": "Large Cogwheel",
|
||||
"block.create.turntable": "Turntable",
|
||||
"block.create.gearbox": "Gearbox",
|
||||
"block.create.gearshifter": "Gearshifter",
|
||||
"block.create.axis_tunnel": "Encased Axis",
|
||||
"block.create.axis": "Axis",
|
||||
"block.create.encased_belt": "Encased Belt",
|
||||
"block.create.axis_tunnel": "Encased Axis",
|
||||
"block.create.motor": "Motor",
|
||||
"block.create.belt": "Mechanical Belt",
|
||||
"block.create.crushing_wheel": "Crushing Wheel",
|
||||
"block.create.drill": "Mechanical Drill",
|
||||
"block.create.harvester": "Mechanical Harvester",
|
||||
"block.create.contact": "Redstone Contact",
|
||||
|
||||
"block.create.sticky_mechanical_piston": "Sticky Mechanical Piston",
|
||||
"block.create.mechanical_piston": "Mechanical Piston",
|
||||
"block.create.mechanical_piston_head": "Mechanical Piston Head",
|
||||
"block.create.piston_pole": "Piston Extension Pole",
|
||||
"block.create.construct": "Movement Chassis",
|
||||
"block.create.sticky_construct": "Sticky Chassis",
|
||||
"block.create.relocation_construct": "Relocation Chassis",
|
||||
|
||||
"block.create.andesite_bricks": "Andesite Bricks",
|
||||
"block.create.diorite_bricks": "Diorite Bricks",
|
||||
"block.create.granite_bricks": "Granite Bricks",
|
||||
"block.create.gabbro": "Gabbro",
|
||||
"block.create.polished_gabbro": "Polished Gabbro",
|
||||
"block.create.gabbro_bricks": "Gabbro Bricks",
|
||||
"block.create.paved_gabbro_bricks": "Paved Gabbro Bricks",
|
||||
"block.create.indented_gabbro": "Indented Gabbro Tile",
|
||||
"block.create.slightly_mossy_gabbro_bricks": "Mossy Gabbro Bricks",
|
||||
"block.create.mossy_gabbro_bricks": "Overgrown Gabbro Bricks",
|
||||
"block.create.limestone": "Limestone",
|
||||
"block.create.polished_limestone": "Polished Limestone",
|
||||
"block.create.limestone_bricks": "Limestone Bricks",
|
||||
"block.create.limestone_pillar": "Limestone Pillar",
|
||||
"block.create.quartziorite": "Quartziorite",
|
||||
"block.create.quartziorite_bricks": "Quartziorite Bricks",
|
||||
"block.create.polished_quartziorite": "Polished Quartziorite",
|
||||
"block.create.dolomite": "Dolomite",
|
||||
"block.create.dolomite_bricks": "Dolomite Bricks",
|
||||
"block.create.polished_dolomite": "Polished Dolomite",
|
||||
"block.create.dolomite_pillar": "Dolomite Pillar",
|
||||
|
||||
"block.create.schematicannon": "Schematicannon",
|
||||
"block.create.schematic_table": "Schematic Table",
|
||||
"block.create.creative_crate": "Schematicannon Creatifier",
|
||||
|
||||
"itemGroup.create": "Create"
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
"name": "Axis",
|
||||
"from": [ 6.0, 0.0, 6.0 ],
|
||||
"to": [ 10.0, 16.0, 10.0 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 16.0 ] },
|
||||
|
@ -11,6 +11,7 @@
|
||||
"name": "Axis",
|
||||
"from": [ 6.0, 8.0, 6.0 ],
|
||||
"to": [ 10.0, 16.0, 10.0 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 8.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 6.0, 0.0, 10.0, 8.0 ] },
|
||||
|
@ -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 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
60
src/main/resources/assets/create/models/block/construct.json
Normal file
60
src/main/resources/assets/create/models/block/construct.json
Normal 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" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "create:block/construct",
|
||||
"textures": {
|
||||
"inner": "block/cobblestone"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "create:block/construct",
|
||||
"textures": {
|
||||
"inner": "block/purpur_pillar"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "create:block/construct",
|
||||
"textures": {
|
||||
"inner": "block/slime_block"
|
||||
}
|
||||
}
|
82
src/main/resources/assets/create/models/block/contact.json
Normal file
82
src/main/resources/assets/create/models/block/contact.json
Normal 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 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user