mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-25 06:27:41 +01:00
Synchronized Flaps
- Belt tunnels can now act as backup-friendly belt mergers - Funnels can now pick up items touching them when not in belt mode - Fixed taking items from belts with right-click - Fixed crash when placing redstone links
This commit is contained in:
parent
7059cf2737
commit
e1a1ce46db
17 changed files with 287 additions and 160 deletions
|
@ -175,6 +175,7 @@ public enum AllBlocks {
|
||||||
VERTICAL_FUNNEL(new FunnelBlock.Vertical()),
|
VERTICAL_FUNNEL(new FunnelBlock.Vertical()),
|
||||||
BELT_TUNNEL(new BeltTunnelBlock()),
|
BELT_TUNNEL(new BeltTunnelBlock()),
|
||||||
BELT_TUNNEL_FLAP(new RenderUtilityBlock()),
|
BELT_TUNNEL_FLAP(new RenderUtilityBlock()),
|
||||||
|
BELT_TUNNEL_INDICATOR(new RenderUtilityBlock()),
|
||||||
ENTITY_DETECTOR(new BeltObserverBlock()),
|
ENTITY_DETECTOR(new BeltObserverBlock()),
|
||||||
PULSE_REPEATER(new PulseRepeaterBlock()),
|
PULSE_REPEATER(new PulseRepeaterBlock()),
|
||||||
FLEXPEATER(new FlexpeaterBlock()),
|
FLEXPEATER(new FlexpeaterBlock()),
|
||||||
|
|
|
@ -42,9 +42,9 @@ import net.minecraftforge.registries.IForgeRegistry;
|
||||||
public enum AllItems {
|
public enum AllItems {
|
||||||
|
|
||||||
__MATERIALS__(),
|
__MATERIALS__(),
|
||||||
|
ANDESITE_ALLOY_CUBE(ingredient()),
|
||||||
COPPER_INGOT(ingredient()),
|
COPPER_INGOT(ingredient()),
|
||||||
ZINC_CUBE(ingredient()),
|
ZINC_CUBE(ingredient()),
|
||||||
ANDESITE_ALLOY_CUBE(ingredient()),
|
|
||||||
BRASS_CUBE(ingredient()),
|
BRASS_CUBE(ingredient()),
|
||||||
COPPER_NUGGET(ingredient()),
|
COPPER_NUGGET(ingredient()),
|
||||||
ZINC_NUGGET(ingredient()),
|
ZINC_NUGGET(ingredient()),
|
||||||
|
|
|
@ -255,7 +255,7 @@ public class AirCurrent {
|
||||||
continue;
|
continue;
|
||||||
World world = belt.getWorld();
|
World world = belt.getWorld();
|
||||||
|
|
||||||
controller.getInventory().forEachWithin(belt.index + .5f, .5f, (transported) -> {
|
controller.getInventory().forEachWithin(belt.index + .5f, .51f, (transported) -> {
|
||||||
InWorldProcessing.spawnParticlesForProcessing(world,
|
InWorldProcessing.spawnParticlesForProcessing(world,
|
||||||
controller.getInventory().getVectorForOffset(transported.beltPosition), processingType);
|
controller.getInventory().getVectorForOffset(transported.beltPosition), processingType);
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
|
|
|
@ -192,7 +192,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IHaveNoBlockIte
|
||||||
return false;
|
return false;
|
||||||
if (worldIn.isRemote)
|
if (worldIn.isRemote)
|
||||||
return true;
|
return true;
|
||||||
controllerBelt.getInventory().forEachWithin(belt.index, .75f, (transportedItemStack) -> {
|
controllerBelt.getInventory().forEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
|
||||||
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
});
|
});
|
||||||
|
|
|
@ -103,6 +103,7 @@ public class BeltInventory {
|
||||||
float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd)
|
float limitedMovement = beltMovementPositive ? Math.min(movement, diffToEnd)
|
||||||
: Math.max(movement, diffToEnd);
|
: Math.max(movement, diffToEnd);
|
||||||
|
|
||||||
|
float nextOffset = current.beltPosition + limitedMovement;
|
||||||
if (!onClient) {
|
if (!onClient) {
|
||||||
// Don't move if belt attachments want to continue processing
|
// Don't move if belt attachments want to continue processing
|
||||||
if (segmentBefore != -1 && current.locked) {
|
if (segmentBefore != -1 && current.locked) {
|
||||||
|
@ -122,10 +123,8 @@ public class BeltInventory {
|
||||||
|
|
||||||
// See if any new belt processing catches the item
|
// See if any new belt processing catches the item
|
||||||
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||||
for (int segment = upcomingSegment; beltMovementPositive
|
for (int segment = upcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||||
? segment + .5f <= current.beltPosition + limitedMovement
|
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
|
||||||
: segment + .5f >= current.beltPosition + limitedMovement; segment += beltMovementPositive ? 1
|
|
||||||
: -1) {
|
|
||||||
BeltTileEntity beltSegment = getBeltSegment(segmentBefore);
|
BeltTileEntity beltSegment = getBeltSegment(segmentBefore);
|
||||||
if (beltSegment == null)
|
if (beltSegment == null)
|
||||||
break;
|
break;
|
||||||
|
@ -140,11 +139,16 @@ public class BeltInventory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client: Belt tunnel flaps
|
// Belt tunnels
|
||||||
if (onClient) {
|
{
|
||||||
int seg1 = (int) current.beltPosition;
|
int seg1 = (int) current.beltPosition;
|
||||||
int seg2 = (int) (current.beltPosition + limitedMovement);
|
int seg2 = (int) nextOffset;
|
||||||
|
if (!beltMovementPositive && nextOffset == 0)
|
||||||
|
seg2 = -1;
|
||||||
if (seg1 != seg2) {
|
if (seg1 != seg2) {
|
||||||
|
if (stuckAtTunnel(seg2, current.stack, belt.getMovementFacing())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
flapTunnel(seg1, belt.getMovementFacing(), false);
|
flapTunnel(seg1, belt.getMovementFacing(), false);
|
||||||
flapTunnel(seg2, belt.getMovementFacing().getOpposite(), true);
|
flapTunnel(seg2, belt.getMovementFacing().getOpposite(), true);
|
||||||
}
|
}
|
||||||
|
@ -247,6 +251,44 @@ public class BeltInventory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean stuckAtTunnel(int offset, ItemStack stack, Direction movementDirection) {
|
||||||
|
BlockPos pos = getPositionForOffset(offset).up();
|
||||||
|
if (!AllBlocks.BELT_TUNNEL.typeOf(belt.getWorld().getBlockState(pos)))
|
||||||
|
return false;
|
||||||
|
TileEntity te = belt.getWorld().getTileEntity(pos);
|
||||||
|
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Direction flapFacing = movementDirection;
|
||||||
|
if (flapFacing.getAxis() == Axis.X)
|
||||||
|
flapFacing = flapFacing.getOpposite();
|
||||||
|
|
||||||
|
BeltTunnelTileEntity tunnel = (BeltTunnelTileEntity) te;
|
||||||
|
if (!tunnel.flaps.containsKey(flapFacing))
|
||||||
|
return false;
|
||||||
|
if (!tunnel.syncedFlaps.containsKey(flapFacing))
|
||||||
|
return false;
|
||||||
|
ItemStack heldItem = tunnel.syncedFlaps.get(flapFacing);
|
||||||
|
if (heldItem == null) {
|
||||||
|
tunnel.syncedFlaps.put(flapFacing, ItemStack.EMPTY);
|
||||||
|
belt.sendData();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (heldItem == ItemStack.EMPTY) {
|
||||||
|
tunnel.syncedFlaps.put(flapFacing, stack);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BeltTunnelTileEntity> group = BeltTunnelBlock.getSynchronizedGroup(belt.getWorld(), pos, flapFacing);
|
||||||
|
for (BeltTunnelTileEntity otherTunnel : group)
|
||||||
|
if (otherTunnel.syncedFlaps.get(flapFacing) == ItemStack.EMPTY)
|
||||||
|
return true;
|
||||||
|
for (BeltTunnelTileEntity otherTunnel : group)
|
||||||
|
otherTunnel.syncedFlaps.put(flapFacing, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void flapTunnel(int offset, Direction side, boolean inward) {
|
private void flapTunnel(int offset, Direction side, boolean inward) {
|
||||||
if (belt.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
|
if (belt.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -159,6 +159,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
|
super.read(compound);
|
||||||
trackerUpdateTag = compound;
|
trackerUpdateTag = compound;
|
||||||
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
controller = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||||
color = compound.getInt("Color");
|
color = compound.getInt("Color");
|
||||||
|
@ -167,7 +168,6 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
if (isController())
|
if (isController())
|
||||||
getInventory().read(compound.getCompound("Inventory"));
|
getInventory().read(compound.getCompound("Inventory"));
|
||||||
super.read(compound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyColor(DyeColor colorIn) {
|
public void applyColor(DyeColor colorIn) {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
package com.simibubi.create.modules.contraptions.relays.belt;
|
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
@ -119,8 +123,35 @@ public class BeltTunnelBlock extends Block implements IWithTileEntity<BeltTunnel
|
||||||
public static void updateTunnel(World world, BlockPos pos) {
|
public static void updateTunnel(World world, BlockPos pos) {
|
||||||
BlockState tunnel = world.getBlockState(pos);
|
BlockState tunnel = world.getBlockState(pos);
|
||||||
BlockState newTunnel = getTunnelState(world, pos);
|
BlockState newTunnel = getTunnelState(world, pos);
|
||||||
if (tunnel != newTunnel)
|
if (tunnel != newTunnel) {
|
||||||
world.setBlockState(pos, newTunnel, 3);
|
world.setBlockState(pos, newTunnel, 3);
|
||||||
|
TileEntity te = world.getTileEntity(pos);
|
||||||
|
if (te != null && (te instanceof BeltTunnelTileEntity))
|
||||||
|
((BeltTunnelTileEntity) te).initFlaps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BeltTunnelTileEntity> getSynchronizedGroup(World world, BlockPos pos, Direction flapFacing) {
|
||||||
|
List<BeltTunnelTileEntity> group = new ArrayList<>();
|
||||||
|
Direction searchDirection = flapFacing.rotateY();
|
||||||
|
|
||||||
|
for (Direction d : Arrays.asList(searchDirection, searchDirection.getOpposite())) {
|
||||||
|
BlockPos currentPos = pos;
|
||||||
|
while (true) {
|
||||||
|
if (!world.isBlockPresent(currentPos))
|
||||||
|
break;
|
||||||
|
TileEntity te = world.getTileEntity(currentPos);
|
||||||
|
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
||||||
|
break;
|
||||||
|
BeltTunnelTileEntity tunnel = (BeltTunnelTileEntity) te;
|
||||||
|
if (!tunnel.syncedFlaps.containsKey(flapFacing))
|
||||||
|
break;
|
||||||
|
group.add(tunnel);
|
||||||
|
currentPos = currentPos.offset(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockState getTunnelState(IBlockReader reader, BlockPos pos) {
|
private static BlockState getTunnelState(IBlockReader reader, BlockPos pos) {
|
||||||
|
@ -159,6 +190,12 @@ public class BeltTunnelBlock extends Block implements IWithTileEntity<BeltTunnel
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||||
|
|
||||||
|
// Toggle sync
|
||||||
|
if (toggleSync(context.getWorld(), context.getPos(), context.getFace()))
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
|
||||||
|
// Toggle windows
|
||||||
if (!hasWindow(state))
|
if (!hasWindow(state))
|
||||||
return IWrenchable.super.onWrenched(state, context);
|
return IWrenchable.super.onWrenched(state, context);
|
||||||
Shape next = state.get(SHAPE);
|
Shape next = state.get(SHAPE);
|
||||||
|
@ -180,6 +217,14 @@ public class BeltTunnelBlock extends Block implements IWithTileEntity<BeltTunnel
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean toggleSync(World world, BlockPos pos, Direction face) {
|
||||||
|
TileEntity te = world.getTileEntity(pos);
|
||||||
|
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
||||||
|
return false;
|
||||||
|
BeltTunnelTileEntity tunnel = (BeltTunnelTileEntity) te;
|
||||||
|
return tunnel.toggleSyncForFlap(face);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||||
boolean isMoving) {
|
boolean isMoving) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelBlock.Shape;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelBlock.Shape;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
@ -24,6 +25,7 @@ import net.minecraftforge.items.IItemHandler;
|
||||||
public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
public HashMap<Direction, InterpolatedChasingValue> flaps;
|
public HashMap<Direction, InterpolatedChasingValue> flaps;
|
||||||
|
public HashMap<Direction, ItemStack> syncedFlaps;
|
||||||
private LazyOptional<IItemHandler> cap = LazyOptional.empty();
|
private LazyOptional<IItemHandler> cap = LazyOptional.empty();
|
||||||
private boolean initialize;
|
private boolean initialize;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
|
||||||
public BeltTunnelTileEntity() {
|
public BeltTunnelTileEntity() {
|
||||||
super(AllTileEntities.BELT_TUNNEL.type);
|
super(AllTileEntities.BELT_TUNNEL.type);
|
||||||
flaps = new HashMap<>();
|
flaps = new HashMap<>();
|
||||||
|
syncedFlaps = new HashMap<>();
|
||||||
initialize = true;
|
initialize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +65,41 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
|
||||||
cap.invalidate();
|
cap.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
|
CompoundNBT dyedFlapsNBT = new CompoundNBT();
|
||||||
|
syncedFlaps.forEach((direction, pair) -> {
|
||||||
|
dyedFlapsNBT.putBoolean(direction.name(), true);
|
||||||
|
});
|
||||||
|
compound.put("syncedFlaps", dyedFlapsNBT);
|
||||||
|
return super.write(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT compound) {
|
||||||
|
if (compound.contains("syncedFlaps")) {
|
||||||
|
syncedFlaps.clear();
|
||||||
|
CompoundNBT dyedFlapsNBT = compound.getCompound("syncedFlaps");
|
||||||
|
for (Direction direction : Direction.values()) {
|
||||||
|
if (dyedFlapsNBT.contains(direction.name()))
|
||||||
|
syncedFlaps.put(direction, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.read(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean toggleSyncForFlap(Direction face) {
|
||||||
|
if (!flaps.containsKey(face))
|
||||||
|
return false;
|
||||||
|
if (syncedFlaps.containsKey(face))
|
||||||
|
syncedFlaps.remove(face);
|
||||||
|
else
|
||||||
|
syncedFlaps.put(face, ItemStack.EMPTY);
|
||||||
|
markDirty();
|
||||||
|
sendData();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT writeToClient(CompoundNBT tag) {
|
public CompoundNBT writeToClient(CompoundNBT tag) {
|
||||||
CompoundNBT writeToClient = super.writeToClient(tag);
|
CompoundNBT writeToClient = super.writeToClient(tag);
|
||||||
|
@ -86,7 +124,6 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
|
||||||
public void initFlaps() {
|
public void initFlaps() {
|
||||||
if (!world.isRemote) {
|
if (!world.isRemote) {
|
||||||
sendData();
|
sendData();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize = false;
|
initialize = false;
|
||||||
|
@ -126,10 +163,10 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (!world.isRemote)
|
|
||||||
return;
|
|
||||||
if (initialize)
|
if (initialize)
|
||||||
initFlaps();
|
initFlaps();
|
||||||
|
if (!world.isRemote)
|
||||||
|
return;
|
||||||
flaps.forEach((d, value) -> value.tick());
|
flaps.forEach((d, value) -> value.tick());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.relays.belt;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -19,7 +20,9 @@ public class BeltTunnelTileEntityRenderer extends TileEntityRendererFast<BeltTun
|
||||||
public void renderTileEntityFast(BeltTunnelTileEntity te, double x, double y, double z, float partialTicks,
|
public void renderTileEntityFast(BeltTunnelTileEntity te, double x, double y, double z, float partialTicks,
|
||||||
int destroyStage, BufferBuilder buffer) {
|
int destroyStage, BufferBuilder buffer) {
|
||||||
BlockState flapState = AllBlocks.BELT_TUNNEL_FLAP.get().getDefaultState();
|
BlockState flapState = AllBlocks.BELT_TUNNEL_FLAP.get().getDefaultState();
|
||||||
|
BlockState indicatorState = AllBlocks.BELT_TUNNEL_INDICATOR.get().getDefaultState();
|
||||||
SuperByteBuffer flapBuffer = CreateClient.bufferCache.renderGenericBlockModel(flapState);
|
SuperByteBuffer flapBuffer = CreateClient.bufferCache.renderGenericBlockModel(flapState);
|
||||||
|
SuperByteBuffer indicatorBuffer = CreateClient.bufferCache.renderGenericBlockModel(indicatorState);
|
||||||
BlockPos pos = te.getPos();
|
BlockPos pos = te.getPos();
|
||||||
World world = getWorld();
|
World world = getWorld();
|
||||||
|
|
||||||
|
@ -41,9 +44,18 @@ public class BeltTunnelTileEntityRenderer extends TileEntityRendererFast<BeltTun
|
||||||
f *= -1;
|
f *= -1;
|
||||||
|
|
||||||
float intensity = segment == 3 ? 1.5f : segment + 1;
|
float intensity = segment == 3 ? 1.5f : segment + 1;
|
||||||
float flapAngle = MathHelper.sin((float) ((1 - Math.abs(f)) * Math.PI * intensity)) * 30 * -f;
|
float abs = Math.abs(f);
|
||||||
|
float flapAngle = MathHelper.sin((float) ((1 - abs) * Math.PI * intensity)) * 30 * -f;
|
||||||
flapAngle = (float) (flapAngle / 180 * Math.PI);
|
flapAngle = (float) (flapAngle / 180 * Math.PI);
|
||||||
|
|
||||||
|
if (te.syncedFlaps.containsKey(direction)) {
|
||||||
|
float lightIntensity = abs * abs * abs;
|
||||||
|
int color = ColorHelper.mixColors(0x808080, 0xFFFFFF, lightIntensity);
|
||||||
|
indicatorBuffer.rotateCentered(Axis.Y, (float) ((horizontalAngle + 90) / 180f * Math.PI))
|
||||||
|
.translate(x, y, z).color(color)
|
||||||
|
.light(world.getCombinedLight(pos, (int) (12 * lightIntensity))).renderInto(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
flapBuffer.translate(0, 0, -segment * 3 / 16f);
|
flapBuffer.translate(0, 0, -segment * 3 / 16f);
|
||||||
flapBuffer.translate(flapPivotX, flapPivotY, flapPivotZ).rotate(Axis.Z, flapAngle)
|
flapBuffer.translate(flapPivotX, flapPivotY, flapPivotZ).rotate(Axis.Z, flapAngle)
|
||||||
.translate(-flapPivotX, -flapPivotY, -flapPivotZ);
|
.translate(-flapPivotX, -flapPivotY, -flapPivotZ);
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
package com.simibubi.create.modules.logistics.block;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
|
|
||||||
public interface IInventoryManipulator {
|
|
||||||
|
|
||||||
public default World getWorld() {
|
|
||||||
return ((TileEntity) this).getWorld();
|
|
||||||
}
|
|
||||||
|
|
||||||
public default BlockPos getPos() {
|
|
||||||
return ((TileEntity) this).getPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockPos getInventoryPos();
|
|
||||||
|
|
||||||
public LazyOptional<IItemHandler> getInventory();
|
|
||||||
|
|
||||||
public void setInventory(LazyOptional<IItemHandler> inventory);
|
|
||||||
|
|
||||||
default boolean findNewInventory() {
|
|
||||||
BlockPos invPos = getInventoryPos();
|
|
||||||
World world = getWorld();
|
|
||||||
|
|
||||||
if (!world.isBlockPresent(invPos))
|
|
||||||
return false;
|
|
||||||
BlockState invState = world.getBlockState(invPos);
|
|
||||||
|
|
||||||
if (!invState.hasTileEntity())
|
|
||||||
return false;
|
|
||||||
TileEntity invTE = world.getTileEntity(invPos);
|
|
||||||
if (invTE == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
LazyOptional<IItemHandler> inventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
|
||||||
setInventory(inventory);
|
|
||||||
if (inventory.isPresent()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public default void neighborChanged() {
|
|
||||||
boolean hasInventory = getInventory().isPresent();
|
|
||||||
if (!hasInventory) {
|
|
||||||
findNewInventory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -44,13 +44,13 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehavioursDeferred(List<TileEntityBehaviour> behaviours) {
|
public void addBehavioursDeferred(List<TileEntityBehaviour> behaviours) {
|
||||||
if (slots == null)
|
|
||||||
createSlotPositioning();
|
|
||||||
createLink();
|
createLink();
|
||||||
behaviours.add(link);
|
behaviours.add(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void createLink() {
|
protected void createLink() {
|
||||||
|
if (slots == null)
|
||||||
|
createSlotPositioning();
|
||||||
if (transmitter)
|
if (transmitter)
|
||||||
link = LinkBehaviour.transmitter(this, this::getSignal);
|
link = LinkBehaviour.transmitter(this, this::getSignal);
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package com.simibubi.create.modules.logistics.block.belts;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||||
|
import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour;
|
||||||
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||||
|
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||||
|
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock implements IBeltAttachment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
|
onAttachmentPlaced(worldIn, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
|
onAttachmentRemoved(worldIn, pos, state);
|
||||||
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
|
worldIn.removeTileEntity(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
||||||
|
return pos.offset(getBlockFacing(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
||||||
|
return Arrays.asList(Direction.values()).stream().filter(d -> d != Direction.UP).map(pos::offset)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||||
|
BlockPos pos = state.attachmentPos;
|
||||||
|
World world = te.getWorld();
|
||||||
|
ItemStack stack = transported.stack;
|
||||||
|
|
||||||
|
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||||
|
ExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, ExtractingBehaviour.TYPE);
|
||||||
|
|
||||||
|
if (extracting == null)
|
||||||
|
return false;
|
||||||
|
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getFilter().getCount()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||||
|
BlockPos pos = state.attachmentPos;
|
||||||
|
World world = te.getWorld();
|
||||||
|
ExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, ExtractingBehaviour.TYPE);
|
||||||
|
|
||||||
|
if (extracting == null)
|
||||||
|
return false;
|
||||||
|
extracting.extract();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,10 +10,11 @@ import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.B
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
|
||||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
|
@ -26,7 +27,6 @@ import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.IWorldReader;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class FunnelBlock extends AttachedLogisticalBlock
|
public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
|
@ -56,6 +56,22 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
|
||||||
|
if (worldIn.isRemote)
|
||||||
|
return;
|
||||||
|
if (!(entityIn instanceof ItemEntity))
|
||||||
|
return;
|
||||||
|
ItemEntity itemEntity = (ItemEntity) entityIn;
|
||||||
|
withTileEntityDo(worldIn, pos, te -> {
|
||||||
|
ItemStack remainder = te.tryToInsert(itemEntity.getItem());
|
||||||
|
if (remainder.isEmpty())
|
||||||
|
itemEntity.remove();
|
||||||
|
if (remainder.getCount() < itemEntity.getItem().getCount())
|
||||||
|
itemEntity.setItem(remainder);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BlockState getVerticalDefaultState() {
|
protected BlockState getVerticalDefaultState() {
|
||||||
return AllBlocks.VERTICAL_FUNNEL.getDefault();
|
return AllBlocks.VERTICAL_FUNNEL.getDefault();
|
||||||
|
@ -95,21 +111,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
@Override
|
@Override
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
onAttachmentPlaced(worldIn, pos, state);
|
onAttachmentPlaced(worldIn, pos, state);
|
||||||
updateObservedInventory(state, worldIn, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
|
||||||
if (!neighbor.equals(pos.offset(state.get(HORIZONTAL_FACING))))
|
|
||||||
return;
|
|
||||||
updateObservedInventory(state, world, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateObservedInventory(BlockState state, IWorldReader world, BlockPos pos) {
|
|
||||||
IInventoryManipulator te = (IInventoryManipulator) world.getTileEntity(pos);
|
|
||||||
if (te == null)
|
|
||||||
return;
|
|
||||||
te.neighborChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,10 +7,10 @@ import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
||||||
|
import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour;
|
||||||
|
import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.ItemHandlerBeltSegment;
|
|
||||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
|
||||||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -18,30 +18,22 @@ import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.particles.ItemParticleData;
|
import net.minecraft.particles.ItemParticleData;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvents;
|
import net.minecraft.util.SoundEvents;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.util.math.Vec3i;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
|
||||||
|
|
||||||
public class FunnelTileEntity extends SmartTileEntity implements ITickableTileEntity, IInventoryManipulator {
|
public class FunnelTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
private static FilteringBehaviour.SlotPositioning slots;
|
private static FilteringBehaviour.SlotPositioning slots;
|
||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
|
private InsertingBehaviour inserting;
|
||||||
private LazyOptional<IItemHandler> inventory;
|
|
||||||
protected boolean waitingForInventorySpace;
|
|
||||||
private ItemStack justEaten;
|
private ItemStack justEaten;
|
||||||
|
|
||||||
public FunnelTileEntity() {
|
public FunnelTileEntity() {
|
||||||
super(AllTileEntities.BELT_FUNNEL.type);
|
super(AllTileEntities.BELT_FUNNEL.type);
|
||||||
inventory = LazyOptional.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -50,22 +42,12 @@ public class FunnelTileEntity extends SmartTileEntity implements ITickableTileEn
|
||||||
createSlotPositioning();
|
createSlotPositioning();
|
||||||
filtering = new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots);
|
filtering = new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots);
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
|
inserting = new InsertingBehaviour(this,
|
||||||
|
Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState())));
|
||||||
|
behaviours.add(inserting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filterChanged(ItemStack stack) {
|
public void filterChanged(ItemStack stack) {
|
||||||
neighborChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(CompoundNBT compound) {
|
|
||||||
waitingForInventorySpace = compound.getBoolean("Waiting");
|
|
||||||
super.read(compound);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
|
||||||
compound.putBoolean("Waiting", waitingForInventorySpace);
|
|
||||||
return super.write(compound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -80,67 +62,29 @@ public class FunnelTileEntity extends SmartTileEntity implements ITickableTileEn
|
||||||
@Override
|
@Override
|
||||||
public void readClientUpdate(CompoundNBT tag) {
|
public void readClientUpdate(CompoundNBT tag) {
|
||||||
super.readClientUpdate(tag);
|
super.readClientUpdate(tag);
|
||||||
if (!waitingForInventorySpace)
|
|
||||||
neighborChanged();
|
|
||||||
if (tag.contains("Nom"))
|
if (tag.contains("Nom"))
|
||||||
justEaten = ItemStack.read(tag.getCompound("Nom"));
|
justEaten = ItemStack.read(tag.getCompound("Nom"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getInventoryPos() {
|
|
||||||
return pos.offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LazyOptional<IItemHandler> getInventory() {
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
if (world.isRemote && justEaten != null) {
|
if (world.isRemote && justEaten != null) {
|
||||||
spawnParticles(justEaten);
|
spawnParticles(justEaten);
|
||||||
justEaten = null;
|
justEaten = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initialize() {
|
|
||||||
neighborChanged();
|
|
||||||
super.initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setInventory(LazyOptional<IItemHandler> inventory) {
|
|
||||||
this.inventory = inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void neighborChanged() {
|
|
||||||
IInventoryManipulator.super.neighborChanged();
|
|
||||||
waitingForInventorySpace = false;
|
|
||||||
if (!world.isRemote)
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack tryToInsert(ItemStack stack) {
|
public ItemStack tryToInsert(ItemStack stack) {
|
||||||
if (!inventory.isPresent())
|
|
||||||
return stack;
|
|
||||||
if (waitingForInventorySpace && !(inventory.orElse(null) instanceof ItemHandlerBeltSegment))
|
|
||||||
return stack;
|
|
||||||
if (!filtering.test(stack))
|
if (!filtering.test(stack))
|
||||||
return stack;
|
return stack;
|
||||||
|
|
||||||
IItemHandler inv = inventory.orElse(null);
|
ItemStack remainder = inserting.insert(stack.copy(), false);
|
||||||
ItemStack inserted = stack.copy();
|
|
||||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, inserted, false);
|
|
||||||
waitingForInventorySpace = true;
|
|
||||||
|
|
||||||
if (remainder.isEmpty()) {
|
if (remainder.isEmpty()) {
|
||||||
if (!world.isRemote)
|
if (!world.isRemote)
|
||||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||||
justEaten = stack.copy();
|
justEaten = stack.copy();
|
||||||
waitingForInventorySpace = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendData();
|
sendData();
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "create:block/belt_tunnel/indicator" }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"credit": "Made with Blockbench",
|
||||||
|
"parent": "block/block",
|
||||||
|
"textures": {
|
||||||
|
"0": "create:block/belt_tunnel",
|
||||||
|
"particle": "create:block/belt_tunnel"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [6, 10, 16],
|
||||||
|
"to": [10, 14, 17],
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [4.75, 0, 5.75, 1], "texture": "#0"},
|
||||||
|
"east": {"uv": [5.5, 0, 5.75, 1], "texture": "#0"},
|
||||||
|
"south": {"uv": [4.75, 0, 5.75, 1], "texture": "#0"},
|
||||||
|
"west": {"uv": [4.75, 0, 5, 1], "texture": "#0"},
|
||||||
|
"up": {"uv": [4.75, 0, 5, 1], "rotation": 270, "texture": "#0"},
|
||||||
|
"down": {"uv": [4.75, 0, 5, 1], "rotation": 90, "texture": "#0"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in a new issue