From c057b9f54afbc74676d5acf4200d3477a9f1d311 Mon Sep 17 00:00:00 2001 From: screret <68943070+screret@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:07:14 +0300 Subject: [PATCH] ITEM PIPES (#437) * feat: ITEM PIPES because someone took too long and people wanted these * fix a sync issue in fluid ingredients * one last bug to fix: the items sometimes cycle back to the input * finish item pipe, start on long distance pipeline * feat: IT WORKS LESSGOOOOOOOO except some textures are wonky, but IT WORKS LESSSGOOOOOOO * chore: changelog, fix endpoint textures * fix: LD pipes not saving data * chore: fill out changelog * Update common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeType.java Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> * Update common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> * Update common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> * Update common/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> * Update common/src/main/java/com/gregtechceu/gtceu/common/machine/storage/LongDistanceEndpointMachine.java Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> * requested changes * more getters * add this back --------- Co-authored-by: Mikerooni <139889766+mikerooni@users.noreply.github.com> --- CHANGELOG.md | 14 +- .../gtceu/api/block/MaterialPipeBlock.java | 2 +- .../gtceu/api/block/PipeBlock.java | 5 + .../api/blockentity/PipeBlockEntity.java | 1 + .../gtceu/api/data/tag/TagPrefix.java | 22 +- .../api/pipenet/longdistance/ILDEndpoint.java | 84 +++ .../longdistance/LongDistanceNetwork.java | 443 ++++++++++++++++ .../longdistance/LongDistancePipeBlock.java | 77 +++ .../longdistance/LongDistancePipeType.java | 96 ++++ .../pipenet/longdistance/NetworkBuilder.java | 111 ++++ .../recipe/ingredient/FluidIngredient.java | 2 + .../gtceu/client/model/PipeModel.java | 38 +- .../gtceu/common/block/CableBlock.java | 2 +- .../gtceu/common/block/FluidPipeBlock.java | 5 - .../gtceu/common/block/ItemPipeBlock.java | 39 ++ .../blockentity/ItemPipeBlockEntity.java | 116 +++++ .../gtceu/common/cover/ConveyorCover.java | 37 +- .../gtceu/common/cover/ItemFilterCover.java | 23 + .../common/cover/data/DistributionMode.java | 30 ++ .../common/cover/data/ItemFilterMode.java | 32 ++ .../cover/data/ManualImportExportMode.java | 30 ++ .../gtceu/common/data/GTBlockEntities.java | 8 + .../gtceu/common/data/GTBlocks.java | 76 ++- .../gtceu/common/data/GTMachines.java | 34 ++ .../gtceu/common/data/GTMaterials.java | 10 +- .../gtceu/common/data/GTModels.java | 10 + .../materials/OrganicChemistryMaterials.java | 2 +- .../storage/LongDistanceEndpointMachine.java | 156 ++++++ .../fluidpipe/FluidPipeNetWalker.java | 3 +- .../longdistance/LDFluidEndpointMachine.java | 81 +++ .../longdistance/LDFluidPipeType.java | 31 ++ .../common/pipelike/item/ItemNetHandler.java | 487 ++++++++++++++++++ .../common/pipelike/item/ItemNetWalker.java | 123 +++++ .../common/pipelike/item/ItemPipeData.java | 52 ++ .../common/pipelike/item/ItemPipeNet.java | 125 +++++ .../common/pipelike/item/ItemPipeType.java | 85 +++ .../pipelike/item/LevelItemPipeNet.java | 25 + .../longdistance/LDItemEndpointMachine.java | 68 +++ .../item/longdistance/LDItemPipeType.java | 31 ++ .../gtceu/config/ConfigHolder.java | 6 + .../gtceu/core/mixins/LootTablesMixin.java | 2 - .../gtceu/core/mixins/TagLoaderMixin.java | 2 - .../gtceu/data/lang/LangHandler.java | 18 +- .../data/recipe/builder/GTRecipeBuilder.java | 9 +- .../recipe/generated/PipeRecipeHandler.java | 24 +- .../recipe/misc/MetaTileEntityLoader.java | 3 +- .../MetaTileEntityMachineRecipeLoader.java | 41 ++ .../gregtechceu/gtceu/utils/FacingPos.java | 35 ++ .../machine/ld_fluid_endpoint_machine.json | 51 ++ .../machine/ld_item_endpoint_machine.json | 51 ++ .../block/pipe/ld_fluid_pipe/block.png | Bin 0 -> 449 bytes .../pipe/ld_fluid_pipe/overlay_bottom.png | Bin 0 -> 6105 bytes .../ld_fluid_pipe/overlay_bottom.png.mcmeta | 5 + .../ld_fluid_pipe/overlay_bottom_emissive.png | Bin 0 -> 5630 bytes .../block/pipe/ld_fluid_pipe/overlay_left.png | Bin 0 -> 5548 bytes .../ld_fluid_pipe/overlay_left.png.mcmeta | 5 + .../ld_fluid_pipe/overlay_left_emissive.png | Bin 0 -> 676 bytes .../pipe/ld_fluid_pipe/overlay_right.png | Bin 0 -> 6159 bytes .../ld_fluid_pipe/overlay_right.png.mcmeta | 5 + .../ld_fluid_pipe/overlay_right_emissive.png | Bin 0 -> 5713 bytes .../block/pipe/ld_fluid_pipe/overlay_top.png | Bin 0 -> 6130 bytes .../pipe/ld_fluid_pipe/overlay_top.png.mcmeta | 5 + .../ld_fluid_pipe/overlay_top_emissive.png | Bin 0 -> 5632 bytes .../block/pipe/ld_item_pipe/block.png | Bin 0 -> 461 bytes .../pipe/ld_item_pipe/overlay_bottom.png | Bin 0 -> 6159 bytes .../ld_item_pipe/overlay_bottom.png.mcmeta | 5 + .../ld_item_pipe/overlay_bottom_emissive.png | Bin 0 -> 5670 bytes .../block/pipe/ld_item_pipe/overlay_left.png | Bin 0 -> 5672 bytes .../pipe/ld_item_pipe/overlay_left.png.mcmeta | 5 + .../ld_item_pipe/overlay_left_emissive.png | Bin 0 -> 685 bytes .../block/pipe/ld_item_pipe/overlay_right.png | Bin 0 -> 6285 bytes .../ld_item_pipe/overlay_right.png.mcmeta | 5 + .../ld_item_pipe/overlay_right_emissive.png | Bin 0 -> 5726 bytes .../block/pipe/ld_item_pipe/overlay_top.png | Bin 0 -> 6274 bytes .../pipe/ld_item_pipe/overlay_top.png.mcmeta | 5 + .../ld_item_pipe/overlay_top_emissive.png | Bin 0 -> 5669 bytes .../long_distance_fluid_pipeline.json | 7 + .../long_distance_item_pipeline.json | 7 + .../nodes/machines/battery_buffer.json | 2 +- .../compass/nodes/machines/block_breaker.json | 4 +- .../gtceu/compass/nodes/machines/charger.json | 2 +- .../gtceu/compass/nodes/machines/crate.json | 2 +- .../gtceu/compass/nodes/machines/drum.json | 2 +- .../gtceu/compass/nodes/machines/fisher.json | 4 +- .../nodes/machines/ld_fluid_pipeline.json | 15 + .../nodes/machines/ld_item_pipeline.json | 15 + .../gtceu/compass/nodes/machines/miner.json | 2 +- .../gtceu/compass/nodes/machines/pump.json | 2 +- .../compass/nodes/machines/super_chest.json | 2 +- .../compass/nodes/machines/super_tank.json | 2 +- .../resources/assets/gtceu/lang/en_ud.json | 20 + .../resources/assets/gtceu/lang/en_us.json | 20 + .../block/long_distance_fluid_pipeline.json | 6 + .../block/long_distance_item_pipeline.json | 6 + .../item/long_distance_fluid_pipeline.json | 3 + .../item/long_distance_item_pipeline.json | 3 + .../blocks/long_distance_fluid_pipeline.json | 21 + .../blocks/long_distance_item_pipeline.json | 21 + .../fabric/MetaMachineBlockEntityImpl.java | 27 + .../fabric/ItemPipeBlockEntityImpl.java | 35 ++ .../common/data/fabric/GTModelsImpl.java | 8 + .../long_distance_fluid_pipeline.json | 7 + .../long_distance_item_pipeline.json | 7 + .../nodes/machines/battery_buffer.json | 2 +- .../compass/nodes/machines/block_breaker.json | 4 +- .../gtceu/compass/nodes/machines/charger.json | 2 +- .../gtceu/compass/nodes/machines/crate.json | 2 +- .../gtceu/compass/nodes/machines/drum.json | 2 +- .../gtceu/compass/nodes/machines/fisher.json | 4 +- .../nodes/machines/ld_fluid_pipeline.json | 15 + .../nodes/machines/ld_item_pipeline.json | 15 + .../gtceu/compass/nodes/machines/miner.json | 2 +- .../gtceu/compass/nodes/machines/pump.json | 2 +- .../compass/nodes/machines/super_chest.json | 2 +- .../compass/nodes/machines/super_tank.json | 2 +- .../resources/assets/gtceu/lang/en_ud.json | 20 + .../resources/assets/gtceu/lang/en_us.json | 20 + .../block/long_distance_fluid_pipeline.json | 6 + .../block/long_distance_item_pipeline.json | 6 + .../item/long_distance_fluid_pipeline.json | 3 + .../item/long_distance_item_pipeline.json | 3 + .../blocks/long_distance_fluid_pipeline.json | 21 + .../blocks/long_distance_item_pipeline.json | 21 + .../forge/MetaMachineBlockEntityImpl.java | 30 ++ .../forge/ItemPipeBlockEntityImpl.java | 47 ++ .../gtceu/common/data/forge/GTModelsImpl.java | 8 + gradle.properties | 4 +- 127 files changed, 3267 insertions(+), 126 deletions(-) create mode 100644 common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/ILDEndpoint.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistanceNetwork.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeBlock.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeType.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/NetworkBuilder.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/block/ItemPipeBlock.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/cover/data/DistributionMode.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ItemFilterMode.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ManualImportExportMode.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/machine/storage/LongDistanceEndpointMachine.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidEndpointMachine.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidPipeType.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeData.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/LevelItemPipeNet.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemEndpointMachine.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemPipeType.java create mode 100644 common/src/main/java/com/gregtechceu/gtceu/utils/FacingPos.java create mode 100644 common/src/main/resources/assets/gtceu/models/block/machine/ld_fluid_endpoint_machine.json create mode 100644 common/src/main/resources/assets/gtceu/models/block/machine/ld_item_endpoint_machine.json create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/block.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/block.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right_emissive.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_top.png create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_top.png.mcmeta create mode 100644 common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_top_emissive.png create mode 100644 fabric/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_fluid_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_item_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/models/block/long_distance_fluid_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/models/block/long_distance_item_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/models/item/long_distance_fluid_pipeline.json create mode 100644 fabric/src/generated/resources/assets/gtceu/models/item/long_distance_item_pipeline.json create mode 100644 fabric/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_fluid_pipeline.json create mode 100644 fabric/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_item_pipeline.json create mode 100644 fabric/src/main/java/com/gregtechceu/gtceu/common/blockentity/fabric/ItemPipeBlockEntityImpl.java create mode 100644 forge/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_fluid_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_item_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/models/block/long_distance_fluid_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/models/block/long_distance_item_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/models/item/long_distance_fluid_pipeline.json create mode 100644 forge/src/generated/resources/assets/gtceu/models/item/long_distance_item_pipeline.json create mode 100644 forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_fluid_pipeline.json create mode 100644 forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_item_pipeline.json create mode 100644 forge/src/main/java/com/gregtechceu/gtceu/common/blockentity/forge/ItemPipeBlockEntityImpl.java diff --git a/CHANGELOG.md b/CHANGELOG.md index be987daa5e..8f6ad930ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,8 @@ # ChangeLog -* fix custom veins not working in non-vanilla dimensions -* fix large miners not macerating ores properly -* fix the turbines' generation being off by factor of turbine efficiency -* fix recipes not working when a world is loaded for the first time -* fix mipmapping issue -* fix the watertight steel mixer recipe -* fix fabric fluid textures -* add fluid ingredients for fluid input/output unification \ No newline at end of file +* add item pipes +* add long distance pipelines +* fix crash when joining servers +* fix pipe covers not having collision +* add oilsands veins +* fix machines sometimes losing NBT \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java b/common/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java index 18a20590d9..be7acf6953 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java +++ b/common/src/main/java/com/gregtechceu/gtceu/api/block/MaterialPipeBlock.java @@ -56,7 +56,7 @@ public static BlockColor tintedColor() { } public int tinted(BlockState blockState, @Nullable BlockAndTintGetter blockAndTintGetter, @Nullable BlockPos blockPos, int index) { - return material.getMaterialRGB(); + return index == 1 ? material.getMaterialRGB() : -1; } @Override diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java b/common/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java index b6af3c59c8..62d835c589 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java +++ b/common/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java @@ -178,6 +178,11 @@ public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState } } + @Override + public boolean isCollisionShapeFullBlock(BlockState state, BlockGetter level, BlockPos pos) { + return false; + } + @Override public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext context) { var pipeNode = getPileTile(pLevel, pPos); diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java b/common/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java index 2fd94de50c..e43edd54dd 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java +++ b/common/src/main/java/com/gregtechceu/gtceu/api/blockentity/PipeBlockEntity.java @@ -113,6 +113,7 @@ public void onChanged() { setChanged(); } + @Override public long getOffsetTimer() { return level == null ? offset : (level.getGameTime() + offset); diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java b/common/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java index 928dee198d..c0df341f32 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java +++ b/common/src/main/java/com/gregtechceu/gtceu/api/data/tag/TagPrefix.java @@ -705,17 +705,15 @@ public static TagPrefix get(String name) { public static final TagPrefix pipeQuadrupleFluid = new TagPrefix("pipeQuadrupleFluid").itemTable(() -> GTBlocks.FLUID_PIPE_BLOCKS).langValue("Quadruple %s Fluid Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 4).unificationEnabled(true); public static final TagPrefix pipeNonupleFluid = new TagPrefix("pipeNonupleFluid").itemTable(() -> GTBlocks.FLUID_PIPE_BLOCKS).langValue("Nonuple %s Fluid Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 9).unificationEnabled(true); - // TODO Item pipes< - //public static final TagPrefix pipeTinyItem = new TagPrefix("pipeTinyItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Tiny %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M / 2).unificationEnabled(true); - //public static final TagPrefix pipeSmallItem = new TagPrefix("pipeSmallItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Small %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M).unificationEnabled(true); - //public static final TagPrefix pipeNormalItem = new TagPrefix("pipeNormalItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Normal %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 3).unificationEnabled(true); - //public static final TagPrefix pipeLargeItem = new TagPrefix("pipeLargeItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Large %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 6).unificationEnabled(true); - //public static final TagPrefix pipeHugeItem = new TagPrefix("pipeHugeItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Huge %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 12).unificationEnabled(true); - - //public static final TagPrefix pipeSmallRestrictive = new TagPrefix("pipeSmallRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Small Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M).unificationEnabled(true); - //public static final TagPrefix pipeNormalRestrictive = new TagPrefix("pipeNormalRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Normal Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 3).unificationEnabled(true); - //public static final TagPrefix pipeLargeRestrictive = new TagPrefix("pipeLargeRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Large Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 6).unificationEnabled(true); - //public static final TagPrefix pipeHugeRestrictive = new TagPrefix("pipeHugeRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Huge Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 12).unificationEnabled(true); + public static final TagPrefix pipeSmallItem = new TagPrefix("pipeSmallItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Small %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M).unificationEnabled(true); + public static final TagPrefix pipeNormalItem = new TagPrefix("pipeNormalItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Normal %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 3).unificationEnabled(true); + public static final TagPrefix pipeLargeItem = new TagPrefix("pipeLargeItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Large %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 6).unificationEnabled(true); + public static final TagPrefix pipeHugeItem = new TagPrefix("pipeHugeItem").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Huge %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 12).unificationEnabled(true); + + public static final TagPrefix pipeSmallRestrictive = new TagPrefix("pipeSmallRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Small Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M).unificationEnabled(true); + public static final TagPrefix pipeNormalRestrictive = new TagPrefix("pipeNormalRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Normal Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 3).unificationEnabled(true); + public static final TagPrefix pipeLargeRestrictive = new TagPrefix("pipeLargeRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Large Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 6).unificationEnabled(true); + public static final TagPrefix pipeHugeRestrictive = new TagPrefix("pipeHugeRestrictive").itemTable(() -> GTBlocks.ITEM_PIPE_BLOCKS).langValue("Huge Restrictive %s Item Pipe").miningToolTag(GTToolType.WRENCH.harvestTag).materialAmount(GTValues.M * 12).unificationEnabled(true); // Wires and cables public static final TagPrefix wireGtHex = new TagPrefix("wireGtHex").itemTable(() -> GTBlocks.CABLE_BLOCKS).langValue("16x %s Wire").miningToolTag(GTToolType.WIRE_CUTTER.harvestTag).materialAmount(GTValues.M * 8).materialIconType(MaterialIconType.wire).unificationEnabled(true); @@ -956,7 +954,7 @@ public boolean doGenerateItem() { } public boolean doGenerateItem(Material material) { - return generateItem && !isIgnored(material) && (generationCondition == null || generationCondition.test(material)); + return (generateItem && !isIgnored(material) && (generationCondition == null || generationCondition.test(material))) || (hasItemTable() && this.itemTable.get() != null && getItemFromTable(material) != null); } public > void executeHandler(PropertyKey propertyKey, TriConsumer handler) { diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/ILDEndpoint.java b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/ILDEndpoint.java new file mode 100644 index 0000000000..d2d5a045f0 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/ILDEndpoint.java @@ -0,0 +1,84 @@ +package com.gregtechceu.gtceu.api.pipenet.longdistance; + +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.entity.BlockEntity; + +import javax.annotation.Nullable; + +public interface ILDEndpoint { + + /** + * @return the current type of this endpoint (input, output or none) + */ + Type getType(); + + /** + * @param type new active type + */ + void setType(Type type); + + /** + * @return true if this endpoint is considered a network input + */ + default boolean isInput() { + return getType() == Type.INPUT; + } + + /** + * @return true if this endpoint is considered a network output + */ + default boolean isOutput() { + return getType() == Type.OUTPUT; + } + + /** + * @return the currently linked endpoint or null + */ + @Nullable + ILDEndpoint getLink(); + + /** + * removes the linked endpoint if there is any + */ + void invalidateLink(); + + /** + * @return the front facing, usually the input face + */ + Direction getFrontFacing(); + + /** + * @return the output facing + */ + Direction getOutputFacing(); + + /** + * @return the ld pipe type for this endpoint + */ + LongDistancePipeType getPipeType(); + + /** + * @return pos in world + */ + BlockPos getPos(); + + static ILDEndpoint tryGet(LevelAccessor world, BlockPos pos) { + BlockEntity te = world.getBlockEntity(pos); + if (te instanceof IMachineBlockEntity iMachineBlock) { + MetaMachine mte = iMachineBlock.getMetaMachine(); + if (mte instanceof ILDEndpoint) { + return (ILDEndpoint) mte; + } + } + return null; + } + + enum Type { + NONE, INPUT, OUTPUT + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistanceNetwork.java b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistanceNetwork.java new file mode 100644 index 0000000000..b25b5bef2d --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistanceNetwork.java @@ -0,0 +1,443 @@ +package com.gregtechceu.gtceu.api.pipenet.longdistance; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectMaps; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.LongTag; +import net.minecraft.nbt.Tag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.saveddata.SavedData; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class LongDistanceNetwork { + + // all pipes and endpoints in this net + private final ObjectOpenHashSet longDistancePipeBlocks = new ObjectOpenHashSet<>(); + @Getter + private final LongDistancePipeType pipeType; + private final WorldData world; + // stores all connected endpoints, but only the first two are being used + private final List endpoints = new ArrayList<>(); + // all endpoint positions, for nbt + private final List endpointPoss = new ArrayList<>(); + private int activeInputIndex = -1, activeOutputIndex = -1; + + protected LongDistanceNetwork(LongDistancePipeType pipeType, WorldData world) { + this.pipeType = pipeType; + this.world = world; + } + + @Nullable + public static LongDistanceNetwork get(LevelAccessor world, BlockPos pos) { + return WorldData.get(world).getNetwork(pos); + } + + /** + * Calculates one or more networks based on the given starting points. + * For this it will start a new thread to keep the main thread free. + */ + protected void recalculateNetwork(Collection starts) { + // remove the every pipe from the network + for (BlockPos pos : this.longDistancePipeBlocks) { + this.world.removeNetwork(pos); + } + invalidateEndpoints(); + this.endpoints.clear(); + this.longDistancePipeBlocks.clear(); + // start a new thread where all given starting points are being walked + Thread thread = new Thread(new NetworkBuilder(world, this, starts)); + thread.start(); + } + + /** + * Called from the {@link NetworkBuilder} to set the gathered data + */ + protected void setData(Collection pipes, List endpoints) { + invalidateEndpoints(); + boolean wasEmpty = this.longDistancePipeBlocks.isEmpty(); + this.longDistancePipeBlocks.clear(); + this.longDistancePipeBlocks.addAll(pipes); + this.endpoints.clear(); + this.endpoints.addAll(endpoints); + if (this.longDistancePipeBlocks.isEmpty()) { + invalidateNetwork(); + return; + } + if (wasEmpty) { + this.world.networkList.add(this); + } + for (BlockPos pos : this.longDistancePipeBlocks) { + this.world.putNetwork(pos, this); + } + } + + /** + * Removes the pipe at the given position and recalculates all neighbour positions if necessary + */ + public void onRemovePipe(BlockPos pos) { + // remove the network from that pos + this.longDistancePipeBlocks.remove(pos); + this.world.removeNetwork(pos); + if (this.longDistancePipeBlocks.isEmpty()) { + invalidateNetwork(); + return; + } + // find amount of neighbour networks + List neighbours = new ArrayList<>(); + BlockPos.MutableBlockPos offsetPos = new BlockPos.MutableBlockPos(); + for (Direction facing : Direction.values()) { + offsetPos.set(pos).move(facing); + LongDistanceNetwork network = world.getNetwork(offsetPos); + if (network == this) { + neighbours.add(offsetPos.immutable()); + } + } + if (neighbours.size() > 1) { + // the pipe had more than 1 neighbour + // the network might need to be recalculated for each neighbour + recalculateNetwork(neighbours); + } + } + + protected void addEndpoint(ILDEndpoint endpoint) { + if (!this.endpoints.contains(endpoint)) { + this.endpoints.add(endpoint); + } + } + + protected void addEndpoint(Collection endpoints) { + for (ILDEndpoint endpoint : endpoints) { + if (!this.endpoints.contains(endpoint)) { + this.endpoints.add(endpoint); + } + } + } + + public void onRemoveEndpoint(ILDEndpoint endpoint) { + // invalidate all linked endpoints + endpoint.invalidateLink(); + if (this.endpoints.remove(endpoint)) { + invalidateEndpoints(); + } + onRemovePipe(endpoint.getPos()); + } + + /** + * Adds a new pipe to the network + */ + public void onPlacePipe(BlockPos pos) { + this.longDistancePipeBlocks.add(pos); + this.world.putNetwork(pos, this); + } + + /** + * Adds a new endpoint to the network + */ + public void onPlaceEndpoint(ILDEndpoint endpoint) { + addEndpoint(endpoint); + this.longDistancePipeBlocks.add(endpoint.getPos()); + this.world.putNetwork(endpoint.getPos(), this); + } + + /** + * Merge a network into this network + */ + protected void mergePipeNet(LongDistanceNetwork network) { + if (getPipeType() != network.getPipeType()) { + throw new IllegalStateException("Can't merge unequal pipe types, " + getPipeType().getName() + " and " + network.getPipeType().getName() + " !"); + } + for (BlockPos pos : network.longDistancePipeBlocks) { + this.world.putNetwork(pos, this); + this.longDistancePipeBlocks.add(pos); + } + addEndpoint(network.endpoints); + for (ILDEndpoint endpoint1 : this.endpoints) { + endpoint1.invalidateLink(); + } + network.invalidateNetwork(); + } + + /** + * invalidate this network + */ + protected void invalidateNetwork() { + this.longDistancePipeBlocks.clear(); + this.world.networkList.remove(this); + invalidateEndpoints(); + this.endpoints.clear(); + } + + protected void invalidateEndpoints() { + this.activeInputIndex = -1; + this.activeOutputIndex = -1; + for (ILDEndpoint endpoint : this.endpoints) { + endpoint.invalidateLink(); + } + } + + /** + * Finds the first other endpoint for the given endpoint connected to this network. + * + * @param endpoint endpoint to find another endpoint for + * @return other endpoint or null if none is found + */ + @Nullable + public ILDEndpoint getOtherEndpoint(ILDEndpoint endpoint) { + // return null for invalid network configurations + if (!isValid() || (!endpoint.isInput() && !endpoint.isOutput())) return null; + + if (isIOIndexInvalid()) { + invalidateEndpoints(); + } else if (this.activeInputIndex >= 0) { + // there is an active input and output endpoint + ILDEndpoint in = this.endpoints.get(this.activeInputIndex); + ILDEndpoint out = this.endpoints.get(this.activeOutputIndex); + if (!this.pipeType.satisfiesMinLength(in, out)) { + invalidateEndpoints(); + return getOtherEndpoint(endpoint); + } + if (in == endpoint) { + if (!endpoint.isInput()) throw new IllegalStateException("Other endpoint from input was itself"); + // given endpoint is the current input, and therefore we return the output + return out; + } + if (out == endpoint) { + if (!endpoint.isOutput()) throw new IllegalStateException("Other endpoint from output was itself"); + // given endpoint is the current output, and therefore we return the input + return in; + } + return null; + } + + // find a valid endpoint in this net + int otherIndex = find(endpoint); + if (otherIndex >= 0) { + // found other endpoint + int thisIndex = this.endpoints.indexOf(endpoint); + if (thisIndex < 0) + throw new IllegalStateException("Tried to get endpoint that is not part of this network. Something is seriously wrong!"); + ILDEndpoint other = this.endpoints.get(otherIndex); + // set active endpoints + this.activeOutputIndex = endpoint.isOutput() ? thisIndex : otherIndex; + this.activeInputIndex = endpoint.isInput() ? thisIndex : otherIndex; + return other; + } + return null; + } + + private int find(ILDEndpoint endpoint) { + for (int i = 0; i < this.endpoints.size(); i++) { + ILDEndpoint other = this.endpoints.get(i); + if (endpoint != other && + (other.isOutput() || other.isInput()) && + other.isInput() != endpoint.isInput() && + this.pipeType.satisfiesMinLength(endpoint, other)) { + // found valid endpoint with minimum distance + return i; + } + } + return -1; + } + + public boolean isIOIndexInvalid() { + return (this.activeInputIndex >= 0 && this.activeInputIndex >= this.endpoints.size()) + || (this.activeOutputIndex >= 0 && this.activeOutputIndex >= this.endpoints.size()) + || this.activeInputIndex < 0 != this.activeOutputIndex < 0; + } + + public ILDEndpoint getActiveInputIndex() { + return this.activeInputIndex >= 0 ? this.endpoints.get(this.activeInputIndex) : null; + } + + public ILDEndpoint getActiveOutputIndex() { + return this.activeOutputIndex >= 0 ? this.endpoints.get(this.activeOutputIndex) : null; + } + + /** + * @return the total amount of connected and valid ld pipe blocks and endpoints + */ + public int getTotalSize() { + return this.longDistancePipeBlocks.size(); + } + + /** + * @return the total amount of connected and valid endpoints + */ + public int getEndpointAmount() { + return this.endpoints.size(); + } + + /** + * @return the total amount of connected and valid ld pipe blocks + */ + public int getPipeAmount() { + return getTotalSize() - getEndpointAmount(); + } + + /** + * @return if this network has more than one valid endpoint + */ + public boolean isValid() { + return getEndpointAmount() > 1; + } + + /** + * Stores all pipe data for a world/dimension + */ + public static class WorldData extends SavedData { + + // A chunk pos to block pos to network map map + private final Long2ObjectMap> networks = new Long2ObjectOpenHashMap<>(); + // All existing networks in this world + private final ObjectOpenHashSet networkList = new ObjectOpenHashSet<>(); + private WeakReference worldRef = new WeakReference<>(null); + + public WorldData() { + super(); + } + + public static WorldData create(ServerLevel level) { + WorldData data = new WorldData(); + data.setWorldAndInit(level); + return data; + } + + public static WorldData get(LevelAccessor level) { + if (level instanceof ServerLevel serverLevel) { + return serverLevel.getDataStorage().computeIfAbsent(WorldData::load, () -> WorldData.create(serverLevel), "gtceu_long_dist_pipe"); + } + return null; + } + + private static long getChunkPos(BlockPos pos) { + return ChunkPos.asLong(pos.getX() >> 4, pos.getZ() >> 4); + } + + /** + * set world and load all endpoints + */ + protected void setWorldAndInit(LevelAccessor world) { + if (this.worldRef.get() != world) { + for (LongDistanceNetwork ld : this.networkList) { + if (!ld.endpointPoss.isEmpty()) { + ld.endpoints.clear(); + for (BlockPos pos : ld.endpointPoss) { + ILDEndpoint endpoint = ILDEndpoint.tryGet(world, pos); + if (endpoint != null) { + ld.addEndpoint(endpoint); + } + } + } + } + } + this.worldRef = new WeakReference<>(world); + this.setDirty(); + } + + public LongDistanceNetwork getNetwork(BlockPos pos) { + return this.networks.getOrDefault(getChunkPos(pos), Object2ObjectMaps.emptyMap()).get(pos); + } + + private void putNetwork(BlockPos pos, LongDistanceNetwork network) { + long chunkPos = getChunkPos(pos); + Object2ObjectMap chunkNetworks = this.networks.get(chunkPos); + if (chunkNetworks == null) { + chunkNetworks = new Object2ObjectOpenHashMap<>(); + this.networks.put(chunkPos, chunkNetworks); + } + chunkNetworks.put(pos, network); + this.networkList.add(network); + this.setDirty(); + } + + private void removeNetwork(BlockPos pos) { + long chunkPos = getChunkPos(pos); + Object2ObjectMap chunkNetworks = this.networks.get(chunkPos); + if (chunkNetworks != null) { + chunkNetworks.remove(pos); + if (chunkNetworks.isEmpty()) { + this.networks.remove(chunkPos); + } + } + this.setDirty(); + } + + public static WorldData load(@NotNull CompoundTag nbtTagCompound) { + WorldData data = new WorldData(); + data.networks.clear(); + data.networkList.clear(); + ListTag list = nbtTagCompound.getList("nets", Tag.TAG_COMPOUND); + for (Tag nbt : list) { + CompoundTag tag = (CompoundTag) nbt; + LongDistancePipeType pipeType = LongDistancePipeType.getPipeType(tag.getString("class")); + LongDistanceNetwork ld = pipeType.createNetwork(data); + ld.activeInputIndex = tag.getInt("in"); + ld.activeOutputIndex = tag.getInt("out"); + data.networkList.add(ld); + ListTag posList = tag.getList("pipes", Tag.TAG_LONG); + for (Tag nbtPos : posList) { + BlockPos pos = BlockPos.of(((LongTag) nbtPos).getAsLong()); + data.putNetwork(pos, ld); + ld.longDistancePipeBlocks.add(pos); + } + ListTag endpoints = tag.getList("endpoints", Tag.TAG_LONG); + for (Tag nbtPos : endpoints) { + BlockPos pos = BlockPos.of(((LongTag) nbtPos).getAsLong()); + if (!ld.endpointPoss.contains(pos)) { + ld.endpointPoss.add(pos); + } + } + } + return data; + } + + @NotNull + @Override + public CompoundTag save(@NotNull CompoundTag nbtTagCompound) { + ListTag list = new ListTag(); + for (LongDistanceNetwork network : this.networkList) { + CompoundTag tag = new CompoundTag(); + list.add(tag); + + String name = network.getPipeType().getName(); + tag.putString("class", name); + tag.putInt("in", network.activeInputIndex); + tag.putInt("out", network.activeOutputIndex); + + ListTag posList = new ListTag(); + tag.put("pipes", posList); + for (BlockPos pos : network.longDistancePipeBlocks) { + posList.add(LongTag.valueOf(pos.asLong())); + } + + ListTag endpoints = new ListTag(); + tag.put("endpoints", endpoints); + for (ILDEndpoint endpoint : network.endpoints) { + endpoints.add(LongTag.valueOf(endpoint.getPos().asLong())); + } + } + nbtTagCompound.put("nets", list); + return nbtTagCompound; + } + + public LevelAccessor getWorld() { + return this.worldRef.get(); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeBlock.java b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeBlock.java new file mode 100644 index 0000000000..3ffd982a09 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeBlock.java @@ -0,0 +1,77 @@ +package com.gregtechceu.gtceu.api.pipenet.longdistance; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; +import java.util.List; + +@ParametersAreNonnullByDefault +public class LongDistancePipeBlock extends Block { + + private final LongDistancePipeType pipeType; + + public LongDistancePipeBlock(BlockBehaviour.Properties properties, LongDistancePipeType pipeType) { + super(properties); + this.pipeType = pipeType; + } + @Override + public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { + super.setPlacedBy(level, pos, state, placer, stack); + if (level.isClientSide) return; + // first find all neighbouring networks + List networks = findNetworks(level, pos); + if (networks.isEmpty()) { + // create network + LongDistanceNetwork network = this.pipeType.createNetwork(level); + network.onPlacePipe(pos); + } else if (networks.size() == 1) { + // add to connected network + networks.get(0).onPlacePipe(pos); + } else { + // merge all connected networks together + LongDistanceNetwork main = networks.get(0); + main.onPlacePipe(pos); + networks.remove(0); + for (LongDistanceNetwork network : networks) { + main.mergePipeNet(network); + } + } + } + + public List findNetworks(Level level, BlockPos pos) { + List networks = new ArrayList<>(); + BlockPos.MutableBlockPos offsetPos = new BlockPos.MutableBlockPos(); + for (Direction facing : Direction.values()) { + offsetPos.set(pos).move(facing); + LongDistanceNetwork network = LongDistanceNetwork.get(level, offsetPos); + if (network != null && pipeType == network.getPipeType()) { + ILDEndpoint endpoint = ILDEndpoint.tryGet(level, offsetPos); + // only count the network as connected if it's not an endpoint or the endpoints input or output face is connected + if (endpoint == null || endpoint.getFrontFacing().getAxis() == facing.getAxis()) { + networks.add(network); + } + } + } + return networks; + } + + @Override + public void destroy(LevelAccessor level, BlockPos pos, BlockState state) { + super.destroy(level, pos, state); + if (level.isClientSide()) return; + LongDistanceNetwork network = LongDistanceNetwork.get(level, pos); + if (network != null) { + network.onRemovePipe(pos); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeType.java b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeType.java new file mode 100644 index 0000000000..4f02ac6289 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/LongDistancePipeType.java @@ -0,0 +1,96 @@ +package com.gregtechceu.gtceu.api.pipenet.longdistance; + +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance.LDFluidPipeType; +import com.gregtechceu.gtceu.common.pipelike.item.longdistance.LDItemPipeType; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import javax.annotation.Nonnull; +import java.util.Objects; + +/** + * This class defines a long distance pipe type. This class MUST be a singleton class! + */ +public abstract class LongDistancePipeType { + + private static final Object2ObjectOpenHashMap PIPE_TYPES = new Object2ObjectOpenHashMap<>(); + + private static LDFluidPipeType FLUID; + private static LDItemPipeType ITEM; + + private final String name; + + protected LongDistancePipeType(String name) { + this.name = Objects.requireNonNull(name); + if (PIPE_TYPES.containsKey(name)) { + throw new IllegalArgumentException("Pipe Type with name " + name + " already exists!"); + } + for (LongDistancePipeType pipeType : PIPE_TYPES.values()) { + if (this.getClass() == pipeType.getClass()) { + throw new IllegalStateException("Duplicate Pipe Type " + name + " and " + pipeType.name); + } + } + PIPE_TYPES.put(name, this); + } + + public static void init() { + FLUID = LDFluidPipeType.INSTANCE; + ITEM = LDItemPipeType.INSTANCE; + } + + public static LDFluidPipeType fluid() { + return FLUID; + } + + public static LDItemPipeType item() { + return ITEM; + } + + public static LongDistancePipeType getPipeType(String name) { + return PIPE_TYPES.get(name); + } + + /** + * Checks if the given block state is a valid ld pipe block for this type + * + * @param blockState potential ld pipe block + * @return if the given block state is a valid ld pipe block for this type + */ + public abstract boolean isValidBlock(BlockState blockState); + + /** + * Checks if the given endpoint is a valid endpoint for this type + * + * @param endpoint potential endpoint + * @return if the given endpoint is a valid endpoint for this type + */ + public abstract boolean isValidEndpoint(ILDEndpoint endpoint); + + /** + * @return The minimum required distance (not pipe count) between two endpoints to work. + */ + public int getMinLength() { + return 0; + } + + public boolean satisfiesMinLength(ILDEndpoint endpoint1, ILDEndpoint endpoint2) { + BlockPos p = endpoint2.getPos(); + int minLength = getMinLength(); + return endpoint1 != endpoint2 && endpoint1.getPos().distSqr(p) >= minLength * minLength; + } + + @Nonnull + public LongDistanceNetwork createNetwork(LongDistanceNetwork.WorldData worldData) { + return new LongDistanceNetwork(this, worldData); + } + + public final LongDistanceNetwork createNetwork(Level world) { + return createNetwork(LongDistanceNetwork.WorldData.get(world)); + } + + public final String getName() { + return name; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/NetworkBuilder.java b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/NetworkBuilder.java new file mode 100644 index 0000000000..d30c71505a --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/api/pipenet/longdistance/NetworkBuilder.java @@ -0,0 +1,111 @@ +package com.gregtechceu.gtceu.api.pipenet.longdistance; + +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * This bad boy is responsible for building the network + */ +public class NetworkBuilder implements Runnable { + + private final LinkedList starts = new LinkedList<>(); + private final LongDistanceNetwork.WorldData worldData; + private LongDistanceNetwork network; + private final LevelAccessor world; + private final LinkedList currentPoints = new LinkedList<>(); + private final ObjectOpenHashSet walked = new ObjectOpenHashSet<>(); + private final List pipes = new ArrayList<>(); + private final List endpoints = new ArrayList<>(); + + public NetworkBuilder(LongDistanceNetwork.WorldData worldData, LongDistanceNetwork network, BlockPos start) { + this.worldData = worldData; + this.network = network; + this.world = worldData.getWorld(); + this.starts.add(start); + } + + public NetworkBuilder(LongDistanceNetwork.WorldData worldData, LongDistanceNetwork network, Collection starts) { + this.worldData = worldData; + this.network = network; + this.world = worldData.getWorld(); + this.starts.addAll(starts); + } + + @Override + public void run() { + // iterate over each given starting point and try to build a network + boolean first = true; + while (!starts.isEmpty()) { + BlockPos start = starts.pollFirst(); + if (first) { + first = false; + checkNetwork(start); + continue; + } + LongDistanceNetwork ldn = worldData.getNetwork(start); + if (ldn != null) { + // this starting point was caught during a previous iteration, so we don't need to create another network here + continue; + } + // create a new network, since the current was already calculated + this.network = this.network.getPipeType().createNetwork(this.worldData); + this.currentPoints.clear(); + this.walked.clear(); + this.pipes.clear(); + this.endpoints.clear(); + checkNetwork(start); + } + } + + private void checkNetwork(BlockPos start) { + // current points stores all current branches of the network + this.currentPoints.add(start); + checkPos(world.getBlockState(start), start); + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + while (!currentPoints.isEmpty()) { + // get and remove the first stored branch + BlockPos current = currentPoints.pollFirst(); + for (Direction facing : Direction.values()) { + pos.set(current).move(facing); + if (walked.contains(pos)) { + continue; + } + BlockState blockState = world.getBlockState(pos); + if (blockState.isAir()) { + continue; + } + checkPos(blockState, pos); + } + } + // the whole net was checked + // now send the data to the given network + network.setData(pipes, endpoints); + } + + /** + * Checks a pos for a pipe or a endpoint + */ + private void checkPos(BlockState blockState, BlockPos pos) { + BlockPos bp = pos.immutable(); + if (blockState.getBlock() instanceof LongDistancePipeBlock && network.getPipeType().isValidBlock(blockState)) { + pipes.add(bp); + // add another branch/block for processing + currentPoints.addLast(bp); + } else { + ILDEndpoint endpoint = ILDEndpoint.tryGet(world, pos); + if (endpoint != null && network.getPipeType().isValidEndpoint(endpoint)) { + pipes.add(bp); + endpoints.add(endpoint); + } + } + walked.add(bp); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/FluidIngredient.java b/common/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/FluidIngredient.java index 2678bcdf54..d7b39934f1 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/FluidIngredient.java +++ b/common/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/FluidIngredient.java @@ -52,6 +52,8 @@ public static FluidIngredient fromValues(Stream public void toNetwork(FriendlyByteBuf buffer) { buffer.writeCollection(Arrays.asList(this.getStacks()), (buf, stack) -> stack.writeToBuf(buf)); + buffer.writeVarLong(amount); + buffer.writeNbt(nbt); } public JsonElement toJson() { diff --git a/common/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java b/common/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java index a2d3770580..aad85db8b6 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java +++ b/common/src/main/java/com/gregtechceu/gtceu/client/model/PipeModel.java @@ -39,10 +39,10 @@ public class PipeModel { public Supplier sideTexture, endTexture; @Setter - public ResourceLocation endOverlayTexture; + public ResourceLocation sideOverlayTexture, endOverlayTexture; @Environment(EnvType.CLIENT) - TextureAtlasSprite sideSprite, endSprite, endOverlaySprite; + TextureAtlasSprite sideSprite, endSprite, sideOverlaySprite, endOverlaySprite; public PipeModel(float thickness, Supplier sideTexture, Supplier endTexture) { this.sideTexture = sideTexture; @@ -87,21 +87,33 @@ public List bakeQuads(@Nullable Direction side, int connections) { if (endSprite == null) { endSprite = ModelFactory.getBlockSprite(endTexture.get()); } + if (sideOverlayTexture != null && sideOverlaySprite == null) { + sideOverlaySprite = ModelFactory.getBlockSprite(sideOverlayTexture); + } if (endOverlayTexture != null && endOverlaySprite == null) { endOverlaySprite = ModelFactory.getBlockSprite(endOverlayTexture); } if (side != null) { if (thickness == 1) { // full block - return List.of(FaceQuad.builder(side, sideSprite).cube(coreCube).cubeUV().tintIndex(0).bake()); + BakedQuad base = FaceQuad.builder(side, sideSprite).cube(coreCube.inflate(-0.001)).cubeUV().tintIndex(1).bake(); + return List.of(base); } if (isConnected(connections, side)) { // side connected - BakedQuad base = FaceQuad.builder(side, endSprite).cube(sideCubes.get(side).inflate(-0.001)).cubeUV().tintIndex(1).bake(); + List quads = new ArrayList<>(); + quads.add(FaceQuad.builder(side, endSprite).cube(sideCubes.get(side).inflate(-0.001)).cubeUV().tintIndex(1).bake()); if (endOverlaySprite != null) { - return List.of(base, FaceQuad.builder(side, endOverlaySprite).cube(sideCubes.get(side).inflate(-0.000)).cubeUV().tintIndex(0).bake()); + quads.add(FaceQuad.builder(side, endOverlaySprite).cube(sideCubes.get(side).inflate(-0.000)).cubeUV().tintIndex(0).bake()); } - return List.of(base); + if (sideOverlaySprite != null) { + for (Direction face : Direction.values()) { + if (face != side && face != side.getOpposite()) { + quads.add(FaceQuad.builder(face, sideOverlaySprite).cube(sideCubes.get(side).inflate(-0.000)).cubeUV().tintIndex(0).bake()); + } + } + } + return quads; } return Collections.emptyList(); @@ -112,16 +124,19 @@ public List bakeQuads(@Nullable Direction side, int connections) { // render core cube for (Direction face : Direction.values()) { if (!isConnected(connections, face)) { - quads.add(FaceQuad.builder(face, sideSprite).cube(coreCube).cubeUV().tintIndex(0).bake()); + quads.add(FaceQuad.builder(face, sideSprite).cube(coreCube).cubeUV().tintIndex(1).bake()); } // render each connected side for (Direction facing : Direction.values()) { if (facing.getAxis() != face.getAxis()) { if (isConnected(connections, facing)) { - quads.add(FaceQuad.builder(face, sideSprite).cube(sideCubes.get(facing)).cubeUV().tintIndex(0).bake()); - //if (endSpriteOverlay != null) { - // quads.add(FaceQuad.builder(face, endSpriteOverlay).cube(sideCubes.get(facing).inflate(0.01)).cubeUV().tintIndex(0).bake()); - //} + quads.add(FaceQuad.builder(face, sideSprite).cube(sideCubes.get(facing)).cubeUV().tintIndex(1).bake()); + if (endOverlaySprite != null) { + quads.add(FaceQuad.builder(face, endOverlaySprite).cube(sideCubes.get(facing).inflate(0.01)).cubeUV().tintIndex(0).bake()); + } + if (sideOverlaySprite != null) { + quads.add(FaceQuad.builder(face, sideOverlaySprite).cube(sideCubes.get(facing).inflate(0.001)).cubeUV().tintIndex(0).bake()); + } } } } @@ -151,6 +166,7 @@ public void renderItem(ItemStack stack, ItemDisplayContext transformType, boolea public void registerTextureAtlas(Consumer register) { register.accept(sideTexture.get()); register.accept(endTexture.get()); + if (sideOverlayTexture != null) register.accept(sideOverlayTexture); if (endOverlayTexture != null) register.accept(endOverlayTexture); sideSprite = null; endSprite = null; diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java b/common/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java index 8da9753b34..3ce057c006 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java @@ -47,7 +47,7 @@ public int tinted(BlockState blockState, @Nullable BlockAndTintGetter blockAndTi if (pipeType.isCable && index == 0) { return 0x404040; } - return material.getMaterialRGB(); + return index == 1 ? material.getMaterialRGB() : -1; } @Override diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java b/common/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java index c2b715142e..cb1f6f90c5 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/block/FluidPipeBlock.java @@ -41,11 +41,6 @@ public FluidPipeBlock(Properties properties, FluidPipeType fluidPipeType, Materi super(properties, fluidPipeType, material); } - @Override - public int tinted(BlockState blockState, @Nullable BlockAndTintGetter blockAndTintGetter, @Nullable BlockPos blockPos, int index) { - return material.getMaterialRGB(); - } - @Override protected FluidPipeData createMaterialData() { return new FluidPipeData(material.getProperty(PropertyKey.FLUID_PIPE), (byte) 0); diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/block/ItemPipeBlock.java b/common/src/main/java/com/gregtechceu/gtceu/common/block/ItemPipeBlock.java new file mode 100644 index 0000000000..78e5e9ba83 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/block/ItemPipeBlock.java @@ -0,0 +1,39 @@ +package com.gregtechceu.gtceu.common.block; + +import com.gregtechceu.gtceu.api.block.MaterialPipeBlock; +import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; +import com.gregtechceu.gtceu.api.data.chemical.material.Material; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey; +import com.gregtechceu.gtceu.client.model.PipeModel; +import com.gregtechceu.gtceu.common.data.GTBlockEntities; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeData; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeType; +import com.gregtechceu.gtceu.common.pipelike.item.LevelItemPipeNet; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public class ItemPipeBlock extends MaterialPipeBlock { + public ItemPipeBlock(Properties properties, ItemPipeType itemPipeType, Material material) { + super(properties, itemPipeType, material); + } + + @Override + protected ItemPipeData createMaterialData() { + return new ItemPipeData(material.getProperty(PropertyKey.ITEM_PIPE), (byte) 0); + } + + @Override + protected PipeModel createPipeModel() { + return pipeType.createPipeModel(material); + } + + @Override + public LevelItemPipeNet getWorldPipeNet(ServerLevel level) { + return LevelItemPipeNet.getOrCreate(level); + } + + @Override + public BlockEntityType> getBlockEntityType() { + return GTBlockEntities.ITEM_PIPE.get(); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java b/common/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java new file mode 100644 index 0000000000..9f359460b8 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/blockentity/ItemPipeBlockEntity.java @@ -0,0 +1,116 @@ +package com.gregtechceu.gtceu.common.blockentity; + +import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; +import com.gregtechceu.gtceu.common.block.ItemPipeBlock; +import com.gregtechceu.gtceu.common.pipelike.item.ItemNetHandler; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeData; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeNet; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeType; +import com.gregtechceu.gtceu.utils.FacingPos; +import com.lowdragmc.lowdraglib.side.item.ItemTransferHelper; +import dev.architectury.injectables.annotations.ExpectPlatform; +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.lang.ref.WeakReference; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +public class ItemPipeBlockEntity extends PipeBlockEntity { + protected WeakReference currentItemPipeNet = new WeakReference<>(null); + + @Getter + protected final EnumMap handlers = new EnumMap<>(Direction.class); + @Getter + private final Map transferred = new HashMap<>(); + @Getter + protected ItemNetHandler defaultHandler; + + TickableSubscription serverTick; + + @Getter + private int transferredItems = 0; + private long timer = 0; + + public ItemPipeBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { + super(type, pos, blockState); + this.serverTick = subscribeServerTick(this::update); + } + + @ExpectPlatform + public static ItemPipeBlockEntity create(BlockEntityType type, BlockPos pos, BlockState blockState) { + throw new AssertionError(); + } + + @ExpectPlatform + public static void onBlockEntityRegister(BlockEntityType cableBlockEntityBlockEntityType) { + throw new AssertionError(); + } + + public void initHandlers() { + ItemPipeNet net = getItemPipeNet(); + if (net == null) { + return; + } + for (Direction facing : Direction.values()) { + handlers.put(facing, new ItemNetHandler(net, this, facing)); + } + defaultHandler = new ItemNetHandler(net, this, null); + } + + public void checkNetwork() { + if (defaultHandler != null) { + ItemPipeNet current = getItemPipeNet(); + if (defaultHandler.getNet() != current) { + defaultHandler.updateNetwork(current); + for (ItemNetHandler handler : handlers.values()) { + handler.updateNetwork(current); + } + } + } + } + + @Override + public boolean canAttachTo(Direction side) { + if (level == null) return false; + if (level.getBlockEntity(getBlockPos().relative(side)) instanceof ItemPipeBlockEntity) { + return false; + } + return ItemTransferHelper.getItemTransfer(level, getBlockPos().relative(side), side.getOpposite()) != null; + } + + @Nullable + public ItemPipeNet getItemPipeNet() { + if (level instanceof ServerLevel serverLevel && getBlockState().getBlock() instanceof ItemPipeBlock itemPipeBlock) { + ItemPipeNet currentItemPipeNet = this.currentItemPipeNet.get(); + if (currentItemPipeNet != null && currentItemPipeNet.isValid() && currentItemPipeNet.containsNode(getBlockPos())) + return currentItemPipeNet; //return current net if it is still valid + currentItemPipeNet = itemPipeBlock.getWorldPipeNet(serverLevel).getNetFromPos(getBlockPos()); + if (currentItemPipeNet != null) { + this.currentItemPipeNet = new WeakReference<>(currentItemPipeNet); + } + } + return this.currentItemPipeNet.get(); + } + + public void update() { + if (++timer % 20 == 0) { + transferredItems = 0; + } + } + + public void transferItems(int amount) { + transferredItems += amount; + } + + public void resetTransferred() { + transferred.clear(); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java b/common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java index f523a82372..2b67693f09 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java @@ -11,9 +11,13 @@ import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers; import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; import com.gregtechceu.gtceu.api.machine.ConditionalSubscriptionHandler; import com.gregtechceu.gtceu.api.syncdata.RequireRerender; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.gregtechceu.gtceu.common.cover.data.DistributionMode; +import com.gregtechceu.gtceu.common.cover.data.ManualImportExportMode; import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; @@ -59,12 +63,16 @@ public class ConveyorCover extends CoverBehavior implements IUICover, IControlla protected int transferRate; @Persisted @DescSynced @Getter @RequireRerender protected IO io; + @Persisted @DescSynced @Getter + protected DistributionMode distributionMode; + @Persisted @DescSynced @Getter + protected ManualImportExportMode manualImportExportMode = ManualImportExportMode.DISABLED; @Persisted @Getter protected boolean isWorkingEnabled = true; protected int itemsLeftToTransferLastSecond; private Widget ioModeSwitch; - @Persisted @DescSynced + @Persisted @DescSynced @Getter protected final FilterHandler filterHandler; protected final ConditionalSubscriptionHandler subscriptionHandler; @@ -75,6 +83,7 @@ public ConveyorCover(CoverDefinition definition, ICoverable coverHolder, Directi this.transferRate = maxItemTransferRate; this.itemsLeftToTransferLastSecond = transferRate; this.io = IO.OUT; + this.distributionMode = DistributionMode.INSERT_FIRST; subscriptionHandler = new ConditionalSubscriptionHandler(coverHolder, this::update, this::isSubscriptionActive); filterHandler = FilterHandlers.item(this) @@ -118,6 +127,17 @@ public void setIo(IO io) { if (io == IO.IN || io == IO.OUT) { this.io = io; } + coverHolder.markDirty(); + } + + public void setDistributionMode(DistributionMode distributionMode) { + this.distributionMode = distributionMode; + coverHolder.markDirty(); + } + + protected void setManualImportExportMode(ManualImportExportMode manualImportExportMode) { + this.manualImportExportMode = manualImportExportMode; + coverHolder.markDirty(); } @Override @@ -226,7 +246,7 @@ protected static boolean moveInventoryItemsExact(IItemTransfer sourceInventory, int itemsLeftToExtract = itemInfo.totalCount; for (int i = 0; i < itemInfo.slots.size(); i++) { - int slotIndex = itemInfo.slots.get(i); + int slotIndex = itemInfo.slots.getInt(i); ItemStack extractedStack = sourceInventory.extractItem(slotIndex, itemsLeftToExtract, true); if (!extractedStack.isEmpty() && ItemStack.isSameItemSameTags(resultStack, extractedStack)) { @@ -258,7 +278,7 @@ protected static boolean moveInventoryItemsExact(IItemTransfer sourceInventory, //perform real extraction of the items from the source inventory now itemsLeftToExtract = itemInfo.totalCount; for (int i = 0; i < itemInfo.slots.size(); i++) { - int slotIndex = itemInfo.slots.get(i); + int slotIndex = itemInfo.slots.getInt(i); ItemStack extractedStack = sourceInventory.extractItem(slotIndex, itemsLeftToExtract, false); if (!extractedStack.isEmpty() && ItemStack.isSameItemSameTags(resultStack, extractedStack)) { @@ -388,6 +408,17 @@ public Widget createUIWidget() { .setPressed(io == IO.IN) .setHoverTooltips(LocalizationUtils.format("cover.conveyor.mode", LocalizationUtils.format(io.tooltip))); group.addWidget(ioModeSwitch); + group.addWidget(new EnumSelectorWidget<>(7, 166, 116, 20, + ManualImportExportMode.VALUES, ManualImportExportMode.DISABLED, + this::setManualImportExportMode) + .setHoverTooltips("cover.universal.manual_import_export.mode.description")); + + if (coverHolder.getLevel().getBlockEntity(coverHolder.getPos()) instanceof ItemPipeBlockEntity || + coverHolder.getLevel().getBlockEntity(coverHolder.getPos().relative(attachedSide)) instanceof ItemPipeBlockEntity) { + group.addWidget(new EnumSelectorWidget<>(149, 166, 20, 20, + DistributionMode.VALUES, DistributionMode.INSERT_FIRST, + this::setDistributionMode)); + } group.addWidget(filterHandler.createFilterSlotUI(148, 107)); group.addWidget(filterHandler.createFilterConfigUI(10, 70, 156, 60)); diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java b/common/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java index 5660a51ad1..bbc8fb9fc9 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java @@ -5,10 +5,16 @@ import com.gregtechceu.gtceu.api.cover.CoverDefinition; import com.gregtechceu.gtceu.api.cover.IUICover; import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.common.cover.data.ItemFilterMode; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.side.item.ItemTransferHelper; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import lombok.Getter; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; @@ -23,7 +29,11 @@ @MethodsReturnNonnullByDefault public class ItemFilterCover extends CoverBehavior implements IUICover { + public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(ItemFilterCover.class, CoverBehavior.MANAGED_FIELD_HOLDER); + protected ItemFilter itemFilter; + @Persisted @DescSynced @Getter + protected ItemFilterMode filterMode = ItemFilterMode.FILTER_INSERT; public ItemFilterCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { super(definition, coverHolder, attachedSide); @@ -36,6 +46,11 @@ public ItemFilter getItemFilter() { return itemFilter; } + public void setFilterMode(ItemFilterMode filterMode) { + this.filterMode = filterMode; + coverHolder.markDirty(); + } + @Override public boolean canAttach() { return ItemTransferHelper.getItemTransfer(coverHolder.getLevel(), coverHolder.getPos(), attachedSide) != null; @@ -45,7 +60,15 @@ public boolean canAttach() { public Widget createUIWidget() { final var group = new WidgetGroup(0, 0, 176, 80); group.addWidget(new LabelWidget(5, 3, attachItem.getDescriptionId())); + group.addWidget(new EnumSelectorWidget<>(10, 20, 110, 20, + ItemFilterMode.VALUES, ItemFilterMode.FILTER_INSERT, + this::setFilterMode)); group.addWidget(getItemFilter().openConfigurator((176 - 80) / 2, (60 - 55) / 2 + 15)); return group; } + + @Override + public ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } } diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/DistributionMode.java b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/DistributionMode.java new file mode 100644 index 0000000000..d5f0beaf3f --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/DistributionMode.java @@ -0,0 +1,30 @@ +package com.gregtechceu.gtceu.common.cover.data; + +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; + +public enum DistributionMode implements EnumSelectorWidget.SelectableEnum { + ROUND_ROBIN_GLOBAL("cover.conveyor.distribution.round_robin_enhanced"), + ROUND_ROBIN_PRIO("cover.conveyor.distribution.round_robin"), + INSERT_FIRST("cover.conveyor.distribution.first_insert"); + + public static final DistributionMode[] VALUES = values(); + private static final float OFFSET = 1.0f / VALUES.length; + + public final String localeName; + + DistributionMode(String localeName) { + this.localeName = localeName; + } + + @Override + public String getTooltip() { + return localeName; + } + + @Override + public IGuiTexture getIcon() { + return GuiTextures.DISTRIBUTION_MODE.getSubTexture(0, this.ordinal() * OFFSET, 1, OFFSET); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ItemFilterMode.java b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ItemFilterMode.java new file mode 100644 index 0000000000..0c3a7c6df0 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ItemFilterMode.java @@ -0,0 +1,32 @@ +package com.gregtechceu.gtceu.common.cover.data; + +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.texture.TextTexture; + +public enum ItemFilterMode implements EnumSelectorWidget.SelectableEnum { + + FILTER_INSERT("cover.filter.mode.filter_insert"), + FILTER_EXTRACT("cover.filter.mode.filter_extract"), + FILTER_BOTH("cover.filter.mode.filter_both"); + + public static final ItemFilterMode[] VALUES = values(); + private static final float OFFSET = 1.0f / VALUES.length; + + public final String localeName; + + ItemFilterMode(String localeName) { + this.localeName = localeName; + } + + @Override + public String getTooltip() { + return this.localeName; + } + + @Override + public IGuiTexture getIcon() { + return new TextTexture(this.localeName); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ManualImportExportMode.java b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ManualImportExportMode.java new file mode 100644 index 0000000000..91f65cccd2 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/cover/data/ManualImportExportMode.java @@ -0,0 +1,30 @@ +package com.gregtechceu.gtceu.common.cover.data; + +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.texture.TextTexture; + +public enum ManualImportExportMode implements EnumSelectorWidget.SelectableEnum { + DISABLED("cover.universal.manual_import_export.mode.disabled"), + FILTERED("cover.universal.manual_import_export.mode.filtered"), + UNFILTERED("cover.universal.manual_import_export.mode.unfiltered"); + + public static final ManualImportExportMode[] VALUES = values(); + + public final String localeName; + + ManualImportExportMode(String localeName) { + this.localeName = localeName; + } + + @Override + public String getTooltip() { + return localeName; + } + + @Override + public IGuiTexture getIcon() { + return new TextTexture(localeName); + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java index 09efac43fe..e3635a6499 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlockEntities.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.common.blockentity.CableBlockEntity; import com.gregtechceu.gtceu.common.blockentity.FluidPipeBlockEntity; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; import com.tterrag.registrate.util.entry.BlockEntityEntry; import com.tterrag.registrate.util.entry.BlockEntry; @@ -27,6 +28,13 @@ public class GTBlockEntities { .validBlocks(GTBlocks.FLUID_PIPE_BLOCKS.values().toArray(BlockEntry[]::new)) .register(); + @SuppressWarnings("unchecked") + public static final BlockEntityEntry ITEM_PIPE = REGISTRATE + .blockEntity("item_pipe", ItemPipeBlockEntity::create) + .onRegister(ItemPipeBlockEntity::onBlockEntityRegister) + .validBlocks(GTBlocks.ITEM_PIPE_BLOCKS.values().toArray(BlockEntry[]::new)) + .register(); + public static void init() { } diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java index 6fb5ca5f5d..3b93012abb 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTBlocks.java @@ -18,6 +18,8 @@ import com.gregtechceu.gtceu.api.item.MaterialPipeBlockItem; import com.gregtechceu.gtceu.api.item.RendererBlockItem; import com.gregtechceu.gtceu.api.item.tool.GTToolType; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistancePipeBlock; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistancePipeType; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.data.tag.TagUtil; import com.gregtechceu.gtceu.api.registry.registrate.CompassNode; @@ -28,6 +30,9 @@ import com.gregtechceu.gtceu.common.block.*; import com.gregtechceu.gtceu.common.pipelike.cable.Insulation; import com.gregtechceu.gtceu.common.pipelike.fluidpipe.FluidPipeType; +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance.LDFluidPipeType; +import com.gregtechceu.gtceu.common.pipelike.item.ItemPipeType; +import com.gregtechceu.gtceu.common.pipelike.item.longdistance.LDItemPipeType; import com.gregtechceu.gtceu.data.recipe.CustomTags; import com.gregtechceu.gtceu.utils.FormattingUtil; import com.lowdragmc.lowdraglib.Platform; @@ -119,9 +124,9 @@ public static void generateMaterialBlocks() { // Frame Block if (material.hasProperty(PropertyKey.DUST) && material.hasFlag(GENERATE_FRAME)) { - var entry = REGISTRATE.block("%s_frame".formatted(material.getName()), properties -> new MaterialBlock(properties.noLootTable(), TagPrefix.frameGt, material)) + var entry = REGISTRATE.block("%s_frame".formatted(material.getName()), properties -> new MaterialBlock(properties, TagPrefix.frameGt, material)) .initialProperties(() -> Blocks.IRON_BLOCK) - .properties(BlockBehaviour.Properties::noOcclusion) + .properties(properties -> properties.noOcclusion().noLootTable()) .transform(unificationBlock(TagPrefix.frameGt, material)) .addLayer(() -> RenderType::cutoutMipped) .blockstate(NonNullBiConsumer.noop()) @@ -175,10 +180,9 @@ public static void generateMaterialBlocks() { return oreType.stoneType().get().getBlock(); }) .properties(properties -> { - properties.noLootTable(); if (oreType.color() != null) properties.mapColor(oreType.color()); if (oreType.sound() != null) properties.sound(oreType.sound()); - return properties; + return properties.noLootTable(); }) .transform(unificationBlock(oreTag, material)) .addLayer(() -> RenderType::cutoutMipped) @@ -212,9 +216,9 @@ public static void generateCableBlocks() { for (Insulation insulation : Insulation.values()) { for (Material material : GTRegistries.MATERIALS) { if (material.hasProperty(PropertyKey.WIRE) && !insulation.tagPrefix.isIgnored(material)) { - var entry = REGISTRATE.block("%s_%s".formatted(material.getName(), insulation.name), p -> new CableBlock(p.noLootTable(), insulation, material)) + var entry = REGISTRATE.block("%s_%s".formatted(material.getName(), insulation.name), p -> new CableBlock(p, insulation, material)) .initialProperties(() -> Blocks.IRON_BLOCK) - .properties(p -> p.dynamicShape().noOcclusion()) + .properties(p -> p.dynamicShape().noOcclusion().noLootTable()) .transform(unificationBlock(insulation.tagPrefix, material)) .blockstate(NonNullBiConsumer.noop()) .setData(ProviderType.LANG, NonNullBiConsumer.noop()) @@ -234,20 +238,21 @@ public static void generateCableBlocks() { } public static Table> FLUID_PIPE_BLOCKS; + public static Table> ITEM_PIPE_BLOCKS; public static void generatePipeBlocks() { // Fluid Pipe Blocks - ImmutableTable.Builder> builder = ImmutableTable.builder(); + ImmutableTable.Builder> fluidsBuilder = ImmutableTable.builder(); for (var fluidPipeType : FluidPipeType.values()) { for (Material material : GTRegistries.MATERIALS) { if (material.hasProperty(PropertyKey.FLUID_PIPE) && !fluidPipeType.tagPrefix.isIgnored(material)) { - var entry = REGISTRATE.block( "%s_%s_fluid_pipe".formatted(material.getName(), fluidPipeType.name), p -> new FluidPipeBlock(p.noLootTable(), fluidPipeType, material)) + var entry = REGISTRATE.block("%s_%s_fluid_pipe".formatted(material.getName(), fluidPipeType.name), p -> new FluidPipeBlock(p, fluidPipeType, material)) .initialProperties(() -> Blocks.IRON_BLOCK) .properties(p -> { if (doMetalPipe(material)) { p.sound(GTSoundTypes.METAL_PIPE); } - return p.dynamicShape().noOcclusion(); + return p.dynamicShape().noOcclusion().noLootTable(); }) .transform(unificationBlock(fluidPipeType.tagPrefix, material)) .blockstate(NonNullBiConsumer.noop()) @@ -260,23 +265,54 @@ public static void generatePipeBlocks() { .color(() -> MaterialPipeBlockItem::tintColor) .build() .register(); - builder.put(fluidPipeType.tagPrefix, material, entry); + fluidsBuilder.put(fluidPipeType.tagPrefix, material, entry); } } } - FLUID_PIPE_BLOCKS = builder.build(); - } + FLUID_PIPE_BLOCKS = fluidsBuilder.build(); - @SuppressWarnings("unchecked") - private static TagKey[] getPipeTags(Material material) { - TagKey[] tags = new TagKey[2]; - tags[0] = GTToolType.WRENCH.harvestTag; - if (material.hasProperty(PropertyKey.WOOD)) { - tags[1] = BlockTags.MINEABLE_WITH_AXE; - } else tags[1] = BlockTags.MINEABLE_WITH_PICKAXE; - return tags; + ImmutableTable.Builder> itemsBuilder = ImmutableTable.builder(); + for (var itemPipeType : ItemPipeType.values()) { + for (Material material : GTRegistries.MATERIALS) { + if (material.hasProperty(PropertyKey.ITEM_PIPE) && !itemPipeType.getTagPrefix().isIgnored(material)) { + var entry = REGISTRATE.block("%s_%s_item_pipe".formatted(material.getName(), itemPipeType.name), p -> new ItemPipeBlock(p, itemPipeType, material)) + .initialProperties(() -> Blocks.IRON_BLOCK) + .properties(p -> { + if (doMetalPipe(material)) { + p.sound(GTSoundTypes.METAL_PIPE); + } + return p.dynamicShape().noOcclusion().noLootTable(); + }) + .transform(unificationBlock(itemPipeType.getTagPrefix(), material)) + .blockstate(NonNullBiConsumer.noop()) + .setData(ProviderType.LANG, NonNullBiConsumer.noop()) + .setData(ProviderType.LOOT, NonNullBiConsumer.noop()) + .addLayer(() -> RenderType::cutoutMipped) + .color(() -> MaterialPipeBlock::tintedColor) + .item(MaterialPipeBlockItem::new) + .model(NonNullBiConsumer.noop()) + .color(() -> MaterialPipeBlockItem::tintColor) + .build() + .register(); + itemsBuilder.put(itemPipeType.getTagPrefix(), material, entry); + } + } + } + ITEM_PIPE_BLOCKS = itemsBuilder.build(); } + public static final BlockEntry LD_ITEM_PIPE = REGISTRATE.block("long_distance_item_pipeline", properties -> new LongDistancePipeBlock(properties, LDItemPipeType.INSTANCE)) + .initialProperties(() -> Blocks.IRON_BLOCK) + .blockstate(GTModels::longDistanceItemPipeModel) + .simpleItem() + .register(); + + public static final BlockEntry LD_FLUID_PIPE = REGISTRATE.block("long_distance_fluid_pipeline", properties -> new LongDistancePipeBlock(properties, LDFluidPipeType.INSTANCE)) + .initialProperties(() -> Blocks.IRON_BLOCK) + .blockstate(GTModels::longDistanceFluidPipeModel) + .simpleItem() + .register(); + static { REGISTRATE.creativeModeTab(() -> GTCreativeModeTabs.DECORATION); } diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java index 18fe01bd40..48193b14f8 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMachines.java @@ -49,6 +49,8 @@ import com.gregtechceu.gtceu.common.machine.steam.SteamMinerMachine; import com.gregtechceu.gtceu.common.machine.steam.SteamSolidBoilerMachine; import com.gregtechceu.gtceu.common.machine.storage.*; +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance.LDFluidEndpointMachine; +import com.gregtechceu.gtceu.common.pipelike.item.longdistance.LDItemEndpointMachine; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.lang.LangHandler; import com.gregtechceu.gtceu.integration.kjs.GTRegistryObjectBuilderTypes; @@ -229,6 +231,38 @@ public class GTMachines { public static final MachineDefinition[] ENERGY_CONVERTER_8A = registerConverter(8); public static final MachineDefinition[] ENERGY_CONVERTER_16A = registerConverter(16); + public static final MachineDefinition LONG_DIST_ITEM_ENDPOINT = REGISTRATE.machine("long_distance_item_pipeline_endpoint", LDItemEndpointMachine::new) + .langValue("Long Distance Item Pipeline Endpoint") + .rotationState(RotationState.ALL) + .tier(LV) + .renderer(() -> new TieredHullMachineRenderer(LV, GTCEu.id("block/machine/ld_item_endpoint_machine"))) + .tooltips(Component.translatable("gtceu.machine.endpoint.tooltip.1"), + Component.translatable("gtceu.machine.endpoint.tooltip.2"), + Component.translatable("gtceu.machine.endpoint.tooltip.3")) + .tooltipBuilder((stack, tooltip) -> { + if (ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance > 0) { + tooltip.add(Component.translatable("gtceu.machine.endpoint.tooltip.min_length", ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance)); + } + }) + .compassNode("ld_item_pipeline") + .register(); + + public static final MachineDefinition LONG_DIST_FLUID_ENDPOINT = REGISTRATE.machine("long_distance_fluid_pipeline_endpoint", LDFluidEndpointMachine::new) + .langValue("Long Distance Fluid Pipeline Endpoint") + .rotationState(RotationState.ALL) + .tier(LV) + .renderer(() -> new TieredHullMachineRenderer(LV, GTCEu.id("block/machine/ld_fluid_endpoint_machine"))) + .tooltips(Component.translatable("gtceu.machine.endpoint.tooltip.1"), + Component.translatable("gtceu.machine.endpoint.tooltip.2"), + Component.translatable("gtceu.machine.endpoint.tooltip.3")) + .tooltipBuilder((stack, tooltip) -> { + if (ConfigHolder.INSTANCE.machines.ldFluidPipeMinDistance > 0) { + tooltip.add(Component.translatable("gtceu.machine.endpoint.tooltip.min_length", ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance)); + } + }) + .compassNode("ld_fluid_pipeline") + .register(); + public final static MachineDefinition[] BATTERY_BUFFER_4 = registerBatteryBuffer(4); public final static MachineDefinition[] BATTERY_BUFFER_8 = registerBatteryBuffer(8); diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java index 1109a16f4e..424249acb0 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTMaterials.java @@ -229,11 +229,11 @@ public static void init() { pipeHugeFluid.setIgnored(TreatedWood); pipeQuadrupleFluid.setIgnored(TreatedWood); pipeNonupleFluid.setIgnored(TreatedWood); - // TODO Item pipes - //pipeSmallRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); - //pipeNormalRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); - //pipeLargeRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); - //pipeHugeRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); + + pipeSmallRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); + pipeNormalRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); + pipeLargeRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); + pipeHugeRestrictive.addSecondaryMaterial(new MaterialStack(Iron, ring.materialAmount() * 2)); cableGtSingle.addSecondaryMaterial(new MaterialStack(Rubber, plate.materialAmount())); cableGtDouble.addSecondaryMaterial(new MaterialStack(Rubber, plate.materialAmount())); diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTModels.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTModels.java index d5695e40c5..6269aa0fa1 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/GTModels.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/GTModels.java @@ -45,4 +45,14 @@ public static void createTextureModel(DataGenContext ctx, public static void rubberTreeSaplingModel(DataGenContext context, RegistrateItemModelProvider provider) { throw new AssertionError(); } + + @ExpectPlatform + public static void longDistanceItemPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + throw new AssertionError(); + } + + @ExpectPlatform + public static void longDistanceFluidPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + throw new AssertionError(); + } } diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java b/common/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java index 5e93b1e7e9..56fbe61511 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/data/materials/OrganicChemistryMaterials.java @@ -154,7 +154,7 @@ public static void register() { Methane = new Material.Builder("methane") .fluid(FluidStorageKeys.GAS, new FluidBuilder() - .translation("gregtech.fluid.gas_generic")) + .translation("gtceu.fluid.gas_generic")) .color(0xFF0078).iconSet(FLUID) .components(Carbon, 1, Hydrogen, 4) .buildAndRegister(); diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/machine/storage/LongDistanceEndpointMachine.java b/common/src/main/java/com/gregtechceu/gtceu/common/machine/storage/LongDistanceEndpointMachine.java new file mode 100644 index 0000000000..c5a73e3eab --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/machine/storage/LongDistanceEndpointMachine.java @@ -0,0 +1,156 @@ +package com.gregtechceu.gtceu.common.machine.storage; + +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.pipenet.longdistance.ILDEndpoint; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistanceNetwork; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistancePipeType; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import lombok.Getter; +import lombok.Setter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.Block; + +import java.util.ArrayList; +import java.util.List; + +public abstract class LongDistanceEndpointMachine extends MetaMachine implements ILDEndpoint { + protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(LongDistanceEndpointMachine.class, MetaMachine.MANAGED_FIELD_HOLDER); + + private final LongDistancePipeType pipeType; + @Persisted @Getter @Setter + private Type type = Type.NONE; + private ILDEndpoint link; + private boolean placed = false; + + public LongDistanceEndpointMachine(IMachineBlockEntity holder, LongDistancePipeType pipeType) { + super(holder); + this.pipeType = pipeType; + } + + public void updateNetwork() { + LongDistanceNetwork network = LongDistanceNetwork.get(getLevel(), getPos()); + if (network != null) { + // manually remove this endpoint from the network + network.onRemoveEndpoint(this); + } + + // find networks on input and output face + List networks = findNetworks(); + if (networks.isEmpty()) { + // no neighbours found, create new network + network = this.pipeType.createNetwork(getLevel()); + network.onPlaceEndpoint(this); + setType(Type.NONE); + } else if (networks.size() == 1) { + // one neighbour network found, attach self to neighbour network + networks.get(0).onPlaceEndpoint(this); + } else { + // two neighbour networks found, configuration invalid + setType(Type.NONE); + } + } + + @Override + public void setFrontFacing(Direction frontFacing) { + this.placed = true; + super.setFrontFacing(frontFacing); + if (getLevel() != null && !getLevel().isClientSide) { + updateNetwork(); + } + } + + @Override + public void onUnload() { + super.onUnload(); + if (this.getLevel().isClientSide) return; + if (link != null) { + // invalidate linked endpoint + link.invalidateLink(); + invalidateLink(); + } + setType(Type.NONE); + LongDistanceNetwork network = LongDistanceNetwork.get(getLevel(), getPos()); + // remove endpoint from network + if (network != null) network.onRemoveEndpoint(this); + } + + @Override + public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { + if (!placed || getLevel() == null || getLevel().isClientSide) return; + + List networks = findNetworks(); + LongDistanceNetwork network = LongDistanceNetwork.get(getLevel(), getPos()); + if (network == null) { + // shouldn't happen + if (networks.isEmpty()) { + // create new network since there are no neighbouring networks + network = this.pipeType.createNetwork(getLevel()); + network.onPlaceEndpoint(this); + } else if (networks.size() == 1) { + // add to neighbour network + networks.get(0).onPlaceEndpoint(this); + } + } else { + if (networks.size() > 1) { + // suddenly there are more than one neighbouring networks, invalidate + onUnload(); + } + } + if (networks.size() != 1) { + setType(Type.NONE); + } + } + + private List findNetworks() { + List networks = new ArrayList<>(); + LongDistanceNetwork network; + // only check input and output side + network = LongDistanceNetwork.get(getLevel(), getPos().relative(getFrontFacing())); + if (network != null && pipeType == network.getPipeType()) { + // found a network on the input face, therefore this is an output of the network + networks.add(network); + setType(Type.OUTPUT); + } + network = LongDistanceNetwork.get(getLevel(), getPos().relative(getOutputFacing())); + if (network != null && pipeType == network.getPipeType()) { + // found a network on the output face, therefore this is an input of the network + networks.add(network); + setType(Type.INPUT); + } + return networks; + } + + @Override + public ILDEndpoint getLink() { + if (link == null) { + LongDistanceNetwork network = LongDistanceNetwork.get(getLevel(), getPos()); + if (network != null && network.isValid()) { + this.link = network.getOtherEndpoint(this); + } + } + return this.link; + } + + @Override + public void invalidateLink() { + this.link = null; + } + + @Override + public Direction getOutputFacing() { + return getFrontFacing().getOpposite(); + } + + @Override + public LongDistancePipeType getPipeType() { + return pipeType; + } + + @Override + public ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNetWalker.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNetWalker.java index 1514b650e0..5083010aeb 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNetWalker.java +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/FluidPipeNetWalker.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.common.pipelike.fluidpipe; +import com.gregtechceu.gtceu.GTCEu; import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.pipelike.Node; import com.lowdragmc.lowdraglib.pipelike.PipeNetWalker; @@ -21,7 +22,7 @@ public static List createNetData(FluidPipeNet pipeNet, BlockPo walker.traversePipeNet(); return walker.routes; } catch (Exception e){ - LDLib.LOGGER.error("error while create net data for FluidPipeNet", e); + GTCEu.LOGGER.error("error while create net data for FluidPipeNet", e); } return null; } diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidEndpointMachine.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidEndpointMachine.java new file mode 100644 index 0000000000..0e860e040c --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidEndpointMachine.java @@ -0,0 +1,81 @@ +package com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance; + +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.common.machine.storage.LongDistanceEndpointMachine; +import com.lowdragmc.lowdraglib.side.fluid.FluidStack; +import com.lowdragmc.lowdraglib.side.fluid.IFluidTransfer; +import org.jetbrains.annotations.NotNull; + +public class LDFluidEndpointMachine extends LongDistanceEndpointMachine { + + public LDFluidEndpointMachine(IMachineBlockEntity holder) { + super(holder, LDFluidPipeType.INSTANCE); + } + + public static class FluidHandlerWrapper implements IFluidTransfer { + + private final IFluidTransfer delegate; + + public FluidHandlerWrapper(IFluidTransfer delegate) { + this.delegate = delegate; + } + + @Override + public int getTanks() { + return delegate.getTanks(); + } + + @NotNull + @Override + public FluidStack getFluidInTank(int tank) { + return delegate.getFluidInTank(tank); + } + + @Override + public void setFluidInTank(int tank, @NotNull FluidStack fluidStack) { + delegate.setFluidInTank(tank, fluidStack); + } + + @Override + public long getTankCapacity(int tank) { + return delegate.getTankCapacity(tank); + } + + @Override + public boolean isFluidValid(int tank, @NotNull FluidStack stack) { + return delegate.isFluidValid(tank, stack); + } + + @Override + public long fill(int tank, FluidStack resource, boolean simulate, boolean notifyChanges) { + return delegate.fill(resource, simulate, notifyChanges); + } + + @Override + public boolean supportsFill(int tank) { + return delegate.supportsFill(tank); + } + + @NotNull + @Override + public FluidStack drain(int tank, FluidStack resource, boolean simulate, boolean notifyChanges) { + return FluidStack.empty(); + } + + @Override + public boolean supportsDrain(int tank) { + return false; + } + + @NotNull + @Override + public Object createSnapshot() { + return delegate.createSnapshot(); + } + + @Override + public void restoreFromSnapshot(Object snapshot) { + delegate.restoreFromSnapshot(snapshot); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidPipeType.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidPipeType.java new file mode 100644 index 0000000000..00814c4ad1 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/fluidpipe/longdistance/LDFluidPipeType.java @@ -0,0 +1,31 @@ +package com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance; + +import com.gregtechceu.gtceu.api.pipenet.longdistance.ILDEndpoint; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistancePipeType; +import com.gregtechceu.gtceu.common.data.GTBlocks; +import com.gregtechceu.gtceu.config.ConfigHolder; +import net.minecraft.world.level.block.state.BlockState; + +public class LDFluidPipeType extends LongDistancePipeType { + + public static final LDFluidPipeType INSTANCE = new LDFluidPipeType(); + + private LDFluidPipeType() { + super("fluid"); + } + + @Override + public boolean isValidBlock(BlockState blockState) { + return GTBlocks.LD_FLUID_PIPE.is(blockState.getBlock()); + } + + @Override + public boolean isValidEndpoint(ILDEndpoint endpoint) { + return endpoint instanceof LDFluidEndpointMachine; + } + + @Override + public int getMinLength() { + return ConfigHolder.INSTANCE.machines.ldFluidPipeMinDistance; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java new file mode 100644 index 0000000000..1f596f31f3 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java @@ -0,0 +1,487 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.gregtechceu.gtceu.common.cover.ConveyorCover; +import com.gregtechceu.gtceu.common.cover.ItemFilterCover; +import com.gregtechceu.gtceu.common.cover.RobotArmCover; +import com.gregtechceu.gtceu.common.cover.data.DistributionMode; +import com.gregtechceu.gtceu.common.cover.data.ItemFilterMode; +import com.gregtechceu.gtceu.utils.FacingPos; +import com.gregtechceu.gtceu.utils.GTTransferUtils; +import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; +import com.lowdragmc.lowdraglib.misc.ItemStackTransfer; +import com.lowdragmc.lowdraglib.side.item.IItemTransfer; +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nonnull; +import java.util.*; + +public class ItemNetHandler implements IItemTransfer { + + @Getter + private ItemPipeNet net; + private ItemPipeBlockEntity pipe; + private final Level world; + private final Direction facing; + private final Map simulatedTransfersGlobalRoundRobin = new HashMap<>(); + private int simulatedTransfers = 0; + private final ItemStackTransfer testHandler = new ItemStackTransfer(1); + + public ItemNetHandler(ItemPipeNet net, ItemPipeBlockEntity pipe, Direction facing) { + this.net = net; + this.pipe = pipe; + this.facing = facing; + this.world = pipe.getPipeLevel(); + } + + public void updateNetwork(ItemPipeNet net) { + this.net = net; + } + + private void copyTransferred() { + simulatedTransfers = pipe.getTransferredItems(); + simulatedTransfersGlobalRoundRobin.clear(); + simulatedTransfersGlobalRoundRobin.putAll(pipe.getTransferred()); + } + + @Nonnull + @Override + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate, boolean notifyChanges) { + if (stack.isEmpty()) return stack; + + if (net == null || pipe == null || pipe.isInValid() || pipe.isBlocked(facing)) { + return stack; + } + + copyTransferred(); + CoverBehavior pipeCover = getCoverOnPipe(pipe.getPipePos(), facing); + CoverBehavior tileCover = getCoverOnNeighbour(pipe.getPipePos(), facing); + + boolean pipeConveyor = pipeCover instanceof ConveyorCover, tileConveyor = tileCover instanceof ConveyorCover; + // abort if there are two conveyors + if (pipeConveyor && tileConveyor) return stack; + + if (tileCover != null && !checkImportCover(tileCover, false, stack)) + return stack; + + if (!pipeConveyor && !tileConveyor) + return insertFirst(stack, simulate); + + ConveyorCover conveyor = (ConveyorCover) (pipeConveyor ? pipeCover : tileCover); + + if (conveyor.getIo() == (pipeConveyor ? IO.IN : IO.OUT)) { + boolean roundRobinGlobal = conveyor.getDistributionMode() == DistributionMode.ROUND_ROBIN_GLOBAL; + if (roundRobinGlobal || conveyor.getDistributionMode() == DistributionMode.ROUND_ROBIN_PRIO) + return insertRoundRobin(stack, simulate, roundRobinGlobal); + } + + return insertFirst(stack, simulate); + } + + public static boolean checkImportCover(CoverBehavior cover, boolean onPipe, ItemStack stack) { + if (cover == null) return true; + if (cover instanceof ItemFilterCover filter) { + return (filter.getFilterMode() != ItemFilterMode.FILTER_BOTH && + (filter.getFilterMode() != ItemFilterMode.FILTER_INSERT || !onPipe) && + (filter.getFilterMode() != ItemFilterMode.FILTER_EXTRACT || onPipe)) || filter.getItemFilter().test(stack); + } + return true; + } + + public ItemStack insertFirst(ItemStack stack, boolean simulate) { + for (ItemPipeNet.Inventory inv : net.getNetData(pipe.getPipePos())) { + stack = insert(inv, stack, simulate); + if (stack.isEmpty()) + return ItemStack.EMPTY; + } + return stack; + } + + public ItemStack insertRoundRobin(ItemStack stack, boolean simulate, boolean global) { + List handlers = net.getNetData(pipe.getPipePos()); + if (handlers.size() == 0) + return stack; + if (handlers.size() == 1) + return insert(handlers.get(0), stack, simulate); + List handlersCopy = new ArrayList<>(handlers); + int original = stack.getCount(); + + if (global) { + stack = insertToHandlersEnhanced(handlersCopy, stack, handlers.size(), simulate); + } else { + stack = insertToHandlers(handlersCopy, stack, simulate); + if (!stack.isEmpty() && handlersCopy.size() > 0) + stack = insertToHandlers(handlersCopy, stack, simulate); + } + + return stack; + } + + /** + * Inserts items equally to all handlers + * if it couldn't insert all items, the handler will be removed + * + * @param copy to insert to + * @param stack to insert + * @param simulate simulate + * @return remainder + */ + private ItemStack insertToHandlers(List copy, ItemStack stack, boolean simulate) { + Iterator handlerIterator = copy.listIterator(); + int inserted = 0; + int count = stack.getCount(); + int c = count / copy.size(); + int m = c == 0 ? count % copy.size() : 0; + while (handlerIterator.hasNext()) { + ItemPipeNet.Inventory handler = handlerIterator.next(); + + int amount = c; + if (m > 0) { + amount++; + m--; + } + amount = Math.min(amount, stack.getCount() - inserted); + if (amount == 0) break; + ItemStack toInsert = stack.copy(); + toInsert.setCount(amount); + int r = insert(handler, toInsert, simulate).getCount(); + if (r < amount) { + inserted += (amount - r); + } + if (r == 1 && c == 0 && amount == 1) { + m++; + } + + if (r > 0) + handlerIterator.remove(); + } + + ItemStack remainder = stack.copy(); + remainder.setCount(count - inserted); + return remainder; + } + + private ItemStack insertToHandlersEnhanced(List copy, ItemStack stack, int dest, boolean simulate) { + LinkedList transferred = new LinkedList<>(); + LinkedList steps = new LinkedList<>(); + int min = Integer.MAX_VALUE; + ItemStack simStack; + + // find inventories that are not full and get the amount that was inserted in total + for (ItemPipeNet.Inventory inv : copy) { + simStack = stack.copy(); + int ins = stack.getCount() - insert(inv, simStack, true, true).getCount(); + if (ins <= 0) + continue; + int didTransfer = didTransferTo(inv, simulate); + EnhancedRoundRobinData data = new EnhancedRoundRobinData(inv, ins, didTransfer); + transferred.addLast(data); + + min = Math.min(min, didTransfer); + + if (!steps.contains(didTransfer)) { + steps.add(didTransfer); + } + } + + if (transferred.isEmpty() || steps.isEmpty()) + return stack; + + if (!simulate && min < Integer.MAX_VALUE) { + decrementBy(min); + } + + transferred.sort(Comparator.comparingInt(data -> data.transferred)); + steps.sort(Integer::compare); + + if (transferred.get(0).transferred != steps.get(0)) { + return stack; + } + + int amount = stack.getCount(); + int c = amount / transferred.size(); + int m = amount % transferred.size(); + List transferredCopy = new ArrayList<>(transferred); + int nextStep = steps.isEmpty() ? -1 : steps.pollFirst(); + + // equally distribute items over all inventories + // it takes into account how much was inserted in total + // f.e. if inv1 has 2 inserted and inv2 has 6 inserted, it will first try to insert 4 into inv1 so that both have 6 and then it will distribute the rest equally + outer: + while (amount > 0 && !transferredCopy.isEmpty()) { + Iterator iterator = transferredCopy.iterator(); + int i = 0; + while (iterator.hasNext()) { + EnhancedRoundRobinData data = iterator.next(); + if (nextStep >= 0 && data.transferred >= nextStep) + break; + + int toInsert; + if (nextStep <= 0) { + if (amount <= m) { + //break outer; + toInsert = 1; + } else { + toInsert = Math.min(c, amount); + } + } else { + toInsert = Math.min(amount, nextStep - data.transferred); + } + if (data.toTransfer + toInsert >= data.maxInsertable) { + data.toTransfer = data.maxInsertable; + iterator.remove(); + } else { + data.toTransfer += toInsert; + } + + data.transferred += toInsert; + + if ((amount -= toInsert) == 0) { + break outer; + } + i++; + } + + for (EnhancedRoundRobinData data : transferredCopy) { + if (data.transferred < nextStep) + continue outer; + } + if (steps.isEmpty()) { + if (nextStep >= 0) { + c = amount / transferredCopy.size(); + m = amount % transferredCopy.size(); + nextStep = -1; + } + } else { + nextStep = steps.pollFirst(); + } + } + + int inserted = 0; + + // finally actually insert the item + for (EnhancedRoundRobinData data : transferred) { + ItemStack toInsert = stack.copy(); + toInsert.setCount(data.toTransfer); + int ins = data.toTransfer - insert(data.inventory, toInsert, simulate).getCount(); + inserted += ins; + transferTo(data.inventory, simulate, ins); + } + + ItemStack remainder = stack.copy(); + remainder.shrink(inserted); + return remainder; + } + + public ItemStack insert(ItemPipeNet.Inventory handler, ItemStack stack, boolean simulate) { + return insert(handler, stack, simulate, false); + } + + public ItemStack insert(ItemPipeNet.Inventory handler, ItemStack stack, boolean simulate, boolean ignoreLimit) { + int allowed = ignoreLimit ? stack.getCount() : checkTransferable(handler.getProperties().getTransferRate(), stack.getCount(), simulate); + if (allowed == 0 || !handler.matchesFilters(stack)) { + return stack; + } + CoverBehavior pipeCover = getCoverOnPipe(handler.getPipePos(), handler.getFaceToHandler()); + CoverBehavior tileCover = getCoverOnNeighbour(handler.getPipePos(), handler.getFaceToHandler()); + if (pipeCover != null) { + testHandler.setStackInSlot(0, stack.copy()); + /*IItemTransfer itemHandler = pipeCover.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, testHandler); + IItemTransfer itemHandler = ItemTransferHelper.getItemTransfer()*/ + if (/*itemHandler == null || (itemHandler != testHandler && (allowed = itemHandler.extractItem(0, allowed, true).getCount()) <= 0)*/true) { + testHandler.setStackInSlot(0, ItemStack.EMPTY); + return stack; + } + testHandler.setStackInSlot(0, ItemStack.EMPTY); + } + IItemTransfer neighbourHandler = handler.getHandler(world); + if (pipeCover instanceof RobotArmCover && ((RobotArmCover) pipeCover).getIo() == IO.OUT) { + return insertOverRobotArm(neighbourHandler, (RobotArmCover) pipeCover, stack, simulate, allowed, ignoreLimit); + } + if (tileCover instanceof RobotArmCover && ((RobotArmCover) tileCover).getIo() == IO.IN) { + return insertOverRobotArm(neighbourHandler, (RobotArmCover) tileCover, stack, simulate, allowed, ignoreLimit); + } + + return insert(neighbourHandler, stack, simulate, allowed, ignoreLimit); + } + + private ItemStack insert(IItemTransfer handler, ItemStack stack, boolean simulate, int allowed, boolean ignoreLimit) { + if (stack.getCount() == allowed) { + ItemStack re = GTTransferUtils.insertItem(handler, stack, simulate); + if (!ignoreLimit) + transfer(simulate, stack.getCount() - re.getCount()); + return re; + } + ItemStack toInsert = stack.copy(); + toInsert.setCount(Math.min(allowed, stack.getCount())); + int r = GTTransferUtils.insertItem(handler, toInsert, simulate).getCount(); + if (!ignoreLimit) + transfer(simulate, toInsert.getCount() - r); + ItemStack remainder = stack.copy(); + remainder.setCount(r + (stack.getCount() - toInsert.getCount())); + return remainder; + } + + public CoverBehavior getCoverOnPipe(BlockPos pos, Direction handlerFacing) { + BlockEntity tile = pipe.getLevel().getBlockEntity(pos); + if (tile instanceof ItemPipeBlockEntity blockEntity) { + ICoverable coverable = blockEntity.getCoverContainer(); + return coverable.getCoverAtSide(handlerFacing); + } + return null; + } + + public CoverBehavior getCoverOnNeighbour(BlockPos pos, Direction handlerFacing) { + BlockEntity tile = pipe.getLevel().getBlockEntity(pos.relative(handlerFacing)); + if (tile != null) { + ICoverable coverable = GTCapabilityHelper.getCoverable(pipe.getLevel(), pos.relative(handlerFacing), handlerFacing.getOpposite()); + if (coverable == null) return null; + return coverable.getCoverAtSide(handlerFacing.getOpposite()); + } + return null; + } + + public ItemStack insertOverRobotArm(IItemTransfer handler, RobotArmCover arm, ItemStack stack, boolean simulate, int allowed, boolean ignoreLimit) { + int rate; + boolean isStackSpecific = false; + rate = arm.getFilterHandler().getFilter().testItemCount(stack); + int count; + switch (arm.getTransferMode()) { + case TRANSFER_ANY: + return insert(handler, stack, simulate, allowed, ignoreLimit); + case KEEP_EXACT: + count = rate - countStack(handler, stack, arm, isStackSpecific); + if (count <= 0) return stack; + count = Math.min(allowed, Math.min(stack.getCount(), count)); + return insert(handler, stack, simulate, count, ignoreLimit); + case TRANSFER_EXACT: + count = Math.min(allowed, Math.min(rate, stack.getCount())); + if (insert(handler, stack, true, count, ignoreLimit).getCount() != stack.getCount() - count) { + return stack; + } + return insert(handler, stack, simulate, count, ignoreLimit); + } + return stack; + } + + public static int countStack(IItemTransfer handler, ItemStack stack, RobotArmCover arm, boolean isStackSpecific) { + if (arm == null) return 0; + int count = 0; + for (int i = 0; i < handler.getSlots(); i++) { + ItemStack slot = handler.getStackInSlot(i); + if (slot.isEmpty()) continue; + if (isStackSpecific ? ItemStackHashStrategy.comparingAllButCount().equals(stack, slot) : + arm.getFilterHandler().getFilter().test(slot)) { + count += slot.getCount(); + } + } + return count; + } + + private int checkTransferable(float rate, int amount, boolean simulate) { + int max = (int) ((rate * 64) + 0.5); + if (simulate) + return Math.max(0, Math.min(max - simulatedTransfers, amount)); + else + return Math.max(0, Math.min(max - pipe.getTransferredItems(), amount)); + } + + private void transfer(boolean simulate, int amount) { + if (simulate) + simulatedTransfers += amount; + else + pipe.transferItems(amount); + } + + @Override + public int getSlots() { + return 1; + } + + @Nonnull + @Override + public ItemStack getStackInSlot(int i) { + return ItemStack.EMPTY; + } + + @Nonnull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate, boolean notifyChanges) { + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int i) { + return 64; + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + return true; + } + + @NotNull + @Override + public Object createSnapshot() { + return new Object(); + } + + @Override + public void restoreFromSnapshot(Object snapshot) { + + } + + private void transferTo(ItemPipeNet.Inventory handler, boolean simulate, int amount) { + if (simulate) + simulatedTransfersGlobalRoundRobin.merge(handler.toFacingPos(), amount, Integer::sum); + else + pipe.getTransferred().merge(handler.toFacingPos(), amount, Integer::sum); + + } + + private boolean contains(ItemPipeNet.Inventory handler, boolean simulate) { + return simulate ? simulatedTransfersGlobalRoundRobin.containsKey(handler.toFacingPos()) : pipe.getTransferred().containsKey(handler.toFacingPos()); + } + + private int didTransferTo(ItemPipeNet.Inventory handler, boolean simulate) { + if (simulate) + return simulatedTransfersGlobalRoundRobin.getOrDefault(handler.toFacingPos(), 0); + return pipe.getTransferred().getOrDefault(handler.toFacingPos(), 0); + } + + private void resetTransferred(boolean simulated) { + if (simulated) + simulatedTransfersGlobalRoundRobin.clear(); + else + pipe.resetTransferred(); + } + + private void decrementBy(int amount) { + for (Map.Entry entry : pipe.getTransferred().entrySet()) { + entry.setValue(entry.getValue() - amount); + } + } + + private static class EnhancedRoundRobinData { + private final ItemPipeNet.Inventory inventory; + private final int maxInsertable; + private int transferred; + private int toTransfer = 0; + + private EnhancedRoundRobinData(ItemPipeNet.Inventory inventory, int maxInsertable, int transferred) { + this.maxInsertable = maxInsertable; + this.transferred = transferred; + this.inventory = inventory; + } + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java new file mode 100644 index 0000000000..82b4046cd5 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java @@ -0,0 +1,123 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.gregtechceu.gtceu.common.cover.ItemFilterCover; +import com.gregtechceu.gtceu.common.cover.data.ItemFilterMode; +import com.lowdragmc.lowdraglib.LDLib; +import com.lowdragmc.lowdraglib.pipelike.Node; +import com.lowdragmc.lowdraglib.pipelike.PipeNetWalker; +import com.lowdragmc.lowdraglib.side.item.IItemTransfer; +import com.lowdragmc.lowdraglib.side.item.ItemTransferHelper; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +public class ItemNetWalker extends PipeNetWalker { + + public static List createNetData(ItemPipeNet pipeNet, BlockPos sourcePipe) { + try { + ItemNetWalker walker = new ItemNetWalker(pipeNet, sourcePipe, 1, new ArrayList<>(), null); + walker.traversePipeNet(); + return walker.inventories; + } catch (Exception e){ + GTCEu.LOGGER.error("error while create net data for ItemPipeNet", e); + } + return null; + } + + private ItemPipeProperties minProperties; + private final List inventories; + private final List> filters = new ArrayList<>(); + private final List> nextFilters = new ArrayList<>(); + private BlockPos sourcePipe; + private Direction facingToHandler; + + protected ItemNetWalker(ItemPipeNet world, BlockPos sourcePipe, int distance, List inventories, ItemPipeProperties properties) { + super(world, sourcePipe, distance); + this.inventories = inventories; + this.minProperties = properties; + } + + @Override + protected PipeNetWalker createSubWalker(ItemPipeNet world, BlockPos nextPos, int walkedBlocks) { + ItemNetWalker walker = new ItemNetWalker(world, nextPos, walkedBlocks, inventories, minProperties); + walker.facingToHandler = facingToHandler; + walker.sourcePipe = sourcePipe; + walker.filters.addAll(filters); + List> moreFilters = nextFilters; + if (moreFilters != null && !moreFilters.isEmpty()) { + walker.filters.addAll(moreFilters); + } + return walker; + } + + @Override + protected boolean checkPipe(Node pipeNode, BlockPos pos) { + if (!nextFilters.isEmpty()) { + this.filters.addAll(nextFilters); + } + nextFilters.clear(); + ItemPipeProperties pipeProperties = pipeNode.data.properties; + if (minProperties == null) { + minProperties = pipeProperties; + } else { + minProperties = new ItemPipeProperties(minProperties.getPriority() + pipeProperties.getPriority(), Math.min(minProperties.getTransferRate(), pipeProperties.getTransferRate())); + } + return true; + } + + @Override + protected void checkNeighbour(Node pipeNode, BlockPos pipePos, Direction faceToNeighbour) { + if (pipeNode == null || (pipePos.equals(sourcePipe) && faceToNeighbour == facingToHandler)) { + return; + } + if (getLevel().getBlockEntity(pipePos.relative(faceToNeighbour)) instanceof ItemPipeBlockEntity) { + if (!isValidPipe(pipePos, faceToNeighbour)) { + return; + } + } + IItemTransfer handler = ItemTransferHelper.getItemTransfer(this.getLevel(), pipePos, faceToNeighbour.getOpposite()); + if (handler != null) { + List> filters = new ArrayList<>(this.filters); + List> moreFilters = nextFilters; + if (moreFilters != null && !moreFilters.isEmpty()) { + filters.addAll(moreFilters); + } + inventories.add(new ItemPipeNet.Inventory(new BlockPos(pipePos), faceToNeighbour, getWalkedBlocks(), minProperties, filters)); + } + } + + protected boolean isValidPipe(BlockPos pipePos, Direction faceToNeighbour) { + BlockEntity currentPipe = getLevel().getBlockEntity(pipePos); + if (!(getLevel().getBlockEntity(pipePos.relative(faceToNeighbour)) instanceof ItemPipeBlockEntity neighbourPipeBE) || !(currentPipe instanceof ItemPipeBlockEntity currentPipeBE)) { + return false; + } + CoverBehavior thisCover = currentPipeBE.getCoverContainer().getCoverAtSide(faceToNeighbour); + CoverBehavior neighbourCover = neighbourPipeBE.getCoverContainer().getCoverAtSide(faceToNeighbour.getOpposite()); + List> filters = new ArrayList<>(); + /*if (thisCover instanceof CoverShutter) { + filters.add(stack -> !thisCover.isValid() || !((CoverShutter) thisCover).isWorkingEnabled()); + } else*/ + if (thisCover instanceof ItemFilterCover filterCover && filterCover.getFilterMode() != ItemFilterMode.FILTER_INSERT) { + filters.add(filterCover.getItemFilter()::test); + } + /*if (neighbourCover instanceof CoverShutter) { + filters.add(stack -> !neighbourCover.isValid() || !((CoverShutter) neighbourCover).isWorkingEnabled()); + } else */ + if (neighbourCover instanceof ItemFilterCover filterCover && filterCover.getFilterMode() != ItemFilterMode.FILTER_EXTRACT) { + filters.add(filterCover.getItemFilter()::test); + } + if (!filters.isEmpty()) { + nextFilters.addAll(filters); + } + return true; + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeData.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeData.java new file mode 100644 index 0000000000..4b926f063b --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeData.java @@ -0,0 +1,52 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties; +import com.gregtechceu.gtceu.api.pipenet.IAttachData; +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.FluidPipeData; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.experimental.Accessors; +import net.minecraft.core.Direction; + +import java.util.Objects; + +@Accessors(fluent = true) +@AllArgsConstructor +public class ItemPipeData implements IAttachData { + + @Getter + ItemPipeProperties properties; + @Getter + byte connections; + + @Override + public boolean canAttachTo(Direction side) { + return (connections & (1 << side.ordinal())) != 0; + } + + @Override + public boolean setAttached(Direction side, boolean attach) { + var result = canAttachTo(side); + if (result != attach) { + if (attach) { + connections |= (1 << side.ordinal()); + } else { + connections &= ~(1 << side.ordinal()); + } + } + return result != attach; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ItemPipeData cableData) { + return cableData.properties.equals(properties) && connections == cableData.connections; + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return Objects.hash(properties, connections); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java new file mode 100644 index 0000000000..a10ef635be --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java @@ -0,0 +1,125 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.gregtechceu.gtceu.common.cover.ItemFilterCover; +import com.gregtechceu.gtceu.utils.FacingPos; +import com.lowdragmc.lowdraglib.pipelike.LevelPipeNet; +import com.lowdragmc.lowdraglib.pipelike.Node; +import com.lowdragmc.lowdraglib.pipelike.PipeNet; +import com.lowdragmc.lowdraglib.side.item.IItemTransfer; +import com.lowdragmc.lowdraglib.side.item.ItemTransferHelper; +import it.unimi.dsi.fastutil.longs.Long2IntMap; +import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +import java.util.*; +import java.util.function.Predicate; + +public class ItemPipeNet extends PipeNet { + + private final Map> NET_DATA = new HashMap<>(); + + public ItemPipeNet(LevelPipeNet> world) { + super(world); + } + + public List getNetData(BlockPos pipePos) { + List data = NET_DATA.get(pipePos); + if (data == null) { + data = ItemNetWalker.createNetData(this, pipePos); + if (data == null) { + // walker failed, don't cache so it tries again on next insertion + return Collections.emptyList(); + } + data.sort(Comparator.comparingInt(inv -> inv.properties.getPriority())); + NET_DATA.put(pipePos, data); + } + return data; + } + + @Override + public void onNeighbourUpdate(BlockPos fromPos) { + NET_DATA.clear(); + } + + @Override + public void onPipeConnectionsUpdate() { + NET_DATA.clear(); + } + + @Override + protected void transferNodeData(Map> transferredNodes, PipeNet parentNet) { + super.transferNodeData(transferredNodes, parentNet); + NET_DATA.clear(); + ((ItemPipeNet) parentNet).NET_DATA.clear(); + } + + @Override + protected void writeNodeData(ItemPipeData nodeData, CompoundTag tagCompound) { + tagCompound.putInt("Resistance", nodeData.properties.getPriority()); + tagCompound.putFloat("Rate", nodeData.properties.getTransferRate()); + tagCompound.putByte("Connections", nodeData.connections); + } + + @Override + protected ItemPipeData readNodeData(CompoundTag tagCompound) { + return new ItemPipeData(new ItemPipeProperties(tagCompound.getInt("Range"), tagCompound.getFloat("Rate")), tagCompound.getByte("Connections")); + } + + ////////////////////////////////////// + //******* Pipe Status *******// + ////////////////////////////////////// + + public static class Inventory { + @Getter + private final BlockPos pipePos; + @Getter + private final Direction faceToHandler; + @Getter + private final int distance; + @Getter + private final ItemPipeProperties properties; + @Getter + private final List> filters; + + public Inventory(BlockPos pipePos, Direction facing, int distance, ItemPipeProperties properties, List> filters) { + this.pipePos = pipePos; + this.faceToHandler = facing; + this.distance = distance; + this.properties = properties; + this.filters = filters; + } + + public boolean matchesFilters(ItemStack stack) { + for (Predicate filter : filters) { + if (!filter.test(stack)) { + return false; + } + } + return true; + } + + public BlockPos getHandlerPos() { + return pipePos.relative(faceToHandler); + } + + public IItemTransfer getHandler(Level world) { + BlockEntity tile = world.getBlockEntity(getHandlerPos()); + if (tile != null) + return ItemTransferHelper.getItemTransfer(world, getHandlerPos(), faceToHandler.getOpposite()); + return null; + } + + public FacingPos toFacingPos() { + return new FacingPos(this.getPipePos(), this.faceToHandler); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java new file mode 100644 index 0000000000..4c4f1717ba --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeType.java @@ -0,0 +1,85 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.data.chemical.material.Material; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey; +import com.gregtechceu.gtceu.api.data.tag.TagPrefix; +import com.gregtechceu.gtceu.api.pipenet.IMaterialPipeType; +import com.gregtechceu.gtceu.client.model.PipeModel; +import lombok.Getter; +import net.minecraft.resources.ResourceLocation; + +public enum ItemPipeType implements IMaterialPipeType { + SMALL("small", 0.375f, TagPrefix.pipeSmallItem, 0.5f, 1.5f), + NORMAL("normal", 0.5f, TagPrefix.pipeNormalItem, 1f, 1f), + LARGE("large", 0.75f, TagPrefix.pipeLargeItem, 2f, 0.75f), + HUGE("huge", 0.875f, TagPrefix.pipeHugeItem, 4f, 0.5f), + + RESTRICTIVE_SMALL("small_restrictive", 0.375f, TagPrefix.pipeSmallRestrictive, 0.5f, 150f), + RESTRICTIVE_NORMAL("normal_restrictive", 0.5f, TagPrefix.pipeNormalRestrictive, 1f, 100f), + RESTRICTIVE_LARGE("large_restrictive", 0.75f, TagPrefix.pipeLargeRestrictive, 2f, 75f), + RESTRICTIVE_HUGE("huge_restrictive", 0.875f, TagPrefix.pipeHugeRestrictive, 4f, 50f); + + public static final ResourceLocation TYPE_ID = GTCEu.id("item"); + public static final ItemPipeType[] VALUES = values(); + + @Getter + public final String name; + @Getter + private final float thickness; + @Getter + private final float rateMultiplier; + private final float resistanceMultiplier; + @Getter + private final TagPrefix tagPrefix; + + ItemPipeType(String name, float thickness, TagPrefix orePrefix, float rateMultiplier, float resistanceMultiplier) { + this.name = name; + this.thickness = thickness; + this.tagPrefix = orePrefix; + this.rateMultiplier = rateMultiplier; + this.resistanceMultiplier = resistanceMultiplier; + } + + public boolean isRestrictive() { + return ordinal() > 3; + } + + public String getSizeForTexture() { + if (!isRestrictive()) + return name; + else + return name.substring(0, name.length() - 12); + } + + @Override + public ItemPipeData modifyProperties(ItemPipeData baseProperties) { + return new ItemPipeData( + new ItemPipeProperties((int) ((baseProperties.properties.getPriority() * resistanceMultiplier) + 0.5), baseProperties.properties.getTransferRate() * rateMultiplier), + baseProperties.connections); + } + + @Override + public boolean isPaintable() { + return true; + } + + @Override + public ResourceLocation type() { + return TYPE_ID; + } + + public PipeModel createPipeModel(Material material) { + PipeModel model; + if (material.hasProperty(PropertyKey.WOOD)) { + model = new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side_wood"), () -> GTCEu.id("block/pipe/pipe_%s_in_wood".formatted(this.isRestrictive() ? values()[this.ordinal() - 4].name : name))); + } else { + model = new PipeModel(thickness, () -> GTCEu.id("block/pipe/pipe_side"), () -> GTCEu.id("block/pipe/pipe_%s_in".formatted(this.isRestrictive() ? values()[this.ordinal() - 4].name : name))); + } + if (isRestrictive()) { + model.setSideOverlayTexture(GTCEu.id("block/pipe/pipe_restrictive")); + } + return model; + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/LevelItemPipeNet.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/LevelItemPipeNet.java new file mode 100644 index 0000000000..d84c26fb7d --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/LevelItemPipeNet.java @@ -0,0 +1,25 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +import com.lowdragmc.lowdraglib.pipelike.LevelPipeNet; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; + +public class LevelItemPipeNet extends LevelPipeNet { + + public static LevelItemPipeNet getOrCreate(ServerLevel serverLevel) { + return serverLevel.getDataStorage().computeIfAbsent(tag -> new LevelItemPipeNet(serverLevel, tag), () -> new LevelItemPipeNet(serverLevel), "gtceu_item_pipe_net"); + } + + public LevelItemPipeNet(ServerLevel serverLevel) { + super(serverLevel); + } + + public LevelItemPipeNet(ServerLevel serverLevel, CompoundTag tag) { + super(serverLevel, tag); + } + + @Override + protected ItemPipeNet createNetInstance() { + return new ItemPipeNet(this); + } +} diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemEndpointMachine.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemEndpointMachine.java new file mode 100644 index 0000000000..6367486513 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemEndpointMachine.java @@ -0,0 +1,68 @@ +package com.gregtechceu.gtceu.common.pipelike.item.longdistance; + +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.common.machine.storage.LongDistanceEndpointMachine; +import com.lowdragmc.lowdraglib.side.item.IItemTransfer; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class LDItemEndpointMachine extends LongDistanceEndpointMachine { + + public LDItemEndpointMachine(IMachineBlockEntity metaTileEntityId) { + super(metaTileEntityId, LDItemPipeType.INSTANCE); + } + + @SuppressWarnings("UnstableApiUsage") + public static class ItemHandlerWrapper implements IItemTransfer { + + private final IItemTransfer delegate; + + public ItemHandlerWrapper(IItemTransfer delegate) { + this.delegate = delegate; + } + + @Override + public int getSlots() { + return delegate.getSlots(); + } + + @NotNull + @Override + public ItemStack getStackInSlot(int slot) { + return delegate.getStackInSlot(slot); + } + + @NotNull + @Override + public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate, boolean notifyChanges) { + return delegate.insertItem(slot, stack, simulate, notifyChanges); + } + + @NotNull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate, boolean notifyChanges) { + return ItemStack.EMPTY; + } + + @Override + public int getSlotLimit(int slot) { + return delegate.getSlotLimit(slot); + } + + @Override + public boolean isItemValid(int slot, @NotNull ItemStack stack) { + return delegate.isItemValid(slot, stack); + } + + @NotNull + @Override + public Object createSnapshot() { + return delegate.createSnapshot(); + } + + @Override + public void restoreFromSnapshot(Object snapshot) { + delegate.restoreFromSnapshot(snapshot); + } + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemPipeType.java b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemPipeType.java new file mode 100644 index 0000000000..25e4059475 --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/longdistance/LDItemPipeType.java @@ -0,0 +1,31 @@ +package com.gregtechceu.gtceu.common.pipelike.item.longdistance; + +import com.gregtechceu.gtceu.api.pipenet.longdistance.ILDEndpoint; +import com.gregtechceu.gtceu.api.pipenet.longdistance.LongDistancePipeType; +import com.gregtechceu.gtceu.common.data.GTBlocks; +import com.gregtechceu.gtceu.config.ConfigHolder; +import net.minecraft.world.level.block.state.BlockState; + +public class LDItemPipeType extends LongDistancePipeType { + + public static final LDItemPipeType INSTANCE = new LDItemPipeType(); + + private LDItemPipeType() { + super("item"); + } + + @Override + public boolean isValidBlock(BlockState blockState) { + return GTBlocks.LD_ITEM_PIPE.is(blockState.getBlock()); + } + + @Override + public boolean isValidEndpoint(ILDEndpoint endpoint) { + return endpoint instanceof LDItemEndpointMachine; + } + + @Override + public int getMinLength() { + return ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance; + } +} \ No newline at end of file diff --git a/common/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java b/common/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java index 0d8c8e85df..ecaaee4bf7 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java +++ b/common/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java @@ -249,6 +249,12 @@ public static class MachineConfigs { @Configurable.Comment({"Makes nearly every GCYM Multiblock require blocks which set their maximum voltages.", "Default: false"}) public boolean enableTieredCasings = false; + @Configurable + @Configurable.Comment({"Minimum distance between Long Distance Item Pipe Endpoints", "Default: 50"}) + public int ldItemPipeMinDistance = 50; + @Configurable + @Configurable.Comment({"Minimum distance betweeb Long Distance Fluid Pipe Endpoints", "Default: 50"}) + public int ldFluidPipeMinDistance = 50; } public static class ClientConfigs { diff --git a/common/src/main/java/com/gregtechceu/gtceu/core/mixins/LootTablesMixin.java b/common/src/main/java/com/gregtechceu/gtceu/core/mixins/LootTablesMixin.java index 629ed3eca8..2cb2b0e16e 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/core/mixins/LootTablesMixin.java +++ b/common/src/main/java/com/gregtechceu/gtceu/core/mixins/LootTablesMixin.java @@ -86,11 +86,9 @@ public abstract class LootTablesMixin { GTBlocks.FLUID_PIPE_BLOCKS.rowMap().forEach((prefix, map) -> { MixinHelpers.addMaterialBlockLootTables(lootTables, prefix, map); }); - /* todo item pipes GTBlocks.ITEM_PIPE_BLOCKS.rowMap().forEach((prefix, map) -> { MixinHelpers.addMaterialBlockLootTables(lootTables, prefix, map); }); - */ GTRegistries.MACHINES.forEach(machine -> { Block block = machine.getBlock(); ResourceLocation id = machine.getId(); diff --git a/common/src/main/java/com/gregtechceu/gtceu/core/mixins/TagLoaderMixin.java b/common/src/main/java/com/gregtechceu/gtceu/core/mixins/TagLoaderMixin.java index f1a44bb9d0..e116bfe211 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/core/mixins/TagLoaderMixin.java +++ b/common/src/main/java/com/gregtechceu/gtceu/core/mixins/TagLoaderMixin.java @@ -82,11 +82,9 @@ public class TagLoaderMixin implements IGTTagLoader { GTBlocks.FLUID_PIPE_BLOCKS.rowMap().forEach((prefix, map) -> { MixinHelpers.addMaterialBlockTags(tagMap, prefix, map); }); - /* GTBlocks.ITEM_PIPE_BLOCKS.rowMap().forEach((prefix, map) -> { MixinHelpers.addMaterialBlockTags(tagMap, prefix, map); }); - */ GTRegistries.MACHINES.forEach(machine -> { ResourceLocation id = machine.getId(); tagMap.computeIfAbsent(GTToolType.WRENCH.harvestTag.location(), path -> new ArrayList<>()) diff --git a/common/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java b/common/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java index 595ba4ac9d..a96cbb582c 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java +++ b/common/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java @@ -696,6 +696,12 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.machine.available_recipe_map_3.tooltip", "Available Recipe Maps: %s, %s, %s"); provider.add("gtceu.machine.available_recipe_map_4.tooltip", "Available Recipe Maps: %s, %s, %s, %s"); + multiLang(provider, "gtceu.machine.endpoint.tooltip", + "Connect with §fLong Distance Pipe§7 blocks to create a pipeline.", + "Pipelines must have exactly §f1 Input§7 and §f1 Output§7 endpoint.", + "Only pipeline endpoints need to be §fchunk-loaded§7."); + provider.add("gtceu.machine.endpoint.tooltip.min_length", "§bMinimum Endpoint Distance: §f%d Blocks"); + provider.add("gtceu.universal.disabled", "Multiblock Sharing §4Disabled"); provider.add("gtceu.universal.enabled", "Multiblock Sharing §aEnabled"); @@ -705,27 +711,17 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.bus.collapse_true", "Bus will collapse Items"); provider.add("gtceu.bus.collapse_false", "Bus will not collapse Items"); provider.add("gtceu.bus.collapse.error", "Bus must be attached to multiblock first"); - provider.add("gtceu.machine.fluid_hatch.import.tooltip", "Fluid Input for Multiblocks"); - + provider.add("gtceu.machine.fluid_hatch.import.tooltip", "Fluid Input for Multiblocks"); provider.add("gtceu.machine.fluid_hatch.export.tooltip", "Fluid Output for Multiblocks"); - provider.add("gtceu.machine.energy_hatch.input.tooltip", "Energy Input for Multiblocks"); - - provider.add("gtceu.machine.energy_hatch.input_hi_amp.tooltip", "Multiple Ampere Energy Input for Multiblocks"); - - provider.add("gtceu.machine.energy_hatch.output.tooltip", "Energy Output for Multiblocks"); - - provider.add("gtceu.machine.energy_hatch.output_hi_amp.tooltip", "Multiple Ampere Energy Output for Multiblocks"); - multiLang(provider, "gtceu.machine.rotor_holder.tooltip", "Rotor Holder for Multiblocks", "Holds Rotor in place so it will not fly away"); - provider.add("gtceu.machine.maintenance_hatch.tooltip", "For maintaining Multiblocks"); multilineLang(provider, "gtceu.machine.maintenance_hatch_configurable.tooltip", "For finer control over Multiblocks\nStarts with no Maintenance problems!"); diff --git a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java index 3b9411a7e6..fb5b10e571 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java +++ b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java @@ -38,6 +38,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.material.Fluids; import org.jetbrains.annotations.Nullable; @@ -271,12 +272,12 @@ public GTRecipeBuilder outputItems(Item input) { return outputItems(new ItemStack(input)); } - public GTRecipeBuilder outputItems(Supplier input) { - return outputItems(new ItemStack(input.get())); + public GTRecipeBuilder outputItems(Supplier input) { + return outputItems(new ItemStack(input.get().asItem())); } - public GTRecipeBuilder outputItems(Supplier input, int amount) { - return outputItems(new ItemStack(input.get(), amount)); + public GTRecipeBuilder outputItems(Supplier input, int amount) { + return outputItems(new ItemStack(input.get().asItem(), amount)); } public GTRecipeBuilder outputItems(TagPrefix orePrefix, Material material) { diff --git a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java index 662d0ca616..4d60fe62d2 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java +++ b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java @@ -1,9 +1,11 @@ package com.gregtechceu.gtceu.data.recipe.generated; +import com.google.common.base.CaseFormat; import com.gregtechceu.gtceu.api.data.chemical.ChemicalHelper; import com.gregtechceu.gtceu.api.data.chemical.material.Material; import com.gregtechceu.gtceu.api.data.chemical.material.properties.FluidPipeProperties; import com.gregtechceu.gtceu.api.data.chemical.material.properties.IMaterialProperty; +import com.gregtechceu.gtceu.api.data.chemical.material.properties.ItemPipeProperties; import com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey; import com.gregtechceu.gtceu.api.data.chemical.material.stack.UnificationEntry; import com.gregtechceu.gtceu.api.data.tag.TagPrefix; @@ -18,6 +20,7 @@ import static com.gregtechceu.gtceu.api.GTValues.*; import static com.gregtechceu.gtceu.api.data.chemical.material.info.MaterialFlags.NO_SMASHING; import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; +import static com.gregtechceu.gtceu.common.data.GTMaterials.Iron; import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.*; public class PipeRecipeHandler { @@ -32,18 +35,17 @@ public static void init(Consumer provider) { pipeQuadrupleFluid.executeHandler(PropertyKey.FLUID_PIPE, (tagPrefix, material, property) -> processPipeQuadruple(tagPrefix, material, property, provider)); pipeNonupleFluid.executeHandler(PropertyKey.FLUID_PIPE, (tagPrefix, material, property) -> processPipeNonuple(tagPrefix, material, property, provider)); - //pipeTinyItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeTiny(tagPrefix, material, property, provider)); - //pipeSmallItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeSmall(tagPrefix, material, property, provider)); - //pipeNormalItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeNormal(tagPrefix, material, property, provider)); - //pipeLargeItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeLarge(tagPrefix, material, property, provider)); - //pipeHugeItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeHuge(tagPrefix, material, property, provider)); + pipeSmallItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeSmall(tagPrefix, material, property, provider)); + pipeNormalItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeNormal(tagPrefix, material, property, provider)); + pipeLargeItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeLarge(tagPrefix, material, property, provider)); + pipeHugeItem.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processPipeHuge(tagPrefix, material, property, provider)); - //pipeSmallRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); - //pipeNormalRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); - //pipeLargeRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); - //pipeHugeRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); + pipeSmallRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); + pipeNormalRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); + pipeLargeRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); + pipeHugeRestrictive.executeHandler(PropertyKey.ITEM_PIPE, (tagPrefix, material, property) -> processRestrictivePipe(tagPrefix, material, property, provider)); } -/* + private static void processRestrictivePipe(TagPrefix pipePrefix, Material material, ItemPipeProperties property, Consumer provider) { TagPrefix unrestrictive; if (pipePrefix == pipeSmallRestrictive) unrestrictive = pipeSmallItem; @@ -64,7 +66,7 @@ private static void processRestrictivePipe(TagPrefix pipePrefix, Material materi ChemicalHelper.get(pipePrefix, material), "PR", "Rh", 'P', new UnificationEntry(unrestrictive, material), 'R', ChemicalHelper.get(ring, Iron)); } -*/ + private static void processPipeTiny(TagPrefix pipePrefix, Material material, IMaterialProperty property, Consumer provider) { if (material.hasProperty(PropertyKey.WOOD)) return; ItemStack pipeStack = ChemicalHelper.get(pipePrefix, material); diff --git a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java index d778793957..f5ea047640 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java +++ b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java @@ -338,8 +338,7 @@ public static void init(Consumer provider) { // Hermetic Casings VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_lv", GTBlocks.HERMETIC_CASING_LV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.Steel), 'F', new UnificationEntry(TagPrefix.pipeLargeFluid, GTMaterials.Polyethylene)); - // TODO enable once item pipes exist - //VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_mv", GTBlocks.HERMETIC_CASING_MV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.Aluminium), 'F', new UnificationEntry(TagPrefix.pipeLargeFluid, GTMaterials.PolyvinylChloride)); + VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_mv", GTBlocks.HERMETIC_CASING_MV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.Aluminium), 'F', new UnificationEntry(TagPrefix.pipeLargeItem, GTMaterials.PolyvinylChloride)); VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_hv", GTBlocks.HERMETIC_CASING_HV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.StainlessSteel), 'F', new UnificationEntry(TagPrefix.pipeLargeFluid, GTMaterials.Polytetrafluoroethylene)); VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_ev", GTBlocks.HERMETIC_CASING_EV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.Titanium), 'F', new UnificationEntry(TagPrefix.pipeLargeFluid, GTMaterials.StainlessSteel)); VanillaRecipeHelper.addShapedRecipe(provider, true, "hermetic_casing_iv", GTBlocks.HERMETIC_CASING_IV.asStack(), "PPP", "PFP", "PPP", 'P', new UnificationEntry(TagPrefix.plate, GTMaterials.TungstenSteel), 'F', new UnificationEntry(TagPrefix.pipeLargeFluid, GTMaterials.Titanium)); diff --git a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java index 84bd4e11a8..dba99adbaf 100644 --- a/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java +++ b/common/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java @@ -12,6 +12,8 @@ import static com.gregtechceu.gtceu.api.GTValues.*; import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; +import static com.gregtechceu.gtceu.common.data.GTBlocks.LD_FLUID_PIPE; +import static com.gregtechceu.gtceu.common.data.GTBlocks.LD_ITEM_PIPE; import static com.gregtechceu.gtceu.common.data.GTItems.*; import static com.gregtechceu.gtceu.common.data.GTMachines.*; import static com.gregtechceu.gtceu.common.data.GTMaterials.*; @@ -637,5 +639,44 @@ public static void init(Consumer provider) { .outputItems(FLUID_DRILLING_RIG[EV]) .duration(400).EUt(VA[LuV]).save(provider); + // Long Distance Pipes + ASSEMBLER_RECIPES.recipeBuilder("long_distance_item_endpoint") + .inputItems(pipeLargeItem, Tin, 2) + .inputItems(plate, Steel, 8) + .inputItems(gear, Steel, 2) + .circuitMeta(1) + .inputFluids(SolderingAlloy.getFluid(L / 2)) + .outputItems(LONG_DIST_ITEM_ENDPOINT, 2) + .duration(400).EUt(16) + .save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("long_distance_fluid_endpoint") + .inputItems(pipeLargeFluid, Bronze, 2) + .inputItems(plate, Steel, 8) + .inputItems(gear, Steel, 2) + .circuitMeta(1) + .inputFluids(SolderingAlloy.getFluid(L / 2)) + .outputItems(LONG_DIST_FLUID_ENDPOINT, 2) + .duration(400).EUt(16) + .save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("long_distance_item_pipe") + .inputItems(pipeLargeItem, Tin, 2) + .inputItems(plate, Steel, 8) + .circuitMeta(2) + .inputFluids(SolderingAlloy.getFluid(L / 2)) + .outputItems(LD_ITEM_PIPE, 64) + .duration(600).EUt(24) + .save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("long_distance_fluid_pipe") + .inputItems(pipeLargeFluid, Bronze, 2) + .inputItems(plate, Steel, 8) + .circuitMeta(2) + .inputFluids(SolderingAlloy.getFluid(L / 2)) + .outputItems(LD_FLUID_PIPE, 64) + .duration(600).EUt(24) + .save(provider); + } } diff --git a/common/src/main/java/com/gregtechceu/gtceu/utils/FacingPos.java b/common/src/main/java/com/gregtechceu/gtceu/utils/FacingPos.java new file mode 100644 index 0000000000..525c13565a --- /dev/null +++ b/common/src/main/java/com/gregtechceu/gtceu/utils/FacingPos.java @@ -0,0 +1,35 @@ +package com.gregtechceu.gtceu.utils; + +import lombok.Getter; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; + +import java.util.Objects; + +public class FacingPos { + + @Getter + private final BlockPos pos; + @Getter + private final Direction facing; + private final int hashCode; + + public FacingPos(BlockPos pos, Direction facing) { + this.pos = pos; + this.facing = facing; + this.hashCode = Objects.hash(pos, facing); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FacingPos facingPos = (FacingPos) o; + return pos.equals(facingPos.pos) && facing == facingPos.getFacing(); + } + + @Override + public int hashCode() { + return hashCode; + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/models/block/machine/ld_fluid_endpoint_machine.json b/common/src/main/resources/assets/gtceu/models/block/machine/ld_fluid_endpoint_machine.json new file mode 100644 index 0000000000..16b9fbd0ff --- /dev/null +++ b/common/src/main/resources/assets/gtceu/models/block/machine/ld_fluid_endpoint_machine.json @@ -0,0 +1,51 @@ +{ + "parent": "block/block", + "textures": { + "particle": "gtceu:block/casings/voltage/lv/side", + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "top": "gtceu:block/casings/voltage/lv/top", + "side": "gtceu:block/casings/voltage/lv/side", + "overlay_bottom": "gtceu:block/pipe/ld_fluid_pipe/overlay_bottom", + "overlay_left": "gtceu:block/pipe/ld_fluid_pipe/overlay_left", + "overlay_right": "gtceu:block/pipe/ld_fluid_pipe/overlay_right", + "overlay_top": "gtceu:block/pipe/ld_fluid_pipe/overlay_top", + "overlay_pipe_in": "gtceu:block/overlay/machine/overlay_pipe_in", + "overlay_fluid_hatch_in": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_fluid_hatch_out": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_pipe_out": "gtceu:block/overlay/machine/overlay_pipe_out" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down", "tintindex": 1 }, + "up": { "texture": "#top", "cullface": "up", "tintindex": 1 }, + "north": { "texture": "#side", "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#side", "cullface": "south", "tintindex": 1 }, + "west": { "texture": "#side", "cullface": "west", "tintindex": 1 }, + "east": { "texture": "#side", "cullface": "east", "tintindex": 1 } + } + }, + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#overlay_pipe_in", "cullface": "north", "tintindex": 2}, + "south": {"uv": [0, 0, 16, 16], "texture": "#overlay_pipe_out", "cullface": "south", "tintindex": 2}, + "up": {"uv": [0, 0, 16, 16], "texture": "#overlay_top", "cullface": "up", "tintindex": 2}, + "down": {"uv": [0, 0, 16, 16], "texture": "#overlay_bottom", "cullface": "down", "tintindex": 2}, + "west": {"uv": [0, 0, 16, 16], "texture": "#overlay_left", "cullface": "west", "tintindex": 2}, + "east": {"uv": [0, 0, 16, 16], "texture": "#overlay_right", "cullface": "east", "tintindex": 2} + } + }, + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#overlay_fluid_hatch_in", "cullface": "north", "tintindex": 2}, + "south": {"uv": [0, 0, 16, 16], "texture": "#overlay_fluid_hatch_out", "cullface": "south", "tintindex": 2} + } + } + ] +} diff --git a/common/src/main/resources/assets/gtceu/models/block/machine/ld_item_endpoint_machine.json b/common/src/main/resources/assets/gtceu/models/block/machine/ld_item_endpoint_machine.json new file mode 100644 index 0000000000..adb45939a8 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/models/block/machine/ld_item_endpoint_machine.json @@ -0,0 +1,51 @@ +{ + "parent": "block/block", + "textures": { + "particle": "gtceu:block/casings/voltage/lv/side", + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "top": "gtceu:block/casings/voltage/lv/top", + "side": "gtceu:block/casings/voltage/lv/side", + "overlay_bottom": "gtceu:block/pipe/ld_item_pipe/overlay_bottom", + "overlay_left": "gtceu:block/pipe/ld_item_pipe/overlay_left", + "overlay_right": "gtceu:block/pipe/ld_item_pipe/overlay_right", + "overlay_top": "gtceu:block/pipe/ld_item_pipe/overlay_top", + "overlay_pipe_in": "gtceu:block/overlay/machine/overlay_pipe_in", + "overlay_item_hatch_in": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_item_hatch_out": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_pipe_out": "gtceu:block/overlay/machine/overlay_pipe_out" + }, + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#bottom", "cullface": "down", "tintindex": 1 }, + "up": { "texture": "#top", "cullface": "up", "tintindex": 1 }, + "north": { "texture": "#side", "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#side", "cullface": "south", "tintindex": 1 }, + "west": { "texture": "#side", "cullface": "west", "tintindex": 1 }, + "east": { "texture": "#side", "cullface": "east", "tintindex": 1 } + } + }, + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#overlay_pipe_in", "cullface": "north", "tintindex": 2}, + "south": {"uv": [0, 0, 16, 16], "texture": "#overlay_pipe_out", "cullface": "south", "tintindex": 2}, + "up": {"uv": [0, 0, 16, 16], "texture": "#overlay_top", "cullface": "up", "tintindex": 2}, + "down": {"uv": [0, 0, 16, 16], "texture": "#overlay_bottom", "cullface": "down", "tintindex": 2}, + "west": {"uv": [0, 0, 16, 16], "texture": "#overlay_left", "cullface": "west", "tintindex": 2}, + "east": {"uv": [0, 0, 16, 16], "texture": "#overlay_right", "cullface": "east", "tintindex": 2} + } + }, + { + "from": [0, 0, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#overlay_item_hatch_in", "cullface": "north", "tintindex": 2}, + "south": {"uv": [0, 0, 16, 16], "texture": "#overlay_item_hatch_out", "cullface": "south", "tintindex": 2} + } + } + ] +} diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/block.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/block.png new file mode 100644 index 0000000000000000000000000000000000000000..75beae29c7e079af8390f4471914c4823b814db0 GIT binary patch literal 449 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 GSn>y2_6u$R literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_bottom_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..1723c87c4c27b0b955cdb81bd6783a46a5a9198f GIT binary patch literal 5630 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 F{TFejgr@)i literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_left_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..3af03260f812c855967722218a3907688590e684 GIT binary patch literal 676 zcmV;V0$crwP)EX>4Tx04R}tkv&MmKpe$iTeU?if_4yb$WS|35EXHhDi*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RRgvGqgl{F$34}bq^0;@1i`*{oJ3UU(Op0@Cd|nOw&!`4dR(i zQ{%i(9AYI=CO#(~*Xe@9k6f1=e&bxU*~>FSdL}hb93mEq9V~S)E9naHG;vr~RLb{e z9hNz7aaJld*19KuVKA?*q`6LW6mcvefg}V-sG*DsOhjo_NimS3{g{h?#P%o2C6TKP zMvetkp+L0#;D7MDTca>F=_CbXK=+GfeT)JAU7%UFtnXvXYMubTXW&Y0`>PFL_LKB_ zTMHin1KYsGbz776fXf|V_(>CW(UyEPy@dksen#Jv1BPya-ZiJU);>-jfDCoDd;=UD z0+AwRue-cE(AnF+XIlOJ09;yfo=xKx1poj524YJ`L;xTFAOIjcq4HAz000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2j>P73k(O0LEc~h005v#L_t(I%VS^|{^0)v1}0>h zFi1G?pC~aXV4~Cz3qJ(#+)Dj@OuFZ;ACTA;O68Y>;+CX7C3%A$&wLWj$wfV`L70ZKgGY`u(GZ7c(X~2_LYYp|4cS_f zP8yX81TkK2oH^&{>2U*JBzw-YEi|rdT`;oE;56@JC%c+e>z`~roOC2+pyRuPxVAoj z?|F7;bFh{(C#__ycbv1=7t@#vr-t1-{-|rruRpZq9H@SDQN4HY)b-nny7u6g9%LSj z+3L6B)+it4EZ=&4xUS*k&ps8CF*p2!qs(xn$bGBtVV|2KbVOlY{RAIXamG1G+qpHL z?i|{n^?$B@z+8HweMtC*%>{`8VOI~YdpLA-w&A*H&D5b=(2+64l?Ay4SpoBA+Li`w zJNEU|m_2j(InC<(siOJgbfZOcTd!n>_MDhF{;BJ_EqlG2FCWSqdOolF;jbrBgWJ~3 zk`J4lk+}YHyeMt|r0c26XV|6K1lbwlidv#8J!j1;pf!3ey3Q=|81NSCv#w4s{o(+kM7HdVaE+{GPcO-_A`xSX*-5W8HhFiU$1P99mOz z_G`PGQPY-u*Iw(X<+vWSA^Zee*~=Ighn4k=F*cjhZcmK;(Y3hVJ(AwBfjKxPc+!%R zDJ}y8zprwf(A0`}ynEPbxVsmoISpWTx=k5K#Gjd7 z$~|B2MqJz=n=yUY{AE)UqBad3e`@EQ_y~^jg9*vsp82hWBR)-UTjnaddgJVneBh2vYyvv)U`W-8zse8M;W~X0{Yw#^=sx|!dk!xV)y|T7x zN5=lz(EUm3VQEWz89toV_@j4AW(YCqVJO$Ru5O6O+ECjuJlC^d73u?uMr^vY{9a6e z-Css+O7LDC67ti^k9JjTxlwjI_I~gkMd_jodA$`nMTF@~-M(Wd;w$or-6gBfCI};r zEN%R>XXi%#+SB*HL}Oh+r01gFz+$XcXz27_3m-g zgPT<$DXH}il55^XaFO#EtwOP-v3Yo9$Z?-RrmYGfyZN|tK;|?|PKU0Q>bZ*g&U7l2& za4uutrfBY=wM}ycv$Idoz96twnhTeTzpIrNZ}X51x>&GRzx18Qw?6aIx79zZkE}}^ zKL@F9n!R76Zz{R@>^Q*4%B1DYhV#o9g@4+AOIKC?1iPP|xOruh@Ne~> zJG7eKuk45}IkkIuy11jVV@%kS4(78#@1J{T?e?@bjQFaXeKa_~_GHO`4g1}SA3X}) zQ*~(bFJw*D(k)xFZpVDPk=g2dYSCBKb?v!5yrcIHpAX$6O278}q+fTAd&)`ss^X5S zxU->8!f!6}YrK+k-8DIPN#?;X*0-Mt>ONi}o|Vr_TGW*NXyXCezO&s=7hmmI@Z!#b zPc~k0l7BPv=WL(AOVbXXbbDIEYaZO0Br42zt&#UQ-U#vWoNHg;jUa;)l;D0$jQUVa zXjDvGu91;Uqe=_zPXq}FHfnJqjWp0@WU^8n$aqkFl0jF>0~s^%Rrda*H(LE(zQ8j4vAI%Q%=3uGil#nMAHI+D&~ z@|bKi%&5%77(q08fKILu$4RF4L4Z$zj1+@GD`v5>va*<2T&6~s%;JbdA{HBCVHgT5 zP<^)AfE!V@el&zIV@OCnp;KxNN{yNhF>#qD!w|?|06pCjpGq4QWrbJk`&a;cu#C8t z#bL5pDiy20hu#pD2|)S+daZ|E3chAoaim_8p(Dt!Oj2za-5)|uSpBsbx^yZXIl&^+ zNfj{FgIzhVY#AOI6>If?6eKHETFMKM{febQsd!1&E3rWhl}`UafV&m<6>CfGlrgZ1 ziV{mSL4>)3( z{{Fm|Ml(pA9`qta<*=Dtvj!GM4AKGA;;>Tz0ObL)5r^tX+@R4(HJbE51`L4?J+0~} zaG>P40hizg5`eNXu9(9XvoR^g5p(!rOz<9?D`xkz*T|KM?0;tsj}JY-T=WQ~9_*h@ ziOgpzo?K}DWd4}0qz)6EP8|y|PMA~BnRT!99qxT5>@m1@GP z(PX8NunvGSl%T@9?d7u~sRsYxWq~I_&zQOu z;3?8kHZ5F&^uoVwCw8p|k^$O?S$YI?s zkb(9#NJozi;$nv&PrJ<)c6N4@4(b=+;7829VQX1H0H}l$I=6-IvO3$^+EVhC&>hr! z7qGRA*8)Ii%Ye>sLT5PO2Bv-h))cxrO_b8&>^azpa)i$JB1#b&D7OWm%VeU~@Wl#X z>g=MzraAN?E(4sA0gm=aFL3Uhz6Wu!nwuApOv`vB1t_#Q!!-=|9|x3mg3T<$3IJ0W zQ9Xy+*`kETv;&Eh3`PVe1pvxu8CC$8f{TL<(pv_9cz!ut9BmQ1iWyb`1TeiW1<0(a z8|(-`Y|5pS10>J{&I8TC7ID~@NXZ~T*XtsHwWY%A1F`H1K{`P*L7mfq*=C!r*H)nu w!SMx1r>V=@vM?$LY;JE8rGw#{0AK$+l0a!CPD*ylh literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_right_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..8cd0e6223a777bd2dde4d4c8e8920fba4bc1c0b8 GIT binary patch literal 5713 zcmeHKdsq`!77vIZ5nRzvMHC5xWyP9zLP#VE5|n5I6rzH!Wo9ygkz^($0RmKU5%Ezg ztcb6bRtpGPv2|H|RRIN|zD21hg1TzaT12e7V%3`734}-W+g+#eK(`a_WRArPg0#0V=^rRZsU<_l5 z4r5>@Tuq~ynjUS5-rVNxlyxgQc=HPTfGMk=>}X@0y_l_-yY%5M;?}XnSFo>!Z@lDi z?NROY^svq`EN_0XXY@I4>Z0vJLtyo*l)Ss4OR`@s@7PkC-@JILD-_7QUvR24{V%zd zWwODgI`o^S_L5Hb=tIlWIDdCPy>3nYgB#&DvobFZYqCEhW_pwr-SBBhxcW11N0QDmk!TeT0JLDNOqAXs(!AKN4pDWI^Sosq`=RjNeoFWZ%JsAF;QzUm05;^sJG*Ks?>b zSAQsgzD)>w$jd7je4IY!Y`HjdG|bP)-L>Ss0@rzo)e#RWep+{V(#Vx(CKiRR^8TcN zXc+$akGdU~Vu-5pOz*XP5ocok+&KNlDT|$CH`XqG?l#n&C?nfD)E&)^dq3dJbp0_Y z;qkDo2JK*oY+U5YYR%JR9{8qoYC}L~Yv@wH5g++vH{O}daGkfgarEgBja1PPV9vMG zuNXbazTy6a!iGaOg+ula$~ZAB+*a7;u&+l9S6tcKI_5}>@y|1S^1e`(p7=H@vV40y9yLv| zFz!H+ntAB*kvVlg)uUl8sqNUMst7m9$u(Zi<5D)QE%H63$cJmU?LO~+Hm|Anh4SXk znSXWjDBO%3jaVrt`q*(nojmFsZGHZTHN~rFL${CNlZ9tKZbn-98>Tz1XH+9sahE}X z?lth`Rrz;wA3&X61nYZu(d)T-Vpm#jGyl;1h8L;MjAhd5K!c&t{HL3AFdB~;83-1O6H@5$*Od?hS4pAy zLIp>m3&P^?kW@VunHs7@Q{z#w3YtER?r)L+0xf2Q878fUFi1>N$igcD&lJpt7#0&_ zycCL3gfoIjJ;o5Q1S}3S*n}tXplNi5zh0%5M95}#Q-C)q6lXN*By4taaxyEK&m#4) zY_3==W^;IK9*+qun1&R>2%DIM!Hc5k;*enmRFCV7I7u)lP8cB*jZz2#^9*Z#TAf1C zLr)mGRRDUhO|Xv5WpUVAExWIW!5EwbNV*extA{}e`Y<~JGmwdT6bnwm2%}eD3KiPp zuS?WxEaj+BHm1R}z|;Vua{GmxC0B&^cu*3=;#!@>3y9s%(uk{j#p;(EHDf8KZz90G zhqs@#wRVd!uu>=_G7?Rs(v!=i5EWmdB2io=>3Z}Pi~YnrJ`=-y#Y_QDrDDQjM8xEA zI2;~^2}OKF+=og|7>qE1ViXl1XW@XySI8HN{17n{_2nag!cWW;^Mqn1SIp%jDy~3; z@CAJ+!t^-Um9VC7Ruq*AP$3vcd1+=3#mR*ozb^m&59=hguj3C8%e#ABsEfq zN{T^w_Dn0lfl|RnSOyz0K+56qC0ve#!&CCO60T6f<-X71OE`V(NfoY6`A^o=@nQIP zEqVxU0P#~SP}iA?#1gvRx?VN7FSH6MHJvAc_9Qys%vtv~w>J^U>OeOe6g>%u_m0-ccE(+a!w zqMFWccy+JCZx{hk4+ME9eFx+kkn5ckcqik5-8CTBJ1Ou^#sj-)?r}nq#qaVm=g@4a!mQ)}R%A?-`3=XnV3tV#jUnwV&Xivd zfqB!AuIFyUQNtX1cYf^ZYdxg)$oIIE3bC-!(OgsO#tT%<9lR z_GDni`#M{(e>e6Jm_PNhrR@x`u|~E!{jgDN!6^LKbCgXFfeq5~+FUHMy|Z3uV|AuR z^KQW#Sl{_Ko+%OvoM1fLQ~TSnHyrx{R)@aW@A!GPTqslSj!dFTlm~~(_RomP_yxnf B4^aRB literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f9dec87d503d3cd1687113094f3330a478fa10 GIT binary patch literal 6130 zcmeHLdsGuw8XtU+1k|Hg3W{h5^+D|LOJ{R6xM&oj?NG_U!ST_Vgbw=jPt|9>4p2 zzx&-ACTk+X-XHBS(E);>(ILTsQD7WPcB(!2oYG;&AZSEqdQ6-#3Nz7ldaYckBIw36 z9YH5jm2wD5z0wdHUvQf@s`s9ke#EdF>67-g-LV(0SbIylC?!06`V!BB;%%$u>~Mgt zmGpI(Vn4nqWd}`Y&02R(xp>;=XK8cmI_6!<|F*2Cb=~!(1kI4!WG^Ild$-)-Ee$htIrshBf&}WT6|w z=q~lc#Osn8>D}d{AcjhPa}>=LN_?ka(t%GdkGDGuWjZZZp#P|Z;%l744vb5>G3`;) z#Qmw|F_+o9o$uEFcw&|F^vTVEA@my8b-nG==s9`LiF*&8OLtR!`~4d4bE134+$3mP zdr(^I7oD@a{u{k%Y368V*VwtEy!3BzByJx*K~K3xR~69;#$OMM2=+1*s1D4(Ol%L> zAawp$I9mO7>_@bz1uUE3UG4>y;itoO(opx}Mse~5wdq=C9Uh)@ zP~3X8Z+K%u>1mhffchzoNNXR@|I06$Dko5Jf|}doZ|C$mMIpLjyjj_N1Z%NWRs@%-6cQ5XEnDb*r$FnsDMH_bNQQlX&l_et^ za-P2Jl*1Ww^l)Ux!ABR`!@Vy)4w{-@+7%G{tYzWU-psPbO`GwUHTay&iWZmUYs!D| zQa^W69aD)bem1-(>Ha2#+A7I#E54f^;=h##?l~R>(45_KC;Ltf0%XXqry!K z4{0{8Zr~$_iV9+y4{eeslyNTvG#Dl-%rR%Hre1B?y0^OG?fQIeQIEhs@Um!$JGbFd z&54=}$5_XV#4pne9-neNGj8oOrwq6>n*H?o-AVV2tM80SGOVv>@_g8)+LEM};z=`> zpMNmN^?2wh%@zBw>Yu7kuYR0esSc0+Wv{w?G&bld+k?A1pWd=LurI=Cq94j^h$=a~=>9UV z1?Id@{r_ILv|EZFuDrCRaCj*azxBU)ytWJo;IYf8WKwO;%T*dD0v-**!1Zt4V)~ z)$@H;*72UTdACgexv`vA(~_TjcYf_S>b5POyJWo)aglV7q=*Y!-OCjjqK?c*vG*2+ ze>)znnQi1fp)6p|oN#?3OWhFZSNBn!Lr(mQwUN8N+u3V6<5#!I*xNPHEH*pNyxsOm z_k(4P5Hx1K5?q0Ck`F|h~3}+E4LJdp}U{&;`CEpK`MA$q?3KUAU&f*2ge#z3Pln;{iQf#Eg zlFraTfV&O%C2MQ$7Gq!~k%$7dcrqDYNT4r+Twf&9;!2swGUcNfkMNfAVM2(>VGhBS z!a|vxfcXNHPhf0|ZI3_1BKFSgH zL&n&r~##)c@4~s8U)E6P<2379tGqPr-nt5dAw2u=-Va0;W+A z;QkmWSgTz58^s_%5jmF-@L(>2qA&*+aA5(?7r+BIWfcJ~_$xj_Lf{W5SfgNvSJ zyXgn`0$cHCwt+JHGnb&#-z@T4{Jx><4PCFrz-t-5sjfG4y%qznW&EbP{xG^62HzD4 z4fqGo1l|PO_oX+1w@7nGR_~@?mW@0O~*l)|{Qoms)KsVO!;|0@#wHQYp3wtj4r&Vl6WAne29U zcE5^X5CEh=wx9jBTSn(G6o@2`+^gXOomBMf3j6I8C^T{x%+QqYmXLN(>*H>y^Ep|| zgN<~4H3b_7B(tQF?CupGTD+cicG*Cz&c6#lR-6@p94C~;L(h8bAQEJ#^Q!>1QqIZF vF_SwnSh53i0Bn)HGJ1G;*n9_*{3~Y4Z@#QMcIOI(TsuS@7PxQj(#-z>n?o-& literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_fluid_pipe/overlay_top_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..a3221b27ab241a0e17e0a99799329289509bad17 GIT binary patch literal 5632 zcmeHLdsGu=79T3|2tLqNSrJPJMG=`~CQlMUL_#EL6d@v_xJ)LKFp^|KG7tnGsMRWV z*@EC&>z-OY9u!5iqPrDE)VlSB)XKW8VkruWijS_X$RcIG2@t{89?x$7*t1Md=5g=u z{=WPDzWd#i$@-XC(+0D=Sr7ybRz}NX!PS%by19U}@8eDkf(A5ZsT1f}%*HlbC>?1a z*z^)J!6q_E9Ry`wy&u0|Ut@?{M{AJI-Nmr_k2i~jlQuWi9C*BWLHeHb3e%o&#oYvS zh-Z~g!RNpA%g!2-+w!wp_{q@szr;tme~`C#!Pdfns-uOYHtb&u9gLRwM@(JR zbf=Qf*)p;AQS2S3qU@-$wg;n2tBP|&1Ekk~3aFp6^!Mjxb-31?xHvNWAJ@opZN)8R z*%wXLhodV3{rvuRr>^!;(XmyF)@*3H>eCWX_80$|&F_vrWiA<$H}!+_xt9WeGoVPh zQZ{mnP;9LA)cnwpa3I-~lZvVe1(M|G;a9eu4Vr)CxBCsQEhlZk<=1ufbx(AU>fB3a zB8tqW`wibO!!FKc$-jTF(2sko$ngGwj}{1ObKI&0yVJ%$^{)B*$+Vw}0u0&z!U4w9kx!5wSBT zkcp}TyHd>FqTMCr6^-V^_JBCS`FOrQ;_`=5qI#2+J8-f`u-DO~Z86iEf<(2=i%Swq zZzX!?&Gvu~*Ot#eUrImt=2Cdp-K(Xy7r6}f**Q$%LpJZvpZ0Oc;<&m&f{ViRs}~N| z?fTRH<=)gb#rVZX^AmHkcDU@jORS2YwBADitu1qNN=x$mVanr^7sjlq^7vxS$2EJ- zM=3r^!>*8iF3zXec^kPcKECU?jmzC7#SKo9U$_=iMC&-qr)k-15_uK(∋pHcT(^ zQu{WZVl9~OTQR$~Bl;1y18?r6Qq~?AweTyq%SY;m-ja@8*bqM_XawitcRPY7m0yc& zvy?>jMwr-J&A}<16#@Tej*}3>;p5uOfrG zTiJetlKixE@xIdW*I2`jWp(%mb7!6PFkByS1|C~YCl<}A50bV{f3&*bRQ=ibl+yO4 zJ|^dmLE(d+#kL$fv{_$%oAoUBNZE+;=KP(z_rk;%mQ5NdXJ@r_QugtJt(53+apSV) zxXV8#-Cz6gX3e~I$)3(Xd{&Xs)P`~9iByQn97&{*(ODKEE^C$=&q~Fm zT2A<6R%oUS5Euy>V`mx-CaWwnjAQ4OfqTZx`;qVCySLUx+%a@7$=3M%`zU(X0vf^0xo6I^H8Z&%0u`(J|6}M*t*0-W0|nY z>d#PgamWcPZXwMyNtxITC#Ip&=`aol_}M-A8OqNV*exWrS4?+9ofSuu|z3oQTRGOtgP*3N7x4H>X<+_UUMG9$_Gi0BQxJqJ4&( zrc}i^A{Ytuq|t1T0%G?;(xmRWSbcJ1Jof4IP6UKIc>ADx=57ZAlu9L&Q+PU)o>Csh zVaAtfDV)^G?6;UeAixPs42y+26c*x$2*yxc0EeIg3_+zrp-`ghMWr-ZY0QKZ3>6^f zl7L5o3q)EX1cOC7i5M0N2o0=31Q?89s1%o?LNTGkdr{1`kf16tL+`8@DlMQA3UHAG z$FwjZ5rx1)p$>sHghm2mBAqlutkGhqMr)_i;xYwgF=AjjNh78wcxIE{?qCF$MZ_q> zID9Vh+!ABJXdMUudw?`)DVz1VOHCSyI2vR0M8#4uUxFg2I7BSwBj|HbJYlhdT4Y#J zgewr*Ji=CK#K4M zG8B;^d^I1HfqQ{?A|j9>z3`Nl)GhgUXlDDcL%S9|nzVxPm)K2Rdn%4d>w4;XG?4bq z#Ae&Kg$%>HreMV~h%Su*SC?Xi=uD25OrrXfN^Vi?zo5wL>S{LYqJVz_+)(edNYaZR}@M{jiX7>;BR{HkK z)i2juDezX{{_5(N>#Y=cD{y~x{nzATJ%5=ZOyC!g4ZJE93s*LP*DM#!jA?SHllg2r zR=g2d+|AMRtq|lfocTI^bA9X2bhp3V>3 z0pkDuaC%9B^V4%m$kMSWu4ad>)ewoT~+=rJ?b7lRqw%LI(| z6(p|;emw#3JozNTk;&_V8G`@#aE#($>K1Y25Lc+Tcs>3Xvw4|-LB59M#b5^dMiGB* yeG0Yyli3ijUIDw~jVF)^i#Tqti#Ou_x1Cw{IJ{+TUo-#pLdvLF@_kd2SN#hB!^?pH literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/block.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/block.png new file mode 100644 index 0000000000000000000000000000000000000000..a1f8c11073a2ea83e9c4a97e3e4b22d12ae1284e GIT binary patch literal 461 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 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_bottom_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..70a79ca573c601fe3646310852e42c56bb26226e GIT binary patch literal 5670 zcmeI0dsGwI9mfOm44_DLQC!??EG?)Z$>c#Yyad8)H5efZO0`aACLxk!VrC$L-Li{Y zRM1uMfhg8TTUVB%$JTa_@=&RZD5!wPZV`*@s<`lIj6g| z$?0Qu!Ccpk!PaNwiEv|YQLAIiG;*`^(ZZ-Z>)wOETzaQ;3$J6~)`_LF+uHw8o7U(5 z!?Q(euXnV4Yk4Sh6rCh@wDpv2^_A+Z-(F~$eSQ`@<`5B^72H=1rv>|`uZX=E|KPBq zY3Y;ei>_qvtx4RMa`9T%`_CpbpH!}XyXk}MKIa=ZHsH6qdoO$6J9B+=MZQAwuR7=b zL0+DH1&8mg``s)jQME8z(OKSdFY{@|vaj?v_s4BX?*B`BQS~xB@xvffT-CX)-R<1u z9*e4DA3xiNyj&9PI#pR8`q_1*+9Pv%RBQ8v+FyrE+j=JNa`3H$ja};%cVmO+_QdR- zQSQ#X`dRYh!0kQv(iu*SEDl%FDZRtUt}L zrI=^>WeHR}Q{LZE-Ch+w<7{H?-8k>$Gj%#_()s`mQ4%rLr&PJyp`+)UM(VLbu^C@j z5NUb*KTa+wE?Px;kBM!wNG zZt{)TwC%0y&n@2ZX@J`wt{wENPxmU9h_xbD&t}~o-~7ncNtcDe zP;ofdy->9$1FAc)T9S`9%Y*9|E=lT1t(1C9sq9VON&cd}wBa{byLYZ>|NNkMdg}7D zKhBH;iP+N(EekA{y3#nCSDeU*jfktPGtb+&>I1fSM**=P+xp8BmXEZB5# zPmKPmo$H1r7v^_HPV3rR>rlBSvmo`*=hfQ#=e@&v2HI=B)-3E!Q5OeZ`Ro4r+vmT3 zw5eu~pf0*`cVWf$=&0vOTfj^p zd~s>lKv+pCb}zr?K+t{8&lX&WElcGL>=K}JXGUJj&kcV!^WlKw#_uA(XbWEXUG?A3 z!@ec!vk zgD8}|XtlPUwp-a%D=w9O!UfeLQwyp>ihL1_68b;{BUE^xMQ;REgTV+1w-^yL9j90- zT%$FFvL95PX0x=e0z6-AhEmM~Bl$m2v?w3!e)jL8ZyVQM&07BhqZPoeBI ziZa4nuGwr3Gz$U=lZMNeN~K&L#DyRZu;7qc1`4ro4CEXdG02eNBx=$cDJ@}O(M&`| zWKf}OHW+6O$EP>S5hsZZ z6N*P?;s$EYXat6i_!~1!I$Jsz%EfiK9+;9~R{oeNW8>wD5f54djaF~8c>%GhpMvvIi86604AK{L%9?son46NjGSVo{3ba?TyP&Pe3j1j07gKf76&KHR>gvWt! zT*?tj_z*|J6R0^-K9A2A;5ep6kx{6414$tU6sJ)D9;gKzL?slcg=#TJ4T*vP0^CW| zK`M?4Lcy;H$5fbP6k@SS3w9-<8yyvm!T>6WheAODT*MLaRS-vrVHiiM=J7Zfsuo~S z5TZgQkPU^Qa13G6BVakTdPIYBjRuWvfEFB%P{fC_p+Mft9)%8})W89p0j&We%;d`< zrB;t8Q3$OkUn~_vK|HBgDuKj&iQuKtGTcOhy+~8}yg-4_HbO594AKG8BJ@rL09!xE z297e}2t}Bb1fdIM(?PLl&yis{I8YcuAu@!*0h9*`U_KA#K}v`ZLl7*K&f^JS-Y9zl z)2g%nn>BrWSRsRp9;YS2{8_fH!84VFuN{0EeAH=ehl$0q9Sayi2U8%COdPYt30Q+e zXc}VB;GljCZP?*{?Q1pzj`7rL5sGmjR4m~Lc@WN#s8AsXMFnCtSXB(i@Ue7~P*Y~a zghyzAjzBB0L2X*G{D+n*V64444X4)uNXFswIHM$EbBB`U(iLMk+Ys(6dW6^vMwJ-g zH`oVC7pR2Xky1FM7hQCI!fR+9e!>|5dSa3{(sx3x3Ax@#fj2Uq*j*EHy^#WMWIVCE zel)q5FJGo`1Na7H2Cqt3L&yv8n&qTg7%O8~>7N5Nhqr?sS7Y3AlEHBEqMO~7_MGRS z)0v8wM>~JRwD)?8pK*SB6!?$Mtaw?3QZm)f)8WAYu=t<8tUFw+)_rrV|0zlP@dmAh zKwSq92E);fVLco)F66ZUoAV?WumS+!;A)#=Jjg2mn=|d=NY4)1sB1jPD3c%g)>`_u z)q2o>-2Cb3UP)m%2J5b=R)!rI2F?1Za9qf10oLs;4VL_xH&F literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png new file mode 100644 index 0000000000000000000000000000000000000000..69789efda0b2934402b87de4beabcb14983e34c4 GIT binary patch literal 5672 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 PBpE_;^PyI{hNb)$WKhl$ literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_left_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..17a3b18585a24c14352433b5fb9798d0d84a3b56 GIT binary patch literal 685 zcmV;e0#f~nP)EX>4Tx04R}tkv&MmP!xqvQ?()$5j%)DWT;LSL`57+6^me@v=v%)FnQ@8G-*gu zTpR`0f`dPcRRmELS-bHwp_q#t=zmhi@;1h|XOgAjz4dU5N zOXs{#9AYI&AwDObFsMM{N3P2*zi}=)Ebz>bkx9)H^ZLbN2g@DIN`^{2LmXCAjq-)8 z%L?Z$&T6H`T6OXt2J_lVn(MSj5yuh|NJ4~+8p^1^LWE9@6cZ`Bk9qh<9DkBrGP%lN zIZc;D?bidg4#~2XU1)6o+{yw(t<_X|`2ClTWzuKS?ev)2q zYvChcU>mr&Zfo)$aJd5vKk1SoIg+2YP$&TJXEdf9Fmwy_t+{<`-Q)BD$WX7AZ-9eC zV7y4#>mL8^?d;pXZ(9BP0f_=~u;n5}m;e9(24YJ`L;xTFAOIjcq4HAz000SaNLh0L z01FZT01FZU(%pXi00007bV*G`2j>P66cIKjJo)7S005~;L_t(I%VS^|{^0)v1}0>h z2n|gCu^93nmwHT7nb{crPv#)n5KIGDxfvK(xf%Y?5JqU=S3)u5{}c`;JO=Q=@&CDs z5JNabA%<{>GW?&w@Sic~$3K{I77PPe*s*(-T^K_Dcul|yZ2WM{7=MEiF3!lrz`!BO zz*xY*_k^aMqT=D`gB_#rl4 Tb*jxr00000NkvXXu0mjf>NX>2 literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png new file mode 100644 index 0000000000000000000000000000000000000000..fd255ffdf74f19f7be2af128c5aabf0c8b8e8e17 GIT binary patch literal 6285 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 S=fTH_h$6!#hwcha%>Fx2vwoHU literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png.mcmeta b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png.mcmeta new file mode 100644 index 0000000000..ced9809160 --- /dev/null +++ b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "emissive": true + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right_emissive.png b/common/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay_right_emissive.png new file mode 100644 index 0000000000000000000000000000000000000000..8119bcb1985ea2ba788912e180348964ef87910d GIT binary patch literal 5726 zcmeHLX;c$g7Op4)g0z4e?qxumQIpEP)FCJm5X3|VX#v4*D^(SUB&m=D2)J-u8*LX_ zZ~>P_(I^b!r~~7IjLYDN!l6Yys3ST~D=?0TOSem7%e)E@f_lyz=S=_UW1y&4_kH(! z_kQob3&q+<6JmgOO5ev?OfK zFpw~5(WoKFa;q&S{^$>r2faxgcFf7oGyB1l(t@$KAI!lGlTwTickayZ5T{jF$|KBp z{`R+b>#=43P*vQqtQ{5QI(*xlz?9ICwv*4E`u%%Ti~h#3XWvu${_ELaHypCA(Ph2J zT{?a5`hwdGO;i5|De&tJhes5)U98LY*;28*!P!{poYen*`P9*yFLX@ItGbj{CU2~- z{o3lgbzsE>wr>2{FNeHJscri9m<4UwwqeJ##Dv}bEy|*sAv5PB)Q=tLno)hVZB}+t zZR9TzMJ`|Hg_%uM*`ka)lOE479^Zm=c+@0+@!7-nfW=M1svpIpW8@=Vv{37(A-A?G~<7CN`?^KaQ@n39%SJuj)^){0Y6%r%o&1_&<+4vr`H zuk)0ppZ6Np>~=zZ;N-=%Qv`l3EsB*z5oOZVdsAy3zZ&j7R-b#Q`HA((ZCC4T$ai)| zhp1iYgIBr9=TQk0*v;XhbK5V~eO_DWxTq0fnQad!~zcGnt;np8me(wB7DQVK2Sw=F=v|E&n-< z+r9tAAu;plAAR$K2Bt8m?KAcaI#M~}(RZ!G7W;oQ1Yrj4J?K|+cEEVQRi5W(uall^ zRpj}o){mN7`|#QylD)kAZwdB!#MgYK`tInr4=f?f8CX7wUaaI=bk9eSA=CLeS$7s zE4>mu$n9t4)RoG%K}g5}W7fVMYu^Tm-<%$NwtJfxRl%=pyfh{_Ih+({)>6mTwm4DO#T}Y1vXF z0L^Y*Th-_laCJ;WP0-(5Hq|bazAWB#pye=gL9pQNmzM|JSfYN?xIA!5UHZ0Xx{Xz1 zuS_fK^z#2~OhJhYnv zJjs|zX0riBko5F)b~>L;850q%R4PR{JcP$%0R+pGp*Ld|mfqw`Q*?32NfU0=7|a?< z57V5Oib^%hm`pGa_r#|&C=_;jy{TITpa){X3<#IaL3BFA(Zgg8NdqL^0e#TJ6b+g( z5=EM*R3lD?q>*~FuOkJ4+x-oxMy)L!0!K(KsRK|GSe4sn$(iAbNV^9uL83-yuz3No z`ykC4b+1@`Vxwnl={N=g-0i%5&^@`^zyPICpmGXNrNaxC%b4`~C_&*G0<{gL5rG}%kCQYNAZKd;4@aVs2r-_B#T5wv zg+xfQFp{rgNjPdDmqQ9jQYdtwm}As{s>HO8QPETcpd$DLmm}t=SOPU6VF@rH&QkG( zB9=%c;0k$s37-&1Y*Yk}hEhfy2DVe9!xBlvpii_-(1N2uk>N5XkIm_|L~1d!8aRM6 zpwSalx~X?6TB9T9nlV~Wu1G54i8&&^SR@hfMABZ+Jkn?awMesaIc$EHB=p9hARQnr zMpr5zuz7%N&|o9@l|UJzDM~A2(m}zrr+r!h4itfzF*#-?0V#*aN4Xr7!;9u|QLY$# zPvP)Ujsu<|H0q51hNh1X9MHAtVHy)yKf`9~I#YAWl&+_)N3F(om|)m;EKm&ZO2LGs zk%TQyz|}Q{Ct>-9)L)>6noWN(4Frtw4d=w1WM+x9WF&qe)L9>3sl_vA7(TgJevkJ6VM87(Lkr zAn)lBU;{X`7~t1s1FZ{mLd4z*yY&LG{+gfeefTw(fZp7fjW0hcqi<(J`{EWyOnl!8Df8goLqXx9~kwf zu-msE!vHaCD>Lk7i1F182IM>#6mIwR4v8JfP&K{nJRt7Jh^t{ZVmhsY_iT>y?~Q2^ p+6eCU+&^S{&(YD)IWFZL<5c||Bf(wXP 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 type) { return null; }, type); ItemStorage.SIDED.registerForBlockEntity((blockEntity, side) -> { + if (((IMachineBlockEntity)blockEntity).getMetaMachine() instanceof LDItemEndpointMachine fluidEndpointMachine) { + if (fluidEndpointMachine.getLevel().isClientSide) return null; + ILDEndpoint endpoint = fluidEndpointMachine.getLink(); + if (endpoint == null) return null; + Direction outputFacing = fluidEndpointMachine.getOutputFacing(); + IItemTransfer transfer = ItemTransferHelperImpl.getItemTransfer(blockEntity.getLevel(), endpoint.getPos().relative(outputFacing), outputFacing.getOpposite()); + if (transfer != null) { + return ItemTransferHelperImpl.toItemVariantStorage(new LDItemEndpointMachine.ItemHandlerWrapper(transfer)); + } + } var transfer = ((IMachineBlockEntity)blockEntity).getMetaMachine().getItemTransferCap(side); return transfer == null ? null : ItemTransferHelperImpl.toItemVariantStorage(transfer); }, type); FluidStorage.SIDED.registerForBlockEntity((blockEntity, side) -> { + if (((IMachineBlockEntity)blockEntity).getMetaMachine() instanceof LDFluidEndpointMachine fluidEndpointMachine) { + if (fluidEndpointMachine.getLevel().isClientSide) return null; + ILDEndpoint endpoint = fluidEndpointMachine.getLink(); + if (endpoint == null) return null; + Direction outputFacing = fluidEndpointMachine.getOutputFacing(); + IFluidTransfer transfer = FluidTransferHelper.getFluidTransfer(blockEntity.getLevel(), endpoint.getPos().relative(outputFacing), outputFacing.getOpposite()); + if (transfer != null) { + return FluidTransferHelperImpl.toFluidVariantStorage(new LDFluidEndpointMachine.FluidHandlerWrapper(transfer)); + } + } var transfer = ((IMachineBlockEntity)blockEntity).getMetaMachine().getFluidTransferCap(side); return transfer == null ? null : FluidTransferHelperImpl.toFluidVariantStorage(transfer); }, type); diff --git a/fabric/src/main/java/com/gregtechceu/gtceu/common/blockentity/fabric/ItemPipeBlockEntityImpl.java b/fabric/src/main/java/com/gregtechceu/gtceu/common/blockentity/fabric/ItemPipeBlockEntityImpl.java new file mode 100644 index 0000000000..99ca664750 --- /dev/null +++ b/fabric/src/main/java/com/gregtechceu/gtceu/common/blockentity/fabric/ItemPipeBlockEntityImpl.java @@ -0,0 +1,35 @@ +package com.gregtechceu.gtceu.common.blockentity.fabric; + +import com.gregtechceu.gtceu.api.capability.fabric.GTCapability; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.lowdragmc.lowdraglib.side.item.fabric.ItemTransferHelperImpl; +import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class ItemPipeBlockEntityImpl extends ItemPipeBlockEntity { + public ItemPipeBlockEntityImpl(BlockEntityType type, BlockPos pos, BlockState blockState) { + super(type, pos, blockState); + } + + public static ItemPipeBlockEntity create(BlockEntityType type, BlockPos pos, BlockState blockState) { + return new ItemPipeBlockEntityImpl(type, pos, blockState); + } + + public static void onBlockEntityRegister(BlockEntityType type) { + ItemStorage.SIDED.registerForBlockEntity((blockEntity, direction) -> { + Level world = blockEntity.getLevel(); + if (world.isClientSide()) + return null; + + if (blockEntity.getHandlers().size() == 0) + blockEntity.initHandlers(); + blockEntity.checkNetwork(); + return ItemTransferHelperImpl.toItemVariantStorage(blockEntity.getHandlers().getOrDefault(direction, blockEntity.getDefaultHandler())); + }, type); + GTCapability.CAPABILITY_COVERABLE.registerForBlockEntity((blockEntity, direction) -> blockEntity.getCoverContainer(), type); + GTCapability.CAPABILITY_TOOLABLE.registerForBlockEntity((blockEntity, direction) -> blockEntity, type); + } +} diff --git a/fabric/src/main/java/com/gregtechceu/gtceu/common/data/fabric/GTModelsImpl.java b/fabric/src/main/java/com/gregtechceu/gtceu/common/data/fabric/GTModelsImpl.java index 20a5c960ce..971ed7c611 100644 --- a/fabric/src/main/java/com/gregtechceu/gtceu/common/data/fabric/GTModelsImpl.java +++ b/fabric/src/main/java/com/gregtechceu/gtceu/common/data/fabric/GTModelsImpl.java @@ -66,4 +66,12 @@ public static void createTextureModel(DataGenContext ctx, public static void rubberTreeSaplingModel(DataGenContext context, RegistrateItemModelProvider provider) { provider.generated(context, provider.modLoc("block/" + provider.name(context))); } + + public static void longDistanceItemPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + prov.simpleBlock(ctx.getEntry(), prov.models().cubeAll("long_distance_item_pipeline", prov.modLoc("block/pipe/ld_item_pipe/block"))); + } + + public static void longDistanceFluidPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + prov.simpleBlock(ctx.getEntry(), prov.models().cubeAll("long_distance_fluid_pipeline", prov.modLoc("block/pipe/ld_fluid_pipe/block"))); + } } diff --git a/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline.json b/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline.json new file mode 100644 index 0000000000..44e8a2dcae --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "gtceu:block/long_distance_fluid_pipeline" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline.json b/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline.json new file mode 100644 index 0000000000..00bb3b7bd0 --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "gtceu:block/long_distance_item_pipeline" + } + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/battery_buffer.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/battery_buffer.json index 9f4f0debe4..200dc2392c 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/battery_buffer.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/battery_buffer.json @@ -37,7 +37,7 @@ ], "page": "gtceu:machines/battery_buffer", "position": [ - -250, + -150, 250 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/block_breaker.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/block_breaker.json index d0797b728c..78bb21b85a 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/block_breaker.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/block_breaker.json @@ -11,8 +11,8 @@ ], "page": "gtceu:machines/block_breaker", "position": [ - -50, - 250 + -350, + 300 ], "section": "gtceu:machines" } \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/charger.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/charger.json index a9ac534a7b..1676392511 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/charger.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/charger.json @@ -17,7 +17,7 @@ ], "page": "gtceu:machines/charger", "position": [ - -200, + -100, 250 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/crate.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/crate.json index 59246268b0..53c8701d14 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/crate.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/crate.json @@ -14,7 +14,7 @@ ], "page": "gtceu:machines/crate", "position": [ - -250, + -150, 300 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/drum.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/drum.json index 5e84a90731..335723659d 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/drum.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/drum.json @@ -15,7 +15,7 @@ ], "page": "gtceu:machines/drum", "position": [ - -200, + -100, 300 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/fisher.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/fisher.json index 01f7efb069..c3474b7083 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/fisher.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/fisher.json @@ -11,8 +11,8 @@ ], "page": "gtceu:machines/fisher", "position": [ - -100, - 250 + -400, + 300 ], "section": "gtceu:machines" } \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_fluid_pipeline.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_fluid_pipeline.json new file mode 100644 index 0000000000..332f046ec1 --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_fluid_pipeline.json @@ -0,0 +1,15 @@ +{ + "button_texture": { + "type": "item", + "res": "gtceu:long_distance_fluid_pipeline_endpoint" + }, + "items": [ + "gtceu:long_distance_fluid_pipeline_endpoint" + ], + "page": "gtceu:machines/ld_fluid_pipeline", + "position": [ + -200, + 250 + ], + "section": "gtceu:machines" +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_item_pipeline.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_item_pipeline.json new file mode 100644 index 0000000000..61d44dfb65 --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/ld_item_pipeline.json @@ -0,0 +1,15 @@ +{ + "button_texture": { + "type": "item", + "res": "gtceu:long_distance_item_pipeline_endpoint" + }, + "items": [ + "gtceu:long_distance_item_pipeline_endpoint" + ], + "page": "gtceu:machines/ld_item_pipeline", + "position": [ + -250, + 250 + ], + "section": "gtceu:machines" +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/miner.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/miner.json index f4b1f2de4f..35f63cffb8 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/miner.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/miner.json @@ -10,7 +10,7 @@ ], "page": "gtceu:machines/miner", "position": [ - -400, + -300, 300 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/pump.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/pump.json index 703b809813..721aee5db0 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/pump.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/pump.json @@ -11,7 +11,7 @@ ], "page": "gtceu:machines/pump", "position": [ - -150, + -50, 250 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_chest.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_chest.json index 7745858942..e308f5ed36 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_chest.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_chest.json @@ -16,7 +16,7 @@ ], "page": "gtceu:machines/super_chest", "position": [ - -350, + -250, 300 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_tank.json b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_tank.json index ee53a3117b..e6cea70aae 100644 --- a/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_tank.json +++ b/forge/src/generated/resources/assets/gtceu/compass/nodes/machines/super_tank.json @@ -16,7 +16,7 @@ ], "page": "gtceu:machines/super_tank", "position": [ - -300, + -200, 300 ], "section": "gtceu:machines" diff --git a/forge/src/generated/resources/assets/gtceu/lang/en_ud.json b/forge/src/generated/resources/assets/gtceu/lang/en_ud.json index 1949bb9f35..058120c242 100644 --- a/forge/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/forge/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -429,6 +429,10 @@ "block.gtceu.large_solidifier": "ʎɐɹɹⱯ uoıʇɐɔıɟıpıןoS ǝbɹɐꞀ", "block.gtceu.large_wiremill": "ʎɹoʇɔɐℲ ǝɹıM ǝbɹɐꞀ", "block.gtceu.laser_safe_engraving_casing": "buısɐƆ buıʌɐɹbuƎ ǝɟɐS-ɹǝsɐꞀ", + "block.gtceu.long_distance_fluid_pipeline": "ǝuıןǝdıԀ pınןℲ ǝɔuɐʇsıᗡ buoꞀ", + "block.gtceu.long_distance_fluid_pipeline_endpoint": "ʇuıodpuƎ ǝuıןǝdıԀ pınןℲ ǝɔuɐʇsıᗡ buoꞀ", + "block.gtceu.long_distance_item_pipeline": "ǝuıןǝdıԀ ɯǝʇI ǝɔuɐʇsıᗡ buoꞀ", + "block.gtceu.long_distance_item_pipeline_endpoint": "ʇuıodpuƎ ǝuıןǝdıԀ ɯǝʇI ǝɔuɐʇsıᗡ buoꞀ", "block.gtceu.lp_steam_alloy_smelter": "ɹǝʇןǝɯS ʎoןןⱯ ɯɐǝʇS ǝɹnssǝɹԀ ʍoꞀ", "block.gtceu.lp_steam_compressor": "ɹossǝɹdɯoƆ ɯɐǝʇS ǝɹnssǝɹԀ ʍoꞀ", "block.gtceu.lp_steam_extractor": "ɹoʇɔɐɹʇxƎ ɯɐǝʇS ǝɹnssǝɹԀ ʍoꞀ", @@ -1086,6 +1090,8 @@ "compass.node.gtceu.machines/gas_turbine": "ǝuıqɹn⟘ sɐ⅁", "compass.node.gtceu.machines/laser_engraver": "ɹǝʌɐɹbuƎ ɹǝsɐꞀ", "compass.node.gtceu.machines/lathe": "ǝɥʇɐꞀ", + "compass.node.gtceu.machines/ld_fluid_pipeline": "ǝuıןǝdıԀ pınןℲ pꞀ", + "compass.node.gtceu.machines/ld_item_pipeline": "ǝuıןǝdıԀ ɯǝʇI pꞀ", "compass.node.gtceu.machines/macerator": "ɹoʇɐɹǝɔɐW", "compass.node.gtceu.machines/machine_hull": "ןןnH ǝuıɥɔɐW", "compass.node.gtceu.machines/miner": "ɹǝuıW", @@ -1270,6 +1276,8 @@ "config.gtceu.option.hideFacadesInJEI": "IƎſuIsǝpɐɔɐℲǝpıɥ", "config.gtceu.option.hideFilledCellsInJEI": "IƎſuIsןןǝƆpǝןןıℲǝpıɥ", "config.gtceu.option.infiniteBedrockOresFluids": "spınןℲsǝɹOʞɔoɹpǝᗺǝʇıuıɟuı", + "config.gtceu.option.ldFluidPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀpınןℲpן", + "config.gtceu.option.ldItemPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀɯǝʇIpן", "config.gtceu.option.machineSounds": "spunoSǝuıɥɔɐɯ", "config.gtceu.option.machines": "sǝuıɥɔɐɯ", "config.gtceu.option.machinesEmissiveTextures": "sǝɹnʇxǝ⟘ǝʌıssıɯƎsǝuıɥɔɐɯ", @@ -1940,6 +1948,10 @@ "gtceu.machine.electromagnetic_separator.mv.tooltip": "ʇsǝɹ ǝɥʇ ɯoɹɟ sǝɹO ɔıʇǝubɐɯ ǝɥʇ buıʇɐɹɐdǝSㄥ§", "gtceu.machine.electromagnetic_separator.uv.tooltip": "ɹǝןןǝdsıᗡ ℲWƎㄥ§", "gtceu.machine.electromagnetic_separator.zpm.tooltip": "ɹǝzıɹobǝʇɐƆ WƎㄥ§", + "gtceu.machine.endpoint.tooltip.1": "˙ǝuıןǝdıd ɐ ǝʇɐǝɹɔ oʇ sʞɔoןq ㄥ§ǝdıԀ ǝɔuɐʇsıᗡ buoꞀɟ§ ɥʇıʍ ʇɔǝuuoƆ", + "gtceu.machine.endpoint.tooltip.2": "˙ʇuıodpuǝ ㄥ§ʇndʇnO Ɩɟ§ puɐ ㄥ§ʇnduI Ɩɟ§ ʎןʇɔɐxǝ ǝʌɐɥ ʇsnɯ sǝuıןǝdıԀ", + "gtceu.machine.endpoint.tooltip.3": "˙ㄥ§pǝpɐoן-ʞunɥɔɟ§ ǝq oʇ pǝǝu sʇuıodpuǝ ǝuıןǝdıd ʎןuO", + "gtceu.machine.endpoint.tooltip.min_length": "sʞɔoןᗺ %dɟ§ :ǝɔuɐʇsıᗡ ʇuıodpuƎ ɯnɯıuıWq§", "gtceu.machine.energy_converter.description": "ƎℲ puɐ ∩Ǝ uǝǝʍʇǝq ʎbɹǝuƎ sʇɹǝʌuoƆ", "gtceu.machine.energy_converter.message_conversion_eu": "ǝʌıʇɐN %d :ʇnO '∩Ǝ %d Ɐ%d :uI '∩Ǝ buıʇɹǝʌuoƆ", "gtceu.machine.energy_converter.message_conversion_native": "∩Ǝ %d Ɐ%d :ʇnO 'ƎℲ %d :uI 'ʎbɹǝuƎ ǝʌıʇɐN buıʇɹǝʌuoƆ", @@ -4247,11 +4259,19 @@ "tagprefix.netherrack": "ǝɹO %s ɹǝɥʇǝN", "tagprefix.nugget": "ʇǝbbnN %s", "tagprefix.pipe_huge_fluid": "ǝdıԀ pınןℲ %s ǝbnH", + "tagprefix.pipe_huge_item": "ǝdıԀ ɯǝʇI %s ǝbnH", + "tagprefix.pipe_huge_restrictive": "ǝdıԀ ɯǝʇI %s ǝʌıʇɔıɹʇsǝᴚ ǝbnH", "tagprefix.pipe_large_fluid": "ǝdıԀ pınןℲ %s ǝbɹɐꞀ", + "tagprefix.pipe_large_item": "ǝdıԀ ɯǝʇI %s ǝbɹɐꞀ", + "tagprefix.pipe_large_restrictive": "ǝdıԀ ɯǝʇI %s ǝʌıʇɔıɹʇsǝᴚ ǝbɹɐꞀ", "tagprefix.pipe_nonuple_fluid": "ǝdıԀ pınןℲ %s ǝןdnuoN", "tagprefix.pipe_normal_fluid": "ǝdıԀ pınןℲ %s ןɐɯɹoN", + "tagprefix.pipe_normal_item": "ǝdıԀ ɯǝʇI %s ןɐɯɹoN", + "tagprefix.pipe_normal_restrictive": "ǝdıԀ ɯǝʇI %s ǝʌıʇɔıɹʇsǝᴚ ןɐɯɹoN", "tagprefix.pipe_quadruple_fluid": "ǝdıԀ pınןℲ %s ǝןdnɹpɐnὉ", "tagprefix.pipe_small_fluid": "ǝdıԀ pınןℲ %s ןןɐɯS", + "tagprefix.pipe_small_item": "ǝdıԀ ɯǝʇI %s ןןɐɯS", + "tagprefix.pipe_small_restrictive": "ǝdıԀ ɯǝʇI %s ǝʌıʇɔıɹʇsǝᴚ ןןɐɯS", "tagprefix.pipe_tiny_fluid": "ǝdıԀ pınןℲ %s ʎuı⟘", "tagprefix.plate": "ǝʇɐןԀ %s", "tagprefix.polymer.dense_plate": "ʇǝǝɥS %s ǝsuǝᗡ", diff --git a/forge/src/generated/resources/assets/gtceu/lang/en_us.json b/forge/src/generated/resources/assets/gtceu/lang/en_us.json index dd54f5fa82..b5c618a728 100644 --- a/forge/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/forge/src/generated/resources/assets/gtceu/lang/en_us.json @@ -429,6 +429,10 @@ "block.gtceu.large_solidifier": "Large Solidification Array", "block.gtceu.large_wiremill": "Large Wire Factory", "block.gtceu.laser_safe_engraving_casing": "Laser-Safe Engraving Casing", + "block.gtceu.long_distance_fluid_pipeline": "Long Distance Fluid Pipeline", + "block.gtceu.long_distance_fluid_pipeline_endpoint": "Long Distance Fluid Pipeline Endpoint", + "block.gtceu.long_distance_item_pipeline": "Long Distance Item Pipeline", + "block.gtceu.long_distance_item_pipeline_endpoint": "Long Distance Item Pipeline Endpoint", "block.gtceu.lp_steam_alloy_smelter": "Low Pressure Steam Alloy Smelter", "block.gtceu.lp_steam_compressor": "Low Pressure Steam Compressor", "block.gtceu.lp_steam_extractor": "Low Pressure Steam Extractor", @@ -1086,6 +1090,8 @@ "compass.node.gtceu.machines/gas_turbine": "Gas Turbine", "compass.node.gtceu.machines/laser_engraver": "Laser Engraver", "compass.node.gtceu.machines/lathe": "Lathe", + "compass.node.gtceu.machines/ld_fluid_pipeline": "Ld Fluid Pipeline", + "compass.node.gtceu.machines/ld_item_pipeline": "Ld Item Pipeline", "compass.node.gtceu.machines/macerator": "Macerator", "compass.node.gtceu.machines/machine_hull": "Machine Hull", "compass.node.gtceu.machines/miner": "Miner", @@ -1270,6 +1276,8 @@ "config.gtceu.option.hideFacadesInJEI": "hideFacadesInJEI", "config.gtceu.option.hideFilledCellsInJEI": "hideFilledCellsInJEI", "config.gtceu.option.infiniteBedrockOresFluids": "infiniteBedrockOresFluids", + "config.gtceu.option.ldFluidPipeMinDistance": "ldFluidPipeMinDistance", + "config.gtceu.option.ldItemPipeMinDistance": "ldItemPipeMinDistance", "config.gtceu.option.machineSounds": "machineSounds", "config.gtceu.option.machines": "machines", "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", @@ -1940,6 +1948,10 @@ "gtceu.machine.electromagnetic_separator.mv.tooltip": "§7Separating the magnetic Ores from the rest", "gtceu.machine.electromagnetic_separator.uv.tooltip": "§7EMF Dispeller", "gtceu.machine.electromagnetic_separator.zpm.tooltip": "§7EM Categorizer", + "gtceu.machine.endpoint.tooltip.1": "Connect with §fLong Distance Pipe§7 blocks to create a pipeline.", + "gtceu.machine.endpoint.tooltip.2": "Pipelines must have exactly §f1 Input§7 and §f1 Output§7 endpoint.", + "gtceu.machine.endpoint.tooltip.3": "Only pipeline endpoints need to be §fchunk-loaded§7.", + "gtceu.machine.endpoint.tooltip.min_length": "§bMinimum Endpoint Distance: §f%d Blocks", "gtceu.machine.energy_converter.description": "Converts Energy between EU and FE", "gtceu.machine.energy_converter.message_conversion_eu": "Converting EU, In: %dA %d EU, Out: %d Native", "gtceu.machine.energy_converter.message_conversion_native": "Converting Native Energy, In: %d FE, Out: %dA %d EU", @@ -4247,11 +4259,19 @@ "tagprefix.netherrack": "Nether %s Ore", "tagprefix.nugget": "%s Nugget", "tagprefix.pipe_huge_fluid": "Huge %s Fluid Pipe", + "tagprefix.pipe_huge_item": "Huge %s Item Pipe", + "tagprefix.pipe_huge_restrictive": "Huge Restrictive %s Item Pipe", "tagprefix.pipe_large_fluid": "Large %s Fluid Pipe", + "tagprefix.pipe_large_item": "Large %s Item Pipe", + "tagprefix.pipe_large_restrictive": "Large Restrictive %s Item Pipe", "tagprefix.pipe_nonuple_fluid": "Nonuple %s Fluid Pipe", "tagprefix.pipe_normal_fluid": "Normal %s Fluid Pipe", + "tagprefix.pipe_normal_item": "Normal %s Item Pipe", + "tagprefix.pipe_normal_restrictive": "Normal Restrictive %s Item Pipe", "tagprefix.pipe_quadruple_fluid": "Quadruple %s Fluid Pipe", "tagprefix.pipe_small_fluid": "Small %s Fluid Pipe", + "tagprefix.pipe_small_item": "Small %s Item Pipe", + "tagprefix.pipe_small_restrictive": "Small Restrictive %s Item Pipe", "tagprefix.pipe_tiny_fluid": "Tiny %s Fluid Pipe", "tagprefix.plate": "%s Plate", "tagprefix.polymer.dense_plate": "Dense %s Sheet", diff --git a/forge/src/generated/resources/assets/gtceu/models/block/long_distance_fluid_pipeline.json b/forge/src/generated/resources/assets/gtceu/models/block/long_distance_fluid_pipeline.json new file mode 100644 index 0000000000..88cc1b3e8a --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/models/block/long_distance_fluid_pipeline.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "gtceu:block/pipe/ld_fluid_pipe/block" + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/models/block/long_distance_item_pipeline.json b/forge/src/generated/resources/assets/gtceu/models/block/long_distance_item_pipeline.json new file mode 100644 index 0000000000..323e0e4dfa --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/models/block/long_distance_item_pipeline.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "gtceu:block/pipe/ld_item_pipe/block" + } +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/models/item/long_distance_fluid_pipeline.json b/forge/src/generated/resources/assets/gtceu/models/item/long_distance_fluid_pipeline.json new file mode 100644 index 0000000000..d53ef5b472 --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/models/item/long_distance_fluid_pipeline.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/long_distance_fluid_pipeline" +} \ No newline at end of file diff --git a/forge/src/generated/resources/assets/gtceu/models/item/long_distance_item_pipeline.json b/forge/src/generated/resources/assets/gtceu/models/item/long_distance_item_pipeline.json new file mode 100644 index 0000000000..23526f23e5 --- /dev/null +++ b/forge/src/generated/resources/assets/gtceu/models/item/long_distance_item_pipeline.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/long_distance_item_pipeline" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_fluid_pipeline.json b/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_fluid_pipeline.json new file mode 100644 index 0000000000..85f62088d5 --- /dev/null +++ b/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_fluid_pipeline.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "gtceu:long_distance_fluid_pipeline" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "gtceu:blocks/long_distance_fluid_pipeline" +} \ No newline at end of file diff --git a/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_item_pipeline.json b/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_item_pipeline.json new file mode 100644 index 0000000000..262f0dc70a --- /dev/null +++ b/forge/src/generated/resources/data/gtceu/loot_tables/blocks/long_distance_item_pipeline.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "gtceu:long_distance_item_pipeline" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "gtceu:blocks/long_distance_item_pipeline" +} \ No newline at end of file diff --git a/forge/src/main/java/com/gregtechceu/gtceu/api/blockentity/forge/MetaMachineBlockEntityImpl.java b/forge/src/main/java/com/gregtechceu/gtceu/api/blockentity/forge/MetaMachineBlockEntityImpl.java index c1309b93a6..a8954d5f73 100644 --- a/forge/src/main/java/com/gregtechceu/gtceu/api/blockentity/forge/MetaMachineBlockEntityImpl.java +++ b/forge/src/main/java/com/gregtechceu/gtceu/api/blockentity/forge/MetaMachineBlockEntityImpl.java @@ -9,9 +9,15 @@ import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.api.pipenet.longdistance.ILDEndpoint; import com.gregtechceu.gtceu.client.renderer.GTRendererProvider; +import com.gregtechceu.gtceu.common.pipelike.fluidpipe.longdistance.LDFluidEndpointMachine; +import com.gregtechceu.gtceu.common.pipelike.item.longdistance.LDItemEndpointMachine; import com.lowdragmc.lowdraglib.client.renderer.IRenderer; +import com.lowdragmc.lowdraglib.side.fluid.FluidTransferHelper; +import com.lowdragmc.lowdraglib.side.fluid.IFluidTransfer; import com.lowdragmc.lowdraglib.side.fluid.forge.FluidTransferHelperImpl; +import com.lowdragmc.lowdraglib.side.item.IItemTransfer; import com.lowdragmc.lowdraglib.side.item.forge.ItemTransferHelperImpl; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -95,11 +101,35 @@ public static LazyOptional getCapability(MetaMachine machine, @NotNull C return GTCapability.CAPABILITY_MAINTENANCE_MACHINE.orEmpty(cap, LazyOptional.of(() -> maintenanceMachine)); } } else if (cap == ForgeCapabilities.ITEM_HANDLER) { + if (machine instanceof LDItemEndpointMachine fluidEndpointMachine) { + if (machine.getLevel().isClientSide) return null; + ILDEndpoint endpoint = fluidEndpointMachine.getLink(); + if (endpoint == null) return null; + Direction outputFacing = fluidEndpointMachine.getOutputFacing(); + IItemTransfer transfer = ItemTransferHelperImpl.getItemTransfer(machine.getLevel(), endpoint.getPos().relative(outputFacing), outputFacing.getOpposite()); + if (transfer != null) { + return ForgeCapabilities.ITEM_HANDLER.orEmpty(cap, LazyOptional.of(() -> + ItemTransferHelperImpl.toItemHandler(new LDItemEndpointMachine.ItemHandlerWrapper(transfer)) + )); + } + } var transfer = machine.getItemTransferCap(side); if (transfer != null) { return ForgeCapabilities.ITEM_HANDLER.orEmpty(cap, LazyOptional.of(() -> ItemTransferHelperImpl.toItemHandler(transfer))); } } else if (cap == ForgeCapabilities.FLUID_HANDLER) { + if (machine instanceof LDFluidEndpointMachine fluidEndpointMachine) { + if (machine.getLevel().isClientSide) return null; + ILDEndpoint endpoint = fluidEndpointMachine.getLink(); + if (endpoint == null) return null; + Direction outputFacing = fluidEndpointMachine.getOutputFacing(); + IFluidTransfer transfer = FluidTransferHelper.getFluidTransfer(machine.getLevel(), endpoint.getPos().relative(outputFacing), outputFacing.getOpposite()); + if (transfer != null) { + return ForgeCapabilities.FLUID_HANDLER.orEmpty(cap, LazyOptional.of(() -> + FluidTransferHelperImpl.toFluidHandler(new LDFluidEndpointMachine.FluidHandlerWrapper(transfer)) + )); + } + } var transfer = machine.getFluidTransferCap(side); if (transfer != null) { return ForgeCapabilities.FLUID_HANDLER.orEmpty(cap, LazyOptional.of(() -> FluidTransferHelperImpl.toFluidHandler(transfer))); diff --git a/forge/src/main/java/com/gregtechceu/gtceu/common/blockentity/forge/ItemPipeBlockEntityImpl.java b/forge/src/main/java/com/gregtechceu/gtceu/common/blockentity/forge/ItemPipeBlockEntityImpl.java new file mode 100644 index 0000000000..97f882feb9 --- /dev/null +++ b/forge/src/main/java/com/gregtechceu/gtceu/common/blockentity/forge/ItemPipeBlockEntityImpl.java @@ -0,0 +1,47 @@ +package com.gregtechceu.gtceu.common.blockentity.forge; + +import com.gregtechceu.gtceu.api.capability.forge.GTCapability; +import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; +import com.lowdragmc.lowdraglib.side.item.forge.ItemTransferHelperImpl; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ItemPipeBlockEntityImpl extends ItemPipeBlockEntity { + public ItemPipeBlockEntityImpl(BlockEntityType type, BlockPos pos, BlockState blockState) { + super(type, pos, blockState); + } + + public static ItemPipeBlockEntity create(BlockEntityType type, BlockPos pos, BlockState blockState) { + return new ItemPipeBlockEntityImpl(type, pos, blockState); + } + + public static void onBlockEntityRegister(BlockEntityType cableBlockEntityBlockEntityType) { + } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { + if (cap == ForgeCapabilities.ITEM_HANDLER) { + Level world = getLevel(); + if (world.isClientSide()) + return LazyOptional.empty(); + + if (getHandlers().size() == 0) + initHandlers(); + checkNetwork(); + return ForgeCapabilities.ITEM_HANDLER.orEmpty(cap, LazyOptional.of(() -> ItemTransferHelperImpl.toItemHandler(getHandlers().getOrDefault(side, getDefaultHandler())))); + } else if (cap == GTCapability.CAPABILITY_COVERABLE) { + return GTCapability.CAPABILITY_COVERABLE.orEmpty(cap, LazyOptional.of(this::getCoverContainer)); + } else if (cap == GTCapability.CAPABILITY_TOOLABLE) { + return GTCapability.CAPABILITY_TOOLABLE.orEmpty(cap, LazyOptional.of(() -> this)); + } + return super.getCapability(cap, side); + } +} diff --git a/forge/src/main/java/com/gregtechceu/gtceu/common/data/forge/GTModelsImpl.java b/forge/src/main/java/com/gregtechceu/gtceu/common/data/forge/GTModelsImpl.java index 6ef2a6bd43..3c6c3f897a 100644 --- a/forge/src/main/java/com/gregtechceu/gtceu/common/data/forge/GTModelsImpl.java +++ b/forge/src/main/java/com/gregtechceu/gtceu/common/data/forge/GTModelsImpl.java @@ -67,4 +67,12 @@ public static void createTextureModel(DataGenContext ctx, public static void rubberTreeSaplingModel(DataGenContext context, RegistrateItemModelProvider provider) { provider.generated(context, provider.modLoc("block/" + provider.name(context))); } + + public static void longDistanceItemPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + prov.simpleBlock(ctx.getEntry(), prov.models().cubeAll("long_distance_item_pipeline", prov.modLoc("block/pipe/ld_item_pipe/block"))); + } + + public static void longDistanceFluidPipeModel(DataGenContext ctx, RegistrateBlockstateProvider prov) { + prov.simpleBlock(ctx.getEntry(), prov.models().cubeAll("long_distance_fluid_pipeline", prov.modLoc("block/pipe/ld_fluid_pipe/block"))); + } } diff --git a/gradle.properties b/gradle.properties index 9cdeecd48b..2ba4dd7946 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,10 @@ org.gradle.jvmargs = -Xmx6G # Mod Info mod_id = gtceu mod_name = GregTech -mod_version = 1.0.12.g +mod_version = 1.0.13 mod_description = GregTech CE Unofficial, ported from 1.12.2 mod_license = LGPL-3.0 license -mod_url = https://https://github.com/GregTechCEu/GregTechCEu-1.19/ +mod_url = https://github.com/GregTechCEu/GregTech-Modern/ maven_group = com.gregtechceu.gtceu