Spout refinements

- Fixed upright items rendering inconsistently between belt and depot
- Fixed various timing and sync issues with the spout
- Added a recipe type for spout filling
- Fixed more co-modification on belts
- Item and fluid nbt tags in recipes are now data-generated as json objects rather than strings
- Transported item processing can now leave items behind
- Transported item processing now has more meaningful result data
- Tweaked spout animation
- Fixed cullfaces on spout model
This commit is contained in:
simibubi 2020-09-11 14:31:26 +02:00
parent c572b48bbe
commit fe2c27db35
25 changed files with 478 additions and 226 deletions

View file

@ -130,7 +130,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets/create/blockstates/fancy_scoria_
fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json
b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json
6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json
3d97226b5e8d8f70ed08e45e78db1faf78d5e28b assets/create/blockstates/fluid_pipe.json
fe9169716dd21a81a3710a89f0a9b7ea4dcd4d51 assets/create/blockstates/fluid_pipe.json
f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json
e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json
ac00d40e1ef50a37041c0481afa1a23a14dea78e assets/create/blockstates/framed_glass.json
@ -2711,6 +2711,7 @@ bd355332d17adcb0460b1d43146ca288efb78395 data/create/recipes/fancy_weathered_lim
d2ab9ce73636773165564506580f2ec13bd1fc50 data/create/recipes/fancy_weathered_limestone_bricks_stairs_from_fancy_weathered_limestone_bricks_stonecutting.json
36947f27d2b2e57b00440fd5acd06a7554e5a387 data/create/recipes/fancy_weathered_limestone_bricks_wall.json
1d0e41ca98e48073c72adf4077610c96e592f9a5 data/create/recipes/fancy_weathered_limestone_bricks_wall_from_fancy_weathered_limestone_bricks_stonecutting.json
3196d3eda9e67771e86e9af7026d4388765a8a73 data/create/recipes/filling/water_bottle.json
5b8bbde7f8b270ab75fac18d6858f2fadbc0efa3 data/create/recipes/framed_glass_from_glass_colorless_stonecutting.json
d697de0c9b706ca4e18da7a2d769e7e5fe8d769d data/create/recipes/framed_glass_pane.json
a0dae50faaa1b7142bb4309675e3084c68daa547 data/create/recipes/gabbro_bricks_from_gabbro_stonecutting.json

View file

@ -303,8 +303,8 @@
{
"when": {
"west": "false",
"down": "false",
"east": "true",
"down": "false",
"up": "true"
},
"apply": {
@ -314,8 +314,8 @@
{
"when": {
"west": "true",
"down": "false",
"east": "false",
"down": "false",
"up": "true"
},
"apply": {
@ -325,8 +325,8 @@
{
"when": {
"west": "false",
"down": "true",
"east": "true",
"down": "true",
"up": "false"
},
"apply": {
@ -336,8 +336,8 @@
{
"when": {
"west": "true",
"down": "true",
"east": "false",
"down": "true",
"up": "false"
},
"apply": {
@ -347,8 +347,8 @@
{
"when": {
"west": "false",
"down": "true",
"east": "false",
"down": "true",
"up": "true"
},
"apply": {
@ -358,8 +358,8 @@
{
"when": {
"west": "false",
"down": "false",
"east": "false",
"down": "false",
"up": "true"
},
"apply": {
@ -369,8 +369,8 @@
{
"when": {
"west": "false",
"down": "true",
"east": "false",
"down": "true",
"up": "false"
},
"apply": {
@ -380,8 +380,8 @@
{
"when": {
"west": "true",
"down": "false",
"east": "true",
"down": "false",
"up": "false"
},
"apply": {
@ -391,8 +391,8 @@
{
"when": {
"west": "false",
"down": "false",
"east": "true",
"down": "false",
"up": "false"
},
"apply": {
@ -402,8 +402,8 @@
{
"when": {
"west": "true",
"down": "false",
"east": "false",
"down": "false",
"up": "false"
},
"apply": {
@ -413,8 +413,8 @@
{
"when": {
"west": "false",
"down": "false",
"east": "false",
"down": "false",
"up": "false"
},
"apply": {

View file

@ -0,0 +1,21 @@
{
"type": "create:filling",
"ingredients": [
{
"item": "minecraft:glass_bottle"
},
{
"fluidTag": "minecraft:water",
"amount": 250
}
],
"results": [
{
"item": "minecraft:potion",
"count": 1,
"nbt": {
"Potion": "minecraft:water"
}
}
]
}

View file

@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.components.millstone.MillingReci
import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe;
import com.simibubi.create.content.contraptions.components.press.PressingRecipe;
import com.simibubi.create.content.contraptions.components.saw.CuttingRecipe;
import com.simibubi.create.content.contraptions.fluids.actors.FillingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeFactory;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer;
@ -39,6 +40,7 @@ public enum AllRecipeTypes {
PRESSING(processingSerializer(PressingRecipe::new)),
SANDPAPER_POLISHING(processingSerializer(SandPaperPolishingRecipe::new)),
SPLASHING(processingSerializer(SplashingRecipe::new)),
FILLING(processingSerializer(FillingRecipe::new)),
;

View file

@ -1,22 +1,32 @@
package com.simibubi.create.content.contraptions.fluids.actors;
import net.minecraft.fluid.Fluids;
import java.util.List;
import java.util.Optional;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper;
import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class FillingBySpout {
public static boolean canItemBeFilled(ItemStack stack) {
// FIXME: Spout recipe type
if (stack.getItem() == Items.GLASS_BOTTLE)
static RecipeWrapper wrapper = new RecipeWrapper(new ItemStackHandler(1));
public static boolean canItemBeFilled(World world, ItemStack stack) {
wrapper.setInventorySlotContents(0, stack);
if (world.getRecipeManager()
.getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world)
.isPresent())
return true;
LazyOptional<IFluidHandlerItem> capability =
@ -32,10 +42,16 @@ public class FillingBySpout {
return false;
}
public static int getRequiredAmountForItem(ItemStack stack, FluidStack availableFluid) {
// FIXME: Spout recipe type
if (stack.getItem() == Items.GLASS_BOTTLE && availableFluid.getFluid() == Fluids.WATER)
return 250;
public static int getRequiredAmountForItem(World world, ItemStack stack, FluidStack availableFluid) {
wrapper.setInventorySlotContents(0, stack);
Optional<IRecipe<RecipeWrapper>> recipe = world.getRecipeManager()
.getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world);
if (recipe.isPresent()) {
FillingRecipe fillingRecipe = (FillingRecipe) recipe.get();
FluidIngredient requiredFluid = fillingRecipe.getRequiredFluid();
if (requiredFluid.test(availableFluid))
return requiredFluid.getRequiredAmount();
}
LazyOptional<IFluidHandlerItem> capability =
stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
@ -49,15 +65,22 @@ public class FillingBySpout {
return filled == 0 ? -1 : filled;
}
public static ItemStack fillItem(int requiredAmount, ItemStack stack, FluidStack availableFluid) {
public static ItemStack fillItem(World world, int requiredAmount, ItemStack stack, FluidStack availableFluid) {
FluidStack toFill = availableFluid.copy();
toFill.setAmount(requiredAmount);
availableFluid.shrink(requiredAmount);
// FIXME: Spout recipe type
if (stack.getItem() == Items.GLASS_BOTTLE && availableFluid.getFluid() == Fluids.WATER) {
wrapper.setInventorySlotContents(0, stack);
Optional<IRecipe<RecipeWrapper>> recipe = world.getRecipeManager()
.getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world);
if (recipe.isPresent()) {
FillingRecipe fillingRecipe = (FillingRecipe) recipe.get();
FluidIngredient requiredFluid = fillingRecipe.getRequiredFluid();
if (requiredFluid.test(toFill)) {
List<ItemStack> results = fillingRecipe.rollResults();
stack.shrink(1);
return PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER);
return results.isEmpty() ? ItemStack.EMPTY : results.get(0);
}
}
ItemStack split = stack.copy();
@ -68,7 +91,8 @@ public class FillingBySpout {
if (tank == null)
return ItemStack.EMPTY;
tank.fill(toFill, FluidAction.EXECUTE);
ItemStack container = tank.getContainer().copy();
ItemStack container = tank.getContainer()
.copy();
stack.shrink(1);
return container;
}

View file

@ -0,0 +1,43 @@
package com.simibubi.create.content.contraptions.fluids.actors;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class FillingRecipe extends ProcessingRecipe<RecipeWrapper> {
public FillingRecipe(ProcessingRecipeParams params) {
super(AllRecipeTypes.FILLING, params);
}
@Override
public boolean matches(RecipeWrapper inv, World p_77569_2_) {
return ingredients.get(0).test(inv.getStackInSlot(0));
}
@Override
protected int getMaxInputCount() {
return 1;
}
@Override
protected int getMaxOutputCount() {
return 1;
}
@Override
protected int getMaxFluidInputCount() {
return 1;
}
public FluidIngredient getRequiredFluid() {
if (fluidIngredients.isEmpty())
throw new IllegalStateException("Filling Recipe: " + id.toString() + " has no fluid ingredient!");
return fluidIngredients.get(0);
}
}

View file

@ -45,24 +45,31 @@ public class SpoutRenderer extends SafeTileEntityRenderer<SpoutTileEntity> {
int processingTicks = te.processingTicks;
float processingPT = te.processingTicks - partialTicks;
float radius = 0;
if (processingTicks != -1) {
float processingProgress = 1 - (processingPT - 5) / 10;
processingProgress = MathHelper.clamp(processingProgress, 0, 1);
radius = (float) (Math.pow(((2 * processingProgress) - 1), 2) - 1) / 32f;
AxisAlignedBB bb = new AxisAlignedBB(0.5, .5, 0.5, 0.5, -1.2, 0.5).grow(radius);
float radius = 0;
if (processingTicks != -1) {
radius = (float) (Math.pow(((2 * processingProgress) - 1), 2) - 1);
AxisAlignedBB bb = new AxisAlignedBB(0.5, .5, 0.5, 0.5, -1.2, 0.5).grow(radius / 32f);
FluidRenderer.renderTiledFluidBB(fluidStack, (float) bb.minX, (float) bb.minY, (float) bb.minZ,
(float) bb.maxX, (float) bb.maxY, (float) bb.maxZ, buffer, ms, light, true);
}
float squeeze = radius;
if (processingPT < 0)
squeeze = 0;
else if (processingPT < 2)
squeeze = MathHelper.lerp(processingPT / 2f, 0, -1);
else if (processingPT < 10)
squeeze = -1;
ms.push();
for (AllBlockPartials bit : BITS) {
bit.renderOn(te.getBlockState())
.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
ms.translate(0, -3 * radius, 0);
ms.translate(0, -3 * squeeze / 32f, 0);
}
ms.pop();

View file

@ -13,6 +13,7 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.LerpedFloat;
import com.simibubi.create.foundation.utility.LerpedFloat.Chaser;
import com.simibubi.create.foundation.utility.Pair;
@ -97,25 +98,25 @@ public class SpoutTileEntity extends SmartTileEntity {
protected ProcessingResult onItemReceived(TransportedItemStack transported,
TransportedItemStackHandlerBehaviour handler) {
if (!FillingBySpout.canItemBeFilled(transported.stack))
if (!FillingBySpout.canItemBeFilled(world, transported.stack))
return PASS;
if (tank.isEmpty())
return HOLD;
if (FillingBySpout.getRequiredAmountForItem(transported.stack, tank.getFluid()) == -1)
if (FillingBySpout.getRequiredAmountForItem(world, transported.stack, tank.getFluid()) == -1)
return PASS;
return HOLD;
}
protected ProcessingResult whenItemHeld(TransportedItemStack transported,
TransportedItemStackHandlerBehaviour handler) {
if (processingTicks > 0)
if (processingTicks != -1 && processingTicks != 5)
return HOLD;
if (!FillingBySpout.canItemBeFilled(transported.stack))
if (!FillingBySpout.canItemBeFilled(world, transported.stack))
return PASS;
if (tank.isEmpty())
return HOLD;
FluidStack fluid = tank.getFluid();
int requiredAmountForItem = FillingBySpout.getRequiredAmountForItem(transported.stack, fluid.copy());
int requiredAmountForItem = FillingBySpout.getRequiredAmountForItem(world, transported.stack, fluid.copy());
if (requiredAmountForItem == -1)
return PASS;
if (requiredAmountForItem > fluid.getAmount())
@ -129,19 +130,18 @@ public class SpoutTileEntity extends SmartTileEntity {
}
// Process finished
processingTicks = -1;
ItemStack out = FillingBySpout.fillItem(requiredAmountForItem, transported.stack, fluid);
ItemStack out = FillingBySpout.fillItem(world, requiredAmountForItem, transported.stack, fluid);
if (!out.isEmpty()) {
List<TransportedItemStack> outList = new ArrayList<>();
TransportedItemStack similar = transported.copy();
similar.stack = out;
// FIXME: original stack keeps waiting
TransportedItemStack held = null;
TransportedItemStack result = transported.copy();
result.stack = out;
if (!transported.stack.isEmpty())
outList.add(transported.copy());
outList.add(similar);
handler.handleProcessingOnItem(transported, outList);
held = transported.copy();
outList.add(result);
handler.handleProcessingOnItem(transported, TransportedResult.convertToAndLeaveHeld(outList, held));
}
tank.setFluid(fluid);
sendSplash = true;
markDirty();
@ -173,14 +173,14 @@ public class SpoutTileEntity extends SmartTileEntity {
tank.readFromNBT(compound.getCompound("TankContent"));
fluidLevel.readNBT(compound.getCompound("Level"), clientPacket);
processingTicks = compound.getInt("ProcessingTicks");
if (!tank.getFluid()
.isEmpty())
renderedFluid = tank.getFluid();
if (!clientPacket)
return;
if (compound.contains("Splash"))
spawnSplash(renderedFluid);
if (!tank.getFluid()
.isEmpty())
renderedFluid = tank.getFluid();
}
@Override
@ -203,9 +203,9 @@ public class SpoutTileEntity extends SmartTileEntity {
@Override
public void tick() {
super.tick();
if (processingTicks > 0)
if (processingTicks >= 0)
processingTicks--;
if (processingTicks >= 0 && world.isRemote)
if (processingTicks >= 8 && world.isRemote)
spawnProcessingParticles(renderedFluid);
if (syncCooldown > 0) {
syncCooldown--;

View file

@ -4,6 +4,7 @@ import java.util.Random;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.Create;
@ -41,7 +42,11 @@ public class ProcessingOutput {
for (int roll = 0; roll < stack.getCount(); roll++)
if (r.nextFloat() > chance)
outputAmount--;
return outputAmount > 0 ? new ItemStack(stack.getItem(), outputAmount) : ItemStack.EMPTY;
if (outputAmount == 0)
return ItemStack.EMPTY;
ItemStack out = stack.copy();
out.setCount(outputAmount);
return out;
}
public JsonElement serialize() {
@ -51,8 +56,7 @@ public class ProcessingOutput {
.toString());
json.addProperty("count", stack.getCount());
if (stack.hasTag())
json.addProperty("nbt", stack.getTag()
.toString());
json.add("nbt", new JsonParser().parse(stack.getTag().toString()));
if (chance != 1)
json.addProperty("chance", chance);
return json;

View file

@ -145,6 +145,10 @@ public class ProcessingRecipeBuilder<T extends ProcessingRecipe<?>> {
return output(chance, new ItemStack(item, amount));
}
public ProcessingRecipeBuilder<T> output(ItemStack output) {
return output(1, output);
}
public ProcessingRecipeBuilder<T> output(float chance, ItemStack output) {
params.results.add(new ProcessingOutput(output, chance));
return this;

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.contraptions.relays.belt;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@ -17,6 +16,7 @@ import com.simibubi.create.content.schematics.ISpecialBlockItemRequirement;
import com.simibubi.create.content.schematics.ItemRequirement;
import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Iterate;
@ -248,7 +248,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
controllerBelt.getInventory()
.applyToEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
player.inventory.placeItemBackInInventory(world, transportedItemStack.stack);
return Collections.emptyList();
return TransportedResult.removeItem();
});
}
@ -466,15 +466,17 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction side, BlockState p_196271_3_,
IWorld world, BlockPos pos, BlockPos p_196271_6_) {
if (side.getAxis().isHorizontal())
public BlockState updatePostPlacement(BlockState state, Direction side, BlockState p_196271_3_, IWorld world,
BlockPos pos, BlockPos p_196271_6_) {
if (side.getAxis()
.isHorizontal())
updateTunnelConnections(world, pos.up());
return state;
}
private void updateTunnelConnections(IWorld world, BlockPos pos) {
Block tunnelBlock = world.getBlockState(pos).getBlock();
Block tunnelBlock = world.getBlockState(pos)
.getBlock();
if (tunnelBlock instanceof BeltTunnelBlock)
((BeltTunnelBlock) tunnelBlock).updateTunnel(world, pos);
}

View file

@ -248,9 +248,12 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
itemRenderer.renderItem(transported.stack, TransformType.FIXED, light, overlay, ms, buffer);
ms.pop();
if (!renderUpright) {
if (!blockItem)
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(10));
ms.translate(0, blockItem ? 1 / 64d : 1 / 16d, 0);
} else
ms.translate(0, 0, -1 / 16f);
}

View file

@ -23,6 +23,7 @@ import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileE
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.NBTHelper;
@ -356,7 +357,7 @@ public class BeltTileEntity extends KineticTileEntity {
}
private void applyToAllItems(float maxDistanceFromCenter,
Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
Function<TransportedItemStack, TransportedResult> processFunction) {
BeltTileEntity controller = getControllerTE();
if (controller != null)
controller.getInventory()

View file

@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.relays.belt.transport;
import static com.simibubi.create.content.contraptions.relays.belt.transport.BeltTunnelInteractionHandler.flapTunnel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
@ -12,13 +11,14 @@ import java.util.function.Function;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import net.minecraft.block.Block;
@ -37,6 +37,7 @@ public class BeltInventory {
final BeltTileEntity belt;
private final List<TransportedItemStack> items;
final List<TransportedItemStack> toInsert;
final List<TransportedItemStack> toRemove;
boolean beltMovementPositive;
final float SEGMENT_WINDOW = .75f;
@ -44,6 +45,7 @@ public class BeltInventory {
this.belt = te;
items = new LinkedList<>();
toInsert = new LinkedList<>();
toRemove = new LinkedList<>();
}
public void tick() {
@ -56,10 +58,12 @@ public class BeltInventory {
belt.sendData();
}
// Add items from previous cycle
if (!toInsert.isEmpty()) {
// Added/Removed items from previous cycle
if (!toInsert.isEmpty() || !toRemove.isEmpty()) {
toInsert.forEach(this::insert);
toInsert.clear();
items.removeAll(toRemove);
toRemove.clear();
belt.markDirty();
belt.sendData();
}
@ -248,7 +252,7 @@ public class BeltInventory {
return true;
if (result == ProcessingResult.HOLD) {
currentItem.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
currentItem.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 512f : -1 / 512f);
currentItem.locked = true;
belt.sendData();
return false;
@ -400,24 +404,25 @@ public class BeltInventory {
}
public void applyToEachWithin(float position, float maxDistanceToPosition,
Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
List<TransportedItemStack> toBeAdded = new ArrayList<>();
Function<TransportedItemStack, TransportedResult> processFunction) {
boolean dirty = false;
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
TransportedItemStack transportedItemStack = iterator.next();
ItemStack stackBefore = transportedItemStack.stack.copy();
if (Math.abs(position - transportedItemStack.beltPosition) < maxDistanceToPosition) {
List<TransportedItemStack> apply = processFunction.apply(transportedItemStack);
if (apply == null)
for (TransportedItemStack transforted : items) {
ItemStack stackBefore = transforted.stack.copy();
if (Math.abs(position - transforted.beltPosition) >= maxDistanceToPosition)
continue;
if (apply.size() == 1 && apply.get(0).stack.equals(stackBefore, false))
TransportedResult result = processFunction.apply(transforted);
if (result.didntChangeFrom(stackBefore))
continue;
dirty = true;
toBeAdded.addAll(apply);
iterator.remove();
if (result.hasHeldOutput()) {
TransportedItemStack held = result.getHeldOutput();
held.beltPosition = ((int) position) + .5f - (beltMovementPositive ? 1 / 512f : -1 / 512f);
toInsert.add(held);
}
toInsert.addAll(result.getOutputs());
toRemove.add(transforted);
}
toBeAdded.forEach(toInsert::add);
if (dirty) {
belt.markDirty();
belt.sendData();

View file

@ -14,6 +14,7 @@ import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlo
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.block.BlockState;
@ -142,7 +143,8 @@ public class InWorldProcessing {
}
}
public static List<TransportedItemStack> applyProcessing(TransportedItemStack transported, World world, Type type) {
public static TransportedResult applyProcessing(TransportedItemStack transported, World world, Type type) {
TransportedResult ignore = TransportedResult.doNothing();
if (transported.processedBy != type) {
transported.processedBy = type;
int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
@ -151,16 +153,16 @@ public class InWorldProcessing {
transported.processingTime = processingTime;
if (!canProcess(transported.stack, type, world))
transported.processingTime = -1;
return null;
return ignore;
}
if (transported.processingTime == -1)
return null;
return ignore;
if (transported.processingTime-- > 0)
return null;
return ignore;
List<ItemStack> stacks = process(transported.stack, type, world);
if (stacks == null)
return null;
return ignore;
List<TransportedItemStack> transportedStacks = new ArrayList<>();
for (ItemStack additional : stacks) {
@ -168,7 +170,7 @@ public class InWorldProcessing {
newTransported.stack = additional.copy();
transportedStacks.add(newTransported);
}
return transportedStacks;
return TransportedResult.convertTo(transportedStacks);
}
private static List<ItemStack> process(ItemStack stack, Type type, World world) {

View file

@ -95,7 +95,7 @@ public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
boolean renderUpright = BeltHelper.isItemUpright(itemStack);
boolean blockItem = itemRenderer.getItemModelWithOverrides(itemStack, null, null)
.isGui3d();
for (int i = 0; i <= count; i++) {
ms.push();
msr.rotateY(angle);
if (!blockItem && !renderUpright) {
@ -109,20 +109,28 @@ public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
Vec3d vectorForOffset = itemPosition;
Vec3d diff = vectorForOffset.subtract(positionVec);
float yRot = (float) MathHelper.atan2(diff.z, -diff.x);
ms.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion((float) (yRot + Math.PI / 2)));
ms.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion((float) (yRot - Math.PI / 2)));
}
ms.translate(0, 3 / 32d, 0);
ms.translate(0, 3 / 32d, 1/16f);
}
for (int i = 0; i <= count; i++) {
ms.push();
if (blockItem)
ms.translate(r.nextFloat() * .0625f * i, 0, r.nextFloat() * .0625f * i);
ms.scale(.5f, .5f, .5f);
itemRenderer.renderItem(itemStack, TransformType.FIXED, light, overlay, ms, buffer);
ms.pop();
if (!renderUpright) {
if (!blockItem)
msr.rotateY(10);
ms.translate(0, blockItem ? 1 / 64d : 1 / 16d, 0);
} else
ms.translate(0, 0, -1 / 16f);
}
ms.pop();
}
}

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.logistics.block.depot;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
@ -12,7 +11,10 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBe
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntityType;
@ -21,6 +23,7 @@ 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.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
public class DepotTileEntity extends SmartTileEntity {
@ -125,6 +128,12 @@ public class DepotTileEntity extends SmartTileEntity {
this.heldItem = heldItem;
}
public void setCenteredHeldItem(TransportedItemStack heldItem) {
this.heldItem = heldItem;
this.heldItem.beltPosition = 0.5f;
this.heldItem.prevBeltPosition = 0.5f;
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
@ -157,40 +166,32 @@ public class DepotTileEntity extends SmartTileEntity {
}
private void applyToAllItems(float maxDistanceFromCentre,
Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
Function<TransportedItemStack, TransportedResult> processFunction) {
if (heldItem == null)
return;
if (.5f - heldItem.beltPosition > maxDistanceFromCentre)
return;
boolean dirty = false;
List<TransportedItemStack> toBeAdded = new ArrayList<>();
TransportedItemStack transportedItemStack = heldItem;
ItemStack stackBefore = transportedItemStack.stack.copy();
List<TransportedItemStack> apply = processFunction.apply(transportedItemStack);
if (apply == null)
return;
if (apply.size() == 1 && apply.get(0).stack.equals(stackBefore, false))
TransportedResult result = processFunction.apply(transportedItemStack);
if (result.didntChangeFrom(stackBefore))
return;
dirty = true;
heldItem = null;
toBeAdded.addAll(apply);
for (TransportedItemStack added : toBeAdded) {
if (heldItem == null) {
heldItem = added;
heldItem.beltPosition = 0.5f;
heldItem.prevBeltPosition = 0.5f;
if (result.hasHeldOutput())
setCenteredHeldItem(result.getHeldOutput());
for (TransportedItemStack added : result.getOutputs()) {
if (getHeldItemStack().isEmpty()) {
setCenteredHeldItem(added);
continue;
}
for (int i = 0; i < processingOutputBuffer.getSlots(); i++) {
ItemStack stackInSlot = processingOutputBuffer.getStackInSlot(i);
if (!stackInSlot.isEmpty())
continue;
processingOutputBuffer.setStackInSlot(i, added.stack);
break;
}
ItemStack remainder = ItemHandlerHelper.insertItemStacked(processingOutputBuffer, added.stack, false);
Vec3d vec = VecHelper.getCenterOf(pos);
InventoryHelper.spawnItemStack(world, vec.x, vec.y + .5f, vec.z, remainder);
}
if (dirty) {

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.logistics.block.funnel;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
@ -15,6 +14,7 @@ import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.ExtractingBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
@ -148,21 +148,22 @@ public class FunnelTileEntity extends SmartTileEntity {
extracting.extract();
}
private List<TransportedItemStack> collectFromHandler(TransportedItemStack stack) {
private TransportedResult collectFromHandler(TransportedItemStack stack) {
TransportedResult ignore = TransportedResult.doNothing();
ItemStack toInsert = stack.stack.copy();
if (!filtering.test(toInsert))
return null;
return ignore;
ItemStack remainder = inserting.insert(toInsert, false);
if (remainder.equals(stack.stack, false))
return null;
List<TransportedItemStack> list = new ArrayList<>();
return ignore;
flap(true);
if (remainder.isEmpty())
return list;
return TransportedResult.removeItem();
TransportedItemStack changed = stack.copy();
changed.stack = remainder;
list.add(changed);
return list;
return TransportedResult.convertTo(changed);
}
@Override

View file

@ -28,7 +28,7 @@ public abstract class CreateRecipeProvider extends RecipeProvider {
@Override
protected void registerRecipes(Consumer<IFinishedRecipe> p_200404_1_) {
all.forEach(c -> c.register(p_200404_1_));
Create.logger.info(getName() + " registered " + all.size() + " recipes");
Create.logger.info(getName() + " registered " + all.size() + " recipe" + (all.size() == 1 ? "" : "s"));
}
@FunctionalInterface

View file

@ -0,0 +1,31 @@
package com.simibubi.create.foundation.data.recipe;
import com.simibubi.create.AllRecipeTypes;
import net.minecraft.data.DataGenerator;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.potion.PotionUtils;
import net.minecraft.potion.Potions;
import net.minecraft.tags.FluidTags;
public class FillingRecipeGen extends ProcessingRecipeGen {
GeneratedRecipe
WATER_BOTTLE = create("water_bottle", b -> b.require(Items.GLASS_BOTTLE)
.require(FluidTags.WATER, 250)
.output(PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER)))
;
public FillingRecipeGen(DataGenerator p_i48262_1_) {
super(p_i48262_1_);
}
@Override
protected AllRecipeTypes getRecipeType() {
return AllRecipeTypes.FILLING;
}
}

View file

@ -1,5 +1,8 @@
package com.simibubi.create.foundation.data.recipe;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@ -10,23 +13,46 @@ import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuild
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DirectoryCache;
import net.minecraft.data.IDataProvider;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.IItemProvider;
import net.minecraftforge.fluids.FluidAttributes;
public abstract class ProcessingRecipeGen extends CreateRecipeProvider {
protected static List<ProcessingRecipeGen> generators = new ArrayList<>();
protected static final int BUCKET = FluidAttributes.BUCKET_VOLUME;
protected static final int BOTTLE = 250;
public static void registerAll(DataGenerator gen) {
gen.addProvider(new CrushingRecipeGen(gen));
gen.addProvider(new MillingRecipeGen(gen));
gen.addProvider(new CuttingRecipeGen(gen));
gen.addProvider(new WashingRecipeGen(gen));
gen.addProvider(new PolishingRecipeGen(gen));
gen.addProvider(new MixingRecipeGen(gen));
gen.addProvider(new PressingRecipeGen(gen));
generators.add(new CrushingRecipeGen(gen));
generators.add(new MillingRecipeGen(gen));
generators.add(new CuttingRecipeGen(gen));
generators.add(new WashingRecipeGen(gen));
generators.add(new PolishingRecipeGen(gen));
generators.add(new MixingRecipeGen(gen));
generators.add(new PressingRecipeGen(gen));
generators.add(new FillingRecipeGen(gen));
gen.addProvider(new IDataProvider() {
@Override
public String getName() {
return "Create's Processing Recipes";
}
@Override
public void act(DirectoryCache dc) throws IOException {
generators.forEach(g -> {
try {
g.act(dc);
} catch (IOException e) {
e.printStackTrace();
}
});
}
});
}
public ProcessingRecipeGen(DataGenerator p_i48262_1_) {

View file

@ -7,6 +7,7 @@ import javax.annotation.Nullable;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import net.minecraft.fluid.Fluid;
@ -150,7 +151,7 @@ public abstract class FluidIngredient implements Predicate<FluidStack> {
protected void writeInternal(JsonObject json) {
json.addProperty("fluid", fluid.getRegistryName()
.toString());
json.addProperty("nbt", tagToMatch.toString());
json.add("nbt", new JsonParser().parse(tagToMatch.toString()));
}
}

View file

@ -3,12 +3,16 @@ package com.simibubi.create.foundation.tileEntity.behaviour.belt;
import java.util.List;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Vec3d;
public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
@ -17,6 +21,68 @@ public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
private ProcessingCallback processingCallback;
private PositionGetter positionGetter;
public static class TransportedResult {
List<TransportedItemStack> outputs;
TransportedItemStack heldOutput;
private static final TransportedResult DO_NOTHING = new TransportedResult(null, null);
private static final TransportedResult REMOVE_ITEM = new TransportedResult(ImmutableList.of(), null);
public static TransportedResult doNothing() {
return DO_NOTHING;
}
public static TransportedResult removeItem() {
return REMOVE_ITEM;
}
public static TransportedResult convertTo(TransportedItemStack output) {
return new TransportedResult(ImmutableList.of(output), null);
}
public static TransportedResult convertTo(List<TransportedItemStack> outputs) {
return new TransportedResult(outputs, null);
}
public static TransportedResult convertToAndLeaveHeld(List<TransportedItemStack> outputs,
TransportedItemStack heldOutput) {
return new TransportedResult(outputs, heldOutput);
}
private TransportedResult(List<TransportedItemStack> outputs, TransportedItemStack heldOutput) {
this.outputs = outputs;
this.heldOutput = heldOutput;
}
public boolean doesNothing() {
return outputs == null;
}
public boolean didntChangeFrom(ItemStack stackBefore) {
return doesNothing()
|| outputs.size() == 1 && outputs.get(0).stack.equals(stackBefore, false) && !hasHeldOutput();
}
public List<TransportedItemStack> getOutputs() {
if (outputs == null)
throw new IllegalStateException("Do not call getOutputs() on a Result that doesNothing().");
return outputs;
}
public boolean hasHeldOutput() {
return heldOutput != null;
}
@Nullable
public TransportedItemStack getHeldOutput() {
if (heldOutput == null)
throw new IllegalStateException(
"Do not call getHeldOutput() on a Result with hasHeldOutput() == false.");
return heldOutput;
}
}
public TransportedItemStackHandlerBehaviour(SmartTileEntity te, ProcessingCallback processingCallback) {
super(te);
this.processingCallback = processingCallback;
@ -28,11 +94,11 @@ public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
return this;
}
public void handleProcessingOnAllItems(Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
public void handleProcessingOnAllItems(Function<TransportedItemStack, TransportedResult> processFunction) {
handleCenteredProcessingOnAllItems(.51f, processFunction);
}
public void handleProcessingOnItem(TransportedItemStack item, List<TransportedItemStack> processOutput) {
public void handleProcessingOnItem(TransportedItemStack item, TransportedResult processOutput) {
handleCenteredProcessingOnAllItems(.51f, t -> {
if (t == item)
return processOutput;
@ -41,7 +107,7 @@ public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
}
public void handleCenteredProcessingOnAllItems(float maxDistanceFromCenter,
Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
Function<TransportedItemStack, TransportedResult> processFunction) {
this.processingCallback.applyToAllItems(maxDistanceFromCenter, processFunction);
}
@ -57,7 +123,7 @@ public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
@FunctionalInterface
public interface ProcessingCallback {
public void applyToAllItems(float maxDistanceFromCenter,
Function<TransportedItemStack, List<TransportedItemStack>> processFunction);
Function<TransportedItemStack, TransportedResult> processFunction);
}
@FunctionalInterface

View file

@ -12,10 +12,10 @@
"to": [14, 16, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [1, 0, 7, 1], "texture": "#0", "cullface": "north"},
"east": {"uv": [1, 0, 7, 1], "texture": "#0", "cullface": "east"},
"south": {"uv": [1, 0, 7, 1], "texture": "#0", "cullface": "south"},
"west": {"uv": [1, 0, 7, 1], "texture": "#0", "cullface": "west"},
"north": {"uv": [1, 0, 7, 1], "texture": "#0"},
"east": {"uv": [1, 0, 7, 1], "texture": "#0"},
"south": {"uv": [1, 0, 7, 1], "texture": "#0"},
"west": {"uv": [1, 0, 7, 1], "texture": "#0"},
"up": {"uv": [1, 9, 7, 15], "texture": "#0"}
}
},
@ -25,12 +25,12 @@
"to": [15, 14, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 6, -24]},
"faces": {
"north": {"uv": [0.5, 1, 7.5, 2], "texture": "#0", "cullface": "north"},
"east": {"uv": [0.5, 1, 7.5, 2], "texture": "#0", "cullface": "east"},
"south": {"uv": [0.5, 1, 7.5, 2], "texture": "#0", "cullface": "south"},
"west": {"uv": [0.5, 1, 7.5, 2], "texture": "#0", "cullface": "west"},
"north": {"uv": [0.5, 1, 7.5, 2], "texture": "#0"},
"east": {"uv": [0.5, 1, 7.5, 2], "texture": "#0"},
"south": {"uv": [0.5, 1, 7.5, 2], "texture": "#0"},
"west": {"uv": [0.5, 1, 7.5, 2], "texture": "#0"},
"up": {"uv": [0.5, 8.5, 7.5, 15.5], "texture": "#0"},
"down": {"uv": [0.5, 8.5, 7.5, 15.5], "texture": "#0", "cullface": "down"}
"down": {"uv": [0.5, 8.5, 7.5, 15.5], "texture": "#0"}
}
},
{
@ -39,11 +39,11 @@
"to": [14, 2, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [1, 7, 7, 8], "texture": "#0", "cullface": "north"},
"east": {"uv": [1, 7, 7, 8], "texture": "#0", "cullface": "east"},
"south": {"uv": [1, 7, 7, 8], "texture": "#0", "cullface": "south"},
"west": {"uv": [1, 7, 7, 8], "texture": "#0", "cullface": "west"},
"down": {"uv": [9, 9, 15, 15], "texture": "#0", "cullface": "down"}
"north": {"uv": [1, 7, 7, 8], "texture": "#0"},
"east": {"uv": [1, 7, 7, 8], "texture": "#0"},
"south": {"uv": [1, 7, 7, 8], "texture": "#0"},
"west": {"uv": [1, 7, 7, 8], "texture": "#0"},
"down": {"uv": [9, 9, 15, 15], "texture": "#0"}
}
},
{
@ -52,12 +52,12 @@
"to": [15, 4, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [7, -4, -24]},
"faces": {
"north": {"uv": [0.5, 6, 7.5, 7], "texture": "#0", "cullface": "north"},
"east": {"uv": [1, 6, 7.5, 7], "texture": "#0", "cullface": "east"},
"south": {"uv": [0.5, 6, 7.5, 7], "texture": "#0", "cullface": "south"},
"west": {"uv": [0.5, 6, 7.5, 7], "texture": "#0", "cullface": "west"},
"north": {"uv": [0.5, 6, 7.5, 7], "texture": "#0"},
"east": {"uv": [1, 6, 7.5, 7], "texture": "#0"},
"south": {"uv": [0.5, 6, 7.5, 7], "texture": "#0"},
"west": {"uv": [0.5, 6, 7.5, 7], "texture": "#0"},
"up": {"uv": [8.5, 8.5, 15.5, 15.5], "texture": "#0"},
"down": {"uv": [0.5, 8.5, 7.5, 15.5], "texture": "#0", "cullface": "down"}
"down": {"uv": [0.5, 8.5, 7.5, 15.5], "texture": "#0"}
}
},
{
@ -66,9 +66,9 @@
"to": [2, 12, 10],
"faces": {
"north": {"uv": [0, 0, 0, 0], "texture": "#0"},
"east": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"east": {"uv": [9, 0, 11, 4], "texture": "#0"},
"south": {"uv": [0, 0, 0, 0], "texture": "#0"},
"west": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"west": {"uv": [9, 0, 11, 4], "texture": "#0"},
"up": {"uv": [0, 0, 0, 0], "texture": "#0"},
"down": {"uv": [0, 0, 0, 0], "texture": "#0"}
}
@ -78,10 +78,10 @@
"from": [6, 4, 2],
"to": [10, 12, 2],
"faces": {
"north": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"east": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"south": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"west": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"north": {"uv": [9, 0, 11, 4], "texture": "#0"},
"east": {"uv": [0, 0, 0, 0], "texture": "#0"},
"south": {"uv": [9, 0, 11, 4], "texture": "#0"},
"west": {"uv": [0, 0, 0, 0], "texture": "#0"},
"up": {"uv": [0, 0, 0, 0], "rotation": 90, "texture": "#0"},
"down": {"uv": [0, 0, 0, 0], "rotation": 270, "texture": "#0"}
}
@ -91,10 +91,10 @@
"from": [14, 4, 6],
"to": [14, 12, 10],
"faces": {
"north": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"east": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"south": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"west": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"north": {"uv": [0, 0, 0, 0], "texture": "#0"},
"east": {"uv": [9, 0, 11, 4], "texture": "#0"},
"south": {"uv": [0, 0, 0, 0], "texture": "#0"},
"west": {"uv": [9, 0, 11, 4], "texture": "#0"},
"up": {"uv": [0, 0, 0, 0], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 0, 0], "rotation": 180, "texture": "#0"}
}
@ -104,10 +104,10 @@
"from": [6, 4, 14],
"to": [10, 12, 14],
"faces": {
"north": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"east": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"south": {"uv": [9, 0, 11, 4], "texture": "#0", "cullface": "west"},
"west": {"uv": [0, 0, 0, 0], "texture": "#0", "cullface": "west"},
"north": {"uv": [9, 0, 11, 4], "texture": "#0"},
"east": {"uv": [0, 0, 0, 0], "texture": "#0"},
"south": {"uv": [9, 0, 11, 4], "texture": "#0"},
"west": {"uv": [0, 0, 0, 0], "texture": "#0"},
"up": {"uv": [0, 0, 0, 0], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 0, 0], "rotation": 90, "texture": "#0"}
}
@ -117,9 +117,9 @@
"from": [1, 4, 1],
"to": [2, 12, 6],
"faces": {
"east": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"south": {"uv": [7, 4.5, 7.5, 5], "texture": "#0", "cullface": "west"},
"west": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"}
"east": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"south": {"uv": [7, 4.5, 7.5, 5], "texture": "#0"},
"west": {"uv": [0.5, 2, 3, 6], "texture": "#0"}
}
},
{
@ -127,9 +127,9 @@
"from": [10, 4, 1],
"to": [15, 12, 2],
"faces": {
"north": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"},
"south": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"west": {"uv": [7, 4.5, 7.5, 5], "texture": "#0", "cullface": "west"}
"north": {"uv": [0.5, 2, 3, 6], "texture": "#0"},
"south": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"west": {"uv": [7, 4.5, 7.5, 5], "texture": "#0"}
}
},
{
@ -137,9 +137,9 @@
"from": [14, 4, 10],
"to": [15, 12, 15],
"faces": {
"north": {"uv": [7, 4.5, 7.5, 5], "texture": "#0", "cullface": "west"},
"east": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"},
"west": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"}
"north": {"uv": [7, 4.5, 7.5, 5], "texture": "#0"},
"east": {"uv": [0.5, 2, 3, 6], "texture": "#0"},
"west": {"uv": [5, 2, 7.5, 6], "texture": "#0"}
}
},
{
@ -147,9 +147,9 @@
"from": [1, 4, 14],
"to": [6, 12, 15],
"faces": {
"north": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"east": {"uv": [7, 4.5, 7.5, 5], "texture": "#0", "cullface": "west"},
"south": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"}
"north": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"east": {"uv": [7, 4.5, 7.5, 5], "texture": "#0"},
"south": {"uv": [0.5, 2, 3, 6], "texture": "#0"}
}
},
{
@ -157,9 +157,9 @@
"from": [1, 4, 10],
"to": [2, 12, 15],
"faces": {
"north": {"uv": [7, 3.5, 7.5, 4], "texture": "#0", "cullface": "west"},
"east": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"},
"west": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"}
"north": {"uv": [7, 3.5, 7.5, 4], "texture": "#0"},
"east": {"uv": [0.5, 2, 3, 6], "texture": "#0"},
"west": {"uv": [5, 2, 7.5, 6], "texture": "#0"}
}
},
{
@ -167,9 +167,9 @@
"from": [1, 4, 1],
"to": [6, 12, 2],
"faces": {
"north": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"east": {"uv": [7, 3.5, 7.5, 4], "texture": "#0", "cullface": "west"},
"south": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"}
"north": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"east": {"uv": [7, 3.5, 7.5, 4], "texture": "#0"},
"south": {"uv": [0.5, 2, 3, 6], "texture": "#0"}
}
},
{
@ -177,9 +177,9 @@
"from": [14, 4, 1],
"to": [15, 12, 6],
"faces": {
"east": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"south": {"uv": [7, 3.5, 7.5, 4], "texture": "#0", "cullface": "west"},
"west": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"}
"east": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"south": {"uv": [7, 3.5, 7.5, 4], "texture": "#0"},
"west": {"uv": [0.5, 2, 3, 6], "texture": "#0"}
}
},
{
@ -187,9 +187,9 @@
"from": [10, 4, 14],
"to": [15, 12, 15],
"faces": {
"north": {"uv": [0.5, 2, 3, 6], "texture": "#0", "cullface": "west"},
"south": {"uv": [5, 2, 7.5, 6], "texture": "#0", "cullface": "west"},
"west": {"uv": [7, 3.5, 7.5, 4], "texture": "#0", "cullface": "west"}
"north": {"uv": [0.5, 2, 3, 6], "texture": "#0"},
"south": {"uv": [5, 2, 7.5, 6], "texture": "#0"},
"west": {"uv": [7, 3.5, 7.5, 4], "texture": "#0"}
}
}
]

File diff suppressed because one or more lines are too long