Merge branch 'better-belts' into 0.2
This commit is contained in:
commit
1e23aa82aa
55 changed files with 3561 additions and 1391 deletions
|
@ -6,7 +6,7 @@ import com.simibubi.create.modules.IModule;
|
|||
import com.simibubi.create.modules.contraptions.WrenchItem;
|
||||
import com.simibubi.create.modules.contraptions.WrenchItemRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.VerticalGearboxItem;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltItem;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItem;
|
||||
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
||||
import com.simibubi.create.modules.curiosities.deforester.DeforesterItem;
|
||||
import com.simibubi.create.modules.curiosities.deforester.DeforesterItemRenderer;
|
||||
|
@ -82,7 +82,7 @@ public enum AllItems {
|
|||
BLUEPRINT(new SchematicItem(standardItemProperties())),
|
||||
|
||||
__CONTRAPTIONS__(),
|
||||
BELT_CONNECTOR(new BeltItem(standardItemProperties())),
|
||||
BELT_CONNECTOR(new BeltConnectorItem(standardItemProperties())),
|
||||
VERTICAL_GEARBOX(new VerticalGearboxItem(new Properties())),
|
||||
FLOUR(ingredient()),
|
||||
DOUGH(ingredient()),
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer;
|
|||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.ExtractorTileEntity;
|
||||
|
@ -180,6 +181,7 @@ public enum AllTileEntities {
|
|||
bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer());
|
||||
bind(LinkedExtractorTileEntity.class, new LinkedExtractorTileEntityRenderer());
|
||||
bind(ExtractorTileEntity.class, new ExtractorTileEntityRenderer());
|
||||
bind(BeltFunnelTileEntity.class, new BeltFunnelTileEntityRenderer());
|
||||
bind(EntityDetectorTileEntity.class, new EntityDetectorTileEntityRenderer());
|
||||
bind(MechanicalPressTileEntity.class, new MechanicalPressTileEntityRenderer());
|
||||
bind(FlexpeaterTileEntity.class, new FlexpeaterTileEntityRenderer());
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.simibubi.create.foundation.utility.TooltipHelper;
|
|||
import com.simibubi.create.modules.contraptions.KineticDebugger;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.TurntableHandler;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltItemHandler;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItemHandler;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -56,7 +56,7 @@ public class ClientEvents {
|
|||
|
||||
public static void onGameTick() {
|
||||
CreateClient.gameTick();
|
||||
BeltItemHandler.gameTick();
|
||||
BeltConnectorItemHandler.gameTick();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
|
@ -28,9 +28,9 @@ public abstract class SyncedTileEntity extends TileEntity {
|
|||
}
|
||||
|
||||
public void sendData() {
|
||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2 | 16);
|
||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2 | 4 | 16);
|
||||
}
|
||||
|
||||
|
||||
public void causeBlockUpdate() {
|
||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 1);
|
||||
}
|
||||
|
|
|
@ -91,6 +91,19 @@ public abstract class BufferManipulator {
|
|||
buffer.put(bufferPosition + 15, a);
|
||||
}
|
||||
|
||||
public ByteBuffer getTranslated(float xIn, float yIn, float zIn, int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn,
|
||||
getZ(original, vertex) + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin,
|
||||
float yOrigin, float zOrigin, float yaw, float pitch) {
|
||||
buffer.rewind();
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
|
||||
/**
|
||||
* Stolen from EntityRenderer
|
||||
*/
|
||||
public class IndependentShadowRenderer {
|
||||
|
||||
private static final ResourceLocation SHADOW_TEXTURES = new ResourceLocation("textures/misc/shadow.png");
|
||||
|
||||
public static void renderShadow(double x, double y, double z, float shadowAlpha, float size) {
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.blendFunc(GlStateManager.SourceFactor.DST_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(SHADOW_TEXTURES);
|
||||
IWorldReader iworldreader = Minecraft.getInstance().world;
|
||||
GlStateManager.depthMask(false);
|
||||
int i = MathHelper.floor(x - size);
|
||||
int j = MathHelper.floor(x + size);
|
||||
int k = MathHelper.floor(y - size);
|
||||
int l = MathHelper.floor(y);
|
||||
int i1 = MathHelper.floor(z - size);
|
||||
int j1 = MathHelper.floor(z + size);
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
|
||||
|
||||
for (BlockPos blockpos : BlockPos.getAllInBoxMutable(new BlockPos(i, k, i1), new BlockPos(j, l, j1))) {
|
||||
BlockPos blockpos1 = blockpos.down();
|
||||
BlockState blockstate = iworldreader.getBlockState(blockpos1);
|
||||
if (blockstate.getRenderType() != BlockRenderType.INVISIBLE && iworldreader.getLight(blockpos) > 3) {
|
||||
func_217759_a(blockstate, iworldreader, blockpos1, 0, 0, 0, blockpos, shadowAlpha, size, -x, -y, -z);
|
||||
}
|
||||
}
|
||||
|
||||
tessellator.draw();
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.depthMask(true);
|
||||
}
|
||||
|
||||
private static void func_217759_a(BlockState p_217759_1_, IWorldReader p_217759_2_, BlockPos p_217759_3_,
|
||||
double p_217759_4_, double p_217759_6_, double p_217759_8_, BlockPos p_217759_10_, float p_217759_11_,
|
||||
float p_217759_12_, double p_217759_13_, double p_217759_15_, double p_217759_17_) {
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
VoxelShape voxelshape = p_217759_1_.getShape(world, p_217759_10_.down());
|
||||
if (!voxelshape.isEmpty()) {
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
double d0 = ((double) p_217759_11_ - (p_217759_6_ - ((double) p_217759_10_.getY() + p_217759_15_)) / 2.0D)
|
||||
* 0.5D * (double) world.getBrightness(p_217759_10_);
|
||||
if (!(d0 < 0.0D)) {
|
||||
if (d0 > 1.0D) {
|
||||
d0 = 1.0D;
|
||||
}
|
||||
|
||||
AxisAlignedBB axisalignedbb = voxelshape.getBoundingBox();
|
||||
double d1 = (double) p_217759_10_.getX() + axisalignedbb.minX + p_217759_13_;
|
||||
double d2 = (double) p_217759_10_.getX() + axisalignedbb.maxX + p_217759_13_;
|
||||
double d3 = (double) p_217759_10_.getY() + axisalignedbb.minY + p_217759_15_ + 0.015625D;
|
||||
double d4 = (double) p_217759_10_.getZ() + axisalignedbb.minZ + p_217759_17_;
|
||||
double d5 = (double) p_217759_10_.getZ() + axisalignedbb.maxZ + p_217759_17_;
|
||||
float f = (float) ((p_217759_4_ - d1) / 2.0D / (double) p_217759_12_ + 0.5D);
|
||||
float f1 = (float) ((p_217759_4_ - d2) / 2.0D / (double) p_217759_12_ + 0.5D);
|
||||
float f2 = (float) ((p_217759_8_ - d4) / 2.0D / (double) p_217759_12_ + 0.5D);
|
||||
float f3 = (float) ((p_217759_8_ - d5) / 2.0D / (double) p_217759_12_ + 0.5D);
|
||||
bufferbuilder.pos(d1, d3, d4).tex((double) f, (double) f2).color(1.0F, 1.0F, 1.0F, (float) d0)
|
||||
.endVertex();
|
||||
bufferbuilder.pos(d1, d3, d5).tex((double) f, (double) f3).color(1.0F, 1.0F, 1.0F, (float) d0)
|
||||
.endVertex();
|
||||
bufferbuilder.pos(d2, d3, d5).tex((double) f1, (double) f3).color(1.0F, 1.0F, 1.0F, (float) d0)
|
||||
.endVertex();
|
||||
bufferbuilder.pos(d2, d3, d4).tex((double) f1, (double) f2).color(1.0F, 1.0F, 1.0F, (float) d0)
|
||||
.endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -16,24 +16,23 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public class TessellatorHelper {
|
||||
|
||||
public static final float fontScale = 1/512f;
|
||||
public static final float fontScale = 1 / 512f;
|
||||
|
||||
public static void prepareForDrawing() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.pushLightingAttributes();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.color4f(1, 1, 1, 1);
|
||||
public static void prepareForDrawing() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.pushLightingAttributes();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.color4f(1, 1, 1, 1);
|
||||
|
||||
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
|
||||
Vec3d view = renderInfo.getProjectedView();
|
||||
GlStateManager.translated(-view.x, -view.y, -view.z);
|
||||
}
|
||||
|
||||
ActiveRenderInfo renderInfo = mc.gameRenderer.getActiveRenderInfo();
|
||||
Vec3d view = renderInfo.getProjectedView();
|
||||
GlStateManager.translated(-view.x, -view.y, -view.z);
|
||||
}
|
||||
|
||||
public static void prepareFastRender() {
|
||||
Minecraft.getInstance().textureManager
|
||||
.bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
Minecraft.getInstance().textureManager.bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.enableBlend();
|
||||
|
@ -43,35 +42,35 @@ public class TessellatorHelper {
|
|||
GlStateManager.shadeModel(GL11.GL_SMOOTH);
|
||||
else
|
||||
GlStateManager.shadeModel(GL11.GL_FLAT);
|
||||
|
||||
|
||||
GlStateManager.color3f(1, 1, 1);
|
||||
}
|
||||
|
||||
public static void begin() {
|
||||
begin(DefaultVertexFormats.POSITION_TEX);
|
||||
}
|
||||
|
||||
public static void begin(VertexFormat format) {
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, format);
|
||||
}
|
||||
public static void begin() {
|
||||
begin(DefaultVertexFormats.POSITION_TEX);
|
||||
}
|
||||
|
||||
public static void draw() {
|
||||
Tessellator.getInstance().draw();
|
||||
}
|
||||
public static void begin(VertexFormat format) {
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, format);
|
||||
}
|
||||
|
||||
public static void cleanUpAfterDrawing() {
|
||||
GlStateManager.disableAlphaTest();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.popAttributes();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
public static void draw() {
|
||||
Tessellator.getInstance().draw();
|
||||
}
|
||||
|
||||
public static void cleanUpAfterDrawing() {
|
||||
GlStateManager.disableAlphaTest();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.popAttributes();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
public static void drawString(String str, float x, float y, float z, boolean scalesUp, boolean hasDepth) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
float pitch = mc.getRenderManager().playerViewX;
|
||||
float yaw = mc.getRenderManager().playerViewY;
|
||||
boolean isThirdPersonFrontal = mc.gameSettings.thirdPersonView == 2;
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.pushLightingAttributes();
|
||||
GlStateManager.translatef(x, y, z);
|
||||
|
@ -82,9 +81,9 @@ public class TessellatorHelper {
|
|||
GlStateManager.disableLighting();
|
||||
if (!hasDepth) {
|
||||
GlStateManager.depthMask(false);
|
||||
GlStateManager.disableDepthTest();
|
||||
GlStateManager.disableDepthTest();
|
||||
}
|
||||
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA,
|
||||
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE,
|
||||
|
@ -98,21 +97,21 @@ public class TessellatorHelper {
|
|||
bufferbuilder.pos((double) (-i - 3), (double) (10), 0.0D).color(1F, 1F, 1F, .5F).endVertex();
|
||||
bufferbuilder.pos((double) (i + 3), (double) (10), 0.0D).color(1F, 1F, 1F, .5F).endVertex();
|
||||
bufferbuilder.pos((double) (i + 3), (double) (-3), 0.0D).color(1F, 1F, 1F, .5F).endVertex();
|
||||
|
||||
|
||||
if (scalesUp) {
|
||||
double distance = mc.player.getEyePosition(mc.getRenderPartialTicks()).squareDistanceTo(x, y, z);
|
||||
double scale = distance * fontScale;
|
||||
GlStateManager.scaled(2 + scale, 2 + scale, 2 + scale);
|
||||
GlStateManager.scaled(2 + scale, 2 + scale, 2 + scale);
|
||||
}
|
||||
tessellator.draw();
|
||||
GlStateManager.enableTexture();
|
||||
if (hasDepth) {
|
||||
GlStateManager.translatef(0, 0, -0.125f);
|
||||
}
|
||||
|
||||
|
||||
mc.fontRenderer.drawString(str, -mc.fontRenderer.getStringWidth(str) / 2, 0, 0);
|
||||
GlStateManager.enableDepthTest();
|
||||
|
||||
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.depthMask(true);
|
||||
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA,
|
||||
|
@ -121,118 +120,124 @@ public class TessellatorHelper {
|
|||
GlStateManager.popMatrix();
|
||||
GlStateManager.popAttributes();
|
||||
}
|
||||
|
||||
public static void cube(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double scale,
|
||||
boolean scaleVertical, boolean doubleFaces) {
|
||||
TessellatorHelper.walls(bufferBuilder, pos, size, scale, scaleVertical, doubleFaces);
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
|
||||
if (doubleFaces) {
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(w, 0, l), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).up(h), new BlockPos(-w, 0, l), scale, true, scaleVertical, false);
|
||||
} else {
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(w, 0, l), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).up(h), new BlockPos(-w, 0, l), scale, true, scaleVertical, false, false);
|
||||
}
|
||||
}
|
||||
public static void cube(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double scale,
|
||||
boolean scaleVertical, boolean doubleFaces) {
|
||||
TessellatorHelper.walls(bufferBuilder, pos, size, scale, scaleVertical, doubleFaces);
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
|
||||
public static void walls(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double scale,
|
||||
boolean scaleVertical, boolean doubleFaces) {
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
if (doubleFaces) {
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(w, 0, l), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).up(h), new BlockPos(-w, 0, l), scale, true,
|
||||
scaleVertical, false);
|
||||
} else {
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(w, 0, l), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).up(h), new BlockPos(-w, 0, l), scale, true, scaleVertical,
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (doubleFaces) {
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(w, h, 0), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).south(l), new BlockPos(0, h, -l), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).south(l), new BlockPos(-w, h, 0), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(0, h, l), scale, true, scaleVertical, false);
|
||||
} else {
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(w, h, 0), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).south(l), new BlockPos(0, h, -l), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).south(l), new BlockPos(-w, h, 0), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(0, h, l), scale, true, scaleVertical, false, false);
|
||||
}
|
||||
}
|
||||
public static void walls(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double scale,
|
||||
boolean scaleVertical, boolean doubleFaces) {
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
|
||||
public static void doubleFace(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double shift,
|
||||
boolean stretch, boolean shiftVertical, boolean mirrorTexture) {
|
||||
TessellatorHelper.face(bufferBuilder, pos, size, shift, stretch, shiftVertical, false, mirrorTexture);
|
||||
TessellatorHelper.face(bufferBuilder, pos.add(size.getX(), 0, (size.getY() == 0) ? 0 : size.getZ()),
|
||||
new BlockPos(-size.getX(), size.getY(), (size.getY() == 0) ? size.getZ() : -size.getZ()), -shift,
|
||||
stretch, shiftVertical, true, mirrorTexture);
|
||||
}
|
||||
if (doubleFaces) {
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(w, h, 0), scale, true, scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).south(l), new BlockPos(0, h, -l), scale, true,
|
||||
scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos.east(w).south(l), new BlockPos(-w, h, 0), scale, true,
|
||||
scaleVertical, false);
|
||||
TessellatorHelper.doubleFace(bufferBuilder, pos, new BlockPos(0, h, l), scale, true, scaleVertical, false);
|
||||
} else {
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(w, h, 0), scale, true, scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).south(l), new BlockPos(0, h, -l), scale, true,
|
||||
scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos.east(w).south(l), new BlockPos(-w, h, 0), scale, true,
|
||||
scaleVertical, false, false);
|
||||
TessellatorHelper.face(bufferBuilder, pos, new BlockPos(0, h, l), scale, true, scaleVertical, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void face(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double shift, boolean stretch,
|
||||
boolean shiftVertical, boolean shiftBackwards, boolean mirrorTexture) {
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
if (shiftBackwards)
|
||||
shift = -shift;
|
||||
public static void doubleFace(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double shift,
|
||||
boolean stretch, boolean shiftVertical, boolean mirrorTexture) {
|
||||
TessellatorHelper.face(bufferBuilder, pos, size, shift, stretch, shiftVertical, false, mirrorTexture);
|
||||
TessellatorHelper.face(bufferBuilder, pos.add(size.getX(), 0, (size.getY() == 0) ? 0 : size.getZ()),
|
||||
new BlockPos(-size.getX(), size.getY(), (size.getY() == 0) ? size.getZ() : -size.getZ()), -shift,
|
||||
stretch, shiftVertical, true, mirrorTexture);
|
||||
}
|
||||
|
||||
if (w == 0) { // YZ plane -> H has to be positive
|
||||
public static void face(BufferBuilder bufferBuilder, BlockPos pos, BlockPos size, double shift, boolean stretch,
|
||||
boolean shiftVertical, boolean shiftBackwards, boolean mirrorTexture) {
|
||||
int w = size.getX();
|
||||
int h = size.getY();
|
||||
int l = size.getZ();
|
||||
if (shiftBackwards)
|
||||
shift = -shift;
|
||||
|
||||
double xs = (l < 0) ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
xs = -xs;
|
||||
double ys1 = shiftVertical ? shift : 0;
|
||||
double zs1 = l < 0 ? -shift : shift;
|
||||
if (!stretch && (l > 0 ^ mirrorTexture))
|
||||
zs1 = -zs1;
|
||||
double ys2 = stretch ? -ys1 : ys1;
|
||||
double zs2 = stretch ? -zs1 : zs1;
|
||||
double u1 = (mirrorTexture) ? l : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : l;
|
||||
if (w == 0) { // YZ plane -> H has to be positive
|
||||
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys2, zs1), pos.south(l), u2, h);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys1, zs1), pos.south(l).up(h), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys1, zs2), pos.up(h), u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys2, zs2), pos, u1, h);
|
||||
double xs = (l < 0) ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
xs = -xs;
|
||||
double ys1 = shiftVertical ? shift : 0;
|
||||
double zs1 = l < 0 ? -shift : shift;
|
||||
if (!stretch && (l > 0 ^ mirrorTexture))
|
||||
zs1 = -zs1;
|
||||
double ys2 = stretch ? -ys1 : ys1;
|
||||
double zs2 = stretch ? -zs1 : zs1;
|
||||
double u1 = (mirrorTexture) ? l : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : l;
|
||||
|
||||
} else if (h == 0) { // XZ plane -> L has to be positive
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys2, zs1), pos.south(l), u2, h);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys1, zs1), pos.south(l).up(h), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys1, zs2), pos.up(h), u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs, ys2, zs2), pos, u1, h);
|
||||
|
||||
double ys = w < 0 ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
ys = -ys;
|
||||
double xs1 = w < 0 ? -shift : shift;
|
||||
double zs1 = shift;
|
||||
double xs2 = stretch ? -xs1 : xs1;
|
||||
double zs2 = stretch ? -zs1 : zs1;
|
||||
double u1 = (mirrorTexture) ? w : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : w;
|
||||
} else if (h == 0) { // XZ plane -> L has to be positive
|
||||
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys, zs1), pos.south(l), u1, l);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys, zs2), pos, u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys, zs2), pos.east(w), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys, zs1), pos.east(w).south(l), u2, l);
|
||||
double ys = w < 0 ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
ys = -ys;
|
||||
double xs1 = w < 0 ? -shift : shift;
|
||||
double zs1 = shift;
|
||||
double xs2 = stretch ? -xs1 : xs1;
|
||||
double zs2 = stretch ? -zs1 : zs1;
|
||||
double u1 = (mirrorTexture) ? w : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : w;
|
||||
|
||||
} else if (l == 0) { // XY plane -> H has to be positive
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys, zs1), pos.south(l), u1, l);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys, zs2), pos, u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys, zs2), pos.east(w), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys, zs1), pos.east(w).south(l), u2, l);
|
||||
|
||||
double zs = w < 0 ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
zs = -zs;
|
||||
double ys1 = shiftVertical ? shift : 0;
|
||||
double xs1 = w < 0 ? -shift : shift;
|
||||
if (!stretch && (w > 0 ^ mirrorTexture))
|
||||
xs1 = -xs1;
|
||||
double ys2 = stretch ? -ys1 : ys1;
|
||||
double xs2 = stretch ? -xs1 : xs1;
|
||||
double u1 = (mirrorTexture) ? w : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : w;
|
||||
} else if (l == 0) { // XY plane -> H has to be positive
|
||||
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys2, zs), pos, u1, h);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys1, zs), pos.up(h), u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys1, zs), pos.east(w).up(h), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys2, zs), pos.east(w), u2, h);
|
||||
double zs = w < 0 ? shift : -shift;
|
||||
if (shiftBackwards)
|
||||
zs = -zs;
|
||||
double ys1 = shiftVertical ? shift : 0;
|
||||
double xs1 = w < 0 ? -shift : shift;
|
||||
if (!stretch && (w > 0 ^ mirrorTexture))
|
||||
xs1 = -xs1;
|
||||
double ys2 = stretch ? -ys1 : ys1;
|
||||
double xs2 = stretch ? -xs1 : xs1;
|
||||
double u1 = (mirrorTexture) ? w : 0;
|
||||
double u2 = (mirrorTexture) ? 0 : w;
|
||||
|
||||
}
|
||||
}
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys2, zs), pos, u1, h);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs2, ys1, zs), pos.up(h), u1, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys1, zs), pos.east(w).up(h), u2, 0);
|
||||
TessellatorHelper.posTexShift(bufferBuilder, new Vec3d(xs1, ys2, zs), pos.east(w), u2, h);
|
||||
|
||||
private static void posTexShift(BufferBuilder bufferBuilder, Vec3d shift, BlockPos pos, double u, double v) {
|
||||
bufferBuilder.pos(shift.x + pos.getX(), shift.y + pos.getY(), shift.z + pos.getZ()).tex(u, v).endVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void posTexShift(BufferBuilder bufferBuilder, Vec3d shift, BlockPos pos, double u, double v) {
|
||||
bufferBuilder.pos(shift.x + pos.getX(), shift.y + pos.getY(), shift.z + pos.getZ()).tex(u, v).endVertex();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@ package com.simibubi.create.foundation.utility;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableObject;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
public class VoxelShaper {
|
||||
|
||||
|
@ -17,7 +21,11 @@ public class VoxelShaper {
|
|||
return shapes.get(direction);
|
||||
}
|
||||
|
||||
public static VoxelShaper forHorizontalBlock(VoxelShape southShape) {
|
||||
public VoxelShape get(Axis axis) {
|
||||
return shapes.get(axisAsFace(axis));
|
||||
}
|
||||
|
||||
public static VoxelShaper forHorizontal(VoxelShape southShape) {
|
||||
VoxelShaper voxelShaper = new VoxelShaper();
|
||||
for (Direction facing : Direction.values()) {
|
||||
if (facing.getAxis().isVertical())
|
||||
|
@ -27,7 +35,27 @@ public class VoxelShaper {
|
|||
return voxelShaper;
|
||||
}
|
||||
|
||||
public static VoxelShaper forDirectionalBlock(VoxelShape southShape) {
|
||||
public static VoxelShaper forHorizontalAxis(VoxelShape zShape) {
|
||||
VoxelShaper voxelShaper = new VoxelShaper();
|
||||
for (Axis axis : Axis.values()) {
|
||||
if (axis.isVertical())
|
||||
continue;
|
||||
Direction facing = axisAsFace(axis);
|
||||
voxelShaper.shapes.put(facing, rotatedCopy(zShape, 0, (int) -facing.getHorizontalAngle()));
|
||||
}
|
||||
return voxelShaper;
|
||||
}
|
||||
|
||||
public static VoxelShaper forRotatedPillar(VoxelShape zShape) {
|
||||
VoxelShaper voxelShaper = new VoxelShaper();
|
||||
for (Axis axis : Axis.values()) {
|
||||
Direction facing = axisAsFace(axis);
|
||||
voxelShaper.shapes.put(facing, rotatedCopy(zShape, 0, (int) -facing.getHorizontalAngle()));
|
||||
}
|
||||
return voxelShaper;
|
||||
}
|
||||
|
||||
public static VoxelShaper forDirectional(VoxelShape southShape) {
|
||||
VoxelShaper voxelShaper = new VoxelShaper();
|
||||
for (Direction facing : Direction.values()) {
|
||||
int rotX = facing.getAxis().isVertical() ? (facing == Direction.UP ? 270 : 90) : 0;
|
||||
|
@ -43,19 +71,28 @@ public class VoxelShaper {
|
|||
return this;
|
||||
}
|
||||
|
||||
public static VoxelShape rotatedCopy(VoxelShape shape, int rotX, int rotY) {
|
||||
Vec3d center = new Vec3d(8, 8, 8);
|
||||
Vec3d v1 = new Vec3d(shape.getStart(Axis.X), shape.getStart(Axis.Y), shape.getStart(Axis.Z)).scale(16)
|
||||
.subtract(center);
|
||||
Vec3d v2 = new Vec3d(shape.getEnd(Axis.X), shape.getEnd(Axis.Y), shape.getEnd(Axis.Z)).scale(16)
|
||||
.subtract(center);
|
||||
private static Direction axisAsFace(Axis axis) {
|
||||
return Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
|
||||
}
|
||||
|
||||
v1 = VecHelper.rotate(v1, rotX, Axis.X);
|
||||
v1 = VecHelper.rotate(v1, rotY, Axis.Y).add(center);
|
||||
v2 = VecHelper.rotate(v2, rotX, Axis.X);
|
||||
v2 = VecHelper.rotate(v2, rotY, Axis.Y).add(center);
|
||||
private static VoxelShape rotatedCopy(VoxelShape shape, int rotX, int rotY) {
|
||||
MutableObject<VoxelShape> result = new MutableObject<>(VoxelShapes.empty());
|
||||
|
||||
return Block.makeCuboidShape(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
|
||||
shape.forEachBox((x1, y1, z1, x2, y2, z2) -> {
|
||||
Vec3d center = new Vec3d(8, 8, 8);
|
||||
Vec3d v1 = new Vec3d(x1, y1, z1).scale(16).subtract(center);
|
||||
Vec3d v2 = new Vec3d(x2, y2, z2).scale(16).subtract(center);
|
||||
|
||||
v1 = VecHelper.rotate(v1, rotX, Axis.X);
|
||||
v1 = VecHelper.rotate(v1, rotY, Axis.Y).add(center);
|
||||
v2 = VecHelper.rotate(v2, rotX, Axis.X);
|
||||
v2 = VecHelper.rotate(v2, rotY, Axis.Y).add(center);
|
||||
|
||||
VoxelShape rotated = Block.makeCuboidShape(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z);
|
||||
result.setValue(VoxelShapes.or(result.getValue(), rotated));
|
||||
});
|
||||
|
||||
return result.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@ import net.minecraft.block.Block;
|
|||
public class VoxelShapers {
|
||||
|
||||
public static final VoxelShaper SHORT_CASING = VoxelShaper
|
||||
.forDirectionalBlock(Block.makeCuboidShape(0, 0, 0, 16, 16, 12));
|
||||
.forDirectional(Block.makeCuboidShape(0, 0, 0, 16, 16, 12));
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
|||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltModelAnimator;
|
||||
|
||||
import net.minecraft.client.resources.ReloadListener;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
|
@ -24,6 +25,7 @@ public class CachedBufferReloader extends ReloadListener<String> {
|
|||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
ColoredIndicatorRenderer.invalidateCache();
|
||||
CTModelTextureHandler.reloadUVs();
|
||||
BeltModelAnimator.invalidateCache();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.modules.contraptions;
|
|||
|
||||
import static com.simibubi.create.AllBlocks.BELT;
|
||||
import static com.simibubi.create.AllBlocks.COGWHEEL;
|
||||
import static com.simibubi.create.AllBlocks.ENCASED_FAN;
|
||||
import static com.simibubi.create.AllBlocks.LARGE_COGWHEEL;
|
||||
import static com.simibubi.create.CreateConfig.parameters;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
|
@ -76,12 +75,6 @@ public class RotationPropagator {
|
|||
return connected ? 1 : 0;
|
||||
}
|
||||
|
||||
// Attached Fans
|
||||
if (ENCASED_FAN.typeOf(stateFrom) && ENCASED_FAN.typeOf(stateTo)) {
|
||||
if (stateFrom.get(AXIS) == stateTo.get(AXIS))
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Large Gear <-> Large Gear
|
||||
if (isLargeToLargeGear(stateFrom, stateTo, diff)) {
|
||||
Axis sourceAxis = stateFrom.get(AXIS);
|
||||
|
|
|
@ -34,7 +34,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
|||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTileEntity> {
|
||||
|
||||
protected static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||
public static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||
public static boolean rainbowMode = false;
|
||||
|
||||
public static class BlockModelSpinner extends BufferManipulator {
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package com.simibubi.create.modules.contraptions.receivers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing;
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing.Type;
|
||||
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EncasedFanBeltHandler {
|
||||
|
||||
// Fans need to be aware of belt TEs within their range
|
||||
// all belts are handled equally
|
||||
// requires ref to controller and index
|
||||
|
||||
static List<BeltTileEntity> findBelts(EncasedFanTileEntity fan) {
|
||||
if (fan.getSpeed() == 0)
|
||||
return Collections.emptyList();
|
||||
List<BeltTileEntity> belts = new ArrayList<>();
|
||||
AxisAlignedBB searchBB = fan.frontBB.shrink(.25).contract(0, 0, 0).expand(0, -.25f, 0);
|
||||
|
||||
BlockPos.getAllInBox((int) searchBB.minX, (int) searchBB.minY, (int) searchBB.minZ, (int) searchBB.maxX - 1,
|
||||
(int) searchBB.maxY - 1, (int) searchBB.maxZ - 1)
|
||||
.filter(p -> AllBlocks.BELT.typeOf(fan.getWorld().getBlockState(p))).forEach(p -> {
|
||||
TileEntity te = fan.getWorld().getTileEntity(p);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return;
|
||||
belts.add((BeltTileEntity) te);
|
||||
});
|
||||
|
||||
return belts;
|
||||
}
|
||||
|
||||
static void tickBelts(EncasedFanTileEntity fan, List<BeltTileEntity> belts) {
|
||||
Type processingType = fan.getProcessingType();
|
||||
if (processingType == null)
|
||||
return;
|
||||
for (BeltTileEntity belt : belts) {
|
||||
BeltTileEntity controller = belt.getControllerTE();
|
||||
if (controller == null)
|
||||
continue;
|
||||
World world = belt.getWorld();
|
||||
|
||||
controller.getInventory().forEachWithin(belt.index + .5f, .5f, (transported) -> {
|
||||
if (world.rand.nextInt(4) == 0 && world.isRemote) {
|
||||
Vec3d vec = controller.getInventory().getVectorForOffset(transported.beltPosition);
|
||||
if (processingType == Type.BLASTING)
|
||||
world.addParticle(ParticleTypes.LARGE_SMOKE, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
|
||||
if (processingType == Type.SMOKING)
|
||||
world.addParticle(ParticleTypes.CLOUD, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
|
||||
if (processingType == Type.SPLASHING)
|
||||
world.addParticle(ParticleTypes.BUBBLE_POP, vec.x + (world.rand.nextFloat() - .5f) * .5f,
|
||||
vec.y + .25f, vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 16f, 0);
|
||||
}
|
||||
if (world.isRemote)
|
||||
return null;
|
||||
return InWorldProcessing.applyProcessing(transported, belt, processingType);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ public class EncasedFanParticleHandler {
|
|||
|
||||
private void initEffects() {
|
||||
List<FanEffect> standardFX = new ArrayList<>(2);
|
||||
standardFX.add(new FanEffect(ParticleTypes.BUBBLE_POP, 1 / 4f, 1 / 4f, 1 / 3f, 1));
|
||||
standardFX.add(new FanEffect(ParticleTypes.BUBBLE_POP, 1 / 4f, 1 / 4f, 1 / 8f, 1));
|
||||
standardFX.add(new FanEffect(new RedstoneParticleData(1, 1, 1, 1), 1 / 2f, 1 / 32f, 1/16f, 512f));
|
||||
effects.put(Blocks.AIR, standardFX);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
|||
import static net.minecraft.util.Direction.AxisDirection.NEGATIVE;
|
||||
import static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlockTags;
|
||||
|
@ -14,6 +15,7 @@ import com.simibubi.create.CreateClient;
|
|||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing;
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing.Type;
|
||||
|
||||
|
@ -51,6 +53,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
protected boolean findFrontBlock;
|
||||
protected BlockState frontBlock;
|
||||
protected boolean isGenerator;
|
||||
protected List<BeltTileEntity> affectedBelts = Collections.emptyList();
|
||||
|
||||
public EncasedFanTileEntity() {
|
||||
super(AllTileEntities.ENCASED_FAN.type);
|
||||
|
@ -67,6 +70,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
super.readClientUpdate(tag);
|
||||
updateFrontBlock();
|
||||
updateBBs();
|
||||
affectedBelts = EncasedFanBeltHandler.findBelts(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -140,6 +144,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
backBB = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
affectedBelts = EncasedFanBeltHandler.findBelts(this);
|
||||
sendData();
|
||||
}
|
||||
|
||||
|
@ -190,6 +195,8 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
if (getSpeed() == 0 || isGenerator)
|
||||
return;
|
||||
|
||||
EncasedFanBeltHandler.tickBelts(this, affectedBelts);
|
||||
|
||||
List<Entity> frontEntities = world.getEntitiesWithinAABBExcludingEntity(null, frontBB);
|
||||
for (Entity entity : frontEntities) {
|
||||
moveEntity(entity, true);
|
||||
|
@ -238,7 +245,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
return;
|
||||
|
||||
if (canProcess((ItemEntity) entity))
|
||||
InWorldProcessing.process((ItemEntity) entity, getProcessingType());
|
||||
InWorldProcessing.applyProcessing((ItemEntity) entity, getProcessingType());
|
||||
|
||||
} else {
|
||||
if (getProcessingType() == Type.SMOKING) {
|
||||
|
|
|
@ -39,7 +39,7 @@ import net.minecraftforge.common.IPlantable;
|
|||
|
||||
public class HarvesterBlock extends HorizontalBlock implements IHaveMovementBehavior {
|
||||
|
||||
private static VoxelShaper SHAPER = VoxelShaper.forHorizontalBlock(Block.makeCuboidShape(0, 2, 0, 16, 14, 3));
|
||||
private static VoxelShaper SHAPER = VoxelShaper.forHorizontal(Block.makeCuboidShape(0, 2, 0, 16, 14, 3));
|
||||
|
||||
public HarvesterBlock() {
|
||||
super(Properties.from(Blocks.IRON_BLOCK));
|
||||
|
|
|
@ -7,21 +7,22 @@ import java.util.Optional;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IRenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.foundation.utility.ItemHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -99,8 +100,8 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te) {
|
||||
return Arrays.asList(te.getPos().up(2));
|
||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
||||
return Arrays.asList(pos.up(2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,15 +113,35 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state) {
|
||||
BlockState blockState = world.getBlockState(pos.down(2));
|
||||
if (!AllBlocks.BELT.typeOf(blockState) || blockState.get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
|
||||
return Optional.empty();
|
||||
return Optional.of(pos.down(2));
|
||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
||||
return pos.down(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
public boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
|
||||
BlockState attachmentState, BlockState beltState) {
|
||||
return AllBlocks.BELT.typeOf(beltState) && beltState.get(BeltBlock.SLOPE) == Slope.HORIZONTAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
MechanicalPressTileEntity pressTe = (MechanicalPressTileEntity) te.getWorld()
|
||||
.getTileEntity(state.attachmentPos);
|
||||
|
||||
if (pressTe == null || pressTe.getSpeed() == 0)
|
||||
return false;
|
||||
if (pressTe.running)
|
||||
return false;
|
||||
if (!pressTe.getRecipe(transported.stack).isPresent())
|
||||
return false;
|
||||
|
||||
state.processingDuration = 1;
|
||||
pressTe.start(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transportedStack, BeltAttachmentState state) {
|
||||
MechanicalPressTileEntity pressTe = (MechanicalPressTileEntity) te.getWorld()
|
||||
.getTileEntity(state.attachmentPos);
|
||||
|
||||
|
@ -128,42 +149,23 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
|
|||
if (pressTe == null || pressTe.getSpeed() == 0)
|
||||
return false;
|
||||
|
||||
// Not an Item
|
||||
if (!(entity instanceof ItemEntity))
|
||||
return false;
|
||||
|
||||
// Running
|
||||
if (pressTe.running) {
|
||||
double distanceTo = entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos()));
|
||||
if (distanceTo < .32f)
|
||||
return true;
|
||||
if (distanceTo < .4f) {
|
||||
entity.setPosition(te.getPos().getX() + .5f, entity.posY, te.getPos().getZ() + .5f);
|
||||
return true;
|
||||
if (pressTe.runningTicks == 30) {
|
||||
Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack);
|
||||
if (!recipe.isPresent())
|
||||
return false;
|
||||
ItemStack out = recipe.get().getRecipeOutput().copy();
|
||||
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
|
||||
if (multipliedOutput.isEmpty())
|
||||
transportedStack.stack = ItemStack.EMPTY;
|
||||
transportedStack.stack = multipliedOutput.get(0);
|
||||
|
||||
TileEntity controllerTE = te.getWorld().getTileEntity(te.getController());
|
||||
if (controllerTE != null && controllerTE instanceof BeltTileEntity)
|
||||
((SyncedTileEntity) controllerTE).sendData();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start process
|
||||
if (state.processingEntity != entity) {
|
||||
state.processingEntity = entity;
|
||||
if (!pressTe.getRecipe((ItemEntity) entity).isPresent()) {
|
||||
state.processingDuration = -1;
|
||||
} else {
|
||||
state.processingDuration = 1;
|
||||
pressTe.start(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Already processed
|
||||
if (state.processingDuration == -1)
|
||||
return false;
|
||||
|
||||
// Just Finished
|
||||
if (pressTe.finished) {
|
||||
state.processingDuration = -1;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -6,13 +6,17 @@ import com.simibubi.create.AllRecipes;
|
|||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
|
@ -85,31 +89,45 @@ public class MechanicalPressTileEntity extends KineticTileEntity {
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
if (runningTicks == 30) {
|
||||
AxisAlignedBB bb = new AxisAlignedBB(pos.down(beltMode ? 2 : 1));
|
||||
for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bb)) {
|
||||
if (!(entity instanceof ItemEntity))
|
||||
continue;
|
||||
ItemEntity itemEntity = (ItemEntity) entity;
|
||||
|
||||
if (world.isRemote) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .25f).mul(1, 0, 1);
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, itemEntity.getItem()), entity.posX,
|
||||
entity.posY, entity.posZ, motion.x, motion.y, motion.z);
|
||||
if (!beltMode) {
|
||||
AxisAlignedBB bb = new AxisAlignedBB(pos.down(beltMode ? 2 : 1));
|
||||
for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bb)) {
|
||||
if (!(entity instanceof ItemEntity))
|
||||
continue;
|
||||
|
||||
ItemEntity itemEntity = (ItemEntity) entity;
|
||||
makeParticleEffect(entity.getPositionVec(), itemEntity.getItem());
|
||||
|
||||
if (!world.isRemote) {
|
||||
Optional<PressingRecipe> recipe = getRecipe(itemEntity.getItem());
|
||||
if (recipe.isPresent())
|
||||
InWorldProcessing.applyRecipeOn(itemEntity, recipe.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (beltMode && world.isRemote) {
|
||||
TileEntity te = world.getTileEntity(pos.down(2));
|
||||
if (te != null && te instanceof BeltTileEntity) {
|
||||
BeltTileEntity beltTE = (BeltTileEntity) te;
|
||||
TileEntity controller = world.getTileEntity(beltTE.getController());
|
||||
if (controller != null && controller instanceof BeltTileEntity) {
|
||||
TransportedItemStack stackAtOffset = ((BeltTileEntity) controller).getInventory()
|
||||
.getStackAtOffset(beltTE.index);
|
||||
if (stackAtOffset != null)
|
||||
makeParticleEffect(VecHelper.getCenterOf(pos.down(2)).add(0, 5 / 16f, 0),
|
||||
stackAtOffset.stack);
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isRemote) {
|
||||
Optional<PressingRecipe> recipe = getRecipe(itemEntity);
|
||||
if (recipe.isPresent())
|
||||
InWorldProcessing.applyRecipeOn(itemEntity, recipe.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (!world.isRemote) {
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, .5f, 1f);
|
||||
world.playSound(null, getPos(), SoundEvents.BLOCK_ANVIL_LAND, SoundCategory.BLOCKS, .125f, 1f);
|
||||
|
@ -128,8 +146,18 @@ public class MechanicalPressTileEntity extends KineticTileEntity {
|
|||
runningTicks++;
|
||||
}
|
||||
|
||||
public Optional<PressingRecipe> getRecipe(ItemEntity itemEntity) {
|
||||
pressingInv.setInventorySlotContents(0, itemEntity.getItem());
|
||||
public void makeParticleEffect(Vec3d pos, ItemStack stack) {
|
||||
if (world.isRemote) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .25f).mul(1, 0, 1);
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y, pos.z, motion.x,
|
||||
motion.y, motion.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<PressingRecipe> getRecipe(ItemStack item) {
|
||||
pressingInv.setInventorySlotContents(0, item);
|
||||
Optional<PressingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.PRESSING, pressingInv,
|
||||
world);
|
||||
return recipe;
|
||||
|
|
|
@ -4,10 +4,11 @@ import net.minecraft.inventory.ItemStackHelper;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
public class ProcessingInventory extends RecipeWrapper {
|
||||
public class ProcessingInventory extends RecipeWrapper implements IItemHandler {
|
||||
protected int remainingTime;
|
||||
protected int recipeDuration;
|
||||
protected boolean appliedRecipe;
|
||||
|
@ -50,8 +51,40 @@ public class ProcessingInventory extends RecipeWrapper {
|
|||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
public ItemStackHandler getItems() {
|
||||
return (ItemStackHandler) inv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
if (!isItemValid(slot, stack))
|
||||
return stack;
|
||||
return inv.insertItem(slot, stack, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return 64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return slot == 0 && isEmpty();
|
||||
}
|
||||
|
||||
}
|
|
@ -7,10 +7,12 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllRecipes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
|
@ -24,15 +26,23 @@ import net.minecraft.particles.BlockParticleData;
|
|||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
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.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
||||
|
||||
public ProcessingInventory inventory;
|
||||
private int recipeIndex;
|
||||
private ItemStack filter;
|
||||
private LazyOptional<IItemHandler> invProvider = LazyOptional.empty();
|
||||
|
||||
public SawTileEntity() {
|
||||
super(AllTileEntities.SAW.type);
|
||||
|
@ -40,6 +50,7 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
inventory.remainingTime = -1;
|
||||
filter = ItemStack.EMPTY;
|
||||
recipeIndex = 0;
|
||||
invProvider = LazyOptional.of(() -> inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,12 +89,17 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
return;
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
if (inventory.remainingTime == -1)
|
||||
if (inventory.remainingTime == -1) {
|
||||
if (!inventory.isEmpty() && !inventory.appliedRecipe)
|
||||
start();
|
||||
return;
|
||||
}
|
||||
|
||||
float processingSpeed = MathHelper.clamp(Math.abs(getSpeed()) / 32, 1, 128);
|
||||
inventory.remainingTime -= processingSpeed;
|
||||
spawnParticles(inventory.getStackInSlot(0));
|
||||
|
||||
if (inventory.remainingTime > 0)
|
||||
spawnParticles(inventory.getStackInSlot(0));
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
@ -95,10 +111,69 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
return;
|
||||
}
|
||||
|
||||
Vec3d outPos = VecHelper.getCenterOf(pos).add(getItemMovementVec().scale(.5f).add(0, .5, 0));
|
||||
Vec3d outMotion = getItemMovementVec().scale(.0625).add(0, .125, 0);
|
||||
Vec3d itemMovement = getItemMovementVec();
|
||||
Direction itemMovementFacing = Direction.getFacingFromVector(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||
Vec3d outPos = VecHelper.getCenterOf(pos).add(itemMovement.scale(.5f).add(0, .5, 0));
|
||||
Vec3d outMotion = itemMovement.scale(.0625).add(0, .125, 0);
|
||||
|
||||
if (inventory.remainingTime <= 0) {
|
||||
|
||||
// Try moving items onto the belt
|
||||
BlockPos nextPos = pos.add(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||
if (AllBlocks.BELT.typeOf(world.getBlockState(nextPos))) {
|
||||
TileEntity te = world.getTileEntity(nextPos);
|
||||
if (te != null && te instanceof BeltTileEntity) {
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
if (itemMovementFacing.getAxis() == Axis.Z)
|
||||
itemMovementFacing = itemMovementFacing.getOpposite();
|
||||
if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false))
|
||||
inventory.setInventorySlotContents(slot, ItemStack.EMPTY);
|
||||
else {
|
||||
inventory.remainingTime = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
inventory.clear();
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
}
|
||||
}
|
||||
|
||||
// Try moving items onto next saw
|
||||
if (AllBlocks.SAW.typeOf(world.getBlockState(nextPos))) {
|
||||
TileEntity te = world.getTileEntity(nextPos);
|
||||
if (te != null && te instanceof SawTileEntity) {
|
||||
SawTileEntity sawTileEntity = (SawTileEntity) te;
|
||||
Vec3d otherMovement = sawTileEntity.getItemMovementVec();
|
||||
if (Direction.getFacingFromVector(otherMovement.x, otherMovement.y,
|
||||
otherMovement.z) != itemMovementFacing.getOpposite()) {
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
ProcessingInventory sawInv = sawTileEntity.inventory;
|
||||
if (sawInv.isEmpty()) {
|
||||
sawInv.insertItem(0, stack, false);
|
||||
inventory.setInventorySlotContents(slot, ItemStack.EMPTY);
|
||||
|
||||
} else {
|
||||
inventory.remainingTime = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
inventory.clear();
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Eject Items
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
|
@ -108,6 +183,7 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
world.addEntity(entityIn);
|
||||
}
|
||||
inventory.clear();
|
||||
world.updateComparatorOutputLevel(pos, getBlockState().getBlock());
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
return;
|
||||
|
@ -116,6 +192,19 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
invProvider.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return invProvider.cast();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
protected void spawnParticles(ItemStack stack) {
|
||||
if (stack == null || stack.isEmpty())
|
||||
return;
|
||||
|
@ -198,6 +287,17 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
|
||||
inventory.clear();
|
||||
inventory.setInventorySlotContents(0, entity.getItem().copy());
|
||||
entity.remove();
|
||||
start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (!canProcess())
|
||||
return;
|
||||
if (inventory.isEmpty())
|
||||
return;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
List<IRecipe<?>> recipes = getRecipes();
|
||||
boolean valid = !recipes.isEmpty();
|
||||
|
@ -206,7 +306,6 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
if (recipes.isEmpty()) {
|
||||
inventory.remainingTime = inventory.recipeDuration = 10;
|
||||
inventory.appliedRecipe = false;
|
||||
entity.remove();
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
@ -222,11 +321,9 @@ public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
|||
time = ((CuttingRecipe) recipe).getProcessingDuration();
|
||||
}
|
||||
|
||||
inventory.remainingTime = time * Math.max(1, (entity.getItem().getCount() / 5));
|
||||
inventory.remainingTime = time * Math.max(1, (inventory.getStackInSlot(0).getCount() / 5));
|
||||
inventory.recipeDuration = inventory.remainingTime;
|
||||
inventory.appliedRecipe = false;
|
||||
entity.remove();
|
||||
|
||||
sendData();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,17 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
|
||||
public SawTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(SawTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
super.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
@ -43,9 +44,11 @@ public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
|||
boolean alongZ = !te.getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
float offset = te.inventory.recipeDuration != 0
|
||||
? (float) (te.inventory.remainingTime) / te.inventory.recipeDuration
|
||||
: 0;
|
||||
boolean moving = te.inventory.recipeDuration != 0;
|
||||
float offset = moving ? (float) (te.inventory.remainingTime) / te.inventory.recipeDuration : 0;
|
||||
if (moving)
|
||||
offset = MathHelper.clamp(offset + (-partialTicks + .5f) / te.inventory.recipeDuration, 0, 1);
|
||||
|
||||
if (te.getSpeed() == 0)
|
||||
offset = .5f;
|
||||
if (te.getSpeed() < 0 ^ alongZ)
|
||||
|
@ -69,7 +72,7 @@ public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
|||
|
||||
// Filter
|
||||
filterRenderer.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
||||
|
||||
// Kinetic renders
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.modules.contraptions.relays.belt;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
@ -14,6 +13,7 @@ import net.minecraft.nbt.CompoundNBT;
|
|||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -33,32 +33,52 @@ public enum AllBeltAttachments {
|
|||
}
|
||||
|
||||
public interface IBeltAttachment {
|
||||
public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te);
|
||||
|
||||
public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state);
|
||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState);
|
||||
|
||||
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state);
|
||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state);
|
||||
|
||||
default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos, BlockState attachmentState,
|
||||
BlockState beltState) {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean processEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default void onAttachmentPlaced(IWorld world, BlockPos pos, BlockState state) {
|
||||
Optional<BlockPos> beltPos = getValidBeltPositionFor(world, pos, state);
|
||||
if (!beltPos.isPresent())
|
||||
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
|
||||
TileEntity te = world.getTileEntity(beltPos);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return;
|
||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(beltPos.get());
|
||||
if (te == null)
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
if (!isAttachedCorrectly(world, pos, belt.getPos(), state, belt.getBlockState()))
|
||||
return;
|
||||
te.attachmentTracker.addAttachment(world, pos);
|
||||
te.sendData();
|
||||
belt.attachmentTracker.addAttachment(world, pos);
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
|
||||
default void onAttachmentRemoved(IWorld world, BlockPos pos, BlockState state) {
|
||||
Optional<BlockPos> beltPos = getValidBeltPositionFor(world, pos, state);
|
||||
if (!beltPos.isPresent())
|
||||
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
|
||||
TileEntity te = world.getTileEntity(beltPos);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return;
|
||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(beltPos.get());
|
||||
if (te == null)
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
if (!isAttachedCorrectly(world, pos, belt.getPos(), state, belt.getBlockState()))
|
||||
return;
|
||||
te.attachmentTracker.removeAttachment(pos);
|
||||
te.sendData();
|
||||
belt.attachmentTracker.removeAttachment(pos);
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +87,7 @@ public enum AllBeltAttachments {
|
|||
public BlockPos attachmentPos;
|
||||
public int processingDuration;
|
||||
public Entity processingEntity;
|
||||
public TransportedItemStack processingStack;
|
||||
|
||||
public BeltAttachmentState(IBeltAttachment attachment, BlockPos attachmentPos) {
|
||||
this.attachment = attachment;
|
||||
|
@ -86,19 +107,25 @@ public enum AllBeltAttachments {
|
|||
|
||||
public void findAttachments(BeltTileEntity belt) {
|
||||
for (AllBeltAttachments ba : AllBeltAttachments.values()) {
|
||||
List<BlockPos> attachmentPositions = ba.attachment.getPotentialAttachmentLocations(belt);
|
||||
World world = belt.getWorld();
|
||||
BlockPos beltPos = belt.getPos();
|
||||
BlockState beltState = belt.getBlockState();
|
||||
List<BlockPos> attachmentPositions = ba.attachment.getPotentialAttachmentPositions(world, beltPos,
|
||||
beltState);
|
||||
|
||||
for (BlockPos potentialPos : attachmentPositions) {
|
||||
if (!world.isBlockPresent(potentialPos))
|
||||
continue;
|
||||
BlockState state = world.getBlockState(potentialPos);
|
||||
if (!(state.getBlock() instanceof IBeltAttachment))
|
||||
if (!(state.getBlock() instanceof IBeltAttachment))
|
||||
continue;
|
||||
Optional<BlockPos> validBeltPos = ((IBeltAttachment) state.getBlock()).getValidBeltPositionFor(world, potentialPos, state);
|
||||
if (!validBeltPos.isPresent())
|
||||
IBeltAttachment attachment = (IBeltAttachment) state.getBlock();
|
||||
if (!attachment.getBeltPositionForAttachment(world, potentialPos, state).equals(beltPos))
|
||||
continue;
|
||||
if (validBeltPos.get().equals(belt.getPos()))
|
||||
addAttachment(world, potentialPos);
|
||||
if (!attachment.isAttachedCorrectly(world, potentialPos, beltPos, state, beltState))
|
||||
continue;
|
||||
|
||||
addAttachment(world, potentialPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -9,20 +10,28 @@ import com.simibubi.create.foundation.block.IWithTileEntity;
|
|||
import com.simibubi.create.foundation.block.IWithoutBlockItem;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity.TransportedEntityInfo;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.MobEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.pathfinding.PathNodeType;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
|
@ -31,121 +40,110 @@ import net.minecraft.util.IStringSerializable;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
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;
|
||||
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.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockItem, IWithTileEntity<BeltTileEntity> {
|
||||
|
||||
public static final IProperty<Slope> SLOPE = EnumProperty.create("slope", Slope.class);
|
||||
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
|
||||
|
||||
private static final VoxelShape FULL = makeCuboidShape(0, 0, 0, 16, 16, 16),
|
||||
FLAT_STRAIGHT_X = makeCuboidShape(1, 3, 0, 15, 13, 16),
|
||||
FLAT_STRAIGHT_Z = makeCuboidShape(0, 3, 1, 16, 13, 15),
|
||||
VERTICAL_STRAIGHT_X = makeCuboidShape(3, 0, 1, 13, 16, 15),
|
||||
VERTICAL_STRAIGHT_Z = makeCuboidShape(1, 0, 3, 15, 16, 13),
|
||||
|
||||
SLOPE_END_EAST = makeCuboidShape(0, 3, 1, 10, 13, 15),
|
||||
SLOPE_END_WEST = makeCuboidShape(6, 3, 1, 16, 13, 15),
|
||||
SLOPE_END_SOUTH = makeCuboidShape(1, 3, 0, 15, 13, 10),
|
||||
SLOPE_END_NORTH = makeCuboidShape(1, 3, 6, 15, 13, 16),
|
||||
|
||||
SLOPE_BUILDING_BLOCK_X = makeCuboidShape(5, 5, 1, 11, 11, 15),
|
||||
SLOPE_BUILDING_BLOCK_Z = makeCuboidShape(1, 5, 5, 15, 11, 11),
|
||||
|
||||
SLOPE_UPWARD_END_EAST = VoxelShapes.or(SLOPE_END_EAST, createHalfSlope(Direction.EAST, false)),
|
||||
SLOPE_UPWARD_END_WEST = VoxelShapes.or(SLOPE_END_WEST, createHalfSlope(Direction.WEST, false)),
|
||||
SLOPE_UPWARD_END_SOUTH = VoxelShapes.or(SLOPE_END_SOUTH, createHalfSlope(Direction.SOUTH, false)),
|
||||
SLOPE_UPWARD_END_NORTH = VoxelShapes.or(SLOPE_END_NORTH, createHalfSlope(Direction.NORTH, false)),
|
||||
|
||||
SLOPE_DOWNWARD_END_EAST = VoxelShapes.or(SLOPE_END_EAST, createHalfSlope(Direction.EAST, true)),
|
||||
SLOPE_DOWNWARD_END_WEST = VoxelShapes.or(SLOPE_END_WEST, createHalfSlope(Direction.WEST, true)),
|
||||
SLOPE_DOWNWARD_END_SOUTH = VoxelShapes.or(SLOPE_END_SOUTH, createHalfSlope(Direction.SOUTH, true)),
|
||||
SLOPE_DOWNWARD_END_NORTH = VoxelShapes.or(SLOPE_END_NORTH, createHalfSlope(Direction.NORTH, true)),
|
||||
|
||||
SLOPE_EAST = createSlope(Direction.EAST), SLOPE_WEST = createSlope(Direction.WEST),
|
||||
SLOPE_NORTH = createSlope(Direction.NORTH), SLOPE_SOUTH = createSlope(Direction.SOUTH);
|
||||
public static final BooleanProperty CASING = BooleanProperty.create("casing");
|
||||
private final VoxelShape collisionMask = makeCuboidShape(0, 0, 0, 16, 19, 16);
|
||||
|
||||
public BeltBlock() {
|
||||
super(Properties.from(Blocks.BROWN_WOOL));
|
||||
setDefaultState(getDefaultState().with(SLOPE, Slope.HORIZONTAL).with(PART, Part.START));
|
||||
setDefaultState(getDefaultState().with(SLOPE, Slope.HORIZONTAL).with(PART, Part.START).with(CASING, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(World world, BlockPos pos, BlockState state, Direction face) {
|
||||
if (face.getAxis() != getRotationAxis(state))
|
||||
return false;
|
||||
BeltTileEntity beltEntity = (BeltTileEntity) world.getTileEntity(pos);
|
||||
return beltEntity != null && beltEntity.hasPulley();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.get(HORIZONTAL_FACING).rotateY().getAxis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
|
||||
PlayerEntity player) {
|
||||
return new ItemStack(AllItems.BELT_CONNECTOR.item);
|
||||
return AllItems.BELT_CONNECTOR.asStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getMaterial(BlockState state) {
|
||||
return state.get(CASING) ? Material.WOOD : Material.WOOL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFlammable(BlockState state, IBlockReader world, BlockPos pos, Direction face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLanded(IBlockReader worldIn, Entity entityIn) {
|
||||
super.onLanded(worldIn, entityIn);
|
||||
|
||||
if (entityIn instanceof PlayerEntity && entityIn.isSneaking())
|
||||
return;
|
||||
if (entityIn instanceof PlayerEntity && ((PlayerEntity) entityIn).moveVertical > 0)
|
||||
return;
|
||||
|
||||
BeltTileEntity belt = null;
|
||||
BlockPos entityPosition = entityIn.getPosition();
|
||||
BlockPos beltPos = null;
|
||||
|
||||
if (AllBlocks.BELT.typeOf(worldIn.getBlockState(entityPosition)))
|
||||
belt = (BeltTileEntity) worldIn.getTileEntity(entityPosition);
|
||||
beltPos = entityPosition;
|
||||
else if (AllBlocks.BELT.typeOf(worldIn.getBlockState(entityPosition.down())))
|
||||
belt = (BeltTileEntity) worldIn.getTileEntity(entityPosition.down());
|
||||
|
||||
if (belt == null || !belt.hasSource())
|
||||
beltPos = entityPosition.down();
|
||||
if (beltPos == null)
|
||||
return;
|
||||
if (!(worldIn instanceof World))
|
||||
return;
|
||||
|
||||
BeltTileEntity controller = (BeltTileEntity) worldIn.getTileEntity(belt.getController());
|
||||
|
||||
if (controller == null)
|
||||
return;
|
||||
if (controller.passengers == null)
|
||||
return;
|
||||
|
||||
if (controller.passengers.containsKey(entityIn))
|
||||
controller.passengers.get(entityIn).refresh(belt.getPos(), belt.getBlockState());
|
||||
else
|
||||
controller.passengers.put(entityIn, new TransportedEntityInfo(belt.getPos(), belt.getBlockState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSlipperiness(BlockState state, IWorldReader world, BlockPos pos, Entity entity) {
|
||||
return super.getSlipperiness(state, world, pos, entity);
|
||||
onEntityCollision(worldIn.getBlockState(beltPos), (World) worldIn, beltPos, entityIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
|
||||
if (entityIn instanceof PlayerEntity && entityIn.isSneaking())
|
||||
return;
|
||||
if (entityIn instanceof PlayerEntity && ((PlayerEntity) entityIn).moveVertical > 0)
|
||||
return;
|
||||
|
||||
BeltTileEntity belt = null;
|
||||
belt = (BeltTileEntity) worldIn.getTileEntity(pos);
|
||||
|
||||
if (belt == null || !belt.hasSource())
|
||||
if (state.get(SLOPE) == Slope.VERTICAL)
|
||||
return;
|
||||
if (entityIn instanceof PlayerEntity && entityIn.isSneaking())
|
||||
return;
|
||||
if (belt == null || belt.getSpeed() == 0)
|
||||
return;
|
||||
if (entityIn instanceof ItemEntity && entityIn.isAlive()) {
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
if (entityIn.getMotion().y > 0)
|
||||
return;
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
ItemEntity itemEntity = (ItemEntity) entityIn;
|
||||
IItemHandler handler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
|
||||
if (handler == null)
|
||||
return;
|
||||
ItemStack remainder = handler.insertItem(0, itemEntity.getItem().copy(), false);
|
||||
if (remainder.isEmpty())
|
||||
itemEntity.remove();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
BeltTileEntity controller = (BeltTileEntity) worldIn.getTileEntity(belt.getController());
|
||||
|
||||
if (controller == null)
|
||||
if (controller == null || controller.passengers == null)
|
||||
return;
|
||||
if (controller.passengers == null)
|
||||
return;
|
||||
|
||||
if (controller.passengers.containsKey(entityIn)) {
|
||||
TransportedEntityInfo transportedEntityInfo = controller.passengers.get(entityIn);
|
||||
if (transportedEntityInfo.ticksSinceLastCollision != 0 || pos.equals(entityIn.getPosition()))
|
||||
transportedEntityInfo.refresh(pos, state);
|
||||
TransportedEntityInfo info = controller.passengers.get(entityIn);
|
||||
if (info.ticksSinceLastCollision != 0 || pos.equals(entityIn.getPosition()))
|
||||
info.refresh(pos, state);
|
||||
} else
|
||||
controller.passengers.put(entityIn, new TransportedEntityInfo(pos, state));
|
||||
}
|
||||
|
@ -163,19 +161,103 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
if (player.isSneaking() || !player.isAllowEdit())
|
||||
return false;
|
||||
ItemStack heldItem = player.getHeldItem(handIn);
|
||||
if (!Tags.Items.DYES.contains(heldItem.getItem()))
|
||||
return false;
|
||||
if (worldIn.isRemote)
|
||||
boolean isShaft = heldItem.getItem() == AllBlocks.SHAFT.get().asItem();
|
||||
boolean isCasing = heldItem.getItem() == AllBlocks.LOGISTICAL_CASING.get().asItem();
|
||||
boolean isDye = Tags.Items.DYES.contains(heldItem.getItem());
|
||||
boolean isHand = heldItem.isEmpty() && handIn == Hand.MAIN_HAND;
|
||||
|
||||
if (isDye) {
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
DyeColor dyeColor = DyeColor.getColor(heldItem);
|
||||
if (dyeColor == null)
|
||||
return;
|
||||
te.applyColor(dyeColor);
|
||||
});
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
return true;
|
||||
withTileEntityDo(worldIn, pos, te -> te.applyColor(DyeColor.getColor(heldItem)));
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntity te = worldIn.getTileEntity(pos);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return false;
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
|
||||
if (isHand) {
|
||||
BeltTileEntity controllerBelt = belt.getControllerTE();
|
||||
if (controllerBelt == null)
|
||||
return false;
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
controllerBelt.getInventory().forEachWithin(belt.index, .75f, (transportedItemStack) -> {
|
||||
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
||||
return Collections.emptyList();
|
||||
});
|
||||
}
|
||||
|
||||
if (isShaft) {
|
||||
if (state.get(PART) != Part.MIDDLE)
|
||||
return false;
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
worldIn.setBlockState(pos, state.with(PART, Part.PULLEY), 2);
|
||||
belt.attachKinetics();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isCasing) {
|
||||
if (state.get(CASING))
|
||||
return false;
|
||||
if (state.get(SLOPE) == Slope.VERTICAL)
|
||||
return false;
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
worldIn.setBlockState(pos, state.with(CASING, true), 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
TileEntity te = world.getTileEntity(context.getPos());
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return ActionResultType.PASS;
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
PlayerEntity player = context.getPlayer();
|
||||
|
||||
if (state.get(CASING)) {
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
world.setBlockState(context.getPos(), state.with(CASING, false), 2);
|
||||
if (!player.isCreative())
|
||||
player.inventory.placeItemBackInInventory(world, new ItemStack(AllBlocks.LOGISTICAL_CASING.block));
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
if (state.get(PART) == Part.PULLEY) {
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
world.setBlockState(context.getPos(), state.with(PART, Part.MIDDLE), 2);
|
||||
belt.detachKinetics();
|
||||
belt.attachKinetics();
|
||||
if (!player.isCreative())
|
||||
player.inventory.placeItemBackInInventory(world, new ItemStack(AllBlocks.SHAFT.block));
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
return super.onWrenched(state, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(SLOPE, PART);
|
||||
builder.add(SLOPE, PART, CASING);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
|
@ -184,47 +266,31 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathNodeType getAiPathNodeType(BlockState state, IBlockReader world, BlockPos pos, MobEntity entity) {
|
||||
return PathNodeType.DANGER_OTHER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
Axis axis = facing.getAxis();
|
||||
Part part = state.get(PART);
|
||||
Slope slope = state.get(SLOPE);
|
||||
return VoxelShapes.or(BeltShapes.getShape(state), BeltShapes.getCasingShape(state));
|
||||
}
|
||||
|
||||
if (slope == Slope.HORIZONTAL)
|
||||
return axis == Axis.Z ? FLAT_STRAIGHT_X : FLAT_STRAIGHT_Z;
|
||||
if (slope == Slope.VERTICAL)
|
||||
return axis == Axis.X ? VERTICAL_STRAIGHT_X : VERTICAL_STRAIGHT_Z;
|
||||
|
||||
if (part != Part.MIDDLE) {
|
||||
if (part == Part.START)
|
||||
slope = slope == Slope.UPWARD ? Slope.DOWNWARD : Slope.UPWARD;
|
||||
else
|
||||
facing = facing.getOpposite();
|
||||
|
||||
if (facing == Direction.NORTH)
|
||||
return slope == Slope.UPWARD ? SLOPE_UPWARD_END_NORTH : SLOPE_DOWNWARD_END_NORTH;
|
||||
if (facing == Direction.SOUTH)
|
||||
return slope == Slope.UPWARD ? SLOPE_UPWARD_END_SOUTH : SLOPE_DOWNWARD_END_SOUTH;
|
||||
if (facing == Direction.EAST)
|
||||
return slope == Slope.UPWARD ? SLOPE_UPWARD_END_EAST : SLOPE_DOWNWARD_END_EAST;
|
||||
if (facing == Direction.WEST)
|
||||
return slope == Slope.UPWARD ? SLOPE_UPWARD_END_WEST : SLOPE_DOWNWARD_END_WEST;
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos,
|
||||
ISelectionContext context) {
|
||||
VoxelShape shape = getShape(state, worldIn, pos, context);
|
||||
BeltTileEntity belt = (BeltTileEntity) worldIn.getTileEntity(pos);
|
||||
if (belt == null || context.getEntity() == null)
|
||||
return shape;
|
||||
BeltTileEntity controller = (BeltTileEntity) worldIn.getTileEntity(belt.getController());
|
||||
if (controller == null)
|
||||
return shape;
|
||||
if (controller.passengers == null || !controller.passengers.containsKey(context.getEntity())) {
|
||||
return VoxelShapes.combine(collisionMask, shape, IBooleanFunction.AND);
|
||||
}
|
||||
|
||||
if (slope == Slope.DOWNWARD)
|
||||
facing = facing.getOpposite();
|
||||
|
||||
if (facing == Direction.NORTH)
|
||||
return SLOPE_NORTH;
|
||||
if (facing == Direction.SOUTH)
|
||||
return SLOPE_SOUTH;
|
||||
if (facing == Direction.EAST)
|
||||
return SLOPE_EAST;
|
||||
if (facing == Direction.WEST)
|
||||
return SLOPE_WEST;
|
||||
|
||||
return FULL;
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -233,15 +299,22 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasStaticPart() {
|
||||
return false;
|
||||
public boolean canRenderInLayer(BlockState state, BlockRenderLayer layer) {
|
||||
return state.get(CASING) && layer == getRenderLayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
if (te.hasPulley())
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
if (te.hasPulley() && (player == null || !player.isCreative()))
|
||||
Block.spawnDrops(AllBlocks.SHAFT.get().getDefaultState(), worldIn, pos);
|
||||
if (te.isController()) {
|
||||
BeltInventory inv = te.getInventory();
|
||||
for (TransportedItemStack stack : inv.items)
|
||||
inv.eject(stack);
|
||||
}
|
||||
});
|
||||
super.onBlockHarvested(worldIn, pos, state, player);
|
||||
}
|
||||
|
@ -250,6 +323,8 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
if (state.getBlock() == newState.getBlock())
|
||||
return;
|
||||
|
||||
boolean endWasDestroyed = state.get(PART) == Part.END;
|
||||
TileEntity tileEntity = worldIn.getTileEntity(pos);
|
||||
|
@ -274,16 +349,20 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
break;
|
||||
|
||||
BeltTileEntity te = (BeltTileEntity) worldIn.getTileEntity(toDestroy);
|
||||
boolean hasPulley = te.hasPulley();
|
||||
if (te.isController()) {
|
||||
BeltInventory inv = te.getInventory();
|
||||
for (TransportedItemStack stack : inv.items)
|
||||
inv.eject(stack);
|
||||
}
|
||||
|
||||
te.setSource(null);
|
||||
te.remove();
|
||||
|
||||
if (hasPulley) {
|
||||
if (te.hasPulley())
|
||||
worldIn.setBlockState(toDestroy, AllBlocks.SHAFT.get().getDefaultState()
|
||||
.with(BlockStateProperties.AXIS, getRotationAxis(destroyedBlock)), 3);
|
||||
} else {
|
||||
else
|
||||
worldIn.destroyBlock(toDestroy, false);
|
||||
}
|
||||
|
||||
if (destroyedBlock.get(PART) == Part.END)
|
||||
break;
|
||||
|
@ -308,19 +387,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(World world, BlockPos pos, BlockState state, Direction face) {
|
||||
if (face.getAxis() != getRotationAxis(state))
|
||||
return false;
|
||||
BeltTileEntity beltEntity = (BeltTileEntity) world.getTileEntity(pos);
|
||||
return beltEntity != null && beltEntity.hasPulley();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.get(HORIZONTAL_FACING).getAxis() == Axis.X ? Axis.Z : Axis.X;
|
||||
}
|
||||
|
||||
public enum Slope implements IStringSerializable {
|
||||
HORIZONTAL, UPWARD, DOWNWARD, VERTICAL;
|
||||
|
||||
|
@ -331,7 +397,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
}
|
||||
|
||||
public enum Part implements IStringSerializable {
|
||||
START, MIDDLE, END;
|
||||
START, MIDDLE, END, PULLEY;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -339,18 +405,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean isUpperEnd(BlockState state, float speed) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
if (state.get(SLOPE) == Slope.UPWARD && state.get(PART) == Part.END) {
|
||||
return facing.getAxisDirection().getOffset() * Math.signum(speed) == (facing.getAxis() == Axis.X ? -1 : 1);
|
||||
}
|
||||
if (state.get(SLOPE) == Slope.DOWNWARD && state.get(PART) == Part.START) {
|
||||
return facing.getAxisDirection().getOffset() * Math.signum(speed) == (facing.getAxis() == Axis.Z ? -1 : 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<BlockPos> getBeltChain(World world, BlockPos controllerPos) {
|
||||
List<BlockPos> positions = new LinkedList<>();
|
||||
|
||||
|
@ -382,33 +436,34 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
return positions;
|
||||
}
|
||||
|
||||
protected static VoxelShape createSlope(Direction facing) {
|
||||
return VoxelShapes.or(createHalfSlope(facing.getOpposite(), false), createHalfSlope(facing, true));
|
||||
@Override
|
||||
protected boolean hasStaticPart() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static VoxelShape createHalfSlope(Direction facing, boolean upward) {
|
||||
VoxelShape shape = VoxelShapes.empty();
|
||||
VoxelShape buildingBlock = facing.getAxis() == Axis.X ? SLOPE_BUILDING_BLOCK_X : SLOPE_BUILDING_BLOCK_Z;
|
||||
Vec3i directionVec = facing.getDirectionVec();
|
||||
public static boolean canAccessFromSide(Direction facing, BlockState belt) {
|
||||
if (facing == null)
|
||||
return true;
|
||||
if (!belt.get(BeltBlock.CASING))
|
||||
return false;
|
||||
Part part = belt.get(BeltBlock.PART);
|
||||
if (part != Part.MIDDLE && facing.getAxis() == belt.get(HORIZONTAL_FACING).rotateY().getAxis())
|
||||
return false;
|
||||
|
||||
int x = directionVec.getX();
|
||||
int y = upward ? 1 : -1;
|
||||
int z = directionVec.getZ();
|
||||
Slope slope = belt.get(BeltBlock.SLOPE);
|
||||
if (slope != Slope.HORIZONTAL) {
|
||||
if (slope == Slope.DOWNWARD && part == Part.END)
|
||||
return true;
|
||||
if (slope == Slope.UPWARD && part == Part.START)
|
||||
return true;
|
||||
Direction beltSide = belt.get(HORIZONTAL_FACING);
|
||||
if (slope == Slope.DOWNWARD)
|
||||
beltSide = beltSide.getOpposite();
|
||||
if (beltSide == facing)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int segment = 0; segment < 6; segment++)
|
||||
shape = VoxelShapes.or(shape,
|
||||
buildingBlock.withOffset(x * segment / 16f, y * segment / 16f, z * segment / 16f));
|
||||
|
||||
if (!upward)
|
||||
return shape;
|
||||
|
||||
VoxelShape mask = makeCuboidShape(0, -8, 0, 16, 24, 16);
|
||||
for (int segment = 6; segment < 11; segment++)
|
||||
shape = VoxelShapes.or(shape,
|
||||
VoxelShapes.combine(mask,
|
||||
buildingBlock.withOffset(x * segment / 16f, y * segment / 16f, z * segment / 16f),
|
||||
IBooleanFunction.AND));
|
||||
return shape;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.ShaftBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
|
@ -22,9 +23,9 @@ import net.minecraft.util.Direction.AxisDirection;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltItem extends Item {
|
||||
public class BeltConnectorItem extends Item {
|
||||
|
||||
public BeltItem(Properties properties) {
|
||||
public BeltConnectorItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
|
@ -95,11 +96,23 @@ public class BeltItem extends Item {
|
|||
List<BlockPos> beltsToCreate = getBeltChainBetween(start, end, slope, facing);
|
||||
BlockState beltBlock = AllBlocks.BELT.get().getDefaultState();
|
||||
|
||||
int index = 0;
|
||||
for (BlockPos pos : beltsToCreate) {
|
||||
BeltBlock.Part part = pos.equals(start) ? Part.START : pos.equals(end) ? Part.END : Part.MIDDLE;
|
||||
boolean pulley = AllBlocks.SHAFT.typeOf(world.getBlockState(pos));
|
||||
if (part == Part.MIDDLE && pulley)
|
||||
part = Part.PULLEY;
|
||||
world.setBlockState(pos, beltBlock.with(BeltBlock.SLOPE, slope).with(BeltBlock.PART, part)
|
||||
.with(BeltBlock.HORIZONTAL_FACING, facing), 3);
|
||||
connectBelt(world, pos, start);
|
||||
|
||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(pos);
|
||||
if (te != null) {
|
||||
te.setController(start);
|
||||
te.beltLength = beltsToCreate.size();
|
||||
te.index = index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,12 +164,6 @@ public class BeltItem extends Item {
|
|||
return positions;
|
||||
}
|
||||
|
||||
private void connectBelt(World world, BlockPos pos, BlockPos target) {
|
||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(pos);
|
||||
if (te != null)
|
||||
te.setController(target);
|
||||
}
|
||||
|
||||
public static boolean canConnect(World world, BlockPos first, BlockPos second) {
|
||||
if (!world.isAreaLoaded(first, 1))
|
||||
return false;
|
||||
|
@ -190,11 +197,15 @@ public class BeltItem extends Item {
|
|||
int limit = 1000;
|
||||
for (BlockPos currentPos = first.add(step); !currentPos.equals(second)
|
||||
&& limit-- > 0; currentPos = currentPos.add(step)) {
|
||||
if (!world.getBlockState(currentPos).getMaterial().isReplaceable())
|
||||
BlockState blockState = world.getBlockState(currentPos);
|
||||
if (AllBlocks.SHAFT.typeOf(blockState) && blockState.get(ShaftBlock.AXIS) == axis)
|
||||
continue;
|
||||
if (!blockState.getMaterial().isReplaceable())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static boolean validateAxis(World world, BlockPos pos) {
|
|
@ -23,7 +23,7 @@ import net.minecraft.util.math.RayTraceResult;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltItemHandler {
|
||||
public class BeltConnectorItemHandler {
|
||||
|
||||
private static Random r = new Random();
|
||||
|
||||
|
@ -73,7 +73,7 @@ public class BeltItemHandler {
|
|||
if (!selected.withinDistance(first, CreateConfig.parameters.maxBeltLength.get()))
|
||||
return;
|
||||
|
||||
boolean canConnect = BeltItem.validateAxis(world, selected) && BeltItem.canConnect(world, first, selected);
|
||||
boolean canConnect = BeltConnectorItem.validateAxis(world, selected) && BeltConnectorItem.canConnect(world, first, selected);
|
||||
|
||||
Vec3d start = new Vec3d(first);
|
||||
Vec3d end = new Vec3d(selected);
|
|
@ -0,0 +1,380 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class BeltInventory {
|
||||
|
||||
final BeltTileEntity belt;
|
||||
final List<TransportedItemStack> items;
|
||||
boolean beltMovementPositive;
|
||||
final float SEGMENT_WINDOW = .75f;
|
||||
|
||||
public BeltInventory(BeltTileEntity te) {
|
||||
this.belt = te;
|
||||
items = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
||||
// Reverse item collection if belt just reversed
|
||||
if (beltMovementPositive != movingPositive()) {
|
||||
beltMovementPositive = movingPositive();
|
||||
Collections.reverse(items);
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
|
||||
// Assuming the first entry is furthest on the belt
|
||||
TransportedItemStack stackInFront = null;
|
||||
TransportedItemStack current = null;
|
||||
Iterator<TransportedItemStack> iterator = items.iterator();
|
||||
|
||||
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
|
||||
float spacing = 1;
|
||||
|
||||
Items: while (iterator.hasNext()) {
|
||||
stackInFront = current;
|
||||
current = iterator.next();
|
||||
current.prevBeltPosition = current.beltPosition;
|
||||
current.prevSideOffset = current.sideOffset;
|
||||
|
||||
if (current.stack.isEmpty()) {
|
||||
iterator.remove();
|
||||
current = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
float movement = beltSpeed;
|
||||
|
||||
// Don't move if locked
|
||||
boolean onClient = belt.getWorld().isRemote;
|
||||
if (onClient && current.locked)
|
||||
continue;
|
||||
|
||||
// Don't move if other items are waiting in front
|
||||
float currentPos = current.beltPosition;
|
||||
if (stackInFront != null) {
|
||||
float diff = stackInFront.beltPosition - currentPos;
|
||||
if (Math.abs(diff) <= spacing)
|
||||
continue;
|
||||
movement = beltMovementPositive ? Math.min(movement, diff - spacing)
|
||||
: Math.max(movement, diff + spacing);
|
||||
}
|
||||
|
||||
// Determine current segment
|
||||
int segmentBefore = (int) currentPos;
|
||||
float min = segmentBefore + .5f - (SEGMENT_WINDOW / 2);
|
||||
float max = segmentBefore + .5f + (SEGMENT_WINDOW / 2);
|
||||
if (currentPos < min || currentPos > max)
|
||||
segmentBefore = -1;
|
||||
|
||||
// Don't move beyond the edge
|
||||
float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos;
|
||||
float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd)
|
||||
: Math.max(movement, diffToEnd);
|
||||
|
||||
if (!onClient) {
|
||||
// Don't move if belt attachments want to continue processing
|
||||
if (segmentBefore != -1 && current.locked) {
|
||||
BeltTileEntity beltSegment = getBeltSegment(segmentBefore);
|
||||
if (beltSegment != null) {
|
||||
|
||||
current.locked = false;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
if (attachmentState.attachment.processItem(beltSegment, current, attachmentState))
|
||||
current.locked = true;
|
||||
}
|
||||
if (!current.locked || current.stack.isEmpty())
|
||||
belt.sendData();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// See if any new belt processing catches the item
|
||||
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
for (int segment = upcomingSegment; beltMovementPositive
|
||||
? segment + .5f <= current.beltPosition + limitedMovement
|
||||
: segment + .5f >= current.beltPosition + limitedMovement; segment += beltMovementPositive ? 1
|
||||
: -1) {
|
||||
BeltTileEntity beltSegment = getBeltSegment(segmentBefore);
|
||||
if (beltSegment == null)
|
||||
break;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
current.locked = true;
|
||||
belt.sendData();
|
||||
continue Items;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Movement
|
||||
current.beltPosition += limitedMovement;
|
||||
current.sideOffset += (current.getTargetSideOffset() - current.sideOffset) * Math.abs(limitedMovement) * 2f;
|
||||
currentPos = current.beltPosition;
|
||||
|
||||
// Determine segment after movement
|
||||
int segmentAfter = (int) currentPos;
|
||||
min = segmentAfter + .5f - (SEGMENT_WINDOW / 2);
|
||||
max = segmentAfter + .5f + (SEGMENT_WINDOW / 2);
|
||||
if (currentPos < min || currentPos > max)
|
||||
segmentAfter = -1;
|
||||
|
||||
// Item changed segments
|
||||
World world = belt.getWorld();
|
||||
if (segmentBefore != segmentAfter) {
|
||||
for (int segment : new int[] { segmentBefore, segmentAfter }) {
|
||||
if (segment == -1)
|
||||
continue;
|
||||
if (!world.isRemote)
|
||||
world.updateComparatorOutputLevel(getPositionForOffset(segment),
|
||||
belt.getBlockState().getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
// End reached
|
||||
if (limitedMovement != movement) {
|
||||
if (world.isRemote)
|
||||
continue;
|
||||
|
||||
BlockPos nextPosition = getPositionForOffset(beltMovementPositive ? belt.beltLength : -1);
|
||||
BlockState state = world.getBlockState(nextPosition);
|
||||
Direction movementFacing = belt.getMovementFacing();
|
||||
|
||||
// next block is a basin or a saw
|
||||
if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)) {
|
||||
TileEntity te = world.getTileEntity(nextPosition);
|
||||
if (te != null) {
|
||||
LazyOptional<IItemHandler> optional = te
|
||||
.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP);
|
||||
if (optional.isPresent()) {
|
||||
IItemHandler itemHandler = optional.orElse(null);
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(itemHandler, current.stack.copy(),
|
||||
false);
|
||||
if (remainder.equals(current.stack, false))
|
||||
continue;
|
||||
|
||||
current.stack = remainder;
|
||||
if (remainder.isEmpty()) {
|
||||
iterator.remove();
|
||||
current = null;
|
||||
}
|
||||
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// next block is not a belt
|
||||
if (!AllBlocks.BELT.typeOf(state)) {
|
||||
if (!Block.hasSolidSide(state, world, nextPosition, movementFacing.getOpposite())) {
|
||||
eject(current);
|
||||
iterator.remove();
|
||||
current = null;
|
||||
belt.sendData();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Next block is a belt
|
||||
TileEntity te = world.getTileEntity(nextPosition);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
continue;
|
||||
BeltTileEntity nextBelt = (BeltTileEntity) te;
|
||||
Direction nextMovementFacing = nextBelt.getMovementFacing();
|
||||
|
||||
// next belt goes the opposite way
|
||||
if (nextMovementFacing == movementFacing.getOpposite())
|
||||
continue;
|
||||
|
||||
// Inserting into other belt
|
||||
if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) {
|
||||
iterator.remove();
|
||||
current = null;
|
||||
belt.sendData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean canInsertAt(int segment) {
|
||||
return canInsertFrom(segment, Direction.UP);
|
||||
}
|
||||
|
||||
public boolean canInsertFrom(int segment, Direction side) {
|
||||
float min = segment + .5f - (SEGMENT_WINDOW / 2);
|
||||
float max = segment + .5f + (SEGMENT_WINDOW / 2);
|
||||
|
||||
for (TransportedItemStack stack : items) {
|
||||
float currentPos = stack.beltPosition;
|
||||
|
||||
// Searched past relevant stacks
|
||||
if (beltMovementPositive ? currentPos < segment : currentPos - 1 > segment)
|
||||
break;
|
||||
|
||||
// Item inside extraction window
|
||||
if (currentPos > min && currentPos < max)
|
||||
return false;
|
||||
|
||||
// Items on the belt get prioritized if the previous item was inserted on the
|
||||
// same segment
|
||||
if (stack.insertedAt == segment && stack.insertedFrom == side
|
||||
&& (beltMovementPositive ? currentPos <= segment + 1.5 : currentPos - 1.5 >= segment))
|
||||
return false;
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void insert(TransportedItemStack newStack) {
|
||||
if (items.isEmpty())
|
||||
items.add(newStack);
|
||||
else {
|
||||
int index = 0;
|
||||
for (TransportedItemStack stack : items) {
|
||||
if (stack.compareTo(newStack) > 0 == beltMovementPositive)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
items.add(index, newStack);
|
||||
}
|
||||
}
|
||||
|
||||
public TransportedItemStack getStackAtOffset(int offset) {
|
||||
float min = offset + .5f - (SEGMENT_WINDOW / 2);
|
||||
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
||||
for (TransportedItemStack stack : items) {
|
||||
if (stack.beltPosition > max)
|
||||
break;
|
||||
if (stack.beltPosition > min)
|
||||
return stack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void read(CompoundNBT nbt) {
|
||||
items.clear();
|
||||
nbt.getList("Items", NBT.TAG_COMPOUND)
|
||||
.forEach(inbt -> items.add(TransportedItemStack.read((CompoundNBT) inbt)));
|
||||
beltMovementPositive = nbt.getBoolean("PositiveOrder");
|
||||
}
|
||||
|
||||
public CompoundNBT write() {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
ListNBT itemsNBT = new ListNBT();
|
||||
items.forEach(stack -> itemsNBT.add(stack.serializeNBT()));
|
||||
nbt.put("Items", itemsNBT);
|
||||
nbt.putBoolean("PositiveOrder", beltMovementPositive);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public void eject(TransportedItemStack stack) {
|
||||
ItemStack ejected = stack.stack;
|
||||
Vec3d outPos = getVectorForOffset(stack.beltPosition);
|
||||
float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f);
|
||||
Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed).add(0, 1 / 8f, 0);
|
||||
outPos.add(outMotion.normalize());
|
||||
ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected);
|
||||
entity.setMotion(outMotion);
|
||||
entity.velocityChanged = true;
|
||||
belt.getWorld().addEntity(entity);
|
||||
}
|
||||
|
||||
public Vec3d getVectorForOffset(float offset) {
|
||||
Slope slope = belt.getBlockState().get(BeltBlock.SLOPE);
|
||||
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
||||
float verticalMovement = verticality;
|
||||
if (offset < .5)
|
||||
verticalMovement = 0;
|
||||
verticalMovement = verticalMovement * (Math.min(offset, belt.beltLength - .5f) - .5f);
|
||||
|
||||
Vec3d vec = VecHelper.getCenterOf(belt.getPos());
|
||||
vec = vec.add(new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f)).add(0, verticalMovement,
|
||||
0);
|
||||
return vec;
|
||||
}
|
||||
|
||||
private BeltTileEntity getBeltSegment(int segment) {
|
||||
BlockPos pos = getPositionForOffset(segment);
|
||||
TileEntity te = belt.getWorld().getTileEntity(pos);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return null;
|
||||
return (BeltTileEntity) te;
|
||||
}
|
||||
|
||||
private BlockPos getPositionForOffset(int offset) {
|
||||
BlockPos pos = belt.getPos();
|
||||
Vec3i vec = belt.getBeltFacing().getDirectionVec();
|
||||
Slope slope = belt.getBlockState().get(BeltBlock.SLOPE);
|
||||
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
||||
|
||||
return pos.add(offset * vec.getX(), MathHelper.clamp(offset, 0, belt.beltLength - 1) * verticality,
|
||||
offset * vec.getZ());
|
||||
}
|
||||
|
||||
private boolean movingPositive() {
|
||||
return belt.getDirectionAwareBeltMovementSpeed() > 0;
|
||||
}
|
||||
|
||||
public IItemHandler createHandlerForSegment(int segment) {
|
||||
return new ItemHandlerBeltSegment(this, segment);
|
||||
}
|
||||
|
||||
public void forEachWithin(float position, float distance,
|
||||
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
||||
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
||||
boolean dirty = false;
|
||||
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
|
||||
TransportedItemStack transportedItemStack = iterator.next();
|
||||
if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
|
||||
List<TransportedItemStack> apply = callback.apply(transportedItemStack);
|
||||
if (apply == null)
|
||||
continue;
|
||||
dirty = true;
|
||||
toBeAdded.addAll(apply);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
toBeAdded.forEach(this::insert);
|
||||
if (dirty) {
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class BeltModelAnimator extends BufferManipulator {
|
||||
protected static TextureAtlasSprite beltTextures;
|
||||
protected static TextureAtlasSprite originalTexture;
|
||||
|
||||
public BeltModelAnimator(ByteBuffer template) {
|
||||
super(template);
|
||||
}
|
||||
|
||||
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(BeltTileEntity te, float x, float y, float z, int color) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
float textureOffsetX = 0;
|
||||
float textureOffsetY = 0;
|
||||
|
||||
if (te.getSpeed() != 0) {
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
Direction direction = te.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
if (direction == Direction.EAST || direction == Direction.NORTH)
|
||||
time = -time;
|
||||
int textureIndex = (int) ((te.getSpeed() * time / 8) % 16);
|
||||
if (textureIndex < 0)
|
||||
textureIndex += 16;
|
||||
|
||||
if (beltTextures == null)
|
||||
initSprites();
|
||||
textureOffsetX = beltTextures.getInterpolatedU((textureIndex % 4) * 4) - originalTexture.getMinU();
|
||||
textureOffsetY = beltTextures.getInterpolatedV((textureIndex / 4) * 4) - originalTexture.getMinV();
|
||||
}
|
||||
|
||||
final BlockState blockState = te.getBlockState();
|
||||
int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
|
||||
float texOffX = textureOffsetX;
|
||||
float texOffY = textureOffsetY;
|
||||
|
||||
boolean defaultColor = color == -1;
|
||||
int b = defaultColor ? 128 : color & 0xFF;
|
||||
int g = defaultColor ? 128 : (color >> 8) & 0xFF;
|
||||
int r = defaultColor ? 128 : (color >> 16) & 0xFF;
|
||||
|
||||
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);
|
||||
|
||||
byte lumByte = getR(original, vertex);
|
||||
float lum = (lumByte < 0 ? 255 + lumByte : lumByte) / 256f;
|
||||
|
||||
int r2 = (int) (r * lum);
|
||||
int g2 = (int) (g * lum);
|
||||
int b2 = (int) (b * lum);
|
||||
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
beltTextures = null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import static net.minecraft.entity.MoverType.SELF;
|
||||
import static net.minecraft.util.Direction.AxisDirection.NEGATIVE;
|
||||
import static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
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.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltMovementHandler {
|
||||
|
||||
public static class TransportedEntityInfo {
|
||||
int ticksSinceLastCollision;
|
||||
BlockPos lastCollidedPos;
|
||||
BlockState lastCollidedState;
|
||||
|
||||
public TransportedEntityInfo(BlockPos collision, BlockState belt) {
|
||||
refresh(collision, belt);
|
||||
}
|
||||
|
||||
public void refresh(BlockPos collision, BlockState belt) {
|
||||
ticksSinceLastCollision = 0;
|
||||
lastCollidedPos = new BlockPos(collision).toImmutable();
|
||||
lastCollidedState = belt;
|
||||
}
|
||||
|
||||
public TransportedEntityInfo tick() {
|
||||
ticksSinceLastCollision++;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canBeTransported(Entity entity) {
|
||||
if (!entity.isAlive())
|
||||
return false;
|
||||
if (entity instanceof PlayerEntity && ((PlayerEntity) entity).isSneaking())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void transportEntity(BeltTileEntity beltTe, Entity entityIn, TransportedEntityInfo info) {
|
||||
BlockPos pos = info.lastCollidedPos;
|
||||
World world = beltTe.getWorld();
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
TileEntity tileEntityBelowPassenger = world.getTileEntity(entityIn.getPosition());
|
||||
BlockState blockState = info.lastCollidedState;
|
||||
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
||||
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
||||
beltTe.getSpeed() < 0 ? POSITIVE : NEGATIVE);
|
||||
|
||||
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
||||
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
||||
|
||||
// Don't fight other Belts
|
||||
if (!collidedWithBelt || betweenBelts) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Too slow
|
||||
boolean notHorizontal = beltTe.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL;
|
||||
if (Math.abs(beltTe.getSpeed()) < (notHorizontal ? 32 : 1))
|
||||
return;
|
||||
|
||||
// Not on top
|
||||
if (entityIn.posY - .25f < pos.getY())
|
||||
return;
|
||||
|
||||
// Lock entities in place
|
||||
boolean isPlayer = entityIn instanceof PlayerEntity;
|
||||
if (entityIn instanceof LivingEntity && !isPlayer) {
|
||||
((LivingEntity) entityIn).addPotionEffect(new EffectInstance(Effects.SLOWNESS, 10, 1, false, false));
|
||||
}
|
||||
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
|
||||
// Attachment pauses movement
|
||||
for (BeltAttachmentState state : belt.attachmentTracker.attachments) {
|
||||
if (state.attachment.processEntity(belt, entityIn, state)) {
|
||||
info.ticksSinceLastCollision--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
final Slope slope = blockState.get(BeltBlock.SLOPE);
|
||||
final Axis axis = beltFacing.getAxis();
|
||||
float movementSpeed = beltTe.getBeltMovementSpeed();
|
||||
final Direction movementDirection = Direction.getFacingFromAxis(axis == Axis.X ? NEGATIVE : POSITIVE, axis);
|
||||
|
||||
Vec3i centeringDirection = Direction.getFacingFromAxis(POSITIVE, beltFacing.rotateY().getAxis())
|
||||
.getDirectionVec();
|
||||
Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(movementSpeed);
|
||||
|
||||
double diffCenter = axis == Axis.Z ? (pos.getX() + .5f - entityIn.posX) : (pos.getZ() + .5f - entityIn.posZ);
|
||||
if (Math.abs(diffCenter) > 48 / 64f)
|
||||
return;
|
||||
|
||||
Part part = blockState.get(BeltBlock.PART);
|
||||
float top = 13 / 16f;
|
||||
boolean onSlope = notHorizontal && (part == Part.MIDDLE || part == Part.PULLEY
|
||||
|| part == (slope == Slope.UPWARD ? Part.END : Part.START) && entityIn.posY - pos.getY() < top
|
||||
|| part == (slope == Slope.UPWARD ? Part.START : Part.END) && entityIn.posY - pos.getY() > top);
|
||||
|
||||
boolean movingDown = onSlope && slope == (movementFacing == beltFacing ? Slope.DOWNWARD : Slope.UPWARD);
|
||||
boolean movingUp = onSlope && slope == (movementFacing == beltFacing ? Slope.UPWARD : Slope.DOWNWARD);
|
||||
|
||||
if (beltFacing.getAxis() == Axis.Z) {
|
||||
boolean b = movingDown;
|
||||
movingDown = movingUp;
|
||||
movingUp = b;
|
||||
}
|
||||
|
||||
if (movingUp)
|
||||
movement = movement.add(0, Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
||||
if (movingDown)
|
||||
movement = movement.add(0, -Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
||||
|
||||
Vec3d centering = new Vec3d(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4);
|
||||
movement = movement.add(centering);
|
||||
|
||||
float step = entityIn.stepHeight;
|
||||
if (!isPlayer)
|
||||
entityIn.stepHeight = 1;
|
||||
|
||||
// Entity Collisions
|
||||
if (Math.abs(movementSpeed) < .5f) {
|
||||
Vec3d checkDistance = movement.normalize().scale(0.5);
|
||||
AxisAlignedBB bb = entityIn.getBoundingBox();
|
||||
AxisAlignedBB checkBB = new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
||||
if (!world
|
||||
.getEntitiesWithinAABBExcludingEntity(entityIn, checkBB.offset(checkDistance)
|
||||
.grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z)))
|
||||
.isEmpty()) {
|
||||
entityIn.setMotion(0, 0, 0);
|
||||
info.ticksSinceLastCollision--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (movingUp) {
|
||||
float minVelocity = .13f;
|
||||
float yMovement = (float) -(Math.max(Math.abs(movement.y), minVelocity));
|
||||
entityIn.move(SELF, new Vec3d(0, yMovement, 0));
|
||||
entityIn.move(SELF, movement.mul(1, 0, 1));
|
||||
} else if (movingDown) {
|
||||
entityIn.move(SELF, movement.mul(1, 0, 1));
|
||||
entityIn.move(SELF, movement.mul(0, 1, 0));
|
||||
} else {
|
||||
entityIn.move(SELF, movement);
|
||||
}
|
||||
|
||||
if (!isPlayer)
|
||||
entityIn.stepHeight = step;
|
||||
|
||||
boolean movedPastEndingSlope = onSlope && (AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition()))
|
||||
|| AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition().down())));
|
||||
|
||||
if (movedPastEndingSlope && !movingDown && Math.abs(movementSpeed) > 0)
|
||||
entityIn.setPosition(entityIn.posX, entityIn.posY + movement.y, entityIn.posZ);
|
||||
if (movedPastEndingSlope) {
|
||||
entityIn.setMotion(movement);
|
||||
entityIn.velocityChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import static net.minecraft.block.Block.makeCuboidShape;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
public class BeltShapes {
|
||||
|
||||
private static final VoxelShape SLOPE_BUILDING_BLOCK_X = makeCuboidShape(5, 5, 1, 11, 11, 15),
|
||||
SLOPE_BUILDING_BLOCK_Z = makeCuboidShape(1, 5, 5, 15, 11, 11),
|
||||
CASING_HORIZONTAL = makeCuboidShape(0, 0, 0, 16, 11, 16);
|
||||
|
||||
private static final VoxelShaper SLOPE_END = VoxelShaper.forHorizontal(makeCuboidShape(1, 3, 0, 15, 13, 10)),
|
||||
SLOPE_TOP_END = VoxelShaper.forHorizontal(
|
||||
VoxelShapes.or(SLOPE_END.get(Direction.SOUTH), createHalfSlope(Direction.SOUTH, false))),
|
||||
SLOPE_BOTTOM_END = VoxelShaper.forHorizontal(
|
||||
VoxelShapes.or(SLOPE_END.get(Direction.SOUTH), createHalfSlope(Direction.SOUTH, true))),
|
||||
FLAT_STRAIGHT = VoxelShaper.forHorizontalAxis(makeCuboidShape(0, 3, 1, 16, 13, 15)),
|
||||
VERTICAL_STRAIGHT = VoxelShaper.forHorizontalAxis(makeCuboidShape(1, 0, 3, 15, 16, 13)),
|
||||
SLOPE_STRAIGHT = VoxelShaper.forHorizontal(createSlope(Direction.SOUTH)),
|
||||
CASING_TOP_END = VoxelShaper.forHorizontal(makeCuboidShape(0, 0, 0, 16, 11, 11));
|
||||
|
||||
public static VoxelShape getShape(BlockState state) {
|
||||
Direction facing = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
Axis axis = facing.getAxis();
|
||||
Axis perpendicularAxis = facing.rotateY().getAxis();
|
||||
Part part = state.get(BeltBlock.PART);
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
|
||||
if (slope == Slope.HORIZONTAL)
|
||||
return FLAT_STRAIGHT.get(perpendicularAxis);
|
||||
if (slope == Slope.VERTICAL)
|
||||
return VERTICAL_STRAIGHT.get(axis);
|
||||
|
||||
if (part != Part.MIDDLE && part != Part.PULLEY) {
|
||||
boolean upward = slope == Slope.UPWARD;
|
||||
if (part == Part.START)
|
||||
upward = !upward;
|
||||
else
|
||||
facing = facing.getOpposite();
|
||||
|
||||
return upward ? SLOPE_TOP_END.get(facing) : SLOPE_BOTTOM_END.get(facing);
|
||||
}
|
||||
|
||||
if (slope == Slope.DOWNWARD)
|
||||
facing = facing.getOpposite();
|
||||
|
||||
return SLOPE_STRAIGHT.get(facing);
|
||||
}
|
||||
|
||||
public static VoxelShape getCasingShape(BlockState state) {
|
||||
if (!state.get(BeltBlock.CASING))
|
||||
return VoxelShapes.empty();
|
||||
|
||||
Direction facing = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
Part part = state.get(BeltBlock.PART);
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
|
||||
if (slope == Slope.HORIZONTAL)
|
||||
return CASING_HORIZONTAL;
|
||||
if (slope == Slope.VERTICAL)
|
||||
return VoxelShapes.empty();
|
||||
|
||||
if (part != Part.MIDDLE) {
|
||||
boolean upward = slope == Slope.UPWARD;
|
||||
if (part == Part.START)
|
||||
upward = !upward;
|
||||
else
|
||||
facing = facing.getOpposite();
|
||||
|
||||
return upward ? CASING_TOP_END.get(facing) : CASING_HORIZONTAL;
|
||||
}
|
||||
|
||||
if (slope == Slope.DOWNWARD)
|
||||
facing = facing.getOpposite();
|
||||
|
||||
return CASING_TOP_END.get(facing.getOpposite());
|
||||
}
|
||||
|
||||
protected static VoxelShape createSlope(Direction facing) {
|
||||
return VoxelShapes.or(createHalfSlope(facing.getOpposite(), false), createHalfSlope(facing, true));
|
||||
}
|
||||
|
||||
protected static VoxelShape createHalfSlope(Direction facing, boolean upward) {
|
||||
VoxelShape shape = VoxelShapes.empty();
|
||||
VoxelShape buildingBlock = facing.getAxis() == Axis.X ? SLOPE_BUILDING_BLOCK_X : SLOPE_BUILDING_BLOCK_Z;
|
||||
Vec3i directionVec = facing.getDirectionVec();
|
||||
|
||||
int x = directionVec.getX();
|
||||
int y = upward ? 1 : -1;
|
||||
int z = directionVec.getZ();
|
||||
|
||||
for (int segment = 0; segment < 6; segment++)
|
||||
shape = VoxelShapes.or(shape,
|
||||
buildingBlock.withOffset(x * segment / 16f, y * segment / 16f, z * segment / 16f));
|
||||
|
||||
if (!upward)
|
||||
return shape;
|
||||
|
||||
VoxelShape mask = makeCuboidShape(0, -8, 0, 16, 24, 16);
|
||||
for (int segment = 6; segment < 11; segment++)
|
||||
shape = VoxelShapes.or(shape,
|
||||
VoxelShapes.combine(mask,
|
||||
buildingBlock.withOffset(x * segment / 16f, y * segment / 16f, z * segment / 16f),
|
||||
IBooleanFunction.AND));
|
||||
return shape;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,13 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import static com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part.END;
|
||||
import static com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part.MIDDLE;
|
||||
import static com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope.DOWNWARD;
|
||||
import static com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope.HORIZONTAL;
|
||||
import static com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope.UPWARD;
|
||||
import static net.minecraft.util.Direction.AxisDirection.NEGATIVE;
|
||||
import static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -9,116 +17,180 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.Tracker;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
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.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class BeltTileEntity extends KineticTileEntity {
|
||||
|
||||
protected BlockPos controller;
|
||||
public Map<Entity, TransportedEntityInfo> passengers;
|
||||
public AllBeltAttachments.Tracker attachmentTracker;
|
||||
private CompoundNBT trackerUpdateTag;
|
||||
public int color;
|
||||
public int beltLength;
|
||||
public int index;
|
||||
|
||||
protected static class TransportedEntityInfo {
|
||||
int ticksSinceLastCollision;
|
||||
BlockPos lastCollidedPos;
|
||||
BlockState lastCollidedState;
|
||||
protected BlockPos controller;
|
||||
protected BeltInventory inventory;
|
||||
protected LazyOptional<IItemHandler> itemHandler;
|
||||
|
||||
public TransportedEntityInfo(BlockPos collision, BlockState belt) {
|
||||
refresh(collision, belt);
|
||||
}
|
||||
|
||||
public void refresh(BlockPos collision, BlockState belt) {
|
||||
ticksSinceLastCollision = 0;
|
||||
lastCollidedPos = new BlockPos(collision).toImmutable();
|
||||
lastCollidedState = belt;
|
||||
}
|
||||
|
||||
public TransportedEntityInfo tick() {
|
||||
ticksSinceLastCollision++;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
private CompoundNBT trackerUpdateTag;
|
||||
|
||||
public BeltTileEntity() {
|
||||
super(AllTileEntities.BELT.type);
|
||||
controller = BlockPos.ZERO;
|
||||
attachmentTracker = new Tracker(this);
|
||||
itemHandler = LazyOptional.empty();
|
||||
color = -1;
|
||||
beltLength = -1;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
protected boolean isLastBelt() {
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
// Initialize Belt Attachments
|
||||
if (world != null && trackerUpdateTag != null) {
|
||||
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
||||
trackerUpdateTag = null;
|
||||
}
|
||||
if (getSpeed() == 0)
|
||||
return false;
|
||||
return;
|
||||
|
||||
Direction direction = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
if (getBlockState().get(BeltBlock.SLOPE) == Slope.VERTICAL)
|
||||
return false;
|
||||
initializeItemHandler();
|
||||
|
||||
Part part = getBlockState().get(BeltBlock.PART);
|
||||
if (part == Part.MIDDLE)
|
||||
return false;
|
||||
// Move Items
|
||||
if (!isController())
|
||||
return;
|
||||
getInventory().tick();
|
||||
|
||||
boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1))
|
||||
^ direction.getAxis() == Axis.X;
|
||||
return part == Part.START ^ movingPositively;
|
||||
// Move Entities
|
||||
if (passengers == null)
|
||||
passengers = new HashMap<>();
|
||||
|
||||
List<Entity> toRemove = new ArrayList<>();
|
||||
passengers.forEach((entity, info) -> {
|
||||
boolean canBeTransported = BeltMovementHandler.canBeTransported(entity);
|
||||
boolean leftTheBelt = info.ticksSinceLastCollision > ((getBlockState().get(BeltBlock.SLOPE) != HORIZONTAL)
|
||||
? 3
|
||||
: 1);
|
||||
if (!canBeTransported || leftTheBelt) {
|
||||
toRemove.add(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
info.tick();
|
||||
BeltMovementHandler.transportEntity(this, entity, info);
|
||||
});
|
||||
toRemove.forEach(passengers::remove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
if (!isController())
|
||||
return super.getRenderBoundingBox();
|
||||
return super.getRenderBoundingBox().grow(beltLength);
|
||||
}
|
||||
|
||||
protected void initializeItemHandler() {
|
||||
if (world.isRemote || itemHandler.isPresent())
|
||||
return;
|
||||
if (!world.isBlockPresent(controller))
|
||||
return;
|
||||
TileEntity te = world.getTileEntity(controller);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return;
|
||||
IItemHandler handler = ((BeltTileEntity) te).getInventory().createHandlerForSegment(index);
|
||||
itemHandler = LazyOptional.of(() -> handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
return !isController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
if (side == Direction.UP || BeltBlock.canAccessFromSide(side, getBlockState())) {
|
||||
return itemHandler.cast();
|
||||
}
|
||||
}
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
itemHandler.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
attachmentTracker.write(compound);
|
||||
compound.put("Controller", NBTUtil.writeBlockPos(controller));
|
||||
compound.putInt("Color", color);
|
||||
attachmentTracker.write(compound);
|
||||
compound.putInt("Length", beltLength);
|
||||
compound.putInt("Index", index);
|
||||
|
||||
if (isController())
|
||||
compound.put("Inventory", getInventory().write());
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||
trackerUpdateTag = compound;
|
||||
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||
color = compound.getInt("Color");
|
||||
beltLength = compound.getInt("Length");
|
||||
index = compound.getInt("Index");
|
||||
|
||||
if (isController())
|
||||
getInventory().read(compound.getCompound("Inventory"));
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
public void applyColor(DyeColor colorIn) {
|
||||
int colorValue = colorIn.getMapColor().colorValue;
|
||||
for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) {
|
||||
BeltTileEntity tileEntity = (BeltTileEntity) world.getTileEntity(blockPos);
|
||||
if (tileEntity != null) {
|
||||
if (tileEntity.color == -1) {
|
||||
tileEntity.color = colorValue;
|
||||
} else {
|
||||
tileEntity.color = ColorHelper.mixColors(tileEntity.color, colorValue, .5f);
|
||||
}
|
||||
tileEntity.sendData();
|
||||
}
|
||||
BeltTileEntity belt = (BeltTileEntity) world.getTileEntity(blockPos);
|
||||
if (belt == null)
|
||||
continue;
|
||||
belt.color = belt.color == -1 ? colorValue : ColorHelper.mixColors(belt.color, colorValue, .5f);
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
|
||||
public BeltTileEntity getControllerTE() {
|
||||
if (!world.isBlockPresent(controller))
|
||||
return null;
|
||||
TileEntity te = world.getTileEntity(controller);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return null;
|
||||
return (BeltTileEntity) te;
|
||||
}
|
||||
|
||||
public void setController(BlockPos controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
@ -131,177 +203,123 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
return controller.equals(pos);
|
||||
}
|
||||
|
||||
public float getBeltMovementSpeed() {
|
||||
return getSpeed() / 1600f;
|
||||
}
|
||||
|
||||
public float getDirectionAwareBeltMovementSpeed() {
|
||||
int offset = getBeltFacing().getAxisDirection().getOffset();
|
||||
if (getBeltFacing().getAxis() == Axis.X)
|
||||
offset *= -1;
|
||||
return getSpeed() / 1600f * offset;
|
||||
}
|
||||
|
||||
public boolean hasPulley() {
|
||||
if (!AllBlocks.BELT.typeOf(getBlockState()))
|
||||
return false;
|
||||
return getBlockState().get(BeltBlock.PART) == Part.END || getBlockState().get(BeltBlock.PART) == Part.START;
|
||||
return getBlockState().get(BeltBlock.PART) != Part.MIDDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (world != null && trackerUpdateTag != null) {
|
||||
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
||||
trackerUpdateTag = null;
|
||||
}
|
||||
if (!isController())
|
||||
return;
|
||||
if (passengers == null)
|
||||
passengers = new HashMap<>();
|
||||
|
||||
passengers.forEach((entity, info) -> {
|
||||
transportEntity(entity, info);
|
||||
});
|
||||
|
||||
List<Entity> toRemove = new ArrayList<>();
|
||||
passengers.forEach((entity, info) -> {
|
||||
if (!canTransport(entity))
|
||||
toRemove.add(entity);
|
||||
if (info.ticksSinceLastCollision > ((getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL) ? 3 : 1)) {
|
||||
toRemove.add(entity);
|
||||
}
|
||||
info.tick();
|
||||
});
|
||||
toRemove.forEach(e -> {
|
||||
if (e instanceof ItemEntity)
|
||||
((ItemEntity) e).setAgeToCreativeDespawnTime();
|
||||
passengers.remove(e);
|
||||
});
|
||||
|
||||
protected boolean isLastBelt() {
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
Direction direction = getBeltFacing();
|
||||
if (getBlockState().get(BeltBlock.SLOPE) == Slope.VERTICAL)
|
||||
return false;
|
||||
|
||||
Part part = getBlockState().get(BeltBlock.PART);
|
||||
if (part == MIDDLE)
|
||||
return false;
|
||||
|
||||
boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1))
|
||||
^ direction.getAxis() == Axis.X;
|
||||
return part == Part.START ^ movingPositively;
|
||||
}
|
||||
|
||||
public void transportEntity(Entity entityIn, TransportedEntityInfo info) {
|
||||
BlockPos pos = info.lastCollidedPos;
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
TileEntity tileEntityBelowPassenger = world.getTileEntity(entityIn.getPosition());
|
||||
BlockState blockState = info.lastCollidedState;
|
||||
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
||||
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
||||
getSpeed() < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
||||
public Vec3i getMovementDirection(boolean firstHalf) {
|
||||
return this.getMovementDirection(firstHalf, false);
|
||||
}
|
||||
|
||||
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
||||
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
||||
public Vec3i getBeltChainDirection() {
|
||||
return this.getMovementDirection(true, true);
|
||||
}
|
||||
|
||||
// Don't fight other Belts
|
||||
if (!collidedWithBelt || betweenBelts) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Too slow
|
||||
boolean notHorizontal = getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL;
|
||||
if (Math.abs(getSpeed()) < (notHorizontal ? 32 : 1))
|
||||
return;
|
||||
|
||||
// Not on top
|
||||
if (entityIn.posY - .25f < pos.getY())
|
||||
return;
|
||||
|
||||
// Lock entities in place
|
||||
if (entityIn instanceof LivingEntity && !(entityIn instanceof PlayerEntity)) {
|
||||
((LivingEntity) entityIn).addPotionEffect(new EffectInstance(Effects.SLOWNESS, 1, 9, false, false));
|
||||
}
|
||||
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
|
||||
// Attachment pauses movement
|
||||
for (BeltAttachmentState state : belt.attachmentTracker.attachments) {
|
||||
if (state.attachment.handleEntity(belt, entityIn, state)) {
|
||||
info.ticksSinceLastCollision--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
protected Vec3i getMovementDirection(boolean firstHalf, boolean ignoreHalves) {
|
||||
if (getSpeed() == 0)
|
||||
return BlockPos.ZERO;
|
||||
|
||||
final BlockState blockState = getBlockState();
|
||||
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
final Slope slope = blockState.get(BeltBlock.SLOPE);
|
||||
final Part part = blockState.get(BeltBlock.PART);
|
||||
final Axis axis = beltFacing.getAxis();
|
||||
float movementSpeed = ((KineticTileEntity) te).getSpeed() / 1600f;
|
||||
final Direction movementDirection = Direction
|
||||
.getFacingFromAxis(axis == Axis.X ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE, axis);
|
||||
|
||||
Vec3i centeringDirection = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis == Axis.X ? Axis.Z : Axis.X)
|
||||
.getDirectionVec();
|
||||
Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(movementSpeed);
|
||||
Direction movementFacing = Direction.getFacingFromAxis(axis == Axis.X ? NEGATIVE : POSITIVE, axis);
|
||||
boolean notHorizontal = blockState.get(BeltBlock.SLOPE) != HORIZONTAL;
|
||||
if (getSpeed() < 0)
|
||||
movementFacing = movementFacing.getOpposite();
|
||||
Vec3i movement = movementFacing.getDirectionVec();
|
||||
|
||||
double diffCenter = axis == Axis.Z ? (pos.getX() + .5f - entityIn.posX) : (pos.getZ() + .5f - entityIn.posZ);
|
||||
float maxDiffCenter = (entityIn instanceof ItemEntity) ? 32 / 64f : 48 / 64f;
|
||||
if (Math.abs(diffCenter) > maxDiffCenter)
|
||||
return;
|
||||
boolean slopeBeforeHalf = (part == END) == (beltFacing.getAxisDirection() == POSITIVE);
|
||||
boolean onSlope = notHorizontal && (part == MIDDLE || slopeBeforeHalf == firstHalf || ignoreHalves);
|
||||
boolean movingUp = onSlope && slope == (movementFacing == beltFacing ? UPWARD : DOWNWARD);
|
||||
|
||||
Part part = blockState.get(BeltBlock.PART);
|
||||
float top = 13 / 16f;
|
||||
boolean onSlope = notHorizontal && (part == Part.MIDDLE
|
||||
|| part == (slope == Slope.UPWARD ? Part.END : Part.START) && entityIn.posY - pos.getY() < top
|
||||
|| part == (slope == Slope.UPWARD ? Part.START : Part.END) && entityIn.posY - pos.getY() > top);
|
||||
if (!onSlope)
|
||||
return movement;
|
||||
|
||||
boolean movingDown = onSlope && slope == (movementFacing == beltFacing ? Slope.DOWNWARD : Slope.UPWARD);
|
||||
boolean movingUp = onSlope && slope == (movementFacing == beltFacing ? Slope.UPWARD : Slope.DOWNWARD);
|
||||
|
||||
if (beltFacing.getAxis() == Axis.Z) {
|
||||
boolean b = movingDown;
|
||||
movingDown = movingUp;
|
||||
movingUp = b;
|
||||
}
|
||||
|
||||
if (movingUp)
|
||||
movement = movement.add(0, Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
||||
if (movingDown)
|
||||
movement = movement.add(0, -Math.abs(axis.getCoordinate(movement.x, movement.y, movement.z)), 0);
|
||||
|
||||
Vec3d centering = new Vec3d(centeringDirection).scale(diffCenter * Math.min(Math.abs(movementSpeed), .1f) * 4);
|
||||
movement = movement.add(centering);
|
||||
|
||||
float step = entityIn.stepHeight;
|
||||
if (!(entityIn instanceof PlayerEntity))
|
||||
entityIn.stepHeight = 1;
|
||||
|
||||
// Entity Collisions
|
||||
if (Math.abs(movementSpeed) < .5f) {
|
||||
Vec3d checkDistance = movement.scale(2f).add(movement.normalize());
|
||||
AxisAlignedBB bb = entityIn.getBoundingBox();
|
||||
AxisAlignedBB checkBB = new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
||||
if (!world
|
||||
.getEntitiesWithinAABBExcludingEntity(entityIn, checkBB.offset(checkDistance)
|
||||
.grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z)))
|
||||
.isEmpty()) {
|
||||
entityIn.setMotion(0, 0, 0);
|
||||
info.ticksSinceLastCollision--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (movingUp) {
|
||||
float minVelocity = entityIn instanceof ItemEntity ? .09f : .13f;
|
||||
float yMovement = (float) -(Math.max(Math.abs(movement.y), minVelocity));
|
||||
entityIn.move(MoverType.SELF, new Vec3d(0, yMovement, 0));
|
||||
entityIn.move(MoverType.SELF, movement.mul(1, 0, 1));
|
||||
} else if (movingDown) {
|
||||
entityIn.move(MoverType.SELF, movement.mul(1, 0, 1));
|
||||
entityIn.move(MoverType.SELF, movement.mul(0, 1, 0));
|
||||
} else {
|
||||
entityIn.move(MoverType.SELF, movement);
|
||||
}
|
||||
|
||||
if (!(entityIn instanceof PlayerEntity))
|
||||
entityIn.stepHeight = step;
|
||||
|
||||
boolean movedPastEndingSlope = onSlope && (AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition()))
|
||||
|| AllBlocks.BELT.typeOf(world.getBlockState(entityIn.getPosition().down())));
|
||||
|
||||
if (movedPastEndingSlope && !movingDown && Math.abs(movementSpeed) > 0)
|
||||
entityIn.setPosition(entityIn.posX, entityIn.posY + movement.y, entityIn.posZ);
|
||||
if (movedPastEndingSlope)
|
||||
entityIn.setMotion(movement);
|
||||
return new Vec3i(movement.getX(), movingUp ? 1 : -1, movement.getZ());
|
||||
}
|
||||
|
||||
public boolean canTransport(Entity entity) {
|
||||
if (!entity.isAlive())
|
||||
return false;
|
||||
if (entity instanceof PlayerEntity && ((PlayerEntity) entity).isSneaking())
|
||||
return false;
|
||||
public Direction getMovementFacing() {
|
||||
return Direction.getFacingFromAxisDirection(getBeltFacing().getAxis(),
|
||||
getBeltMovementSpeed() < 0 ? POSITIVE : NEGATIVE);
|
||||
}
|
||||
|
||||
protected Direction getBeltFacing() {
|
||||
return getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
}
|
||||
|
||||
public BeltInventory getInventory() {
|
||||
if (inventory == null)
|
||||
inventory = new BeltInventory(this);
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public boolean tryInsertingFromSide(Direction side, ItemStack stack, boolean simulate) {
|
||||
return tryInsertingFromSide(side, new TransportedItemStack(stack), simulate);
|
||||
}
|
||||
|
||||
public boolean tryInsertingFromSide(Direction side, TransportedItemStack transportedStack, boolean simulate) {
|
||||
BeltTileEntity nextBeltController = getControllerTE();
|
||||
if (nextBeltController == null)
|
||||
return false;
|
||||
BeltInventory nextInventory = nextBeltController.getInventory();
|
||||
|
||||
if (!nextInventory.canInsertFrom(index, side))
|
||||
return false;
|
||||
if (simulate)
|
||||
return true;
|
||||
|
||||
transportedStack.beltPosition = index + .5f;
|
||||
|
||||
Direction movementFacing = getMovementFacing();
|
||||
if (!side.getAxis().isVertical()) {
|
||||
if (movementFacing != side)
|
||||
transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f;
|
||||
else
|
||||
transportedStack.beltPosition = getDirectionAwareBeltMovementSpeed() > 0 ? index : index + 1;
|
||||
if (side.getAxis() == Axis.X ^ movementFacing.getAxis() == Axis.X)
|
||||
transportedStack.sideOffset *= -1;
|
||||
}
|
||||
|
||||
transportedStack.prevSideOffset = transportedStack.sideOffset;
|
||||
transportedStack.insertedAt = index;
|
||||
transportedStack.insertedFrom = side;
|
||||
transportedStack.prevBeltPosition = transportedStack.beltPosition;
|
||||
nextInventory.insert(transportedStack);
|
||||
nextBeltController.markDirty();
|
||||
nextBeltController.sendData();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,114 +1,159 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Random;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.foundation.utility.IndependentShadowRenderer;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
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 com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
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.minecraft.util.math.Vec3i;
|
||||
|
||||
public class BeltTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
||||
|
||||
protected static class BeltModelAnimator extends BufferManipulator {
|
||||
protected static TextureAtlasSprite beltTextures;
|
||||
protected static TextureAtlasSprite originalTexture;
|
||||
@Override
|
||||
public void render(BeltTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
super.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
||||
public BeltModelAnimator(ByteBuffer template) {
|
||||
super(template);
|
||||
if (beltTextures == null)
|
||||
initSprites();
|
||||
}
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
|
||||
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"));
|
||||
}
|
||||
if (te.isController()) {
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
public ByteBuffer getTransformed(BeltTileEntity te, float x, float y, float z, int color) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
Vec3i directionVec = te.getBeltFacing().getDirectionVec();
|
||||
Vec3d beltStartOffset = new Vec3d(directionVec).scale(-.5).add(.5, 13 / 16f + .125f, .5);
|
||||
GlStateManager.translated(x + beltStartOffset.x, y + beltStartOffset.y, z + beltStartOffset.z);
|
||||
Slope slope = te.getBlockState().get(BeltBlock.SLOPE);
|
||||
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
||||
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
|
||||
|
||||
float textureOffsetX = 0;
|
||||
float textureOffsetY = 0;
|
||||
for (TransportedItemStack transported : te.getInventory().items) {
|
||||
GlStateManager.pushMatrix();
|
||||
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
|
||||
float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset);
|
||||
float verticalMovement = verticality;
|
||||
|
||||
if (te.getSpeed() == 0) {
|
||||
offset = transported.beltPosition;
|
||||
sideOffset = transported.sideOffset;
|
||||
}
|
||||
|
||||
if (te.getSpeed() != 0) {
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
Direction direction = te.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
if (direction == Direction.EAST || direction == Direction.NORTH)
|
||||
time = -time;
|
||||
int textureIndex = (int) ((te.getSpeed() * time / 8) % 16);
|
||||
if (textureIndex < 0)
|
||||
textureIndex += 16;
|
||||
if (offset < .5)
|
||||
verticalMovement = 0;
|
||||
verticalMovement = verticalMovement * (Math.min(offset, te.beltLength - .5f) - .5f);
|
||||
Vec3d offsetVec = new Vec3d(directionVec).scale(offset).add(0, verticalMovement, 0);
|
||||
boolean onSlope = slope != Slope.HORIZONTAL
|
||||
&& MathHelper.clamp(offset, .5f, te.beltLength - .5f) == offset;
|
||||
float slopeAngle = onSlope
|
||||
? slope == Slope.DOWNWARD ^ te.getDirectionAwareBeltMovementSpeed() > 0
|
||||
^ te.getBeltMovementSpeed() < 0 ? -45 : 45
|
||||
: 0;
|
||||
|
||||
textureOffsetX = beltTextures.getInterpolatedU((textureIndex % 4) * 4) - originalTexture.getMinU();
|
||||
textureOffsetY = beltTextures.getInterpolatedV((textureIndex / 4) * 4) - originalTexture.getMinV();
|
||||
GlStateManager.translated(offsetVec.x, offsetVec.y, offsetVec.z);
|
||||
|
||||
boolean alongX = te.getBeltFacing().rotateY().getAxis() == Axis.X;
|
||||
if (!alongX)
|
||||
sideOffset *= -1;
|
||||
GlStateManager.translated(alongX ? sideOffset : 0, 0, alongX ? 0 : sideOffset);
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
boolean blockItem = itemRenderer.getModelWithOverrides(transported.stack).isGui3d();
|
||||
if (Minecraft.getInstance().gameSettings.fancyGraphics) {
|
||||
Vec3d shadowPos = new Vec3d(te.getPos()).add(beltStartOffset.scale(1).add(offsetVec)
|
||||
.add(alongX ? sideOffset : 0, .39, alongX ? 0 : sideOffset));
|
||||
IndependentShadowRenderer.renderShadow(shadowPos.x, shadowPos.y, shadowPos.z, .75f,
|
||||
blockItem ? .2f : .2f);
|
||||
}
|
||||
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
int count = (int) (MathHelper.log2((int) (transported.stack.getCount()))) / 2;
|
||||
GlStateManager.rotated(slopeAngle, slopeAlongX ? 0 : 1, 0, slopeAlongX ? 1 : 0);
|
||||
if (onSlope)
|
||||
GlStateManager.translated(0, 1 / 8f, 0);
|
||||
Random r = new Random(transported.angle);
|
||||
|
||||
for (int i = 0; i <= count; i++) {
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.rotated(transported.angle, 0, 1, 0);
|
||||
if (!blockItem) {
|
||||
GlStateManager.translated(0, -.09375, 0);
|
||||
GlStateManager.rotated(90, 1, 0, 0);
|
||||
}
|
||||
|
||||
if (blockItem) {
|
||||
GlStateManager.translated(r.nextFloat() * .25f, 0, r.nextFloat() * .25f);
|
||||
}
|
||||
|
||||
GlStateManager.scaled(.5, .5, .5);
|
||||
itemRenderer.renderItem(transported.stack, TransformType.FIXED);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if (!blockItem)
|
||||
GlStateManager.rotated(10, 0, 1, 0);
|
||||
GlStateManager.translated(0, blockItem ? 1 / 64d : 1 / 16d, 0);
|
||||
|
||||
}
|
||||
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
final BlockState blockState = te.getBlockState();
|
||||
int packedLightCoords = blockState.getPackedLightmapCoords(te.getWorld(), te.getPos());
|
||||
float texOffX = textureOffsetX;
|
||||
float texOffY = textureOffsetY;
|
||||
|
||||
boolean defaultColor = color == -1;
|
||||
int b = defaultColor ? 128 : color & 0xFF;
|
||||
int g = defaultColor ? 128 : (color >> 8) & 0xFF;
|
||||
int r = defaultColor ? 128 : (color >> 16) & 0xFF;
|
||||
|
||||
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);
|
||||
|
||||
byte lumByte = getR(original, vertex);
|
||||
float lum = (lumByte < 0 ? 255 + lumByte : lumByte) / 256f;
|
||||
|
||||
int r2 = (int) (r * lum);
|
||||
int g2 = (int) (g * lum);
|
||||
int b2 = (int) (b * lum);
|
||||
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
public void renderTileEntityFast(BeltTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
BeltTileEntity beltEntity = (BeltTileEntity) te;
|
||||
|
||||
if (beltEntity.hasPulley())
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
if (te.hasPulley()) {
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float angle = KineticTileEntityRenderer.getAngleForTe(te, pos, axis);
|
||||
KineticTileEntityRenderer.renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos,
|
||||
axis, angle);
|
||||
}
|
||||
|
||||
cacheIfMissing(beltEntity.getBlockState(), getWorld(), BeltModelAnimator::new);
|
||||
renderBeltFromCache(beltEntity, (float) x, (float) y, (float) z, buffer);
|
||||
KineticTileEntityRenderer.cacheIfMissing(te.getBlockState().with(BeltBlock.CASING, false), getWorld(),
|
||||
BeltModelAnimator::new);
|
||||
renderBeltFromCache(te, (float) x, (float) y, (float) z, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
return AllBlocks.BELT_PULLEY.get().getDefaultState().with(BlockStateProperties.AXIS,
|
||||
((IRotate) AllBlocks.BELT.get()).getRotationAxis(te.getBlockState()));
|
||||
}
|
||||
|
||||
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, te.color));
|
||||
buffer.putBulkData(((BeltModelAnimator) KineticTileEntityRenderer.cachedBuffers
|
||||
.get(te.getBlockState().with(BeltBlock.CASING, false))).getTransformed(te, x, y, z, te.color));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class ItemHandlerBeltSegment implements IItemHandler {
|
||||
|
||||
private final BeltInventory beltInventory;
|
||||
int offset;
|
||||
|
||||
public ItemHandlerBeltSegment(BeltInventory beltInventory, int offset) {
|
||||
this.beltInventory = beltInventory;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
TransportedItemStack stackAtOffset = this.beltInventory.getStackAtOffset(offset);
|
||||
if (stackAtOffset == null)
|
||||
return ItemStack.EMPTY;
|
||||
return stackAtOffset.stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
if (this.beltInventory.canInsertAt(offset)) {
|
||||
if (!simulate) {
|
||||
TransportedItemStack newStack = new TransportedItemStack(stack);
|
||||
newStack.insertedAt = offset;
|
||||
newStack.beltPosition = offset + .5f;
|
||||
newStack.prevBeltPosition = newStack.beltPosition;
|
||||
this.beltInventory.insert(newStack);
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
TransportedItemStack transported = this.beltInventory.getStackAtOffset(offset);
|
||||
if (transported == null)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
amount = Math.min(amount, transported.stack.getCount());
|
||||
ItemStack extracted = simulate ? transported.stack.copy().split(amount) : transported.stack.split(amount);
|
||||
if (!simulate) {
|
||||
this.beltInventory.belt.markDirty();
|
||||
this.beltInventory.belt.sendData();
|
||||
}
|
||||
return extracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return Math.min(getStackInSlot(slot).getMaxStackSize(), 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.modules.logistics.InWorldProcessing;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
||||
public ItemStack stack;
|
||||
public float beltPosition;
|
||||
public float sideOffset;
|
||||
public int angle;
|
||||
public int insertedAt;
|
||||
public Direction insertedFrom;
|
||||
public boolean locked;
|
||||
|
||||
public float prevBeltPosition;
|
||||
public float prevSideOffset;
|
||||
|
||||
public InWorldProcessing.Type processedBy;
|
||||
public int processingTime;
|
||||
|
||||
public TransportedItemStack(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
angle = new Random().nextInt(360);
|
||||
sideOffset = prevSideOffset = getTargetSideOffset();
|
||||
insertedFrom = Direction.UP;
|
||||
}
|
||||
|
||||
public float getTargetSideOffset() {
|
||||
return (angle - 180) / (360 * 3f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(TransportedItemStack o) {
|
||||
return beltPosition < o.beltPosition ? 1 : beltPosition > o.beltPosition ? -1 : 0;
|
||||
}
|
||||
|
||||
public TransportedItemStack getSimilar() {
|
||||
TransportedItemStack copy = new TransportedItemStack(stack.copy());
|
||||
copy.beltPosition = beltPosition;
|
||||
copy.insertedAt = insertedAt;
|
||||
copy.insertedFrom = insertedFrom;
|
||||
copy.prevBeltPosition = prevBeltPosition;
|
||||
copy.prevSideOffset = prevSideOffset;
|
||||
copy.processedBy = processedBy;
|
||||
copy.processingTime = processingTime;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public TransportedItemStack copy() {
|
||||
TransportedItemStack copy = getSimilar();
|
||||
copy.angle = angle;
|
||||
return copy;
|
||||
}
|
||||
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.put("Item", stack.serializeNBT());
|
||||
nbt.putFloat("Pos", beltPosition);
|
||||
nbt.putFloat("PrevPos", prevBeltPosition);
|
||||
nbt.putFloat("Offset", sideOffset);
|
||||
nbt.putFloat("PrevOffset", prevSideOffset);
|
||||
nbt.putInt("InSegment", insertedAt);
|
||||
nbt.putInt("Angle", angle);
|
||||
nbt.putInt("InDirection", insertedFrom.getIndex());
|
||||
nbt.putBoolean("Locked", locked);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public static TransportedItemStack read(CompoundNBT nbt) {
|
||||
TransportedItemStack stack = new TransportedItemStack(ItemStack.read(nbt.getCompound("Item")));
|
||||
stack.beltPosition = nbt.getFloat("Pos");
|
||||
stack.prevBeltPosition = nbt.getFloat("PrevPos");
|
||||
stack.sideOffset = nbt.getFloat("Offset");
|
||||
stack.prevSideOffset = nbt.getFloat("PrevOffset");
|
||||
stack.insertedAt = nbt.getInt("InSegment");
|
||||
stack.angle = nbt.getInt("Angle");
|
||||
stack.insertedFrom = Direction.byIndex(nbt.getInt("InDirection"));
|
||||
stack.locked = nbt.getBoolean("Locked");
|
||||
return stack;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,7 +20,7 @@ public class WindowInABlockTileEntity extends SyncedTileEntity {
|
|||
|
||||
private BlockState partialBlock = Blocks.AIR.getDefaultState();
|
||||
private BlockState windowBlock = Blocks.AIR.getDefaultState();
|
||||
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
private IModelData modelData;
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class WindowInABlockTileEntity extends SyncedTileEntity {
|
|||
windowBlock = getWindowBlock().updatePostPlacement(side, world.getBlockState(offsetPos), world, pos,
|
||||
offsetPos);
|
||||
}
|
||||
sendData();
|
||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2 | 16);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
package com.simibubi.create.modules.logistics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllRecipes;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.foundation.utility.ItemHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.ProcessingRecipe;
|
||||
import com.simibubi.create.modules.contraptions.receivers.SplashingRecipe;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -40,12 +44,27 @@ public class InWorldProcessing {
|
|||
}
|
||||
|
||||
public static boolean canProcess(ItemEntity entity, Type type) {
|
||||
World world = entity.world;
|
||||
if (entity.getPersistentData().contains("CreateData")) {
|
||||
CompoundNBT compound = entity.getPersistentData().getCompound("CreateData");
|
||||
if (compound.contains("Processing")) {
|
||||
CompoundNBT processing = compound.getCompound("Processing");
|
||||
|
||||
if (entity.getPersistentData().contains("CreateData")
|
||||
&& entity.getPersistentData().getCompound("CreateData").contains("Processing"))
|
||||
return true;
|
||||
if (Type.valueOf(processing.getString("Type")) != type) {
|
||||
boolean canProcess = canProcess(entity.getItem(), type, entity.world);
|
||||
processing.putString("Type", type.name());
|
||||
if (!canProcess)
|
||||
processing.putInt("Time", -1);
|
||||
return canProcess;
|
||||
} else if (processing.getInt("Time") >= 0)
|
||||
return true;
|
||||
else if (processing.getInt("Time") == -1)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return canProcess(entity.getItem(), type, entity.world);
|
||||
}
|
||||
|
||||
private static boolean canProcess(ItemStack stack, Type type, World world) {
|
||||
if (type == Type.BLASTING) {
|
||||
return true;
|
||||
}
|
||||
|
@ -53,13 +72,13 @@ public class InWorldProcessing {
|
|||
if (type == Type.SMOKING) {
|
||||
SmokerTileEntity smoker = new SmokerTileEntity();
|
||||
smoker.setWorld(world);
|
||||
smoker.setInventorySlotContents(0, entity.getItem());
|
||||
smoker.setInventorySlotContents(0, stack);
|
||||
Optional<SmokingRecipe> recipe = world.getRecipeManager().getRecipe(IRecipeType.SMOKING, smoker, world);
|
||||
return recipe.isPresent();
|
||||
}
|
||||
|
||||
if (type == Type.SPLASHING) {
|
||||
splashingInv.setInventorySlotContents(0, entity.getItem());
|
||||
splashingInv.setInventorySlotContents(0, stack);
|
||||
Optional<SplashingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.SPLASHING,
|
||||
splashingInv, world);
|
||||
return recipe.isPresent();
|
||||
|
@ -68,59 +87,90 @@ public class InWorldProcessing {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static void process(ItemEntity entity, Type type) {
|
||||
World world = entity.world;
|
||||
public static void applyProcessing(ItemEntity entity, Type type) {
|
||||
if (decrementProcessingTime(entity, type) != 0)
|
||||
return;
|
||||
List<ItemStack> stacks = process(entity.getItem(), type, entity.world);
|
||||
if (stacks == null)
|
||||
return;
|
||||
if (stacks.isEmpty()) {
|
||||
entity.remove();
|
||||
return;
|
||||
}
|
||||
entity.setItem(stacks.remove(0));
|
||||
for (ItemStack additional : stacks) {
|
||||
ItemEntity entityIn = new ItemEntity(entity.world, entity.posX, entity.posY, entity.posZ, additional);
|
||||
entityIn.setMotion(entity.getMotion());
|
||||
entity.world.addEntity(entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<TransportedItemStack> applyProcessing(TransportedItemStack transported, BeltTileEntity belt, Type type) {
|
||||
if (transported.processedBy != type) {
|
||||
transported.processedBy = type;
|
||||
transported.processingTime = CreateConfig.parameters.inWorldProcessingTime.get() + 1;
|
||||
if (!canProcess(transported.stack, type, belt.getWorld()))
|
||||
transported.processingTime = -1;
|
||||
return null;
|
||||
}
|
||||
if (transported.processingTime == -1)
|
||||
return null;
|
||||
if (transported.processingTime-- > 0)
|
||||
return null;
|
||||
|
||||
List<ItemStack> stacks = process(transported.stack, type, belt.getWorld());
|
||||
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
||||
for (ItemStack additional : stacks) {
|
||||
TransportedItemStack newTransported = transported.getSimilar();
|
||||
newTransported.stack = additional.copy();
|
||||
transportedStacks.add(newTransported);
|
||||
}
|
||||
return transportedStacks;
|
||||
}
|
||||
|
||||
private static List<ItemStack> process(ItemStack stack, Type type, World world) {
|
||||
if (type == Type.SPLASHING) {
|
||||
splashingInv.setInventorySlotContents(0, entity.getItem());
|
||||
splashingInv.setInventorySlotContents(0, stack);
|
||||
Optional<SplashingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.SPLASHING,
|
||||
splashingInv, world);
|
||||
if (recipe.isPresent())
|
||||
applyRecipeOn(entity, recipe.get());
|
||||
return;
|
||||
return applyRecipeOn(stack, recipe.get());
|
||||
return null;
|
||||
}
|
||||
|
||||
SmokerTileEntity smoker = new SmokerTileEntity();
|
||||
smoker.setWorld(world);
|
||||
smoker.setInventorySlotContents(0, entity.getItem());
|
||||
smoker.setInventorySlotContents(0, stack);
|
||||
Optional<SmokingRecipe> smokingRecipe = world.getRecipeManager().getRecipe(IRecipeType.SMOKING, smoker, world);
|
||||
|
||||
if (type == Type.BLASTING) {
|
||||
FurnaceTileEntity furnace = new FurnaceTileEntity();
|
||||
furnace.setWorld(world);
|
||||
furnace.setInventorySlotContents(0, entity.getItem());
|
||||
furnace.setInventorySlotContents(0, stack);
|
||||
Optional<FurnaceRecipe> smeltingRecipe = world.getRecipeManager().getRecipe(IRecipeType.SMELTING, furnace,
|
||||
world);
|
||||
|
||||
if (!smokingRecipe.isPresent()) {
|
||||
if (smeltingRecipe.isPresent()) {
|
||||
applyRecipeOn(entity, smeltingRecipe.get());
|
||||
return;
|
||||
}
|
||||
if (smeltingRecipe.isPresent())
|
||||
return applyRecipeOn(stack, smeltingRecipe.get());
|
||||
|
||||
BlastFurnaceTileEntity blastFurnace = new BlastFurnaceTileEntity();
|
||||
blastFurnace.setWorld(world);
|
||||
blastFurnace.setInventorySlotContents(0, entity.getItem());
|
||||
blastFurnace.setInventorySlotContents(0, stack);
|
||||
Optional<BlastingRecipe> blastingRecipe = world.getRecipeManager().getRecipe(IRecipeType.BLASTING,
|
||||
blastFurnace, world);
|
||||
|
||||
if (blastingRecipe.isPresent()) {
|
||||
applyRecipeOn(entity, blastingRecipe.get());
|
||||
return;
|
||||
}
|
||||
if (blastingRecipe.isPresent())
|
||||
return applyRecipeOn(stack, blastingRecipe.get());
|
||||
}
|
||||
|
||||
entity.remove();
|
||||
return;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (type == Type.SMOKING && smokingRecipe.isPresent()) {
|
||||
applyRecipeOn(entity, smokingRecipe.get());
|
||||
return;
|
||||
}
|
||||
if (type == Type.SMOKING && smokingRecipe.isPresent())
|
||||
return applyRecipeOn(stack, smokingRecipe.get());
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int decrementProcessingTime(ItemEntity entity, Type type) {
|
||||
|
@ -143,14 +193,31 @@ public class InWorldProcessing {
|
|||
processing.putInt("Time", value);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public static void applyRecipeOn(ItemEntity entity, IRecipe<?> recipe) {
|
||||
List<ItemStack> stacks = applyRecipeOn(entity.getItem(), recipe);
|
||||
if (stacks == null)
|
||||
return;
|
||||
if (stacks.isEmpty()) {
|
||||
entity.remove();
|
||||
return;
|
||||
}
|
||||
entity.setItem(stacks.remove(0));
|
||||
for (ItemStack additional : stacks) {
|
||||
ItemEntity entityIn = new ItemEntity(entity.world, entity.posX, entity.posY, entity.posZ, additional);
|
||||
entityIn.setMotion(entity.getMotion());
|
||||
entity.world.addEntity(entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ItemStack> applyRecipeOn(ItemStack stackIn, IRecipe<?> recipe) {
|
||||
List<ItemStack> stacks;
|
||||
|
||||
if (recipe instanceof SplashingRecipe) {
|
||||
if (recipe instanceof ProcessingRecipe) {
|
||||
stacks = new ArrayList<>();
|
||||
for (int i = 0; i < entity.getItem().getCount(); i++) {
|
||||
for (ItemStack stack : ((SplashingRecipe) recipe).rollResults()) {
|
||||
for (int i = 0; i < stackIn.getCount(); i++) {
|
||||
List<ItemStack> rollResults = ((ProcessingRecipe<?>) recipe).rollResults();
|
||||
for (ItemStack stack : rollResults) {
|
||||
for (ItemStack previouslyRolled : stacks) {
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
@ -170,19 +237,10 @@ public class InWorldProcessing {
|
|||
}
|
||||
} else {
|
||||
ItemStack out = recipe.getRecipeOutput().copy();
|
||||
stacks = ItemHelper.multipliedOutput(entity.getItem(), out);
|
||||
stacks = ItemHelper.multipliedOutput(stackIn, out);
|
||||
}
|
||||
|
||||
if (stacks.isEmpty()) {
|
||||
entity.remove();
|
||||
return;
|
||||
}
|
||||
entity.setItem(stacks.remove(0));
|
||||
for (ItemStack additional : stacks) {
|
||||
ItemEntity entityIn = new ItemEntity(entity.world, entity.posX, entity.posY, entity.posZ, additional);
|
||||
entityIn.setMotion(entity.getMotion());
|
||||
entity.world.addEntity(entityIn);
|
||||
}
|
||||
return stacks;
|
||||
}
|
||||
|
||||
public static boolean isFrozen() {
|
||||
|
|
|
@ -2,8 +2,10 @@ package com.simibubi.create.modules.logistics.block;
|
|||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
|
@ -11,10 +13,12 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
@ -119,13 +123,29 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
|
|||
}
|
||||
|
||||
default boolean hasSpaceForExtracting() {
|
||||
return getWorld().getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty();
|
||||
BlockPos pos = getPos();
|
||||
World world = getWorld();
|
||||
|
||||
if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) {
|
||||
TileEntity te = world.getTileEntity(pos.down());
|
||||
if (te != null && te instanceof BeltTileEntity) {
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
BeltTileEntity controller = belt.getControllerTE();
|
||||
if (controller != null) {
|
||||
if (!controller.getInventory().canInsertFrom(belt.index, Direction.UP))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return world.getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty();
|
||||
}
|
||||
|
||||
default ItemStack extract(boolean simulate) {
|
||||
IItemHandler inv = getInventory().orElse(null);
|
||||
ItemStack extracting = ItemStack.EMPTY;
|
||||
ItemStack filterItem = (this instanceof IHaveFilter) ? ((IHaveFilter) this).getFilter() : ItemStack.EMPTY;
|
||||
World world = getWorld();
|
||||
int extractionCount = filterItem.isEmpty() ? CreateConfig.parameters.extractorAmount.get()
|
||||
: filterItem.getCount();
|
||||
boolean checkHasEnoughItems = !filterItem.isEmpty();
|
||||
|
@ -172,17 +192,16 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
|
|||
} while (true);
|
||||
|
||||
if (!simulate && hasEnoughItems) {
|
||||
World world = getWorld();
|
||||
Vec3d pos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
||||
Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
||||
Entity entityIn = null;
|
||||
|
||||
if (extracting.getItem() instanceof CardboardBoxItem) {
|
||||
Direction face = getWorld().getBlockState(getPos()).get(HORIZONTAL_FACING).getOpposite();
|
||||
entityIn = new CardboardBoxEntity(world, pos, extracting, face);
|
||||
entityIn = new CardboardBoxEntity(world, entityPos, extracting, face);
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .25f, .05f);
|
||||
|
||||
} else {
|
||||
entityIn = new ItemEntity(world, pos.x, pos.y, pos.z, extracting);
|
||||
entityIn = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, extracting);
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
|
@ -10,22 +10,25 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
|
@ -35,7 +38,8 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, IWithTileEntity<BeltFunnelTileEntity> {
|
||||
public class BeltFunnelBlock extends HorizontalBlock
|
||||
implements IBeltAttachment, IWithTileEntity<BeltFunnelTileEntity>, IBlockWithFilter {
|
||||
|
||||
public static final VoxelShape SHAPE_NORTH = makeCuboidShape(3, -4, -1, 13, 8, 5),
|
||||
SHAPE_SOUTH = makeCuboidShape(3, -4, 11, 13, 8, 17), SHAPE_WEST = makeCuboidShape(-1, -4, 3, 5, 8, 13),
|
||||
|
@ -43,13 +47,14 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
|
||||
public BeltFunnelBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
cacheItemPositions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
|
@ -77,9 +82,14 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||
BlockPos neighbourPos = pos.offset(state.get(HORIZONTAL_FACING));
|
||||
BlockState neighbour = worldIn.getBlockState(neighbourPos);
|
||||
|
||||
if (AllBlocks.BELT.typeOf(neighbour)) {
|
||||
return BeltBlock.canAccessFromSide(state.get(HORIZONTAL_FACING), neighbour);
|
||||
}
|
||||
|
||||
return !neighbour.getShape(worldIn, pos).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockState state = getDefaultState();
|
||||
|
@ -138,34 +148,89 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te) {
|
||||
return Arrays.asList(te.getPos().up());
|
||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
||||
return Arrays.asList(pos.up());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state) {
|
||||
BlockPos validPos = pos.down();
|
||||
BlockState blockState = world.getBlockState(validPos);
|
||||
if (!AllBlocks.BELT.typeOf(blockState)
|
||||
|| blockState.get(HORIZONTAL_FACING).getAxis() != state.get(HORIZONTAL_FACING).getAxis())
|
||||
return Optional.empty();
|
||||
return Optional.of(validPos);
|
||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
||||
return pos.down();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
boolean isItem = entity instanceof ItemEntity;
|
||||
if (!isItem && !(entity instanceof CardboardBoxEntity))
|
||||
return false;
|
||||
boolean slope = te.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL;
|
||||
if (isItem && entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > (slope ? .6f : .4f))
|
||||
return false;
|
||||
entity.setMotion(Vec3d.ZERO);
|
||||
withTileEntityDo(te.getWorld(), state.attachmentPos, funnelTE -> {
|
||||
funnelTE.tryToInsert(entity);
|
||||
});
|
||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
return process(te, transported, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
Direction movementFacing = te.getMovementFacing();
|
||||
if (movementFacing.getAxis() == Axis.Z)
|
||||
movementFacing = movementFacing.getOpposite();
|
||||
if (movementFacing != te.getWorld().getBlockState(state.attachmentPos)
|
||||
.get(HORIZONTAL_FACING))
|
||||
return false;
|
||||
return process(te, transported, state);
|
||||
}
|
||||
|
||||
public boolean process(BeltTileEntity belt, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
TileEntity te = belt.getWorld().getTileEntity(state.attachmentPos);
|
||||
if (te == null || !(te instanceof BeltFunnelTileEntity))
|
||||
return false;
|
||||
BeltFunnelTileEntity funnel = (BeltFunnelTileEntity) te;
|
||||
ItemStack stack = funnel.tryToInsert(transported.stack);
|
||||
transported.stack = stack;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit);
|
||||
}
|
||||
|
||||
private static final List<Vec3d> itemPositions = new ArrayList<>(Direction.values().length);
|
||||
|
||||
private void cacheItemPositions() {
|
||||
itemPositions.clear();
|
||||
|
||||
Vec3d position = Vec3d.ZERO;
|
||||
Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||
float zFightOffset = 1 / 128f;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Direction facing = Direction.byHorizontalIndex(i);
|
||||
position = new Vec3d(8f / 16f + zFightOffset, 9f / 16f, 2.25f / 16f);
|
||||
|
||||
float angle = facing.getHorizontalAngle();
|
||||
if (facing.getAxis() == Axis.X)
|
||||
angle = -angle;
|
||||
|
||||
position = VecHelper.rotate(position.subtract(shift), angle, Axis.Y).add(shift);
|
||||
|
||||
itemPositions.add(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showsCount() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getItemHitboxScale() {
|
||||
return 1.76f / 16f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d getFilterPosition(BlockState state) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING).getOpposite();
|
||||
return itemPositions.get(facing.getHorizontalIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getFilterFacing(BlockState state) {
|
||||
return state.get(HORIZONTAL_FACING).getOpposite();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.simibubi.create.modules.logistics.block.belts;
|
|||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.ItemHandlerBeltSegment;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
|
@ -16,44 +16,63 @@ import net.minecraft.tileentity.ITickableTileEntity;
|
|||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity, IInventoryManipulator {
|
||||
public class BeltFunnelTileEntity extends SyncedTileEntity
|
||||
implements ITickableTileEntity, IInventoryManipulator, IHaveFilter {
|
||||
|
||||
private LazyOptional<IItemHandler> inventory;
|
||||
protected boolean waitingForInventorySpace;
|
||||
private boolean initialize;
|
||||
private ItemStack filter;
|
||||
|
||||
private ItemStack justEaten;
|
||||
|
||||
public BeltFunnelTileEntity() {
|
||||
super(AllTileEntities.BELT_FUNNEL.type);
|
||||
inventory = LazyOptional.empty();
|
||||
filter = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
filter = ItemStack.read(compound.getCompound("Filter"));
|
||||
waitingForInventorySpace = compound.getBoolean("Waiting");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.put("Filter", filter.serializeNBT());
|
||||
compound.putBoolean("Waiting", waitingForInventorySpace);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
initialize = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT writeToClient(CompoundNBT tag) {
|
||||
if (justEaten != null) {
|
||||
tag.put("Nom", justEaten.serializeNBT());
|
||||
justEaten = null;
|
||||
}
|
||||
return super.writeToClient(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readClientUpdate(CompoundNBT tag) {
|
||||
super.readClientUpdate(tag);
|
||||
if (!waitingForInventorySpace)
|
||||
neighborChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putBoolean("Waiting", waitingForInventorySpace);
|
||||
return super.write(compound);
|
||||
if (tag.contains("Nom"))
|
||||
justEaten = ItemStack.read(tag.getCompound("Nom"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,6 +91,10 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
neighborChanged();
|
||||
initialize = false;
|
||||
}
|
||||
if (world.isRemote && justEaten != null) {
|
||||
spawnParticles(justEaten);
|
||||
justEaten = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,42 +110,57 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
sendData();
|
||||
}
|
||||
|
||||
public void tryToInsert(Entity entity) {
|
||||
public ItemStack tryToInsert(ItemStack stack) {
|
||||
if (!inventory.isPresent())
|
||||
return;
|
||||
if (waitingForInventorySpace)
|
||||
return;
|
||||
|
||||
ItemStack stack = null;
|
||||
if (entity instanceof ItemEntity)
|
||||
stack = ((ItemEntity) entity).getItem().copy();
|
||||
if (entity instanceof CardboardBoxEntity)
|
||||
stack = ((CardboardBoxEntity) entity).getBox().copy();
|
||||
return stack;
|
||||
if (waitingForInventorySpace && !(inventory.orElse(null) instanceof ItemHandlerBeltSegment))
|
||||
return stack;
|
||||
if (!filter.isEmpty() && !ItemStack.areItemsEqual(filter, stack))
|
||||
return stack;
|
||||
|
||||
IItemHandler inv = inventory.orElse(null);
|
||||
stack = ItemHandlerHelper.insertItemStacked(inv, stack, false);
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
if (!world.isRemote) {
|
||||
entity.remove();
|
||||
ItemStack inserted = stack.copy();
|
||||
int amountToExtract = Math.min(filter.isEmpty() ? 64 : filter.getCount(), stack.getCount());
|
||||
inserted.setCount(amountToExtract);
|
||||
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, inserted, false);
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
if (!world.isRemote)
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||
} else {
|
||||
Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec();
|
||||
float xSpeed = directionVec.getX() * 1 / 8f;
|
||||
float zSpeed = directionVec.getZ() * 1 / 8f;
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), entity.posX,
|
||||
entity.posY, entity.posZ, xSpeed, 1 / 6f, zSpeed);
|
||||
}
|
||||
return;
|
||||
justEaten = stack.copy();
|
||||
remainder = stack.copy();
|
||||
remainder.setCount(stack.getCount() - amountToExtract);
|
||||
|
||||
} else {
|
||||
waitingForInventorySpace = true;
|
||||
remainder.grow(stack.getCount() - amountToExtract);
|
||||
}
|
||||
|
||||
waitingForInventorySpace = true;
|
||||
sendData();
|
||||
return remainder;
|
||||
}
|
||||
|
||||
if (entity instanceof ItemEntity)
|
||||
if (!stack.equals(((ItemEntity) entity).getItem(), false))
|
||||
((ItemEntity) entity).setItem(stack);
|
||||
public void spawnParticles(ItemStack stack) {
|
||||
Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec();
|
||||
float xSpeed = directionVec.getX() * 1 / 8f;
|
||||
float zSpeed = directionVec.getZ() * 1 / 8f;
|
||||
Vec3d vec = VecHelper.getCenterOf(pos);
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), vec.x, vec.y - 9 / 16f, vec.z, xSpeed,
|
||||
1 / 6f, zSpeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(ItemStack stack) {
|
||||
filter = stack.copy();
|
||||
markDirty();
|
||||
sendData();
|
||||
neighborChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getFilter() {
|
||||
return filter.copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
|
||||
public class BeltFunnelTileEntityRenderer extends TileEntityRenderer<BeltFunnelTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public BeltFunnelTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BeltFunnelTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@ package com.simibubi.create.modules.logistics.block.belts;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
@ -15,6 +14,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
|||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -129,16 +129,20 @@ public class EntityDetectorBlock extends HorizontalBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te) {
|
||||
Direction side = te.getBlockState().get(BeltBlock.HORIZONTAL_FACING).rotateY();
|
||||
return Arrays.asList(te.getPos().offset(side), te.getPos().offset(side.getOpposite()));
|
||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
||||
Direction side = beltState.get(BeltBlock.HORIZONTAL_FACING).rotateY();
|
||||
return Arrays.asList(pos.offset(side), pos.offset(side.getOpposite()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state) {
|
||||
if (!state.get(BELT))
|
||||
return Optional.empty();
|
||||
return Optional.of(pos.offset(state.get(HORIZONTAL_FACING)));
|
||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
||||
return pos.offset(state.get(HORIZONTAL_FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos, BlockState attachmentState,
|
||||
BlockState beltState) {
|
||||
return attachmentState.get(BELT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -178,11 +182,39 @@ public class EntityDetectorBlock extends HorizontalBlock
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
|
||||
state.processingDuration = 0;
|
||||
withTileEntityDo(te.getWorld(), state.attachmentPos, detectorTE -> {
|
||||
ItemStack filter = detectorTE.getFilter();
|
||||
if (filter.isEmpty())
|
||||
return;
|
||||
|
||||
// Todo: Package filters
|
||||
if (!ItemStack.areItemsEqual(transported.stack, filter)) {
|
||||
state.processingDuration = -1;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
World world = te.getWorld();
|
||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
||||
if (state.processingDuration == 0) {
|
||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
||||
world.getPendingBlockTicks().scheduleTick(state.attachmentPos, this, 6);
|
||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
|
||||
if (te.getWorld().isRemote)
|
||||
return false;
|
||||
|
||||
|
||||
if (state.processingEntity != entity) {
|
||||
state.processingEntity = entity;
|
||||
state.processingDuration = 0;
|
||||
|
@ -190,6 +222,8 @@ public class EntityDetectorBlock extends HorizontalBlock
|
|||
ItemStack filter = detectorTE.getFilter();
|
||||
if (filter.isEmpty())
|
||||
return;
|
||||
|
||||
// Todo: Package filters
|
||||
if (!(entity instanceof ItemEntity)
|
||||
|| !ItemStack.areItemsEqual(((ItemEntity) entity).getItem(), filter)) {
|
||||
state.processingDuration = -1;
|
||||
|
|
|
@ -3,7 +3,9 @@ package com.simibubi.create.modules.logistics.block.belts;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IExtractor;
|
||||
|
||||
|
@ -91,11 +93,17 @@ public class ExtractorBlock extends HorizontalBlock implements IBlockWithFilter
|
|||
|
||||
@Override
|
||||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||
BlockPos neighbourPos = pos.offset(state.get(HORIZONTAL_FACING));
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
BlockPos neighbourPos = pos.offset(facing);
|
||||
BlockState neighbour = worldIn.getBlockState(neighbourPos);
|
||||
|
||||
if (AllBlocks.BELT.typeOf(neighbour)) {
|
||||
return BeltBlock.canAccessFromSide(facing, neighbour);
|
||||
}
|
||||
|
||||
return !neighbour.getShape(worldIn, pos).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||
if (world.isRemote())
|
||||
|
@ -121,7 +129,7 @@ public class ExtractorBlock extends HorizontalBlock implements IBlockWithFilter
|
|||
boolean isMoving) {
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
|
||||
|
||||
Direction blockFacing = state.get(HORIZONTAL_FACING);
|
||||
if (fromPos.equals(pos.offset(blockFacing))) {
|
||||
if (!isValidPosition(state, worldIn, pos)) {
|
||||
|
|
|
@ -1,75 +1,175 @@
|
|||
{
|
||||
"forgemarker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/belt/horizontal_middle"
|
||||
},
|
||||
"variants": {
|
||||
|
||||
"slope=horizontal,part=start,facing=north": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 180 },
|
||||
"slope=horizontal,part=start,facing=south": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 0 },
|
||||
"slope=horizontal,part=start,facing=east": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 270 },
|
||||
"slope=horizontal,part=start,facing=west": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 90 },
|
||||
"casing=false,slope=horizontal,part=start,facing=north": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 180 },
|
||||
"casing=false,slope=horizontal,part=start,facing=south": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 0 },
|
||||
"casing=false,slope=horizontal,part=start,facing=east": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 270 },
|
||||
"casing=false,slope=horizontal,part=start,facing=west": { "model": "create:block/belt/horizontal_end", "x": 0, "y": 90 },
|
||||
|
||||
"slope=horizontal,part=middle,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 180 },
|
||||
"slope=horizontal,part=middle,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 0 },
|
||||
"slope=horizontal,part=middle,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 270 },
|
||||
"slope=horizontal,part=middle,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 90 },
|
||||
"casing=false,slope=horizontal,part=middle,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=horizontal,part=middle,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=horizontal,part=middle,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=horizontal,part=middle,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 90 },
|
||||
|
||||
"slope=horizontal,part=end,facing=north": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 180 },
|
||||
"slope=horizontal,part=end,facing=south": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 0 },
|
||||
"slope=horizontal,part=end,facing=east": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 270 },
|
||||
"slope=horizontal,part=end,facing=west": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 90 },
|
||||
"casing=false,slope=horizontal,part=end,facing=north": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 180 },
|
||||
"casing=false,slope=horizontal,part=end,facing=south": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 0 },
|
||||
"casing=false,slope=horizontal,part=end,facing=east": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 270 },
|
||||
"casing=false,slope=horizontal,part=end,facing=west": { "model": "create:block/belt/horizontal_start", "x": 0, "y": 90 },
|
||||
|
||||
"casing=false,slope=horizontal,part=pulley,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=horizontal,part=pulley,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=horizontal,part=pulley,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=horizontal,part=pulley,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 0, "y": 90 },
|
||||
|
||||
|
||||
"casing=false,slope=vertical,part=end,facing=north": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 180 },
|
||||
"casing=false,slope=vertical,part=end,facing=south": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 0 },
|
||||
"casing=false,slope=vertical,part=end,facing=east": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 270 },
|
||||
"casing=false,slope=vertical,part=end,facing=west": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 90 },
|
||||
|
||||
"slope=vertical,part=end,facing=north": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 180 },
|
||||
"slope=vertical,part=end,facing=south": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 0 },
|
||||
"slope=vertical,part=end,facing=east": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 270 },
|
||||
"slope=vertical,part=end,facing=west": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 90 },
|
||||
|
||||
"slope=vertical,part=middle,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 180 },
|
||||
"slope=vertical,part=middle,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 0 },
|
||||
"slope=vertical,part=middle,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 270 },
|
||||
"slope=vertical,part=middle,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 90 },
|
||||
|
||||
"slope=vertical,part=start,facing=north": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 180 },
|
||||
"slope=vertical,part=start,facing=south": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 0 },
|
||||
"slope=vertical,part=start,facing=east": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 270 },
|
||||
"slope=vertical,part=start,facing=west": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 90 },
|
||||
"casing=false,slope=vertical,part=middle,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 180 },
|
||||
"casing=false,slope=vertical,part=middle,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 0 },
|
||||
"casing=false,slope=vertical,part=middle,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 270 },
|
||||
"casing=false,slope=vertical,part=middle,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 90 },
|
||||
|
||||
"casing=false,slope=vertical,part=start,facing=north": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 180 },
|
||||
"casing=false,slope=vertical,part=start,facing=south": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 0 },
|
||||
"casing=false,slope=vertical,part=start,facing=east": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 270 },
|
||||
"casing=false,slope=vertical,part=start,facing=west": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 90 },
|
||||
|
||||
"casing=false,slope=vertical,part=pulley,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 180 },
|
||||
"casing=false,slope=vertical,part=pulley,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 0 },
|
||||
"casing=false,slope=vertical,part=pulley,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 270 },
|
||||
"casing=false,slope=vertical,part=pulley,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 90 },
|
||||
|
||||
|
||||
"slope=upward,part=start,facing=north": { "model": "create:block/belt/downward_end", "x": 0, "y": 180 },
|
||||
"slope=upward,part=start,facing=south": { "model": "create:block/belt/downward_end", "x": 0, "y": 0 },
|
||||
"slope=upward,part=start,facing=east": { "model": "create:block/belt/downward_end", "x": 0, "y": 270 },
|
||||
"slope=upward,part=start,facing=west": { "model": "create:block/belt/downward_end", "x": 0, "y": 90 },
|
||||
"casing=false,slope=upward,part=start,facing=north": { "model": "create:block/belt/downward_end", "x": 0, "y": 180 },
|
||||
"casing=false,slope=upward,part=start,facing=south": { "model": "create:block/belt/downward_end", "x": 0, "y": 0 },
|
||||
"casing=false,slope=upward,part=start,facing=east": { "model": "create:block/belt/downward_end", "x": 0, "y": 270 },
|
||||
"casing=false,slope=upward,part=start,facing=west": { "model": "create:block/belt/downward_end", "x": 0, "y": 90 },
|
||||
|
||||
"slope=upward,part=middle,facing=north": { "model": "create:block/belt/downward_middle", "x": 0, "y": 180 },
|
||||
"slope=upward,part=middle,facing=south": { "model": "create:block/belt/downward_middle", "x": 0, "y": 0 },
|
||||
"slope=upward,part=middle,facing=east": { "model": "create:block/belt/downward_middle", "x": 0, "y": 270 },
|
||||
"slope=upward,part=middle,facing=west": { "model": "create:block/belt/downward_middle", "x": 0, "y": 90 },
|
||||
|
||||
"slope=upward,part=end,facing=north": { "model": "create:block/belt/downward_start", "x": 0, "y": 180 },
|
||||
"slope=upward,part=end,facing=south": { "model": "create:block/belt/downward_start", "x": 0, "y": 0 },
|
||||
"slope=upward,part=end,facing=east": { "model": "create:block/belt/downward_start", "x": 0, "y": 270 },
|
||||
"slope=upward,part=end,facing=west": { "model": "create:block/belt/downward_start", "x": 0, "y": 90 },
|
||||
"casing=false,slope=upward,part=middle,facing=north": { "model": "create:block/belt/downward_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=upward,part=middle,facing=south": { "model": "create:block/belt/downward_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=upward,part=middle,facing=east": { "model": "create:block/belt/downward_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=upward,part=middle,facing=west": { "model": "create:block/belt/downward_middle", "x": 0, "y": 90 },
|
||||
|
||||
"casing=false,slope=upward,part=end,facing=north": { "model": "create:block/belt/downward_start", "x": 0, "y": 180 },
|
||||
"casing=false,slope=upward,part=end,facing=south": { "model": "create:block/belt/downward_start", "x": 0, "y": 0 },
|
||||
"casing=false,slope=upward,part=end,facing=east": { "model": "create:block/belt/downward_start", "x": 0, "y": 270 },
|
||||
"casing=false,slope=upward,part=end,facing=west": { "model": "create:block/belt/downward_start", "x": 0, "y": 90 },
|
||||
|
||||
"casing=false,slope=upward,part=pulley,facing=north": { "model": "create:block/belt/downward_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=upward,part=pulley,facing=south": { "model": "create:block/belt/downward_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=upward,part=pulley,facing=east": { "model": "create:block/belt/downward_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=upward,part=pulley,facing=west": { "model": "create:block/belt/downward_middle", "x": 0, "y": 90 },
|
||||
|
||||
|
||||
"slope=downward,part=start,facing=north": { "model": "create:block/belt/upward_end", "x": 0, "y": 180 },
|
||||
"slope=downward,part=start,facing=south": { "model": "create:block/belt/upward_end", "x": 0, "y": 0 },
|
||||
"slope=downward,part=start,facing=east": { "model": "create:block/belt/upward_end", "x": 0, "y": 270 },
|
||||
"slope=downward,part=start,facing=west": { "model": "create:block/belt/upward_end", "x": 0, "y": 90 },
|
||||
"casing=false,slope=downward,part=start,facing=north": { "model": "create:block/belt/upward_end", "x": 0, "y": 180 },
|
||||
"casing=false,slope=downward,part=start,facing=south": { "model": "create:block/belt/upward_end", "x": 0, "y": 0 },
|
||||
"casing=false,slope=downward,part=start,facing=east": { "model": "create:block/belt/upward_end", "x": 0, "y": 270 },
|
||||
"casing=false,slope=downward,part=start,facing=west": { "model": "create:block/belt/upward_end", "x": 0, "y": 90 },
|
||||
|
||||
"slope=downward,part=middle,facing=north": { "model": "create:block/belt/upward_middle", "x": 0, "y": 180 },
|
||||
"slope=downward,part=middle,facing=south": { "model": "create:block/belt/upward_middle", "x": 0, "y": 0 },
|
||||
"slope=downward,part=middle,facing=east": { "model": "create:block/belt/upward_middle", "x": 0, "y": 270 },
|
||||
"slope=downward,part=middle,facing=west": { "model": "create:block/belt/upward_middle", "x": 0, "y": 90 },
|
||||
"casing=false,slope=downward,part=middle,facing=north": { "model": "create:block/belt/upward_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=downward,part=middle,facing=south": { "model": "create:block/belt/upward_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=downward,part=middle,facing=east": { "model": "create:block/belt/upward_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=downward,part=middle,facing=west": { "model": "create:block/belt/upward_middle", "x": 0, "y": 90 },
|
||||
|
||||
"slope=downward,part=end,facing=north": { "model": "create:block/belt/upward_start", "x": 0, "y": 180 },
|
||||
"slope=downward,part=end,facing=south": { "model": "create:block/belt/upward_start", "x": 0, "y": 0 },
|
||||
"slope=downward,part=end,facing=east": { "model": "create:block/belt/upward_start", "x": 0, "y": 270 },
|
||||
"slope=downward,part=end,facing=west": { "model": "create:block/belt/upward_start", "x": 0, "y": 90 }
|
||||
"casing=false,slope=downward,part=end,facing=north": { "model": "create:block/belt/upward_start", "x": 0, "y": 180 },
|
||||
"casing=false,slope=downward,part=end,facing=south": { "model": "create:block/belt/upward_start", "x": 0, "y": 0 },
|
||||
"casing=false,slope=downward,part=end,facing=east": { "model": "create:block/belt/upward_start", "x": 0, "y": 270 },
|
||||
"casing=false,slope=downward,part=end,facing=west": { "model": "create:block/belt/upward_start", "x": 0, "y": 90 },
|
||||
|
||||
"casing=false,slope=downward,part=pulley,facing=north": { "model": "create:block/belt/upward_middle", "x": 0, "y": 180 },
|
||||
"casing=false,slope=downward,part=pulley,facing=south": { "model": "create:block/belt/upward_middle", "x": 0, "y": 0 },
|
||||
"casing=false,slope=downward,part=pulley,facing=east": { "model": "create:block/belt/upward_middle", "x": 0, "y": 270 },
|
||||
"casing=false,slope=downward,part=pulley,facing=west": { "model": "create:block/belt/upward_middle", "x": 0, "y": 90 },
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"casing=true,slope=horizontal,part=start,facing=north": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 180 },
|
||||
"casing=true,slope=horizontal,part=start,facing=south": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 0 },
|
||||
"casing=true,slope=horizontal,part=start,facing=east": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 270 },
|
||||
"casing=true,slope=horizontal,part=start,facing=west": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=horizontal,part=middle,facing=north": { "model": "create:block/belt/horizontal_casing", "x": 0, "y": 180 },
|
||||
"casing=true,slope=horizontal,part=middle,facing=south": { "model": "create:block/belt/horizontal_casing", "x": 0, "y": 0 },
|
||||
"casing=true,slope=horizontal,part=middle,facing=east": { "model": "create:block/belt/horizontal_casing", "x": 0, "y": 270 },
|
||||
"casing=true,slope=horizontal,part=middle,facing=west": { "model": "create:block/belt/horizontal_casing", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=horizontal,part=end,facing=north": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 180 },
|
||||
"casing=true,slope=horizontal,part=end,facing=south": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 0 },
|
||||
"casing=true,slope=horizontal,part=end,facing=east": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 270 },
|
||||
"casing=true,slope=horizontal,part=end,facing=west": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=horizontal,part=pulley,facing=north": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 180 },
|
||||
"casing=true,slope=horizontal,part=pulley,facing=south": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 0 },
|
||||
"casing=true,slope=horizontal,part=pulley,facing=east": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 270 },
|
||||
"casing=true,slope=horizontal,part=pulley,facing=west": { "model": "create:block/belt/horizontal_casing_pulley", "x": 0, "y": 90 },
|
||||
|
||||
|
||||
"casing=true,slope=upward,part=start,facing=north": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 0 },
|
||||
"casing=true,slope=upward,part=start,facing=south": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 180 },
|
||||
"casing=true,slope=upward,part=start,facing=east": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 90 },
|
||||
"casing=true,slope=upward,part=start,facing=west": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 270 },
|
||||
|
||||
"casing=true,slope=upward,part=middle,facing=north": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 0 },
|
||||
"casing=true,slope=upward,part=middle,facing=south": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 180 },
|
||||
"casing=true,slope=upward,part=middle,facing=east": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 90 },
|
||||
"casing=true,slope=upward,part=middle,facing=west": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 270 },
|
||||
|
||||
"casing=true,slope=upward,part=end,facing=north": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 180 },
|
||||
"casing=true,slope=upward,part=end,facing=south": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 0 },
|
||||
"casing=true,slope=upward,part=end,facing=east": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 270 },
|
||||
"casing=true,slope=upward,part=end,facing=west": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=upward,part=pulley,facing=north": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 0 },
|
||||
"casing=true,slope=upward,part=pulley,facing=south": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 180 },
|
||||
"casing=true,slope=upward,part=pulley,facing=east": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 90 },
|
||||
"casing=true,slope=upward,part=pulley,facing=west": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 270 },
|
||||
|
||||
|
||||
"casing=true,slope=vertical,part=end,facing=north": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 180 },
|
||||
"casing=true,slope=vertical,part=end,facing=south": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 0 },
|
||||
"casing=true,slope=vertical,part=end,facing=east": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 270 },
|
||||
"casing=true,slope=vertical,part=end,facing=west": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 90 },
|
||||
|
||||
"casing=true,slope=vertical,part=middle,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 180 },
|
||||
"casing=true,slope=vertical,part=middle,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 0 },
|
||||
"casing=true,slope=vertical,part=middle,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 270 },
|
||||
"casing=true,slope=vertical,part=middle,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 90 },
|
||||
|
||||
"casing=true,slope=vertical,part=start,facing=north": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 180 },
|
||||
"casing=true,slope=vertical,part=start,facing=south": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 0 },
|
||||
"casing=true,slope=vertical,part=start,facing=east": { "model": "create:block/belt/horizontal_end", "x": 90, "y": 270 },
|
||||
"casing=true,slope=vertical,part=start,facing=west": { "model": "create:block/belt/horizontal_start", "x": 90, "y": 90 },
|
||||
|
||||
"casing=true,slope=vertical,part=pulley,facing=north": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 180 },
|
||||
"casing=true,slope=vertical,part=pulley,facing=south": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 0 },
|
||||
"casing=true,slope=vertical,part=pulley,facing=east": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 270 },
|
||||
"casing=true,slope=vertical,part=pulley,facing=west": { "model": "create:block/belt/horizontal_middle", "x": 90, "y": 90 },
|
||||
|
||||
|
||||
"casing=true,slope=downward,part=start,facing=north": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 0 },
|
||||
"casing=true,slope=downward,part=start,facing=south": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 180 },
|
||||
"casing=true,slope=downward,part=start,facing=east": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 90 },
|
||||
"casing=true,slope=downward,part=start,facing=west": { "model": "create:block/belt/diagonal_casing_top", "x": 0, "y": 270 },
|
||||
|
||||
"casing=true,slope=downward,part=middle,facing=north": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 180 },
|
||||
"casing=true,slope=downward,part=middle,facing=south": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 0 },
|
||||
"casing=true,slope=downward,part=middle,facing=east": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 270 },
|
||||
"casing=true,slope=downward,part=middle,facing=west": { "model": "create:block/belt/diagonal_casing_middle", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=downward,part=end,facing=north": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 180 },
|
||||
"casing=true,slope=downward,part=end,facing=south": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 0 },
|
||||
"casing=true,slope=downward,part=end,facing=east": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 270 },
|
||||
"casing=true,slope=downward,part=end,facing=west": { "model": "create:block/belt/diagonal_casing_bottom", "x": 0, "y": 90 },
|
||||
|
||||
"casing=true,slope=downward,part=pulley,facing=north": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 180 },
|
||||
"casing=true,slope=downward,part=pulley,facing=south": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 0 },
|
||||
"casing=true,slope=downward,part=pulley,facing=east": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 270 },
|
||||
"casing=true,slope=downward,part=pulley,facing=west": { "model": "create:block/belt/diagonal_casing_middle_pulley", "x": 0, "y": 90 }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"1": "create:block/belt_support_side",
|
||||
"2": "create:block/brass_casing_side",
|
||||
"8": "create:block/gearbox"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 5, 2],
|
||||
"to": [14.9, 11, 14],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"east": {"uv": [2, 5, 14, 11], "texture": "#8"},
|
||||
"south": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"west": {"uv": [2, 5, 14, 11], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 11, 6],
|
||||
"to": [14.9, 13, 10],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"east": {"uv": [6, 3, 10, 5], "texture": "#8"},
|
||||
"west": {"uv": [6, 3, 10, 5], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 10, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 10, 16], "rotation": 90, "texture": "#2"},
|
||||
"east": {"uv": [11, 1, 16, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 1, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [0, 1, 5, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Zfighter2",
|
||||
"from": [0.5, 0.1, 15.1],
|
||||
"to": [15.5, 11.1, 16.1],
|
||||
"faces": {
|
||||
"east": {"uv": [12, 0, 13, 10.8], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 15, 10.8], "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 1, 10.8], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 15, 1], "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 1, 15], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Right",
|
||||
"from": [0, 0, 11],
|
||||
"to": [16, 11, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 2, 11], "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 4, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [12, 0, 16, 11], "texture": "#2"},
|
||||
"up": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Down",
|
||||
"from": [0, 0, 5],
|
||||
"to": [16, 5.1, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"west": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 2, 16, 8], "texture": "#2"},
|
||||
"down": {"uv": [4, 0, 10, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, -3.325],
|
||||
"to": [16.1, 11, 4.7],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"2": "create:block/brass_casing_side",
|
||||
"8": "create:block/gearbox"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 11, 6],
|
||||
"to": [14.9, 13, 10],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"east": {"uv": [6, 3, 10, 5], "texture": "#8"},
|
||||
"west": {"uv": [6, 3, 10, 5], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 10, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 10, 16], "rotation": 90, "texture": "#2"},
|
||||
"east": {"uv": [11, 1, 16, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 1, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [0, 1, 5, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Down",
|
||||
"from": [0, 0, 5],
|
||||
"to": [16, 5.1, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"west": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 2, 16, 8], "texture": "#2"},
|
||||
"down": {"uv": [4, 0, 10, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, -3.325],
|
||||
"to": [16.1, 11, 10],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 13.325, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, 10],
|
||||
"to": [16.1, 11, 19.3],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 9.3, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 9.3, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"1": "create:block/belt_support_side",
|
||||
"2": "create:block/brass_casing_side",
|
||||
"8": "create:block/gearbox"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 5, 2],
|
||||
"to": [14.9, 11, 14],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"east": {"uv": [2, 5, 14, 11], "texture": "#8"},
|
||||
"south": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"west": {"uv": [2, 5, 14, 11], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 11, 6],
|
||||
"to": [14.9, 13, 10],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"east": {"uv": [6, 3, 10, 5], "texture": "#8"},
|
||||
"west": {"uv": [6, 3, 10, 5], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 10, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 10, 16], "rotation": 90, "texture": "#2"},
|
||||
"east": {"uv": [11, 1, 16, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 1, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [0, 1, 5, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Down",
|
||||
"from": [0, 0, 5],
|
||||
"to": [16, 5.1, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"west": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 2, 16, 8], "texture": "#2"},
|
||||
"down": {"uv": [4, 0, 10, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, -3.325],
|
||||
"to": [16.1, 11, 4.7],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, 11.275],
|
||||
"to": [16.1, 11, 19.3],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"1": "create:block/belt_support_side",
|
||||
"2": "create:block/brass_casing_side",
|
||||
"8": "create:block/gearbox"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 4, 4],
|
||||
"to": [14.9, 11, 14],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"east": {"uv": [2, 5, 12, 12], "texture": "#8"},
|
||||
"south": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"west": {"uv": [4, 5, 14, 12], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1.1, 11, 6],
|
||||
"to": [14.9, 13, 10],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"east": {"uv": [6, 3, 10, 5], "texture": "#8"},
|
||||
"west": {"uv": [6, 3, 10, 5], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Zfighter2",
|
||||
"from": [0.5, 0.1, 15.1],
|
||||
"to": [15.5, 11.1, 16.1],
|
||||
"faces": {
|
||||
"east": {"uv": [12, 0, 13, 10.8], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 15, 10.8], "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 1, 10.8], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 15, 1], "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 1, 15], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Right",
|
||||
"from": [0, 0, 11],
|
||||
"to": [16, 11, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 2, 11], "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 4, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [12, 0, 16, 11], "texture": "#2"},
|
||||
"up": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Down",
|
||||
"from": [0, 0, 5],
|
||||
"to": [16, 5.1, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 6, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 5], "texture": "#missing"},
|
||||
"west": {"uv": [4, 5.9, 10, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 2, 16, 8], "texture": "#2"},
|
||||
"down": {"uv": [4, 0, 10, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Diagonal",
|
||||
"from": [-0.1, 2, -3.328],
|
||||
"to": [16.1, 11, 4.697],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"south": {"uv": [7, 0, 16, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 8.025, 9], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 8.025, 16], "rotation": 270, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"1": "create:block/belt_support_side",
|
||||
"2": "create:block/brass_casing_side"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 11, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 11], "texture": "#1"},
|
||||
"east": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 11], "texture": "#1"},
|
||||
"west": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"1": "create:block/belt_support_side",
|
||||
"2": "create:block/brass_casing_side",
|
||||
"8": "create:block/gearbox"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Casing",
|
||||
"from": [1, 5, 2],
|
||||
"to": [15, 11, 14],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"east": {"uv": [2, 5, 14, 11], "texture": "#8"},
|
||||
"south": {"uv": [0, 0, 15, 6], "texture": "#1"},
|
||||
"west": {"uv": [2, 5, 14, 11], "texture": "#8"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 11, 4],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [12, 0, 16, 11], "texture": "#2"},
|
||||
"south": {"uv": [14, 0, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 4, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 4, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 4, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Zfighter",
|
||||
"from": [0.5, 0.1, -0.1],
|
||||
"to": [15.5, 10.9, 0.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 15, 10.8], "texture": "#2"},
|
||||
"east": {"uv": [12, 0, 13, 10.8], "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 1, 10.8], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 15, 1], "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 1, 15], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Zfighter2",
|
||||
"from": [0.5, 0.1, 15.1],
|
||||
"to": [15.5, 10.9, 16.1],
|
||||
"faces": {
|
||||
"east": {"uv": [12, 0, 13, 10.8], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 15, 10.8], "texture": "#2"},
|
||||
"west": {"uv": [0, 0, 1, 10.8], "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 15, 1], "texture": "#2"},
|
||||
"down": {"uv": [0, 0, 1, 15], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Right",
|
||||
"from": [0, 0, 12],
|
||||
"to": [16, 11, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 2, 11], "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 4, 11], "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 11], "texture": "#2"},
|
||||
"west": {"uv": [12, 0, 16, 11], "texture": "#2"},
|
||||
"up": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Down",
|
||||
"from": [0, 0, 4],
|
||||
"to": [16, 4, 12],
|
||||
"faces": {
|
||||
"east": {"uv": [4, 7, 12, 11], "texture": "#2"},
|
||||
"west": {"uv": [4, 7, 12, 11], "texture": "#2"},
|
||||
"up": {"uv": [0, 2, 16, 10], "texture": "#2"},
|
||||
"down": {"uv": [4, 0, 12, 16], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,95 +1,140 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"particle": "create:block/belt_funnel",
|
||||
"belt_funnel": "create:block/belt_funnel",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [ 3, -4.1, -1 ],
|
||||
"to": [ 13, -3.1, 5 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#belt_funnel", "uv": [ 0, 11, 10, 12 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 10, 11, 16, 12 ] },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 0, 11, 10, 12 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 10, 11, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 13 ], "rotation": 90 },
|
||||
"down": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 12 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 3, 7, -1 ],
|
||||
"to": [ 13, 8, 5 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#belt_funnel", "uv": [ 0, 0, 10, 1 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 1 ] },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 0, 0, 10, 1 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 1 ], "rotation": 180 },
|
||||
"up": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 12 ], "rotation": 90 },
|
||||
"down": { "texture": "#belt_funnel", "uv": [ 10, 0, 16, 13 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 3, -3.1, -1 ],
|
||||
"to": [ 4, 7, 5 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#belt_funnel", "uv": [ 9, 1, 10, 11.1 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 10, 1, 16, 11 ] },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 0, 1, 1, 11.1 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 10, 1, 16, 11 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 4, -3.1, -1 ],
|
||||
"to": [ 12, 7, 4 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 4, 3, 12, 13.1 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 9, 3, 10, 9 ], "rotation": 90 },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 1, 1, 9, 11.1 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 0, 2, 1, 8 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 4, 6, 0 ],
|
||||
"to": [ 12, 8, 4.8 ],
|
||||
"rotation": { "origin": [ 8, 8, 0 ], "axis": "x", "angle": -22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#belt_funnel", "uv": [ 1, 7, 9, 9 ], "rotation": 180 },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 11, 4.6, 16, 6.6 ], "rotation": 180 },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 9, 2, 11, 10 ], "rotation": 90 },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 10, 5, 15, 7.4 ], "rotation": 180 },
|
||||
"up": { "texture": "#belt_funnel", "uv": [ 11, 2, 16, 9.4 ], "rotation": 90 },
|
||||
"down": { "texture": "#belt_funnel", "uv": [ 1, 8, 9, 12.8 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Ramp",
|
||||
"from": [ 4, -4, -8 ],
|
||||
"to": [ 12, 3, -1 ],
|
||||
"rotation": { "origin": [ 8, -4, -1 ], "axis": "x", "angle": 45.0 },
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 4, 5, 12, 12 ] },
|
||||
"east": { "texture": "#brass_casing", "uv": [ 4, 9, 11, 16 ], "rotation": 90 },
|
||||
"west": { "texture": "#brass_casing", "uv": [ 5, 9, 12, 16 ], "rotation": 270 },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 4, 0, 12, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 12, -3.1, -1 ],
|
||||
"to": [ 13, 7, 5 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#belt_funnel", "uv": [ 0, 1, 1, 11.1 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 10, 1, 16, 11 ], "rotation": 180 },
|
||||
"south": { "texture": "#belt_funnel", "uv": [ 9, 1, 10, 11.1 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 10, 1, 16, 11 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
"credit": "Made with Blockbench",
|
||||
"textures": {
|
||||
"belt_funnel": "create:block/belt_funnel",
|
||||
"particle": "create:block/belt_funnel",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [3, -4.1, -1],
|
||||
"to": [13, -3.1, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 11, 10, 12], "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 11, 16, 12], "texture": "#belt_funnel"},
|
||||
"south": {"uv": [0, 11, 10, 12], "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 11, 16, 12], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"up": {"uv": [10, 0, 16, 13], "rotation": 90, "texture": "#belt_funnel"},
|
||||
"down": {"uv": [10, 1, 16, 11], "rotation": 90, "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [3, 7, -1],
|
||||
"to": [13, 8, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 10, 1], "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 0, 16, 1], "texture": "#belt_funnel"},
|
||||
"south": {"uv": [0, 0, 10, 1], "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 0, 16, 1], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"up": {"uv": [10, 1, 16, 11], "rotation": 90, "texture": "#belt_funnel"},
|
||||
"down": {"uv": [10, 0, 16, 13], "rotation": 90, "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [3, -3.1, -1],
|
||||
"to": [4, 7, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [9, 1, 10, 11.1], "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 1, 16, 11], "texture": "#belt_funnel"},
|
||||
"south": {"uv": [0, 1, 1, 11.1], "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 1, 16, 11], "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [4, -3.1, -1],
|
||||
"to": [12, 7, 4],
|
||||
"faces": {
|
||||
"north": {"uv": [4, 3, 12, 13.1], "texture": "#brass_casing"},
|
||||
"east": {"uv": [9, 3, 10, 9], "rotation": 90, "texture": "#belt_funnel"},
|
||||
"south": {"uv": [1, 1, 9, 11.1], "texture": "#belt_funnel"},
|
||||
"west": {"uv": [0, 2, 1, 8], "rotation": 90, "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [4, 9, -1],
|
||||
"to": [12, 10, 4.25],
|
||||
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 8, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 12, 9, 13], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 5, 16, 6], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"south": {"uv": [9, 2, 11, 10], "rotation": 90, "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 5, 16, 6], "texture": "#belt_funnel"},
|
||||
"up": {"uv": [10, 2, 16, 10], "rotation": 90, "texture": "#belt_funnel"},
|
||||
"down": {"uv": [1, 8, 9, 12.8], "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [4, 7, -1],
|
||||
"to": [12, 9, 2.5],
|
||||
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 8, 0]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 11, 9, 13], "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 5, 14, 7], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 5, 14, 6], "texture": "#belt_funnel"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Ramp",
|
||||
"from": [4, -4, -8],
|
||||
"to": [12, 3, -1],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, -4, -1]},
|
||||
"faces": {
|
||||
"north": {"uv": [4, 5, 12, 12], "texture": "#brass_casing"},
|
||||
"east": {"uv": [4, 9, 11, 16], "rotation": 90, "texture": "#brass_casing"},
|
||||
"west": {"uv": [5, 9, 12, 16], "rotation": 270, "texture": "#brass_casing"},
|
||||
"down": {"uv": [4, 0, 12, 7], "texture": "#brass_casing"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [12, -3.1, -1],
|
||||
"to": [13, 7, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 1, 1, 11.1], "texture": "#belt_funnel"},
|
||||
"east": {"uv": [10, 1, 16, 11], "rotation": 180, "texture": "#belt_funnel"},
|
||||
"south": {"uv": [9, 1, 10, 11.1], "texture": "#belt_funnel"},
|
||||
"west": {"uv": [10, 1, 16, 11], "texture": "#belt_funnel"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, -149, 0],
|
||||
"translation": [-0.5, 3.25, 2.25],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, -149, 0],
|
||||
"translation": [-0.5, 3.25, 2.25],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, -55, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, -55, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 0, 2.25],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 45, 0],
|
||||
"translation": [2.5, 1.75, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 180, 0],
|
||||
"translation": [0, 3.5, -4.5],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,75 +1,115 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"extractor": "create:block/extractor",
|
||||
"textures": {
|
||||
"1": "create:block/brass_casing",
|
||||
"extractor": "create:block/extractor",
|
||||
"particle": "create:block/extractor"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [ 4, 2, -1 ],
|
||||
"to": [ 12, 3, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 7, 14, 8 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 4, 9, -1 ],
|
||||
"to": [ 12, 10, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 0, 14, 1 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 4, 3, -1 ],
|
||||
"to": [ 5, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 1, 7, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 11, 3, -1 ],
|
||||
"to": [ 12, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 13, 1, 14, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 5, 3, 3 ],
|
||||
"to": [ 11, 9, 4 ],
|
||||
"faces": {
|
||||
"south": { "texture": "#extractor", "uv": [ 7, 1, 13, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [ 5, 10, -0.6 ],
|
||||
"to": [ 11, 12, 4 ],
|
||||
"rotation": { "origin": [ 8, 11, -1 ], "axis": "x", "angle": 22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#extractor", "uv": [ 13, 1, 15, 7 ], "rotation": 90 },
|
||||
"east": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 4, 1, 5, 7 ], "rotation": 270 },
|
||||
"west": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [4, 2, -1],
|
||||
"to": [12, 3, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 7, 14, 8], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 7, 14, 8], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 0, 6, 1], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 0, 6, 8], "rotation": 90, "texture": "#extractor"},
|
||||
"down": {"uv": [0, 0, 6, 8], "rotation": 270, "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [4, 9, -1],
|
||||
"to": [12, 10, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 0, 14, 1], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 0, 14, 1], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 0, 6, 1], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 0, 6, 8], "rotation": 90, "texture": "#extractor"},
|
||||
"down": {"uv": [0, 0, 6, 8], "rotation": 270, "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [4, 3, -1],
|
||||
"to": [5, 9, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [13, 1, 14, 7], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 1, 6, 7], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 1, 7, 7], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 1, 6, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [11, 3, -1],
|
||||
"to": [12, 9, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 1, 7, 7], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 1, 6, 7], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [13, 1, 14, 7], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 1, 6, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [5, 3, 0],
|
||||
"to": [11, 9, 4],
|
||||
"faces": {
|
||||
"north": {"uv": [5, 5, 11, 11], "texture": "#1"},
|
||||
"south": {"uv": [7, 1, 13, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [5, 10, -0.6],
|
||||
"to": [11, 12, 4],
|
||||
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, -1]},
|
||||
"faces": {
|
||||
"north": {"uv": [13, 1, 15, 7], "rotation": 90, "texture": "#extractor"},
|
||||
"east": {"uv": [0.1, 0, 4.7, 2], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [4, 1, 5, 7], "rotation": 270, "texture": "#extractor"},
|
||||
"west": {"uv": [0.1, 0, 4.7, 2], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 9, 5, 15], "rotation": 90, "texture": "#extractor"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, -149, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, -149, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, -55, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, -55, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 1, 1.25],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 45, 0],
|
||||
"translation": [2.5, -0.5, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 180, 0],
|
||||
"translation": [0, 1.75, -4.5],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +1,118 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"redstone_antenna": "create:block/redstone_antenna",
|
||||
"extractor": "create:block/extractor",
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "create:block/extractor",
|
||||
"textures": {
|
||||
"2": "create:block/brass_casing",
|
||||
"redstone_antenna": "create:block/redstone_antenna",
|
||||
"extractor": "create:block/extractor",
|
||||
"particle": "create:block/extractor"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [ 4, 2, -1 ],
|
||||
"to": [ 12, 3, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 7, 14, 8 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 4, 9, -1 ],
|
||||
"to": [ 12, 10, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 0, 14, 1 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 4, 3, -1 ],
|
||||
"to": [ 5, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 1, 7, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 11, 3, -1 ],
|
||||
"to": [ 12, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 13, 1, 14, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 5, 3, 3 ],
|
||||
"to": [ 11, 9, 4 ],
|
||||
"faces": {
|
||||
"south": { "texture": "#extractor", "uv": [ 7, 1, 13, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [ 5, 10, -0.6 ],
|
||||
"to": [ 11, 12, 4 ],
|
||||
"rotation": { "origin": [ 8, 11, -1 ], "axis": "x", "angle": 22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#extractor", "uv": [ 13, 1, 15, 7 ], "rotation": 90 },
|
||||
"east": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 4, 1, 5, 7 ], "rotation": 270 },
|
||||
"west": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaX",
|
||||
"from": [ 11, 7, 2 ],
|
||||
"to": [ 14, 17, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"south": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"down": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaZ",
|
||||
"from": [ 12, 7, 1 ],
|
||||
"to": [ 13, 17, 4 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaTop",
|
||||
"from": [ 12, 15, 2 ],
|
||||
"to": [ 13, 16, 3 ],
|
||||
"faces": {
|
||||
"up": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaDish",
|
||||
"from": [ 10, 13, 0 ],
|
||||
"to": [ 15, 13, 5 ],
|
||||
"faces": {
|
||||
"up": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] },
|
||||
"down": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [4, 2, -1],
|
||||
"to": [12, 3, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 7, 14, 8], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 7, 14, 8], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 0, 6, 1], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 0, 6, 8], "rotation": 90, "texture": "#extractor"},
|
||||
"down": {"uv": [0, 0, 6, 8], "rotation": 270, "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [4, 9, -1],
|
||||
"to": [12, 10, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 0, 14, 1], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 0, 6, 1], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 0, 14, 1], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 0, 6, 1], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 0, 6, 8], "rotation": 90, "texture": "#extractor"},
|
||||
"down": {"uv": [0, 0, 6, 8], "rotation": 270, "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [4, 3, -1],
|
||||
"to": [5, 9, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [13, 1, 14, 7], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 1, 6, 7], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [6, 1, 7, 7], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 1, 6, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [11, 3, -1],
|
||||
"to": [12, 9, 5],
|
||||
"faces": {
|
||||
"north": {"uv": [6, 1, 7, 7], "texture": "#extractor"},
|
||||
"east": {"uv": [0, 1, 6, 7], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [13, 1, 14, 7], "texture": "#extractor"},
|
||||
"west": {"uv": [0, 1, 6, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [5, 3, 0],
|
||||
"to": [11, 9, 4],
|
||||
"faces": {
|
||||
"north": {"uv": [5, 5, 11, 11], "texture": "#2"},
|
||||
"south": {"uv": [7, 1, 13, 7], "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [5, 10, -0.6],
|
||||
"to": [11, 12, 4],
|
||||
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, -1]},
|
||||
"faces": {
|
||||
"north": {"uv": [13, 1, 15, 7], "rotation": 90, "texture": "#extractor"},
|
||||
"east": {"uv": [0.1, 0, 4.7, 2], "rotation": 180, "texture": "#extractor"},
|
||||
"south": {"uv": [4, 1, 5, 7], "rotation": 270, "texture": "#extractor"},
|
||||
"west": {"uv": [0.1, 0, 4.7, 2], "texture": "#extractor"},
|
||||
"up": {"uv": [0, 9, 5, 15], "rotation": 90, "texture": "#extractor"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaX",
|
||||
"from": [11, 7, 2],
|
||||
"to": [14, 17, 3],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 3, 10], "texture": "#redstone_antenna"},
|
||||
"south": {"uv": [0, 0, 3, 10], "texture": "#redstone_antenna"},
|
||||
"down": {"uv": [0, 9, 3, 10], "texture": "#redstone_antenna"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaZ",
|
||||
"from": [12, 7, 1],
|
||||
"to": [13, 17, 4],
|
||||
"faces": {
|
||||
"east": {"uv": [0, 0, 3, 10], "texture": "#redstone_antenna"},
|
||||
"west": {"uv": [0, 0, 3, 10], "texture": "#redstone_antenna"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaTop",
|
||||
"from": [12, 15, 2],
|
||||
"to": [13, 16, 3],
|
||||
"faces": {
|
||||
"up": {"uv": [1, 1, 2, 2], "texture": "#redstone_antenna"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaDish",
|
||||
"from": [10, 13, 0],
|
||||
"to": [15, 13, 5],
|
||||
"faces": {
|
||||
"up": {"uv": [4, 0, 9, 5], "texture": "#redstone_antenna"},
|
||||
"down": {"uv": [4, 0, 9, 5], "texture": "#redstone_antenna"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,86 +1,3 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 45, 0 ],
|
||||
"translation": [ 0, 0, 0],
|
||||
"scale":[ 0.625, 0.625, 0.625 ]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [ 0, 180, 0 ],
|
||||
"translation": [ 0, 0, -3.5],
|
||||
"scale":[ 0.5, 0.5, 0.5 ]
|
||||
}
|
||||
},
|
||||
"textures": {
|
||||
"extractor": "create:block/extractor",
|
||||
"particle": "create:block/extractor"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [ 4, 2, -1 ],
|
||||
"to": [ 12, 3, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 7, 14, 8 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 4, 9, -1 ],
|
||||
"to": [ 12, 10, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 0, 14, 1 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 4, 3, -1 ],
|
||||
"to": [ 5, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 1, 7, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 11, 3, -1 ],
|
||||
"to": [ 12, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 13, 1, 14, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 5, 3, 3 ],
|
||||
"to": [ 11, 9, 4 ],
|
||||
"faces": {
|
||||
"south": { "texture": "#extractor", "uv": [ 7, 1, 13, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [ 5, 10, -0.6 ],
|
||||
"to": [ 11, 12, 4 ],
|
||||
"rotation": { "origin": [ 8, 11, -1 ], "axis": "x", "angle": 22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#extractor", "uv": [ 13, 1, 15, 7 ], "rotation": 90 },
|
||||
"east": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 4, 1, 5, 7 ], "rotation": 270 },
|
||||
"west": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 }
|
||||
}
|
||||
}
|
||||
]
|
||||
"parent": "create:block/extractor"
|
||||
}
|
|
@ -1,123 +1,3 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 45, 0 ],
|
||||
"translation": [ 0, 0, 0],
|
||||
"scale":[ 0.625, 0.625, 0.625 ]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [ 0, 180, 0 ],
|
||||
"translation": [ 0, 0, -3.5],
|
||||
"scale":[ 0.5, 0.5, 0.5 ]
|
||||
}
|
||||
},
|
||||
"textures": {
|
||||
"redstone_antenna": "create:block/redstone_antenna",
|
||||
"extractor": "create:block/extractor",
|
||||
"particle": "create:block/extractor"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Bottom",
|
||||
"from": [ 4, 2, -1 ],
|
||||
"to": [ 12, 3, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 7, 14, 8 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 4, 9, -1 ],
|
||||
"to": [ 12, 10, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 0, 14, 1 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 90 },
|
||||
"down": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 270 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 4, 3, -1 ],
|
||||
"to": [ 5, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 6, 1, 7, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Side",
|
||||
"from": [ 11, 3, -1 ],
|
||||
"to": [ 12, 9, 5 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 13, 1, 14, 7 ] },
|
||||
"west": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 5, 3, 3 ],
|
||||
"to": [ 11, 9, 4 ],
|
||||
"faces": {
|
||||
"south": { "texture": "#extractor", "uv": [ 7, 1, 13, 7 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "FilterSpot",
|
||||
"from": [ 5, 10, -0.6 ],
|
||||
"to": [ 11, 12, 4 ],
|
||||
"rotation": { "origin": [ 8, 11, -1 ], "axis": "x", "angle": 22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#extractor", "uv": [ 13, 1, 15, 7 ], "rotation": 90 },
|
||||
"east": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ], "rotation": 180 },
|
||||
"south": { "texture": "#extractor", "uv": [ 4, 1, 5, 7 ], "rotation": 270 },
|
||||
"west": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ] },
|
||||
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaX",
|
||||
"from": [ 11, 7, 2 ],
|
||||
"to": [ 14, 17, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"south": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"down": { "texture": "#redstone_antenna", "uv": [ 0, 9, 3, 10 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaZ",
|
||||
"from": [ 12, 7, 1 ],
|
||||
"to": [ 13, 17, 4 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] },
|
||||
"west": { "texture": "#redstone_antenna", "uv": [ 0, 0, 3, 10 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaTop",
|
||||
"from": [ 12, 15, 2 ],
|
||||
"to": [ 13, 16, 3 ],
|
||||
"faces": {
|
||||
"up": { "texture": "#redstone_antenna", "uv": [ 1, 1, 2, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AntennaDish",
|
||||
"from": [ 10, 13, 0 ],
|
||||
"to": [ 15, 13, 5 ],
|
||||
"faces": {
|
||||
"up": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] },
|
||||
"down": { "texture": "#redstone_antenna", "uv": [ 4, 0, 9, 5 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
"parent": "create:block/extractor_wireless"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "create:belt_support"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"create:belt",
|
||||
"create:crushing_wheel",
|
||||
"create:limestone_wall",
|
||||
"create:limestone_bricks_wall",
|
||||
"create:weathered_limestone_wall",
|
||||
|
|
Loading…
Reference in a new issue