├── src ├── main │ ├── resources │ │ ├── assets │ │ │ └── pipez │ │ │ │ ├── sounds.json │ │ │ │ ├── models │ │ │ │ ├── item │ │ │ │ │ ├── gas_pipe.json │ │ │ │ │ ├── item_pipe.json │ │ │ │ │ ├── energy_pipe.json │ │ │ │ │ ├── fluid_pipe.json │ │ │ │ │ ├── universal_pipe.json │ │ │ │ │ ├── basic_upgrade.json │ │ │ │ │ ├── wrench.json │ │ │ │ │ ├── advanced_upgrade.json │ │ │ │ │ ├── improved_upgrade.json │ │ │ │ │ ├── infinity_upgrade.json │ │ │ │ │ ├── ultimate_upgrade.json │ │ │ │ │ └── filter_destination_tool.json │ │ │ │ └── block │ │ │ │ │ ├── gas_pipe_core.json │ │ │ │ │ ├── gas_pipe_part.json │ │ │ │ │ ├── fluid_pipe_core.json │ │ │ │ │ ├── fluid_pipe_part.json │ │ │ │ │ ├── item_pipe_core.json │ │ │ │ │ ├── item_pipe_part.json │ │ │ │ │ ├── energy_pipe_core.json │ │ │ │ │ ├── energy_pipe_part.json │ │ │ │ │ ├── gas_pipe_extract.json │ │ │ │ │ ├── item_pipe_extract.json │ │ │ │ │ ├── energy_pipe_extract.json │ │ │ │ │ ├── fluid_pipe_extract.json │ │ │ │ │ ├── universal_pipe_core.json │ │ │ │ │ ├── universal_pipe_part.json │ │ │ │ │ ├── universal_pipe_extract.json │ │ │ │ │ ├── pipe_part.json │ │ │ │ │ ├── pipe_extract.json │ │ │ │ │ └── pipe_core.json │ │ │ │ ├── items │ │ │ │ ├── wrench.json │ │ │ │ ├── gas_pipe.json │ │ │ │ ├── energy_pipe.json │ │ │ │ ├── fluid_pipe.json │ │ │ │ ├── item_pipe.json │ │ │ │ ├── basic_upgrade.json │ │ │ │ ├── advanced_upgrade.json │ │ │ │ ├── improved_upgrade.json │ │ │ │ ├── infinity_upgrade.json │ │ │ │ ├── ultimate_upgrade.json │ │ │ │ ├── universal_pipe.json │ │ │ │ └── filter_destination_tool.json │ │ │ │ ├── textures │ │ │ │ ├── item │ │ │ │ │ ├── wrench.png │ │ │ │ │ ├── basic_upgrade.png │ │ │ │ │ ├── advanced_upgrade.png │ │ │ │ │ ├── improved_upgrade.png │ │ │ │ │ ├── infinity_upgrade.png │ │ │ │ │ ├── ultimate_upgrade.png │ │ │ │ │ └── filter_destination_tool.png │ │ │ │ ├── block │ │ │ │ │ ├── fluid_pipe.png │ │ │ │ │ ├── gas_pipe.png │ │ │ │ │ ├── item_pipe.png │ │ │ │ │ ├── energy_pipe.png │ │ │ │ │ └── universal_pipe.png │ │ │ │ └── gui │ │ │ │ │ └── container │ │ │ │ │ ├── extract.png │ │ │ │ │ └── filter.png │ │ │ │ ├── blockstates │ │ │ │ ├── gas_pipe.json │ │ │ │ ├── item_pipe.json │ │ │ │ ├── fluid_pipe.json │ │ │ │ ├── energy_pipe.json │ │ │ │ └── universal_pipe.json │ │ │ │ └── lang │ │ │ │ ├── zh_cn.json │ │ │ │ ├── ja_jp.json │ │ │ │ ├── ko_kr.json │ │ │ │ └── en_us.json │ │ ├── icon.png │ │ ├── pack.mcmeta │ │ ├── data │ │ │ ├── pipez │ │ │ │ ├── recipe │ │ │ │ │ ├── clear_upgrade.json │ │ │ │ │ ├── copy_upgrade_basic.json │ │ │ │ │ ├── copy_upgrade_advanced.json │ │ │ │ │ ├── copy_upgrade_improved.json │ │ │ │ │ ├── copy_upgrade_infinity.json │ │ │ │ │ ├── copy_upgrade_ultimate.json │ │ │ │ │ ├── wrench.json │ │ │ │ │ ├── fluid_pipe.json │ │ │ │ │ ├── item_pipe.json │ │ │ │ │ ├── basic_upgrade.json │ │ │ │ │ ├── energy_pipe.json │ │ │ │ │ ├── improved_upgrade.json │ │ │ │ │ ├── advanced_upgrade.json │ │ │ │ │ ├── ultimate_upgrade.json │ │ │ │ │ ├── filter_destination_tool.json │ │ │ │ │ ├── universal_pipe.json │ │ │ │ │ └── gas_pipe.json │ │ │ │ └── loot_table │ │ │ │ │ └── blocks │ │ │ │ │ ├── fluid_pipe.json │ │ │ │ │ ├── gas_pipe.json │ │ │ │ │ ├── item_pipe.json │ │ │ │ │ ├── energy_pipe.json │ │ │ │ │ └── universal_pipe.json │ │ │ └── minecraft │ │ │ │ └── tags │ │ │ │ └── block │ │ │ │ └── mineable │ │ │ │ └── pickaxe.json │ │ └── META-INF │ │ │ └── neoforge.mods.toml │ └── java │ │ └── de │ │ └── maxhenkel │ │ └── pipez │ │ ├── gui │ │ ├── IPipeContainer.java │ │ ├── UpgradeSlot.java │ │ ├── containerfactory │ │ │ ├── PipeContainerFactory.java │ │ │ ├── FilterContainerFactory.java │ │ │ ├── PipeContainerProvider.java │ │ │ └── FilterContainerProvider.java │ │ ├── FilterContainer.java │ │ ├── ExtractContainer.java │ │ ├── Containers.java │ │ ├── WidgetBase.java │ │ └── CycleIconButton.java │ │ ├── ClientConfig.java │ │ ├── blocks │ │ ├── tileentity │ │ │ ├── render │ │ │ │ ├── PipeRenderState.java │ │ │ │ ├── GasPipeRenderer.java │ │ │ │ ├── ItemPipeRenderer.java │ │ │ │ ├── FluidPipeRenderer.java │ │ │ │ ├── EnergyPipeRenderer.java │ │ │ │ ├── UniversalPipeRenderer.java │ │ │ │ └── PipeRenderer.java │ │ │ ├── GasPipeTileEntity.java │ │ │ ├── ItemPipeTileEntity.java │ │ │ ├── FluidPipeTileEntity.java │ │ │ ├── EnergyPipeTileEntity.java │ │ │ ├── UniversalPipeTileEntity.java │ │ │ ├── configuration │ │ │ │ ├── FilterCache.java │ │ │ │ ├── FilterModeCache.java │ │ │ │ ├── DistributionCache.java │ │ │ │ ├── RedstoneModeCache.java │ │ │ │ └── CachedPipeConfiguration.java │ │ │ └── ModTileEntities.java │ │ ├── ModBlocks.java │ │ ├── ItemPipeBlock.java │ │ ├── FluidPipeBlock.java │ │ ├── EnergyPipeBlock.java │ │ ├── GasPipeBlock.java │ │ └── UniversalPipeBlock.java │ │ ├── utils │ │ ├── MekanismUtils.java │ │ ├── ChemicalTag.java │ │ ├── NbtUtils.java │ │ ├── DummyItemHandler.java │ │ ├── ComponentUtils.java │ │ ├── DummyFluidHandler.java │ │ ├── PipeEnergyStorage.java │ │ ├── WrappedGasStack.java │ │ └── GasUtils.java │ │ ├── integration │ │ ├── theoneprobe │ │ │ ├── TheOneProbeModule.java │ │ │ └── TileInfoProvider.java │ │ ├── IMC.java │ │ ├── jei │ │ │ ├── ExtractScreenHandler.java │ │ │ ├── JEIPlugin.java │ │ │ └── FilterScreenGhostIngredientHandler.java │ │ └── waila │ │ │ ├── PluginPipes.java │ │ │ ├── HUDHandlerPipes.java │ │ │ └── DataProviderPipes.java │ │ ├── tags │ │ └── ModItemTags.java │ │ ├── capabilities │ │ └── ModCapabilities.java │ │ ├── PipezClientMod.java │ │ ├── codec │ │ └── EnumIndexCodec.java │ │ ├── recipes │ │ ├── ModRecipes.java │ │ └── ClearComponentsRecipe.java │ │ ├── datacomponents │ │ ├── EnergyData.java │ │ ├── ItemData.java │ │ ├── GasData.java │ │ └── FluidData.java │ │ ├── items │ │ ├── WrenchItem.java │ │ ├── FilterDestinationToolItem.java │ │ ├── UpgradeItem.java │ │ └── ModItems.java │ │ ├── Upgrade.java │ │ ├── ItemFilter.java │ │ ├── FluidFilter.java │ │ ├── DirectionalPosition.java │ │ ├── net │ │ ├── CycleFilterModeMessage.java │ │ ├── OpenExtractMessage.java │ │ ├── CycleDistributionMessage.java │ │ ├── CycleRedstoneModeMessage.java │ │ ├── RemoveFilterMessage.java │ │ ├── EditFilterMessage.java │ │ └── UpdateFilterMessage.java │ │ ├── ModCreativeTabs.java │ │ ├── ModelRegistry.java │ │ ├── events │ │ └── BlockEvents.java │ │ └── PipezMod.java └── generated │ └── resources │ └── data │ ├── c │ └── tags │ │ └── item │ │ ├── tools.json │ │ ├── tools │ │ └── wrench.json │ │ └── wrenches.json │ └── pipez │ └── tags │ └── item │ └── upgrades.json ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .github └── ISSUE_TEMPLATE │ ├── config.yml │ ├── translation.yml │ └── bug_report.yml ├── changelog.md ├── settings.gradle ├── .gitignore ├── gradle.properties └── gradlew.bat /src/main/resources/assets/pipez/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/icon.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/gas_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/gas_pipe_core" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/item_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/item_pipe_core" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/energy_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/energy_pipe_core" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/fluid_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/fluid_pipe_core" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/universal_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/universal_pipe_core" 3 | } 4 | -------------------------------------------------------------------------------- /src/generated/resources/data/c/tags/item/tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "#c:tools/wrench" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/generated/resources/data/c/tags/item/tools/wrench.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "pipez:wrench" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/generated/resources/data/c/tags/item/wrenches.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "#c:tools/wrench" 5 | ] 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/wrench.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/wrench" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/gas_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/gas_pipe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/energy_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/energy_pipe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/fluid_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/fluid_pipe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/item_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/item_pipe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/wrench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/wrench.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/basic_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/basic_upgrade" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/advanced_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/advanced_upgrade" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/improved_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/improved_upgrade" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/infinity_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/infinity_upgrade" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/ultimate_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/ultimate_upgrade" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/universal_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/universal_pipe" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/block/fluid_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/block/fluid_pipe.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/block/gas_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/block/gas_pipe.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/block/item_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/block/item_pipe.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/block/energy_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/block/energy_pipe.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/basic_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/basic_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/block/universal_pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/block/universal_pipe.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/gui/container/extract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/gui/container/extract.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/gui/container/filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/gui/container/filter.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/advanced_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/advanced_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/improved_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/improved_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/infinity_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/infinity_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/ultimate_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/ultimate_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/items/filter_destination_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "model": { 3 | "type": "minecraft:model", 4 | "model": "pipez:item/filter_destination_tool" 5 | } 6 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/basic_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/basic_upgrade" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/wrench.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "minecraft:item/handheld", 3 | "textures": { 4 | "layer0": "pipez:item/wrench" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "pipez resources", 4 | "min_format": [65, 0], 5 | "max_format": [999, 0] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/advanced_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/advanced_upgrade" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/improved_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/improved_upgrade" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/infinity_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/infinity_upgrade" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/ultimate_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/ultimate_upgrade" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: FAQ 4 | about: Frequently asked questions 5 | url: https://modrepo.de/minecraft/pipez/faq 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/textures/item/filter_destination_tool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henkelmax/pipez/HEAD/src/main/resources/assets/pipez/textures/item/filter_destination_tool.png -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/gas_pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_core", 3 | "textures": { 4 | "0": "pipez:block/gas_pipe", 5 | "particle": "pipez:block/gas_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/gas_pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_part", 3 | "textures": { 4 | "0": "pipez:block/gas_pipe", 5 | "particle": "pipez:block/gas_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/item/filter_destination_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "pipez:item/filter_destination_tool" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/fluid_pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_core", 3 | "textures": { 4 | "0": "pipez:block/fluid_pipe", 5 | "particle": "pipez:block/fluid_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/fluid_pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_part", 3 | "textures": { 4 | "0": "pipez:block/fluid_pipe", 5 | "particle": "pipez:block/fluid_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/item_pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_core", 3 | "textures": { 4 | "0": "pipez:block/item_pipe", 5 | "particle": "pipez:block/item_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/item_pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_part", 3 | "textures": { 4 | "0": "pipez:block/item_pipe", 5 | "particle": "pipez:block/item_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/energy_pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_core", 3 | "textures": { 4 | "0": "pipez:block/energy_pipe", 5 | "particle": "pipez:block/energy_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/energy_pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_part", 3 | "textures": { 4 | "0": "pipez:block/energy_pipe", 5 | "particle": "pipez:block/energy_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/gas_pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_extract", 3 | "textures": { 4 | "0": "pipez:block/gas_pipe", 5 | "particle": "pipez:block/gas_pipe" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/item_pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_extract", 3 | "textures": { 4 | "0": "pipez:block/item_pipe", 5 | "particle": "pipez:block/item_pipe" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/energy_pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_extract", 3 | "textures": { 4 | "0": "pipez:block/energy_pipe", 5 | "particle": "pipez:block/energy_pipe" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/fluid_pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_extract", 3 | "textures": { 4 | "0": "pipez:block/fluid_pipe", 5 | "particle": "pipez:block/fluid_pipe" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/universal_pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_core", 3 | "textures": { 4 | "0": "pipez:block/universal_pipe", 5 | "particle": "pipez:block/universal_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/universal_pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_part", 3 | "textures": { 4 | "0": "pipez:block/universal_pipe", 5 | "particle": "pipez:block/universal_pipe" 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/universal_pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "pipez:block/pipe_extract", 3 | "textures": { 4 | "0": "pipez:block/universal_pipe", 5 | "particle": "pipez:block/universal_pipe" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | - Updated to 1.21.11 2 | 3 | **NOTE** 4 | 5 | This version is in very early development and might not be fully compatible with future versions! 6 | 7 | Pipe configurations from Minecraft versions 1.20.4 and lower won't be carried over to this version! -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/clear_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:clear_components", 3 | "item": "#pipez:upgrades", 4 | "components": [ 5 | "pipez:item", 6 | "pipez:fluid", 7 | "pipez:gas", 8 | "pipez:energy" 9 | ] 10 | } -------------------------------------------------------------------------------- /src/generated/resources/data/pipez/tags/item/upgrades.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "pipez:basic_upgrade", 5 | "pipez:improved_upgrade", 6 | "pipez:advanced_upgrade", 7 | "pipez:ultimate_upgrade", 8 | "pipez:infinity_upgrade" 9 | ] 10 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/copy_upgrade_basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:copy_components", 3 | "source": "#pipez:upgrades", 4 | "target": "pipez:basic_upgrade", 5 | "components": [ 6 | "pipez:item", 7 | "pipez:fluid", 8 | "pipez:gas", 9 | "pipez:energy" 10 | ] 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/copy_upgrade_advanced.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:copy_components", 3 | "source": "#pipez:upgrades", 4 | "target": "pipez:advanced_upgrade", 5 | "components": [ 6 | "pipez:item", 7 | "pipez:fluid", 8 | "pipez:gas", 9 | "pipez:energy" 10 | ] 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/copy_upgrade_improved.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:copy_components", 3 | "source": "#pipez:upgrades", 4 | "target": "pipez:improved_upgrade", 5 | "components": [ 6 | "pipez:item", 7 | "pipez:fluid", 8 | "pipez:gas", 9 | "pipez:energy" 10 | ] 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/copy_upgrade_infinity.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:copy_components", 3 | "source": "#pipez:upgrades", 4 | "target": "pipez:infinity_upgrade", 5 | "components": [ 6 | "pipez:item", 7 | "pipez:fluid", 8 | "pipez:gas", 9 | "pipez:energy" 10 | ] 11 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/copy_upgrade_ultimate.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "pipez:copy_components", 3 | "source": "#pipez:upgrades", 4 | "target": "pipez:ultimate_upgrade", 5 | "components": [ 6 | "pipez:item", 7 | "pipez:fluid", 8 | "pipez:gas", 9 | "pipez:energy" 10 | ] 11 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/tags/block/mineable/pickaxe.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "pipez:energy_pipe", 5 | "pipez:fluid_pipe", 6 | { 7 | "id": "pipez:gas_pipe", 8 | "required": false 9 | }, 10 | "pipez:item_pipe", 11 | "pipez:universal_pipe" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/wrench.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " F ", 5 | " SF", 6 | "S " 7 | ], 8 | "key": { 9 | "F": "minecraft:flint", 10 | "S": "#c:rods" 11 | }, 12 | "result": { 13 | "id": "pipez:wrench", 14 | "count": 1 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/IPipeContainer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 4 | import net.minecraft.core.Direction; 5 | 6 | public interface IPipeContainer { 7 | 8 | PipeLogicTileEntity getPipe(); 9 | 10 | Direction getSide(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven { url = 'https://maven.neoforged.net/releases' } 5 | maven { url = 'https://maven.maxhenkel.de/repository/public' } 6 | } 7 | } 8 | 9 | plugins { 10 | id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # eclipse 2 | bin 3 | *.launch 4 | .settings 5 | .metadata 6 | .classpath 7 | .project 8 | 9 | # idea 10 | out 11 | *.ipr 12 | *.iws 13 | *.iml 14 | .idea 15 | 16 | # gradle 17 | build 18 | .gradle 19 | 20 | # other 21 | eclipse 22 | run 23 | logs 24 | .cache 25 | 26 | curseforge_api_key.txt 27 | mod_update_api_key.txt 28 | modrinth_token.txt 29 | 30 | runs -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/ClientConfig.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import de.maxhenkel.corelib.config.ConfigBase; 4 | import net.neoforged.neoforge.common.ModConfigSpec; 5 | 6 | public class ClientConfig extends ConfigBase { 7 | 8 | public ClientConfig(ModConfigSpec.Builder builder) { 9 | super(builder); 10 | 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/fluid_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "III", 5 | "BRB", 6 | "III" 7 | ], 8 | "key": { 9 | "B": "minecraft:bucket", 10 | "I": "#c:ingots/iron", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:fluid_pipe", 15 | "count": 16 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/item_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "III", 5 | "DRD", 6 | "III" 7 | ], 8 | "key": { 9 | "D": "minecraft:dropper", 10 | "I": "#c:ingots/iron", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:item_pipe", 15 | "count": 16 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/basic_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "INI", 5 | "NRN", 6 | "INI" 7 | ], 8 | "key": { 9 | "N": "#c:nuggets/iron", 10 | "I": "#c:ingots/iron", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:basic_upgrade", 15 | "count": 1 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/energy_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "III", 5 | "BRB", 6 | "III" 7 | ], 8 | "key": { 9 | "B": "#c:storage_blocks/redstone", 10 | "I": "#c:ingots/iron", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:energy_pipe", 15 | "count": 16 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/improved_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "GRG", 5 | "RUR", 6 | "GRG" 7 | ], 8 | "key": { 9 | "U": "pipez:basic_upgrade", 10 | "G": "#c:ingots/gold", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:improved_upgrade", 15 | "count": 1 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/advanced_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "DRD", 5 | "RUR", 6 | "DRD" 7 | ], 8 | "key": { 9 | "D": "#c:gems/diamond", 10 | "R": "#c:storage_blocks/redstone", 11 | "U": "pipez:improved_upgrade" 12 | }, 13 | "result": { 14 | "id": "pipez:advanced_upgrade", 15 | "count": 1 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/ultimate_upgrade.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "NRN", 5 | "RUR", 6 | "NRN" 7 | ], 8 | "key": { 9 | "N": "#c:ingots/netherite", 10 | "R": "#c:storage_blocks/redstone", 11 | "U": "pipez:advanced_upgrade" 12 | }, 13 | "result": { 14 | "id": "pipez:ultimate_upgrade", 15 | "count": 1 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/PipeRenderState.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState; 4 | import net.minecraft.core.Direction; 5 | 6 | public class PipeRenderState extends BlockEntityRenderState { 7 | 8 | public boolean[] extracting = new boolean[Direction.values().length]; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/filter_destination_tool.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "III", 5 | "RGR", 6 | "IBI" 7 | ], 8 | "key": { 9 | "I": "#c:ingots/iron", 10 | "R": "#c:dusts/redstone", 11 | "G": "#c:glass_panes", 12 | "B": "#minecraft:buttons" 13 | }, 14 | "result": { 15 | "id": "pipez:filter_destination_tool", 16 | "count": 1 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/loot_table/blocks/fluid_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "entries": [ 7 | { 8 | "type": "minecraft:item", 9 | "name": "pipez:fluid_pipe" 10 | } 11 | ], 12 | "conditions": [ 13 | { 14 | "condition": "minecraft:survives_explosion" 15 | } 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/loot_table/blocks/gas_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "entries": [ 7 | { 8 | "type": "minecraft:item", 9 | "name": "pipez:gas_pipe" 10 | } 11 | ], 12 | "conditions": [ 13 | { 14 | "condition": "minecraft:survives_explosion" 15 | } 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/loot_table/blocks/item_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "entries": [ 7 | { 8 | "type": "minecraft:item", 9 | "name": "pipez:item_pipe" 10 | } 11 | ], 12 | "conditions": [ 13 | { 14 | "condition": "minecraft:survives_explosion" 15 | } 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/MekanismUtils.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import net.neoforged.fml.ModList; 4 | 5 | public class MekanismUtils { 6 | 7 | private static Boolean isLoaded; 8 | 9 | public static boolean isMekanismInstalled() { 10 | if (isLoaded == null) { 11 | isLoaded = ModList.get().isLoaded("mekanism"); 12 | } 13 | return isLoaded; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/data/pipez/loot_table/blocks/energy_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "entries": [ 7 | { 8 | "type": "minecraft:item", 9 | "name": "pipez:energy_pipe" 10 | } 11 | ], 12 | "conditions": [ 13 | { 14 | "condition": "minecraft:survives_explosion" 15 | } 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/loot_table/blocks/universal_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "rolls": 1, 6 | "entries": [ 7 | { 8 | "type": "minecraft:item", 9 | "name": "pipez:universal_pipe" 10 | } 11 | ], 12 | "conditions": [ 13 | { 14 | "condition": "minecraft:survives_explosion" 15 | } 16 | ] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/universal_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "IEF", 5 | "MRM", 6 | "IEF" 7 | ], 8 | "key": { 9 | "I": "pipez:item_pipe", 10 | "E": "pipez:energy_pipe", 11 | "F": "pipez:fluid_pipe", 12 | "R": "#c:storage_blocks/redstone", 13 | "M": "#c:ingots/iron" 14 | }, 15 | "result": { 16 | "id": "pipez:universal_pipe", 17 | "count": 6 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/theoneprobe/TheOneProbeModule.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.theoneprobe; 2 | 3 | import mcjty.theoneprobe.api.ITheOneProbe; 4 | 5 | import java.util.function.Function; 6 | 7 | public class TheOneProbeModule implements Function { 8 | 9 | @Override 10 | public Void apply(ITheOneProbe input) { 11 | input.registerProvider(new TileInfoProvider()); 12 | return null; 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /src/main/resources/data/pipez/recipe/gas_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "III", 5 | "ARA", 6 | "III" 7 | ], 8 | "key": { 9 | "A": "mekanism:alloy_infused", 10 | "I": "#c:ingots/iron", 11 | "R": "#c:dusts/redstone" 12 | }, 13 | "result": { 14 | "id": "pipez:gas_pipe", 15 | "count": 16 16 | }, 17 | "neoforge:conditions": [ 18 | { 19 | "type": "neoforge:mod_loaded", 20 | "modid": "mekanism" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/GasPipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import de.maxhenkel.pipez.ModelRegistry.Model; 4 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 5 | 6 | public class GasPipeRenderer extends PipeRenderer { 7 | 8 | public GasPipeRenderer(BlockEntityRendererProvider.Context renderer) { 9 | super(renderer); 10 | } 11 | 12 | @Override 13 | Model getModel() { 14 | return Model.GAS_PIPE_EXTRACT; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/ItemPipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import de.maxhenkel.pipez.ModelRegistry.Model; 4 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 5 | 6 | public class ItemPipeRenderer extends PipeRenderer { 7 | 8 | public ItemPipeRenderer(BlockEntityRendererProvider.Context renderer) { 9 | super(renderer); 10 | } 11 | 12 | @Override 13 | Model getModel() { 14 | return Model.ITEM_PIPE_EXTRACT; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/FluidPipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import de.maxhenkel.pipez.ModelRegistry.Model; 4 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 5 | 6 | public class FluidPipeRenderer extends PipeRenderer { 7 | 8 | public FluidPipeRenderer(BlockEntityRendererProvider.Context renderer) { 9 | super(renderer); 10 | } 11 | 12 | @Override 13 | Model getModel() { 14 | return Model.FLUID_PIPE_EXTRACT; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/EnergyPipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import de.maxhenkel.pipez.ModelRegistry.Model; 4 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 5 | 6 | public class EnergyPipeRenderer extends PipeRenderer { 7 | 8 | public EnergyPipeRenderer(BlockEntityRendererProvider.Context renderer) { 9 | super(renderer); 10 | } 11 | 12 | @Override 13 | Model getModel() { 14 | return Model.ENERGY_PIPE_EXTRACT; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/UniversalPipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import de.maxhenkel.pipez.ModelRegistry.Model; 4 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 5 | 6 | public class UniversalPipeRenderer extends PipeRenderer { 7 | 8 | public UniversalPipeRenderer(BlockEntityRendererProvider.Context renderer) { 9 | super(renderer); 10 | } 11 | 12 | @Override 13 | Model getModel() { 14 | return Model.UNIVERSAL_PIPE_EXTRACT; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/pipe_part.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/block", 3 | "elements": [ 4 | { 5 | "from": [5, 5, 0], 6 | "to": [11, 11, 5], 7 | "shade": false, 8 | "faces": { 9 | "north": {"uv": [10, 0, 16, 6], "texture": "#0"}, 10 | "east": {"uv": [0, 0, 5, 6], "texture": "#0"}, 11 | "south": {"uv": [10, 0, 16, 6], "texture": "#0"}, 12 | "west": {"uv": [0, 0, 5, 6], "texture": "#0"}, 13 | "up": {"uv": [0, 0, 5, 6], "rotation": 90, "texture": "#0"}, 14 | "down": {"uv": [0, 0, 5, 6], "rotation": 90, "texture": "#0"} 15 | } 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/pipe_extract.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/block", 3 | "elements": [ 4 | { 5 | "from": [4, 4, 0], 6 | "to": [12, 12, 1], 7 | "shade": false, 8 | "faces": { 9 | "north": {"uv": [8, 6, 16, 14], "texture": "#0"}, 10 | "east": {"uv": [0, 6, 1, 14], "texture": "#0"}, 11 | "south": {"uv": [8, 6, 16, 14], "texture": "#0"}, 12 | "west": {"uv": [0, 6, 1, 14], "texture": "#0"}, 13 | "up": {"uv": [0, 6, 1, 14], "rotation": 90, "texture": "#0"}, 14 | "down": {"uv": [0, 6, 1, 14], "rotation": 90, "texture": "#0"} 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/GasPipeTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.GasPipeType; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class GasPipeTileEntity extends PipeLogicTileEntity { 9 | 10 | public GasPipeTileEntity(BlockPos pos, BlockState state) { 11 | super(ModTileEntities.GAS_PIPE.get(), new PipeType[]{GasPipeType.INSTANCE}, pos, state); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/ItemPipeTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.ItemPipeType; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class ItemPipeTileEntity extends PipeLogicTileEntity { 9 | 10 | public ItemPipeTileEntity(BlockPos pos, BlockState state) { 11 | super(ModTileEntities.ITEM_PIPE.get(), new PipeType[]{ItemPipeType.INSTANCE}, pos, state); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/FluidPipeTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.FluidPipeType; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class FluidPipeTileEntity extends PipeLogicTileEntity { 9 | 10 | public FluidPipeTileEntity(BlockPos pos, BlockState state) { 11 | super(ModTileEntities.FLUID_PIPE.get(), new PipeType[]{FluidPipeType.INSTANCE}, pos, state); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/EnergyPipeTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.EnergyPipeType; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class EnergyPipeTileEntity extends PipeLogicTileEntity { 9 | 10 | public EnergyPipeTileEntity(BlockPos pos, BlockState state) { 11 | super(ModTileEntities.ENERGY_PIPE.get(), new PipeType[]{EnergyPipeType.INSTANCE}, pos, state); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/IMC.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration; 2 | 3 | import de.maxhenkel.pipez.integration.theoneprobe.TheOneProbeModule; 4 | import net.neoforged.bus.api.SubscribeEvent; 5 | import net.neoforged.fml.InterModComms; 6 | import net.neoforged.fml.ModList; 7 | import net.neoforged.fml.event.lifecycle.InterModEnqueueEvent; 8 | 9 | public class IMC { 10 | 11 | @SubscribeEvent 12 | public static void enqueueIMC(InterModEnqueueEvent event) { 13 | if (ModList.get().isLoaded("theoneprobe")) { 14 | InterModComms.sendTo("theoneprobe", "getTheOneProbe", TheOneProbeModule::new); 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/UpgradeSlot.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.pipez.items.UpgradeItem; 4 | import net.minecraft.world.Container; 5 | import net.minecraft.world.inventory.Slot; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | public class UpgradeSlot extends Slot { 9 | 10 | public UpgradeSlot(Container inventoryIn, int index, int xPosition, int yPosition) { 11 | super(inventoryIn, index, xPosition, yPosition); 12 | } 13 | 14 | @Override 15 | public boolean mayPlace(ItemStack stack) { 16 | return stack.getItem() instanceof UpgradeItem; 17 | } 18 | 19 | @Override 20 | public int getMaxStackSize() { 21 | return 1; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/jei/ExtractScreenHandler.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.jei; 2 | 3 | import de.maxhenkel.pipez.gui.ExtractScreen; 4 | import mezz.jei.api.gui.handlers.IGuiContainerHandler; 5 | import net.minecraft.client.renderer.Rect2i; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | public class ExtractScreenHandler implements IGuiContainerHandler { 11 | 12 | @Override 13 | public List getGuiExtraAreas(ExtractScreen screen) { 14 | if (screen.hasTabs()) { 15 | return Collections.singletonList(new Rect2i(Math.max(screen.getTabsX() - 10, 0), screen.getTabsY(), screen.getTabsWidth(), screen.getTabsHeight() + 10)); 16 | } 17 | return Collections.emptyList(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/UniversalPipeTileEntity.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.*; 4 | import de.maxhenkel.pipez.utils.MekanismUtils; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.world.level.block.state.BlockState; 7 | 8 | public class UniversalPipeTileEntity extends PipeLogicTileEntity { 9 | 10 | public UniversalPipeTileEntity(BlockPos pos, BlockState state) { 11 | super(ModTileEntities.UNIVERSAL_PIPE.get(), MekanismUtils.isMekanismInstalled() ? new PipeType[]{ItemPipeType.INSTANCE, FluidPipeType.INSTANCE, EnergyPipeType.INSTANCE, GasPipeType.INSTANCE} : new PipeType[]{ItemPipeType.INSTANCE, FluidPipeType.INSTANCE, EnergyPipeType.INSTANCE}, pos, state); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/tags/ModItemTags.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.tags; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import net.minecraft.resources.Identifier; 5 | import net.minecraft.tags.ItemTags; 6 | import net.minecraft.tags.TagKey; 7 | import net.minecraft.world.item.Item; 8 | 9 | public class ModItemTags { 10 | 11 | public static final TagKey WRENCHES_TAG = ItemTags.create(Identifier.fromNamespaceAndPath("c", "wrenches")); 12 | public static final TagKey WRENCH_TAG = ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools/wrench")); 13 | public static final TagKey TOOLS_TAG = ItemTags.create(Identifier.fromNamespaceAndPath("c", "tools")); 14 | public static final TagKey UPGRADES_TAG = ItemTags.create(Identifier.fromNamespaceAndPath(PipezMod.MODID, "upgrades")); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/waila/PluginPipes.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.waila; 2 | 3 | import de.maxhenkel.pipez.blocks.PipeBlock; 4 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 5 | import snownee.jade.api.IWailaClientRegistration; 6 | import snownee.jade.api.IWailaCommonRegistration; 7 | import snownee.jade.api.IWailaPlugin; 8 | import snownee.jade.api.WailaPlugin; 9 | 10 | @WailaPlugin 11 | public class PluginPipes implements IWailaPlugin { 12 | 13 | @Override 14 | public void registerClient(IWailaClientRegistration registration) { 15 | registration.registerBlockComponent(HUDHandlerPipes.INSTANCE, PipeBlock.class); 16 | } 17 | 18 | @Override 19 | public void register(IWailaCommonRegistration registration) { 20 | registration.registerBlockDataProvider(DataProviderPipes.INSTANCE, UpgradeTileEntity.class); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/capabilities/ModCapabilities.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.capabilities; 2 | 3 | import mekanism.api.chemical.IChemicalHandler; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.resources.Identifier; 6 | import net.neoforged.neoforge.capabilities.BlockCapability; 7 | import net.neoforged.neoforge.capabilities.ItemCapability; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class ModCapabilities { 11 | 12 | public static final BlockCapability CHEMICAL_HANDLER_CAPABILITY = BlockCapability.createSided(Identifier.fromNamespaceAndPath("mekanism", "chemical_handler"), IChemicalHandler.class); 13 | public static final ItemCapability CHEMICAL_HANDLER_ITEM_CAPABILITY = ItemCapability.createVoid(Identifier.fromNamespaceAndPath("mekanism", "chemical_handler"), IChemicalHandler.class); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/jei/JEIPlugin.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.jei; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import de.maxhenkel.pipez.gui.ExtractScreen; 5 | import de.maxhenkel.pipez.gui.FilterScreen; 6 | import mezz.jei.api.IModPlugin; 7 | import mezz.jei.api.JeiPlugin; 8 | import mezz.jei.api.registration.IGuiHandlerRegistration; 9 | import net.minecraft.resources.Identifier; 10 | 11 | @JeiPlugin 12 | public class JEIPlugin implements IModPlugin { 13 | 14 | @Override 15 | public Identifier getPluginUid() { 16 | return Identifier.fromNamespaceAndPath(PipezMod.MODID, "pipez"); 17 | } 18 | 19 | @Override 20 | public void registerGuiHandlers(IGuiHandlerRegistration registration) { 21 | registration.addGuiContainerHandler(ExtractScreen.class, new ExtractScreenHandler()); 22 | registration.addGhostIngredientHandler(FilterScreen.class, new FilterScreenGhostIngredientHandler()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/translation.yml: -------------------------------------------------------------------------------- 1 | name: Translation 2 | description: Submit a translation for this project 3 | labels: [translation] 4 | assignees: henkelmax 5 | body: 6 | - type: textarea 7 | id: notes 8 | attributes: 9 | label: Additional notes 10 | description: Additional information. 11 | validations: 12 | required: false 13 | - type: input 14 | id: locale_code 15 | attributes: 16 | label: Locale code 17 | description: The Minecraft locale code (See [this](https://minecraft.wiki/w/Language#Languages) for more information). 18 | placeholder: en_us 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: translation 23 | attributes: 24 | label: Translation json 25 | description: The contents of your translation file. 26 | render: json 27 | placeholder: | 28 | { 29 | "translation.key": "Translated value" 30 | } 31 | validations: 32 | required: true 33 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/ChemicalTag.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import de.maxhenkel.corelib.tag.Tag; 4 | import mekanism.api.chemical.Chemical; 5 | import net.minecraft.core.Holder; 6 | import net.minecraft.core.HolderSet; 7 | import net.minecraft.resources.Identifier; 8 | 9 | import java.util.List; 10 | 11 | public class ChemicalTag implements Tag { 12 | 13 | private final HolderSet.Named tag; 14 | private final Identifier id; 15 | 16 | public ChemicalTag(HolderSet.Named tag, Identifier id) { 17 | this.tag = tag; 18 | this.id = id; 19 | } 20 | 21 | @Override 22 | public Identifier getName() { 23 | return id; 24 | } 25 | 26 | @Override 27 | public boolean contains(Chemical gas) { 28 | return gas.is(tag.key()); 29 | } 30 | 31 | @Override 32 | public List getAll() { 33 | return tag.stream().map(Holder::value).toList(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/PipezClientMod.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.ModTileEntities; 4 | import de.maxhenkel.pipez.gui.Containers; 5 | import net.neoforged.api.distmarker.Dist; 6 | import net.neoforged.bus.api.IEventBus; 7 | import net.neoforged.bus.api.SubscribeEvent; 8 | import net.neoforged.fml.common.EventBusSubscriber; 9 | import net.neoforged.fml.common.Mod; 10 | import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; 11 | 12 | @Mod(value = PipezMod.MODID, dist = Dist.CLIENT) 13 | @EventBusSubscriber(modid = PipezMod.MODID, value = Dist.CLIENT) 14 | public class PipezClientMod { 15 | 16 | public PipezClientMod(IEventBus eventBus) { 17 | eventBus.addListener(ModelRegistry::onModelRegister); 18 | eventBus.addListener(ModelRegistry::onModelBake); 19 | Containers.initClient(eventBus); 20 | } 21 | 22 | @SubscribeEvent 23 | static void clientSetup(FMLClientSetupEvent event) { 24 | ModTileEntities.clientSetup(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/blockstates/gas_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "multipart": [ 3 | { "apply": { "model": "pipez:block/gas_pipe_core" }}, 4 | { "when": { "north": "true" }, 5 | "apply": { "model": "pipez:block/gas_pipe_part", "uvlock": false } 6 | }, 7 | { "when": { "east": "true" }, 8 | "apply": { "model": "pipez:block/gas_pipe_part", "y": 90, "uvlock": false } 9 | }, 10 | { "when": { "south": "true" }, 11 | "apply": { "model": "pipez:block/gas_pipe_part", "y": 180, "uvlock": false } 12 | }, 13 | { "when": { "west": "true" }, 14 | "apply": { "model": "pipez:block/gas_pipe_part", "y": 270, "uvlock": false } 15 | }, 16 | { "when": { "up": "true" }, 17 | "apply": { "model": "pipez:block/gas_pipe_part", "x": 270, "uvlock": false } 18 | }, 19 | { "when": { "down": "true" }, 20 | "apply": { "model": "pipez:block/gas_pipe_part", "x": 90, "uvlock": false } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/blockstates/item_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "multipart": [ 3 | { "apply": { "model": "pipez:block/item_pipe_core" }}, 4 | { "when": { "north": "true" }, 5 | "apply": { "model": "pipez:block/item_pipe_part", "uvlock": false } 6 | }, 7 | { "when": { "east": "true" }, 8 | "apply": { "model": "pipez:block/item_pipe_part", "y": 90, "uvlock": false } 9 | }, 10 | { "when": { "south": "true" }, 11 | "apply": { "model": "pipez:block/item_pipe_part", "y": 180, "uvlock": false } 12 | }, 13 | { "when": { "west": "true" }, 14 | "apply": { "model": "pipez:block/item_pipe_part", "y": 270, "uvlock": false } 15 | }, 16 | { "when": { "up": "true" }, 17 | "apply": { "model": "pipez:block/item_pipe_part", "x": 270, "uvlock": false } 18 | }, 19 | { "when": { "down": "true" }, 20 | "apply": { "model": "pipez:block/item_pipe_part", "x": 90, "uvlock": false } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/configuration/FilterCache.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.configuration; 2 | 3 | import de.maxhenkel.pipez.Filter; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.NonNullList; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.function.Supplier; 11 | 12 | public class FilterCache extends CachedPipeConfiguration>> { 13 | 14 | public FilterCache(Supplier> upgradeInventory, Runnable onDirty) { 15 | super(upgradeInventory, pipeType -> new ArrayList<>(), onDirty); 16 | } 17 | 18 | @Override 19 | public List> get(PipeType pipeType, ItemStack stack) { 20 | return pipeType.getFilters(stack); 21 | } 22 | 23 | @Override 24 | public void set(PipeType pipeType, ItemStack stack, List> value) { 25 | pipeType.setFilters(stack, value); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/blockstates/fluid_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "multipart": [ 3 | { "apply": { "model": "pipez:block/fluid_pipe_core" }}, 4 | { "when": { "north": "true" }, 5 | "apply": { "model": "pipez:block/fluid_pipe_part", "uvlock": false } 6 | }, 7 | { "when": { "east": "true" }, 8 | "apply": { "model": "pipez:block/fluid_pipe_part", "y": 90, "uvlock": false } 9 | }, 10 | { "when": { "south": "true" }, 11 | "apply": { "model": "pipez:block/fluid_pipe_part", "y": 180, "uvlock": false } 12 | }, 13 | { "when": { "west": "true" }, 14 | "apply": { "model": "pipez:block/fluid_pipe_part", "y": 270, "uvlock": false } 15 | }, 16 | { "when": { "up": "true" }, 17 | "apply": { "model": "pipez:block/fluid_pipe_part", "x": 270, "uvlock": false } 18 | }, 19 | { "when": { "down": "true" }, 20 | "apply": { "model": "pipez:block/fluid_pipe_part", "x": 90, "uvlock": false } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/blockstates/energy_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "multipart": [ 3 | { "apply": { "model": "pipez:block/energy_pipe_core" }}, 4 | { "when": { "north": "true" }, 5 | "apply": { "model": "pipez:block/energy_pipe_part", "uvlock": false } 6 | }, 7 | { "when": { "east": "true" }, 8 | "apply": { "model": "pipez:block/energy_pipe_part", "y": 90, "uvlock": false } 9 | }, 10 | { "when": { "south": "true" }, 11 | "apply": { "model": "pipez:block/energy_pipe_part", "y": 180, "uvlock": false } 12 | }, 13 | { "when": { "west": "true" }, 14 | "apply": { "model": "pipez:block/energy_pipe_part", "y": 270, "uvlock": false } 15 | }, 16 | { "when": { "up": "true" }, 17 | "apply": { "model": "pipez:block/energy_pipe_part", "x": 270, "uvlock": false } 18 | }, 19 | { "when": { "down": "true" }, 20 | "apply": { "model": "pipez:block/energy_pipe_part", "x": 90, "uvlock": false } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/blockstates/universal_pipe.json: -------------------------------------------------------------------------------- 1 | { 2 | "multipart": [ 3 | { "apply": { "model": "pipez:block/universal_pipe_core" }}, 4 | { "when": { "north": "true" }, 5 | "apply": { "model": "pipez:block/universal_pipe_part", "uvlock": false } 6 | }, 7 | { "when": { "east": "true" }, 8 | "apply": { "model": "pipez:block/universal_pipe_part", "y": 90, "uvlock": false } 9 | }, 10 | { "when": { "south": "true" }, 11 | "apply": { "model": "pipez:block/universal_pipe_part", "y": 180, "uvlock": false } 12 | }, 13 | { "when": { "west": "true" }, 14 | "apply": { "model": "pipez:block/universal_pipe_part", "y": 270, "uvlock": false } 15 | }, 16 | { "when": { "up": "true" }, 17 | "apply": { "model": "pipez:block/universal_pipe_part", "x": 270, "uvlock": false } 18 | }, 19 | { "when": { "down": "true" }, 20 | "apply": { "model": "pipez:block/universal_pipe_part", "x": 90, "uvlock": false } 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/codec/EnumIndexCodec.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.codec; 2 | 3 | import com.mojang.serialization.Codec; 4 | import net.minecraft.network.RegistryFriendlyByteBuf; 5 | import net.minecraft.network.codec.StreamCodec; 6 | 7 | public class EnumIndexCodec { 8 | 9 | public static > Codec of(Class enumClass) { 10 | T[] enumConstants = enumClass.getEnumConstants(); 11 | return Codec.BYTE.xmap(b -> enumConstants[b], t -> (byte) t.ordinal()); 12 | } 13 | 14 | public static > StreamCodec ofStream(Class enumClass) { 15 | T[] enumConstants = enumClass.getEnumConstants(); 16 | return new StreamCodec<>() { 17 | @Override 18 | public T decode(RegistryFriendlyByteBuf buf) { 19 | return enumConstants[buf.readByte()]; 20 | } 21 | 22 | @Override 23 | public void encode(RegistryFriendlyByteBuf buf, T value) { 24 | buf.writeByte(value.ordinal()); 25 | } 26 | }; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/recipes/ModRecipes.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.recipes; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import net.minecraft.core.registries.BuiltInRegistries; 5 | import net.minecraft.world.item.crafting.RecipeSerializer; 6 | import net.neoforged.bus.api.IEventBus; 7 | import net.neoforged.neoforge.registries.DeferredHolder; 8 | import net.neoforged.neoforge.registries.DeferredRegister; 9 | 10 | public class ModRecipes { 11 | 12 | private static final DeferredRegister> RECIPE_REGISTER = DeferredRegister.create(BuiltInRegistries.RECIPE_SERIALIZER, PipezMod.MODID); 13 | 14 | public static final DeferredHolder, CopyComponentsRecipe.Serializer> COPY_NBT = RECIPE_REGISTER.register("copy_components", CopyComponentsRecipe.Serializer::new); 15 | public static final DeferredHolder, ClearComponentsRecipe.Serializer> CLEAR_NBT = RECIPE_REGISTER.register("clear_components", ClearComponentsRecipe.Serializer::new); 16 | 17 | public static void init(IEventBus eventBus) { 18 | RECIPE_REGISTER.register(eventBus); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/configuration/FilterModeCache.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.configuration; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.NonNullList; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.util.function.Function; 9 | import java.util.function.Supplier; 10 | 11 | public class FilterModeCache extends CachedPipeConfiguration { 12 | 13 | public FilterModeCache(Supplier> upgradeInventory, Function, UpgradeTileEntity.FilterMode> defaultValue, Runnable onDirty) { 14 | super(upgradeInventory, defaultValue, onDirty); 15 | } 16 | 17 | @Override 18 | public UpgradeTileEntity.FilterMode get(PipeType pipeType, ItemStack stack) { 19 | return pipeType.getFilterMode(stack); 20 | } 21 | 22 | @Override 23 | public void set(PipeType pipeType, ItemStack stack, UpgradeTileEntity.FilterMode value) { 24 | pipeType.setFilterMode(stack, value); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/configuration/DistributionCache.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.configuration; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.NonNullList; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.util.function.Function; 9 | import java.util.function.Supplier; 10 | 11 | public class DistributionCache extends CachedPipeConfiguration { 12 | 13 | public DistributionCache(Supplier> upgradeInventory, Function, UpgradeTileEntity.Distribution> defaultValue, Runnable onDirty) { 14 | super(upgradeInventory, defaultValue, onDirty); 15 | } 16 | 17 | @Override 18 | public UpgradeTileEntity.Distribution get(PipeType pipeType, ItemStack stack) { 19 | return pipeType.getDistribution(stack); 20 | } 21 | 22 | @Override 23 | public void set(PipeType pipeType, ItemStack stack, UpgradeTileEntity.Distribution value) { 24 | pipeType.setDistribution(stack, value); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/configuration/RedstoneModeCache.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.configuration; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 5 | import net.minecraft.core.NonNullList; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.util.function.Function; 9 | import java.util.function.Supplier; 10 | 11 | public class RedstoneModeCache extends CachedPipeConfiguration { 12 | 13 | public RedstoneModeCache(Supplier> upgradeInventory, Function, UpgradeTileEntity.RedstoneMode> defaultValue, Runnable onDirty) { 14 | super(upgradeInventory, defaultValue, onDirty); 15 | } 16 | 17 | @Override 18 | public UpgradeTileEntity.RedstoneMode get(PipeType pipeType, ItemStack stack) { 19 | return pipeType.getRedstoneMode(stack); 20 | } 21 | 22 | @Override 23 | public void set(PipeType pipeType, ItemStack stack, UpgradeTileEntity.RedstoneMode value) { 24 | pipeType.setRedstoneMode(stack, value); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G 2 | org.gradle.daemon=false 3 | 4 | java_version=21 5 | java_toolchain_version=21 6 | 7 | neogradle.subsystems.parchment.minecraftVersion=1.21.10 8 | neogradle.subsystems.parchment.mappingsVersion=2025.10.12 9 | 10 | mod_loader=neoforge 11 | minecraft_version=1.21.11 12 | neoforge_version=21.11.0-beta 13 | neoforge_dependency=[21.11.0-beta,) 14 | corelib_version=2.1.12 15 | 16 | jei_version=21.3.2.22 17 | theoneprobe_version=1.21_neo-12.0.6 18 | jade_version=19.0.3+neoforge 19 | mekanism_version=1.21.1-10.7.14.79 20 | mekanism_dependency=[1.21.1-10.7.3.59,) 21 | 22 | # Mod information 23 | mod_version=1.21.11-1.2.27 24 | mod_id=pipez 25 | mod_display_name=Pipez 26 | 27 | # Project upload 28 | curseforge_upload_id=443900 29 | modrinth_upload_id=iRmWy6ga 30 | upload_release_type=alpha 31 | upload_recommended=true 32 | 33 | curseforge_upload_optional_dependencies=jei, the-one-probe, jade, mekanism 34 | modrinth_upload_optional_dependencies=jei, the-one-probe, jade, mekanism 35 | 36 | # Gradle plugins 37 | mod_gradle_script_version=1.0.47 38 | neogradle_version=[7.1.11,7.2) 39 | mod_update_version=2.0.0 40 | cursegradle_version=1.5.0 41 | shadow_version=9.2.2 42 | minotaur_version=2.+ 43 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/models/block/pipe_core.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/block", 3 | "elements": [ 4 | { 5 | "from": [5, 5, 5], 6 | "to": [11, 11, 11], 7 | "shade": false, 8 | "faces": { 9 | "north": {"uv": [10, 0, 16, 6], "texture": "#0"}, 10 | "east": {"uv": [10, 0, 16, 6], "texture": "#0"}, 11 | "south": {"uv": [10, 0, 16, 6], "texture": "#0"}, 12 | "west": {"uv": [10, 0, 16, 6], "texture": "#0"}, 13 | "up": {"uv": [10, 0, 16, 6], "texture": "#0"}, 14 | "down": {"uv": [10, 0, 16, 6], "texture": "#0"} 15 | } 16 | } 17 | ], 18 | "display": { 19 | "thirdperson_righthand": { 20 | "translation": [0, 1.5, 0], 21 | "scale": [0.5, 0.5, 0.5] 22 | }, 23 | "thirdperson_lefthand": { 24 | "translation": [0, 1.5, 0], 25 | "scale": [0.5, 0.5, 0.5] 26 | }, 27 | "firstperson_righthand": { 28 | "scale": [0.75, 0.75, 0.75] 29 | }, 30 | "firstperson_lefthand": { 31 | "scale": [0.75, 0.75, 0.75] 32 | }, 33 | "ground": { 34 | "translation": [0, 3, 0], 35 | "scale": [0.5, 0.5, 0.5] 36 | }, 37 | "gui": { 38 | "rotation": [30, -135, 0], 39 | "scale": [1.4, 1.4, 1.4] 40 | }, 41 | "head": { 42 | "scale": [2.5, 2.5, 2.5] 43 | }, 44 | "fixed": { 45 | "scale": [1.4, 1.4, 1.4] 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/NbtUtils.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import com.mojang.datafixers.util.Pair; 4 | import com.mojang.serialization.Codec; 5 | import net.minecraft.core.component.DataComponentPatch; 6 | import net.minecraft.nbt.CompoundTag; 7 | import net.minecraft.nbt.NbtOps; 8 | 9 | import java.util.Optional; 10 | 11 | public class NbtUtils { 12 | 13 | public static Optional componentPatchToNbtOptional(DataComponentPatch patch) { 14 | if(patch.isEmpty()) { 15 | return Optional.empty(); 16 | } 17 | return codecToNbtOptional(DataComponentPatch.CODEC, patch); 18 | } 19 | 20 | public static Optional nbtToCodecOptional(Codec codec, CompoundTag tag) { 21 | return codec.decode(NbtOps.INSTANCE, tag).result().map(Pair::getFirst); 22 | } 23 | 24 | public static Optional codecToNbtOptional(Codec codec, T value) { 25 | return codec.encodeStart(NbtOps.INSTANCE, value).result().filter(tag -> tag instanceof CompoundTag).map(CompoundTag.class::cast); 26 | } 27 | 28 | public static CompoundTag codecToNbtDefault(Codec codec, T value) { 29 | return codecToNbtOptional(codec, value).orElse(new CompoundTag()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/DummyItemHandler.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import net.neoforged.neoforge.transfer.ResourceHandler; 4 | import net.neoforged.neoforge.transfer.item.ItemResource; 5 | import net.neoforged.neoforge.transfer.transaction.TransactionContext; 6 | 7 | public class DummyItemHandler implements ResourceHandler { 8 | 9 | public static final DummyItemHandler INSTANCE = new DummyItemHandler(); 10 | 11 | @Override 12 | public int size() { 13 | return 0; 14 | } 15 | 16 | @Override 17 | public ItemResource getResource(int index) { 18 | return ItemResource.EMPTY; 19 | } 20 | 21 | @Override 22 | public long getAmountAsLong(int index) { 23 | return 0; 24 | } 25 | 26 | @Override 27 | public long getCapacityAsLong(int index, ItemResource resource) { 28 | return 0; 29 | } 30 | 31 | @Override 32 | public boolean isValid(int index, ItemResource resource) { 33 | return false; 34 | } 35 | 36 | @Override 37 | public int insert(int index, ItemResource resource, int amount, TransactionContext transaction) { 38 | return 0; 39 | } 40 | 41 | @Override 42 | public int extract(int index, ItemResource resource, int amount, TransactionContext transaction) { 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/ComponentUtils.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import com.mojang.datafixers.util.Pair; 4 | import net.minecraft.core.HolderLookup; 5 | import net.minecraft.core.component.DataComponentPatch; 6 | import net.minecraft.nbt.CompoundTag; 7 | import net.minecraft.nbt.NbtOps; 8 | import net.minecraft.nbt.Tag; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.neoforged.neoforge.fluids.FluidStack; 11 | 12 | public class ComponentUtils { 13 | 14 | public static CompoundTag getTag(HolderLookup.Provider provider, ItemStack stack) { 15 | return (CompoundTag) DataComponentPatch.CODEC.encodeStart(provider.createSerializationContext(NbtOps.INSTANCE), stack.getComponentsPatch()).result().orElseGet(CompoundTag::new); 16 | } 17 | 18 | public static CompoundTag getTag(HolderLookup.Provider provider, FluidStack stack) { 19 | return (CompoundTag) DataComponentPatch.CODEC.encodeStart(provider.createSerializationContext(NbtOps.INSTANCE), stack.getComponentsPatch()).result().orElseGet(CompoundTag::new); 20 | } 21 | 22 | public static DataComponentPatch getPatch(HolderLookup.Provider provider, Tag tag) { 23 | return DataComponentPatch.CODEC.decode(provider.createSerializationContext(NbtOps.INSTANCE), tag).result().map(Pair::getFirst).orElse(DataComponentPatch.EMPTY); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/DummyFluidHandler.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import net.neoforged.neoforge.transfer.ResourceHandler; 4 | import net.neoforged.neoforge.transfer.fluid.FluidResource; 5 | import net.neoforged.neoforge.transfer.transaction.TransactionContext; 6 | 7 | public class DummyFluidHandler implements ResourceHandler { 8 | 9 | public static final DummyFluidHandler INSTANCE = new DummyFluidHandler(); 10 | 11 | @Override 12 | public int size() { 13 | return 0; 14 | } 15 | 16 | @Override 17 | public FluidResource getResource(int index) { 18 | return FluidResource.EMPTY; 19 | } 20 | 21 | @Override 22 | public long getAmountAsLong(int index) { 23 | return 0; 24 | } 25 | 26 | @Override 27 | public long getCapacityAsLong(int index, FluidResource resource) { 28 | return 0; 29 | } 30 | 31 | @Override 32 | public boolean isValid(int index, FluidResource resource) { 33 | return false; 34 | } 35 | 36 | @Override 37 | public int insert(int index, FluidResource resource, int amount, TransactionContext transaction) { 38 | return 0; 39 | } 40 | 41 | @Override 42 | public int extract(int index, FluidResource resource, int amount, TransactionContext transaction) { 43 | return 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/neoforge.mods.toml: -------------------------------------------------------------------------------- 1 | modLoader = "javafml" 2 | loaderVersion = "*" 3 | license = "All rights reserved" 4 | issueTrackerURL = "https://github.com/henkelmax/pipez/issues" 5 | [[mods]] 6 | modId = "pipez" 7 | version = "${mod_version}" 8 | displayName = "Pipez" 9 | updateJSONURL = "https://update.maxhenkel.de/neoforge/pipez" 10 | displayURL = "https://www.curseforge.com/minecraft/mc-mods/pipez" 11 | logoFile = "icon.png" 12 | authors = "Max Henkel" 13 | description = '''Simple and efficient pipes''' 14 | [[dependencies.pipez]] 15 | modId = "neoforge" 16 | type = "required" 17 | versionRange = "${neoforge_dependency}" 18 | ordering = "NONE" 19 | side = "BOTH" 20 | [[dependencies.pipez]] 21 | modId = "minecraft" 22 | type = "required" 23 | versionRange = "[${minecraft_version}]" 24 | ordering = "NONE" 25 | side = "BOTH" 26 | [[dependencies.pipez]] 27 | modId = "mekanism" 28 | type = "optional" 29 | versionRange = "${mekanism_dependency}" 30 | ordering = "AFTER" 31 | side = "BOTH" 32 | [[dependencies.pipez]] 33 | modId = "jei" 34 | type = "optional" 35 | versionRange = "*" 36 | ordering = "NONE" 37 | side = "BOTH" 38 | [[dependencies.pipez]] 39 | modId = "theoneprobe" 40 | type = "optional" 41 | versionRange = "*" 42 | ordering = "NONE" 43 | side = "BOTH" 44 | [[dependencies.pipez]] 45 | modId = "jade" 46 | type = "optional" 47 | versionRange = "*" 48 | ordering = "NONE" 49 | side = "BOTH" -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/datacomponents/EnergyData.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.datacomponents; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 6 | import net.minecraft.network.RegistryFriendlyByteBuf; 7 | import net.minecraft.network.codec.StreamCodec; 8 | 9 | import java.util.List; 10 | 11 | public class EnergyData extends AbstractPipeTypeData { 12 | 13 | public static final Codec CODEC = codec(EnergyData.class, null); 14 | public static final StreamCodec STREAM_CODEC = streamCodec(EnergyData.class, null); 15 | 16 | public EnergyData(UpgradeTileEntity.FilterMode filterMode, UpgradeTileEntity.RedstoneMode redstoneMode, UpgradeTileEntity.Distribution distribution, List> filters) { 17 | super(filterMode, redstoneMode, distribution, filters); 18 | } 19 | 20 | @Override 21 | public EnergyDataBuilder builder() { 22 | return new EnergyDataBuilder(this); 23 | } 24 | 25 | public static class EnergyDataBuilder extends PipeTypeDataBuilder { 26 | 27 | public EnergyDataBuilder(EnergyData data) { 28 | super(data); 29 | } 30 | 31 | @Override 32 | public EnergyData build() { 33 | return new EnergyData(filterMode, redstoneMode, distribution, filters); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/ModBlocks.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import net.minecraft.world.level.block.Block; 5 | import net.minecraft.world.level.block.state.BlockBehaviour; 6 | import net.neoforged.bus.api.IEventBus; 7 | import net.neoforged.neoforge.registries.DeferredHolder; 8 | import net.neoforged.neoforge.registries.DeferredRegister; 9 | 10 | public class ModBlocks { 11 | 12 | private static final DeferredRegister.Blocks BLOCK_REGISTER = DeferredRegister.createBlocks(PipezMod.MODID); 13 | 14 | public static final DeferredHolder ITEM_PIPE = BLOCK_REGISTER.registerBlock("item_pipe", ItemPipeBlock::new, BlockBehaviour.Properties::of); 15 | public static final DeferredHolder FLUID_PIPE = BLOCK_REGISTER.registerBlock("fluid_pipe", FluidPipeBlock::new, BlockBehaviour.Properties::of); 16 | public static final DeferredHolder ENERGY_PIPE = BLOCK_REGISTER.registerBlock("energy_pipe", EnergyPipeBlock::new, BlockBehaviour.Properties::of); 17 | public static final DeferredHolder UNIVERSAL_PIPE = BLOCK_REGISTER.registerBlock("universal_pipe", UniversalPipeBlock::new, BlockBehaviour.Properties::of); 18 | public static final DeferredHolder GAS_PIPE = BLOCK_REGISTER.registerBlock("gas_pipe", GasPipeBlock::new, BlockBehaviour.Properties::of); 19 | 20 | public static void init(IEventBus eventBus) { 21 | BLOCK_REGISTER.register(eventBus); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/datacomponents/ItemData.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.datacomponents; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.ItemFilter; 6 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.codec.StreamCodec; 9 | import net.minecraft.world.item.Item; 10 | 11 | import java.util.List; 12 | 13 | public class ItemData extends AbstractPipeTypeData { 14 | 15 | public static final Codec CODEC = codec(ItemData.class, ItemFilter.CODEC); 16 | public static final StreamCodec STREAM_CODEC = streamCodec(ItemData.class, ItemFilter.STREAM_CODEC); 17 | 18 | public ItemData(UpgradeTileEntity.FilterMode filterMode, UpgradeTileEntity.RedstoneMode redstoneMode, UpgradeTileEntity.Distribution distribution, List> filters) { 19 | super(filterMode, redstoneMode, distribution, filters); 20 | } 21 | 22 | @Override 23 | public ItemDataBuilder builder() { 24 | return new ItemDataBuilder(this); 25 | } 26 | 27 | public static class ItemDataBuilder extends PipeTypeDataBuilder { 28 | 29 | public ItemDataBuilder(ItemData data) { 30 | super(data); 31 | } 32 | 33 | @Override 34 | public ItemData build() { 35 | return new ItemData(filterMode, redstoneMode, distribution, filters); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/datacomponents/GasData.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.datacomponents; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.GasFilter; 6 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 7 | import mekanism.api.chemical.Chemical; 8 | import net.minecraft.network.RegistryFriendlyByteBuf; 9 | import net.minecraft.network.codec.StreamCodec; 10 | 11 | import java.util.List; 12 | 13 | public class GasData extends AbstractPipeTypeData { 14 | 15 | public static final Codec CODEC = codec(GasData.class, GasFilter.CODEC); 16 | public static final StreamCodec STREAM_CODEC = streamCodec(GasData.class, GasFilter.STREAM_CODEC); 17 | 18 | public GasData(UpgradeTileEntity.FilterMode filterMode, UpgradeTileEntity.RedstoneMode redstoneMode, UpgradeTileEntity.Distribution distribution, List> filters) { 19 | super(filterMode, redstoneMode, distribution, filters); 20 | } 21 | 22 | @Override 23 | public GasDataBuilder builder() { 24 | return new GasDataBuilder(this); 25 | } 26 | 27 | public static class GasDataBuilder extends PipeTypeDataBuilder { 28 | 29 | public GasDataBuilder(GasData data) { 30 | super(data); 31 | } 32 | 33 | @Override 34 | public GasData build() { 35 | return new GasData(filterMode, redstoneMode, distribution, filters); 36 | } 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/PipeEnergyStorage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 4 | import de.maxhenkel.pipez.blocks.tileentity.types.EnergyPipeType; 5 | import net.minecraft.core.Direction; 6 | import net.neoforged.neoforge.transfer.energy.EnergyHandler; 7 | import net.neoforged.neoforge.transfer.transaction.TransactionContext; 8 | 9 | public class PipeEnergyStorage implements EnergyHandler { 10 | 11 | protected PipeLogicTileEntity pipe; 12 | protected Direction side; 13 | protected long lastReceived; 14 | 15 | public PipeEnergyStorage(PipeLogicTileEntity pipe, Direction side) { 16 | this.pipe = pipe; 17 | this.side = side; 18 | } 19 | 20 | public void tick() { 21 | if (pipe.getLevel().getGameTime() - lastReceived > 1) { 22 | EnergyPipeType.INSTANCE.pullEnergy(pipe, side); 23 | } 24 | } 25 | 26 | @Override 27 | public long getAmountAsLong() { 28 | return 0; 29 | } 30 | 31 | @Override 32 | public long getCapacityAsLong() { 33 | return Long.MAX_VALUE; 34 | } 35 | 36 | @Override 37 | public int insert(int amount, TransactionContext transaction) { 38 | //TODO Check if this needs to be rolled back 39 | lastReceived = pipe.getLevel().getGameTime(); 40 | return EnergyPipeType.INSTANCE.receive(pipe, side, amount, transaction); 41 | } 42 | 43 | @Override 44 | public int extract(int amount, TransactionContext transaction) { 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/containerfactory/PipeContainerFactory.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui.containerfactory; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.network.RegistryFriendlyByteBuf; 6 | import net.minecraft.world.entity.player.Inventory; 7 | import net.minecraft.world.inventory.AbstractContainerMenu; 8 | import net.minecraft.world.level.block.entity.BlockEntity; 9 | import net.neoforged.neoforge.network.IContainerFactory; 10 | 11 | public class PipeContainerFactory implements IContainerFactory { 12 | 13 | private final ContainerCreator containerCreator; 14 | 15 | public PipeContainerFactory(ContainerCreator containerCreator) { 16 | this.containerCreator = containerCreator; 17 | } 18 | 19 | @Override 20 | public T create(int windowId, Inventory inv, RegistryFriendlyByteBuf data) { 21 | BlockEntity te = inv.player.level().getBlockEntity(data.readBlockPos()); 22 | Direction direction = data.readEnum(Direction.class); 23 | int index = data.readInt(); 24 | try { 25 | return containerCreator.create(windowId, inv, (U) te, direction, index); 26 | } catch (ClassCastException e) { 27 | return null; 28 | } 29 | } 30 | 31 | public interface ContainerCreator { 32 | T create(int windowId, Inventory inv, U tileEntity, Direction side, int index); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/datacomponents/FluidData.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.datacomponents; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.FluidFilter; 6 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.codec.StreamCodec; 9 | import net.minecraft.world.level.material.Fluid; 10 | 11 | import java.util.List; 12 | 13 | public class FluidData extends AbstractPipeTypeData { 14 | 15 | public static final Codec CODEC = codec(FluidData.class, FluidFilter.CODEC); 16 | public static final StreamCodec STREAM_CODEC = streamCodec(FluidData.class, FluidFilter.STREAM_CODEC); 17 | 18 | public FluidData(UpgradeTileEntity.FilterMode filterMode, UpgradeTileEntity.RedstoneMode redstoneMode, UpgradeTileEntity.Distribution distribution, List> filters) { 19 | super(filterMode, redstoneMode, distribution, filters); 20 | } 21 | 22 | @Override 23 | public FluidDataBuilder builder() { 24 | return new FluidDataBuilder(this); 25 | } 26 | 27 | public static class FluidDataBuilder extends PipeTypeDataBuilder { 28 | 29 | public FluidDataBuilder(FluidData data) { 30 | super(data); 31 | } 32 | 33 | @Override 34 | public FluidData build() { 35 | return new FluidData(filterMode, redstoneMode, distribution, filters); 36 | } 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/items/WrenchItem.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.items; 2 | 3 | import de.maxhenkel.pipez.tags.ModItemTags; 4 | import net.minecraft.ChatFormatting; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.world.InteractionHand; 7 | import net.minecraft.world.entity.player.Player; 8 | import net.minecraft.world.item.Item; 9 | import net.minecraft.world.item.ItemStack; 10 | import net.minecraft.world.item.TooltipFlag; 11 | import net.minecraft.world.item.component.TooltipDisplay; 12 | 13 | import java.util.function.Consumer; 14 | 15 | public class WrenchItem extends Item { 16 | 17 | public static final Component WRENCH_TOOLTIP = Component.translatable("tooltip.pipez.wrench").withStyle(ChatFormatting.GRAY); 18 | 19 | public WrenchItem(Properties properties) { 20 | super(properties.stacksTo(1)); 21 | } 22 | 23 | @Override 24 | public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay tooltipDisplay, Consumer consumer, TooltipFlag flag) { 25 | consumer.accept(WRENCH_TOOLTIP); 26 | super.appendHoverText(stack, context, tooltipDisplay, consumer, flag); 27 | } 28 | 29 | public static boolean isWrench(ItemStack stack) { 30 | return stack.is(ModItemTags.WRENCH_TAG) || stack.is(ModItemTags.WRENCHES_TAG); 31 | } 32 | 33 | public static boolean isHoldingWrench(Player player) { 34 | for (InteractionHand hand : InteractionHand.values()) { 35 | ItemStack stack = player.getItemInHand(hand); 36 | if (isWrench(stack)) { 37 | return true; 38 | } 39 | } 40 | return false; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/FilterContainer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.corelib.inventory.ContainerBase; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.world.Container; 8 | import net.minecraft.world.entity.player.Player; 9 | 10 | public class FilterContainer extends ContainerBase implements IPipeContainer { 11 | 12 | private PipeLogicTileEntity pipe; 13 | private Direction side; 14 | private int index; 15 | private Filter filter; 16 | 17 | public FilterContainer(int id, Container playerInventory, PipeLogicTileEntity pipe, Direction side, int index, Filter filter) { 18 | super(Containers.FILTER.get(), id, playerInventory, null); 19 | this.pipe = pipe; 20 | this.side = side; 21 | this.index = index; 22 | this.filter = filter; 23 | 24 | addPlayerInventorySlots(); 25 | } 26 | 27 | @Override 28 | public PipeLogicTileEntity getPipe() { 29 | return pipe; 30 | } 31 | 32 | public int getIndex() { 33 | return index; 34 | } 35 | 36 | public Filter getFilter() { 37 | return filter; 38 | } 39 | 40 | @Override 41 | public Direction getSide() { 42 | return side; 43 | } 44 | 45 | @Override 46 | public int getInventorySize() { 47 | return 0; 48 | } 49 | 50 | @Override 51 | public int getInvOffset() { 52 | return 56; 53 | } 54 | 55 | @Override 56 | public boolean stillValid(Player player) { 57 | return !pipe.isRemoved(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/ExtractContainer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.corelib.inventory.ContainerBase; 4 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 5 | import net.minecraft.core.Direction; 6 | import net.minecraft.world.Container; 7 | import net.minecraft.world.entity.player.Player; 8 | 9 | public class ExtractContainer extends ContainerBase implements IPipeContainer { 10 | 11 | private PipeLogicTileEntity pipe; 12 | private Direction side; 13 | private int index; 14 | 15 | public ExtractContainer(int id, Container playerInventory, PipeLogicTileEntity pipe, Direction side, int index) { 16 | super(Containers.EXTRACT.get(), id, playerInventory, null); 17 | this.pipe = pipe; 18 | this.side = side; 19 | this.index = index; 20 | 21 | addSlot(new UpgradeSlot(pipe.getUpgradeInventory(), side.get3DDataValue(), 9, 81)); 22 | 23 | addPlayerInventorySlots(); 24 | } 25 | 26 | @Override 27 | public PipeLogicTileEntity getPipe() { 28 | return pipe; 29 | } 30 | 31 | @Override 32 | public Direction getSide() { 33 | return side; 34 | } 35 | 36 | /** 37 | * This value is -1 if no specific tab was selected 38 | * 39 | * @return the pipeType index 40 | */ 41 | public int getIndex() { 42 | return index; 43 | } 44 | 45 | @Override 46 | public int getInventorySize() { 47 | return 1; 48 | } 49 | 50 | @Override 51 | public int getInvOffset() { 52 | return 30; 53 | } 54 | 55 | @Override 56 | public boolean stillValid(Player player) { 57 | return !pipe.isRemoved(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/Containers.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import de.maxhenkel.pipez.gui.containerfactory.FilterContainerFactory; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerFactory; 6 | import net.minecraft.core.registries.BuiltInRegistries; 7 | import net.minecraft.world.inventory.MenuType; 8 | import net.neoforged.bus.api.IEventBus; 9 | import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; 10 | import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; 11 | import net.neoforged.neoforge.registries.DeferredHolder; 12 | import net.neoforged.neoforge.registries.DeferredRegister; 13 | 14 | public class Containers { 15 | 16 | private static final DeferredRegister> MENU_TYPE_REGISTER = DeferredRegister.create(BuiltInRegistries.MENU, PipezMod.MODID); 17 | 18 | public static final DeferredHolder, MenuType> EXTRACT = MENU_TYPE_REGISTER.register("extract", () -> 19 | IMenuTypeExtension.create(new PipeContainerFactory<>(ExtractContainer::new)) 20 | ); 21 | public static final DeferredHolder, MenuType> FILTER = MENU_TYPE_REGISTER.register("filter", () -> 22 | IMenuTypeExtension.create(new FilterContainerFactory<>(FilterContainer::new)) 23 | ); 24 | 25 | public static void registerScreens(RegisterMenuScreensEvent containers) { 26 | containers.register(EXTRACT.get(), ExtractScreen::new); 27 | containers.register(FILTER.get(), FilterScreen::new); 28 | } 29 | 30 | public static void init(IEventBus eventBus) { 31 | MENU_TYPE_REGISTER.register(eventBus); 32 | } 33 | 34 | public static void initClient(IEventBus eventBus) { 35 | eventBus.addListener(Containers::registerScreens); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/containerfactory/FilterContainerFactory.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui.containerfactory; 2 | 3 | import de.maxhenkel.pipez.Filter; 4 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 5 | import net.minecraft.core.Direction; 6 | import net.minecraft.network.RegistryFriendlyByteBuf; 7 | import net.minecraft.world.entity.player.Inventory; 8 | import net.minecraft.world.inventory.AbstractContainerMenu; 9 | import net.minecraft.world.level.block.entity.BlockEntity; 10 | import net.neoforged.neoforge.network.IContainerFactory; 11 | 12 | public class FilterContainerFactory implements IContainerFactory { 13 | 14 | private final ContainerCreator containerCreator; 15 | 16 | public FilterContainerFactory(ContainerCreator containerCreator) { 17 | this.containerCreator = containerCreator; 18 | } 19 | 20 | @Override 21 | public T create(int windowId, Inventory inv, RegistryFriendlyByteBuf data) { 22 | try { 23 | U pipe = (U) inv.player.level().getBlockEntity(data.readBlockPos()); 24 | Direction direction = data.readEnum(Direction.class); 25 | int index = data.readInt(); 26 | Filter filter = pipe.getPipeTypes()[index].createFilter(); 27 | if (filter == null) { 28 | return null; 29 | } 30 | filter = filter.fromNetwork(data); 31 | return containerCreator.create(windowId, inv, pipe, direction, index, filter); 32 | } catch (ClassCastException e) { 33 | return null; 34 | } 35 | } 36 | 37 | public interface ContainerCreator { 38 | T create(int windowId, Inventory inv, U tileEntity, Direction side, int index, Filter filter); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/containerfactory/PipeContainerProvider.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui.containerfactory; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.MenuProvider; 8 | import net.minecraft.world.entity.player.Inventory; 9 | import net.minecraft.world.entity.player.Player; 10 | import net.minecraft.world.inventory.AbstractContainerMenu; 11 | 12 | public class PipeContainerProvider implements MenuProvider { 13 | 14 | private ContainerCreator container; 15 | private UpgradeTileEntity tileEntity; 16 | 17 | public PipeContainerProvider(ContainerCreator container, UpgradeTileEntity tileEntity) { 18 | this.container = container; 19 | this.tileEntity = tileEntity; 20 | } 21 | 22 | @Override 23 | public Component getDisplayName() { 24 | return Component.translatable(tileEntity.getBlockState().getBlock().getDescriptionId()); 25 | } 26 | 27 | public static void openGui(Player player, UpgradeTileEntity tileEntity, Direction direction, int index, ContainerCreator containerCreator) { 28 | if (player instanceof ServerPlayer serverPlayer) { 29 | serverPlayer.openMenu(new PipeContainerProvider(containerCreator, tileEntity), packetBuffer -> { 30 | packetBuffer.writeBlockPos(tileEntity.getBlockPos()); 31 | packetBuffer.writeEnum(direction); 32 | packetBuffer.writeInt(index); 33 | }); 34 | } 35 | } 36 | 37 | @Override 38 | public AbstractContainerMenu createMenu(int i, Inventory playerInventory, Player playerEntity) { 39 | return container.create(i, playerInventory, playerEntity); 40 | } 41 | 42 | public interface ContainerCreator { 43 | AbstractContainerMenu create(int i, Inventory playerInventory, Player playerEntity); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/Upgrade.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | public enum Upgrade { 6 | 7 | BASIC("basic", true, false, false), 8 | IMPROVED("improved", true, true, false), 9 | ADVANCED("advanced", true, true, true), 10 | ULTIMATE("ultimate", true, true, true), 11 | INFINITY("infinity", true, true, true); 12 | 13 | private final String name; 14 | private final boolean canChangeRedstoneMode; 15 | private final boolean canChangeDistributionMode; 16 | private final boolean canChangeFilter; 17 | 18 | 19 | Upgrade(String name, boolean canChangeRedstoneMode, boolean canChangeDistributionMode, boolean canChangeFilter) { 20 | this.name = name; 21 | this.canChangeRedstoneMode = canChangeRedstoneMode; 22 | this.canChangeDistributionMode = canChangeDistributionMode; 23 | this.canChangeFilter = canChangeFilter; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public boolean canChangeRedstoneMode() { 31 | return canChangeRedstoneMode; 32 | } 33 | 34 | public boolean canChangeDistributionMode() { 35 | return canChangeDistributionMode; 36 | } 37 | 38 | public boolean canChangeFilter() { 39 | return canChangeFilter; 40 | } 41 | 42 | public static boolean canChangeRedstoneMode(@Nullable Upgrade upgrade) { 43 | if (upgrade == null) { 44 | return false; 45 | } 46 | return upgrade.canChangeRedstoneMode(); 47 | } 48 | 49 | public static boolean canChangeDistributionMode(@Nullable Upgrade upgrade) { 50 | if (upgrade == null) { 51 | return false; 52 | } 53 | return upgrade.canChangeDistributionMode(); 54 | } 55 | 56 | public static boolean canChangeFilter(@Nullable Upgrade upgrade) { 57 | if (upgrade == null) { 58 | return false; 59 | } 60 | return upgrade.canChangeFilter(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/WidgetBase.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import de.maxhenkel.corelib.inventory.ScreenBase; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiGraphics; 6 | import net.minecraft.client.gui.components.Button; 7 | import net.minecraft.client.input.MouseButtonEvent; 8 | 9 | public abstract class WidgetBase { 10 | 11 | protected ExtractScreen screen; 12 | protected Minecraft mc; 13 | protected int posX, posY, width, height, guiLeft, guiTop, xSize, ySize; 14 | 15 | public WidgetBase(ExtractScreen screen, int posX, int posY, int xSize, int ySize) { 16 | this.screen = screen; 17 | mc = Minecraft.getInstance(); 18 | this.posX = posX; 19 | this.posY = posY; 20 | this.xSize = xSize; 21 | this.ySize = ySize; 22 | 23 | width = screen.width; 24 | height = screen.height; 25 | guiLeft = screen.getGuiLeft() + posX; 26 | guiTop = screen.getGuiTop() + posY; 27 | } 28 | 29 | public void tick() { 30 | 31 | } 32 | 33 | protected void drawGuiContainerForegroundLayer(GuiGraphics guiGraphics, int mouseX, int mouseY) { 34 | 35 | } 36 | 37 | protected void drawGuiContainerBackgroundLayer(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { 38 | 39 | } 40 | 41 | public boolean mouseClicked(MouseButtonEvent event, boolean b) { 42 | return false; 43 | } 44 | 45 | public boolean mouseReleased(MouseButtonEvent event) { 46 | return false; 47 | } 48 | 49 | public boolean mouseScrolled(double mouseX, double mouseY, double deltaX, double deltaY) { 50 | return false; 51 | } 52 | 53 | protected void addButton(Button widget) { 54 | screen.addRenderableWidget(widget); 55 | } 56 | 57 | public ExtractContainer getContainer() { 58 | return screen.getMenu(); 59 | } 60 | 61 | public void addHoverArea(ScreenBase.HoverArea hoverArea) { 62 | screen.addHoverArea(hoverArea); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/CycleIconButton.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui; 2 | 3 | import net.minecraft.client.gui.GuiGraphics; 4 | import net.minecraft.client.gui.components.AbstractButton; 5 | import net.minecraft.client.gui.narration.NarrationElementOutput; 6 | import net.minecraft.client.input.InputWithModifiers; 7 | import net.minecraft.client.renderer.RenderPipelines; 8 | import net.minecraft.network.chat.Component; 9 | import net.minecraft.resources.Identifier; 10 | 11 | import java.util.List; 12 | import java.util.function.Consumer; 13 | import java.util.function.Supplier; 14 | 15 | public class CycleIconButton extends AbstractButton { 16 | 17 | private List icons; 18 | private Supplier index; 19 | private Consumer onPress; 20 | 21 | public CycleIconButton(int x, int y, List icons, Supplier index, Consumer onPress) { 22 | super(x, y, 20, 20, Component.empty()); 23 | this.icons = icons; 24 | this.index = index; 25 | this.onPress = onPress; 26 | } 27 | 28 | @Override 29 | public void renderContents(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTicks) { 30 | renderDefaultSprite(guiGraphics); 31 | Icon icon = icons.get(index.get()); 32 | guiGraphics.blit(RenderPipelines.GUI_TEXTURED, icon.texture, getX() + 2, getY() + 2, icon.offsetX, icon.offsetY, 16, 16, 256, 256); 33 | } 34 | 35 | @Override 36 | protected void updateWidgetNarration(NarrationElementOutput output) { 37 | defaultButtonNarrationText(output); 38 | } 39 | 40 | @Override 41 | public void onPress(InputWithModifiers input) { 42 | onPress.accept(this); 43 | } 44 | 45 | public static class Icon { 46 | private Identifier texture; 47 | private int offsetX, offsetY; 48 | 49 | public Icon(Identifier texture, int offsetX, int offsetY) { 50 | this.texture = texture; 51 | this.offsetX = offsetX; 52 | this.offsetY = offsetY; 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/waila/HUDHandlerPipes.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.waila; 2 | 3 | import de.maxhenkel.corelib.codec.CodecUtils; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import net.minecraft.nbt.CompoundTag; 6 | import net.minecraft.nbt.ListTag; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.network.chat.ComponentSerialization; 9 | import net.minecraft.resources.Identifier; 10 | import snownee.jade.api.BlockAccessor; 11 | import snownee.jade.api.IBlockComponentProvider; 12 | import snownee.jade.api.ITooltip; 13 | import snownee.jade.api.config.IPluginConfig; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.Optional; 18 | 19 | public class HUDHandlerPipes implements IBlockComponentProvider { 20 | 21 | static final HUDHandlerPipes INSTANCE = new HUDHandlerPipes(); 22 | 23 | private static final Identifier UID = Identifier.fromNamespaceAndPath(PipezMod.MODID, "pipe"); 24 | 25 | @Override 26 | public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { 27 | CompoundTag compound = blockAccessor.getServerData(); 28 | 29 | compound.getString("Upgrade").flatMap(s -> CodecUtils.fromJson(ComponentSerialization.CODEC, s)).ifPresent(iTooltip::add); 30 | 31 | iTooltip.addAll(getTooltips(blockAccessor, compound)); 32 | } 33 | 34 | public List getTooltips(BlockAccessor blockAccessor, CompoundTag compound) { 35 | List tooltips = new ArrayList<>(); 36 | Optional optionalList = compound.getList("Tooltips"); 37 | if (optionalList.isEmpty()) { 38 | return tooltips; 39 | } 40 | ListTag list = optionalList.get(); 41 | for (int i = 0; i < list.size(); i++) { 42 | list.getString(i).flatMap(s -> CodecUtils.fromJson(ComponentSerialization.CODEC, s)).ifPresent(tooltips::add); 43 | } 44 | return tooltips; 45 | } 46 | 47 | @Override 48 | public Identifier getUid() { 49 | return UID; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/gui/containerfactory/FilterContainerProvider.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.gui.containerfactory; 2 | 3 | import de.maxhenkel.pipez.Filter; 4 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 5 | import net.minecraft.core.Direction; 6 | import net.minecraft.network.chat.Component; 7 | import net.minecraft.server.level.ServerPlayer; 8 | import net.minecraft.world.MenuProvider; 9 | import net.minecraft.world.entity.player.Inventory; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.inventory.AbstractContainerMenu; 12 | 13 | public class FilterContainerProvider implements MenuProvider { 14 | 15 | private ContainerCreator container; 16 | private PipeLogicTileEntity pipe; 17 | 18 | public FilterContainerProvider(ContainerCreator container, PipeLogicTileEntity pipe) { 19 | this.container = container; 20 | this.pipe = pipe; 21 | } 22 | 23 | @Override 24 | public Component getDisplayName() { 25 | return Component.translatable(pipe.getBlockState().getBlock().getDescriptionId()); 26 | } 27 | 28 | public static void openGui(Player player, PipeLogicTileEntity tileEntity, Direction direction, Filter filter, int index, ContainerCreator containerCreator) { 29 | if (player instanceof ServerPlayer serverPlayer) { 30 | 31 | serverPlayer.openMenu(new FilterContainerProvider(containerCreator, tileEntity), packetBuffer -> { 32 | packetBuffer.writeBlockPos(tileEntity.getBlockPos()); 33 | packetBuffer.writeEnum(direction); 34 | packetBuffer.writeInt(index); 35 | filter.toNetwork(packetBuffer); 36 | }); 37 | } 38 | } 39 | 40 | @Override 41 | public AbstractContainerMenu createMenu(int i, Inventory playerInventory, Player playerEntity) { 42 | return container.create(i, playerInventory, playerEntity); 43 | } 44 | 45 | public interface ContainerCreator { 46 | AbstractContainerMenu create(int i, Inventory playerInventory, Player playerEntity); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/items/FilterDestinationToolItem.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.items; 2 | 3 | import de.maxhenkel.pipez.DirectionalPosition; 4 | import net.minecraft.ChatFormatting; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.network.chat.MutableComponent; 7 | import net.minecraft.world.item.Item; 8 | import net.minecraft.world.item.ItemStack; 9 | import net.minecraft.world.item.TooltipFlag; 10 | import net.minecraft.world.item.component.TooltipDisplay; 11 | 12 | import javax.annotation.Nullable; 13 | import java.util.function.Consumer; 14 | 15 | public class FilterDestinationToolItem extends Item { 16 | 17 | public FilterDestinationToolItem(Properties properties) { 18 | super(properties.stacksTo(1)); 19 | } 20 | 21 | @Override 22 | public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay tooltipDisplay, Consumer consumer, TooltipFlag flag) { 23 | consumer.accept(Component.translatable("tooltip.pipez.filter_destination_tool").withStyle(ChatFormatting.GRAY)); 24 | DirectionalPosition dst = getDestination(stack); 25 | if (dst != null) { 26 | consumer.accept(Component.translatable("tooltip.pipez.filter_destination_tool.destination", number(dst.getPos().getX()), number(dst.getPos().getY()), number(dst.getPos().getZ()), Component.translatable("message.pipez.direction." + dst.getDirection().getName()).withStyle(ChatFormatting.GREEN)).withStyle(ChatFormatting.GRAY)); 27 | } 28 | super.appendHoverText(stack, context, tooltipDisplay, consumer, flag); 29 | } 30 | 31 | private MutableComponent number(int num) { 32 | return Component.literal(String.valueOf(num)).withStyle(ChatFormatting.GREEN); 33 | } 34 | 35 | @Nullable 36 | public static DirectionalPosition getDestination(ItemStack stack) { 37 | return stack.get(ModItems.DIRECTIONAL_POSITION_DATA_COMPONENT); 38 | } 39 | 40 | public static void setDestination(ItemStack stack, DirectionalPosition dest) { 41 | stack.set(ModItems.DIRECTIONAL_POSITION_DATA_COMPONENT, dest); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/ItemFilter.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.corelib.tag.SingleElementTag; 5 | import de.maxhenkel.corelib.tag.Tag; 6 | import de.maxhenkel.corelib.tag.TagUtils; 7 | import net.minecraft.core.Holder; 8 | import net.minecraft.core.registries.BuiltInRegistries; 9 | import net.minecraft.nbt.CompoundTag; 10 | import net.minecraft.network.RegistryFriendlyByteBuf; 11 | import net.minecraft.network.codec.StreamCodec; 12 | import net.minecraft.world.item.Item; 13 | import net.minecraft.world.item.Items; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | import java.util.UUID; 17 | 18 | public class ItemFilter extends Filter { 19 | 20 | private static final TagConverter TAG_CONVERTER = (single, location) -> { 21 | if (single) { 22 | return new SingleElementTag<>(location, BuiltInRegistries.ITEM.get(location).map(Holder.Reference::value).orElse(Items.AIR)); 23 | } else { 24 | return TagUtils.getItemTag(location); 25 | } 26 | }; 27 | public static final Codec> TAG_CODEC = tagCodec(TAG_CONVERTER); 28 | public static final StreamCodec> STREAM_TAG_CODEC = tagStreamCodec(TAG_CONVERTER); 29 | 30 | public static final Codec CODEC = codec(ItemFilter.class, TAG_CODEC); 31 | public static final StreamCodec STREAM_CODEC = streamCodec(ItemFilter.class, STREAM_TAG_CODEC); 32 | 33 | public ItemFilter(UUID id, @Nullable Tag tag, @Nullable CompoundTag metadata, boolean exactMetadata, @Nullable DirectionalPosition destination, boolean invert) { 34 | super(id, tag, metadata, exactMetadata, destination, invert); 35 | } 36 | 37 | @Override 38 | public Codec getCodec() { 39 | return CODEC; 40 | } 41 | 42 | @Override 43 | public StreamCodec getStreamCodec() { 44 | return STREAM_CODEC; 45 | } 46 | 47 | public ItemFilter() { 48 | this(UUID.randomUUID(), null, null, false, null, false); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/FluidFilter.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import com.mojang.serialization.Codec; 4 | import de.maxhenkel.corelib.tag.SingleElementTag; 5 | import de.maxhenkel.corelib.tag.Tag; 6 | import de.maxhenkel.corelib.tag.TagUtils; 7 | import net.minecraft.core.Holder; 8 | import net.minecraft.core.registries.BuiltInRegistries; 9 | import net.minecraft.nbt.CompoundTag; 10 | import net.minecraft.network.RegistryFriendlyByteBuf; 11 | import net.minecraft.network.codec.StreamCodec; 12 | import net.minecraft.world.level.material.Fluid; 13 | import net.minecraft.world.level.material.Fluids; 14 | import org.jetbrains.annotations.Nullable; 15 | 16 | import java.util.UUID; 17 | 18 | public class FluidFilter extends Filter { 19 | 20 | private static final TagConverter TAG_CONVERTER = (single, location) -> { 21 | if (single) { 22 | return new SingleElementTag<>(location, BuiltInRegistries.FLUID.get(location).map(Holder.Reference::value).orElse(Fluids.EMPTY)); 23 | } else { 24 | return TagUtils.getFluidTag(location); 25 | } 26 | }; 27 | public static final Codec> TAG_CODEC = tagCodec(TAG_CONVERTER); 28 | public static final StreamCodec> STREAM_TAG_CODEC = tagStreamCodec(TAG_CONVERTER); 29 | 30 | public static final Codec CODEC = codec(FluidFilter.class, TAG_CODEC); 31 | public static final StreamCodec STREAM_CODEC = streamCodec(FluidFilter.class, STREAM_TAG_CODEC); 32 | 33 | public FluidFilter(UUID id, @Nullable Tag tag, @Nullable CompoundTag metadata, boolean exactMetadata, @Nullable DirectionalPosition destination, boolean invert) { 34 | super(id, tag, metadata, exactMetadata, destination, invert); 35 | } 36 | 37 | @Override 38 | public Codec getCodec() { 39 | return CODEC; 40 | } 41 | 42 | @Override 43 | public StreamCodec getStreamCodec() { 44 | return STREAM_CODEC; 45 | } 46 | 47 | public FluidFilter() { 48 | this(UUID.randomUUID(), null, null, false, null, false); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/DirectionalPosition.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import com.mojang.serialization.Codec; 4 | import com.mojang.serialization.codecs.RecordCodecBuilder; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.codec.StreamCodec; 9 | 10 | public class DirectionalPosition { 11 | 12 | public static final Codec CODEC = RecordCodecBuilder.create(i -> { 13 | return i.group( 14 | BlockPos.CODEC.fieldOf("position").forGetter(DirectionalPosition::getPos), 15 | Direction.CODEC.fieldOf("direction").forGetter(DirectionalPosition::getDirection) 16 | ).apply(i, DirectionalPosition::new); 17 | }); 18 | 19 | public static final StreamCodec STREAM_CODEC = StreamCodec.composite( 20 | BlockPos.STREAM_CODEC, 21 | DirectionalPosition::getPos, 22 | Direction.STREAM_CODEC, 23 | DirectionalPosition::getDirection, 24 | DirectionalPosition::new 25 | ); 26 | 27 | private BlockPos pos; 28 | private Direction direction; 29 | 30 | public DirectionalPosition(BlockPos pos, Direction direction) { 31 | this.pos = pos; 32 | this.direction = direction; 33 | } 34 | 35 | public DirectionalPosition() { 36 | 37 | } 38 | 39 | public BlockPos getPos() { 40 | return pos; 41 | } 42 | 43 | public Direction getDirection() { 44 | return direction; 45 | } 46 | 47 | @Override 48 | public boolean equals(Object o) { 49 | if (this == o) { 50 | return true; 51 | } 52 | if (o == null || getClass() != o.getClass()) { 53 | return false; 54 | } 55 | DirectionalPosition that = (DirectionalPosition) o; 56 | if (!pos.equals(that.pos)) { 57 | return false; 58 | } 59 | return direction == that.direction; 60 | } 61 | 62 | @Override 63 | public int hashCode() { 64 | int result = pos.hashCode(); 65 | result = 31 * result + direction.hashCode(); 66 | return result; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/CycleFilterModeMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 6 | import de.maxhenkel.pipez.gui.ExtractContainer; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.protocol.PacketFlow; 9 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 10 | import net.minecraft.resources.Identifier; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.neoforged.neoforge.network.handling.IPayloadContext; 13 | 14 | public class CycleFilterModeMessage implements Message { 15 | 16 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "cycle_filter_mode")); 17 | 18 | private int index; 19 | 20 | public CycleFilterModeMessage() { 21 | 22 | } 23 | 24 | public CycleFilterModeMessage(int index) { 25 | this.index = index; 26 | } 27 | 28 | @Override 29 | public PacketFlow getExecutingSide() { 30 | return PacketFlow.SERVERBOUND; 31 | } 32 | 33 | @Override 34 | public void executeServerSide(IPayloadContext context) { 35 | if (!(context.player() instanceof ServerPlayer sender)) { 36 | return; 37 | } 38 | if (sender.containerMenu instanceof ExtractContainer extractContainer) { 39 | PipeType pipeType = extractContainer.getPipe().getPipeTypes()[index]; 40 | extractContainer.getPipe().setFilterMode(extractContainer.getSide(), pipeType, extractContainer.getPipe().getFilterMode(extractContainer.getSide(), pipeType).cycle()); 41 | } 42 | } 43 | 44 | @Override 45 | public CycleFilterModeMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 46 | this.index = packetBuffer.readInt(); 47 | return this; 48 | } 49 | 50 | @Override 51 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 52 | packetBuffer.writeInt(index); 53 | } 54 | 55 | @Override 56 | public Type type() { 57 | return TYPE; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/OpenExtractMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.gui.ExtractContainer; 6 | import de.maxhenkel.pipez.gui.FilterContainer; 7 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 8 | import net.minecraft.network.RegistryFriendlyByteBuf; 9 | import net.minecraft.network.protocol.PacketFlow; 10 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 11 | import net.minecraft.resources.Identifier; 12 | import net.minecraft.server.level.ServerPlayer; 13 | import net.neoforged.neoforge.network.handling.IPayloadContext; 14 | 15 | public class OpenExtractMessage implements Message { 16 | 17 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "open_extract")); 18 | 19 | private int index; 20 | 21 | public OpenExtractMessage() { 22 | 23 | } 24 | 25 | public OpenExtractMessage(int index) { 26 | this.index = index; 27 | } 28 | 29 | @Override 30 | public PacketFlow getExecutingSide() { 31 | return PacketFlow.SERVERBOUND; 32 | } 33 | 34 | @Override 35 | public void executeServerSide(IPayloadContext context) { 36 | if (!(context.player() instanceof ServerPlayer sender)) { 37 | return; 38 | } 39 | if (sender.containerMenu instanceof FilterContainer filterContainer) { 40 | PipeContainerProvider.openGui(sender, filterContainer.getPipe(), filterContainer.getSide(), index, (id, playerInventory, playerEntity) -> new ExtractContainer(id, playerInventory, filterContainer.getPipe(), filterContainer.getSide(), index)); 41 | } 42 | } 43 | 44 | @Override 45 | public OpenExtractMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 46 | index = packetBuffer.readInt(); 47 | return this; 48 | } 49 | 50 | @Override 51 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 52 | packetBuffer.writeInt(index); 53 | } 54 | 55 | @Override 56 | public Type type() { 57 | return TYPE; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/CycleDistributionMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 6 | import de.maxhenkel.pipez.gui.ExtractContainer; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.protocol.PacketFlow; 9 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 10 | import net.minecraft.resources.Identifier; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.neoforged.neoforge.network.handling.IPayloadContext; 13 | 14 | public class CycleDistributionMessage implements Message { 15 | 16 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "cycle_distribution")); 17 | 18 | private int index; 19 | 20 | public CycleDistributionMessage() { 21 | 22 | } 23 | 24 | public CycleDistributionMessage(int index) { 25 | this.index = index; 26 | } 27 | 28 | @Override 29 | public PacketFlow getExecutingSide() { 30 | return PacketFlow.SERVERBOUND; 31 | } 32 | 33 | @Override 34 | public void executeServerSide(IPayloadContext context) { 35 | if (!(context.player() instanceof ServerPlayer sender)) { 36 | return; 37 | } 38 | if (sender.containerMenu instanceof ExtractContainer extractContainer) { 39 | PipeType pipeType = extractContainer.getPipe().getPipeTypes()[index]; 40 | extractContainer.getPipe().setDistribution(extractContainer.getSide(), pipeType, extractContainer.getPipe().getDistribution(extractContainer.getSide(), pipeType).cycle()); 41 | } 42 | } 43 | 44 | @Override 45 | public CycleDistributionMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 46 | this.index = packetBuffer.readInt(); 47 | return this; 48 | } 49 | 50 | @Override 51 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 52 | packetBuffer.writeInt(index); 53 | } 54 | 55 | @Override 56 | public Type type() { 57 | return TYPE; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/CycleRedstoneModeMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 6 | import de.maxhenkel.pipez.gui.ExtractContainer; 7 | import net.minecraft.network.RegistryFriendlyByteBuf; 8 | import net.minecraft.network.protocol.PacketFlow; 9 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 10 | import net.minecraft.resources.Identifier; 11 | import net.minecraft.server.level.ServerPlayer; 12 | import net.neoforged.neoforge.network.handling.IPayloadContext; 13 | 14 | public class CycleRedstoneModeMessage implements Message { 15 | 16 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "cycle_redstone_mode")); 17 | 18 | private int index; 19 | 20 | public CycleRedstoneModeMessage() { 21 | 22 | } 23 | 24 | public CycleRedstoneModeMessage(int index) { 25 | this.index = index; 26 | } 27 | 28 | @Override 29 | public PacketFlow getExecutingSide() { 30 | return PacketFlow.SERVERBOUND; 31 | } 32 | 33 | @Override 34 | public void executeServerSide(IPayloadContext context) { 35 | if (!(context.player() instanceof ServerPlayer sender)) { 36 | return; 37 | } 38 | if (sender.containerMenu instanceof ExtractContainer extractContainer) { 39 | PipeType pipeType = extractContainer.getPipe().getPipeTypes()[index]; 40 | extractContainer.getPipe().setRedstoneMode(extractContainer.getSide(), pipeType, extractContainer.getPipe().getRedstoneMode(extractContainer.getSide(), pipeType).cycle()); 41 | } 42 | } 43 | 44 | @Override 45 | public CycleRedstoneModeMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 46 | this.index = packetBuffer.readInt(); 47 | return this; 48 | } 49 | 50 | @Override 51 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 52 | packetBuffer.writeInt(index); 53 | } 54 | 55 | @Override 56 | public Type type() { 57 | return TYPE; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/ModCreativeTabs.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import de.maxhenkel.pipez.blocks.ModBlocks; 4 | import de.maxhenkel.pipez.items.ModItems; 5 | import net.minecraft.core.registries.Registries; 6 | import net.minecraft.network.chat.Component; 7 | import net.minecraft.world.item.CreativeModeTab; 8 | import net.minecraft.world.item.ItemStack; 9 | import net.neoforged.bus.api.IEventBus; 10 | import net.neoforged.neoforge.registries.DeferredHolder; 11 | import net.neoforged.neoforge.registries.DeferredRegister; 12 | 13 | public class ModCreativeTabs { 14 | 15 | private static final DeferredRegister TAB_REGISTER = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, PipezMod.MODID); 16 | 17 | public static final DeferredHolder TAB_PIPEZ = TAB_REGISTER.register("pipez", () -> { 18 | return CreativeModeTab.builder() 19 | .icon(() -> new ItemStack(ModBlocks.ITEM_PIPE.get())) 20 | .displayItems((features, output) -> { 21 | output.accept(new ItemStack(ModBlocks.ITEM_PIPE.get())); 22 | output.accept(new ItemStack(ModBlocks.FLUID_PIPE.get())); 23 | output.accept(new ItemStack(ModBlocks.ENERGY_PIPE.get())); 24 | output.accept(new ItemStack(ModBlocks.UNIVERSAL_PIPE.get())); 25 | output.accept(new ItemStack(ModBlocks.GAS_PIPE.get())); 26 | 27 | output.accept(new ItemStack(ModItems.BASIC_UPGRADE.get())); 28 | output.accept(new ItemStack(ModItems.IMPROVED_UPGRADE.get())); 29 | output.accept(new ItemStack(ModItems.ADVANCED_UPGRADE.get())); 30 | output.accept(new ItemStack(ModItems.ULTIMATE_UPGRADE.get())); 31 | output.accept(new ItemStack(ModItems.INFINITY_UPGRADE.get())); 32 | 33 | output.accept(new ItemStack(ModItems.WRENCH.get())); 34 | output.accept(new ItemStack(ModItems.FILTER_DESTINATION_TOOL.get())); 35 | }) 36 | .title(Component.translatable("itemGroup.pipez")) 37 | .build(); 38 | }); 39 | 40 | public static void init(IEventBus eventBus) { 41 | TAB_REGISTER.register(eventBus); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/WrappedGasStack.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import de.maxhenkel.corelib.helpers.AbstractStack; 4 | import mekanism.api.MekanismAPI; 5 | import mekanism.api.chemical.Chemical; 6 | import mekanism.api.chemical.ChemicalStack; 7 | import net.minecraft.ChatFormatting; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.gui.GuiGraphics; 10 | import net.minecraft.network.chat.Component; 11 | import net.minecraft.resources.Identifier; 12 | 13 | import javax.annotation.Nullable; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class WrappedGasStack extends AbstractStack { 18 | 19 | public WrappedGasStack(ChemicalStack stack) { 20 | super(stack); 21 | } 22 | 23 | @Nullable 24 | public static WrappedGasStack dummyStack(Object o) { 25 | if (o instanceof Chemical chemical) { 26 | return new WrappedGasStack(new ChemicalStack(chemical, 1000)); 27 | } 28 | return null; 29 | } 30 | 31 | @Override 32 | public void render(GuiGraphics guiGraphics, int x, int y) { 33 | // TODO Re-add once mekanism is updated 34 | /*TextureAtlasSprite texture = Minecraft.getInstance().getAtlasManager().getAtlasOrThrow(AtlasIds.BLOCKS).getSprite(stack.getChemical().getIcon()); 35 | int chemicalTint = stack.getChemicalTint(); 36 | guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURED, texture, x, y, 16, 16, chemicalTint);*/ 37 | } 38 | 39 | @Override 40 | public List getTooltip() { 41 | List tooltip = new ArrayList<>(); 42 | 43 | tooltip.add(getDisplayName()); 44 | 45 | if (Minecraft.getInstance().options.advancedItemTooltips) { 46 | Identifier registryName = MekanismAPI.CHEMICAL_REGISTRY.getKey(stack.getChemical()); 47 | if (registryName != null) { 48 | tooltip.add((Component.literal(registryName.toString())).withStyle(ChatFormatting.DARK_GRAY)); 49 | } 50 | } 51 | 52 | return tooltip; 53 | } 54 | 55 | @Override 56 | public Component getDisplayName() { 57 | return Component.empty().append(stack.getTextComponent()); 58 | } 59 | 60 | @Override 61 | public boolean isEmpty() { 62 | return stack.isEmpty(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/ItemPipeBlock.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.ItemPipeTileEntity; 4 | import de.maxhenkel.pipez.gui.ExtractContainer; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.core.Direction; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.LevelAccessor; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.phys.BlockHitResult; 17 | import net.neoforged.neoforge.capabilities.Capabilities; 18 | 19 | public class ItemPipeBlock extends PipeBlock { 20 | 21 | protected ItemPipeBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public boolean canConnectTo(Level world, BlockPos pos, Direction facing) { 27 | return world.getCapability(Capabilities.Item.BLOCK, pos.relative(facing), facing.getOpposite()) != null; 28 | } 29 | 30 | @Override 31 | public boolean isPipe(LevelAccessor world, BlockPos pos, Direction facing) { 32 | BlockState state = world.getBlockState(pos.relative(facing)); 33 | return state.getBlock().equals(this); 34 | } 35 | 36 | @Override 37 | BlockEntity createTileEntity(BlockPos pos, BlockState state) { 38 | return new ItemPipeTileEntity(pos, state); 39 | } 40 | 41 | @Override 42 | public InteractionResult onPipeSideActivated(ItemStack stack, BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, Direction direction) { 43 | BlockEntity tileEntity = worldIn.getBlockEntity(pos); 44 | if (tileEntity instanceof ItemPipeTileEntity && isExtracting(worldIn, pos, direction)) { 45 | if (worldIn.isClientSide()) { 46 | return InteractionResult.SUCCESS; 47 | } 48 | ItemPipeTileEntity pipe = (ItemPipeTileEntity) tileEntity; 49 | PipeContainerProvider.openGui(player, pipe, direction, -1, (i, playerInventory, playerEntity) -> new ExtractContainer(i, playerInventory, pipe, direction, -1)); 50 | return InteractionResult.SUCCESS; 51 | } 52 | return super.onPipeSideActivated(stack, state, worldIn, pos, player, handIn, hit, direction); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/RemoveFilterMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.PipezMod; 6 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 7 | import de.maxhenkel.pipez.gui.ExtractContainer; 8 | import net.minecraft.network.RegistryFriendlyByteBuf; 9 | import net.minecraft.network.protocol.PacketFlow; 10 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 11 | import net.minecraft.resources.Identifier; 12 | import net.minecraft.server.level.ServerPlayer; 13 | import net.neoforged.neoforge.network.handling.IPayloadContext; 14 | 15 | import java.util.List; 16 | import java.util.UUID; 17 | 18 | public class RemoveFilterMessage implements Message { 19 | 20 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "remove_filter")); 21 | 22 | private UUID filter; 23 | private int index; 24 | 25 | public RemoveFilterMessage() { 26 | 27 | } 28 | 29 | public RemoveFilterMessage(UUID filter, int index) { 30 | this.filter = filter; 31 | this.index = index; 32 | } 33 | 34 | @Override 35 | public PacketFlow getExecutingSide() { 36 | return PacketFlow.SERVERBOUND; 37 | } 38 | 39 | @Override 40 | public void executeServerSide(IPayloadContext context) { 41 | if (!(context.player() instanceof ServerPlayer sender)) { 42 | return; 43 | } 44 | if (sender.containerMenu instanceof ExtractContainer extractContainer) { 45 | PipeType pipeType = extractContainer.getPipe().getPipeTypes()[index]; 46 | List> filters = extractContainer.getPipe().getFilters(extractContainer.getSide(), pipeType); 47 | filters.removeIf(f -> f.getId().equals(filter)); 48 | extractContainer.getPipe().setFilters(extractContainer.getSide(), pipeType, filters); 49 | } 50 | } 51 | 52 | @Override 53 | public RemoveFilterMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 54 | filter = packetBuffer.readUUID(); 55 | index = packetBuffer.readInt(); 56 | return this; 57 | } 58 | 59 | @Override 60 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 61 | packetBuffer.writeUUID(filter); 62 | packetBuffer.writeInt(index); 63 | } 64 | 65 | @Override 66 | public Type type() { 67 | return TYPE; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/FluidPipeBlock.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.FluidPipeTileEntity; 4 | import de.maxhenkel.pipez.gui.ExtractContainer; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.core.Direction; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.LevelAccessor; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.phys.BlockHitResult; 17 | import net.neoforged.neoforge.capabilities.Capabilities; 18 | 19 | public class FluidPipeBlock extends PipeBlock { 20 | 21 | protected FluidPipeBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public boolean canConnectTo(Level world, BlockPos pos, Direction facing) { 27 | return world.getCapability(Capabilities.Fluid.BLOCK, pos.relative(facing), facing.getOpposite()) != null; 28 | } 29 | 30 | @Override 31 | public boolean isPipe(LevelAccessor world, BlockPos pos, Direction facing) { 32 | BlockState state = world.getBlockState(pos.relative(facing)); 33 | return state.getBlock().equals(this); 34 | } 35 | 36 | @Override 37 | BlockEntity createTileEntity(BlockPos pos, BlockState state) { 38 | return new FluidPipeTileEntity(pos, state); 39 | } 40 | 41 | @Override 42 | public InteractionResult onPipeSideActivated(ItemStack stack, BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, Direction direction) { 43 | BlockEntity tileEntity = worldIn.getBlockEntity(pos); 44 | if (tileEntity instanceof FluidPipeTileEntity && isExtracting(worldIn, pos, direction)) { 45 | if (worldIn.isClientSide()) { 46 | return InteractionResult.SUCCESS; 47 | } 48 | FluidPipeTileEntity pipe = (FluidPipeTileEntity) tileEntity; 49 | PipeContainerProvider.openGui(player, pipe, direction, -1, (i, playerInventory, playerEntity) -> new ExtractContainer(i, playerInventory, pipe, direction, -1)); 50 | return InteractionResult.SUCCESS; 51 | } 52 | return super.onPipeSideActivated(stack, state, worldIn, pos, player, handIn, hit, direction); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/EnergyPipeBlock.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.EnergyPipeTileEntity; 4 | import de.maxhenkel.pipez.gui.ExtractContainer; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.core.Direction; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.LevelAccessor; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.phys.BlockHitResult; 17 | import net.neoforged.neoforge.capabilities.Capabilities; 18 | 19 | public class EnergyPipeBlock extends PipeBlock { 20 | 21 | protected EnergyPipeBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public boolean canConnectTo(Level world, BlockPos pos, Direction facing) { 27 | return world.getCapability(Capabilities.Energy.BLOCK, pos.relative(facing), facing.getOpposite()) != null; 28 | } 29 | 30 | @Override 31 | public boolean isPipe(LevelAccessor world, BlockPos pos, Direction facing) { 32 | BlockState state = world.getBlockState(pos.relative(facing)); 33 | return state.getBlock().equals(this); 34 | } 35 | 36 | @Override 37 | BlockEntity createTileEntity(BlockPos pos, BlockState state) { 38 | return new EnergyPipeTileEntity(pos, state); 39 | } 40 | 41 | @Override 42 | public InteractionResult onPipeSideActivated(ItemStack stack, BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, Direction direction) { 43 | BlockEntity tileEntity = worldIn.getBlockEntity(pos); 44 | if (tileEntity instanceof EnergyPipeTileEntity && isExtracting(worldIn, pos, direction)) { 45 | if (worldIn.isClientSide()) { 46 | return InteractionResult.SUCCESS; 47 | } 48 | EnergyPipeTileEntity pipe = (EnergyPipeTileEntity) tileEntity; 49 | PipeContainerProvider.openGui(player, pipe, direction, -1, (i, playerInventory, playerEntity) -> new ExtractContainer(i, playerInventory, pipe, direction, -1)); 50 | return InteractionResult.SUCCESS; 51 | } 52 | return super.onPipeSideActivated(stack, state, worldIn, pos, player, handIn, hit, direction); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: File a bug report 3 | labels: [triage] 4 | assignees: henkelmax 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | > [!WARNING] 10 | > This form is **only for bug reports**! 11 | > Please don't abuse this for feature requests or questions. 12 | > Forms that are not filled out properly will be closed without response! 13 | - type: textarea 14 | id: description 15 | attributes: 16 | label: Bug description 17 | description: A clear and concise description of what the bug is. 18 | validations: 19 | required: true 20 | - type: input 21 | id: mc_version 22 | attributes: 23 | label: Minecraft version 24 | description: The Minecraft version you are using. 25 | placeholder: 1.20.4 26 | validations: 27 | required: true 28 | - type: input 29 | id: mod_version 30 | attributes: 31 | label: Mod version 32 | description: The version of the mod. 33 | placeholder: 1.20.4-1.2.3 34 | validations: 35 | required: true 36 | - type: input 37 | id: mod_loader_version 38 | attributes: 39 | label: Mod loader and version 40 | description: The mod loader and mod loader version you are using. 41 | placeholder: Fabric Loader 0.15.6 / NeoForge 20.4.1 / Forge 48.1.0 42 | validations: 43 | required: true 44 | - type: textarea 45 | id: steps 46 | attributes: 47 | label: Steps to reproduce 48 | description: | 49 | Steps to reproduce the issue. 50 | Please **don't** report issues that are not reproducible. 51 | placeholder: | 52 | 1. Go to '...' 53 | 2. Click on '...' 54 | 3. Scroll down to '...' 55 | 4. See error 56 | validations: 57 | required: true 58 | - type: textarea 59 | id: expected 60 | attributes: 61 | label: Expected behavior 62 | description: A clear and concise description of what you expected to happen. 63 | validations: 64 | required: false 65 | - type: input 66 | id: logs 67 | attributes: 68 | label: Log files 69 | description: | 70 | Please provide log files of the game session in which the problem occurred. 71 | Don't paste the complete logs into the issue. 72 | You can use [https://gist.github.com/](https://gist.github.com/). 73 | placeholder: https://gist.github.com/exampleuser/example 74 | validations: 75 | required: true 76 | - type: textarea 77 | id: screenshots 78 | attributes: 79 | label: Screenshots 80 | description: Screenshots of the issue. 81 | validations: 82 | required: false 83 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/theoneprobe/TileInfoProvider.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.theoneprobe; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import de.maxhenkel.pipez.blocks.PipeBlock; 5 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 6 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 7 | import mcjty.theoneprobe.api.IProbeHitData; 8 | import mcjty.theoneprobe.api.IProbeInfo; 9 | import mcjty.theoneprobe.api.IProbeInfoProvider; 10 | import mcjty.theoneprobe.api.ProbeMode; 11 | import net.minecraft.core.Direction; 12 | import net.minecraft.network.chat.Component; 13 | import net.minecraft.resources.Identifier; 14 | import net.minecraft.world.entity.player.Player; 15 | import net.minecraft.world.item.ItemStack; 16 | import net.minecraft.world.level.Level; 17 | import net.minecraft.world.level.block.entity.BlockEntity; 18 | import net.minecraft.world.level.block.state.BlockState; 19 | 20 | public class TileInfoProvider implements IProbeInfoProvider { 21 | 22 | public static final Identifier ID = Identifier.fromNamespaceAndPath(PipezMod.MODID, "probeinfoprovider"); 23 | 24 | @Override 25 | public Identifier getID() { 26 | return ID; 27 | } 28 | 29 | @Override 30 | public void addProbeInfo(ProbeMode probeMode, IProbeInfo info, Player player, Level world, BlockState state, IProbeHitData hitData) { 31 | BlockEntity te = world.getBlockEntity(hitData.getPos()); 32 | 33 | if (state.getBlock() instanceof PipeBlock) { 34 | PipeBlock pipe = (PipeBlock) state.getBlock(); 35 | Direction selectedSide = pipe.getSelection(state, world, hitData.getPos(), player).getKey(); 36 | if (selectedSide == null) { 37 | return; 38 | } 39 | if (!(te instanceof PipeLogicTileEntity)) { 40 | return; 41 | } 42 | 43 | PipeLogicTileEntity pipeTile = (PipeLogicTileEntity) te; 44 | 45 | if (!pipeTile.isExtracting(selectedSide)) { 46 | return; 47 | } 48 | 49 | ItemStack upgrade = pipeTile.getUpgradeItem(selectedSide); 50 | 51 | IProbeInfo i; 52 | if (upgrade.isEmpty()) { 53 | i = info.text(Component.translatable("tooltip.pipez.no_upgrade")); 54 | } else { 55 | i = info.horizontal() 56 | .item(upgrade) 57 | .vertical() 58 | .itemLabel(upgrade); 59 | } 60 | for (PipeType type : pipeTile.getPipeTypes()) { 61 | if (pipeTile.isEnabled(selectedSide, type)) { 62 | i = i.text(type.getTransferText(pipeTile.getUpgrade(selectedSide))); 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/EditFilterMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.PipezMod; 6 | import de.maxhenkel.pipez.gui.ExtractContainer; 7 | import de.maxhenkel.pipez.gui.FilterContainer; 8 | import de.maxhenkel.pipez.gui.containerfactory.FilterContainerProvider; 9 | import net.minecraft.nbt.CompoundTag; 10 | import net.minecraft.network.RegistryFriendlyByteBuf; 11 | import net.minecraft.network.protocol.PacketFlow; 12 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 13 | import net.minecraft.resources.Identifier; 14 | import net.minecraft.server.level.ServerPlayer; 15 | import net.neoforged.neoforge.network.handling.IPayloadContext; 16 | 17 | public class EditFilterMessage implements Message { 18 | 19 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "edit_filter_message")); 20 | 21 | private Filter filter; 22 | private CompoundTag filterTag; 23 | private int index; 24 | 25 | public EditFilterMessage() { 26 | 27 | } 28 | 29 | public EditFilterMessage(Filter filter, int index) { 30 | this.filter = filter; 31 | this.index = index; 32 | } 33 | 34 | @Override 35 | public PacketFlow getExecutingSide() { 36 | return PacketFlow.SERVERBOUND; 37 | } 38 | 39 | @Override 40 | public void executeServerSide(IPayloadContext context) { 41 | if (!(context.player() instanceof ServerPlayer sender)) { 42 | return; 43 | } 44 | if (!(sender.containerMenu instanceof ExtractContainer extractContainer)) { 45 | return; 46 | } 47 | filter = extractContainer.getPipe().getPipeTypes()[index].createFilter(); 48 | if (filter == null) { 49 | return; 50 | } 51 | filter = filter.fromNbt(filterTag); 52 | FilterContainerProvider.openGui(sender, extractContainer.getPipe(), extractContainer.getSide(), filter, index, (id, playerInventory, playerEntity) -> new FilterContainer(id, playerInventory, extractContainer.getPipe(), extractContainer.getSide(), index, filter)); 53 | } 54 | 55 | @Override 56 | public EditFilterMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 57 | filterTag = packetBuffer.readNbt(); 58 | index = packetBuffer.readInt(); 59 | return this; 60 | } 61 | 62 | @Override 63 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 64 | packetBuffer.writeNbt(filter.toNbt()); 65 | packetBuffer.writeInt(index); 66 | } 67 | 68 | @Override 69 | public Type type() { 70 | return TYPE; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/ModelRegistry.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import net.minecraft.client.renderer.block.model.TextureSlots; 4 | import net.minecraft.client.resources.model.*; 5 | import net.minecraft.resources.Identifier; 6 | import net.neoforged.neoforge.client.event.ModelEvent; 7 | import net.neoforged.neoforge.client.model.standalone.SimpleUnbakedStandaloneModel; 8 | import net.neoforged.neoforge.client.model.standalone.StandaloneModelKey; 9 | 10 | import java.util.concurrent.atomic.AtomicReference; 11 | 12 | public class ModelRegistry { 13 | 14 | public enum Model { 15 | ENERGY_PIPE_EXTRACT(Identifier.fromNamespaceAndPath(PipezMod.MODID, "block/energy_pipe_extract")), 16 | FLUID_PIPE_EXTRACT(Identifier.fromNamespaceAndPath(PipezMod.MODID, "block/fluid_pipe_extract")), 17 | GAS_PIPE_EXTRACT(Identifier.fromNamespaceAndPath(PipezMod.MODID, "block/gas_pipe_extract")), 18 | ITEM_PIPE_EXTRACT(Identifier.fromNamespaceAndPath(PipezMod.MODID, "block/item_pipe_extract")), 19 | UNIVERSAL_PIPE_EXTRACT(Identifier.fromNamespaceAndPath(PipezMod.MODID, "block/universal_pipe_extract")); 20 | 21 | private final Identifier resource; 22 | private final StandaloneModelKey modelKey; 23 | private final AtomicReference model; 24 | 25 | Model(Identifier rl) { 26 | resource = rl; 27 | modelKey = new StandaloneModelKey<>(rl::toString); 28 | model = new AtomicReference<>(); 29 | } 30 | 31 | public Identifier getIdentifier() { 32 | return resource; 33 | } 34 | 35 | public StandaloneModelKey getModelKey() { 36 | return modelKey; 37 | } 38 | 39 | public AtomicReference getModel() { 40 | return model; 41 | } 42 | } 43 | 44 | public static void onModelRegister(ModelEvent.RegisterStandalone event) { 45 | for (Model model : Model.values()) { 46 | event.register(model.getModelKey(), new SimpleUnbakedStandaloneModel<>(model.resource, (resolvedModel, baker) -> { 47 | ResolvedModel resolvedmodel = baker.getModel(model.getIdentifier()); 48 | TextureSlots textureslots = resolvedmodel.getTopTextureSlots(); 49 | return resolvedModel.bakeTopGeometry(textureslots, baker, BlockModelRotation.IDENTITY); 50 | })); 51 | } 52 | } 53 | 54 | public static void onModelBake(ModelEvent.BakingCompleted event) { 55 | for (Model model : Model.values()) { 56 | QuadCollection quads = event.getBakingResult().standaloneModels().get(model.getModelKey()); 57 | if (quads == null) { 58 | continue; 59 | } 60 | model.getModel().set(quads); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/events/BlockEvents.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.events; 2 | 3 | import de.maxhenkel.pipez.DirectionalPosition; 4 | import de.maxhenkel.pipez.blocks.PipeBlock; 5 | import de.maxhenkel.pipez.items.FilterDestinationToolItem; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.util.TriState; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.item.ItemStack; 11 | import net.minecraft.world.level.block.entity.BlockEntity; 12 | import net.minecraft.world.level.block.state.BlockState; 13 | import net.neoforged.bus.api.SubscribeEvent; 14 | import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; 15 | 16 | public class BlockEvents { 17 | 18 | @SubscribeEvent 19 | public void onBlockClick(PlayerInteractEvent.RightClickBlock event) { 20 | onDestinationToolClick(event); 21 | onPipeClick(event); 22 | } 23 | 24 | private void onPipeClick(PlayerInteractEvent.RightClickBlock event) { 25 | BlockState state = event.getLevel().getBlockState(event.getPos()); 26 | if (!(state.getBlock() instanceof PipeBlock)) { 27 | return; 28 | } 29 | 30 | PipeBlock pipe = (PipeBlock) state.getBlock(); 31 | 32 | Direction side = pipe.getSelection(state, event.getLevel(), event.getPos(), event.getEntity()).getKey(); 33 | InteractionResult result = pipe.onPipeSideForceActivated(state, event.getLevel(), event.getPos(), event.getEntity(), event.getHand(), event.getHitVec(), side); 34 | if (result.consumesAction()) { 35 | event.setUseItem(TriState.TRUE); 36 | event.setCancellationResult(result); 37 | event.setCanceled(true); 38 | } 39 | } 40 | 41 | private void onDestinationToolClick(PlayerInteractEvent.RightClickBlock event) { 42 | ItemStack heldItem = event.getEntity().getItemInHand(event.getHand()); 43 | if (!(heldItem.getItem() instanceof FilterDestinationToolItem)) { 44 | return; 45 | } 46 | 47 | BlockEntity te = event.getLevel().getBlockEntity(event.getPos()); 48 | 49 | if (te == null) { 50 | return; 51 | } 52 | 53 | BlockState blockState = event.getLevel().getBlockState(event.getPos()); 54 | if (blockState.getBlock() instanceof PipeBlock) { 55 | return; 56 | } 57 | 58 | FilterDestinationToolItem.setDestination(heldItem, new DirectionalPosition(event.getPos().immutable(), event.getFace())); 59 | event.getEntity().displayClientMessage(Component.translatable("message.pipez.filter_destination_tool.destination.set"), true); 60 | event.setUseItem(TriState.TRUE); 61 | event.setCancellationResult(InteractionResult.SUCCESS); 62 | event.setCanceled(true); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/GasPipeBlock.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.GasPipeTileEntity; 4 | import de.maxhenkel.pipez.gui.ExtractContainer; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 6 | import de.maxhenkel.pipez.utils.MekanismUtils; 7 | import net.minecraft.core.BlockPos; 8 | import net.minecraft.core.Direction; 9 | import net.minecraft.world.InteractionHand; 10 | import net.minecraft.world.InteractionResult; 11 | import net.minecraft.world.entity.player.Player; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraft.world.level.Level; 14 | import net.minecraft.world.level.LevelAccessor; 15 | import net.minecraft.world.level.block.entity.BlockEntity; 16 | import net.minecraft.world.level.block.state.BlockState; 17 | import net.minecraft.world.phys.BlockHitResult; 18 | 19 | public class GasPipeBlock extends PipeBlock { 20 | 21 | protected GasPipeBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public boolean canConnectTo(Level world, BlockPos pos, Direction facing) { 27 | if (!MekanismUtils.isMekanismInstalled()) { 28 | return false; 29 | } 30 | // TODO Re-add once mekanism is updated 31 | //return GasUtils.hasChemicalCapability(world, pos.relative(facing), facing.getOpposite()); 32 | return false; 33 | } 34 | 35 | @Override 36 | public boolean isPipe(LevelAccessor world, BlockPos pos, Direction facing) { 37 | BlockState state = world.getBlockState(pos.relative(facing)); 38 | return state.getBlock().equals(this); 39 | } 40 | 41 | @Override 42 | BlockEntity createTileEntity(BlockPos pos, BlockState state) { 43 | if (!MekanismUtils.isMekanismInstalled()) { 44 | return null; 45 | } 46 | return new GasPipeTileEntity(pos, state); 47 | } 48 | 49 | @Override 50 | public InteractionResult onPipeSideActivated(ItemStack stack, BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, Direction direction) { 51 | BlockEntity tileEntity = worldIn.getBlockEntity(pos); 52 | if (tileEntity instanceof GasPipeTileEntity && isExtracting(worldIn, pos, direction)) { 53 | if (worldIn.isClientSide()) { 54 | return InteractionResult.SUCCESS; 55 | } 56 | GasPipeTileEntity pipe = (GasPipeTileEntity) tileEntity; 57 | PipeContainerProvider.openGui(player, pipe, direction, -1, (i, playerInventory, playerEntity) -> new ExtractContainer(i, playerInventory, pipe, direction, -1)); 58 | return InteractionResult.SUCCESS; 59 | } 60 | return super.onPipeSideActivated(stack, state, worldIn, pos, player, handIn, hit, direction); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/jei/FilterScreenGhostIngredientHandler.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.jei; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | 7 | import de.maxhenkel.pipez.Filter; 8 | import de.maxhenkel.pipez.FluidFilter; 9 | import de.maxhenkel.pipez.GasFilter; 10 | import de.maxhenkel.pipez.gui.FilterScreen; 11 | import de.maxhenkel.pipez.utils.GasUtils; 12 | import mekanism.api.chemical.ChemicalStack; 13 | import mezz.jei.api.gui.handlers.IGhostIngredientHandler; 14 | import mezz.jei.api.ingredients.ITypedIngredient; 15 | import net.minecraft.client.renderer.Rect2i; 16 | import net.minecraft.world.item.ItemStack; 17 | import net.neoforged.neoforge.fluids.FluidStack; 18 | import net.neoforged.neoforge.transfer.fluid.FluidUtil; 19 | 20 | public class FilterScreenGhostIngredientHandler implements IGhostIngredientHandler { 21 | 22 | @Override 23 | public List> getTargetsTyped(FilterScreen gui, ITypedIngredient ingredient, boolean doStart) { 24 | Filter filter = gui.getMenu().getFilter(); 25 | List> list = new ArrayList<>(); 26 | 27 | if (ingredient.getIngredient() instanceof ItemStack stack) { 28 | if (testItemStack(filter, stack)) { 29 | list.add(this.getItemHoverAreaTarget(gui, i -> gui.onInsertStack(stack))); 30 | } 31 | } else if (filter instanceof FluidFilter && ingredient.getIngredient() instanceof FluidStack stack) { 32 | list.add(this.getItemHoverAreaTarget(gui, i -> gui.onInsertStack(stack))); 33 | } else if (filter instanceof GasFilter && ingredient.getIngredient() instanceof ChemicalStack stack) { 34 | list.add(this.getItemHoverAreaTarget(gui, i -> gui.onInsertStack(stack))); 35 | } 36 | 37 | return list; 38 | } 39 | 40 | private boolean testItemStack(Filter filter, ItemStack stack) { 41 | if (filter instanceof FluidFilter) { 42 | return !FluidUtil.getFirstStackContained(stack).isEmpty(); 43 | } else if (filter instanceof GasFilter) { 44 | return GasUtils.getGasContained(stack) != null; 45 | } else { 46 | return true; 47 | } 48 | } 49 | 50 | private Target getItemHoverAreaTarget(FilterScreen gui, Consumer consumer) { 51 | return new IGhostIngredientHandler.Target() { 52 | 53 | @Override 54 | public Rect2i getArea() { 55 | return new Rect2i(gui.getGuiLeft() + 8, gui.getGuiTop() + 18, 16, 16); 56 | } 57 | 58 | @Override 59 | public void accept(I ingredient) { 60 | consumer.accept(ingredient); 61 | } 62 | }; 63 | } 64 | 65 | @Override 66 | public void onComplete() { 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/PipezMod.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez; 2 | 3 | import de.maxhenkel.corelib.CommonRegistry; 4 | import de.maxhenkel.pipez.blocks.ModBlocks; 5 | import de.maxhenkel.pipez.blocks.tileentity.ModTileEntities; 6 | import de.maxhenkel.pipez.events.BlockEvents; 7 | import de.maxhenkel.pipez.gui.Containers; 8 | import de.maxhenkel.pipez.items.ModItems; 9 | import de.maxhenkel.pipez.net.*; 10 | import de.maxhenkel.pipez.recipes.ModRecipes; 11 | import net.neoforged.bus.api.IEventBus; 12 | import net.neoforged.bus.api.SubscribeEvent; 13 | import net.neoforged.fml.common.EventBusSubscriber; 14 | import net.neoforged.fml.common.Mod; 15 | import net.neoforged.fml.config.ModConfig; 16 | import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; 17 | import net.neoforged.neoforge.common.NeoForge; 18 | import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; 19 | import net.neoforged.neoforge.network.registration.PayloadRegistrar; 20 | import org.apache.logging.log4j.LogManager; 21 | import org.apache.logging.log4j.Logger; 22 | 23 | @Mod(PipezMod.MODID) 24 | @EventBusSubscriber(modid = PipezMod.MODID) 25 | public class PipezMod { 26 | 27 | public static final String MODID = "pipez"; 28 | 29 | public static final Logger LOGGER = LogManager.getLogger(MODID); 30 | 31 | public static ServerConfig SERVER_CONFIG; 32 | public static ClientConfig CLIENT_CONFIG; 33 | 34 | public PipezMod(IEventBus eventBus) { 35 | //TODO Add back 36 | //eventBus.addListener(IMC::enqueueIMC); 37 | 38 | SERVER_CONFIG = CommonRegistry.registerConfig(MODID, ModConfig.Type.SERVER, ServerConfig.class); 39 | CLIENT_CONFIG = CommonRegistry.registerConfig(MODID, ModConfig.Type.CLIENT, ClientConfig.class); 40 | 41 | ModBlocks.init(eventBus); 42 | ModItems.init(eventBus); 43 | ModRecipes.init(eventBus); 44 | Containers.init(eventBus); 45 | ModTileEntities.init(eventBus); 46 | ModCreativeTabs.init(eventBus); 47 | } 48 | 49 | @SubscribeEvent 50 | static void commonSetup(FMLCommonSetupEvent event) { 51 | NeoForge.EVENT_BUS.register(new BlockEvents()); 52 | } 53 | 54 | @SubscribeEvent 55 | static void onRegisterPayloadHandler(RegisterPayloadHandlersEvent event) { 56 | PayloadRegistrar registrar = event.registrar(MODID).versioned("1"); 57 | CommonRegistry.registerMessage(registrar, CycleDistributionMessage.class); 58 | CommonRegistry.registerMessage(registrar, CycleRedstoneModeMessage.class); 59 | CommonRegistry.registerMessage(registrar, CycleFilterModeMessage.class); 60 | CommonRegistry.registerMessage(registrar, UpdateFilterMessage.class); 61 | CommonRegistry.registerMessage(registrar, RemoveFilterMessage.class); 62 | CommonRegistry.registerMessage(registrar, EditFilterMessage.class); 63 | CommonRegistry.registerMessage(registrar, OpenExtractMessage.class); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/configuration/CachedPipeConfiguration.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.configuration; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 4 | import net.minecraft.core.Direction; 5 | import net.minecraft.core.NonNullList; 6 | import net.minecraft.world.item.ItemStack; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.function.Function; 11 | import java.util.function.Supplier; 12 | 13 | public abstract class CachedPipeConfiguration { 14 | 15 | private final Map, T>[] cachedValues; 16 | 17 | protected Supplier> upgradeInventory; 18 | 19 | protected Function, T> defaultValue; 20 | protected Runnable onDirty; 21 | 22 | public CachedPipeConfiguration(Supplier> upgradeInventory, Function, T> defaultValue, Runnable onDirty) { 23 | this.upgradeInventory = upgradeInventory; 24 | this.defaultValue = defaultValue; 25 | this.onDirty = onDirty; 26 | this.cachedValues = new HashMap[Direction.values().length]; 27 | } 28 | 29 | public T getValue(Direction side, PipeType pipeType) { 30 | Map, T> map = cachedValues[side.ordinal()]; 31 | if (map == null) { 32 | map = new HashMap<>(); 33 | cachedValues[side.ordinal()] = map; 34 | } 35 | 36 | if (map.containsKey(pipeType)) { 37 | return map.get(pipeType); 38 | } 39 | 40 | ItemStack stack = upgradeInventory.get().get(side.ordinal()); 41 | T value = get(pipeType, stack); 42 | if (stack.isEmpty() || value == null) { 43 | return putDefault(pipeType, map); 44 | } 45 | map.put(pipeType, value); 46 | return value; 47 | } 48 | 49 | public T putDefault(PipeType pipeType, Map, T> map) { 50 | T def = defaultValue.apply(pipeType); 51 | map.put(pipeType, def); 52 | return def; 53 | } 54 | 55 | public void setValue(Direction side, PipeType pipeType, T value) { 56 | Map, T> map = cachedValues[side.ordinal()]; 57 | if (map == null) { 58 | map = new HashMap<>(); 59 | cachedValues[side.ordinal()] = map; 60 | } 61 | 62 | ItemStack stack = upgradeInventory.get().get(side.ordinal()); 63 | if (stack.isEmpty()) { 64 | return; 65 | } 66 | map.put(pipeType, value); 67 | set(pipeType, stack, value); 68 | onDirty.run(); 69 | } 70 | 71 | public void invalidate() { 72 | for (Map, T> map : cachedValues) { 73 | if (map != null) { 74 | map.clear(); 75 | } 76 | } 77 | } 78 | 79 | public abstract T get(PipeType pipeType, ItemStack stack); 80 | 81 | public abstract void set(PipeType pipeType, ItemStack stack, T value); 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/UniversalPipeBlock.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks; 2 | 3 | import de.maxhenkel.pipez.blocks.tileentity.UniversalPipeTileEntity; 4 | import de.maxhenkel.pipez.gui.ExtractContainer; 5 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.core.Direction; 8 | import net.minecraft.world.InteractionHand; 9 | import net.minecraft.world.InteractionResult; 10 | import net.minecraft.world.entity.player.Player; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.Level; 13 | import net.minecraft.world.level.LevelAccessor; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | import net.minecraft.world.phys.BlockHitResult; 17 | import net.neoforged.neoforge.capabilities.Capabilities; 18 | 19 | public class UniversalPipeBlock extends PipeBlock { 20 | 21 | protected UniversalPipeBlock(Properties properties) { 22 | super(properties); 23 | } 24 | 25 | @Override 26 | public boolean canConnectTo(Level world, BlockPos pos, Direction facing) { 27 | return world.getCapability(Capabilities.Item.BLOCK, pos.relative(facing), facing.getOpposite()) != null 28 | || world.getCapability(Capabilities.Fluid.BLOCK, pos.relative(facing), facing.getOpposite()) != null 29 | || world.getCapability(Capabilities.Energy.BLOCK, pos.relative(facing), facing.getOpposite()) != null 30 | /*|| (MekanismUtils.isMekanismInstalled() && GasUtils.hasChemicalCapability(world, pos.relative(facing), facing.getOpposite()))*/; 31 | } 32 | 33 | @Override 34 | public boolean isPipe(LevelAccessor world, BlockPos pos, Direction facing) { 35 | BlockState state = world.getBlockState(pos.relative(facing)); 36 | return state.getBlock().equals(this); 37 | } 38 | 39 | @Override 40 | BlockEntity createTileEntity(BlockPos pos, BlockState state) { 41 | return new UniversalPipeTileEntity(pos, state); 42 | } 43 | 44 | @Override 45 | public InteractionResult onPipeSideActivated(ItemStack stack, BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, Direction direction) { 46 | BlockEntity tileEntity = worldIn.getBlockEntity(pos); 47 | if (tileEntity instanceof UniversalPipeTileEntity && isExtracting(worldIn, pos, direction)) { 48 | if (worldIn.isClientSide()) { 49 | return InteractionResult.SUCCESS; 50 | } 51 | UniversalPipeTileEntity pipe = (UniversalPipeTileEntity) tileEntity; 52 | PipeContainerProvider.openGui(player, pipe, direction, -1, (i, playerInventory, playerEntity) -> new ExtractContainer(i, playerInventory, pipe, direction, -1)); 53 | return InteractionResult.SUCCESS; 54 | } 55 | return super.onPipeSideActivated(stack, state, worldIn, pos, player, handIn, hit, direction); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/items/UpgradeItem.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.items; 2 | 3 | import de.maxhenkel.pipez.Upgrade; 4 | import de.maxhenkel.pipez.datacomponents.EnergyData; 5 | import de.maxhenkel.pipez.datacomponents.FluidData; 6 | import de.maxhenkel.pipez.datacomponents.GasData; 7 | import de.maxhenkel.pipez.datacomponents.ItemData; 8 | import net.minecraft.ChatFormatting; 9 | import net.minecraft.network.chat.Component; 10 | import net.minecraft.network.chat.MutableComponent; 11 | import net.minecraft.world.item.Item; 12 | import net.minecraft.world.item.ItemStack; 13 | import net.minecraft.world.item.TooltipFlag; 14 | import net.minecraft.world.item.component.TooltipDisplay; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.function.Consumer; 19 | 20 | public class UpgradeItem extends Item { 21 | 22 | public static final Component CONFIGURED_ITEM_TOOLTIP = Component.translatable("tooltip.pipez.upgrade.configured.item"); 23 | public static final Component CONFIGURED_ENERGY_TOOLTIP = Component.translatable("tooltip.pipez.upgrade.configured.energy"); 24 | public static final Component CONFIGURED_FLUID_TOOLTIP = Component.translatable("tooltip.pipez.upgrade.configured.fluid"); 25 | public static final Component CONFIGURED_GAS_TOOLTIP = Component.translatable("tooltip.pipez.upgrade.configured.gas"); 26 | 27 | private final Upgrade tier; 28 | 29 | public UpgradeItem(Upgrade tier, Properties properties) { 30 | super(properties); 31 | this.tier = tier; 32 | } 33 | 34 | public Upgrade getTier() { 35 | return tier; 36 | } 37 | 38 | @Override 39 | public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay tooltipDisplay, Consumer consumer, TooltipFlag flag) { 40 | super.appendHoverText(stack, context, tooltipDisplay, consumer, flag); 41 | List list = new ArrayList<>(); 42 | 43 | ItemData itemData = stack.get(ModItems.ITEM_DATA_COMPONENT); 44 | if (itemData != null) { 45 | list.add(CONFIGURED_ITEM_TOOLTIP.copy()); 46 | } 47 | 48 | EnergyData energyData = stack.get(ModItems.ENERGY_DATA_COMPONENT); 49 | if (energyData != null) { 50 | list.add(CONFIGURED_ENERGY_TOOLTIP.copy()); 51 | } 52 | 53 | FluidData fluidData = stack.get(ModItems.FLUID_DATA_COMPONENT); 54 | if (fluidData != null) { 55 | list.add(CONFIGURED_FLUID_TOOLTIP.copy()); 56 | } 57 | GasData gasData = stack.get(ModItems.GAS_DATA_COMPONENT); 58 | if (gasData != null) { 59 | list.add(CONFIGURED_GAS_TOOLTIP.copy()); 60 | } 61 | 62 | if (!list.isEmpty()) { 63 | MutableComponent types = list.stream().reduce((text1, text2) -> text1.append(", ").append(text2)).get(); 64 | consumer.accept(Component.translatable("tooltip.pipez.upgrade.configured", types.withStyle(ChatFormatting.WHITE)).withStyle(ChatFormatting.YELLOW)); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | 74 | 75 | @rem Execute Gradle 76 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* 77 | 78 | :end 79 | @rem End local scope for the variables with windows NT shell 80 | if %ERRORLEVEL% equ 0 goto mainEnd 81 | 82 | :fail 83 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 84 | rem the _cmd.exe /c_ return code! 85 | set EXIT_CODE=%ERRORLEVEL% 86 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 87 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 88 | exit /b %EXIT_CODE% 89 | 90 | :mainEnd 91 | if "%OS%"=="Windows_NT" endlocal 92 | 93 | :omega 94 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/utils/GasUtils.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.utils; 2 | 3 | import de.maxhenkel.corelib.tag.SingleElementTag; 4 | import de.maxhenkel.corelib.tag.Tag; 5 | import de.maxhenkel.pipez.capabilities.ModCapabilities; 6 | import mekanism.api.MekanismAPI; 7 | import mekanism.api.chemical.*; 8 | import net.minecraft.core.*; 9 | import net.minecraft.resources.Identifier; 10 | import net.minecraft.tags.TagKey; 11 | import net.minecraft.world.item.ItemStack; 12 | import net.minecraft.world.level.Level; 13 | import net.neoforged.neoforge.capabilities.ItemCapability; 14 | 15 | import javax.annotation.Nullable; 16 | import java.util.Optional; 17 | 18 | public class GasUtils { 19 | 20 | public static final Tag EMPTY_CHEMICAL_TAG = new SingleElementTag<>(ChemicalStack.EMPTY.getChemical().getRegistryName(), ChemicalStack.EMPTY.getChemical()); 21 | 22 | @Nullable 23 | public static Tag getGas(String name, boolean nullIfNotExists) { 24 | Identifier id; 25 | if (name.startsWith("#")) { 26 | Identifier resourceLocation = Identifier.tryParse(name.substring(1)); 27 | if (resourceLocation == null) { 28 | return nullIfNotExists ? null : EMPTY_CHEMICAL_TAG; 29 | } 30 | return getGasTag(resourceLocation, nullIfNotExists); 31 | } else { 32 | id = Identifier.tryParse(name); 33 | if (id == null) { 34 | return nullIfNotExists ? null : EMPTY_CHEMICAL_TAG; 35 | } 36 | if (!MekanismAPI.CHEMICAL_REGISTRY.containsKey(id)) { 37 | return nullIfNotExists ? null : EMPTY_CHEMICAL_TAG; 38 | } else { 39 | return new SingleElementTag<>(id, MekanismAPI.CHEMICAL_REGISTRY.get(id).map(Holder.Reference::value).orElse(MekanismAPI.EMPTY_CHEMICAL)); 40 | } 41 | } 42 | } 43 | 44 | @Nullable 45 | public static Tag getGasTag(Identifier id, boolean nullIfNotExists) { 46 | TagKey tagKey = TagKey.create(MekanismAPI.CHEMICAL_REGISTRY_NAME, id); 47 | DefaultedRegistry registry = MekanismAPI.CHEMICAL_REGISTRY; 48 | Optional> tag = registry.get((TagKey) tagKey); 49 | if (tag.isEmpty()) { 50 | return nullIfNotExists ? null : EMPTY_CHEMICAL_TAG; 51 | } else { 52 | return new ChemicalTag(tag.get(), id); 53 | } 54 | } 55 | 56 | @Nullable 57 | public static ChemicalStack getGasContained(ItemStack stack) { 58 | ChemicalStack gas = getGasContained(stack, ModCapabilities.CHEMICAL_HANDLER_ITEM_CAPABILITY); 59 | if (gas == null || gas.isEmpty()) { 60 | return null; 61 | } 62 | return gas; 63 | } 64 | 65 | @Nullable 66 | public static ChemicalStack getGasContained(ItemStack stack, ItemCapability capability) { 67 | IChemicalHandler handler = stack.getCapability(capability, null); 68 | if (handler == null) { 69 | return null; 70 | } 71 | if (handler.getChemicalTanks() <= 0) { 72 | return null; 73 | } 74 | return handler.getChemicalInTank(0).copy(); 75 | } 76 | 77 | public static boolean hasChemicalCapability(Level world, BlockPos pos, Direction facing) { 78 | return world.getCapability(ModCapabilities.CHEMICAL_HANDLER_CAPABILITY, pos, facing) != null; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/integration/waila/DataProviderPipes.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.integration.waila; 2 | 3 | import de.maxhenkel.corelib.codec.CodecUtils; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.blocks.PipeBlock; 6 | import de.maxhenkel.pipez.blocks.tileentity.PipeLogicTileEntity; 7 | import de.maxhenkel.pipez.blocks.tileentity.UpgradeTileEntity; 8 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 9 | import net.minecraft.core.Direction; 10 | import net.minecraft.nbt.CompoundTag; 11 | import net.minecraft.nbt.ListTag; 12 | import net.minecraft.nbt.StringTag; 13 | import net.minecraft.network.chat.Component; 14 | import net.minecraft.network.chat.ComponentSerialization; 15 | import net.minecraft.resources.Identifier; 16 | import net.minecraft.world.item.ItemStack; 17 | import net.minecraft.world.level.block.entity.BlockEntity; 18 | import snownee.jade.api.BlockAccessor; 19 | import snownee.jade.api.IServerDataProvider; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class DataProviderPipes implements IServerDataProvider { 25 | 26 | static final DataProviderPipes INSTANCE = new DataProviderPipes(); 27 | 28 | private static final Identifier UID = Identifier.fromNamespaceAndPath(PipezMod.MODID, "pipe_data"); 29 | 30 | @Override 31 | public void appendServerData(CompoundTag compound, BlockAccessor blockAccessor) { 32 | if (blockAccessor.getBlockState().getBlock() instanceof PipeBlock pipe) { 33 | BlockEntity te = blockAccessor.getBlockEntity(); 34 | Direction selectedSide = pipe.getSelection(te.getBlockState(), blockAccessor.getLevel(), te.getBlockPos(), blockAccessor.getPlayer()).getKey(); 35 | if (selectedSide == null) { 36 | return; 37 | } 38 | if (!(te instanceof UpgradeTileEntity)) { 39 | return; 40 | } 41 | 42 | PipeLogicTileEntity pipeTile = (PipeLogicTileEntity) te; 43 | 44 | if (!pipeTile.isExtracting(selectedSide)) { 45 | return; 46 | } 47 | 48 | ItemStack upgrade = pipeTile.getUpgradeItem(selectedSide); 49 | 50 | if (upgrade.isEmpty()) { 51 | CodecUtils.toJsonString(ComponentSerialization.CODEC, Component.translatable("tooltip.pipez.no_upgrade")).ifPresent(s -> compound.putString("Upgrade", s)); 52 | } else { 53 | CodecUtils.toJsonString(ComponentSerialization.CODEC, upgrade.getHoverName()).ifPresent(s -> compound.putString("Upgrade", s)); 54 | } 55 | 56 | List tooltips = new ArrayList<>(); 57 | for (PipeType pipeType : pipeTile.getPipeTypes()) { 58 | if (pipeTile.isEnabled(selectedSide, pipeType)) { 59 | tooltips.add(pipeType.getTransferText(pipeTile.getUpgrade(selectedSide))); 60 | } 61 | } 62 | putTooltips(blockAccessor, compound, tooltips); 63 | } 64 | } 65 | 66 | public void putTooltips(BlockAccessor blockAccessor, CompoundTag compound, List tooltips) { 67 | ListTag list = new ListTag(); 68 | for (Component tooltip : tooltips) { 69 | CodecUtils.toJsonString(ComponentSerialization.CODEC, tooltip).ifPresent(s -> list.add(StringTag.valueOf(s))); 70 | } 71 | compound.put("Tooltips", list); 72 | } 73 | 74 | @Override 75 | public Identifier getUid() { 76 | return UID; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/net/UpdateFilterMessage.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.net; 2 | 3 | import de.maxhenkel.corelib.net.Message; 4 | import de.maxhenkel.pipez.Filter; 5 | import de.maxhenkel.pipez.PipezMod; 6 | import de.maxhenkel.pipez.blocks.tileentity.types.PipeType; 7 | import de.maxhenkel.pipez.gui.ExtractContainer; 8 | import de.maxhenkel.pipez.gui.IPipeContainer; 9 | import de.maxhenkel.pipez.gui.containerfactory.PipeContainerProvider; 10 | import net.minecraft.nbt.CompoundTag; 11 | import net.minecraft.network.RegistryFriendlyByteBuf; 12 | import net.minecraft.network.protocol.PacketFlow; 13 | import net.minecraft.network.protocol.common.custom.CustomPacketPayload; 14 | import net.minecraft.resources.Identifier; 15 | import net.minecraft.server.level.ServerPlayer; 16 | import net.neoforged.neoforge.network.handling.IPayloadContext; 17 | 18 | import java.util.List; 19 | import java.util.Optional; 20 | 21 | public class UpdateFilterMessage implements Message { 22 | 23 | public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Identifier.fromNamespaceAndPath(PipezMod.MODID, "update_filter")); 24 | 25 | private Filter filter; 26 | private CompoundTag filterTag; 27 | private int index; 28 | 29 | public UpdateFilterMessage() { 30 | 31 | } 32 | 33 | public UpdateFilterMessage(Filter filter, int index) { 34 | this.filter = filter; 35 | this.index = index; 36 | } 37 | 38 | @Override 39 | public PacketFlow getExecutingSide() { 40 | return PacketFlow.SERVERBOUND; 41 | } 42 | 43 | @Override 44 | public void executeServerSide(IPayloadContext context) { 45 | if (!(context.player() instanceof ServerPlayer sender)) { 46 | return; 47 | } 48 | if (!(sender.containerMenu instanceof IPipeContainer pipeContainer)) { 49 | return; 50 | } 51 | PipeType[] pipeTypes = pipeContainer.getPipe().getPipeTypes(); 52 | if (index >= pipeTypes.length) { 53 | return; 54 | } 55 | PipeType pipeType = pipeTypes[index]; 56 | filter = pipeType.createFilter(); 57 | if (filter == null) { 58 | return; 59 | } 60 | filter = filter.fromNbt(filterTag); 61 | 62 | List> filters = pipeContainer.getPipe().getFilters(pipeContainer.getSide(), pipeType); 63 | 64 | Optional> editFilter = filters.stream().filter(f1 -> filter.getId().equals(f1.getId())).findFirst(); 65 | if (editFilter.isPresent()) { 66 | int index = filters.indexOf(editFilter.get()); 67 | if (index >= 0) { 68 | filters.set(index, filter); 69 | } else { 70 | filters.add(filter); 71 | } 72 | } else { 73 | filters.add(filter); 74 | } 75 | pipeContainer.getPipe().setFilters(pipeContainer.getSide(), pipeType, filters); 76 | 77 | PipeContainerProvider.openGui(sender, pipeContainer.getPipe(), pipeContainer.getSide(), index, (id, playerInventory, playerEntity) -> new ExtractContainer(id, playerInventory, pipeContainer.getPipe(), pipeContainer.getSide(), index)); 78 | } 79 | 80 | @Override 81 | public UpdateFilterMessage fromBytes(RegistryFriendlyByteBuf packetBuffer) { 82 | filterTag = packetBuffer.readNbt(); 83 | index = packetBuffer.readInt(); 84 | return this; 85 | } 86 | 87 | @Override 88 | public void toBytes(RegistryFriendlyByteBuf packetBuffer) { 89 | packetBuffer.writeNbt(filter.toNbt()); 90 | packetBuffer.writeInt(index); 91 | } 92 | 93 | @Override 94 | public Type type() { 95 | return TYPE; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/ModTileEntities.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity; 2 | 3 | import de.maxhenkel.pipez.PipezMod; 4 | import de.maxhenkel.pipez.blocks.ModBlocks; 5 | import de.maxhenkel.pipez.blocks.tileentity.render.*; 6 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; 7 | import net.minecraft.core.registries.BuiltInRegistries; 8 | import net.minecraft.world.level.block.entity.BlockEntityType; 9 | import net.neoforged.bus.api.IEventBus; 10 | import net.neoforged.neoforge.capabilities.Capabilities; 11 | import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; 12 | import net.neoforged.neoforge.registries.DeferredHolder; 13 | import net.neoforged.neoforge.registries.DeferredRegister; 14 | 15 | public class ModTileEntities { 16 | 17 | private static final DeferredRegister> BLOCK_ENTITY_REGISTER = DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, PipezMod.MODID); 18 | 19 | public static final DeferredHolder, BlockEntityType> ITEM_PIPE = BLOCK_ENTITY_REGISTER.register("item_pipe", () -> 20 | new BlockEntityType<>(ItemPipeTileEntity::new, ModBlocks.ITEM_PIPE.get()) 21 | ); 22 | public static final DeferredHolder, BlockEntityType> FLUID_PIPE = BLOCK_ENTITY_REGISTER.register("fluid_pipe", () -> 23 | new BlockEntityType<>(FluidPipeTileEntity::new, ModBlocks.FLUID_PIPE.get()) 24 | ); 25 | public static final DeferredHolder, BlockEntityType> ENERGY_PIPE = BLOCK_ENTITY_REGISTER.register("energy_pipe", () -> 26 | new BlockEntityType<>(EnergyPipeTileEntity::new, ModBlocks.ENERGY_PIPE.get()) 27 | ); 28 | public static final DeferredHolder, BlockEntityType> GAS_PIPE = BLOCK_ENTITY_REGISTER.register("gas_pipe", () -> 29 | new BlockEntityType<>(GasPipeTileEntity::new, ModBlocks.GAS_PIPE.get()) 30 | ); 31 | public static final DeferredHolder, BlockEntityType> UNIVERSAL_PIPE = BLOCK_ENTITY_REGISTER.register("universal_pipe", () -> 32 | new BlockEntityType<>(UniversalPipeTileEntity::new, ModBlocks.UNIVERSAL_PIPE.get()) 33 | ); 34 | 35 | public static void init(IEventBus eventBus) { 36 | BLOCK_ENTITY_REGISTER.register(eventBus); 37 | eventBus.addListener(ModTileEntities::onRegisterCapabilities); 38 | } 39 | 40 | public static void clientSetup() { 41 | BlockEntityRenderers.register(ITEM_PIPE.get(), ItemPipeRenderer::new); 42 | BlockEntityRenderers.register(FLUID_PIPE.get(), FluidPipeRenderer::new); 43 | BlockEntityRenderers.register(ENERGY_PIPE.get(), EnergyPipeRenderer::new); 44 | BlockEntityRenderers.register(GAS_PIPE.get(), GasPipeRenderer::new); 45 | BlockEntityRenderers.register(UNIVERSAL_PIPE.get(), UniversalPipeRenderer::new); 46 | } 47 | 48 | public static void onRegisterCapabilities(RegisterCapabilitiesEvent event) { 49 | onRegisterPipeCapabilities(event, ITEM_PIPE); 50 | onRegisterPipeCapabilities(event, FLUID_PIPE); 51 | onRegisterPipeCapabilities(event, ENERGY_PIPE); 52 | onRegisterPipeCapabilities(event, GAS_PIPE); 53 | onRegisterPipeCapabilities(event, UNIVERSAL_PIPE); 54 | } 55 | 56 | public static > void onRegisterPipeCapabilities(RegisterCapabilitiesEvent event, DeferredHolder, T> holder) { 57 | event.registerBlockEntity(Capabilities.Item.BLOCK, holder.get(), (object, context) -> object.onRegisterCapability(Capabilities.Item.BLOCK, context)); 58 | event.registerBlockEntity(Capabilities.Energy.BLOCK, holder.get(), (object, context) -> object.onRegisterCapability(Capabilities.Energy.BLOCK, context)); 59 | event.registerBlockEntity(Capabilities.Fluid.BLOCK, holder.get(), (object, context) -> object.onRegisterCapability(Capabilities.Fluid.BLOCK, context)); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/lang/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.pipez": "Pipez", 3 | "block.pipez.item_pipe": "物品管道", 4 | "block.pipez.fluid_pipe": "流体管道", 5 | "block.pipez.energy_pipe": "能量管道", 6 | "block.pipez.universal_pipe": "通用管道", 7 | "block.pipez.gas_pipe": "气体管道", 8 | "item.pipez.basic_upgrade": "基础管道升级", 9 | "item.pipez.improved_upgrade": "进阶管道升级", 10 | "item.pipez.advanced_upgrade": "高级管道升级", 11 | "item.pipez.ultimate_upgrade": "终极管道升级", 12 | "item.pipez.infinity_upgrade": "无限管道升级", 13 | "item.pipez.wrench": "管道扳手", 14 | "item.pipez.filter_destination_tool": "过滤器目标工具", 15 | "tooltip.pipez.wrench": "点击管道以设置", 16 | "tooltip.pipez.distribution": "分配规则:%s", 17 | "tooltip.pipez.distribution.nearest": "最近优先", 18 | "tooltip.pipez.distribution.furthest": "最远优先", 19 | "tooltip.pipez.distribution.round_robin": "轮询调度", 20 | "tooltip.pipez.distribution.random": "随机分配", 21 | "tooltip.pipez.redstone_mode": "红石模式:%s", 22 | "tooltip.pipez.redstone_mode.ignored": "忽略", 23 | "tooltip.pipez.redstone_mode.off_when_powered": "充能时关闭", 24 | "tooltip.pipez.redstone_mode.on_when_powered": "充能时开启", 25 | "tooltip.pipez.redstone_mode.always_off": "始终关闭", 26 | "tooltip.pipez.filter_mode": "过滤模式:%s", 27 | "tooltip.pipez.filter_mode.whitelist": "白名单", 28 | "tooltip.pipez.filter_mode.blacklist": "黑名单", 29 | "tooltip.pipez.filter.not": "排除", 30 | "tooltip.pipez.filter.accepts_tag": "任何%s", 31 | "tooltip.pipez.filter.item_tag.description": "以#为前缀的标签或物品ID", 32 | "tooltip.pipez.filter.nbt_string.description": "NBT数据", 33 | "tooltip.pipez.filter.nbt_string.no_nbt": "该类型无法具有NBT标签", 34 | "tooltip.pipez.filter.nbt.exact": "精确匹配NBT数据", 35 | "tooltip.pipez.filter.nbt.not_exact": "仅匹配设置的标签", 36 | "tooltip.pipez.filter.not_inverted": "常规", 37 | "tooltip.pipez.filter.inverted": "反选", 38 | "tooltip.pipez.filter_destination_tool": "点击方块来设定目标", 39 | "tooltip.pipez.filter_destination_tool.destination": "目标:X=%s,Y=%s,Z=%s,%s", 40 | "tooltip.pipez.filter.destination.description": "使用过滤器目标工具来设定目标", 41 | "tooltip.pipez.filter.destination.click_to_remove": "点击以移除", 42 | "tooltip.pipez.filter.unknown_block": "未知方块", 43 | "tooltip.pipez.filter.destination_location": "位于X=%s,Y=%s,Z=%s", 44 | "tooltip.pipez.filter.destination_distance": "%s格开外", 45 | "tooltip.pipez.filter.destination_side": "面向%s", 46 | "tooltip.pipez.upgrade.configured": "已存储%s的配置", 47 | "tooltip.pipez.upgrade.configured.item": "物品", 48 | "tooltip.pipez.upgrade.configured.energy": "能量", 49 | "tooltip.pipez.upgrade.configured.fluid": "流体", 50 | "tooltip.pipez.upgrade.configured.gas": "气体", 51 | "tooltip.pipez.rate.item": "单次输送%s个物品,输送间隔%s刻", 52 | "tooltip.pipez.rate.fluid": "每刻输送%smB流体", 53 | "tooltip.pipez.rate.energy": "每刻输送%sFE能量", 54 | "tooltip.pipez.rate.gas": "每刻输送%smB气体", 55 | "tooltip.pipez.no_upgrade": "无升级", 56 | "tooltip.pipez.energy": "能量", 57 | "tooltip.pipez.fluid": "流体", 58 | "tooltip.pipez.gas": "气体", 59 | "tooltip.pipez.item": "物品", 60 | "message.pipez.filter.tag": "标签:%s", 61 | "message.pipez.filter.item": "物品:%s", 62 | "message.pipez.filter.any_item": "任意物品", 63 | "message.pipez.filter.nbt": "NBT:%s", 64 | "message.pipez.filter.nbt.tags": "%s个标签", 65 | "message.pipez.filter.nbt.tag": "%s个标签", 66 | "message.pipez.filter.nbt.exact": "(精确匹配)", 67 | "message.pipez.filter.inverted": "反选", 68 | "message.pipez.direction.north": "北", 69 | "message.pipez.direction.south": "南", 70 | "message.pipez.direction.east": "东", 71 | "message.pipez.direction.west": "西", 72 | "message.pipez.direction.up": "上", 73 | "message.pipez.direction.down": "下", 74 | "message.pipez.filter.add": "添加", 75 | "message.pipez.filter.edit": "编辑", 76 | "message.pipez.filter.remove": "移除", 77 | "message.pipez.filter.cancel": "取消", 78 | "message.pipez.filter.submit": "确定", 79 | "message.pipez.filter.item_tag": "物品/标签", 80 | "message.pipez.filter.nbt_string": "NBT数据", 81 | "message.pipez.filter.destination": "目标", 82 | "message.pipez.filter_destination_tool.destination": "目标:%s,%s,%s,%s", 83 | "message.pipez.filter_destination_tool.destination.any": "目标:任何", 84 | "message.pipez.filter_destination_tool.destination.set": "目标已设定" 85 | } -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/lang/ja_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.pipez": "Pipez", 3 | "block.pipez.item_pipe": "アイテムパイプ", 4 | "block.pipez.fluid_pipe": "流体パイプ", 5 | "block.pipez.energy_pipe": "エネルギーパイプ", 6 | "block.pipez.universal_pipe": "ユニバーサルパイプ", 7 | "block.pipez.gas_pipe": "ガスパイプ", 8 | "item.pipez.basic_upgrade": "基本パイプアップグレード", 9 | "item.pipez.improved_upgrade": "改良パイプアップグレード", 10 | "item.pipez.advanced_upgrade": "発展パイプアップグレード", 11 | "item.pipez.ultimate_upgrade": "究極パイプアップグレード", 12 | "item.pipez.infinity_upgrade": "無限パイプアップグレード", 13 | "item.pipez.wrench": "パイプレンチ", 14 | "item.pipez.filter_destination_tool": "目的地フィルターツール", 15 | "tooltip.pipez.wrench": "パイプをクリックして設定", 16 | "tooltip.pipez.distribution": "目的地:%s", 17 | "tooltip.pipez.distribution.nearest": "近い方を優先", 18 | "tooltip.pipez.distribution.furthest": "遠い方を優先", 19 | "tooltip.pipez.distribution.round_robin": "順繰り分配", 20 | "tooltip.pipez.distribution.random": "ランダム", 21 | "tooltip.pipez.redstone_mode": "レッドストーン:%s", 22 | "tooltip.pipez.redstone_mode.ignored": "無視", 23 | "tooltip.pipez.redstone_mode.off_when_powered": "オフのときのみ動作", 24 | "tooltip.pipez.redstone_mode.on_when_powered": "オンのときのみ動作", 25 | "tooltip.pipez.redstone_mode.always_off": "常にオフ", 26 | "tooltip.pipez.filter_mode": "フィルター:%s", 27 | "tooltip.pipez.filter_mode.whitelist": "ホワイトリスト", 28 | "tooltip.pipez.filter_mode.blacklist": "ブラックリスト", 29 | "tooltip.pipez.filter.not": "以外", 30 | "tooltip.pipez.filter.accepts_tag": "任意の%s", 31 | "tooltip.pipez.filter.item_tag.description": "タグ(接頭辞:#)またはアイテムID", 32 | "tooltip.pipez.filter.nbt_string.description": "NBTデータ", 33 | "tooltip.pipez.filter.nbt_string.no_nbt": "NBTタグを持つことができない種類です", 34 | "tooltip.pipez.filter.nbt.exact": "正確なNBTデータと一致", 35 | "tooltip.pipez.filter.nbt.not_exact": "指定されたタグのみと一致", 36 | "tooltip.pipez.filter.not_inverted": "通常", 37 | "tooltip.pipez.filter.inverted": "反転", 38 | "tooltip.pipez.filter_destination_tool": "ブロックをクリックして目的地を設定", 39 | "tooltip.pipez.filter_destination_tool.destination": "目的地:X=%s, Y=%s, Z=%s, %s", 40 | "tooltip.pipez.filter.destination.description": "目的地フィルターツールで目的地を設定", 41 | "tooltip.pipez.filter.destination.click_to_remove": "クリックして削除", 42 | "tooltip.pipez.filter.unknown_block": "不明なブロック", 43 | "tooltip.pipez.filter.destination_location": "位置:X=%s, Y=%s, Z=%s", 44 | "tooltip.pipez.filter.destination_distance": "距離:%sブロック", 45 | "tooltip.pipez.filter.destination_side": "方向:%s", 46 | "tooltip.pipez.upgrade.configured": "設定済み:%s", 47 | "tooltip.pipez.upgrade.configured.item": "アイテム", 48 | "tooltip.pipez.upgrade.configured.energy": "エネルギー", 49 | "tooltip.pipez.upgrade.configured.fluid": "流体", 50 | "tooltip.pipez.upgrade.configured.gas": "ガス", 51 | "tooltip.pipez.rate.item": "%2$sティック毎に%1$s個のアイテムを輸送", 52 | "tooltip.pipez.rate.fluid": "1ティック毎に%s mBの流体を輸送", 53 | "tooltip.pipez.rate.energy": "1ティック毎に%s FEのエネルギーを輸送", 54 | "tooltip.pipez.rate.gas": "1ティック毎に%s mBのガスを輸送", 55 | "tooltip.pipez.no_upgrade": "アップグレードなし", 56 | "tooltip.pipez.energy": "エネルギー", 57 | "tooltip.pipez.fluid": "流体", 58 | "tooltip.pipez.gas": "ガス", 59 | "tooltip.pipez.item": "アイテム", 60 | "message.pipez.filter.tag": "タグ:%s", 61 | "message.pipez.filter.item": "アイテム:%s", 62 | "message.pipez.filter.any_item": "任意の", 63 | "message.pipez.filter.nbt": "NBT:%s", 64 | "message.pipez.filter.nbt.tags": "%s個のタグ", 65 | "message.pipez.filter.nbt.tag": "%s個のタグ", 66 | "message.pipez.filter.nbt.exact": "(正確)", 67 | "message.pipez.filter.inverted": "反転", 68 | "message.pipez.direction.north": "北", 69 | "message.pipez.direction.south": "南", 70 | "message.pipez.direction.east": "東", 71 | "message.pipez.direction.west": "西", 72 | "message.pipez.direction.up": "上", 73 | "message.pipez.direction.down": "下", 74 | "message.pipez.filter.add": "追加", 75 | "message.pipez.filter.edit": "編集", 76 | "message.pipez.filter.remove": "削除", 77 | "message.pipez.filter.cancel": "キャンセル", 78 | "message.pipez.filter.submit": "確定", 79 | "message.pipez.filter.item_tag": "アイテム/タグ", 80 | "message.pipez.filter.nbt_string": "NBTデータ", 81 | "message.pipez.filter.destination": "目的地", 82 | "message.pipez.filter_destination_tool.destination": "目的地:%s, %s, %s, %s", 83 | "message.pipez.filter_destination_tool.destination.any": "目的地:任意", 84 | "message.pipez.filter_destination_tool.destination.set": "目的地を設定しました" 85 | } 86 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/lang/ko_kr.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.pipez": "Pipez", 3 | "block.pipez.item_pipe": "아이템 파이프", 4 | "block.pipez.fluid_pipe": "유체 파이프", 5 | "block.pipez.energy_pipe": "에너지 파이프", 6 | "block.pipez.universal_pipe": "범용 파이프", 7 | "block.pipez.gas_pipe": "가스 파이프", 8 | "item.pipez.basic_upgrade": "기본 파이프 업그레이드", 9 | "item.pipez.improved_upgrade": "개선된 파이프 업그레이드", 10 | "item.pipez.advanced_upgrade": "고급 파이프 업그레이드", 11 | "item.pipez.ultimate_upgrade": "궁극의 파이프 업그레이드", 12 | "item.pipez.infinity_upgrade": "무한 파이프 업그레이드", 13 | "item.pipez.wrench": "파이프 렌치", 14 | "item.pipez.filter_destination_tool": "필터 목적지 도구", 15 | "tooltip.pipez.wrench": "파이프에 클릭하여 구성합니다.", 16 | "tooltip.pipez.distribution": "분배: %s", 17 | "tooltip.pipez.distribution.nearest": "가까운 곳부터", 18 | "tooltip.pipez.distribution.furthest": "먼 곳부터", 19 | "tooltip.pipez.distribution.round_robin": "라운드 로빈", 20 | "tooltip.pipez.distribution.random": "무작위", 21 | "tooltip.pipez.redstone_mode": "레드스톤 모드: %s", 22 | "tooltip.pipez.redstone_mode.ignored": "무시", 23 | "tooltip.pipez.redstone_mode.off_when_powered": "신호 시 꺼짐", 24 | "tooltip.pipez.redstone_mode.on_when_powered": "신호 시 켜짐", 25 | "tooltip.pipez.redstone_mode.always_off": "언제나 꺼짐", 26 | "tooltip.pipez.filter_mode": "필터 모드: %s", 27 | "tooltip.pipez.filter_mode.whitelist": "화이트리스트", 28 | "tooltip.pipez.filter_mode.blacklist": "블랙리스트", 29 | "tooltip.pipez.filter.not": "Not", 30 | "tooltip.pipez.filter.accepts_tag": "모든 %s", 31 | "tooltip.pipez.filter.item_tag.description": "태그는 접두사로 # 이나 아이템 ID를 가집니다.", 32 | "tooltip.pipez.filter.nbt_string.description": "NBT 데이터", 33 | "tooltip.pipez.filter.nbt_string.no_nbt": "이 유형은 NBT 태그를 가질 수 없습니다.", 34 | "tooltip.pipez.filter.nbt.exact": "정확한 NBT 데이터 일치", 35 | "tooltip.pipez.filter.nbt.not_exact": "주어진 태그만 일치시킵니다.", 36 | "tooltip.pipez.filter.not_inverted": "기본", 37 | "tooltip.pipez.filter.inverted": "반대", 38 | "tooltip.pipez.filter_destination_tool": "블록에 클릭하여 목적지를 설정하세요.", 39 | "tooltip.pipez.filter_destination_tool.destination": "목적지: X=%s, Y=%s, Z=%s, %s", 40 | "tooltip.pipez.filter.destination.description": "필터 목적지 도구로 목적지를 설정하세요.", 41 | "tooltip.pipez.filter.destination.click_to_remove": "클릭하여 삭제", 42 | "tooltip.pipez.filter.unknown_block": "알려지지 않은 블록", 43 | "tooltip.pipez.filter.destination_location": "위치 X=%s, Y=%s, Z=%s", 44 | "tooltip.pipez.filter.destination_distance": "%s 블록 떨어짐", 45 | "tooltip.pipez.filter.destination_side": "%s를 보고 있음", 46 | "tooltip.pipez.upgrade.configured": "%s를 구성했습니다.", 47 | "tooltip.pipez.upgrade.configured.item": "아이템", 48 | "tooltip.pipez.upgrade.configured.energy": "에너지", 49 | "tooltip.pipez.upgrade.configured.fluid": "유체", 50 | "tooltip.pipez.upgrade.configured.gas": "가스", 51 | "tooltip.pipez.rate.item": "Transferring %s items every %s tick(s)", 52 | "tooltip.pipez.rate.fluid": "Transferring %s mB every tick", 53 | "tooltip.pipez.rate.energy": "Transferring %s FE every tick", 54 | "tooltip.pipez.rate.gas": "Transferring %s mB gas every tick", 55 | "tooltip.pipez.no_upgrade": "업그레이드 없음", 56 | "tooltip.pipez.energy": "에너지", 57 | "tooltip.pipez.fluid": "유체", 58 | "tooltip.pipez.gas": "가스", 59 | "tooltip.pipez.item": "아이템", 60 | "message.pipez.filter.tag": "태그: %s", 61 | "message.pipez.filter.item": "아이템: %s", 62 | "message.pipez.filter.any_item": "아무 아이템", 63 | "message.pipez.filter.nbt": "NBT: %s", 64 | "message.pipez.filter.nbt.tags": "%s 태그", 65 | "message.pipez.filter.nbt.tag": "%s 태그", 66 | "message.pipez.filter.nbt.exact": "(정확)", 67 | "message.pipez.filter.inverted": "반대", 68 | "message.pipez.direction.north": "북쪽", 69 | "message.pipez.direction.south": "남쪽", 70 | "message.pipez.direction.east": "동쪽", 71 | "message.pipez.direction.west": "서쪽", 72 | "message.pipez.direction.up": "위", 73 | "message.pipez.direction.down": "아래", 74 | "message.pipez.filter.add": "추가", 75 | "message.pipez.filter.edit": "편집", 76 | "message.pipez.filter.remove": "제거", 77 | "message.pipez.filter.cancel": "취소", 78 | "message.pipez.filter.submit": "확인", 79 | "message.pipez.filter.item_tag": "아이템/태그", 80 | "message.pipez.filter.nbt_string": "NBT 데이터", 81 | "message.pipez.filter.destination": "목적지", 82 | "message.pipez.filter_destination_tool.destination": "목적지: %s, %s, %s, %s", 83 | "message.pipez.filter_destination_tool.destination.any": "목적지: 아무데나", 84 | "message.pipez.filter_destination_tool.destination.set": "목적지 설정" 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/recipes/ClearComponentsRecipe.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.recipes; 2 | 3 | import com.mojang.serialization.Codec; 4 | import com.mojang.serialization.MapCodec; 5 | import com.mojang.serialization.codecs.RecordCodecBuilder; 6 | import net.minecraft.core.HolderLookup; 7 | import net.minecraft.core.component.DataComponentType; 8 | import net.minecraft.core.registries.BuiltInRegistries; 9 | import net.minecraft.network.RegistryFriendlyByteBuf; 10 | import net.minecraft.network.codec.ByteBufCodecs; 11 | import net.minecraft.network.codec.StreamCodec; 12 | import net.minecraft.resources.Identifier; 13 | import net.minecraft.world.item.ItemStack; 14 | import net.minecraft.world.item.crafting.*; 15 | import net.minecraft.world.level.Level; 16 | 17 | import javax.annotation.Nullable; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.Map; 21 | import java.util.Optional; 22 | 23 | public class ClearComponentsRecipe extends CustomRecipe { 24 | 25 | private final Ingredient ingredient; 26 | private final List components; 27 | 28 | public ClearComponentsRecipe(Ingredient ingredient, List components) { 29 | super(CraftingBookCategory.MISC); 30 | this.ingredient = ingredient; 31 | this.components = components; 32 | } 33 | 34 | @Nullable 35 | public ItemStack getIngredient(CraftingInput inv) { 36 | ItemStack found = null; 37 | for (int i = 0; i < inv.size(); i++) { 38 | ItemStack stackInSlot = inv.getItem(i); 39 | if (ingredient.test(stackInSlot)) { 40 | if (found != null) { 41 | return null; 42 | } else { 43 | found = stackInSlot; 44 | } 45 | } else if (!stackInSlot.isEmpty()) { 46 | return null; 47 | } 48 | } 49 | return found; 50 | } 51 | 52 | @Override 53 | public boolean matches(CraftingInput inv, Level worldIn) { 54 | return getIngredient(inv) != null; 55 | } 56 | 57 | @Override 58 | public ItemStack assemble(CraftingInput inv, HolderLookup.Provider provider) { 59 | ItemStack ingredient = getIngredient(inv); 60 | if (ingredient == null) { 61 | return ItemStack.EMPTY; 62 | } else { 63 | ItemStack stack = ingredient.copy(); 64 | for (Map.Entry, Optional> e : stack.getComponentsPatch().entrySet()) { 65 | Identifier key = BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(e.getKey()); 66 | if (key == null) { 67 | continue; 68 | } 69 | if (!components.contains(key)) { 70 | continue; 71 | } 72 | stack.remove(e.getKey()); 73 | } 74 | 75 | stack.setCount(1); 76 | return stack; 77 | } 78 | } 79 | 80 | @Override 81 | public RecipeSerializer getSerializer() { 82 | return ModRecipes.CLEAR_NBT.get(); 83 | } 84 | 85 | public static class Serializer implements RecipeSerializer { 86 | 87 | private static final MapCodec CODEC = RecordCodecBuilder.mapCodec((builder) -> builder 88 | .group( 89 | Ingredient.CODEC 90 | .fieldOf("item") 91 | .forGetter((recipe) -> recipe.ingredient), 92 | Codec.list(Identifier.CODEC) 93 | .fieldOf("components") 94 | .forGetter((recipe) -> recipe.components) 95 | ).apply(builder, ClearComponentsRecipe::new)); 96 | 97 | private static final StreamCodec STREAM_CODEC = StreamCodec.composite( 98 | Ingredient.CONTENTS_STREAM_CODEC, 99 | r -> r.ingredient, 100 | ByteBufCodecs.collection(ArrayList::new, Identifier.STREAM_CODEC), 101 | r -> r.components, 102 | ClearComponentsRecipe::new 103 | ); 104 | 105 | public Serializer() { 106 | 107 | } 108 | 109 | @Override 110 | public MapCodec codec() { 111 | return CODEC; 112 | } 113 | 114 | @Override 115 | public StreamCodec streamCodec() { 116 | return STREAM_CODEC; 117 | } 118 | 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/blocks/tileentity/render/PipeRenderer.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.blocks.tileentity.render; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.mojang.math.Axis; 5 | import de.maxhenkel.pipez.ModelRegistry.Model; 6 | import de.maxhenkel.pipez.blocks.tileentity.PipeTileEntity; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.renderer.SubmitNodeCollector; 9 | import net.minecraft.client.renderer.block.model.BakedQuad; 10 | import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; 11 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 12 | import net.minecraft.client.renderer.feature.ModelFeatureRenderer; 13 | import net.minecraft.client.renderer.rendertype.RenderTypes; 14 | import net.minecraft.client.renderer.state.CameraRenderState; 15 | import net.minecraft.client.renderer.texture.OverlayTexture; 16 | import net.minecraft.client.resources.model.QuadCollection; 17 | import net.minecraft.core.Direction; 18 | import net.minecraft.world.phys.Vec3; 19 | import org.jetbrains.annotations.Nullable; 20 | import org.joml.Quaternionf; 21 | 22 | import java.util.List; 23 | import java.util.concurrent.atomic.AtomicReference; 24 | 25 | public abstract class PipeRenderer implements BlockEntityRenderer { 26 | 27 | protected Minecraft minecraft; 28 | protected BlockEntityRendererProvider.Context renderer; 29 | protected AtomicReference cachedModel; 30 | 31 | public PipeRenderer(BlockEntityRendererProvider.Context renderer) { 32 | this.renderer = renderer; 33 | minecraft = Minecraft.getInstance(); 34 | cachedModel = getModel().getModel(); 35 | } 36 | 37 | @Override 38 | public PipeRenderState createRenderState() { 39 | return new PipeRenderState(); 40 | } 41 | 42 | @Override 43 | public void extractRenderState(PipeTileEntity entity, PipeRenderState state, float partialTicks, Vec3 pos, @Nullable ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) { 44 | BlockEntityRenderer.super.extractRenderState(entity, state, partialTicks, pos, crumblingOverlay); 45 | 46 | for (Direction side : Direction.values()) { 47 | state.extracting[side.ordinal()] = entity.isExtracting(side); 48 | } 49 | } 50 | 51 | @Override 52 | public void submit(PipeRenderState state, PoseStack stack, SubmitNodeCollector collector, CameraRenderState cameraRenderState) { 53 | QuadCollection model = cachedModel.get(); 54 | if (model == null) { 55 | return; 56 | } 57 | 58 | for (Direction side : Direction.values()) { 59 | if (state.extracting[side.ordinal()]) { 60 | renderExtractor(model, side, stack, collector, state.lightCoords, OverlayTexture.NO_OVERLAY); 61 | } 62 | } 63 | } 64 | 65 | private void renderExtractor(QuadCollection model, Direction direction, PoseStack stack, SubmitNodeCollector collector, int combinedLight, int combinedOverlay) { 66 | stack.pushPose(); 67 | stack.translate(direction.getStepX() * 0.001D, direction.getStepY() * 0.001D, direction.getStepZ() * 0.001D); 68 | stack.translate(0.5D, 0.5D, 0.5D); 69 | stack.mulPose(getRotation(direction)); 70 | stack.translate(-0.5D, -0.5D, -0.5D); 71 | List quads = model.getQuads(null); 72 | collector.submitCustomGeometry(stack, RenderTypes.solidMovingBlock(), (pose, vertexConsumer) -> { 73 | for (BakedQuad quad : quads) { 74 | vertexConsumer.putBulkData(pose, quad, 1F, 1F, 1F, 1F, combinedLight, combinedOverlay); 75 | } 76 | }); 77 | 78 | stack.popPose(); 79 | } 80 | 81 | private Quaternionf getRotation(Direction direction) { 82 | Quaternionf q = new Quaternionf(); 83 | switch (direction) { 84 | case NORTH: 85 | return q; 86 | case SOUTH: 87 | q.mul(Axis.YP.rotationDegrees(180F)); 88 | return q; 89 | case WEST: 90 | q.mul(Axis.YP.rotationDegrees(90F)); 91 | return q; 92 | case EAST: 93 | q.mul(Axis.YP.rotationDegrees(270F)); 94 | return q; 95 | case UP: 96 | q.mul(Axis.XP.rotationDegrees(90F)); 97 | return q; 98 | case DOWN: 99 | default: 100 | q.mul(Axis.XP.rotationDegrees(270F)); 101 | return q; 102 | } 103 | } 104 | 105 | abstract Model getModel(); 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/de/maxhenkel/pipez/items/ModItems.java: -------------------------------------------------------------------------------- 1 | package de.maxhenkel.pipez.items; 2 | 3 | import de.maxhenkel.pipez.DirectionalPosition; 4 | import de.maxhenkel.pipez.PipezMod; 5 | import de.maxhenkel.pipez.Upgrade; 6 | import de.maxhenkel.pipez.blocks.ModBlocks; 7 | import de.maxhenkel.pipez.datacomponents.EnergyData; 8 | import de.maxhenkel.pipez.datacomponents.FluidData; 9 | import de.maxhenkel.pipez.datacomponents.GasData; 10 | import de.maxhenkel.pipez.datacomponents.ItemData; 11 | import net.minecraft.core.component.DataComponentType; 12 | import net.minecraft.core.registries.BuiltInRegistries; 13 | import net.minecraft.world.item.BlockItem; 14 | import net.minecraft.world.item.Item; 15 | import net.neoforged.bus.api.IEventBus; 16 | import net.neoforged.neoforge.registries.DeferredHolder; 17 | import net.neoforged.neoforge.registries.DeferredRegister; 18 | 19 | public class ModItems { 20 | 21 | private static final DeferredRegister.Items ITEM_REGISTER = DeferredRegister.createItems(PipezMod.MODID); 22 | 23 | public static final DeferredHolder BASIC_UPGRADE = ITEM_REGISTER.registerItem(Upgrade.BASIC.getName() + "_upgrade", p -> new UpgradeItem(Upgrade.BASIC, p)); 24 | public static final DeferredHolder IMPROVED_UPGRADE = ITEM_REGISTER.registerItem(Upgrade.IMPROVED.getName() + "_upgrade", p -> new UpgradeItem(Upgrade.IMPROVED, p)); 25 | public static final DeferredHolder ADVANCED_UPGRADE = ITEM_REGISTER.registerItem(Upgrade.ADVANCED.getName() + "_upgrade", p -> new UpgradeItem(Upgrade.ADVANCED, p)); 26 | public static final DeferredHolder ULTIMATE_UPGRADE = ITEM_REGISTER.registerItem(Upgrade.ULTIMATE.getName() + "_upgrade", p -> new UpgradeItem(Upgrade.ULTIMATE, p)); 27 | public static final DeferredHolder INFINITY_UPGRADE = ITEM_REGISTER.registerItem(Upgrade.INFINITY.getName() + "_upgrade", p -> new UpgradeItem(Upgrade.INFINITY, p)); 28 | public static final DeferredHolder WRENCH = ITEM_REGISTER.registerItem("wrench", WrenchItem::new); 29 | public static final DeferredHolder FILTER_DESTINATION_TOOL = ITEM_REGISTER.registerItem("filter_destination_tool", FilterDestinationToolItem::new); 30 | 31 | public static final DeferredHolder ITEM_PIPE = ITEM_REGISTER.registerSimpleBlockItem(ModBlocks.ITEM_PIPE); 32 | public static final DeferredHolder FLUID_PIPE = ITEM_REGISTER.registerSimpleBlockItem(ModBlocks.FLUID_PIPE); 33 | public static final DeferredHolder ENERGY_PIPE = ITEM_REGISTER.registerSimpleBlockItem(ModBlocks.ENERGY_PIPE); 34 | public static final DeferredHolder UNIVERSAL_PIPE = ITEM_REGISTER.registerSimpleBlockItem(ModBlocks.UNIVERSAL_PIPE); 35 | public static final DeferredHolder GAS_PIPE = ITEM_REGISTER.registerSimpleBlockItem(ModBlocks.GAS_PIPE); 36 | 37 | private static final DeferredRegister> DATA_COMPONENT_TYPE_REGISTER = DeferredRegister.create(BuiltInRegistries.DATA_COMPONENT_TYPE, PipezMod.MODID); 38 | 39 | public static final DeferredHolder, DataComponentType> DIRECTIONAL_POSITION_DATA_COMPONENT = DATA_COMPONENT_TYPE_REGISTER.register("directional_position", () -> DataComponentType.builder().persistent(DirectionalPosition.CODEC).networkSynchronized(DirectionalPosition.STREAM_CODEC).build()); 40 | 41 | public static final DeferredHolder, DataComponentType> ITEM_DATA_COMPONENT = DATA_COMPONENT_TYPE_REGISTER.register("item", () -> DataComponentType.builder().persistent(ItemData.CODEC).networkSynchronized(ItemData.STREAM_CODEC).build()); 42 | public static final DeferredHolder, DataComponentType> FLUID_DATA_COMPONENT = DATA_COMPONENT_TYPE_REGISTER.register("fluid", () -> DataComponentType.builder().persistent(FluidData.CODEC).networkSynchronized(FluidData.STREAM_CODEC).build()); 43 | public static final DeferredHolder, DataComponentType> GAS_DATA_COMPONENT = DATA_COMPONENT_TYPE_REGISTER.register("gas", () -> DataComponentType.builder().persistent(GasData.CODEC).networkSynchronized(GasData.STREAM_CODEC).build()); 44 | public static final DeferredHolder, DataComponentType> ENERGY_DATA_COMPONENT = DATA_COMPONENT_TYPE_REGISTER.register("energy", () -> DataComponentType.builder().persistent(EnergyData.CODEC).networkSynchronized(EnergyData.STREAM_CODEC).build()); 45 | 46 | public static void init(IEventBus eventBus) { 47 | ITEM_REGISTER.register(eventBus); 48 | DATA_COMPONENT_TYPE_REGISTER.register(eventBus); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/assets/pipez/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.pipez": "Pipez", 3 | "block.pipez.item_pipe": "Item Pipe", 4 | "block.pipez.fluid_pipe": "Fluid Pipe", 5 | "block.pipez.energy_pipe": "Energy Pipe", 6 | "block.pipez.universal_pipe": "Universal Pipe", 7 | "block.pipez.gas_pipe": "Gas Pipe", 8 | "item.pipez.basic_upgrade": "Basic Pipe Upgrade", 9 | "item.pipez.improved_upgrade": "Improved Pipe Upgrade", 10 | "item.pipez.advanced_upgrade": "Advanced Pipe Upgrade", 11 | "item.pipez.ultimate_upgrade": "Ultimate Pipe Upgrade", 12 | "item.pipez.infinity_upgrade": "Infinity Pipe Upgrade", 13 | "item.pipez.wrench": "Pipe Wrench", 14 | "item.pipez.filter_destination_tool": "Filter Destination Tool", 15 | "tooltip.pipez.wrench": "Click on a pipe to configure", 16 | "tooltip.pipez.distribution": "Distribution: %s", 17 | "tooltip.pipez.distribution.nearest": "Nearest First", 18 | "tooltip.pipez.distribution.furthest": "Furthest First", 19 | "tooltip.pipez.distribution.round_robin": "Round Robin", 20 | "tooltip.pipez.distribution.random": "Random", 21 | "tooltip.pipez.redstone_mode": "Redstone Mode: %s", 22 | "tooltip.pipez.redstone_mode.ignored": "Ignored", 23 | "tooltip.pipez.redstone_mode.off_when_powered": "Off When Powered", 24 | "tooltip.pipez.redstone_mode.on_when_powered": "On When Powered", 25 | "tooltip.pipez.redstone_mode.always_off": "Always Off", 26 | "tooltip.pipez.filter_mode": "Filter Mode: %s", 27 | "tooltip.pipez.filter_mode.whitelist": "Whitelist", 28 | "tooltip.pipez.filter_mode.blacklist": "Blacklist", 29 | "tooltip.pipez.filter.not": "Not", 30 | "tooltip.pipez.filter.accepts_tag": "Any %s", 31 | "tooltip.pipez.filter.item_tag.description": "Tags prefixed with # or item IDs", 32 | "tooltip.pipez.filter.nbt_string.description": "NBT Data", 33 | "tooltip.pipez.filter.nbt_string.no_nbt": "This type can't have NBT tags", 34 | "tooltip.pipez.filter.nbt.exact": "Match exact NBT data", 35 | "tooltip.pipez.filter.nbt.not_exact": "Match only provided tags", 36 | "tooltip.pipez.filter.not_inverted": "Regular", 37 | "tooltip.pipez.filter.inverted": "Inverted", 38 | "tooltip.pipez.filter_destination_tool": "Click on a block to set destination", 39 | "tooltip.pipez.filter_destination_tool.destination": "Destination: X=%s, Y=%s, Z=%s, %s", 40 | "tooltip.pipez.filter.destination.description": "Use the filter destination tool to set a destination", 41 | "tooltip.pipez.filter.destination.click_to_remove": "Click to remove", 42 | "tooltip.pipez.filter.unknown_block": "UNKNOWN BLOCK", 43 | "tooltip.pipez.filter.destination_location": "At X=%s, Y=%s, Z=%s", 44 | "tooltip.pipez.filter.destination_distance": "%s block(s) away", 45 | "tooltip.pipez.filter.destination_side": "Facing %s", 46 | "tooltip.pipez.upgrade.configured": "Configured for %s", 47 | "tooltip.pipez.upgrade.configured.item": "Items", 48 | "tooltip.pipez.upgrade.configured.energy": "Energy", 49 | "tooltip.pipez.upgrade.configured.fluid": "Fluids", 50 | "tooltip.pipez.upgrade.configured.gas": "Gases", 51 | "tooltip.pipez.rate.item": "Transferring %s items every %s tick(s)", 52 | "tooltip.pipez.rate.fluid": "Transferring %s mB every tick", 53 | "tooltip.pipez.rate.energy": "Transferring %s FE every tick", 54 | "tooltip.pipez.rate.gas": "Transferring %s mB gas every tick", 55 | "tooltip.pipez.no_upgrade": "No Upgrade", 56 | "tooltip.pipez.energy": "Energy", 57 | "tooltip.pipez.fluid": "Fluid", 58 | "tooltip.pipez.gas": "Gas", 59 | "tooltip.pipez.item": "Items", 60 | "message.pipez.filter.tag": "Tag: %s", 61 | "message.pipez.filter.item": "Item: %s", 62 | "message.pipez.filter.any_item": "Any item", 63 | "message.pipez.filter.nbt": "NBT: %s", 64 | "message.pipez.filter.nbt.tags": "%s Tags", 65 | "message.pipez.filter.nbt.tag": "%s Tag", 66 | "message.pipez.filter.nbt.exact": "(exact)", 67 | "message.pipez.filter.inverted": "Inverted", 68 | "message.pipez.direction.north": "North", 69 | "message.pipez.direction.south": "South", 70 | "message.pipez.direction.east": "East", 71 | "message.pipez.direction.west": "West", 72 | "message.pipez.direction.up": "Up", 73 | "message.pipez.direction.down": "Down", 74 | "message.pipez.filter.add": "Add", 75 | "message.pipez.filter.edit": "Edit", 76 | "message.pipez.filter.remove": "Remove", 77 | "message.pipez.filter.cancel": "Cancel", 78 | "message.pipez.filter.submit": "Submit", 79 | "message.pipez.filter.item_tag": "Item/Tag", 80 | "message.pipez.filter.nbt_string": "NBT Data", 81 | "message.pipez.filter.destination": "Destination", 82 | "message.pipez.filter_destination_tool.destination": "Destination: %s, %s, %s, %s", 83 | "message.pipez.filter_destination_tool.destination.any": "Destination: Any", 84 | "message.pipez.filter_destination_tool.destination.set": "Destination set", 85 | "config.jade.plugin_pipez.pipe": "Pipez" 86 | } --------------------------------------------------------------------------------