mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Spinny vortex
- Crushing wheels no longer z-fight with chutes - Improved rendering of items and fluids inside basins
This commit is contained in:
parent
d5f08aab76
commit
dbfe7f93fa
16 changed files with 672 additions and 197 deletions
|
@ -30,6 +30,7 @@ public enum AllParticleTypes {
|
|||
HEATER_PARTICLE(HeaterParticleData::new),
|
||||
CUBE(CubeParticleData::new),
|
||||
FLUID_PARTICLE(FluidParticleData::new),
|
||||
BASIN_FLUID(FluidParticleData::new),
|
||||
FLUID_DRIP(FluidParticleData::new)
|
||||
|
||||
;
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Optional;
|
|||
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
|
||||
import com.simibubi.create.content.contraptions.fluids.FluidFX;
|
||||
import com.simibubi.create.content.contraptions.fluids.potion.PotionMixingRecipeManager;
|
||||
import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.processing.BasinTileEntity;
|
||||
|
@ -12,6 +13,8 @@ import com.simibubi.create.foundation.advancement.AllTriggers;
|
|||
import com.simibubi.create.foundation.advancement.ITriggerable;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.item.SmartInventory;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
|
@ -19,6 +22,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
|
@ -86,6 +90,9 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||
running = compound.getBoolean("Running");
|
||||
runningTicks = compound.getInt("Ticks");
|
||||
super.read(compound, clientPacket);
|
||||
|
||||
if (clientPacket && hasWorld())
|
||||
getBasin().ifPresent(bte -> bte.setAreFluidsMoving(running && runningTicks <= 20));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,7 +134,6 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||
if (runningTicks != 20)
|
||||
runningTicks++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void renderParticles() {
|
||||
|
@ -135,24 +141,38 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||
if (!basin.isPresent() || world == null)
|
||||
return;
|
||||
|
||||
SmartInventory inputs = basin.get()
|
||||
.getInputInventory();
|
||||
for (int slot = 0; slot < inputs.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inputs.getStackInSlot(slot);
|
||||
if (stackInSlot.isEmpty())
|
||||
continue;
|
||||
|
||||
ItemParticleData data = new ItemParticleData(ParticleTypes.ITEM, stackInSlot);
|
||||
float angle = world.rand.nextFloat() * 360;
|
||||
Vec3d offset = new Vec3d(0, 0, 0.25f);
|
||||
offset = VecHelper.rotate(offset, angle, Axis.Y);
|
||||
Vec3d target = VecHelper.rotate(offset, getSpeed() > 0 ? 25 : -25, Axis.Y)
|
||||
.add(0, .25f, 0);
|
||||
|
||||
Vec3d center = offset.add(VecHelper.getCenterOf(pos));
|
||||
target = VecHelper.offsetRandomly(target.subtract(offset), world.rand, 1 / 128f);
|
||||
world.addParticle(data, center.x, center.y - 2, center.z, target.x, target.y, target.z);
|
||||
for (SmartInventory inv : basin.get()
|
||||
.getInvs()) {
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
if (stackInSlot.isEmpty())
|
||||
continue;
|
||||
ItemParticleData data = new ItemParticleData(ParticleTypes.ITEM, stackInSlot);
|
||||
spillParticle(data);
|
||||
}
|
||||
}
|
||||
|
||||
for (SmartFluidTankBehaviour behaviour : basin.get()
|
||||
.getTanks()) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks()) {
|
||||
if (tankSegment.isEmpty(0))
|
||||
continue;
|
||||
spillParticle(FluidFX.getFluidParticle(tankSegment.getRenderedFluid()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void spillParticle(IParticleData data) {
|
||||
float angle = world.rand.nextFloat() * 360;
|
||||
Vec3d offset = new Vec3d(0, 0, 0.25f);
|
||||
offset = VecHelper.rotate(offset, angle, Axis.Y);
|
||||
Vec3d target = VecHelper.rotate(offset, getSpeed() > 0 ? 25 : -25, Axis.Y)
|
||||
.add(0, .25f, 0);
|
||||
Vec3d center = offset.add(VecHelper.getCenterOf(pos));
|
||||
target = VecHelper.offsetRandomly(target.subtract(offset), world.rand, 1 / 128f);
|
||||
world.addParticle(data, center.x, center.y - 1.75f, center.z, target.x, target.y, target.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,10 +45,6 @@ public class FluidFX {
|
|||
}
|
||||
|
||||
public static IParticleData getFluidParticle(FluidStack fluid) {
|
||||
if (FluidHelper.hasBlockState(fluid.getFluid()))
|
||||
return new BlockParticleData(ParticleTypes.BLOCK, fluid.getFluid()
|
||||
.getDefaultState()
|
||||
.getBlockState());
|
||||
return new FluidParticleData(AllParticleTypes.FLUID_PARTICLE.get(), fluid);
|
||||
}
|
||||
|
||||
|
@ -82,17 +78,17 @@ public class FluidFX {
|
|||
public static void spawnPouringLiquid(World world, BlockPos pos, int amount, IParticleData particle,
|
||||
float rimRadius, Vec3d directionVec, boolean inbound) {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Vec3d vec = VecHelper.offsetRandomly(Vec3d.ZERO, r, rimRadius);
|
||||
Vec3d vec = VecHelper.offsetRandomly(Vec3d.ZERO, r, rimRadius * .75f);
|
||||
vec = vec.mul(VecHelper.axisAlingedPlaneOf(directionVec))
|
||||
.add(directionVec.scale(.5 + r.nextFloat() / 4f));
|
||||
Vec3d m = vec;
|
||||
Vec3d m = vec.scale(1 / 4f);
|
||||
Vec3d centerOf = VecHelper.getCenterOf(pos);
|
||||
vec = vec.add(centerOf);
|
||||
if (inbound) {
|
||||
vec = vec.add(m);
|
||||
m = centerOf.add(directionVec.scale(.5))
|
||||
.subtract(vec)
|
||||
.scale(3);
|
||||
.scale(1 / 16f);
|
||||
}
|
||||
world.addOptionalParticle(particle, vec.x, vec.y - 1 / 16f, vec.z, m.x, m.y, m.z);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.particle;
|
||||
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.processing.BasinTileEntity;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
public class BasinFluidParticle extends FluidStackParticle {
|
||||
|
||||
BlockPos basinPos;
|
||||
Vec3d targetPos;
|
||||
Vec3d centerOfBasin;
|
||||
float yOffset;
|
||||
|
||||
public BasinFluidParticle(World world, FluidStack fluid, double x, double y, double z, double vx, double vy,
|
||||
double vz) {
|
||||
super(world, fluid, x, y, z, vx, vy, vz);
|
||||
particleGravity = 0;
|
||||
motionX = 0;
|
||||
motionY = 0;
|
||||
motionZ = 0;
|
||||
yOffset = world.rand.nextFloat() * 1 / 32f;
|
||||
posY += yOffset;
|
||||
particleScale = 0;
|
||||
maxAge = 60;
|
||||
Vec3d currentPos = new Vec3d(posX, posY, posZ);
|
||||
basinPos = new BlockPos(currentPos);
|
||||
centerOfBasin = VecHelper.getCenterOf(basinPos);
|
||||
|
||||
if (vx != 0) {
|
||||
maxAge = 20;
|
||||
Vec3d centerOf = VecHelper.getCenterOf(basinPos);
|
||||
Vec3d diff = currentPos.subtract(centerOf)
|
||||
.mul(1, 0, 1)
|
||||
.normalize()
|
||||
.scale(.375);
|
||||
targetPos = centerOf.add(diff);
|
||||
prevPosX = posX = centerOfBasin.x;
|
||||
prevPosZ = posZ = centerOfBasin.z;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
particleScale = targetPos != null ? Math.max(1 / 32f, ((1f * age) / maxAge) / 8)
|
||||
: 1 / 8f * (1 - ((Math.abs(age - (maxAge / 2)) / (1f * maxAge))));
|
||||
|
||||
if (age % 2 == 0) {
|
||||
if (!AllBlocks.BASIN.has(world.getBlockState(basinPos))) {
|
||||
setExpired();
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntity tileEntity = world.getTileEntity(basinPos);
|
||||
if (tileEntity instanceof BasinTileEntity) {
|
||||
float totalUnits = ((BasinTileEntity) tileEntity).getTotalFluidUnits();
|
||||
if (totalUnits < 1)
|
||||
totalUnits = 0;
|
||||
float fluidLevel = MathHelper.clamp(totalUnits / 2000, 0, 1);
|
||||
posY = 2 / 16f + basinPos.getY() + 12 / 16f * fluidLevel + yOffset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (targetPos != null) {
|
||||
float progess = (1f * age) / maxAge;
|
||||
Vec3d currentPos = centerOfBasin.add(targetPos.subtract(centerOfBasin)
|
||||
.scale(progess));
|
||||
posX = currentPos.x;
|
||||
posZ = currentPos.z;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildGeometry(IVertexBuilder vb, ActiveRenderInfo info, float pt) {
|
||||
Quaternion rotation = info.getRotation();
|
||||
Quaternion prevRotation = new Quaternion(rotation);
|
||||
rotation.set(1, 0, 0, 1);
|
||||
rotation.normalize();
|
||||
super.buildGeometry(vb, info, pt);
|
||||
rotation.set(0, 0, 0, 1);
|
||||
rotation.multiply(prevRotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canEvaporate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,8 @@ public class FluidParticleData implements IParticleData, ICustomParticleData<Flu
|
|||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public IParticleFactory<FluidParticleData> getFactory() {
|
||||
return (data, world, x, y, z, vx, vy, vz) -> new FluidStackParticle(world, data.fluid, x, y, z, vx, vy, vz);
|
||||
return (data, world, x, y, z, vx, vy, vz) -> FluidStackParticle.create(data.type, world, data.fluid, x, y, z,
|
||||
vx, vy, vz);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.fluids.particle;
|
||||
|
||||
import com.simibubi.create.AllParticleTypes;
|
||||
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluid;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
|
@ -7,6 +8,7 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.SpriteTexturedParticle;
|
||||
import net.minecraft.inventory.container.PlayerContainer;
|
||||
import net.minecraft.particles.ParticleType;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -17,6 +19,13 @@ public class FluidStackParticle extends SpriteTexturedParticle {
|
|||
private final float field_217588_H;
|
||||
private FluidStack fluid;
|
||||
|
||||
public static FluidStackParticle create(ParticleType<FluidParticleData> type, World world, FluidStack fluid, double x,
|
||||
double y, double z, double vx, double vy, double vz) {
|
||||
if (type == AllParticleTypes.BASIN_FLUID.get())
|
||||
return new BasinFluidParticle(world, fluid, x, y, z, vx, vy, vz);
|
||||
return new FluidStackParticle(world, fluid, x, y, z, vx, vy, vz);
|
||||
}
|
||||
|
||||
public FluidStackParticle(World world, FluidStack fluid, double x, double y, double z, double vx, double vy,
|
||||
double vz) {
|
||||
super(world, x, y, z, vx, vy, vz);
|
||||
|
@ -34,14 +43,25 @@ public class FluidStackParticle extends SpriteTexturedParticle {
|
|||
this.multiplyColor(fluid.getFluid()
|
||||
.getAttributes()
|
||||
.getColor(fluid));
|
||||
|
||||
this.motionX = vx;
|
||||
this.motionY = vy;
|
||||
this.motionZ = vz;
|
||||
|
||||
this.particleScale /= 2.0F;
|
||||
this.field_217587_G = this.rand.nextFloat() * 3.0F;
|
||||
this.field_217588_H = this.rand.nextFloat() * 3.0F;
|
||||
}
|
||||
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.TERRAIN_SHEET;
|
||||
@Override
|
||||
protected int getBrightnessForRender(float p_189214_1_) {
|
||||
int brightnessForRender = super.getBrightnessForRender(p_189214_1_);
|
||||
int skyLight = brightnessForRender >> 20;
|
||||
int blockLight = (brightnessForRender >> 4) & 0xf;
|
||||
blockLight = Math.max(blockLight, fluid.getFluid()
|
||||
.getAttributes()
|
||||
.getLuminosity(fluid));
|
||||
return (skyLight << 20) | (blockLight << 4);
|
||||
}
|
||||
|
||||
protected void multiplyColor(int color) {
|
||||
|
@ -69,13 +89,13 @@ public class FluidStackParticle extends SpriteTexturedParticle {
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!(fluid.getFluid() instanceof PotionFluid))
|
||||
if (!canEvaporate())
|
||||
return;
|
||||
if (onGround)
|
||||
setExpired();
|
||||
if (!isExpired)
|
||||
return;
|
||||
if (!onGround && world.rand.nextFloat() < 1/8f)
|
||||
if (!onGround && world.rand.nextFloat() < 1 / 8f)
|
||||
return;
|
||||
|
||||
Vec3d rgb = ColorHelper.getRGB(fluid.getFluid()
|
||||
|
@ -83,5 +103,14 @@ public class FluidStackParticle extends SpriteTexturedParticle {
|
|||
.getColor(fluid));
|
||||
world.addParticle(ParticleTypes.ENTITY_EFFECT, posX, posY, posZ, rgb.x, rgb.y, rgb.z);
|
||||
}
|
||||
|
||||
protected boolean canEvaporate() {
|
||||
return fluid.getFluid() instanceof PotionFluid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.TERRAIN_SHEET;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,14 +7,20 @@ import com.simibubi.create.foundation.fluid.FluidRenderer;
|
|||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.IntAttached;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -33,35 +39,92 @@ public class BasinRenderer extends SmartTileEntityRenderer<BasinTileEntity> {
|
|||
int light, int overlay) {
|
||||
super.renderSafe(basin, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
renderFluids(basin, partialTicks, ms, buffer, light, overlay);
|
||||
float fluidLevel = renderFluids(basin, partialTicks, ms, buffer, light, overlay);
|
||||
float level = MathHelper.clamp(fluidLevel - .3f, .125f, .6f);
|
||||
|
||||
ms.push();
|
||||
|
||||
BlockPos pos = basin.getPos();
|
||||
ms.translate(.5, .2f, .5);
|
||||
MatrixStacker.of(ms)
|
||||
.rotateY(basin.ingredientRotation.getValue(partialTicks));
|
||||
|
||||
Random r = new Random(pos.hashCode());
|
||||
Vec3d baseVector = new Vec3d(.125, level, 0);
|
||||
|
||||
IItemHandlerModifiable inv = basin.itemCapability.orElse(new ItemStackHandler());
|
||||
int itemCount = 0;
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++)
|
||||
if (!inv.getStackInSlot(slot)
|
||||
.isEmpty())
|
||||
itemCount++;
|
||||
|
||||
if (itemCount == 1)
|
||||
baseVector = new Vec3d(0, level, 0);
|
||||
|
||||
float anglePartition = 360f / itemCount;
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stack = inv.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
ms.push();
|
||||
|
||||
if (fluidLevel > 0) {
|
||||
ms.translate(0,
|
||||
(MathHelper.sin(AnimationTickHolder.getRenderTick() / 12f + anglePartition * itemCount) + 1.5f) * 1
|
||||
/ 32f,
|
||||
0);
|
||||
}
|
||||
|
||||
Vec3d itemPosition = VecHelper.rotate(baseVector, anglePartition * itemCount, Axis.Y);
|
||||
ms.translate(itemPosition.x, itemPosition.y, itemPosition.z);
|
||||
MatrixStacker.of(ms)
|
||||
.rotateY(anglePartition * itemCount + 35)
|
||||
.rotateX(65);
|
||||
|
||||
for (int i = 0; i <= stack.getCount() / 8; i++) {
|
||||
ms.push();
|
||||
Vec3d vec = VecHelper.offsetRandomly(Vec3d.ZERO, r, .25f);
|
||||
Vec3d vec2 = VecHelper.offsetRandomly(Vec3d.ZERO, r, .5f);
|
||||
Vec3d vec = VecHelper.offsetRandomly(Vec3d.ZERO, r, 1 / 16f);
|
||||
ms.translate(vec.x, vec.y, vec.z);
|
||||
ms.multiply(new Vector3f((float) vec2.z, (float) vec2.y, 0).getDegreesQuaternion((float) vec2.x * 180));
|
||||
|
||||
Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.renderItem(stack, TransformType.GROUND, light, overlay, ms, buffer);
|
||||
renderItem(ms, buffer, light, overlay, stack);
|
||||
ms.pop();
|
||||
}
|
||||
ms.translate(0, 1 / 64f, 0);
|
||||
ms.pop();
|
||||
|
||||
itemCount--;
|
||||
}
|
||||
ms.pop();
|
||||
|
||||
BlockState blockState = basin.getBlockState();
|
||||
if (!(blockState.getBlock() instanceof BasinBlock))
|
||||
return;
|
||||
Direction direction = blockState.get(BasinBlock.FACING);
|
||||
if (direction == Direction.DOWN)
|
||||
return;
|
||||
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
|
||||
Vec3d outVec = VecHelper.getCenterOf(BlockPos.ZERO)
|
||||
.add(directionVec.scale(.55)
|
||||
.subtract(0, 1 / 2f, 0));
|
||||
|
||||
for (IntAttached<ItemStack> intAttached : basin.visualizedOutputItems) {
|
||||
float progress = 1 - (intAttached.getFirst() - partialTicks) / BasinTileEntity.OUTPUT_ANIMATION_TIME;
|
||||
ms.push();
|
||||
MatrixStacker.of(ms)
|
||||
.translate(outVec)
|
||||
.translate(new Vec3d(0, Math.max(-.55f, -(progress * progress * 2)), 0))
|
||||
.translate(directionVec.scale(progress * .5f))
|
||||
.rotateY(AngleHelper.horizontalAngle(direction))
|
||||
.rotateX(progress * 180);
|
||||
renderItem(ms, buffer, light, overlay, intAttached.getValue());
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderItem(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay, ItemStack stack) {
|
||||
Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.renderItem(stack, TransformType.GROUND, light, overlay, ms, buffer);
|
||||
}
|
||||
|
||||
protected float renderFluids(BasinTileEntity basin, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
|
@ -69,26 +132,7 @@ public class BasinRenderer extends SmartTileEntityRenderer<BasinTileEntity> {
|
|||
SmartFluidTankBehaviour inputFluids = basin.getBehaviour(SmartFluidTankBehaviour.INPUT);
|
||||
SmartFluidTankBehaviour outputFluids = basin.getBehaviour(SmartFluidTankBehaviour.OUTPUT);
|
||||
SmartFluidTankBehaviour[] tanks = { inputFluids, outputFluids };
|
||||
int renderedFluids = 0;
|
||||
float totalUnits = 0;
|
||||
|
||||
for (SmartFluidTankBehaviour behaviour : tanks) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks()) {
|
||||
if (tankSegment.getRenderedFluid()
|
||||
.isEmpty())
|
||||
continue;
|
||||
float units = tankSegment.getTotalUnits(partialTicks);
|
||||
if (units < 1)
|
||||
continue;
|
||||
totalUnits += units;
|
||||
renderedFluids++;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderedFluids == 0)
|
||||
return 0;
|
||||
float totalUnits = basin.getTotalFluidUnits();
|
||||
if (totalUnits < 1)
|
||||
return 0;
|
||||
|
||||
|
@ -111,8 +155,8 @@ public class BasinRenderer extends SmartTileEntityRenderer<BasinTileEntity> {
|
|||
float units = tankSegment.getTotalUnits(partialTicks);
|
||||
if (units < 1)
|
||||
continue;
|
||||
|
||||
float partial = units / totalUnits;
|
||||
|
||||
float partial = MathHelper.clamp(units / totalUnits, 0, 1);
|
||||
xMax += partial * 12 / 16f;
|
||||
FluidRenderer.renderTiledFluidBB(renderedFluid, xMin, yMin, zMin, xMax, yMax, zMax, buffer, ms, light,
|
||||
false);
|
||||
|
@ -121,7 +165,7 @@ public class BasinRenderer extends SmartTileEntityRenderer<BasinTileEntity> {
|
|||
}
|
||||
}
|
||||
|
||||
return fluidLevel;
|
||||
return yMax;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package com.simibubi.create.content.contraptions.processing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.simibubi.create.AllParticleTypes;
|
||||
import com.simibubi.create.AllTags;
|
||||
import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerTileEntity;
|
||||
import com.simibubi.create.content.contraptions.fluids.FluidFX;
|
||||
import com.simibubi.create.content.contraptions.fluids.particle.FluidParticleData;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
|
@ -16,21 +23,32 @@ import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
|||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.IntAttached;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.LerpedFloat;
|
||||
import com.simibubi.create.foundation.utility.LerpedFloat.Chaser;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
|
@ -44,25 +62,44 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
|||
|
||||
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
||||
|
||||
private boolean areFluidsMoving;
|
||||
LerpedFloat ingredientRotationSpeed;
|
||||
LerpedFloat ingredientRotation;
|
||||
|
||||
public BasinInventory inputInventory;
|
||||
public SmartFluidTankBehaviour inputTank;
|
||||
protected SmartInventory outputInventory;
|
||||
protected SmartFluidTankBehaviour outputTank;
|
||||
private FilteringBehaviour filtering;
|
||||
private boolean contentsChanged;
|
||||
|
||||
private Couple<SmartInventory> invs;
|
||||
private Couple<SmartFluidTankBehaviour> tanks;
|
||||
|
||||
protected LazyOptional<IItemHandlerModifiable> itemCapability;
|
||||
protected LazyOptional<IFluidHandler> fluidCapability;
|
||||
|
||||
private FilteringBehaviour filtering;
|
||||
private boolean contentsChanged;
|
||||
public static final int OUTPUT_ANIMATION_TIME = 10;
|
||||
List<IntAttached<ItemStack>> visualizedOutputItems;
|
||||
List<IntAttached<FluidStack>> visualizedOutputFluids;
|
||||
|
||||
public BasinTileEntity(TileEntityType<? extends BasinTileEntity> type) {
|
||||
super(type);
|
||||
inputInventory = new BasinInventory(9, this);
|
||||
inputInventory.whenContentsChanged($ -> contentsChanged = true);
|
||||
outputInventory = new BasinInventory(9, this).forbidInsertion();
|
||||
|
||||
areFluidsMoving = false;
|
||||
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory));
|
||||
contentsChanged = true;
|
||||
ingredientRotation = LerpedFloat.angular()
|
||||
.startWithValue(0);
|
||||
ingredientRotationSpeed = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
|
||||
invs = Couple.create(inputInventory, outputInventory);
|
||||
tanks = Couple.create(inputTank, outputTank);
|
||||
visualizedOutputItems = Collections.synchronizedList(new ArrayList<>());
|
||||
visualizedOutputFluids = Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,6 +115,7 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true).forbidInsertion();
|
||||
behaviours.add(inputTank);
|
||||
behaviours.add(outputTank);
|
||||
|
||||
fluidCapability = LazyOptional.of(() -> {
|
||||
LazyOptional<? extends IFluidHandler> inputCap = inputTank.getCapability();
|
||||
LazyOptional<? extends IFluidHandler> outputCap = outputTank.getCapability();
|
||||
|
@ -90,6 +128,15 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
super.read(compound, clientPacket);
|
||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
|
||||
|
||||
if (!clientPacket)
|
||||
return;
|
||||
|
||||
NBTHelper.iterateCompoundList(compound.getList("VisualizedItems", NBT.TAG_COMPOUND),
|
||||
c -> visualizedOutputItems.add(IntAttached.with(OUTPUT_ANIMATION_TIME, ItemStack.read(c))));
|
||||
NBTHelper.iterateCompoundList(compound.getList("VisualizedFluids", NBT.TAG_COMPOUND),
|
||||
c -> visualizedOutputFluids
|
||||
.add(IntAttached.with(OUTPUT_ANIMATION_TIME, FluidStack.loadFluidStackFromNBT(c))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,6 +144,16 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
super.write(compound, clientPacket);
|
||||
compound.put("InputItems", inputInventory.serializeNBT());
|
||||
compound.put("OutputItems", outputInventory.serializeNBT());
|
||||
|
||||
if (!clientPacket)
|
||||
return;
|
||||
|
||||
compound.put("VisualizedItems", NBTHelper.writeCompoundList(visualizedOutputItems, ia -> ia.getValue()
|
||||
.serializeNBT()));
|
||||
compound.put("VisualizedFluids", NBTHelper.writeCompoundList(visualizedOutputFluids, ia -> ia.getValue()
|
||||
.writeToNBT(new CompoundNBT())));
|
||||
visualizedOutputItems.clear();
|
||||
visualizedOutputFluids.clear();
|
||||
}
|
||||
|
||||
public void onEmptied() {
|
||||
|
@ -129,11 +186,26 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
if (!world.isRemote)
|
||||
return;
|
||||
TileEntity tileEntity = world.getTileEntity(pos.up(2));
|
||||
if (!(tileEntity instanceof MechanicalMixerTileEntity)) {
|
||||
setAreFluidsMoving(false);
|
||||
return;
|
||||
}
|
||||
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tileEntity;
|
||||
setAreFluidsMoving(mixer.running && mixer.runningTicks <= 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (world.isRemote) {
|
||||
createFluidParticles();
|
||||
tickVisualizedOutputs();
|
||||
ingredientRotationSpeed.tickChaser();
|
||||
ingredientRotation.setValue(ingredientRotation.getValue() + ingredientRotationSpeed.getValue());
|
||||
}
|
||||
if (!contentsChanged)
|
||||
return;
|
||||
contentsChanged = false;
|
||||
|
@ -143,7 +215,8 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
BlockPos toUpdate = pos.up()
|
||||
.offset(offset);
|
||||
BlockState stateToUpdate = world.getBlockState(toUpdate);
|
||||
if (stateToUpdate.getBlock() instanceof BasinBlock && stateToUpdate.get(BasinBlock.FACING) == offset.getOpposite()) {
|
||||
if (stateToUpdate.getBlock() instanceof BasinBlock
|
||||
&& stateToUpdate.get(BasinBlock.FACING) == offset.getOpposite()) {
|
||||
TileEntity te = world.getTileEntity(toUpdate);
|
||||
if (te instanceof BasinTileEntity)
|
||||
((BasinTileEntity) te).contentsChanged = true;
|
||||
|
@ -151,6 +224,32 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
}
|
||||
}
|
||||
|
||||
public float getTotalFluidUnits() {
|
||||
int renderedFluids = 0;
|
||||
float totalUnits = 0;
|
||||
|
||||
for (SmartFluidTankBehaviour behaviour : getTanks()) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks()) {
|
||||
if (tankSegment.getRenderedFluid()
|
||||
.isEmpty())
|
||||
continue;
|
||||
float units = tankSegment.getTotalUnits(0);
|
||||
if (units < 1)
|
||||
continue;
|
||||
totalUnits += units;
|
||||
renderedFluids++;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderedFluids == 0)
|
||||
return 0;
|
||||
if (totalUnits < 1)
|
||||
return 0;
|
||||
return totalUnits;
|
||||
}
|
||||
|
||||
private Optional<BasinOperatingTileEntity> getOperator() {
|
||||
if (world == null)
|
||||
return Optional.empty();
|
||||
|
@ -224,6 +323,8 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate)
|
||||
.isEmpty())
|
||||
return false;
|
||||
else if (!simulate)
|
||||
visualizedOutputItems.add(IntAttached.withZero(itemStack));
|
||||
|
||||
if (targetTank == null)
|
||||
return false;
|
||||
|
@ -231,10 +332,145 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
if (targetTank.fill(fluidStack.copy(), simulate ? FluidAction.SIMULATE : FluidAction.EXECUTE) != fluidStack
|
||||
.getAmount())
|
||||
return false;
|
||||
else if (!simulate)
|
||||
visualizedOutputFluids.add(IntAttached.withZero(fluidStack));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void readOnlyItems(CompoundNBT compound) {
|
||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
|
||||
}
|
||||
|
||||
public static HeatLevel getHeatLevelOf(BlockState state) {
|
||||
if (state.has(BlazeBurnerBlock.HEAT_LEVEL))
|
||||
return state.get(BlazeBurnerBlock.HEAT_LEVEL);
|
||||
return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE;
|
||||
}
|
||||
|
||||
public Couple<SmartFluidTankBehaviour> getTanks() {
|
||||
return tanks;
|
||||
}
|
||||
|
||||
public Couple<SmartInventory> getInvs() {
|
||||
return invs;
|
||||
}
|
||||
|
||||
// client things
|
||||
|
||||
private void tickVisualizedOutputs() {
|
||||
visualizedOutputFluids.forEach(IntAttached::decrement);
|
||||
visualizedOutputItems.forEach(IntAttached::decrement);
|
||||
visualizedOutputFluids.removeIf(IntAttached::isOrBelowZero);
|
||||
visualizedOutputItems.removeIf(IntAttached::isOrBelowZero);
|
||||
}
|
||||
|
||||
private void createFluidParticles() {
|
||||
Random r = world.rand;
|
||||
|
||||
if (!visualizedOutputFluids.isEmpty())
|
||||
createOutputFluidParticles(r);
|
||||
|
||||
if (!areFluidsMoving && r.nextFloat() > 1 / 8f)
|
||||
return;
|
||||
|
||||
int segments = 0;
|
||||
for (SmartFluidTankBehaviour behaviour : getTanks()) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks())
|
||||
if (!tankSegment.isEmpty(0))
|
||||
segments++;
|
||||
}
|
||||
if (segments < 2)
|
||||
return;
|
||||
|
||||
float totalUnits = getTotalFluidUnits();
|
||||
if (totalUnits == 0)
|
||||
return;
|
||||
float fluidLevel = MathHelper.clamp(totalUnits / 2000, 0, 1);
|
||||
float rim = 2 / 16f;
|
||||
float space = 12 / 16f;
|
||||
float surface = pos.getY() + rim + space * fluidLevel + 1 / 32f;
|
||||
|
||||
if (areFluidsMoving) {
|
||||
createMovingFluidParticles(surface, segments);
|
||||
return;
|
||||
}
|
||||
|
||||
for (SmartFluidTankBehaviour behaviour : getTanks()) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks()) {
|
||||
if (tankSegment.isEmpty(0))
|
||||
continue;
|
||||
float x = pos.getX() + rim + space * r.nextFloat();
|
||||
float z = pos.getZ() + rim + space * r.nextFloat();
|
||||
world.addOptionalParticle(
|
||||
new FluidParticleData(AllParticleTypes.BASIN_FLUID.get(), tankSegment.getRenderedFluid()), x,
|
||||
surface, z, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createOutputFluidParticles(Random r) {
|
||||
BlockState blockState = getBlockState();
|
||||
if (!(blockState.getBlock() instanceof BasinBlock))
|
||||
return;
|
||||
Direction direction = blockState.get(BasinBlock.FACING);
|
||||
if (direction == Direction.DOWN)
|
||||
return;
|
||||
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
|
||||
Vec3d outVec = VecHelper.getCenterOf(pos)
|
||||
.add(directionVec.scale(.65)
|
||||
.subtract(0, 1 / 4f, 0));
|
||||
Vec3d outMotion = directionVec.scale(1 / 16f)
|
||||
.add(0, -1 / 16f, 0);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
visualizedOutputFluids.forEach(ia -> {
|
||||
FluidStack fluidStack = ia.getValue();
|
||||
IParticleData fluidParticle = FluidFX.getFluidParticle(fluidStack);
|
||||
Vec3d m = VecHelper.offsetRandomly(outMotion, r, 1 / 16f);
|
||||
world.addOptionalParticle(fluidParticle, outVec.x, outVec.y, outVec.z, m.x, m.y, m.z);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void createMovingFluidParticles(float surface, int segments) {
|
||||
Vec3d pointer = new Vec3d(1, 0, 0).scale(1 / 16f);
|
||||
float interval = 360f / segments;
|
||||
Vec3d centerOf = VecHelper.getCenterOf(pos);
|
||||
float intervalOffset = (AnimationTickHolder.ticks * 18) % 360;
|
||||
|
||||
int currentSegment = 0;
|
||||
for (SmartFluidTankBehaviour behaviour : getTanks()) {
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
for (TankSegment tankSegment : behaviour.getTanks()) {
|
||||
if (tankSegment.isEmpty(0))
|
||||
continue;
|
||||
float angle = interval * (1 + currentSegment) + intervalOffset;
|
||||
Vec3d vec = centerOf.add(VecHelper.rotate(pointer, angle, Axis.Y));
|
||||
world.addOptionalParticle(
|
||||
new FluidParticleData(AllParticleTypes.BASIN_FLUID.get(), tankSegment.getRenderedFluid()),
|
||||
vec.getX(), surface, vec.getZ(), 1, 0, 0);
|
||||
currentSegment++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean areFluidsMoving() {
|
||||
return areFluidsMoving;
|
||||
}
|
||||
|
||||
public boolean setAreFluidsMoving(boolean areFluidsMoving) {
|
||||
this.areFluidsMoving = areFluidsMoving;
|
||||
ingredientRotationSpeed.chase(areFluidsMoving ? 20 : 0, .1f, Chaser.EXP);
|
||||
return areFluidsMoving;
|
||||
}
|
||||
|
||||
class BasinValueBox extends ValueBoxTransform.Sided {
|
||||
|
||||
@Override
|
||||
|
@ -249,15 +485,4 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public void readOnlyItems(CompoundNBT compound) {
|
||||
inputInventory.deserializeNBT(compound.getCompound("InputItems"));
|
||||
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
|
||||
}
|
||||
|
||||
public static HeatLevel getHeatLevelOf(BlockState state) {
|
||||
if (state.has(BlazeBurnerBlock.HEAT_LEVEL))
|
||||
return state.get(BlazeBurnerBlock.HEAT_LEVEL);
|
||||
return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,6 +267,16 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour {
|
|||
.isEmpty())
|
||||
renderedFluid = tank.getFluid();
|
||||
}
|
||||
|
||||
public boolean isEmpty(float partialTicks) {
|
||||
FluidStack renderedFluid = getRenderedFluid();
|
||||
if (renderedFluid.isEmpty())
|
||||
return true;
|
||||
float units = getTotalUnits(partialTicks);
|
||||
if (units < 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
@ -12,7 +13,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
|
||||
public class Couple<T> extends Pair<T, T> {
|
||||
public class Couple<T> extends Pair<T, T> implements Iterable<T> {
|
||||
|
||||
private static Couple<Boolean> TRUE_AND_FALSE = Couple.create(true, false);
|
||||
|
||||
|
@ -62,7 +63,8 @@ public class Couple<T> extends Pair<T, T> {
|
|||
setSecond(function.apply(getSecond(), values.getSecond()));
|
||||
}
|
||||
|
||||
public void forEach(Consumer<T> consumer) {
|
||||
@Override
|
||||
public void forEach(Consumer<? super T> consumer) {
|
||||
consumer.accept(getFirst());
|
||||
consumer.accept(getSecond());
|
||||
}
|
||||
|
@ -89,4 +91,36 @@ public class Couple<T> extends Pair<T, T> {
|
|||
return new Couple<>(readCompoundList.get(0), readCompoundList.get(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Couplerator<>(this);
|
||||
}
|
||||
|
||||
private static class Couplerator<T> implements Iterator<T> {
|
||||
|
||||
int state;
|
||||
private Couple<T> couple;
|
||||
|
||||
public Couplerator(Couple<T> couple) {
|
||||
this.couple = couple;
|
||||
state = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return state != 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
state++;
|
||||
if (state == 1)
|
||||
return couple.first;
|
||||
if (state == 2)
|
||||
return couple.second;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
public class IntAttached<V> extends Pair<Integer, V> {
|
||||
|
||||
protected IntAttached(Integer first, V second) {
|
||||
super(first, second);
|
||||
}
|
||||
|
||||
public static <V> IntAttached<V> with(int number, V value) {
|
||||
return new IntAttached<>(number, value);
|
||||
}
|
||||
|
||||
public static <V> IntAttached<V> withZero(V value) {
|
||||
return new IntAttached<>(0, value);
|
||||
}
|
||||
|
||||
public boolean isZero() {
|
||||
return first.intValue() == 0;
|
||||
}
|
||||
|
||||
public boolean isOrBelowZero() {
|
||||
return first.intValue() <= 0;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
first++;
|
||||
}
|
||||
|
||||
public void decrement() {
|
||||
first--;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return getSecond();
|
||||
}
|
||||
|
||||
}
|
|
@ -123,23 +123,10 @@
|
|||
"up": {"uv": [6, 0, 8, 6], "rotation": 90, "texture": "#3"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "BackBottom",
|
||||
"from": [3.9, -2, 18],
|
||||
"to": [12.1, 2, 26],
|
||||
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, -4, 17]},
|
||||
"faces": {
|
||||
"east": {"uv": [12, 12, 14, 16], "rotation": 270, "texture": "#7"},
|
||||
"south": {"uv": [8, 13, 12, 15], "rotation": 180, "texture": "#7"},
|
||||
"west": {"uv": [12, 12, 14, 16], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [8, 12, 12, 16], "rotation": 180, "texture": "#7"},
|
||||
"down": {"uv": [8, 12, 12, 16], "rotation": 180, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Back",
|
||||
"from": [2.1, -2.1, 14],
|
||||
"to": [13.9, 13.9, 17.9],
|
||||
"to": [13.9, 13.95, 18.1],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 6]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 4, 16, 16], "rotation": 90, "texture": "#5"},
|
||||
|
@ -204,7 +191,7 @@
|
|||
{
|
||||
"name": "Base",
|
||||
"origin": [9, -4, 8],
|
||||
"children": [9, 10, 11, 12, 13]
|
||||
"children": [9, 10, 11, 12]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -108,23 +108,10 @@
|
|||
"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "BackBottom",
|
||||
"from": [3.9, -2, 18],
|
||||
"to": [12.1, 2, 26],
|
||||
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, -4, 17]},
|
||||
"faces": {
|
||||
"east": {"uv": [12, 12, 14, 16], "rotation": 270, "texture": "#7"},
|
||||
"south": {"uv": [8, 13, 12, 15], "rotation": 180, "texture": "#7"},
|
||||
"west": {"uv": [12, 12, 14, 16], "rotation": 270, "texture": "#7"},
|
||||
"up": {"uv": [8, 12, 12, 16], "rotation": 180, "texture": "#7"},
|
||||
"down": {"uv": [8, 12, 12, 16], "rotation": 180, "texture": "#7"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Back",
|
||||
"from": [2.1, -2.1, 14],
|
||||
"to": [13.9, 13.9, 17.9],
|
||||
"to": [13.9, 13.95, 18.1],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -8.1, 6]},
|
||||
"faces": {
|
||||
"east": {"uv": [0, 0, 16, 4], "rotation": 90, "texture": "#5"},
|
||||
|
@ -196,8 +183,8 @@
|
|||
{
|
||||
"name": "Base",
|
||||
"origin": [9, -4, 8],
|
||||
"children": [8, 9, 10, 11, 12]
|
||||
"children": [8, 9, 10, 11]
|
||||
}
|
||||
]
|
||||
}, 13]
|
||||
}, 12]
|
||||
}
|
|
@ -3,11 +3,10 @@
|
|||
"parent": "create:block/large_wheels",
|
||||
"textures": {
|
||||
"6": "create:block/crushing_wheel_body",
|
||||
"spruce_log_top": "block/spruce_log",
|
||||
"spruce_log_top": "create:block/smooth_dark_log_top",
|
||||
"axis_top": "create:block/axis_top",
|
||||
"axis": "create:block/axis",
|
||||
"crushing_wheel": "create:block/crushing_wheel",
|
||||
"spruce_log": "block/spruce_log",
|
||||
"particle": "block/polished_andesite"
|
||||
},
|
||||
"elements": [
|
||||
|
@ -27,68 +26,69 @@
|
|||
},
|
||||
{
|
||||
"name": "B1",
|
||||
"from": [2, 2, -8],
|
||||
"to": [9, 14, 7],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [2, 1.95, -8],
|
||||
"to": [9, 14.05, 7],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 6, 11, 12], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"up": {"uv": [0, 9.5, 7.5, 13], "rotation": 270, "texture": "#6"},
|
||||
"down": {"uv": [0, 9.5, 7.5, 13], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B2",
|
||||
"from": [2, 2.1, -8],
|
||||
"to": [10, 13.9, 7],
|
||||
"from": [2, 1.9, -8],
|
||||
"to": [10, 14.1, 7],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"north": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 270, "texture": "#6"},
|
||||
"west": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 270, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B3",
|
||||
"from": [2, 2, -8],
|
||||
"to": [9, 14, 7],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [2, 1.95, -8],
|
||||
"to": [9, 14.05, 7],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [11, 0, 14.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 270, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B4",
|
||||
"from": [2, 2.1, -8],
|
||||
"to": [10, 13.9, 7],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [2, 1.9, -8],
|
||||
"to": [10, 14.1, 7],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8.05, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"north": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [8.5, 12.5, 16, 16], "rotation": 270, "texture": "#6"},
|
||||
"west": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 270, "texture": "#6"},
|
||||
"down": {"uv": [8.5, 12.5, 16, 16], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B5",
|
||||
"from": [-8, 2, 7],
|
||||
"to": [7, 14, 14],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [-8, 1.95, 7],
|
||||
"to": [7, 14.05, 14],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"west": {"uv": [7.5, 6, 11, 12], "texture": "#6"},
|
||||
"up": {"uv": [0, 9.5, 7.5, 13], "rotation": 180, "texture": "#6"},
|
||||
"down": {"uv": [0, 9.5, 7.5, 13], "rotation": 180, "texture": "#6"}
|
||||
|
@ -96,26 +96,27 @@
|
|||
},
|
||||
{
|
||||
"name": "B6",
|
||||
"from": [-8, 2.1, 6],
|
||||
"to": [7, 13.9, 14],
|
||||
"from": [-8, 1.9, 6],
|
||||
"to": [7, 14.1, 14],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"west": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 180, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 180, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B7",
|
||||
"from": [-8, 2, 7],
|
||||
"to": [7, 14, 14],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [-8, 1.95, 7],
|
||||
"to": [7, 14.05, 14],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"west": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 180, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 180, "texture": "#6"}
|
||||
|
@ -123,26 +124,26 @@
|
|||
},
|
||||
{
|
||||
"name": "B8",
|
||||
"from": [-8, 2.1, 6],
|
||||
"to": [7, 13.9, 14],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [-8, 1.9, 6],
|
||||
"to": [7, 14.1, 14],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [11, 0, 14.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [8.5, 12.5, 16, 16], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"west": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 180, "texture": "#6"},
|
||||
"down": {"uv": [8.5, 12.5, 16, 16], "rotation": 180, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B9",
|
||||
"from": [7, 2, 9],
|
||||
"to": [14, 14, 24],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [7, 1.95, 9],
|
||||
"to": [14, 14.05, 24],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [7.5, 6, 11, 12], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 9.5, 7.5, 13], "rotation": 90, "texture": "#6"},
|
||||
|
@ -151,26 +152,27 @@
|
|||
},
|
||||
{
|
||||
"name": "B10",
|
||||
"from": [6, 2.1, 9],
|
||||
"to": [14, 13.9, 24],
|
||||
"from": [6, 1.9, 9],
|
||||
"to": [14, 14.1, 24],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 90, "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 10], "rotation": 90, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 270, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B11",
|
||||
"from": [7, 2, 9],
|
||||
"to": [14, 14, 24],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [7, 1.95, 9],
|
||||
"to": [14, 14.05, 24],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [11, 0, 14.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [7.5, 6, 11, 12], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [8.5, 12.5, 16, 16], "rotation": 90, "texture": "#6"},
|
||||
"down": {"uv": [8.5, 12.5, 16, 16], "rotation": 270, "texture": "#6"}
|
||||
|
@ -178,25 +180,25 @@
|
|||
},
|
||||
{
|
||||
"name": "B12",
|
||||
"from": [6, 2.1, 9],
|
||||
"to": [14, 13.9, 24],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [6, 1.9, 9],
|
||||
"to": [14, 14.1, 24],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"east": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"south": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 90, "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 90, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 270, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B13",
|
||||
"from": [9, 2, 2],
|
||||
"to": [24, 14, 9],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [9, 1.95, 2],
|
||||
"to": [24, 14.05, 9],
|
||||
"rotation": {"angle": -22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"north": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"east": {"uv": [7.5, 6, 11, 12], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
|
@ -206,24 +208,25 @@
|
|||
},
|
||||
{
|
||||
"name": "B14",
|
||||
"from": [9, 2.1, 2],
|
||||
"to": [24, 13.9, 10],
|
||||
"from": [9, 1.9, 2],
|
||||
"to": [24, 14.1, 10],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"north": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"east": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "texture": "#6"},
|
||||
"up": {"uv": [0, 7.5, 7.5, 11.5], "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "texture": "#6"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "B15",
|
||||
"from": [9, 2, 2],
|
||||
"to": [24, 14, 9],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [9, 1.95, 2],
|
||||
"to": [24, 14.05, 9],
|
||||
"rotation": {"angle": 22.5, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"north": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"east": {"uv": [11, 0, 14.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"west": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
|
@ -233,15 +236,15 @@
|
|||
},
|
||||
{
|
||||
"name": "B16",
|
||||
"from": [2, 2.1, -8],
|
||||
"to": [10, 13.9, 7],
|
||||
"rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]},
|
||||
"from": [2, 1.9, -8],
|
||||
"to": [10, 14.1, 7],
|
||||
"rotation": {"angle": -45, "axis": "y", "origin": [8, 7.95, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"north": {"uv": [3.5, 0, 7.5, 6], "texture": "#6"},
|
||||
"east": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"south": {"uv": [7.5, 0, 11, 6], "texture": "#6"},
|
||||
"west": {"uv": [0, 0, 7.5, 6], "texture": "#6"},
|
||||
"up": {"uv": [0, 6, 7.5, 9.5], "rotation": 270, "texture": "#6"},
|
||||
"west": {"uv": [1.5, 6, 7.5, 0], "rotation": 180, "texture": "#6"},
|
||||
"up": {"uv": [0, 6.5, 7.5, 10.5], "rotation": 270, "texture": "#6"},
|
||||
"down": {"uv": [0, 6, 7.5, 9.5], "rotation": 90, "texture": "#6"}
|
||||
}
|
||||
},
|
||||
|
@ -251,18 +254,18 @@
|
|||
"to": [12, 15, 12],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": {"uv": [4, 1, 12, 15], "texture": "#spruce_log"},
|
||||
"east": {"uv": [4, 1, 12, 15], "texture": "#spruce_log"},
|
||||
"south": {"uv": [4, 1, 12, 15], "texture": "#spruce_log"},
|
||||
"west": {"uv": [4, 1, 12, 15], "texture": "#spruce_log"},
|
||||
"north": {"uv": [4, 1, 12, 15], "texture": "#spruce_log_top"},
|
||||
"east": {"uv": [4, 1, 12, 15], "texture": "#spruce_log_top"},
|
||||
"south": {"uv": [4, 1, 12, 15], "texture": "#spruce_log_top"},
|
||||
"west": {"uv": [4, 1, 12, 15], "texture": "#spruce_log_top"},
|
||||
"up": {"uv": [4, 4, 12, 12], "texture": "#spruce_log_top"},
|
||||
"down": {"uv": [4, 4, 12, 12], "texture": "#spruce_log_top"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cover",
|
||||
"from": [-4, 1.9, -4],
|
||||
"to": [20, 14.1, 20],
|
||||
"from": [-4, 1.85, -4],
|
||||
"to": [20, 14.15, 20],
|
||||
"faces": {
|
||||
"up": {"uv": [2, 2, 14, 14], "texture": "#crushing_wheel"},
|
||||
"down": {"uv": [2, 2, 14, 14], "texture": "#crushing_wheel"}
|
||||
|
@ -276,4 +279,4 @@
|
|||
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{}
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 826 B |
Loading…
Reference in a new issue