From c8c37bd01cc7bf5f67521a617dbeef9d63c54d40 Mon Sep 17 00:00:00 2001 From: rearth Date: Mon, 1 Apr 2024 20:47:48 +0200 Subject: [PATCH] Begin adding energy storage blocks --- .../19c08d24c255c2719fbb8ac01f9dff290b763461 | 18 +- .../blockstates/small_storage_block.json | 7 + .../models/item/small_storage_block.json | 3 + .../base/block/UpgradableMachineBlock.java | 8 +- .../ExpandableEnergyStorageBlockEntity.java | 189 ++++++++++++++++++ ...ItemEnergyFrameInteractionBlockEntity.java | 2 +- .../block/base/entity/MachineBlockEntity.java | 2 +- .../entity/PassiveGeneratorBlockEntity.java | 2 +- .../machines/storage/SmallStorageBlock.java | 98 +++++++++ .../entity/machines/MachineCoreEntity.java | 2 +- .../EnergyAcceptorAddonBlockEntity.java | 4 +- .../interaction/LaserArmBlockEntity.java | 2 +- .../machines/interaction/PumpBlockEntity.java | 2 +- .../storage/SmallStorageBlockEntity.java | 39 ++++ .../pipes/EnergyPipeInterfaceEntity.java | 2 +- .../client/ui/BasicMachineScreenHandler.java | 2 +- .../rearth/oritech/init/BlockContent.java | 4 + .../oritech/init/BlockEntitiesContent.java | 7 +- .../oritech/init/datagen/ModelGenerator.java | 1 + .../rearth/oritech/util/EnergyProvider.java | 4 +- .../java/rearth/oritech/util/Geometry.java | 3 +- .../blockstates/small_storage_block.json | 27 +++ .../models/block/small_storage_block.json | 130 ++++++++++++ .../textures/block/small_storage_block.png | Bin 0 -> 2053 bytes 24 files changed, 529 insertions(+), 29 deletions(-) create mode 100644 src/main/generated/assets/oritech/blockstates/small_storage_block.json create mode 100644 src/main/generated/assets/oritech/models/item/small_storage_block.json create mode 100644 src/main/java/rearth/oritech/block/base/entity/ExpandableEnergyStorageBlockEntity.java create mode 100644 src/main/java/rearth/oritech/block/blocks/machines/storage/SmallStorageBlock.java create mode 100644 src/main/java/rearth/oritech/block/entity/machines/storage/SmallStorageBlockEntity.java create mode 100644 src/main/resources/assets/oritech/blockstates/small_storage_block.json create mode 100644 src/main/resources/assets/oritech/models/block/small_storage_block.json create mode 100644 src/main/resources/assets/oritech/textures/block/small_storage_block.png diff --git a/src/main/generated/.cache/19c08d24c255c2719fbb8ac01f9dff290b763461 b/src/main/generated/.cache/19c08d24c255c2719fbb8ac01f9dff290b763461 index 394fe52cb..b17045ca0 100644 --- a/src/main/generated/.cache/19c08d24c255c2719fbb8ac01f9dff290b763461 +++ b/src/main/generated/.cache/19c08d24c255c2719fbb8ac01f9dff290b763461 @@ -1,4 +1,4 @@ -// 1.20.4 2024-03-29T22:10:13.6086234 Oritech/Model Definitions +// 1.20.4 2024-04-01T19:45:11.2977587 Oritech/Model Definitions 0ea8315aed10abcf90ec950fee0062aed26075cb assets\oritech\models\item\energy_pipe.json 8ede0997449fd1c3f65a07df184768a843b473ed assets\oritech\models\item\centrifuge_block.json 90e28b721796ff7ee21c8eefe4525f03a251d2fb assets\oritech\models\block\machine_extender.json @@ -6,14 +6,14 @@ e6f197ee5ac22cd68bc502a86d40b65bfe40884a assets\oritech\models\item\target_designator.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\centrifuge_block.json 8ef5ff056a3d2fa26393ec9ccb4b6f3b410f8be8 assets\oritech\models\item\item_pipe.json -7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\fragment_forge_block.json b91305cbccecb97f9d74e2b92787ae9fa6387786 assets\oritech\blockstates\fluid_pipe.json -7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\big_solar_panel_block.json +7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\fragment_forge_block.json 98d62a615b70fca694eb00c6b8aa9297c4a92b62 assets\oritech\blockstates\energy_pipe_connection.json +7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\big_solar_panel_block.json 3ceff0ef4325bb269831205626285bc857c60de8 assets\oritech\models\item\destroyer_block.json 829faf2dfb04c9aea2dd6c971037fbfdaa9aa389 assets\oritech\models\item\pump_block.json -7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\laser_arm_block.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\pulverizer_block.json +7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\laser_arm_block.json e4497bad8afbd4f4b4e830d892284a05718b06dd assets\oritech\models\block\machine_core_basic.json 505d30e3b61ee0ba1f2616e1226689e2cdb7ab58 assets\oritech\models\block\addon_indicator_block.json a5651b8d4a27308b40c404f7cd3abcf9769b64b6 assets\oritech\models\item\machine_core_basic.json @@ -24,13 +24,14 @@ ee822d455f99c8c53c789fdb744979f678ca2729 assets\oritech\blockstates\fertilizer_b 46af77abe62b29d232feadccde429fd59d5603fc assets\oritech\blockstates\placer_block.json 3d37038977380bd685f913e722cc3b1c3a25c35d assets\oritech\models\item\atomic_forge_block.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\test_generator_block.json -eafe84c787830ab2a866e0878e9ed718d58659f5 assets\oritech\blockstates\banana_block.json b5ee97616ae0d2da17dfaecf45aa42f2cf19f691 assets\oritech\blockstates\machine_extender.json +eafe84c787830ab2a866e0878e9ed718d58659f5 assets\oritech\blockstates\banana_block.json 25864df3cd7786f2bf4fe6fa9855b3cf366c28ca assets\oritech\models\item\banana.json 1fdbeb99862a58436d745edb768b503539ecb295 assets\oritech\models\item\placer_block.json 58b38bcc6c404953490330d4cc797464b6874d88 assets\oritech\models\item\test_generator_block.json -9cd64a2fe3b9a0ee479646d36cc0302bcd7cab4f assets\oritech\models\block\destroyer_block.json b8bc03092cb1eb686ede01daffc7421253af860c assets\oritech\models\item\machine_extender.json +9cd64a2fe3b9a0ee479646d36cc0302bcd7cab4f assets\oritech\models\block\destroyer_block.json +45fbece69084d6df6eaa4ba344d25eef914c63c3 assets\oritech\models\item\small_storage_block.json 63f14855c688ce7ec236097ce232dd381cbc1538 assets\oritech\blockstates\addon_indicator_block.json 7ee14de0149c70d1145dbf338518690b536cc02e assets\oritech\models\item\powered_furnace_block.json 746b98d721e5ae0d96dd769e71b786afa8c2d142 assets\oritech\models\item\banana_block.json @@ -45,8 +46,8 @@ c641d411ad252487b93d779cee9028b9ee920281 assets\oritech\blockstates\machine_core a5afa0ba8780ec08bd0a9284bc08e0c681fe7158 assets\oritech\blockstates\block_placer_head.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\assembler_block.json 5054284e6d5fe0785ac93bdda5101c47337953cf assets\oritech\models\item\machine_frame_block.json -56c7ceb5cc86d67913ad95cb4ae5ec192aed926f assets\oritech\models\block\pump_block.json 7b3ae67ec28f9b36b96539cd48b92096861d0853 assets\oritech\models\item\oil_bucket.json +56c7ceb5cc86d67913ad95cb4ae5ec192aed926f assets\oritech\models\block\pump_block.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\powered_furnace_block.json 1b9cd3719105dc1e03398de41f2cab37337816fe assets\oritech\blockstates\machine_core_good.json ccd7e87c2ba5a5062bb88aa6e103d49d47cd56ff assets\oritech\blockstates\energy_pipe.json @@ -56,6 +57,7 @@ a3f9b72f6f36d42af4e5c3a87d7e180b2e36a2ed assets\oritech\models\item\machine_core 97794db126be871e2cb68297abbe8917c343e705 assets\oritech\models\item\fluid_pipe.json 469ea8a66c529fe26bc029c21092e7f062ed0e40 assets\oritech\models\block\banana_block.json d35ecef5df9198b12dc04267780c727c144b1959 assets\oritech\models\item\assembler_block.json +f337c5c80895d0c133e8218a41a0915b307cce18 assets\oritech\blockstates\small_storage_block.json d39d7a8eaa54d12c155fb1acd1722e322c0aeac3 assets\oritech\models\block\block_destroyer_head.json 7eb395cd65df72caf43bedc54067cbf53940fd6c assets\oritech\blockstates\foundry_block.json 30525b49546801c90bc77faa6eab332ba288eca5 assets\oritech\models\item\fertilizer_block.json @@ -66,6 +68,6 @@ f53b229ded70f8ae0bff50e829d62326601b0fe8 assets\oritech\models\block\block_place b7e73ae6ffd983038af7540301bf488242562790 assets\oritech\models\block\fertilizer_block.json 83b81f38fd21e58e98aab409d36368b3a78b675e assets\oritech\blockstates\item_pipe.json 66c23bb916995ef1664b6119475d183a66f32624 assets\oritech\blockstates\block_fertilizer_head.json -42580a93e058faa5381bfac746ed2a200ec5f323 assets\oritech\models\item\laser_arm_block.json 3d6d17333aeaef12a7bd95f18b169ee69a0bab5f assets\oritech\blockstates\fluid_pipe_connection.json +42580a93e058faa5381bfac746ed2a200ec5f323 assets\oritech\models\item\laser_arm_block.json 3166a5959c87c4465c5eed82034d3178c4b8b518 assets\oritech\models\block\machine_core_good.json diff --git a/src/main/generated/assets/oritech/blockstates/small_storage_block.json b/src/main/generated/assets/oritech/blockstates/small_storage_block.json new file mode 100644 index 000000000..0e3d5b81f --- /dev/null +++ b/src/main/generated/assets/oritech/blockstates/small_storage_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "oritech:block/small_storage_block" + } + } +} \ No newline at end of file diff --git a/src/main/generated/assets/oritech/models/item/small_storage_block.json b/src/main/generated/assets/oritech/models/item/small_storage_block.json new file mode 100644 index 000000000..db760923e --- /dev/null +++ b/src/main/generated/assets/oritech/models/item/small_storage_block.json @@ -0,0 +1,3 @@ +{ + "parent": "oritech:block/small_storage_block" +} \ No newline at end of file diff --git a/src/main/java/rearth/oritech/block/base/block/UpgradableMachineBlock.java b/src/main/java/rearth/oritech/block/base/block/UpgradableMachineBlock.java index f8cf2fd03..9a438e614 100644 --- a/src/main/java/rearth/oritech/block/base/block/UpgradableMachineBlock.java +++ b/src/main/java/rearth/oritech/block/base/block/UpgradableMachineBlock.java @@ -1,18 +1,12 @@ package rearth.oritech.block.base.block; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.BooleanProperty; -import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import rearth.oritech.block.base.entity.MultiblockMachineEntity; -import rearth.oritech.block.base.entity.UpgradableMachineBlockEntity; import rearth.oritech.util.MachineAddonController; public abstract class UpgradableMachineBlock extends MachineBlock { @@ -27,7 +21,7 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt if (!world.isClient) { var entity = world.getBlockEntity(pos); - if (!(entity instanceof UpgradableMachineBlockEntity machineEntity)) { + if (!(entity instanceof MachineAddonController machineEntity)) { return ActionResult.SUCCESS; } diff --git a/src/main/java/rearth/oritech/block/base/entity/ExpandableEnergyStorageBlockEntity.java b/src/main/java/rearth/oritech/block/base/entity/ExpandableEnergyStorageBlockEntity.java new file mode 100644 index 000000000..4488e7254 --- /dev/null +++ b/src/main/java/rearth/oritech/block/base/entity/ExpandableEnergyStorageBlockEntity.java @@ -0,0 +1,189 @@ +package rearth.oritech.block.base.entity; + +import net.fabricmc.fabric.api.lookup.v1.block.BlockApiCache; +import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.inventory.SimpleInventory; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; +import rearth.oritech.block.blocks.machines.storage.SmallStorageBlock; +import rearth.oritech.client.init.ParticleContent; +import rearth.oritech.util.*; +import team.reborn.energy.api.EnergyStorage; +import team.reborn.energy.api.base.DelegatingEnergyStorage; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; + +public abstract class ExpandableEnergyStorageBlockEntity extends BlockEntity implements EnergyProvider, MachineAddonController, BlockEntityTicker { + + private final List connectedAddons = new ArrayList<>(); + private final List openSlots = new ArrayList<>(); + private BaseAddonData addonData = MachineAddonController.DEFAULT_ADDON_DATA; + private HashMap> directionCaches; + + + //own storage + protected final DynamicEnergyStorage energyStorage = new DynamicEnergyStorage(getDefaultCapacity(), getDefaultInsertRate(), getDefaultExtractionRate()) { + @Override + public void onFinalCommit() { + super.onFinalCommit(); + ExpandableEnergyStorageBlockEntity.this.markDirty(); + } + }; + + private final EnergyStorage outputStorage = new DelegatingEnergyStorage(energyStorage, null) { + @Override + public boolean supportsInsertion() { + return false; + } + }; + + private final EnergyStorage inputStorage = new DelegatingEnergyStorage(energyStorage, null) { + @Override + public boolean supportsExtraction() { + return false; + } + }; + + public ExpandableEnergyStorageBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + } + + @Override + public void tick(World world, BlockPos pos, BlockState state, ExpandableEnergyStorageBlockEntity blockEntity) { + if (world.isClient) return; + + outputEnergy(); + } + + private void outputEnergy() { + if (energyStorage.amount <= 0) return; + var availableOutput = Math.min(energyStorage.amount, energyStorage.maxExtract); + var totalInserted = 0L; + + if (directionCaches == null) directionCaches = getNeighborCaches(pos, world); + + try (var tx = Transaction.openOuter()) { + for (var entry : directionCaches.entrySet()) { + var insertDirection = entry.getKey().getOpposite(); + var targetCandidate = entry.getValue().find(insertDirection); + if (targetCandidate == null) continue; + var inserted = targetCandidate.insert(availableOutput, tx); + availableOutput -= inserted; + totalInserted += inserted; + if (availableOutput <= 0) break; + } + energyStorage.extract(totalInserted, tx); + tx.commit(); + } + + this.markDirty(); + } + + // defaults only to front block + protected HashMap> getNeighborCaches(BlockPos pos, World world) { + + var res = new HashMap>(6); + var facing = getFacing(); + var blockInFront = (BlockPos) Geometry.offsetToWorldPosition(facing, new Vec3i(-1, 0, 0), pos); + + System.out.println(blockInFront.toCenterPos()); + ParticleContent.HIGHLIGHT_BLOCK.spawn(world, Vec3d.of(blockInFront)); + + var frontCache = BlockApiCache.create(EnergyStorage.SIDED, (ServerWorld) world, blockInFront); + res.put(Direction.DOWN, frontCache); + + return res; + } + + @Override + public void writeNbt(NbtCompound nbt) { + super.writeNbt(nbt); + writeAddonToNbt(nbt); + nbt.putLong("energy_stored", energyStorage.amount); + } + + @Override + public void readNbt(NbtCompound nbt) { + super.readNbt(nbt); + loadAddonNbtData(nbt); + updateEnergyContainer(); + energyStorage.amount = nbt.getLong("energy_stored"); + } + + public Direction getFacing() { + return getCachedState().get(SmallStorageBlock.TARGET_DIR); + } + + + @Override + public EnergyStorage getStorage(Direction direction) { + + if (direction == null) + return energyStorage; + + if (direction.equals(getFacing())) { + return outputStorage; + } else { + return inputStorage; + } + } + + @Override + public List getConnectedAddons() { + return connectedAddons; + } + + @Override + public List getOpenSlots() { + return openSlots; + } + + @Override + public Direction getFacingForAddon() { + var facing = Objects.requireNonNull(world).getBlockState(getPos()).get(SmallStorageBlock.TARGET_DIR); + + if (facing.equals(Direction.UP) || facing.equals(Direction.DOWN)) + return Direction.NORTH; + + return facing; + } + + @Override + public DynamicEnergyStorage getStorageForAddon() { + return energyStorage; + } + + @Override + public SimpleInventory getInventoryForAddon() { + return null; + } + + @Override + public ScreenProvider getScreenProvider() { + return null; + } + + @Override + public BaseAddonData getBaseAddonData() { + return addonData; + } + + @Override + public void setBaseAddonData(BaseAddonData data) { + this.addonData = data; + } + + public abstract long getDefaultExtractionRate(); +} diff --git a/src/main/java/rearth/oritech/block/base/entity/ItemEnergyFrameInteractionBlockEntity.java b/src/main/java/rearth/oritech/block/base/entity/ItemEnergyFrameInteractionBlockEntity.java index 21ce8b7c6..dcc0aea6e 100644 --- a/src/main/java/rearth/oritech/block/base/entity/ItemEnergyFrameInteractionBlockEntity.java +++ b/src/main/java/rearth/oritech/block/base/entity/ItemEnergyFrameInteractionBlockEntity.java @@ -99,7 +99,7 @@ public InventoryStorage getInventory(Direction direction) { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/block/base/entity/MachineBlockEntity.java b/src/main/java/rearth/oritech/block/base/entity/MachineBlockEntity.java index d6cebc11f..70e28d160 100644 --- a/src/main/java/rearth/oritech/block/base/entity/MachineBlockEntity.java +++ b/src/main/java/rearth/oritech/block/base/entity/MachineBlockEntity.java @@ -464,7 +464,7 @@ public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, Pla } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/block/base/entity/PassiveGeneratorBlockEntity.java b/src/main/java/rearth/oritech/block/base/entity/PassiveGeneratorBlockEntity.java index ec027baf9..6831b14ad 100644 --- a/src/main/java/rearth/oritech/block/base/entity/PassiveGeneratorBlockEntity.java +++ b/src/main/java/rearth/oritech/block/base/entity/PassiveGeneratorBlockEntity.java @@ -79,7 +79,7 @@ protected void writeNbt(NbtCompound nbt) { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/block/blocks/machines/storage/SmallStorageBlock.java b/src/main/java/rearth/oritech/block/blocks/machines/storage/SmallStorageBlock.java new file mode 100644 index 000000000..90d977b71 --- /dev/null +++ b/src/main/java/rearth/oritech/block/blocks/machines/storage/SmallStorageBlock.java @@ -0,0 +1,98 @@ +package rearth.oritech.block.blocks.machines.storage; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityTicker; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.DirectionProperty; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import rearth.oritech.block.entity.machines.storage.SmallStorageBlockEntity; +import rearth.oritech.util.MachineAddonController; + +import java.util.Objects; + +public class SmallStorageBlock extends Block implements BlockEntityProvider { + + public static final DirectionProperty TARGET_DIR = DirectionProperty.of("target_dir"); + + public SmallStorageBlock(Settings settings) { + super(settings); + this.setDefaultState(getDefaultState().with(TARGET_DIR, Direction.NORTH)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(TARGET_DIR); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return Objects.requireNonNull(super.getPlacementState(ctx)).with(TARGET_DIR, ctx.getPlayerLookDirection().getOpposite()); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new SmallStorageBlockEntity(pos, state); + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + + if (!world.isClient) { + + var entity = world.getBlockEntity(pos); + if (!(entity instanceof MachineAddonController machineEntity)) { + return ActionResult.SUCCESS; + } + + machineEntity.initAddons(); + + } + + return super.onUse(state, world, pos, player, hand, hit); + } + + @Override + public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + + if (!world.isClient()) { + + var entity = world.getBlockEntity(pos); + if (entity instanceof MachineAddonController machineEntity) { + machineEntity.resetAddons(); + } + } + + return super.onBreak(world, pos, state, player); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Nullable + @Override + public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { + return (world1, pos, state1, blockEntity) -> { + if (blockEntity instanceof BlockEntityTicker ticker) + ticker.tick(world1, pos, state1, blockEntity); + }; + } + +} diff --git a/src/main/java/rearth/oritech/block/entity/machines/MachineCoreEntity.java b/src/main/java/rearth/oritech/block/entity/machines/MachineCoreEntity.java index 28852f3dc..ab23f4042 100644 --- a/src/main/java/rearth/oritech/block/entity/machines/MachineCoreEntity.java +++ b/src/main/java/rearth/oritech/block/entity/machines/MachineCoreEntity.java @@ -74,7 +74,7 @@ public boolean isEnabled() { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return delegatedStorage; } diff --git a/src/main/java/rearth/oritech/block/entity/machines/addons/EnergyAcceptorAddonBlockEntity.java b/src/main/java/rearth/oritech/block/entity/machines/addons/EnergyAcceptorAddonBlockEntity.java index 5d963a851..44981df38 100644 --- a/src/main/java/rearth/oritech/block/entity/machines/addons/EnergyAcceptorAddonBlockEntity.java +++ b/src/main/java/rearth/oritech/block/entity/machines/addons/EnergyAcceptorAddonBlockEntity.java @@ -2,7 +2,7 @@ import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; -import rearth.oritech.block.base.entity.UpgradableMachineBlockEntity; +import net.minecraft.util.math.Direction; import rearth.oritech.block.blocks.machines.addons.MachineAddonBlock; import rearth.oritech.init.BlockEntitiesContent; import rearth.oritech.util.EnergyProvider; @@ -45,7 +45,7 @@ private MachineAddonController getCachedController() { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return delegatedStorage; } } diff --git a/src/main/java/rearth/oritech/block/entity/machines/interaction/LaserArmBlockEntity.java b/src/main/java/rearth/oritech/block/entity/machines/interaction/LaserArmBlockEntity.java index 8bb5857fd..331f22e1a 100644 --- a/src/main/java/rearth/oritech/block/entity/machines/interaction/LaserArmBlockEntity.java +++ b/src/main/java/rearth/oritech/block/entity/machines/interaction/LaserArmBlockEntity.java @@ -322,7 +322,7 @@ public List getCorePositions() { // energyprovider @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/block/entity/machines/interaction/PumpBlockEntity.java b/src/main/java/rearth/oritech/block/entity/machines/interaction/PumpBlockEntity.java index 7e5f5c2ed..2a4e453d7 100644 --- a/src/main/java/rearth/oritech/block/entity/machines/interaction/PumpBlockEntity.java +++ b/src/main/java/rearth/oritech/block/entity/machines/interaction/PumpBlockEntity.java @@ -214,7 +214,7 @@ public Storage getFluidStorage(Direction direction) { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/block/entity/machines/storage/SmallStorageBlockEntity.java b/src/main/java/rearth/oritech/block/entity/machines/storage/SmallStorageBlockEntity.java new file mode 100644 index 000000000..b055d16d8 --- /dev/null +++ b/src/main/java/rearth/oritech/block/entity/machines/storage/SmallStorageBlockEntity.java @@ -0,0 +1,39 @@ +package rearth.oritech.block.entity.machines.storage; + +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import rearth.oritech.block.base.entity.ExpandableEnergyStorageBlockEntity; +import rearth.oritech.init.BlockEntitiesContent; + +import java.util.List; + +public class SmallStorageBlockEntity extends ExpandableEnergyStorageBlockEntity { + + public SmallStorageBlockEntity(BlockPos pos, BlockState state) { + super(BlockEntitiesContent.SMALL_STORAGE_ENTITY, pos, state); + } + + @Override + public List getAddonSlots() { + return List.of( + new Vec3i(0, 0,-1), + new Vec3i(0, 0,1) + ); + } + + @Override + public long getDefaultCapacity() { + return 64000; + } + + @Override + public long getDefaultInsertRate() { + return 1000; + } + + @Override + public long getDefaultExtractionRate() { + return 1000; + } +} diff --git a/src/main/java/rearth/oritech/block/entity/pipes/EnergyPipeInterfaceEntity.java b/src/main/java/rearth/oritech/block/entity/pipes/EnergyPipeInterfaceEntity.java index 75865fece..b9311ca12 100644 --- a/src/main/java/rearth/oritech/block/entity/pipes/EnergyPipeInterfaceEntity.java +++ b/src/main/java/rearth/oritech/block/entity/pipes/EnergyPipeInterfaceEntity.java @@ -41,7 +41,7 @@ public void readNbt(NbtCompound nbt) { } @Override - public EnergyStorage getStorage() { + public EnergyStorage getStorage(Direction direction) { return energyStorage; } diff --git a/src/main/java/rearth/oritech/client/ui/BasicMachineScreenHandler.java b/src/main/java/rearth/oritech/client/ui/BasicMachineScreenHandler.java index 154372558..f4c38d88e 100644 --- a/src/main/java/rearth/oritech/client/ui/BasicMachineScreenHandler.java +++ b/src/main/java/rearth/oritech/client/ui/BasicMachineScreenHandler.java @@ -56,7 +56,7 @@ public BasicMachineScreenHandler(int syncId, PlayerInventory playerInventory, Bl this.playerInventory = playerInventory; if (blockEntity instanceof EnergyProvider energyProvider) { - energyStorage = energyProvider.getStorage(); + energyStorage = energyProvider.getStorage(null); } else { Oritech.LOGGER.error("Opened oritech block interface without any energy data at " + blockEntity); energyStorage = null; diff --git a/src/main/java/rearth/oritech/init/BlockContent.java b/src/main/java/rearth/oritech/init/BlockContent.java index b26346dcc..a70e013d6 100644 --- a/src/main/java/rearth/oritech/init/BlockContent.java +++ b/src/main/java/rearth/oritech/init/BlockContent.java @@ -20,6 +20,7 @@ import rearth.oritech.block.blocks.machines.generators.TestGeneratorBlock; import rearth.oritech.block.blocks.machines.interaction.*; import rearth.oritech.block.blocks.machines.processing.*; +import rearth.oritech.block.blocks.machines.storage.SmallStorageBlock; import rearth.oritech.block.blocks.pipes.*; import rearth.oritech.util.item.OritechGeoItem; @@ -43,6 +44,7 @@ public class BlockContent implements BlockRegistryContainer { @ItemGroups.ItemGroupTarget(ItemGroups.GROUPS.second) public static final Block ITEM_PIPE = new ItemPipeBlock(FabricBlockSettings.copyOf(Blocks.IRON_BARS)); @ItemGroups.ItemGroupTarget(ItemGroups.GROUPS.second) + public static final Block ITEM_FILTER_BLOCK = new ItemFilterBlock(FabricBlockSettings.copyOf(Blocks.IRON_BARS)); @NoBlockItem public static final Block FLUID_PIPE_CONNECTION = new FluidPipeConnectionBlock(FabricBlockSettings.copyOf(Blocks.IRON_BARS)); @@ -86,6 +88,8 @@ public class BlockContent implements BlockRegistryContainer { @UseGeoBlockItem(scale = 0.5f) public static final Block LASER_ARM_BLOCK = new LaserArmBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()); + public static final Block SMALL_STORAGE_BLOCK = new SmallStorageBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()); + public static final Block PLACER_BLOCK = new PlacerBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()); public static final Block DESTROYER_BLOCK = new DestroyerBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()); public static final Block FERTILIZER_BLOCK = new FertilizerBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()); diff --git a/src/main/java/rearth/oritech/init/BlockEntitiesContent.java b/src/main/java/rearth/oritech/init/BlockEntitiesContent.java index d1688a64b..34c49e4ff 100644 --- a/src/main/java/rearth/oritech/init/BlockEntitiesContent.java +++ b/src/main/java/rearth/oritech/init/BlockEntitiesContent.java @@ -16,6 +16,7 @@ import rearth.oritech.block.entity.machines.generators.TestGeneratorEntity; import rearth.oritech.block.entity.machines.interaction.*; import rearth.oritech.block.entity.machines.processing.*; +import rearth.oritech.block.entity.machines.storage.SmallStorageBlockEntity; import rearth.oritech.block.entity.pipes.EnergyPipeInterfaceEntity; import rearth.oritech.block.entity.pipes.FluidPipeInterfaceEntity; import rearth.oritech.block.entity.pipes.ItemFilterBlockEntity; @@ -98,6 +99,10 @@ public class BlockEntitiesContent implements AutoRegistryContainer INVENTORY_PROXY_ADDON_ENTITY = FabricBlockEntityTypeBuilder.create(InventoryProxyAddonBlockEntity::new, BlockContent.MACHINE_INVENTORY_PROXY_ADDON).build(); + + @AssignSidedEnergy + public static final BlockEntityType SMALL_STORAGE_ENTITY = FabricBlockEntityTypeBuilder.create(SmallStorageBlockEntity::new, BlockContent.SMALL_STORAGE_BLOCK).build(); + @AssignSidedFluid public static final BlockEntityType FLUID_PIPE_ENTITY = FabricBlockEntityTypeBuilder.create(FluidPipeInterfaceEntity::new, BlockContent.FLUID_PIPE_CONNECTION).build(); @AssignSidedEnergy @@ -140,7 +145,7 @@ public void postProcessField(String namespace, BlockEntityType value, String AutoRegistryContainer.super.postProcessField(namespace, value, identifier, field); if (field.isAnnotationPresent(AssignSidedEnergy.class)) - EnergyStorage.SIDED.registerForBlockEntity((blockEntity, direction) -> ((EnergyProvider) blockEntity).getStorage(), value); + EnergyStorage.SIDED.registerForBlockEntity((blockEntity, direction) -> ((EnergyProvider) blockEntity).getStorage(direction), value); if (field.isAnnotationPresent(AssignSidedFluid.class)) FluidStorage.SIDED.registerForBlockEntity((blockEntity, direction) -> ((FluidProvider) blockEntity).getFluidStorage(direction), value); diff --git a/src/main/java/rearth/oritech/init/datagen/ModelGenerator.java b/src/main/java/rearth/oritech/init/datagen/ModelGenerator.java index e1a3e2d97..0a51a0df6 100644 --- a/src/main/java/rearth/oritech/init/datagen/ModelGenerator.java +++ b/src/main/java/rearth/oritech/init/datagen/ModelGenerator.java @@ -26,6 +26,7 @@ public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGen blockStateModelGenerator.registerSimpleState(BlockContent.ENERGY_PIPE_CONNECTION); blockStateModelGenerator.registerSimpleState(BlockContent.ITEM_PIPE_CONNECTION); blockStateModelGenerator.registerSimpleState(BlockContent.ITEM_FILTER_BLOCK); + blockStateModelGenerator.registerSimpleState(BlockContent.SMALL_STORAGE_BLOCK); blockStateModelGenerator.registerSimpleCubeAll(BlockContent.PLACER_BLOCK); blockStateModelGenerator.registerSimpleCubeAll(BlockContent.DESTROYER_BLOCK); diff --git a/src/main/java/rearth/oritech/util/EnergyProvider.java b/src/main/java/rearth/oritech/util/EnergyProvider.java index 583f9234c..3be3e75c6 100644 --- a/src/main/java/rearth/oritech/util/EnergyProvider.java +++ b/src/main/java/rearth/oritech/util/EnergyProvider.java @@ -1,10 +1,10 @@ package rearth.oritech.util; +import net.minecraft.util.math.Direction; import team.reborn.energy.api.EnergyStorage; -import team.reborn.energy.api.EnergyStorageUtil; public interface EnergyProvider { - EnergyStorage getStorage(); + EnergyStorage getStorage(Direction direction); } diff --git a/src/main/java/rearth/oritech/util/Geometry.java b/src/main/java/rearth/oritech/util/Geometry.java index 9523b57ea..97e696305 100644 --- a/src/main/java/rearth/oritech/util/Geometry.java +++ b/src/main/java/rearth/oritech/util/Geometry.java @@ -3,7 +3,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3i; -import rearth.oritech.block.base.entity.MultiblockMachineEntity; public class Geometry { @@ -19,6 +18,8 @@ public static Vec3i rotatePosition(Vec3i relativePos, Direction facing) { case WEST -> new BlockPos(relativePos.getX(), relativePos.getY(), -relativePos.getZ()); case SOUTH -> new BlockPos(-relativePos.getZ(), relativePos.getY(), -relativePos.getX()); case EAST -> new BlockPos(-relativePos.getX(), relativePos.getY(), relativePos.getZ()); + case UP -> new BlockPos(relativePos.getZ(), -relativePos.getX(), -relativePos.getY()); + case DOWN -> new BlockPos(relativePos.getZ(), relativePos.getX(), relativePos.getY()); default -> relativePos; }; } diff --git a/src/main/resources/assets/oritech/blockstates/small_storage_block.json b/src/main/resources/assets/oritech/blockstates/small_storage_block.json new file mode 100644 index 000000000..6b758d436 --- /dev/null +++ b/src/main/resources/assets/oritech/blockstates/small_storage_block.json @@ -0,0 +1,27 @@ +{ + "variants": { + "target_dir=south": { + "model": "oritech:block/small_storage_block", + "y": 180 + }, + "target_dir=east": { + "model": "oritech:block/small_storage_block", + "y": 90 + }, + "target_dir=north": { + "model": "oritech:block/small_storage_block" + }, + "target_dir=west": { + "model": "oritech:block/small_storage_block", + "y": 270 + }, + "target_dir=up": { + "model": "oritech:block/small_storage_block", + "x": -90 + }, + "target_dir=down": { + "model": "oritech:block/small_storage_block", + "x": 90 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/oritech/models/block/small_storage_block.json b/src/main/resources/assets/oritech/models/block/small_storage_block.json new file mode 100644 index 000000000..07302124c --- /dev/null +++ b/src/main/resources/assets/oritech/models/block/small_storage_block.json @@ -0,0 +1,130 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [64, 64], + "textures": { + "1": "oritech:block/small_storage_block", + "particle": "oritech:block/machine_particle_texture" + }, + "elements": [ + { + "name": "side", + "from": [0, 0, 0], + "to": [2, 16, 16], + "faces": { + "north": {"uv": [9, 12, 9.5, 16], "texture": "#1"}, + "east": {"uv": [0, 0, 4, 4], "texture": "#1"}, + "south": {"uv": [9.5, 12, 10, 16], "texture": "#1"}, + "west": {"uv": [0, 4, 4, 8], "texture": "#1"}, + "up": {"uv": [10.5, 16, 10, 12], "texture": "#1"}, + "down": {"uv": [11, 12, 10.5, 16], "texture": "#1"} + } + }, + { + "name": "side", + "from": [14, 0, 0], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [21, 8, 8]}, + "faces": { + "north": {"uv": [11, 12, 11.5, 16], "texture": "#1"}, + "east": {"uv": [4, 0, 8, 4], "texture": "#1"}, + "south": {"uv": [11.5, 12, 12, 16], "texture": "#1"}, + "west": {"uv": [4, 4, 8, 8], "texture": "#1"}, + "up": {"uv": [12.5, 16, 12, 12], "texture": "#1"}, + "down": {"uv": [13, 0, 12.5, 4], "texture": "#1"} + } + }, + { + "name": "inner", + "from": [2, 2, 2], + "to": [14, 14, 14], + "faces": { + "north": {"uv": [0, 8, 3, 11], "texture": "#1"}, + "east": {"uv": [8, 0, 11, 3], "texture": "#1"}, + "south": {"uv": [3, 8, 6, 11], "texture": "#1"}, + "west": {"uv": [8, 3, 11, 6], "texture": "#1"}, + "up": {"uv": [9, 11, 6, 8], "texture": "#1"}, + "down": {"uv": [12, 6, 9, 9], "texture": "#1"} + } + }, + { + "name": "edge", + "from": [2, 1, 1], + "to": [14, 3, 3], + "faces": { + "north": {"uv": [12, 8.5, 15, 9], "texture": "#1"}, + "east": {"uv": [8, 6, 8.5, 6.5], "texture": "#1"}, + "south": {"uv": [12.5, 4, 15.5, 4.5], "texture": "#1"}, + "west": {"uv": [8, 6.5, 8.5, 7], "texture": "#1"}, + "up": {"uv": [15.5, 5, 12.5, 4.5], "texture": "#1"}, + "down": {"uv": [15.5, 5, 12.5, 5.5], "texture": "#1"} + } + }, + { + "name": "edge", + "from": [2, 13, 1], + "to": [14, 15, 3], + "faces": { + "north": {"uv": [12.5, 12, 15.5, 12.5], "texture": "#1"}, + "east": {"uv": [8, 7, 8.5, 7.5], "texture": "#1"}, + "south": {"uv": [12.5, 12.5, 15.5, 13], "texture": "#1"}, + "west": {"uv": [8, 7.5, 8.5, 8], "texture": "#1"}, + "up": {"uv": [16, 0.5, 13, 0], "texture": "#1"}, + "down": {"uv": [16, 0.5, 13, 1], "texture": "#1"} + } + }, + { + "name": "edge", + "from": [2, 13, 13], + "to": [14, 15, 15], + "faces": { + "north": {"uv": [13, 1, 16, 1.5], "texture": "#1"}, + "east": {"uv": [8.5, 6, 9, 6.5], "texture": "#1"}, + "south": {"uv": [13, 1.5, 16, 2], "texture": "#1"}, + "west": {"uv": [8.5, 6.5, 9, 7], "texture": "#1"}, + "up": {"uv": [16, 2.5, 13, 2], "texture": "#1"}, + "down": {"uv": [16, 2.5, 13, 3], "texture": "#1"} + } + }, + { + "name": "edge", + "from": [2, 1, 13], + "to": [14, 3, 15], + "faces": { + "north": {"uv": [13, 3, 16, 3.5], "texture": "#1"}, + "east": {"uv": [8.5, 7, 9, 7.5], "texture": "#1"}, + "south": {"uv": [13, 3.5, 16, 4], "texture": "#1"}, + "west": {"uv": [8.5, 7.5, 9, 8], "texture": "#1"}, + "up": {"uv": [16, 9.5, 13, 9], "texture": "#1"}, + "down": {"uv": [16, 9.5, 13, 10], "texture": "#1"} + } + }, + { + "name": "cable", + "from": [5, 5, 0], + "to": [11, 11, 16], + "faces": { + "north": {"uv": [11, 4, 12.5, 5.5], "texture": "#1"}, + "east": {"uv": [9, 9, 13, 10.5], "texture": "#1"}, + "south": {"uv": [7.5, 11, 9, 12.5], "texture": "#1"}, + "west": {"uv": [9, 10.5, 13, 12], "texture": "#1"}, + "up": {"uv": [1.5, 15, 0, 11], "texture": "#1"}, + "down": {"uv": [12.5, 0, 11, 4], "texture": "#1"} + } + }, + { + "name": "cable", + "from": [5, 0, 5], + "to": [11, 16, 11], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [1.5, 11, 3, 15], "texture": "#1"}, + "east": {"uv": [3, 11, 4.5, 15], "texture": "#1"}, + "south": {"uv": [4.5, 11, 6, 15], "texture": "#1"}, + "west": {"uv": [6, 11, 7.5, 15], "texture": "#1"}, + "up": {"uv": [13.5, 7, 12, 5.5], "texture": "#1"}, + "down": {"uv": [13.5, 7, 12, 8.5], "texture": "#1"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/oritech/textures/block/small_storage_block.png b/src/main/resources/assets/oritech/textures/block/small_storage_block.png new file mode 100644 index 0000000000000000000000000000000000000000..d867678ab025c8d18aa9df50d3d0389152c2345f GIT binary patch literal 2053 zcmV+g2>SPlP)kpk>okG{j$s zF%5*oq>Vp@sQO10)>WX5Q3qZ6aNZon&!SCvLJi^}HmF${+T-+@0_2 z_wMYvh<*Oaz4yNF`R?6&-(UAq*At4|!iN6H001M=3w9zU`fkc-% zt39~DT%J$QON}M)h>Pw6?EqvZKh+wKaV~$+(xlZjcW(e-^89tfKvw;&u}C%-U9uR0fvENljo#6 zWhOsmc;h$dkE|&+{n8f?|GoYm08Wie;0=egNhr5X+@Pum*Xav(Z(mkMEc>}fhM0R~ z?M>^;=B-g{inf3%{gDBK*7t@(Z0zuJZ7yk$+uGr0H5`K1jD4M{LYwR;otnEhaCrKx=E;dV z(LWa(#~TiDYGgud&*|QNbN2=orn6f4Vro|Drc2@44-j_V))6X$u=BQ#kcn4LE=i3m z_VHZfIJ#<3EV_09E5SC8BN zvONFE-&y?Ef}w6xODlWvIvURd81}LrS=(yvuM!Tcl8DCv2n2&#IX%Asd>(MQ1q9{? zP<1kdoKxq-31aEXZh_dFuh)THK0q;^cbiX8<)@p!j&LE<%PpK(A5(twf|B_FD^&6U zD)|Ii0>L0$hd;ghPd?6OIk@v40>L0{Nj2ps476=Nz)3vsHlH9%>RN)2vsrS>%UYf5 z6(DdM&%4bhlp_(3Q(qtE;Ldvh$Yd5t#1r%l{77k>iSa0)n*gWryxV+&6Hcs;>8wB^ z|5woi6c|>3KAs2QomUOzjSoLoGM<;sClonZ3iOZW>HrvhAAqmE;JF2`Cz7``$!HFM ze>`-vPG&rh+jzbb$ar|ANd0;rDZtlp7XbA~UY71_8xG&Dc>bG58V%(~hn_1b|JQ>( zhVK|JMXrKnam=CyTf^bxvSI{^neW71UQZ7UFQ>af7@1W zVLEFWJegm>uBSdIEc-PjC`*wJP>tu!sOA&QI$-dDDYkSq6(vpdh_=zwQ*d1BwrsJ@ z2bd`p&s+6(l1~uKPGvRMx|EC{Zv}1wdBc(SFdNm~V-TLWyKb>>UdneA$==|0e|SpmD%Cfd3W zv~%1)#_Gv$X>IAbt8_l`w!A0k)b3VGUcdKSw>K5(3@aT~f8=G&3aFSsfV#2Y^xZ0D zcf}8i83#(*X}9wFkQ&NQ*e^fnmVH(LCdQ+Nm0_>~vUazc^5yowxxFpzED<8`jGk7s zyM>#mmi(FH3-}{mK5YKE)C08^{=WF=NfPlmLycc5DIdP?YX+U?0d>1uZTY2{2KMig zJ2xa){3xF)uSiz7miQxHmS&vw4FrSqea^udAyvCuZFx5+e;eFeh`vf?gGHN2W>!=F zOmqyNzd`9C1c`W@*y#IG_FrJw095 zmAC3+mfcf-gFrBd_ulW?j$y^oLr;^8=A=D9fk$?Ks-PlYB%8d!;ztYkB)=F7mS!3N zH7^jr^W1l)0c;Zrs`chGysG28@Jg>{(o|820tKGD*=f*BkI&ygHa zL^SWHx0FvtbFSj}O5r)Q{2u%FZ8ub2ypmrPR`t*L{#@jwTujZhWB^7+KLW9 zWY14=^w86+cHG5@3x6}j@rh^R_}W@=f@(Sp?f^$s|Zv~R&<;>J< z0>s;TaL@gu=dNmXLyccyerz7bUednx&!^`NN8t4JqC9`97l57+Quz%L71neGh&a9r zXUkWQ>e(R6&*Qg~HG6H;+Tr`;-e9Guxelll6+0jBzlu52Bg?w-BDa^FJ-wFKW*NIS zRqnV6xZT{5TR{I^VrNe;+JW*Od%4(~uRHp!&sIRKZ@>!uLCY%>mx>%A^A{&4|1c@= z?0fP7GN$NjUrQ@Ld2)(BzHQ9RG;UjAM+V}TjP*OVt&lmq%CyA~94!PxhH?5<;Af8S zxuSUN&fX@YD?rW|u4=xvU43ylyqGF2Z|2IxCCh6&8Mk=Mr>-;}5*K#ywO##9MfuwD jf3E~Tn}Ay1K&|;N&?GuJGo4bZ00000NkvXXu0mjf?93C? literal 0 HcmV?d00001