Light and Shadow

- Added config for disabling sand paper tool repairs
- Fixed belts and filtering renderers leaving behind an undesirable GL state
- Fixed pick block not working on vertical extractors/funnels
- Shadow Steel and Refined Radiance are now obtainable
This commit is contained in:
simibubi 2020-01-27 14:57:21 +01:00
parent eff0c170b6
commit 5ecfa7792c
16 changed files with 443 additions and 62 deletions

View file

@ -9,6 +9,8 @@ import com.simibubi.create.modules.contraptions.WrenchItemRenderer;
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItem;
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
import com.simibubi.create.modules.curiosities.RefinedRadianceItem;
import com.simibubi.create.modules.curiosities.ShadowSteelItem;
import com.simibubi.create.modules.curiosities.blockzapper.BlockzapperItem;
import com.simibubi.create.modules.curiosities.blockzapper.BlockzapperItemRenderer;
import com.simibubi.create.modules.curiosities.deforester.DeforesterItem;
@ -67,8 +69,8 @@ public enum AllItems {
ROSE_QUARTZ(ingredient()),
POLISHED_ROSE_QUARTZ(ingredient()),
CHROMATIC_COMPOUND(new ChromaticCompoundCubeItem(standardItemProperties().rarity(Rarity.UNCOMMON))),
SHADOW_STEEL(new Item(standardItemProperties().rarity(Rarity.UNCOMMON))),
REFINED_RADIANCE(new Item(standardItemProperties().rarity(Rarity.UNCOMMON))),
SHADOW_STEEL(new ShadowSteelItem(standardItemProperties().rarity(Rarity.UNCOMMON))),
REFINED_RADIANCE(new RefinedRadianceItem(standardItemProperties().rarity(Rarity.UNCOMMON))),
ELECTRON_TUBE(ingredient()),
INTEGRATED_CIRCUIT(ingredient()),

View file

@ -54,6 +54,10 @@ public class CreateConfig {
// Curiosities
public IntValue maxSymmetryWandRange;
public BooleanValue allowGlassPanesInPartialBlocks;
public IntValue lightSourceCountForRefinedRadiance;
public BooleanValue enableRefinedRadianceRecipe;
public BooleanValue enableShadowSteelRecipe;
public BooleanValue enableSandPaperToolPolishing;
// Contraptions
public IntValue maxBeltLength, crushingDamage, maxMotorSpeed, maxRotationSpeed;
@ -279,6 +283,26 @@ public class CreateConfig {
.comment("", "Allow Glass Panes to be put inside Blocks like Stairs, Slabs, Fences etc.")
.translation(basePath + name).define(name, true);
name = "enableShadowSteelRecipe";
enableShadowSteelRecipe = builder
.comment("", "Allow the standard Shadow Steel recipe.")
.translation(basePath + name).define(name, true);
name = "enableRefinedRadianceRecipe";
enableRefinedRadianceRecipe = builder
.comment("", "Allow the standard Refined Radiance recipes.")
.translation(basePath + name).define(name, true);
name = "lightSourceCountForRefinedRadiance";
lightSourceCountForRefinedRadiance = builder
.comment("", "The amount of Light sources destroyed before Chromatic Compound turns into Refined Radiance.")
.translation(basePath + name).defineInRange(name, 10, 1, Integer.MAX_VALUE);
name = "enableSandPaperToolPolishing";
enableSandPaperToolPolishing = builder
.comment("", "Enable the tool repairing mechanic involving sand paper.")
.translation(basePath + name).define(name, true);
builder.pop();
}

View file

@ -68,7 +68,7 @@ public enum ScreenResources {
// JEI
JEI_SLOT("jei/widgets.png", 18, 18),
JEI_CATALYST_SLOT("jei/widgets.png", 0, 136, 18, 18),
JEI_CATALYST_SLOT("jei/widgets.png", 0, 156, 18, 18),
JEI_ARROW("jei/widgets.png", 19, 10, 42, 10),
JEI_LONG_ARROW("jei/widgets.png", 19, 0, 71, 10),
JEI_DOWN_ARROW("jei/widgets.png", 0, 21, 18, 14),

View file

@ -170,6 +170,7 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
GlStateManager.popMatrix();
}
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
}

View file

@ -1,14 +1,34 @@
package com.simibubi.create.modules.curiosities;
import java.util.Random;
import com.simibubi.create.AllItems;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.foundation.item.IItemWithColorHandler;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.BeaconTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.math.RayTraceContext.BlockMode;
import net.minecraft.util.math.RayTraceContext.FluidMode;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -38,6 +58,142 @@ public class ChromaticCompoundCubeItem extends Item implements IItemWithColorHan
super(properties);
}
@Override
public boolean shouldSyncTag() {
return true;
}
@Override
public double getDurabilityForDisplay(ItemStack stack) {
int light = stack.getOrCreateTag().getInt("CollectingLight");
return 1 - light / (float) CreateConfig.parameters.lightSourceCountForRefinedRadiance.get();
}
@Override
public boolean showDurabilityBar(ItemStack stack) {
int light = stack.getOrCreateTag().getInt("CollectingLight");
return light > 0;
}
@Override
public int getRGBDurabilityForDisplay(ItemStack stack) {
return ColorHelper.mixColors(0x413c69, 0xFFFFFF, (float) (1 - getDurabilityForDisplay(stack)));
}
@Override
public int getItemStackLimit(ItemStack stack) {
return showDurabilityBar(stack) ? 1 : 16;
}
@Override
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
double y = entity.posY;
double yMotion = entity.getMotion().y;
World world = entity.world;
CompoundNBT data = entity.getPersistentData();
CompoundNBT itemData = entity.getItem().getOrCreateTag();
Vec3d positionVec = entity.getPositionVec();
if (world.isRemote) {
int light = itemData.getInt("CollectingLight");
if (random.nextInt(CreateConfig.parameters.lightSourceCountForRefinedRadiance.get() + 20) < light) {
Vec3d start = VecHelper.offsetRandomly(positionVec, random, 3);
Vec3d motion = positionVec.subtract(start).normalize().scale(.2f);
world.addParticle(ParticleTypes.END_ROD, start.x, start.y, start.z, motion.x, motion.y, motion.z);
}
return false;
}
// Convert to Shadow steel if in void
if (y < 0 && y - yMotion < -10 && CreateConfig.parameters.enableShadowSteelRecipe.get()) {
ItemStack newStack = AllItems.SHADOW_STEEL.asStack();
newStack.setCount(stack.getCount());
data.putBoolean("FromVoid", true);
entity.setItem(newStack);
}
if (!CreateConfig.parameters.enableRefinedRadianceRecipe.get())
return false;
// Convert to Refined Radiance if eaten enough light sources
if (itemData.getInt("CollectingLight") >= CreateConfig.parameters.lightSourceCountForRefinedRadiance.get()) {
ItemStack newStack = AllItems.REFINED_RADIANCE.asStack();
ItemEntity newEntity = new ItemEntity(world, entity.posX, entity.posY, entity.posZ, newStack);
newEntity.setMotion(entity.getMotion());
newEntity.getPersistentData().putBoolean("FromLight", true);
itemData.remove("CollectingLight");
world.addEntity(newEntity);
stack.split(1);
entity.setItem(stack);
if (stack.isEmpty())
entity.remove();
return false;
}
// Is inside beacon beam?
boolean isOverBeacon = false;
MutableBlockPos testPos = new MutableBlockPos(entity.getPosition());
while (testPos.getY() > 0) {
testPos.move(Direction.DOWN);
BlockState state = world.getBlockState(testPos);
if (state.getOpacity(world, testPos) >= 15 && state.getBlock() != Blocks.BEDROCK)
break;
if (state.getBlock() == Blocks.BEACON) {
TileEntity te = world.getTileEntity(testPos);
if (!(te instanceof BeaconTileEntity))
break;
BeaconTileEntity bte = (BeaconTileEntity) te;
if (bte.getLevels() != 0)
isOverBeacon = true;
break;
}
}
if (isOverBeacon) {
ItemStack newStack = AllItems.REFINED_RADIANCE.asStack();
newStack.setCount(stack.getCount());
data.putBoolean("FromLight", true);
entity.setItem(newStack);
return false;
}
// Find a light source and eat it.
Random r = world.rand;
int range = 3;
float rate = 1 / 2f;
if (r.nextFloat() > rate)
return false;
BlockPos randomOffset = new BlockPos(VecHelper.offsetRandomly(positionVec, r, range));
BlockState state = world.getBlockState(randomOffset);
if (state.getLightValue(world, randomOffset) == 0)
return false;
if (state.getBlockHardness(world, randomOffset) == -1)
return false;
if (state.getBlock() == Blocks.BEACON)
return false;
RayTraceContext context = new RayTraceContext(positionVec, VecHelper.getCenterOf(randomOffset),
BlockMode.COLLIDER, FluidMode.NONE, entity);
if (!randomOffset.equals(world.rayTraceBlocks(context).getPos()))
return false;
world.destroyBlock(randomOffset, false);
ItemStack newStack = stack.split(1);
newStack.getOrCreateTag().putInt("CollectingLight", itemData.getInt("CollectingLight") + 1);
ItemEntity newEntity = new ItemEntity(world, entity.posX, entity.posY, entity.posZ, newStack);
newEntity.setMotion(entity.getMotion());
newEntity.setDefaultPickupDelay();
world.addEntity(newEntity);
entity.lifespan = 6000;
if (stack.isEmpty())
entity.remove();
return false;
}
@Override
@OnlyIn(value = Dist.CLIENT)
public IItemColor getColorHandler() {

View file

@ -0,0 +1,59 @@
package com.simibubi.create.modules.curiosities;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class RefinedRadianceItem extends Item {
public RefinedRadianceItem(Properties properties) {
super(properties);
}
@Override
public boolean hasEffect(ItemStack stack) {
return true;
}
@Override
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
World world = entity.world;
Vec3d pos = entity.getPositionVec();
if (world.isRemote && entity.hasNoGravity()) {
if (world.rand.nextFloat() < MathHelper.clamp(entity.getItem().getCount() - 10, 1, 100) / 64f) {
Vec3d ppos = VecHelper.offsetRandomly(pos, world.rand, .5f);
world.addParticle(ParticleTypes.END_ROD, ppos.x, pos.y, ppos.z, 0, -.1f, 0);
}
if (!entity.getPersistentData().contains("ClientAnimationPlayed")) {
Vec3d basemotion = new Vec3d(0, 1, 0);
world.addParticle(ParticleTypes.FLASH, pos.x, pos.y, pos.z, 0, 0, 0);
for (int i = 0; i < 20; i++) {
Vec3d motion = VecHelper.offsetRandomly(basemotion, world.rand, 1);
world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
}
entity.getPersistentData().putBoolean("ClientAnimationPlayed", true);
}
return false;
}
if (!entity.getPersistentData().contains("FromLight"))
return false;
entity.lifespan = 6000;
entity.setNoGravity(true);
entity.setMotion(entity.getMotion().add(0, .15f, 0));
entity.getPersistentData().remove("FromLight");
return false;
}
}

View file

@ -0,0 +1,56 @@
package com.simibubi.create.modules.curiosities;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class ShadowSteelItem extends Item {
public ShadowSteelItem(Properties properties) {
super(properties);
}
@Override
public boolean onEntityItemUpdate(ItemStack stack, ItemEntity entity) {
World world = entity.world;
Vec3d pos = entity.getPositionVec();
if (world.isRemote && entity.hasNoGravity()) {
if (world.rand.nextFloat() < MathHelper.clamp(entity.getItem().getCount() - 10,
Math.min(entity.getMotion().y * 20, 20), 100) / 64f) {
Vec3d ppos = VecHelper.offsetRandomly(pos, world.rand, .5f);
world.addParticle(ParticleTypes.END_ROD, ppos.x, pos.y, ppos.z, 0, -.1f, 0);
}
if (!entity.getPersistentData().contains("ClientAnimationPlayed")) {
Vec3d basemotion = new Vec3d(0, 1, 0);
world.addParticle(ParticleTypes.FLASH, pos.x, pos.y, pos.z, 0, 0, 0);
for (int i = 0; i < 20; i++) {
Vec3d motion = VecHelper.offsetRandomly(basemotion, world.rand, 1);
world.addParticle(ParticleTypes.WITCH, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
world.addParticle(ParticleTypes.END_ROD, pos.x, pos.y, pos.z, motion.x, motion.y, motion.z);
}
entity.getPersistentData().putBoolean("ClientAnimationPlayed", true);
}
return false;
}
if (!entity.getPersistentData().contains("FromVoid"))
return false;
entity.setNoGravity(true);
float yMotion = (entity.fallDistance + 3) / 50f;
entity.setMotion(0, yMotion, 0);
entity.lifespan = 6000;
entity.getPersistentData().remove("FromVoid");
return false;
}
}

View file

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import com.simibubi.create.AllRecipes;
import com.simibubi.create.CreateConfig;
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe;
@ -33,14 +34,15 @@ public class SandPaperPolishingRecipe extends ProcessingRecipe<SandPaperInv> {
}
public static boolean canPolish(World world, ItemStack stack) {
return stack.isDamageable() || !getMatchingRecipes(world, stack).isEmpty();
return (stack.isDamageable() && CreateConfig.parameters.enableSandPaperToolPolishing.get())
|| !getMatchingRecipes(world, stack).isEmpty();
}
public static ItemStack applyPolish(World world, Vec3d position, ItemStack stack, ItemStack sandPaperStack) {
List<IRecipe<SandPaperInv>> matchingRecipes = getMatchingRecipes(world, stack);
if (!matchingRecipes.isEmpty())
return matchingRecipes.get(0).getCraftingResult(new SandPaperInv(stack)).copy();
if (stack.isDamageable()) {
if (stack.isDamageable() && CreateConfig.parameters.enableSandPaperToolPolishing.get()) {
stack.setDamage(stack.getDamage() - (stack.getMaxDamage() - stack.getDamage()) / 2);
@ -96,6 +98,4 @@ public class SandPaperPolishingRecipe extends ProcessingRecipe<SandPaperInv> {
}
}

View file

@ -10,11 +10,16 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.HorizontalBlock;
import net.minecraft.block.material.PushReaction;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
@ -35,6 +40,8 @@ public abstract class AttachedLogisticalBlock extends HorizontalBlock implements
protected abstract BlockState getVerticalDefaultState();
protected abstract BlockState getHorizontalDefaultState();
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState state = getDefaultState();
@ -50,6 +57,21 @@ public abstract class AttachedLogisticalBlock extends HorizontalBlock implements
return state;
}
@Override
public ResourceLocation getLootTable() {
if (isVertical())
return getHorizontalDefaultState().getBlock().getLootTable();
return super.getLootTable();
}
@Override
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
PlayerEntity player) {
if (isVertical())
return getHorizontalDefaultState().getBlock().getPickBlock(state, target, world, pos, player);
return super.getPickBlock(state, target, world, pos, player);
}
@Override
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
Direction facing = getBlockFacing(state);

View file

@ -22,7 +22,6 @@ import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
@ -77,6 +76,11 @@ public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachm
return AllBlocks.VERTICAL_FUNNEL.getDefault();
}
@Override
protected BlockState getHorizontalDefaultState() {
return AllBlocks.BELT_FUNNEL.getDefault();
}
@Override
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
BlockPos currentPos, BlockPos facingPos) {
@ -181,11 +185,6 @@ public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachm
protected boolean isVertical() {
return true;
}
@Override
public ResourceLocation getLootTable() {
return AllBlocks.BELT_FUNNEL.get().getLootTable();
}
}
}

View file

@ -15,7 +15,6 @@ import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.shapes.ISelectionContext;
@ -42,6 +41,11 @@ public class ExtractorBlock extends BeltAttachableLogisticalBlock {
return AllBlocks.VERTICAL_EXTRACTOR.getDefault();
}
@Override
protected BlockState getHorizontalDefaultState() {
return AllBlocks.EXTRACTOR.getDefault();
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
super.fillStateContainer(builder.add(POWERED));
@ -113,11 +117,6 @@ public class ExtractorBlock extends BeltAttachableLogisticalBlock {
protected boolean isVertical() {
return true;
}
@Override
public ResourceLocation getLootTable() {
return AllBlocks.EXTRACTOR.get().getLootTable();
}
}
}

View file

@ -11,7 +11,6 @@ import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockReader;
@ -27,6 +26,11 @@ public class LinkedExtractorBlock extends ExtractorBlock {
return AllBlocks.VERTICAL_LINKED_EXTRACTOR.get().getDefaultState();
}
@Override
protected BlockState getHorizontalDefaultState() {
return AllBlocks.LINKED_EXTRACTOR.get().getDefaultState();
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new LinkedExtractorTileEntity();
@ -76,11 +80,6 @@ public class LinkedExtractorBlock extends ExtractorBlock {
protected boolean isVertical() {
return true;
}
@Override
public ResourceLocation getLootTable() {
return AllBlocks.LINKED_EXTRACTOR.get().getLootTable();
}
}
}

View file

@ -5,7 +5,6 @@ import com.simibubi.create.AllBlocks;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockReader;
public class LinkedTransposerBlock extends TransposerBlock {
@ -20,6 +19,11 @@ public class LinkedTransposerBlock extends TransposerBlock {
return AllBlocks.VERTICAL_LINKED_TRANSPOSER.get().getDefaultState();
}
@Override
protected BlockState getHorizontalDefaultState() {
return AllBlocks.LINKED_TRANSPOSER.get().getDefaultState();
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new LinkedTransposerTileEntity();
@ -35,11 +39,6 @@ public class LinkedTransposerBlock extends TransposerBlock {
protected boolean isVertical() {
return true;
}
@Override
public ResourceLocation getLootTable() {
return AllBlocks.LINKED_TRANSPOSER.get().getLootTable();
}
}
}

View file

@ -12,7 +12,6 @@ import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
@ -58,6 +57,11 @@ public class TransposerBlock extends BeltAttachableLogisticalBlock {
return AllBlocks.VERTICAL_TRANSPOSER.getDefault();
}
@Override
protected BlockState getHorizontalDefaultState() {
return AllBlocks.TRANSPOSER.getDefault();
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState stateForPlacement = super.getStateForPlacement(context);
@ -102,11 +106,6 @@ public class TransposerBlock extends BeltAttachableLogisticalBlock {
protected boolean isVertical() {
return true;
}
@Override
public ResourceLocation getLootTable() {
return AllBlocks.TRANSPOSER.get().getLootTable();
}
}
}

View file

@ -12,63 +12,129 @@
"elements": [
{
"name": "Cube",
"from": [1, 1, -1],
"from": [1, 1, 0],
"to": [15, 2, 3],
"faces": {
"north": {"uv": [1, 14, 15, 15], "texture": "#3"},
"east": {"uv": [0, 12, 1, 16], "rotation": 270, "texture": "#belt_funnel"},
"east": {"uv": [0, 12, 1, 15], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 13, 14, 14], "texture": "#package_funnel_horizontal"},
"west": {"uv": [0, 12, 1, 16], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 12, 14, 16], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 14, 16], "texture": "#belt_funnel"}
"west": {"uv": [0, 12, 1, 15], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 12, 14, 15], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 14, 15], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [1.1, 1.1, -1],
"to": [14.9, 2, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 5]},
"faces": {
"north": {"uv": [1, 14, 15, 15], "texture": "#3"},
"east": {"uv": [0, 15, 1, 16], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 13, 14, 14], "texture": "#package_funnel_horizontal"},
"west": {"uv": [0, 15, 1, 16], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 12, 14, 13], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 15, 14, 16], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [11, 14, 0],
"to": [15, 15, 3],
"faces": {
"north": {"uv": [11, 1, 15, 2], "texture": "#3"},
"east": {"uv": [13, 12, 14, 15], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [10, 0, 14, 1], "texture": "#package_funnel_horizontal"},
"west": {"uv": [13, 12, 14, 15], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 12, 4, 15], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 15], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [11, 14, -1],
"to": [15, 15, 3],
"to": [14.9, 14.9, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 5]},
"faces": {
"north": {"uv": [11, 1, 15, 2], "texture": "#3"},
"east": {"uv": [13, 12, 14, 16], "rotation": 270, "texture": "#belt_funnel"},
"east": {"uv": [13, 15, 14, 16], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [10, 0, 14, 1], "texture": "#package_funnel_horizontal"},
"west": {"uv": [13, 12, 14, 16], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 12, 4, 16], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 16], "texture": "#belt_funnel"}
"west": {"uv": [13, 12, 14, 13], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [0, 15, 4, 16], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 13], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [1, 14, -1],
"from": [1, 14, 0],
"to": [5, 15, 3],
"faces": {
"north": {"uv": [1, 1, 5, 2], "texture": "#3"},
"east": {"uv": [13, 12, 14, 16], "rotation": 270, "texture": "#belt_funnel"},
"east": {"uv": [13, 12, 14, 15], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 0, 4, 1], "texture": "#package_funnel_horizontal"},
"west": {"uv": [13, 12, 14, 16], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [10, 12, 14, 16], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 16], "texture": "#belt_funnel"}
"west": {"uv": [13, 12, 14, 15], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [10, 12, 14, 15], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 15], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [1, 2, -1],
"from": [1.1, 14, -1],
"to": [5, 14.9, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 5]},
"faces": {
"north": {"uv": [1, 1, 5, 2], "texture": "#3"},
"east": {"uv": [13, 12, 14, 13], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 0, 4, 1], "texture": "#package_funnel_horizontal"},
"west": {"uv": [13, 15, 14, 16], "rotation": 90, "texture": "#belt_funnel"},
"up": {"uv": [10, 15, 14, 16], "rotation": 180, "texture": "#belt_funnel"},
"down": {"uv": [0, 12, 4, 13], "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [1, 2, 0],
"to": [2, 14, 3],
"faces": {
"north": {"uv": [14, 2, 15, 14], "texture": "#3"},
"east": {"uv": [1, 12, 13, 16], "rotation": 270, "texture": "#belt_funnel"},
"east": {"uv": [1, 12, 13, 15], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 1, 1, 13], "texture": "#package_funnel_horizontal"},
"west": {"uv": [1, 12, 13, 16], "rotation": 90, "texture": "#belt_funnel"}
"west": {"uv": [1, 12, 13, 15], "rotation": 90, "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [1.1, 2, -1],
"to": [2, 14, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 5]},
"faces": {
"north": {"uv": [14, 2, 15, 14], "texture": "#3"},
"east": {"uv": [1, 12, 13, 13], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [0, 1, 1, 13], "texture": "#package_funnel_horizontal"},
"west": {"uv": [1, 15, 13, 16], "rotation": 90, "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [14, 2, 0],
"to": [15, 14, 3],
"faces": {
"north": {"uv": [1, 2, 2, 14], "texture": "#3"},
"east": {"uv": [1, 12, 13, 15], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [13, 1, 14, 13], "texture": "#package_funnel_horizontal"},
"west": {"uv": [1, 12, 13, 15], "rotation": 90, "texture": "#belt_funnel"}
}
},
{
"name": "Cube",
"from": [14, 2, -1],
"to": [15, 14, 3],
"to": [14.9, 14, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 5]},
"faces": {
"north": {"uv": [1, 2, 2, 14], "texture": "#3"},
"east": {"uv": [1, 12, 13, 16], "rotation": 270, "texture": "#belt_funnel"},
"east": {"uv": [1, 15, 13, 16], "rotation": 270, "texture": "#belt_funnel"},
"south": {"uv": [13, 1, 14, 13], "texture": "#package_funnel_horizontal"},
"west": {"uv": [1, 12, 13, 16], "rotation": 90, "texture": "#belt_funnel"}
"west": {"uv": [1, 12, 13, 13], "rotation": 90, "texture": "#belt_funnel"}
}
},
{
@ -112,7 +178,7 @@
{
"name": "Filter",
"from": [5, 14, -1],
"to": [11, 15, 0],
"to": [11, 14.9, 0],
"faces": {
"north": {"uv": [6, 8, 12, 9], "texture": "#4"},
"east": {"uv": [2, 0, 3, 1], "rotation": 180, "texture": "#4"},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB