From 8799fb38e88cd71b9df4f6241d877086afebeeef Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 22 Mar 2023 12:32:22 +0100 Subject: [PATCH] No turning back - Mechanical Pumps no longer reverse direction based on kinetic input - Fixed pipe connections pulling fluids with half the speed compared to a directly attached pump - Substantially increased speed of visual flow propagation inside pipe networks - Fixed observers on elevator contacts firing in the wrong order when triggered by manual floor selection - Portable storage interfaces now stall for longer after an exchange has happened, and shorter otherwise --- .../com/simibubi/create/AllPartialModels.java | 2 +- .../java/com/simibubi/create/AllShapes.java | 2 +- .../PortableStorageInterfaceBlockEntity.java | 4 +- .../elevator/ElevatorContactBlock.java | 6 +- .../elevator/ElevatorTargetFloorPacket.java | 19 +-- .../contraptions/fluids/PipeConnection.java | 2 +- .../contraptions/fluids/PumpBlock.java | 26 ++- .../contraptions/fluids/PumpBlockEntity.java | 71 +++----- .../contraptions/fluids/PumpCogInstance.java | 58 +------ .../contraptions/fluids/PumpRenderer.java | 32 ---- .../create/foundation/config/CLogistics.java | 2 +- .../models/block/mechanical_pump/arrow.json | 117 -------------- .../models/block/mechanical_pump/block.json | 66 +++++++- .../models/block/mechanical_pump/item.json | 152 ++++++++---------- .../assets/create/textures/block/pipes.png | Bin 808 -> 881 bytes .../assets/create/textures/block/pump.png | Bin 678 -> 684 bytes 16 files changed, 193 insertions(+), 366 deletions(-) delete mode 100644 src/main/resources/assets/create/models/block/mechanical_pump/arrow.json diff --git a/src/main/java/com/simibubi/create/AllPartialModels.java b/src/main/java/com/simibubi/create/AllPartialModels.java index 1519988e1..0ce78b729 100644 --- a/src/main/java/com/simibubi/create/AllPartialModels.java +++ b/src/main/java/com/simibubi/create/AllPartialModels.java @@ -92,7 +92,7 @@ public class AllPartialModels { ARM_HEAD = block("mechanical_arm/head"), ARM_CLAW_BASE = block("mechanical_arm/claw_base"), ARM_CLAW_GRIP = block("mechanical_arm/claw_grip"), - MECHANICAL_PUMP_ARROW = block("mechanical_pump/arrow"), MECHANICAL_PUMP_COG = block("mechanical_pump/cog"), + MECHANICAL_PUMP_COG = block("mechanical_pump/cog"), FLUID_PIPE_CASING = block("fluid_pipe/casing"), FLUID_VALVE_POINTER = block("fluid_valve/pointer"), SPOUT_TOP = block("spout/top"), SPOUT_MIDDLE = block("spout/middle"), SPOUT_BOTTOM = block("spout/bottom"), diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 28e13b1ff..48acad91e 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -109,7 +109,7 @@ public class AllShapes { .add(5, -1, 6, 11, 0, 8) .forHorizontal(SOUTH), PUMP = shape(2, 0, 2, 14, 5, 14).add(4, 0, 4, 12, 16, 12) - .add(3, 12, 3, 13, 16, 13) + .add(3, 11, 3, 13, 16, 13) .forDirectional(Direction.UP), CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16).forDirectional(Direction.DOWN), diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlockEntity.java index 082a7e97b..da30c9f61 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlockEntity.java @@ -84,7 +84,7 @@ public abstract class PortableStorageInterfaceBlockEntity extends SmartBlockEnti } } - transferTimer = Math.min(transferTimer, ANIMATION * 2 + getTransferTimeout()); + transferTimer = Math.min(transferTimer, ANIMATION * 2 + timeUnit); boolean timerCanDecrement = transferTimer > ANIMATION || transferTimer > 0 && keepAlive == 0 && (isVirtual() || !level.isClientSide || transferTimer != ANIMATION); @@ -180,7 +180,7 @@ public abstract class PortableStorageInterfaceBlockEntity extends SmartBlockEnti } public void startConnecting() { - transferTimer = getTransferTimeout() + ANIMATION * 2; + transferTimer = 6 + ANIMATION * 2; } public void onContentTransferred() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java index 319ef50e0..3b34d358e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorContactBlock.java @@ -90,9 +90,13 @@ public class ElevatorContactBlock extends WrenchableDirectionalBlock if (pState.getValue(CALLING)) return; + ElevatorColumn elevatorColumn = ElevatorColumn.getOrCreate(pLevel, getColumnCoords(pLevel, pPos)); + callToContactAndUpdate(elevatorColumn, pState, pLevel, pPos); + } + + public void callToContactAndUpdate(ElevatorColumn elevatorColumn, BlockState pState, Level pLevel, BlockPos pPos) { pLevel.setBlock(pPos, pState.cycle(CALLING), 2); - ElevatorColumn elevatorColumn = ElevatorColumn.getOrCreate(pLevel, getColumnCoords(pLevel, pPos)); for (BlockPos otherPos : elevatorColumn.getContacts()) { if (otherPos.equals(pPos)) continue; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java index 0bc29f19d..001371986 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/elevator/ElevatorTargetFloorPacket.java @@ -1,6 +1,5 @@ package com.simibubi.create.content.contraptions.components.structureMovement.elevator; -import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.foundation.networking.SimplePacketBase; @@ -41,7 +40,7 @@ public class ElevatorTargetFloorPacket extends SimplePacketBase { .getEntity(entityId); if (!(entityByID instanceof AbstractContraptionEntity ace)) return; - if (!(ace.getContraption()instanceof ElevatorContraption ec)) + if (!(ace.getContraption() instanceof ElevatorContraption ec)) return; if (ace.distanceToSqr(sender) > 50 * 50) return; @@ -53,18 +52,12 @@ public class ElevatorTargetFloorPacket extends SimplePacketBase { if (ec.isTargetUnreachable(targetY)) return; - for (BlockPos otherPos : elevatorColumn.getContacts()) { - BlockState otherState = level.getBlockState(otherPos); - if (!AllBlocks.ELEVATOR_CONTACT.has(otherState)) - continue; - level.setBlock(otherPos, otherState.setValue(ElevatorContactBlock.CALLING, otherPos.getY() == targetY), - 2); - AllBlocks.ELEVATOR_CONTACT.get() - .scheduleActivation(level, otherPos); - } + BlockPos pos = elevatorColumn.contactAt(targetY); + BlockState blockState = level.getBlockState(pos); + if (!(blockState.getBlock() instanceof ElevatorContactBlock ecb)) + return; - elevatorColumn.target(targetY); - elevatorColumn.markDirty(); + ecb.callToContactAndUpdate(elevatorColumn, blockState, level, pos); }); return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PipeConnection.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PipeConnection.java index d1961bf7b..1b6d3461f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PipeConnection.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PipeConnection.java @@ -201,7 +201,7 @@ public class PipeConnection { particleSplashNextTick = false; } - float flowSpeed = 1 / 32f + Mth.clamp(pressure.get(flow.inbound) / 512f, 0, 1) * 31 / 32f; + float flowSpeed = 1 / 32f + Mth.clamp(pressure.get(flow.inbound) / 128f, 0, 1) * 31 / 32f; flow.progress.setValue(Math.min(flow.progress.getValue() + flowSpeed, 1)); if (flow.progress.getValue() >= 1) flow.complete = true; diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlock.java index 681d2cc17..fb0333cc3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlock.java @@ -32,6 +32,7 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.ticks.TickPriority; @@ -107,20 +108,33 @@ public class PumpBlock extends DirectionalKineticBlock Player player = context.getPlayer(); toPlace = ProperWaterloggedBlock.withWater(level, toPlace, pos); - if (player != null && player.isSteppingCarefully()) - return toPlace; + Direction nearestLookingDirection = context.getNearestLookingDirection(); + Direction targetDirection = context.getPlayer() != null && context.getPlayer() + .isShiftKeyDown() ? nearestLookingDirection : nearestLookingDirection.getOpposite(); + Direction bestConnectedDirection = null; + double bestDistance = Double.MAX_VALUE; for (Direction d : Iterate.directions) { BlockPos adjPos = pos.relative(d); BlockState adjState = level.getBlockState(adjPos); if (!FluidPipeBlock.canConnectTo(level, adjPos, adjState, d)) continue; - toPlace = toPlace.setValue(FACING, d); - if (context.getClickedFace() == d.getOpposite()) - break; + double distance = Vec3.atLowerCornerOf(d.getNormal()) + .distanceTo(Vec3.atLowerCornerOf(targetDirection.getNormal())); + if (distance > bestDistance) + continue; + bestDistance = distance; + bestConnectedDirection = d; } - return toPlace; + if (bestConnectedDirection == null) + return toPlace; + if (bestConnectedDirection.getAxis() == targetDirection.getAxis()) + return toPlace; + if (player.isSteppingCarefully() && bestConnectedDirection.getAxis() != targetDirection.getAxis()) + return toPlace; + + return toPlace.setValue(FACING, bestConnectedDirection); } public static boolean isPump(BlockState state) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlockEntity.java index c1dfb23da..9bacc5d80 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpBlockEntity.java @@ -21,8 +21,6 @@ import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Pair; -import com.simibubi.create.foundation.utility.animation.LerpedFloat; -import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -38,15 +36,14 @@ import net.minecraftforge.fluids.capability.IFluidHandler; public class PumpBlockEntity extends KineticBlockEntity { - LerpedFloat arrowDirection; Couple sidesToUpdate; boolean pressureUpdate; - boolean reversed; + + // Backcompat- flips any pump blockstate that loads with reversed=true + boolean scheduleFlip; public PumpBlockEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { super(typeIn, pos, state); - arrowDirection = LerpedFloat.linear() - .startWithValue(1); sidesToUpdate = Couple.create(MutableBoolean::new); } @@ -58,55 +55,36 @@ public class PumpBlockEntity extends KineticBlockEntity { registerAwardables(behaviours, AllAdvancements.PUMP); } - @Override - public void initialize() { - super.initialize(); - reversed = getSpeed() < 0; - } - @Override public void tick() { super.tick(); - float speed = getSpeed(); - if (level.isClientSide) { - if (speed == 0) - return; - arrowDirection.chase(speed >= 0 ? 1 : -1, .5f, Chaser.EXP); - arrowDirection.tickChaser(); - if (!isVirtual()) - return; + if (level.isClientSide && !isVirtual()) + return; + + if (scheduleFlip) { + level.setBlockAndUpdate(worldPosition, + getBlockState().setValue(PumpBlock.FACING, getBlockState().getValue(PumpBlock.FACING) + .getOpposite())); + scheduleFlip = false; } -// if (pressureUpdate) -// updatePressureChange(); - sidesToUpdate.forEachWithContext((update, isFront) -> { if (update.isFalse()) return; update.setFalse(); distributePressureTo(isFront ? getFront() : getFront().getOpposite()); }); - - if (speed == 0) - return; - if (speed < 0 != reversed) { - reversed = speed < 0; - updatePressureChange(); - return; - } } @Override public void onSpeedChanged(float previousSpeed) { super.onSpeedChanged(previousSpeed); - if (previousSpeed == getSpeed()) + if (Math.abs(previousSpeed) == Math.abs(getSpeed())) return; - if (speed != 0) { - reversed = speed < 0; + if (speed != 0) award(AllAdvancements.PUMP); - } if (level.isClientSide && !isVirtual()) return; @@ -126,6 +104,13 @@ public class PumpBlockEntity extends KineticBlockEntity { sidesToUpdate.forEach(MutableBoolean::setTrue); } + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + if (compound.getBoolean("Reversed")) + scheduleFlip = true; + } + protected void distributePressureTo(Direction side) { if (getSpeed() == 0) return; @@ -216,7 +201,7 @@ public class PumpBlockEntity extends KineticBlockEntity { float pressure = Math.abs(getSpeed()); for (Set set : validFaces.values()) { - int parallelBranches = set.size(); + int parallelBranches = Math.max(1, set.size() - 1); for (BlockFace face : set) { BlockPos pipePos = face.getPos(); Direction pipeSide = face.getFace(); @@ -309,18 +294,6 @@ public class PumpBlockEntity extends KineticBlockEntity { return FluidPropagator.isOpenEnd(world, blockFace.getPos(), face); } - @Override - public void write(CompoundTag compound, boolean clientPacket) { - compound.putBoolean("Reversed", reversed); - super.write(compound, clientPacket); - } - - @Override - protected void read(CompoundTag compound, boolean clientPacket) { - reversed = compound.getBoolean("Reversed"); - super.read(compound, clientPacket); - } - public void updatePipesOnSide(Direction side) { if (!isSideAccessible(side)) return; @@ -359,7 +332,7 @@ public class PumpBlockEntity extends KineticBlockEntity { } public boolean isPullingOnSide(boolean front) { - return front == reversed; + return !front; } class PumpFluidTransferBehaviour extends FluidTransportBehaviour { diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java index 37cf56e9f..14693ac31 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java @@ -3,74 +3,28 @@ package com.simibubi.create.content.contraptions.fluids; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.core.Materials; -import com.jozufozu.flywheel.core.materials.model.ModelData; import com.simibubi.create.AllPartialModels; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.content.contraptions.base.flwdata.RotatingData; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.core.Direction; -import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class PumpCogInstance extends SingleRotatingInstance implements DynamicInstance { - private final ModelData[] arrows = new ModelData[2]; - private final Direction direction = blockState.getValue(PumpBlock.FACING); - - public PumpCogInstance(MaterialManager materialManager, PumpBlockEntity blockEntity) { - super(materialManager, blockEntity); - } - - @Override - public void init() { - super.init(); - - materialManager.defaultSolid() - .material(Materials.TRANSFORMED) - .getModel(AllPartialModels.MECHANICAL_PUMP_ARROW, blockState) - .createInstances(arrows); + public PumpCogInstance(MaterialManager materialManager, PumpBlockEntity blockEntity) { + super(materialManager, blockEntity); } + + @Override + public void beginFrame() {} @Override - public void beginFrame() { - float angle = Mth.lerp(blockEntity.arrowDirection.getValue(AnimationTickHolder.getPartialTicks()), 0, 90) - 90; - for (int i = 0, arrowsLength = arrows.length; i < arrowsLength; i++) { - arrows[i].loadIdentity() - .translate(getInstancePosition()) - .centre() - .rotateY(AngleHelper.horizontalAngle(direction) + 180) - .rotateX(-AngleHelper.verticalAngle(direction) - 90) - .unCentre() - .translate(.5, 14 / 16f, .5) - .rotateY(90 * i) - .rotateZ(angle) - .translateBack(.5, 14 / 16f, .5); - } - } - - @Override - public void updateLight() { - super.updateLight(); - relight(pos, arrows); - } - - @Override - protected Instancer getModel() { + protected Instancer getModel() { BlockState referenceState = blockEntity.getBlockState(); Direction facing = referenceState.getValue(BlockStateProperties.FACING); return getRotatingMaterial().getModel(AllPartialModels.MECHANICAL_PUMP_COG, referenceState, facing); } - @Override - public void remove() { - super.remove(); - - for (ModelData arrow : arrows) { - arrow.delete(); - } - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java index c9dd5777d..b9ff47060 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpRenderer.java @@ -1,20 +1,12 @@ package com.simibubi.create.content.contraptions.fluids; -import com.jozufozu.flywheel.backend.Backend; -import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllPartialModels; import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer; import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.utility.AngleHelper; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; public class PumpRenderer extends KineticBlockEntityRenderer { @@ -22,30 +14,6 @@ public class PumpRenderer extends KineticBlockEntityRenderer { super(context); } - @Override - protected void renderSafe(PumpBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, - int light, int overlay) { - super.renderSafe(be, partialTicks, ms, buffer, light, overlay); - if (Backend.canUseInstancing(be.getLevel())) return; - Vec3 rotationOffset = new Vec3(.5, 14 / 16f, .5); - BlockState blockState = be.getBlockState(); - float angle = Mth.lerp(be.arrowDirection.getValue(partialTicks), 0, 90) - 90; - SuperByteBuffer arrow = CachedBufferer.partial(AllPartialModels.MECHANICAL_PUMP_ARROW, blockState); - for (float yRot : new float[] { 0, 90 }) { - Direction direction = blockState.getValue(PumpBlock.FACING); - arrow.centre() - .rotateY(AngleHelper.horizontalAngle(direction) + 180) - .rotateX(-AngleHelper.verticalAngle(direction) - 90) - .unCentre() - .translate(rotationOffset) - .rotateY(yRot) - .rotateZ(angle) - .translateBack(rotationOffset) - .light(light) - .renderInto(ms, buffer.getBuffer(RenderType.solid())); - } - } - @Override protected SuperByteBuffer getRotatedModel(PumpBlockEntity be, BlockState state) { return CachedBufferer.partialFacing(AllPartialModels.MECHANICAL_PUMP_COG, state); diff --git a/src/main/java/com/simibubi/create/foundation/config/CLogistics.java b/src/main/java/com/simibubi/create/foundation/config/CLogistics.java index cde5fe2d3..4ba3b7d49 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CLogistics.java +++ b/src/main/java/com/simibubi/create/foundation/config/CLogistics.java @@ -5,7 +5,7 @@ public class CLogistics extends ConfigBase { public final ConfigInt defaultExtractionLimit = i(64, 1, 64, "defaultExtractionLimit", Comments.defaultExtractionLimit); public final ConfigInt defaultExtractionTimer = i(8, 1, "defaultExtractionTimer", Comments.defaultExtractionTimer); - public final ConfigInt psiTimeout = i(20, 1, "psiTimeout", Comments.psiTimeout); + public final ConfigInt psiTimeout = i(60, 1, "psiTimeout", Comments.psiTimeout); public final ConfigInt mechanicalArmRange = i(5, 1, "mechanicalArmRange", Comments.mechanicalArmRange); public final ConfigInt linkRange = i(256, 1, "linkRange", Comments.linkRange); public final ConfigInt displayLinkRange = i(64, 1, "displayLinkRange", Comments.displayLinkRange); diff --git a/src/main/resources/assets/create/models/block/mechanical_pump/arrow.json b/src/main/resources/assets/create/models/block/mechanical_pump/arrow.json deleted file mode 100644 index 56ff46484..000000000 --- a/src/main/resources/assets/create/models/block/mechanical_pump/arrow.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "credit": "Made with Blockbench", - "parent": "create:block/large_wheels", - "textures": { - "4": "create:block/pump", - "particle": "create:block/fluid_pipe" - }, - "elements": [ - { - "from": [7, 11.5, 1.5], - "to": [9, 13.5, 2.5], - "rotation": {"angle": -45, "axis": "z", "origin": [8, 14.5, 9.5]}, - "faces": { - "north": {"uv": [12, 2, 14, 4], "rotation": 270, "texture": "#4"}, - "east": {"uv": [12, 2, 14, 3], "rotation": 270, "texture": "#4"}, - "south": {"uv": [14, 2, 12, 4], "rotation": 90, "texture": "#4"}, - "west": {"uv": [12, 3, 14, 4], "rotation": 90, "texture": "#4"}, - "up": {"uv": [12, 3, 14, 4], "texture": "#4"}, - "down": {"uv": [12, 2, 13, 4], "rotation": 90, "texture": "#4"} - } - }, - { - "from": [7, 11.5, 13.5], - "to": [9, 13.5, 14.5], - "rotation": {"angle": -45, "axis": "z", "origin": [8, 14.5, 6.5]}, - "faces": { - "north": {"uv": [14, 4, 12, 2], "rotation": 90, "texture": "#4"}, - "east": {"uv": [12, 3, 14, 2], "rotation": 270, "texture": "#4"}, - "south": {"uv": [12, 4, 14, 2], "rotation": 270, "texture": "#4"}, - "west": {"uv": [12, 4, 14, 3], "rotation": 90, "texture": "#4"}, - "up": {"uv": [12, 4, 14, 3], "texture": "#4"}, - "down": {"uv": [13, 2, 12, 4], "rotation": 90, "texture": "#4"} - } - }, - { - "from": [7, 13.5, 1.5], - "to": [11, 15.5, 2.5], - "rotation": {"angle": -45, "axis": "z", "origin": [8, 14.5, 9.5]}, - "faces": { - "north": {"uv": [14, 0, 16, 4], "rotation": 270, "texture": "#4"}, - "east": {"uv": [14, 0, 16, 1], "rotation": 270, "texture": "#4"}, - "south": {"uv": [16, 0, 14, 4], "rotation": 90, "texture": "#4"}, - "west": {"uv": [12, 3, 14, 4], "rotation": 270, "texture": "#4"}, - "up": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"}, - "down": {"uv": [12, 0, 13, 4], "rotation": 270, "texture": "#4"} - } - }, - { - "from": [7, 13.5, 13.5], - "to": [11, 15.5, 14.5], - "rotation": {"angle": -45, "axis": "z", "origin": [8, 14.5, 6.5]}, - "faces": { - "north": {"uv": [16, 4, 14, 0], "rotation": 90, "texture": "#4"}, - "east": {"uv": [14, 1, 16, 0], "rotation": 270, "texture": "#4"}, - "south": {"uv": [14, 4, 16, 0], "rotation": 270, "texture": "#4"}, - "west": {"uv": [12, 4, 14, 3], "rotation": 270, "texture": "#4"}, - "up": {"uv": [16, 0, 15, 4], "rotation": 90, "texture": "#4"}, - "down": {"uv": [13, 0, 12, 4], "rotation": 270, "texture": "#4"} - } - }, - { - "name": "rod", - "from": [7.5, 13.5, 1], - "to": [8.5, 14.5, 15], - "rotation": {"angle": 0, "axis": "y", "origin": [15.5, 21.5, 10]}, - "faces": { - "north": {"uv": [0, 15, 1, 16], "texture": "#4"}, - "east": {"uv": [0, 15, 14, 16], "texture": "#4"}, - "south": {"uv": [0, 15, 1, 16], "texture": "#4"}, - "west": {"uv": [0, 15, 14, 16], "texture": "#4"}, - "up": {"uv": [0, 15, 14, 16], "rotation": 90, "texture": "#4"}, - "down": {"uv": [0, 15, 14, 16], "rotation": 90, "texture": "#4"} - } - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [75, -149, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "thirdperson_lefthand": { - "rotation": [75, -149, 0], - "translation": [0, 2.5, 0], - "scale": [0.375, 0.375, 0.375] - }, - "firstperson_righthand": { - "rotation": [0, -55, 0], - "scale": [0.4, 0.4, 0.4] - }, - "firstperson_lefthand": { - "rotation": [0, -55, 0], - "scale": [0.4, 0.4, 0.4] - }, - "ground": { - "translation": [0, 1, 1.25], - "scale": [0.25, 0.25, 0.25] - }, - "gui": { - "rotation": [30, 45, 0], - "translation": [2.5, -0.5, 0], - "scale": [0.625, 0.625, 0.625] - }, - "fixed": { - "rotation": [0, 180, 0], - "translation": [0, 1.75, -4.5], - "scale": [0.5, 0.5, 0.5] - } - }, - "groups": [ - { - "name": "arrow", - "origin": [8, 8, 8], - "children": [0, 1, 2, 3, 4] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_pump/block.json b/src/main/resources/assets/create/models/block/mechanical_pump/block.json index df7988ce9..8dd3ab9b7 100644 --- a/src/main/resources/assets/create/models/block/mechanical_pump/block.json +++ b/src/main/resources/assets/create/models/block/mechanical_pump/block.json @@ -37,17 +37,67 @@ }, { "name": "front", - "from": [3, 12, 3], + "from": [3, 11, 3], "to": [13, 16, 13], "rotation": {"angle": 0, "axis": "z", "origin": [8.33333, 8.5, 8]}, "faces": { - "north": {"uv": [12, 4, 16, 14], "rotation": 90, "texture": "#4"}, - "east": {"uv": [12, 4, 16, 14], "rotation": 90, "texture": "#4"}, - "south": {"uv": [12, 4, 16, 14], "rotation": 90, "texture": "#4"}, - "west": {"uv": [12, 4, 16, 14], "rotation": 90, "texture": "#4"}, + "north": {"uv": [10.5, 2.5, 13, 7.5], "rotation": 90, "texture": "#2"}, + "east": {"uv": [10.5, 2.5, 13, 7.5], "rotation": 90, "texture": "#2"}, + "south": {"uv": [10.5, 2.5, 13, 7.5], "rotation": 90, "texture": "#2"}, + "west": {"uv": [10.5, 2.5, 13, 7.5], "rotation": 90, "texture": "#2"}, "up": {"uv": [11, 11, 16, 16], "texture": "#2"}, "down": {"uv": [6, 11, 11, 16], "texture": "#2"} } + }, + { + "from": [5.85355, 13.25, 1.75], + "to": [9.85355, 15.25, 13.75], + "rotation": {"angle": 45, "axis": "z", "origin": [8.35355, 13.25, 7.75]}, + "faces": { + "north": {"uv": [16, 0, 12, 2], "texture": "#4"}, + "east": {"uv": [15, 0, 16, 2], "texture": "#4"}, + "south": {"uv": [12, 0, 16, 2], "texture": "#4"}, + "west": {"uv": [12, 0, 13, 2], "texture": "#4"}, + "up": {"uv": [12, 0, 16, 1], "texture": "#4"}, + "down": {"uv": [12, 1, 16, 2], "texture": "#4"} + } + }, + { + "from": [7.85355, 11.25, 1.75], + "to": [9.85355, 13.25, 13.75], + "rotation": {"angle": 45, "axis": "z", "origin": [8.35355, 13.25, 7.75]}, + "faces": { + "north": {"uv": [16, 2, 14, 4], "texture": "#4"}, + "east": {"uv": [15, 2, 16, 4], "texture": "#4"}, + "south": {"uv": [14, 2, 16, 4], "texture": "#4"}, + "west": {"uv": [14, 2, 15, 4], "texture": "#4"}, + "down": {"uv": [14, 3, 16, 4], "texture": "#4"} + } + }, + { + "from": [2.35355, 10.75, 7.75], + "to": [14.35355, 12.75, 9.75], + "rotation": {"angle": -45, "axis": "x", "origin": [8.35355, 13.25, 7.75]}, + "faces": { + "north": {"uv": [14, 2, 15, 4], "texture": "#4"}, + "east": {"uv": [16, 2, 14, 4], "texture": "#4"}, + "south": {"uv": [15, 2, 16, 4], "texture": "#4"}, + "west": {"uv": [14, 2, 16, 4], "texture": "#4"}, + "down": {"uv": [14, 3, 16, 4], "rotation": 270, "texture": "#4"} + } + }, + { + "from": [2.35355, 12.75, 5.75], + "to": [14.35355, 14.75, 9.75], + "rotation": {"angle": -45, "axis": "x", "origin": [8.35355, 13.25, 7.75]}, + "faces": { + "north": {"uv": [12, 0, 13, 2], "texture": "#4"}, + "east": {"uv": [16, 0, 12, 2], "texture": "#4"}, + "south": {"uv": [15, 0, 16, 2], "texture": "#4"}, + "west": {"uv": [12, 0, 16, 2], "texture": "#4"}, + "up": {"uv": [12, 0, 16, 1], "rotation": 90, "texture": "#4"}, + "down": {"uv": [12, 1, 16, 2], "rotation": 270, "texture": "#4"} + } } ], "display": { @@ -87,6 +137,10 @@ "origin": [8, 8, 8], "color": 0, "children": [0, 1, 2] - } + }, + 3, + 4, + 5, + 6 ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_pump/item.json b/src/main/resources/assets/create/models/block/mechanical_pump/item.json index c2dd84152..161c4910c 100644 --- a/src/main/resources/assets/create/models/block/mechanical_pump/item.json +++ b/src/main/resources/assets/create/models/block/mechanical_pump/item.json @@ -8,72 +8,6 @@ "particle": "create:block/pump" }, "elements": [ - { - "from": [1, 3, 1.5], - "to": [3, 5, 2.5], - "rotation": {"angle": -45, "axis": "z", "origin": [6.5, 4, 8]}, - "faces": { - "north": {"uv": [12, 2, 14, 4], "texture": "#4"}, - "east": {"uv": [12, 2, 13, 4], "texture": "#4"}, - "south": {"uv": [14, 2, 12, 4], "texture": "#4"}, - "west": {"uv": [12, 3, 14, 4], "rotation": 270, "texture": "#4"}, - "up": {"uv": [12, 2, 14, 3], "rotation": 180, "texture": "#4"}, - "down": {"uv": [12, 3, 14, 4], "texture": "#4"} - } - }, - { - "from": [1, 3, 13.5], - "to": [3, 5, 14.5], - "rotation": {"angle": -45, "axis": "z", "origin": [6.5, 4, 8]}, - "faces": { - "north": {"uv": [14, 4, 12, 2], "rotation": 180, "texture": "#4"}, - "east": {"uv": [13, 2, 12, 4], "texture": "#4"}, - "south": {"uv": [12, 4, 14, 2], "rotation": 180, "texture": "#4"}, - "west": {"uv": [12, 4, 14, 3], "rotation": 270, "texture": "#4"}, - "up": {"uv": [12, 3, 14, 2], "rotation": 180, "texture": "#4"}, - "down": {"uv": [12, 4, 14, 3], "texture": "#4"} - } - }, - { - "from": [-1, 3, 1.5], - "to": [1, 7, 2.5], - "rotation": {"angle": -45, "axis": "z", "origin": [6.5, 4, 8]}, - "faces": { - "north": {"uv": [14, 0, 16, 4], "texture": "#4"}, - "east": {"uv": [12, 0, 13, 4], "rotation": 180, "texture": "#4"}, - "south": {"uv": [16, 0, 14, 4], "texture": "#4"}, - "west": {"uv": [15, 0, 16, 4], "texture": "#4"}, - "up": {"uv": [14, 0, 16, 1], "rotation": 180, "texture": "#4"}, - "down": {"uv": [12, 3, 14, 4], "rotation": 180, "texture": "#4"} - } - }, - { - "from": [-1, 3, 13.5], - "to": [1, 7, 14.5], - "rotation": {"angle": -45, "axis": "z", "origin": [6.5, 4, 8]}, - "faces": { - "north": {"uv": [16, 4, 14, 0], "rotation": 180, "texture": "#4"}, - "east": {"uv": [13, 0, 12, 4], "rotation": 180, "texture": "#4"}, - "south": {"uv": [14, 4, 16, 0], "rotation": 180, "texture": "#4"}, - "west": {"uv": [16, 0, 15, 4], "texture": "#4"}, - "up": {"uv": [14, 1, 16, 0], "rotation": 180, "texture": "#4"}, - "down": {"uv": [12, 4, 14, 3], "rotation": 180, "texture": "#4"} - } - }, - { - "name": "rod", - "from": [2, 8, 1], - "to": [3, 9, 15], - "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 16, 8]}, - "faces": { - "north": {"uv": [0, 15, 1, 16], "rotation": 90, "texture": "#4"}, - "east": {"uv": [0, 15, 14, 16], "texture": "#4"}, - "south": {"uv": [0, 15, 1, 16], "rotation": 270, "texture": "#4"}, - "west": {"uv": [0, 15, 14, 16], "texture": "#4"}, - "up": {"uv": [0, 15, 14, 16], "rotation": 270, "texture": "#4"}, - "down": {"uv": [0, 15, 14, 16], "rotation": 270, "texture": "#4"} - } - }, { "name": "Gear5", "from": [5.5, 7, -1], @@ -158,6 +92,20 @@ "down": {"uv": [11.5, 15.5, 15.5, 11.5], "texture": "#2"} } }, + { + "name": "front", + "from": [0.5, 3.5, 3], + "to": [5.5, 13.5, 13], + "rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [10.5, 2.5, 13, 7.5], "rotation": 180, "texture": "#2"}, + "east": {"uv": [6, 11, 11, 16], "rotation": 270, "texture": "#2"}, + "south": {"uv": [10.5, 2.5, 13, 7.5], "texture": "#2"}, + "west": {"uv": [11, 11, 16, 16], "rotation": 270, "texture": "#2"}, + "up": {"uv": [10.5, 2.5, 13, 7.5], "texture": "#2"}, + "down": {"uv": [10.5, 2.5, 13, 7.5], "texture": "#2"} + } + }, { "name": "back", "from": [11.5, 2.5, 2], @@ -173,17 +121,53 @@ } }, { - "name": "front", - "from": [0.5, 3.5, 3], - "to": [4.5, 13.5, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [8.5, 10.5, 8]}, + "from": [1.70355, 6.15, 2], + "to": [3.70355, 10.15, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [3.35355, 8.25, 7.75]}, "faces": { - "north": {"uv": [12, 4, 16, 14], "rotation": 180, "texture": "#4"}, - "east": {"uv": [6, 11, 11, 16], "rotation": 270, "texture": "#2"}, - "south": {"uv": [12, 4, 16, 14], "texture": "#4"}, - "west": {"uv": [11, 11, 16, 16], "rotation": 270, "texture": "#2"}, - "up": {"uv": [12, 4, 16, 14], "texture": "#4"}, - "down": {"uv": [12, 4, 16, 14], "texture": "#4"} + "north": {"uv": [16, 0, 12, 2], "rotation": 90, "texture": "#4"}, + "east": {"uv": [12, 1, 16, 2], "rotation": 270, "texture": "#4"}, + "south": {"uv": [12, 0, 16, 2], "rotation": 270, "texture": "#4"}, + "west": {"uv": [12, 0, 16, 1], "rotation": 270, "texture": "#4"}, + "up": {"uv": [15, 0, 16, 2], "rotation": 270, "texture": "#4"}, + "down": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"} + } + }, + { + "from": [3.70355, 8.15, 2], + "to": [5.70355, 10.15, 14], + "rotation": {"angle": 45, "axis": "z", "origin": [3.35355, 8.25, 7.75]}, + "faces": { + "north": {"uv": [16, 2, 14, 4], "rotation": 90, "texture": "#4"}, + "east": {"uv": [14, 3, 16, 4], "rotation": 270, "texture": "#4"}, + "south": {"uv": [14, 2, 16, 4], "rotation": 270, "texture": "#4"}, + "up": {"uv": [15, 2, 16, 4], "rotation": 270, "texture": "#4"}, + "down": {"uv": [14, 2, 15, 4], "rotation": 270, "texture": "#4"} + } + }, + { + "from": [3.85355, 2.5, 7.75], + "to": [5.85355, 14.5, 9.75], + "rotation": {"angle": -45, "axis": "y", "origin": [3.35355, 8.25, 7.75]}, + "faces": { + "north": {"uv": [14, 2, 15, 4], "rotation": 90, "texture": "#4"}, + "east": {"uv": [14, 3, 16, 4], "rotation": 180, "texture": "#4"}, + "south": {"uv": [15, 2, 16, 4], "rotation": 270, "texture": "#4"}, + "up": {"uv": [16, 2, 14, 4], "rotation": 270, "texture": "#4"}, + "down": {"uv": [14, 2, 16, 4], "rotation": 270, "texture": "#4"} + } + }, + { + "from": [1.85355, 2.5, 5.75], + "to": [3.85355, 14.5, 9.75], + "rotation": {"angle": -45, "axis": "y", "origin": [3.35355, 8.25, 7.75]}, + "faces": { + "north": {"uv": [12, 0, 13, 2], "rotation": 90, "texture": "#4"}, + "east": {"uv": [12, 1, 16, 2], "rotation": 180, "texture": "#4"}, + "south": {"uv": [15, 0, 16, 2], "rotation": 270, "texture": "#4"}, + "west": {"uv": [12, 0, 16, 1], "texture": "#4"}, + "up": {"uv": [16, 0, 12, 2], "rotation": 270, "texture": "#4"}, + "down": {"uv": [12, 0, 16, 2], "rotation": 270, "texture": "#4"} } } ], @@ -220,22 +204,22 @@ }, "groups": [ { - "name": "arrow", + "name": "cogwheel", "origin": [8, 8, 8], "color": 0, "children": [0, 1, 2, 3, 4] }, - { - "name": "cogwheel", - "origin": [8, 8, 8], - "color": 0, - "children": [5, 6, 7, 8, 9] - }, { "name": "pump", "origin": [8, 8, 8], "color": 0, - "children": [10, 11, 12] + "children": [5, 6, 7] + }, + { + "name": "Arrow", + "origin": [8, 8, 8], + "color": 0, + "children": [8, 9, 10, 11] } ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/pipes.png b/src/main/resources/assets/create/textures/block/pipes.png index 790be85be0fb42833cd722f50ea3ee4e0326a72c..c9166a8b1daadbcc1a0bd5c920e390ddd3f2bb98 100644 GIT binary patch delta 806 zcmV+>1KIqj2Jr@vEhSKLZ)Rz1WdHyu&y|rqNW)MRg-_FJMOqx}AmWgrcCsKU;wVv( zQZ9cgc;WFr&U@!@-+h44s4~q8j02i(o9Tok=JG3I@D;uAA&eLTGP8_iW+98N^>t5o zsqW%D3;(OITCf=46NzV;VcNv&#M7I$!FiuJ!pgErd`>)OQiH^gTvt4P<6LrC;F%FK zo1P<%5R0V_RyvrKO^tYpII3zoEa{4A*ImAb~|Bk%9;X zHB?ZAjX3Q(DHhUnE_Lw_yZ#ip6mnI-$T5!%Xpmh$_#gb9tyP?y@RC9j(DULrAEQ8U z7iiWU=lj@knkRt&8MxBh{*4AO^GSNWtwoQ3fo`H!GLa~1c zyr0oG<$=LlpnuhyTk9OB4?vb?wR8g<90IWtWv_L4cVFk+{=DPP57G}RI&z9q#rZ=3 z001^nOjJd^UQghQWAwIp%4k%uR7#jeLwGhj*mGK>O-77BK>x~x>7#ALV^UQhEC2Vx zJr*8iDK!890NaiCE&u=k5_D2dQ~!Ve|NsC0|NsC0|NsC0|Ns90;=jKV00009a7bBm z000XU000XU0RWnu7ytkPGD$>1R5(wClI?cFFbqTOB#uJ74*LEtJGm)c*AFIsVeYXd z1rbe}i`Dr?Qb3?R?g2sn2hadMoLGQs4{+}ifS&-%MeGeAfP)9oF9?C|0VIDvnG}V} zT#A{En8yuB{LBCZQm#y*2jFl5mnK(0ysW^nhxLS@EHTeT?M)8gQ_STx55S+I?w@-A zCONlOt3VT_T)n7TRw}b7&gg+(Q}2nR0ZfxNdej97leEj`7~2L=O)Y8D<%ICW82>5& zRbkp2#fgY;3v4F8`KMa7^YM0TS$c2T-Ieo7XaJ&>2|_CFbQ)?PFs1=aPimqEfB;v( zP=NsesmAZmrz9zbKu-stzkx1~M*#f@*ap0FfNAN_+RU22ABd;kCd07*qoM6N<$f-(zw_5c6? delta 733 zcmV<30wVqK2B-#*EhTVrZ)Rz1WdHzpoPCi!NW)MRg-_FJMOqx}AmWgrcCsKU;wV*- zQZ9evg~$6i@1DbZ_W?q)##A#f4yc-CWReLnUsw@?ujqvjVZ;!Sn5n0-3pse!*FE)8 z-Nkv9ci*2CR*EJAd?N8I(+!Jwop^fF(mC%FM_5Hth|h_~47wokBiCh@-#C{Y7IKTr#<;VC0y`22@CnAN&t~&(-1km$h+aIGq za2IGbZ2SAzwp%BF{~5T_I{u9&F!M=zqoYNSfPrn`;<}^Bd%)!mF!ZELhU7?oT0(!R z1iYWoHx+=vTcCf{om=}Hrw>4mX0>z!92^3%GG(uMyt}V^ZvXbQ=l26DI&z9Vf(r!z z000SaNLh0L01FcU01FcV0GgZ_0000pP)t-s00030_rm|mh4i+0>7#Ani(}YxTFPit zy1nBb7OM^Jx&)gQN4+OXpIBDpxYbU1DHd*=M%%4ki7xvRjqt}!C}@|xwwb{*pA&JM*mmll8Ay^AH5 zc+k^GZ8Ah1_k`K4y!-l~=6k@#x-RfO#c4n0F+W(^MlZ&4zW?{R~ zosUS>JOH@$p%Lp->rs(imE)jF8~{f@XyC&Ry&<2l797}xd2a_kkwsgewSv-nL09?9 z08G|8-9-cJqTDFuw+f(kDJd-s0mO6)BfFkI-rbaiqY-$A8j7a?&Ia`v@jr2W+Jz7> P00000NkvXXu0mjfW{Xsk diff --git a/src/main/resources/assets/create/textures/block/pump.png b/src/main/resources/assets/create/textures/block/pump.png index 0f5a56bef6fbe35737a4574ac250598d627d97e1..d7335ec98b6848b4307c09949e11de14a8718c72 100644 GIT binary patch delta 579 zcmV-J0=)gE1*`>-BNhRLX+uL$Nkc;*P;zf(X>4Tx04UFukxm!^QITgZe=2z4@jlLb z=WySBfY7Ki%?gYInr@rvge2zjD`M~!z3?H77y>f0jAUjZi>~!`Pj{*A;yergtFT(I z7~m6$XPIHz#OuV+?K&wI z(sV9$@ejNH6uA^~RlvwGj}2&$T|f9A{GP24lwj&$foQ{ep*7Ye+ayv(KqFR!CRnz z)tg)E9H$RJmS(kd0~{Ozu@Yskb$NGR=iL6h7#AEUQgI_T1!btL_t8XR7zf3T5@b@m_|dSO-77BKvf_sJr*9yXjC{bEC2ui%sQ}d z0000HbW%=J|NsC05&!@H|NsC0|NsC0{{SVenPQP47k>b8NklAQ=$AnGhZuoedjhybDS&fNf z%&nE8Nf`MFeGsa#3SXAah{U)W^DM>4xc44>>?D%PDHLkV1m`n3)BDr delta 595 zcmV-Z0<8V41*Qd%Ba;vU6)ypWX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmP!xqv(`rRp z9PA+CkfC<6AS&W0RgqFIf8&M6`#A5O!+ZAuLbJwHGcXRQnq_2?2{B(-5rePjg%4rG z5RjOur?Lw$FCY#3E8iLxhYvs;I$2oOX>A6B#;Bc=(4Mf0|q}xvF5~n8yZGNRA);4}QuX((?uX}F) z_O$2s11dUliaml01poj5JWxzjMF0Q*|H_5*wt4BJZQzSz*mGLSXjH^wQoUYJuvAK< zO-7hTLySN`SxrV#NI^_OJV!k^I4~?#AS*o<9x9@@xc~qFe*tt-PE!Ct=GbNc0044H zL_t(|0R_P^V#7cP05HK3r%Q(Z|B>D80F@%etB2RK#wW`Wl1NRcFnPgbe1dxKxdJ;J zrXCp(tMfUV1EBRxCjc;;DFF1CDmJiDzDwPCTg07{sFg;$(h5okjag@90Km`pOaZ`| h3;+P}3jqH76$9lWGD;O$*RlWr002ovPDHLkV1h3_2N3`O