From 56fe0c9c8af66d101b3df903231e2482dd90ad44 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 29 May 2020 17:59:56 +0200 Subject: [PATCH 01/17] S.A.T. will separate thee! - Implemented a prototype of a new collision resolver that supports rotated bounding boxes --- .../ContraptionCollider.java | 179 +++++++++++++----- .../structureMovement/ContraptionEntity.java | 7 +- .../bearing/MechanicalBearingTileEntity.java | 32 ++-- .../create/foundation/collision/Matrix3d.java | 117 ++++++++++++ .../foundation/collision/OrientedBB.java | 148 +++++++++++++++ 5 files changed, 417 insertions(+), 66 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java create mode 100644 src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 768d7a906..8071ed2bb 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -3,8 +3,14 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.mutable.MutableBoolean; + import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour; +import com.simibubi.create.foundation.collision.Matrix3d; +import com.simibubi.create.foundation.collision.OrientedBB; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.block.CocoaBlock; @@ -23,7 +29,6 @@ import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -43,10 +48,11 @@ public class ContraptionCollider { return; World world = contraptionEntity.getEntityWorld(); - Vec3d contraptionMotion = contraptionEntity.getMotion(); +// Vec3d contraptionMotion = contraptionEntity.getMotion(); Contraption contraption = contraptionEntity.getContraption(); AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); Vec3d contraptionPosition = contraptionEntity.getPositionVec(); + Vec3d contraptionRotation = contraptionEntity.getRotationVec(); contraptionEntity.collidingEntities.clear(); if (contraption == null) @@ -55,41 +61,104 @@ public class ContraptionCollider { return; for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(1), - e -> canBeCollidedWith(e))) { - - ReuseableStream potentialHits = - getPotentiallyCollidedShapes(world, contraption, contraptionPosition, entity); - if (potentialHits.createStream().count() == 0) - continue; - - Vec3d positionOffset = contraptionPosition.scale(-1); - AxisAlignedBB entityBB = entity.getBoundingBox().offset(positionOffset).grow(1.0E-7D); - Vec3d entityMotion = entity.getMotion(); - Vec3d relativeMotion = entityMotion.subtract(contraptionMotion); - Vec3d allowedMovement = Entity.getAllowedMovement(relativeMotion, entityBB, world, - ISelectionContext.forEntity(entity), potentialHits); - potentialHits.createStream() - .forEach(voxelShape -> pushEntityOutOfShape(entity, voxelShape, positionOffset, contraptionMotion)); - - contraptionEntity.collidingEntities.add(entity); - - if (allowedMovement.equals(relativeMotion)) - continue; - - if (allowedMovement.y != relativeMotion.y) { - entity.handleFallDamage(entity.fallDistance, 1); - entity.fallDistance = 0; - entity.onGround = true; - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); - } - - if (entity instanceof ServerPlayerEntity) - ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; + e -> canBeCollidedWith(e))) { if (entity instanceof PlayerEntity && !world.isRemote) return; - entity.setMotion(allowedMovement.add(contraptionMotion)); - entity.velocityChanged = true; + Vec3d centerOf = VecHelper.getCenterOf(BlockPos.ZERO); + Vec3d entityPosition = entity.getPositionVec(); + Vec3d position = entityPosition.subtract(contraptionPosition) + .subtract(centerOf); + position = + VecHelper.rotate(position, -contraptionRotation.x, -contraptionRotation.y, -contraptionRotation.z); + position = position.add(centerOf) + .subtract(entityPosition); + AxisAlignedBB localBB = entity.getBoundingBox() + .offset(position) + .grow(1.0E-7D); + + OrientedBB obb = new OrientedBB(localBB); + if (!contraptionRotation.equals(Vec3d.ZERO)) { + Matrix3d rotation = new Matrix3d().asIdentity(); + rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(contraptionRotation.x))); + rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(contraptionRotation.y))); + rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(contraptionRotation.z))); + obb.setRotation(rotation); + } + + ReuseableStream potentialHits = getPotentiallyCollidedShapes(world, contraption, localBB); + if (potentialHits.createStream() + .count() == 0) + continue; + + MutableBoolean onCollide = new MutableBoolean(true); + potentialHits.createStream() + .forEach(shape -> { + AxisAlignedBB bb = shape.getBoundingBox(); + Vec3d intersect = obb.intersect(bb); + if (intersect == null) + return; + intersect = VecHelper.rotate(intersect, contraptionRotation.x, contraptionRotation.y, + contraptionRotation.z); + + obb.setCenter(obb.getCenter() + .add(intersect)); + entity.move(MoverType.PISTON, intersect); + + Vec3d entityMotion = entity.getMotion(); + if (entityMotion.getX() > 0 == intersect.getX() < 0) + entityMotion = entityMotion.mul(0, 1, 1); + if (entityMotion.getY() > 0 == intersect.getY() < 0) + entityMotion = entityMotion.mul(1, 0, 1); + if (entityMotion.getZ() > 0 == intersect.getZ() < 0) + entityMotion = entityMotion.mul(1, 1, 0); + entity.setMotion(entityMotion); + + if (onCollide.isTrue()) { + onCollide.setFalse(); + contraptionEntity.collidingEntities.add(entity); + entity.velocityChanged = true; + } + + if (intersect.y > 0) { + entity.handleFallDamage(entity.fallDistance, 1); + entity.fallDistance = 0; + entity.onGround = true; + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); + } + + if (entity instanceof ServerPlayerEntity) + ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; + }); + +// Vec3d positionOffset = contraptionPosition.scale(-1); +// AxisAlignedBB entityBB = entity.getBoundingBox() +// .offset(positionOffset) +// .grow(1.0E-7D); +// Vec3d entityMotion = entity.getMotion(); +// Vec3d relativeMotion = entityMotion.subtract(contraptionMotion); +// Vec3d allowedMovement = Entity.getAllowedMovement(relativeMotion, entityBB, world, +// ISelectionContext.forEntity(entity), potentialHits); +// potentialHits.createStream() +// .forEach(voxelShape -> pushEntityOutOfShape(entity, voxelShape, positionOffset, contraptionMotion)); +// +// +// if (allowedMovement.equals(relativeMotion)) +// continue; +// +// if (allowedMovement.y != relativeMotion.y) { +// entity.handleFallDamage(entity.fallDistance, 1); +// entity.fallDistance = 0; +// entity.onGround = true; +// DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); +// } +// +// if (entity instanceof ServerPlayerEntity) +// ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; +// if (entity instanceof PlayerEntity && !world.isRemote) +// return; +// +// entity.setMotion(allowedMovement.add(contraptionMotion)); } } @@ -112,11 +181,14 @@ public class ContraptionCollider { } public static void pushEntityOutOfShape(Entity entity, VoxelShape voxelShape, Vec3d positionOffset, - Vec3d shapeMotion) { - AxisAlignedBB entityBB = entity.getBoundingBox().offset(positionOffset); + Vec3d shapeMotion) { + AxisAlignedBB entityBB = entity.getBoundingBox() + .offset(positionOffset); Vec3d entityMotion = entity.getMotion(); - if (!voxelShape.toBoundingBoxList().stream().anyMatch(entityBB::intersects)) + if (!voxelShape.toBoundingBoxList() + .stream() + .anyMatch(entityBB::intersects)) return; AxisAlignedBB shapeBB = voxelShape.getBoundingBox(); @@ -127,8 +199,7 @@ public class ContraptionCollider { for (Direction face : Direction.values()) { Axis axis = face.getAxis(); double d = axis == Axis.X ? entityBB.getXSize() + shapeBB.getXSize() - : axis == Axis.Y ? entityBB.getYSize() + shapeBB.getYSize() - : entityBB.getZSize() + shapeBB.getZSize(); + : axis == Axis.Y ? entityBB.getYSize() + shapeBB.getYSize() : entityBB.getZSize() + shapeBB.getZSize(); d = d + .5f; Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d); @@ -171,13 +242,14 @@ public class ContraptionCollider { } public static ReuseableStream getPotentiallyCollidedShapes(World world, Contraption contraption, - Vec3d contraptionPosition, Entity entity) { - AxisAlignedBB blockScanBB = entity.getBoundingBox().offset(contraptionPosition.scale(-1)).grow(.5f); + AxisAlignedBB localBB) { + AxisAlignedBB blockScanBB = localBB.grow(.5f); BlockPos min = new BlockPos(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ); BlockPos max = new BlockPos(blockScanBB.maxX, blockScanBB.maxY, blockScanBB.maxZ); - ReuseableStream potentialHits = - new ReuseableStream<>(BlockPos.getAllInBox(min, max).filter(contraption.blocks::containsKey).map(p -> { + ReuseableStream potentialHits = new ReuseableStream<>(BlockPos.getAllInBox(min, max) + .filter(contraption.blocks::containsKey) + .map(p -> { BlockState blockState = contraption.blocks.get(p).state; BlockPos pos = contraption.blocks.get(p).pos; VoxelShape collisionShape = blockState.getCollisionShape(world, p); @@ -217,7 +289,7 @@ public class ContraptionCollider { // Other moving Contraptions for (ContraptionEntity otherContraptionEntity : world.getEntitiesWithinAABB(ContraptionEntity.class, - bounds.grow(1), e -> !e.equals(contraptionEntity))) { + bounds.grow(1), e -> !e.equals(contraptionEntity))) { if (!otherContraptionEntity.collisionEnabled()) continue; @@ -232,11 +304,13 @@ public class ContraptionCollider { if (otherBounds == null) return false; - if (!bounds.offset(motion).intersects(otherBounds.offset(otherMotion))) + if (!bounds.offset(motion) + .intersects(otherBounds.offset(otherMotion))) continue; for (BlockPos colliderPos : contraption.getColliders(world, movementDirection)) { - colliderPos = colliderPos.add(gridPos).subtract(new BlockPos(otherPosition)); + colliderPos = colliderPos.add(gridPos) + .subtract(new BlockPos(otherPosition)); if (!otherContraption.blocks.containsKey(colliderPos)) continue; return true; @@ -247,7 +321,7 @@ public class ContraptionCollider { } public static boolean isCollidingWithWorld(World world, Contraption contraption, BlockPos anchor, - Direction movementDirection) { + Direction movementDirection) { for (BlockPos pos : contraption.getColliders(world, movementDirection)) { BlockPos colliderPos = pos.add(anchor); @@ -263,7 +337,8 @@ public class ContraptionCollider { BlockBreakingMovementBehaviour behaviour = (BlockBreakingMovementBehaviour) block.getMovementBehaviour(); if (!behaviour.canBreak(world, colliderPos, collidedState) - && !collidedState.getCollisionShape(world, pos).isEmpty()) { + && !collidedState.getCollisionShape(world, pos) + .isEmpty()) { return true; } continue; @@ -271,12 +346,14 @@ public class ContraptionCollider { } if (AllBlocks.PULLEY_MAGNET.has(collidedState) && pos.equals(BlockPos.ZERO) - && movementDirection == Direction.UP) + && movementDirection == Direction.UP) continue; if (collidedState.getBlock() instanceof CocoaBlock) continue; - if (!collidedState.getMaterial().isReplaceable() - && !collidedState.getCollisionShape(world, colliderPos).isEmpty()) { + if (!collidedState.getMaterial() + .isReplaceable() + && !collidedState.getCollisionShape(world, colliderPos) + .isEmpty()) { return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index af3528114..731e3cd51 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -14,7 +14,6 @@ import com.simibubi.create.AllEntityTypes; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption; -import com.simibubi.create.content.contraptions.components.structureMovement.piston.LinearActuatorTileEntity; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.AngleHelper; @@ -136,7 +135,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public boolean collisionEnabled() { - return getController() instanceof LinearActuatorTileEntity; + return true; } @Override @@ -624,5 +623,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public float getInitialAngle() { return initialAngle; } + + public Vec3d getRotationVec() { + return new Vec3d(pitch, yaw, roll); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index fdd2ae3e8..f5463d1ad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -46,7 +46,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); movementMode = new ScrollOptionBehaviour<>(RotationMode.class, Lang.translate("contraptions.movement_mode"), - this, getMovementModeSlot()); + this, getMovementModeSlot()); movementMode.requiresWrench(); behaviours.add(movementMode); } @@ -64,7 +64,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp public void neighbourChanged() { if (!hasWorld()) return; - + boolean shouldWindmill = world.isBlockPowered(pos); if (shouldWindmill == isWindmill) return; @@ -153,7 +153,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp } public void assemble() { - if (!(world.getBlockState(pos).getBlock() instanceof MechanicalBearingBlock)) + if (!(world.getBlockState(pos) + .getBlock() instanceof MechanicalBearingBlock)) return; Direction direction = getBlockState().get(FACING); @@ -168,7 +169,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp return; contraption.removeBlocksFromWorld(world, BlockPos.ZERO); - movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this); + movedContraption = ContraptionEntity.createStationary(world, contraption) + .controlledBy(this); BlockPos anchor = pos.offset(direction); movedContraption.setPosition(anchor.getX(), anchor.getY(), anchor.getZ()); world.addEntity(movedContraption); @@ -206,7 +208,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp if (world.isRemote) clientAngleDiff /= 2; - + if (movedContraption != null) + movedContraption.collisionTick(); if (running && Contraption.isFrozen()) disassemble(); @@ -214,11 +217,12 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp assembleNextTick = false; if (running) { boolean canDisassemble = movementMode.get() == RotationMode.ROTATE_PLACE - || (isNearInitialAngle() && movementMode.get() == RotationMode.ROTATE_PLACE_RETURNED); + || (isNearInitialAngle() && movementMode.get() == RotationMode.ROTATE_PLACE_RETURNED); if (speed == 0 && (canDisassemble || movedContraption == null - || movedContraption.getContraption().blocks.isEmpty())) { + || movedContraption.getContraption().blocks.isEmpty())) { if (movedContraption != null) - movedContraption.getContraption().stop(world); + movedContraption.getContraption() + .stop(world); disassemble(); } return; @@ -255,9 +259,11 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp protected void applyRotation() { if (movedContraption != null) { - Axis axis = getBlockState().get(FACING).getAxis(); + Axis axis = getBlockState().get(FACING) + .getAxis(); Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); - Vec3d vec = new Vec3d(1, 1, 1).scale(angle).mul(new Vec3d(direction.getDirectionVec())); + Vec3d vec = new Vec3d(1, 1, 1).scale(angle) + .mul(new Vec3d(direction.getDirectionVec())); movedContraption.rotateTo(vec.x, vec.y, vec.z); } } @@ -294,14 +300,14 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp protected ValueBoxTransform getMovementModeSlot() { return new DirectionalExtenderScrollOptionSlot((state, d) -> { Axis axis = d.getAxis(); - Axis bearingAxis = state.get(MechanicalBearingBlock.FACING).getAxis(); + Axis bearingAxis = state.get(MechanicalBearingBlock.FACING) + .getAxis(); return bearingAxis != axis; }); } @Override - public void collided() { - } + public void collided() {} @Override public boolean isAttachedTo(ContraptionEntity contraption) { diff --git a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java new file mode 100644 index 000000000..473e97f13 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java @@ -0,0 +1,117 @@ +package com.simibubi.create.foundation.collision; + +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class Matrix3d { + + double m00, m01, m02; + double m10, m11, m12; + double m20, m21, m22; + + public Matrix3d asIdentity() { + m00 = m11 = m22 = 1; + m01 = m02 = m10 = m12 = m20 = m21 = 0; + return this; + } + + public Matrix3d asXRotation(float radians) { + asIdentity(); + double s = MathHelper.sin(radians); + double c = MathHelper.cos(radians); + m22 = m11 = c; + m21 = s; + m12 = -s; + return this; + } + + public Matrix3d asYRotation(float radians) { + asIdentity(); + double s = MathHelper.sin(radians); + double c = MathHelper.cos(radians); + m00 = m22 = c; + m20 = s; + m02 = -s; + return this; + } + + public Matrix3d asZRotation(float radians) { + asIdentity(); + double s = MathHelper.sin(radians); + double c = MathHelper.cos(radians); + m00 = m11 = c; + m01 = -s; + m10 = s; + return this; + } + + public Matrix3d transpose() { + double d = m01; + m01 = m10; + m10 = d; + d = m02; + m02 = m20; + m20 = d; + d = m12; + m12 = m21; + m21 = d; + return this; + } + + public Matrix3d scale(double d) { + m00 *= d; + m11 *= d; + m22 *= d; + return this; + } + + public Matrix3d add(Matrix3d matrix) { + m00 += matrix.m00; + m01 += matrix.m01; + m02 += matrix.m02; + m10 += matrix.m10; + m11 += matrix.m11; + m12 += matrix.m12; + m20 += matrix.m20; + m21 += matrix.m21; + m22 += matrix.m22; + return this; + } + + public Matrix3d multiply(Matrix3d m) { + double new00 = m00 * m.m00 + m01 * m.m10 + m02 * m.m20; + double new01 = m00 * m.m01 + m01 * m.m11 + m02 * m.m21; + double new02 = m00 * m.m02 + m01 * m.m12 + m02 * m.m22; + double new10 = m10 * m.m00 + m11 * m.m10 + m12 * m.m20; + double new11 = m10 * m.m01 + m11 * m.m11 + m12 * m.m21; + double new12 = m10 * m.m02 + m11 * m.m12 + m12 * m.m22; + double new20 = m20 * m.m00 + m21 * m.m10 + m22 * m.m20; + double new21 = m20 * m.m01 + m21 * m.m11 + m22 * m.m21; + double new22 = m20 * m.m02 + m21 * m.m12 + m22 * m.m22; + m00 = new00; + m01 = new01; + m02 = new02; + m10 = new10; + m11 = new11; + m12 = new12; + m20 = new20; + m21 = new21; + m22 = new22; + return this; + } + + public Vec3d transform(Vec3d vec) { + double x = vec.x; + double y = vec.y; + double z = vec.z; + x = x * m00 + y * m01 + z * m02; + y = x * m10 + y * m11 + z * m12; + z = x * m20 + y * m21 + z * m22; + return new Vec3d(x, y, z); + } + + public Matrix3d copy() { + return new Matrix3d().add(this); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java new file mode 100644 index 000000000..fc80f26d0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java @@ -0,0 +1,148 @@ +package com.simibubi.create.foundation.collision; + +import static java.lang.Math.abs; + +import org.apache.commons.lang3.mutable.MutableDouble; +import org.apache.commons.lang3.mutable.MutableObject; + +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; + +public class OrientedBB { + + Vec3d center; + Vec3d extents; + Matrix3d rotation; + + public OrientedBB(AxisAlignedBB bb) { + this(bb.getCenter(), extentsFromBB(bb), new Matrix3d().asIdentity()); + } + + public OrientedBB() { + this(Vec3d.ZERO, Vec3d.ZERO, new Matrix3d().asIdentity()); + } + + public OrientedBB(Vec3d center, Vec3d extents, Matrix3d rotation) { + this.setCenter(center); + this.extents = extents; + this.setRotation(rotation); + } + + public Vec3d intersect(AxisAlignedBB bb) { + Vec3d extentsA = extentsFromBB(bb); + // Inverse rotation, to bring our OBB to AA space + Vec3d intersects = separateBBs(bb.getCenter(), center, extentsA, extents, rotation.transpose()); + // clean up + rotation.transpose(); + return intersects; + } + + private static Vec3d extentsFromBB(AxisAlignedBB bb) { + return new Vec3d(bb.getXSize() / 2, bb.getYSize() / 2, bb.getZSize() / 2); + } + + public static Vec3d separateBBs(Vec3d cA, Vec3d cB, Vec3d eA, Vec3d eB, Matrix3d m) { + Vec3d t = cB.subtract(cA); + double a00 = abs(m.m00); + double a01 = abs(m.m01); + double a02 = abs(m.m02); + double a10 = abs(m.m10); + double a11 = abs(m.m11); + double a12 = abs(m.m12); + double a20 = abs(m.m20); + double a21 = abs(m.m21); + double a22 = abs(m.m22); + + MutableObject bestAxis = new MutableObject<>(Vec3d.ZERO); + MutableDouble bestSep = new MutableDouble(Double.MAX_VALUE); + + Vec3d uA0 = new Vec3d(1, 0, 0); + Vec3d uA1 = new Vec3d(0, 1, 0); + Vec3d uA2 = new Vec3d(0, 0, 1); + + Vec3d uB0 = new Vec3d(m.m00, m.m01, m.m02); + Vec3d uB1 = new Vec3d(m.m10, m.m11, m.m12); + Vec3d uB2 = new Vec3d(m.m20, m.m21, m.m22); + + checkCount = 0; + + if ( + + // Separate along A's local axes (global XYZ) + !(isSeparatedAlong(bestAxis, bestSep, uA0, t.x, eA.x, a00 * eB.x + a01 * eB.y + a02 * eB.z) + || isSeparatedAlong(bestAxis, bestSep, uA1, t.y, eA.y, a10 * eB.x + a11 * eB.y + a12 * eB.z) + || isSeparatedAlong(bestAxis, bestSep, uA2, t.z, eA.z, a20 * eB.x + a21 * eB.y + a22 * eB.z) + + // Separate along B's local axes + || isSeparatedAlong(bestAxis, bestSep, uB0, t.x * m.m00 + t.y * m.m10 + t.z * m.m20, + eA.x * a00 + eA.y * a10 + eA.z * a20, eB.x) + || isSeparatedAlong(bestAxis, bestSep, uB1, t.x * m.m01 + t.y * m.m11 + t.z * m.m21, + eA.x * a01 + eA.y * a11 + eA.z * a21, eB.y) + || isSeparatedAlong(bestAxis, bestSep, uB2, t.x * m.m02 + t.y * m.m12 + t.z * m.m22, + eA.x * a02 + eA.y * a12 + eA.z * a22, eB.z) + + // Separate along axes perpendicular to AxB + || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB0), t.z * m.m10 - t.y * m.m20, + eA.y * a20 + eA.z * a10, eB.y * a02 + eB.z * a01) + || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB1), t.z * m.m11 - t.y * m.m21, + eA.y * a21 + eA.z * a11, eB.x * a02 + eB.z * a00) + || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB2), t.z * m.m12 - t.y * m.m22, + eA.y * a22 + eA.z * a12, eB.x * a01 + eB.y * a00) + + || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB0), t.x * m.m20 - t.z * m.m00, + eA.x * a20 + eA.z * a00, eB.y * a12 + eB.z * a11) + || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB1), t.x * m.m21 - t.z * m.m01, + eA.x * a21 + eA.z * a01, eB.x * a12 + eB.z * a10) + || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB2), t.x * m.m22 - t.z * m.m02, + eA.x * a22 + eA.z * a02, eB.x * a11 + eB.y * a10) + + || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB0), t.y * m.m00 - t.x * m.m10, + eA.x * a10 + eA.y * a00, eB.y * a22 + eB.z * a21) + || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB1), t.y * m.m01 - t.x * m.m11, + eA.x * a11 + eA.y * a01, eB.x * a22 + eB.z * a20) + || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB2), t.y * m.m02 - t.x * m.m12, + eA.x * a12 + eA.y * a02, eB.x * a21 + eB.y * a20))) + + return bestAxis.getValue() + .normalize() + .scale(bestSep.getValue()); + + return null; + } + + static int checkCount = 0; + + static boolean isSeparatedAlong(MutableObject bestAxis, MutableDouble bestSeparation, Vec3d axis, double TL, + double rA, double rB) { + double distance = abs(TL); + + checkCount++; + + double diff = distance - (rA + rB); + if (diff > 0) + return true; + if (distance != 0 && -diff < abs(bestSeparation.getValue())) { + bestAxis.setValue(axis); + bestSeparation.setValue(Math.signum(TL) * abs(diff)); + } + + return false; + } + + public Matrix3d getRotation() { + return rotation; + } + + public void setRotation(Matrix3d rotation) { + this.rotation = rotation; + } + + public Vec3d getCenter() { + return center; + } + + public void setCenter(Vec3d center) { + this.center = center; + } + +} From d9105b4e60efbd531f1c03eb35034d2826bd3463 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 19 Jun 2020 14:14:42 +0200 Subject: [PATCH 02/17] Collision refinements - Fixed reversed matrices and swapped rotation axes passed into the collision resolver - Temporarily reduced collision manifold generation to collisions that are NOT edge-to-edge collisions. - Enabled collision response for clockwork bearings --- .../com/simibubi/create/ClientEvents.java | 2 + .../com/simibubi/create/CreateClient.java | 1 + .../ContraptionCollider.java | 36 +++--- .../bearing/ClockworkBearingTileEntity.java | 4 + .../collision/CollisionDebugger.java | 82 ++++++++++++++ .../create/foundation/collision/Matrix3d.java | 24 ++++ .../foundation/collision/OrientedBB.java | 105 ++++++++++++------ 7 files changed, 203 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/ClientEvents.java index cd986dc09..1ad2cd5b8 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/ClientEvents.java @@ -73,6 +73,7 @@ public class ClientEvents { SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); CreateClient.schematicHandler.render(ms, buffer); CreateClient.outliner.renderOutlines(ms, buffer); +// CollisionDebugger.render(ms, buffer); buffer.draw(); ms.pop(); @@ -110,6 +111,7 @@ public class ClientEvents { double delta = event.getScrollDelta(); +// CollisionDebugger.onScroll(delta); boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta) || CreateClient.schematicAndQuillHandler.mouseScrolled(delta) || FilteringHandler.onScroll(delta) || ScrollValueHandler.onScroll(delta); diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 54a9d8b36..96361fccf 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -109,6 +109,7 @@ public class CreateClient { KineticDebugger.tick(); ZapperRenderHandler.tick(); ExtendoGripRenderHandler.tick(); +// CollisionDebugger.tick(); outliner.tickOutlines(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 8071ed2bb..3291cc07b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -65,32 +65,36 @@ public class ContraptionCollider { if (entity instanceof PlayerEntity && !world.isRemote) return; - Vec3d centerOf = VecHelper.getCenterOf(BlockPos.ZERO); + Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO); Vec3d entityPosition = entity.getPositionVec(); + Vec3d centerY = new Vec3d(0, entity.getBoundingBox() + .getYSize() / 2, 0); Vec3d position = entityPosition.subtract(contraptionPosition) - .subtract(centerOf); + .subtract(centerOfBlock) + .add(centerY); position = - VecHelper.rotate(position, -contraptionRotation.x, -contraptionRotation.y, -contraptionRotation.z); - position = position.add(centerOf) + VecHelper.rotate(position, -contraptionRotation.z, -contraptionRotation.y, -contraptionRotation.x); + position = position.add(centerOfBlock) + .subtract(centerY) .subtract(entityPosition); AxisAlignedBB localBB = entity.getBoundingBox() .offset(position) .grow(1.0E-7D); - OrientedBB obb = new OrientedBB(localBB); - if (!contraptionRotation.equals(Vec3d.ZERO)) { - Matrix3d rotation = new Matrix3d().asIdentity(); - rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(contraptionRotation.x))); - rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(contraptionRotation.y))); - rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(contraptionRotation.z))); - obb.setRotation(rotation); - } - ReuseableStream potentialHits = getPotentiallyCollidedShapes(world, contraption, localBB); if (potentialHits.createStream() .count() == 0) continue; + OrientedBB obb = new OrientedBB(localBB); + if (!contraptionRotation.equals(Vec3d.ZERO)) { + Matrix3d rotation = new Matrix3d().asIdentity(); + rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(contraptionRotation.z))); + rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(contraptionRotation.y))); + rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(contraptionRotation.x))); + obb.setRotation(rotation); + } + MutableBoolean onCollide = new MutableBoolean(true); potentialHits.createStream() .forEach(shape -> { @@ -98,12 +102,12 @@ public class ContraptionCollider { Vec3d intersect = obb.intersect(bb); if (intersect == null) return; - intersect = VecHelper.rotate(intersect, contraptionRotation.x, contraptionRotation.y, - contraptionRotation.z); + intersect = VecHelper.rotate(intersect, contraptionRotation.z, contraptionRotation.y, + contraptionRotation.x); obb.setCenter(obb.getCenter() .add(intersect)); - entity.move(MoverType.PISTON, intersect); + entity.move(MoverType.PLAYER, intersect); Vec3d entityMotion = entity.getMotion(); if (entityMotion.getX() > 0 == intersect.getX() < 0) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index d137d9c31..ed6aac7ba 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -47,6 +47,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe if (running && Contraption.isFrozen()) disassemble(); + if (hourHand != null) + hourHand.collisionTick(); + if (minuteHand != null) + minuteHand.collisionTick(); if (!world.isRemote && assembleNextTick) { assembleNextTick = false; diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java new file mode 100644 index 000000000..9901e28f4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java @@ -0,0 +1,82 @@ +package com.simibubi.create.foundation.collision; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllSpecialTextures; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.outliner.AABBOutline; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.RayTraceResult.Type; +import net.minecraft.util.math.Vec3d; + +public class CollisionDebugger { + + static AxisAlignedBB staticBB = new AxisAlignedBB(BlockPos.ZERO.up(10)); + static OrientedBB movingBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO)); + static Vec3d seperation; + static double angle = 0; + static AABBOutline outline; + + public static void onScroll(double delta) { + angle += delta; + movingBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); + } + + public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + ms.push(); + outline = new AABBOutline(movingBB.getAsAxisAlignedBB()); + outline.getParams() + .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null) + .colored(0xffffff); + if (seperation != null) + outline.getParams() + .lineWidth(1 / 64f) + .colored(0xff6544); + MatrixStacker.of(ms) + .translate(movingBB.center); + ms.peek() + .getModel() + .multiply(movingBB.rotation.getAsMatrix4f()); + MatrixStacker.of(ms) + .translateBack(movingBB.center); + outline.render(ms, buffer); + ms.pop(); + + ms.push(); + if (seperation != null) { + outline.getParams() + .colored(0x65ff44) + .lineWidth(1 / 32f); + MatrixStacker.of(ms) + .translate(seperation) + .translate(movingBB.center); + ms.peek() + .getModel() + .multiply(movingBB.rotation.getAsMatrix4f()); + MatrixStacker.of(ms) + .translateBack(movingBB.center); + outline.render(ms, buffer); + } + ms.pop(); + } + + public static void tick() { + staticBB = new AxisAlignedBB(BlockPos.ZERO.up(60)); + RayTraceResult mouse = Minecraft.getInstance().objectMouseOver; + if (mouse != null && mouse.getType() == Type.BLOCK) { + BlockRayTraceResult hit = (BlockRayTraceResult) mouse; + movingBB.setCenter(hit.getHitVec()); + seperation = movingBB.intersect(staticBB); + } + CreateClient.outliner.showAABB(staticBB, staticBB) + .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java index 473e97f13..49f31a2cd 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java +++ b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java @@ -1,7 +1,10 @@ package com.simibubi.create.foundation.collision; +import net.minecraft.client.renderer.Matrix4f; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; public class Matrix3d { @@ -113,5 +116,26 @@ public class Matrix3d { public Matrix3d copy() { return new Matrix3d().add(this); } + + float[] conversionBuffer = new float[16]; + + @OnlyIn(Dist.CLIENT) + public Matrix4f getAsMatrix4f() { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + conversionBuffer[j * 4 + i] = i == j ? 1 : 0; + + conversionBuffer[0] = (float) m00; + conversionBuffer[1] = (float) m01; + conversionBuffer[2] = (float) m02; + conversionBuffer[4] = (float) m10; + conversionBuffer[5] = (float) m11; + conversionBuffer[6] = (float) m12; + conversionBuffer[8] = (float) m20; + conversionBuffer[9] = (float) m21; + conversionBuffer[10] = (float) m22; + + return new Matrix4f(conversionBuffer); + } } diff --git a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java index fc80f26d0..1fa62944d 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java +++ b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java @@ -5,6 +5,8 @@ import static java.lang.Math.abs; import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableObject; +import com.simibubi.create.CreateClient; + import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.Vec3d; @@ -30,10 +32,7 @@ public class OrientedBB { public Vec3d intersect(AxisAlignedBB bb) { Vec3d extentsA = extentsFromBB(bb); - // Inverse rotation, to bring our OBB to AA space - Vec3d intersects = separateBBs(bb.getCenter(), center, extentsA, extents, rotation.transpose()); - // clean up - rotation.transpose(); + Vec3d intersects = separateBBs(bb.getCenter(), center, extentsA, extents, rotation); return intersects; } @@ -60,9 +59,9 @@ public class OrientedBB { Vec3d uA1 = new Vec3d(0, 1, 0); Vec3d uA2 = new Vec3d(0, 0, 1); - Vec3d uB0 = new Vec3d(m.m00, m.m01, m.m02); - Vec3d uB1 = new Vec3d(m.m10, m.m11, m.m12); - Vec3d uB2 = new Vec3d(m.m20, m.m21, m.m22); + Vec3d uB0 = new Vec3d(m.m00, m.m10, m.m20); + Vec3d uB1 = new Vec3d(m.m01, m.m11, m.m21); + Vec3d uB2 = new Vec3d(m.m02, m.m12, m.m22); checkCount = 0; @@ -74,34 +73,42 @@ public class OrientedBB { || isSeparatedAlong(bestAxis, bestSep, uA2, t.z, eA.z, a20 * eB.x + a21 * eB.y + a22 * eB.z) // Separate along B's local axes - || isSeparatedAlong(bestAxis, bestSep, uB0, t.x * m.m00 + t.y * m.m10 + t.z * m.m20, + || isSeparatedAlong(bestAxis, bestSep, uB0, (t.x * m.m00 + t.y * m.m10 + t.z * m.m20), eA.x * a00 + eA.y * a10 + eA.z * a20, eB.x) - || isSeparatedAlong(bestAxis, bestSep, uB1, t.x * m.m01 + t.y * m.m11 + t.z * m.m21, + || isSeparatedAlong(bestAxis, bestSep, uB1, (t.x * m.m01 + t.y * m.m11 + t.z * m.m21), eA.x * a01 + eA.y * a11 + eA.z * a21, eB.y) - || isSeparatedAlong(bestAxis, bestSep, uB2, t.x * m.m02 + t.y * m.m12 + t.z * m.m22, + || isSeparatedAlong(bestAxis, bestSep, uB2, (t.x * m.m02 + t.y * m.m12 + t.z * m.m22), eA.x * a02 + eA.y * a12 + eA.z * a22, eB.z) - // Separate along axes perpendicular to AxB - || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB0), t.z * m.m10 - t.y * m.m20, - eA.y * a20 + eA.z * a10, eB.y * a02 + eB.z * a01) - || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB1), t.z * m.m11 - t.y * m.m21, - eA.y * a21 + eA.z * a11, eB.x * a02 + eB.z * a00) - || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB2), t.z * m.m12 - t.y * m.m22, - eA.y * a22 + eA.z * a12, eB.x * a01 + eB.y * a00) + /* + * The following checks (edge-to-edge) need special separation logic. They are + * not necessary as long as the obb is only rotated around one axis at a time + * (Which is the case for contraptions at the moment) + * + */ - || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB0), t.x * m.m20 - t.z * m.m00, - eA.x * a20 + eA.z * a00, eB.y * a12 + eB.z * a11) - || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB1), t.x * m.m21 - t.z * m.m01, - eA.x * a21 + eA.z * a01, eB.x * a12 + eB.z * a10) - || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB2), t.x * m.m22 - t.z * m.m02, - eA.x * a22 + eA.z * a02, eB.x * a11 + eB.y * a10) - - || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB0), t.y * m.m00 - t.x * m.m10, - eA.x * a10 + eA.y * a00, eB.y * a22 + eB.z * a21) - || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB1), t.y * m.m01 - t.x * m.m11, - eA.x * a11 + eA.y * a01, eB.x * a22 + eB.z * a20) - || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB2), t.y * m.m02 - t.x * m.m12, - eA.x * a12 + eA.y * a02, eB.x * a21 + eB.y * a20))) + // Separate along axes perpendicular to AxB +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB0), t.z * m.m10 - t.y * m.m20, +// eA.y * a20 + eA.z * a10, eB.y * a02 + eB.z * a01) +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB1), t.z * m.m11 - t.y * m.m21, +// eA.y * a21 + eA.z * a11, eB.x * a02 + eB.z * a00) +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB2), t.z * m.m12 - t.y * m.m22, +// eA.y * a22 + eA.z * a12, eB.x * a01 + eB.y * a00) +// +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB0), t.x * m.m20 - t.z * m.m00, +// eA.x * a20 + eA.z * a00, eB.y * a12 + eB.z * a11) +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB1), t.x * m.m21 - t.z * m.m01, +// eA.x * a21 + eA.z * a01, eB.x * a12 + eB.z * a10) +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB2), t.x * m.m22 - t.z * m.m02, +// eA.x * a22 + eA.z * a02, eB.x * a11 + eB.y * a10) +// +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB0), t.y * m.m00 - t.x * m.m10, +// eA.x * a10 + eA.y * a00, eB.y * a22 + eB.z * a21) +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB1), t.y * m.m01 - t.x * m.m11, +// eA.x * a11 + eA.y * a01, eB.x * a22 + eB.z * a20) +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB2), t.y * m.m02 - t.x * m.m12, +// eA.x * a12 + eA.y * a02, eB.x * a21 + eB.y * a20) + )) return bestAxis.getValue() .normalize() @@ -121,18 +128,41 @@ public class OrientedBB { double diff = distance - (rA + rB); if (diff > 0) return true; - if (distance != 0 && -diff < abs(bestSeparation.getValue())) { - bestAxis.setValue(axis); - bestSeparation.setValue(Math.signum(TL) * abs(diff)); + boolean isBestSeperation = distance != 0 && -(diff) <= abs(bestSeparation.getValue()); +// boolean isBestSeperation = checkCount == 12; // Debug specific separations + if (isBestSeperation) { + bestAxis.setValue(axis.normalize()); + double sTL = Math.signum(TL); + double value = sTL * abs(diff); + bestSeparation.setValue(value); + + // Visualize values +// if (CollisionDebugger.staticBB != null) { +// Vec3d normalizedAxis = axis.normalize(); +// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(TL), 0xbb00bb, "tl", 4); +// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(sTL * rA), 0xff4444, "ra", 3); +// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), normalizedAxis.scale(TL), 0x4444ff, "rb", 2); +// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), +// normalizedAxis.scale(sTL * (distance - rB) + value), 0xff9966, "separation", 1); +// System.out.println("TL:" + TL + ", rA: " + rA + ", rB: " + rB); +// } } return false; } + static void showDebugLine(Vec3d relativeStart, Vec3d relativeEnd, int color, String id, int offset) { + Vec3d center = CollisionDebugger.staticBB.getCenter() + .add(0, 1 + offset / 16f, 0); + CreateClient.outliner.showLine(id + checkCount, center.add(relativeStart), center.add(relativeEnd)) + .colored(color) + .lineWidth(1 / 32f); + } + public Matrix3d getRotation() { return rotation; } - + public void setRotation(Matrix3d rotation) { this.rotation = rotation; } @@ -140,9 +170,14 @@ public class OrientedBB { public Vec3d getCenter() { return center; } - + public void setCenter(Vec3d center) { this.center = center; } + public AxisAlignedBB getAsAxisAlignedBB() { + return new AxisAlignedBB(0, 0, 0, 0, 0, 0).offset(center) + .grow(extents.x, extents.y, extents.z); + } + } From a13d9fcedefe6c9e02f4004f98fe51b985009fc1 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Mon, 22 Jun 2020 10:58:02 +0200 Subject: [PATCH 03/17] CollideCarts - Contraptions now run their collision from a separate ticking hook - Minecart mounted contraptions now run the collision algorithm --- gradle.properties | 2 +- .../ContraptionCollider.java | 128 ++++++++++-------- .../structureMovement/ContraptionEntity.java | 90 ++++++++---- 3 files changed, 135 insertions(+), 85 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5d6ed258b..648b66d9a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.daemon=false # mod version info mod_version=0.3 minecraft_version=1.15.2 -forge_version=31.2.3 +forge_version=31.2.21 # dependency versions registrate_version=0.0.3.17 diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 3291cc07b..235858024 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -1,10 +1,18 @@ package com.simibubi.create.content.contraptions.components.structureMovement; -import java.util.HashMap; -import java.util.Map; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutionException; import org.apache.commons.lang3.mutable.MutableBoolean; +import com.google.common.base.Predicates; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour; import com.simibubi.create.foundation.collision.Matrix3d; @@ -14,11 +22,10 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.block.CocoaBlock; -import net.minecraft.block.material.PushReaction; import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.IProjectile; import net.minecraft.entity.MoverType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; @@ -34,21 +41,72 @@ import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.TickEvent.ClientTickEvent; +import net.minecraftforge.event.TickEvent.Phase; +import net.minecraftforge.event.TickEvent.WorldTickEvent; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +@EventBusSubscriber public class ContraptionCollider { - static Map renderedBBs = new HashMap<>(); public static boolean wasClientPlayerGrounded; + public static Cache>> activeContraptions = CacheBuilder.newBuilder() + .expireAfterAccess(20, SECONDS) + .build(); + + @SubscribeEvent + public static void addSpawnedContraptionsToCollisionList(EntityJoinWorldEvent event) { + Entity entity = event.getEntity(); + if (!(entity instanceof ContraptionEntity)) + return; + try { + List> list = activeContraptions.get(event.getWorld(), ArrayList::new); + ContraptionEntity contraption = (ContraptionEntity) entity; + list.add(new WeakReference<>(contraption)); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void playerCollisionHappensOnClientTick(ClientTickEvent event) { + if (event.phase == Phase.START) + return; + ClientWorld world = Minecraft.getInstance().world; + if (world == null) + return; + runCollisions(world); + } + + @SubscribeEvent + public static void entityCollisionHappensPreWorldTick(WorldTickEvent event) { + if (event.phase == Phase.START) + return; + World world = event.world; + runCollisions(world); + } + + private static void runCollisions(World world) { + List> list = activeContraptions.getIfPresent(world); + if (list == null) + return; + for (Iterator> iterator = list.iterator(); iterator.hasNext();) { + WeakReference weakReference = iterator.next(); + ContraptionEntity contraptionEntity = weakReference.get(); + if (contraptionEntity == null || !contraptionEntity.isAlive()) { + iterator.remove(); + continue; + } + collideEntities(contraptionEntity); + } + } public static void collideEntities(ContraptionEntity contraptionEntity) { - if (Contraption.isFrozen()) - return; - if (!contraptionEntity.collisionEnabled()) - return; - World world = contraptionEntity.getEntityWorld(); -// Vec3d contraptionMotion = contraptionEntity.getMotion(); Contraption contraption = contraptionEntity.getContraption(); AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); Vec3d contraptionPosition = contraptionEntity.getPositionVec(); @@ -61,7 +119,7 @@ public class ContraptionCollider { return; for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(1), - e -> canBeCollidedWith(e))) { + contraptionEntity::canCollideWith)) { if (entity instanceof PlayerEntity && !world.isRemote) return; @@ -70,7 +128,7 @@ public class ContraptionCollider { Vec3d centerY = new Vec3d(0, entity.getBoundingBox() .getYSize() / 2, 0); Vec3d position = entityPosition.subtract(contraptionPosition) - .subtract(centerOfBlock) + .subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0)) .add(centerY); position = VecHelper.rotate(position, -contraptionRotation.z, -contraptionRotation.y, -contraptionRotation.x); @@ -107,7 +165,7 @@ public class ContraptionCollider { obb.setCenter(obb.getCenter() .add(intersect)); - entity.move(MoverType.PLAYER, intersect); + entity.move(MoverType.PISTON, intersect); Vec3d entityMotion = entity.getMotion(); if (entityMotion.getX() > 0 == intersect.getX() < 0) @@ -134,49 +192,10 @@ public class ContraptionCollider { if (entity instanceof ServerPlayerEntity) ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; }); - -// Vec3d positionOffset = contraptionPosition.scale(-1); -// AxisAlignedBB entityBB = entity.getBoundingBox() -// .offset(positionOffset) -// .grow(1.0E-7D); -// Vec3d entityMotion = entity.getMotion(); -// Vec3d relativeMotion = entityMotion.subtract(contraptionMotion); -// Vec3d allowedMovement = Entity.getAllowedMovement(relativeMotion, entityBB, world, -// ISelectionContext.forEntity(entity), potentialHits); -// potentialHits.createStream() -// .forEach(voxelShape -> pushEntityOutOfShape(entity, voxelShape, positionOffset, contraptionMotion)); -// -// -// if (allowedMovement.equals(relativeMotion)) -// continue; -// -// if (allowedMovement.y != relativeMotion.y) { -// entity.handleFallDamage(entity.fallDistance, 1); -// entity.fallDistance = 0; -// entity.onGround = true; -// DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); -// } -// -// if (entity instanceof ServerPlayerEntity) -// ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; -// if (entity instanceof PlayerEntity && !world.isRemote) -// return; -// -// entity.setMotion(allowedMovement.add(contraptionMotion)); } } - public static boolean canBeCollidedWith(Entity e) { - if (e instanceof PlayerEntity && e.isSpectator()) - return false; - if (e.noClip) - return false; - if (e instanceof IProjectile) - return false; - return e.getPushReaction() == PushReaction.NORMAL; - } - @OnlyIn(Dist.CLIENT) private static void checkForClientPlayerCollision(Entity entity) { if (entity != Minecraft.getInstance().player) @@ -258,7 +277,8 @@ public class ContraptionCollider { BlockPos pos = contraption.blocks.get(p).pos; VoxelShape collisionShape = blockState.getCollisionShape(world, p); return collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ()); - })); + }) + .filter(Predicates.not(VoxelShape::isEmpty))); return potentialHits; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index 731e3cd51..db84d00ca 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -12,6 +12,7 @@ import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntityTypes; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption; import com.simibubi.create.foundation.item.ItemHelper; @@ -24,8 +25,11 @@ import net.minecraft.block.material.PushReaction; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.IProjectile; import net.minecraft.entity.item.BoatEntity; +import net.minecraft.entity.item.HangingEntity; import net.minecraft.entity.item.minecart.FurnaceMinecartEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.crafting.Ingredient; @@ -103,7 +107,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle, - Direction facing) { + Direction facing) { ContraptionEntity entity = createMounted(world, contraption, initialAngle); entity.forcedAngle = facing.getHorizontalAngle(); entity.forceYaw(entity.forcedAngle); @@ -170,7 +174,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void collisionTick() { - ContraptionCollider.collideEntities(this); +// ContraptionCollider.collideEntities(this); } public void tickAsPassenger(Entity e) { @@ -233,14 +237,17 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD int i = MathHelper.floor(furnaceCart.getX()); int j = MathHelper.floor(furnaceCart.getY()); int k = MathHelper.floor(furnaceCart.getZ()); - if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k)).isIn(BlockTags.RAILS)) + if (furnaceCart.world.getBlockState(new BlockPos(i, j - 1, k)) + .isIn(BlockTags.RAILS)) --j; BlockPos blockpos = new BlockPos(i, j, k); BlockState blockstate = this.world.getBlockState(blockpos); if (furnaceCart.canUseRail() && blockstate.isIn(BlockTags.RAILS)) if (fuel > 1) - riding.setMotion(riding.getMotion().normalize().scale(1)); + riding.setMotion(riding.getMotion() + .normalize() + .scale(1)); if (fuel < 5 && contraption != null) { ItemStack coal = ItemHelper.extract(contraption.inventory, FUEL_ITEMS, 1, false); if (!coal.isEmpty()) @@ -277,7 +284,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD Vec3d actorPosition = new Vec3d(blockInfo.pos); actorPosition = actorPosition.add(actor.getActiveAreaOffset(context)); actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch); - actorPosition = actorPosition.add(rotationOffset).add(getAnchorVec()); + actorPosition = actorPosition.add(rotationOffset) + .add(getAnchorVec()); boolean newPosVisited = false; BlockPos gridPosition = new BlockPos(actorPosition); @@ -290,7 +298,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD relativeMotion = VecHelper.rotate(relativeMotion, -angleRoll, -angleYaw, -anglePitch); context.relativeMotion = relativeMotion; newPosVisited = !new BlockPos(previousPosition).equals(gridPosition) - || context.relativeMotion.length() > 0 && context.firstMovement; + || context.relativeMotion.length() > 0 && context.firstMovement; } if (getContraption() instanceof BearingContraption) { @@ -298,10 +306,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD Direction facing = bc.getFacing(); Vec3d activeAreaOffset = actor.getActiveAreaOffset(context); if (activeAreaOffset.mul(VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec()))) - .equals(Vec3d.ZERO)) { + .equals(Vec3d.ZERO)) { if (VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) { - context.motion = new Vec3d(facing.getDirectionVec()).scale( - facing.getAxis().getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch)); + context.motion = new Vec3d(facing.getDirectionVec()).scale(facing.getAxis() + .getCoordinate(roll - prevRoll, yaw - prevYaw, pitch - prevPitch)); context.relativeMotion = context.motion; int timer = context.data.getInt("StationaryTimer"); if (timer > 0) { @@ -333,7 +341,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (getController() != null) getController().onStall(); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionStallPacket(getEntityId(), getX(), getY(), getZ(), yaw, pitch, roll)); + new ContraptionStallPacket(getEntityId(), getX(), getY(), getZ(), yaw, pitch, roll)); } dataManager.set(STALLED, contraption.stalled); } else { @@ -353,7 +361,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public void rotateTo(double roll, double yaw, double pitch) { rotate(getShortestAngleDiff(this.roll, roll), getShortestAngleDiff(this.yaw, yaw), - getShortestAngleDiff(this.pitch, pitch)); + getShortestAngleDiff(this.pitch, pitch)); } @Override @@ -397,7 +405,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public float getYaw(float partialTicks) { return (getRidingEntity() == null ? 1 : -1) - * (partialTicks == 1.0F ? yaw : angleLerp(partialTicks, prevYaw, yaw)) + initialAngle; + * (partialTicks == 1.0F ? yaw : angleLerp(partialTicks, prevYaw, yaw)) + initialAngle; } public float getPitch(float partialTicks) { @@ -463,7 +471,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD compound.put("Contraption", contraption.writeNBT()); if (!stationary && motionBeforeStall != null) compound.put("CachedMotion", - newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z)); + newDoubleNBTList(motionBeforeStall.x, motionBeforeStall.y, motionBeforeStall.z)); if (controllerPos != null) compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); if (forcedAngle != -1) @@ -504,8 +512,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } @Override - protected void doWaterSplashEffect() { - } + protected void doWaterSplashEffect() {} public void preventMovedEntitiesFromGettingStuck() { Vec3d stuckTest = new Vec3d(0, -2, 0); @@ -514,31 +521,33 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD e.onGround = true; Vec3d vec = stuckTest; - AxisAlignedBB axisalignedbb = e.getBoundingBox().offset(0, 2, 0); + AxisAlignedBB axisalignedbb = e.getBoundingBox() + .offset(0, 2, 0); ISelectionContext iselectioncontext = ISelectionContext.forEntity(this); - VoxelShape voxelshape = e.world.getWorldBorder().getShape(); + VoxelShape voxelshape = e.world.getWorldBorder() + .getShape(); Stream stream = VoxelShapes.compare(voxelshape, VoxelShapes.create(axisalignedbb.shrink(1.0E-7D)), IBooleanFunction.AND) - ? Stream.empty() - : Stream.of(voxelshape); + ? Stream.empty() + : Stream.of(voxelshape); Stream stream1 = this.world.getEmptyCollisionShapes(e, axisalignedbb.expand(vec), ImmutableSet.of()); ReuseableStream reuseablestream = new ReuseableStream<>(Stream.concat(stream1, stream)); Vec3d vec3d = vec.lengthSquared() == 0.0D ? vec - : collideBoundingBoxHeuristically(this, vec, axisalignedbb, e.world, iselectioncontext, - reuseablestream); + : collideBoundingBoxHeuristically(this, vec, axisalignedbb, e.world, iselectioncontext, + reuseablestream); boolean flag = vec.x != vec3d.x; boolean flag1 = vec.y != vec3d.y; boolean flag2 = vec.z != vec3d.z; boolean flag3 = e.onGround || flag1 && vec.y < 0.0D; if (this.stepHeight > 0.0F && flag3 && (flag || flag2)) { Vec3d vec3d1 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, (double) e.stepHeight, vec.z), - axisalignedbb, e.world, iselectioncontext, reuseablestream); + axisalignedbb, e.world, iselectioncontext, reuseablestream); Vec3d vec3d2 = collideBoundingBoxHeuristically(e, new Vec3d(0.0D, (double) e.stepHeight, 0.0D), - axisalignedbb.expand(vec.x, 0.0D, vec.z), e.world, iselectioncontext, reuseablestream); + axisalignedbb.expand(vec.x, 0.0D, vec.z), e.world, iselectioncontext, reuseablestream); if (vec3d2.y < (double) e.stepHeight) { Vec3d vec3d3 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, 0.0D, vec.z), - axisalignedbb.offset(vec3d2), e.world, iselectioncontext, reuseablestream).add(vec3d2); + axisalignedbb.offset(vec3d2), e.world, iselectioncontext, reuseablestream).add(vec3d2); if (horizontalMag(vec3d3) > horizontalMag(vec3d1)) { vec3d1 = vec3d3; } @@ -546,7 +555,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (horizontalMag(vec3d1) > horizontalMag(vec3d)) { vec3d = vec3d1.add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + vec.y, 0.0D), - axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); + axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); } } @@ -568,7 +577,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @OnlyIn(Dist.CLIENT) @Override public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, - int posRotationIncrements, boolean teleport) { + int posRotationIncrements, boolean teleport) { // Stationary Anchors are responsible for keeping position and motion in sync // themselves. if (stationary) @@ -592,8 +601,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override // Make sure nothing can move contraptions out of the way - public void setMotion(Vec3d motionIn) { - } + public void setMotion(Vec3d motionIn) {} @Override public void setPositionAndUpdate(double x, double y, double z) { @@ -623,9 +631,31 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public float getInitialAngle() { return initialAngle; } - + public Vec3d getRotationVec() { - return new Vec3d(pitch, yaw, roll); + return new Vec3d(getPitch(1), getYaw(1), getRoll(1)); + } + + public boolean canCollideWith(Entity e) { + if (e instanceof PlayerEntity && e.isSpectator()) + return false; + if (e.noClip) + return false; + if (e instanceof HangingEntity) + return false; + if (e instanceof SuperGlueEntity) + return false; + if (e instanceof IProjectile) + return false; + + Entity riding = this.getRidingEntity(); + while (riding != null) { + if (riding == e) + return false; + riding = riding.getRidingEntity(); + } + + return e.getPushReaction() == PushReaction.NORMAL; } } From 04b81128cd691ae37875d092f8a3c12a45cac79c Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sat, 11 Jul 2020 01:28:37 +0200 Subject: [PATCH 04/17] SeatState - Added textures, models and blockstates for seats --- src/generated/resources/.cache/cache | 72 +++++++++- .../assets/create/blockstates/black_seat.json | 7 + .../assets/create/blockstates/blue_seat.json | 7 + .../assets/create/blockstates/brown_seat.json | 7 + .../assets/create/blockstates/cyan_seat.json | 7 + .../assets/create/blockstates/fluid_pipe.json | 132 +++++++++--------- .../assets/create/blockstates/gray_seat.json | 7 + .../assets/create/blockstates/green_seat.json | 7 + .../create/blockstates/light_blue_seat.json | 7 + .../create/blockstates/light_gray_seat.json | 7 + .../assets/create/blockstates/lime_seat.json | 7 + .../create/blockstates/magenta_seat.json | 7 + .../create/blockstates/orange_seat.json | 7 + .../assets/create/blockstates/pink_seat.json | 7 + .../create/blockstates/purple_seat.json | 7 + .../create/blockstates/radial_chassis.json | 48 +++---- .../assets/create/blockstates/red_seat.json | 7 + .../assets/create/blockstates/white_seat.json | 7 + .../create/blockstates/yellow_seat.json | 7 + .../resources/assets/create/lang/en_ud.json | 16 +++ .../resources/assets/create/lang/en_us.json | 16 +++ .../create/models/block/black_seat.json | 7 + .../assets/create/models/block/blue_seat.json | 7 + .../create/models/block/brown_seat.json | 7 + .../assets/create/models/block/cyan_seat.json | 7 + .../assets/create/models/block/gray_seat.json | 7 + .../create/models/block/green_seat.json | 7 + .../create/models/block/light_blue_seat.json | 7 + .../create/models/block/light_gray_seat.json | 7 + .../assets/create/models/block/lime_seat.json | 7 + .../create/models/block/magenta_seat.json | 7 + .../create/models/block/orange_seat.json | 7 + .../assets/create/models/block/pink_seat.json | 7 + .../create/models/block/purple_seat.json | 7 + .../assets/create/models/block/red_seat.json | 7 + .../create/models/block/white_seat.json | 7 + .../create/models/block/yellow_seat.json | 7 + .../assets/create/models/item/black_seat.json | 3 + .../assets/create/models/item/blue_seat.json | 3 + .../assets/create/models/item/brown_seat.json | 3 + .../assets/create/models/item/cyan_seat.json | 3 + .../assets/create/models/item/gray_seat.json | 3 + .../assets/create/models/item/green_seat.json | 3 + .../create/models/item/light_blue_seat.json | 3 + .../create/models/item/light_gray_seat.json | 3 + .../assets/create/models/item/lime_seat.json | 3 + .../create/models/item/magenta_seat.json | 3 + .../create/models/item/orange_seat.json | 3 + .../assets/create/models/item/pink_seat.json | 3 + .../create/models/item/purple_seat.json | 3 + .../assets/create/models/item/red_seat.json | 3 + .../assets/create/models/item/white_seat.json | 3 + .../create/models/item/yellow_seat.json | 3 + .../create/loot_tables/blocks/black_seat.json | 19 +++ .../create/loot_tables/blocks/blue_seat.json | 19 +++ .../create/loot_tables/blocks/brown_seat.json | 19 +++ .../create/loot_tables/blocks/cyan_seat.json | 19 +++ .../create/loot_tables/blocks/gray_seat.json | 19 +++ .../create/loot_tables/blocks/green_seat.json | 19 +++ .../loot_tables/blocks/light_blue_seat.json | 19 +++ .../loot_tables/blocks/light_gray_seat.json | 19 +++ .../create/loot_tables/blocks/lime_seat.json | 19 +++ .../loot_tables/blocks/magenta_seat.json | 19 +++ .../loot_tables/blocks/orange_seat.json | 19 +++ .../create/loot_tables/blocks/pink_seat.json | 19 +++ .../loot_tables/blocks/purple_seat.json | 19 +++ .../create/loot_tables/blocks/red_seat.json | 19 +++ .../create/loot_tables/blocks/white_seat.json | 19 +++ .../loot_tables/blocks/yellow_seat.json | 19 +++ .../java/com/simibubi/create/AllBlocks.java | 18 +++ .../java/com/simibubi/create/AllShapes.java | 1 + .../components/actors/SeatBlock.java | 37 +++++ .../assets/create/models/block/seat.json | 24 ++++ .../create/textures/block/seat/bottom.png | Bin 0 -> 304 bytes .../create/textures/block/seat/side_black.png | Bin 0 -> 387 bytes .../create/textures/block/seat/side_blue.png | Bin 0 -> 389 bytes .../create/textures/block/seat/side_brown.png | Bin 0 -> 385 bytes .../create/textures/block/seat/side_cyan.png | Bin 0 -> 389 bytes .../create/textures/block/seat/side_gray.png | Bin 0 -> 385 bytes .../create/textures/block/seat/side_green.png | Bin 0 -> 387 bytes .../textures/block/seat/side_light_blue.png | Bin 0 -> 391 bytes .../textures/block/seat/side_light_gray.png | Bin 0 -> 407 bytes .../create/textures/block/seat/side_lime.png | Bin 0 -> 390 bytes .../textures/block/seat/side_magenta.png | Bin 0 -> 386 bytes .../textures/block/seat/side_orange.png | Bin 0 -> 387 bytes .../create/textures/block/seat/side_pink.png | Bin 0 -> 404 bytes .../textures/block/seat/side_purple.png | Bin 0 -> 407 bytes .../create/textures/block/seat/side_red.png | Bin 0 -> 387 bytes .../create/textures/block/seat/side_white.png | Bin 0 -> 400 bytes .../textures/block/seat/side_yellow.png | Bin 0 -> 387 bytes .../create/textures/block/seat/top_black.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_blue.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_brown.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_cyan.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_gray.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_green.png | Bin 0 -> 270 bytes .../textures/block/seat/top_light_blue.png | Bin 0 -> 270 bytes .../textures/block/seat/top_light_gray.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_lime.png | Bin 0 -> 270 bytes .../textures/block/seat/top_magenta.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_orange.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_pink.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_purple.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_red.png | Bin 0 -> 271 bytes .../create/textures/block/seat/top_white.png | Bin 0 -> 270 bytes .../create/textures/block/seat/top_yellow.png | Bin 0 -> 270 bytes 106 files changed, 846 insertions(+), 94 deletions(-) create mode 100644 src/generated/resources/assets/create/blockstates/black_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/blue_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/brown_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/cyan_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/gray_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/green_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/light_blue_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/light_gray_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/lime_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/magenta_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/orange_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/pink_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/purple_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/red_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/white_seat.json create mode 100644 src/generated/resources/assets/create/blockstates/yellow_seat.json create mode 100644 src/generated/resources/assets/create/models/block/black_seat.json create mode 100644 src/generated/resources/assets/create/models/block/blue_seat.json create mode 100644 src/generated/resources/assets/create/models/block/brown_seat.json create mode 100644 src/generated/resources/assets/create/models/block/cyan_seat.json create mode 100644 src/generated/resources/assets/create/models/block/gray_seat.json create mode 100644 src/generated/resources/assets/create/models/block/green_seat.json create mode 100644 src/generated/resources/assets/create/models/block/light_blue_seat.json create mode 100644 src/generated/resources/assets/create/models/block/light_gray_seat.json create mode 100644 src/generated/resources/assets/create/models/block/lime_seat.json create mode 100644 src/generated/resources/assets/create/models/block/magenta_seat.json create mode 100644 src/generated/resources/assets/create/models/block/orange_seat.json create mode 100644 src/generated/resources/assets/create/models/block/pink_seat.json create mode 100644 src/generated/resources/assets/create/models/block/purple_seat.json create mode 100644 src/generated/resources/assets/create/models/block/red_seat.json create mode 100644 src/generated/resources/assets/create/models/block/white_seat.json create mode 100644 src/generated/resources/assets/create/models/block/yellow_seat.json create mode 100644 src/generated/resources/assets/create/models/item/black_seat.json create mode 100644 src/generated/resources/assets/create/models/item/blue_seat.json create mode 100644 src/generated/resources/assets/create/models/item/brown_seat.json create mode 100644 src/generated/resources/assets/create/models/item/cyan_seat.json create mode 100644 src/generated/resources/assets/create/models/item/gray_seat.json create mode 100644 src/generated/resources/assets/create/models/item/green_seat.json create mode 100644 src/generated/resources/assets/create/models/item/light_blue_seat.json create mode 100644 src/generated/resources/assets/create/models/item/light_gray_seat.json create mode 100644 src/generated/resources/assets/create/models/item/lime_seat.json create mode 100644 src/generated/resources/assets/create/models/item/magenta_seat.json create mode 100644 src/generated/resources/assets/create/models/item/orange_seat.json create mode 100644 src/generated/resources/assets/create/models/item/pink_seat.json create mode 100644 src/generated/resources/assets/create/models/item/purple_seat.json create mode 100644 src/generated/resources/assets/create/models/item/red_seat.json create mode 100644 src/generated/resources/assets/create/models/item/white_seat.json create mode 100644 src/generated/resources/assets/create/models/item/yellow_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/black_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/blue_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/brown_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/cyan_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/gray_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/green_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/light_blue_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/light_gray_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/lime_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/magenta_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/orange_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/pink_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/purple_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/red_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/white_seat.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/yellow_seat.json create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java create mode 100644 src/main/resources/assets/create/models/block/seat.json create mode 100644 src/main/resources/assets/create/textures/block/seat/bottom.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_black.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_blue.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_brown.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_cyan.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_gray.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_green.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_light_blue.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_light_gray.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_lime.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_magenta.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_orange.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_pink.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_purple.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_red.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_white.png create mode 100644 src/main/resources/assets/create/textures/block/seat/side_yellow.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_black.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_blue.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_brown.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_cyan.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_gray.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_green.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_light_blue.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_light_gray.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_lime.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_magenta.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_orange.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_pink.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_purple.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_red.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_white.png create mode 100644 src/main/resources/assets/create/textures/block/seat/top_yellow.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index fda4d9596..18b24e191 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -21,8 +21,11 @@ f9fa6aa530eb0891a74eadfbebc663172a57147a assets\create\blockstates\basin.json 4325605fbdea60d5f54286c309c825bebcd74b95 assets\create\blockstates\belt_tunnel.json cf9045eb16e5299a1d917c4cb536289f49411276 assets\create\blockstates\birch_window.json 94a1a91403eb4b035fec48071e7fcae57a8a6abd assets\create\blockstates\birch_window_pane.json +58b07d2af6030342f0354f6d3fd0ee128d2d74b4 assets\create\blockstates\black_seat.json +4854d1ef52130a7887aecc60bcaffbd66f0871a8 assets\create\blockstates\blue_seat.json 8b1dd00adcc7e74c5a9feed069e2610b15a338cb assets\create\blockstates\brass_block.json b8dd6e505943e06706d0718ece620ab3cf943650 assets\create\blockstates\brass_casing.json +e81608346d43406ee72cae0f78b8bcfb37ba2d75 assets\create\blockstates\brown_seat.json 26f3b6a8f8249e4e622ab200057d75e228762817 assets\create\blockstates\cart_assembler.json 7299cea212d879d6d5611bd139b24768b9af236f assets\create\blockstates\chiseled_dark_scoria.json 0f01f813388d3e6907c1cfd992e4b21c914e267e assets\create\blockstates\chiseled_dolomite.json @@ -42,6 +45,7 @@ f0031f5e970b3d5695472ed384950b8631b015ed assets\create\blockstates\creative_moto fe2f78b94c20944399101e7369e2d43324297fb6 assets\create\blockstates\crushing_wheel.json a1dd6cb3daa97ea871290ef7b178d28b564ee2a2 assets\create\blockstates\crushing_wheel_controller.json b1126c191877cff86b4e2de83e1fcbd151451cb7 assets\create\blockstates\cuckoo_clock.json +4de72f65bff4e5d9c8153fa3adeee6b61d6f912b assets\create\blockstates\cyan_seat.json 1726b1b9e04a0634e7e1fdcf1cf4cc898efc5c2f assets\create\blockstates\dark_oak_window.json 50d4627d8e8b5adade12de764ab528ddacfa9ea5 assets\create\blockstates\dark_oak_window_pane.json 21e435ad3baf69970446b0acd3db0d6d02dc9fcb assets\create\blockstates\dark_scoria.json @@ -114,7 +118,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 -3aa8213ea6cd12a6964e3a70900b12d76d794d20 assets\create\blockstates\fluid_pipe.json +4cbd66ed3da77d1caad6ef4e657a86b1b4017a39 assets\create\blockstates\fluid_pipe.json 9d0e78a4d6d0ccac37c06d0f5810a800a04844b2 assets\create\blockstates\fluid_tank.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets\create\blockstates\flywheel.json ac00d40e1ef50a37041c0481afa1a23a14dea78e assets\create\blockstates\framed_glass.json @@ -142,6 +146,8 @@ a4b0337149cb0617cc60061477c7178d37dbb831 assets\create\blockstates\granite_cobbl d97fdea02187e63f6b63913357c79a18660d676d assets\create\blockstates\granite_cobblestone_stairs.json 9ce66b5a61c3aad398756d26e4efee2b9e12a275 assets\create\blockstates\granite_cobblestone_wall.json f8659e81cd2a623475a6a9aca59149e82de56b1c assets\create\blockstates\granite_pillar.json +a5ec5401ba9f3e102a2e1b35837f643847afbca4 assets\create\blockstates\gray_seat.json +13059309684db0cc7a0f1f4fce2407cf06cce80a assets\create\blockstates\green_seat.json 6ab675fa06317e6d07c0c1a453e7bb43e3f46b3b assets\create\blockstates\hand_crank.json be3bef7e091d8b50bfc1c6b7275946d1f636aefd assets\create\blockstates\horizontal_framed_glass.json 18d9fdaa1352a7e2ec91135e46dae5c02ccd8f8f assets\create\blockstates\horizontal_framed_glass_pane.json @@ -157,6 +163,8 @@ a4cfcdc038af0f93a58d88ea8860b34d73632ff4 assets\create\blockstates\layered_dolom 038f532f7364c1e793196fcc5856df9ceff93578 assets\create\blockstates\layered_limestone.json 8535d628f8834be62cdf62ef4b60c2ce3a7af99f assets\create\blockstates\layered_scoria.json 419d7fffc5cbd392f10211afa8d17e3eb8df8380 assets\create\blockstates\layered_weathered_limestone.json +2a0a8b1715700bf1e284ee57ef9f7f163c12f3ee assets\create\blockstates\light_blue_seat.json +d9a2551e001bb315d071bb9f1f013323a66a5d09 assets\create\blockstates\light_gray_seat.json c4dcb169bd1dffe8501bff455e3eb6ba979f60ab assets\create\blockstates\limesand.json e7cb0b25e511610b46dfd219e0cc5ea60a79d56b assets\create\blockstates\limestone.json e7c7b952137c4cb615988ea59b9f14303c9a4dfe assets\create\blockstates\limestone_bricks.json @@ -168,9 +176,11 @@ e7c7b952137c4cb615988ea59b9f14303c9a4dfe assets\create\blockstates\limestone_bri 43532aec1893f7d2f37798d5dbb11ecde0a3bfab assets\create\blockstates\limestone_cobblestone_stairs.json 17c5a6c1dd094c9201ed90fdcebde620a8a39900 assets\create\blockstates\limestone_cobblestone_wall.json b7506b862d13b3f915c60d38bb7a20afc935f70a assets\create\blockstates\limestone_pillar.json +1de3a88c003df03f5006e1bbaa0236589aba08ad assets\create\blockstates\lime_seat.json 69790737767e06f000c7824749c46664a123160e assets\create\blockstates\linear_chassis.json c793ab3aa6cf09d8d6d4136757629689f0365771 assets\create\blockstates\linked_extractor.json c5422866667331f1d5cf6753c0889747ee02762b assets\create\blockstates\linked_transposer.json +84c494d24cc58af274fdd054896c680e8095d2d0 assets\create\blockstates\magenta_seat.json e82e69ae4c7a784ef89fc5d954b2b01946746d48 assets\create\blockstates\mechanical_arm.json ddcf4bb281e046fbb1026b8f46a2cf12448598df assets\create\blockstates\mechanical_bearing.json 5586beef2d9183dc34d8e8d2723620c0569592ae assets\create\blockstates\mechanical_crafter.json @@ -200,6 +210,7 @@ b1126c191877cff86b4e2de83e1fcbd151451cb7 assets\create\blockstates\mysterious_cu 36e46e65003a8d0b8555fe5e8f8dc980d6559bc5 assets\create\blockstates\nozzle.json cf60989f63f02067fc4e4ad25033ac83167cdeb0 assets\create\blockstates\oak_window.json 4a796509c3953171f04f957351282205840b3760 assets\create\blockstates\oak_window_pane.json +5764a24f6c4fa552b61d2a02135adfc7d93c2e10 assets\create\blockstates\orange_seat.json 8e2028e1a0450a592eed5e10276ba19b1195a206 assets\create\blockstates\ornate_iron_window.json f59198fd966927e21e9bf76e64de533d05ea893b assets\create\blockstates\ornate_iron_window_pane.json c46f0b62967cf483ec0720a9297c8ccc97f5547d assets\create\blockstates\overgrown_andesite.json @@ -247,6 +258,7 @@ c17d334e938dcb742550ba8307ca8266a1fc9b49 assets\create\blockstates\paved_weather cb23aef25f3106b06c8fa8f152c638bb0d2185d8 assets\create\blockstates\paved_weathered_limestone_slab.json d62b0992cec1de45dad1f2c273132225f4ef33a0 assets\create\blockstates\paved_weathered_limestone_stairs.json dba4cf86e82ed4502fffed363fbce226a445e774 assets\create\blockstates\paved_weathered_limestone_wall.json +919a79e4a4a5fab0aac3ef48e1c786017d6aa001 assets\create\blockstates\pink_seat.json 975c97018e9e2419943eaab43aed0970e96feaf7 assets\create\blockstates\piston_extension_pole.json 2f764f460aa1d75ba995da180bc6f8d2bd9db385 assets\create\blockstates\polished_dark_scoria.json 262b22dcf3e151e63f58710f6b6fe4fc4fc2a70c assets\create\blockstates\polished_dark_scoria_slab.json @@ -277,9 +289,11 @@ b7829c2ef2c47188713f8cab21b2c9bc7f9c5b79 assets\create\blockstates\portable_stor e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets\create\blockstates\powered_toggle_latch.json 3a739f9d4276828d83f2d2750bf3227c87bcd438 assets\create\blockstates\pulley_magnet.json 469e430d96cb0a5e1aaf6b7cc5d401d488c9e600 assets\create\blockstates\pulse_repeater.json -5d1b30c2bab556f57c78e7780fd445b08f541a50 assets\create\blockstates\radial_chassis.json +92957119abd5fbcca36a113b2a80255fd70fc303 assets\create\blockstates\purple_seat.json +6fa36883e76e9e403bb429c8f86b8c0d3bba0cff assets\create\blockstates\radial_chassis.json 8929677f2cc5354aa19ef182af69f9f0b41eb242 assets\create\blockstates\redstone_contact.json c29213b77ac0c78d8979c5f6188d2b265696f9b9 assets\create\blockstates\redstone_link.json +da1b08387af7afa0855ee8d040f620c01f20660a assets\create\blockstates\red_seat.json 1eac804cba08aebb5f4646758ae1ef9b32e01365 assets\create\blockstates\reinforced_rail.json e2990fe70ad5d10437a376e70e167d1856277cc1 assets\create\blockstates\rope.json e14d5f7252105934295b4e156ec0e6d62d3d6b1c assets\create\blockstates\rope_pulley.json @@ -327,10 +341,12 @@ fd7a9c7095372485081436c91489cadb2b0c514e assets\create\blockstates\weathered_lim 47f8c91ff4c3f5cad782ab469a1fe5f4909dc7f1 assets\create\blockstates\weathered_limestone_cobblestone_stairs.json c60c3115fd6eeaa3a696428a87a74d184ab7d62d assets\create\blockstates\weathered_limestone_cobblestone_wall.json c77b46d8b459e5c7cc495393546f3fcca8a1fa1d assets\create\blockstates\weathered_limestone_pillar.json +4647010162eb4c350fad236d860317eaa1884c77 assets\create\blockstates\white_seat.json +a3a11524cd3515fc01d905767b4b7ea782adaf03 assets\create\blockstates\yellow_seat.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets\create\blockstates\zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets\create\blockstates\zinc_ore.json -81f8eb319377b9fbe2188304886316120bb29c64 assets\create\lang\en_ud.json -4158ea22d8b9a3e21a47180fbd1ff5040c0b6a06 assets\create\lang\en_us.json +237cff4ba13aa7ab9a8c7b98e04d028195b420ab assets\create\lang\en_ud.json +147611124c17a338cf9a0869086391723ff8ab67 assets\create\lang\en_us.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets\create\models\block\acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets\create\models\block\acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets\create\models\block\acacia_window_pane_noside_alt.json @@ -393,8 +409,11 @@ fa79580db6187c864bc8148a41987ecdd1eb03b7 assets\create\models\block\belt_observe 3905ced5892afa60009bf26279f9fa4756c273d4 assets\create\models\block\birch_window_pane_post.json 62b3f2edc5ef5d7dabbcff19220921b0e3582376 assets\create\models\block\birch_window_pane_side.json 95d4230eb366f5e7684820c9337e3956ed34042a assets\create\models\block\birch_window_pane_side_alt.json +97d79ab99c0fb278a9b5dc54e1c6563868f87b76 assets\create\models\block\black_seat.json +e58b00a7222152d7facbe0e82f00933b974df747 assets\create\models\block\blue_seat.json 0934933df6bfbb19a1b14cd0e3cab2c18d5a3ebc assets\create\models\block\brass_block.json 166a5c053a81e6aadc24509ed24dc144a7255969 assets\create\models\block\brass_casing.json +4eed0ad902f5e84f2b6c160f3283e8028640e77d assets\create\models\block\brown_seat.json 028a07b49c05fe8a93f1d8c229d81e73d887c2df assets\create\models\block\chiseled_dark_scoria.json b1f9ee4867373dd8f976625bab744a1c72c7fd16 assets\create\models\block\chiseled_dolomite.json cd7751090cf3d55296b8e415d0af9b6f18d69770 assets\create\models\block\chiseled_gabbro.json @@ -413,6 +432,7 @@ a09f639bde4c61d68592eb06c807e7a6791ff950 assets\create\models\block\crate\brass\ 7635211e4d833748acaea37ea48b1f749c32ea5f assets\create\models\block\crate\creative\right.json a123e3c8a9e2ea1665f268cf3991aa7e4b3119c6 assets\create\models\block\crate\creative\single.json 29ab5cfe7aed1271ede125e91bf78c1372b5f96e assets\create\models\block\crate\creative\top.json +6704782830b3d872321e895b6903709c18e3778f assets\create\models\block\cyan_seat.json 57e70af1da4e971eca075616b787b70104189d60 assets\create\models\block\dark_oak_window.json c7b06bc1688f3f9417d38c492d83069f493df78e assets\create\models\block\dark_oak_window_pane_noside.json 3cf8adcb5d1c8f53d2144e1a85bebe593522a34e assets\create\models\block\dark_oak_window_pane_noside_alt.json @@ -606,6 +626,8 @@ d25cb5553bfd89cd3fca61ebd2204bf2a44cc3da assets\create\models\block\granite_cobb cf267628d47aa424bc20977e69e255ceda3ddfe4 assets\create\models\block\granite_cobblestone_wall_post.json a4f50b75a3186829fc5d62ee4e33997cd202dbd5 assets\create\models\block\granite_cobblestone_wall_side.json 349a58ac4e4535d0fe9ea467632ed904da2c6098 assets\create\models\block\granite_pillar.json +6eb5e59e803e1055968b90f3099cd0a17a1d3fd5 assets\create\models\block\gray_seat.json +1438b8ce54ac5557b8f10dcef94f3525eae19461 assets\create\models\block\green_seat.json 9730fcb02f679087e81e24c836751e625be6a298 assets\create\models\block\horizontal_framed_glass.json d13df8a5920c5778d98081fb0e97f045e2fd46a2 assets\create\models\block\horizontal_framed_glass_pane_noside.json 3e975bec02e2670ce2b1868cebcbd780a5ebf3f8 assets\create\models\block\horizontal_framed_glass_pane_noside_alt.json @@ -627,6 +649,8 @@ ff78465839cbd36a356cd4153c721c88b1f0b297 assets\create\models\block\layered_gabb 8f1014b1fdef246c2ce525f33ade4f03c85d0217 assets\create\models\block\layered_limestone.json 9408ce7ba29a96053c9333b15a05d716752392c6 assets\create\models\block\layered_scoria.json da71aca99ac5cf3731896be47e15d774397a3330 assets\create\models\block\layered_weathered_limestone.json +1a28b07da68d1461cd04c971ae548d94165e0cf3 assets\create\models\block\light_blue_seat.json +292bec1b9f962b17b29147d982a9b177618b7eb9 assets\create\models\block\light_gray_seat.json ce6fb36a386c895486e021823eb008b0fa4862c3 assets\create\models\block\limesand.json a2cbc86d24fdd70c5f33c8b30ba52a8928dde63f assets\create\models\block\limestone.json 447686a6861773e03c5c18f2de4bc11d06c65f78 assets\create\models\block\limestone_bricks.json @@ -646,10 +670,12 @@ abef3f97c28321ded3bafc90918377981038d7b2 assets\create\models\block\limestone_co eee8ae85daa99fcd594da3d4af393726af69493b assets\create\models\block\limestone_cobblestone_wall_post.json 0effd13c1ff224f4c2d7017c6505f48d31815934 assets\create\models\block\limestone_cobblestone_wall_side.json 7336e008b3af80e054c9f15be381b7fe307e97d4 assets\create\models\block\limestone_pillar.json +31c9474210d8535c5417021fe042d4cc31e17328 assets\create\models\block\lime_seat.json 20432687c62402a4bc0f2415113e7470231cdf03 assets\create\models\block\linear_chassis.json 595bfec2293c44deae49147016cb7971bdd721df assets\create\models\block\linear_chassis_bottom.json 999ce855842170f47db9d1e8e8636c24f7d3ad3d assets\create\models\block\linear_chassis_top.json b9abbd1dcf71e0a1416fd998a82a560c06cef5a3 assets\create\models\block\linear_chassis_top_bottom.json +cbee001cd1bb1125a97d1bb2d1e6e5a68f129303 assets\create\models\block\magenta_seat.json 0492070642fda75b943080022368505f2d065730 assets\create\models\block\mechanical_bearing.json edf6ee4e590ebf162c00aa952d992f1bee2cad8a assets\create\models\block\mossy_andesite.json 55256e4df0038a619d80d3e6c50b0f3e3682e90a assets\create\models\block\mossy_dark_scoria.json @@ -667,6 +693,7 @@ e55363147cc27fba84590c7e24460603988118e3 assets\create\models\block\oak_window_p 88883e266828422f86ec71db455a41f0279926fd assets\create\models\block\oak_window_pane_post.json aa12818d00d1995e5b8a218cb613215ec0161d23 assets\create\models\block\oak_window_pane_side.json 488dfd3f4bd82ab1b5b751b4a46881befb8d6819 assets\create\models\block\oak_window_pane_side_alt.json +fda0628a09ef726e3e8323b2f38b6a3e612dc2ca assets\create\models\block\orange_seat.json 006115bf8e36367c0c409effdeab939a54c20776 assets\create\models\block\ornate_iron_window.json cc9614e892b12c6053d45a35d534eddf36285cf1 assets\create\models\block\ornate_iron_window_pane_noside.json 6b935d54de7c37f835df48f7b6e5e614a0d12b6e assets\create\models\block\ornate_iron_window_pane_noside_alt.json @@ -787,6 +814,7 @@ cc36e21013b80b1dfa041b55047096db127ffa51 assets\create\models\block\paved_weathe 743fc37d4c96834f9bd0697ad7990c721436b901 assets\create\models\block\paved_weathered_limestone_stairs_outer.json 34ba32e570e0a54501db071b9f8c38513edea93d assets\create\models\block\paved_weathered_limestone_wall_post.json daf65510d95730bcf0373d746f2a2dbfe6b44fc0 assets\create\models\block\paved_weathered_limestone_wall_side.json +ecc60ce7ee6b753073a99c597db95d6d9df3d438 assets\create\models\block\pink_seat.json 83a4922d5799a5a1391a2675e9273caa24cde192 assets\create\models\block\polished_dark_scoria.json 3fcab24848791fcd591bf4a2a73147c3391e24b8 assets\create\models\block\polished_dark_scoria_slab.json 7c1b4b3b22c711224a54d55d7c49429c4238d5a7 assets\create\models\block\polished_dark_scoria_slab_double.json @@ -847,12 +875,14 @@ f22d7d8263dcabd726aa04784031ae9062633579 assets\create\models\block\powered_togg e6097d9ab9dc9954cbc750020bc33c7a423b73c6 assets\create\models\block\powered_toggle_latch_on_powered.json 622239a3a09fcac7235b9670eb395a530839a59b assets\create\models\block\pulse_repeater_powered.json 0102e253c941904f12de7acdd46b0079ee3ccf69 assets\create\models\block\pulse_repeater_pulsing.json +96adc7865ebe64b43865bc2fe914830c11258856 assets\create\models\block\purple_seat.json 27d64a828607f94296c0b86cdb35fad996bc5d23 assets\create\models\block\radial_chassis_side_x.json 7d1439a0b06e4014e396d498a9e42168f67773a5 assets\create\models\block\radial_chassis_side_x_sticky.json a9885a3f69e3e2a2812c33bafd9140fcc5cc7c25 assets\create\models\block\radial_chassis_side_y.json 92a48c22cf2af0a3156844322f6bb469883608fb assets\create\models\block\radial_chassis_side_y_sticky.json 522f4733118d6fba172696e9478c8f9fe88b236e assets\create\models\block\radial_chassis_side_z.json bffca231a146a6ac49e028f3790cdcbf375e98b0 assets\create\models\block\radial_chassis_side_z_sticky.json +12d4f4119b994c5d71c96ab3aa09beb89dad1e10 assets\create\models\block\red_seat.json c145d8e0d7f8f41afa80b9727a107b2ad2f0c3c9 assets\create\models\block\scoria.json 59c6f6a4ffe43485244a8561d7e8341f796e268b assets\create\models\block\scoria_bricks.json d86ca38a0c1bac89e545916c59f23f6f0c9f7d7a assets\create\models\block\scoria_bricks_slab.json @@ -918,6 +948,8 @@ eb838d687f7a925f5b91c4784bfbf33070515e31 assets\create\models\block\weathered_li 7b70d26bf88ccc3bb0657e00c6ca50b7149d3643 assets\create\models\block\weathered_limestone_cobblestone_wall_post.json 5a866d7cca51056c15a5f51e171d89598426fade assets\create\models\block\weathered_limestone_cobblestone_wall_side.json a5b04a1a35735713f51dcd5a80d9e582e6575bbc assets\create\models\block\weathered_limestone_pillar.json +1377e12f56dce1466ce44078d7154870c5cf7b2a assets\create\models\block\white_seat.json +0a0e2cc973e35586ae00ed17b919383868e992e8 assets\create\models\block\yellow_seat.json c94c60d1d77404af7d74a29a094c7bdf7501b385 assets\create\models\block\zinc_block.json a3ff06384fff574ac4cd6c253259f0734b025cab assets\create\models\block\zinc_ore.json 67ef6fd6ec26fc216fa5319b8538beb223da1530 assets\create\models\item\acacia_window.json @@ -944,12 +976,15 @@ bf1fc6bdf7fca6f1958a2d3e96202c1cecb50669 assets\create\models\item\basin.json 5006164d5bdb17cc5ec9759d7cdaf218e2b45f04 assets\create\models\item\belt_tunnel.json 9044243882cfd49a2827e1b910a4c9b0e46daa47 assets\create\models\item\birch_window.json 6ed49f59ea91068ef68720f43e67a9237594bdf0 assets\create\models\item\birch_window_pane.json +22632bd681c8a605f0845f7549770389a741156a assets\create\models\item\black_seat.json +0e1977585128fc0ecef640f72e5fc5e9fb47ef92 assets\create\models\item\blue_seat.json 17d340c3678bd24cb085ba49490b2b4cb341a9e7 assets\create\models\item\brass_block.json f5a18f4279c2e845a5967b1c2f9e807c2bb77afb assets\create\models\item\brass_casing.json 361f75a79de5007d7a99ad0a38103c9aa8c3017c assets\create\models\item\brass_hand.json 1786bdffa2ab5a07c88d2797db3d7b54461323c4 assets\create\models\item\brass_ingot.json a37be4a0ec9bf6c381527403c57ced4f81abd67c assets\create\models\item\brass_nugget.json 14ea6ee4db6e7e76446e331a70b6b6bec31e8eb7 assets\create\models\item\brass_sheet.json +24df6f8391d8ba09cef46e69d65d32ea770745cd assets\create\models\item\brown_seat.json 3e232a103f7f916fc11edb4d541ca99fe7b44181 assets\create\models\item\cart_assembler.json 99d64b76b3baa84c3bd4b96ccd3376ca12425950 assets\create\models\item\chiseled_dark_scoria.json 83d3571eacde52568786802b268f24c6578c1e5d assets\create\models\item\chiseled_dolomite.json @@ -977,6 +1012,7 @@ d7cb2f7bac8fae893fc5179af8140786a908f3f5 assets\create\models\item\copper_shingl 8b9c0aa8aaf979ec85eac59b27799cc1c0cf427a assets\create\models\item\crushed_zinc_ore.json 823c91f63565db54ec3944a1e90e7aee18e41062 assets\create\models\item\crushing_wheel.json dae5cffa4e1263d6a113469f79fba8695fa8232a assets\create\models\item\cuckoo_clock.json +3e3edc9ccded444496d3336926b93bbf1234cd84 assets\create\models\item\cyan_seat.json f786a43e296d9f10d7c302fe3ae9cddf4ba9984e assets\create\models\item\dark_oak_window.json e3e9ebbc694edad1f473e5c3a897d95cc87528ae assets\create\models\item\dark_oak_window_pane.json f0e98871e4bb68c29954f2de24566a6404f21d9c assets\create\models\item\dark_scoria.json @@ -1084,6 +1120,8 @@ c1bb87fdbbefaf74e1ead186c43417a051ab3965 assets\create\models\item\granite_cobbl 3c5f83809f945134a861d4ea600a1708de58a422 assets\create\models\item\granite_cobblestone_stairs.json e2d8561a8048fe6144362d13478bba4825588810 assets\create\models\item\granite_cobblestone_wall.json b84a947a1b297513c85bb8d2dbbb780304c95e43 assets\create\models\item\granite_pillar.json +e7daa31c1fc445d542bad476dfe1d6a8811f2070 assets\create\models\item\gray_seat.json +1c9c9157a06108bf58967bfc4fb069c35d20e90a assets\create\models\item\green_seat.json cfab82a2cf7495d21778c1de9730a26afbdd523d assets\create\models\item\handheld_blockzapper.json dee43bf1a9c211a752fac2c07aeba123f7f0c914 assets\create\models\item\handheld_worldshaper.json 398b1a7c76c7bdb6a23b1248fdce98f6d835467f assets\create\models\item\hand_crank.json @@ -1104,6 +1142,8 @@ bcaaf60d9a853cce90169dabcb36d29a3ce19e18 assets\create\models\item\large_cogwhee ad40f8eb28bea731131aeaffee55abecb8bc6a56 assets\create\models\item\layered_limestone.json e7585210cf4754c89b4ba3dc95827b75029f0523 assets\create\models\item\layered_scoria.json 2df30e7f8cacc1efd6e025564d495f782e0dc697 assets\create\models\item\layered_weathered_limestone.json +be2b6d54afc515d93d6d5b3023c506c53cc946f8 assets\create\models\item\light_blue_seat.json +1b36382eae41b35585e5659cda019310731000fc assets\create\models\item\light_gray_seat.json a29733a916141abf84492a288fe9ac4ed531f47d assets\create\models\item\limesand.json e0a1c6102acc10a36de5ae87da629dd3d676e204 assets\create\models\item\limestone.json 1c2b99db54863eac4947824f4169e51c25d05bde assets\create\models\item\limestone_bricks.json @@ -1115,9 +1155,11 @@ c26a0887356e9e55a0bdc3d885838e4722e0c0c2 assets\create\models\item\limestone_cob ebdf23b99b7895e347c29057c8070a6e16e56beb assets\create\models\item\limestone_cobblestone_stairs.json 8cd46904fd9709377d514e0faf9150ca317f6a9f assets\create\models\item\limestone_cobblestone_wall.json 8065de871ad2fbaed711735561b8ed91a2ce0004 assets\create\models\item\limestone_pillar.json +2127f20dca4421802812e249b3caca6230a37eee assets\create\models\item\lime_seat.json d245aa4994ff197b1ffeb7980d05f96bd20cdeb3 assets\create\models\item\linear_chassis.json eb0053df13e362e0a05be65252944f0c94eab3db assets\create\models\item\linked_extractor.json 0242f25a8eb02b25f8b03344a1dfaf9ad0ab192c assets\create\models\item\linked_transposer.json +d912be3e87f2beaa8e22747f867739139667241b assets\create\models\item\magenta_seat.json 932facf4bf93b471e8630f4132a4284a9f4d0d39 assets\create\models\item\mechanical_arm.json 49dcc373c33f6fc3760add10eb51bd96cd4fd028 assets\create\models\item\mechanical_bearing.json 65ac4f19973ddeb1bb4d672f57319130e736e116 assets\create\models\item\mechanical_crafter.json @@ -1146,6 +1188,7 @@ bafe601f186e868819da3d29f7be7dc96f9ba790 assets\create\models\item\nixie_tube.js 366a60447bbbd61eb25aecf191a01e8d9417ad61 assets\create\models\item\nozzle.json 7a336a340f3e4927d7a35f9d79e8a03693b802aa assets\create\models\item\oak_window.json f274fe391ac584656c9817a5650b1c1e38e44c58 assets\create\models\item\oak_window_pane.json +25dfcc8b6f085722f6b2a0c686b77d437e61542e assets\create\models\item\orange_seat.json 0ffe242e3165d9a0e3fe16ad4c4ca91c7e9828b2 assets\create\models\item\ornate_iron_window.json 7d7da05da6248abc177e89988ed5c2aff1151767 assets\create\models\item\ornate_iron_window_pane.json db23dec78b3355fc0de3485b8e9d915a20dc1f93 assets\create\models\item\overgrown_andesite.json @@ -1193,6 +1236,7 @@ d60c4fb6e0e68d8f6c137a0c601145c342236c18 assets\create\models\item\paved_limesto 5ec22c676e301a7004ff7d127d20b46f49063c64 assets\create\models\item\paved_weathered_limestone_slab.json d81f85aea5e683539a0f3c805c154b76a9d88a9d assets\create\models\item\paved_weathered_limestone_stairs.json 25eaccadfbabb60301f487807b0e839d525f2c80 assets\create\models\item\paved_weathered_limestone_wall.json +9664f171c7856661776c5c4ef0b6880a77db648e assets\create\models\item\pink_seat.json 04ce23dc141bedccc75b4512263da8b498f13205 assets\create\models\item\piston_extension_pole.json 1f7846aa06c3c22614c98cbec9112cc8632fa1b8 assets\create\models\item\polished_dark_scoria.json c46f1191cfa225fa76973208646e7bd86d7fcb5f assets\create\models\item\polished_dark_scoria_slab.json @@ -1225,10 +1269,12 @@ d3cfc1a1137c4bc98848947d425d2972df144c95 assets\create\models\item\powdered_obsi 3a6dfc7f36e31ebfcd650c3144a7f2210e8a4f9f assets\create\models\item\powered_toggle_latch.json 16f363038d5afeae34e0724a6a9f0b8f6e65424a assets\create\models\item\propeller.json 4b8a27ff05ed5331889dfc4b0b4562f3e94b0dfe assets\create\models\item\pulse_repeater.json +a598b2f5eb34b061e81efb8a55267a02f8e08a61 assets\create\models\item\purple_seat.json 469652eb5baa92008dbfc4deec232c3381684af6 assets\create\models\item\radial_chassis.json b9a4ac219a27e60a82f55129f2df5ae6183981e2 assets\create\models\item\redstone_contact.json 52e561abeb954d0349e640566de92ef80ccbf919 assets\create\models\item\redstone_link.json ba99e2fdb64892f4f479a8ac51c226cb5f71f659 assets\create\models\item\red_sand_paper.json +3e251514aa698076b73fdbfef720b78b21d3bd93 assets\create\models\item\red_seat.json d9dd4546f4f4c6ed5fef66de9d272d469db4e81f assets\create\models\item\refined_radiance.json 901f7ad587dd07c9494d95bf7f08f93bb20db774 assets\create\models\item\reinforced_rail.json 6daff6b82b33374d7add65e352e05ecb2fd9ebdd assets\create\models\item\rope_pulley.json @@ -1282,7 +1328,9 @@ def7382f3216c59d835ab64f534678f3d31ecc51 assets\create\models\item\weathered_lim 40bed7f5e9e97da45c5d9cebc3fcf87b2b13a808 assets\create\models\item\weathered_limestone_pillar.json 8914910270736f8f15364c623cd08d4638383cc5 assets\create\models\item\wheat_flour.json 0cc80844db689404d4722c93f1002b0bed05edcd assets\create\models\item\whisk.json +69328eb4f91c4407fbcad5e3c4b88363f1a9572c assets\create\models\item\white_seat.json 2527b52413965a3e84b4718e08a9b8bb30a741ea assets\create\models\item\wrench.json +4b49bc2418410cded5f0b7da3430f1a22e049f18 assets\create\models\item\yellow_seat.json 9365b5cf29e35d070d077c54520f6cc780aeb842 assets\create\models\item\zinc_block.json 9dfaa12884667458f8f727ae7666e7e4e50181d9 assets\create\models\item\zinc_ingot.json 9f9455ccb5fc9e3cbfce73862b46078346a522a5 assets\create\models\item\zinc_nugget.json @@ -1726,8 +1774,11 @@ c7f81e30c31837a287d6d6040cdb02c7dec11441 data\create\loot_tables\blocks\belt.jso f2acadb49cac3aa6347cae606536cbbde89f0a5f data\create\loot_tables\blocks\belt_tunnel.json 67a8e2513c3cb09e6fe80279fda94f79d5018c37 data\create\loot_tables\blocks\birch_window.json bf1d5843f93533f84bc4adec5b77da2114fa2025 data\create\loot_tables\blocks\birch_window_pane.json +cccc209d172cc7bac76f1b4ac79085ee90742ab2 data\create\loot_tables\blocks\black_seat.json +3834f7ac2bbc42cead02d4973842adb9ad97e6bf data\create\loot_tables\blocks\blue_seat.json 70d9d4def43d5b31fa7cdc5ca5002c71cf4a90b0 data\create\loot_tables\blocks\brass_block.json 8a14258ad5d79d9e4dc5a318905644b446196420 data\create\loot_tables\blocks\brass_casing.json +d415862a0abe20e8c5c2c8125bb672065330a9bc data\create\loot_tables\blocks\brown_seat.json 0be542fef3bc0e1a0d556883568a1400a8b97df1 data\create\loot_tables\blocks\cart_assembler.json ab820bbaaf67c6697dfbab33c05fb73b18c70bfb data\create\loot_tables\blocks\chiseled_dark_scoria.json 1f907058afd7d8dbe628c9ab315b8ddbdccfbfda data\create\loot_tables\blocks\chiseled_dolomite.json @@ -1747,6 +1798,7 @@ d8f2f8921b9200b1d9476a77ee1be32c25308ac3 data\create\loot_tables\blocks\creative c28fa42746a4d5ca2f824001b67e58673810169e data\create\loot_tables\blocks\crushing_wheel.json 205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\crushing_wheel_controller.json d370ee874b5b6b98e9a8c368218fe61f644d956d data\create\loot_tables\blocks\cuckoo_clock.json +49a14b9e93abdf02a7aef9c0c4085ac89617fae4 data\create\loot_tables\blocks\cyan_seat.json fd309e1d39dcbcb25c3361edecd8c9afa0f847d0 data\create\loot_tables\blocks\dark_oak_window.json 58e6307ba0efa65a0715662a391fe7dc6fba0c68 data\create\loot_tables\blocks\dark_oak_window_pane.json 7a40002e4c05f6456b52558b9ee9607cfc868a69 data\create\loot_tables\blocks\dark_scoria.json @@ -1847,6 +1899,8 @@ fa0ddf45d108f55550164113cb5cfd002586a9d4 data\create\loot_tables\blocks\granite_ feca8a1f62e0e13fcb2252d5f782d74938b84431 data\create\loot_tables\blocks\granite_cobblestone_stairs.json 1d225a68b09d6f389aa7ed48aa05979bdaa482a9 data\create\loot_tables\blocks\granite_cobblestone_wall.json 87a4ac3db5ec80613b940abccc72fc4b37cee0ba data\create\loot_tables\blocks\granite_pillar.json +d014357b3a467b23473c8223f32471a04a9ff94c data\create\loot_tables\blocks\gray_seat.json +a71599eecd3f1179e3d0367623460e798828aa6d data\create\loot_tables\blocks\green_seat.json 9bdc47ea3ffc52f037f12f40f387e6b72a352c4e data\create\loot_tables\blocks\hand_crank.json 22012e7759f1dbccbb06bcaf0311a54190270825 data\create\loot_tables\blocks\horizontal_framed_glass.json 5d3f585539942f13bbc458a0a002849c1f034fc1 data\create\loot_tables\blocks\horizontal_framed_glass_pane.json @@ -1862,6 +1916,8 @@ fa8a5922f7346a15a80b5c7e5dfc26d24ea98728 data\create\loot_tables\blocks\layered_ 197ecf9c00c06f6014ecbec678a5466492902cb0 data\create\loot_tables\blocks\layered_limestone.json 0ec9e366708637a01e600a2a12cc267d81b3f69b data\create\loot_tables\blocks\layered_scoria.json 54816065cd735dfe53b1eb551110ba18c6e3746a data\create\loot_tables\blocks\layered_weathered_limestone.json +b403848d3a4b4ad7a048e70c21e200e40d0c67e3 data\create\loot_tables\blocks\light_blue_seat.json +0cc2b20cb6e2dae6cf9d759c85926663f6066c99 data\create\loot_tables\blocks\light_gray_seat.json 7dfd638cc6f0d22bbc8fcbdb7212a3bfc8c85223 data\create\loot_tables\blocks\limesand.json 9d585f677a32a2336df5f17b5b389cdee867939f data\create\loot_tables\blocks\limestone.json 57134f7d3d32fc1c48f2a20c4be84388587092bc data\create\loot_tables\blocks\limestone_bricks.json @@ -1873,9 +1929,11 @@ cb315814960850b5080598b89ee94c833b5048f7 data\create\loot_tables\blocks\limeston 8db1e3f0dac48b91a4839206a7d5a88cef415fdc data\create\loot_tables\blocks\limestone_cobblestone_stairs.json 92fb16606f289ad33860270d098fad2522b24e09 data\create\loot_tables\blocks\limestone_cobblestone_wall.json 371115e5ceb08c07a9ab2371509960c31e0baa8a data\create\loot_tables\blocks\limestone_pillar.json +f7893090c6ecb4862c90c408b7f9ce8316f8b608 data\create\loot_tables\blocks\lime_seat.json aa751d2e8a7889907c08c4bec6f6ca266230b6d7 data\create\loot_tables\blocks\linear_chassis.json dac789cf53b00eed34308848b5e267b7ccec090c data\create\loot_tables\blocks\linked_extractor.json 7af5a13c9e10903b11732fbc01ae3299328216f0 data\create\loot_tables\blocks\linked_transposer.json +9e5e017cd3b4f544f487a5ca22ef610a4addc8ec data\create\loot_tables\blocks\magenta_seat.json e64c32da44b7e92dbef36fcb448c42b9bd9ae47c data\create\loot_tables\blocks\mechanical_arm.json 90ddf7b5c3b61758a4ad12a1e6ef16fe6ebf7794 data\create\loot_tables\blocks\mechanical_bearing.json e93872a90e4f4642a003539e7db28fdacfdcd114 data\create\loot_tables\blocks\mechanical_crafter.json @@ -1905,6 +1963,7 @@ d3ea271bb5774c73d44ab2e73195c9d5a4ff9c92 data\create\loot_tables\blocks\nixie_tu 6237eb3999181f1db09ca01b08e7785b70722d3b data\create\loot_tables\blocks\nozzle.json 0b2b142cfb3ebe9d4506e498a8e31f48d00db58d data\create\loot_tables\blocks\oak_window.json 90cc4d5857f47c48e2b82f394de9567023c5c8ce data\create\loot_tables\blocks\oak_window_pane.json +2333aaea940816b6bc8454ba24e0c9f52af94ac0 data\create\loot_tables\blocks\orange_seat.json 267e9e24fac93e3496a80fcb6ed8e9d1c329d2d2 data\create\loot_tables\blocks\ornate_iron_window.json 1fe77a16f4c86993b5fb30f1f48362787fd7cd0b data\create\loot_tables\blocks\ornate_iron_window_pane.json 8d91485a5f353c6fb84e16bd0d9d4a55aaeb31ab data\create\loot_tables\blocks\overgrown_andesite.json @@ -1952,6 +2011,7 @@ dfeba5c6de20e9ec0252e43b7c4046f017284d3d data\create\loot_tables\blocks\paved_we 32eed137f13c25a7b9db2fb457901e0c03cabb16 data\create\loot_tables\blocks\paved_weathered_limestone_slab.json 67b9227237ed2a8c09c4183c0f2ab1b3bd07084b data\create\loot_tables\blocks\paved_weathered_limestone_stairs.json d3e4ab984aef19ee21a1c5b868eb3fde96c05afd data\create\loot_tables\blocks\paved_weathered_limestone_wall.json +6f32e1217986407e41358e9417de63602c78e810 data\create\loot_tables\blocks\pink_seat.json 1087b6c6d88dc7c71ed81e1d3e180fe065e6d098 data\create\loot_tables\blocks\piston_extension_pole.json 05302657546d8d410e367e84d4d5e01f01523236 data\create\loot_tables\blocks\polished_dark_scoria.json 1b323a883816428ff851462f61d00eaee7255e33 data\create\loot_tables\blocks\polished_dark_scoria_slab.json @@ -1982,9 +2042,11 @@ fbe98efcb1a5970b6795fdbbb671fee704c0945f data\create\loot_tables\blocks\portable a3fb7d3e3bf9dc73ce754002f10c469d57db1f71 data\create\loot_tables\blocks\powered_toggle_latch.json 205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\pulley_magnet.json e8fb62c91226ac107dee45c5ebc54c8dd0aee224 data\create\loot_tables\blocks\pulse_repeater.json +d7f6caa568e6508177a644fb78dc18ce26c9b2c0 data\create\loot_tables\blocks\purple_seat.json 768420dab8785909891e52c4d77a182d99ba11d3 data\create\loot_tables\blocks\radial_chassis.json f5907a694206facc01f61f3428f72488486761c7 data\create\loot_tables\blocks\redstone_contact.json 886a0c1386fb12104b736a15689030aaff771270 data\create\loot_tables\blocks\redstone_link.json +71b0fa3b174efe94a2a735ab2426c376c0ef674a data\create\loot_tables\blocks\red_seat.json 97c945de837a6360c0ab7e1371f16ebc1645f6ea data\create\loot_tables\blocks\reinforced_rail.json 205f5899101262f31f5c1a88bb7d954918d08d04 data\create\loot_tables\blocks\rope.json cecaac07bd275bb1ae9e302f0bf44b581e74105d data\create\loot_tables\blocks\rope_pulley.json @@ -2032,6 +2094,8 @@ c2a62f12680d04ed4f586c501bb026e367243dd2 data\create\loot_tables\blocks\weathere a89f425c47c3831071b556697169a3124370aed7 data\create\loot_tables\blocks\weathered_limestone_cobblestone_stairs.json e8f3af61d9a2fd1ff5b32c9bb474ed005e6d70c4 data\create\loot_tables\blocks\weathered_limestone_cobblestone_wall.json 54358a64639957cc66ffa5296ff45723f7adf00e data\create\loot_tables\blocks\weathered_limestone_pillar.json +969eda31556feb5a68e350762848d17453275fee data\create\loot_tables\blocks\white_seat.json +37ead431a278928a09b260ae06a448e2c791a73e data\create\loot_tables\blocks\yellow_seat.json 94661e726b3d19271550359ae898a5590939512e data\create\loot_tables\blocks\zinc_block.json 37248ca92d474e440b91c27e3c8e78e568328100 data\create\loot_tables\blocks\zinc_ore.json b65bac8bc2fbfd476040c1aab1c0588b8bd59ebe data\create\recipes\acacia_window.json diff --git a/src/generated/resources/assets/create/blockstates/black_seat.json b/src/generated/resources/assets/create/blockstates/black_seat.json new file mode 100644 index 000000000..f232c6c76 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/black_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/black_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/blue_seat.json b/src/generated/resources/assets/create/blockstates/blue_seat.json new file mode 100644 index 000000000..10e98b04a --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/blue_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/blue_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/brown_seat.json b/src/generated/resources/assets/create/blockstates/brown_seat.json new file mode 100644 index 000000000..2b501fab7 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/brown_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/brown_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/cyan_seat.json b/src/generated/resources/assets/create/blockstates/cyan_seat.json new file mode 100644 index 000000000..a40f1bf88 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/cyan_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/cyan_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/fluid_pipe.json b/src/generated/resources/assets/create/blockstates/fluid_pipe.json index 44255c27a..96f2f6808 100644 --- a/src/generated/resources/assets/create/blockstates/fluid_pipe.json +++ b/src/generated/resources/assets/create/blockstates/fluid_pipe.json @@ -181,10 +181,10 @@ }, { "when": { - "west": "true", - "east": "false", "north": "false", - "south": "true" + "south": "true", + "west": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lu_y" @@ -192,10 +192,10 @@ }, { "when": { - "west": "false", - "east": "true", "north": "false", - "south": "true" + "south": "true", + "west": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/ru_y" @@ -203,10 +203,10 @@ }, { "when": { - "west": "true", - "east": "false", "north": "true", - "south": "false" + "south": "false", + "west": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ld_y" @@ -214,10 +214,10 @@ }, { "when": { - "west": "false", - "east": "true", "north": "true", - "south": "false" + "south": "false", + "west": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/rd_y" @@ -225,10 +225,10 @@ }, { "when": { - "west": "false", - "east": "false", "north": "true", - "south": "true" + "south": "true", + "west": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -236,10 +236,10 @@ }, { "when": { - "west": "false", - "east": "false", "north": "false", - "south": "true" + "south": "true", + "west": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -247,10 +247,10 @@ }, { "when": { - "west": "false", - "east": "false", "north": "true", - "south": "false" + "south": "false", + "west": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_y" @@ -258,10 +258,10 @@ }, { "when": { + "north": "false", + "south": "false", "west": "true", - "east": "true", - "north": "false", - "south": "false" + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -269,10 +269,10 @@ }, { "when": { + "north": "false", + "south": "false", "west": "true", - "east": "false", - "north": "false", - "south": "false" + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -280,10 +280,10 @@ }, { "when": { - "west": "false", - "east": "true", "north": "false", - "south": "false" + "south": "false", + "west": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_y" @@ -291,10 +291,10 @@ }, { "when": { - "west": "false", - "east": "false", "north": "false", - "south": "false" + "south": "false", + "west": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/none_y" @@ -302,10 +302,10 @@ }, { "when": { - "west": "false", - "east": "true", "up": "true", - "down": "false" + "west": "false", + "down": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lu_z" @@ -313,10 +313,10 @@ }, { "when": { - "west": "true", - "east": "false", "up": "true", - "down": "false" + "west": "true", + "down": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ru_z" @@ -324,10 +324,10 @@ }, { "when": { - "west": "false", - "east": "true", "up": "false", - "down": "true" + "west": "false", + "down": "true", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/ld_z" @@ -335,10 +335,10 @@ }, { "when": { - "west": "true", - "east": "false", "up": "false", - "down": "true" + "west": "true", + "down": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/rd_z" @@ -346,10 +346,10 @@ }, { "when": { - "west": "false", - "east": "false", "up": "true", - "down": "true" + "west": "false", + "down": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -357,10 +357,10 @@ }, { "when": { - "west": "false", - "east": "false", "up": "true", - "down": "false" + "west": "false", + "down": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -368,10 +368,10 @@ }, { "when": { - "west": "false", - "east": "false", "up": "false", - "down": "true" + "west": "false", + "down": "true", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/ud_z" @@ -379,10 +379,10 @@ }, { "when": { + "up": "false", "west": "true", - "east": "true", - "up": "false", - "down": "false" + "down": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -390,10 +390,10 @@ }, { "when": { + "up": "false", "west": "false", - "east": "true", - "up": "false", - "down": "false" + "down": "false", + "east": "true" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -401,10 +401,10 @@ }, { "when": { + "up": "false", "west": "true", - "east": "false", - "up": "false", - "down": "false" + "down": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/lr_z" @@ -412,10 +412,10 @@ }, { "when": { - "west": "false", - "east": "false", "up": "false", - "down": "false" + "west": "false", + "down": "false", + "east": "false" }, "apply": { "model": "create:block/fluid_pipe/none_z" diff --git a/src/generated/resources/assets/create/blockstates/gray_seat.json b/src/generated/resources/assets/create/blockstates/gray_seat.json new file mode 100644 index 000000000..271ea6449 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/gray_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/gray_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/green_seat.json b/src/generated/resources/assets/create/blockstates/green_seat.json new file mode 100644 index 000000000..b799ebf68 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/green_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/green_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/light_blue_seat.json b/src/generated/resources/assets/create/blockstates/light_blue_seat.json new file mode 100644 index 000000000..fac160941 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/light_blue_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/light_blue_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/light_gray_seat.json b/src/generated/resources/assets/create/blockstates/light_gray_seat.json new file mode 100644 index 000000000..ed9d20dfa --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/light_gray_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/light_gray_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/lime_seat.json b/src/generated/resources/assets/create/blockstates/lime_seat.json new file mode 100644 index 000000000..f9ae64b35 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/lime_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/lime_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/magenta_seat.json b/src/generated/resources/assets/create/blockstates/magenta_seat.json new file mode 100644 index 000000000..6b8bc862f --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/magenta_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/magenta_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/orange_seat.json b/src/generated/resources/assets/create/blockstates/orange_seat.json new file mode 100644 index 000000000..3c7cbfce2 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/orange_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/orange_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/pink_seat.json b/src/generated/resources/assets/create/blockstates/pink_seat.json new file mode 100644 index 000000000..93a0255d3 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/pink_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/pink_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/purple_seat.json b/src/generated/resources/assets/create/blockstates/purple_seat.json new file mode 100644 index 000000000..bfb1a6f60 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/purple_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/purple_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 04e5c08ae..f97d8c8bc 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -89,8 +89,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "true" + "sticky_west": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -99,8 +99,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "true" + "sticky_west": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -109,8 +109,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "true" + "sticky_west": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky", @@ -119,8 +119,8 @@ }, { "when": { - "axis": "x", - "sticky_west": "false" + "sticky_west": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -129,8 +129,8 @@ }, { "when": { - "axis": "y", - "sticky_west": "false" + "sticky_west": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -139,8 +139,8 @@ }, { "when": { - "axis": "z", - "sticky_west": "false" + "sticky_west": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_z", @@ -149,8 +149,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "true" + "sticky_north": "true", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky" @@ -158,8 +158,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "true" + "sticky_north": "true", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -168,8 +168,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "true" + "sticky_north": "true", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -178,8 +178,8 @@ }, { "when": { - "axis": "x", - "sticky_north": "false" + "sticky_north": "false", + "axis": "x" }, "apply": { "model": "create:block/radial_chassis_side_x" @@ -187,8 +187,8 @@ }, { "when": { - "axis": "y", - "sticky_north": "false" + "sticky_north": "false", + "axis": "y" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -197,8 +197,8 @@ }, { "when": { - "axis": "z", - "sticky_north": "false" + "sticky_north": "false", + "axis": "z" }, "apply": { "model": "create:block/radial_chassis_side_x", diff --git a/src/generated/resources/assets/create/blockstates/red_seat.json b/src/generated/resources/assets/create/blockstates/red_seat.json new file mode 100644 index 000000000..329cbdd13 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/red_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/red_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/white_seat.json b/src/generated/resources/assets/create/blockstates/white_seat.json new file mode 100644 index 000000000..46d275648 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/white_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/white_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/yellow_seat.json b/src/generated/resources/assets/create/blockstates/yellow_seat.json new file mode 100644 index 000000000..a5be9be3f --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/yellow_seat.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/yellow_seat" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index 6fd3cfafb..c8ea29be7 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -22,8 +22,11 @@ "block.create.belt_tunnel": "\u05DF\u01DDuun\u27D8 \u0287\u05DF\u01DD\u15FA", "block.create.birch_window": "\u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA", "block.create.birch_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA", + "block.create.black_seat": "\u0287\u0250\u01DDS \u029E\u0254\u0250\u05DF\u15FA", + "block.create.blue_seat": "\u0287\u0250\u01DDS \u01DDn\u05DF\u15FA", "block.create.brass_block": "\u029E\u0254o\u05DF\u15FA ss\u0250\u0279\u15FA", "block.create.brass_casing": "bu\u0131s\u0250\u0186 ss\u0250\u0279\u15FA", + "block.create.brown_seat": "\u0287\u0250\u01DDS u\u028Do\u0279\u15FA", "block.create.cart_assembler": "\u0279\u01DD\u05DFq\u026F\u01DDss\u2C6F \u0287\u0279\u0250\u0186", "block.create.chiseled_dark_scoria": "\u0250\u0131\u0279o\u0254S \u029E\u0279\u0250\u15E1 p\u01DD\u05DF\u01DDs\u0131\u0265\u0186", "block.create.chiseled_dolomite": "\u01DD\u0287\u0131\u026Fo\u05DFo\u15E1 p\u01DD\u05DF\u01DDs\u0131\u0265\u0186", @@ -43,6 +46,7 @@ "block.create.crushing_wheel": "\u05DF\u01DD\u01DD\u0265M bu\u0131\u0265sn\u0279\u0186", "block.create.crushing_wheel_controller": "\u0279\u01DD\u05DF\u05DFo\u0279\u0287uo\u0186 \u05DF\u01DD\u01DD\u0265M bu\u0131\u0265sn\u0279\u0186", "block.create.cuckoo_clock": "\u029E\u0254o\u05DF\u0186 oo\u029E\u0254n\u0186", + "block.create.cyan_seat": "\u0287\u0250\u01DDS u\u0250\u028E\u0186", "block.create.dark_oak_window": "\u028Dopu\u0131M \u029E\u0250O \u029E\u0279\u0250\u15E1", "block.create.dark_oak_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u029E\u0250O \u029E\u0279\u0250\u15E1", "block.create.dark_scoria": "\u0250\u0131\u0279o\u0254S \u029E\u0279\u0250\u15E1", @@ -143,6 +147,8 @@ "block.create.granite_cobblestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DD\u0287\u0131u\u0250\u0279\u2141", "block.create.granite_cobblestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DD\u0287\u0131u\u0250\u0279\u2141", "block.create.granite_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u01DD\u0287\u0131u\u0250\u0279\u2141", + "block.create.gray_seat": "\u0287\u0250\u01DDS \u028E\u0250\u0279\u2141", + "block.create.green_seat": "\u0287\u0250\u01DDS u\u01DD\u01DD\u0279\u2141", "block.create.hand_crank": "\u029Eu\u0250\u0279\u0186 pu\u0250H", "block.create.horizontal_framed_glass": "ss\u0250\u05DF\u2141 p\u01DD\u026F\u0250\u0279\u2132 \u05DF\u0250\u0287uoz\u0131\u0279oH", "block.create.horizontal_framed_glass_pane": "\u01DDu\u0250\u0500 ss\u0250\u05DF\u2141 p\u01DD\u026F\u0250\u0279\u2132 \u05DF\u0250\u0287uoz\u0131\u0279oH", @@ -158,6 +164,9 @@ "block.create.layered_limestone": "\u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u028E\u0250\uA780", "block.create.layered_scoria": "\u0250\u0131\u0279o\u0254S p\u01DD\u0279\u01DD\u028E\u0250\uA780", "block.create.layered_weathered_limestone": "\u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u0279\u01DD\u028E\u0250\uA780", + "block.create.light_blue_seat": "\u0287\u0250\u01DDS \u01DDn\u05DF\u15FA \u0287\u0265b\u0131\uA780", + "block.create.light_gray_seat": "\u0287\u0250\u01DDS \u028E\u0250\u0279\u2141 \u0287\u0265b\u0131\uA780", + "block.create.lime_seat": "\u0287\u0250\u01DDS \u01DD\u026F\u0131\uA780", "block.create.limesand": "pu\u0250s\u01DD\u026F\u0131\uA780", "block.create.limestone": "\u01DDuo\u0287s\u01DD\u026F\u0131\uA780", "block.create.limestone_bricks": "s\u029E\u0254\u0131\u0279\u15FA \u01DDuo\u0287s\u01DD\u026F\u0131\uA780", @@ -172,6 +181,7 @@ "block.create.linear_chassis": "s\u0131ss\u0250\u0265\u0186 \u0279\u0250\u01DDu\u0131\uA780", "block.create.linked_extractor": "\u0279o\u0287\u0254\u0250\u0279\u0287x\u018E p\u01DD\u029Eu\u0131\uA780", "block.create.linked_transposer": "\u0279\u01DDsodsu\u0250\u0279\u27D8 p\u01DD\u029Eu\u0131\uA780", + "block.create.magenta_seat": "\u0287\u0250\u01DDS \u0250\u0287u\u01DDb\u0250W", "block.create.mechanical_arm": "\u026F\u0279\u2C6F \u05DF\u0250\u0254\u0131u\u0250\u0265\u0254\u01DDW", "block.create.mechanical_bearing": "bu\u0131\u0279\u0250\u01DD\u15FA \u05DF\u0250\u0254\u0131u\u0250\u0265\u0254\u01DDW", "block.create.mechanical_crafter": "\u0279\u01DD\u0287\u025F\u0250\u0279\u0186 \u05DF\u0250\u0254\u0131u\u0250\u0265\u0254\u01DDW", @@ -201,6 +211,7 @@ "block.create.nozzle": "\u01DD\u05DFzzoN", "block.create.oak_window": "\u028Dopu\u0131M \u029E\u0250O", "block.create.oak_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u029E\u0250O", + "block.create.orange_seat": "\u0287\u0250\u01DDS \u01DDbu\u0250\u0279O", "block.create.ornate_iron_window": "\u028Dopu\u0131M uo\u0279I \u01DD\u0287\u0250u\u0279O", "block.create.ornate_iron_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M uo\u0279I \u01DD\u0287\u0250u\u0279O", "block.create.overgrown_andesite": "\u01DD\u0287\u0131s\u01DDpu\u2C6F u\u028Do\u0279b\u0279\u01DD\u028CO", @@ -248,6 +259,7 @@ "block.create.paved_weathered_limestone_slab": "q\u0250\u05DFS \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u028C\u0250\u0500", "block.create.paved_weathered_limestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u028C\u0250\u0500", "block.create.paved_weathered_limestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u028C\u0250\u0500", + "block.create.pink_seat": "\u0287\u0250\u01DDS \u029Eu\u0131\u0500", "block.create.piston_extension_pole": "\u01DD\u05DFo\u0500 uo\u0131su\u01DD\u0287x\u018E uo\u0287s\u0131\u0500", "block.create.polished_dark_scoria": "\u0250\u0131\u0279o\u0254S \u029E\u0279\u0250\u15E1 p\u01DD\u0265s\u0131\u05DFo\u0500", "block.create.polished_dark_scoria_slab": "q\u0250\u05DFS \u0250\u0131\u0279o\u0254S \u029E\u0279\u0250\u15E1 p\u01DD\u0265s\u0131\u05DFo\u0500", @@ -278,7 +290,9 @@ "block.create.powered_toggle_latch": "\u0265\u0254\u0287\u0250\uA780 \u01DD\u05DFbbo\u27D8 p\u01DD\u0279\u01DD\u028Do\u0500", "block.create.pulley_magnet": "\u0287\u01DDub\u0250W \u028E\u01DD\u05DF\u05DFn\u0500", "block.create.pulse_repeater": "\u0279\u01DD\u0287\u0250\u01DDd\u01DD\u1D1A \u01DDs\u05DFn\u0500", + "block.create.purple_seat": "\u0287\u0250\u01DDS \u01DD\u05DFd\u0279n\u0500", "block.create.radial_chassis": "s\u0131ss\u0250\u0265\u0186 \u05DF\u0250\u0131p\u0250\u1D1A", + "block.create.red_seat": "\u0287\u0250\u01DDS p\u01DD\u1D1A", "block.create.redstone_contact": "\u0287\u0254\u0250\u0287uo\u0186 \u01DDuo\u0287sp\u01DD\u1D1A", "block.create.redstone_link": "\u029Eu\u0131\uA780 \u01DDuo\u0287sp\u01DD\u1D1A", "block.create.reinforced_rail": "\u05DF\u0131\u0250\u1D1A p\u01DD\u0254\u0279o\u025Fu\u0131\u01DD\u1D1A", @@ -328,6 +342,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", "block.create.weathered_limestone_cobblestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u05DFqqo\u0186 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", "block.create.weathered_limestone_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM", + "block.create.white_seat": "\u0287\u0250\u01DDS \u01DD\u0287\u0131\u0265M", + "block.create.yellow_seat": "\u0287\u0250\u01DDS \u028Do\u05DF\u05DF\u01DD\u028E", "block.create.zinc_block": "\u029E\u0254o\u05DF\u15FA \u0254u\u0131Z", "block.create.zinc_ore": "\u01DD\u0279O \u0254u\u0131Z", "entity.create.contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 06a677af8..714cc3079 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -25,8 +25,11 @@ "block.create.belt_tunnel": "Belt Tunnel", "block.create.birch_window": "Birch Window", "block.create.birch_window_pane": "Birch Window Pane", + "block.create.black_seat": "Black Seat", + "block.create.blue_seat": "Blue Seat", "block.create.brass_block": "Brass Block", "block.create.brass_casing": "Brass Casing", + "block.create.brown_seat": "Brown Seat", "block.create.cart_assembler": "Cart Assembler", "block.create.chiseled_dark_scoria": "Chiseled Dark Scoria", "block.create.chiseled_dolomite": "Chiseled Dolomite", @@ -46,6 +49,7 @@ "block.create.crushing_wheel": "Crushing Wheel", "block.create.crushing_wheel_controller": "Crushing Wheel Controller", "block.create.cuckoo_clock": "Cuckoo Clock", + "block.create.cyan_seat": "Cyan Seat", "block.create.dark_oak_window": "Dark Oak Window", "block.create.dark_oak_window_pane": "Dark Oak Window Pane", "block.create.dark_scoria": "Dark Scoria", @@ -146,6 +150,8 @@ "block.create.granite_cobblestone_stairs": "Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "Granite Cobblestone Wall", "block.create.granite_pillar": "Granite Pillar", + "block.create.gray_seat": "Gray Seat", + "block.create.green_seat": "Green Seat", "block.create.hand_crank": "Hand Crank", "block.create.horizontal_framed_glass": "Horizontal Framed Glass", "block.create.horizontal_framed_glass_pane": "Horizontal Framed Glass Pane", @@ -161,6 +167,9 @@ "block.create.layered_limestone": "Layered Limestone", "block.create.layered_scoria": "Layered Scoria", "block.create.layered_weathered_limestone": "Layered Weathered Limestone", + "block.create.light_blue_seat": "Light Blue Seat", + "block.create.light_gray_seat": "Light Gray Seat", + "block.create.lime_seat": "Lime Seat", "block.create.limesand": "Limesand", "block.create.limestone": "Limestone", "block.create.limestone_bricks": "Limestone Bricks", @@ -175,6 +184,7 @@ "block.create.linear_chassis": "Linear Chassis", "block.create.linked_extractor": "Linked Extractor", "block.create.linked_transposer": "Linked Transposer", + "block.create.magenta_seat": "Magenta Seat", "block.create.mechanical_arm": "Mechanical Arm", "block.create.mechanical_bearing": "Mechanical Bearing", "block.create.mechanical_crafter": "Mechanical Crafter", @@ -204,6 +214,7 @@ "block.create.nozzle": "Nozzle", "block.create.oak_window": "Oak Window", "block.create.oak_window_pane": "Oak Window Pane", + "block.create.orange_seat": "Orange Seat", "block.create.ornate_iron_window": "Ornate Iron Window", "block.create.ornate_iron_window_pane": "Ornate Iron Window Pane", "block.create.overgrown_andesite": "Overgrown Andesite", @@ -251,6 +262,7 @@ "block.create.paved_weathered_limestone_slab": "Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "Paved Weathered Limestone Wall", + "block.create.pink_seat": "Pink Seat", "block.create.piston_extension_pole": "Piston Extension Pole", "block.create.polished_dark_scoria": "Polished Dark Scoria", "block.create.polished_dark_scoria_slab": "Polished Dark Scoria Slab", @@ -281,7 +293,9 @@ "block.create.powered_toggle_latch": "Powered Toggle Latch", "block.create.pulley_magnet": "Pulley Magnet", "block.create.pulse_repeater": "Pulse Repeater", + "block.create.purple_seat": "Purple Seat", "block.create.radial_chassis": "Radial Chassis", + "block.create.red_seat": "Red Seat", "block.create.redstone_contact": "Redstone Contact", "block.create.redstone_link": "Redstone Link", "block.create.reinforced_rail": "Reinforced Rail", @@ -331,6 +345,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Weathered Limestone Pillar", + "block.create.white_seat": "White Seat", + "block.create.yellow_seat": "Yellow Seat", "block.create.zinc_block": "Zinc Block", "block.create.zinc_ore": "Zinc Ore", diff --git a/src/generated/resources/assets/create/models/block/black_seat.json b/src/generated/resources/assets/create/models/block/black_seat.json new file mode 100644 index 000000000..c5e3b9429 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/black_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_black", + "2": "create:block/seat/side_black" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/blue_seat.json b/src/generated/resources/assets/create/models/block/blue_seat.json new file mode 100644 index 000000000..5b23c4325 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/blue_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_blue", + "2": "create:block/seat/side_blue" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/brown_seat.json b/src/generated/resources/assets/create/models/block/brown_seat.json new file mode 100644 index 000000000..5734d07ff --- /dev/null +++ b/src/generated/resources/assets/create/models/block/brown_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_brown", + "2": "create:block/seat/side_brown" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/cyan_seat.json b/src/generated/resources/assets/create/models/block/cyan_seat.json new file mode 100644 index 000000000..a1b7657eb --- /dev/null +++ b/src/generated/resources/assets/create/models/block/cyan_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_cyan", + "2": "create:block/seat/side_cyan" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/gray_seat.json b/src/generated/resources/assets/create/models/block/gray_seat.json new file mode 100644 index 000000000..bebf4b2a3 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/gray_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_gray", + "2": "create:block/seat/side_gray" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/green_seat.json b/src/generated/resources/assets/create/models/block/green_seat.json new file mode 100644 index 000000000..ba27dc660 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/green_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_green", + "2": "create:block/seat/side_green" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/light_blue_seat.json b/src/generated/resources/assets/create/models/block/light_blue_seat.json new file mode 100644 index 000000000..9621c729c --- /dev/null +++ b/src/generated/resources/assets/create/models/block/light_blue_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_light_blue", + "2": "create:block/seat/side_light_blue" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/light_gray_seat.json b/src/generated/resources/assets/create/models/block/light_gray_seat.json new file mode 100644 index 000000000..fd48a9cc2 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/light_gray_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_light_gray", + "2": "create:block/seat/side_light_gray" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/lime_seat.json b/src/generated/resources/assets/create/models/block/lime_seat.json new file mode 100644 index 000000000..d30c6df57 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/lime_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_lime", + "2": "create:block/seat/side_lime" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/magenta_seat.json b/src/generated/resources/assets/create/models/block/magenta_seat.json new file mode 100644 index 000000000..f6ab2380b --- /dev/null +++ b/src/generated/resources/assets/create/models/block/magenta_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_magenta", + "2": "create:block/seat/side_magenta" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/orange_seat.json b/src/generated/resources/assets/create/models/block/orange_seat.json new file mode 100644 index 000000000..bc267cb18 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/orange_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_orange", + "2": "create:block/seat/side_orange" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/pink_seat.json b/src/generated/resources/assets/create/models/block/pink_seat.json new file mode 100644 index 000000000..a6a9781aa --- /dev/null +++ b/src/generated/resources/assets/create/models/block/pink_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_pink", + "2": "create:block/seat/side_pink" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/purple_seat.json b/src/generated/resources/assets/create/models/block/purple_seat.json new file mode 100644 index 000000000..1db18ce5e --- /dev/null +++ b/src/generated/resources/assets/create/models/block/purple_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_purple", + "2": "create:block/seat/side_purple" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/red_seat.json b/src/generated/resources/assets/create/models/block/red_seat.json new file mode 100644 index 000000000..0d294e9f0 --- /dev/null +++ b/src/generated/resources/assets/create/models/block/red_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_red", + "2": "create:block/seat/side_red" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/white_seat.json b/src/generated/resources/assets/create/models/block/white_seat.json new file mode 100644 index 000000000..c3b473e2a --- /dev/null +++ b/src/generated/resources/assets/create/models/block/white_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_white", + "2": "create:block/seat/side_white" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/block/yellow_seat.json b/src/generated/resources/assets/create/models/block/yellow_seat.json new file mode 100644 index 000000000..561829e5e --- /dev/null +++ b/src/generated/resources/assets/create/models/block/yellow_seat.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/seat", + "textures": { + "1": "create:block/seat/top_yellow", + "2": "create:block/seat/side_yellow" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/black_seat.json b/src/generated/resources/assets/create/models/item/black_seat.json new file mode 100644 index 000000000..740ab204c --- /dev/null +++ b/src/generated/resources/assets/create/models/item/black_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/black_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/blue_seat.json b/src/generated/resources/assets/create/models/item/blue_seat.json new file mode 100644 index 000000000..421c18440 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/blue_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/blue_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/brown_seat.json b/src/generated/resources/assets/create/models/item/brown_seat.json new file mode 100644 index 000000000..fae33e56d --- /dev/null +++ b/src/generated/resources/assets/create/models/item/brown_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/brown_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/cyan_seat.json b/src/generated/resources/assets/create/models/item/cyan_seat.json new file mode 100644 index 000000000..0ffbe72d0 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/cyan_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/cyan_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/gray_seat.json b/src/generated/resources/assets/create/models/item/gray_seat.json new file mode 100644 index 000000000..46eba51d3 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/gray_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/gray_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/green_seat.json b/src/generated/resources/assets/create/models/item/green_seat.json new file mode 100644 index 000000000..0bd47c5e6 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/green_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/green_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/light_blue_seat.json b/src/generated/resources/assets/create/models/item/light_blue_seat.json new file mode 100644 index 000000000..be049f6d1 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/light_blue_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/light_blue_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/light_gray_seat.json b/src/generated/resources/assets/create/models/item/light_gray_seat.json new file mode 100644 index 000000000..6552e78f7 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/light_gray_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/light_gray_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/lime_seat.json b/src/generated/resources/assets/create/models/item/lime_seat.json new file mode 100644 index 000000000..68264f55d --- /dev/null +++ b/src/generated/resources/assets/create/models/item/lime_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/lime_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/magenta_seat.json b/src/generated/resources/assets/create/models/item/magenta_seat.json new file mode 100644 index 000000000..ac661a20a --- /dev/null +++ b/src/generated/resources/assets/create/models/item/magenta_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/magenta_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/orange_seat.json b/src/generated/resources/assets/create/models/item/orange_seat.json new file mode 100644 index 000000000..e64ba3711 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/orange_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/orange_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/pink_seat.json b/src/generated/resources/assets/create/models/item/pink_seat.json new file mode 100644 index 000000000..808bca5d0 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/pink_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/pink_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/purple_seat.json b/src/generated/resources/assets/create/models/item/purple_seat.json new file mode 100644 index 000000000..21d6d00b9 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/purple_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/purple_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/red_seat.json b/src/generated/resources/assets/create/models/item/red_seat.json new file mode 100644 index 000000000..bb30dc0fb --- /dev/null +++ b/src/generated/resources/assets/create/models/item/red_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/red_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/white_seat.json b/src/generated/resources/assets/create/models/item/white_seat.json new file mode 100644 index 000000000..609a09653 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/white_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/white_seat" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/yellow_seat.json b/src/generated/resources/assets/create/models/item/yellow_seat.json new file mode 100644 index 000000000..d55fbb130 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/yellow_seat.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/yellow_seat" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/black_seat.json b/src/generated/resources/data/create/loot_tables/blocks/black_seat.json new file mode 100644 index 000000000..adebd728e --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/black_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:black_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/blue_seat.json b/src/generated/resources/data/create/loot_tables/blocks/blue_seat.json new file mode 100644 index 000000000..1a89498c9 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/blue_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:blue_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/brown_seat.json b/src/generated/resources/data/create/loot_tables/blocks/brown_seat.json new file mode 100644 index 000000000..502d1e5bb --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/brown_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:brown_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/cyan_seat.json b/src/generated/resources/data/create/loot_tables/blocks/cyan_seat.json new file mode 100644 index 000000000..75aeb06c0 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/cyan_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:cyan_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/gray_seat.json b/src/generated/resources/data/create/loot_tables/blocks/gray_seat.json new file mode 100644 index 000000000..83fa2bff9 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/gray_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:gray_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/green_seat.json b/src/generated/resources/data/create/loot_tables/blocks/green_seat.json new file mode 100644 index 000000000..a517336e1 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/green_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:green_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/light_blue_seat.json b/src/generated/resources/data/create/loot_tables/blocks/light_blue_seat.json new file mode 100644 index 000000000..c8e44be0f --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/light_blue_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:light_blue_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/light_gray_seat.json b/src/generated/resources/data/create/loot_tables/blocks/light_gray_seat.json new file mode 100644 index 000000000..4adbfa03c --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/light_gray_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:light_gray_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/lime_seat.json b/src/generated/resources/data/create/loot_tables/blocks/lime_seat.json new file mode 100644 index 000000000..3eae5d688 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/lime_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:lime_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/magenta_seat.json b/src/generated/resources/data/create/loot_tables/blocks/magenta_seat.json new file mode 100644 index 000000000..2c2867862 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/magenta_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:magenta_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/orange_seat.json b/src/generated/resources/data/create/loot_tables/blocks/orange_seat.json new file mode 100644 index 000000000..8b6461277 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/orange_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:orange_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/pink_seat.json b/src/generated/resources/data/create/loot_tables/blocks/pink_seat.json new file mode 100644 index 000000000..0bfac1ff2 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/pink_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:pink_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/purple_seat.json b/src/generated/resources/data/create/loot_tables/blocks/purple_seat.json new file mode 100644 index 000000000..053d3f5a7 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/purple_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:purple_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/red_seat.json b/src/generated/resources/data/create/loot_tables/blocks/red_seat.json new file mode 100644 index 000000000..740c68eaf --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/red_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:red_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/white_seat.json b/src/generated/resources/data/create/loot_tables/blocks/white_seat.json new file mode 100644 index 000000000..301d51e21 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/white_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:white_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/yellow_seat.json b/src/generated/resources/data/create/loot_tables/blocks/yellow_seat.json new file mode 100644 index 000000000..4b63ee7e3 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/yellow_seat.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:yellow_seat" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 885c35b6d..f6e4d1dc2 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -14,6 +14,7 @@ import com.simibubi.create.content.contraptions.components.actors.DrillBlock; import com.simibubi.create.content.contraptions.components.actors.HarvesterBlock; import com.simibubi.create.content.contraptions.components.actors.PloughBlock; import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceBlock; +import com.simibubi.create.content.contraptions.components.actors.SeatBlock; import com.simibubi.create.content.contraptions.components.clock.CuckooClockBlock; import com.simibubi.create.content.contraptions.components.crafter.CrafterCTBehaviour; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlock; @@ -120,6 +121,7 @@ import net.minecraft.block.Blocks; import net.minecraft.block.SoundType; import net.minecraft.block.material.MaterialColor; import net.minecraft.client.renderer.RenderType; +import net.minecraft.item.DyeColor; import net.minecraft.state.properties.PistonType; import net.minecraft.tags.BlockTags; import net.minecraft.util.Direction.Axis; @@ -590,6 +592,22 @@ public class AllBlocks { .simpleItem() .register(); + static { + for (DyeColor colour : DyeColor.values()) { + String colourName = colour.getName(); + REGISTRATE.block(colourName + "_seat", p -> new SeatBlock(p, colour == DyeColor.RED)) + .initialProperties(SharedProperties::wooden) + .blockstate((c, p) -> { + p.simpleBlock(c.get(), p.models() + .withExistingParent(colourName + "_seat", p.modLoc("block/seat")) + .texture("1", p.modLoc("block/seat/top_" + colourName)) + .texture("2", p.modLoc("block/seat/side_" + colourName))); + }) + .simpleItem() + .register(); + } + } + public static final BlockEntry ANDESITE_CASING = REGISTRATE.block("andesite_casing", CasingBlock::new) .transform(BuilderTransformers.casing(AllSpriteShifts.ANDESITE_CASING)) .register(); diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 285d7c400..bcf46e91d 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -99,6 +99,7 @@ public class AllShapes { .add(2, 0, 2, 14, 2, 14) .build(), CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16), + SEAT = cuboid(0, 0, 0, 16, 8, 16), MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12) .build(), TURNTABLE_SHAPE = shape(1, 4, 1, 15, 8, 15).add(5, 0, 5, 11, 4, 11) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java new file mode 100644 index 000000000..1f32e1d24 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -0,0 +1,37 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.AllShapes; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; + +public class SeatBlock extends Block { + + private boolean inCreativeTab; + + public SeatBlock(Properties p_i48440_1_, boolean inCreativeTab) { + super(p_i48440_1_); + this.inCreativeTab = inCreativeTab; + } + + @Override + public void fillItemGroup(ItemGroup group, NonNullList p_149666_2_) { + if (group != ItemGroup.SEARCH && !inCreativeTab) + return; + super.fillItemGroup(group, p_149666_2_); + } + + @Override + public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_, + ISelectionContext p_220053_4_) { + return AllShapes.SEAT; + } + +} diff --git a/src/main/resources/assets/create/models/block/seat.json b/src/main/resources/assets/create/models/block/seat.json new file mode 100644 index 000000000..2f23ff9e9 --- /dev/null +++ b/src/main/resources/assets/create/models/block/seat.json @@ -0,0 +1,24 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "0": "create:block/seat/bottom", + "1": "create:block/seat/top_red", + "2": "create:block/seat/side_red", + "particle": "#1" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 8, 16], + "faces": { + "north": {"uv": [0, 8, 16, 16], "texture": "#2"}, + "east": {"uv": [0, 8, 16, 16], "texture": "#2"}, + "south": {"uv": [0, 8, 16, 16], "texture": "#2"}, + "west": {"uv": [0, 8, 16, 16], "texture": "#2"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/seat/bottom.png b/src/main/resources/assets/create/textures/block/seat/bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..744293ab69cc2cf06fb87c802110e6ff03df3be2 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF0soHq=b70&7bx20)I)Ft}{33?^*o$+Q;2YOD9xtv`jy-E^DK} z%(fRThFxbi-8D_x`ss+3>b7&G5s|MCZkG^MTO>5U(*M)dU7lf@YI76Je=fXqvB{^g eXN|eam+AJuPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T@X{K~y+T?NUuk z12GVNiJQZ2KM+wN_SP1PzemKIH~*0*1rNoGi2p|Lx z@WC)MZ{C}P5MiywZy=ZX$M|3H7Z!-!(a0(lK}8CtHZZ0}631M7E}VVU%8>B*&K$z? zzLbTth_&}n|w^vzOnd@{D_Y>JEVDU+sl*Noh)c*&>OhvyFtkDzyY z5NGFCwk!*@9xpM_TWknXR`2dj)|Op^+w=*=_CAuN1xaQq2ru~@*Ejbppqk7C%G8G( zdB`gl^PGz+TOd{mbZ--SeS<}5_PUC!cw??IC2Pq;UfJ$+L2r=jJ={G^RwB+$NXvW> h(&;m6$Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0UAj}K~y+T?UF%C z!$25?Us984rWKW@cIy?~xbg@Jf}X>@H*q6^u3WhD2p&VI8->~wwQVL%Vi|pZn=pzi z-MH|BVcxv|y%`ActhM+J{&N2@{}=p)3%s496T1>>1c63b8oU(-Q7aZ*dG73M)_0AH z@5(Nf&#t$xT3e@VSFlWVVim=(1 z+2QUM;y8wPetBi{B1iN22Hno46kLjYj!-q0rv<~&6J{HGP@#g)G6hM^1P}c?2~e|4 zxby6K?6B)+#)v4!V+0M2^Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0TxL_K~y+T?NZB1 z!$1^0Gts6Qiw~08FA%zN=U=#RuWO-Sq#F?w7w-KS7eZGGwJBtKGc#WpJ960^c5@3CGooZ zJtRp2b$Wj3in2iS;R@||QwnvIvtnbu$YVIV$8=*CVIzcQnS{vfGj97g5+G-p;N-oo zvBR#;trb#^$5;*w);k@nwPFc9O-74j^IWu-%1V|Uc6DS7_zkl59)@@QMTlUK%lsi8 f2Ls8n6B&bdjghotew2}E00000NkvXXu0mjfS#Fx_ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_cyan.png b/src/main/resources/assets/create/textures/block/seat/side_cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..8b353336a93304151b8f23edf20eb2359b786233 GIT binary patch literal 389 zcmV;00eb$4P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0UAj}K~y+T?UFxB z!%!5(&r7sPo`ot+?It)o_(dF?T?>wW9uY*Sle=HU!AmshqZ3xrSC=ykUx;8GS9T7kd3eK46mBHubd&7^oR0 zth~EDW|;LdV?>m*8PE jWz8YaPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0TxL_K~y+T?NU8U z!%!4GFQRGFCWutw+0h@-K`7$pCP@F8lY@h}iQwkyj}V;vK&Sz~2x*fviac{}`s$-N z>Ehsl%f0v9b525tGRELH@TUF8_z(CC0cyM7H@?3F-}h0LWmRv8qEKebxwm<(=Mom* znO#_(UbWfl$*)La{^){Fv$uM$L)HGlk%=FMxHvz7ZFB^}}N>Q)4tX(rgYyBt0A zdgDttdeXZT=AZZmL7V&b{K)*Ak}-gxx1fyj6xp+&uC-fG00000NkvXXu0mjf(7dV3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_green.png b/src/main/resources/assets/create/textures/block/seat/side_green.png new file mode 100644 index 0000000000000000000000000000000000000000..a635009ea22bc115589fd02924df5b772e96688d GIT binary patch literal 387 zcmV-}0et?6P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T@X{K~y+T?UKDp z13?sp&(8j@f{|=Yt)OpVX_vxhu=iW}$f@D~mgu%;&c1q;*=YGLY|{3b zwGNK=h{TW_Jn+Q0N?YW7^WbL^bHT=dofTmOjvn0 zd(1GavNRP@&gXFL2%UZ(JKJ3`y}r-ZC(SbHRZS{hW|&oB6oKDh(L2TTalAGW8o8`J h@x}002ovPDHLkV1g|^rV0Q6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_light_blue.png b/src/main/resources/assets/create/textures/block/seat/side_light_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c84096dc4a795d1fba9e6ab38f5e3ad5bef6636b GIT binary patch literal 391 zcmV;20eJq2P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0USw0K~y+T?T|fA z!$1&)pEru_tP@CNha8B8f`T(~0a_Y_6e@aJZh{n15Gje1fa8A@E&CQbS|KWED0tFn zW@p|vmd8;_;WrXZ{;~cS{DlS1+2xh$`Vy|+LtPelFLMOL(9~_uo_+NSyV2@9*jC#o zE7HvpoB6ZZ#;Eets;SVRUF57+-9h=oi^>@$pPG8pmX2A1UW0S1b%R2 zW~ZY7Q53u$pz*b%D;d-6s^{Lf*iE?xf&-EY(v!F8l^_SU`F|Z~~ zG4pNr$dDC9uK!IJb&{alkr+-UIPQnW^p>sPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0W3*GK~y+T?U27t z!!QuWKPRHWP9#7{=>t?Sv+x!SyhA76g2!N~kYHlxEm)WlQYVl~6G2OClRuToU7IRG zOt3KUS=OEJzTd^MaL(a3^49Uk`XBHY28grK$SEZurGm8v##qF0%z0bu_P%<(ZlTq8 za93@eSpQ%+JfANX5Y4Kp8rm4ng;<&Ey5dM*YkTBNvy5xvVtnP&G{wXH9dez+=;oTC zL=;8{m13Ac>S=8dhKhTKN5@E#1mg1g#ua6O?bloM<9!CYDvKq0fxkYjG|OJ_v3G)? z7r-N!5|TFWc$z%2fpUUL6zSZp5kstJo9j_hHt(?IE9?#i*ok5`>%tjkR2>mWI8= z5bMe2Kj{s0{}i+5$;Lz?BMoae>1{e?FELUnd;;g`!W`VHXPy86002ovPDHLkV1lyf BukZi> literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_lime.png b/src/main/resources/assets/create/textures/block/seat/side_lime.png new file mode 100644 index 0000000000000000000000000000000000000000..a0c7347203dd92b794172a2a8a8b7696546849ea GIT binary patch literal 390 zcmV;10eSw3P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0UJp~K~y+T?T|4} z!$1&4zt_Qzmsk+lAq_|22ozLYgPTy(ph!?b&2f+-AwUXt1laL9-o#m$Nj6#`DrhM9 z(r9M?{5QpV#u)rYV$*-D{{w&FfOmF&WJ2j7hy--KLZb}g#OK+1?(S<=xQ5ktuq*2m zD~fD^{Gs7%T-B1hg=}|sRKyVLU0hz7JkRl{Z=uQ-^Vt&JUI#Mv5$<-@@Fz&Sy3~l` zfOm(%Dbh5BH@dztjc(9=y~7|mV8E4bS_GlLd99UAUoh_IXyo&z)! zOrlP2*CU2lQ7grRE(+}U68pm;_Ie42-e=Qosk&xw(JIaoL#&9T1pPrZI6?M2-iAmN kq+_;7Z<7gUiHW4d2VlIPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T)R`K~y+T?U2Dr z!%z@KZ&I2xk6M+a_6PhGH{!y7@k89Y5uvW!i(gYHE)>$H7}MsxCZ#-c$G#H8m2O;k z;WG1P?ioltYb|~we^-C3{{w&FfOma%WmPvs)Yxn)=*F=cNbhFt-Pf$&9yommx8>$! z{aKmgIZx#py{e5=2f5nb(PYSaH@9P(Wf|<#1j|}CUgIF>HCE^ck-!AGD=LFQ7|G5% zKSh!x@b2y(Y*kn2y**+Wp9s)aU2PGBo!#qG^TiD7;|qjA^9h96P^DhtWjc`nd%_ee z-|ZP0vcAz;nz|^^?I;|LMmX%p5_(@P_SVM8Y_rvpB}3Malmh=jIlRRDb-E8x4Dy&W gm8Yp>$wW%w0}bcTZ7uUMf&c&j07*qoM6N<$f-}&gXaE2J literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_orange.png b/src/main/resources/assets/create/textures/block/seat/side_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..267ab3c3e252d57af90a76a8c77dbe8b01b4f625 GIT binary patch literal 387 zcmV-}0et?6P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T@X{K~y+T?T|rA z!$25?-%M%JPTEv$YAzxOp23A1@c>?`8xicPdynA}gsv27Q?yAlX;R|I8%-I-m2O=4 z!7wlXd+#5JFvj3F$dCKS{4e+m3&iB|#Hc`^(-YXN4RmgB5KF6@nd^PcN_WukUD>6X zvn$5u$JPzPmNoOVwwk63Uu!%#w1CC=x&NEe?^vV(GT0`2l7*xUb?Cf4m|56 zM;C~q2;zD&HDy(z^L&fZ@X!`qsTxWQg-P-^)%Y-+- z-5ERV%0g=^sx(ErrLY&r81#lVv|2BBM;C>iZEJ0_?651lN`e0%ADvEIVDL@CGbzwOT57?~4Ec002ovPDHLkV1mIpqhbI6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_pink.png b/src/main/resources/assets/create/textures/block/seat/side_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..cc1a19c0ea72e0a13bb0fe8f59922ce0fadc4803 GIT binary patch literal 404 zcmV;F0c-w=P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0VzpDK~y+T?T}4Q z!!Q(t#|bov6H2S3^akv>0pbKKxCHm$5G;@oLV^{0Zo(F+E09W4O7mkUZK}YSriu_N z*sx$M%g^)XdzLKfy2fv0tN)R@-Rw z9o$yqleLfb56|XV3LylRRfSwDQ*%+(hez?XrpH`7do`Z8xVow1I7aYLA<-F9m19Tx z=z0NsPa2pYdr6+5>j$Qn9c&?rB8cnTySiMIaA)@zgnI^PYf-MyaqRW&Q1HdfjkjDWlO;pe y@}va+ARnAy@;usvCPx#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0W3*GK~y+T?T|rE zg)k6?e;^N}kf;IV0LF#!6z)y*6kfm!cnmkjL{~0Nyo(D>-b#}vy!b>~q!lYuUJWs> zbmPK5DKnkPModfWS3NYfO~*~O)9Ws8-kYh=lW0mhPT2S4zZyFtbL5wGie z2>bvp!IY4=c)|Vj&KM{sm_(8G;~Fu$FP>?Sd9~7dhY+zF3}7RsXAf2 z#1QL-jDg;OX9p-Ark^Gf8EKeZq{VDzyu^fz;RDMK!WC83oMQk0002ovPDHLkV1fdG Br&|C3 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_red.png b/src/main/resources/assets/create/textures/block/seat/side_red.png new file mode 100644 index 0000000000000000000000000000000000000000..f275d37ea82d2c6defeae5fa54969ba2c4f3e1ee GIT binary patch literal 387 zcmV-}0et?6P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T@X{K~y+T?U2Dr z!$1&*|J`j86H-)?+9&bu1BiI^sXTiTK`(k0A4e!26xyb!O}a5@H!CykmPI`2#e+W# zGyBi~&0&SL7Qd0)^dIa0z+X5Z&JT}lA}wOop*9k_6UYL?v-AAj*R1pnr|)22&L>t* zT7jop@inSy1?~=V-QQ6WL#(*CytYMApu4?CX$-2RK^iFZl|tHMmOB<7eZU|)SQDPw#vqK;=C#&zHo?dKF`_VnB$x)$LYH_RJ#v6%f=Sfr z?R&%!D{HNJXyyv&6(nf=}j@!1{ojq7485002ovPDHLkV1g1vqB8&h literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_white.png b/src/main/resources/assets/create/textures/block/seat/side_white.png new file mode 100644 index 0000000000000000000000000000000000000000..4998d81e2d876034a97bb524f1a14052e9b6ab48 GIT binary patch literal 400 zcmV;B0dM|^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0VPR9K~y+T?T}4Q z!!QtqpA)4a&JUoZ^e7W}q*!C$yQTwa_TDJ48lqG=SAQi$V(`@tK}zGkhlG3YyZtidPN zK0Z1;%kvyU2xzTQ*ERS3Vy#x1D}8O4Q7+3;_Qciot;wJ@C90}I5Cn*#5Wep- zOd!pQvP2YyJkySkBuOA{?(R+7wb*%mz%)K!V63iPW8&JI)2Gtq3*Prn;7(jv1XDw* zRf(thBL}D_m_(J%V~-eOt)~AEYPzC;V@vGKX4nm44&~KyyH(S$r`L+J#1LzF{Y%mt u)YDU>&+~1FL_xZ2*rd0`g0sYUQsM(DF~Zcg`?*K}0000Nvr literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/side_yellow.png b/src/main/resources/assets/create/textures/block/seat/side_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..d25d7af9e163cd23ca2145fbf7c2ca770bbd1cfa GIT binary patch literal 387 zcmV-}0et?6P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA0T@X{K~y+T?U2Dv z!ax*7Z->yrU;(AT!awmFT)6XR{17+BL{{wm91<1=4YovRZA)A0z#SbjF|Ksu!kgT@ zH}Bo^7UL+T@EeKG`eXec_zMS|$<>*X9S5zwx2Zz5_sK};-puUX*Q~GyM&H4<%$%$U zpWg5=tMoNGjcZ*EWU9TR$&hufZ|+nSMF+}rLnJP%_Fm*YpuoYpQrN`w<#smq6(?AjqzxRt&tK$KuV4P&agocF zl}uh@ifS46?kwlzIk~EK;_7`K{Y#-n2oI1@teb%A*2|!6)pmLq-A)p**fk$L90|U1( z2s1Lwnj--eO!stg43W63+Ix}rfC2~WN?{Yzm)qIcSDavBk~VPoK7Wx{y?*(7$3-qz zRx){sDXL}MyR)2==j5u|iL3W{lv{~=uJY$Tp7W|<;Tt_O@kC=zp`Uk}t>p{;{M>ir kr;<#i#R(bl8G_u?_}x!RF7n*JfCuD8Pgg&ebxsLQ0RL@HR{#J2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_brown.png b/src/main/resources/assets/create/textures/block/seat/top_brown.png new file mode 100644 index 0000000000000000000000000000000000000000..c05b5386fb6751642e9780593c57340549d8715a GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF7Fi*ArhBWdoS`HP~c!)DQsf;ayuLQiW4kM(gqIS=P&ZA*DrtXxX9(o zN+vHcMYW83cb0SVoLp5qarHiraw~DqRsP(^b6zzpe4}S3o@mS|^z%-$wS2*!pZjk7 kRFbK*I3XiGLy&tKzxzqaMV|W?@PORt>FVdQ&MBb@0H;VyasU7T literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_cyan.png b/src/main/resources/assets/create/textures/block/seat/top_cyan.png new file mode 100644 index 0000000000000000000000000000000000000000..0211f1f79e1c29d2e7b5152df910d9e5f251cf26 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFmdKI;Vst0Oo5>O#lD@ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_gray.png b/src/main/resources/assets/create/textures/block/seat/top_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..445600cade60e144fbd839349b9c00ceb5f2492c GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF+}rLnJP%_Fm*YpuoYpQrN`w<#smq6(?AjqzxRt&tK$KuV4P&agocF zl}uh@ifS46?kwlzIk~EK;_7`Kvk^lez literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_green.png b/src/main/resources/assets/create/textures/block/seat/top_green.png new file mode 100644 index 0000000000000000000000000000000000000000..4f259754731c4743b5d787d251bb40186e6a9c85 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFo6lZ3dXmx0Q0#Fhcc>nR01W=B%z$3Dlfq`2X zgc%uT%>fCfd%8G=NL*I!y~uk&frE9Wu!-r*?QHBTPOvaZ8#sKQzsRdzzx=)9B9|*G znY_dl)iUngSl!qA{n?&pXZ5@&$i>?z{0* jNv6``gpBwMLGEe%?k6P|dG24p19GFMtDnm{r-UW|U$ab2 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_light_blue.png b/src/main/resources/assets/create/textures/block/seat/top_light_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..1b8798945bf22dbbaca6086ca1e2a0e4f5bc3887 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFQ zL70(Y)*K0-V7jM^V~E6M)!vJ|2NXD1R|=b$zTD2nzTyN6leB@u_xX#w>h;UtJ1%m$ zvXaS5Oi?Z4-ks%~JSSJxPF%guquff|bCo~$@tju;3*YFOi6lMBBS??~Npdnbg zs$r6A2j?vF@0m=_o3i4ctkS*xh~B^@dNAi{1AJ=h$WH_vx4I k<8YVbGdj+icBJVkbMX!-t*M1GOF?e*boFyt=akR{05OMAlmGw# literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_lime.png b/src/main/resources/assets/create/textures/block/seat/top_lime.png new file mode 100644 index 0000000000000000000000000000000000000000..a6623db59ff94460e1a170685e6b50f1ee4bcd60 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFbFSoO?uQMQ&h{icV{^#&&gG_6Ibu^D7O;#T;9GX%M(@w=atT;#cb0T0NHp00i_>zopr0DBNl(EtDd literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_magenta.png b/src/main/resources/assets/create/textures/block/seat/top_magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..a3f3d564746bad62d825cd909de2dbc7f9796a25 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFd?-0k==*pCjcdJ0n0VNM1gXg1s;*b3=G`D zAk4@xYmNj^Fx}I|F+}3BYVSqf0}33hD}_x=Uv6h(UvYwkN!q~S`}{>-_4?)S9T&M= zS;^!jrl^*2@6K{go|CI;C$8S-QEnyfxyqmWc+RVag>UrC#1oA?ww5pW^K;*g lpGq>77AIuHX9#jn<99zPxyW<>0v?bXJzf1=);T3K0RS6vPs0EJ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_orange.png b/src/main/resources/assets/create/textures/block/seat/top_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..c8df63fe7a79e3d3dfd52fab1a76774ec6f86643 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF#bEb`&w)c_Bb7yp8%A^1%ACM+6$E9EbxddW?_;YP`3a8 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_pink.png b/src/main/resources/assets/create/textures/block/seat/top_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..a66c30ebf44709adab1230a780c21844277f547a GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFXfCqbJvwF-B!Ey(ENm*jT?ZHxPXst)>NPzXMsm#F#`j) zFbFd;%$g$s6ioMYaSV~TtlE1}@PGmbOQ&ecqbKW|SzVSeB~~ow__bcqYoGP*@(CJ( zrK=hyxpr{QGXI{*{>du+OLNb;PI`6ukl}2r1dZL@XI*djG`ZM)e{hanrhcD( l***?;IX8z{$F;1OBOz`!jG z!i)^F=12eq(>+}rLnJP%_Fm*YpuoYpQrN`w<#smq6(?AjqzxRt&tK$KuV4P&agocF zl}uh@ifS46?kwlzIk~EK;_7`Kq;7CsmV5o?)uLc`m1_pH9s5g zA~)86WgLc%pPt##kYt^y6CjxAPEYf1NLsH8(?&Fy4IpM@_xjU7upU;0k mdQSY|iNlW1b{y!OVOT#~n!iix_)=YvBRyUHT-G@yGywnw(^2{W literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_white.png b/src/main/resources/assets/create/textures/block/seat/top_white.png new file mode 100644 index 0000000000000000000000000000000000000000..aa3e1bde614183604451ddbabad30470009db3b0 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFjL@ zuGWGS!K9{VXKQC2n6T!Sc;&0clBLxXm;BmRaAp~w#Hn{l#e!y&6(*jy-SL_6`TY0Y mbM+5RY;QhO*eJO%;U`1-9z~N!y*I5vZuE5Zb6Mw<&;$UhW>{kY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/seat/top_yellow.png b/src/main/resources/assets/create/textures/block/seat/top_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..28d163965f8bf349e1719197a18b8080606fa6aa GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF#dV)_RY09G(X|sA}63EF5rAJ_6<;uv%n*=n1O-s zFbFdq&tH)O6ioMYaSV~TtlE1}@PGmbOQ&ecqbKW|SzVSeB~~ow__bcqYoGP*@(CJ( zrK=hyxpr{QGXI{*{>du+OLNb;PI`6ukl}2r1dZL@XI*djG`ZM)e{hanrhcD( l***?;IX Date: Sun, 12 Jul 2020 23:57:27 +0200 Subject: [PATCH 05/17] Actually playable - Fixed some left-over math bugs - Greatly improved contraption-player collision response, especially with rotating structures --- gradle.properties | 2 +- .../ContraptionCollider.java | 138 ++++++++++++------ .../collision/CollisionDebugger.java | 45 +++--- .../foundation/collision/OrientedBB.java | 10 +- .../create/foundation/utility/VecHelper.java | 2 + 5 files changed, 124 insertions(+), 73 deletions(-) diff --git a/gradle.properties b/gradle.properties index 79739da3d..14cb1efe7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.daemon=false # mod version info mod_version=0.3 minecraft_version=1.15.2 -forge_version=31.2.21 +forge_version=31.2.31 # dependency versions registrate_version=0.0.4.18 diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 235858024..e91c2221d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -8,7 +8,7 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; -import org.apache.commons.lang3.mutable.MutableBoolean; +import org.apache.commons.lang3.mutable.MutableObject; import com.google.common.base.Predicates; import com.google.common.cache.Cache; @@ -29,6 +29,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.MoverType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; @@ -41,6 +42,7 @@ import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.WorldTickEvent; @@ -118,7 +120,11 @@ public class ContraptionCollider { if (bounds == null) return; - for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(1), + double conRotX = contraptionRotation.z; + double conRotY = contraptionRotation.y; + double conRotZ = contraptionRotation.x; + + for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2), contraptionEntity::canCollideWith)) { if (entity instanceof PlayerEntity && !world.isRemote) return; @@ -127,11 +133,13 @@ public class ContraptionCollider { Vec3d entityPosition = entity.getPositionVec(); Vec3d centerY = new Vec3d(0, entity.getBoundingBox() .getYSize() / 2, 0); - Vec3d position = entityPosition.subtract(contraptionPosition) - .subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0)) - .add(centerY); - position = - VecHelper.rotate(position, -contraptionRotation.z, -contraptionRotation.y, -contraptionRotation.x); + + Vec3d position = + entityPosition.subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0)) + .add(centerY); + + position = position.subtract(contraptionPosition); + position = VecHelper.rotate(position, -conRotX, -conRotY, -conRotZ); position = position.add(centerOfBlock) .subtract(centerY) .subtract(entityPosition); @@ -139,6 +147,16 @@ public class ContraptionCollider { .offset(position) .grow(1.0E-7D); + String nbtMotionKey = "ContraptionCollisionFeedback"; + CompoundNBT entityData = entity.getPersistentData(); + Vec3d previousIntersection = Vec3d.ZERO; + if (entityData.contains(nbtMotionKey)) { + previousIntersection = VecHelper.readNBT(entityData.getList(nbtMotionKey, NBT.TAG_DOUBLE)); + entity.setMotion(entity.getMotion() + .subtract(previousIntersection.mul(1, 0, 1))); + entityData.remove(nbtMotionKey); + } + ReuseableStream potentialHits = getPotentiallyCollidedShapes(world, contraption, localBB); if (potentialHits.createStream() .count() == 0) @@ -147,51 +165,72 @@ public class ContraptionCollider { OrientedBB obb = new OrientedBB(localBB); if (!contraptionRotation.equals(Vec3d.ZERO)) { Matrix3d rotation = new Matrix3d().asIdentity(); - rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(contraptionRotation.z))); - rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(contraptionRotation.y))); - rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(contraptionRotation.x))); + rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(-conRotX))); + rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(conRotY))); + rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(-conRotZ))); obb.setRotation(rotation); } - MutableBoolean onCollide = new MutableBoolean(true); + MutableObject collisionResponse = new MutableObject<>(Vec3d.ZERO); + Vec3d obbCenter = obb.getCenter(); + potentialHits.createStream() .forEach(shape -> { - AxisAlignedBB bb = shape.getBoundingBox(); - Vec3d intersect = obb.intersect(bb); - if (intersect == null) - return; - intersect = VecHelper.rotate(intersect, contraptionRotation.z, contraptionRotation.y, - contraptionRotation.x); - - obb.setCenter(obb.getCenter() - .add(intersect)); - entity.move(MoverType.PISTON, intersect); - - Vec3d entityMotion = entity.getMotion(); - if (entityMotion.getX() > 0 == intersect.getX() < 0) - entityMotion = entityMotion.mul(0, 1, 1); - if (entityMotion.getY() > 0 == intersect.getY() < 0) - entityMotion = entityMotion.mul(1, 0, 1); - if (entityMotion.getZ() > 0 == intersect.getZ() < 0) - entityMotion = entityMotion.mul(1, 1, 0); - entity.setMotion(entityMotion); - - if (onCollide.isTrue()) { - onCollide.setFalse(); - contraptionEntity.collidingEntities.add(entity); - entity.velocityChanged = true; - } - - if (intersect.y > 0) { - entity.handleFallDamage(entity.fallDistance, 1); - entity.fallDistance = 0; - entity.onGround = true; - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); - } - - if (entity instanceof ServerPlayerEntity) - ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; + Vec3d currentResponse = collisionResponse.getValue(); + shape.toBoundingBoxList() + .parallelStream() + .forEach(bb -> { + obb.setCenter(obbCenter.add(currentResponse)); + Vec3d intersect = obb.intersect(bb); + if (intersect != null) + collisionResponse.setValue(currentResponse.add(intersect)); + }); }); + + Vec3d entityMotion = entity.getMotion(); + Vec3d totalResponse = collisionResponse.getValue(); + + if (totalResponse == Vec3d.ZERO) + continue; + + totalResponse = VecHelper.rotate(totalResponse, conRotX, Axis.X); + totalResponse = VecHelper.rotate(totalResponse, conRotY, Axis.Y); + totalResponse = VecHelper.rotate(totalResponse, conRotZ, Axis.Z); + + double motionX = entityMotion.getX(); + double motionY = entityMotion.getY(); + double motionZ = entityMotion.getZ(); + double intersectX = totalResponse.getX(); + double intersectY = totalResponse.getY(); + double intersectZ = totalResponse.getZ(); + + double horizonalEpsilon = 1 / 128f; + + if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0) + entityMotion = entityMotion.mul(0, 1, 1); + if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0) + entityMotion = entityMotion.mul(1, 0, 1); + if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0) + entityMotion = entityMotion.mul(1, 1, 0); + + entityMotion = entityMotion.add(totalResponse.mul(1, 0, 1)); + contraptionEntity.collidingEntities.add(entity); + entity.velocityChanged = true; + + if (totalResponse.y > 0) { + entity.handleFallDamage(entity.fallDistance, 1); + entity.fallDistance = 0; + entity.onGround = true; + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); + } + + if (entity instanceof ServerPlayerEntity) + ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; + + entity.setMotion(entityMotion); + Vec3d epos = entityPosition; + entity.setPosition(epos.x, epos.y + totalResponse.y, epos.z); + entityData.put(nbtMotionKey, VecHelper.writeNBT(totalResponse)); } } @@ -266,7 +305,14 @@ public class ContraptionCollider { public static ReuseableStream getPotentiallyCollidedShapes(World world, Contraption contraption, AxisAlignedBB localBB) { + + double height = localBB.getYSize(); + double width = localBB.getXSize(); + double horizontalFactor = (height > width && width != 0) ? height / width : 1; + double verticalFactor = (width > height && height != 0) ? width / height : 1; AxisAlignedBB blockScanBB = localBB.grow(.5f); + blockScanBB = blockScanBB.grow(horizontalFactor, verticalFactor, horizontalFactor); + BlockPos min = new BlockPos(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ); BlockPos max = new BlockPos(blockScanBB.maxX, blockScanBB.maxY, blockScanBB.maxZ); diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java index 9901e28f4..32270f0f1 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java +++ b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java @@ -4,34 +4,31 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.outliner.AABBOutline; -import net.minecraft.client.Minecraft; import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.RayTraceResult.Type; import net.minecraft.util.math.Vec3d; public class CollisionDebugger { - static AxisAlignedBB staticBB = new AxisAlignedBB(BlockPos.ZERO.up(10)); - static OrientedBB movingBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO)); + public static AxisAlignedBB AABB = null; + public static OrientedBB OBB = null; static Vec3d seperation; static double angle = 0; static AABBOutline outline; public static void onScroll(double delta) { - angle += delta; - movingBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); +// angle += delta; +// movingBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO).expand(0, 1, 0)); +// movingBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); } public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { + if (OBB == null) + return; ms.push(); - outline = new AABBOutline(movingBB.getAsAxisAlignedBB()); + outline = new AABBOutline(OBB.getAsAxisAlignedBB()); outline.getParams() .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null) .colored(0xffffff); @@ -40,12 +37,12 @@ public class CollisionDebugger { .lineWidth(1 / 64f) .colored(0xff6544); MatrixStacker.of(ms) - .translate(movingBB.center); + .translate(OBB.center); ms.peek() .getModel() - .multiply(movingBB.rotation.getAsMatrix4f()); + .multiply(OBB.rotation.getAsMatrix4f()); MatrixStacker.of(ms) - .translateBack(movingBB.center); + .translateBack(OBB.center); outline.render(ms, buffer); ms.pop(); @@ -56,26 +53,24 @@ public class CollisionDebugger { .lineWidth(1 / 32f); MatrixStacker.of(ms) .translate(seperation) - .translate(movingBB.center); + .translate(OBB.center); ms.peek() .getModel() - .multiply(movingBB.rotation.getAsMatrix4f()); + .multiply(OBB.rotation.getAsMatrix4f()); MatrixStacker.of(ms) - .translateBack(movingBB.center); + .translateBack(OBB.center); outline.render(ms, buffer); } ms.pop(); } public static void tick() { - staticBB = new AxisAlignedBB(BlockPos.ZERO.up(60)); - RayTraceResult mouse = Minecraft.getInstance().objectMouseOver; - if (mouse != null && mouse.getType() == Type.BLOCK) { - BlockRayTraceResult hit = (BlockRayTraceResult) mouse; - movingBB.setCenter(hit.getHitVec()); - seperation = movingBB.intersect(staticBB); - } - CreateClient.outliner.showAABB(staticBB, staticBB) + if (OBB == null) + return; + if (AABB == null) + return; + seperation = OBB.intersect(AABB); + CreateClient.outliner.showAABB(AABB, AABB) .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null); } diff --git a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java index 1fa62944d..0c7a2e770 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java +++ b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java @@ -29,6 +29,10 @@ public class OrientedBB { this.extents = extents; this.setRotation(rotation); } + + public OrientedBB copy() { + return new OrientedBB(center, extents, rotation); + } public Vec3d intersect(AxisAlignedBB bb) { Vec3d extentsA = extentsFromBB(bb); @@ -152,7 +156,7 @@ public class OrientedBB { } static void showDebugLine(Vec3d relativeStart, Vec3d relativeEnd, int color, String id, int offset) { - Vec3d center = CollisionDebugger.staticBB.getCenter() + Vec3d center = CollisionDebugger.AABB.getCenter() .add(0, 1 + offset / 16f, 0); CreateClient.outliner.showLine(id + checkCount, center.add(relativeStart), center.add(relativeEnd)) .colored(color) @@ -174,6 +178,10 @@ public class OrientedBB { public void setCenter(Vec3d center) { this.center = center; } + + public void move(Vec3d offset) { + setCenter(getCenter().add(offset)); + } public AxisAlignedBB getAsAxisAlignedBB() { return new AxisAlignedBB(0, 0, 0, 0, 0, 0).offset(center) diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 1ad8edf3e..3852632ff 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -26,6 +26,8 @@ public class VecHelper { public static Vec3d rotate(Vec3d vec, double deg, Axis axis) { if (deg == 0) return vec; + if (vec == Vec3d.ZERO) + return vec; float angle = (float) (deg / 180f * Math.PI); double sin = MathHelper.sin(angle); From 85d10a7ce5240b47f639ad1d4044232bcf15b7cb Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 12 Jul 2020 23:57:42 +0200 Subject: [PATCH 06/17] Seat lang merge --- .../assets/create/lang/unfinished/de_de.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/fr_fr.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/it_it.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/ja_jp.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/ko_kr.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/nl_nl.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/pt_br.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/ru_ru.json | 18 +++++++++++++++++- .../assets/create/lang/unfinished/zh_cn.json | 18 +++++++++++++++++- 9 files changed, 153 insertions(+), 9 deletions(-) diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index 9a8c82e36..3a6611510 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 781", + "_": "Missing Localizations: 797", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Fließband-Beobachter", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", "block.create.brass_casing": "UNLOCALIZED: Brass Casing", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "UNLOCALIZED: Cart Assembler", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Mahlwerkrad", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "UNLOCALIZED: Cuckoo Clock", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "UNLOCALIZED: Dark Scoria", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "UNLOCALIZED: Hand Crank", "block.create.horizontal_framed_glass": "UNLOCALIZED: Horizontal Framed Glass", "block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Kalksand", "block.create.limestone": "Kalkstein", "block.create.limestone_bricks": "Kalksteinziegel", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Schubgerüst", "block.create.linked_extractor": "Verknüpfter Auswerfer", "block.create.linked_transposer": "UNLOCALIZED: Linked Transposer", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Mechanisches Lager", "block.create.mechanical_crafter": "UNLOCALIZED: Mechanical Crafter", @@ -213,6 +223,7 @@ "block.create.nozzle": "UNLOCALIZED: Nozzle", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Kolben-Pleuelverlängerung", "block.create.polished_dark_scoria": "UNLOCALIZED: Polished Dark Scoria", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "UNLOCALIZED: Pulley Magnet", "block.create.pulse_repeater": "Pulsierender Verstärker", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Drehgerüst", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "Redstone-Kontakt", "block.create.redstone_link": "Redstone-Verbindung", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Verwitterte Kalksteinsäule", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "UNLOCALIZED: Zinc Block", "block.create.zinc_ore": "UNLOCALIZED: Zinc Ore", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 4f2fc8b3d..326d3a3fc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 384", + "_": "Missing Localizations: 400", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Observateur d'entité", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", "block.create.brass_casing": "Boîtier en laiton", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "Assembleur de wagon", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Roue de concassage", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "Horloge à coucou", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "Scorie sombre", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "Manivelle", "block.create.horizontal_framed_glass": "Fenêtre en verre horizontale", "block.create.horizontal_framed_glass_pane": "Vitre encadrée horizontale", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Chaux", "block.create.limestone": "Calcaire", "block.create.limestone_bricks": "Briques de calcaire", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Châssis linéaire", "block.create.linked_extractor": "Extracteur lié", "block.create.linked_transposer": "Transposeur lié", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Roulement mécanique", "block.create.mechanical_crafter": "Établi mécanique", @@ -213,6 +223,7 @@ "block.create.nozzle": "Buse", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Pôle d'extension de piston", "block.create.polished_dark_scoria": "Scorie sombre polie", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "Verrou alimenté à bascule", "block.create.pulley_magnet": "Aimant de poulie", "block.create.pulse_repeater": "Répéteur d'impulsions", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Châssis radial", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "redstone_contact Redstone", "block.create.redstone_link": "Liaison Redstone", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Pillier de calcaire patinées", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "UNLOCALIZED: Zinc Block", "block.create.zinc_ore": "Minerai de zinc", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index b91adee26..764a30eba 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 368", + "_": "Missing Localizations: 384", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Osservatore a Cinghia", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "Blocco di Ottone", "block.create.brass_casing": "Involucro di Ottone", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "Assemblatore Carrello da Miniera", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Ruota di Frantumazione", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "Orologio a Cucù", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "Scoria Scura", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "Manovella", "block.create.horizontal_framed_glass": "Finestra Orizzontale Vetro", "block.create.horizontal_framed_glass_pane": "Pannello di Finestra Orizzontale Vetro", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Silico Calcare", "block.create.limestone": "Calcare", "block.create.limestone_bricks": "Mattoni di Calcare", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Telaio Lineare", "block.create.linked_extractor": "Estrattore Connesso", "block.create.linked_transposer": "Traspositore Connesso", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Supporto Meccanico", "block.create.mechanical_crafter": "Costruttore Meccanico", @@ -213,6 +223,7 @@ "block.create.nozzle": "Ugello", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Palo Pistome", "block.create.polished_dark_scoria": "Scoria Scura Levigata", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "Leva Alimentata Alterata", "block.create.pulley_magnet": "Magnete della Puleggia", "block.create.pulse_repeater": "Ripetitore di Impulsi", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Telaio Radiale", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "Contatto Redstone", "block.create.redstone_link": "Collegamento Redstone", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Pilastro di Calcare Consumato", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "Blocco di Zinco", "block.create.zinc_ore": "Zinco Grezzo", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 16000f239..0ffc1ade3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 363", + "_": "Missing Localizations: 379", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "ベルトオブザーバー", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "真鍮ブロック", "block.create.brass_casing": "真鍮ケーシング", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "カートアセンブラ", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "破砕ホイール", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "鳩時計", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "ダークスコリア", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "ハンドクランク", "block.create.horizontal_framed_glass": "横型ガラス窓", "block.create.horizontal_framed_glass_pane": "横型ガラス窓板", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "石灰砕砂", "block.create.limestone": "石灰岩", "block.create.limestone_bricks": "石灰岩レンガ", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "リニアシャーシ", "block.create.linked_extractor": "リンクされたエクストラクター", "block.create.linked_transposer": "リンクされたトランスポーザー", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "メカニカルベアリング", "block.create.mechanical_crafter": "メカニカルクラフター", @@ -213,6 +223,7 @@ "block.create.nozzle": "ノズル", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "ピストン延長ポール", "block.create.polished_dark_scoria": "磨かれたダークスコリア", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "パワードトグルラッチ", "block.create.pulley_magnet": "プーリーマグネット", "block.create.pulse_repeater": "パルスリピーター", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "ラジアルシャーシ", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "レッドストーンコンタクト", "block.create.redstone_link": "レッドストーンリンク", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "風化した石灰岩の柱", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "亜鉛ブロック", "block.create.zinc_ore": "亜鉛鉱石", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index ac39c9e93..b72075f93 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 368", + "_": "Missing Localizations: 384", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "벨트 감지기", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "황동 블럭", "block.create.brass_casing": "황동 케이스", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "카트 조립기", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "분쇄 휠", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "뻐꾸기 시계", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "짙은 스코리아", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "핸드 크랭크", "block.create.horizontal_framed_glass": "수평 유리", "block.create.horizontal_framed_glass_pane": "수평 유리판", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "석회모래", "block.create.limestone": "석회암", "block.create.limestone_bricks": "석회암 벽돌", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "직선 섀시", "block.create.linked_extractor": "무선 추출기", "block.create.linked_transposer": "무선 트랜스포저", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "베어링", "block.create.mechanical_crafter": "기계식 조합기", @@ -213,6 +223,7 @@ "block.create.nozzle": "노즐", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "피스톤 연장 축", "block.create.polished_dark_scoria": "윤나는 짙은 스코리아", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "레드스톤 토글 걸쇠", "block.create.pulley_magnet": "도르래 자석", "block.create.pulse_repeater": "펄스 리피터", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "원형 섀시", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "동형 감지기", "block.create.redstone_link": "레드스톤 링크", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "풍화된 석회암 기둥", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "아연 블럭", "block.create.zinc_ore": "아연 광석", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 6bbaa48c1..390a2082e 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 718", + "_": "Missing Localizations: 734", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Transportband Observeerder", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", "block.create.brass_casing": "UNLOCALIZED: Brass Casing", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "Kar Assembler", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Verpulveraar", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "UNLOCALIZED: Cuckoo Clock", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "UNLOCALIZED: Dark Scoria", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "UNLOCALIZED: Hand Crank", "block.create.horizontal_framed_glass": "UNLOCALIZED: Horizontal Framed Glass", "block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Kalkzand", "block.create.limestone": "Kalksteen", "block.create.limestone_bricks": "Kalksteenstenen", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Lineaar Frame", "block.create.linked_extractor": "Gelinkte Extractor", "block.create.linked_transposer": "UNLOCALIZED: Linked Transposer", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Mechanische Lager", "block.create.mechanical_crafter": "Mechanische Werkbank", @@ -213,6 +223,7 @@ "block.create.nozzle": "UNLOCALIZED: Nozzle", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Zuiger Verlengpaal", "block.create.polished_dark_scoria": "UNLOCALIZED: Polished Dark Scoria", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "UNLOCALIZED: Pulley Magnet", "block.create.pulse_repeater": "Pulse Versterker", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Rotation Frame", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "Redstone redstone_contact", "block.create.redstone_link": "Redstone Brug", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Verweerde Kalksteen Pilaar", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "UNLOCALIZED: Zinc Block", "block.create.zinc_ore": "UNLOCALIZED: Zinc Ore", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index d49c96b2a..5fcaac6ce 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 788", + "_": "Missing Localizations: 804", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Observador de Esteira", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", "block.create.brass_casing": "UNLOCALIZED: Brass Casing", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "UNLOCALIZED: Cart Assembler", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Roda de Moer", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "UNLOCALIZED: Cuckoo Clock", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "UNLOCALIZED: Dark Scoria", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "UNLOCALIZED: Hand Crank", "block.create.horizontal_framed_glass": "UNLOCALIZED: Horizontal Framed Glass", "block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Areia Calcária", "block.create.limestone": "Calcário", "block.create.limestone_bricks": "Tijolos de Calcário", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Chassis de Translado", "block.create.linked_extractor": "Extrator Conectado", "block.create.linked_transposer": "UNLOCALIZED: Linked Transposer", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Rolamento Mecânico", "block.create.mechanical_crafter": "UNLOCALIZED: Mechanical Crafter", @@ -213,6 +223,7 @@ "block.create.nozzle": "UNLOCALIZED: Nozzle", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Vara de Extensão do Pistão", "block.create.polished_dark_scoria": "UNLOCALIZED: Polished Dark Scoria", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "UNLOCALIZED: Pulley Magnet", "block.create.pulse_repeater": "Repetidor de Pulso", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Chassis de Rotação", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "Contato de Redstone", "block.create.redstone_link": "Conexão de Redstone", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Pilar de Calcário Resistido", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "UNLOCALIZED: Zinc Block", "block.create.zinc_ore": "UNLOCALIZED: Zinc Ore", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index cf9239c4f..51f4156fd 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 782", + "_": "Missing Localizations: 798", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "Ленточный сканер", "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", "block.create.brass_casing": "UNLOCALIZED: Brass Casing", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "UNLOCALIZED: Cart Assembler", "block.create.chiseled_dark_scoria": "UNLOCALIZED: Chiseled Dark Scoria", "block.create.chiseled_dolomite": "UNLOCALIZED: Chiseled Dolomite", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "Дробильное колесо", "block.create.crushing_wheel_controller": "UNLOCALIZED: Crushing Wheel Controller", "block.create.cuckoo_clock": "UNLOCALIZED: Cuckoo Clock", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "UNLOCALIZED: Dark Oak Window", "block.create.dark_oak_window_pane": "UNLOCALIZED: Dark Oak Window Pane", "block.create.dark_scoria": "UNLOCALIZED: Dark Scoria", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "UNLOCALIZED: Granite Cobblestone Stairs", "block.create.granite_cobblestone_wall": "UNLOCALIZED: Granite Cobblestone Wall", "block.create.granite_pillar": "UNLOCALIZED: Granite Pillar", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "UNLOCALIZED: Hand Crank", "block.create.horizontal_framed_glass": "UNLOCALIZED: Horizontal Framed Glass", "block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "UNLOCALIZED: Layered Limestone", "block.create.layered_scoria": "UNLOCALIZED: Layered Scoria", "block.create.layered_weathered_limestone": "UNLOCALIZED: Layered Weathered Limestone", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "Известь", "block.create.limestone": "Известняк", "block.create.limestone_bricks": "Известковые кирпичи", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "Поступательная рама", "block.create.linked_extractor": "Сигнальный экстрактор", "block.create.linked_transposer": "UNLOCALIZED: Linked Transposer", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "Механический подшипник", "block.create.mechanical_crafter": "UNLOCALIZED: Mechanical Crafter", @@ -213,6 +223,7 @@ "block.create.nozzle": "UNLOCALIZED: Nozzle", "block.create.oak_window": "UNLOCALIZED: Oak Window", "block.create.oak_window_pane": "UNLOCALIZED: Oak Window Pane", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "UNLOCALIZED: Ornate Iron Window", "block.create.ornate_iron_window_pane": "UNLOCALIZED: Ornate Iron Window Pane", "block.create.overgrown_andesite": "UNLOCALIZED: Overgrown Andesite", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "UNLOCALIZED: Paved Weathered Limestone Slab", "block.create.paved_weathered_limestone_stairs": "UNLOCALIZED: Paved Weathered Limestone Stairs", "block.create.paved_weathered_limestone_wall": "UNLOCALIZED: Paved Weathered Limestone Wall", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "Удлинитель поршня", "block.create.polished_dark_scoria": "UNLOCALIZED: Polished Dark Scoria", "block.create.polished_dark_scoria_slab": "UNLOCALIZED: Polished Dark Scoria Slab", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "UNLOCALIZED: Pulley Magnet", "block.create.pulse_repeater": "Повторитель импульса", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "Поворотная рама", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "Контактное соединение", "block.create.redstone_link": "Сигнальное соединение", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "UNLOCALIZED: Weathered Limestone Cobblestone Stairs", "block.create.weathered_limestone_cobblestone_wall": "UNLOCALIZED: Weathered Limestone Cobblestone Wall", "block.create.weathered_limestone_pillar": "Колонна из обветренного известняка", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "UNLOCALIZED: Zinc Block", "block.create.zinc_ore": "UNLOCALIZED: Zinc Ore", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index b691687f8..980ed4113 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 44", + "_": "Missing Localizations: 60", "_": "->------------------------] Game Elements [------------------------<-", @@ -29,12 +29,15 @@ "block.create.belt_observer": "传送带侦测器", "block.create.birch_window": "白桦窗户", "block.create.birch_window_pane": "白桦窗户板", + "block.create.black_seat": "UNLOCALIZED: Black Seat", + "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "黄铜块", "block.create.brass_casing": "黄铜机壳", "block.create.brass_chute_funnel": "UNLOCALIZED: Brass Chute Funnel", "block.create.brass_funnel": "UNLOCALIZED: Brass Funnel", "block.create.brass_tunnel": "UNLOCALIZED: Brass Tunnel", + "block.create.brown_seat": "UNLOCALIZED: Brown Seat", "block.create.cart_assembler": "矿车装配站", "block.create.chiseled_dark_scoria": "錾制深色熔渣", "block.create.chiseled_dolomite": "錾制白云岩", @@ -55,6 +58,7 @@ "block.create.crushing_wheel": "粉碎轮", "block.create.crushing_wheel_controller": "粉碎轮控制器", "block.create.cuckoo_clock": "布谷鸟闹钟", + "block.create.cyan_seat": "UNLOCALIZED: Cyan Seat", "block.create.dark_oak_window": "深色橡木窗户", "block.create.dark_oak_window_pane": "深色橡木窗户板", "block.create.dark_scoria": "深色熔渣", @@ -155,6 +159,8 @@ "block.create.granite_cobblestone_stairs": "花岗岩圆石楼梯", "block.create.granite_cobblestone_wall": "花岗岩圆石墙", "block.create.granite_pillar": "竖纹花岗岩", + "block.create.gray_seat": "UNLOCALIZED: Gray Seat", + "block.create.green_seat": "UNLOCALIZED: Green Seat", "block.create.hand_crank": "手摇曲柄", "block.create.horizontal_framed_glass": "竖直边框玻璃", "block.create.horizontal_framed_glass_pane": "竖直边框玻璃板", @@ -170,6 +176,9 @@ "block.create.layered_limestone": "层叠石灰岩", "block.create.layered_scoria": "层叠熔渣", "block.create.layered_weathered_limestone": "层叠风化石灰岩", + "block.create.light_blue_seat": "UNLOCALIZED: Light Blue Seat", + "block.create.light_gray_seat": "UNLOCALIZED: Light Gray Seat", + "block.create.lime_seat": "UNLOCALIZED: Lime Seat", "block.create.limesand": "石灰沙", "block.create.limestone": "石灰岩", "block.create.limestone_bricks": "石灰岩砖", @@ -184,6 +193,7 @@ "block.create.linear_chassis": "机壳底盘", "block.create.linked_extractor": "无线提取器", "block.create.linked_transposer": "无线传输器", + "block.create.magenta_seat": "UNLOCALIZED: Magenta Seat", "block.create.mechanical_arm": "UNLOCALIZED: Mechanical Arm", "block.create.mechanical_bearing": "动力轴承", "block.create.mechanical_crafter": "动力制造器", @@ -213,6 +223,7 @@ "block.create.nozzle": "分散网", "block.create.oak_window": "橡木窗户", "block.create.oak_window_pane": "橡木窗户板", + "block.create.orange_seat": "UNLOCALIZED: Orange Seat", "block.create.ornate_iron_window": "华丽铁窗户", "block.create.ornate_iron_window_pane": "华丽铁窗户板", "block.create.overgrown_andesite": "生草安山岩", @@ -261,6 +272,7 @@ "block.create.paved_weathered_limestone_slab": "风化石灰岩铺路石台阶", "block.create.paved_weathered_limestone_stairs": "风化石灰岩铺路石楼梯", "block.create.paved_weathered_limestone_wall": "风化石灰岩铺路石墙", + "block.create.pink_seat": "UNLOCALIZED: Pink Seat", "block.create.piston_extension_pole": "活塞杆", "block.create.polished_dark_scoria": "磨制深色熔渣", "block.create.polished_dark_scoria_slab": "磨制深色熔渣台阶", @@ -291,7 +303,9 @@ "block.create.powered_toggle_latch": "T触发器", "block.create.pulley_magnet": "传送带磁铁", "block.create.pulse_repeater": "脉冲中继器", + "block.create.purple_seat": "UNLOCALIZED: Purple Seat", "block.create.radial_chassis": "旋转底盘", + "block.create.red_seat": "UNLOCALIZED: Red Seat", "block.create.redstone_contact": "信号检测器", "block.create.redstone_link": "无限红石信号终端", "block.create.reinforced_rail": "UNLOCALIZED: Reinforced Rail", @@ -340,6 +354,8 @@ "block.create.weathered_limestone_cobblestone_stairs": "风化石灰岩圆石楼梯", "block.create.weathered_limestone_cobblestone_wall": "风化石灰岩圆石墙", "block.create.weathered_limestone_pillar": "竖纹风化石灰岩", + "block.create.white_seat": "UNLOCALIZED: White Seat", + "block.create.yellow_seat": "UNLOCALIZED: Yellow Seat", "block.create.zinc_block": "锌块", "block.create.zinc_ore": "锌矿石", From ebc29447888ae96c01bd4ff7999942f2d06f929b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 14 Jul 2020 16:58:10 +0200 Subject: [PATCH 07/17] Robust entry collisions - Collision separation now supports motion sweeping in order to avoid tunnelling when entities drop onto contraptions from a greater height - Further improved the collision response - Entities can no longer be clipped into solid walls by the collision response --- .../ContraptionCollider.java | 211 +++++++++++++----- .../collision/CollisionDebugger.java | 68 ++++-- .../collision/ContinuousOBBCollider.java | 146 ++++++++++++ .../create/foundation/collision/Matrix3d.java | 18 +- .../foundation/collision/OBBCollider.java | 103 +++++++++ .../foundation/collision/OrientedBB.java | 166 ++++---------- .../foundation/utility/AngleHelper.java | 4 + 7 files changed, 508 insertions(+), 208 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java create mode 100644 src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index e91c2221d..fb1f6cac2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -1,20 +1,26 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import static java.util.concurrent.TimeUnit.SECONDS; +import static net.minecraft.entity.Entity.collideBoundingBoxHeuristically; +import static net.minecraft.entity.Entity.horizontalMag; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.stream.Stream; +import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableObject; import com.google.common.base.Predicates; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour; +import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.OrientedBB; import com.simibubi.create.foundation.utility.AngleHelper; @@ -29,7 +35,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.MoverType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; @@ -37,12 +43,14 @@ import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.IBooleanFunction; +import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.WorldTickEvent; @@ -54,9 +62,11 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber public class ContraptionCollider { + public static DamageSource damageSourceContraptionSuffocate = + new DamageSource("create.contraption_suffocate").setDamageBypassesArmor(); public static boolean wasClientPlayerGrounded; public static Cache>> activeContraptions = CacheBuilder.newBuilder() - .expireAfterAccess(20, SECONDS) + .expireAfterAccess(40, SECONDS) .build(); @SubscribeEvent @@ -86,7 +96,7 @@ public class ContraptionCollider { @SubscribeEvent public static void entityCollisionHappensPreWorldTick(WorldTickEvent event) { - if (event.phase == Phase.START) + if (event.phase == Phase.END) return; World world = event.world; runCollisions(world); @@ -124,15 +134,17 @@ public class ContraptionCollider { double conRotY = contraptionRotation.y; double conRotZ = contraptionRotation.x; - for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2), - contraptionEntity::canCollideWith)) { - if (entity instanceof PlayerEntity && !world.isRemote) - return; + for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2) + .expand(0, 32, 0), contraptionEntity::canCollideWith)) { + boolean serverPlayer = entity instanceof PlayerEntity && !world.isRemote; + // Transform entity position and motion to local space Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO); Vec3d entityPosition = entity.getPositionVec(); - Vec3d centerY = new Vec3d(0, entity.getBoundingBox() - .getYSize() / 2, 0); + AxisAlignedBB entityBounds = entity.getBoundingBox(); + Vec3d centerY = new Vec3d(0, entityBounds.getYSize() / 2, 0); + Vec3d motion = entity.getMotion(); + boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); Vec3d position = entityPosition.subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0)) @@ -143,27 +155,22 @@ public class ContraptionCollider { position = position.add(centerOfBlock) .subtract(centerY) .subtract(entityPosition); - AxisAlignedBB localBB = entity.getBoundingBox() - .offset(position) + + // Find all potential block shapes to collide with + AxisAlignedBB localBB = entityBounds.offset(position) .grow(1.0E-7D); - - String nbtMotionKey = "ContraptionCollisionFeedback"; - CompoundNBT entityData = entity.getPersistentData(); - Vec3d previousIntersection = Vec3d.ZERO; - if (entityData.contains(nbtMotionKey)) { - previousIntersection = VecHelper.readNBT(entityData.getList(nbtMotionKey, NBT.TAG_DOUBLE)); - entity.setMotion(entity.getMotion() - .subtract(previousIntersection.mul(1, 0, 1))); - entityData.remove(nbtMotionKey); - } - - ReuseableStream potentialHits = getPotentiallyCollidedShapes(world, contraption, localBB); + ReuseableStream potentialHits = + getPotentiallyCollidedShapes(world, contraption, localBB.expand(motion)); if (potentialHits.createStream() .count() == 0) continue; + if (!axisAlignedCollision) + motion = VecHelper.rotate(motion, -conRotX, -conRotY, -conRotZ); + + // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); - if (!contraptionRotation.equals(Vec3d.ZERO)) { + if (!axisAlignedCollision) { Matrix3d rotation = new Matrix3d().asIdentity(); rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(-conRotX))); rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(conRotY))); @@ -171,32 +178,87 @@ public class ContraptionCollider { obb.setRotation(rotation); } +// Vec3d visualizerOrigin = new Vec3d(10, 64, 0); +// CollisionDebugger.OBB = obb.copy(); +// CollisionDebugger.OBB.move(visualizerOrigin); + MutableObject collisionResponse = new MutableObject<>(Vec3d.ZERO); + MutableObject allowedMotion = new MutableObject<>(motion); + MutableBoolean futureCollision = new MutableBoolean(false); + MutableBoolean surfaceCollision = new MutableBoolean(false); Vec3d obbCenter = obb.getCenter(); + // Apply separation maths + List bbs = new ArrayList<>(); potentialHits.createStream() - .forEach(shape -> { - Vec3d currentResponse = collisionResponse.getValue(); - shape.toBoundingBoxList() - .parallelStream() - .forEach(bb -> { - obb.setCenter(obbCenter.add(currentResponse)); - Vec3d intersect = obb.intersect(bb); - if (intersect != null) - collisionResponse.setValue(currentResponse.add(intersect)); - }); - }); + .forEach(shape -> shape.toBoundingBoxList() + .forEach(bbs::add)); + for (AxisAlignedBB bb : bbs) { + Vec3d currentResponse = collisionResponse.getValue(); + obb.setCenter(obbCenter.add(currentResponse)); + ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue()); +// OutlineParams params = CreateClient.outliner.showAABB(bb, bb.offset(visualizerOrigin)) +// .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED); +// params.colored(0xffffff); + + if (intersect == null) + continue; + if (surfaceCollision.isFalse()) + surfaceCollision.setValue(intersect.isSurfaceCollision()); + + double timeOfImpact = intersect.getTimeOfImpact(); + if (timeOfImpact > 0 && timeOfImpact < 1) { + futureCollision.setTrue(); +// Vec3d prev = allowedMotion.getValue(); + allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue())); +// Debug.debugChat("Allowed Motion FROM " + prev.toString()); +// Debug.debugChat("Allowed Motion TO " + allowedMotion.getValue() +// .toString()); +// params.colored(0x4499ff); + continue; + } + Vec3d separation = intersect.asSeparationVec(); + if (separation != null && !separation.equals(Vec3d.ZERO)) { + collisionResponse.setValue(currentResponse.add(separation)); +// Debug.debugChat("Collision " + currentResponse.add(separation) +// .toString()); +// params.colored(0xff9944); + } + } + +// Debug.debugChat("----"); + + // Resolve collision Vec3d entityMotion = entity.getMotion(); Vec3d totalResponse = collisionResponse.getValue(); + Vec3d motionResponse = allowedMotion.getValue(); - if (totalResponse == Vec3d.ZERO) + if (futureCollision.isTrue() && !serverPlayer) { + if (!axisAlignedCollision) + motionResponse = VecHelper.rotate(motionResponse, conRotX, conRotY, conRotZ); + if (motionResponse.y != entityMotion.y) { + entity.setMotion(entityMotion.mul(1, 0, 1) + .add(0, motionResponse.y, 0)); + entityMotion = entity.getMotion(); + } + } + + if (!axisAlignedCollision) + totalResponse = VecHelper.rotate(totalResponse, conRotX, conRotY, conRotZ); + + if (surfaceCollision.isTrue()) { +// entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue + entity.fallDistance = 0; + entity.onGround = true; + if (!serverPlayer) { + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); + } + } + + if (totalResponse.equals(Vec3d.ZERO)) continue; - totalResponse = VecHelper.rotate(totalResponse, conRotX, Axis.X); - totalResponse = VecHelper.rotate(totalResponse, conRotY, Axis.Y); - totalResponse = VecHelper.rotate(totalResponse, conRotZ, Axis.Z); - double motionX = entityMotion.getX(); double motionY = entityMotion.getY(); double motionZ = entityMotion.getZ(); @@ -205,7 +267,6 @@ public class ContraptionCollider { double intersectZ = totalResponse.getZ(); double horizonalEpsilon = 1 / 128f; - if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0) entityMotion = entityMotion.mul(0, 1, 1); if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0) @@ -213,28 +274,62 @@ public class ContraptionCollider { if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0) entityMotion = entityMotion.mul(1, 1, 0); - entityMotion = entityMotion.add(totalResponse.mul(1, 0, 1)); - contraptionEntity.collidingEntities.add(entity); - entity.velocityChanged = true; - - if (totalResponse.y > 0) { - entity.handleFallDamage(entity.fallDistance, 1); - entity.fallDistance = 0; - entity.onGround = true; - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); - } - if (entity instanceof ServerPlayerEntity) ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; - entity.setMotion(entityMotion); - Vec3d epos = entityPosition; - entity.setPosition(epos.x, epos.y + totalResponse.y, epos.z); - entityData.put(nbtMotionKey, VecHelper.writeNBT(totalResponse)); + if (!serverPlayer) { + Vec3d allowedMovement = getAllowedMovement(totalResponse, entity); + contraptionEntity.collidingEntities.add(entity); + entity.velocityChanged = true; + entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, + entityPosition.z + allowedMovement.z); + entity.setMotion(entityMotion); + } } } + /** From Entity#getAllowedMovement **/ + static Vec3d getAllowedMovement(Vec3d movement, Entity e) { + AxisAlignedBB bb = e.getBoundingBox(); + ISelectionContext ctx = ISelectionContext.forEntity(e); + World world = e.world; + VoxelShape voxelshape = world.getWorldBorder() + .getShape(); + Stream stream = + VoxelShapes.compare(voxelshape, VoxelShapes.create(bb.shrink(1.0E-7D)), IBooleanFunction.AND) + ? Stream.empty() + : Stream.of(voxelshape); + Stream stream1 = world.getEmptyCollisionShapes(e, bb.expand(movement), ImmutableSet.of()); + ReuseableStream reuseablestream = new ReuseableStream<>(Stream.concat(stream1, stream)); + Vec3d vec3d = movement.lengthSquared() == 0.0D ? movement + : collideBoundingBoxHeuristically(e, movement, bb, world, ctx, reuseablestream); + boolean flag = movement.x != vec3d.x; + boolean flag1 = movement.y != vec3d.y; + boolean flag2 = movement.z != vec3d.z; + boolean flag3 = e.onGround || flag1 && movement.y < 0.0D; + if (e.stepHeight > 0.0F && flag3 && (flag || flag2)) { + Vec3d vec3d1 = collideBoundingBoxHeuristically(e, new Vec3d(movement.x, (double) e.stepHeight, movement.z), + bb, world, ctx, reuseablestream); + Vec3d vec3d2 = collideBoundingBoxHeuristically(e, new Vec3d(0.0D, (double) e.stepHeight, 0.0D), + bb.expand(movement.x, 0.0D, movement.z), world, ctx, reuseablestream); + if (vec3d2.y < (double) e.stepHeight) { + Vec3d vec3d3 = collideBoundingBoxHeuristically(e, new Vec3d(movement.x, 0.0D, movement.z), + bb.offset(vec3d2), world, ctx, reuseablestream).add(vec3d2); + if (horizontalMag(vec3d3) > horizontalMag(vec3d1)) { + vec3d1 = vec3d3; + } + } + + if (horizontalMag(vec3d1) > horizontalMag(vec3d)) { + return vec3d1.add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + movement.y, 0.0D), + bb.offset(vec3d1), world, ctx, reuseablestream)); + } + } + + return vec3d; + } + @OnlyIn(Dist.CLIENT) private static void checkForClientPlayerCollision(Entity entity) { if (entity != Minecraft.getInstance().player) @@ -310,7 +405,7 @@ public class ContraptionCollider { double width = localBB.getXSize(); double horizontalFactor = (height > width && width != 0) ? height / width : 1; double verticalFactor = (width > height && height != 0) ? width / height : 1; - AxisAlignedBB blockScanBB = localBB.grow(.5f); + AxisAlignedBB blockScanBB = localBB.grow(0.5f); blockScanBB = blockScanBB.grow(horizontalFactor, verticalFactor, horizontalFactor); BlockPos min = new BlockPos(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ); diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java index 32270f0f1..b8c3ec26c 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java +++ b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java @@ -3,30 +3,35 @@ package com.simibubi.create.foundation.collision; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.outliner.AABBOutline; +import net.minecraft.client.Minecraft; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.RayTraceResult.Type; import net.minecraft.util.math.Vec3d; public class CollisionDebugger { - public static AxisAlignedBB AABB = null; - public static OrientedBB OBB = null; - static Vec3d seperation; + public static AxisAlignedBB AABB = new AxisAlignedBB(BlockPos.ZERO.up(10)); + public static OrientedBB OBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO)); + public static Vec3d motion = Vec3d.ZERO; + static ContinuousSeparationManifold seperation; static double angle = 0; static AABBOutline outline; public static void onScroll(double delta) { -// angle += delta; -// movingBB = new OrientedBB(new AxisAlignedBB(BlockPos.ZERO).expand(0, 1, 0)); -// movingBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); + angle += delta; + OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); } public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { - if (OBB == null) - return; ms.push(); outline = new AABBOutline(OBB.getAsAxisAlignedBB()); outline.getParams() @@ -47,12 +52,12 @@ public class CollisionDebugger { ms.pop(); ms.push(); - if (seperation != null) { + if (motion.length() != 0 && (seperation == null || seperation.getTimeOfImpact() != 1)) { outline.getParams() - .colored(0x65ff44) + .colored(0x6544ff) .lineWidth(1 / 32f); MatrixStacker.of(ms) - .translate(seperation) + .translate(seperation != null ? seperation.getAllowedMotion(motion) : motion) .translate(OBB.center); ms.peek() .getModel() @@ -62,16 +67,47 @@ public class CollisionDebugger { outline.render(ms, buffer); } ms.pop(); + + ms.push(); + if (seperation != null) { + Vec3d asSeparationVec = seperation.asSeparationVec(); + if (asSeparationVec != null) { + outline.getParams() + .colored(0x65ff44) + .lineWidth(1 / 32f); + MatrixStacker.of(ms) + .translate(asSeparationVec) + .translate(OBB.center); + ms.peek() + .getModel() + .multiply(OBB.rotation.getAsMatrix4f()); + MatrixStacker.of(ms) + .translateBack(OBB.center); + outline.render(ms, buffer); + } + } + ms.pop(); } public static void tick() { - if (OBB == null) - return; - if (AABB == null) - return; - seperation = OBB.intersect(AABB); + AABB = new AxisAlignedBB(BlockPos.ZERO.up(60)).offset(.5, 0, .5); + motion = new Vec3d(0, -2, -.5f); + RayTraceResult mouse = Minecraft.getInstance().objectMouseOver; + if (mouse != null && mouse.getType() == Type.BLOCK) { + BlockRayTraceResult hit = (BlockRayTraceResult) mouse; + OBB.setCenter(hit.getHitVec()); + seperation = OBB.intersect(AABB, motion); + } CreateClient.outliner.showAABB(AABB, AABB) .withFaceTexture(seperation == null ? AllSpecialTextures.CHECKERED : null); } + static void showDebugLine(Vec3d relativeStart, Vec3d relativeEnd, int color, String id, int offset) { + Vec3d center = CollisionDebugger.AABB.getCenter() + .add(0, 1 + offset / 16f, 0); + CreateClient.outliner.showLine(id + OBBCollider.checkCount, center.add(relativeStart), center.add(relativeEnd)) + .colored(color) + .lineWidth(1 / 32f); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java b/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java new file mode 100644 index 000000000..4d951c985 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java @@ -0,0 +1,146 @@ +package com.simibubi.create.foundation.collision; + +import static java.lang.Math.abs; +import static java.lang.Math.signum; + +import net.minecraft.util.math.Vec3d; + +public class ContinuousOBBCollider extends OBBCollider { + + public static ContinuousSeparationManifold separateBBs(Vec3d cA, Vec3d cB, Vec3d eA, Vec3d eB, Matrix3d m, + Vec3d motion) { + ContinuousSeparationManifold mf = new ContinuousSeparationManifold(); + + Vec3d diff = cB.subtract(cA); + + m.transpose(); + Vec3d diff2 = m.transform(diff); + Vec3d motion2 = m.transform(motion); + m.transpose(); + + double a00 = abs(m.m00); + double a01 = abs(m.m01); + double a02 = abs(m.m02); + double a10 = abs(m.m10); + double a11 = abs(m.m11); + double a12 = abs(m.m12); + double a20 = abs(m.m20); + double a21 = abs(m.m21); + double a22 = abs(m.m22); + + Vec3d uB0 = new Vec3d(m.m00, m.m10, m.m20); + Vec3d uB1 = new Vec3d(m.m01, m.m11, m.m21); + Vec3d uB2 = new Vec3d(m.m02, m.m12, m.m22); + + checkCount = 0; + + if ( + // Separate along A's local axes (global XYZ) + !(separate(mf, uA0, diff.x, eA.x, a00 * eB.x + a01 * eB.y + a02 * eB.z, motion.x) + || separate(mf, uA1, diff.y, eA.y, a10 * eB.x + a11 * eB.y + a12 * eB.z, motion.y) + || separate(mf, uA2, diff.z, eA.z, a20 * eB.x + a21 * eB.y + a22 * eB.z, motion.z) + + // Separate along B's local axes + || separate(mf, uB0, diff2.x, eA.x * a00 + eA.y * a10 + eA.z * a20, eB.x, motion2.x) + || separate(mf, uB1, diff2.y, eA.x * a01 + eA.y * a11 + eA.z * a21, eB.y, motion2.y) + || separate(mf, uB2, diff2.z, eA.x * a02 + eA.y * a12 + eA.z * a22, eB.z, motion2.z))) + return mf; + + return null; + } + + static boolean separate(ContinuousSeparationManifold mf, Vec3d axis, double TL, double rA, double rB, + double projectedMotion) { + checkCount++; + double distance = abs(TL); + double diff = distance - (rA + rB); + + boolean discreteCollision = diff <= 0; + if (!discreteCollision && signum(projectedMotion) == signum(TL)) + return true; + + double sTL = signum(TL); + double value = sTL * abs(diff); + + double entryTime = 0; + double exitTime = Double.MAX_VALUE; + if (!discreteCollision) { + mf.isDiscreteCollision = false; + + if (abs(value) > abs(projectedMotion)) + return true; + + entryTime = abs(value) / abs(projectedMotion); + exitTime = (diff + abs(rA) + abs(rB)) / abs(projectedMotion); + mf.latestCollisionEntryTime = Math.max(entryTime, mf.latestCollisionEntryTime); + mf.earliestCollisionExitTime = Math.min(exitTime, mf.earliestCollisionExitTime); + } + + boolean isBestSeperation = distance != 0 && -(diff) <= abs(mf.separation); +// boolean isBestSeperation = discreteCollision && checkCount == 5; // Debug specific separations + + if (isBestSeperation) { + + mf.axis = axis.normalize(); + mf.separation = value; + + // Visualize values +// if (CollisionDebugger.AABB != null) { +// Vec3d normalizedAxis = axis.normalize(); +// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(projectedMotion), 0x111155, "motion", 5); +// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(TL), 0xbb00bb, "tl", 4); +// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(sTL * rA), 0xff4444, "ra", 3); +// showDebugLine(normalizedAxis.scale(sTL * rA), +// normalizedAxis.scale(sTL * rA - entryTime * projectedMotion), 0x44ff44, "entry", 0); +// showDebugLine(normalizedAxis.scale(sTL * rA - entryTime * projectedMotion), +// normalizedAxis.scale(sTL * rA - entryTime * projectedMotion + exitTime * projectedMotion), 0x44ffff, +// "exit", -1); +// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), normalizedAxis.scale(TL), 0x4444ff, "rb", 2); +// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), +// normalizedAxis.scale(sTL * (distance - rB) + value), 0xff9966, "separation", 1); +//// System.out.println("TL:" + TL + ", rA: " + rA + ", rB: " + rB); +// } + + } + + return false; + } + + public static class ContinuousSeparationManifold extends SeparationManifold { + + static final double UNDEFINED = -1; + double latestCollisionEntryTime = UNDEFINED; + double earliestCollisionExitTime = Double.MAX_VALUE; + boolean isDiscreteCollision = true; + + public double getTimeOfImpact() { + if (latestCollisionEntryTime == UNDEFINED) + return UNDEFINED; + if (latestCollisionEntryTime > earliestCollisionExitTime) + return UNDEFINED; + return latestCollisionEntryTime; + } + + public boolean isSurfaceCollision() { + return true; + } + + public Vec3d getAllowedMotion(Vec3d motion) { + double length = motion.length(); + return motion.normalize() + .scale(getTimeOfImpact() * length); + } + + @Override + public Vec3d asSeparationVec() { + if (isDiscreteCollision) + return super.asSeparationVec(); + double t = getTimeOfImpact(); + if (t == UNDEFINED) + return null; + return Vec3d.ZERO; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java index 49f31a2cd..05e24b0f2 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java +++ b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java @@ -20,6 +20,9 @@ public class Matrix3d { public Matrix3d asXRotation(float radians) { asIdentity(); + if (radians == 0) + return this; + double s = MathHelper.sin(radians); double c = MathHelper.cos(radians); m22 = m11 = c; @@ -30,6 +33,9 @@ public class Matrix3d { public Matrix3d asYRotation(float radians) { asIdentity(); + if (radians == 0) + return this; + double s = MathHelper.sin(radians); double c = MathHelper.cos(radians); m00 = m22 = c; @@ -40,6 +46,9 @@ public class Matrix3d { public Matrix3d asZRotation(float radians) { asIdentity(); + if (radians == 0) + return this; + double s = MathHelper.sin(radians); double c = MathHelper.cos(radians); m00 = m11 = c; @@ -104,12 +113,9 @@ public class Matrix3d { } public Vec3d transform(Vec3d vec) { - double x = vec.x; - double y = vec.y; - double z = vec.z; - x = x * m00 + y * m01 + z * m02; - y = x * m10 + y * m11 + z * m12; - z = x * m20 + y * m21 + z * m22; + double x = vec.x * m00 + vec.y * m01 + vec.z * m02; + double y = vec.x * m10 + vec.y * m11 + vec.z * m12; + double z = vec.x * m20 + vec.y * m21 + vec.z * m22; return new Vec3d(x, y, z); } diff --git a/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java new file mode 100644 index 000000000..3d51e398c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java @@ -0,0 +1,103 @@ +package com.simibubi.create.foundation.collision; + +import static com.simibubi.create.foundation.collision.CollisionDebugger.showDebugLine; +import static java.lang.Math.abs; +import static java.lang.Math.signum; + +import net.minecraft.util.math.Vec3d; + +public class OBBCollider { + + static final Vec3d uA0 = new Vec3d(1, 0, 0); + static final Vec3d uA1 = new Vec3d(0, 1, 0); + static final Vec3d uA2 = new Vec3d(0, 0, 1); + + public static Vec3d separateBBs(Vec3d cA, Vec3d cB, Vec3d eA, Vec3d eB, Matrix3d m) { + SeparationManifold mf = new SeparationManifold(); + + Vec3d t = cB.subtract(cA); + + double a00 = abs(m.m00); + double a01 = abs(m.m01); + double a02 = abs(m.m02); + double a10 = abs(m.m10); + double a11 = abs(m.m11); + double a12 = abs(m.m12); + double a20 = abs(m.m20); + double a21 = abs(m.m21); + double a22 = abs(m.m22); + + Vec3d uB0 = new Vec3d(m.m00, m.m10, m.m20); + Vec3d uB1 = new Vec3d(m.m01, m.m11, m.m21); + Vec3d uB2 = new Vec3d(m.m02, m.m12, m.m22); + + checkCount = 0; + + if ( + // Separate along A's local axes (global XYZ) + !(isSeparatedAlong(mf, uA0, t.x, eA.x, a00 * eB.x + a01 * eB.y + a02 * eB.z) + || isSeparatedAlong(mf, uA1, t.y, eA.y, a10 * eB.x + a11 * eB.y + a12 * eB.z) + || isSeparatedAlong(mf, uA2, t.z, eA.z, a20 * eB.x + a21 * eB.y + a22 * eB.z) + + // Separate along B's local axes + || isSeparatedAlong(mf, uB0, (t.x * m.m00 + t.y * m.m10 + t.z * m.m20), + eA.x * a00 + eA.y * a10 + eA.z * a20, eB.x) + || isSeparatedAlong(mf, uB1, (t.x * m.m01 + t.y * m.m11 + t.z * m.m21), + eA.x * a01 + eA.y * a11 + eA.z * a21, eB.y) + || isSeparatedAlong(mf, uB2, (t.x * m.m02 + t.y * m.m12 + t.z * m.m22), + eA.x * a02 + eA.y * a12 + eA.z * a22, eB.z))) + return mf.asSeparationVec(); + + return null; + } + + static int checkCount = 0; + + static boolean isSeparatedAlong(SeparationManifold mf, Vec3d axis, double TL, double rA, double rB) { + checkCount++; + double distance = abs(TL); + double diff = distance - (rA + rB); + if (diff > 0) + return true; + +// boolean isBestSeperation = distance != 0 && -(diff) <= abs(bestSeparation.getValue()); + boolean isBestSeperation = checkCount == 2; // Debug specific separations + + if (isBestSeperation) { + double sTL = signum(TL); + double value = sTL * abs(diff); + mf.axis = axis.normalize(); + mf.separation = value; + + // Visualize values + if (CollisionDebugger.AABB != null) { + Vec3d normalizedAxis = axis.normalize(); + showDebugLine(Vec3d.ZERO, normalizedAxis.scale(TL), 0xbb00bb, "tl", 4); + showDebugLine(Vec3d.ZERO, normalizedAxis.scale(sTL * rA), 0xff4444, "ra", 3); + showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), normalizedAxis.scale(TL), 0x4444ff, "rb", 2); + showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), + normalizedAxis.scale(sTL * (distance - rB) + value), 0xff9966, "separation", 1); + System.out.println("TL:" + TL + ", rA: " + rA + ", rB: " + rB); + } + } + + return false; + } + + static class SeparationManifold { + Vec3d axis; + double separation; + + public SeparationManifold() { + axis = Vec3d.ZERO; + separation = Double.MAX_VALUE; + } + + public Vec3d asSeparationVec() { + double sep = separation; + return axis.normalize() + .scale(signum(sep) * (abs(sep) + 1E-4)); + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java index 0c7a2e770..8b7c75225 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java +++ b/src/main/java/com/simibubi/create/foundation/collision/OrientedBB.java @@ -1,11 +1,6 @@ package com.simibubi.create.foundation.collision; -import static java.lang.Math.abs; - -import org.apache.commons.lang3.mutable.MutableDouble; -import org.apache.commons.lang3.mutable.MutableObject; - -import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.Vec3d; @@ -29,140 +24,26 @@ public class OrientedBB { this.extents = extents; this.setRotation(rotation); } - + public OrientedBB copy() { return new OrientedBB(center, extents, rotation); } public Vec3d intersect(AxisAlignedBB bb) { Vec3d extentsA = extentsFromBB(bb); - Vec3d intersects = separateBBs(bb.getCenter(), center, extentsA, extents, rotation); + Vec3d intersects = OBBCollider.separateBBs(bb.getCenter(), center, extentsA, extents, rotation); return intersects; } + public ContinuousSeparationManifold intersect(AxisAlignedBB bb, Vec3d motion) { + Vec3d extentsA = extentsFromBB(bb); + return ContinuousOBBCollider.separateBBs(bb.getCenter(), center, extentsA, extents, rotation, motion); + } + private static Vec3d extentsFromBB(AxisAlignedBB bb) { return new Vec3d(bb.getXSize() / 2, bb.getYSize() / 2, bb.getZSize() / 2); } - public static Vec3d separateBBs(Vec3d cA, Vec3d cB, Vec3d eA, Vec3d eB, Matrix3d m) { - Vec3d t = cB.subtract(cA); - double a00 = abs(m.m00); - double a01 = abs(m.m01); - double a02 = abs(m.m02); - double a10 = abs(m.m10); - double a11 = abs(m.m11); - double a12 = abs(m.m12); - double a20 = abs(m.m20); - double a21 = abs(m.m21); - double a22 = abs(m.m22); - - MutableObject bestAxis = new MutableObject<>(Vec3d.ZERO); - MutableDouble bestSep = new MutableDouble(Double.MAX_VALUE); - - Vec3d uA0 = new Vec3d(1, 0, 0); - Vec3d uA1 = new Vec3d(0, 1, 0); - Vec3d uA2 = new Vec3d(0, 0, 1); - - Vec3d uB0 = new Vec3d(m.m00, m.m10, m.m20); - Vec3d uB1 = new Vec3d(m.m01, m.m11, m.m21); - Vec3d uB2 = new Vec3d(m.m02, m.m12, m.m22); - - checkCount = 0; - - if ( - - // Separate along A's local axes (global XYZ) - !(isSeparatedAlong(bestAxis, bestSep, uA0, t.x, eA.x, a00 * eB.x + a01 * eB.y + a02 * eB.z) - || isSeparatedAlong(bestAxis, bestSep, uA1, t.y, eA.y, a10 * eB.x + a11 * eB.y + a12 * eB.z) - || isSeparatedAlong(bestAxis, bestSep, uA2, t.z, eA.z, a20 * eB.x + a21 * eB.y + a22 * eB.z) - - // Separate along B's local axes - || isSeparatedAlong(bestAxis, bestSep, uB0, (t.x * m.m00 + t.y * m.m10 + t.z * m.m20), - eA.x * a00 + eA.y * a10 + eA.z * a20, eB.x) - || isSeparatedAlong(bestAxis, bestSep, uB1, (t.x * m.m01 + t.y * m.m11 + t.z * m.m21), - eA.x * a01 + eA.y * a11 + eA.z * a21, eB.y) - || isSeparatedAlong(bestAxis, bestSep, uB2, (t.x * m.m02 + t.y * m.m12 + t.z * m.m22), - eA.x * a02 + eA.y * a12 + eA.z * a22, eB.z) - - /* - * The following checks (edge-to-edge) need special separation logic. They are - * not necessary as long as the obb is only rotated around one axis at a time - * (Which is the case for contraptions at the moment) - * - */ - - // Separate along axes perpendicular to AxB -// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB0), t.z * m.m10 - t.y * m.m20, -// eA.y * a20 + eA.z * a10, eB.y * a02 + eB.z * a01) -// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB1), t.z * m.m11 - t.y * m.m21, -// eA.y * a21 + eA.z * a11, eB.x * a02 + eB.z * a00) -// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB2), t.z * m.m12 - t.y * m.m22, -// eA.y * a22 + eA.z * a12, eB.x * a01 + eB.y * a00) -// -// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB0), t.x * m.m20 - t.z * m.m00, -// eA.x * a20 + eA.z * a00, eB.y * a12 + eB.z * a11) -// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB1), t.x * m.m21 - t.z * m.m01, -// eA.x * a21 + eA.z * a01, eB.x * a12 + eB.z * a10) -// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB2), t.x * m.m22 - t.z * m.m02, -// eA.x * a22 + eA.z * a02, eB.x * a11 + eB.y * a10) -// -// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB0), t.y * m.m00 - t.x * m.m10, -// eA.x * a10 + eA.y * a00, eB.y * a22 + eB.z * a21) -// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB1), t.y * m.m01 - t.x * m.m11, -// eA.x * a11 + eA.y * a01, eB.x * a22 + eB.z * a20) -// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB2), t.y * m.m02 - t.x * m.m12, -// eA.x * a12 + eA.y * a02, eB.x * a21 + eB.y * a20) - )) - - return bestAxis.getValue() - .normalize() - .scale(bestSep.getValue()); - - return null; - } - - static int checkCount = 0; - - static boolean isSeparatedAlong(MutableObject bestAxis, MutableDouble bestSeparation, Vec3d axis, double TL, - double rA, double rB) { - double distance = abs(TL); - - checkCount++; - - double diff = distance - (rA + rB); - if (diff > 0) - return true; - boolean isBestSeperation = distance != 0 && -(diff) <= abs(bestSeparation.getValue()); -// boolean isBestSeperation = checkCount == 12; // Debug specific separations - if (isBestSeperation) { - bestAxis.setValue(axis.normalize()); - double sTL = Math.signum(TL); - double value = sTL * abs(diff); - bestSeparation.setValue(value); - - // Visualize values -// if (CollisionDebugger.staticBB != null) { -// Vec3d normalizedAxis = axis.normalize(); -// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(TL), 0xbb00bb, "tl", 4); -// showDebugLine(Vec3d.ZERO, normalizedAxis.scale(sTL * rA), 0xff4444, "ra", 3); -// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), normalizedAxis.scale(TL), 0x4444ff, "rb", 2); -// showDebugLine(normalizedAxis.scale(sTL * (distance - rB)), -// normalizedAxis.scale(sTL * (distance - rB) + value), 0xff9966, "separation", 1); -// System.out.println("TL:" + TL + ", rA: " + rA + ", rB: " + rB); -// } - } - - return false; - } - - static void showDebugLine(Vec3d relativeStart, Vec3d relativeEnd, int color, String id, int offset) { - Vec3d center = CollisionDebugger.AABB.getCenter() - .add(0, 1 + offset / 16f, 0); - CreateClient.outliner.showLine(id + checkCount, center.add(relativeStart), center.add(relativeEnd)) - .colored(color) - .lineWidth(1 / 32f); - } - public Matrix3d getRotation() { return rotation; } @@ -178,7 +59,7 @@ public class OrientedBB { public void setCenter(Vec3d center) { this.center = center; } - + public void move(Vec3d offset) { setCenter(getCenter().add(offset)); } @@ -188,4 +69,33 @@ public class OrientedBB { .grow(extents.x, extents.y, extents.z); } + /* + * The following checks (edge-to-edge) need special separation logic. They are + * not necessary as long as the obb is only rotated around one axis at a time + * (Which is the case for contraptions at the moment) + * + */ + + // Separate along axes perpendicular to AxB +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB0), t.z * m.m10 - t.y * m.m20, +// eA.y * a20 + eA.z * a10, eB.y * a02 + eB.z * a01) +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB1), t.z * m.m11 - t.y * m.m21, +// eA.y * a21 + eA.z * a11, eB.x * a02 + eB.z * a00) +// || isSeparatedAlong(bestAxis, bestSep, uA0.crossProduct(uB2), t.z * m.m12 - t.y * m.m22, +// eA.y * a22 + eA.z * a12, eB.x * a01 + eB.y * a00) +// +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB0), t.x * m.m20 - t.z * m.m00, +// eA.x * a20 + eA.z * a00, eB.y * a12 + eB.z * a11) +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB1), t.x * m.m21 - t.z * m.m01, +// eA.x * a21 + eA.z * a01, eB.x * a12 + eB.z * a10) +// || isSeparatedAlong(bestAxis, bestSep, uA1.crossProduct(uB2), t.x * m.m22 - t.z * m.m02, +// eA.x * a22 + eA.z * a02, eB.x * a11 + eB.y * a10) +// +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB0), t.y * m.m00 - t.x * m.m10, +// eA.x * a10 + eA.y * a00, eB.y * a22 + eB.z * a21) +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB1), t.y * m.m01 - t.x * m.m11, +// eA.x * a11 + eA.y * a01, eB.x * a22 + eB.z * a20) +// || isSeparatedAlong(bestAxis, bestSep, uA2.crossProduct(uB2), t.y * m.m02 - t.x * m.m12, +// eA.x * a12 + eA.y * a02, eB.x * a21 + eB.y * a20) + } diff --git a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 4469d2051..f42a9f6c0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -28,10 +28,14 @@ public class AngleHelper { } public static float rad(double angle) { + if (angle == 0) + return 0; return (float) (angle / 180 * Math.PI); } public static float deg(double angle) { + if (angle == 0) + return 0; return (float) (angle * 180 / Math.PI); } From 53a58def498d3d08a1bc373b6022bfd37af94afb Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 15 Jul 2020 15:01:59 +0200 Subject: [PATCH 08/17] Contact points and Friction - Entities are now moved with the relative motion of their contact point --- .../ContraptionCollider.java | 113 ++++++++++-------- .../structureMovement/ContraptionEntity.java | 12 +- 2 files changed, 76 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index fb1f6cac2..8171a9767 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -130,28 +130,40 @@ public class ContraptionCollider { if (bounds == null) return; + Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO); double conRotX = contraptionRotation.z; double conRotY = contraptionRotation.y; double conRotZ = contraptionRotation.x; + Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); + Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec()); + Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0); + boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); + Matrix3d rotation = null; for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2) .expand(0, 32, 0), contraptionEntity::canCollideWith)) { boolean serverPlayer = entity instanceof PlayerEntity && !world.isRemote; + // Init matrix + if (rotation == null) { + rotation = new Matrix3d().asIdentity(); + if (!axisAlignedCollision) { + rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(-conRotX))); + rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(conRotY))); + rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(-conRotZ))); + } + } + // Transform entity position and motion to local space - Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO); Vec3d entityPosition = entity.getPositionVec(); AxisAlignedBB entityBounds = entity.getBoundingBox(); Vec3d centerY = new Vec3d(0, entityBounds.getYSize() / 2, 0); Vec3d motion = entity.getMotion(); - boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); - - Vec3d position = - entityPosition.subtract(contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0)) - .add(centerY); + Vec3d position = entityPosition.subtract(contraptionCentreOffset) + .add(centerY); position = position.subtract(contraptionPosition); - position = VecHelper.rotate(position, -conRotX, -conRotY, -conRotZ); + position = rotation.transform(position); position = position.add(centerOfBlock) .subtract(centerY) .subtract(entityPosition); @@ -165,18 +177,10 @@ public class ContraptionCollider { .count() == 0) continue; - if (!axisAlignedCollision) - motion = VecHelper.rotate(motion, -conRotX, -conRotY, -conRotZ); - // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); - if (!axisAlignedCollision) { - Matrix3d rotation = new Matrix3d().asIdentity(); - rotation.multiply(new Matrix3d().asXRotation(AngleHelper.rad(-conRotX))); - rotation.multiply(new Matrix3d().asYRotation(AngleHelper.rad(conRotY))); - rotation.multiply(new Matrix3d().asZRotation(AngleHelper.rad(-conRotZ))); - obb.setRotation(rotation); - } + obb.setRotation(rotation); + motion = rotation.transform(motion); // Vec3d visualizerOrigin = new Vec3d(10, 64, 0); // CollisionDebugger.OBB = obb.copy(); @@ -233,10 +237,14 @@ public class ContraptionCollider { Vec3d entityMotion = entity.getMotion(); Vec3d totalResponse = collisionResponse.getValue(); Vec3d motionResponse = allowedMotion.getValue(); + boolean hardCollision = !totalResponse.equals(Vec3d.ZERO); + + rotation.transpose(); + motionResponse = rotation.transform(motionResponse); + totalResponse = rotation.transform(totalResponse); + rotation.transpose(); if (futureCollision.isTrue() && !serverPlayer) { - if (!axisAlignedCollision) - motionResponse = VecHelper.rotate(motionResponse, conRotX, conRotY, conRotZ); if (motionResponse.y != entityMotion.y) { entity.setMotion(entityMotion.mul(1, 0, 1) .add(0, motionResponse.y, 0)); @@ -244,47 +252,58 @@ public class ContraptionCollider { } } - if (!axisAlignedCollision) - totalResponse = VecHelper.rotate(totalResponse, conRotX, conRotY, conRotZ); - + Vec3d contactPointMotion = Vec3d.ZERO; if (surfaceCollision.isTrue()) { // entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue entity.fallDistance = 0; entity.onGround = true; if (!serverPlayer) { + + Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset) + .subtract(contraptionPosition); + contactPoint = + VecHelper.rotate(contactPoint, conAngularMotion.z, conAngularMotion.y, conAngularMotion.x); + contactPoint = contactPoint.add(contraptionPosition) + .add(contraptionCentreOffset) + .add(conMotion); + contactPointMotion = contactPoint.subtract(entityPosition); + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); } } - if (totalResponse.equals(Vec3d.ZERO)) + if (hardCollision) { + double motionX = entityMotion.getX(); + double motionY = entityMotion.getY(); + double motionZ = entityMotion.getZ(); + double intersectX = totalResponse.getX(); + double intersectY = totalResponse.getY(); + double intersectZ = totalResponse.getZ(); + + double horizonalEpsilon = 1 / 128f; + if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0) + entityMotion = entityMotion.mul(0, 1, 1); + if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0) + entityMotion = entityMotion.mul(1, 0, 1); + if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0) + entityMotion = entityMotion.mul(1, 1, 0); + } + + if (!hardCollision && surfaceCollision.isFalse()) continue; - double motionX = entityMotion.getX(); - double motionY = entityMotion.getY(); - double motionZ = entityMotion.getZ(); - double intersectX = totalResponse.getX(); - double intersectY = totalResponse.getY(); - double intersectZ = totalResponse.getZ(); - - double horizonalEpsilon = 1 / 128f; - if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0) - entityMotion = entityMotion.mul(0, 1, 1); - if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0) - entityMotion = entityMotion.mul(1, 0, 1); - if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0) - entityMotion = entityMotion.mul(1, 1, 0); - - if (entity instanceof ServerPlayerEntity) + if (serverPlayer && entity instanceof ServerPlayerEntity) { ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; - - if (!serverPlayer) { - Vec3d allowedMovement = getAllowedMovement(totalResponse, entity); - contraptionEntity.collidingEntities.add(entity); - entity.velocityChanged = true; - entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, - entityPosition.z + allowedMovement.z); - entity.setMotion(entityMotion); + continue; } + + totalResponse = totalResponse.add(contactPointMotion); + Vec3d allowedMovement = getAllowedMovement(totalResponse, entity); + contraptionEntity.collidingEntities.add(entity); + entity.velocityChanged = true; + entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, + entityPosition.z + allowedMovement.z); + entity.setMotion(entityMotion); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index db84d00ca..3a1a815d7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -636,6 +636,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return new Vec3d(getPitch(1), getYaw(1), getRoll(1)); } + public Vec3d getPrevRotationVec() { + return new Vec3d(getPitch(0), getYaw(0), getRoll(0)); + } + + public Vec3d getPrevPositionVec() { + return new Vec3d(prevPosX, prevPosY, prevPosZ); + } + public boolean canCollideWith(Entity e) { if (e instanceof PlayerEntity && e.isSpectator()) return false; @@ -647,14 +655,14 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return false; if (e instanceof IProjectile) return false; - + Entity riding = this.getRidingEntity(); while (riding != null) { if (riding == e) return false; riding = riding.getRidingEntity(); } - + return e.getPushReaction() == PushReaction.NORMAL; } From 5ebb44f50b7f6a80254066cd1763dd946b81f68f Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 19 Jul 2020 20:54:29 +0200 Subject: [PATCH 09/17] Projected stepheight - The oriented collision response now accounts for an entities' step height to automatically climb blocks such as stairs or slabs --- .../ContraptionCollider.java | 2 +- .../collision/CollisionDebugger.java | 39 ++++++------ .../collision/ContinuousOBBCollider.java | 61 ++++++++++++++++--- .../foundation/collision/OBBCollider.java | 5 ++ 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 8171a9767..6de3581fa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -222,7 +222,7 @@ public class ContraptionCollider { // params.colored(0x4499ff); continue; } - Vec3d separation = intersect.asSeparationVec(); + Vec3d separation = intersect.asSeparationVec(entity.stepHeight); if (separation != null && !separation.equals(Vec3d.ZERO)) { collisionResponse.setValue(currentResponse.add(separation)); // Debug.debugChat("Collision " + currentResponse.add(separation) diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java index b8c3ec26c..d7423304c 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java +++ b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java @@ -6,6 +6,7 @@ import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Debug; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.outliner.AABBOutline; @@ -28,7 +29,9 @@ public class CollisionDebugger { public static void onScroll(double delta) { angle += delta; + angle = (int) angle; OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); + Debug.debugMessage("Angle: " + angle); } public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { @@ -51,26 +54,26 @@ public class CollisionDebugger { outline.render(ms, buffer); ms.pop(); - ms.push(); - if (motion.length() != 0 && (seperation == null || seperation.getTimeOfImpact() != 1)) { - outline.getParams() - .colored(0x6544ff) - .lineWidth(1 / 32f); - MatrixStacker.of(ms) - .translate(seperation != null ? seperation.getAllowedMotion(motion) : motion) - .translate(OBB.center); - ms.peek() - .getModel() - .multiply(OBB.rotation.getAsMatrix4f()); - MatrixStacker.of(ms) - .translateBack(OBB.center); - outline.render(ms, buffer); - } - ms.pop(); +// ms.push(); +// if (motion.length() != 0 && (seperation == null || seperation.getTimeOfImpact() != 1)) { +// outline.getParams() +// .colored(0x6544ff) +// .lineWidth(1 / 32f); +// MatrixStacker.of(ms) +// .translate(seperation != null ? seperation.getAllowedMotion(motion) : motion) +// .translate(OBB.center); +// ms.peek() +// .getModel() +// .multiply(OBB.rotation.getAsMatrix4f()); +// MatrixStacker.of(ms) +// .translateBack(OBB.center); +// outline.render(ms, buffer); +// } +// ms.pop(); ms.push(); if (seperation != null) { - Vec3d asSeparationVec = seperation.asSeparationVec(); + Vec3d asSeparationVec = seperation.asSeparationVec(.5f); if (asSeparationVec != null) { outline.getParams() .colored(0x65ff44) @@ -91,7 +94,7 @@ public class CollisionDebugger { public static void tick() { AABB = new AxisAlignedBB(BlockPos.ZERO.up(60)).offset(.5, 0, .5); - motion = new Vec3d(0, -2, -.5f); + motion = Vec3d.ZERO; RayTraceResult mouse = Minecraft.getInstance().objectMouseOver; if (mouse != null && mouse.getType() == Type.BLOCK) { BlockRayTraceResult hit = (BlockRayTraceResult) mouse; diff --git a/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java b/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java index 4d951c985..b87de83b9 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java +++ b/src/main/java/com/simibubi/create/foundation/collision/ContinuousOBBCollider.java @@ -33,6 +33,8 @@ public class ContinuousOBBCollider extends OBBCollider { Vec3d uB2 = new Vec3d(m.m02, m.m12, m.m22); checkCount = 0; + mf.stepSeparationAxis = uB1; + mf.stepSeparation = Double.MAX_VALUE; if ( // Separate along A's local axes (global XYZ) @@ -60,29 +62,62 @@ public class ContinuousOBBCollider extends OBBCollider { return true; double sTL = signum(TL); - double value = sTL * abs(diff); + double seperation = sTL * abs(diff); double entryTime = 0; double exitTime = Double.MAX_VALUE; if (!discreteCollision) { mf.isDiscreteCollision = false; - if (abs(value) > abs(projectedMotion)) + if (abs(seperation) > abs(projectedMotion)) return true; - entryTime = abs(value) / abs(projectedMotion); + entryTime = abs(seperation) / abs(projectedMotion); exitTime = (diff + abs(rA) + abs(rB)) / abs(projectedMotion); mf.latestCollisionEntryTime = Math.max(entryTime, mf.latestCollisionEntryTime); mf.earliestCollisionExitTime = Math.min(exitTime, mf.earliestCollisionExitTime); } + Vec3d normalizedAxis = axis.normalize(); + boolean isBestSeperation = distance != 0 && -(diff) <= abs(mf.separation); // boolean isBestSeperation = discreteCollision && checkCount == 5; // Debug specific separations + double dot = mf.stepSeparationAxis.dotProduct(axis); + if (dot != 0 && discreteCollision) { + Vec3d cross = axis.crossProduct(mf.stepSeparationAxis); + double dotSeparation = signum(dot) * TL - (rA + rB); + double stepSeparation = -dotSeparation; + Vec3d stepSeparationVec = axis; + + if (!cross.equals(Vec3d.ZERO)) { + Vec3d sepVec = normalizedAxis.scale(dotSeparation); + Vec3d axisPlane = axis.crossProduct(cross); + Vec3d stepPlane = mf.stepSeparationAxis.crossProduct(cross); + stepSeparationVec = + sepVec.subtract(axisPlane.scale(sepVec.dotProduct(stepPlane) / axisPlane.dotProduct(stepPlane))); + stepSeparation = stepSeparationVec.length(); + + + if (abs(mf.stepSeparation) > abs(stepSeparation) && stepSeparation != 0) { +// CollisionDebugger.showDebugLine(Vec3d.ZERO, sepVec, 0x111155, "stepsep", -16); + mf.stepSeparation = stepSeparation; + } + + } else { + if (abs(mf.stepSeparation) > stepSeparation) { + mf.stepSeparation = stepSeparation; +// CollisionDebugger.showDebugLine(Vec3d.ZERO, stepSeparationVec, 0xff9999, "axis", -16); + } + } + +// if (abs(mf.separation) < abs(stepSeparation) && stepSeparation != 0) + } + if (isBestSeperation) { - mf.axis = axis.normalize(); - mf.separation = value; + mf.axis = normalizedAxis; + mf.separation = seperation; // Visualize values // if (CollisionDebugger.AABB != null) { @@ -113,6 +148,9 @@ public class ContinuousOBBCollider extends OBBCollider { double earliestCollisionExitTime = Double.MAX_VALUE; boolean isDiscreteCollision = true; + Vec3d stepSeparationAxis; + double stepSeparation; + public double getTimeOfImpact() { if (latestCollisionEntryTime == UNDEFINED) return UNDEFINED; @@ -131,15 +169,22 @@ public class ContinuousOBBCollider extends OBBCollider { .scale(getTimeOfImpact() * length); } - @Override - public Vec3d asSeparationVec() { - if (isDiscreteCollision) + public Vec3d asSeparationVec(double obbStepHeight) { + if (isDiscreteCollision) { + if (stepSeparation <= obbStepHeight) + return createSeparationVec(stepSeparation, stepSeparationAxis); return super.asSeparationVec(); + } double t = getTimeOfImpact(); if (t == UNDEFINED) return null; return Vec3d.ZERO; } + + @Override + public Vec3d asSeparationVec() { + return asSeparationVec(0); + } } diff --git a/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java index 3d51e398c..daf13ab6b 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java +++ b/src/main/java/com/simibubi/create/foundation/collision/OBBCollider.java @@ -95,6 +95,11 @@ public class OBBCollider { public Vec3d asSeparationVec() { double sep = separation; + Vec3d axis = this.axis; + return createSeparationVec(sep, axis); + } + + protected Vec3d createSeparationVec(double sep, Vec3d axis) { return axis.normalize() .scale(signum(sep) * (abs(sep) + 1E-4)); } From d3e7b23d6e5714a658dbb0046c8297bb6a6d4b3d Mon Sep 17 00:00:00 2001 From: Zelophed Date: Mon, 20 Jul 2020 01:19:04 +0200 Subject: [PATCH 10/17] Seats, part I --- .../com/simibubi/create/AllEntityTypes.java | 4 + .../components/actors/SeatBlock.java | 33 ++++++- .../components/actors/SeatEntity.java | 97 +++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java diff --git a/src/main/java/com/simibubi/create/AllEntityTypes.java b/src/main/java/com/simibubi/create/AllEntityTypes.java index 80e5bbf50..0e2e5b593 100644 --- a/src/main/java/com/simibubi/create/AllEntityTypes.java +++ b/src/main/java/com/simibubi/create/AllEntityTypes.java @@ -1,5 +1,6 @@ package com.simibubi.create; +import com.simibubi.create.content.contraptions.components.actors.SeatEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntityRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; @@ -24,6 +25,8 @@ public class AllEntityTypes { register("stationary_contraption", ContraptionEntity::new, EntityClassification.MISC, 20, 40, false, ContraptionEntity::build); public static final RegistryEntry> SUPER_GLUE = register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build); + public static final RegistryEntry> SEAT = + register("seat", SeatEntity::new, EntityClassification.MISC, 0, Integer.MAX_VALUE, false, SeatEntity::build); private static RegistryEntry> register(String name, IFactory factory, EntityClassification group, int range, int updateFrequency, boolean sendVelocity, @@ -45,5 +48,6 @@ public class AllEntityTypes { RenderingRegistry.registerEntityRenderingHandler(STATIONARY_CONTRAPTION.get(), ContraptionEntityRenderer::new); RenderingRegistry.registerEntityRenderingHandler(CONTRAPTION.get(), ContraptionEntityRenderer::new); RenderingRegistry.registerEntityRenderingHandler(SUPER_GLUE.get(), SuperGlueRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(SEAT.get(), SeatEntity.Render::new); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java index 1f32e1d24..93c502916 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -4,13 +4,20 @@ import com.simibubi.create.AllShapes; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; public class SeatBlock extends Block { @@ -27,11 +34,35 @@ public class SeatBlock extends Block { return; super.fillItemGroup(group, p_149666_2_); } - + + @Override + public void onFallenUpon(World p_180658_1_, BlockPos p_180658_2_, Entity p_180658_3_, float p_180658_4_) { + super.onFallenUpon(p_180658_1_, p_180658_2_, p_180658_3_, p_180658_4_ * 0.5F); + } + + @Override + public void onLanded(IBlockReader p_176216_1_, Entity p_176216_2_) { + Blocks.PINK_BED.onLanded(p_176216_1_, p_176216_2_); + } + @Override public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_, ISelectionContext p_220053_4_) { return AllShapes.SEAT; } + @Override + public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) { + if (SeatEntity.TAKEN.containsKey(pos)) + return ActionResultType.FAIL; + + if (world.isRemote) + return ActionResultType.SUCCESS; + + SeatEntity seat = new SeatEntity(world, pos); + world.addEntity(seat); + player.startRiding(seat); + + return ActionResultType.SUCCESS; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java new file mode 100644 index 000000000..9e5cab53a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java @@ -0,0 +1,97 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.AllEntityTypes; +import net.minecraft.client.renderer.culling.ClippingHelperImpl; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.IPacket; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; + +import java.util.HashMap; +import java.util.Map; + +public class SeatEntity extends Entity { + + public static final Map TAKEN = new HashMap<>(); + + public SeatEntity(EntityType p_i48580_1_, World p_i48580_2_) { + super(p_i48580_1_, p_i48580_2_); + } + + public SeatEntity(World world, BlockPos pos) { + this(AllEntityTypes.SEAT.get(), world); + this.setPos(pos.getX() + 0.5, pos.getY() + 0.30, pos.getZ() + 0.5); + noClip = true; + TAKEN.put(pos, this); + + } + + public static EntityType.Builder build(EntityType.Builder builder) { + @SuppressWarnings("unchecked") + EntityType.Builder entityBuilder = (EntityType.Builder) builder; + return entityBuilder.size(0, 0); + } + + @Override + public void tick() { + if (world.isRemote) + return; + + BlockPos blockPos = new BlockPos(getX(), getY(), getZ()); + if (isBeingRidden() && world.getBlockState(blockPos).getBlock() instanceof SeatBlock) + return; + + TAKEN.remove(blockPos); + this.remove(); + } + + @Override + protected boolean canBeRidden(Entity p_184228_1_) { + return true; + } + + @Override + protected void removePassenger(Entity entity) { + super.removePassenger(entity); + Vec3d pos = entity.getPositionVec(); + entity.setPosition(pos.x, pos.y + 0.7, pos.z); + } + + @Override + protected void registerData() {} + + @Override + protected void readAdditional(CompoundNBT p_70037_1_) {} + + @Override + protected void writeAdditional(CompoundNBT p_213281_1_) {} + + @Override + public IPacket createSpawnPacket() { + return NetworkHooks.getEntitySpawningPacket(this); + } + + public static class Render extends EntityRenderer { + + public Render(EntityRendererManager p_i46179_1_) { + super(p_i46179_1_); + } + + @Override + public boolean shouldRender(SeatEntity p_225626_1_, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_, double p_225626_7_) { + return false; + } + + @Override + public ResourceLocation getEntityTexture(SeatEntity p_110775_1_) { + return null; + } + } +} From 7994835cb012a1568ad761be2c93dc9c423c8b75 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 22 Jul 2020 01:18:09 +0200 Subject: [PATCH 11/17] Seats, part II - Any living entity can now use seats - Fix client sync issues with seats - Fixed contraptions double-reversing roll and pitch values when communicating to the collision engine - Seats now transfer their passengers to a contraption when moved and back when disassembled - Attempted further refinements to the collision response of horizontally rotated contraptions - Set up a hook to inject custom interaction between players and contraption mounted blocks on right-click - Seats can now by mounted by players while assembled to a contraption - Minor refactors to the contraption class --- .../java/ContraptionInteractionHandler.java | 89 ++ .../com/simibubi/create/AllEntityTypes.java | 2 +- .../components/actors/SeatBlock.java | 75 +- .../components/actors/SeatEntity.java | 53 +- .../actors/SeatMovementBehaviour.java | 9 + .../structureMovement/Contraption.java | 1233 +++++++++-------- .../ContraptionCollider.java | 100 +- .../structureMovement/ContraptionEntity.java | 170 ++- .../ContraptionInteractionPacket.java | 65 + .../ContraptionSeatMappingPacket.java | 58 + .../bearing/ClockworkBearingTileEntity.java | 4 - .../bearing/MechanicalBearingTileEntity.java | 2 - .../mounted/MountedContraption.java | 11 +- .../piston/LinearActuatorTileEntity.java | 1 - .../piston/PistonContraption.java | 54 +- .../collision/CollisionDebugger.java | 2 - .../foundation/networking/AllPackets.java | 4 + .../create/foundation/utility/VecHelper.java | 4 + .../create/textures/block/seat/bottom.png | Bin 304 -> 306 bytes .../create/textures/block/seat/side_black.png | Bin 387 -> 379 bytes .../create/textures/block/seat/side_blue.png | Bin 389 -> 392 bytes .../create/textures/block/seat/side_brown.png | Bin 385 -> 389 bytes .../create/textures/block/seat/side_cyan.png | Bin 389 -> 401 bytes .../create/textures/block/seat/side_gray.png | Bin 385 -> 375 bytes .../create/textures/block/seat/side_green.png | Bin 387 -> 390 bytes .../textures/block/seat/side_light_blue.png | Bin 391 -> 398 bytes .../textures/block/seat/side_light_gray.png | Bin 407 -> 412 bytes .../create/textures/block/seat/side_lime.png | Bin 390 -> 403 bytes .../textures/block/seat/side_magenta.png | Bin 386 -> 398 bytes .../textures/block/seat/side_orange.png | Bin 387 -> 404 bytes .../create/textures/block/seat/side_pink.png | Bin 404 -> 408 bytes .../textures/block/seat/side_purple.png | Bin 407 -> 413 bytes .../create/textures/block/seat/side_red.png | Bin 387 -> 399 bytes .../create/textures/block/seat/side_white.png | Bin 400 -> 416 bytes .../textures/block/seat/side_yellow.png | Bin 387 -> 404 bytes 35 files changed, 1231 insertions(+), 705 deletions(-) create mode 100644 src/main/java/ContraptionInteractionHandler.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java diff --git a/src/main/java/ContraptionInteractionHandler.java b/src/main/java/ContraptionInteractionHandler.java new file mode 100644 index 000000000..8ae1d08c5 --- /dev/null +++ b/src/main/java/ContraptionInteractionHandler.java @@ -0,0 +1,89 @@ +import org.apache.commons.lang3.mutable.MutableObject; + +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.RaycastHelper; +import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.gen.feature.template.Template.BlockInfo; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.InputEvent.ClickInputEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber +public class ContraptionInteractionHandler { + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void rightClickingOnContraptionsGetsHandledLocally(ClickInputEvent event) { + Minecraft mc = Minecraft.getInstance(); + ClientPlayerEntity player = mc.player; + if (player == null) + return; + if (mc.world == null) + return; + if (!event.isUseItem()) + return; + Vec3d origin = RaycastHelper.getTraceOrigin(player); + + double reach = mc.playerController.getBlockReachDistance(); + if (mc.objectMouseOver != null && mc.objectMouseOver.getHitVec() != null) + reach = Math.min(mc.objectMouseOver.getHitVec().distanceTo(origin), reach); + + Vec3d target = RaycastHelper.getTraceTarget(player, reach, origin); + for (ContraptionEntity contraptionEntity : mc.world.getEntitiesWithinAABB(ContraptionEntity.class, + new AxisAlignedBB(origin, target))) { + + Vec3d localOrigin = contraptionEntity.toLocalVector(origin); + Vec3d localTarget = contraptionEntity.toLocalVector(target); + Contraption contraption = contraptionEntity.getContraption(); + + MutableObject mutableResult = new MutableObject<>(); + PredicateTraceResult predicateResult = RaycastHelper.rayTraceUntil(localOrigin, localTarget, p -> { + BlockInfo blockInfo = contraption.blocks.get(p); + if (blockInfo == null) + return false; + BlockState state = blockInfo.state; + VoxelShape raytraceShape = state.getShape(Minecraft.getInstance().world, BlockPos.ZERO.down()); + if (raytraceShape.isEmpty()) + return false; + BlockRayTraceResult rayTrace = raytraceShape.rayTrace(localOrigin, localTarget, p); + if (rayTrace != null) { + mutableResult.setValue(rayTrace); + return true; + } + return false; + }); + + if (predicateResult == null || predicateResult.missed()) + return; + + BlockRayTraceResult rayTraceResult = mutableResult.getValue(); + Hand hand = event.getHand(); + Direction face = rayTraceResult.getFace(); + BlockPos pos = rayTraceResult.getPos(); + + if (!contraptionEntity.handlePlayerInteraction(player, pos, face, hand)) + return; + AllPackets.channel.sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand, + pos, face)); + event.setCanceled(true); + event.setSwingHand(false); + } + } + +} diff --git a/src/main/java/com/simibubi/create/AllEntityTypes.java b/src/main/java/com/simibubi/create/AllEntityTypes.java index 0e2e5b593..13d75af47 100644 --- a/src/main/java/com/simibubi/create/AllEntityTypes.java +++ b/src/main/java/com/simibubi/create/AllEntityTypes.java @@ -26,7 +26,7 @@ public class AllEntityTypes { public static final RegistryEntry> SUPER_GLUE = register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build); public static final RegistryEntry> SEAT = - register("seat", SeatEntity::new, EntityClassification.MISC, 0, Integer.MAX_VALUE, false, SeatEntity::build); + register("seat", SeatEntity::new, EntityClassification.MISC, 5, Integer.MAX_VALUE, false, SeatEntity::build); private static RegistryEntry> register(String name, IFactory factory, EntityClassification group, int range, int updateFrequency, boolean sendVelocity, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java index 93c502916..b5df0a8c2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -1,17 +1,25 @@ package com.simibubi.create.content.contraptions.components.actors; +import java.util.List; + import com.simibubi.create.AllShapes; +import com.simibubi.create.content.contraptions.components.structureMovement.IPortableBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; +import net.minecraft.pathfinding.PathNodeType; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.NonNullList; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; @@ -19,15 +27,16 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class SeatBlock extends Block { +public class SeatBlock extends Block implements IPortableBlock { + public static MovementBehaviour MOVEMENT = new SeatMovementBehaviour(); private boolean inCreativeTab; public SeatBlock(Properties p_i48440_1_, boolean inCreativeTab) { super(p_i48440_1_); this.inCreativeTab = inCreativeTab; } - + @Override public void fillItemGroup(ItemGroup group, NonNullList p_149666_2_) { if (group != ItemGroup.SEARCH && !inCreativeTab) @@ -41,8 +50,21 @@ public class SeatBlock extends Block { } @Override - public void onLanded(IBlockReader p_176216_1_, Entity p_176216_2_) { - Blocks.PINK_BED.onLanded(p_176216_1_, p_176216_2_); + public void onLanded(IBlockReader reader, Entity entity) { + BlockPos pos = entity.getPosition(); + if (entity instanceof PlayerEntity || !(entity instanceof LivingEntity) || isSeatOccupied(entity.world, pos)) { + Blocks.PINK_BED.onLanded(reader, entity); + return; + } + if (reader.getBlockState(pos) + .getBlock() != this) + return; + sitDown(entity.world, pos, entity); + } + + @Override + public PathNodeType getAiPathNodeType(BlockState state, IBlockReader world, BlockPos pos, MobEntity entity) { + return PathNodeType.RAIL; } @Override @@ -52,17 +74,46 @@ public class SeatBlock extends Block { } @Override - public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand p_225533_5_, BlockRayTraceResult p_225533_6_) { - if (SeatEntity.TAKEN.containsKey(pos)) - return ActionResultType.FAIL; + public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, + Hand p_225533_5_, BlockRayTraceResult p_225533_6_) { + if (player.isSneaking()) + return ActionResultType.PASS; + + List seats = world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos)); + if (!seats.isEmpty()) { + SeatEntity seatEntity = seats.get(0); + List passengers = seatEntity.getPassengers(); + if (!passengers.isEmpty() && passengers.get(0) instanceof PlayerEntity) + return ActionResultType.PASS; + if (!world.isRemote) { + seatEntity.removePassengers(); + player.startRiding(seatEntity); + } + return ActionResultType.SUCCESS; + } if (world.isRemote) return ActionResultType.SUCCESS; - - SeatEntity seat = new SeatEntity(world, pos); - world.addEntity(seat); - player.startRiding(seat); - + sitDown(world, pos, player); return ActionResultType.SUCCESS; } + + public static boolean isSeatOccupied(World world, BlockPos pos) { + return !world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos)) + .isEmpty(); + } + + public static void sitDown(World world, BlockPos pos, Entity entity) { + if (world.isRemote) + return; + SeatEntity seat = new SeatEntity(world, pos); + seat.setPos(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f); + world.addEntity(seat); + entity.startRiding(seat, true); + } + + @Override + public MovementBehaviour getMovementBehaviour() { + return MOVEMENT; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java index 9e5cab53a..18e8cd48f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.actors; import com.simibubi.create.AllEntityTypes; + import net.minecraft.client.renderer.culling.ClippingHelperImpl; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererManager; @@ -8,18 +9,16 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.IPacket; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; import net.minecraftforge.fml.network.NetworkHooks; -import java.util.HashMap; -import java.util.Map; - -public class SeatEntity extends Entity { - - public static final Map TAKEN = new HashMap<>(); +public class SeatEntity extends Entity implements IEntityAdditionalSpawnData { public SeatEntity(EntityType p_i48580_1_, World p_i48580_2_) { super(p_i48580_1_, p_i48580_2_); @@ -27,28 +26,39 @@ public class SeatEntity extends Entity { public SeatEntity(World world, BlockPos pos) { this(AllEntityTypes.SEAT.get(), world); - this.setPos(pos.getX() + 0.5, pos.getY() + 0.30, pos.getZ() + 0.5); noClip = true; - TAKEN.put(pos, this); - } public static EntityType.Builder build(EntityType.Builder builder) { @SuppressWarnings("unchecked") EntityType.Builder entityBuilder = (EntityType.Builder) builder; - return entityBuilder.size(0, 0); + return entityBuilder.size(0.25f, 0.35f); } + @Override + public AxisAlignedBB getBoundingBox() { + return super.getBoundingBox(); + } + + @Override + public void setPos(double x, double y, double z) { + super.setPos(x, y, z); + AxisAlignedBB bb = getBoundingBox(); + Vec3d diff = new Vec3d(x, y, z).subtract(bb.getCenter()); + setBoundingBox(bb.offset(diff)); + } + + @Override + public void setMotion(Vec3d p_213317_1_) {} + @Override public void tick() { - if (world.isRemote) + if (world.isRemote) return; - - BlockPos blockPos = new BlockPos(getX(), getY(), getZ()); - if (isBeingRidden() && world.getBlockState(blockPos).getBlock() instanceof SeatBlock) + boolean blockPresent = world.getBlockState(getPosition()) + .getBlock() instanceof SeatBlock; + if (isBeingRidden() && blockPresent) return; - - TAKEN.remove(blockPos); this.remove(); } @@ -61,7 +71,7 @@ public class SeatEntity extends Entity { protected void removePassenger(Entity entity) { super.removePassenger(entity); Vec3d pos = entity.getPositionVec(); - entity.setPosition(pos.x, pos.y + 0.7, pos.z); + entity.setPosition(pos.x, pos.y + 0.85f, pos.z); } @Override @@ -85,7 +95,8 @@ public class SeatEntity extends Entity { } @Override - public boolean shouldRender(SeatEntity p_225626_1_, ClippingHelperImpl p_225626_2_, double p_225626_3_, double p_225626_5_, double p_225626_7_) { + public boolean shouldRender(SeatEntity p_225626_1_, ClippingHelperImpl p_225626_2_, double p_225626_3_, + double p_225626_5_, double p_225626_7_) { return false; } @@ -94,4 +105,10 @@ public class SeatEntity extends Entity { return null; } } + + @Override + public void writeSpawnData(PacketBuffer buffer) {} + + @Override + public void readSpawnData(PacketBuffer additionalData) {} } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java new file mode 100644 index 000000000..21d1b545c --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java @@ -0,0 +1,9 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; + +public class SeatMovementBehaviour extends MovementBehaviour { + + + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index f89f05aa0..6ad59f9b2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -1,7 +1,29 @@ package com.simibubi.create.content.contraptions.components.structureMovement; +import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole; +import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.stream.Collectors; + +import javax.annotation.Nullable; + +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; + import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.actors.SeatBlock; +import com.simibubi.create.content.contraptions.components.actors.SeatEntity; import com.simibubi.create.content.contraptions.components.saw.SawBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity; @@ -22,9 +44,19 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; -import net.minecraft.block.*; + +import net.minecraft.block.AbstractButtonBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ChestBlock; +import net.minecraft.block.DoorBlock; +import net.minecraft.block.IWaterLoggable; +import net.minecraft.block.PressurePlateBlock; +import net.minecraft.block.SlimeBlock; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderTypeLookup; +import net.minecraft.entity.Entity; import net.minecraft.fluid.Fluids; import net.minecraft.fluid.IFluidState; import net.minecraft.nbt.CompoundNBT; @@ -45,668 +77,733 @@ import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.common.util.Constants.BlockFlags; +import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; -import org.apache.commons.lang3.tuple.MutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.BiPredicate; -import java.util.stream.Collectors; - -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; public abstract class Contraption { - public Map blocks; - public Map storage; - public List> actors; - public CombinedInvWrapper inventory; - public List customRenderTEs; - public Set> superglue; + public Map blocks; + public Map storage; + public List> actors; + public CombinedInvWrapper inventory; + public List customRenderTEs; + public Set> superglue; - public AxisAlignedBB bounds; - public boolean stalled; + public AxisAlignedBB bounds; + public boolean stalled; - protected Set cachedColliders; - protected Direction cachedColliderDirection; - protected BlockPos anchor; - protected List glueToRemove; - List renderOrder; + protected List seats; + protected Map seatMapping; + protected Map initialPassengers; - public Contraption() { - blocks = new HashMap<>(); - storage = new HashMap<>(); - actors = new ArrayList<>(); - superglue = new HashSet<>(); - renderOrder = new ArrayList<>(); - customRenderTEs = new ArrayList<>(); - glueToRemove = new ArrayList<>(); - } + protected Set cachedColliders; + protected Direction cachedColliderDirection; + protected BlockPos anchor; + protected List glueToRemove; + List renderOrder; - protected static boolean isChassis(BlockState state) { - return state.getBlock() instanceof AbstractChassisBlock; - } + public Contraption() { + blocks = new HashMap<>(); + storage = new HashMap<>(); + actors = new ArrayList<>(); + seats = new ArrayList<>(); + seatMapping = new HashMap<>(); + initialPassengers = new HashMap<>(); + superglue = new HashSet<>(); + renderOrder = new ArrayList<>(); + customRenderTEs = new ArrayList<>(); + glueToRemove = new ArrayList<>(); + } - public static CompoundNBT getTileEntityNBT(World world, BlockPos pos) { - TileEntity tileentity = world.getTileEntity(pos); - CompoundNBT compoundnbt = null; - if (tileentity != null) { - compoundnbt = tileentity.write(new CompoundNBT()); - compoundnbt.remove("x"); - compoundnbt.remove("y"); - compoundnbt.remove("z"); - } - return compoundnbt; - } + protected static boolean isChassis(BlockState state) { + return state.getBlock() instanceof AbstractChassisBlock; + } - public static Contraption fromNBT(World world, CompoundNBT nbt) { - String type = nbt.getString("Type"); - Contraption contraption = AllContraptionTypes.fromType(type); - contraption.readNBT(world, nbt); - return contraption; - } + public static CompoundNBT getTileEntityNBT(World world, BlockPos pos) { + TileEntity tileentity = world.getTileEntity(pos); + CompoundNBT compoundnbt = null; + if (tileentity != null) { + compoundnbt = tileentity.write(new CompoundNBT()); + compoundnbt.remove("x"); + compoundnbt.remove("y"); + compoundnbt.remove("z"); + } + return compoundnbt; + } - public static boolean isFrozen() { - return AllConfigs.SERVER.control.freezeContraptions.get(); - } + public static Contraption fromNBT(World world, CompoundNBT nbt) { + String type = nbt.getString("Type"); + Contraption contraption = AllContraptionTypes.fromType(type); + contraption.readNBT(world, nbt); + return contraption; + } - protected static MovementBehaviour getMovement(BlockState state) { - Block block = state.getBlock(); - if (!(block instanceof IPortableBlock)) - return null; - return ((IPortableBlock) block).getMovementBehaviour(); - } + public static boolean isFrozen() { + return AllConfigs.SERVER.control.freezeContraptions.get(); + } - public Set getColliders(World world, Direction movementDirection) { - if (blocks == null) - return null; - if (cachedColliders == null || cachedColliderDirection != movementDirection) { - cachedColliders = new HashSet<>(); - cachedColliderDirection = movementDirection; + protected static MovementBehaviour getMovement(BlockState state) { + Block block = state.getBlock(); + if (!(block instanceof IPortableBlock)) + return null; + return ((IPortableBlock) block).getMovementBehaviour(); + } - for (BlockInfo info : blocks.values()) { - BlockPos offsetPos = info.pos.offset(movementDirection); - if (info.state.getCollisionShape(world, offsetPos) - .isEmpty()) - continue; - if (blocks.containsKey(offsetPos) && !blocks.get(offsetPos).state.getCollisionShape(world, offsetPos) - .isEmpty()) - continue; - cachedColliders.add(info.pos); - } + public Set getColliders(World world, Direction movementDirection) { + if (blocks == null) + return null; + if (cachedColliders == null || cachedColliderDirection != movementDirection) { + cachedColliders = new HashSet<>(); + cachedColliderDirection = movementDirection; - } - return cachedColliders; - } + for (BlockInfo info : blocks.values()) { + BlockPos offsetPos = info.pos.offset(movementDirection); + if (info.state.getCollisionShape(world, offsetPos) + .isEmpty()) + continue; + if (blocks.containsKey(offsetPos) && !blocks.get(offsetPos).state.getCollisionShape(world, offsetPos) + .isEmpty()) + continue; + cachedColliders.add(info.pos); + } - public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { - List frontier = new ArrayList<>(); - Set visited = new HashSet<>(); - anchor = pos; + } + return cachedColliders; + } - if (bounds == null) - bounds = new AxisAlignedBB(BlockPos.ZERO); + public boolean searchMovedStructure(World world, BlockPos pos, @Nullable Direction forcedDirection) { + initialPassengers.clear(); + List frontier = new ArrayList<>(); + Set visited = new HashSet<>(); + anchor = pos; - if (!BlockMovementTraits.isBrittle(world.getBlockState(pos))) - frontier.add(pos); - if (!addToInitialFrontier(world, pos, forcedDirection, frontier)) - return false; - for (int limit = 100000; limit > 0; limit--) { - if (frontier.isEmpty()) - return true; - if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) - return false; - } - return false; - } + if (bounds == null) + bounds = new AxisAlignedBB(BlockPos.ZERO); - public void gatherStoredItems() { - List list = storage.values() - .stream() - .map(MountedStorage::getItemHandler) - .collect(Collectors.toList()); - inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); - } + if (!BlockMovementTraits.isBrittle(world.getBlockState(pos))) + frontier.add(pos); + if (!addToInitialFrontier(world, pos, forcedDirection, frontier)) + return false; + for (int limit = 100000; limit > 0; limit--) { + if (frontier.isEmpty()) + return true; + if (!moveBlock(world, frontier.remove(0), forcedDirection, frontier, visited)) + return false; + } + return false; + } - protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, - List frontier) { - return true; - } + public void gatherStoredItems() { + List list = storage.values() + .stream() + .map(MountedStorage::getItemHandler) + .collect(Collectors.toList()); + inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); + } - protected boolean moveBlock(World world, BlockPos pos, Direction forcedDirection, List frontier, - Set visited) { - visited.add(pos); - frontier.remove(pos); + public void mountPassengers(ContraptionEntity contraptionEntity) { + if (contraptionEntity.world.isRemote) + return; + for (BlockPos seatPos : seats) { + Entity passenger = initialPassengers.get(seatPos); + if (passenger == null) + continue; + int seatIndex = seats.indexOf(seatPos); + if (seatIndex == -1) + continue; + contraptionEntity.addSittingPassenger(passenger, seatIndex); + } + } - if (!world.isBlockPresent(pos)) - return false; - if (isAnchoringBlockAt(pos)) - return true; - if (!BlockMovementTraits.movementNecessary(world, pos)) - return true; - if (!BlockMovementTraits.movementAllowed(world, pos)) - return false; - BlockState state = world.getBlockState(pos); - if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited)) - return false; + protected boolean addToInitialFrontier(World world, BlockPos pos, Direction forcedDirection, + List frontier) { + return true; + } - if (AllBlocks.ADJUSTABLE_CRATE.has(state)) - AdjustableCrateBlock.splitCrate(world, pos); - if (AllBlocks.BELT.has(state)) { - BlockPos nextPos = BeltBlock.nextSegmentPosition(state, pos, true); - BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false); - if (nextPos != null && !visited.contains(nextPos)) - frontier.add(nextPos); - if (prevPos != null && !visited.contains(prevPos)) - frontier.add(prevPos); - } + protected boolean moveBlock(World world, BlockPos pos, Direction forcedDirection, List frontier, + Set visited) { + visited.add(pos); + frontier.remove(pos); - // Pulleys drag their rope and their attached structure - if (state.getBlock() instanceof PulleyBlock) { - int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get(); - BlockPos ropePos = pos; - while (limit-- >= 0) { - ropePos = ropePos.down(); - if (!world.isBlockPresent(ropePos)) - break; - BlockState ropeState = world.getBlockState(ropePos); - Block block = ropeState.getBlock(); - if (!(block instanceof RopeBlock) && !(block instanceof MagnetBlock)) { - if (!visited.contains(ropePos)) - frontier.add(ropePos); - break; - } - add(ropePos, capture(world, ropePos)); - } - } + if (!world.isBlockPresent(pos)) + return false; + if (isAnchoringBlockAt(pos)) + return true; + if (!BlockMovementTraits.movementNecessary(world, pos)) + return true; + if (!BlockMovementTraits.movementAllowed(world, pos)) + return false; + BlockState state = world.getBlockState(pos); + if (isChassis(state) && !moveChassis(world, pos, forcedDirection, frontier, visited)) + return false; - // Pistons drag their attaches poles and extension - if (state.getBlock() instanceof MechanicalPistonBlock) { - int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); - Direction direction = state.get(MechanicalPistonBlock.FACING); - if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - if (isPistonHead(blockState)) - if (!visited.contains(searchPos)) - frontier.add(searchPos); - break; - } - if (limit <= -1) - return false; - } + if (AllBlocks.ADJUSTABLE_CRATE.has(state)) + AdjustableCrateBlock.splitCrate(world, pos); + if (AllBlocks.BELT.has(state)) { + BlockPos nextPos = BeltBlock.nextSegmentPosition(state, pos, true); + BlockPos prevPos = BeltBlock.nextSegmentPosition(state, pos, false); + if (nextPos != null && !visited.contains(nextPos)) + frontier.add(nextPos); + if (prevPos != null && !visited.contains(prevPos)) + frontier.add(prevPos); + } - BlockPos searchPos = pos; - while (limit-- >= 0) { - searchPos = searchPos.offset(direction.getOpposite()); - BlockState blockState = world.getBlockState(searchPos); - if (isExtensionPole(blockState)) { - if (blockState.get(PistonExtensionPoleBlock.FACING) - .getAxis() != direction.getAxis()) - break; - if (!visited.contains(searchPos)) - frontier.add(searchPos); - continue; - } - break; - } + // Seats transfer their passenger to the contraption + if (state.getBlock() instanceof SeatBlock) { + BlockPos local = toLocalPos(pos); + seats.add(local); + List seatsEntities = world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos)); + if (!seatsEntities.isEmpty()) { + SeatEntity seat = seatsEntities.get(0); + List passengers = seat.getPassengers(); + if (!passengers.isEmpty()) + initialPassengers.put(local, passengers.get(0)); + } + } - if (limit <= -1) - return false; - } + // Pulleys drag their rope and their attached structure + if (state.getBlock() instanceof PulleyBlock) { + int limit = AllConfigs.SERVER.kinetics.maxRopeLength.get(); + BlockPos ropePos = pos; + while (limit-- >= 0) { + ropePos = ropePos.down(); + if (!world.isBlockPresent(ropePos)) + break; + BlockState ropeState = world.getBlockState(ropePos); + Block block = ropeState.getBlock(); + if (!(block instanceof RopeBlock) && !(block instanceof MagnetBlock)) { + if (!visited.contains(ropePos)) + frontier.add(ropePos); + break; + } + add(ropePos, capture(world, ropePos)); + } + } - // Doors try to stay whole - if (state.getBlock() instanceof DoorBlock) { - BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1); - if (!visited.contains(otherPartPos)) - frontier.add(otherPartPos); - } + // Pistons drag their attaches poles and extension + if (state.getBlock() instanceof MechanicalPistonBlock) { + int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get(); + Direction direction = state.get(MechanicalPistonBlock.FACING); + if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { + BlockPos searchPos = pos; + while (limit-- >= 0) { + searchPos = searchPos.offset(direction); + BlockState blockState = world.getBlockState(searchPos); + if (isExtensionPole(blockState)) { + if (blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() != direction.getAxis()) + break; + if (!visited.contains(searchPos)) + frontier.add(searchPos); + continue; + } + if (isPistonHead(blockState)) + if (!visited.contains(searchPos)) + frontier.add(searchPos); + break; + } + if (limit <= -1) + return false; + } - Map superglue = SuperGlueHandler.gatherGlue(world, pos); + BlockPos searchPos = pos; + while (limit-- >= 0) { + searchPos = searchPos.offset(direction.getOpposite()); + BlockState blockState = world.getBlockState(searchPos); + if (isExtensionPole(blockState)) { + if (blockState.get(PistonExtensionPoleBlock.FACING) + .getAxis() != direction.getAxis()) + break; + if (!visited.contains(searchPos)) + frontier.add(searchPos); + continue; + } + break; + } - // Slime blocks drag adjacent blocks if possible - boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock; - for (Direction offset : Direction.values()) { - BlockPos offsetPos = pos.offset(offset); - BlockState blockState = world.getBlockState(offsetPos); - if (isAnchoringBlockAt(offsetPos)) - continue; - if (!BlockMovementTraits.movementAllowed(world, offsetPos)) { - if (offset == forcedDirection && isSlimeBlock) - return false; - continue; - } + if (limit <= -1) + return false; + } - boolean wasVisited = visited.contains(offsetPos); - boolean faceHasGlue = superglue.containsKey(offset); - boolean blockAttachedTowardsFace = - BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()); - boolean brittle = BlockMovementTraits.isBrittle(blockState); + // Doors try to stay whole + if (state.getBlock() instanceof DoorBlock) { + BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1); + if (!visited.contains(otherPartPos)) + frontier.add(otherPartPos); + } - if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) - frontier.add(offsetPos); + Map superglue = SuperGlueHandler.gatherGlue(world, pos); - if (faceHasGlue) - addGlue(superglue.get(offset)); - } + // Slime blocks drag adjacent blocks if possible + boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock; + for (Direction offset : Direction.values()) { + BlockPos offsetPos = pos.offset(offset); + BlockState blockState = world.getBlockState(offsetPos); + if (isAnchoringBlockAt(offsetPos)) + continue; + if (!BlockMovementTraits.movementAllowed(world, offsetPos)) { + if (offset == forcedDirection && isSlimeBlock) + return false; + continue; + } - add(pos, capture(world, pos)); + boolean wasVisited = visited.contains(offsetPos); + boolean faceHasGlue = superglue.containsKey(offset); + boolean blockAttachedTowardsFace = + BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()); + boolean brittle = BlockMovementTraits.isBrittle(blockState); + + if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) + frontier.add(offsetPos); + + if (faceHasGlue) + addGlue(superglue.get(offset)); + } + + add(pos, capture(world, pos)); return blocks.size() <= AllConfigs.SERVER.kinetics.maxBlocksMoved.get(); } - protected boolean isAnchoringBlockAt(BlockPos pos) { - return pos.equals(anchor); - } + protected boolean isAnchoringBlockAt(BlockPos pos) { + return pos.equals(anchor); + } - private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List frontier, - Set visited) { - TileEntity te = world.getTileEntity(pos); - if (!(te instanceof ChassisTileEntity)) - return false; - ChassisTileEntity chassis = (ChassisTileEntity) te; - chassis.addAttachedChasses(frontier, visited); - List includedBlockPositions = chassis.getIncludedBlockPositions(movementDirection, false); - if (includedBlockPositions == null) - return false; - for (BlockPos blockPos : includedBlockPositions) - if (!visited.contains(blockPos)) - frontier.add(blockPos); - return true; - } + private boolean moveChassis(World world, BlockPos pos, Direction movementDirection, List frontier, + Set visited) { + TileEntity te = world.getTileEntity(pos); + if (!(te instanceof ChassisTileEntity)) + return false; + ChassisTileEntity chassis = (ChassisTileEntity) te; + chassis.addAttachedChasses(frontier, visited); + List includedBlockPositions = chassis.getIncludedBlockPositions(movementDirection, false); + if (includedBlockPositions == null) + return false; + for (BlockPos blockPos : includedBlockPositions) + if (!visited.contains(blockPos)) + frontier.add(blockPos); + return true; + } - protected Pair capture(World world, BlockPos pos) { - BlockState blockstate = world.getBlockState(pos); - if (AllBlocks.MECHANICAL_SAW.has(blockstate)) - blockstate = blockstate.with(SawBlock.RUNNING, true); - if (blockstate.getBlock() instanceof ChestBlock) - blockstate = blockstate.with(ChestBlock.TYPE, ChestType.SINGLE); - if (AllBlocks.ADJUSTABLE_CRATE.has(blockstate)) - blockstate = blockstate.with(AdjustableCrateBlock.DOUBLE, false); - if (AllBlocks.REDSTONE_CONTACT.has(blockstate)) - blockstate = blockstate.with(RedstoneContactBlock.POWERED, true); - if (blockstate.getBlock() instanceof AbstractButtonBlock) { - blockstate = blockstate.with(AbstractButtonBlock.POWERED, false); - world.getPendingBlockTicks() - .scheduleTick(pos, blockstate.getBlock(), -1); - } - if (blockstate.getBlock() instanceof PressurePlateBlock) { - blockstate = blockstate.with(PressurePlateBlock.POWERED, false); - world.getPendingBlockTicks() - .scheduleTick(pos, blockstate.getBlock(), -1); - } - CompoundNBT compoundnbt = getTileEntityNBT(world, pos); - TileEntity tileentity = world.getTileEntity(pos); - return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity); - } + protected Pair capture(World world, BlockPos pos) { + BlockState blockstate = world.getBlockState(pos); + if (AllBlocks.MECHANICAL_SAW.has(blockstate)) + blockstate = blockstate.with(SawBlock.RUNNING, true); + if (blockstate.getBlock() instanceof ChestBlock) + blockstate = blockstate.with(ChestBlock.TYPE, ChestType.SINGLE); + if (AllBlocks.ADJUSTABLE_CRATE.has(blockstate)) + blockstate = blockstate.with(AdjustableCrateBlock.DOUBLE, false); + if (AllBlocks.REDSTONE_CONTACT.has(blockstate)) + blockstate = blockstate.with(RedstoneContactBlock.POWERED, true); + if (blockstate.getBlock() instanceof AbstractButtonBlock) { + blockstate = blockstate.with(AbstractButtonBlock.POWERED, false); + world.getPendingBlockTicks() + .scheduleTick(pos, blockstate.getBlock(), -1); + } + if (blockstate.getBlock() instanceof PressurePlateBlock) { + blockstate = blockstate.with(PressurePlateBlock.POWERED, false); + world.getPendingBlockTicks() + .scheduleTick(pos, blockstate.getBlock(), -1); + } + CompoundNBT compoundnbt = getTileEntityNBT(world, pos); + TileEntity tileentity = world.getTileEntity(pos); + return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity); + } - public void addGlue(SuperGlueEntity entity) { - BlockPos pos = entity.getHangingPosition(); - Direction direction = entity.getFacingDirection(); - BlockPos localPos = pos.subtract(anchor); - this.superglue.add(Pair.of(localPos, direction)); - glueToRemove.add(entity); - } + public void addGlue(SuperGlueEntity entity) { + BlockPos pos = entity.getHangingPosition(); + Direction direction = entity.getFacingDirection(); + this.superglue.add(Pair.of(toLocalPos(pos), direction)); + glueToRemove.add(entity); + } - public void add(BlockPos pos, Pair pair) { - BlockInfo captured = pair.getKey(); - BlockPos localPos = pos.subtract(anchor); - BlockInfo blockInfo = new BlockInfo(localPos, captured.state, captured.nbt); + public BlockPos toLocalPos(BlockPos globalPos) { + return globalPos.subtract(anchor); + } - if (blocks.put(localPos, blockInfo) != null) - return; - bounds = bounds.union(new AxisAlignedBB(localPos)); + public void add(BlockPos pos, Pair pair) { + BlockInfo captured = pair.getKey(); + BlockPos localPos = pos.subtract(anchor); + BlockInfo blockInfo = new BlockInfo(localPos, captured.state, captured.nbt); - TileEntity te = pair.getValue(); - if (te != null && MountedStorage.canUseAsStorage(te)) - storage.put(localPos, new MountedStorage(te)); - if (captured.state.getBlock() instanceof IPortableBlock) - getActors().add(MutablePair.of(blockInfo, null)); - } + if (blocks.put(localPos, blockInfo) != null) + return; + bounds = bounds.union(new AxisAlignedBB(localPos)); - public void readNBT(World world, CompoundNBT nbt) { - blocks.clear(); - renderOrder.clear(); - customRenderTEs.clear(); + TileEntity te = pair.getValue(); + if (te != null && MountedStorage.canUseAsStorage(te)) + storage.put(localPos, new MountedStorage(te)); + if (captured.state.getBlock() instanceof IPortableBlock) + actors.add(MutablePair.of(blockInfo, null)); + } - nbt.getList("Blocks", 10) - .forEach(c -> { - CompoundNBT comp = (CompoundNBT) c; - BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")), - NBTUtil.readBlockState(comp.getCompound("Block")), - comp.contains("Data") ? comp.getCompound("Data") : null); - blocks.put(info.pos, info); + public void readNBT(World world, CompoundNBT nbt) { + blocks.clear(); + renderOrder.clear(); + customRenderTEs.clear(); - if (world.isRemote) { - Block block = info.state.getBlock(); - if (RenderTypeLookup.canRenderInLayer(info.state, RenderType.getTranslucent())) - renderOrder.add(info.pos); - else - renderOrder.add(0, info.pos); - CompoundNBT tag = info.nbt; - if (tag == null || block instanceof IPortableBlock) - return; + nbt.getList("Blocks", 10) + .forEach(c -> { + CompoundNBT comp = (CompoundNBT) c; + BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")), + NBTUtil.readBlockState(comp.getCompound("Block")), + comp.contains("Data") ? comp.getCompound("Data") : null); + blocks.put(info.pos, info); - tag.putInt("x", info.pos.getX()); - tag.putInt("y", info.pos.getY()); - tag.putInt("z", info.pos.getZ()); + if (world.isRemote) { + Block block = info.state.getBlock(); + if (RenderTypeLookup.canRenderInLayer(info.state, RenderType.getTranslucent())) + renderOrder.add(info.pos); + else + renderOrder.add(0, info.pos); + CompoundNBT tag = info.nbt; + if (tag == null || block instanceof IPortableBlock) + return; - TileEntity te = TileEntity.create(tag); - te.setLocation(new WrappedWorld(world) { + tag.putInt("x", info.pos.getX()); + tag.putInt("y", info.pos.getY()); + tag.putInt("z", info.pos.getZ()); - @Override - public BlockState getBlockState(BlockPos pos) { - if (!pos.equals(te.getPos())) - return Blocks.AIR.getDefaultState(); - return info.state; - } + TileEntity te = TileEntity.create(tag); + te.setLocation(new WrappedWorld(world) { - }, te.getPos()); - if (te instanceof KineticTileEntity) - ((KineticTileEntity) te).setSpeed(0); - te.getBlockState(); - customRenderTEs.add(te); - } - }); + @Override + public BlockState getBlockState(BlockPos pos) { + if (!pos.equals(te.getPos())) + return Blocks.AIR.getDefaultState(); + return info.state; + } - actors.clear(); - nbt.getList("Actors", 10) - .forEach(c -> { - CompoundNBT comp = (CompoundNBT) c; - BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos"))); - MovementContext context = MovementContext.readNBT(world, info, comp); - context.contraption = this; - getActors().add(MutablePair.of(info, context)); - }); + }, te.getPos()); + if (te instanceof KineticTileEntity) + ((KineticTileEntity) te).setSpeed(0); + te.getBlockState(); + customRenderTEs.add(te); + } + }); - superglue.clear(); - nbt.getList("Superglue", 10) - .forEach(c -> { - CompoundNBT comp = (CompoundNBT) c; - superglue.add(Pair.of(NBTUtil.readBlockPos(comp.getCompound("Pos")), - Direction.byIndex(comp.getByte("Direction")))); - }); + actors.clear(); + nbt.getList("Actors", 10) + .forEach(c -> { + CompoundNBT comp = (CompoundNBT) c; + BlockInfo info = blocks.get(NBTUtil.readBlockPos(comp.getCompound("Pos"))); + MovementContext context = MovementContext.readNBT(world, info, comp); + context.contraption = this; + getActors().add(MutablePair.of(info, context)); + }); - storage.clear(); - nbt.getList("Storage", 10) - .forEach(c -> { - CompoundNBT comp = (CompoundNBT) c; - storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), - new MountedStorage(comp.getCompound("Data"))); - }); - List list = storage.values() - .stream() - .map(MountedStorage::getItemHandler) - .collect(Collectors.toList()); - inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); + superglue.clear(); + nbt.getList("Superglue", 10) + .forEach(c -> { + CompoundNBT comp = (CompoundNBT) c; + superglue.add(Pair.of(NBTUtil.readBlockPos(comp.getCompound("Pos")), + Direction.byIndex(comp.getByte("Direction")))); + }); - if (nbt.contains("BoundsFront")) - bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5)); + storage.clear(); + nbt.getList("Storage", 10) + .forEach(c -> { + CompoundNBT comp = (CompoundNBT) c; + storage.put(NBTUtil.readBlockPos(comp.getCompound("Pos")), + new MountedStorage(comp.getCompound("Data"))); + }); + List list = storage.values() + .stream() + .map(MountedStorage::getItemHandler) + .collect(Collectors.toList()); + inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); - stalled = nbt.getBoolean("Stalled"); - anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor")); - } + if (nbt.contains("BoundsFront")) + bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5)); - public CompoundNBT writeNBT() { - CompoundNBT nbt = new CompoundNBT(); - nbt.putString("Type", getType().id); - ListNBT blocksNBT = new ListNBT(); - for (BlockInfo block : this.blocks.values()) { - CompoundNBT c = new CompoundNBT(); - c.put("Block", NBTUtil.writeBlockState(block.state)); - c.put("Pos", NBTUtil.writeBlockPos(block.pos)); - if (block.nbt != null) - c.put("Data", block.nbt); - blocksNBT.add(c); - } + seats.clear(); + NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), c -> seats.add(NBTUtil.readBlockPos(c))); + seatMapping.clear(); + NBTHelper.iterateCompoundList(nbt.getList("Passengers", NBT.TAG_COMPOUND), + c -> seatMapping.put(NBTUtil.readUniqueId(c.getCompound("Id")), c.getInt("Seat"))); - ListNBT actorsNBT = new ListNBT(); - for (MutablePair actor : getActors()) { - CompoundNBT compound = new CompoundNBT(); - compound.put("Pos", NBTUtil.writeBlockPos(actor.left.pos)); - getMovement(actor.left.state).writeExtraData(actor.right); - actor.right.writeToNBT(compound); - actorsNBT.add(compound); - } + stalled = nbt.getBoolean("Stalled"); + anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor")); + } - ListNBT superglueNBT = new ListNBT(); - for (Pair glueEntry : superglue) { - CompoundNBT c = new CompoundNBT(); - c.put("Pos", NBTUtil.writeBlockPos(glueEntry.getKey())); - c.putByte("Direction", (byte) glueEntry.getValue() - .getIndex()); - superglueNBT.add(c); - } + public CompoundNBT writeNBT() { + CompoundNBT nbt = new CompoundNBT(); + nbt.putString("Type", getType().id); + ListNBT blocksNBT = new ListNBT(); + for (BlockInfo block : this.blocks.values()) { + CompoundNBT c = new CompoundNBT(); + c.put("Block", NBTUtil.writeBlockState(block.state)); + c.put("Pos", NBTUtil.writeBlockPos(block.pos)); + if (block.nbt != null) + c.put("Data", block.nbt); + blocksNBT.add(c); + } - ListNBT storageNBT = new ListNBT(); - for (BlockPos pos : storage.keySet()) { - CompoundNBT c = new CompoundNBT(); - MountedStorage mountedStorage = storage.get(pos); - if (!mountedStorage.isWorking()) - continue; - c.put("Pos", NBTUtil.writeBlockPos(pos)); - c.put("Data", mountedStorage.serialize()); - storageNBT.add(c); - } + ListNBT actorsNBT = new ListNBT(); + for (MutablePair actor : getActors()) { + CompoundNBT compound = new CompoundNBT(); + compound.put("Pos", NBTUtil.writeBlockPos(actor.left.pos)); + getMovement(actor.left.state).writeExtraData(actor.right); + actor.right.writeToNBT(compound); + actorsNBT.add(compound); + } - nbt.put("Blocks", blocksNBT); - nbt.put("Actors", actorsNBT); - nbt.put("Superglue", superglueNBT); - nbt.put("Storage", storageNBT); - nbt.put("Anchor", NBTUtil.writeBlockPos(anchor)); - nbt.putBoolean("Stalled", stalled); + ListNBT superglueNBT = new ListNBT(); + for (Pair glueEntry : superglue) { + CompoundNBT c = new CompoundNBT(); + c.put("Pos", NBTUtil.writeBlockPos(glueEntry.getKey())); + c.putByte("Direction", (byte) glueEntry.getValue() + .getIndex()); + superglueNBT.add(c); + } - if (bounds != null) { - ListNBT bb = NBTHelper.writeAABB(bounds); - nbt.put("BoundsFront", bb); - } + ListNBT storageNBT = new ListNBT(); + for (BlockPos pos : storage.keySet()) { + CompoundNBT c = new CompoundNBT(); + MountedStorage mountedStorage = storage.get(pos); + if (!mountedStorage.isWorking()) + continue; + c.put("Pos", NBTUtil.writeBlockPos(pos)); + c.put("Data", mountedStorage.serialize()); + storageNBT.add(c); + } - return nbt; - } + nbt.put("Seats", NBTHelper.writeCompoundList(seats, NBTUtil::writeBlockPos)); + nbt.put("Passengers", NBTHelper.writeCompoundList(seatMapping.entrySet(), e -> { + CompoundNBT tag = new CompoundNBT(); + tag.put("Id", NBTUtil.writeUniqueId(e.getKey())); + tag.putInt("Seat", e.getValue()); + return tag; + })); - public void removeBlocksFromWorld(IWorld world, BlockPos offset) { - removeBlocksFromWorld(world, offset, (pos, state) -> false); - } + nbt.put("Blocks", blocksNBT); + nbt.put("Actors", actorsNBT); + nbt.put("Superglue", superglueNBT); + nbt.put("Storage", storageNBT); + nbt.put("Anchor", NBTUtil.writeBlockPos(anchor)); + nbt.putBoolean("Stalled", stalled); - public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate customRemoval) { - storage.values() - .forEach(MountedStorage::empty); - glueToRemove.forEach(SuperGlueEntity::remove); + if (bounds != null) { + ListNBT bb = NBTHelper.writeAABB(bounds); + nbt.put("BoundsFront", bb); + } - for (boolean brittles : Iterate.trueAndFalse) { - for (Iterator iterator = blocks.values() - .iterator(); iterator.hasNext(); ) { - BlockInfo block = iterator.next(); - if (brittles != BlockMovementTraits.isBrittle(block.state)) - continue; + return nbt; + } - BlockPos add = block.pos.add(anchor) - .add(offset); - if (customRemoval.test(add, block.state)) - continue; - BlockState oldState = world.getBlockState(add); - Block blockIn = oldState.getBlock(); - if (block.state.getBlock() != blockIn) - iterator.remove(); - world.getWorld() - .removeTileEntity(add); - int flags = 67; - if (blockIn instanceof DoorBlock) - flags = flags | 32 | 16; - if (blockIn instanceof IWaterLoggable && oldState.has(BlockStateProperties.WATERLOGGED) && oldState.get(BlockStateProperties.WATERLOGGED).booleanValue()) { - world.setBlockState(add, Blocks.WATER.getDefaultState(), flags); - continue; - } - world.setBlockState(add, Blocks.AIR.getDefaultState(), flags); - } - } - } + protected boolean customBlockPlacement(IWorld world, BlockPos pos, BlockState state) { + return false; + } - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { - addBlocksToWorld(world, offset, rotation, (pos, state) -> false); - } + protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) { + return false; + } - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation, - BiPredicate customPlacement) { - stop(world); - StructureTransform transform = new StructureTransform(offset, rotation); + public void removeBlocksFromWorld(IWorld world, BlockPos offset) { + storage.values() + .forEach(MountedStorage::empty); + glueToRemove.forEach(SuperGlueEntity::remove); - for (boolean nonBrittles : Iterate.trueAndFalse) { - for (BlockInfo block : blocks.values()) { - if (nonBrittles == BlockMovementTraits.isBrittle(block.state)) - continue; + for (boolean brittles : Iterate.trueAndFalse) { + for (Iterator iterator = blocks.values() + .iterator(); iterator.hasNext();) { + BlockInfo block = iterator.next(); + if (brittles != BlockMovementTraits.isBrittle(block.state)) + continue; - BlockPos targetPos = transform.apply(block.pos); + BlockPos add = block.pos.add(anchor) + .add(offset); + if (customBlockRemoval(world, add, block.state)) + continue; + BlockState oldState = world.getBlockState(add); + Block blockIn = oldState.getBlock(); + if (block.state.getBlock() != blockIn) + iterator.remove(); + world.getWorld() + .removeTileEntity(add); + int flags = 67; + if (blockIn instanceof DoorBlock) + flags = flags | 32 | 16; + if (blockIn instanceof IWaterLoggable && oldState.has(BlockStateProperties.WATERLOGGED) + && oldState.get(BlockStateProperties.WATERLOGGED) + .booleanValue()) { + world.setBlockState(add, Blocks.WATER.getDefaultState(), flags); + continue; + } + world.setBlockState(add, Blocks.AIR.getDefaultState(), flags); + } + } + } - BlockState state = transform.apply(block.state); + public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation, List seatedEntities) { + stop(world); + StructureTransform transform = new StructureTransform(offset, rotation); - if (customPlacement.test(targetPos, state)) - continue; + for (boolean nonBrittles : Iterate.trueAndFalse) { + for (BlockInfo block : blocks.values()) { + if (nonBrittles == BlockMovementTraits.isBrittle(block.state)) + continue; - if (nonBrittles) - for (Direction face : Direction.values()) - state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, - targetPos, targetPos.offset(face)); + BlockPos targetPos = transform.apply(block.pos); + BlockState state = transform.apply(block.state); - if (AllBlocks.MECHANICAL_SAW.has(state)) - state = state.with(SawBlock.RUNNING, false); + if (customBlockPlacement(world, targetPos, state)) + continue; - BlockState blockState = world.getBlockState(targetPos); - if (blockState.getBlockHardness(world, targetPos) == -1 || (state.getCollisionShape(world, targetPos) - .isEmpty() - && !blockState.getCollisionShape(world, targetPos) - .isEmpty())) { - if (targetPos.getY() == 0) - targetPos = targetPos.up(); - world.playEvent(2001, targetPos, Block.getStateId(state)); - Block.spawnDrops(state, world, targetPos, null); - continue; - } - if (state.getBlock() instanceof IWaterLoggable && state.has(BlockStateProperties.WATERLOGGED)) { - IFluidState ifluidstate = world.getFluidState(targetPos); - state = state.with(BlockStateProperties.WATERLOGGED, Boolean.valueOf(ifluidstate.getFluid() == Fluids.WATER)); - } + if (nonBrittles) + for (Direction face : Direction.values()) + state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, + targetPos, targetPos.offset(face)); - world.destroyBlock(targetPos, true); - world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING); + if (AllBlocks.MECHANICAL_SAW.has(state)) + state = state.with(SawBlock.RUNNING, false); - boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal(); - verticalRotation = verticalRotation && transform.rotation != Rotation.NONE; - if (verticalRotation) { - if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock) - world.destroyBlock(targetPos, true); - } + BlockState blockState = world.getBlockState(targetPos); + if (blockState.getBlockHardness(world, targetPos) == -1 || (state.getCollisionShape(world, targetPos) + .isEmpty() + && !blockState.getCollisionShape(world, targetPos) + .isEmpty())) { + if (targetPos.getY() == 0) + targetPos = targetPos.up(); + world.playEvent(2001, targetPos, Block.getStateId(state)); + Block.spawnDrops(state, world, targetPos, null); + continue; + } + if (state.getBlock() instanceof IWaterLoggable && state.has(BlockStateProperties.WATERLOGGED)) { + IFluidState ifluidstate = world.getFluidState(targetPos); + state = state.with(BlockStateProperties.WATERLOGGED, + Boolean.valueOf(ifluidstate.getFluid() == Fluids.WATER)); + } - TileEntity tileEntity = world.getTileEntity(targetPos); - CompoundNBT tag = block.nbt; - if (tileEntity != null && tag != null) { - tag.putInt("x", targetPos.getX()); - tag.putInt("y", targetPos.getY()); - tag.putInt("z", targetPos.getZ()); + world.destroyBlock(targetPos, true); + world.setBlockState(targetPos, state, 3 | BlockFlags.IS_MOVING); - if (verticalRotation && tileEntity instanceof PulleyTileEntity) { - tag.remove("Offset"); - tag.remove("InitialOffset"); - } + boolean verticalRotation = transform.rotationAxis == null || transform.rotationAxis.isHorizontal(); + verticalRotation = verticalRotation && transform.rotation != Rotation.NONE; + if (verticalRotation) { + if (state.getBlock() instanceof RopeBlock || state.getBlock() instanceof MagnetBlock) + world.destroyBlock(targetPos, true); + } - tileEntity.read(tag); + TileEntity tileEntity = world.getTileEntity(targetPos); + CompoundNBT tag = block.nbt; + if (tileEntity != null && tag != null) { + tag.putInt("x", targetPos.getX()); + tag.putInt("y", targetPos.getY()); + tag.putInt("z", targetPos.getZ()); - if (storage.containsKey(block.pos)) { - MountedStorage mountedStorage = storage.get(block.pos); - if (mountedStorage.isWorking()) - mountedStorage.fill(tileEntity); - } - } - } - } + if (verticalRotation && tileEntity instanceof PulleyTileEntity) { + tag.remove("Offset"); + tag.remove("InitialOffset"); + } - for (Pair pair : superglue) { - BlockPos targetPos = transform.apply(pair.getKey()); - Direction targetFacing = transform.transformFacing(pair.getValue()); + tileEntity.read(tag); - SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing); - if (entity.onValidSurface()) { - if (!world.isRemote) - world.addEntity(entity); - } + if (storage.containsKey(block.pos)) { + MountedStorage mountedStorage = storage.get(block.pos); + if (mountedStorage.isWorking()) + mountedStorage.fill(tileEntity); + } + } + } + } - } + for (Pair pair : superglue) { + BlockPos targetPos = transform.apply(pair.getKey()); + Direction targetFacing = transform.transformFacing(pair.getValue()); - } + SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing); + if (entity.onValidSurface()) { + if (!world.isRemote) + world.addEntity(entity); + } + } - public void initActors(World world) { - for (MutablePair pair : actors) { - MovementContext context = new MovementContext(world, pair.left); - context.contraption = this; - getMovement(pair.left.state).startMoving(context); - pair.setRight(context); - } - } + for (Entity seatedEntity : seatedEntities) { + if (seatMapping.isEmpty()) + continue; + Integer seatIndex = seatMapping.get(seatedEntity.getUniqueID()); + BlockPos seatPos = seats.get(seatIndex); + seatPos = transform.apply(seatPos); + if (!(world.getBlockState(seatPos) + .getBlock() instanceof SeatBlock)) + continue; + if (SeatBlock.isSeatOccupied(world, seatPos)) + continue; + SeatBlock.sitDown(world, seatPos, seatedEntity); + } - public AxisAlignedBB getBoundingBox() { - return bounds; - } + } - public List> getActors() { - return actors; - } + public void initActors(World world) { + for (MutablePair pair : actors) { + MovementContext context = new MovementContext(world, pair.left); + context.contraption = this; + getMovement(pair.left.state).startMoving(context); + pair.setRight(context); + } + } - public BlockPos getAnchor() { - return anchor; - } + public AxisAlignedBB getBoundingBox() { + return bounds; + } - public void stop(World world) { - foreachActor(world, (behaviour, ctx) -> { - behaviour.stopMoving(ctx); - ctx.position = null; - ctx.motion = Vec3d.ZERO; - ctx.relativeMotion = Vec3d.ZERO; - ctx.rotation = Vec3d.ZERO; - }); - } + public List> getActors() { + return actors; + } - public void foreachActor(World world, BiConsumer callBack) { - for (MutablePair pair : actors) - callBack.accept(getMovement(pair.getLeft().state), pair.getRight()); - } + public BlockPos getAnchor() { + return anchor; + } - public void expandBoundsAroundAxis(Axis axis) { - AxisAlignedBB bb = bounds; - double maxXDiff = Math.max(bb.maxX - 1, -bb.minX); - double maxYDiff = Math.max(bb.maxY - 1, -bb.minY); - double maxZDiff = Math.max(bb.maxZ - 1, -bb.minZ); - double maxDiff = 0; + public void stop(World world) { + foreachActor(world, (behaviour, ctx) -> { + behaviour.stopMoving(ctx); + ctx.position = null; + ctx.motion = Vec3d.ZERO; + ctx.relativeMotion = Vec3d.ZERO; + ctx.rotation = Vec3d.ZERO; + }); + } - if (axis == Axis.X) - maxDiff = Math.max(maxZDiff, maxYDiff); - if (axis == Axis.Y) - maxDiff = Math.max(maxZDiff, maxXDiff); - if (axis == Axis.Z) - maxDiff = Math.max(maxXDiff, maxYDiff); + public void foreachActor(World world, BiConsumer callBack) { + for (MutablePair pair : actors) + callBack.accept(getMovement(pair.getLeft().state), pair.getRight()); + } - Vec3d vec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis) - .getDirectionVec()); - Vec3d planeByNormal = VecHelper.planeByNormal(vec); - Vec3d min = vec.mul(bb.minX, bb.minY, bb.minZ) - .add(planeByNormal.scale(-maxDiff)); - Vec3d max = vec.mul(bb.maxX, bb.maxY, bb.maxZ) - .add(planeByNormal.scale(maxDiff + 1)); - bounds = new AxisAlignedBB(min, max); - } + public void expandBoundsAroundAxis(Axis axis) { + AxisAlignedBB bb = bounds; + double maxXDiff = Math.max(bb.maxX - 1, -bb.minX); + double maxYDiff = Math.max(bb.maxY - 1, -bb.minY); + double maxZDiff = Math.max(bb.maxZ - 1, -bb.minZ); + double maxDiff = 0; - protected abstract AllContraptionTypes getType(); + if (axis == Axis.X) + maxDiff = Math.max(maxZDiff, maxYDiff); + if (axis == Axis.Y) + maxDiff = Math.max(maxZDiff, maxXDiff); + if (axis == Axis.Z) + maxDiff = Math.max(maxXDiff, maxYDiff); + + Vec3d vec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis) + .getDirectionVec()); + Vec3d planeByNormal = VecHelper.planeByNormal(vec); + Vec3d min = vec.mul(bb.minX, bb.minY, bb.minZ) + .add(planeByNormal.scale(-maxDiff)); + Vec3d max = vec.mul(bb.maxX, bb.maxY, bb.maxZ) + .add(planeByNormal.scale(maxDiff + 1)); + bounds = new AxisAlignedBB(min, max); + } + + public BlockPos getSeat(UUID entityId) { + if (!seatMapping.containsKey(entityId)) + return null; + int seatIndex = seatMapping.get(entityId); + if (seatIndex >= seats.size()) + return null; + return seats.get(seatIndex); + } + + protected abstract AllContraptionTypes getType(); } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 6de3581fa..4c3770901 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -24,6 +24,7 @@ import com.simibubi.create.foundation.collision.ContinuousOBBCollider.Continuous import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.OrientedBB; import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; @@ -32,9 +33,11 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.MoverType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; @@ -51,10 +54,12 @@ import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.WorldTickEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @@ -66,7 +71,7 @@ public class ContraptionCollider { new DamageSource("create.contraption_suffocate").setDamageBypassesArmor(); public static boolean wasClientPlayerGrounded; public static Cache>> activeContraptions = CacheBuilder.newBuilder() - .expireAfterAccess(40, SECONDS) + .expireAfterAccess(400, SECONDS) .build(); @SubscribeEvent @@ -102,6 +107,22 @@ public class ContraptionCollider { runCollisions(world); } + @SubscribeEvent + public static void entitiesWhoJustDismountedGetSentToTheRightLocation(LivingUpdateEvent event) { + LivingEntity entityLiving = event.getEntityLiving(); + if (entityLiving == null) + return; + if (entityLiving.world.isRemote) + return; + CompoundNBT data = entityLiving.getPersistentData(); + if (!data.contains("ContraptionDismountLocation")) + return; + Vec3d position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", NBT.TAG_DOUBLE)); + if (entityLiving.getRidingEntity() == null) + entityLiving.setPositionAndUpdate(position.x, position.y, position.z); + data.remove("ContraptionDismountLocation"); + } + private static void runCollisions(World world) { List> list = activeContraptions.getIfPresent(world); if (list == null) @@ -131,9 +152,9 @@ public class ContraptionCollider { return; Vec3d centerOfBlock = VecHelper.getCenterOf(BlockPos.ZERO); - double conRotX = contraptionRotation.z; + double conRotX = contraptionRotation.x; double conRotY = contraptionRotation.y; - double conRotZ = contraptionRotation.x; + double conRotZ = contraptionRotation.z; Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec()); Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0); @@ -180,6 +201,7 @@ public class ContraptionCollider { // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); obb.setRotation(rotation); + motion = motion.subtract(conMotion); motion = rotation.transform(motion); // Vec3d visualizerOrigin = new Vec3d(10, 64, 0); @@ -198,41 +220,48 @@ public class ContraptionCollider { .forEach(shape -> shape.toBoundingBoxList() .forEach(bbs::add)); - for (AxisAlignedBB bb : bbs) { - Vec3d currentResponse = collisionResponse.getValue(); - obb.setCenter(obbCenter.add(currentResponse)); - ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue()); -// OutlineParams params = CreateClient.outliner.showAABB(bb, bb.offset(visualizerOrigin)) -// .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED); -// params.colored(0xffffff); + boolean doHorizontalPass = conRotX == 0 && conRotZ == 0; + for (boolean horizontalPass : Iterate.trueAndFalse) { - if (intersect == null) - continue; - if (surfaceCollision.isFalse()) - surfaceCollision.setValue(intersect.isSurfaceCollision()); + for (AxisAlignedBB bb : bbs) { + Vec3d currentResponse = collisionResponse.getValue(); + obb.setCenter(obbCenter.add(currentResponse)); + ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue()); - double timeOfImpact = intersect.getTimeOfImpact(); - if (timeOfImpact > 0 && timeOfImpact < 1) { - futureCollision.setTrue(); -// Vec3d prev = allowedMotion.getValue(); - allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue())); -// Debug.debugChat("Allowed Motion FROM " + prev.toString()); -// Debug.debugChat("Allowed Motion TO " + allowedMotion.getValue() -// .toString()); -// params.colored(0x4499ff); - continue; - } - Vec3d separation = intersect.asSeparationVec(entity.stepHeight); - if (separation != null && !separation.equals(Vec3d.ZERO)) { - collisionResponse.setValue(currentResponse.add(separation)); -// Debug.debugChat("Collision " + currentResponse.add(separation) -// .toString()); -// params.colored(0xff9944); + if (intersect == null) + continue; + if ((!horizontalPass || !doHorizontalPass) && surfaceCollision.isFalse()) + surfaceCollision.setValue(intersect.isSurfaceCollision()); + + double timeOfImpact = intersect.getTimeOfImpact(); + if (timeOfImpact > 0 && timeOfImpact < 1) { + futureCollision.setTrue(); + allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue())); + continue; + } + + Vec3d separation = intersect.asSeparationVec(entity.stepHeight); + if (separation != null && !separation.equals(Vec3d.ZERO)) + collisionResponse.setValue(currentResponse.add(separation)); } + + if (!horizontalPass || !doHorizontalPass) + break; + + boolean noVerticalMotionResponse = allowedMotion.getValue().y == motion.y; + boolean noVerticalCollision = collisionResponse.getValue().y == 0; + if (noVerticalCollision && noVerticalMotionResponse) + break; + + // Re-run collisions with horizontal offset + collisionResponse.setValue(collisionResponse.getValue() + .mul(1, 0, 1)); + allowedMotion.setValue(allowedMotion.getValue() + .mul(1, 0, 1) + .add(0, motion.y, 0)); + continue; } -// Debug.debugChat("----"); - // Resolve collision Vec3d entityMotion = entity.getMotion(); Vec3d totalResponse = collisionResponse.getValue(); @@ -240,7 +269,8 @@ public class ContraptionCollider { boolean hardCollision = !totalResponse.equals(Vec3d.ZERO); rotation.transpose(); - motionResponse = rotation.transform(motionResponse); + motionResponse = rotation.transform(motionResponse) + .add(conMotion); totalResponse = rotation.transform(totalResponse); rotation.transpose(); @@ -262,7 +292,7 @@ public class ContraptionCollider { Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset) .subtract(contraptionPosition); contactPoint = - VecHelper.rotate(contactPoint, conAngularMotion.z, conAngularMotion.y, conAngularMotion.x); + VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z); contactPoint = contactPoint.add(contraptionPosition) .add(contraptionCentreOffset) .add(conMotion); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index 3a1a815d7..2dedebad0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -5,12 +5,15 @@ import static com.simibubi.create.foundation.utility.AngleHelper.getShortestAngl import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; +import java.util.UUID; import java.util.stream.Stream; import org.apache.commons.lang3.tuple.MutablePair; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntityTypes; +import com.simibubi.create.content.contraptions.components.actors.SeatEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; @@ -45,6 +48,7 @@ import net.minecraft.tags.BlockTags; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; +import net.minecraft.util.Hand; import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; @@ -70,7 +74,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected BlockPos controllerPos; protected Vec3d motionBeforeStall; protected boolean stationary; - + protected boolean initialized; final List collidingEntities = new ArrayList<>(); private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL); @@ -98,11 +102,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) { ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.CONTRAPTION.get(), world); - entity.contraption = contraption; + entity.contraptionCreated(contraption); entity.initialAngle = initialAngle; entity.forceYaw(initialAngle); - if (contraption != null) - contraption.gatherStoredItems(); return entity; } @@ -116,12 +118,25 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public static ContraptionEntity createStationary(World world, Contraption contraption) { ContraptionEntity entity = new ContraptionEntity(AllEntityTypes.STATIONARY_CONTRAPTION.get(), world); - entity.contraption = contraption; - if (contraption != null) - contraption.gatherStoredItems(); + entity.contraptionCreated(contraption); return entity; } + protected void contraptionCreated(Contraption contraption) { + this.contraption = contraption; + if (contraption == null) + return; + if (world.isRemote) + return; + contraption.gatherStoredItems(); + } + + protected void contraptionInitialize() { + if (!world.isRemote) + contraption.mountPassengers(this); + initialized = true; + } + public ContraptionEntity controlledBy(T controller) { this.controllerPos = controller.getPos(); return this; @@ -142,6 +157,110 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return true; } + @Override + protected void addPassenger(Entity passenger) { + super.addPassenger(passenger); + } + + public void addSittingPassenger(Entity passenger, int seatIndex) { + passenger.startRiding(this, true); + if (world.isRemote) + return; + contraption.seatMapping.put(passenger.getUniqueID(), seatIndex); + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), + new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + } + + @Override + protected void removePassenger(Entity passenger) { + Vec3d transformedVector = getPassengerPosition(passenger); + super.removePassenger(passenger); + if (world.isRemote) + return; + if (transformedVector != null) + passenger.getPersistentData() + .put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector)); + contraption.seatMapping.remove(passenger.getUniqueID()); + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), + new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + } + + @Override + public void updatePassengerPosition(Entity passenger, IMoveCallback callback) { + if (!isPassenger(passenger)) + return; + Vec3d transformedVector = getPassengerPosition(passenger); + if (transformedVector == null) + return; + callback.accept(passenger, transformedVector.x, transformedVector.y, transformedVector.z); + } + + protected Vec3d getPassengerPosition(Entity passenger) { + AxisAlignedBB bb = passenger.getBoundingBox(); + double ySize = bb.getYSize(); + BlockPos seat = contraption.getSeat(passenger.getUniqueID()); + if (seat == null) + return null; + Vec3d transformedVector = toGlobalVector(new Vec3d(seat).add(.5, passenger.getYOffset() + ySize - .15f, .5)) + .add(VecHelper.getCenterOf(BlockPos.ZERO)) + .subtract(0.5, ySize, 0.5); + return transformedVector; + } + + @Override + protected boolean canFitPassenger(Entity p_184219_1_) { + return getPassengers().size() < contraption.seats.size(); + } + + public boolean handlePlayerInteraction(PlayerEntity player, BlockPos localPos, Direction side, + Hand interactionHand) { + int indexOfSeat = contraption.seats.indexOf(localPos); + if (indexOfSeat == -1) + return false; + + // Eject potential existing passenger + for (Entry entry : contraption.seatMapping.entrySet()) { + if (entry.getValue() != indexOfSeat) + continue; + for (Entity entity : getPassengers()) { + if (!entry.getKey().equals(entity.getUniqueID())) + continue; + if (entity instanceof PlayerEntity) + return false; + if (!world.isRemote) { + Vec3d transformedVector = getPassengerPosition(entity); + entity.stopRiding(); + if (transformedVector != null) + entity.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z); + } + + } + } + + if (world.isRemote) + return true; + addSittingPassenger(player, indexOfSeat); + return true; + } + + public Vec3d toGlobalVector(Vec3d localVec) { + Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO); + localVec = localVec.subtract(rotationOffset); + localVec = VecHelper.rotate(localVec, getRotationVec()); + localVec = localVec.add(rotationOffset) + .add(getAnchorVec()); + return localVec; + } + + public Vec3d toLocalVector(Vec3d globalVec) { + Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO); + globalVec = globalVec.subtract(getAnchorVec()) + .subtract(rotationOffset); + globalVec = VecHelper.rotate(globalVec, getRotationVec().scale(-1)); + globalVec = globalVec.add(rotationOffset); + return globalVec; + } + @Override public void tick() { if (contraption == null) { @@ -149,6 +268,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return; } + if (!initialized) + contraptionInitialize(); + checkController(); Entity mountedEntity = getRidingEntity(); @@ -173,10 +295,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD super.tick(); } - public void collisionTick() { -// ContraptionCollider.collideEntities(this); - } - public void tickAsPassenger(Entity e) { boolean rotationLock = false; boolean pauseWhileRotating = false; @@ -266,10 +384,8 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void tickActors(Vec3d movementVector) { - float anglePitch = getPitch(1); - float angleYaw = getYaw(1); - float angleRoll = getRoll(1); - Vec3d rotationVec = new Vec3d(angleRoll, angleYaw, anglePitch); + Vec3d rotationVec = getRotationVec(); + Vec3d reversedRotationVec = rotationVec.scale(-1); Vec3d rotationOffset = VecHelper.getCenterOf(BlockPos.ZERO); boolean stalledPreviously = contraption.stalled; @@ -283,7 +399,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD Vec3d actorPosition = new Vec3d(blockInfo.pos); actorPosition = actorPosition.add(actor.getActiveAreaOffset(context)); - actorPosition = VecHelper.rotate(actorPosition, angleRoll, angleYaw, anglePitch); + actorPosition = VecHelper.rotate(actorPosition, rotationVec); actorPosition = actorPosition.add(rotationOffset) .add(getAnchorVec()); @@ -295,7 +411,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (previousPosition != null) { context.motion = actorPosition.subtract(previousPosition); Vec3d relativeMotion = context.motion; - relativeMotion = VecHelper.rotate(relativeMotion, -angleRoll, -angleYaw, -anglePitch); + relativeMotion = VecHelper.rotate(relativeMotion, reversedRotationVec); context.relativeMotion = relativeMotion; newPosVisited = !new BlockPos(previousPosition).equals(gridPosition) || context.relativeMotion.length() > 0 && context.firstMovement; @@ -429,6 +545,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected void readAdditional(CompoundNBT compound) { + initialized = compound.getBoolean("Initialized"); contraption = Contraption.fromNBT(world, compound.getCompound("Contraption")); initialAngle = compound.getFloat("InitialAngle"); forceYaw(compound.contains("ForcedYaw") ? compound.getFloat("ForcedYaw") : initialAngle); @@ -479,6 +596,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD compound.putFloat("InitialAngle", initialAngle); compound.putBoolean("Stalled", isStalled()); + compound.putBoolean("Initialized", initialized); } @Override @@ -499,15 +617,15 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public void disassemble() { - if (!isAlive()) { + if (!isAlive()) return; - } if (getContraption() != null) { remove(); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); - Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1)); - getContraption().addBlocksToWorld(world, offset, rotation); - preventMovedEntitiesFromGettingStuck(); + Vec3d rotation = getRotationVec(); + setBoundingBox(new AxisAlignedBB(0, 300, 0, 0, 300, 0)); + contraption.addBlocksToWorld(world, offset, rotation, getPassengers()); +// preventMovedEntitiesFromGettingStuck(); } } @@ -633,11 +751,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public Vec3d getRotationVec() { - return new Vec3d(getPitch(1), getYaw(1), getRoll(1)); + return new Vec3d(getRoll(1), getYaw(1), getPitch(1)); } public Vec3d getPrevRotationVec() { - return new Vec3d(getPitch(0), getYaw(0), getRoll(0)); + return new Vec3d(getRoll(0), getYaw(0), getPitch(0)); } public Vec3d getPrevPositionVec() { @@ -653,8 +771,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return false; if (e instanceof SuperGlueEntity) return false; + if (e instanceof SeatEntity) + return false; if (e instanceof IProjectile) return false; + if (e.getRidingEntity() != null) + return false; Entity riding = this.getRidingEntity(); while (riding != null) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java new file mode 100644 index 000000000..0b2d2c56a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java @@ -0,0 +1,65 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ContraptionInteractionPacket extends SimplePacketBase { + + private Hand interactionHand; + private int target; + private BlockPos localPos; + private Direction face; + + public ContraptionInteractionPacket(ContraptionEntity target, Hand hand, BlockPos localPos, Direction side) { + this.interactionHand = hand; + this.localPos = localPos; + this.target = target.getEntityId(); + this.face = side; + } + + public ContraptionInteractionPacket(PacketBuffer buffer) { + target = buffer.readInt(); + int handId = buffer.readInt(); + interactionHand = handId == -1 ? null : Hand.values()[handId]; + localPos = buffer.readBlockPos(); + face = Direction.byIndex(buffer.readShort()); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(target); + buffer.writeInt(interactionHand == null ? -1 : interactionHand.ordinal()); + buffer.writeBlockPos(localPos); + buffer.writeShort(face.getIndex()); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity sender = context.get() + .getSender(); + if (sender == null) + return; + Entity entityByID = sender.getServerWorld() + .getEntityByID(target); + if (!(entityByID instanceof ContraptionEntity)) + return; + ContraptionEntity contraptionEntity = (ContraptionEntity) entityByID; + if (contraptionEntity.handlePlayerInteraction(sender, localPos, face, interactionHand)) + sender.swingHand(interactionHand, true); + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java new file mode 100644 index 000000000..d67e51504 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java @@ -0,0 +1,58 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ContraptionSeatMappingPacket extends SimplePacketBase { + + private Map mapping; + private int entityID; + + public ContraptionSeatMappingPacket(int entityID, Map mapping) { + this.entityID = entityID; + this.mapping = mapping; + } + + public ContraptionSeatMappingPacket(PacketBuffer buffer) { + entityID = buffer.readInt(); + mapping = new HashMap<>(); + short size = buffer.readShort(); + for (int i = 0; i < size; i++) + mapping.put(buffer.readUniqueId(), (int) buffer.readShort()); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(entityID); + buffer.writeShort(mapping.size()); + mapping.forEach((k, v) -> { + buffer.writeUniqueId(k); + buffer.writeShort(v); + }); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + Entity entityByID = Minecraft.getInstance().world + .getEntityByID(entityID); + if (!(entityByID instanceof ContraptionEntity)) + return; + ContraptionEntity contraptionEntity = (ContraptionEntity) entityByID; + contraptionEntity.contraption.seatMapping = mapping; + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java index ed6aac7ba..d137d9c31 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkBearingTileEntity.java @@ -47,10 +47,6 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe if (running && Contraption.isFrozen()) disassemble(); - if (hourHand != null) - hourHand.collisionTick(); - if (minuteHand != null) - minuteHand.collisionTick(); if (!world.isRemote && assembleNextTick) { assembleNextTick = false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java index f5463d1ad..9a013ba7d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/MechanicalBearingTileEntity.java @@ -208,8 +208,6 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp if (world.isRemote) clientAngleDiff /= 2; - if (movedContraption != null) - movedContraption.collisionTick(); if (running && Contraption.isFrozen()) disassemble(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index 4f7b006c8..928eff3c8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -20,7 +20,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -91,13 +90,13 @@ public class MountedContraption extends Contraption { } @Override - public void removeBlocksFromWorld(IWorld world, BlockPos offset) { - super.removeBlocksFromWorld(world, offset, (pos, state) -> pos.equals(anchor)); + protected boolean customBlockPlacement(IWorld world, BlockPos pos, BlockState state) { + return AllBlocks.MINECART_ANCHOR.has(state); } - + @Override - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { - super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.has(state)); + protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) { + return pos.equals(anchor); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 53211b904..43140fb09 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -53,7 +53,6 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme super.tick(); if (movedContraption != null) { - movedContraption.collisionTick(); if (!movedContraption.isAlive()) movedContraption = null; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index cff0e3afc..7af815d55 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -16,7 +16,6 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; -import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.NBTHelper; @@ -32,7 +31,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -174,44 +172,36 @@ public class PistonContraption extends Contraption { } @Override - public void addGlue(SuperGlueEntity entity) { - BlockPos pos = entity.getHangingPosition(); - Direction direction = entity.getFacingDirection(); - BlockPos localPos = pos.subtract(anchor) + public BlockPos toLocalPos(BlockPos globalPos) { + return globalPos.subtract(anchor) .offset(orientation, -initialExtensionProgress); - this.superglue.add(Pair.of(localPos, direction)); - glueToRemove.add(entity); } @Override - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) { - super.addBlocksToWorld(world, offset, rotation, (pos, state) -> { - BlockPos pistonPos = anchor.offset(orientation, -1); - BlockState pistonState = world.getBlockState(pistonPos); - TileEntity te = world.getTileEntity(pistonPos); - if (pos.equals(pistonPos)) { - if (te == null || te.isRemoved()) - return true; - if (!isExtensionPole(state) && isPiston(pistonState)) - world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED), - 3 | 16); + protected boolean customBlockPlacement(IWorld world, BlockPos pos, BlockState state) { + BlockPos pistonPos = anchor.offset(orientation, -1); + BlockState pistonState = world.getBlockState(pistonPos); + TileEntity te = world.getTileEntity(pistonPos); + if (pos.equals(pistonPos)) { + if (te == null || te.isRemoved()) return true; - } - return false; - }); + if (!isExtensionPole(state) && isPiston(pistonState)) + world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED), + 3 | 16); + return true; + } + return false; } @Override - public void removeBlocksFromWorld(IWorld world, BlockPos offset) { - super.removeBlocksFromWorld(world, offset, (pos, state) -> { - BlockPos pistonPos = anchor.offset(orientation, -1); - BlockState blockState = world.getBlockState(pos); - if (pos.equals(pistonPos) && isPiston(blockState)) { - world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16); - return true; - } - return false; - }); + protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) { + BlockPos pistonPos = anchor.offset(orientation, -1); + BlockState blockState = world.getBlockState(pos); + if (pos.equals(pistonPos) && isPiston(blockState)) { + world.setBlockState(pos, blockState.with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66 | 16); + return true; + } + return false; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java index d7423304c..0f697c166 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java +++ b/src/main/java/com/simibubi/create/foundation/collision/CollisionDebugger.java @@ -6,7 +6,6 @@ import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.Debug; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.outliner.AABBOutline; @@ -31,7 +30,6 @@ public class CollisionDebugger { angle += delta; angle = (int) angle; OBB.setRotation(new Matrix3d().asZRotation(AngleHelper.rad(angle))); - Debug.debugMessage("Angle: " + angle); } public static void render(MatrixStack ms, SuperRenderTypeBuffer buffer) { diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 141a0499c..a8b304c24 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -6,6 +6,8 @@ import java.util.function.Supplier; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket; @@ -45,6 +47,7 @@ public enum AllPackets { CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), + CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), // Server to Client @@ -54,6 +57,7 @@ public enum AllPackets { CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new), + CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new), ; diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 3852632ff..17123dd50 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -13,6 +13,10 @@ import net.minecraft.util.math.Vec3i; public class VecHelper { + public static Vec3d rotate(Vec3d vec, Vec3d rotationVec) { + return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z); + } + public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) { return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z); } diff --git a/src/main/resources/assets/create/textures/block/seat/bottom.png b/src/main/resources/assets/create/textures/block/seat/bottom.png index 744293ab69cc2cf06fb87c802110e6ff03df3be2..97a2c28d03e98b2e6c3d55185c50728ae7f32810 100644 GIT binary patch delta 241 zcmdnMw25hgXMJjFYC%CkWo2b`b#;4=O-H`-tU8YcJz=Y+#;>1|xpjUH0}|MCZtia& zm$SelvY3H^?;r>>?wFYU7AV;5>Eak7ahbPwBj;fQ5tsFWf)Ho(HURow7 z|CmvyG>>VLsl$(=$;Xa-ir150XR#yeyTz9CF`IYrnSUw25#C(aWB1{BgO`?#`l0A2 zS9pF1S$dZooaAb@l7DW*YM&d|581T{TCbk>sKGT+Y1gCeb6xqa#(wlNe978wdd|(C h*Rq*y?b*;tum7d+JFNKra7_Wo?VhfFF6*2UngHc;Vm<%> delta 239 zcmdnQw1H`YXMIjVX<1!UdydVlI*$cCVXLObub+{*b$(7uXCDIwNZVv^7bwVC;1OBO zz`%DHgc*>%L6-m)O~pTg2u1tm@9?H+ITu5K-OUh8mU zvxrZLx8b{3T_&&fKKGXYuE2A9ph?olwEiGX2E5tc?OQ+g`L7 zcAeRD*EDJCrz2LX+s>6nM7}<_T|!iCkx$x4(CZEQhHRdW` ZrrZCL*W<`K)$;@7eot3Fmvv4FO#o2!Vi^Dc diff --git a/src/main/resources/assets/create/textures/block/seat/side_black.png b/src/main/resources/assets/create/textures/block/seat/side_black.png index 3dec26d414a346ea1d16bb910c49791214c0d97d..4f952499d686d6ea9992e5dfc442e9e25bd69a8b 100644 GIT binary patch delta 302 zcmV+}0nz@01N#DyR(}vlL_t(IPh6Q+>C&bDA3l7@FmKKru;A}MKxeW5T?IA-p%{i?;(tjgDGc)R@(e5*8X90l zu110k!hGCdHVnM|^cBitfXl(eK$<~%;Vv)}x&xLF;Nt?*$l$}LZ(tf(Zr1}Tup!JQ zCMFH9UcF+F<#@sHPx# delta 310 zcmV-60m=UR0)qpPR(}{tL_t(IPwi4oO9L?weTkdHZa)xFA@YWFCj}41 zi-`Y5@Z<-DcEK-}ZFg75O3chQHHas@c<{k6GjHCTgb-n^#cv>&`N#NQ@D~<{-Oh=`(A|)9!Tf0Sn`^6Zz4b2LJ#707*qo IM6N<$g2xte00VD7L2O}QXMoGS{d5mZ%gYxrfb_y$U?y}2EFr*$>U0qJ@CgzI z$a1?LNP%6zY+_>4@aoko23d|53{RfEWMKIBi{Z=X&kT3&Jz;q9@->+M=hqJ~28o04 z-~TKO=O6xI_%!q94+CRCK>;`re?B=3Hd&Yt)f?yl<}G#^TOi56001i}mW5k@3!DG| N002ovPDHLkV1hfBj4%KI delta 312 zcmV-80muG`1BC;SR(~2vL_t(IPwkRHO2a@Hg@x3WA=)y*F_q zg05V+^9UY8s2hda6t!(8O=1~+f15ChE8V#8gJIsh|GgOq@vOD@4gPZfG5;6*g$ul$ zqZ7LlY6O8sSsJ_*22m>(U3u>8Yu0y-itoxUmCvrXy?-pfVt=4oi(#IM=Fo+&RWm|O zywkG_nZdSg#cYbO*_PSi?iS)WhIf8>W%D9O^Z5qd&ZZPxihPbx zHI}CZ!_gCF8+%Zpg3mGqNzDWg{W}RzvrM@2?0W35>u1J@D8^$14UP3)4{Pm?gkGnk zdYLQ}ubdmnvN6N1A88GKgS2~q;bXrJ5e9i#waCk0AX#=It?>?eAGG2mPx#9K0000< KMNUMnLSTX^IFxb# diff --git a/src/main/resources/assets/create/textures/block/seat/side_brown.png b/src/main/resources/assets/create/textures/block/seat/side_brown.png index 87110fe8246c6eff7064972775d1211a3ebc388b..b4a7eea166e9c9c459032eae21778b809a90baaa 100644 GIT binary patch delta 312 zcmV-80muG<1BC;SR(~2vL_t(IPhuHiX&4#H8WXt5*!N94{E2JblT)@b4GHm(QOW?%aFA@Z#lbF#pf5A7Bg;2jRc} zSs2bg{KN3)&oLhc#)5(Za3KDCau{r~Fq${e0n7{RGPXdHfdK%CRFyy+qwg*N0000< KMNUMnLSTYBJdjWT delta 308 zcmV-40n7e{1AzmOR(}>rL_t(IPwi66O2a@DJu}g!8H*2++Ak2ga_3*TaIb5jU!)rm z6c_IO7#BiU3biR}Z6-}Ljy=~-4dO~SE<7;YGv{#!LX>k3zk#05ALD<)Us#|Hce>7m z3Q?$$7jLkIL%bRY_gdZin$>l|M#&^Le6`f#V;7PX6_wGHPEeoX-euKv6`eXbX z`~?HC(?3T?ptj=VX#PChsm>c`+vC4U$MEg%w+jC<(SAi z=rqF-C?<#?2vit`IKRDv$|fjtUDVbF_R3r_aZ;}qnQQK3Zx@c^z;a!ei;k`@(CbzL zAmurEtxh2rE=iw&0$O|s(tdTY-yLwlT4%m>!b@7cL7lsN*x(MDp68v#ag43@5YgiZ zcrP#+k1@E9Fg+YS^IjG?56aUhm4%y7LP`nY`#wM7EV^RnUdLQxF_N^pR%`P>&%g(K WxtJ{hM8wDd00007p4bPlwQ=aIgi-SLS-1F`|=ROEg)>`}qZ&`oL|AN1;KXPiO|Sp%^}a@v3Qw@w8lF+iL}5T{0G+n0000< KMNUMnLSTaaahQt$ diff --git a/src/main/resources/assets/create/textures/block/seat/side_gray.png b/src/main/resources/assets/create/textures/block/seat/side_gray.png index d9249a4fecc7978f926cc14096513228dc7446ed..39732edad2786b28d378015810ddbcfe8b8c6cad 100644 GIT binary patch delta 298 zcmV+_0oDG21NQ=uR(}jhL_t(IPhl z`ST|b|6<_d;{~%}V#spnYMGD)U;vwDWB?Nf>1DJwHwPz0kN~>mbUK0YuT z2Ht-93S}|C*g-@r7o+^z>wU_+QqOiUVHy?VtU z%khHY$?`T@ouaS;CdpM~N4!#@mv{`_HJEGQ@d w2jb5shruQb^CNMCXrL_t(IPwi4YOT$nUJujkZ(i;n~q2(LpHU<|au0nUjNq zxQXEA>W>hd{6MGyzX)lQG>SZPZu;t@IO*cxfy=%3+;dJsh%(0DH}IzY$M_HU3ju1o z-#5O$1mE{jmSt6Mh@wzt%el9Ct>+RJ-&dT3Vt@YVf={!zdapy({=t!n zABMO%Kf|OV?Q1q9Hyxhc6OoHyHJP6rzX!cv>s2ep;yJ=A}>A=G#92@jqCUc z+1da>(1J%Z2jV3i;qvNM1e|Fm*txqLJ@k6xQ7S``jL}>Spt~LDoH1NZ_(3`A%ng0%iglZ|U;bjun%>BWOT*v#bnW+s^sp|!?uXnn>X^FQD( z3=sQ=d)o0_xZVoNyg-$g@OmB2jb?kz+LkRCzH7EII`xX(;eQVQiqey8s$6kSrVTyK zcm(Byh~ro%NrLl>GpN@R)k48(OUPCCOEG(ObZU*flj9M5--ir>fQybc`WSROoEsiy z&mYM;mY&h5nR=IRaL^yK(d({pw0WGpaJ0S4+f5$ggkgA^Wf``;3DUbM@K)eyKF9bb z#bkQV_o~SGkTOoE(h}E6y_QlCQ55k4HL1_#=;MVd*w`S$Ae z$#nLFe0Kof^Pw1~AdB=35950=P%}(ec{h8^FsrgO6;aOTaP0`4ejhvAT`|4B&(%3NM19xGKx~`$Pu1o)U8Qsw2_A}ZLPw4F)HY@M}x)!$< T9CoWm00000NkvXXu0mjf)`gV= delta 314 zcmV-A0mc4~1BU~UR(~8xL_t(IPwkLBPQySDg`YQy?W_|>WQQDxhJu1KaRFKygcK@z zT5f_AQ4lGKlYrxY6fOG}J6a(sXefBnXl7^LHiQC{ z-$Pv%crSAV!_d@i&z^nt3cJzjJJ?p+Co9s;5}Wz6*~X~y)PLj_YO_6KkRj__-%M2; z$9UXksI#3m?cm7)++d({-@pVpE3*WCaAanuqX1D9!MVM=S5;lX-#%a*o*2MZUG3p| zo#yqa)q06?bPmt;APBRdGX3?J*^@D_CQLE&ZTHBK6-BQ9O&4{NpxcocP9`|+hsN}l zt`CtH%`Nu&J~P@&hOFpG3Em(ZUtl$#9ZVFBT-FBlx>y)5nVyvR01L6tVe8>f{{R30 M07*qoM6N<$f)>-40ssI2 diff --git a/src/main/resources/assets/create/textures/block/seat/side_light_gray.png b/src/main/resources/assets/create/textures/block/seat/side_light_gray.png index cddf833d3d0e89e63b33e942ebf7f91dea198be4..376d9763c56ef29b66054ebc0dd1201e5c248e58 100644 GIT binary patch delta 335 zcmV-V0kHm;1DpepR(~-`L_t(IPwi7NPQx%1eQuE;NmU`TAy9@2DNDDA2@b&-I~u5|x~@UfbQA>#=LJmDq*!rHt)1Ix5(?j$n^3&;c7G2BgYk2kf>mR+Dv@(e zF=KUdS*~c6rzuV5Jthfp%=0`Eh9QE<1X-Se=T)1AhMv)bq3dLpMycgFhhgZX*~1|$ z%L4O#Uj#vb>x*-keS-`NNt&-Cd}@k2Iyr-F+g}|V?o3J8?$@U_@s!qY(9|yPcBzA| z<2d6uj-g1N3s|MP2fMU~sv hXhU6LbMLtN0w0!LsnM_*r1k&+002ovPDHLkV1i;on*#s< delta 330 zcmV-Q0k!^|1D6AkR(~u>L_t(IPwkMuPQx$|#y=;b!A>MVN$CSrFthL$47@`p-h#(q zsgPh|=Pg*65mG0RN)tg#Y?D8g$z7W&LQJqQ@LATK@4nx~v2f1eH}cl;$NC@e7Y2y4 z(a0$!A*F(~2F6&#am;yJ>-N5Sy>6k^cW_s2oml^1I6R*(7Jm@Us;U~=7|w-Qnd`dZ zNMCDv&fOn=?!%M6tm~a#zZ0`4Qn^)Z8~Ky cF;Xdf0_W+%9NemBo&W#<07*qoM6N<$f)78V0{{R3 diff --git a/src/main/resources/assets/create/textures/block/seat/side_lime.png b/src/main/resources/assets/create/textures/block/seat/side_lime.png index a0c7347203dd92b794172a2a8a8b7696546849ea..ae9c2575f6d8e24d0702c5d560fdea26136e8f0e 100644 GIT binary patch delta 326 zcmV-M0lEH$1Cs-gR(~i-L_t(IPwi7nPQx%1oP5+YDX9?MA!xQaK*S2JfW%4Y5jX+2 z$Qp?yTMoblDnv?<+N70G(xyr3)WokCSqL_;VZlh_vERITvKQ7k=lBiucl|N`2mFNr z+U4~rw;T-}TSvX#qAEDtfkAs&Q@zi}I zJ<67IV3DopsI}aAHWsO`~W1NkiL=&W6V YH*M3k3f`W{b^rhX07*qoM6N<$f>pGjssI20 delta 313 zcmV-90mlB51BL^TR(~5wL_t(IPwkK~PQySDMZed73KdhYIPR=9@Mcd#q#6Dx{rf&8K2Yh2ZmyMKjjcXw385bIrBUYR`4 z@u+X1$`pl}%qT?;j%!LI{FsAXTcw)A*hPG!smsPH)#EhFDQ6#e*&i?D!JuiKN5_V7$+<<@{H400000 LNkvXXu0mjfxs8>L diff --git a/src/main/resources/assets/create/textures/block/seat/side_magenta.png b/src/main/resources/assets/create/textures/block/seat/side_magenta.png index d355e56d412b9aaff32f928d219d7ffaea2702f2..01703d91d36158f8c325822da1eec2b913bf0841 100644 GIT binary patch delta 321 zcmV-H0lxl%1C9fbR(~T&L_t(IPwi7dPJ>Vs9B3^Cm6)O%Q^S@65I5@5^g1M7pf~Uo zEIoj3b?*flBMF*HkMY0YFD%eb zk57cPX26uJo@o@Ksnv*QczWE;B?~!hhR{i>6}jLY=A}kusFk z!Y~w36k&B9qi9OWCu|Oek`^`wCWk3VUS3zQ4U@gzWDM7J(f2%$hpu+c;MnVMxB}?A z_xbXzkRWec>Z9xxQV-n&Q1;^l`=c2TZrK*AiYzZ#Rqx_JwL@kL##K+qTexAmIPGjxTvL9rZiV6$r-oNIrpAMFO(d Th5aiL00000NkvXXu0mjfJA|A+ delta 309 zcmV-50m}Z41A+sPR(}^sL_t(IPwkMwO2bePMQ>7?G>=-9r1l5=6*uC-fAK@yx)GtS z+>2jRC@vJzrWn)ay(XnRbH~0C#FcJbc;PbhX6_kCJZmj}BY#(atp5Xl;edC2c4bvJ zMAX=9D(J?s8c6SE?cLX`-yS%92e;+sWc^v0<2g^|8ojEGRDTD#+TPJ*$a*)oW1D3e z?9&9xS~p(fAm}w#=m(L&1i33JgFzU{&O1Lvk|gl%?jLMbSLnSxVi=zY&{kb-5rm!H z>r?Z^4C~_yghBHOgxOG~UgBjskpO$b6f58D85y#^(OR0iDA4UF9F0ae?8g#%UoH05 z#>i~5)siJc)-I2f0{=ldyu|!SJgL`vZU4d>5oE%P#h00000NkvXX Hu0mjfau}9F diff --git a/src/main/resources/assets/create/textures/block/seat/side_orange.png b/src/main/resources/assets/create/textures/block/seat/side_orange.png index 267ab3c3e252d57af90a76a8c77dbe8b01b4f625..9ada1ff3bff553cf7100d1932403b4ddbaadd879 100644 GIT binary patch delta 327 zcmV-N0l5By1C#@hR(~l;L_t(IPwkLFO2bePhX0pVt&NS6E-a#Co2?KOM9<*L6L^6f z!DG0W9KfwxUE2$kVjw~rshFfGHNNJV8H_wdTNgFs<~(fEPyvY4|`o@}9-=!X(gN(kTg`4OL^Yo6S-s#U*XLcdV4vVByY Zz$+jPo5^SMpZNd)002ovPDHLkV1gEHqKp6l delta 310 zcmV-60m=T91A_yQR(}{tL_t(IPwkLFO2a@Hh2KnR(oWh`ZE7we2%f=(8}R^Msv8mP zs(X*&5rnQ3YE!gHGig%d$Qw-=#g%Sc_`xtQ|9kHrh%m zpwkoBtPON-a1cwYo0;o<%}RIB@Lk!ZnX@a#=f~C!!j?7jw12jmrVC$dJVH&x`0Bm^4Qh@uGMdNMU-Rig8Ji_!4V7F?>bhUdR8 zYFI3vu-QL_@A;4{Q;=L|c$nSW05!{mH^1E(JM79rYb&ZWMZ2Z27snX%hBmZXFLy^5 zg`I6{ZL{pKD=)iBf&U;Moni4f+l2^&T-F@&GN0QlJ6)yl1}ty2S}J$%ivR!s07*qo IM6N<$g8RdkMF0Q* diff --git a/src/main/resources/assets/create/textures/block/seat/side_pink.png b/src/main/resources/assets/create/textures/block/seat/side_pink.png index cc1a19c0ea72e0a13bb0fe8f59922ce0fadc4803..b8ac240990d2eefe99c281a97db3c442d601aa2a 100644 GIT binary patch delta 331 zcmV-R0kr;<1DFGlR(~x?L_t(IPwi8?PQx%1J#H(JM~MpE5GWgpm?NgbKkyOkQNN&H zz{JL!nVl8Zhz(_^5Rrn^hIihSfT=GvL=h7#3>?e$^*Q%kKO{5GIevrIV*WAy3;cxw z>}daxYl;e0QBag6^0Gj`w?eVx>RL0mRVO6AGuI(`;cf434u3{ZX#&O=UaAUNky9+1 zKsDzC#BNd(dAASu#4*=(c@PB9E;@*d6iJ?8S<_*tUFfPtW?>XsoTV`IE@}Bz1=BRa zJkR64@8j(F0DVIzgT!5&Eh2nsk{j#|VOiGK3AR_qB=n4rUF&#^bDHbg$<-R2pl#ds zD2gI%C=-O&Q$*lxhBQeqz6>#$-q5<5mDB|<`YZ3?JgDe>nBzF~pP$21s@%Lr6Y>g6 d>pSxicn5s6s(cCXi);V@002ovPDHLkV1fkDoBsd+ delta 327 zcmV-N0l5B{1C#@hR(~l;L_t(IPwkLRPQx%1gvSXqi4#hzr1S>txB=n>EVu;s;1Dd3 z5JG|#dv3xOsVk65Q%dt=CvB?0n5K#lE7-7LEX&XH=6jYb>bk~nWUbF1>wmys7$7cB z&ui&=@LU(VD4+_Bu-7+r z@wKMMTs(U_#eo}udprk5RTA&Mf1>)X4! zT$FHU_ZWnG254(huF!Gp_3cxW=?jYfF`SMAi!ci+S1F!Gk0!vHFvXMiwnv7nrIj+p zB1y1qOZ0|A>_7&g3C*+VW-G0Yw_GWcB}3Noqy+yUADm$FJlcdP205(R)Z2J$vSd6d Z@eck#!pEOb2^#T!-X^w|{+pG8`>dG2aC!w3`0HCz{-A iJfjKuEcNt?pTGxR@uQJ4vDR(?0000L_t(IPwkLFPK7WKhJPRrq>!iqxO}vW>P2NhAC%pJXTBH>#Q(g@*u5{zVKPfYv`M+tYqqW9ww5_N04~9lkhplk{q)WlC?}Xik@n*nF~qu! z5GIjTg^9djoZvX%Q diff --git a/src/main/resources/assets/create/textures/block/seat/side_red.png b/src/main/resources/assets/create/textures/block/seat/side_red.png index f275d37ea82d2c6defeae5fa54969ba2c4f3e1ee..c21eb5131dc84170beeae01654981cb1d89d0141 100644 GIT binary patch delta 322 zcmV-I0lof%1CIlcR(~W(L_t(IPwi7NPQySDob%ZPLJ}d;A&?6iKfq9dM8yyIho8U; z_=PKekQRC#K!mVlq{Ijb#U_E{&WCq{(Fq|6XebzIJ$ExZtG&X)T8rPnd*>hHf52ZD zAkOxVY}d0`lQkB`!@L$428PeA=6audJy&S)RoF$VQ`Re#K!3K7JdLW-U~WS#yB-x~ zC@a!5wON)ypN~))gX-0w7fAG_M9=3e2gxgyMt{X;&p$av7>4kpDB`Be-4esWIyzXU z6lz@0p7=~ydI269t!nNEO_;JD8|-h6xp8CAWp?p6n=`xK=yr=YkZ~NJ7Da)b)d}*u zDNrj^Wr^`kjyuWpp6^;cbCFJEtdFZqLu(C@Bnkh|FZl&erd7WKJ%P~KK5V|g8!9ZN Ufv8mIBWOT3^V)B|IJ~AwHCjT-1Hyo|G-~3AkGhuY$7dU z)uA>Lx)aC(!?W}J-Pf%24X5v5U(P31PFjJdTJbfiY6b2Na(~_5Q4vF|xVXHwMNy!; zy+>&bs-;01DD;&=+GCbM+Li4J{jkS7d3J(4&mpdE?rhUG*m-@xAUjwSp4!GBjMV0} z)^s+($Nn**FoGnQ2GT;8cpg1+fM$Y8)amVe#1JcMt$AqYa|9~E-f)QBG~>{FHQSc1 zYxb5#bCwulWiOm0pg&j)PBDEMZ9^mq(lJ-0xAB;>#KcL0Pv(@s`hc6F4FCWD07*qo IM6N<$fk=)#GI!DP!rMO|jen-D>q661lx2x5%fJ|` zqbaVclCn6h)kK}}_`VP3I1cwb4`C2MQ52+UN?A0NWtq&v7{>|XB!Q-?RC8h&FijH! z%d)7*f4BuJWT;|O0Le2jk2BH)bWO%Vomb0-Gsj~H@5cleM>7%*HHmT;FL84RUF~ju zN)z;L+nz>IgiN#j1%js#c-tVYN1eF=7U7ci)ux~jyofCy;L)q<`>DVtlL@`&*WjKy li&4MBYWG`v#%28l-T}U3s3Mal{W<^u002ovPDHLkV1gb4qI3WN delta 323 zcmV-J0lfa81CRrdR(~Z)L_t(IPwkLRPQx$|g`X3pANuJj?SOLI`NBQGeGp_x)n6R+=k)ZJ1Fm z%To5l)%C5(vJ8%{Q4}SrszMM1h@ud_?=wsw&5E)_6ox$0j*lcsAa3sNP208Dd40e% zK44(1u3cl|+MCm-(&Y=@_fOzXTv!BCL#kDYr}-lXs3(|2mCj?27-Fra{|{=qqJU#d z?9FD_4Pp-E)jV>$RnxGi*NU^m5Nmn;OVS(E(^I6+^KFPkLAq?%q_@R_v&48(;sYu% V!qm3=xkvy2002ovPDHLkV1gPqo$LSr diff --git a/src/main/resources/assets/create/textures/block/seat/side_yellow.png b/src/main/resources/assets/create/textures/block/seat/side_yellow.png index d25d7af9e163cd23ca2145fbf7c2ca770bbd1cfa..6e992a4bf3d02073c534947f4425d3e45addfb9b 100644 GIT binary patch delta 327 zcmV-N0l5By1C#@hR(~l;L_t(IPwh}aO2a@DeMzgf4T&*=h$z|S06{_Q8N5mk;KI8| z4&c_UuJr<;7>t^xRGOqIHJx^x`4|~QThheoSEQ8W3CN(U3oxGRbQ@E~+w&!`&baTtFZ5e>w zMK1376c|5M%biyGBK`nh2JCaQWzt@EC3v{{-4HM)pUYF?hUA>D=FA)R*oZHD%6=i|e%RPpJkp^s)MGe>c zIAj#Ap0PbXhv#|_gxOGOmS8cT=>U7e6f58Mj0{V*mgE From 9a04c514184c49b5b611cb5dbe43acea355482e8 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 22 Jul 2020 14:12:19 +0200 Subject: [PATCH 12/17] These are not the chunks you are looking for - Experimental fix to disappearing entities when contraption seating reaches across chunk boundaries on save --- .../com/simibubi/create/AllEntityTypes.java | 2 +- .../CancelPlayerFallPacket.java | 36 -------- .../ContraptionCollider.java | 26 +----- .../structureMovement/ContraptionEntity.java | 86 +++++++++++++++++-- .../piston/LinearActuatorTileEntity.java | 15 +--- .../foundation/networking/AllPackets.java | 2 - 6 files changed, 83 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/CancelPlayerFallPacket.java diff --git a/src/main/java/com/simibubi/create/AllEntityTypes.java b/src/main/java/com/simibubi/create/AllEntityTypes.java index 13d75af47..0e2e5b593 100644 --- a/src/main/java/com/simibubi/create/AllEntityTypes.java +++ b/src/main/java/com/simibubi/create/AllEntityTypes.java @@ -26,7 +26,7 @@ public class AllEntityTypes { public static final RegistryEntry> SUPER_GLUE = register("super_glue", SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build); public static final RegistryEntry> SEAT = - register("seat", SeatEntity::new, EntityClassification.MISC, 5, Integer.MAX_VALUE, false, SeatEntity::build); + register("seat", SeatEntity::new, EntityClassification.MISC, 0, Integer.MAX_VALUE, false, SeatEntity::build); private static RegistryEntry> register(String name, IFactory factory, EntityClassification group, int range, int updateFrequency, boolean sendVelocity, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/CancelPlayerFallPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/CancelPlayerFallPacket.java deleted file mode 100644 index f26e99bff..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/CancelPlayerFallPacket.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.simibubi.create.content.contraptions.components.structureMovement; - -import java.util.function.Supplier; - -import com.simibubi.create.foundation.networking.SimplePacketBase; - -import net.minecraft.entity.player.ServerPlayerEntity; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fml.network.NetworkEvent.Context; - -public class CancelPlayerFallPacket extends SimplePacketBase { - - public CancelPlayerFallPacket() { - } - - public CancelPlayerFallPacket(PacketBuffer buffer) { - } - - @Override - public void write(PacketBuffer buffer) { - } - - @Override - public void handle(Supplier context) { - context.get().enqueueWork(() -> { - ServerPlayerEntity sender = context.get().getSender(); - if (sender == null) - return; - sender.handleFallDamage(sender.fallDistance, 1.0F); - sender.fallDistance = 0; - sender.onGround = true; - }); - context.get().setPacketHandled(true); - } - -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index 4c3770901..d90f71db4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -61,7 +61,6 @@ import net.minecraftforge.event.TickEvent.WorldTickEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber @@ -118,7 +117,7 @@ public class ContraptionCollider { if (!data.contains("ContraptionDismountLocation")) return; Vec3d position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", NBT.TAG_DOUBLE)); - if (entityLiving.getRidingEntity() == null) + if (entityLiving.getRidingEntity() == null) entityLiving.setPositionAndUpdate(position.x, position.y, position.z); data.remove("ContraptionDismountLocation"); } @@ -156,7 +155,6 @@ public class ContraptionCollider { double conRotY = contraptionRotation.y; double conRotZ = contraptionRotation.z; Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); - Vec3d conAngularMotion = contraptionRotation.subtract(contraptionEntity.getPrevRotationVec()); Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0); boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); Matrix3d rotation = null; @@ -287,19 +285,8 @@ public class ContraptionCollider { // entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue entity.fallDistance = 0; entity.onGround = true; - if (!serverPlayer) { - - Vec3d contactPoint = entityPosition.subtract(contraptionCentreOffset) - .subtract(contraptionPosition); - contactPoint = - VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z); - contactPoint = contactPoint.add(contraptionPosition) - .add(contraptionCentreOffset) - .add(conMotion); - contactPointMotion = contactPoint.subtract(entityPosition); - - DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); - } + if (!serverPlayer) + contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition); } if (hardCollision) { @@ -379,13 +366,6 @@ public class ContraptionCollider { return vec3d; } - @OnlyIn(Dist.CLIENT) - private static void checkForClientPlayerCollision(Entity entity) { - if (entity != Minecraft.getInstance().player) - return; - wasClientPlayerGrounded = true; - } - public static void pushEntityOutOfShape(Entity entity, VoxelShape voxelShape, Vec3d positionOffset, Vec3d shapeMotion) { AxisAlignedBB entityBB = entity.getBoundingBox() diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index 2dedebad0..bf1748e47 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -171,6 +171,11 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); } + @Override + public void remove() { + super.remove(); + } + @Override protected void removePassenger(Entity passenger) { Vec3d transformedVector = getPassengerPosition(passenger); @@ -219,24 +224,27 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return false; // Eject potential existing passenger + Entity toDismount = null; for (Entry entry : contraption.seatMapping.entrySet()) { if (entry.getValue() != indexOfSeat) continue; for (Entity entity : getPassengers()) { - if (!entry.getKey().equals(entity.getUniqueID())) + if (!entry.getKey() + .equals(entity.getUniqueID())) continue; if (entity instanceof PlayerEntity) return false; - if (!world.isRemote) { - Vec3d transformedVector = getPassengerPosition(entity); - entity.stopRiding(); - if (transformedVector != null) - entity.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z); - } - + toDismount = entity; } } + if (toDismount != null && !world.isRemote) { + Vec3d transformedVector = getPassengerPosition(toDismount); + toDismount.stopRiding(); + if (transformedVector != null) + toDismount.setPositionAndUpdate(transformedVector.x, transformedVector.y, transformedVector.z); + } + if (world.isRemote) return true; addSittingPassenger(player, indexOfSeat); @@ -623,12 +631,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD remove(); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); Vec3d rotation = getRotationVec(); - setBoundingBox(new AxisAlignedBB(0, 300, 0, 0, 300, 0)); contraption.addBlocksToWorld(world, offset, rotation, getPassengers()); + removePassengers(); // preventMovedEntitiesFromGettingStuck(); } } + @Override + public void onKillCommand() { + removePassengers(); + super.onKillCommand(); + } + + @Override + protected void outOfWorld() { + removePassengers(); + super.outOfWorld(); + } + + @Override + public void onRemovedFromWorld() { + super.onRemovedFromWorld(); + if (world != null && world.isRemote) + return; + getPassengers().forEach(Entity::remove); + } + @Override protected void doWaterSplashEffect() {} @@ -684,6 +712,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } } + @SuppressWarnings("deprecation") + @Override + public CompoundNBT writeWithoutTypeId(CompoundNBT nbt) { + Vec3d vec = getPositionVec(); + List passengers = getPassengers(); + List positionVecs = new ArrayList<>(passengers.size()); + + for (Entity entity : passengers) { + Vec3d prevVec = entity.getPositionVec(); + positionVecs.add(prevVec); + + // setPos has world accessing side-effects when removed == false + entity.removed = true; + + // Gather passengers into same chunk when saving + entity.setPos(vec.x, prevVec.y, vec.z); + + // Super requires all passengers to not be removed in order to write them to the + // tag + entity.removed = false; + } + + CompoundNBT tag = super.writeWithoutTypeId(nbt); + return tag; + } + public Contraption getContraption() { return contraption; } @@ -762,6 +816,20 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return new Vec3d(prevPosX, prevPosY, prevPosZ); } + public Vec3d getContactPointMotion(Vec3d globalContactPoint) { + Vec3d positionVec = getPositionVec(); + Vec3d conMotion = positionVec.subtract(getPrevPositionVec()); + Vec3d conAngularMotion = getRotationVec().subtract(getPrevRotationVec()); + Vec3d contraptionCentreOffset = stationary ? VecHelper.getCenterOf(BlockPos.ZERO) : Vec3d.ZERO.add(0, 0.5, 0); + Vec3d contactPoint = globalContactPoint.subtract(contraptionCentreOffset) + .subtract(positionVec); + contactPoint = VecHelper.rotate(contactPoint, conAngularMotion.x, conAngularMotion.y, conAngularMotion.z); + contactPoint = contactPoint.add(positionVec) + .add(contraptionCentreOffset) + .add(conMotion); + return contactPoint.subtract(globalContactPoint); + } + public boolean canCollideWith(Entity e) { if (e instanceof PlayerEntity && e.isSpectator()) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java index 43140fb09..b9c4ea478 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/LinearActuatorTileEntity.java @@ -3,11 +3,8 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pi import java.util.List; import com.simibubi.create.content.contraptions.base.KineticTileEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionCollider; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.IControlContraption; -import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour; @@ -42,7 +39,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); movementMode = new ScrollOptionBehaviour<>(MovementMode.class, Lang.translate("contraptions.movement_mode"), - this, getMovementModeSlot()); + this, getMovementModeSlot()); movementMode.requiresWrench(); movementMode.withCallback(t -> waitingForSpeedChange = false); behaviours.add(movementMode); @@ -208,15 +205,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme protected abstract Vec3d toPosition(float offset); - protected void visitNewPosition() { - if (!world.isRemote) - return; - if (!ContraptionCollider.wasClientPlayerGrounded) - return; - // Send falldamage-cancel for the colliding player - ContraptionCollider.wasClientPlayerGrounded = false; - AllPackets.channel.sendToServer(new CancelPlayerFallPacket()); - } + protected void visitNewPosition() {} protected void tryDisassemble() { if (removed) { diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index a8b304c24..0f7c095af 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -5,7 +5,6 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; -import com.simibubi.create.content.contraptions.components.structureMovement.CancelPlayerFallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; @@ -45,7 +44,6 @@ public enum AllPackets { CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new), CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new), CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), - CANCEL_FALL(CancelPlayerFallPacket.class, CancelPlayerFallPacket::new), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), From f48d1f7b1c3eae6265e2bac8b43b5908611919d5 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 22 Jul 2020 18:56:48 +0200 Subject: [PATCH 13/17] Pick me up - Seats now pick up non-player entities when touching them while being moved - Seats now drop off entities when being moved into a solid block - Previously colliding entities now get moved to match their position on the placed structure on disassembly - Contraption motion no longer gets fed into the collision response for non-minecart contraptions - The server now gets frequent updates about client players riding a contraption, fixes instabilities with projectiles, damage and anti-fly detection - Players can now take fall damage when colliding with contraptions --- .../java/com/simibubi/create/AllShapes.java | 1 + .../components/actors/SeatBlock.java | 6 ++ .../actors/SeatMovementBehaviour.java | 79 +++++++++++++- .../structureMovement/ClientMotionPacket.java | 55 ++++++++++ .../structureMovement/Contraption.java | 50 +++++---- .../ContraptionCollider.java | 18 ++-- .../structureMovement/ContraptionEntity.java | 100 +++++------------- .../structureMovement/MovementContext.java | 5 +- .../structureMovement/StructureTransform.java | 7 ++ .../foundation/networking/AllPackets.java | 2 + 10 files changed, 221 insertions(+), 102 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 8e43223a2..095b94753 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -116,6 +116,7 @@ public class AllShapes { .build(), CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16), SEAT = cuboid(0, 0, 0, 16, 8, 16), + SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16), MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12) .build(), TURNTABLE_SHAPE = shape(1, 4, 1, 15, 8, 15).add(5, 0, 5, 11, 4, 11) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java index b5df0a8c2..fb4d5c96f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatBlock.java @@ -72,6 +72,12 @@ public class SeatBlock extends Block implements IPortableBlock { ISelectionContext p_220053_4_) { return AllShapes.SEAT; } + + @Override + public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, + ISelectionContext p_220071_4_) { + return AllShapes.SEAT_COLLISION; + } @Override public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java index 21d1b545c..e400628cd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/SeatMovementBehaviour.java @@ -1,9 +1,84 @@ package com.simibubi.create.content.contraptions.components.actors; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.block.SlabBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.state.properties.SlabType; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; public class SeatMovementBehaviour extends MovementBehaviour { - - + @Override + public void startMoving(MovementContext context) { + super.startMoving(context); + int indexOf = context.contraption.getSeats() + .indexOf(context.localPos); + context.data.putInt("SeatIndex", indexOf); + } + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + super.visitNewPosition(context, pos); + ContraptionEntity contraptionEntity = context.contraption.entity; + if (contraptionEntity == null) + return; + int index = context.data.getInt("SeatIndex"); + if (index == -1) + return; + + Map seatMapping = context.contraption.getSeatMapping(); + BlockState blockState = context.world.getBlockState(pos); + boolean slab = blockState.getBlock() instanceof SlabBlock && blockState.get(SlabBlock.TYPE) == SlabType.BOTTOM; + boolean solid = blockState.isSolid() || slab; + + // Occupied + if (seatMapping.containsValue(index)) { + if (!solid) + return; + Entity toDismount = null; + for (Map.Entry entry : seatMapping.entrySet()) { + if (entry.getValue() != index) + continue; + for (Entity entity : contraptionEntity.getPassengers()) { + if (!entry.getKey() + .equals(entity.getUniqueID())) + continue; + toDismount = entity; + } + } + if (toDismount != null) { + toDismount.stopRiding(); + Vec3d position = VecHelper.getCenterOf(pos) + .add(0, slab ? .5f : 1f, 0); + toDismount.setPositionAndUpdate(position.x, position.y, position.z); + toDismount.getPersistentData() + .remove("ContraptionDismountLocation"); + } + return; + } + + if (solid) + return; + + List entitiesWithinAABB = context.world.getEntitiesWithinAABB(LivingEntity.class, + new AxisAlignedBB(pos).shrink(1 / 16f), e -> !(e instanceof PlayerEntity)); + if (entitiesWithinAABB.isEmpty()) + return; + LivingEntity passenger = entitiesWithinAABB.get(0); + contraptionEntity.addSittingPassenger(passenger, index); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java new file mode 100644 index 000000000..17261237b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java @@ -0,0 +1,55 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ClientMotionPacket extends SimplePacketBase { + + private Vec3d motion; + private boolean onGround; + + public ClientMotionPacket(Vec3d motion, boolean onGround) { + this.motion = motion; + this.onGround = onGround; + } + + public ClientMotionPacket(PacketBuffer buffer) { + motion = new Vec3d(buffer.readFloat(), buffer.readFloat(), buffer.readFloat()); + onGround = buffer.readBoolean(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeFloat((float) motion.x); + buffer.writeFloat((float) motion.y); + buffer.writeFloat((float) motion.z); + buffer.writeBoolean(onGround); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity sender = context.get() + .getSender(); + if (sender == null) + return; + sender.setMotion(motion); + sender.onGround = onGround; + if (onGround) { + sender.handleFallDamage(sender.fallDistance, 1); + sender.fallDistance = 0; + sender.connection.floatingTickCount = 0; + } + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 6ad59f9b2..4989e3d36 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -89,6 +89,7 @@ public abstract class Contraption { public CombinedInvWrapper inventory; public List customRenderTEs; public Set> superglue; + public ContraptionEntity entity; public AxisAlignedBB bounds; public boolean stalled; @@ -203,13 +204,14 @@ public abstract class Contraption { } public void mountPassengers(ContraptionEntity contraptionEntity) { + this.entity = contraptionEntity; if (contraptionEntity.world.isRemote) return; - for (BlockPos seatPos : seats) { + for (BlockPos seatPos : getSeats()) { Entity passenger = initialPassengers.get(seatPos); if (passenger == null) continue; - int seatIndex = seats.indexOf(seatPos); + int seatIndex = getSeats().indexOf(seatPos); if (seatIndex == -1) continue; contraptionEntity.addSittingPassenger(passenger, seatIndex); @@ -252,7 +254,7 @@ public abstract class Contraption { // Seats transfer their passenger to the contraption if (state.getBlock() instanceof SeatBlock) { BlockPos local = toLocalPos(pos); - seats.add(local); + getSeats().add(local); List seatsEntities = world.getEntitiesWithinAABB(SeatEntity.class, new AxisAlignedBB(pos)); if (!seatsEntities.isEmpty()) { SeatEntity seat = seatsEntities.get(0); @@ -516,11 +518,12 @@ public abstract class Contraption { if (nbt.contains("BoundsFront")) bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5)); - seats.clear(); - NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), c -> seats.add(NBTUtil.readBlockPos(c))); - seatMapping.clear(); + getSeats().clear(); + NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), + c -> getSeats().add(NBTUtil.readBlockPos(c))); + getSeatMapping().clear(); NBTHelper.iterateCompoundList(nbt.getList("Passengers", NBT.TAG_COMPOUND), - c -> seatMapping.put(NBTUtil.readUniqueId(c.getCompound("Id")), c.getInt("Seat"))); + c -> getSeatMapping().put(NBTUtil.readUniqueId(c.getCompound("Id")), c.getInt("Seat"))); stalled = nbt.getBoolean("Stalled"); anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor")); @@ -568,8 +571,8 @@ public abstract class Contraption { storageNBT.add(c); } - nbt.put("Seats", NBTHelper.writeCompoundList(seats, NBTUtil::writeBlockPos)); - nbt.put("Passengers", NBTHelper.writeCompoundList(seatMapping.entrySet(), e -> { + nbt.put("Seats", NBTHelper.writeCompoundList(getSeats(), NBTUtil::writeBlockPos)); + nbt.put("Passengers", NBTHelper.writeCompoundList(getSeatMapping().entrySet(), e -> { CompoundNBT tag = new CompoundNBT(); tag.put("Id", NBTUtil.writeUniqueId(e.getKey())); tag.putInt("Seat", e.getValue()); @@ -635,10 +638,8 @@ public abstract class Contraption { } } - public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation, List seatedEntities) { + public void addBlocksToWorld(World world, StructureTransform transform) { stop(world); - StructureTransform transform = new StructureTransform(offset, rotation); - for (boolean nonBrittles : Iterate.trueAndFalse) { for (BlockInfo block : blocks.values()) { if (nonBrittles == BlockMovementTraits.isBrittle(block.state)) @@ -718,12 +719,14 @@ public abstract class Contraption { world.addEntity(entity); } } + } + public void addPassengersToWorld(World world, StructureTransform transform, List seatedEntities) { for (Entity seatedEntity : seatedEntities) { - if (seatMapping.isEmpty()) + if (getSeatMapping().isEmpty()) continue; - Integer seatIndex = seatMapping.get(seatedEntity.getUniqueID()); - BlockPos seatPos = seats.get(seatIndex); + Integer seatIndex = getSeatMapping().get(seatedEntity.getUniqueID()); + BlockPos seatPos = getSeats().get(seatIndex); seatPos = transform.apply(seatPos); if (!(world.getBlockState(seatPos) .getBlock() instanceof SeatBlock)) @@ -732,7 +735,6 @@ public abstract class Contraption { continue; SeatBlock.sitDown(world, seatPos, seatedEntity); } - } public void initActors(World world) { @@ -796,14 +798,22 @@ public abstract class Contraption { } public BlockPos getSeat(UUID entityId) { - if (!seatMapping.containsKey(entityId)) + if (!getSeatMapping().containsKey(entityId)) return null; - int seatIndex = seatMapping.get(entityId); - if (seatIndex >= seats.size()) + int seatIndex = getSeatMapping().get(entityId); + if (seatIndex >= getSeats().size()) return null; - return seats.get(seatIndex); + return getSeats().get(seatIndex); } protected abstract AllContraptionTypes getType(); + public Map getSeatMapping() { + return seatMapping; + } + + public List getSeats() { + return seats; + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index d90f71db4..e8369ef14 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -23,6 +23,7 @@ import com.simibubi.create.content.contraptions.components.actors.BlockBreakingM import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.OrientedBB; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; @@ -143,6 +144,8 @@ public class ContraptionCollider { AxisAlignedBB bounds = contraptionEntity.getBoundingBox(); Vec3d contraptionPosition = contraptionEntity.getPositionVec(); Vec3d contraptionRotation = contraptionEntity.getRotationVec(); + Vec3d contraptionMotion = contraptionEntity.stationary ? Vec3d.ZERO + : contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); contraptionEntity.collidingEntities.clear(); if (contraption == null) @@ -154,14 +157,14 @@ public class ContraptionCollider { double conRotX = contraptionRotation.x; double conRotY = contraptionRotation.y; double conRotZ = contraptionRotation.z; - Vec3d conMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); Vec3d contraptionCentreOffset = contraptionEntity.stationary ? centerOfBlock : Vec3d.ZERO.add(0, 0.5, 0); boolean axisAlignedCollision = contraptionRotation.equals(Vec3d.ZERO); Matrix3d rotation = null; for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2) .expand(0, 32, 0), contraptionEntity::canCollideWith)) { - boolean serverPlayer = entity instanceof PlayerEntity && !world.isRemote; + boolean player = entity instanceof PlayerEntity; + boolean serverPlayer = player && !world.isRemote; // Init matrix if (rotation == null) { @@ -199,8 +202,8 @@ public class ContraptionCollider { // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); obb.setRotation(rotation); - motion = motion.subtract(conMotion); motion = rotation.transform(motion); + motion = motion.subtract(contraptionMotion); // Vec3d visualizerOrigin = new Vec3d(10, 64, 0); // CollisionDebugger.OBB = obb.copy(); @@ -268,7 +271,7 @@ public class ContraptionCollider { rotation.transpose(); motionResponse = rotation.transform(motionResponse) - .add(conMotion); + .add(contraptionMotion); totalResponse = rotation.transform(totalResponse); rotation.transpose(); @@ -282,10 +285,10 @@ public class ContraptionCollider { Vec3d contactPointMotion = Vec3d.ZERO; if (surfaceCollision.isTrue()) { -// entity.handleFallDamage(entity.fallDistance, 1); tunnelling issue entity.fallDistance = 0; entity.onGround = true; - if (!serverPlayer) + contraptionEntity.collidingEntities.add(entity); + if (!serverPlayer) contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition); } @@ -321,6 +324,9 @@ public class ContraptionCollider { entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, entityPosition.z + allowedMovement.z); entity.setMotion(entityMotion); + + if (!serverPlayer && player) + AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true)); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index bf1748e47..2f468a4e8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -7,11 +7,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.UUID; -import java.util.stream.Stream; import org.apache.commons.lang3.tuple.MutablePair; -import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllEntityTypes; import com.simibubi.create.content.contraptions.components.actors.SeatEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingContraption; @@ -49,15 +47,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.Hand; -import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.shapes.IBooleanFunction; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; @@ -166,9 +159,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD passenger.startRiding(this, true); if (world.isRemote) return; - contraption.seatMapping.put(passenger.getUniqueID(), seatIndex); + contraption.getSeatMapping() + .put(passenger.getUniqueID(), seatIndex); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + new ContraptionSeatMappingPacket(getEntityId(), contraption.getSeatMapping())); } @Override @@ -185,9 +179,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (transformedVector != null) passenger.getPersistentData() .put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector)); - contraption.seatMapping.remove(passenger.getUniqueID()); + contraption.getSeatMapping() + .remove(passenger.getUniqueID()); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionSeatMappingPacket(getEntityId(), contraption.seatMapping)); + new ContraptionSeatMappingPacket(getEntityId(), contraption.getSeatMapping())); } @Override @@ -199,7 +194,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD return; callback.accept(passenger, transformedVector.x, transformedVector.y, transformedVector.z); } - + protected Vec3d getPassengerPosition(Entity passenger) { AxisAlignedBB bb = passenger.getBoundingBox(); double ySize = bb.getYSize(); @@ -214,18 +209,21 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected boolean canFitPassenger(Entity p_184219_1_) { - return getPassengers().size() < contraption.seats.size(); + return getPassengers().size() < contraption.getSeats() + .size(); } public boolean handlePlayerInteraction(PlayerEntity player, BlockPos localPos, Direction side, Hand interactionHand) { - int indexOfSeat = contraption.seats.indexOf(localPos); + int indexOfSeat = contraption.getSeats() + .indexOf(localPos); if (indexOfSeat == -1) return false; // Eject potential existing passenger Entity toDismount = null; - for (Entry entry : contraption.seatMapping.entrySet()) { + for (Entry entry : contraption.getSeatMapping() + .entrySet()) { if (entry.getValue() != indexOfSeat) continue; for (Entity entity : getPassengers()) { @@ -631,9 +629,20 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD remove(); BlockPos offset = new BlockPos(getAnchorVec().add(.5, .5, .5)); Vec3d rotation = getRotationVec(); - contraption.addBlocksToWorld(world, offset, rotation, getPassengers()); + StructureTransform transform = new StructureTransform(offset, rotation); + contraption.addBlocksToWorld(world, transform); + contraption.addPassengersToWorld(world, transform, getPassengers()); removePassengers(); -// preventMovedEntitiesFromGettingStuck(); + + for (Entity entity : collidingEntities) { + Vec3d positionVec = getPositionVec(); + Vec3d localVec = entity.getPositionVec() + .subtract(positionVec); + localVec = VecHelper.rotate(localVec, getRotationVec().scale(-1)); + Vec3d transformed = transform.apply(localVec); + entity.setPositionAndUpdate(transformed.x, transformed.y, transformed.z); + } + } } @@ -660,73 +669,18 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @Override protected void doWaterSplashEffect() {} - public void preventMovedEntitiesFromGettingStuck() { - Vec3d stuckTest = new Vec3d(0, -2, 0); - for (Entity e : collidingEntities) { - e.fallDistance = 0; - e.onGround = true; - - Vec3d vec = stuckTest; - AxisAlignedBB axisalignedbb = e.getBoundingBox() - .offset(0, 2, 0); - ISelectionContext iselectioncontext = ISelectionContext.forEntity(this); - VoxelShape voxelshape = e.world.getWorldBorder() - .getShape(); - Stream stream = - VoxelShapes.compare(voxelshape, VoxelShapes.create(axisalignedbb.shrink(1.0E-7D)), IBooleanFunction.AND) - ? Stream.empty() - : Stream.of(voxelshape); - Stream stream1 = - this.world.getEmptyCollisionShapes(e, axisalignedbb.expand(vec), ImmutableSet.of()); - ReuseableStream reuseablestream = new ReuseableStream<>(Stream.concat(stream1, stream)); - Vec3d vec3d = vec.lengthSquared() == 0.0D ? vec - : collideBoundingBoxHeuristically(this, vec, axisalignedbb, e.world, iselectioncontext, - reuseablestream); - boolean flag = vec.x != vec3d.x; - boolean flag1 = vec.y != vec3d.y; - boolean flag2 = vec.z != vec3d.z; - boolean flag3 = e.onGround || flag1 && vec.y < 0.0D; - if (this.stepHeight > 0.0F && flag3 && (flag || flag2)) { - Vec3d vec3d1 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, (double) e.stepHeight, vec.z), - axisalignedbb, e.world, iselectioncontext, reuseablestream); - Vec3d vec3d2 = collideBoundingBoxHeuristically(e, new Vec3d(0.0D, (double) e.stepHeight, 0.0D), - axisalignedbb.expand(vec.x, 0.0D, vec.z), e.world, iselectioncontext, reuseablestream); - if (vec3d2.y < (double) e.stepHeight) { - Vec3d vec3d3 = collideBoundingBoxHeuristically(e, new Vec3d(vec.x, 0.0D, vec.z), - axisalignedbb.offset(vec3d2), e.world, iselectioncontext, reuseablestream).add(vec3d2); - if (horizontalMag(vec3d3) > horizontalMag(vec3d1)) { - vec3d1 = vec3d3; - } - } - - if (horizontalMag(vec3d1) > horizontalMag(vec3d)) { - vec3d = vec3d1.add(collideBoundingBoxHeuristically(e, new Vec3d(0.0D, -vec3d1.y + vec.y, 0.0D), - axisalignedbb.offset(vec3d1), e.world, iselectioncontext, reuseablestream)); - } - } - - vec = vec3d.subtract(stuckTest); - if (vec.equals(Vec3d.ZERO)) - continue; - e.setPosition(e.getX() + vec.x, e.getY() + vec.y, e.getZ() + vec.z); - } - } - @SuppressWarnings("deprecation") @Override public CompoundNBT writeWithoutTypeId(CompoundNBT nbt) { Vec3d vec = getPositionVec(); List passengers = getPassengers(); - List positionVecs = new ArrayList<>(passengers.size()); for (Entity entity : passengers) { - Vec3d prevVec = entity.getPositionVec(); - positionVecs.add(prevVec); - // setPos has world accessing side-effects when removed == false entity.removed = true; // Gather passengers into same chunk when saving + Vec3d prevVec = entity.getPositionVec(); entity.setPos(vec.x, prevVec.y, vec.z); // Super requires all passengers to not be removed in order to write them to the diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java index 8b1ad911f..c3228b4c5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovementContext.java @@ -4,6 +4,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; @@ -17,6 +18,7 @@ public class MovementContext { public Vec3d rotation; public World world; public BlockState state; + public BlockPos localPos; public CompoundNBT tileData; public boolean stall; @@ -29,7 +31,8 @@ public class MovementContext { this.world = world; this.state = info.state; this.tileData = info.nbt; - + localPos = info.pos; + firstMovement = true; motion = Vec3d.ZERO; relativeMotion = Vec3d.ZERO; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java index a152542f7..ded55dfad 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java @@ -69,6 +69,13 @@ public class StructureTransform { } + public Vec3d apply(Vec3d localVec) { + Vec3d vec = localVec; + vec = VecHelper.rotateCentered(vec, angle, rotationAxis); + vec = vec.add(new Vec3d(offset)); + return vec; + } + public BlockPos apply(BlockPos localPos) { Vec3d vec = VecHelper.getCenterOf(localPos); vec = VecHelper.rotateCentered(vec, angle, rotationAxis); diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 0f7c095af..bd2e888da 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -5,6 +5,7 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.structureMovement.ClientMotionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; @@ -46,6 +47,7 @@ public enum AllPackets { CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new), + CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new), PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), // Server to Client From 8087d7013c69c601a5c0033db44a1e03446f4377 Mon Sep 17 00:00:00 2001 From: tterrag Date: Wed, 22 Jul 2020 23:37:42 -0400 Subject: [PATCH 14/17] Fix server crash when using heater on a spawner --- .../processing/HeaterBlockItem.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java index 88be8b0f2..7235bb978 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java @@ -1,10 +1,14 @@ package com.simibubi.create.content.contraptions.processing; +import java.util.ArrayList; +import java.util.List; + import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import mcp.MethodsReturnNonnullByDefault; +import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; +import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.monster.BlazeEntity; import net.minecraft.entity.player.PlayerEntity; @@ -16,8 +20,12 @@ import net.minecraft.tileentity.MobSpawnerTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.WeightedSpawnerEntity; import net.minecraft.world.World; +import net.minecraft.world.spawner.AbstractSpawner; import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault @@ -30,13 +38,24 @@ public class HeaterBlockItem extends BlockItem { public ActionResultType onItemUse(ItemUseContext context) { TileEntity te = context.getWorld() .getTileEntity(context.getPos()); - if (te instanceof MobSpawnerTileEntity && ((MobSpawnerTileEntity) te).getSpawnerBaseLogic() - .getCachedEntity() instanceof BlazeEntity) { - ItemStack itemWithBlaze = withBlaze(context.getItem()); - context.getItem() - .shrink(1); - dropOrPlaceBack(context.getWorld(), context.getPlayer(), itemWithBlaze); - return ActionResultType.SUCCESS; + if (te instanceof MobSpawnerTileEntity) { + AbstractSpawner spawner = ((MobSpawnerTileEntity) te).getSpawnerBaseLogic(); + List possibleSpawns = ObfuscationReflectionHelper + .getPrivateValue(AbstractSpawner.class, spawner, "field_98285_e"); + if (possibleSpawns.isEmpty()) { + possibleSpawns = new ArrayList<>(); + possibleSpawns.add( + ObfuscationReflectionHelper.getPrivateValue(AbstractSpawner.class, spawner, "field_98282_f")); + } + for (WeightedSpawnerEntity e : possibleSpawns) { + if (new ResourceLocation(e.getNbt().getString("id")).equals(EntityType.BLAZE.getRegistryName())) { + ItemStack itemWithBlaze = withBlaze(context.getItem()); + context.getItem() + .shrink(1); + dropOrPlaceBack(context.getWorld(), context.getPlayer(), itemWithBlaze); + return ActionResultType.SUCCESS; + } + } } return super.onItemUse(context); } From f2b8d8530375a93f1519ff087581eb47b7288a65 Mon Sep 17 00:00:00 2001 From: tterrag Date: Thu, 23 Jul 2020 01:34:58 -0400 Subject: [PATCH 15/17] Better blaze head rotation --- .../processing/HeaterRenderer.java | 27 ++----- .../processing/HeaterTileEntity.java | 73 ++++++++++++++++++- 2 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java index bb4750280..e7c71e2e7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java @@ -1,21 +1,18 @@ package com.simibubi.create.content.contraptions.processing; +import java.util.HashMap; + import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.SuperByteBuffer; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.util.Direction; -import java.util.HashMap; - public class HeaterRenderer extends SafeTileEntityRenderer { - private static final Minecraft INSTANCE = Minecraft.getInstance(); private static final HashMap blazeModelMap = new HashMap<>(); public HeaterRenderer(TileEntityRendererDispatcher dispatcher) { @@ -30,23 +27,9 @@ public class HeaterRenderer extends SafeTileEntityRenderer { int light, int overlay) { AllBlockPartials blazeModel = blazeModelMap.getOrDefault(te.getHeatLevel(), AllBlockPartials.BLAZE_HEATER_BLAZE_ONE); - - float angle; - if (INSTANCE.player == null) { - angle = 0; - } else { - Vector3f difference = new Vector3f(INSTANCE.player.getPositionVector() - .subtract(te.getPos() - .getX() + 0.5, 0, - te.getPos() - .getZ() + 0.5) - .mul(1, 0, 1)); - difference.normalize(); - angle = (float) ((difference.getX() < 0 ? 1 : -1) * Math.acos(Direction.NORTH.getUnitVector() - .dot(difference))); - } + SuperByteBuffer blazeBuffer = blazeModel.renderOn(te.getBlockState()); - blazeBuffer.rotateCentered(Direction.UP, angle); - blazeBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid())); + blazeBuffer.rotateCentered(Direction.UP, (float) Math.toRadians(-te.rot + (te.speed * partialTicks))); + blazeBuffer.light(0xF000F0).renderInto(ms, buffer.getBuffer(RenderType.getSolid())); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java index cae5645e7..0b813f46e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java @@ -10,12 +10,15 @@ import com.simibubi.create.content.contraptions.particle.CubeParticleData; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.EggEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.TileEntity; import net.minecraft.particles.IParticleData; +import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; @@ -42,6 +45,9 @@ public class HeaterTileEntity extends SmartTileEntity { private int remainingBurnTime; private FuelType activeFuel; + + // Rendering state + float rot, speed; public HeaterTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); @@ -53,6 +59,9 @@ public class HeaterTileEntity extends SmartTileEntity { @Override public void tick() { super.tick(); + if (world.isRemote) { + tickRotation(); + } spawnParticles(getHeatLevel()); @@ -71,6 +80,68 @@ public class HeaterTileEntity extends SmartTileEntity { } markDirty(); } + + private static final float MAX_ROT_SPEED = 5; + private static final float ROT_DAMPING = 15; + + private void tickRotation() { + ClientPlayerEntity player = Minecraft.getInstance().player; + Angle target; + if (player == null) { + target = new Angle(360, 0); + } else { + double dx = player.getX() - (getPos().getX() + 0.5); + double dz = player.getZ() - (getPos().getZ() + 0.5); + target = new Angle(360, (float) (MathHelper.atan2(dz, dx) * 180.0 / Math.PI + 90)); + } + + Angle current = new Angle(360, rot); + float diff = new Angle(180, current.get() - target.get()).get(); + if (diff > 0.1 || diff < -0.1) { + // Inverse function https://www.desmos.com/calculator/kiaberb6sf + speed = MAX_ROT_SPEED + (-MAX_ROT_SPEED / ((Math.abs(diff) / ROT_DAMPING) + 1)); + if (diff > 0) { + current.add(-Math.min(diff, speed)); + speed = Math.min(diff, speed); + } else { + current.add(Math.min(-diff, speed)); + speed = Math.min(-diff, -speed); + } + } else { + speed = 0; + } + + rot = current.get(); + } + + // From EnderIO with <3 + private static class Angle { + private final float offset; + private float a; + + Angle(float offset, float a) { + this.offset = offset; + set(a); + } + + void set(float a) { + while (a >= offset) { + a -= 360; + } + while (a < (offset - 360)) { + a += 360; + } + this.a = a; + } + + void add(float b) { + set(a + b); + } + + float get() { + return a; + } + } @Override public void lazyTick() { From 80406e87822cb916e1583c140ad5912c1985db67 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 23 Jul 2020 17:41:15 +0200 Subject: [PATCH 16/17] Cleanup crew - More refactors and enhancements to the blaze burner --- src/generated/resources/.cache/cache | 35 ++-- .../create/blockstates/blaze_burner.json | 7 + .../create/blockstates/blaze_heater.json | 7 - .../resources/assets/create/lang/en_ud.json | 3 +- .../resources/assets/create/lang/en_us.json | 3 +- .../assets/create/lang/unfinished/de_de.json | 5 +- .../assets/create/lang/unfinished/fr_fr.json | 5 +- .../assets/create/lang/unfinished/it_it.json | 5 +- .../assets/create/lang/unfinished/ja_jp.json | 5 +- .../assets/create/lang/unfinished/ko_kr.json | 5 +- .../assets/create/lang/unfinished/nl_nl.json | 5 +- .../assets/create/lang/unfinished/pt_br.json | 5 +- .../assets/create/lang/unfinished/ru_ru.json | 5 +- .../assets/create/lang/unfinished/zh_cn.json | 5 +- .../create/models/item/blaze_burner.json | 3 + .../create/models/item/blaze_heater.json | 3 - .../models/item/empty_blaze_burner.json | 3 + .../loot_tables/blocks/blaze_burner.json | 90 +++++++++ .../loot_tables/blocks/blaze_heater.json | 19 -- .../data/create/tags/blocks/fan_heaters.json | 2 +- .../create/tags/blocks/fan_transparent.json | 2 +- .../com/simibubi/create/AllBlockPartials.java | 19 +- .../java/com/simibubi/create/AllBlocks.java | 10 +- .../java/com/simibubi/create/AllItems.java | 6 + .../com/simibubi/create/AllTileEntities.java | 8 +- .../simibubi/create/compat/jei/CreateJEI.java | 2 +- .../compat/jei/category/MixingCategory.java | 4 +- ...zeHeater.java => AnimatedBlazeBurner.java} | 28 +-- .../components/fan/AirCurrent.java | 4 +- .../components/fan/EncasedFanTileEntity.java | 4 +- .../mixer/MechanicalMixerTileEntity.java | 14 +- .../contraptions/processing/HeaterBlock.java | 144 ------------- .../processing/HeaterBlockItem.java | 92 --------- .../processing/HeaterRenderer.java | 35 ---- .../processing/burner/BlazeBurnerBlock.java | 184 +++++++++++++++++ .../burner/BlazeBurnerBlockItem.java | 167 +++++++++++++++ .../burner/BlazeBurnerRenderer.java | 39 ++++ .../BlazeBurnerTileEntity.java} | 37 ++-- .../content/logistics/InWorldProcessing.java | 10 +- .../create/foundation/data/BlockStateGen.java | 4 +- .../create/foundation/utility/VecHelper.java | 6 +- .../block/blaze_burner/blaze/fading.json | 23 +++ .../block/blaze_burner/blaze/kindled.json | 23 +++ .../block/blaze_burner/blaze/seething.json | 22 ++ .../block/blaze_burner/blaze/smouldering.json | 22 ++ .../{blaze_heater => blaze_burner}/block.json | 71 ++++--- .../block/blaze_burner/block_with_blaze.json | 191 ++++++++++++++++++ .../models/block/blaze_heater/blaze/four.json | 29 --- .../models/block/blaze_heater/blaze/one.json | 28 --- .../block/blaze_heater/blaze/three.json | 29 --- .../models/block/blaze_heater/blaze/two.json | 29 --- .../textures/block/blaze_burner_inner.png | Bin 0 -> 567 bytes .../textures/block/blaze_burner_side.png | Bin 0 -> 518 bytes .../create/textures/block/blaze_kindled.png | Bin 0 -> 530 bytes .../create/textures/block/blaze_seething.png | Bin 0 -> 536 bytes .../textures/block/blaze_smouldering.png | Bin 0 -> 585 bytes .../textures/block/dark_metal_block.png | Bin 0 -> 305 bytes .../create/textures/block/tamed_blaze.png | Bin 1538 -> 0 bytes 58 files changed, 940 insertions(+), 566 deletions(-) create mode 100644 src/generated/resources/assets/create/blockstates/blaze_burner.json delete mode 100644 src/generated/resources/assets/create/blockstates/blaze_heater.json create mode 100644 src/generated/resources/assets/create/models/item/blaze_burner.json delete mode 100644 src/generated/resources/assets/create/models/item/blaze_heater.json create mode 100644 src/generated/resources/assets/create/models/item/empty_blaze_burner.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/blaze_burner.json delete mode 100644 src/generated/resources/data/create/loot_tables/blocks/blaze_heater.json rename src/main/java/com/simibubi/create/compat/jei/category/animations/{AnimatedBlazeHeater.java => AnimatedBlazeBurner.java} (57%) delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlock.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java delete mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlockItem.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerRenderer.java rename src/main/java/com/simibubi/create/content/contraptions/processing/{HeaterTileEntity.java => burner/BlazeBurnerTileEntity.java} (86%) create mode 100644 src/main/resources/assets/create/models/block/blaze_burner/blaze/fading.json create mode 100644 src/main/resources/assets/create/models/block/blaze_burner/blaze/kindled.json create mode 100644 src/main/resources/assets/create/models/block/blaze_burner/blaze/seething.json create mode 100644 src/main/resources/assets/create/models/block/blaze_burner/blaze/smouldering.json rename src/main/resources/assets/create/models/block/{blaze_heater => blaze_burner}/block.json (58%) create mode 100644 src/main/resources/assets/create/models/block/blaze_burner/block_with_blaze.json delete mode 100644 src/main/resources/assets/create/models/block/blaze_heater/blaze/four.json delete mode 100644 src/main/resources/assets/create/models/block/blaze_heater/blaze/one.json delete mode 100644 src/main/resources/assets/create/models/block/blaze_heater/blaze/three.json delete mode 100644 src/main/resources/assets/create/models/block/blaze_heater/blaze/two.json create mode 100644 src/main/resources/assets/create/textures/block/blaze_burner_inner.png create mode 100644 src/main/resources/assets/create/textures/block/blaze_burner_side.png create mode 100644 src/main/resources/assets/create/textures/block/blaze_kindled.png create mode 100644 src/main/resources/assets/create/textures/block/blaze_seething.png create mode 100644 src/main/resources/assets/create/textures/block/blaze_smouldering.png create mode 100644 src/main/resources/assets/create/textures/block/dark_metal_block.png delete mode 100644 src/main/resources/assets/create/textures/block/tamed_blaze.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 9af7474d5..6b94b1566 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -25,7 +25,7 @@ f25693a9429f6337149ff24f27900dc4eb82a7c2 assets/create/blockstates/belt.json cf9045eb16e5299a1d917c4cb536289f49411276 assets/create/blockstates/birch_window.json 94a1a91403eb4b035fec48071e7fcae57a8a6abd assets/create/blockstates/birch_window_pane.json 58b07d2af6030342f0354f6d3fd0ee128d2d74b4 assets/create/blockstates/black_seat.json -0626725f70103a55dabcda6f87ca943279d45793 assets/create/blockstates/blaze_heater.json +923aeb2a556f67bc0526f237dd97af2d37b4c9f1 assets/create/blockstates/blaze_burner.json 4854d1ef52130a7887aecc60bcaffbd66f0871a8 assets/create/blockstates/blue_seat.json fba967b1f6e44b34a9d9662e2fedfc13aad7f36c assets/create/blockstates/brass_belt_funnel.json 8b1dd00adcc7e74c5a9feed069e2610b15a338cb assets/create/blockstates/brass_block.json @@ -300,7 +300,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl 3a739f9d4276828d83f2d2750bf3227c87bcd438 assets/create/blockstates/pulley_magnet.json 469e430d96cb0a5e1aaf6b7cc5d401d488c9e600 assets/create/blockstates/pulse_repeater.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json -4bb26546ac954604a0317b059f2c36a1123772cb assets/create/blockstates/radial_chassis.json +8d7e653bfd9846e684a0d3725595714a19201017 assets/create/blockstates/radial_chassis.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 8929677f2cc5354aa19ef182af69f9f0b41eb242 assets/create/blockstates/redstone_contact.json c29213b77ac0c78d8979c5f6188d2b265696f9b9 assets/create/blockstates/redstone_link.json @@ -354,17 +354,17 @@ c77b46d8b459e5c7cc495393546f3fcca8a1fa1d assets/create/blockstates/weathered_lim a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -8701a4473878ef76b77b853b7b5ee0e1570e35b5 assets/create/lang/en_ud.json -28b0c222c3bc23ade20b30acbeba4dff45b8aac6 assets/create/lang/en_us.json -99cfc3bf44135741f3cab754126c7b9020ca6afd assets/create/lang/unfinished/de_de.json -5eaf282418b78d3b642489f12d1d4e39a84c8158 assets/create/lang/unfinished/fr_fr.json -d8a9050112ff115115035e5af996cf67d1c7857f assets/create/lang/unfinished/it_it.json -52d6a899466025fafd1235486e8a142acd650827 assets/create/lang/unfinished/ja_jp.json -67249a783b7bdb3306b2616fa05675f446930cb9 assets/create/lang/unfinished/ko_kr.json -49d048a89d98ec8e15f91155f466f06634656e28 assets/create/lang/unfinished/nl_nl.json -c88f1d0814ddd3c8a7925372ea9d5f5677b2abe8 assets/create/lang/unfinished/pt_br.json -76c6a11afca6c102194f2b32a4e84c83d73e741c assets/create/lang/unfinished/ru_ru.json -e49755abda2b5df4c1a83fc058cf2693940259d1 assets/create/lang/unfinished/zh_cn.json +0f82b1cb0f026895a75feb06fba8c33b44d14711 assets/create/lang/en_ud.json +0c28bf9b20b27caa23ec5eb0cf77b3557cc07f19 assets/create/lang/en_us.json +2adfeab7ad690f28e21c885f5952d285430df646 assets/create/lang/unfinished/de_de.json +4faaa837fc1c9aa2734c4462970626cb7f8de9a8 assets/create/lang/unfinished/fr_fr.json +b2d7fac85167362bfed655394fe7a7ed31d76929 assets/create/lang/unfinished/it_it.json +57813585da4b9b3605c557ddc044cfd9839049eb assets/create/lang/unfinished/ja_jp.json +5349034d41e56df04d7c54bef0e17ee5941c8de4 assets/create/lang/unfinished/ko_kr.json +20b02ad64a22d931e62ad32bc880ba9a8b6b44f3 assets/create/lang/unfinished/nl_nl.json +321cf5d17bd7f881675125ac2b3ec79d85b2d364 assets/create/lang/unfinished/pt_br.json +8a23811e1d9fd60a96611071d140038e64977826 assets/create/lang/unfinished/ru_ru.json +06f2a0836d475ba095e8fcc11d5be4626c2eb11b assets/create/lang/unfinished/zh_cn.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json @@ -1027,7 +1027,7 @@ bf1fc6bdf7fca6f1958a2d3e96202c1cecb50669 assets/create/models/item/basin.json 9044243882cfd49a2827e1b910a4c9b0e46daa47 assets/create/models/item/birch_window.json 6ed49f59ea91068ef68720f43e67a9237594bdf0 assets/create/models/item/birch_window_pane.json 22632bd681c8a605f0845f7549770389a741156a assets/create/models/item/black_seat.json -fa2761dc44857eb840a94df869de66a91988f0da assets/create/models/item/blaze_heater.json +80a6e8b00709fe0521aca5b789ae17485ed9c56d assets/create/models/item/blaze_burner.json 0e1977585128fc0ecef640f72e5fc5e9fb47ef92 assets/create/models/item/blue_seat.json 17d340c3678bd24cb085ba49490b2b4cb341a9e7 assets/create/models/item/brass_block.json f5a18f4279c2e845a5967b1c2f9e807c2bb77afb assets/create/models/item/brass_casing.json @@ -1103,6 +1103,7 @@ be7de1e1529fb2a2e842204136520a760676d4e9 assets/create/models/item/dolomite_cobb e974cd23a5456baef8b634f2d21fd8c3822931ab assets/create/models/item/dolomite_pillar.json 82b73fafdb8bf4f0706012d5baab44cd0e1aa7bc assets/create/models/item/dough.json 36139f3de5fc9e57cb96f2d2daad108bc0635b7b assets/create/models/item/electron_tube.json +971be8e52e8dfef50c8329be83f9c5d5ea869279 assets/create/models/item/empty_blaze_burner.json 3bbf9f6b33ef075fb2e1d20d58a6169e2e942314 assets/create/models/item/empty_schematic.json f2d6b88c3174de01e16da555236727efc33b490c assets/create/models/item/encased_belt.json 250bd0716cc1f04b03892ab74eb0b3a0f32a6158 assets/create/models/item/encased_fan.json @@ -1837,7 +1838,7 @@ c7f81e30c31837a287d6d6040cdb02c7dec11441 data/create/loot_tables/blocks/belt.jso 67a8e2513c3cb09e6fe80279fda94f79d5018c37 data/create/loot_tables/blocks/birch_window.json bf1d5843f93533f84bc4adec5b77da2114fa2025 data/create/loot_tables/blocks/birch_window_pane.json cccc209d172cc7bac76f1b4ac79085ee90742ab2 data/create/loot_tables/blocks/black_seat.json -798ef290b388dee758df3e779b4b1c9289955f7b data/create/loot_tables/blocks/blaze_heater.json +a2313c9b7d114396fca3c86a740d23fce3873679 data/create/loot_tables/blocks/blaze_burner.json 3834f7ac2bbc42cead02d4973842adb9ad97e6bf data/create/loot_tables/blocks/blue_seat.json 1dbc446abe190b2832b2ce7d52c2f2d2bdd45949 data/create/loot_tables/blocks/brass_belt_funnel.json 70d9d4def43d5b31fa7cdc5ca5002c71cf4a90b0 data/create/loot_tables/blocks/brass_block.json @@ -2543,8 +2544,8 @@ d3fdb8ece6cb072a93ddb64a0baad5ac952117a4 data/create/recipes/weathered_limestone 11667414f73bc2d00bda7c5c1a7d2934bf6e9165 data/create/recipes/weathered_limestone_pillar_from_weathered_limestone_stonecutting.json 266f08e604d229a9d2b46f7272c0b06ec270bf3d data/create/recipes/zinc_block.json 4ace4302e3f0ee8ca063c150a046deab06c52710 data/create/tags/blocks/brittle.json -228290109dd691e508cad11547e30d30bf111c3f data/create/tags/blocks/fan_heaters.json -74ad330d6e347b339002a9d83be7061c1c91ae26 data/create/tags/blocks/fan_transparent.json +246ee2ec4e778e38a362f319506564886d4e0e76 data/create/tags/blocks/fan_heaters.json +798ef82869dbe22682121504a372e95607a785dc data/create/tags/blocks/fan_transparent.json 081f5aa35602fc27af2ca01ea9f2fd5e7eb284dc data/create/tags/items/create_ingots.json d2dc4ff179ef7b2aa9276455c196e15d44aa95a8 data/create/tags/items/crushed_ores.json 16bcb8fcbe9170c2c11f1ca8d99d8b36cd812bbd data/forge/tags/blocks/glass/colorless.json diff --git a/src/generated/resources/assets/create/blockstates/blaze_burner.json b/src/generated/resources/assets/create/blockstates/blaze_burner.json new file mode 100644 index 000000000..076b83aae --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/blaze_burner.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "create:block/blaze_burner/block" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/blaze_heater.json b/src/generated/resources/assets/create/blockstates/blaze_heater.json deleted file mode 100644 index ede37bfd8..000000000 --- a/src/generated/resources/assets/create/blockstates/blaze_heater.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "create:block/blaze_heater/block" - } - } -} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index f114a594d..df347443d 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -26,7 +26,7 @@ "block.create.birch_window": "\u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA", "block.create.birch_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA", "block.create.black_seat": "\u0287\u0250\u01DDS \u029E\u0254\u0250\u05DF\u15FA", - "block.create.blaze_heater": "\u0279\u01DD\u0287\u0250\u01DDH \u01DDz\u0250\u05DF\u15FA", + "block.create.blaze_burner": "\u0279\u01DDu\u0279n\u15FA \u01DDz\u0250\u05DF\u15FA", "block.create.blue_seat": "\u0287\u0250\u01DDS \u01DDn\u05DF\u15FA", "block.create.brass_belt_funnel": "\u05DF\u01DDuun\u2132 \u0287\u05DF\u01DD\u15FA ss\u0250\u0279\u15FA", "block.create.brass_block": "\u029E\u0254o\u05DF\u15FA ss\u0250\u0279\u15FA", @@ -379,6 +379,7 @@ "item.create.deforester": "\u0279\u01DD\u0287s\u01DD\u0279o\u025F\u01DD\u15E1", "item.create.dough": "\u0265bno\u15E1", "item.create.electron_tube": "\u01DDqn\u27D8 uo\u0279\u0287\u0254\u01DD\u05DF\u018E", + "item.create.empty_blaze_burner": "\u0279\u01DDu\u0279n\u15FA \u01DDz\u0250\u05DF\u15FA \u028E\u0287d\u026F\u018E", "item.create.empty_schematic": "\u0254\u0131\u0287\u0250\u026F\u01DD\u0265\u0254S \u028E\u0287d\u026F\u018E", "item.create.extendo_grip": "d\u0131\u0279\u2141 opu\u01DD\u0287x\u018E", "item.create.filter": "\u0279\u01DD\u0287\u05DF\u0131\u2132", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 247ee4ec8..883a7ee2d 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -29,7 +29,7 @@ "block.create.birch_window": "Birch Window", "block.create.birch_window_pane": "Birch Window Pane", "block.create.black_seat": "Black Seat", - "block.create.blaze_heater": "Blaze Heater", + "block.create.blaze_burner": "Blaze Burner", "block.create.blue_seat": "Blue Seat", "block.create.brass_belt_funnel": "Brass Belt Funnel", "block.create.brass_block": "Brass Block", @@ -384,6 +384,7 @@ "item.create.deforester": "Deforester", "item.create.dough": "Dough", "item.create.electron_tube": "Electron Tube", + "item.create.empty_blaze_burner": "Empty Blaze Burner", "item.create.empty_schematic": "Empty Schematic", "item.create.extendo_grip": "Extendo Grip", "item.create.filter": "Filter", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index e8795b6a1..175e62e23 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 809", + "_": "Missing Localizations: 810", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", @@ -385,6 +385,7 @@ "item.create.deforester": "UNLOCALIZED: Deforester", "item.create.dough": "Teig", "item.create.electron_tube": "UNLOCALIZED: Electron Tube", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Leerer Bauplan", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Filter", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index a65280c05..7c2fb3dc2 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 412", + "_": "Missing Localizations: 413", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", @@ -385,6 +385,7 @@ "item.create.deforester": "Déforesteur", "item.create.dough": "Pâte", "item.create.electron_tube": "Tube électronique", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Schéma vide", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Filtre", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 33f8cd547..a421aa963 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 396", + "_": "Missing Localizations: 397", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "Blocco di Ottone", @@ -385,6 +385,7 @@ "item.create.deforester": "Deforestatore", "item.create.dough": "Impasto", "item.create.electron_tube": "Valvola", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Schematica Vuota", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Filtro", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index dc910a63d..753b230e9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 391", + "_": "Missing Localizations: 392", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "真鍮ブロック", @@ -385,6 +385,7 @@ "item.create.deforester": "デフォレスター", "item.create.dough": "生地", "item.create.electron_tube": "電子管", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "空の概略図", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "フィルター", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index a13eeb763..1a896e625 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 396", + "_": "Missing Localizations: 397", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "황동 블럭", @@ -385,6 +385,7 @@ "item.create.deforester": "산림파괴자", "item.create.dough": "반죽", "item.create.electron_tube": "전지 튜브", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "빈 청사진", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "필터 틀", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 5c76d94ae..8a086de65 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 746", + "_": "Missing Localizations: 747", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", @@ -385,6 +385,7 @@ "item.create.deforester": "Ontbosser", "item.create.dough": "Deeg", "item.create.electron_tube": "UNLOCALIZED: Electron Tube", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Lege bouwtekening", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Filter", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 4472e40cc..843ab7e33 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 816", + "_": "Missing Localizations: 817", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", @@ -385,6 +385,7 @@ "item.create.deforester": "UNLOCALIZED: Deforester", "item.create.dough": "Massa", "item.create.electron_tube": "UNLOCALIZED: Electron Tube", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Esquema vazio", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Filtro", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 72bf40dd8..d996c9f99 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 810", + "_": "Missing Localizations: 811", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "UNLOCALIZED: Birch Window", "block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "UNLOCALIZED: Brass Block", @@ -385,6 +385,7 @@ "item.create.deforester": "UNLOCALIZED: Deforester", "item.create.dough": "Тесто", "item.create.electron_tube": "UNLOCALIZED: Electron Tube", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "Пустая схема", "item.create.extendo_grip": "UNLOCALIZED: Extendo Grip", "item.create.filter": "Фильтр", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 819593e4d..eab7d3c6a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 72", + "_": "Missing Localizations: 73", "_": "->------------------------] Game Elements [------------------------<-", @@ -30,7 +30,7 @@ "block.create.birch_window": "白桦窗户", "block.create.birch_window_pane": "白桦窗户板", "block.create.black_seat": "UNLOCALIZED: Black Seat", - "block.create.blaze_heater": "UNLOCALIZED: Blaze Heater", + "block.create.blaze_burner": "UNLOCALIZED: Blaze Burner", "block.create.blue_seat": "UNLOCALIZED: Blue Seat", "block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel", "block.create.brass_block": "黄铜块", @@ -385,6 +385,7 @@ "item.create.deforester": "树林毁灭者", "item.create.dough": "面团", "item.create.electron_tube": "电子管", + "item.create.empty_blaze_burner": "UNLOCALIZED: Empty Blaze Burner", "item.create.empty_schematic": "空白蓝图", "item.create.extendo_grip": "伸缩机械手", "item.create.filter": "过滤器", diff --git a/src/generated/resources/assets/create/models/item/blaze_burner.json b/src/generated/resources/assets/create/models/item/blaze_burner.json new file mode 100644 index 000000000..79214d256 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/blaze_burner.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/blaze_burner/block_with_blaze" +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/blaze_heater.json b/src/generated/resources/assets/create/models/item/blaze_heater.json deleted file mode 100644 index 40a3c3428..000000000 --- a/src/generated/resources/assets/create/models/item/blaze_heater.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "create:block/blaze_heater/block" -} \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/empty_blaze_burner.json b/src/generated/resources/assets/create/models/item/empty_blaze_burner.json new file mode 100644 index 000000000..a1a7275c1 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/empty_blaze_burner.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/blaze_burner/block" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/blaze_burner.json b/src/generated/resources/data/create/loot_tables/blocks/blaze_burner.json new file mode 100644 index 000000000..5e359f9ca --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/blaze_burner.json @@ -0,0 +1,90 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "condition": "minecraft:block_state_property", + "block": "create:blaze_burner", + "properties": { + "blaze": "none" + } + } + ], + "name": "create:empty_blaze_burner" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "condition": "minecraft:block_state_property", + "block": "create:blaze_burner", + "properties": { + "blaze": "smouldering" + } + } + ], + "name": "create:blaze_burner" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "condition": "minecraft:block_state_property", + "block": "create:blaze_burner", + "properties": { + "blaze": "fading" + } + } + ], + "name": "create:blaze_burner" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "condition": "minecraft:block_state_property", + "block": "create:blaze_burner", + "properties": { + "blaze": "kindled" + } + } + ], + "name": "create:blaze_burner" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "condition": "minecraft:block_state_property", + "block": "create:blaze_burner", + "properties": { + "blaze": "seething" + } + } + ], + "name": "create:blaze_burner" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/blaze_heater.json b/src/generated/resources/data/create/loot_tables/blocks/blaze_heater.json deleted file mode 100644 index 291dbd019..000000000 --- a/src/generated/resources/data/create/loot_tables/blocks/blaze_heater.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1, - "entries": [ - { - "type": "minecraft:item", - "name": "create:blaze_heater" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/create/tags/blocks/fan_heaters.json b/src/generated/resources/data/create/tags/blocks/fan_heaters.json index 7d6b87f02..ef385188e 100644 --- a/src/generated/resources/data/create/tags/blocks/fan_heaters.json +++ b/src/generated/resources/data/create/tags/blocks/fan_heaters.json @@ -1,7 +1,7 @@ { "replace": false, "values": [ - "create:blaze_heater", + "create:blaze_burner", "minecraft:magma_block", "minecraft:campfire", "minecraft:lava", diff --git a/src/generated/resources/data/create/tags/blocks/fan_transparent.json b/src/generated/resources/data/create/tags/blocks/fan_transparent.json index 099a5f090..68f9d3c80 100644 --- a/src/generated/resources/data/create/tags/blocks/fan_transparent.json +++ b/src/generated/resources/data/create/tags/blocks/fan_transparent.json @@ -1,7 +1,7 @@ { "replace": false, "values": [ - "create:blaze_heater", + "create:blaze_burner", "#minecraft:fences", "minecraft:iron_bars" ] diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 6dbff9bca..c0a1b9d1c 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.MatrixStacker; @@ -43,12 +44,11 @@ public class AllBlockPartials { BELT_DIAGONAL_MIDDLE = get("belt/diagonal_middle"), BELT_DIAGONAL_END = get("belt/diagonal_end"), - ENCASED_FAN_INNER = get("encased_fan/propeller"), HAND_CRANK_HANDLE = get("hand_crank/handle"), - MECHANICAL_PRESS_HEAD = get("mechanical_press/head"), MECHANICAL_MIXER_POLE = get("mechanical_mixer/pole"), - MECHANICAL_MIXER_HEAD = get("mechanical_mixer/head"), BLAZE_HEATER_BLAZE_ONE = get("blaze_heater/blaze/one"), - BLAZE_HEATER_BLAZE_TWO = get("blaze_heater/blaze/two"), - BLAZE_HEATER_BLAZE_THREE = get("blaze_heater/blaze/three"), - BLAZE_HEATER_BLAZE_FOUR = get("blaze_heater/blaze/four"), + ENCASED_FAN_INNER = get("encased_fan/propeller"), + HAND_CRANK_HANDLE = get("hand_crank/handle"), + MECHANICAL_PRESS_HEAD = get("mechanical_press/head"), + MECHANICAL_MIXER_POLE = get("mechanical_mixer/pole"), + MECHANICAL_MIXER_HEAD = get("mechanical_mixer/head"), MECHANICAL_CRAFTER_LID = get("mechanical_crafter/lid"), MECHANICAL_CRAFTER_ARROW = get("mechanical_crafter/arrow"), MECHANICAL_CRAFTER_BELT_FRAME = get("mechanical_crafter/belt"), @@ -97,6 +97,7 @@ public class AllBlockPartials { FLUID_PIPE_CASING = get("fluid_pipe/casing"); public static final Map PIPE_RIMS = map(); + public static final Map BLAZES = map(); static { populateMaps(); @@ -110,8 +111,12 @@ public class AllBlockPartials { private AllBlockPartials() {} private static void populateMaps() { - for (Direction d : Iterate.directions) { + for (Direction d : Iterate.directions) PIPE_RIMS.put(d, get("fluid_pipe/rim/" + d.getName())); + for (HeatLevel heat : HeatLevel.values()) { + if (heat == HeatLevel.NONE) + continue; + BLAZES.put(heat, get("blaze_burner/blaze/" + heat.getName())); } } diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index c30771a51..bd1fe7cfd 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -59,8 +59,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTankItem; import com.simibubi.create.content.contraptions.fluids.FluidTankModel; import com.simibubi.create.content.contraptions.fluids.PumpBlock; import com.simibubi.create.content.contraptions.processing.BasinBlock; -import com.simibubi.create.content.contraptions.processing.HeaterBlock; -import com.simibubi.create.content.contraptions.processing.HeaterBlockItem; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlockItem; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerBlock; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftGenerator; @@ -403,13 +403,15 @@ public class AllBlocks { .simpleItem() .register(); - public static final BlockEntry HEATER = REGISTRATE.block("blaze_heater", HeaterBlock::new) + public static final BlockEntry BLAZE_BURNER = REGISTRATE.block("blaze_burner", BlazeBurnerBlock::new) .initialProperties(SharedProperties::softMetal) .properties(p -> p.lightValue(12)) .addLayer(() -> RenderType::getCutoutMipped) .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag) + .loot((lt, block) -> lt.registerLootTable(block, BlazeBurnerBlock.buildLootTable())) .blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p))) - .item(HeaterBlockItem::new) + .item(BlazeBurnerBlockItem::withBlaze) + .model(AssetLookup.customItemModel("blaze_burner", "block_with_blaze")) .build() .register(); diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index 6ac8e3b60..ce9ed043d 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -14,6 +14,7 @@ import static com.simibubi.create.content.AllSections.SCHEMATICS; import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MinecartContraptionItem; import com.simibubi.create.content.contraptions.goggles.GogglesItem; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlockItem; import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorItem; import com.simibubi.create.content.contraptions.relays.gearbox.VerticalGearboxItem; import com.simibubi.create.content.contraptions.wrench.WrenchItem; @@ -121,6 +122,11 @@ public class AllItems { REGISTRATE.item("vertical_gearbox", VerticalGearboxItem::new) .model(AssetLookup.customItemModel("gearbox", "item_vertical")) .register(); + + public static final ItemEntry EMPTY_BLAZE_BURNER = + REGISTRATE.item("empty_blaze_burner", BlazeBurnerBlockItem::empty) + .model(AssetLookup.customItemModel("blaze_burner", "block")) + .register(); public static final ItemEntry SUPER_GLUE = REGISTRATE.item("super_glue", SuperGlueItem::new) .register(); diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index f191f5eac..fde940f3d 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -50,6 +50,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTankTileEntity; import com.simibubi.create.content.contraptions.fluids.PumpRenderer; import com.simibubi.create.content.contraptions.fluids.PumpTileEntity; import com.simibubi.create.content.contraptions.processing.*; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerRenderer; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerTileEntity; import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerRenderer; import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity; @@ -200,8 +202,8 @@ public class AllTileEntities { register("deployer", DeployerTileEntity::new, AllBlocks.DEPLOYER); public static final TileEntityEntry BASIN = register("basin", BasinTileEntity::new, AllBlocks.BASIN); - public static final TileEntityEntry HEATER = - register("blaze_heater", HeaterTileEntity::new, AllBlocks.HEATER); + public static final TileEntityEntry HEATER = + register("blaze_heater", BlazeBurnerTileEntity::new, AllBlocks.BLAZE_BURNER); public static final TileEntityEntry MECHANICAL_CRAFTER = register("mechanical_crafter", MechanicalCrafterTileEntity::new, AllBlocks.MECHANICAL_CRAFTER); public static final TileEntityEntry SEQUENCED_GEARSHIFT = @@ -301,7 +303,7 @@ public class AllTileEntities { bind(SPEEDOMETER, GaugeRenderer::speed); bind(STRESSOMETER, GaugeRenderer::stress); bind(BASIN, BasinRenderer::new); - bind(HEATER, HeaterRenderer::new); + bind(HEATER, BlazeBurnerRenderer::new); bind(DEPLOYER, DeployerRenderer::new); bind(FLYWHEEL, FlywheelRenderer::new); bind(FURNACE_ENGINE, EngineRenderer::new); diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 18d414246..32599792f 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -162,7 +162,7 @@ public class CreateJEI implements IModPlugin { registration.addRecipeCatalyst(new ItemStack(AllItems.BLOCKZAPPER.get()), blockzapperCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_MIXER.get()), mixingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), mixingCategory.getUid()); - registration.addRecipeCatalyst(new ItemStack(AllBlocks.HEATER.get()), mixingCategory.getUid()); + registration.addRecipeCatalyst(new ItemStack(AllBlocks.BLAZE_BURNER.get()), mixingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), sawingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), blockCuttingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(Blocks.STONECUTTER), blockCuttingCategory.getUid()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java index fd2ada44b..9c70c93f0 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java @@ -10,7 +10,7 @@ import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; -import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeHeater; +import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeBurner; import com.simibubi.create.compat.jei.category.animations.AnimatedMixer; import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe; import com.simibubi.create.content.contraptions.processing.ProcessingIngredient; @@ -28,7 +28,7 @@ import net.minecraft.util.NonNullList; public class MixingCategory extends CreateRecipeCategory { private AnimatedMixer mixer = new AnimatedMixer(); - private AnimatedBlazeHeater heater = new AnimatedBlazeHeater(); + private AnimatedBlazeBurner heater = new AnimatedBlazeBurner(); public MixingCategory() { super("mixing", doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), AllBlocks.BASIN.get()), diff --git a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeHeater.java b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeBurner.java similarity index 57% rename from src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeHeater.java rename to src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeBurner.java index 84483c08a..e31a8ac98 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeHeater.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedBlazeBurner.java @@ -1,29 +1,20 @@ package com.simibubi.create.compat.jei.category.animations; -import java.util.HashMap; - import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.gui.GuiGameElement; import mezz.jei.api.gui.drawable.IDrawable; -public class AnimatedBlazeHeater implements IDrawable { - private static final HashMap blazeModelMap = new HashMap<>(); - - public AnimatedBlazeHeater() { - super(); - blazeModelMap.put(2, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO); - blazeModelMap.put(3, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE); - blazeModelMap.put(4, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR); - } +public class AnimatedBlazeBurner implements IDrawable { @Override public void draw(int xOffset, int yOffset) { drawWithHeatLevel(xOffset, yOffset, 3); } - + public void drawWithHeatLevel(int xOffset, int yOffset, int heatLevel) { RenderSystem.pushMatrix(); RenderSystem.translatef(xOffset, yOffset, 200); @@ -31,12 +22,13 @@ public class AnimatedBlazeHeater implements IDrawable { RenderSystem.rotatef(22.5f, 0, 1, 0); int scale = 23; - GuiGameElement.of(AllBlocks.HEATER.getDefaultState()) - .atLocal(0, 1.65, 0) - .scale(scale) - .render(); - - GuiGameElement.of(blazeModelMap.getOrDefault(heatLevel, AllBlockPartials.BLAZE_HEATER_BLAZE_ONE)) + GuiGameElement.of(AllBlocks.BLAZE_BURNER.getDefaultState()) + .atLocal(0, 1.65, 0) + .scale(scale) + .render(); + + AllBlockPartials blaze = AllBlockPartials.BLAZES.get(HeatLevel.byIndex(heatLevel)); + GuiGameElement.of(blaze) .atLocal(1, 1.65, 1) .rotate(0, 180, 0) .scale(scale) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java index 8331bcf87..b0e415670 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java @@ -4,9 +4,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import com.simibubi.create.AllTags; import org.apache.commons.lang3.tuple.Pair; +import com.simibubi.create.AllTags; import com.simibubi.create.content.contraptions.particle.AirFlowParticleData; import com.simibubi.create.content.logistics.InWorldProcessing; import com.simibubi.create.content.logistics.InWorldProcessing.Type; @@ -17,7 +17,6 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.item.ItemEntity; @@ -38,7 +37,6 @@ import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; -import net.minecraftforge.common.Tags; public class AirCurrent { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java index 0b08cfb3e..a50454373 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/EncasedFanTileEntity.java @@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.fan; import com.simibubi.create.AllTags.AllBlockTags; import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; -import com.simibubi.create.content.contraptions.processing.HeaterBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.CKinetics; @@ -80,7 +80,7 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity { if (!checkState.getBlock().isIn(AllBlockTags.FAN_HEATERS.tag)) return false; - if (checkState.has(HeaterBlock.BLAZE_LEVEL) && !checkState.get(HeaterBlock.BLAZE_LEVEL).min(HeaterBlock.HeatLevel.FADING)) + if (checkState.has(BlazeBurnerBlock.HEAT_LEVEL) && !checkState.get(BlazeBurnerBlock.HEAT_LEVEL).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING)) return false; if (checkState.has(BlockStateProperties.LIT) && !checkState.get(BlockStateProperties.LIT)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java index 6cf5041bd..a0086e9f5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java @@ -11,7 +11,7 @@ import com.simibubi.create.content.contraptions.fluids.CombinedFluidHandler; import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity; import com.simibubi.create.content.contraptions.processing.BasinTileEntity.BasinInventory; import com.simibubi.create.content.contraptions.processing.CombinedItemFluidList; -import com.simibubi.create.content.contraptions.processing.HeaterBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour; @@ -35,8 +35,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraftforge.items.IItemHandler; -import static com.simibubi.create.content.contraptions.processing.HeaterBlock.getHeaterLevel; - public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { private static final Object shapelessOrMixingRecipesKey = new Object(); @@ -269,12 +267,12 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { return running; } - private HeaterBlock.HeatLevel getHeatLevelApplied() { + private BlazeBurnerBlock.HeatLevel getHeatLevelApplied() { if (world == null) - return HeaterBlock.HeatLevel.NONE; + return BlazeBurnerBlock.HeatLevel.NONE; BlockState state = world.getBlockState(pos.down(3)); - if (state.has(HeaterBlock.BLAZE_LEVEL)) - return state.get(HeaterBlock.BLAZE_LEVEL); - return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeaterBlock.HeatLevel.SMOULDERING : HeaterBlock.HeatLevel.NONE; + if (state.has(BlazeBurnerBlock.HEAT_LEVEL)) + return state.get(BlazeBurnerBlock.HEAT_LEVEL); + return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? BlazeBurnerBlock.HeatLevel.SMOULDERING : BlazeBurnerBlock.HeatLevel.NONE; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlock.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlock.java deleted file mode 100644 index f5721df2e..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlock.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.simibubi.create.content.contraptions.processing; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -import com.simibubi.create.AllShapes; -import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.block.ITE; - -import com.simibubi.create.foundation.utility.Lang; -import mcp.MethodsReturnNonnullByDefault; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.state.EnumProperty; -import net.minecraft.state.IProperty; -import net.minecraft.state.StateContainer.Builder; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ActionResultType; -import net.minecraft.util.Hand; -import net.minecraft.util.IStringSerializable; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.World; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class HeaterBlock extends Block implements ITE { - - //public static IProperty BLAZE_LEVEL = IntegerProperty.create("blaze_level", 0, 4); - public static IProperty BLAZE_LEVEL = EnumProperty.create("blaze", HeatLevel.class); - - public HeaterBlock(Properties properties) { - super(properties); - setDefaultState(super.getDefaultState().with(BLAZE_LEVEL, HeatLevel.NONE)); - } - - @Override - protected void fillStateContainer(Builder builder) { - super.fillStateContainer(builder); - builder.add(BLAZE_LEVEL); - } - - @Override - public boolean hasTileEntity(BlockState state) { - return state.get(BLAZE_LEVEL).min(HeatLevel.SMOULDERING); - } - - @Nullable - @Override - public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return AllTileEntities.HEATER.create(); - } - - @Override - public Class getTileEntityClass() { - return HeaterTileEntity.class; - } - - @Override - public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult blockRayTraceResult) { - if (!hasTileEntity(state)) - return ActionResultType.PASS; - - TileEntity te = world.getTileEntity(pos); - if (!(te instanceof HeaterTileEntity)) - return ActionResultType.PASS; - - if (!((HeaterTileEntity) te).tryUpdateFuel(player.getHeldItem(hand), player)) - return ActionResultType.PASS; - - if (!player.isCreative()) - player.getHeldItem(hand).shrink(1); - - return ActionResultType.SUCCESS; - } - - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - if (!context.getItem().hasTag()) - return getDefaultState(); - - CompoundNBT tag = context.getItem().getTag(); - if (!tag.contains("has_blaze")) - return getDefaultState(); - - if (tag.getBoolean("has_blaze")) - return getDefaultState().with(BLAZE_LEVEL, HeatLevel.SMOULDERING); - - return getDefaultState(); - } - - @Override - public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) { - return AllShapes.HEATER_BLOCK_SHAPE; - } - - @Override - public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, ISelectionContext p_220071_4_) { - if (p_220071_4_ == ISelectionContext.dummy()) - return AllShapes.HEATER_BLOCK_SPECIAL_COLLISION_SHAPE; - - return super.getShape(p_220071_1_, p_220071_2_, p_220071_3_, p_220071_4_); - } - - @Override - public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) { - return MathHelper.clamp(state.get(BLAZE_LEVEL).ordinal() * 4 - 1, 0, 15); - } - - static void setBlazeLevel(@Nullable World world, BlockPos pos, HeatLevel blazeLevel) { - if (world != null) - world.setBlockState(pos, world.getBlockState(pos).with(BLAZE_LEVEL, blazeLevel)); - } - - public static HeatLevel getHeaterLevel(BlockState blockState) { - return blockState.has(HeaterBlock.BLAZE_LEVEL) ? blockState.get(HeaterBlock.BLAZE_LEVEL) : HeatLevel.NONE; - } - - public enum HeatLevel implements IStringSerializable { - NONE, - SMOULDERING, - FADING, - KINDLED, - SEETHING, - //if you think you have better names let me know :) - ; - - @Override - public String getName() { - return Lang.asId(name()); - } - - public boolean min(HeatLevel heatLevel) { - return this.ordinal() >= heatLevel.ordinal(); - } - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java deleted file mode 100644 index 7235bb978..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterBlockItem.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.simibubi.create.content.contraptions.processing; - -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -import mcp.MethodsReturnNonnullByDefault; -import net.minecraft.block.Block; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.monster.BlazeEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUseContext; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.MobSpawnerTileEntity; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ActionResultType; -import net.minecraft.util.Hand; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.WeightedSpawnerEntity; -import net.minecraft.world.World; -import net.minecraft.world.spawner.AbstractSpawner; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; - -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -public class HeaterBlockItem extends BlockItem { - public HeaterBlockItem(Block block, Properties properties) { - super(block, properties); - } - - @Override - public ActionResultType onItemUse(ItemUseContext context) { - TileEntity te = context.getWorld() - .getTileEntity(context.getPos()); - if (te instanceof MobSpawnerTileEntity) { - AbstractSpawner spawner = ((MobSpawnerTileEntity) te).getSpawnerBaseLogic(); - List possibleSpawns = ObfuscationReflectionHelper - .getPrivateValue(AbstractSpawner.class, spawner, "field_98285_e"); - if (possibleSpawns.isEmpty()) { - possibleSpawns = new ArrayList<>(); - possibleSpawns.add( - ObfuscationReflectionHelper.getPrivateValue(AbstractSpawner.class, spawner, "field_98282_f")); - } - for (WeightedSpawnerEntity e : possibleSpawns) { - if (new ResourceLocation(e.getNbt().getString("id")).equals(EntityType.BLAZE.getRegistryName())) { - ItemStack itemWithBlaze = withBlaze(context.getItem()); - context.getItem() - .shrink(1); - dropOrPlaceBack(context.getWorld(), context.getPlayer(), itemWithBlaze); - return ActionResultType.SUCCESS; - } - } - } - return super.onItemUse(context); - } - - @Override - public boolean itemInteractionForEntity(ItemStack heldItem, PlayerEntity player, LivingEntity entity, Hand hand) { - if (entity instanceof BlazeEntity) { - ItemStack itemWithBlaze = withBlaze(heldItem); - heldItem.shrink(1); - dropOrPlaceBack(player.getEntityWorld(), player, itemWithBlaze); - entity.remove(); - return true; - } - return super.itemInteractionForEntity(heldItem, player, entity, hand); - } - - private static ItemStack withBlaze(ItemStack base) { - ItemStack newItem = new ItemStack(base.getItem(), 1); - CompoundNBT tag = new CompoundNBT(); - tag.putBoolean("has_blaze", true); - newItem.setTag(tag); - return newItem; - } - - private static void dropOrPlaceBack(@Nullable World world, @Nullable PlayerEntity player, ItemStack item) { - if (player == null) - return; - if (player instanceof FakePlayer || world == null) { - player.dropItem(item, false, false); - } else { - player.inventory.placeItemBackInInventory(world, item); - } - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java deleted file mode 100644 index e7c71e2e7..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.simibubi.create.content.contraptions.processing; - -import java.util.HashMap; - -import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.AllBlockPartials; -import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; -import com.simibubi.create.foundation.utility.SuperByteBuffer; - -import net.minecraft.client.renderer.IRenderTypeBuffer; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; -import net.minecraft.util.Direction; - -public class HeaterRenderer extends SafeTileEntityRenderer { - private static final HashMap blazeModelMap = new HashMap<>(); - - public HeaterRenderer(TileEntityRendererDispatcher dispatcher) { - super(dispatcher); - blazeModelMap.put(HeaterBlock.HeatLevel.FADING, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO); - blazeModelMap.put(HeaterBlock.HeatLevel.KINDLED, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE); - blazeModelMap.put(HeaterBlock.HeatLevel.SEETHING, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR); - } - - @Override - protected void renderSafe(HeaterTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, - int light, int overlay) { - AllBlockPartials blazeModel = - blazeModelMap.getOrDefault(te.getHeatLevel(), AllBlockPartials.BLAZE_HEATER_BLAZE_ONE); - - SuperByteBuffer blazeBuffer = blazeModel.renderOn(te.getBlockState()); - blazeBuffer.rotateCentered(Direction.UP, (float) Math.toRadians(-te.rot + (te.speed * partialTicks))); - blazeBuffer.light(0xF000F0).renderInto(ms, buffer.getBuffer(RenderType.getSolid())); - } -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlock.java new file mode 100644 index 000000000..a9713bcb4 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlock.java @@ -0,0 +1,184 @@ +package com.simibubi.create.content.contraptions.processing.burner; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.ITE; +import com.simibubi.create.foundation.utility.Lang; + +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.advancements.criterion.StatePropertiesPredicate; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.state.EnumProperty; +import net.minecraft.state.IProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.IItemProvider; +import net.minecraft.util.IStringSerializable; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; +import net.minecraft.world.storage.loot.ConstantRange; +import net.minecraft.world.storage.loot.ItemLootEntry; +import net.minecraft.world.storage.loot.LootPool; +import net.minecraft.world.storage.loot.LootTable; +import net.minecraft.world.storage.loot.conditions.BlockStateProperty; +import net.minecraft.world.storage.loot.conditions.ILootCondition.IBuilder; +import net.minecraft.world.storage.loot.conditions.SurvivesExplosion; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class BlazeBurnerBlock extends Block implements ITE { + + public static IProperty HEAT_LEVEL = EnumProperty.create("blaze", HeatLevel.class); + + public BlazeBurnerBlock(Properties properties) { + super(properties); + setDefaultState(super.getDefaultState().with(HEAT_LEVEL, HeatLevel.NONE)); + } + + @Override + protected void fillStateContainer(Builder builder) { + super.fillStateContainer(builder); + builder.add(HEAT_LEVEL); + } + + @Override + public boolean hasTileEntity(BlockState state) { + return state.get(HEAT_LEVEL) + .isAtLeast(HeatLevel.SMOULDERING); + } + + @Override + public void fillItemGroup(ItemGroup p_149666_1_, NonNullList p_149666_2_) { + p_149666_2_.add(AllItems.EMPTY_BLAZE_BURNER.asStack()); + super.fillItemGroup(p_149666_1_, p_149666_2_); + } + + @Nullable + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.HEATER.create(); + } + + @Override + public Class getTileEntityClass() { + return BlazeBurnerTileEntity.class; + } + + @Override + public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult blockRayTraceResult) { + if (!hasTileEntity(state)) + return ActionResultType.PASS; + + TileEntity te = world.getTileEntity(pos); + if (!(te instanceof BlazeBurnerTileEntity)) + return ActionResultType.PASS; + + if (!((BlazeBurnerTileEntity) te).tryUpdateFuel(player.getHeldItem(hand), player)) + return ActionResultType.PASS; + + if (!player.isCreative()) + player.getHeldItem(hand) + .shrink(1); + + return ActionResultType.SUCCESS; + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + ItemStack stack = context.getItem(); + Item item = stack.getItem(); + BlockState defaultState = getDefaultState(); + if (!(item instanceof BlazeBurnerBlockItem)) + return defaultState; + HeatLevel initialHeat = + ((BlazeBurnerBlockItem) item).hasCapturedBlaze() ? HeatLevel.SMOULDERING : HeatLevel.NONE; + return defaultState.with(HEAT_LEVEL, initialHeat); + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) { + return AllShapes.HEATER_BLOCK_SHAPE; + } + + @Override + public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, + ISelectionContext p_220071_4_) { + if (p_220071_4_ == ISelectionContext.dummy()) + return AllShapes.HEATER_BLOCK_SPECIAL_COLLISION_SHAPE; + return getShape(p_220071_1_, p_220071_2_, p_220071_3_, p_220071_4_); + } + + @Override + public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) { + return MathHelper.clamp(state.get(HEAT_LEVEL) + .ordinal() * 4 - 1, 0, 15); + } + + static void setBlazeLevel(World world, BlockPos pos, HeatLevel blazeLevel) { + BlockState blockState = world.getBlockState(pos); + if (!(blockState.getBlock() instanceof BlazeBurnerBlock)) + return; + world.setBlockState(pos, blockState.with(HEAT_LEVEL, blazeLevel)); + } + + public static HeatLevel getHeatLevelOf(BlockState blockState) { + return blockState.has(BlazeBurnerBlock.HEAT_LEVEL) ? blockState.get(BlazeBurnerBlock.HEAT_LEVEL) + : HeatLevel.NONE; + } + + public static LootTable.Builder buildLootTable() { + IBuilder survivesExplosion = SurvivesExplosion.builder(); + BlazeBurnerBlock block = AllBlocks.BLAZE_BURNER.get(); + + LootTable.Builder builder = LootTable.builder(); + LootPool.Builder poolBuilder = LootPool.builder(); + for (HeatLevel level : HeatLevel.values()) { + IItemProvider drop = + level == HeatLevel.NONE ? AllItems.EMPTY_BLAZE_BURNER.get() : AllBlocks.BLAZE_BURNER.get(); + poolBuilder.addEntry(ItemLootEntry.builder(drop) + .acceptCondition(survivesExplosion) + .acceptCondition(BlockStateProperty.builder(block) + .func_227567_a_(StatePropertiesPredicate.Builder.create() + .exactMatch(HEAT_LEVEL, level)))); + } + builder.addLootPool(poolBuilder.rolls(ConstantRange.of(1))); + return builder; + } + + public enum HeatLevel implements IStringSerializable { + NONE, SMOULDERING, FADING, KINDLED, SEETHING,; + + public static HeatLevel byIndex(int index) { + return values()[index]; + } + + @Override + public String getName() { + return Lang.asId(name()); + } + + public boolean isAtLeast(HeatLevel heatLevel) { + return this.ordinal() >= heatLevel.ordinal(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlockItem.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlockItem.java new file mode 100644 index 000000000..95ff6f7dc --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerBlockItem.java @@ -0,0 +1,167 @@ +package com.simibubi.create.content.contraptions.processing.burner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.annotation.ParametersAreNonnullByDefault; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.utility.VecHelper; + +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.block.Block; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.monster.BlazeEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.tileentity.MobSpawnerTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.WeightedSpawnerEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.spawner.AbstractSpawner; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class BlazeBurnerBlockItem extends BlockItem { + + private boolean capturedBlaze; + + public static BlazeBurnerBlockItem empty(Properties properties) { + return new BlazeBurnerBlockItem(AllBlocks.BLAZE_BURNER.get(), properties, false); + } + + public static BlazeBurnerBlockItem withBlaze(Block block, Properties properties) { + return new BlazeBurnerBlockItem(block, properties, true); + } + + @Override + public void addToBlockToItemMap(Map p_195946_1_, Item p_195946_2_) { + if (!hasCapturedBlaze()) + return; + super.addToBlockToItemMap(p_195946_1_, p_195946_2_); + } + + private BlazeBurnerBlockItem(Block block, Properties properties, boolean capturedBlaze) { + super(block, properties); + this.capturedBlaze = capturedBlaze; + } + + @Override + public void fillItemGroup(ItemGroup p_150895_1_, NonNullList p_150895_2_) { + if (!hasCapturedBlaze()) + return; + super.fillItemGroup(p_150895_1_, p_150895_2_); + } + + @Override + public String getTranslationKey() { + return hasCapturedBlaze() ? super.getTranslationKey() : "item.create." + getRegistryName().getPath(); + } + + @Override + public ActionResultType onItemUse(ItemUseContext context) { + if (hasCapturedBlaze()) + return super.onItemUse(context); + + World world = context.getWorld(); + BlockPos pos = context.getPos(); + TileEntity te = world.getTileEntity(pos); + PlayerEntity player = context.getPlayer(); + + if (!(te instanceof MobSpawnerTileEntity)) + return super.onItemUse(context); + + AbstractSpawner spawner = ((MobSpawnerTileEntity) te).getSpawnerBaseLogic(); + List possibleSpawns = + ObfuscationReflectionHelper.getPrivateValue(AbstractSpawner.class, spawner, "field_98285_e"); + if (possibleSpawns.isEmpty()) { + possibleSpawns = new ArrayList<>(); + possibleSpawns + .add(ObfuscationReflectionHelper.getPrivateValue(AbstractSpawner.class, spawner, "field_98282_f")); + } + + ResourceLocation blazeId = EntityType.BLAZE.getRegistryName(); + for (WeightedSpawnerEntity e : possibleSpawns) { + ResourceLocation spawnerEntityId = new ResourceLocation(e.getNbt() + .getString("id")); + if (!spawnerEntityId.equals(blazeId)) + continue; + + spawnCaptureEffects(world, VecHelper.getCenterOf(pos)); + if (world.isRemote) + return ActionResultType.SUCCESS; + + giveBurnerItemTo(player, context.getItem(), context.getHand()); + return ActionResultType.SUCCESS; + } + + return super.onItemUse(context); + } + + @Override + public boolean itemInteractionForEntity(ItemStack heldItem, PlayerEntity player, LivingEntity entity, Hand hand) { + if (hasCapturedBlaze()) + return false; + if (!(entity instanceof BlazeEntity)) + return false; + + World world = player.world; + spawnCaptureEffects(world, entity.getPositionVec()); + if (world.isRemote) + return true; + + giveBurnerItemTo(player, heldItem, hand); + entity.remove(); + return true; + } + + protected void giveBurnerItemTo(PlayerEntity player, ItemStack heldItem, Hand hand) { + ItemStack filled = AllBlocks.BLAZE_BURNER.asStack(); + if (!player.isCreative()) + heldItem.shrink(1); + if (heldItem.isEmpty()) { + player.setHeldItem(hand, filled); + return; + } + player.inventory.placeItemBackInInventory(player.world, filled); + } + + private void spawnCaptureEffects(World world, Vec3d vec) { + if (world.isRemote) { + for (int i = 0; i < 40; i++) { + Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f); + world.addParticle(ParticleTypes.FLAME, vec.x, vec.y, vec.z, motion.x, motion.y, motion.z); + Vec3d circle = motion.mul(1, 0, 1) + .normalize() + .scale(.5f); + world.addParticle(ParticleTypes.SMOKE, circle.x, vec.y, circle.z, 0, -0.125, 0); + } + return; + } + + BlockPos soundPos = new BlockPos(vec); + world.playSound(null, soundPos, SoundEvents.ENTITY_BLAZE_HURT, SoundCategory.HOSTILE, .25f, .75f); + world.playSound(null, soundPos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.HOSTILE, .5f, .75f); + } + + public boolean hasCapturedBlaze() { + return capturedBlaze; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerRenderer.java new file mode 100644 index 000000000..0f6d60479 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerRenderer.java @@ -0,0 +1,39 @@ +package com.simibubi.create.content.contraptions.processing.burner; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; +import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.SuperByteBuffer; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.util.Direction; +import net.minecraft.util.math.MathHelper; + +public class BlazeBurnerRenderer extends SafeTileEntityRenderer { + + public BlazeBurnerRenderer(TileEntityRendererDispatcher dispatcher) { + super(dispatcher); + } + + @Override + protected void renderSafe(BlazeBurnerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, + int light, int overlay) { + HeatLevel heatLevel = te.getHeatLevel(); + if (heatLevel == HeatLevel.NONE) + return; + + float renderTick = AnimationTickHolder.getRenderTick() + (te.hashCode() % 13) * 16f; + float offset = (MathHelper.sin((float) ((renderTick / 16f) % (2 * Math.PI))) + .5f) / 16f; + + AllBlockPartials blazeModel = AllBlockPartials.BLAZES.get(heatLevel); + SuperByteBuffer blazeBuffer = blazeModel.renderOn(te.getBlockState()); + blazeBuffer.rotateCentered(Direction.UP, (float) Math.toRadians(-te.rot + (te.speed * partialTicks))); + blazeBuffer.translate(0, offset, 0); + blazeBuffer.light(0xF000F0) + .renderInto(ms, buffer.getBuffer(RenderType.getSolid())); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java similarity index 86% rename from src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java rename to src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java index 0b813f46e..b62829e01 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/burner/BlazeBurnerTileEntity.java @@ -1,4 +1,4 @@ -package com.simibubi.create.content.contraptions.processing; +package com.simibubi.create.content.contraptions.processing.burner; import java.util.List; import java.util.Random; @@ -32,7 +32,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @Mod.EventBusSubscriber -public class HeaterTileEntity extends SmartTileEntity { +public class BlazeBurnerTileEntity extends SmartTileEntity { private final static int[][] heatParticleColors = { {0x3B141A, 0x47141A, 0x7A3B24, 0x854D26}, @@ -49,7 +49,7 @@ public class HeaterTileEntity extends SmartTileEntity { // Rendering state float rot, speed; - public HeaterTileEntity(TileEntityType tileEntityTypeIn) { + public BlazeBurnerTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); activeFuel = FuelType.NONE; remainingBurnTime = 0; @@ -165,7 +165,6 @@ public class HeaterTileEntity extends SmartTileEntity { activeFuel = FuelType.values()[compound.getInt("fuelLevel")]; remainingBurnTime = compound.getInt("burnTimeRemaining"); super.read(compound); - updateHeatLevel(); } /** @@ -198,48 +197,48 @@ public class HeaterTileEntity extends SmartTileEntity { return true; } - public HeaterBlock.HeatLevel getHeatLevel() { - return HeaterBlock.getHeaterLevel(getBlockState()); + public BlazeBurnerBlock.HeatLevel getHeatLevel() { + return BlazeBurnerBlock.getHeatLevelOf(getBlockState()); } private void updateHeatLevel() { switch (activeFuel) { case SPECIAL: - HeaterBlock.setBlazeLevel(world, pos, HeaterBlock.HeatLevel.SEETHING); + BlazeBurnerBlock.setBlazeLevel(world, pos, BlazeBurnerBlock.HeatLevel.SEETHING); break; case NORMAL: boolean lowPercent = (double) remainingBurnTime / maxHeatCapacity < 0.1; - HeaterBlock.setBlazeLevel(world, pos, lowPercent ? HeaterBlock.HeatLevel.FADING : HeaterBlock.HeatLevel.KINDLED); + BlazeBurnerBlock.setBlazeLevel(world, pos, lowPercent ? BlazeBurnerBlock.HeatLevel.FADING : BlazeBurnerBlock.HeatLevel.KINDLED); break; case NONE: - HeaterBlock.setBlazeLevel(world, pos, HeaterBlock.HeatLevel.SMOULDERING); + BlazeBurnerBlock.setBlazeLevel(world, pos, BlazeBurnerBlock.HeatLevel.SMOULDERING); } } - private void spawnParticles(HeaterBlock.HeatLevel heatLevel) { + private void spawnParticles(BlazeBurnerBlock.HeatLevel heatLevel) { if (world == null) return; - if (heatLevel == HeaterBlock.HeatLevel.NONE) + if (heatLevel == BlazeBurnerBlock.HeatLevel.NONE) return; Random r = world.getRandom(); - if (heatLevel == HeaterBlock.HeatLevel.SMOULDERING) { + if (heatLevel == BlazeBurnerBlock.HeatLevel.SMOULDERING) { if (r.nextDouble() > 0.25) return; Vec3d color = randomColor(heatLevel); spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.03F, 15), 0.015, 0.1); - } else if (heatLevel == HeaterBlock.HeatLevel.FADING) { + } else if (heatLevel == BlazeBurnerBlock.HeatLevel.FADING) { if (r.nextDouble() > 0.5) return; Vec3d color = randomColor(heatLevel); spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.035F, 18), 0.03, 0.15); - } else if (heatLevel == HeaterBlock.HeatLevel.KINDLED) { + } else if (heatLevel == BlazeBurnerBlock.HeatLevel.KINDLED) { Vec3d color = randomColor(heatLevel); spawnParticle(new CubeParticleData((float) color.x,(float) color.y,(float) color.z, 0.04F, 21), 0.05, 0.2); - }else if (heatLevel == HeaterBlock.HeatLevel.SEETHING) { + }else if (heatLevel == BlazeBurnerBlock.HeatLevel.SEETHING) { for (int i = 0; i < 2; i++) { if (r.nextDouble() > 0.6) return; @@ -262,8 +261,8 @@ public class HeaterTileEntity extends SmartTileEntity { 0.0D); } - private static Vec3d randomColor(HeaterBlock.HeatLevel heatLevel) { - if (heatLevel == HeaterBlock.HeatLevel.NONE) + private static Vec3d randomColor(BlazeBurnerBlock.HeatLevel heatLevel) { + if (heatLevel == BlazeBurnerBlock.HeatLevel.NONE) return new Vec3d(0,0,0); return ColorHelper.getRGB(heatParticleColors[heatLevel.ordinal()-1][(int) (Math.random()*4)]); @@ -278,7 +277,7 @@ public class HeaterTileEntity extends SmartTileEntity { return; TileEntity tile = event.getThrowable().world.getTileEntity(new BlockPos(event.getRayTraceResult().getHitVec())); - if (!(tile instanceof HeaterTileEntity)) { + if (!(tile instanceof BlazeBurnerTileEntity)) { return; } @@ -286,7 +285,7 @@ public class HeaterTileEntity extends SmartTileEntity { event.getThrowable().setMotion(Vec3d.ZERO); event.getThrowable().remove(); - HeaterTileEntity heater = (HeaterTileEntity) tile; + BlazeBurnerTileEntity heater = (BlazeBurnerTileEntity) tile; if (heater.activeFuel != FuelType.SPECIAL) { heater.activeFuel = FuelType.NORMAL; heater.remainingBurnTime = MathHelper.clamp(heater.remainingBurnTime + 80, 0, maxHeatCapacity); diff --git a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java index ccae9be56..c8329e070 100644 --- a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java +++ b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java @@ -1,5 +1,7 @@ package com.simibubi.create.content.logistics; +import static com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.getHeatLevelOf; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -7,8 +9,8 @@ import java.util.Optional; import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe; -import com.simibubi.create.content.contraptions.processing.HeaterBlock; import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.ItemHelper; @@ -40,8 +42,6 @@ import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; -import static com.simibubi.create.content.contraptions.processing.HeaterBlock.getHeaterLevel; - public class InWorldProcessing { public static class SplashingInv extends RecipeWrapper { @@ -63,9 +63,9 @@ public class InWorldProcessing { if (fluidState.getFluid() == Fluids.WATER || fluidState.getFluid() == Fluids.FLOWING_WATER) return Type.SPLASHING; if (blockState.getBlock() == Blocks.FIRE - || (blockState.getBlock() == Blocks.CAMPFIRE && blockState.get(CampfireBlock.LIT)) || getHeaterLevel(blockState) == HeaterBlock.HeatLevel.SMOULDERING) + || (blockState.getBlock() == Blocks.CAMPFIRE && blockState.get(CampfireBlock.LIT)) || getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING) return Type.SMOKING; - if (blockState.getBlock() == Blocks.LAVA || getHeaterLevel(blockState).min(HeaterBlock.HeatLevel.FADING)) + if (blockState.getBlock() == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING)) return Type.BLASTING; return null; } diff --git a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java index 4216d5c04..bbf81c149 100644 --- a/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/BlockStateGen.java @@ -20,7 +20,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.mou import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock; import com.simibubi.create.content.contraptions.components.tracks.ReinforcedRailBlock; import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock; -import com.simibubi.create.content.contraptions.processing.HeaterBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverBlock; import com.simibubi.create.content.palettes.PavedBlock; import com.simibubi.create.foundation.utility.Iterate; @@ -213,7 +213,7 @@ public class BlockStateGen { }); } - public static NonNullBiConsumer, RegistrateBlockstateProvider> blazeHeater(){ + public static NonNullBiConsumer, RegistrateBlockstateProvider> blazeHeater(){ return (c, p) -> ConfiguredModel.builder().modelFile(p.models().getExistingFile(p.modLoc("block/" + c.getName() + "/block"))).build(); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 17123dd50..30eeb44c0 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -13,10 +13,12 @@ import net.minecraft.util.math.Vec3i; public class VecHelper { + public static final Vec3d CENTER_OF_ORIGIN = new Vec3d(.5, .5, .5); + public static Vec3d rotate(Vec3d vec, Vec3d rotationVec) { return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z); } - + public static Vec3d rotate(Vec3d vec, double xRot, double yRot, double zRot) { return rotate(rotate(rotate(vec, xRot, Axis.X), yRot, Axis.Y), zRot, Axis.Z); } @@ -54,6 +56,8 @@ public class VecHelper { } public static Vec3d getCenterOf(Vec3i pos) { + if (pos.equals(Vec3i.NULL_VECTOR)) + return CENTER_OF_ORIGIN; return new Vec3d(pos).add(.5f, .5f, .5f); } diff --git a/src/main/resources/assets/create/models/block/blaze_burner/blaze/fading.json b/src/main/resources/assets/create/models/block/blaze_burner/blaze/fading.json new file mode 100644 index 000000000..d6f517fad --- /dev/null +++ b/src/main/resources/assets/create/models/block/blaze_burner/blaze/fading.json @@ -0,0 +1,23 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "2": "create:block/blaze_smouldering", + "particle": "create:block/blaze_smouldering" + }, + "elements": [ + { + "name": "Blaze 3", + "from": [5, 6, 5], + "to": [11, 12, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [6, 0, 12, 6], "texture": "#2"}, + "east": {"uv": [0, 0, 6, 6], "texture": "#2"}, + "south": {"uv": [0, 0, 6, 6], "texture": "#2"}, + "west": {"uv": [0, 0, 6, 6], "texture": "#2"}, + "up": {"uv": [0, 6, 6, 12], "texture": "#2"}, + "down": {"uv": [6, 6, 12, 12], "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_burner/blaze/kindled.json b/src/main/resources/assets/create/models/block/blaze_burner/blaze/kindled.json new file mode 100644 index 000000000..5300221b8 --- /dev/null +++ b/src/main/resources/assets/create/models/block/blaze_burner/blaze/kindled.json @@ -0,0 +1,23 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "2": "create:block/blaze_kindled", + "particle": "create:block/blaze_kindled" + }, + "elements": [ + { + "name": "Blaze 4", + "from": [4, 6, 4], + "to": [12, 14, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, + "faces": { + "north": {"uv": [8, 0, 16, 8], "texture": "#2"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#2"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#2"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#2"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#2"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_burner/blaze/seething.json b/src/main/resources/assets/create/models/block/blaze_burner/blaze/seething.json new file mode 100644 index 000000000..a7ba42fbd --- /dev/null +++ b/src/main/resources/assets/create/models/block/blaze_burner/blaze/seething.json @@ -0,0 +1,22 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "1": "create:block/blaze_seething" + }, + "elements": [ + { + "name": "Blaze 5", + "from": [4, 6, 4], + "to": [12, 14, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, + "faces": { + "north": {"uv": [8, 0, 16, 8], "texture": "#1"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#1"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#1"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_burner/blaze/smouldering.json b/src/main/resources/assets/create/models/block/blaze_burner/blaze/smouldering.json new file mode 100644 index 000000000..e831fdbfb --- /dev/null +++ b/src/main/resources/assets/create/models/block/blaze_burner/blaze/smouldering.json @@ -0,0 +1,22 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "2": "create:block/blaze_smouldering", + "particle": "create:block/blaze_smouldering" + }, + "elements": [ + { + "name": "Blaze", + "from": [6, 6, 6], + "to": [10, 10, 10], + "faces": { + "north": {"uv": [0, 12, 4, 16], "texture": "#2"}, + "east": {"uv": [8, 12, 4, 16], "texture": "#2"}, + "south": {"uv": [4, 12, 8, 16], "texture": "#2"}, + "west": {"uv": [4, 12, 8, 16], "texture": "#2"}, + "up": {"uv": [8, 12, 12, 16], "texture": "#2"}, + "down": {"uv": [12, 12, 16, 16], "texture": "#2"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_heater/block.json b/src/main/resources/assets/create/models/block/blaze_burner/block.json similarity index 58% rename from src/main/resources/assets/create/models/block/blaze_heater/block.json rename to src/main/resources/assets/create/models/block/blaze_burner/block.json index 135de425a..c42a49e1e 100644 --- a/src/main/resources/assets/create/models/block/blaze_heater/block.json +++ b/src/main/resources/assets/create/models/block/blaze_burner/block.json @@ -2,8 +2,10 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { - "0": "create:block/blaze_heater_brazier", - "particle": "create:block/blaze_heater_brazier" + "1": "create:block/blaze_burner_inner", + "2": "create:block/blaze_burner_side", + "3": "create:block/dark_metal_block", + "particle": "create:block/dark_metal_block" }, "elements": [ { @@ -11,10 +13,10 @@ "from": [2, 5, 2], "to": [14, 14, 14], "faces": { - "north": {"uv": [1, 1, 7, 5.5], "texture": "#0"}, - "east": {"uv": [1, 1, 7, 5.5], "texture": "#0"}, - "south": {"uv": [1, 1, 7, 5.5], "texture": "#0"}, - "west": {"uv": [1, 1, 7, 5.5], "texture": "#0"} + "north": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "east": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "south": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "west": {"uv": [0, 6, 12, 15], "texture": "#2"} } }, { @@ -22,7 +24,7 @@ "from": [2, 5, 14], "to": [14, 14, 15], "faces": { - "north": {"uv": [1, 1, 7, 5.5], "texture": "#0"} + "north": {"uv": [12, 6, 0, 15], "texture": "#2"} } }, { @@ -30,7 +32,7 @@ "from": [1, 5, 2], "to": [2, 14, 14], "faces": { - "east": {"uv": [1, 1, 7, 5.5], "texture": "#0"} + "east": {"uv": [12, 6, 0, 15], "texture": "#2"} } }, { @@ -38,7 +40,7 @@ "from": [2, 5, 1], "to": [14, 14, 2], "faces": { - "south": {"uv": [1, 1, 7, 5.5], "texture": "#0"} + "south": {"uv": [12, 6, 0, 15], "texture": "#2"} } }, { @@ -46,7 +48,7 @@ "from": [14, 5, 2], "to": [15, 14, 14], "faces": { - "west": {"uv": [1, 1, 7, 5.5], "texture": "#0"} + "west": {"uv": [12, 6, 0, 15], "texture": "#2"} } }, { @@ -55,7 +57,7 @@ "to": [14, 17, 14], "rotation": {"angle": 45, "axis": "x", "origin": [8, 14, 14]}, "faces": { - "south": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "south": {"uv": [0, 3, 12, 6], "texture": "#2"} } }, { @@ -64,7 +66,7 @@ "to": [3, 17, 14], "rotation": {"angle": 45, "axis": "z", "origin": [2, 14, 8]}, "faces": { - "west": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "west": {"uv": [0, 3, 12, 6], "texture": "#2"} } }, { @@ -73,7 +75,7 @@ "to": [14, 17, 3], "rotation": {"angle": -45, "axis": "x", "origin": [8, 14, 2]}, "faces": { - "north": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "north": {"uv": [0, 3, 12, 6], "texture": "#2"} } }, { @@ -82,7 +84,7 @@ "to": [14, 17, 14], "rotation": {"angle": -45, "axis": "z", "origin": [14, 14, 8]}, "faces": { - "east": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "east": {"uv": [0, 3, 12, 6], "texture": "#2"} } }, { @@ -91,34 +93,34 @@ "to": [14, 17, 15], "rotation": {"angle": 45, "axis": "x", "origin": [8, 14, 14]}, "faces": { - "north": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "north": {"uv": [12, 3, 0, 6], "texture": "#2"} } }, { - "name": "Brazier Spikes 2b", + "name": "Brazier Spikes 1b", "from": [1, 14, 2], "to": [2, 17, 14], "rotation": {"angle": 45, "axis": "z", "origin": [2, 14, 8]}, "faces": { - "east": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "east": {"uv": [12, 3, 0, 6], "texture": "#2"} } }, { - "name": "Brazier Spikes 3b", + "name": "Brazier Spikes 1b", "from": [2, 14, 1], "to": [14, 17, 2], "rotation": {"angle": -45, "axis": "x", "origin": [8, 14, 2]}, "faces": { - "south": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "south": {"uv": [12, 3, 0, 6], "texture": "#2"} } }, { - "name": "Brazier Spikes 4b", + "name": "Brazier Spikes 1b", "from": [14, 14, 2], "to": [15, 17, 14], "rotation": {"angle": -45, "axis": "z", "origin": [14, 14, 8]}, "faces": { - "west": {"uv": [8, 8, 14, 9.5], "texture": "#0"} + "west": {"uv": [12, 3, 0, 6], "texture": "#2"} } }, { @@ -127,12 +129,12 @@ "to": [16, 4, 16], "rotation": {"angle": 0, "axis": "y", "origin": [0.5, 8, 0.5]}, "faces": { - "north": {"uv": [0, 6, 8, 8], "texture": "#0", "cullface": "north"}, - "east": {"uv": [0, 6, 8, 8], "texture": "#0", "cullface": "east"}, - "south": {"uv": [0, 6, 8, 8], "texture": "#0", "cullface": "south"}, - "west": {"uv": [0, 6, 8, 8], "texture": "#0", "cullface": "west"}, - "up": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "down": {"uv": [0, 8, 8, 16], "texture": "#0", "cullface": "down"} + "north": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}, + "east": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}, + "south": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}, + "west": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#3", "cullface": "down"} } }, { @@ -141,11 +143,11 @@ "to": [14, 5, 14], "rotation": {"angle": 0, "axis": "y", "origin": [2.5, 8, 2.5]}, "faces": { - "north": {"uv": [1, 5.5, 7, 6], "texture": "#0"}, - "east": {"uv": [1, 5.5, 7, 6], "texture": "#0"}, - "south": {"uv": [1, 5.5, 7, 6], "texture": "#0"}, - "west": {"uv": [1, 5.5, 7, 6], "texture": "#0"}, - "up": {"uv": [9, 1, 15, 7], "texture": "#0"} + "north": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "east": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "south": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "west": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "up": {"uv": [2, 2, 14, 14], "texture": "#1"} } } ], @@ -164,11 +166,6 @@ "origin": [0.5, 0.5, 0.5], "children": [5, 6, 7, 8, 9, 10, 11, 12] }, 13, 14] - }, - { - "name": "Blazes", - "origin": [8, 8, 8], - "children": [] } ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_burner/block_with_blaze.json b/src/main/resources/assets/create/models/block/blaze_burner/block_with_blaze.json new file mode 100644 index 000000000..8e20426fb --- /dev/null +++ b/src/main/resources/assets/create/models/block/blaze_burner/block_with_blaze.json @@ -0,0 +1,191 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/blaze_burner_inner", + "2": "create:block/blaze_burner_side", + "3": "create:block/dark_metal_block", + "particle": "create:block/dark_metal_block", + "2_2": "create:block/blaze_kindled" + }, + "elements": [ + { + "name": "Brazier Sides 1", + "from": [2, 5, 2], + "to": [14, 14, 14], + "faces": { + "north": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "east": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "south": {"uv": [0, 6, 12, 15], "texture": "#2"}, + "west": {"uv": [0, 6, 12, 15], "texture": "#2"} + } + }, + { + "name": "Brazier Sides 2", + "from": [2, 5, 14], + "to": [14, 14, 15], + "faces": { + "north": {"uv": [12, 6, 0, 15], "texture": "#2"} + } + }, + { + "name": "Brazier Sides 3", + "from": [1, 5, 2], + "to": [2, 14, 14], + "faces": { + "east": {"uv": [12, 6, 0, 15], "texture": "#2"} + } + }, + { + "name": "Brazier Sides 4", + "from": [2, 5, 1], + "to": [14, 14, 2], + "faces": { + "south": {"uv": [12, 6, 0, 15], "texture": "#2"} + } + }, + { + "name": "Brazier Sides 5", + "from": [14, 5, 2], + "to": [15, 14, 14], + "faces": { + "west": {"uv": [12, 6, 0, 15], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 1", + "from": [2, 14, 13], + "to": [14, 17, 14], + "rotation": {"angle": 45, "axis": "x", "origin": [8, 14, 14]}, + "faces": { + "south": {"uv": [0, 3, 12, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 2", + "from": [2, 14, 2], + "to": [3, 17, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [2, 14, 8]}, + "faces": { + "west": {"uv": [0, 3, 12, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 3", + "from": [2, 14, 2], + "to": [14, 17, 3], + "rotation": {"angle": -45, "axis": "x", "origin": [8, 14, 2]}, + "faces": { + "north": {"uv": [0, 3, 12, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 4", + "from": [13, 14, 2], + "to": [14, 17, 14], + "rotation": {"angle": -45, "axis": "z", "origin": [14, 14, 8]}, + "faces": { + "east": {"uv": [0, 3, 12, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 1b", + "from": [2, 14, 14], + "to": [14, 17, 15], + "rotation": {"angle": 45, "axis": "x", "origin": [8, 14, 14]}, + "faces": { + "north": {"uv": [12, 3, 0, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 1b", + "from": [1, 14, 2], + "to": [2, 17, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [2, 14, 8]}, + "faces": { + "east": {"uv": [12, 3, 0, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 1b", + "from": [2, 14, 1], + "to": [14, 17, 2], + "rotation": {"angle": -45, "axis": "x", "origin": [8, 14, 2]}, + "faces": { + "south": {"uv": [12, 3, 0, 6], "texture": "#2"} + } + }, + { + "name": "Brazier Spikes 1b", + "from": [14, 14, 2], + "to": [15, 17, 14], + "rotation": {"angle": -45, "axis": "z", "origin": [14, 14, 8]}, + "faces": { + "west": {"uv": [12, 3, 0, 6], "texture": "#2"} + } + }, + { + "name": "Base", + "from": [0, 0, 0], + "to": [16, 4, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [0.5, 8, 0.5]}, + "faces": { + "north": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2", "cullface": "west"}, + "east": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2", "cullface": "west"}, + "south": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2", "cullface": "west"}, + "west": {"uv": [12, 0, 16, 16], "rotation": 90, "texture": "#2", "cullface": "west"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#3", "cullface": "down"} + } + }, + { + "name": "Brazier bottom", + "from": [2, 4, 2], + "to": [14, 5, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [2.5, 8, 2.5]}, + "faces": { + "north": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "east": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "south": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "west": {"uv": [0, 15, 12, 16], "texture": "#2"}, + "up": {"uv": [2, 2, 14, 14], "texture": "#1"} + } + }, + { + "name": "Blaze 4", + "from": [4, 6, 4], + "to": [12, 14, 12], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [8, 0, 16, 8], "texture": "#2_2"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#2_2"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#2_2"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#2_2"}, + "up": {"uv": [0, 8, 8, 16], "texture": "#2_2"}, + "down": {"uv": [8, 8, 16, 16], "texture": "#2_2"} + } + } + ], + "groups": [ + { + "name": "Brazier", + "origin": [0.5, 0.5, 0.5], + "children": [ + { + "name": "Brazier Sides", + "origin": [0.5, 0.5, 0.5], + "children": [0, 1, 2, 3, 4] + }, + { + "name": "Brazier Spikes", + "origin": [0.5, 0.5, 0.5], + "children": [5, 6, 7, 8, 9, 10, 11, 12] + }, 13, 14] + }, + { + "name": "kindled", + "origin": [8, 8, 8], + "children": [15] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_heater/blaze/four.json b/src/main/resources/assets/create/models/block/blaze_heater/blaze/four.json deleted file mode 100644 index cc0f8c54f..000000000 --- a/src/main/resources/assets/create/models/block/blaze_heater/blaze/four.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "1": "create:block/tamed_blaze" - }, - "elements": [ - { - "name": "Blaze 4", - "from": [4, 6, 4], - "to": [12, 14, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, - "faces": { - "north": {"uv": [12, 0, 16, 4], "texture": "#1"}, - "east": {"uv": [8, 0, 12, 4], "texture": "#1"}, - "south": {"uv": [8, 0, 12, 4], "texture": "#1"}, - "west": {"uv": [8, 0, 12, 4], "texture": "#1"}, - "up": {"uv": [8, 4, 12, 8], "texture": "#1"}, - "down": {"uv": [12, 4, 16, 8], "texture": "#1"} - } - } - ], - "groups": [ - { - "name": "Blazes", - "origin": [8, 8, 8], - "children": [15, 16, 17, 18] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_heater/blaze/one.json b/src/main/resources/assets/create/models/block/blaze_heater/blaze/one.json deleted file mode 100644 index b0b318ff6..000000000 --- a/src/main/resources/assets/create/models/block/blaze_heater/blaze/one.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "1": "create:block/tamed_blaze" - }, - "elements": [ - { - "name": "Blaze 1", - "from": [6, 6, 6], - "to": [10, 10, 10], - "faces": { - "north": {"uv": [8, 8, 10, 10], "texture": "#1"}, - "east": {"uv": [6, 8, 8, 10], "texture": "#1"}, - "south": {"uv": [6, 8, 8, 10], "texture": "#1"}, - "west": {"uv": [6, 8, 8, 10], "texture": "#1"}, - "up": {"uv": [6, 10, 8, 12], "texture": "#1"}, - "down": {"uv": [8, 10, 10, 12], "texture": "#1"} - } - } - ], - "groups": [ - { - "name": "Blazes", - "origin": [8, 8, 8], - "children": [15, 16, 17, 18] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_heater/blaze/three.json b/src/main/resources/assets/create/models/block/blaze_heater/blaze/three.json deleted file mode 100644 index a9d78104f..000000000 --- a/src/main/resources/assets/create/models/block/blaze_heater/blaze/three.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "1": "create:block/tamed_blaze" - }, - "elements": [ - { - "name": "Blaze 3", - "from": [4, 6, 4], - "to": [12, 14, 12], - "rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 6]}, - "faces": { - "north": {"uv": [4, 0, 8, 4], "texture": "#1"}, - "east": {"uv": [0, 0, 4, 4], "texture": "#1"}, - "south": {"uv": [0, 0, 4, 4], "texture": "#1"}, - "west": {"uv": [0, 0, 4, 4], "texture": "#1"}, - "up": {"uv": [0, 4, 4, 8], "texture": "#1"}, - "down": {"uv": [4, 4, 8, 8], "texture": "#1"} - } - } - ], - "groups": [ - { - "name": "Blazes", - "origin": [8, 8, 8], - "children": [15, 16, 17, 18] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/blaze_heater/blaze/two.json b/src/main/resources/assets/create/models/block/blaze_heater/blaze/two.json deleted file mode 100644 index ab5e5aea4..000000000 --- a/src/main/resources/assets/create/models/block/blaze_heater/blaze/two.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "credit": "Made with Blockbench", - "textures": { - "1": "create:block/tamed_blaze" - }, - "elements": [ - { - "name": "Blaze 2", - "from": [5, 6, 5], - "to": [11, 12, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, - "faces": { - "north": {"uv": [3, 8, 6, 11], "texture": "#1"}, - "east": {"uv": [0, 8, 3, 11], "texture": "#1"}, - "south": {"uv": [0, 8, 3, 11], "texture": "#1"}, - "west": {"uv": [0, 8, 3, 11], "texture": "#1"}, - "up": {"uv": [0, 11, 3, 14], "texture": "#1"}, - "down": {"uv": [3, 11, 6, 14], "texture": "#1"} - } - } - ], - "groups": [ - { - "name": "Blazes", - "origin": [8, 8, 8], - "children": [15, 16, 17, 18] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/blaze_burner_inner.png b/src/main/resources/assets/create/textures/block/blaze_burner_inner.png new file mode 100644 index 0000000000000000000000000000000000000000..ff33417f2e27aea4061276e06dbf0dd17ffbf64a GIT binary patch literal 567 zcmV-70?7S|P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0nAB6K~y+TWm1W5 z+b|53WJ~fTFK~)>UGfzj^8cT)Pw22AahmwhVM%*FmKE3oLC`eGN0Fqb(}^tbKCH%y zBw^5>ovSA~91cZUX|3}--|cqAUxW~3me)$bjxkQtR4L`0rEhQFk!OsCrj!XGthLZ{ zO+sMDxRFSifn;VuZRqG+u%>G-(CH$&yTgXxbln<;4(EijETI7@#J(z@YxS~kzV4g7 zv>9e3G|k*G7gctNKAlG zBC@n7KSY6ucTZ6fGu*}s;2Vu%-#@#-CFzH;Sjert!1LqR8B=+zFL{0ahRtg|QY2Uh z-YH3aj6)z-I~ikyL}@{j890#ScsyF`yq^f?3Fj>3GB46aaBhWCf#5ZBBQeel^R?pm z?zbB@zm5wHV9<~C1DMY^j;gMQzT3|G|1Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0h>ugK~y+Tom0zB z!ax+ggQd`-l(z|DLRfwZ3zEn~X_OXPV4QO;4UoFPlQj2r=FIfY z9YH6e-EPZlHb?WhO^d}B#e)1v&@_z-g*?UM@&5@-r!$&N#_UH5bi2>;;qgfZ;Q=e^ zC(m1wt|z&$^Ve&iV_>yf61dgs4b48LWGi7lfngYw$yih_Us0uUO|@E`eRLXReBeYO zoP%bwDF=f=TK6 z^KYh0WYt%mcR1|$N&HU07*qo IM6N<$f?IdlcK`qY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/blaze_kindled.png b/src/main/resources/assets/create/textures/block/blaze_kindled.png new file mode 100644 index 0000000000000000000000000000000000000000..1626fc3397c7677e7898d236cd1145792294e942 GIT binary patch literal 530 zcmV+t0`2{YP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0jEhsK~y+TO;SNG z15ps3c`IommG&gkgAGljK}Z@GL3)uoyAx;sfW$u_apUGh-24E9sJL!aT2T$@;($b= zDT;LW`Cex|CNI;OH{Unko7uAdoT1nhS^GNuOA%Ys6t+T&O)9$aZQ){h#r#}un;T); z!=&OluIzGagUWX_GM@=ft^l^Nlgm)rjnu5vjnBm;8tOIi`WEM>_5Pvpa^o!OY$EPG zPXd=6zxV2I!6x(SScLNf?K*6LM7V*!4tT(cg4sR|aRg32#Ya_oIOkXoC6%EeZZtV? zxpqt_z0~-%MvqC}J0SAeNj)0q_mlBLL)`4vsDX_3(gkT<6OM`}RB-Ebb}91|qDC=# zRmn3RDbUvAur6mz1q-o;MH8(pR3rlwvk3udyRocKHVAZ^3NJ!&xENZwC(0 zZ3P%w0wi8icx4cSa~5PcNYgH!AvhSIf`+ETpCoE;KPQ5JA`-xaufnRYv9Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0j)_yK~y+TWm3CJ z15ps2*;PcN5YZHhxRnwyL=dzwwn=Sgp`YL%_y-Dpft|0)P6Z3Wh>b-+iQuD2Vn9g< zL=qDT$zIRwBv--1?l5!jIdkUTT~1w_)d*SKl*yLJ|HAkE#5i&E!gxbn()QUyYB`>7 z5LSTyjSg~#>9|eB$7n46RPD%4FOP;@+sIm>7t_u?P0gd=^F0$!^1~&fu9$UqcxExN zp8@Y}Yq9>C;gb&Y=1!Ma&U3^I8j)zw;{C-;%yyHdHJBrDc_B&JE3Oo&e}F?_kyVQP zU1PsP<(zEQE7YiR^@HwCnaJhQNujn|5>?i2nN|~f5KDXQf~@h0$93ltj`6v#->?I! zC;=;O)1d}HKy zQYagxp3<5C;uG;4FXUj1l`)Z}OY-OHF?1x=sI2GEpu+;+R%A9HUGmidu*ZGnW%$+@bD?nn0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0p3YOK~y+TZIMe$ zTTu|l|L1z|rN&^%3#=|85(I@}R~EXdWKk%70b9CIT)PllOTU2&H?Ga5pFr%wh0u*9 zi{ipQ2%?qxz?y1M)81TjdS-GaIT3$wnK^UM{Leg;K3vr3o5X|Me726E(FETcc&luL zQNNdqI`eW67u&}i5T7h2ra9IYs+5~;ITk%Fp2ZyYYvi6Vj@ab*#33Z z-NNJ0M>6p3vBSYZP!M)J=0(x!UJ_Q{u;P5O0}I<)PWKu z*{w?O__e5Pj|Mv1p-Q4uB7<~MYcu2A#Oa>~ZZ9-O3TE$>2#Jj1GueSuz%gRudqp7itO)h~w#&jMW5V#HNtL?b*MOYr4Xx(EMM6MIK>#LWbnIzU6$p=I-U?9TXIrkdO>i z4gohK8TSKOoCO|{#S9F5he4R}c>anMpkSA$i(`nyW!V!O1)B^cj(#+6ie#SQpjp`R zfaTfgo6e6IW*za8@?YW9zHy_Pw!xIf^8b&@`S+{}a_=jOoF9B~U z%M)ERdn+Q$A1TbP3etX|#;f||%8O~+o~N8URC;4_Rbi2TO3B{qR*KW}SFiniLVtc8 n$6ohuy~P}V`Fl3X9=IW&HpSxi67`1PAV+(;`njxgN@xNAJT+-L literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/tamed_blaze.png b/src/main/resources/assets/create/textures/block/tamed_blaze.png deleted file mode 100644 index ba3918be145e2182eb34d9d6bd83ff70a464cd91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1538 zcmV+d2L1VoP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00nAEL_t(o!|j$`Y!p=#$A5Qr zyQSOKO3OxQnoe!8DNx#^Vu_(^6-bGanD9b)K*jjvgAXJoYC_PM_@I*TK%!BCCI*ZT zCd3CmBnT-D62Mei+DgARol;6=Eg#)>3)7vwKFr=bGhKNS!;9zT-gEAq`Ty_#oO5S{ zyuU?K7$;y4x(LJ`bOqNXWHVVPY~z&+dx^(_%UwwVv92U}md$2qTLwb*H%RJC4cPm^ z9-2Pd0;3kxneOg~5R`p~Sv~OwX4C`RbF7ywtxZ^IFr#klVFVA4NkrxgWdArcz1D!! zc?|%+A8K#FPcWdysDcgJdQTynI&@s_2vPD( z3vGwGvC?q;ofc+?yAeM)h|kvvsX#49Vuplf*s)mxFysj8L*9Jb(~|yicfNhRr zA!4RiDoq_Ov71B474_cyxot4fkGMHR7~tT~km`Zb=A1N+B-JATLCs4rb{0AvG`XV) zI!{Z?5U>jPU%aK|MHI_C@8e7od@tD_Y{yRV>EjI-@CDbU3N};+jM_|YV{V3gd39&cqCPpbA)lTaLtx z!cH>?7>~IzGm0y@uSiwybrB+cx10Z#d(f4qg5Uh4)am`VTvsw*g}~<|N6N?!TS!Mj zt(gyAXX=9U11dshNMOxnkx~YVP=T9K?@sWmpp}T37)HHYfZ6Z{q$82(bAdWgDNrO7 z5jC2{2JskdsBnp#yCnm4pi-bnC?Z+`MlHnP5e(6u0t^Hh0OJFJz&(m9KVxLSn=wS|LbJOKMj} z0GPV7pnT!?0lgAW0`Axg9Jpff-liJT(~<*MEVx3ze|<$2QxyvU{C;C5?~LN)u4m=C>N4K_u9qDz zx{|M}E(2iM$7hh%ZWu`-HXY`#y&HM;z#zp-7MQzV5O|R_7fG z9avwiK)5Ut#*z8;cX2HDVjnSp~TN24zUu@wEC$_^% z-(Ta1d!4=c)=5-q*4LD4LJD-T%=(0P?`i+)Z2tOU^P0D~6@NP>Y@38_lboE@DOg`q zu3Jl4c|;O6(v(Lew{4*TGubFJnfbi+JOx-8b5E`Qiki2=+@(P7RSFWe&9|3_18@0| ze`oH;$bad~UD9dr=RQ_h!hc}~0$BYrI1*+q=52^omS}L*rjM4uND}Pdf<>4sN(HQx o(4FxJO-LzuoM!Nt?SBG)1L0owHDjIeo&W#<07*qoM6N<$f{Fdb_5c6? From f0abbaacd744dee705bd12d0fe66a30c5ae97a09 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 24 Jul 2020 19:43:33 +0200 Subject: [PATCH 17/17] Riding the engine - Fixed incompatibility between seats and furnace cart contraptions --- src/main/java/ContraptionInteractionHandler.java | 2 +- src/main/java/com/simibubi/create/Create.java | 1 - src/main/java/com/simibubi/create/CreateClient.java | 2 +- .../components/structureMovement/Contraption.java | 4 ++++ .../structureMovement/ContraptionCollider.java | 1 + .../structureMovement/ContraptionEntity.java | 11 +++++++++++ .../{ => chassis}/ChassisRangeDisplay.java | 3 +-- .../structureMovement/chassis/ChassisTileEntity.java | 1 - .../{ => sync}/ClientMotionPacket.java | 2 +- .../{ => sync}/ContraptionInteractionPacket.java | 3 ++- .../{ => sync}/ContraptionSeatMappingPacket.java | 9 +++++---- .../simibubi/create/{ => events}/ClientEvents.java | 4 +++- .../simibubi/create/{ => events}/CommonEvents.java | 5 +++-- .../create/foundation/networking/AllPackets.java | 6 +++--- 14 files changed, 36 insertions(+), 18 deletions(-) rename src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/{ => chassis}/ChassisRangeDisplay.java (97%) rename src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/{ => sync}/ClientMotionPacket.java (98%) rename src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/{ => sync}/ContraptionInteractionPacket.java (94%) rename src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/{ => sync}/ContraptionSeatMappingPacket.java (84%) rename src/main/java/com/simibubi/create/{ => events}/ClientEvents.java (98%) rename src/main/java/com/simibubi/create/{ => events}/CommonEvents.java (93%) diff --git a/src/main/java/ContraptionInteractionHandler.java b/src/main/java/ContraptionInteractionHandler.java index 8ae1d08c5..2ad46f867 100644 --- a/src/main/java/ContraptionInteractionHandler.java +++ b/src/main/java/ContraptionInteractionHandler.java @@ -2,7 +2,7 @@ import org.apache.commons.lang3.mutable.MutableObject; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.RaycastHelper; import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 64b99568b..a10d6c7a9 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -89,7 +89,6 @@ public class Create { if (schematicReceiver == null) schematicReceiver = new ServerSchematicLoader(); schematicReceiver.tick(); - lagger.tick(); } diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 3cfd33723..e27420044 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -7,8 +7,8 @@ import java.util.function.Function; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; -import com.simibubi.create.content.contraptions.components.structureMovement.ChassisRangeDisplay; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRenderer; +import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisRangeDisplay; import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorHandler; import com.simibubi.create.content.curiosities.tools.ExtendoGripRenderHandler; import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 4989e3d36..f3f97426c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -811,6 +811,10 @@ public abstract class Contraption { public Map getSeatMapping() { return seatMapping; } + + public void setSeatMapping(Map seatMapping) { + this.seatMapping = seatMapping; + } public List getSeats() { return seats; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index e8369ef14..6ae155701 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -20,6 +20,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.collision.OrientedBB; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index 2f468a4e8..49011f157 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -16,6 +16,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.bea import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity.CartMovementMode; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.AngleHelper; @@ -69,6 +70,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD protected boolean stationary; protected boolean initialized; final List collidingEntities = new ArrayList<>(); + private boolean isSerializingFurnaceCart; private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL); private static final DataParameter STALLED = @@ -90,6 +92,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD super(entityTypeIn, worldIn); motionBeforeStall = Vec3d.ZERO; stationary = entityTypeIn == AllEntityTypes.STATIONARY_CONTRAPTION.get(); + isSerializingFurnaceCart = false; forcedAngle = -1; } @@ -352,7 +355,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD if (!isStalled() && (riding instanceof FurnaceMinecartEntity)) { FurnaceMinecartEntity furnaceCart = (FurnaceMinecartEntity) riding; + + // Notify to not trigger serialization side-effects + isSerializingFurnaceCart = true; CompoundNBT nbt = furnaceCart.serializeNBT(); + isSerializingFurnaceCart = false; + int fuel = nbt.getInt("Fuel"); int fuelBefore = fuel; double pushX = nbt.getDouble("PushX"); @@ -672,6 +680,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD @SuppressWarnings("deprecation") @Override public CompoundNBT writeWithoutTypeId(CompoundNBT nbt) { + if (isSerializingFurnaceCart) + return nbt; + Vec3d vec = getPositionVec(); List passengers = getPassengers(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ChassisRangeDisplay.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java similarity index 97% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ChassisRangeDisplay.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java index fdb17e76c..796c5793e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ChassisRangeDisplay.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java @@ -1,4 +1,4 @@ -package com.simibubi.create.content.contraptions.components.structureMovement; +package com.simibubi.create.content.contraptions.components.structureMovement.chassis; import java.util.ArrayList; import java.util.Collections; @@ -14,7 +14,6 @@ import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; -import com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.PlayerEntity; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java index 454af89ea..c7efc5d12 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisTileEntity.java @@ -11,7 +11,6 @@ import java.util.Set; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; -import com.simibubi.create.content.contraptions.components.structureMovement.ChassisRangeDisplay; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java similarity index 98% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java index 17261237b..a80351080 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ClientMotionPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java @@ -1,4 +1,4 @@ -package com.simibubi.create.content.contraptions.components.structureMovement; +package com.simibubi.create.content.contraptions.components.structureMovement.sync; import java.util.function.Supplier; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java similarity index 94% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java index 0b2d2c56a..731c791e4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionInteractionPacket.java @@ -1,7 +1,8 @@ -package com.simibubi.create.content.contraptions.components.structureMovement; +package com.simibubi.create.content.contraptions.components.structureMovement.sync; import java.util.function.Supplier; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.entity.Entity; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java similarity index 84% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java index d67e51504..4596dbd28 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionSeatMappingPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java @@ -1,10 +1,11 @@ -package com.simibubi.create.content.contraptions.components.structureMovement; +package com.simibubi.create.content.contraptions.components.structureMovement.sync; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.function.Supplier; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity; import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.client.Minecraft; @@ -44,12 +45,12 @@ public class ContraptionSeatMappingPacket extends SimplePacketBase { public void handle(Supplier context) { context.get() .enqueueWork(() -> { - Entity entityByID = Minecraft.getInstance().world - .getEntityByID(entityID); + Entity entityByID = Minecraft.getInstance().world.getEntityByID(entityID); if (!(entityByID instanceof ContraptionEntity)) return; ContraptionEntity contraptionEntity = (ContraptionEntity) entityByID; - contraptionEntity.contraption.seatMapping = mapping; + contraptionEntity.getContraption() + .setSeatMapping(mapping); }); context.get() .setPacketHandled(true); diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java similarity index 98% rename from src/main/java/com/simibubi/create/ClientEvents.java rename to src/main/java/com/simibubi/create/events/ClientEvents.java index c38981966..e3a3fc2c7 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -1,9 +1,11 @@ -package com.simibubi.create; +package com.simibubi.create.events; import java.util.ArrayList; import java.util.List; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.Create; +import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.contraptions.components.turntable.TurntableHandler; diff --git a/src/main/java/com/simibubi/create/CommonEvents.java b/src/main/java/com/simibubi/create/events/CommonEvents.java similarity index 93% rename from src/main/java/com/simibubi/create/CommonEvents.java rename to src/main/java/com/simibubi/create/events/CommonEvents.java index 0c4da0e88..12cd8d21b 100644 --- a/src/main/java/com/simibubi/create/CommonEvents.java +++ b/src/main/java/com/simibubi/create/events/CommonEvents.java @@ -1,5 +1,7 @@ -package com.simibubi.create; +package com.simibubi.create.events; +import com.simibubi.create.Create; +import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.command.CreateCommand; import net.minecraft.world.IWorld; @@ -20,7 +22,6 @@ public class CommonEvents { public static void onTick(ServerTickEvent event) { if (event.phase == Phase.END) return; - Create.tick(); } diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index bd2e888da..57a6b3a82 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -5,11 +5,11 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; -import com.simibubi.create.content.contraptions.components.structureMovement.ClientMotionPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionInteractionPacket; -import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket; import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket; import com.simibubi.create.content.curiosities.tools.ExtendoGripInteractionPacket;