From 2e3fcb5432b8802c994929d925bc19c7aec2511a Mon Sep 17 00:00:00 2001 From: DrMangoTea Date: Wed, 13 Sep 2023 17:12:57 +0200 Subject: [PATCH] distillery --- ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../tfmg/recipes/cut_bauxite_brick_slab.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../cut_bauxite_brick_slab_recycling.json | 14 - .../recipes/cut_bauxite_brick_stairs.json | 18 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../tfmg/recipes/cut_bauxite_brick_wall.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../data/tfmg/recipes/cut_bauxite_slab.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../recipes/cut_bauxite_slab_recycling.json | 14 - .../data/tfmg/recipes/cut_bauxite_stairs.json | 18 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../data/tfmg/recipes/cut_bauxite_wall.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../recipes/polished_cut_bauxite_slab.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../polished_cut_bauxite_slab_recycling.json | 14 - .../recipes/polished_cut_bauxite_stairs.json | 18 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../recipes/polished_cut_bauxite_wall.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../recipes/small_bauxite_brick_slab.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../small_bauxite_brick_slab_recycling.json | 14 - .../recipes/small_bauxite_brick_stairs.json | 18 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../recipes/small_bauxite_brick_wall.json | 16 - ...from_stone_types_bauxite_stonecutting.json | 8 - ...from_stone_types_bauxite_stonecutting.json | 8 - .../java/com/drmangotea/tfmg/CreateTFMG.java | 2 + .../DistillationControllerBlock.java | 210 +++++++ .../DistillationControllerBlockEntity.java | 358 +++++++++++ .../distillation/DistillationOutputBlock.java | 57 ++ .../DistillationOutputBlockEntity.java | 427 +++++++++++++ .../FluidProcessingBlockEntity.java | 150 +++++ .../distillation/DistillationRecipe.java | 41 ++ .../recipes/distillation/ItemlessRecipe.java | 206 ++++++ .../tfmg/recipes/jei/AnimatedDistiller.java | 123 ++++ .../recipes/jei/DistillationCategory.java | 86 +++ .../drmangotea/tfmg/recipes/jei/TFMGJei.java | 330 ++++++++++ .../tfmg/registry/TFMGBlockEntities.java | 13 + .../drmangotea/tfmg/registry/TFMGBlocks.java | 22 + .../tfmg/registry/TFMGRecipeTypes.java | 112 ++++ .../backup/DistillationControllerBlock.java | 210 +++++++ .../DistillationControllerBlockEntity.java | 588 ++++++++++++++++++ .../backup/DistillationOutputBlock.java | 57 ++ .../backup/DistillationOutputBlockEntity.java | 423 +++++++++++++ .../backup/FluidProcessingBlockEntity.java | 156 +++++ src/main/resources/changelog.txt | 6 +- .../tfmg/recipes/distillation/heavy_oil.json | 35 ++ .../tfmg/recipes/distillation/naphtha.json | 35 ++ 57 files changed, 3646 insertions(+), 409 deletions(-) delete mode 100644 src/generated/resources/data/tfmg/recipes/bauxite_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/bauxite_pillar_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_recycling.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_bricks_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_slab.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_recycling.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_wall.json delete mode 100644 src/generated/resources/data/tfmg/recipes/cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/layered_bauxite_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_recycling.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall.json delete mode 100644 src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_recycling.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json delete mode 100644 src/generated/resources/data/tfmg/recipes/small_bauxite_bricks_from_stone_types_bauxite_stonecutting.json create mode 100644 src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlock.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlockEntity.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlock.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlockEntity.java create mode 100644 src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/FluidProcessingBlockEntity.java create mode 100644 src/main/java/com/drmangotea/tfmg/recipes/distillation/DistillationRecipe.java create mode 100644 src/main/java/com/drmangotea/tfmg/recipes/distillation/ItemlessRecipe.java create mode 100644 src/main/java/com/drmangotea/tfmg/recipes/jei/AnimatedDistiller.java create mode 100644 src/main/java/com/drmangotea/tfmg/recipes/jei/DistillationCategory.java create mode 100644 src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java create mode 100644 src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java create mode 100644 src/main/resources/backup/DistillationControllerBlock.java create mode 100644 src/main/resources/backup/DistillationControllerBlockEntity.java create mode 100644 src/main/resources/backup/DistillationOutputBlock.java create mode 100644 src/main/resources/backup/DistillationOutputBlockEntity.java create mode 100644 src/main/resources/backup/FluidProcessingBlockEntity.java create mode 100644 src/main/resources/data/tfmg/recipes/distillation/heavy_oil.json create mode 100644 src/main/resources/data/tfmg/recipes/distillation/naphtha.json diff --git a/src/generated/resources/data/tfmg/recipes/bauxite_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/bauxite_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index d7408f0f..00000000 --- a/src/generated/resources/data/tfmg/recipes/bauxite_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:bauxite" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/bauxite_pillar_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/bauxite_pillar_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index dbab2729..00000000 --- a/src/generated/resources/data/tfmg/recipes/bauxite_pillar_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:bauxite_pillar" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab.json deleted file mode 100644 index 7e9b6110..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "cut_bauxite_brick_slab", - "key": { - "X": { - "item": "tfmg:cut_bauxite_bricks" - } - }, - "pattern": [ - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:cut_bauxite_brick_slab" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 82519606..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 2, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_brick_slab" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_recycling.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_recycling.json deleted file mode 100644 index 443965fb..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_slab_recycling.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "tfmg:cut_bauxite_brick_slab" - }, - { - "item": "tfmg:cut_bauxite_brick_slab" - } - ], - "result": { - "item": "tfmg:cut_bauxite_bricks" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs.json deleted file mode 100644 index c8cd57be..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "cut_bauxite_brick_stairs", - "key": { - "X": { - "item": "tfmg:cut_bauxite_bricks" - } - }, - "pattern": [ - "X ", - "XX ", - "XXX" - ], - "result": { - "count": 4, - "item": "tfmg:cut_bauxite_brick_stairs" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index fd25aaa1..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_brick_stairs" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall.json deleted file mode 100644 index 4ee119a7..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "key": { - "X": { - "item": "tfmg:cut_bauxite_bricks" - } - }, - "pattern": [ - "XXX", - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:cut_bauxite_brick_wall" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index cbbba670..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_brick_wall" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_bricks_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_bricks_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 2b915ab5..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_bricks_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_bricks" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 8fc25b0f..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab.json deleted file mode 100644 index 4ce5bebc..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "cut_bauxite_slab", - "key": { - "X": { - "item": "tfmg:cut_bauxite" - } - }, - "pattern": [ - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:cut_bauxite_slab" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index f7319fa1..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 2, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_slab" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_recycling.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_recycling.json deleted file mode 100644 index 2aa94ac8..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_slab_recycling.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "tfmg:cut_bauxite_slab" - }, - { - "item": "tfmg:cut_bauxite_slab" - } - ], - "result": { - "item": "tfmg:cut_bauxite" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs.json deleted file mode 100644 index 022fd22e..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "cut_bauxite_stairs", - "key": { - "X": { - "item": "tfmg:cut_bauxite" - } - }, - "pattern": [ - "X ", - "XX ", - "XXX" - ], - "result": { - "count": 4, - "item": "tfmg:cut_bauxite_stairs" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 7eba9d75..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_stairs" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall.json deleted file mode 100644 index 703f941c..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "key": { - "X": { - "item": "tfmg:cut_bauxite" - } - }, - "pattern": [ - "XXX", - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:cut_bauxite_wall" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index cb930e93..00000000 --- a/src/generated/resources/data/tfmg/recipes/cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:cut_bauxite_wall" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/layered_bauxite_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/layered_bauxite_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 4a325a71..00000000 --- a/src/generated/resources/data/tfmg/recipes/layered_bauxite_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:layered_bauxite" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 0a7ee73b..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:polished_cut_bauxite" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab.json deleted file mode 100644 index b8ef9836..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "polished_cut_bauxite_slab", - "key": { - "X": { - "item": "tfmg:polished_cut_bauxite" - } - }, - "pattern": [ - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:polished_cut_bauxite_slab" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index c9d0e8aa..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 2, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:polished_cut_bauxite_slab" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_recycling.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_recycling.json deleted file mode 100644 index 70ec8875..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_slab_recycling.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "tfmg:polished_cut_bauxite_slab" - }, - { - "item": "tfmg:polished_cut_bauxite_slab" - } - ], - "result": { - "item": "tfmg:polished_cut_bauxite" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs.json deleted file mode 100644 index d3e11707..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "polished_cut_bauxite_stairs", - "key": { - "X": { - "item": "tfmg:polished_cut_bauxite" - } - }, - "pattern": [ - "X ", - "XX ", - "XXX" - ], - "result": { - "count": 4, - "item": "tfmg:polished_cut_bauxite_stairs" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 1f960e94..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_stairs_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:polished_cut_bauxite_stairs" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall.json deleted file mode 100644 index f69491a3..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "key": { - "X": { - "item": "tfmg:polished_cut_bauxite" - } - }, - "pattern": [ - "XXX", - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:polished_cut_bauxite_wall" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 9615f1e0..00000000 --- a/src/generated/resources/data/tfmg/recipes/polished_cut_bauxite_wall_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:polished_cut_bauxite_wall" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab.json deleted file mode 100644 index ebd34d9a..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "small_bauxite_brick_slab", - "key": { - "X": { - "item": "tfmg:small_bauxite_bricks" - } - }, - "pattern": [ - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:small_bauxite_brick_slab" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 71c122e2..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 2, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:small_bauxite_brick_slab" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_recycling.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_recycling.json deleted file mode 100644 index 62266244..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_slab_recycling.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "tfmg:small_bauxite_brick_slab" - }, - { - "item": "tfmg:small_bauxite_brick_slab" - } - ], - "result": { - "item": "tfmg:small_bauxite_bricks" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs.json deleted file mode 100644 index 7295b4df..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "small_bauxite_brick_stairs", - "key": { - "X": { - "item": "tfmg:small_bauxite_bricks" - } - }, - "pattern": [ - "X ", - "XX ", - "XXX" - ], - "result": { - "count": 4, - "item": "tfmg:small_bauxite_brick_stairs" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index ce303468..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_stairs_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:small_bauxite_brick_stairs" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall.json deleted file mode 100644 index f87a2789..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "key": { - "X": { - "item": "tfmg:small_bauxite_bricks" - } - }, - "pattern": [ - "XXX", - "XXX" - ], - "result": { - "count": 6, - "item": "tfmg:small_bauxite_brick_wall" - } -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 7d1f84b6..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_brick_wall_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:small_bauxite_brick_wall" -} \ No newline at end of file diff --git a/src/generated/resources/data/tfmg/recipes/small_bauxite_bricks_from_stone_types_bauxite_stonecutting.json b/src/generated/resources/data/tfmg/recipes/small_bauxite_bricks_from_stone_types_bauxite_stonecutting.json deleted file mode 100644 index 9c614555..00000000 --- a/src/generated/resources/data/tfmg/recipes/small_bauxite_bricks_from_stone_types_bauxite_stonecutting.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "count": 1, - "ingredient": { - "tag": "tfmg:stone_types/bauxite" - }, - "result": "tfmg:small_bauxite_bricks" -} \ No newline at end of file diff --git a/src/main/java/com/drmangotea/tfmg/CreateTFMG.java b/src/main/java/com/drmangotea/tfmg/CreateTFMG.java index e06ac23c..d0b2d204 100644 --- a/src/main/java/com/drmangotea/tfmg/CreateTFMG.java +++ b/src/main/java/com/drmangotea/tfmg/CreateTFMG.java @@ -54,8 +54,10 @@ public class CreateTFMG TFMGCreativeModeTabs.init(); TFMGFluids.register(); TFMGPaletteBlocks.register(); + TFMGColoredFires.register(modEventBus); TFMGFeatures.register(modEventBus); + TFMGRecipeTypes.register(modEventBus); // modEventBus.addListener(EventPriority.LOWEST, CreateTFMG::gatherData); diff --git a/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlock.java b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlock.java new file mode 100644 index 00000000..10ef01ae --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlock.java @@ -0,0 +1,210 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation; + + +import com.drmangotea.tfmg.registry.TFMGBlockEntities; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.Create; +import com.simibubi.create.content.equipment.wrench.IWrenchable; +import com.simibubi.create.content.fluids.transfer.GenericItemEmptying; +import com.simibubi.create.content.fluids.transfer.GenericItemFilling; +import com.simibubi.create.content.kinetics.belt.BeltBlockEntity; +import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour; +import com.simibubi.create.content.logistics.funnel.FunnelBlock; +import com.simibubi.create.content.processing.basin.BasinOperatingBlockEntity; +import com.simibubi.create.foundation.block.IBE; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.fluid.FluidHelper; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +public class DistillationControllerBlock extends Block implements IBE, IWrenchable { + + public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER; + + public DistillationControllerBlock(Properties p_i48440_1_) { + super(p_i48440_1_); + registerDefaultState(defaultBlockState().setValue(FACING, Direction.DOWN)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder p_206840_1_) { + super.createBlockStateDefinition(p_206840_1_.add(FACING)); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockEntity tileEntity = world.getBlockEntity(pos.above()); + if (tileEntity instanceof BasinOperatingBlockEntity) + return false; + return true; + } + + + + @Override + public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, + BlockHitResult hit) { + ItemStack heldItem = player.getItemInHand(handIn); + + return onBlockEntityUse(worldIn, pos, te -> { + if (!heldItem.isEmpty()) { + if (FluidHelper.tryEmptyItemIntoBE(worldIn, player, handIn, heldItem, te)) + return InteractionResult.SUCCESS; + if (FluidHelper.tryFillItemFromBE(worldIn, player, handIn, heldItem, te)) + return InteractionResult.SUCCESS; + + if (GenericItemEmptying.canItemBeEmptied(worldIn, heldItem) + || GenericItemFilling.canItemBeFilled(worldIn, heldItem)) + return InteractionResult.SUCCESS; + if (heldItem.getItem() + .equals(Items.SPONGE) + && !te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .map(iFluidHandler -> iFluidHandler.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE)) + .orElse(FluidStack.EMPTY) + .isEmpty()) { + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + + IItemHandlerModifiable inv = te.itemCapability.orElse(new ItemStackHandler(1)); + boolean success = false; + for (int slot = 0; slot < inv.getSlots(); slot++) { + ItemStack stackInSlot = inv.getStackInSlot(slot); + if (stackInSlot.isEmpty()) + continue; + player.getInventory() + .placeItemBackInInventory(stackInSlot); + inv.setStackInSlot(slot, ItemStack.EMPTY); + success = true; + } + if (success) + worldIn.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, .2f, + 1f + Create.RANDOM.nextFloat()); + te.onEmptied(); + return InteractionResult.SUCCESS; + }); + } + + @Override + public void updateEntityAfterFallOn(BlockGetter worldIn, Entity entityIn) { + super.updateEntityAfterFallOn(worldIn, entityIn); + if (!AllBlocks.BASIN.has(worldIn.getBlockState(entityIn.blockPosition()))) + return; + if (!(entityIn instanceof ItemEntity)) + return; + if (!entityIn.isAlive()) + return; + ItemEntity itemEntity = (ItemEntity) entityIn; + withBlockEntityDo(worldIn, entityIn.blockPosition(), te -> { + + // Tossed items bypass the quarter-stack limit + + + + + + }); + } + + @Override + public VoxelShape getInteractionShape(BlockState p_199600_1_, BlockGetter p_199600_2_, BlockPos p_199600_3_) { + return AllShapes.BASIN_RAYTRACE_SHAPE; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { + return AllShapes.BASIN_BLOCK_SHAPE; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockGetter reader, BlockPos pos, CollisionContext ctx) { + if (ctx instanceof EntityCollisionContext && ((EntityCollisionContext) ctx).getEntity() instanceof ItemEntity) + return AllShapes.BASIN_COLLISION_SHAPE; + return getShape(state, reader, pos, ctx); + } + + @Override + public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + IBE.onRemove(state, worldIn, pos, newState); + } + + @Override + public boolean hasAnalogOutputSignal(BlockState state) { + return true; + } + + + + @Override + public Class getBlockEntityClass() { + return DistillationControllerBlockEntity.class; + } + + @Override + public BlockEntityType getBlockEntityType() { + return TFMGBlockEntities.CAST_IRON_DISTILLATION_CONTROLLER.get(); + } + + public static boolean canOutputTo(BlockGetter world, BlockPos basinPos, Direction direction) { + BlockPos neighbour = basinPos.relative(direction); + BlockPos output = neighbour.below(); + BlockState blockState = world.getBlockState(neighbour); + + if (FunnelBlock.isFunnel(blockState)) { + if (FunnelBlock.getFunnelFacing(blockState) == direction) + return false; + } else if (!blockState.getCollisionShape(world, neighbour) + .isEmpty()) { + return false; + } else { + BlockEntity tileEntity = world.getBlockEntity(output); + if (tileEntity instanceof BeltBlockEntity) { + BeltBlockEntity belt = (BeltBlockEntity) tileEntity; + return belt.getSpeed() == 0 || belt.getMovementFacing() != direction.getOpposite(); + } + } + + DirectBeltInputBehaviour directBeltInputBehaviour = + BlockEntityBehaviour.get(world, output, DirectBeltInputBehaviour.TYPE); + if (directBeltInputBehaviour != null) + return directBeltInputBehaviour.canInsertFromSide(direction); + return false; + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; + } + +} diff --git a/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlockEntity.java b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlockEntity.java new file mode 100644 index 00000000..ae8c8ca4 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationControllerBlockEntity.java @@ -0,0 +1,358 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllTags; +import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; +import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour; +import com.simibubi.create.foundation.fluid.CombinedTankWrapper; +import com.simibubi.create.foundation.item.SmartInventory; +import com.simibubi.create.foundation.utility.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.wrapper.CombinedInvWrapper; + +import javax.annotation.Nonnull; +import java.util.*; + +public class DistillationControllerBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation { + + public SmartFluidTankBehaviour inputTank; + protected SmartInventory outputInventory; + protected SmartFluidTankBehaviour outputTank; + + private boolean contentsChanged; + + + private Couple tanks; + + public LazyOptional itemCapability; + protected LazyOptional fluidCapability; + + + int recipeBackupCheck; + + + public DistillationControllerBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + + outputInventory = new SmartInventory(9, this).forbidInsertion() + .withMaxStackSize(64); + + itemCapability = LazyOptional.of(() -> new CombinedInvWrapper( outputInventory)); + contentsChanged = true; + + tanks = Couple.create(inputTank, outputTank); + recipeBackupCheck = 20; + } + + @Override + public void addBehaviours(List behaviours) { + behaviours.add(new DirectBeltInputBehaviour(this)); + + + + inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true) + .whenFluidUpdates(() -> contentsChanged = true); + outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true) + .whenFluidUpdates(() -> contentsChanged = true) + .forbidInsertion(); + behaviours.add(inputTank); + behaviours.add(outputTank); + + fluidCapability = LazyOptional.of(() -> { + LazyOptional inputCap = inputTank.getCapability(); + LazyOptional outputCap = outputTank.getCapability(); + return new CombinedTankWrapper(outputCap.orElse(null), inputCap.orElse(null)); + }); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + + outputInventory.deserializeNBT(compound.getCompound("OutputItems")); + + + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + super.write(compound, clientPacket); + + compound.put("OutputItems", outputInventory.serializeNBT()); + + } +/* + @Override + public void destroy() { + super.destroy(); + + ItemHelper.dropContents(level, worldPosition, outputInventory); + spoutputBuffer.forEach(is -> Block.popResource(level, worldPosition, is)); + } + + */ + + @Override + public void remove() { + super.remove(); + onEmptied(); + } + + public void onEmptied() { + getOperator().ifPresent(te -> te.basinRemoved = true); + } + + @Override + public void invalidate() { + super.invalidate(); + itemCapability.invalidate(); + fluidCapability.invalidate(); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, Direction side) { + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return itemCapability.cast(); + if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + return fluidCapability.cast(); + return super.getCapability(cap, side); + } + + @Override + public void notifyUpdate() { + super.notifyUpdate(); + } + + @Override + public void lazyTick() { + super.lazyTick(); + notifyUpdate(); + if (!level.isClientSide) { + if (recipeBackupCheck-- > 0) + return; + recipeBackupCheck = 20; + + } + + + + + } + + + @Override + public void tick() { + super.tick(); + + + + if (!contentsChanged) + return; + + contentsChanged = false; + getOperator().ifPresent(te -> te.basinChecker.scheduleUpdate()); + + for (Direction offset : Iterate.horizontalDirections) { + BlockPos toUpdate = worldPosition.above() + .relative(offset); + BlockState stateToUpdate = level.getBlockState(toUpdate); + if (stateToUpdate.getBlock() instanceof DistillationControllerBlock + && stateToUpdate.getValue(DistillationControllerBlock.FACING) == offset.getOpposite()) { + BlockEntity te = level.getBlockEntity(toUpdate); + if (te instanceof DistillationControllerBlockEntity) + ((DistillationControllerBlockEntity) te).contentsChanged = true; + } + } + } + + + private Optional getOperator() { + if (level == null) + return Optional.empty(); + BlockEntity te = level.getBlockEntity(worldPosition.above()); + if (te instanceof FluidProcessingBlockEntity) + return Optional.of((FluidProcessingBlockEntity) te); + return Optional.empty(); + } + + + + public void notifyChangeOfContents() { + contentsChanged = true; + } + + + + public SmartInventory getOutputInventory() { + return outputInventory; + } + + + + public boolean acceptOutputs(List outputItems, List outputFluids, boolean simulate) { + outputInventory.allowInsertion(); + outputTank.allowInsertion(); + boolean acceptOutputsInner = acceptOutputsInner(outputItems, outputFluids, simulate); + outputInventory.forbidInsertion(); + outputTank.forbidInsertion(); + return acceptOutputsInner; + } + + private boolean acceptOutputsInner(List outputItems, List outputFluids, boolean simulate) { + BlockState blockState = getBlockState(); + if (!(blockState.getBlock() instanceof DistillationControllerBlock)) + return false; + + Direction direction = blockState.getValue(DistillationControllerBlock.FACING); + if (direction != Direction.DOWN) { + + BlockEntity te = level.getBlockEntity(worldPosition.below() + .relative(direction)); + + InvManipulationBehaviour inserter = + te == null ? null : BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE); + IItemHandler targetInv = te == null ? null + : te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(inserter == null ? null : inserter.getInventory()); + IFluidHandler targetTank = te == null ? null + : te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(null); + boolean externalTankNotPresent = targetTank == null; + + if (!outputItems.isEmpty() && targetInv == null) + return false; + if (!outputFluids.isEmpty() && externalTankNotPresent) { + // Special case - fluid outputs but output only accepts items + targetTank = outputTank.getCapability() + .orElse(null); + if (targetTank == null) + return false; + if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank)) + return false; + } + + if (simulate) + return true; + + if (!externalTankNotPresent) + + return true; + } + + IItemHandler targetInv = outputInventory; + IFluidHandler targetTank = outputTank.getCapability() + .orElse(null); + + if (targetInv == null && !outputItems.isEmpty()) + return false; + if (!acceptItemOutputsIntoBasin(outputItems, simulate, targetInv)) + return false; + if (outputFluids.isEmpty()) + return true; + if (targetTank == null) + return false; + if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank)) + return false; + + return true; + } + + private boolean acceptFluidOutputsIntoBasin(List outputFluids, boolean simulate, + IFluidHandler targetTank) { + for (FluidStack fluidStack : outputFluids) { + IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE; + int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler + ? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action) + : targetTank.fill(fluidStack.copy(), action); + if (fill != fluidStack.getAmount()) + return false; + } + return true; + } + + private boolean acceptItemOutputsIntoBasin(List outputItems, boolean simulate, IItemHandler targetInv) { + for (ItemStack itemStack : outputItems) { + // Catalyst items are never consumed + if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem() + .sameItem(itemStack)) + continue; + if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate) + .isEmpty()) + return false; + } + return true; + } + + public void readOnlyItems(CompoundTag compound) { + + outputInventory.deserializeNBT(compound.getCompound("OutputItems")); + } + + public static BlazeBurnerBlock.HeatLevel getHeatLevelOf(BlockState state) { + if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL)) + return state.getValue(BlazeBurnerBlock.HEAT_LEVEL); + return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? BlazeBurnerBlock.HeatLevel.SMOULDERING : BlazeBurnerBlock.HeatLevel.NONE; + } + + public Couple getTanks() { + return tanks; + } + + + + // client things + + + + + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + return containedFluidTooltip(tooltip, isPlayerSneaking, + getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)); + } + + class BasinValueBox extends ValueBoxTransform.Sided { + + @Override + protected Vec3 getSouthLocation() { + return VecHelper.voxelSpace(8, 12, 15.75); + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + return direction.getAxis() + .isHorizontal(); + } + + } +} diff --git a/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlock.java b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlock.java new file mode 100644 index 00000000..0e7038b1 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlock.java @@ -0,0 +1,57 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation; + + +import com.drmangotea.tfmg.registry.TFMGBlockEntities; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.foundation.block.IBE; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class DistillationOutputBlock extends Block implements IBE { + + public DistillationOutputBlock(Properties properties) { + super(properties); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { + return !AllBlocks.BASIN.has(worldIn.getBlockState(pos.below())); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { + if (context instanceof EntityCollisionContext + && ((EntityCollisionContext) context).getEntity() instanceof Player) + return AllShapes.CASING_14PX.get(Direction.DOWN); + + return AllShapes.MECHANICAL_PROCESSOR_SHAPE; + } + + + @Override + public Class getBlockEntityClass() { + return DistillationOutputBlockEntity.class; + } + + @Override + public BlockEntityType getBlockEntityType() { + return TFMGBlockEntities.CAST_IRON_DISTILLATION_OUTPUT.get(); + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlockEntity.java b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlockEntity.java new file mode 100644 index 00000000..a64d9a0b --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/DistillationOutputBlockEntity.java @@ -0,0 +1,427 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation; + + +import com.drmangotea.tfmg.CreateTFMG; +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe; +import com.drmangotea.tfmg.registry.TFMGFluids; +import com.drmangotea.tfmg.registry.TFMGRecipeTypes; +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; +import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.fluid.SmartFluidTank; +import com.simibubi.create.foundation.recipe.RecipeFinder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.crafting.IShapedRecipe; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.templates.FluidTank; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity implements IHaveGoggleInformation { + + protected LazyOptional fluidCapability; + public FluidTank tankInventory; + protected BlockPos lastKnownPos; + + private static final int SYNC_RATE = 8; + protected int syncCooldown; + protected boolean queuedSync; + + + private static final Object DistillationRecipesKey = new Object(); + + public boolean running; + + public DistillationOutputBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + tankInventory = createInventory(); + fluidCapability = LazyOptional.of(() -> tankInventory); + refreshCapability(); + } + + protected boolean matchItemlessRecipe(Recipe recipe) { + if (recipe == null) + return false; + Optional controller = getController(); + if (!controller.isPresent()) + return false; + return DistillationRecipe.match(controller.get(), recipe); + } + + @Override + protected boolean updateController() { + + + + if (level == null || level.isClientSide) + return true; + Optional basin = getController(); + + + List> recipes = getMatchingRecipes(); + if (recipes.isEmpty()) + return true; + currentRecipe = recipes.get(0); + startProcessing(); + sendData(); + return true; + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + // registerAwardables(behaviours, AllAdvancements.MIXER); + } + + @Override + protected AABB createRenderBoundingBox() { + return new AABB(worldPosition).expandTowards(0, -1.5, 0); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + running = compound.getBoolean("Running"); + + super.read(compound, clientPacket); + lastKnownPos = null; + + if (compound.contains("LastKnownPos")) + lastKnownPos = NbtUtils.readBlockPos(compound.getCompound("LastKnownPos")); + + + tankInventory.setCapacity(8000); + tankInventory.readFromNBT(compound.getCompound("TankContent")); + if (tankInventory.getSpace() < 0) + tankInventory.drain(-tankInventory.getSpace(), IFluidHandler.FluidAction.EXECUTE); + + + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + compound.putBoolean("Running", running); + if (lastKnownPos != null) + compound.put("LastKnownPos", NbtUtils.writeBlockPos(lastKnownPos)); + + compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag())); + + super.write(compound, clientPacket); + super.write(compound, clientPacket); + } + + @Override + public void tick() { + super.tick(); + + + + if (level != null) { + if ((!level.isClientSide || isVirtual())) { + process(); + sendData(); + } + } + if (syncCooldown > 0) { + syncCooldown--; + if (syncCooldown == 0 && queuedSync) + sendData(); + } + } + + protected void process() { + updateController(); + + if (currentRecipe == null) + return; + + + + // if((currentRecipe instanceof ShapelessRecipe)) + // return; + + BlockEntity above1 = level.getBlockEntity(this.getBlockPos().above(1)); + BlockEntity above2 = level.getBlockEntity(this.getBlockPos().above(2)); + BlockEntity burner = level.getBlockEntity(this.getBlockPos().below(2)); + if(!(burner instanceof BlazeBurnerBlockEntity)) + return; + if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.NONE) + return; + if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.SMOULDERING) + return; + + +if(above1 !=null&& above2 !=null + // && + /// tankInventory.getFluidAmount()+ + /// ((DistillationRecipe)currentRecipe) + /// .getFirstFluidResult() + /// .getAmount() + /// <8000&& + // ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(1).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()&& + // ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(2).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity() +){ + Optional optionalController = getController(); + if (!optionalController.isPresent()) + return; + + if(!(above1 instanceof DistillationOutputBlockEntity)&& + !( above2 instanceof DistillationOutputBlockEntity)) { + return; + } + + CreateTFMG.LOGGER.debug("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe"); + + FluidStack fluidInRecipe1 = ((DistillationRecipe) currentRecipe).getFirstFluidResult(); + FluidStack fluidInRecipe2 = ((DistillationRecipe) currentRecipe).getSecondFluidResult(); + FluidStack fluidInRecipe3 = ((DistillationRecipe) currentRecipe).getThirdFluidResult(); + + + + + if (fluidInRecipe1.getFluid() != this.tankInventory.getFluid().getFluid() + && tankInventory.getFluidAmount()!=0 + ) + return; + + if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above1).tankInventory.getFluid().getFluid()) + &&((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()!=0 + ) + return; + if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above2).tankInventory.getFluid().getFluid()) + &&((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()!=0 + ) + return; + + + + + if(getController().get().getTanks().get(true).getPrimaryHandler().getFluid().getFluid() != ((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid()) + return; + + DistillationControllerBlockEntity controller = optionalController.get(); + IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + + if(controller.outputInventory.getStackInSlot(0).getCount()>=1|| + controller.outputInventory.getStackInSlot(1).getCount()>=1|| + controller.outputInventory.getStackInSlot(2).getCount()>=1) + return; + + if (!controller.getTanks().get(true).isEmpty()) { + if(!level.isClientSide) { + // if(((DistillationRecipe)currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get()) + // return; + + controller.getTanks().get(true).getPrimaryHandler().drain(((DistillationRecipe) currentRecipe).getFluidIngredients().get(0).getRequiredAmount(), IFluidHandler.FluidAction.EXECUTE); + + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(0).isEmpty())) + tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(0).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(0).getAmount() + this.tankInventory.getFluidAmount())); + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(1).isEmpty())) + ((DistillationOutputBlockEntity) above1).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(1).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(1).getAmount() + ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount())); + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(2).isEmpty())) + ((DistillationOutputBlockEntity) above2).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(2).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(2).getAmount() + ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount())); + + + if (!(((DistillationRecipe) currentRecipe).getFirstItemResult().isEmpty())) + controller.outputInventory.setItem(0, ((DistillationRecipe) currentRecipe).getFirstItemResult()); + + if (!(((DistillationRecipe) currentRecipe).getSecondItemResult().isEmpty())) + controller.outputInventory.setItem(1, ((DistillationRecipe) currentRecipe).getSecondItemResult()); +} +/* +if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty())) + controller.outputInventory.setItem(2,((DistillationRecipe) currentRecipe).getFirstItemResult()); + + + */ + + + + + + controller.notifyChangeOfContents(); + } + +} + +} + + @Override + protected List> getMatchingRecipes() { + + + List> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters); + return list.stream() + .filter(this::matchItemlessRecipe) + .sorted((r1, r2) -> r2.getIngredients() + .size() + - r1.getIngredients() + .size()) + .collect(Collectors.toList()); + } + + @Override + protected boolean matchStaticFilters(Recipe r) { + return ((r instanceof CraftingRecipe && !(r instanceof IShapedRecipe) + && r.getIngredients() + .size() > 1 + && !MechanicalPressBlockEntity.canCompress(r)) && !AllRecipeTypes.shouldIgnoreInAutomation(r) + || r.getType() == TFMGRecipeTypes.DISTILLATION.getType()); + } + + @Override + public void startProcessing() { + if (running ) + return; + super.startProcessing(); + running = true; + + } + + @Override + public boolean continueWithPreviousRecipe() { + return true; + } + + @Override + protected void onBasinRemoved() { + if (!running) + return; + + running = false; + } + + @Override + protected Object getRecipeCacheKey() { + return DistillationRecipesKey; + } + + @Override + protected boolean isRunning() { + return running; + } +/* + @Override + protected Optional getProcessedRecipeTrigger() { + return Optional.of(AllAdvancements.MIXER); + } + */ + @Override + @OnlyIn(Dist.CLIENT) + public void tickAudio() { + super.tickAudio(); + + // SoundEvents.BLOCK_STONE_BREAK + + + + } + + + protected SmartFluidTank createInventory() { + return new SmartFluidTank(8000, this::onFluidStackChanged); + } + + + protected void onFluidStackChanged(FluidStack newFluidStack) { + if (!hasLevel()) + return; + + + } + + + public void sendDataImmediately() { + syncCooldown = 0; + queuedSync = false; + sendData(); + } + + @Override + public void sendData() { + if (syncCooldown > 0) { + queuedSync = true; + return; + } + super.sendData(); + queuedSync = false; + syncCooldown = SYNC_RATE; + } + + + + + + + private void refreshCapability() { + LazyOptional oldCap = fluidCapability; + fluidCapability = LazyOptional.of(() -> handlerForCapability()); + oldCap.invalidate(); + } + + private IFluidHandler handlerForCapability() { + + return tankInventory; + } + + + + + + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + + return containedFluidTooltip(tooltip, isPlayerSneaking, + this.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (!fluidCapability.isPresent()) + refreshCapability(); + if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + return fluidCapability.cast(); + return super.getCapability(cap, side); + } + + + public IFluidTank getTankInventory() { + return tankInventory; + } + + + public FluidStack getFluid(int tank) { + return tankInventory.getFluid() + .copy(); +} + +} + diff --git a/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/FluidProcessingBlockEntity.java b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/FluidProcessingBlockEntity.java new file mode 100644 index 00000000..43acef29 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/content/machines/oil_processing/distillation/FluidProcessingBlockEntity.java @@ -0,0 +1,150 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation; + + +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe; +import com.drmangotea.tfmg.registry.TFMGFluids; +import com.simibubi.create.content.kinetics.base.KineticBlockEntity; +import com.simibubi.create.foundation.advancement.CreateAdvancement; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.simple.DeferralBehaviour; +import com.simibubi.create.foundation.recipe.RecipeFinder; +import net.minecraft.core.BlockPos; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.units.qual.C; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public abstract class FluidProcessingBlockEntity extends KineticBlockEntity { + + public DeferralBehaviour basinChecker; + public boolean basinRemoved; + protected Recipe currentRecipe; + + public FluidProcessingBlockEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + basinChecker = new DeferralBehaviour(this, this::updateController); + behaviours.add(basinChecker); + } + + @Override + public void onSpeedChanged(float prevSpeed) { + super.onSpeedChanged(prevSpeed); + if (getSpeed() == 0) + basinRemoved = true; + basinRemoved = false; + basinChecker.scheduleUpdate(); + } + + @Override + public void tick() { + if (basinRemoved) { + basinRemoved = false; + onBasinRemoved(); + sendData(); + return; + } + + super.tick(); + } + + protected boolean updateController() { + + + if (isRunning()) + return true; + if (level == null || level.isClientSide) + return true; + + List> recipes = getMatchingRecipes(); + if (recipes.isEmpty()) + return true; + currentRecipe = recipes.get(0); + // if(currentRecipe instanceof DistillationRecipe) { + // if (((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get()) { + // return true; + // } + // } + startProcessing(); + sendData(); + return true; + } + + protected abstract boolean isRunning(); + + public void startProcessing() {} + + public boolean continueWithPreviousRecipe() { + return true; + } + + protected boolean matchItemlessRecipe(Recipe recipe) { + if (recipe == null) + return false; + Optional basin = getController(); + if (!basin.isPresent()) + return false; + return ItemlessRecipe.match(basin.get(), recipe); + } + + protected void applyItemlessRecipe() { + if (currentRecipe == null) + return; + + Optional optionalBasin = getController(); + if (!optionalBasin.isPresent()) + return; + DistillationControllerBlockEntity basin = optionalBasin.get(); + if (!ItemlessRecipe.apply(basin, currentRecipe)) + return; + getProcessedRecipeTrigger().ifPresent(this::award); + basin.inputTank.sendDataImmediately(); + + + + basin.notifyChangeOfContents(); + } + + protected List> getMatchingRecipes() { + + + List> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters); + return list.stream() + .filter(this::matchItemlessRecipe) + .sorted((r1, r2) -> r2.getIngredients() + .size() + - r1.getIngredients() + .size()) + .collect(Collectors.toList()); + } + + protected abstract void onBasinRemoved(); + + protected Optional getController() { + if (level == null) + return Optional.empty(); + BlockEntity basinTE = level.getBlockEntity(worldPosition.below(1)); + if (!(basinTE instanceof DistillationControllerBlockEntity)) + return Optional.empty(); + return Optional.of((DistillationControllerBlockEntity) basinTE); + } + + protected Optional getProcessedRecipeTrigger() { + return Optional.empty(); + } + + protected abstract boolean matchStaticFilters(Recipe recipe); + + protected abstract Object getRecipeCacheKey(); +} diff --git a/src/main/java/com/drmangotea/tfmg/recipes/distillation/DistillationRecipe.java b/src/main/java/com/drmangotea/tfmg/recipes/distillation/DistillationRecipe.java new file mode 100644 index 00000000..3e850a74 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/recipes/distillation/DistillationRecipe.java @@ -0,0 +1,41 @@ +package com.drmangotea.tfmg.recipes.distillation; + + + +import com.drmangotea.tfmg.registry.TFMGRecipeTypes; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder; +import com.simibubi.create.foundation.fluid.FluidIngredient; +import mezz.jei.api.constants.RecipeTypes; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +public class DistillationRecipe extends ItemlessRecipe { + + public DistillationRecipe(ProcessingRecipeBuilder.ProcessingRecipeParams params) { + super(TFMGRecipeTypes.DISTILLATION, params); + } + + public FluidIngredient getInputFluid(){ + return getFluidIngredients().get(0); + } + + public FluidStack getFirstFluidResult(){ + return fluidResults.get(0); + } + public FluidStack getSecondFluidResult(){ + return fluidResults.get(1); + } + public FluidStack getThirdFluidResult(){ + return fluidResults.get(2); + } + + public ItemStack getFirstItemResult(){ + return results.get(0).getStack(); + } + public ItemStack getSecondItemResult(){ + return results.get(1).getStack(); + } + public ItemStack getThirdItemResult(){ + return results.get(2).getStack(); + } +} diff --git a/src/main/java/com/drmangotea/tfmg/recipes/distillation/ItemlessRecipe.java b/src/main/java/com/drmangotea/tfmg/recipes/distillation/ItemlessRecipe.java new file mode 100644 index 00000000..7d910440 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/recipes/distillation/ItemlessRecipe.java @@ -0,0 +1,206 @@ +package com.drmangotea.tfmg.recipes.distillation; + +import com.drmangotea.tfmg.CreateTFMG; +import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlockEntity; +import com.drmangotea.tfmg.registry.TFMGFluids; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.processing.recipe.ProcessingRecipe; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.fluid.FluidIngredient; +import com.simibubi.create.foundation.item.SmartInventory; +import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; +import com.simibubi.create.foundation.utility.Iterate; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.Fluid; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class ItemlessRecipe extends ProcessingRecipe { + + public static boolean match(DistillationControllerBlockEntity controller, Recipe recipe) { + + + + + if(recipe instanceof ItemlessRecipe) { + + + + return apply(controller, recipe, true); + } + + + return false; + + } + + public static boolean apply(DistillationControllerBlockEntity basin, Recipe recipe) { + return apply(basin, recipe, false); + } + + private static boolean apply(DistillationControllerBlockEntity controller, Recipe recipe, boolean test) { + boolean isItemlessRecipe = recipe instanceof ItemlessRecipe; + IItemHandler availableItems = controller.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + .orElse(null); + IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + + if (availableItems == null || availableFluids == null) + return false; + + BlazeBurnerBlock.HeatLevel heat = DistillationControllerBlockEntity.getHeatLevelOf(controller.getLevel() + .getBlockState(controller.getBlockPos() + .below(1))); + if (isItemlessRecipe && !((ItemlessRecipe) recipe).getRequiredHeat() + .testBlazeBurner(heat)) + return false; + + List recipeOutputItems = new ArrayList<>(); + List recipeOutputFluids = new ArrayList<>(); + + List ingredients = new LinkedList<>(recipe.getIngredients()); + List fluidIngredients = + isItemlessRecipe ? ((ItemlessRecipe) recipe).getFluidIngredients() : Collections.emptyList(); + if(!fluidIngredients.isEmpty()) + + + + + for (boolean simulate : Iterate.trueAndFalse) { + + if (!simulate && test) + return true; + + int[] extractedItemsFromSlot = new int[availableItems.getSlots()]; + int[] extractedFluidsFromTank = new int[availableFluids.getTanks()]; + + Ingredients: for (int i = 0; i < ingredients.size(); i++) { + Ingredient ingredient = ingredients.get(i); + + for (int slot = 0; slot < availableItems.getSlots(); slot++) { + if (simulate && availableItems.getStackInSlot(slot) + .getCount() <= extractedItemsFromSlot[slot]) + continue; + ItemStack extracted = availableItems.extractItem(slot, 1, true); + if (!ingredient.test(extracted)) + continue; + if (!simulate) + availableItems.extractItem(slot, 1, false); + extractedItemsFromSlot[slot]++; + continue Ingredients; + } + + // something wasn't found + return false; + } + + boolean fluidsAffected = false; + FluidIngredients: for (int i = 0; i < fluidIngredients.size(); i++) { + FluidIngredient fluidIngredient = fluidIngredients.get(i); + int amountRequired = fluidIngredient.getRequiredAmount(); + + + for (int tank = 0; tank < availableFluids.getTanks(); tank++) { + FluidStack fluidStack = availableFluids.getFluidInTank(tank); + if (simulate && fluidStack.getAmount() <= extractedFluidsFromTank[tank]) + continue; + if (!fluidIngredient.test(fluidStack)) + continue; + int drainedAmount = Math.min(amountRequired, fluidStack.getAmount()); + if (!simulate) { + fluidStack.shrink(drainedAmount); + fluidsAffected = true; + } + amountRequired -= drainedAmount; + if (amountRequired != 0) + continue; + extractedFluidsFromTank[tank] += drainedAmount; + continue FluidIngredients; + } + + // something wasn't found + return false; + } + + if (fluidsAffected) { + controller.getBehaviour(SmartFluidTankBehaviour.INPUT) + .forEach(SmartFluidTankBehaviour.TankSegment::onFluidStackChanged); + controller.getBehaviour(SmartFluidTankBehaviour.OUTPUT) + .forEach(SmartFluidTankBehaviour.TankSegment::onFluidStackChanged); + } + + if (simulate) { + if (recipe instanceof ItemlessRecipe ItemlessRecipe) { + recipeOutputItems.addAll(ItemlessRecipe.rollResults()); + recipeOutputFluids.addAll(ItemlessRecipe.getFluidResults()); + + } else { + recipeOutputItems.add(recipe.getResultItem()); +/* + if (recipe instanceof CraftingRecipe craftingRecipe) { + recipeOutputItems.addAll(craftingRecipe.getRemainingItems(new DummyCraftingContainer(availableItems, extractedItemsFromSlot))); + } + + */ + } + } + + if (!controller.acceptOutputs(recipeOutputItems, recipeOutputFluids, simulate)) + return false; + } + + return true; + } + + + + protected ItemlessRecipe(IRecipeTypeInfo type, ProcessingRecipeBuilder.ProcessingRecipeParams params) { + super(type, params); + } + + + @Override + protected int getMaxInputCount() { + return 0; + } + + @Override + protected int getMaxOutputCount() { + return 2; + } + + @Override + protected int getMaxFluidInputCount() { + return 1; + } + + @Override + protected int getMaxFluidOutputCount() { + return 3; + } + + @Override + protected boolean canRequireHeat() { + return true; + } + + @Override + public boolean matches(SmartInventory inv, @Nonnull Level worldIn) { + return false; + } + +} diff --git a/src/main/java/com/drmangotea/tfmg/recipes/jei/AnimatedDistiller.java b/src/main/java/com/drmangotea/tfmg/recipes/jei/AnimatedDistiller.java new file mode 100644 index 00000000..906398af --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/recipes/jei/AnimatedDistiller.java @@ -0,0 +1,123 @@ +package com.drmangotea.tfmg.recipes.jei; + + +import com.drmangotea.tfmg.registry.TFMGBlocks; +import com.jozufozu.flywheel.core.PartialModel; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Vector3f; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPartialModels; +import com.simibubi.create.AllSpriteShifts; +import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.foundation.block.render.SpriteShiftEntry; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.Blocks; + +public class AnimatedDistiller extends AnimatedKinetics { + + + + public AnimatedDistiller() { + + } + + @Override + public void draw(PoseStack matrixStack, int xOffset, int yOffset) { + matrixStack.pushPose(); + matrixStack.translate(xOffset, yOffset, 200); + matrixStack.mulPose(Vector3f.XP.rotationDegrees(-15.5f)); + matrixStack.mulPose(Vector3f.YP.rotationDegrees(22.5f)); + int scale = 23; + BlazeBurnerBlock.HeatLevel heatLevel = BlazeBurnerBlock.HeatLevel.SMOULDERING; + + + blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState()) + .scale(scale) + .render(matrixStack); + blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState()) + .atLocal(0,1,0) + .scale(scale) + .render(matrixStack); + blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState()) + .atLocal(0,2,0) + .scale(scale) + .render(matrixStack); + blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER.getDefaultState()) + .atLocal(0,3,0) + .scale(scale) + .render(matrixStack); + + float offset = (Mth.sin(AnimationTickHolder.getRenderTime() / 16f) + 0.5f) / 16f; + + blockElement(AllBlocks.BLAZE_BURNER.getDefaultState()) + .atLocal(0, 4.1, 0) + .scale(scale) + .render(matrixStack); + + PartialModel blaze = + AllPartialModels.BLAZE_ACTIVE; + PartialModel rods2 = AllPartialModels.BLAZE_BURNER_RODS_2; + + + + blockElement(blaze).atLocal(1, 4.1, 1) + .rotate(0, 180, 0) + .scale(scale) + .render(matrixStack); + blockElement(rods2).atLocal(1, 4.1 + offset, 1) + .rotate(0, 180, 0) + .scale(scale) + .render(matrixStack); + + + + + matrixStack.scale(scale, -scale, scale); + matrixStack.translate(0, -1.8, 0); + + SpriteShiftEntry spriteShift = + AllSpriteShifts.BURNER_FLAME; + + float spriteWidth = spriteShift.getTarget() + .getU1() + - spriteShift.getTarget() + .getU0(); + + float spriteHeight = spriteShift.getTarget() + .getV1() + - spriteShift.getTarget() + .getV0(); + + float time = AnimationTickHolder.getRenderTime(Minecraft.getInstance().level); + float speed = 1 / 32f + 1 / 64f * BlazeBurnerBlock.HeatLevel.KINDLED.ordinal(); + + double vScroll = speed * time; + vScroll = vScroll - Math.floor(vScroll); + vScroll = vScroll * spriteHeight / 2; + + double uScroll = speed * time / 2; + uScroll = uScroll - Math.floor(uScroll); + uScroll = uScroll * spriteWidth / 2; + + Minecraft mc = Minecraft.getInstance(); + MultiBufferSource.BufferSource buffer = mc.renderBuffers() + .bufferSource(); + VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped()); + CachedBufferer.partial(AllPartialModels.BLAZE_BURNER_FLAME, Blocks.AIR.defaultBlockState()) + .shiftUVScrolling(spriteShift, (float) uScroll, (float) vScroll) + .light(LightTexture.FULL_BRIGHT) + .renderInto(matrixStack, vb); + matrixStack.popPose(); + } + + + +} diff --git a/src/main/java/com/drmangotea/tfmg/recipes/jei/DistillationCategory.java b/src/main/java/com/drmangotea/tfmg/recipes/jei/DistillationCategory.java new file mode 100644 index 00000000..83f21eff --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/recipes/jei/DistillationCategory.java @@ -0,0 +1,86 @@ +package com.drmangotea.tfmg.recipes.jei; + + + +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.compat.jei.category.CreateRecipeCategory; +import com.simibubi.create.foundation.fluid.FluidIngredient; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import mezz.jei.api.forge.ForgeTypes; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class DistillationCategory extends CreateRecipeCategory { + + private final AnimatedDistiller distiller = new AnimatedDistiller(); + + public DistillationCategory(Info info) { + super(info); + } + + + + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, DistillationRecipe recipe, IFocusGroup focuses) { + ItemStack result1 = recipe.getFirstItemResult(); + ItemStack result2 = recipe.getSecondItemResult(); + FluidIngredient fluidIngredient=recipe.getInputFluid(); + + + builder + .addSlot(RecipeIngredientRole.INPUT, 2, 75) + .setBackground(getRenderedSlot(), -1, -1) + .addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getInputFluid().getMatchingFluidStacks())) + .addTooltipCallback(addFluidTooltip(recipe.getInputFluid().getRequiredAmount())); + + + + builder + .addSlot(RecipeIngredientRole.OUTPUT,150, 55) + .setBackground(getRenderedSlot(), -1, -1) + .addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getFirstFluidResult())) + .addTooltipCallback(addFluidTooltip(recipe.getFirstFluidResult().getAmount())); + builder + .addSlot(RecipeIngredientRole.OUTPUT,150, 33) + .setBackground(getRenderedSlot(), -1, -1) + .addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getSecondFluidResult())) + .addTooltipCallback(addFluidTooltip(recipe.getSecondFluidResult().getAmount())); + + builder + .addSlot(RecipeIngredientRole.OUTPUT,150, 12) + .setBackground(getRenderedSlot(), -1, -1) + .addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getThirdFluidResult())) + .addTooltipCallback(addFluidTooltip(recipe.getThirdFluidResult().getAmount())); + + + + builder + .addSlot(RecipeIngredientRole.OUTPUT, 105, 100) + .setBackground(getRenderedSlot(), -1, -1) + .addItemStack(recipe.getFirstItemResult()); + builder + .addSlot(RecipeIngredientRole.OUTPUT, 127, 100) + .setBackground(getRenderedSlot(), -1, -1) + .addItemStack(recipe.getSecondItemResult()); + } + + @Override + public void draw(DistillationRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) { + distiller + .draw(matrixStack, 65, 27); + AllGuiTextures.JEI_ARROW.render(matrixStack, 20, 80); + AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 14); + AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 35); + AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 57); + AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 100, 79); + } + +} diff --git a/src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java b/src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java new file mode 100644 index 00000000..e9a895b4 --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java @@ -0,0 +1,330 @@ +package com.drmangotea.tfmg.recipes.jei; + + +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.drmangotea.tfmg.registry.TFMGBlocks; +import com.drmangotea.tfmg.registry.TFMGFluids; +import com.drmangotea.tfmg.registry.TFMGRecipeTypes; +import com.simibubi.create.Create; +import com.simibubi.create.compat.jei.*; +import com.simibubi.create.compat.jei.category.CreateRecipeCategory; +import com.simibubi.create.content.equipment.blueprint.BlueprintScreen; +import com.simibubi.create.content.logistics.filter.AbstractFilterScreen; +import com.simibubi.create.content.redstone.link.controller.LinkedControllerScreen; +import com.simibubi.create.content.trains.schedule.ScheduleScreen; +import com.simibubi.create.foundation.config.ConfigBase; +import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen; +import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.infrastructure.config.AllConfigs; +import com.simibubi.create.infrastructure.config.CRecipes; +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.recipe.category.IRecipeCategory; +import mezz.jei.api.registration.*; +import mezz.jei.api.runtime.IIngredientManager; +import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.ItemLike; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +@JeiPlugin +@SuppressWarnings("unused") +@ParametersAreNonnullByDefault +public class TFMGJei implements IModPlugin { + + private static final ResourceLocation ID = Create.asResource("jei_plugin"); + + private final List> allCategories = new ArrayList<>(); + private IIngredientManager ingredientManager; + + private void loadCategories() { + allCategories.clear(); + + CreateRecipeCategory + + distillation = builder(DistillationRecipe.class) + .addTypedRecipes(TFMGRecipeTypes.DISTILLATION) + .catalyst(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER::get) + .itemIcon(TFMGFluids.CRUDE_OIL.getBucket().get()) + .emptyBackground(177, 123) + .build("distillation", DistillationCategory::new); + + } + + private > CategoryBuilder builder(Class recipeClass) { + return new CategoryBuilder<>(recipeClass); + } + + @Override + @Nonnull + public ResourceLocation getPluginUid() { + return ID; + } + + @Override + public void registerCategories(IRecipeCategoryRegistration registration) { + loadCategories(); + registration.addRecipeCategories(allCategories.toArray(IRecipeCategory[]::new)); + } + + @Override + public void registerRecipes(IRecipeRegistration registration) { + ingredientManager = registration.getIngredientManager(); + + allCategories.forEach(c -> c.registerRecipes(registration)); + + registration.addRecipes(RecipeTypes.CRAFTING, ToolboxColoringRecipeMaker.createRecipes().toList()); + } + + @Override + public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { + allCategories.forEach(c -> c.registerCatalysts(registration)); + } + + @Override + public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) { + registration.addRecipeTransferHandler(new BlueprintTransferHandler(), RecipeTypes.CRAFTING); + } + + /** + * + * check + */ + /* + @Override + public void registerFluidSubtypes(ISubtypeRegistration registration) { + PotionFluidSubtypeInterpreter interpreter = new PotionFluidSubtypeInterpreter(); + PotionFluid potionFluid = AllFluids.POTION.get(); + registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getSource(), interpreter); + registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter); + } + + */ + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void registerGuiHandlers(IGuiHandlerRegistration registration) { + registration.addGenericGuiContainerHandler(AbstractSimiContainerScreen.class, new SlotMover()); + + registration.addGhostIngredientHandler(AbstractFilterScreen.class, new GhostIngredientHandler()); + registration.addGhostIngredientHandler(BlueprintScreen.class, new GhostIngredientHandler()); + registration.addGhostIngredientHandler(LinkedControllerScreen.class, new GhostIngredientHandler()); + registration.addGhostIngredientHandler(ScheduleScreen.class, new GhostIngredientHandler()); + } + + private class CategoryBuilder> { + private final Class recipeClass; + private Predicate predicate = cRecipes -> true; + + private IDrawable background; + private IDrawable icon; + + private final List>> recipeListConsumers = new ArrayList<>(); + private final List> catalysts = new ArrayList<>(); + + public CategoryBuilder(Class recipeClass) { + this.recipeClass = recipeClass; + } + + public CategoryBuilder enableIf(Predicate predicate) { + this.predicate = predicate; + return this; + } + + public CategoryBuilder enableWhen(Function configValue) { + predicate = c -> configValue.apply(c).get(); + return this; + } + + public CategoryBuilder addRecipeListConsumer(Consumer> consumer) { + recipeListConsumers.add(consumer); + return this; + } + + public CategoryBuilder addRecipes(Supplier> collection) { + return addRecipeListConsumer(recipes -> recipes.addAll(collection.get())); + } + + public CategoryBuilder addAllRecipesIf(Predicate> pred) { + return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> { + if (pred.test(recipe)) { + recipes.add((T) recipe); + } + })); + } + + public CategoryBuilder addAllRecipesIf(Predicate> pred, Function, T> converter) { + return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> { + if (pred.test(recipe)) { + recipes.add(converter.apply(recipe)); + } + })); + } + + public CategoryBuilder addTypedRecipes(IRecipeTypeInfo recipeTypeEntry) { + return addTypedRecipes(recipeTypeEntry::getType); + } + + public CategoryBuilder addTypedRecipes(Supplier> recipeType) { + return addRecipeListConsumer(recipes -> CreateJEI.consumeTypedRecipes(recipes::add, recipeType.get())); + } + + public CategoryBuilder addTypedRecipes(Supplier> recipeType, Function, T> converter) { + return addRecipeListConsumer(recipes -> CreateJEI.consumeTypedRecipes(recipe -> recipes.add(converter.apply(recipe)), recipeType.get())); + } + + public CategoryBuilder addTypedRecipesIf(Supplier> recipeType, Predicate> pred) { + return addRecipeListConsumer(recipes -> CreateJEI.consumeTypedRecipes(recipe -> { + if (pred.test(recipe)) { + recipes.add(recipe); + } + }, recipeType.get())); + } + + public CategoryBuilder addTypedRecipesExcluding(Supplier> recipeType, + Supplier> excluded) { + return addRecipeListConsumer(recipes -> { + List> excludedRecipes = getTypedRecipes(excluded.get()); + CreateJEI.consumeTypedRecipes(recipe -> { + for (Recipe excludedRecipe : excludedRecipes) { + if (doInputsMatch(recipe, excludedRecipe)) { + return; + } + } + recipes.add(recipe); + }, recipeType.get()); + }); + } + + public CategoryBuilder removeRecipes(Supplier> recipeType) { + return addRecipeListConsumer(recipes -> { + List> excludedRecipes = getTypedRecipes(recipeType.get()); + recipes.removeIf(recipe -> { + for (Recipe excludedRecipe : excludedRecipes) { + if (doInputsMatch(recipe, excludedRecipe)) { + return true; + } + } + return false; + }); + }); + } + + public CategoryBuilder catalystStack(Supplier supplier) { + catalysts.add(supplier); + return this; + } + + public CategoryBuilder catalyst(Supplier supplier) { + return catalystStack(() -> new ItemStack(supplier.get() + .asItem())); + } + + public CategoryBuilder icon(IDrawable icon) { + this.icon = icon; + return this; + } + + public CategoryBuilder itemIcon(ItemLike item) { + icon(new ItemIcon(() -> new ItemStack(item))); + return this; + } + + public CategoryBuilder doubleItemIcon(ItemLike item1, ItemLike item2) { + icon(new DoubleItemIcon(() -> new ItemStack(item1), () -> new ItemStack(item2))); + return this; + } + + public CategoryBuilder background(IDrawable background) { + this.background = background; + return this; + } + + public CategoryBuilder emptyBackground(int width, int height) { + background(new EmptyBackground(width, height)); + return this; + } + + public CreateRecipeCategory build(String name, CreateRecipeCategory.Factory factory) { + Supplier> recipesSupplier; + if (predicate.test(AllConfigs.server().recipes)) { + recipesSupplier = () -> { + List recipes = new ArrayList<>(); + for (Consumer> consumer : recipeListConsumers) + consumer.accept(recipes); + return recipes; + }; + } else { + recipesSupplier = () -> Collections.emptyList(); + } + + CreateRecipeCategory.Info info = new CreateRecipeCategory.Info<>( + new mezz.jei.api.recipe.RecipeType<>(Create.asResource(name), recipeClass), + Lang.translateDirect("recipe." + name), background, icon, recipesSupplier, catalysts); + CreateRecipeCategory category = factory.create(info); + allCategories.add(category); + return category; + } + } + + public static void consumeAllRecipes(Consumer> consumer) { + Minecraft.getInstance() + .getConnection() + .getRecipeManager() + .getRecipes() + .forEach(consumer); + } + + public static > void consumeTypedRecipes(Consumer consumer, RecipeType type) { + Map> map = (Map>) Minecraft.getInstance() + .getConnection() + .getRecipeManager().getRecipes(); + if (map != null) { + map.values().forEach(recipe -> consumer.accept((T) recipe)); + } + } + + public static List> getTypedRecipes(RecipeType type) { + List> recipes = new ArrayList<>(); + consumeTypedRecipes(recipes::add, type); + return recipes; + } + + public static List> getTypedRecipesExcluding(RecipeType type, Predicate> exclusionPred) { + List> recipes = getTypedRecipes(type); + recipes.removeIf(exclusionPred); + return recipes; + } + + public static boolean doInputsMatch(Recipe recipe1, Recipe recipe2) { + if (recipe1.getIngredients() + .isEmpty() + || recipe2.getIngredients() + .isEmpty()) { + return false; + } + ItemStack[] matchingStacks = recipe1.getIngredients() + .get(0) + .getItems(); + if (matchingStacks.length == 0) { + return false; + } + return recipe2.getIngredients() + .get(0) + .test(matchingStacks[0]); + } + +} \ No newline at end of file diff --git a/src/main/java/com/drmangotea/tfmg/registry/TFMGBlockEntities.java b/src/main/java/com/drmangotea/tfmg/registry/TFMGBlockEntities.java index 44cc1b70..9c2a8900 100644 --- a/src/main/java/com/drmangotea/tfmg/registry/TFMGBlockEntities.java +++ b/src/main/java/com/drmangotea/tfmg/registry/TFMGBlockEntities.java @@ -7,6 +7,8 @@ import com.drmangotea.tfmg.content.decoration.doors.TFMGSlidingDoorRenderer; import com.drmangotea.tfmg.content.deposits.FluidDepositBlockEntity; import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerRenderer; import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerTileEntity; +import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlockEntity; +import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationOutputBlockEntity; import com.drmangotea.tfmg.content.machines.pipes.normal.LockablePipeBlockEntity; import com.drmangotea.tfmg.content.machines.tanks.SteelFluidTankRenderer; import com.drmangotea.tfmg.content.machines.tanks.SteelTankBlockEntity; @@ -100,5 +102,16 @@ public class TFMGBlockEntities { .register(); + public static final BlockEntityEntry CAST_IRON_DISTILLATION_OUTPUT = REGISTRATE + .blockEntity("distiller", DistillationOutputBlockEntity::new) + .validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT) + .register(); + + public static final BlockEntityEntry CAST_IRON_DISTILLATION_CONTROLLER = REGISTRATE + .blockEntity("distiller_controller", DistillationControllerBlockEntity::new) + .validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER) + .register(); + + public static void register() {} } diff --git a/src/main/java/com/drmangotea/tfmg/registry/TFMGBlocks.java b/src/main/java/com/drmangotea/tfmg/registry/TFMGBlocks.java index 5a08036a..308536f0 100644 --- a/src/main/java/com/drmangotea/tfmg/registry/TFMGBlocks.java +++ b/src/main/java/com/drmangotea/tfmg/registry/TFMGBlocks.java @@ -10,6 +10,8 @@ import com.drmangotea.tfmg.content.gadgets.explosives.napalm.NapalmBombBlock; import com.drmangotea.tfmg.content.items.CoalCokeBlockItem; import com.drmangotea.tfmg.content.items.FossilstoneItem; import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerBlock; +import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlock; +import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationOutputBlock; import com.drmangotea.tfmg.content.machines.pipes.normal.steel.EncasedSteelPipeBlock; import com.drmangotea.tfmg.content.machines.pipes.normal.steel.GlassSteelPipeBlock; import com.drmangotea.tfmg.content.machines.pipes.normal.steel.SteelPipeAttachmentModel; @@ -30,6 +32,7 @@ import com.simibubi.create.content.decoration.encasing.EncasingRegistry; import com.simibubi.create.content.fluids.pipes.SmartFluidPipeGenerator; import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlock; import com.simibubi.create.content.kinetics.BlockStressDefaults; +import com.simibubi.create.content.processing.AssemblyOperatorBlockItem; import com.simibubi.create.foundation.data.*; import com.tterrag.registrate.util.entry.BlockEntry; import net.minecraft.client.renderer.RenderType; @@ -233,8 +236,27 @@ public class TFMGBlocks { .register(); ///// + //Distillation + public static final BlockEntry CAST_IRON_DISTILLATION_OUTPUT = + REGISTRATE.block("cast_iron_distillation_output", DistillationOutputBlock::new) + .initialProperties(SharedProperties::copperMetal) + .properties(p -> p.color(MaterialColor.STONE)) + .properties(BlockBehaviour.Properties::noOcclusion) + .transform(axeOrPickaxe()) + .item(AssemblyOperatorBlockItem::new) + .build() + .register(); + public static final BlockEntry CAST_IRON_DISTILLATION_CONTROLLER = + REGISTRATE.block("cast_iron_distillation_controller", DistillationControllerBlock::new) + .initialProperties(SharedProperties::copperMetal) + .item() + .build() + .register(); + + ////// + diff --git a/src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java b/src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java new file mode 100644 index 00000000..853b503e --- /dev/null +++ b/src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java @@ -0,0 +1,112 @@ +package com.drmangotea.tfmg.registry; + + +import com.drmangotea.tfmg.CreateTFMG; +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.google.common.collect.ImmutableSet; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeFactory; +import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer; +import com.simibubi.create.foundation.recipe.IRecipeTypeInfo; +import com.simibubi.create.foundation.utility.Lang; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.ShapedRecipe; +import net.minecraft.world.level.Level; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.Set; +import java.util.function.Supplier; + +public enum TFMGRecipeTypes implements IRecipeTypeInfo { + +DISTILLATION(DistillationRecipe::new); + + private final ResourceLocation id; + private final RegistryObject> serializerObject; + @Nullable + private final RegistryObject> typeObject; + private final Supplier> type; + + TFMGRecipeTypes(Supplier> serializerSupplier, Supplier> typeSupplier, boolean registerType) { + String name = Lang.asId(name()); + id = CreateTFMG.asResource(name); + serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); + if (registerType) { + typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier); + type = typeObject; + } else { + typeObject = null; + type = typeSupplier; + } + } + + TFMGRecipeTypes(Supplier> serializerSupplier) { + String name = Lang.asId(name()); + id = CreateTFMG.asResource(name); + serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); + typeObject = Registers.TYPE_REGISTER.register(name, () -> simpleType(id)); + type = typeObject; + } + + TFMGRecipeTypes(ProcessingRecipeFactory processingFactory) { + this(() -> new ProcessingRecipeSerializer<>(processingFactory)); + } + + public static > RecipeType simpleType(ResourceLocation id) { + String stringId = id.toString(); + return new RecipeType() { + @Override + public String toString() { + return stringId; + } + }; + } + + public static void register(IEventBus modEventBus) { + ShapedRecipe.setCraftingSize(9, 9); + + Registers.SERIALIZER_REGISTER.register(modEventBus); + Registers.TYPE_REGISTER.register(modEventBus); + } + + @Override + public ResourceLocation getId() { + return id; + } + + @SuppressWarnings("unchecked") + @Override + public > T getSerializer() { + return (T) serializerObject.get(); + } + + @SuppressWarnings("unchecked") + @Override + public > T getType() { + return (T) type.get(); + } + + public > Optional find(C inv, Level world) { + return world.getRecipeManager() + .getRecipeFor(getType(), inv, world); + } + + public static final Set RECIPE_DENY_SET = + ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual")); + + + private static class Registers { + private static final DeferredRegister> SERIALIZER_REGISTER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, CreateTFMG.MOD_ID); + private static final DeferredRegister> TYPE_REGISTER = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, CreateTFMG.MOD_ID); + } + +} diff --git a/src/main/resources/backup/DistillationControllerBlock.java b/src/main/resources/backup/DistillationControllerBlock.java new file mode 100644 index 00000000..c22c7526 --- /dev/null +++ b/src/main/resources/backup/DistillationControllerBlock.java @@ -0,0 +1,210 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup; + + +import com.drmangotea.tfmg.registry.TFMGBlockEntities; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.Create; +import com.simibubi.create.content.equipment.wrench.IWrenchable; +import com.simibubi.create.content.fluids.transfer.GenericItemEmptying; +import com.simibubi.create.content.fluids.transfer.GenericItemFilling; +import com.simibubi.create.content.kinetics.belt.BeltBlockEntity; +import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour; +import com.simibubi.create.content.logistics.funnel.FunnelBlock; +import com.simibubi.create.content.processing.basin.BasinOperatingBlockEntity; +import com.simibubi.create.foundation.block.IBE; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.fluid.FluidHelper; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +public class DistillationControllerBlock extends Block implements IBE, IWrenchable { + + public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER; + + public DistillationControllerBlock(Properties p_i48440_1_) { + super(p_i48440_1_); + registerDefaultState(defaultBlockState().setValue(FACING, Direction.DOWN)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder p_206840_1_) { + super.createBlockStateDefinition(p_206840_1_.add(FACING)); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + BlockEntity tileEntity = world.getBlockEntity(pos.above()); + if (tileEntity instanceof BasinOperatingBlockEntity) + return false; + return true; + } + + + + @Override + public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, + BlockHitResult hit) { + ItemStack heldItem = player.getItemInHand(handIn); + + return onBlockEntityUse(worldIn, pos, te -> { + if (!heldItem.isEmpty()) { + if (FluidHelper.tryEmptyItemIntoBE(worldIn, player, handIn, heldItem, te)) + return InteractionResult.SUCCESS; + if (FluidHelper.tryFillItemFromBE(worldIn, player, handIn, heldItem, te)) + return InteractionResult.SUCCESS; + + if (GenericItemEmptying.canItemBeEmptied(worldIn, heldItem) + || GenericItemFilling.canItemBeFilled(worldIn, heldItem)) + return InteractionResult.SUCCESS; + if (heldItem.getItem() + .equals(Items.SPONGE) + && !te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .map(iFluidHandler -> iFluidHandler.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE)) + .orElse(FluidStack.EMPTY) + .isEmpty()) { + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + + IItemHandlerModifiable inv = te.itemCapability.orElse(new ItemStackHandler(1)); + boolean success = false; + for (int slot = 0; slot < inv.getSlots(); slot++) { + ItemStack stackInSlot = inv.getStackInSlot(slot); + if (stackInSlot.isEmpty()) + continue; + player.getInventory() + .placeItemBackInInventory(stackInSlot); + inv.setStackInSlot(slot, ItemStack.EMPTY); + success = true; + } + if (success) + worldIn.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, .2f, + 1f + Create.RANDOM.nextFloat()); + te.onEmptied(); + return InteractionResult.SUCCESS; + }); + } + + @Override + public void updateEntityAfterFallOn(BlockGetter worldIn, Entity entityIn) { + super.updateEntityAfterFallOn(worldIn, entityIn); + if (!AllBlocks.BASIN.has(worldIn.getBlockState(entityIn.blockPosition()))) + return; + if (!(entityIn instanceof ItemEntity)) + return; + if (!entityIn.isAlive()) + return; + ItemEntity itemEntity = (ItemEntity) entityIn; + withBlockEntityDo(worldIn, entityIn.blockPosition(), te -> { + + // Tossed items bypass the quarter-stack limit + + + + + + }); + } + + @Override + public VoxelShape getInteractionShape(BlockState p_199600_1_, BlockGetter p_199600_2_, BlockPos p_199600_3_) { + return AllShapes.BASIN_RAYTRACE_SHAPE; + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { + return AllShapes.BASIN_BLOCK_SHAPE; + } + + @Override + public VoxelShape getCollisionShape(BlockState state, BlockGetter reader, BlockPos pos, CollisionContext ctx) { + if (ctx instanceof EntityCollisionContext && ((EntityCollisionContext) ctx).getEntity() instanceof ItemEntity) + return AllShapes.BASIN_COLLISION_SHAPE; + return getShape(state, reader, pos, ctx); + } + + @Override + public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + IBE.onRemove(state, worldIn, pos, newState); + } + + @Override + public boolean hasAnalogOutputSignal(BlockState state) { + return true; + } + + + + @Override + public Class getBlockEntityClass() { + return DistillationControllerBlockEntity.class; + } + + @Override + public BlockEntityType getBlockEntityType() { + return TFMGBlockEntities.CAST_IRON_DISTILLATION_CONTROLLER.get(); + } + + public static boolean canOutputTo(BlockGetter world, BlockPos basinPos, Direction direction) { + BlockPos neighbour = basinPos.relative(direction); + BlockPos output = neighbour.below(); + BlockState blockState = world.getBlockState(neighbour); + + if (FunnelBlock.isFunnel(blockState)) { + if (FunnelBlock.getFunnelFacing(blockState) == direction) + return false; + } else if (!blockState.getCollisionShape(world, neighbour) + .isEmpty()) { + return false; + } else { + BlockEntity tileEntity = world.getBlockEntity(output); + if (tileEntity instanceof BeltBlockEntity) { + BeltBlockEntity belt = (BeltBlockEntity) tileEntity; + return belt.getSpeed() == 0 || belt.getMovementFacing() != direction.getOpposite(); + } + } + + DirectBeltInputBehaviour directBeltInputBehaviour = + BlockEntityBehaviour.get(world, output, DirectBeltInputBehaviour.TYPE); + if (directBeltInputBehaviour != null) + return directBeltInputBehaviour.canInsertFromSide(direction); + return false; + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; + } + +} diff --git a/src/main/resources/backup/DistillationControllerBlockEntity.java b/src/main/resources/backup/DistillationControllerBlockEntity.java new file mode 100644 index 00000000..cd14569a --- /dev/null +++ b/src/main/resources/backup/DistillationControllerBlockEntity.java @@ -0,0 +1,588 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.AllTags; +import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; +import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour; +import com.simibubi.create.foundation.fluid.CombinedTankWrapper; +import com.simibubi.create.foundation.item.SmartInventory; +import com.simibubi.create.foundation.utility.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.wrapper.CombinedInvWrapper; + +import javax.annotation.Nonnull; +import java.util.*; + +public class DistillationControllerBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation { + + public SmartFluidTankBehaviour inputTank; + protected SmartInventory outputInventory; + protected SmartFluidTankBehaviour outputTank; + + private boolean contentsChanged; + + + private Couple tanks; + + public LazyOptional itemCapability; + protected LazyOptional fluidCapability; + + List disabledSpoutputs; + Direction preferredSpoutput; + protected List spoutputBuffer; + protected List spoutputFluidBuffer; + int recipeBackupCheck; + + public static final int OUTPUT_ANIMATION_TIME = 10; + List> visualizedOutputItems; + List> visualizedOutputFluids; + + public DistillationControllerBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + + outputInventory = new SmartInventory(9, this).forbidInsertion() + .withMaxStackSize(64); + + itemCapability = LazyOptional.of(() -> new CombinedInvWrapper( outputInventory)); + contentsChanged = true; + + + + + + tanks = Couple.create(inputTank, outputTank); + visualizedOutputItems = Collections.synchronizedList(new ArrayList<>()); + visualizedOutputFluids = Collections.synchronizedList(new ArrayList<>()); + disabledSpoutputs = new ArrayList<>(); + preferredSpoutput = null; + spoutputBuffer = new ArrayList<>(); + spoutputFluidBuffer = new ArrayList<>(); + recipeBackupCheck = 20; + } + + @Override + public void addBehaviours(List behaviours) { + behaviours.add(new DirectBeltInputBehaviour(this)); + + + + inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true) + .whenFluidUpdates(() -> contentsChanged = true); + outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true) + .whenFluidUpdates(() -> contentsChanged = true) + .forbidInsertion(); + behaviours.add(inputTank); + behaviours.add(outputTank); + + fluidCapability = LazyOptional.of(() -> { + LazyOptional inputCap = inputTank.getCapability(); + LazyOptional outputCap = outputTank.getCapability(); + return new CombinedTankWrapper(outputCap.orElse(null), inputCap.orElse(null)); + }); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + + outputInventory.deserializeNBT(compound.getCompound("OutputItems")); + + preferredSpoutput = null; + if (compound.contains("PreferredSpoutput")) + preferredSpoutput = NBTHelper.readEnum(compound, "PreferredSpoutput", Direction.class); + disabledSpoutputs.clear(); + ListTag disabledList = compound.getList("DisabledSpoutput", Tag.TAG_STRING); + disabledList.forEach(d -> disabledSpoutputs.add(Direction.valueOf(((StringTag) d).getAsString()))); + spoutputBuffer = NBTHelper.readItemList(compound.getList("Overflow", Tag.TAG_COMPOUND)); + spoutputFluidBuffer = NBTHelper.readCompoundList(compound.getList("FluidOverflow", Tag.TAG_COMPOUND), + FluidStack::loadFluidStackFromNBT); + + if (!clientPacket) + return; + + NBTHelper.iterateCompoundList(compound.getList("VisualizedItems", Tag.TAG_COMPOUND), + c -> visualizedOutputItems.add(IntAttached.with(OUTPUT_ANIMATION_TIME, ItemStack.of(c)))); + NBTHelper.iterateCompoundList(compound.getList("VisualizedFluids", Tag.TAG_COMPOUND), + c -> visualizedOutputFluids + .add(IntAttached.with(OUTPUT_ANIMATION_TIME, FluidStack.loadFluidStackFromNBT(c)))); + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + super.write(compound, clientPacket); + + compound.put("OutputItems", outputInventory.serializeNBT()); + + if (preferredSpoutput != null) + NBTHelper.writeEnum(compound, "PreferredSpoutput", preferredSpoutput); + ListTag disabledList = new ListTag(); + disabledSpoutputs.forEach(d -> disabledList.add(StringTag.valueOf(d.name()))); + compound.put("DisabledSpoutput", disabledList); + compound.put("Overflow", NBTHelper.writeItemList(spoutputBuffer)); + compound.put("FluidOverflow", + NBTHelper.writeCompoundList(spoutputFluidBuffer, fs -> fs.writeToNBT(new CompoundTag()))); + + if (!clientPacket) + return; + + compound.put("VisualizedItems", NBTHelper.writeCompoundList(visualizedOutputItems, ia -> ia.getValue() + .serializeNBT())); + compound.put("VisualizedFluids", NBTHelper.writeCompoundList(visualizedOutputFluids, ia -> ia.getValue() + .writeToNBT(new CompoundTag()))); + visualizedOutputItems.clear(); + visualizedOutputFluids.clear(); + } +/* + @Override + public void destroy() { + super.destroy(); + + ItemHelper.dropContents(level, worldPosition, outputInventory); + spoutputBuffer.forEach(is -> Block.popResource(level, worldPosition, is)); + } + + */ + + @Override + public void remove() { + super.remove(); + onEmptied(); + } + + public void onEmptied() { + getOperator().ifPresent(te -> te.basinRemoved = true); + } + + @Override + public void invalidate() { + super.invalidate(); + itemCapability.invalidate(); + fluidCapability.invalidate(); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, Direction side) { + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return itemCapability.cast(); + if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + return fluidCapability.cast(); + return super.getCapability(cap, side); + } + + @Override + public void notifyUpdate() { + super.notifyUpdate(); + } + + @Override + public void lazyTick() { + super.lazyTick(); + notifyUpdate(); + if (!level.isClientSide) { + updateSpoutput(); + if (recipeBackupCheck-- > 0) + return; + recipeBackupCheck = 20; + + } + + + + + } + + + + + + private void updateSpoutput() { + BlockState blockState = getBlockState(); + Direction currentFacing = blockState.getValue(DistillationControllerBlock.FACING); + Direction newFacing = Direction.DOWN; + for (Direction test : Iterate.horizontalDirections) { + boolean canOutputTo = DistillationControllerBlock.canOutputTo(level, worldPosition, test); + if (canOutputTo && !disabledSpoutputs.contains(test)) + newFacing = test; + } + + if (preferredSpoutput != null && DistillationControllerBlock.canOutputTo(level, worldPosition, preferredSpoutput) + && preferredSpoutput != Direction.UP) + newFacing = preferredSpoutput; + + if (newFacing == currentFacing) + return; + + level.setBlockAndUpdate(worldPosition, blockState.setValue(DistillationControllerBlock.FACING, newFacing)); + + if (newFacing.getAxis() + .isVertical()) + return; + + for (int slot = 0; slot < outputInventory.getSlots(); slot++) { + ItemStack extractItem = outputInventory.extractItem(slot, 64, true); + if (extractItem.isEmpty()) + continue; + if (acceptOutputs(ImmutableList.of(extractItem), Collections.emptyList(), true)) + acceptOutputs(ImmutableList.of(outputInventory.extractItem(slot, 64, false)), Collections.emptyList(), + false); + } + + IFluidHandler handler = outputTank.getCapability() + .orElse(null); + for (int slot = 0; slot < handler.getTanks(); slot++) { + FluidStack fs = handler.getFluidInTank(slot) + .copy(); + if (fs.isEmpty()) + continue; + if (acceptOutputs(Collections.emptyList(), ImmutableList.of(fs), true)) { + handler.drain(fs, IFluidHandler.FluidAction.EXECUTE); + acceptOutputs(Collections.emptyList(), ImmutableList.of(fs), false); + } + } + + notifyChangeOfContents(); + notifyUpdate(); + } + + @Override + public void tick() { + super.tick(); + + if (level.isClientSide) { + tickVisualizedOutputs(); + + } + + if ((!spoutputBuffer.isEmpty() || !spoutputFluidBuffer.isEmpty()) && !level.isClientSide) + tryClearingSpoutputOverflow(); + if (!contentsChanged) + return; + + contentsChanged = false; + getOperator().ifPresent(te -> te.basinChecker.scheduleUpdate()); + + for (Direction offset : Iterate.horizontalDirections) { + BlockPos toUpdate = worldPosition.above() + .relative(offset); + BlockState stateToUpdate = level.getBlockState(toUpdate); + if (stateToUpdate.getBlock() instanceof DistillationControllerBlock + && stateToUpdate.getValue(DistillationControllerBlock.FACING) == offset.getOpposite()) { + BlockEntity te = level.getBlockEntity(toUpdate); + if (te instanceof DistillationControllerBlockEntity) + ((DistillationControllerBlockEntity) te).contentsChanged = true; + } + } + } + + private void tryClearingSpoutputOverflow() { + BlockState blockState = getBlockState(); + if (!(blockState.getBlock() instanceof DistillationControllerBlock)) + return; + Direction direction = blockState.getValue(DistillationControllerBlock.FACING); + BlockEntity te = level.getBlockEntity(worldPosition.below() + .relative(direction)); + + FilteringBehaviour filter = null; + InvManipulationBehaviour inserter = null; + if (te != null) { + filter = BlockEntityBehaviour.get(level, te.getBlockPos(), FilteringBehaviour.TYPE); + inserter = BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE); + } + + IItemHandler targetInv = te == null ? null + : te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(inserter == null ? null : inserter.getInventory()); + + IFluidHandler targetTank = te == null ? null + : te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(null); + + boolean update = false; + + for (Iterator iterator = spoutputBuffer.iterator(); iterator.hasNext();) { + ItemStack itemStack = iterator.next(); + + if (direction == Direction.DOWN) { + Block.popResource(level, worldPosition, itemStack); + iterator.remove(); + update = true; + continue; + } + + if (targetInv == null) + break; + if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack, true) + .isEmpty()) + continue; + // if (filter != null && !filter.test(itemStack)) + // continue; + + update = true; + ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); + iterator.remove(); + visualizedOutputItems.add(IntAttached.withZero(itemStack)); + } + + for (Iterator iterator = spoutputFluidBuffer.iterator(); iterator.hasNext();) { + FluidStack fluidStack = iterator.next(); + + if (direction == Direction.DOWN) { + iterator.remove(); + update = true; + continue; + } + + if (targetTank == null) + break; + + for (boolean simulate : Iterate.trueAndFalse) { + IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE; + int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler + ? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action) + : targetTank.fill(fluidStack.copy(), action); + if (fill != fluidStack.getAmount()) + break; + if (simulate) + continue; + + update = true; + iterator.remove(); + visualizedOutputFluids.add(IntAttached.withZero(fluidStack)); + } + } + + if (update) { + notifyChangeOfContents(); + sendData(); + } + } + + public float getTotalFluidUnits(float partialTicks) { + int renderedFluids = 0; + float totalUnits = 0; + + for (SmartFluidTankBehaviour behaviour : getTanks()) { + if (behaviour == null) + continue; + for (SmartFluidTankBehaviour.TankSegment tankSegment : behaviour.getTanks()) { + if (tankSegment.getRenderedFluid() + .isEmpty()) + continue; + float units = tankSegment.getTotalUnits(partialTicks); + if (units < 1) + continue; + totalUnits += units; + renderedFluids++; + } + } + + if (renderedFluids == 0) + return 0; + if (totalUnits < 1) + return 0; + return totalUnits; + } + + private Optional getOperator() { + if (level == null) + return Optional.empty(); + BlockEntity te = level.getBlockEntity(worldPosition.above()); + if (te instanceof FluidProcessingBlockEntity) + return Optional.of((FluidProcessingBlockEntity) te); + return Optional.empty(); + } + + + + public void notifyChangeOfContents() { + contentsChanged = true; + } + + + + public SmartInventory getOutputInventory() { + return outputInventory; + } + + public boolean canContinueProcessing() { + return spoutputBuffer.isEmpty() && spoutputFluidBuffer.isEmpty(); + } + + public boolean acceptOutputs(List outputItems, List outputFluids, boolean simulate) { + outputInventory.allowInsertion(); + outputTank.allowInsertion(); + boolean acceptOutputsInner = acceptOutputsInner(outputItems, outputFluids, simulate); + outputInventory.forbidInsertion(); + outputTank.forbidInsertion(); + return acceptOutputsInner; + } + + private boolean acceptOutputsInner(List outputItems, List outputFluids, boolean simulate) { + BlockState blockState = getBlockState(); + if (!(blockState.getBlock() instanceof DistillationControllerBlock)) + return false; + + Direction direction = blockState.getValue(DistillationControllerBlock.FACING); + if (direction != Direction.DOWN) { + + BlockEntity te = level.getBlockEntity(worldPosition.below() + .relative(direction)); + + InvManipulationBehaviour inserter = + te == null ? null : BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE); + IItemHandler targetInv = te == null ? null + : te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(inserter == null ? null : inserter.getInventory()); + IFluidHandler targetTank = te == null ? null + : te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite()) + .orElse(null); + boolean externalTankNotPresent = targetTank == null; + + if (!outputItems.isEmpty() && targetInv == null) + return false; + if (!outputFluids.isEmpty() && externalTankNotPresent) { + // Special case - fluid outputs but output only accepts items + targetTank = outputTank.getCapability() + .orElse(null); + if (targetTank == null) + return false; + if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank)) + return false; + } + + if (simulate) + return true; + for (ItemStack itemStack : outputItems) { + if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem() + .sameItem(itemStack)) + continue; + spoutputBuffer.add(itemStack.copy()); + } + if (!externalTankNotPresent) + for (FluidStack fluidStack : outputFluids) + spoutputFluidBuffer.add(fluidStack.copy()); + return true; + } + + IItemHandler targetInv = outputInventory; + IFluidHandler targetTank = outputTank.getCapability() + .orElse(null); + + if (targetInv == null && !outputItems.isEmpty()) + return false; + if (!acceptItemOutputsIntoBasin(outputItems, simulate, targetInv)) + return false; + if (outputFluids.isEmpty()) + return true; + if (targetTank == null) + return false; + if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank)) + return false; + + return true; + } + + private boolean acceptFluidOutputsIntoBasin(List outputFluids, boolean simulate, + IFluidHandler targetTank) { + for (FluidStack fluidStack : outputFluids) { + IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE; + int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler + ? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action) + : targetTank.fill(fluidStack.copy(), action); + if (fill != fluidStack.getAmount()) + return false; + } + return true; + } + + private boolean acceptItemOutputsIntoBasin(List outputItems, boolean simulate, IItemHandler targetInv) { + for (ItemStack itemStack : outputItems) { + // Catalyst items are never consumed + if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem() + .sameItem(itemStack)) + continue; + if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate) + .isEmpty()) + return false; + } + return true; + } + + public void readOnlyItems(CompoundTag compound) { + + outputInventory.deserializeNBT(compound.getCompound("OutputItems")); + } + + public static BlazeBurnerBlock.HeatLevel getHeatLevelOf(BlockState state) { + if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL)) + return state.getValue(BlazeBurnerBlock.HEAT_LEVEL); + return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? BlazeBurnerBlock.HeatLevel.SMOULDERING : BlazeBurnerBlock.HeatLevel.NONE; + } + + public Couple getTanks() { + return tanks; + } + + + + // client things + + private void tickVisualizedOutputs() { + visualizedOutputFluids.forEach(IntAttached::decrement); + visualizedOutputItems.forEach(IntAttached::decrement); + visualizedOutputFluids.removeIf(IntAttached::isOrBelowZero); + visualizedOutputItems.removeIf(IntAttached::isOrBelowZero); + } + + + + @Override + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + return containedFluidTooltip(tooltip, isPlayerSneaking, + getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)); + } + + class BasinValueBox extends ValueBoxTransform.Sided { + + @Override + protected Vec3 getSouthLocation() { + return VecHelper.voxelSpace(8, 12, 15.75); + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + return direction.getAxis() + .isHorizontal(); + } + + } +} diff --git a/src/main/resources/backup/DistillationOutputBlock.java b/src/main/resources/backup/DistillationOutputBlock.java new file mode 100644 index 00000000..df3b4ed1 --- /dev/null +++ b/src/main/resources/backup/DistillationOutputBlock.java @@ -0,0 +1,57 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup; + + +import com.drmangotea.tfmg.registry.TFMGBlockEntities; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.foundation.block.IBE; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.EntityCollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class DistillationOutputBlock extends Block implements IBE { + + public DistillationOutputBlock(Properties properties) { + super(properties); + } + + @Override + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { + return !AllBlocks.BASIN.has(worldIn.getBlockState(pos.below())); + } + + @Override + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { + if (context instanceof EntityCollisionContext + && ((EntityCollisionContext) context).getEntity() instanceof Player) + return AllShapes.CASING_14PX.get(Direction.DOWN); + + return AllShapes.MECHANICAL_PROCESSOR_SHAPE; + } + + + @Override + public Class getBlockEntityClass() { + return DistillationOutputBlockEntity.class; + } + + @Override + public BlockEntityType getBlockEntityType() { + return TFMGBlockEntities.CAST_IRON_DISTILLATION_OUTPUT.get(); + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/resources/backup/DistillationOutputBlockEntity.java b/src/main/resources/backup/DistillationOutputBlockEntity.java new file mode 100644 index 00000000..61222f63 --- /dev/null +++ b/src/main/resources/backup/DistillationOutputBlockEntity.java @@ -0,0 +1,423 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup; + + +import com.drmangotea.tfmg.CreateTFMG; +import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe; +import com.drmangotea.tfmg.registry.TFMGRecipeTypes; +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; +import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.fluid.SmartFluidTank; +import com.simibubi.create.foundation.recipe.RecipeFinder; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.crafting.IShapedRecipe; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.templates.FluidTank; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity implements IHaveGoggleInformation { + + protected LazyOptional fluidCapability; + public FluidTank tankInventory; + protected BlockPos lastKnownPos; + + private static final int SYNC_RATE = 8; + protected int syncCooldown; + protected boolean queuedSync; + + + private static final Object DistillationRecipesKey = new Object(); + + public boolean running; + + public DistillationOutputBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + tankInventory = createInventory(); + fluidCapability = LazyOptional.of(() -> tankInventory); + refreshCapability(); + } + + protected boolean matchItemlessRecipe(Recipe recipe) { + if (recipe == null) + return false; + Optional controller = getController(); + if (!controller.isPresent()) + return false; + return DistillationRecipe.match(controller.get(), recipe); + } + + @Override + protected boolean updateController() { + + + + if (level == null || level.isClientSide) + return true; + Optional basin = getController(); + + + List> recipes = getMatchingRecipes(); + if (recipes.isEmpty()) + return true; + currentRecipe = recipes.get(0); + startProcessing(); + sendData(); + return true; + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + // registerAwardables(behaviours, AllAdvancements.MIXER); + } + + @Override + protected AABB createRenderBoundingBox() { + return new AABB(worldPosition).expandTowards(0, -1.5, 0); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + running = compound.getBoolean("Running"); + + super.read(compound, clientPacket); + lastKnownPos = null; + + if (compound.contains("LastKnownPos")) + lastKnownPos = NbtUtils.readBlockPos(compound.getCompound("LastKnownPos")); + + + tankInventory.setCapacity(8000); + tankInventory.readFromNBT(compound.getCompound("TankContent")); + if (tankInventory.getSpace() < 0) + tankInventory.drain(-tankInventory.getSpace(), IFluidHandler.FluidAction.EXECUTE); + + + } + + @Override + public void write(CompoundTag compound, boolean clientPacket) { + compound.putBoolean("Running", running); + if (lastKnownPos != null) + compound.put("LastKnownPos", NbtUtils.writeBlockPos(lastKnownPos)); + + compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag())); + + super.write(compound, clientPacket); + super.write(compound, clientPacket); + } + + @Override + public void tick() { + super.tick(); + + + + if (level != null) { + if ((!level.isClientSide || isVirtual())) { + process(); + sendData(); + } + } + if (syncCooldown > 0) { + syncCooldown--; + if (syncCooldown == 0 && queuedSync) + sendData(); + } + } + + protected void process() { + updateController(); + + if (currentRecipe == null) + return; + + + + // if((currentRecipe instanceof ShapelessRecipe)) + // return; + + BlockEntity above1 = level.getBlockEntity(this.getBlockPos().above(1)); + BlockEntity above2 = level.getBlockEntity(this.getBlockPos().above(2)); + BlockEntity burner = level.getBlockEntity(this.getBlockPos().below(2)); + if(!(burner instanceof BlazeBurnerBlockEntity)) + return; + if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.NONE) + return; + if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.SMOULDERING) + return; + + +if(above1 !=null&& above2 !=null + // && + /// tankInventory.getFluidAmount()+ + /// ((DistillationRecipe)currentRecipe) + /// .getFirstFluidResult() + /// .getAmount() + /// <8000&& + // ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(1).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()&& + // ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(2).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity() +){ + Optional optionalController = getController(); + if (!optionalController.isPresent()) + return; + + if(!(above1 instanceof DistillationOutputBlockEntity)&& + !( above2 instanceof DistillationOutputBlockEntity)) { + return; + } + + CreateTFMG.LOGGER.debug("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe"); + + FluidStack fluidInRecipe1 = ((DistillationRecipe) currentRecipe).getFirstFluidResult(); + FluidStack fluidInRecipe2 = ((DistillationRecipe) currentRecipe).getSecondFluidResult(); + FluidStack fluidInRecipe3 = ((DistillationRecipe) currentRecipe).getThirdFluidResult(); + + + + + if (fluidInRecipe1.getFluid() != this.tankInventory.getFluid().getFluid() + && tankInventory.getFluidAmount()!=0 + ) + return; + + if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above1).tankInventory.getFluid().getFluid()) + &&((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()!=0 + ) + return; + if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above2).tankInventory.getFluid().getFluid()) + &&((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()!=0 + ) + return; + + + + + if(getController().get().getTanks().get(true).getPrimaryHandler().getFluid().getFluid() != ((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid()) + return; + + DistillationControllerBlockEntity controller = optionalController.get(); + IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + + if(controller.outputInventory.getStackInSlot(0).getCount()>=1|| + controller.outputInventory.getStackInSlot(1).getCount()>=1|| + controller.outputInventory.getStackInSlot(2).getCount()>=1) + return; + + if (!controller.getTanks().get(true).isEmpty()) { + if(!level.isClientSide) { + // if(((DistillationRecipe)currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get()) + // return; + + controller.getTanks().get(true).getPrimaryHandler().drain(((DistillationRecipe) currentRecipe).getFluidIngredients().get(0).getRequiredAmount(), IFluidHandler.FluidAction.EXECUTE); + + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(0).isEmpty())) + tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(0).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(0).getAmount() + this.tankInventory.getFluidAmount())); + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(1).isEmpty())) + ((DistillationOutputBlockEntity) above1).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(1).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(1).getAmount() + ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount())); + if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(2).isEmpty())) + ((DistillationOutputBlockEntity) above2).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(2).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(2).getAmount() + ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount())); + + + if (!(((DistillationRecipe) currentRecipe).getFirstItemResult().isEmpty())) + controller.outputInventory.setItem(0, ((DistillationRecipe) currentRecipe).getFirstItemResult()); + + if (!(((DistillationRecipe) currentRecipe).getSecondItemResult().isEmpty())) + controller.outputInventory.setItem(1, ((DistillationRecipe) currentRecipe).getSecondItemResult()); +} +/* +if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty())) + controller.outputInventory.setItem(2,((DistillationRecipe) currentRecipe).getFirstItemResult()); + + + */ + + + + + + controller.notifyChangeOfContents(); + } + +} + +} + + @Override + protected List> getMatchingRecipes() { + + + List> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters); + return list.stream() + .filter(this::matchItemlessRecipe) + .sorted((r1, r2) -> r2.getIngredients() + .size() + - r1.getIngredients() + .size()) + .collect(Collectors.toList()); + } + + @Override + protected boolean matchStaticFilters(Recipe r) { + return ((r instanceof CraftingRecipe && !(r instanceof IShapedRecipe) + && r.getIngredients() + .size() > 1 + && !MechanicalPressBlockEntity.canCompress(r)) && !AllRecipeTypes.shouldIgnoreInAutomation(r) + || r.getType() == TFMGRecipeTypes.DISTILLATION.getType()); + } + + @Override + public void startProcessing() { + if (running ) + return; + super.startProcessing(); + running = true; + + } + + @Override + public boolean continueWithPreviousRecipe() { + return true; + } + + @Override + protected void onBasinRemoved() { + if (!running) + return; + + running = false; + } + + @Override + protected Object getRecipeCacheKey() { + return DistillationRecipesKey; + } + + @Override + protected boolean isRunning() { + return running; + } +/* + @Override + protected Optional getProcessedRecipeTrigger() { + return Optional.of(AllAdvancements.MIXER); + } + */ + @Override + @OnlyIn(Dist.CLIENT) + public void tickAudio() { + super.tickAudio(); + + // SoundEvents.BLOCK_STONE_BREAK + + + + } + + + protected SmartFluidTank createInventory() { + return new SmartFluidTank(8000, this::onFluidStackChanged); + } + + + protected void onFluidStackChanged(FluidStack newFluidStack) { + if (!hasLevel()) + return; + + + } + + + public void sendDataImmediately() { + syncCooldown = 0; + queuedSync = false; + sendData(); + } + + @Override + public void sendData() { + if (syncCooldown > 0) { + queuedSync = true; + return; + } + super.sendData(); + queuedSync = false; + syncCooldown = SYNC_RATE; + } + + + + + + + private void refreshCapability() { + LazyOptional oldCap = fluidCapability; + fluidCapability = LazyOptional.of(() -> handlerForCapability()); + oldCap.invalidate(); + } + + private IFluidHandler handlerForCapability() { + + return tankInventory; + } + + + + + + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + + return containedFluidTooltip(tooltip, isPlayerSneaking, + this.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (!fluidCapability.isPresent()) + refreshCapability(); + if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + return fluidCapability.cast(); + return super.getCapability(cap, side); + } + + + public IFluidTank getTankInventory() { + return tankInventory; + } + + + public FluidStack getFluid(int tank) { + return tankInventory.getFluid() + .copy(); +} + +} + diff --git a/src/main/resources/backup/FluidProcessingBlockEntity.java b/src/main/resources/backup/FluidProcessingBlockEntity.java new file mode 100644 index 00000000..09417ecc --- /dev/null +++ b/src/main/resources/backup/FluidProcessingBlockEntity.java @@ -0,0 +1,156 @@ +package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup; + + +import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe; +import com.simibubi.create.content.kinetics.base.KineticBlockEntity; +import com.simibubi.create.foundation.advancement.CreateAdvancement; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.simple.DeferralBehaviour; +import com.simibubi.create.foundation.recipe.RecipeFinder; +import net.minecraft.core.BlockPos; +import net.minecraft.world.Container; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public abstract class FluidProcessingBlockEntity extends KineticBlockEntity { + + public DeferralBehaviour basinChecker; + public boolean basinRemoved; + protected Recipe currentRecipe; + + public FluidProcessingBlockEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + basinChecker = new DeferralBehaviour(this, this::updateController); + behaviours.add(basinChecker); + } + + @Override + public void onSpeedChanged(float prevSpeed) { + super.onSpeedChanged(prevSpeed); + if (getSpeed() == 0) + basinRemoved = true; + basinRemoved = false; + basinChecker.scheduleUpdate(); + } + + @Override + public void tick() { + if (basinRemoved) { + basinRemoved = false; + onBasinRemoved(); + sendData(); + return; + } + + super.tick(); + } + + protected boolean updateController() { + + + if (isRunning()) + return true; + if (level == null || level.isClientSide) + return true; + Optional basin = getController(); + if (!basin.filter(DistillationControllerBlockEntity::canContinueProcessing) + .isPresent()) + return true; + + List> recipes = getMatchingRecipes(); + if (recipes.isEmpty()) + return true; + currentRecipe = recipes.get(0); + // if(currentRecipe instanceof DistillationRecipe) { + // if (((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get()) { + // return true; + // } + // } + startProcessing(); + sendData(); + return true; + } + + protected abstract boolean isRunning(); + + public void startProcessing() {} + + public boolean continueWithPreviousRecipe() { + return true; + } + + protected boolean matchItemlessRecipe(Recipe recipe) { + if (recipe == null) + return false; + Optional basin = getController(); + if (!basin.isPresent()) + return false; + return ItemlessRecipe.match(basin.get(), recipe); + } + + protected void applyItemlessRecipe() { + if (currentRecipe == null) + return; + + Optional optionalBasin = getController(); + if (!optionalBasin.isPresent()) + return; + DistillationControllerBlockEntity basin = optionalBasin.get(); + boolean wasEmpty = basin.canContinueProcessing(); + if (!ItemlessRecipe.apply(basin, currentRecipe)) + return; + getProcessedRecipeTrigger().ifPresent(this::award); + basin.inputTank.sendDataImmediately(); + + // Continue mixing + if (wasEmpty && matchItemlessRecipe(currentRecipe)) { + continueWithPreviousRecipe(); + sendData(); + } + + basin.notifyChangeOfContents(); + } + + protected List> getMatchingRecipes() { + + + List> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters); + return list.stream() + .filter(this::matchItemlessRecipe) + .sorted((r1, r2) -> r2.getIngredients() + .size() + - r1.getIngredients() + .size()) + .collect(Collectors.toList()); + } + + protected abstract void onBasinRemoved(); + + protected Optional getController() { + if (level == null) + return Optional.empty(); + BlockEntity basinTE = level.getBlockEntity(worldPosition.below(1)); + if (!(basinTE instanceof DistillationControllerBlockEntity)) + return Optional.empty(); + return Optional.of((DistillationControllerBlockEntity) basinTE); + } + + protected Optional getProcessedRecipeTrigger() { + return Optional.empty(); + } + + protected abstract boolean matchStaticFilters(Recipe recipe); + + protected abstract Object getRecipeCacheKey(); +} diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 26001fa6..c0c1d9ee 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -18,4 +18,8 @@ Version 0.6.0 -created a building block creative mode tab -added lead -added steel valves and smart pipes --added brass, lead, plastic, aluminum and cast iron pipes, smart pipes, pumps and valves \ No newline at end of file +-added brass, lead, plastic, aluminum and cast iron pipes, smart pipes, pumps and valves +-added compass to the surface scanner that shows directions to found deposit +-added flag to the surface scanner that gets raised when oil is under 10 block away +-doubled the range of surface scanners +-added sheetmetals \ No newline at end of file diff --git a/src/main/resources/data/tfmg/recipes/distillation/heavy_oil.json b/src/main/resources/data/tfmg/recipes/distillation/heavy_oil.json new file mode 100644 index 00000000..09596cfe --- /dev/null +++ b/src/main/resources/data/tfmg/recipes/distillation/heavy_oil.json @@ -0,0 +1,35 @@ +{ + "type": "tfmg:distillation", + "ingredients": [ + + { + "fluid": "tfmg:heavy_oil", + "nbt": {}, + "amount": 90 + } + ], + "results": [ + { + "fluid": "tfmg:diesel", + "amount": 30 + }, + { + "fluid": "tfmg:lubrication_oil", + "amount": 30 + }, + { + "fluid": "tfmg:lubrication_oil", + "amount": 30 + }, + { + "item": "tfmg:steel_ingot" + + }, + { + "item": "minecraft:air" + + } + ] + + +} diff --git a/src/main/resources/data/tfmg/recipes/distillation/naphtha.json b/src/main/resources/data/tfmg/recipes/distillation/naphtha.json new file mode 100644 index 00000000..97578494 --- /dev/null +++ b/src/main/resources/data/tfmg/recipes/distillation/naphtha.json @@ -0,0 +1,35 @@ +{ + "type": "tfmg:distillation", + "ingredients": [ + + { + "fluid": "tfmg:naphtha", + "nbt": {}, + "amount": 9 + } + ], + "results": [ + { + "fluid": "tfmg:propylene", + "amount": 3 + }, + { + "fluid": "tfmg:ethylene", + "amount": 3 + }, + { + "fluid": "tfmg:ethylene", + "amount": 3 + }, + { + "item": "minecraft:air" + + }, + { + "item": "minecraft:air" + + } + ] + + +}