From e5c78fbd04b3d04fe58294e51fc95ca6d5480e7b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 14 Nov 2019 13:00:55 +0100 Subject: [PATCH] Jank Control - More blocks now support the new belt system - Fixed the extractor models - Prepared the funnel model for filtering - Items now look 80% better on belts --- .../utility/IndependentShadowRenderer.java | 94 ++++++ .../foundation/utility/TessellatorHelper.java | 277 +++++++++--------- .../contraptions/CachedBufferReloader.java | 2 - .../contraptions/RotationPropagator.java | 1 - .../receivers/MechanicalPressBlock.java | 92 +++--- .../receivers/MechanicalPressTileEntity.java | 64 ++-- .../receivers/ProcessingInventory.java | 35 ++- .../contraptions/receivers/SawTileEntity.java | 113 ++++++- .../receivers/SawTileEntityRenderer.java | 15 +- .../relays/belt/AllBeltAttachments.java | 72 +++-- .../contraptions/relays/belt/BeltBlock.java | 79 +++-- .../relays/belt/BeltInventory.java | 192 +++++++++--- .../relays/belt/BeltMovementHandler.java | 2 +- .../relays/belt/BeltTileEntity.java | 49 ++++ .../relays/belt/BeltTileEntityRenderer.java | 75 ++++- .../relays/belt/FastItemRenderer.java | 120 -------- .../modules/logistics/block/IExtractor.java | 22 +- .../block/belts/BeltFunnelBlock.java | 54 ++-- .../block/belts/BeltFunnelTileEntity.java | 83 +++--- .../block/belts/EntityDetectorBlock.java | 23 +- .../create/models/block/belt_funnel.json | 231 +++++++++------ .../assets/create/models/block/extractor.json | 182 +++++++----- .../models/block/extractor_wireless.json | 224 +++++++------- .../assets/create/models/item/extractor.json | 85 +----- .../create/models/item/linked_extractor.json | 122 +------- 25 files changed, 1312 insertions(+), 996 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java delete mode 100644 src/main/java/com/simibubi/create/modules/contraptions/relays/belt/FastItemRenderer.java diff --git a/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java b/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java new file mode 100644 index 000000000..e4584a584 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/IndependentShadowRenderer.java @@ -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(); + } + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java index 81f529ac2..472666268 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java @@ -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(); + } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/CachedBufferReloader.java b/src/main/java/com/simibubi/create/modules/contraptions/CachedBufferReloader.java index 899742dc0..862496802 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/CachedBufferReloader.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/CachedBufferReloader.java @@ -4,7 +4,6 @@ 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.FastItemRenderer; import net.minecraft.client.resources.ReloadListener; import net.minecraft.profiler.IProfiler; @@ -23,7 +22,6 @@ public class CachedBufferReloader extends ReloadListener { ContraptionRenderer.invalidateCache(); MechanicalBearingTileEntityRenderer.invalidateCache(); ColoredIndicatorRenderer.invalidateCache(); - FastItemRenderer.invalidateCache(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index f4f929ae7..1606125c7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressBlock.java index ed3529f17..c88e2ea80 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressBlock.java @@ -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.BeltBlock.Slope; +import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.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 getPotentialAttachmentLocations(BeltTileEntity te) { - return Arrays.asList(te.getPos().up(2)); + public List 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 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 recipe = pressTe.getRecipe(transportedStack.stack); + if (!recipe.isPresent()) + return false; + ItemStack out = recipe.get().getRecipeOutput().copy(); + List 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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressTileEntity.java index 876247563..bc00afb61 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalPressTileEntity.java @@ -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.BeltInventory.TransportedItemStack; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; 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 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 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 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 getRecipe(ItemStack item) { + pressingInv.setInventorySlotContents(0, item); Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.PRESSING, pressingInv, world); return recipe; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java index 4906d93c4..63bb24193 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java @@ -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(); + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java index 623a254f9..631c28311 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java @@ -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 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 LazyOptional getCapability(Capability 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> 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(); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java index 5a2a075d1..ad1bc7d2b 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java @@ -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 { 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 { 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 { // Filter filterRenderer.render(te, x, y, z, partialTicks, destroyStage); - + // Kinetic renders final BlockState state = getRenderedBlockState(te); KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java index 80e7e331e..4252dfe56 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java @@ -2,11 +2,11 @@ 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; import com.simibubi.create.Create; +import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.TransportedItemStack; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -14,6 +14,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 +34,52 @@ public enum AllBeltAttachments { } public interface IBeltAttachment { - public List getPotentialAttachmentLocations(BeltTileEntity te); - public Optional getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state); + public List 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 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 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 +88,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 +108,25 @@ public enum AllBeltAttachments { public void findAttachments(BeltTileEntity belt) { for (AllBeltAttachments ba : AllBeltAttachments.values()) { - List attachmentPositions = ba.attachment.getPotentialAttachmentLocations(belt); World world = belt.getWorld(); + BlockPos beltPos = belt.getPos(); + BlockState beltState = belt.getBlockState(); + List 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 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); } } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java index e703e64bd..cdc1cec3c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java @@ -9,6 +9,7 @@ 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.BeltInventory.TransportedItemStack; import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo; import net.minecraft.block.Block; @@ -38,7 +39,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraftforge.common.Tags; import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.IItemHandler; public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockItem, IWithTileEntity { @@ -99,10 +100,14 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt if (entityIn instanceof ItemEntity && entityIn.isAlive()) { if (worldIn.isRemote) return; + if (entityIn.getMotion().y > 0) + return; withTileEntityDo(worldIn, pos, te -> { ItemEntity itemEntity = (ItemEntity) entityIn; - ItemStack remainder = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - .orElseGet(() -> new ItemStackHandler(0)).insertItem(0, itemEntity.getItem().copy(), false); + 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(); }); @@ -133,19 +138,42 @@ 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 isDye = Tags.Items.DYES.contains(heldItem.getItem()); + + if (isShaft) { + TileEntity te = worldIn.getTileEntity(pos); + if (te == null || !(te instanceof BeltTileEntity)) + return false; + BeltTileEntity belt = (BeltTileEntity) te; + if (belt.hasPulley()) + return false; + if (worldIn.isRemote) + return true; + if (!player.isCreative()) + heldItem.shrink(1); + belt.hasPulley = true; + belt.markDirty(); + belt.sendData(); + belt.attachKinetics(); 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; + } + + 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; + } + + return false; } @Override @@ -177,8 +205,15 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt @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); } @@ -211,16 +246,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; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java index fb75c4748..f581bf2c3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java @@ -4,9 +4,11 @@ import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Random; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -21,7 +23,10 @@ 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 { @@ -36,7 +41,7 @@ public class BeltInventory { } public void tick() { - + // Reverse item collection if belt just reversed if (beltMovementPositive != movingPositive()) { beltMovementPositive = movingPositive(); @@ -49,12 +54,15 @@ public class BeltInventory { TransportedItemStack stackInFront = null; TransportedItemStack current = null; Iterator iterator = items.iterator(); - float beltSpeed = belt.getBeltMovementSpeed(); + + float beltSpeed = belt.getDirectionAwareBeltMovementSpeed(); float spacing = 1; - while (iterator.hasNext()) { + Items: while (iterator.hasNext()) { stackInFront = current; current = iterator.next(); + current.prevBeltPosition = current.beltPosition; + current.prevSideOffset = current.sideOffset; if (current.stack.isEmpty()) { iterator.remove(); @@ -64,6 +72,11 @@ public class BeltInventory { 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) { @@ -74,18 +87,60 @@ public class BeltInventory { : Math.max(movement, diff + spacing); } - float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos; - float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd) - : Math.max(movement, diffToEnd); - + // 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; - current.beltPosition += limitedMovement; + // 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 <= current.beltPosition + limitedMovement + : segment >= 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) - current.beltPosition; + 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); @@ -113,12 +168,38 @@ public class BeltInventory { 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 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; } @@ -135,25 +216,12 @@ public class BeltInventory { continue; // Inserting into other belt - BlockPos controller = nextBelt.getController(); - if (!world.isBlockPresent(controller)) - continue; - te = world.getTileEntity(controller); - if (te == null || !(te instanceof BeltTileEntity)) - continue; - BeltTileEntity nextBeltController = (BeltTileEntity) te; - BeltInventory nextInventory = nextBeltController.getInventory(); + if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) { + iterator.remove(); + current = null; + belt.sendData(); + } - if (!nextInventory.canInsertAt(nextBelt.index)) - continue; - - current.beltPosition = nextBelt.index + .5f; - current.insertedAt = nextBelt.index; - nextInventory.insert(current); - iterator.remove(); - current = null; - belt.sendData(); - nextBeltController.sendData(); } } @@ -164,10 +232,23 @@ public class BeltInventory { 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 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 @@ -179,22 +260,36 @@ public class BeltInventory { 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; } } 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); @@ -211,7 +306,8 @@ public class BeltInventory { // Items on the belt get prioritized if the previous item was inserted on the // same segment - if (stack.insertedAt == segment && currentPos <= segment + 1) + if (stack.insertedAt == segment && stack.insertedFrom == side + && (beltMovementPositive ? currentPos <= segment + 1.5 : currentPos - 1.5 >= segment)) return false; } @@ -219,20 +315,23 @@ public class BeltInventory { } protected void insert(TransportedItemStack newStack) { - int index = 0; if (items.isEmpty()) items.add(newStack); - for (TransportedItemStack stack : items) { - if (stack.compareTo(newStack) > 0 == beltMovementPositive) - break; - index++; + else { + int index = 0; + for (TransportedItemStack stack : items) { + if (stack.compareTo(newStack) > 0 == beltMovementPositive) + break; + index++; + } + items.add(index, newStack); } - items.add(index, newStack); + belt.markDirty(); belt.sendData(); } - protected TransportedItemStack getStackAtOffset(int offset) { + public TransportedItemStack getStackAtOffset(int offset) { float min = offset + .5f - (SEGMENT_WINDOW / 2); float max = offset + .5f + (SEGMENT_WINDOW / 2); for (TransportedItemStack stack : items) { @@ -260,28 +359,40 @@ public class BeltInventory { return nbt; } - private void eject(TransportedItemStack stack) { + public void eject(TransportedItemStack stack) { ItemStack ejected = stack.stack; Vec3d outPos = getVectorForOffset(stack.beltPosition); - ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y, outPos.z, ejected); - entity.setMotion(new Vec3d(belt.getBeltChainDirection()).scale(Math.abs(belt.getBeltMovementSpeed()))); + Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(Math.abs(belt.getBeltMovementSpeed())).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); } private Vec3d getVectorForOffset(float offset) { Vec3d vec = VecHelper.getCenterOf(belt.getPos()); - vec.add(new Vec3d(belt.getBeltChainDirection()).scale(offset)); + vec = vec.add(new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f)); 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.getBeltChainDirection(); + Vec3i vec = belt.getBeltFacing().getDirectionVec(); return pos.add(offset * vec.getX(), offset * vec.getY(), offset * vec.getZ()); } private boolean movingPositive() { - return belt.getBeltMovementSpeed() > 0; + return belt.getDirectionAwareBeltMovementSpeed() > 0; } public class ItemHandlerSegment implements IItemHandler { @@ -311,6 +422,7 @@ public class BeltInventory { TransportedItemStack newStack = new TransportedItemStack(stack); newStack.insertedAt = offset; newStack.beltPosition = offset + .5f; + newStack.prevBeltPosition = newStack.beltPosition; insert(newStack); } return ItemStack.EMPTY; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java index 2b994a15a..f62d7ab5a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltMovementHandler.java @@ -93,7 +93,7 @@ public class BeltMovementHandler { // Attachment pauses movement for (BeltAttachmentState state : belt.attachmentTracker.attachments) { - if (state.attachment.handleEntity(belt, entityIn, state)) { + if (state.attachment.processEntity(belt, entityIn, state)) { info.ticksSinceLastCollision--; return; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index a9bbac170..6fb016fb8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -20,11 +20,13 @@ import com.simibubi.create.modules.contraptions.base.KineticTileEntity; 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.BeltInventory.TransportedItemStack; import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.item.DyeColor; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.state.properties.BlockStateProperties; @@ -197,6 +199,13 @@ public class BeltTileEntity extends KineticTileEntity { 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; @@ -270,4 +279,44 @@ public class BeltTileEntity extends KineticTileEntity { 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) { + BlockPos controller = getController(); + if (!world.isBlockPresent(controller)) + return false; + TileEntity te = world.getTileEntity(controller); + if (te == null || !(te instanceof BeltTileEntity)) + return false; + BeltTileEntity nextBeltController = (BeltTileEntity) te; + 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.sendData(); + return true; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java index ed5dc140d..dc318bd70 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java @@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.relays.belt; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllBlocks; +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; @@ -12,6 +13,8 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.Transp import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.BufferBuilder; +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; @@ -19,6 +22,7 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.state.properties.BlockStateProperties; 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; @@ -28,27 +32,66 @@ public class BeltTileEntityRenderer extends TileEntityRenderer { @Override public void render(BeltTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) { super.render(te, x, y, z, partialTicks, destroyStage); - if (te.isController()) { - GlStateManager.pushMatrix(); - GlStateManager.translated(x + .5, y + 13 / 16f + .25, z + .5); - - for (TransportedItemStack transported : te.getInventory().items) { - GlStateManager.pushMatrix(); - Vec3i direction = te.getBeltChainDirection(); - float offset = transported.beltPosition; - Vec3d offsetVec = new Vec3d(direction).scale(offset); - GlStateManager.translated(offsetVec.x, offsetVec.y, offsetVec.z); - Minecraft.getInstance().getItemRenderer().renderItem(transported.stack, TransformType.FIXED); - GlStateManager.popMatrix(); - } - - GlStateManager.popMatrix(); - } TessellatorHelper.prepareFastRender(); TessellatorHelper.begin(DefaultVertexFormats.BLOCK); renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, Tessellator.getInstance().getBuffer()); TessellatorHelper.draw(); + + if (te.isController()) { + GlStateManager.pushMatrix(); + + 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); + + 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); + Vec3d offsetVec = new Vec3d(directionVec).scale(offset); + 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; + 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); + } + + GlStateManager.scaled(.5, .5, .5); + itemRenderer.renderItem(transported.stack, TransformType.FIXED); + GlStateManager.popMatrix(); + GlStateManager.rotated(10, 0, 1, 0); + GlStateManager.translated(0, 1/16d, 0); + } + + RenderHelper.disableStandardItemLighting(); + GlStateManager.popMatrix(); + } + + GlStateManager.popMatrix(); + } } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/FastItemRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/FastItemRenderer.java deleted file mode 100644 index 9a594a7fb..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/FastItemRenderer.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.simibubi.create.modules.contraptions.relays.belt; - -import java.nio.ByteBuffer; -import java.util.Random; -import java.util.concurrent.TimeUnit; - -import org.lwjgl.opengl.GL11; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.simibubi.create.foundation.utility.BufferManipulator; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.ItemRenderer; -import net.minecraft.client.renderer.model.IBakedModel; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.item.Item; -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; -import net.minecraft.world.World; -import net.minecraftforge.client.model.data.EmptyModelData; - -public class FastItemRenderer extends BufferManipulator { - - public FastItemRenderer(ByteBuffer original) { - super(original); - } - - public ByteBuffer getTranslatedAndRotated(World world, float x, float y, float z, float yaw, float pitch) { - original.rewind(); - mutable.rewind(); - - float cosYaw = MathHelper.cos(yaw); - float sinYaw = MathHelper.sin(yaw); - float cosPitch = MathHelper.cos(pitch); - float sinPitch = MathHelper.sin(pitch); - - for (int vertex = 0; vertex < vertexCount(original); vertex++) { - float xL = getX(original, vertex); // - (float) rotationOffset.x; - float yL = getY(original, vertex); // - (float) rotationOffset.y; - float zL = getZ(original, vertex); // - (float) rotationOffset.z; - - float xL2 = rotateX(xL, yL, zL, sinPitch, cosPitch, Axis.X); - float yL2 = rotateY(xL, yL, zL, sinPitch, cosPitch, Axis.X); - float zL2 = rotateZ(xL, yL, zL, sinPitch, cosPitch, Axis.X); - // - xL = rotateX(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y); - yL = rotateY(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y); - zL = rotateZ(xL2, yL2, zL2, sinYaw, cosYaw, Axis.Y); - - float xPos = xL + x; // + (float) (offset.x + rotationOffset.x); - float yPos = yL + y; // + (float) (offset.y + rotationOffset.y); - float zPos = zL + z; // + (float) (offset.z + rotationOffset.z); - putPos(mutable, vertex, xPos, yPos, zPos); - BlockPos pos = new BlockPos(xPos + .5f, yPos + .5f, zPos + .5f); - putLight(mutable, vertex, world.getCombinedLight(pos, 15)); - } - - return mutable; - } - - protected static Cache cachedItems; - - public static void renderItem(BufferBuilder buffer, World world, ItemStack stack, float x, float y, float z, - float yaw, float pitch) { - if (stack.isEmpty()) - return; - - ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); - IBakedModel model = itemRenderer.getModelWithOverrides(stack); - - if (model.isBuiltInRenderer()) { - renderItemIntoBuffer(stack, itemRenderer, model, 0, buffer); - return; - } - - cacheIfMissing(stack); - FastItemRenderer renderer = cachedItems.getIfPresent(stack.getItem()); - if (renderer == null) - return; - buffer.putBulkData(renderer.getTranslatedAndRotated(world, x, y +1, z, yaw, pitch)); - } - - protected static void cacheIfMissing(ItemStack stack) { - if (cachedItems == null) - cachedItems = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.SECONDS).build(); - if (cachedItems.getIfPresent(stack.getItem()) != null) - return; - - ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); - IBakedModel model = itemRenderer.getModelWithOverrides(stack); - - int color = 0; - BufferBuilder bufferbuilder = new BufferBuilder(0); - bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); - renderItemIntoBuffer(stack, itemRenderer, model, color, bufferbuilder); - bufferbuilder.finishDrawing(); - cachedItems.put(stack.getItem(), new FastItemRenderer(bufferbuilder.getByteBuffer())); - } - - protected static void renderItemIntoBuffer(ItemStack stack, ItemRenderer itemRenderer, IBakedModel model, int color, - BufferBuilder bufferbuilder) { - Random random = new Random(42L); - for (Direction direction : Direction.values()) - itemRenderer.renderQuads(bufferbuilder, model.getQuads(null, direction, random, EmptyModelData.INSTANCE), - color, stack); - itemRenderer.renderQuads(bufferbuilder, model.getQuads(null, null, random, EmptyModelData.INSTANCE), color, - stack); - } - - public static void invalidateCache() { - if (cachedItems != null) - cachedItems.invalidateAll(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java index e0dd32aae..fa8a01087 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java @@ -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; @@ -126,6 +130,8 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { IItemHandler inv = getInventory().orElse(null); ItemStack extracting = ItemStack.EMPTY; ItemStack filterItem = (this instanceof IHaveFilter) ? ((IHaveFilter) this).getFilter() : ItemStack.EMPTY; + World world = getWorld(); + BlockPos pos = getPos(); int extractionCount = filterItem.isEmpty() ? CreateConfig.parameters.extractorAmount.get() : filterItem.getCount(); boolean checkHasEnoughItems = !filterItem.isEmpty(); @@ -171,18 +177,26 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { break Extraction; } while (true); + if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) { + TileEntity te = world.getTileEntity(pos.down()); + if (te != null && te instanceof BeltTileEntity && !extracting.isEmpty()) { + if (((BeltTileEntity) te).tryInsertingFromSide(Direction.UP, extracting.copy(), simulate)) + return extracting; + return ItemStack.EMPTY; + } + } + 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); } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelBlock.java index 6f3add356..42e28ec4d 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelBlock.java @@ -2,31 +2,24 @@ package com.simibubi.create.modules.logistics.block.belts; import java.util.Arrays; import java.util.List; -import java.util.Optional; -import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.block.IWithTileEntity; -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.BeltInventory.TransportedItemStack; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; 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.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.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; @@ -49,7 +42,7 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, public boolean hasTileEntity(BlockState state) { return true; } - + @Override public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { @@ -79,7 +72,7 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, BlockState neighbour = worldIn.getBlockState(neighbourPos); return !neighbour.getShape(worldIn, pos).isEmpty(); } - + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState state = getDefaultState(); @@ -138,33 +131,32 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, } @Override - public List getPotentialAttachmentLocations(BeltTileEntity te) { - return Arrays.asList(te.getPos().up()); + public List getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) { + return Arrays.asList(pos.up()); } @Override - public Optional 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) { + 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; } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelTileEntity.java index dfbf5e4e6..48dede4ac 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltFunnelTileEntity.java @@ -2,11 +2,10 @@ 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.BeltInventory.ItemHandlerSegment; 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,6 +15,7 @@ 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; @@ -27,6 +27,8 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT protected boolean waitingForInventorySpace; private boolean initialize; + private ItemStack justEaten; + public BeltFunnelTileEntity() { super(AllTileEntities.BELT_FUNNEL.type); inventory = LazyOptional.empty(); @@ -38,22 +40,33 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT super.read(compound); } + @Override + public CompoundNBT write(CompoundNBT compound) { + 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 +85,10 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT neighborChanged(); initialize = false; } + if (world.isRemote && justEaten != null) { + spawnParticles(justEaten); + justEaten = null; + } } @Override @@ -87,42 +104,34 @@ 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 ItemHandlerSegment)) + return stack; IItemHandler inv = inventory.orElse(null); - stack = ItemHandlerHelper.insertItemStacked(inv, stack, false); - - if (stack.isEmpty()) { - if (!world.isRemote) { - entity.remove(); + ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, stack.copy(), 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; + } else { + waitingForInventorySpace = true; } - 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); } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/EntityDetectorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/EntityDetectorBlock.java index 601e206b6..e24eff5d6 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/EntityDetectorBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/EntityDetectorBlock.java @@ -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; @@ -129,16 +128,20 @@ public class EntityDetectorBlock extends HorizontalBlock } @Override - public List 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 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 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 +181,11 @@ public class EntityDetectorBlock extends HorizontalBlock } @Override - public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) { + 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; diff --git a/src/main/resources/assets/create/models/block/belt_funnel.json b/src/main/resources/assets/create/models/block/belt_funnel.json index 8ba5f3c81..e60aba5c4 100644 --- a/src/main/resources/assets/create/models/block/belt_funnel.json +++ b/src/main/resources/assets/create/models/block/belt_funnel.json @@ -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] + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/extractor.json b/src/main/resources/assets/create/models/block/extractor.json index bf006e499..6ef918d7b 100644 --- a/src/main/resources/assets/create/models/block/extractor.json +++ b/src/main/resources/assets/create/models/block/extractor.json @@ -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] + } + } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/extractor_wireless.json b/src/main/resources/assets/create/models/block/extractor_wireless.json index 0e7a78d33..df565ee16 100644 --- a/src/main/resources/assets/create/models/block/extractor_wireless.json +++ b/src/main/resources/assets/create/models/block/extractor_wireless.json @@ -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"} + } + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/extractor.json b/src/main/resources/assets/create/models/item/extractor.json index 0a39d9155..948131ef6 100644 --- a/src/main/resources/assets/create/models/item/extractor.json +++ b/src/main/resources/assets/create/models/item/extractor.json @@ -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" } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/linked_extractor.json b/src/main/resources/assets/create/models/item/linked_extractor.json index 7ad05603f..195ee3078 100644 --- a/src/main/resources/assets/create/models/item/linked_extractor.json +++ b/src/main/resources/assets/create/models/item/linked_extractor.json @@ -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" } \ No newline at end of file