diff --git a/build.gradle b/build.gradle
index d9b2f0e93..5b473075d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -223,12 +223,19 @@ sourceSets {
include 'appeng/block/grindstone/**'
include 'appeng/tile/grindstone/**'
include 'appeng/container/implementations/ContainerGrinder.java'
+ include 'appeng/recipes/conditions/**'
+ include 'appeng/recipes/game/DisassembleRecipe.java'
+ include 'appeng/recipes/ingredients/**'
+ include 'appeng/forge/data/**'
include 'appeng/client/render/tesr/CrankTESR.java'
include 'appeng/client/render/FacingToRotation.java'
include 'appeng/client/gui/implementations/GuiGrinder.java'
}
compileClasspath += sourceSets.api.output
runtimeClasspath += sourceSets.api.output
+ resources {
+ srcDir 'src/generated/resources'
+ }
}
test {
compileClasspath += sourceSets.api.output
diff --git a/src/api/java/appeng/api/definitions/IItemDefinition.java b/src/api/java/appeng/api/definitions/IItemDefinition.java
index bc8a91660..c43916641 100644
--- a/src/api/java/appeng/api/definitions/IItemDefinition.java
+++ b/src/api/java/appeng/api/definitions/IItemDefinition.java
@@ -25,9 +25,11 @@ package appeng.api.definitions;
import java.util.Optional;
+import java.util.Set;
import javax.annotation.Nonnull;
+import appeng.api.features.AEFeature;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -60,7 +62,7 @@ public interface IItemDefinition extends IComparableDefinition
ItemStack stack( int stackSize );
/**
- * @return true if definition is enabled
+ * @return an immutable set of the features of this item
*/
- boolean isEnabled();
+ Set features();
}
diff --git a/src/main/java/appeng/core/features/AEFeature.java b/src/api/java/appeng/api/features/AEFeature.java
similarity index 99%
rename from src/main/java/appeng/core/features/AEFeature.java
rename to src/api/java/appeng/api/features/AEFeature.java
index f7e1e707c..1ac5303fb 100644
--- a/src/main/java/appeng/core/features/AEFeature.java
+++ b/src/api/java/appeng/api/features/AEFeature.java
@@ -16,7 +16,7 @@
* along with Applied Energistics 2. If not, see .
*/
-package appeng.core.features;
+package appeng.api.features;
public enum AEFeature
diff --git a/src/api/java/appeng/api/features/IRecipeHandlerRegistry.java b/src/api/java/appeng/api/features/IRecipeHandlerRegistry.java
index 620f67114..baf77354e 100644
--- a/src/api/java/appeng/api/features/IRecipeHandlerRegistry.java
+++ b/src/api/java/appeng/api/features/IRecipeHandlerRegistry.java
@@ -39,18 +39,6 @@ import appeng.api.recipes.ISubItemResolver;
*/
public interface IRecipeHandlerRegistry
{
-
- /**
- * Add a new Recipe Handler to the parser.
- *
- * MUST BE CALLED IN PRE-INIT
- *
- * @param name name of crafthandler
- * @param handler class of crafthandler
- */
- @Deprecated
- void addNewCraftHandler( String name, Class extends ICraftHandler> handler );
-
/**
* Add a new resolver to the parser.
*
@@ -60,21 +48,6 @@ public interface IRecipeHandlerRegistry
*/
void addNewSubItemResolver( ISubItemResolver sir );
- /**
- * @param name name of crafting handler
- *
- * @return A recipe handler by name, returns null on failure.
- */
- @Nullable
- @Deprecated
- ICraftHandler getCraftHandlerFor( String name );
-
- /**
- * @return a new recipe handler, which can be used to parse, and read recipe files.
- */
- @Deprecated
- IRecipeHandler createNewRecipehandler();
-
/**
* resolve sub items by name.
*
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/charged_quartz_ore.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/charged_quartz_ore.json
new file mode 100644
index 000000000..b7ab6cde2
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/charged_quartz_ore.json
@@ -0,0 +1,48 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "conditions": [
+ {
+ "condition": "minecraft:match_tool",
+ "predicate": {
+ "enchantments": [
+ {
+ "enchantment": "minecraft:silk_touch",
+ "levels": {
+ "min": 1
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "name": "appliedenergistics2:charged_quartz_ore"
+ },
+ {
+ "type": "minecraft:item",
+ "functions": [
+ {
+ "function": "minecraft:apply_bonus",
+ "enchantment": "minecraft:fortune",
+ "formula": "minecraft:ore_drops"
+ },
+ {
+ "function": "minecraft:explosion_decay"
+ }
+ ],
+ "name": "minecraft:lapis_lazuli"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_block.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_block.json
new file mode 100644
index 000000000..402d65586
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:chiseled_quartz_block"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_slab.json
new file mode 100644
index 000000000..99800725e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:chiseled_quartz_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_stairs.json
new file mode 100644
index 000000000..e4615a458
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/chiseled_quartz_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:chiseled_quartz_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_block.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_block.json
new file mode 100644
index 000000000..7b2b9a6ae
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:fluix_block"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_slab.json
new file mode 100644
index 000000000..5366eed60
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:fluix_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_stairs.json
new file mode 100644
index 000000000..69218ef61
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/fluix_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:fluix_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/matrix_frame.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/matrix_frame.json
new file mode 100644
index 000000000..68701f9f6
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/matrix_frame.json
@@ -0,0 +1,3 @@
+{
+ "type": "minecraft:block"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_block.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_block.json
new file mode 100644
index 000000000..f3b91c4db
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_block"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_fixture.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_fixture.json
new file mode 100644
index 000000000..4f0f463ea
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_fixture.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_fixture"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_glass.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_glass.json
new file mode 100644
index 000000000..f42bc412f
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_glass.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_glass"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_ore.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_ore.json
new file mode 100644
index 000000000..9f00e7dca
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_ore.json
@@ -0,0 +1,48 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:alternatives",
+ "children": [
+ {
+ "type": "minecraft:item",
+ "conditions": [
+ {
+ "condition": "minecraft:match_tool",
+ "predicate": {
+ "enchantments": [
+ {
+ "enchantment": "minecraft:silk_touch",
+ "levels": {
+ "min": 1
+ }
+ }
+ ]
+ }
+ }
+ ],
+ "name": "appliedenergistics2:quartz_ore"
+ },
+ {
+ "type": "minecraft:item",
+ "functions": [
+ {
+ "function": "minecraft:apply_bonus",
+ "enchantment": "minecraft:fortune",
+ "formula": "minecraft:ore_drops"
+ },
+ {
+ "function": "minecraft:explosion_decay"
+ }
+ ],
+ "name": "minecraft:quartz"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar.json
new file mode 100644
index 000000000..ecabb9222
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_pillar"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_slab.json
new file mode 100644
index 000000000..e30e7cef0
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_pillar_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_stairs.json
new file mode 100644
index 000000000..f9a9fbecc
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_pillar_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_pillar_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_slab.json
new file mode 100644
index 000000000..eaf5b95a6
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_stairs.json
new file mode 100644
index 000000000..a5d0892ac
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_vibrant_glass.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_vibrant_glass.json
new file mode 100644
index 000000000..fea390735
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/quartz_vibrant_glass.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:quartz_vibrant_glass"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_block.json
new file mode 100644
index 000000000..bbc449c5d
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_block"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick.json
new file mode 100644
index 000000000..44955f15e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_brick"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_slab.json
new file mode 100644
index 000000000..37ba6528f
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_brick_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_stairs.json
new file mode 100644
index 000000000..ed691afdc
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_brick_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_brick_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_chest.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_chest.json
new file mode 100644
index 000000000..22995d06e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_chest.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_chest"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_slab.json
new file mode 100644
index 000000000..dcb3acc10
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick.json
new file mode 100644
index 000000000..a7aa9f17b
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_small_brick"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_slab.json
new file mode 100644
index 000000000..c9c4ee37e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_small_brick_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_stairs.json
new file mode 100644
index 000000000..c9ed09d77
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_small_brick_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_small_brick_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_stairs.json
new file mode 100644
index 000000000..ae26bfaf3
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/sky_stone_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:sky_stone_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_block.json
new file mode 100644
index 000000000..85591354e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:smooth_sky_stone_block"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_chest.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_chest.json
new file mode 100644
index 000000000..f01323eb0
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_chest.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:smooth_sky_stone_chest"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_slab.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_slab.json
new file mode 100644
index 000000000..3dc859e8f
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:smooth_sky_stone_slab"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_stairs.json b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_stairs.json
new file mode 100644
index 000000000..6b04849cf
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/loot_tables/blocks/smooth_sky_stone_stairs.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "name": "main",
+ "rolls": 1,
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "appliedenergistics2:smooth_sky_stone_stairs"
+ }
+ ],
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/chiseled_quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/chiseled_quartz_block.json
new file mode 100644
index 000000000..9d0b3efe9
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/chiseled_quartz_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:chiseled_quartz_block"
+ },
+ "result": "appliedenergistics2:chiseled_quartz_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/fluix_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/fluix_block.json
new file mode 100644
index 000000000..36f622037
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/fluix_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "FLUIX",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:fluix_block"
+ },
+ "result": "appliedenergistics2:fluix_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_block.json
new file mode 100644
index 000000000..21f1f62b1
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:quartz_block"
+ },
+ "result": "appliedenergistics2:quartz_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_pillar.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_pillar.json
new file mode 100644
index 000000000..f5756c2c6
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/quartz_pillar.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:quartz_pillar"
+ },
+ "result": "appliedenergistics2:quartz_pillar_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_block.json
new file mode 100644
index 000000000..bcc489c3f
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_block"
+ },
+ "result": "appliedenergistics2:sky_stone_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_brick.json
new file mode 100644
index 000000000..59e96045b
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_brick.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_brick"
+ },
+ "result": "appliedenergistics2:sky_stone_brick_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_small_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_small_brick.json
new file mode 100644
index 000000000..a35ae0555
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/sky_stone_small_brick.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_small_brick"
+ },
+ "result": "appliedenergistics2:sky_stone_small_brick_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/smooth_sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/smooth_sky_stone_block.json
new file mode 100644
index 000000000..d8c005681
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/block_cutter/smooth_sky_stone_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:smooth_sky_stone_block"
+ },
+ "result": "appliedenergistics2:smooth_sky_stone_slab",
+ "count": 2
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/chiseled_quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/chiseled_quartz_block.json
new file mode 100644
index 000000000..88aa8736b
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/chiseled_quartz_block.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:chiseled_quartz_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:chiseled_quartz_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/fluix_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/fluix_block.json
new file mode 100644
index 000000000..0fba6dabf
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/fluix_block.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "FLUIX",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:fluix_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:fluix_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_block.json
new file mode 100644
index 000000000..35183a69a
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_block.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:quartz_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:quartz_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_pillar.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_pillar.json
new file mode 100644
index 000000000..457d5702c
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/quartz_pillar.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:quartz_pillar"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:quartz_pillar_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_block.json
new file mode 100644
index 000000000..5492a7a6f
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_block.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_brick.json
new file mode 100644
index 000000000..b1c036ec2
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_brick.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_brick"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_brick_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_small_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_small_brick.json
new file mode 100644
index 000000000..46c1d331c
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/sky_stone_small_brick.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_small_brick"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_small_brick_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/slabs/smooth_sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/slabs/smooth_sky_stone_block.json
new file mode 100644
index 000000000..cd04860d1
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/slabs/smooth_sky_stone_block.json
@@ -0,0 +1,31 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:smooth_sky_stone_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:smooth_sky_stone_slab",
+ "count": 6
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/chiseled_quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/chiseled_quartz_block.json
new file mode 100644
index 000000000..57a491918
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/chiseled_quartz_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:chiseled_quartz_block"
+ },
+ "result": "appliedenergistics2:chiseled_quartz_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/fluix_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/fluix_block.json
new file mode 100644
index 000000000..611d3588e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/fluix_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "FLUIX",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:fluix_block"
+ },
+ "result": "appliedenergistics2:fluix_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_block.json
new file mode 100644
index 000000000..e50e68a33
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:quartz_block"
+ },
+ "result": "appliedenergistics2:quartz_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_pillar.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_pillar.json
new file mode 100644
index 000000000..d2b3ac908
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/quartz_pillar.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:quartz_pillar"
+ },
+ "result": "appliedenergistics2:quartz_pillar_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_block.json
new file mode 100644
index 000000000..947027d74
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_block"
+ },
+ "result": "appliedenergistics2:sky_stone_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_brick.json
new file mode 100644
index 000000000..eb1e8060e
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_brick.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_brick"
+ },
+ "result": "appliedenergistics2:sky_stone_brick_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_small_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_small_brick.json
new file mode 100644
index 000000000..e834ed172
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/sky_stone_small_brick.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:sky_stone_small_brick"
+ },
+ "result": "appliedenergistics2:sky_stone_small_brick_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/smooth_sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/smooth_sky_stone_block.json
new file mode 100644
index 000000000..dcf3a0d02
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/block_cutter/smooth_sky_stone_block.json
@@ -0,0 +1,24 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:stonecutting",
+ "ingredient": {
+ "item": "appliedenergistics2:smooth_sky_stone_block"
+ },
+ "result": "appliedenergistics2:smooth_sky_stone_stairs",
+ "count": 1
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/chiseled_quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/chiseled_quartz_block.json
new file mode 100644
index 000000000..aa155ac80
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/chiseled_quartz_block.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:chiseled_quartz_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:chiseled_quartz_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/fluix_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/fluix_block.json
new file mode 100644
index 000000000..7505d32c7
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/fluix_block.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "FLUIX",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:fluix_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:fluix_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_block.json
new file mode 100644
index 000000000..5ed6dbb70
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_block.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:quartz_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:quartz_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_pillar.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_pillar.json
new file mode 100644
index 000000000..0fb45e803
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/quartz_pillar.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "CERTUS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:quartz_pillar"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:quartz_pillar_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_block.json
new file mode 100644
index 000000000..b3943e00b
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_block.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_brick.json
new file mode 100644
index 000000000..0d3df1788
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_brick.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_brick"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_brick_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_small_brick.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_small_brick.json
new file mode 100644
index 000000000..9e4e92bd3
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/sky_stone_small_brick.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "DECORATIVE_BLOCKS",
+ "SKY_STONE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:sky_stone_small_brick"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:sky_stone_small_brick_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/stairs/smooth_sky_stone_block.json b/src/generated/resources/data/appliedenergistics2/recipes/stairs/smooth_sky_stone_block.json
new file mode 100644
index 000000000..b8739d331
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/stairs/smooth_sky_stone_block.json
@@ -0,0 +1,33 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "SKY_STONE",
+ "DECORATIVE_BLOCKS"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "appliedenergistics2:smooth_sky_stone_block"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:smooth_sky_stone_stairs",
+ "count": 4
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_axe.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_axe.json
new file mode 100644
index 000000000..901715f1b
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_axe.json
@@ -0,0 +1,35 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_AXE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "XX ",
+ "X/ ",
+ " / "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_axe"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_cutting_knife.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_cutting_knife.json
new file mode 100644
index 000000000..a815ba18a
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_cutting_knife.json
@@ -0,0 +1,38 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_KNIFE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ " /",
+ "I/ ",
+ "XX "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "I": {
+ "tag": "forge:ingots/iron"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_cutting_knife"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_hoe.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_hoe.json
new file mode 100644
index 000000000..c214492d9
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_hoe.json
@@ -0,0 +1,35 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_HOE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "XX ",
+ " / ",
+ " / "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_hoe"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_pickaxe.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_pickaxe.json
new file mode 100644
index 000000000..216d8dae8
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_pickaxe.json
@@ -0,0 +1,35 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_PICKAXE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "XXX",
+ " / ",
+ " / "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_pickaxe"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_spade.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_spade.json
new file mode 100644
index 000000000..059694487
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_spade.json
@@ -0,0 +1,35 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_SPADE"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ " X ",
+ " / ",
+ " / "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_spade"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_sword.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_sword.json
new file mode 100644
index 000000000..2dc0353ba
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_sword.json
@@ -0,0 +1,35 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_SWORD"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ " X ",
+ " X ",
+ " / "
+ ],
+ "key": {
+ "/": {
+ "tag": "forge:rods/wooden"
+ },
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_sword"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_wrench.json b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_wrench.json
new file mode 100644
index 000000000..3dbe9bfd9
--- /dev/null
+++ b/src/generated/resources/data/appliedenergistics2/recipes/tools/nether_quartz_wrench.json
@@ -0,0 +1,32 @@
+{
+ "type": "forge:conditional",
+ "recipes": [
+ {
+ "conditions": [
+ {
+ "features": [
+ "NETHER_QUARTZ_TOOLS",
+ "QUARTZ_WRENCH"
+ ],
+ "type": "appliedenergistics2:feature"
+ }
+ ],
+ "recipe": {
+ "type": "minecraft:crafting_shaped",
+ "pattern": [
+ "X X",
+ " X ",
+ "X X"
+ ],
+ "key": {
+ "X": {
+ "tag": "forge:gems/quartz"
+ }
+ },
+ "result": {
+ "item": "appliedenergistics2:nether_quartz_wrench"
+ }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/main/java/appeng/block/crafting/ItemCraftingStorage.java b/src/main/java/appeng/block/crafting/ItemCraftingStorage.java
index 16df341d6..98db10c2d 100644
--- a/src/main/java/appeng/block/crafting/ItemCraftingStorage.java
+++ b/src/main/java/appeng/block/crafting/ItemCraftingStorage.java
@@ -22,10 +22,9 @@ package appeng.block.crafting;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
-import appeng.api.AEApi;
import appeng.block.AEBaseBlockItem;
import appeng.core.AEConfig;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
public class ItemCraftingStorage extends AEBaseBlockItem
diff --git a/src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java b/src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java
index c8803f62d..a6f0b490a 100644
--- a/src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java
+++ b/src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java
@@ -28,14 +28,10 @@ import java.util.function.Supplier;
import javax.annotation.Nullable;
-import appeng.bootstrap.components.ITileEntityRegistrationComponent;
import net.minecraft.block.Block;
-import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
-import net.minecraft.tileentity.TileEntityType;
-import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -45,16 +41,12 @@ import appeng.block.AEBaseBlockItem;
import appeng.block.AEBaseTileBlock;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
-import appeng.bootstrap.components.IPreInitComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AppEng;
import appeng.core.CreativeTab;
-import appeng.core.features.AEFeature;
-import appeng.core.features.ActivityState;
+import appeng.api.features.AEFeature;
import appeng.core.features.BlockDefinition;
-import appeng.core.features.BlockStackSrc;
import appeng.core.features.TileDefinition;
-import appeng.tile.AEBaseTile;
import appeng.util.Platform;
@@ -200,11 +192,11 @@ class BlockDefinitionBuilder implements IBlockBuilder
if( block instanceof AEBaseTileBlock )
{
- return (T) new TileDefinition( this.registryName, (AEBaseTileBlock) block, item );
+ return (T) new TileDefinition( this.registryName, (AEBaseTileBlock) block, item, features );
}
else
{
- return (T) new BlockDefinition( this.registryName, block, item );
+ return (T) new BlockDefinition( this.registryName, block, item, features );
}
}
diff --git a/src/main/java/appeng/bootstrap/FeatureFactory.java b/src/main/java/appeng/bootstrap/FeatureFactory.java
index 9ebda838d..9e3f96b64 100644
--- a/src/main/java/appeng/bootstrap/FeatureFactory.java
+++ b/src/main/java/appeng/bootstrap/FeatureFactory.java
@@ -45,7 +45,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.definitions.IItemDefinition;
import appeng.api.util.AEColor;
import appeng.api.util.AEColoredItemDefinition;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.ActivityState;
import appeng.core.features.ColoredItemDefinition;
import appeng.core.features.ItemStackSrc;
@@ -113,7 +113,7 @@ public class FeatureFactory
{
for( final AEColor color : AEColor.VALID_COLORS )
{
- final ActivityState state = ActivityState.from( target.isEnabled() );
+ final ActivityState state = ActivityState.from( true );
definition.add( color, new ItemStackSrc( targetItem, state ) );
}
diff --git a/src/main/java/appeng/bootstrap/IBlockBuilder.java b/src/main/java/appeng/bootstrap/IBlockBuilder.java
index f366c2ad7..c5a08cfd1 100644
--- a/src/main/java/appeng/bootstrap/IBlockBuilder.java
+++ b/src/main/java/appeng/bootstrap/IBlockBuilder.java
@@ -20,16 +20,14 @@ package appeng.bootstrap;
import java.util.function.BiFunction;
-import java.util.function.Function;
import net.minecraft.block.Block;
-import net.minecraft.client.renderer.RenderType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import appeng.api.definitions.IBlockDefinition;
import appeng.bootstrap.definitions.TileEntityDefinition;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
public interface IBlockBuilder
diff --git a/src/main/java/appeng/bootstrap/IItemBuilder.java b/src/main/java/appeng/bootstrap/IItemBuilder.java
index f4c30949b..01d3aaf45 100644
--- a/src/main/java/appeng/bootstrap/IItemBuilder.java
+++ b/src/main/java/appeng/bootstrap/IItemBuilder.java
@@ -26,7 +26,7 @@ import net.minecraft.dispenser.IDispenseItemBehavior;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.ItemDefinition;
diff --git a/src/main/java/appeng/bootstrap/ItemDefinitionBuilder.java b/src/main/java/appeng/bootstrap/ItemDefinitionBuilder.java
index 4cbe22d0a..0478d5fc9 100644
--- a/src/main/java/appeng/bootstrap/ItemDefinitionBuilder.java
+++ b/src/main/java/appeng/bootstrap/ItemDefinitionBuilder.java
@@ -30,15 +30,12 @@ import net.minecraft.block.DispenserBlock;
import net.minecraft.dispenser.IDispenseItemBehavior;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.components.IItemRegistrationComponent;
import appeng.bootstrap.components.IPostInitComponent;
-import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.core.CreativeTab;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.ItemDefinition;
import appeng.util.Platform;
@@ -134,7 +131,7 @@ class ItemDefinitionBuilder implements IItemBuilder
Item item = this.itemSupplier.get();
item.setRegistryName( AppEng.MOD_ID, this.registryName );
- ItemDefinition definition = new ItemDefinition( this.registryName, item );
+ ItemDefinition definition = new ItemDefinition( this.registryName, item, features );
// Register all extra handlers
this.boostrapComponents.forEach( component -> this.factory.addBootstrapComponent( component.apply( item ) ) );
diff --git a/src/main/java/appeng/bootstrap/TileEntityBuilder.java b/src/main/java/appeng/bootstrap/TileEntityBuilder.java
index 6e8d04184..4b7b548db 100644
--- a/src/main/java/appeng/bootstrap/TileEntityBuilder.java
+++ b/src/main/java/appeng/bootstrap/TileEntityBuilder.java
@@ -5,7 +5,7 @@ import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.ITileEntityRegistrationComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.ActivityState;
import appeng.core.features.BlockStackSrc;
import appeng.tile.AEBaseTile;
diff --git a/src/main/java/appeng/core/AEConfig.java b/src/main/java/appeng/core/AEConfig.java
index 4abb0749e..ac32132c1 100644
--- a/src/main/java/appeng/core/AEConfig.java
+++ b/src/main/java/appeng/core/AEConfig.java
@@ -22,7 +22,7 @@ package appeng.core;
import appeng.api.config.*;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.settings.TickRates;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
diff --git a/src/main/java/appeng/core/AELog.java b/src/main/java/appeng/core/AELog.java
index 0e4ddfc90..0e9c464a6 100644
--- a/src/main/java/appeng/core/AELog.java
+++ b/src/main/java/appeng/core/AELog.java
@@ -29,7 +29,7 @@ import org.apache.logging.log4j.message.ParameterizedMessage;
import net.minecraft.util.math.BlockPos;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
public final class AELog
diff --git a/src/main/java/appeng/core/AppEng.java b/src/main/java/appeng/core/AppEng.java
index f583b6d79..38d9ad91d 100644
--- a/src/main/java/appeng/core/AppEng.java
+++ b/src/main/java/appeng/core/AppEng.java
@@ -21,26 +21,21 @@ package appeng.core;
import java.io.File;
-import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.client.ClientHelper;
import appeng.client.render.model.GlassModelLoader;
-import appeng.core.features.AEFeature;
import appeng.server.ServerHelper;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item;
+import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.particles.ParticleType;
-import net.minecraft.stats.StatType;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.ModelLoaderRegistry;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.event.RegistryEvent;
-import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.CrashReportExtender;
import net.minecraftforge.fml.DistExecutor;
@@ -54,8 +49,7 @@ import appeng.services.export.ExportConfig;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
-import net.minecraftforge.fml.loading.FMLEnvironment;
-import net.minecraftforge.registries.IForgeRegistry;
+
@Mod(AppEng.MOD_ID)
public final class AppEng
@@ -109,6 +103,7 @@ public final class AppEng
modEventBus.addGenericListener(ParticleType.class, registration::registerParticleTypes);
modEventBus.addGenericListener(TileEntityType.class, registration::registerTileEntities);
modEventBus.addGenericListener(ContainerType.class, registration::registerContainerTypes);
+ modEventBus.addGenericListener(IRecipeSerializer.class, registration::registerRecipeSerializers);
modEventBus.addListener(registration::registerParticleFactories);
modEventBus.addListener(registration::registerTextures);
diff --git a/src/main/java/appeng/core/Registration.java b/src/main/java/appeng/core/Registration.java
index 4138c8776..5d465b09d 100644
--- a/src/main/java/appeng/core/Registration.java
+++ b/src/main/java/appeng/core/Registration.java
@@ -31,6 +31,9 @@ import appeng.client.render.tesr.SkyChestTESR;
import appeng.container.implementations.ContainerGrinder;
import appeng.container.implementations.ContainerSkyChest;
import appeng.core.stats.AeStats;
+import appeng.recipes.conditions.FeaturesEnabled;
+import appeng.recipes.game.DisassembleRecipe;
+import appeng.recipes.ingredients.PartIngredientSerializer;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScreenManager;
@@ -39,6 +42,7 @@ import net.minecraft.client.renderer.model.ModelResourceLocation;
import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item;
+import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.particles.ParticleType;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
@@ -48,9 +52,11 @@ import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoaderRegistry;
+import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.GenericEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.registries.ForgeRegistryEntry;
@@ -252,35 +258,24 @@ final class Registration
});
}
-// @SubscribeEvent
-// public void registerRecipes( RegistryEvent.Register event )
-// {
-// final IForgeRegistry registry = event.getRegistry();
-//
-// final Api api = Api.INSTANCE;
-// final ApiDefinitions definitions = api.definitions();
-// final Dist dist = FMLCommonHandler.instance().getEffectiveSide();
-//
-// if( AEConfig.instance().isFeatureEnabled( AEFeature.ENABLE_DISASSEMBLY_CRAFTING ) )
-// {
-// DisassembleRecipe r = new DisassembleRecipe();
-// registry.register( r.setRegistryName( AppEng.MOD_ID.toLowerCase(), "disassemble" ) );
-// }
-//
-// if( AEConfig.instance().isFeatureEnabled( AEFeature.ENABLE_FACADE_CRAFTING ) )
-// {
-// definitions.items().facade().maybeItem().ifPresent( facadeItem ->
-// {
-// FacadeRecipe f = new FacadeRecipe( (ItemFacade) facadeItem );
-// registry.register( f.setRegistryName( AppEng.MOD_ID.toLowerCase(), "facade" ) );
-// } );
-// }
-//
-// definitions.getRegistry().getBootstrapComponents( IRecipeRegistrationComponent.class ).forEachRemaining( b -> b.recipeRegistration( side, registry ) );
-//
-// final AERecipeLoader ldr = new AERecipeLoader();
-// ldr.loadProcessingRecipes();
-// }
+ public void registerRecipeSerializers( RegistryEvent.Register> event )
+ {
+ IForgeRegistry> r = event.getRegistry();
+
+ final ApiDefinitions definitions = Api.INSTANCE.definitions();
+
+ r.registerAll(
+ DisassembleRecipe.SERIALIZER
+// FacadeRecipe.getSerializer( (ItemFacade) definitions.items().facade().item() ) FIXME reimplement facades
+// this.factories.put( new ResourceLocation( AppEng.MOD_ID, "inscriber" ), new InscriberHandler() ); FIXME re-implement machine recipes
+// this.factories.put( new ResourceLocation( AppEng.MOD_ID, "smelt" ), new SmeltingHandler() );
+// this.factories.put( new ResourceLocation( AppEng.MOD_ID, "grinder" ), new GrinderHandler() );
+ );
+
+ CraftingHelper.register( FeaturesEnabled.Serializer.INSTANCE );
+
+ CraftingHelper.register( new ResourceLocation( AppEng.MOD_ID, "part" ), PartIngredientSerializer.INSTANCE );
+ }
public void registerEntities( RegistryEvent.Register> event )
diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java
index dc8ad6b97..fe1033ddc 100644
--- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java
+++ b/src/main/java/appeng/core/api/definitions/ApiBlocks.java
@@ -31,14 +31,17 @@ import appeng.bootstrap.*;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.SkyChestTESR;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.registries.PartModels;
import appeng.decorative.AEDecorativeBlock;
import appeng.decorative.solid.*;
import appeng.tile.grindstone.TileCrank;
import appeng.tile.grindstone.TileGrinder;
import appeng.tile.storage.TileSkyChest;
-import net.minecraft.block.*;
+import net.minecraft.block.Block;
+import net.minecraft.block.SlabBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.StairsBlock;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.RenderType;
import net.minecraftforge.api.distmarker.Dist;
diff --git a/src/main/java/appeng/core/api/definitions/ApiItems.java b/src/main/java/appeng/core/api/definitions/ApiItems.java
index 97c5ed38c..5ad9524e3 100644
--- a/src/main/java/appeng/core/api/definitions/ApiItems.java
+++ b/src/main/java/appeng/core/api/definitions/ApiItems.java
@@ -23,7 +23,7 @@ import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IItems;
import appeng.api.util.AEColoredItemDefinition;
import appeng.bootstrap.FeatureFactory;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.items.tools.quartz.*;
diff --git a/src/main/java/appeng/core/features/BlockDefinition.java b/src/main/java/appeng/core/features/BlockDefinition.java
index ee7660228..1fcbdce37 100644
--- a/src/main/java/appeng/core/features/BlockDefinition.java
+++ b/src/main/java/appeng/core/features/BlockDefinition.java
@@ -19,8 +19,9 @@
package appeng.core.features;
-import java.util.Optional;
+import java.util.Set;
+import appeng.api.features.AEFeature;
import com.google.common.base.Preconditions;
import net.minecraft.block.Block;
@@ -30,7 +31,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import appeng.api.definitions.IBlockDefinition;
-import net.minecraftforge.fml.RegistryObject;
public class BlockDefinition extends ItemDefinition implements IBlockDefinition
@@ -39,9 +39,9 @@ public class BlockDefinition extends ItemDefinition implements IBlockDefinition
private final BlockItem blockItem;
- public BlockDefinition( String registryName, Block block, BlockItem item )
+ public BlockDefinition( String registryName, Block block, BlockItem item, Set features )
{
- super( registryName, item );
+ super( registryName, item, features );
this.block = block;
this.blockItem = item;
}
diff --git a/src/main/java/appeng/core/features/DamagedItemDefinition.java b/src/main/java/appeng/core/features/DamagedItemDefinition.java
index d2c24497e..b2d944ce4 100644
--- a/src/main/java/appeng/core/features/DamagedItemDefinition.java
+++ b/src/main/java/appeng/core/features/DamagedItemDefinition.java
@@ -19,10 +19,13 @@
package appeng.core.features;
+import java.util.Collections;
import java.util.Optional;
+import java.util.Set;
import javax.annotation.Nonnull;
+import appeng.api.features.AEFeature;
import com.google.common.base.Preconditions;
import net.minecraft.item.Item;
@@ -71,9 +74,9 @@ public final class DamagedItemDefinition implements IItemDefinition
}
@Override
- public boolean isEnabled()
+ public Set features()
{
- return this.source.isPresent();
+ return Collections.emptySet();
}
@Override
@@ -84,7 +87,7 @@ public final class DamagedItemDefinition implements IItemDefinition
return false;
}
- return this.isEnabled() && comparableStack.getItem() == this.source.get().getItem();
+ return comparableStack.getItem() == this.source.get().getItem();
}
}
diff --git a/src/main/java/appeng/core/features/ItemDefinition.java b/src/main/java/appeng/core/features/ItemDefinition.java
index 20dd032a4..b7fe2e34d 100644
--- a/src/main/java/appeng/core/features/ItemDefinition.java
+++ b/src/main/java/appeng/core/features/ItemDefinition.java
@@ -19,13 +19,15 @@
package appeng.core.features;
-import java.util.Optional;
+import java.util.Set;
import javax.annotation.Nonnull;
+import appeng.api.features.AEFeature;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -37,12 +39,14 @@ public class ItemDefinition implements IItemDefinition
{
private final String identifier;
private final Item item;
+ private final Set features;
- public ItemDefinition( String registryName, Item item )
+ public ItemDefinition( String registryName, Item item, Set features )
{
Preconditions.checkArgument( !Strings.isNullOrEmpty( registryName ), "registryName" );
this.identifier = registryName;
this.item = item;
+ this.features = ImmutableSet.copyOf(features);
}
@Nonnull
@@ -65,10 +69,9 @@ public class ItemDefinition implements IItemDefinition
}
@Override
- public boolean isEnabled()
+ public Set features()
{
- // FIXME sadly we can only set this after registration
- return true;
+ return features;
}
@Override
diff --git a/src/main/java/appeng/core/features/TileDefinition.java b/src/main/java/appeng/core/features/TileDefinition.java
index e0ca2fb35..4922ed4eb 100644
--- a/src/main/java/appeng/core/features/TileDefinition.java
+++ b/src/main/java/appeng/core/features/TileDefinition.java
@@ -20,9 +20,11 @@ package appeng.core.features;
import java.util.Optional;
+import java.util.Set;
import javax.annotation.Nonnull;
+import appeng.api.features.AEFeature;
import net.minecraft.item.BlockItem;
import net.minecraft.tileentity.TileEntity;
@@ -35,9 +37,9 @@ public final class TileDefinition extends BlockDefinition implements ITileDefini
private final Optional block;
- public TileDefinition( @Nonnull String registryName, AEBaseTileBlock block, BlockItem item )
+ public TileDefinition( @Nonnull String registryName, AEBaseTileBlock block, BlockItem item, Set features )
{
- super( registryName, block, item );
+ super( registryName, block, item, features );
this.block = Optional.ofNullable( block );
}
diff --git a/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java b/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
index d7cba63ba..490134b63 100644
--- a/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
+++ b/src/main/java/appeng/core/features/registries/MatterCannonAmmoRegistry.java
@@ -26,7 +26,6 @@ import net.minecraft.item.Items;
import appeng.api.features.IMatterCannonAmmoRegistry;
import appeng.recipes.ores.IOreListener;
-import appeng.recipes.ores.OreDictionaryHandler;
public class MatterCannonAmmoRegistry implements IOreListener, IMatterCannonAmmoRegistry
diff --git a/src/main/java/appeng/core/features/registries/RecipeHandlerRegistry.java b/src/main/java/appeng/core/features/registries/RecipeHandlerRegistry.java
index 5f89f14c5..7f867b4f3 100644
--- a/src/main/java/appeng/core/features/registries/RecipeHandlerRegistry.java
+++ b/src/main/java/appeng/core/features/registries/RecipeHandlerRegistry.java
@@ -32,7 +32,6 @@ import appeng.api.recipes.ICraftHandler;
import appeng.api.recipes.IRecipeHandler;
import appeng.api.recipes.ISubItemResolver;
import appeng.core.AELog;
-import appeng.recipes.RecipeHandler;
/**
@@ -43,51 +42,14 @@ import appeng.recipes.RecipeHandler;
*/
public class RecipeHandlerRegistry implements IRecipeHandlerRegistry
{
- private final Map> handlers = new HashMap<>( 20 );
private final Collection resolvers = new ArrayList<>();
- @Override
- public void addNewCraftHandler( final String name, final Class extends ICraftHandler> handler )
- {
- this.handlers.put( name.toLowerCase( Locale.ENGLISH ), handler );
- }
-
@Override
public void addNewSubItemResolver( final ISubItemResolver sir )
{
this.resolvers.add( sir );
}
- @Nullable
- @Override
- public ICraftHandler getCraftHandlerFor( final String name )
- {
- final Class extends ICraftHandler> clz = this.handlers.get( name );
- if( clz == null )
- {
- return null;
- }
- try
- {
- return clz.newInstance();
- }
- catch( final Throwable e )
- {
- AELog.error( "Error Caused when trying to construct " + clz.getName() );
- AELog.debug( e );
-
- this.handlers.put( name, null ); // clear it..
-
- return null;
- }
- }
-
- @Override
- public IRecipeHandler createNewRecipehandler()
- {
- return new RecipeHandler();
- }
-
@Nullable
@Override
public Object resolveItem( final String nameSpace, final String itemName )
diff --git a/src/main/java/appeng/core/features/registries/grinder/GrinderRecipeManager.java b/src/main/java/appeng/core/features/registries/grinder/GrinderRecipeManager.java
index 31d31056e..e74222e90 100644
--- a/src/main/java/appeng/core/features/registries/grinder/GrinderRecipeManager.java
+++ b/src/main/java/appeng/core/features/registries/grinder/GrinderRecipeManager.java
@@ -42,7 +42,6 @@ import appeng.api.features.IInscriberRecipeBuilder;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.recipes.ores.IOreListener;
-import appeng.recipes.ores.OreDictionaryHandler;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/core/sync/AppEngPacket.java b/src/main/java/appeng/core/sync/AppEngPacket.java
index 16ceb607e..6b1f2d6af 100644
--- a/src/main/java/appeng/core/sync/AppEngPacket.java
+++ b/src/main/java/appeng/core/sync/AppEngPacket.java
@@ -19,8 +19,6 @@
package appeng.core.sync;
-import org.apache.commons.lang3.tuple.Pair;
-
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.IPacket;
import net.minecraft.network.PacketBuffer;
@@ -28,7 +26,7 @@ import net.minecraftforge.fml.network.NetworkDirection;
import appeng.core.AEConfig;
import appeng.core.AELog;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.sync.network.INetworkInfo;
diff --git a/src/main/java/appeng/entity/EntityChargedQuartz.java b/src/main/java/appeng/entity/EntityChargedQuartz.java
index e51bb255a..f59a2c048 100644
--- a/src/main/java/appeng/entity/EntityChargedQuartz.java
+++ b/src/main/java/appeng/entity/EntityChargedQuartz.java
@@ -32,13 +32,12 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
-import appeng.api.AEApi;
import appeng.api.definitions.IMaterials;
import appeng.client.EffectType;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/entity/EntityGrowingCrystal.java b/src/main/java/appeng/entity/EntityGrowingCrystal.java
index f6b6404e3..207731cba 100644
--- a/src/main/java/appeng/entity/EntityGrowingCrystal.java
+++ b/src/main/java/appeng/entity/EntityGrowingCrystal.java
@@ -34,7 +34,7 @@ import appeng.api.implementations.tiles.ICrystalGrowthAccelerator;
import appeng.client.EffectType;
import appeng.core.AEConfig;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/entity/EntitySingularity.java b/src/main/java/appeng/entity/EntitySingularity.java
index 1b7f37d33..1ee9ab619 100644
--- a/src/main/java/appeng/entity/EntitySingularity.java
+++ b/src/main/java/appeng/entity/EntitySingularity.java
@@ -30,11 +30,10 @@ import net.minecraft.util.DamageSource;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World;
-import appeng.api.AEApi;
import appeng.api.definitions.IMaterials;
import appeng.core.AEConfig;
import appeng.core.Api;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.helpers.Reflected;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/entity/EntityTinyTNTPrimed.java b/src/main/java/appeng/entity/EntityTinyTNTPrimed.java
index 8f7bfd63a..ee99551d4 100644
--- a/src/main/java/appeng/entity/EntityTinyTNTPrimed.java
+++ b/src/main/java/appeng/entity/EntityTinyTNTPrimed.java
@@ -42,11 +42,10 @@ import net.minecraft.world.Explosion.Mode;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
-import appeng.api.AEApi;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.sync.packets.PacketMockExplosion;
import appeng.helpers.Reflected;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/facade/FacadeContainer.java b/src/main/java/appeng/facade/FacadeContainer.java
index e75a14270..1e45ded54 100644
--- a/src/main/java/appeng/facade/FacadeContainer.java
+++ b/src/main/java/appeng/facade/FacadeContainer.java
@@ -22,7 +22,6 @@ package appeng.facade;
import java.io.IOException;
import java.util.Optional;
-import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.PacketBuffer;
@@ -129,7 +128,7 @@ public class FacadeContainer implements IFacadeContainer
{
final int id = Math.abs( out.readInt() );
- Optional- maybeFacadeItem = Api.INSTANCE.definitions().items().facade().maybeItem();
+ Optional maybeFacadeItem = Api.INSTANCE.definitions().items().facade().maybeItem();
if( maybeFacadeItem.isPresent() )
{
final ItemFacade ifa = (ItemFacade) maybeFacadeItem.get();
@@ -164,7 +163,7 @@ public class FacadeContainer implements IFacadeContainer
final ItemStack is = ItemStack.read( t );
if( !is.isEmpty() )
{
- final Item i = is.getItem();
+ final net.minecraft.item.Item i = is.getItem();
if( i instanceof IFacadeItem )
{
this.storage.setFacade( x, ( (IFacadeItem) i ).createPartFromItemStack( is, AEPartLocation.fromOrdinal( x ) ) );
@@ -192,7 +191,7 @@ public class FacadeContainer implements IFacadeContainer
final IFacadePart part = this.getFacade( AEPartLocation.fromOrdinal( x ) );
if( part != null )
{
- final int itemID = Item.getIdFromItem( part.getItem() );
+ final int itemID = net.minecraft.item.Item.getIdFromItem( part.getItem() );
out.writeInt( itemID * ( part.notAEFacade() ? -1 : 1 ) );
}
}
diff --git a/src/main/java/appeng/forge/data/AE2DataGenerators.java b/src/main/java/appeng/forge/data/AE2DataGenerators.java
new file mode 100644
index 000000000..8deae5d63
--- /dev/null
+++ b/src/main/java/appeng/forge/data/AE2DataGenerators.java
@@ -0,0 +1,32 @@
+package appeng.forge.data;
+
+
+import appeng.core.AppEng;
+import appeng.forge.data.providers.loot.BlockDropProvider;
+import appeng.forge.data.providers.recipes.QuartzToolRecipes;
+import appeng.forge.data.providers.recipes.SlabStairRecipes;
+import appeng.forge.data.providers.recipes.SpecialRecipes;
+import net.minecraft.data.DataGenerator;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
+
+
+@Mod.EventBusSubscriber( modid = AppEng.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
+public class AE2DataGenerators
+{
+
+ @SubscribeEvent
+ public static void onGatherData( GatherDataEvent dataEvent )
+ {
+ DataGenerator generator = dataEvent.getGenerator();
+ if( dataEvent.includeServer() )
+ {
+ generator.addProvider( new BlockDropProvider( dataEvent ) );
+ generator.addProvider( new SlabStairRecipes( generator ) );
+ generator.addProvider( new QuartzToolRecipes( generator ) );
+ generator.addProvider( new SpecialRecipes( generator ) );
+ }
+ }
+
+}
diff --git a/src/main/java/appeng/forge/data/providers/IAE2DataProvider.java b/src/main/java/appeng/forge/data/providers/IAE2DataProvider.java
new file mode 100644
index 000000000..490df729b
--- /dev/null
+++ b/src/main/java/appeng/forge/data/providers/IAE2DataProvider.java
@@ -0,0 +1,26 @@
+package appeng.forge.data.providers;
+
+
+import appeng.api.definitions.IBlocks;
+import appeng.api.definitions.IItems;
+import appeng.api.definitions.IMaterials;
+import appeng.core.Api;
+import appeng.core.AppEng;
+import com.google.gson.JsonElement;
+import net.minecraft.data.IDataProvider;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.storage.loot.LootParameterSet;
+import net.minecraft.world.storage.loot.LootParameterSets;
+import net.minecraft.world.storage.loot.LootTable;
+import net.minecraft.world.storage.loot.LootTableManager;
+
+import javax.annotation.Nonnull;
+import java.nio.file.Path;
+
+
+public interface IAE2DataProvider extends IDataProvider
+{
+ IBlocks BLOCKS = Api.INSTANCE.definitions().blocks();
+ IItems ITEMS = Api.INSTANCE.definitions().items();
+ IMaterials MATERIALS = Api.INSTANCE.definitions().materials();
+}
diff --git a/src/main/java/appeng/forge/data/providers/loot/BlockDropProvider.java b/src/main/java/appeng/forge/data/providers/loot/BlockDropProvider.java
new file mode 100644
index 000000000..7c3725862
--- /dev/null
+++ b/src/main/java/appeng/forge/data/providers/loot/BlockDropProvider.java
@@ -0,0 +1,97 @@
+package appeng.forge.data.providers.loot;
+
+
+import appeng.core.AppEng;
+import appeng.forge.data.providers.IAE2DataProvider;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import net.minecraft.block.Block;
+import net.minecraft.data.DirectoryCache;
+import net.minecraft.data.IDataProvider;
+import net.minecraft.data.loot.BlockLootTables;
+import net.minecraft.item.Items;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.storage.loot.*;
+import net.minecraft.world.storage.loot.conditions.SurvivesExplosion;
+import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
+import net.minecraftforge.registries.ForgeRegistries;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.function.Function;
+
+
+public class BlockDropProvider extends BlockLootTables implements IAE2DataProvider
+{
+ private Map> overrides = ImmutableMap.>builder()
+ .put( BLOCKS.matrixFrame().block(), $ -> LootTable.builder() )
+ .put( BLOCKS.quartzOre().block(), b -> droppingItemWithFortune( b, Items.QUARTZ ) ) // FIXME replace with the material reference
+ .put( BLOCKS.quartzOreCharged().block(), b -> droppingItemWithFortune( b, Items.LAPIS_LAZULI ) ) // FIXME replace with the material reference
+ .build();
+
+ private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+
+ private final Path outputFolder;
+
+ public BlockDropProvider( GatherDataEvent dataEvent )
+ {
+ outputFolder = dataEvent.getGenerator().getOutputFolder();
+ }
+
+ @Override
+ public void act( @Nonnull DirectoryCache cache ) throws IOException
+ {
+ for( Map.Entry entry : ForgeRegistries.BLOCKS.getEntries() )
+ {
+ LootTable.Builder builder;
+ if( entry.getKey().getNamespace().equals( AppEng.MOD_ID ) )
+ {
+ builder = overrides.getOrDefault( entry.getValue(), this::defaultBuilder )
+ .apply( entry.getValue() );
+
+ IDataProvider.save( GSON, cache, toJson( builder ), getPath( outputFolder, entry.getKey() ) );
+ }
+ }
+ }
+
+ private LootTable.Builder defaultBuilder( Block block )
+ {
+ LootEntry.Builder> entry = ItemLootEntry.builder( block );
+ LootPool.Builder pool = LootPool.builder()
+ .name( "main" )
+ .rolls( ConstantRange.of( 1 ) )
+ .addEntry( entry )
+ .acceptCondition( SurvivesExplosion.builder() );
+
+ return LootTable.builder()
+ .addLootPool( pool );
+ }
+
+ private Path getPath( Path root, ResourceLocation id )
+ {
+ return root.resolve( "data/" + id.getNamespace() + "/loot_tables/blocks/" + id.getPath() + ".json" );
+ }
+
+ public JsonElement toJson( LootTable.Builder builder )
+ {
+ return LootTableManager.toJson( finishBuilding( builder ) );
+ }
+
+ @Nonnull
+ public LootTable finishBuilding( LootTable.Builder builder )
+ {
+ return builder.setParameterSet( LootParameterSets.BLOCK ).build();
+ }
+
+ @Nonnull
+ @Override
+ public String getName()
+ {
+ return AppEng.MOD_NAME + " Block Drops";
+ }
+
+}
diff --git a/src/main/java/appeng/forge/data/providers/recipes/QuartzToolRecipes.java b/src/main/java/appeng/forge/data/providers/recipes/QuartzToolRecipes.java
new file mode 100644
index 000000000..c6e978ab8
--- /dev/null
+++ b/src/main/java/appeng/forge/data/providers/recipes/QuartzToolRecipes.java
@@ -0,0 +1,137 @@
+package appeng.forge.data.providers.recipes;
+
+
+import appeng.api.definitions.IItemDefinition;
+import appeng.core.AppEng;
+import appeng.forge.data.providers.IAE2DataProvider;
+import appeng.recipes.conditions.FeaturesEnabled;
+import com.google.common.collect.ImmutableMap;
+import it.unimi.dsi.fastutil.chars.Char2ObjectArrayMap;
+import it.unimi.dsi.fastutil.chars.Char2ObjectMap;
+import it.unimi.dsi.fastutil.chars.CharOpenHashSet;
+import it.unimi.dsi.fastutil.chars.CharSet;
+import net.minecraft.data.DataGenerator;
+import net.minecraft.data.IFinishedRecipe;
+import net.minecraft.data.RecipeProvider;
+import net.minecraft.data.ShapedRecipeBuilder;
+import net.minecraft.item.Item;
+import net.minecraft.tags.Tag;
+import net.minecraftforge.common.Tags;
+import net.minecraftforge.common.crafting.ConditionalRecipe;
+
+import javax.annotation.Nonnull;
+import java.util.Map;
+import java.util.function.Consumer;
+
+
+public class QuartzToolRecipes extends RecipeProvider implements IAE2DataProvider
+{
+
+ private Map, IItemDefinition[]> items = ImmutableMap.of(
+ Tags.Items.GEMS_QUARTZ,
+ new IItemDefinition[] {
+ ITEMS.netherQuartzAxe(),
+ ITEMS.netherQuartzHoe(),
+ ITEMS.netherQuartzShovel(),
+ ITEMS.netherQuartzPick(),
+ ITEMS.netherQuartzSword(),
+ ITEMS.netherQuartzWrench(),
+ ITEMS.netherQuartzKnife()
+ }
+ // FIXME certus quartz
+ );
+
+ private String[][] patterns = {
+ {
+ "XX ",
+ "X/ ",
+ " / "
+ },
+ {
+ "XX ",
+ " / ",
+ " / "
+ },
+ {
+ " X ",
+ " / ",
+ " / "
+ },
+ {
+ "XXX",
+ " / ",
+ " / "
+ },
+ {
+ " X ",
+ " X ",
+ " / "
+ },
+ {
+ "X X",
+ " X ",
+ "X X"
+ },
+ {
+ " /",
+ "I/ ",
+ "XX "
+ }
+ };
+
+ private Char2ObjectMap> keys = new Char2ObjectArrayMap<>(
+ new char[] { 'I', '/' },
+ new Tag[] { Tags.Items.INGOTS_IRON, Tags.Items.RODS_WOODEN }
+ );
+
+ public QuartzToolRecipes( DataGenerator generatorIn )
+ {
+ super( generatorIn );
+ }
+
+ @Override
+ protected void registerRecipes( @Nonnull Consumer consumer )
+ {
+ for( Map.Entry, IItemDefinition[]> entry : items.entrySet() )
+ {
+ Tag
- tag = entry.getKey();
+ IItemDefinition[] tools = entry.getValue();
+
+ for( int i = 0; i < tools.length; i++ )
+ {
+ CharSet keySet = new CharOpenHashSet( new char[] { 'X', ' ' } );
+
+ ShapedRecipeBuilder shapedBuilder = ShapedRecipeBuilder.shapedRecipe( tools[i].item() );
+ for( String s : patterns[i] )
+ {
+ shapedBuilder.patternLine( s );
+
+ for( int j = 0; j < s.length(); j++ )
+ {
+ char c = s.charAt( j );
+ if( !keySet.contains( c ) )
+ {
+ keySet.add( c );
+ shapedBuilder.key( c, keys.get( c ) );
+ }
+ }
+ }
+
+ shapedBuilder.key( 'X', tag )
+ .addCriterion( "has_" + tag.getId(), hasItem( tag ) );
+
+ ConditionalRecipe.builder()
+ .addCondition( new FeaturesEnabled( tools[i].features() ) )
+ .addRecipe( shapedBuilder::build )
+ .build( consumer, AppEng.MOD_ID, "tools/" + tools[i].identifier() );
+ }
+
+ }
+ }
+
+ @Override public String getName()
+ {
+ return AppEng.MOD_NAME + " Quartz Tools";
+ }
+
+}
diff --git a/src/main/java/appeng/forge/data/providers/recipes/SlabStairRecipes.java b/src/main/java/appeng/forge/data/providers/recipes/SlabStairRecipes.java
new file mode 100644
index 000000000..3e2c2f459
--- /dev/null
+++ b/src/main/java/appeng/forge/data/providers/recipes/SlabStairRecipes.java
@@ -0,0 +1,117 @@
+package appeng.forge.data.providers.recipes;
+
+
+import appeng.api.definitions.IBlockDefinition;
+import appeng.core.AppEng;
+import appeng.forge.data.providers.IAE2DataProvider;
+import appeng.recipes.conditions.FeaturesEnabled;
+import com.google.common.collect.Sets;
+import net.minecraft.block.Block;
+import net.minecraft.data.*;
+import net.minecraft.item.crafting.Ingredient;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.crafting.ConditionalRecipe;
+
+import javax.annotation.Nonnull;
+import java.nio.file.Path;
+import java.util.function.Consumer;
+
+
+public class SlabStairRecipes extends RecipeProvider implements IAE2DataProvider
+{
+
+ IBlockDefinition[][] blocks = {
+ { BLOCKS.skyStoneBlock(), BLOCKS.skyStoneSlab(), BLOCKS.skyStoneStairs() },
+ { BLOCKS.smoothSkyStoneBlock(), BLOCKS.smoothSkyStoneSlab(), BLOCKS.smoothSkyStoneStairs() },
+ { BLOCKS.skyStoneBrick(), BLOCKS.skyStoneBrickSlab(), BLOCKS.skyStoneBrickStairs() },
+ { BLOCKS.skyStoneSmallBrick(), BLOCKS.skyStoneSmallBrickSlab(), BLOCKS.skyStoneSmallBrickStairs() },
+ { BLOCKS.fluixBlock(), BLOCKS.fluixSlab(), BLOCKS.fluixStairs() },
+ { BLOCKS.quartzBlock(), BLOCKS.quartzSlab(), BLOCKS.quartzStairs() },
+ { BLOCKS.chiseledQuartzBlock(), BLOCKS.chiseledQuartzSlab(), BLOCKS.chiseledQuartzStairs() },
+ { BLOCKS.quartzPillar(), BLOCKS.quartzPillarSlab(), BLOCKS.quartzPillarStairs() },
+ };
+
+ public SlabStairRecipes( DataGenerator generatorIn )
+ {
+ super( generatorIn );
+ }
+
+ @Override
+ public void registerRecipes( @Nonnull Consumer consumer )
+ {
+ for( IBlockDefinition[] block : blocks )
+ {
+ slabRecipe( consumer, block[0], block[1] );
+ stairRecipe( consumer, block[0], block[2] );
+ }
+ }
+
+ private void slabRecipe( Consumer consumer, IBlockDefinition block, IBlockDefinition slabs )
+ {
+ Block inputBlock = block.block();
+ Block outputBlock = slabs.block();
+
+ FeaturesEnabled condition = new FeaturesEnabled( Sets.union( block.features(), slabs.features() ) );
+ ConditionalRecipe.builder()
+ .addCondition( condition )
+ .addRecipe(
+ ShapedRecipeBuilder.shapedRecipe( slabs.block(), 6 )
+ .patternLine( "###" )
+ .key( '#', inputBlock )
+ .addCriterion( criterionName( block ), hasItem( inputBlock ) )
+ ::build
+ )
+ .build( consumer, AppEng.MOD_ID, "slabs/" + block.identifier() );
+
+ ConditionalRecipe.builder()
+ .addCondition( condition )
+ .addRecipe(
+ c -> SingleItemRecipeBuilder.stonecuttingRecipe( Ingredient.fromItems( inputBlock ), outputBlock, 2 )
+ .addCriterion( criterionName( block ), hasItem( inputBlock ) )
+ .build( c, new ResourceLocation( AppEng.MOD_ID, slabs.identifier() ) )
+ )
+ .build( consumer, AppEng.MOD_ID, "slabs/block_cutter/" + block.identifier() );
+
+ }
+
+ private void stairRecipe( Consumer consumer, IBlockDefinition block, IBlockDefinition stairs )
+ {
+ Block inputBlock = block.block();
+ Block outputBlock = stairs.block();
+
+ FeaturesEnabled condition = new FeaturesEnabled( Sets.union( block.features(), stairs.features() ) );
+ ConditionalRecipe.builder()
+ .addCondition( condition )
+ .addRecipe(
+ ShapedRecipeBuilder.shapedRecipe( outputBlock, 4 )
+ .patternLine( "# " )
+ .patternLine( "## " )
+ .patternLine( "###" )
+ .key( '#', inputBlock )
+ .addCriterion( criterionName( block ), hasItem( inputBlock ) )
+ ::build
+ )
+ .build( consumer, AppEng.MOD_ID, "stairs/" + block.identifier() );
+
+ ConditionalRecipe.builder()
+ .addCondition( condition )
+ .addRecipe(
+ c -> SingleItemRecipeBuilder.stonecuttingRecipe( Ingredient.fromItems( inputBlock ), outputBlock )
+ .addCriterion( criterionName( block ), hasItem( inputBlock ) )
+ .build( c, new ResourceLocation( AppEng.MOD_ID, stairs.identifier() ) )
+ )
+ .build( consumer, AppEng.MOD_ID, "stairs/block_cutter/" + block.identifier() );
+
+ }
+
+ private String criterionName( IBlockDefinition block )
+ {
+ return String.format( "has_%s", block.identifier() );
+ }
+
+ @Override public String getName()
+ {
+ return AppEng.MOD_NAME + " Slabs and Stairs";
+ }
+
+}
diff --git a/src/main/java/appeng/forge/data/providers/recipes/SpecialRecipes.java b/src/main/java/appeng/forge/data/providers/recipes/SpecialRecipes.java
new file mode 100644
index 000000000..7679744fc
--- /dev/null
+++ b/src/main/java/appeng/forge/data/providers/recipes/SpecialRecipes.java
@@ -0,0 +1,92 @@
+package appeng.forge.data.providers.recipes;
+
+
+import appeng.core.AppEng;
+import appeng.forge.data.providers.IAE2DataProvider;
+import com.google.gson.JsonObject;
+import net.minecraft.data.DataGenerator;
+import net.minecraft.data.IFinishedRecipe;
+import net.minecraft.data.RecipeProvider;
+import net.minecraft.item.crafting.IRecipeSerializer;
+import net.minecraft.util.ResourceLocation;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+
+public class SpecialRecipes extends RecipeProvider implements IAE2DataProvider
+{
+
+ public SpecialRecipes( DataGenerator generatorIn )
+ {
+ super( generatorIn );
+ }
+
+ @Override
+ protected void registerRecipes( @Nonnull Consumer consumer )
+ {
+// ConditionalRecipe.builder() FIXME this works, but NPEs at runtime
+// .addCondition( new FeaturesEnabled( AEFeature.ENABLE_DISASSEMBLY_CRAFTING ) )
+// .addRecipe( new FinishedRecipe( DisassembleRecipe.SERIALIZER ) )
+// .build( consumer, AppEng.MOD_ID, "special/disassemble" );
+
+// ConditionalRecipe.builder() FIXME re-implement facades
+// .addCondition( new FeaturesEnabled( AEFeature.ENABLE_FACADE_CRAFTING ) )
+// .addRecipe( new FinishedRecipe( FacadeRecipe.SERIALIZER ) )
+// .build( consumer, AppEng.MOD_ID, "special/facade" );
+ }
+
+ private static class FinishedRecipe implements IFinishedRecipe
+ {
+
+ private final IRecipeSerializer> serializer;
+
+ public FinishedRecipe( IRecipeSerializer> serializer )
+ {
+ this.serializer = serializer;
+ }
+
+ @Override public void serialize( @Nonnull JsonObject json )
+ {
+ }
+
+ @Nonnull
+ @Override
+ public ResourceLocation getID()
+ {
+ return Objects.requireNonNull( serializer.getRegistryName() );
+ }
+
+ @Nonnull
+ @Override
+ public IRecipeSerializer> getSerializer()
+ {
+ return serializer;
+ }
+
+ @Nullable
+ @Override
+ public JsonObject getAdvancementJson()
+ {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public ResourceLocation getAdvancementID()
+ {
+ return null;
+ }
+
+ }
+
+ @Nonnull
+ @Override
+ public String getName()
+ {
+ return AppEng.MOD_NAME + " Special Crafting Recipes";
+ }
+
+}
diff --git a/src/main/java/appeng/helpers/PatternHelper.java b/src/main/java/appeng/helpers/PatternHelper.java
index dde59813b..07bb67ea3 100644
--- a/src/main/java/appeng/helpers/PatternHelper.java
+++ b/src/main/java/appeng/helpers/PatternHelper.java
@@ -43,7 +43,7 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.container.ContainerNull;
import appeng.core.AEConfig;
import appeng.core.AELog;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
diff --git a/src/main/java/appeng/items/materials/ItemMaterial.java b/src/main/java/appeng/items/materials/ItemMaterial.java
index 2a9f003e1..fb954b2ea 100644
--- a/src/main/java/appeng/items/materials/ItemMaterial.java
+++ b/src/main/java/appeng/items/materials/ItemMaterial.java
@@ -59,7 +59,7 @@ import appeng.api.implementations.tiles.ISegmentedInventory;
import appeng.api.parts.IPartHost;
import appeng.api.parts.SelectedPart;
import appeng.core.AEConfig;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.IStackSrc;
import appeng.core.features.MaterialStackSrc;
import appeng.items.AEBaseItem;
diff --git a/src/main/java/appeng/items/materials/MaterialType.java b/src/main/java/appeng/items/materials/MaterialType.java
index c090df5d0..7c3a86276 100644
--- a/src/main/java/appeng/items/materials/MaterialType.java
+++ b/src/main/java/appeng/items/materials/MaterialType.java
@@ -29,7 +29,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.features.MaterialStackSrc;
import appeng.entity.EntityChargedQuartz;
import appeng.entity.EntitySingularity;
diff --git a/src/main/java/appeng/items/parts/PartType.java b/src/main/java/appeng/items/parts/PartType.java
index 851a217c8..fab98ae89 100644
--- a/src/main/java/appeng/items/parts/PartType.java
+++ b/src/main/java/appeng/items/parts/PartType.java
@@ -39,7 +39,7 @@ import appeng.api.parts.IPart;
import appeng.api.util.AEColor;
import appeng.core.AEConfig;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.fluids.parts.PartFluidAnnihilationPlane;
import appeng.fluids.parts.PartFluidExportBus;
diff --git a/src/main/java/appeng/items/storage/AbstractStorageCell.java b/src/main/java/appeng/items/storage/AbstractStorageCell.java
index 34fae218a..c3b377e88 100644
--- a/src/main/java/appeng/items/storage/AbstractStorageCell.java
+++ b/src/main/java/appeng/items/storage/AbstractStorageCell.java
@@ -51,7 +51,7 @@ import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.core.AEConfig;
import appeng.core.Api;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.localization.GuiText;
import appeng.items.AEBaseItem;
import appeng.items.contents.CellConfig;
diff --git a/src/main/java/appeng/items/tools/powered/ToolMatterCannon.java b/src/main/java/appeng/items/tools/powered/ToolMatterCannon.java
index ac49f7a92..397557b06 100644
--- a/src/main/java/appeng/items/tools/powered/ToolMatterCannon.java
+++ b/src/main/java/appeng/items/tools/powered/ToolMatterCannon.java
@@ -62,7 +62,7 @@ import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.Api;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.localization.PlayerMessages;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketMatterCannon;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzAxe.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzAxe.java
index 808d84bba..4d0b283d5 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzAxe.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzAxe.java
@@ -25,7 +25,7 @@ import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTier;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzCuttingKnife.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzCuttingKnife.java
index d07563e55..246b26360 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzCuttingKnife.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzCuttingKnife.java
@@ -32,7 +32,7 @@ import net.minecraft.world.World;
import appeng.api.implementations.guiobjects.IGuiItem;
import appeng.api.implementations.guiobjects.IGuiItemObject;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.items.AEBaseItem;
import appeng.items.contents.QuartzKnifeObj;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzHoe.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzHoe.java
index 4f9d589e5..1622fcd76 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzHoe.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzHoe.java
@@ -25,7 +25,7 @@ import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTier;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzPickaxe.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzPickaxe.java
index 5723a8529..e9e0abda5 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzPickaxe.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzPickaxe.java
@@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTier;
import net.minecraft.item.PickaxeItem;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzSpade.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzSpade.java
index 22dc153a0..a94f910a8 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzSpade.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzSpade.java
@@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTier;
import net.minecraft.item.ShovelItem;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/items/tools/quartz/ToolQuartzSword.java b/src/main/java/appeng/items/tools/quartz/ToolQuartzSword.java
index 6774f011b..078bab035 100644
--- a/src/main/java/appeng/items/tools/quartz/ToolQuartzSword.java
+++ b/src/main/java/appeng/items/tools/quartz/ToolQuartzSword.java
@@ -25,7 +25,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTier;
import net.minecraft.item.SwordItem;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.util.Platform;
diff --git a/src/main/java/appeng/me/GridConnection.java b/src/main/java/appeng/me/GridConnection.java
index 5c4330cdc..8c6e602be 100644
--- a/src/main/java/appeng/me/GridConnection.java
+++ b/src/main/java/appeng/me/GridConnection.java
@@ -36,7 +36,7 @@ import appeng.api.util.DimensionalCoord;
import appeng.api.util.IReadOnlyCollection;
import appeng.core.AEConfig;
import appeng.core.AELog;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.me.pathfinding.IPathItem;
import appeng.util.Platform;
import appeng.util.ReadOnlyCollection;
diff --git a/src/main/java/appeng/me/cache/PathGridCache.java b/src/main/java/appeng/me/cache/PathGridCache.java
index 520a95337..10cbe8936 100644
--- a/src/main/java/appeng/me/cache/PathGridCache.java
+++ b/src/main/java/appeng/me/cache/PathGridCache.java
@@ -29,7 +29,6 @@ import java.util.Set;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
-import appeng.api.AEApi;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridBlock;
@@ -49,7 +48,7 @@ import appeng.api.util.DimensionalCoord;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.stats.IAdvancementTrigger;
import appeng.me.GridConnection;
import appeng.me.GridNode;
diff --git a/src/main/java/appeng/recipes/AEItemResolver.java b/src/main/java/appeng/recipes/AEItemResolver.java
index 4330f2cff..92828b0d8 100644
--- a/src/main/java/appeng/recipes/AEItemResolver.java
+++ b/src/main/java/appeng/recipes/AEItemResolver.java
@@ -19,6 +19,7 @@
package appeng.recipes;
+import appeng.core.Api;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
diff --git a/src/main/java/appeng/recipes/AERecipeLoader.java b/src/main/java/appeng/recipes/AERecipeLoader.java
deleted file mode 100644
index b77e5b012..000000000
--- a/src/main/java/appeng/recipes/AERecipeLoader.java
+++ /dev/null
@@ -1,131 +0,0 @@
-
-package appeng.recipes;
-
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSyntaxException;
-
-import net.minecraft.util.JSONUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-
-import net.minecraft.util.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
-import net.minecraftforge.common.crafting.JsonContext;
-import net.minecraftforge.fml.common.FMLLog;
-import net.minecraftforge.fml.common.Loader;
-import net.minecraftforge.fml.common.ModContainer;
-
-import appeng.core.AppEng;
-import appeng.recipes.handlers.GrinderHandler;
-import appeng.recipes.handlers.InscriberHandler;
-import appeng.recipes.handlers.SmeltingHandler;
-
-
-public class AERecipeLoader
-{
- private static final String AERECIPE_BASE = "/aerecipes";
- private static Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
- private final Map factories = new HashMap<>();
-
- private final ModContainer mod;
- private final JsonContext ctx;
-
- public AERecipeLoader()
- {
- this.mod = Loader.instance().getIndexedModList().get( AppEng.MOD_ID );
- this.ctx = new JsonContext( AppEng.MOD_ID );
-
- this.initFactories();
- }
-
- public boolean loadProcessingRecipes()
- {
- return CraftingHelper.findFiles( this.mod, "assets/" + AppEng.MOD_ID + AERECIPE_BASE, this::preprocess, this::process, true, true );
- }
-
- private boolean preprocess( final Path root )
- {
- return true;
- }
-
- private boolean process( final Path root, final Path file )
- {
- String relative = root.relativize( file ).toString();
- if( !"json".equals( FilenameUtils.getExtension( file.toString() ) ) || relative.startsWith( "_" ) )
- {
- return true;
- }
-
- String name = FilenameUtils.removeExtension( relative ).replaceAll( "\\\\", "/" );
- ResourceLocation key = new ResourceLocation( this.ctx.getModId(), name );
-
- BufferedReader reader = null;
- try
- {
- reader = Files.newBufferedReader( file );
- JsonObject json = JSONUtils.fromJson( GSON, reader, JsonObject.class );
- if( json.has( "conditions" ) && !CraftingHelper.processConditions( JSONUtils.getJsonArray( json, "conditions" ), this.ctx ) )
- {
- return true;
- }
-
- this.register( json );
- }
- catch( JsonParseException e )
- {
- FMLLog.log.error( "Parsing error loading recipe {}", key, e );
- return false;
- }
- catch( IOException e )
- {
- FMLLog.log.error( "Couldn't read recipe {} from {}", key, file, e );
- return false;
- }
- finally
- {
- IOUtils.closeQuietly( reader );
- }
-
- return true;
- }
-
- private void register( JsonObject json )
- {
- if( json == null || json.isJsonNull() )
- {
- throw new JsonSyntaxException( "Json cannot be null" );
- }
-
- String type = this.ctx.appendModId( JSONUtils.getString( json, "type" ) );
- if( type.isEmpty() )
- {
- throw new JsonSyntaxException( "Recipe type can not be an empty string" );
- }
-
- IAERecipeFactory factory = this.factories.get( new ResourceLocation( type ) );
- if( factory == null )
- {
- throw new JsonSyntaxException( "Unknown recipe type: " + type );
- }
-
- factory.register( json, this.ctx );
- }
-
- private void initFactories()
- {
- this.factories.put( new ResourceLocation( AppEng.MOD_ID, "inscriber" ), new InscriberHandler() );
- this.factories.put( new ResourceLocation( AppEng.MOD_ID, "smelt" ), new SmeltingHandler() );
- this.factories.put( new ResourceLocation( AppEng.MOD_ID, "grinder" ), new GrinderHandler() );
- }
-}
diff --git a/src/main/java/appeng/recipes/IAERecipeFactory.java b/src/main/java/appeng/recipes/IAERecipeFactory.java
deleted file mode 100644
index 091ddff9f..000000000
--- a/src/main/java/appeng/recipes/IAERecipeFactory.java
+++ /dev/null
@@ -1,13 +0,0 @@
-
-package appeng.recipes;
-
-
-import com.google.gson.JsonObject;
-
-import net.minecraftforge.common.crafting.JsonContext;
-
-
-public interface IAERecipeFactory
-{
- void register( JsonObject json, JsonContext ctx );
-}
diff --git a/src/main/java/appeng/recipes/RecipeHandler.java b/src/main/java/appeng/recipes/RecipeHandler.java
deleted file mode 100644
index f578e9965..000000000
--- a/src/main/java/appeng/recipes/RecipeHandler.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes;
-
-
-import appeng.api.recipes.IRecipeHandler;
-import appeng.api.recipes.IRecipeLoader;
-
-
-/**
- * @author AlgorithmX2
- * @author thatsIch
- * @version rv3 - 10.08.2015
- * @since rv0
- */
-public class RecipeHandler implements IRecipeHandler
-{
- @Override
- public void parseRecipes( final IRecipeLoader loader, final String path )
- {
- // dummy
- }
-
- @Override
- public void injectRecipes()
- {
- // dummy
- }
-}
diff --git a/src/main/java/appeng/recipes/conditions/FeaturesEnabled.java b/src/main/java/appeng/recipes/conditions/FeaturesEnabled.java
new file mode 100644
index 000000000..d4512bfeb
--- /dev/null
+++ b/src/main/java/appeng/recipes/conditions/FeaturesEnabled.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of Applied Energistics 2.
+ * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
+ *
+ * Applied Energistics 2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Applied Energistics 2 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Applied Energistics 2. If not, see .
+ */
+
+package appeng.recipes.conditions;
+
+
+import appeng.core.AEConfig;
+import appeng.core.AppEng;
+import appeng.api.features.AEFeature;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import net.minecraft.util.JSONUtils;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.crafting.conditions.ICondition;
+import net.minecraftforge.common.crafting.conditions.IConditionSerializer;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.StreamSupport;
+
+
+public class FeaturesEnabled implements ICondition
+{
+ private static final ResourceLocation NAME = new ResourceLocation( AppEng.MOD_ID, "feature" );
+ private final AEFeature[] features;
+
+ public FeaturesEnabled( AEFeature... features )
+ {
+ this.features = features;
+ }
+
+ public FeaturesEnabled( Set features ) {
+ this(features.toArray(new AEFeature[0]));
+ }
+
+ @Override
+ public ResourceLocation getID()
+ {
+ return NAME;
+ }
+
+ @Override
+ public boolean test()
+ {
+ for( AEFeature feature : features )
+ {
+ if( !AEConfig.instance().isFeatureEnabled( feature ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static class Serializer implements IConditionSerializer
+ {
+ private static final String JSON_FEATURES_KEY = "features";
+
+ public static final Serializer INSTANCE = new Serializer();
+
+ private Serializer()
+ {
+ }
+
+ @Override
+ public void write( JsonObject json, FeaturesEnabled value )
+ {
+ json.add( JSON_FEATURES_KEY, Arrays.stream( value.features )
+ .map( AEFeature::toString )
+ .reduce( new JsonArray(), ( JsonArray array, String string ) -> {
+ array.add( string );
+ return array;
+ }, ( a, b ) -> b ) );
+ }
+
+ @Override
+ public FeaturesEnabled read( JsonObject jsonObject )
+ {
+ AEFeature[] features;
+
+ if( JSONUtils.isJsonArray( jsonObject, JSON_FEATURES_KEY ) )
+ {
+ final JsonArray featuresArray = JSONUtils.getJsonArray( jsonObject, JSON_FEATURES_KEY );
+
+ features = StreamSupport.stream( featuresArray.spliterator(), false )
+ .filter( JsonElement::isJsonPrimitive )
+ .map( JsonElement::getAsString )
+ .map( s -> s.toUpperCase( Locale.ENGLISH ) )
+ .map( AEFeature::valueOf )
+ .toArray( AEFeature[]::new );
+ }
+ else if( JSONUtils.isString( jsonObject, JSON_FEATURES_KEY ) )
+ {
+ final String featureName = JSONUtils.getString( jsonObject, JSON_FEATURES_KEY ).toUpperCase( Locale.ENGLISH );
+ features = new AEFeature[] { AEFeature.valueOf( featureName ) };
+ }
+ else
+ {
+ features = new AEFeature[] {};
+ }
+
+ return new FeaturesEnabled( features );
+ }
+
+ @Override
+ public ResourceLocation getID()
+ {
+ return NAME;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/factories/conditions/Features.java b/src/main/java/appeng/recipes/factories/conditions/Features.java
deleted file mode 100644
index c4e19659e..000000000
--- a/src/main/java/appeng/recipes/factories/conditions/Features.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes.factories.conditions;
-
-
-import java.util.Locale;
-import java.util.function.BooleanSupplier;
-import java.util.stream.Stream;
-
-import com.google.gson.JsonArray;
-import com.google.gson.JsonObject;
-
-import net.minecraft.util.JSONUtils;
-import net.minecraftforge.common.crafting.IConditionFactory;
-import net.minecraftforge.common.crafting.JsonContext;
-
-import appeng.core.AEConfig;
-import appeng.core.features.AEFeature;
-
-
-public class Features implements IConditionFactory
-{
- private static final String JSON_FEATURES_KEY = "features";
-
- @Override
- public BooleanSupplier parse( JsonContext jsonContext, JsonObject jsonObject )
- {
- final boolean result;
-
- if( JSONUtils.isJsonArray( jsonObject, JSON_FEATURES_KEY ) )
- {
- final JsonArray features = JSONUtils.getJsonArray( jsonObject, JSON_FEATURES_KEY );
-
- result = Stream.of( features )
- .allMatch( p -> AEConfig.instance().isFeatureEnabled( AEFeature.valueOf( p.getAsString().toUpperCase( Locale.ENGLISH ) ) ) );
- }
- else if( JSONUtils.isString( jsonObject, JSON_FEATURES_KEY ) )
- {
- final String featureName = JSONUtils.getString( jsonObject, JSON_FEATURES_KEY ).toUpperCase( Locale.ENGLISH );
- final AEFeature feature = AEFeature.valueOf( featureName );
-
- result = AEConfig.instance().isFeatureEnabled( feature );
- }
- else
- {
- result = false;
- }
-
- return () -> result;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/factories/conditions/MaterialExists.java b/src/main/java/appeng/recipes/factories/conditions/MaterialExists.java
deleted file mode 100644
index 4caaff3ce..000000000
--- a/src/main/java/appeng/recipes/factories/conditions/MaterialExists.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes.factories.conditions;
-
-
-import java.util.function.BooleanSupplier;
-
-import com.google.gson.JsonObject;
-
-import net.minecraft.util.JSONUtils;
-import net.minecraftforge.common.crafting.IConditionFactory;
-import net.minecraftforge.common.crafting.JsonContext;
-
-import appeng.core.Api;
-import appeng.core.AppEng;
-
-
-public class MaterialExists implements IConditionFactory
-{
- private static final String JSON_MATERIAL_KEY = "material";
-
- @Override
- public BooleanSupplier parse( JsonContext jsonContext, JsonObject jsonObject )
- {
- final boolean result;
-
- if( JSONUtils.isString( jsonObject, JSON_MATERIAL_KEY ) )
- {
- final String material = JSONUtils.getString( jsonObject, JSON_MATERIAL_KEY );
- final Object item = Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, material );
-
- result = item != null;
- }
- else
- {
- result = false;
- }
-
- return () -> result;
-
- }
-}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java b/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java
deleted file mode 100644
index 234130172..000000000
--- a/src/main/java/appeng/recipes/factories/recipes/PartRecipeFactory.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes.factories.recipes;
-
-
-import java.util.Map;
-import java.util.Set;
-
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSyntaxException;
-
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.crafting.IRecipe;
-import net.minecraft.item.crafting.Ingredient;
-import net.minecraft.util.JSONUtils;
-import net.minecraft.util.NonNullList;
-import net.minecraft.util.ResourceLocation;
-import net.minecraftforge.common.crafting.CraftingHelper;
-import net.minecraftforge.common.crafting.IRecipeFactory;
-import net.minecraftforge.common.crafting.JsonContext;
-import net.minecraftforge.oredict.ShapedOreRecipe;
-import net.minecraftforge.oredict.ShapelessOreRecipe;
-
-import appeng.api.AEApi;
-import appeng.api.recipes.ResolverResult;
-import appeng.core.AELog;
-import appeng.core.AppEng;
-
-
-/**
- * @author GuntherDW
- */
-public class PartRecipeFactory implements IRecipeFactory
-{
- @Override
- public IRecipe parse( JsonContext context, JsonObject json )
- {
- String type = JSONUtils.getString( json, "type" );
- if( type.contains( "shaped" ) )
- {
- return shapedFactory( context, json );
- }
- else if( type.contains( "shapeless" ) )
- {
- return shapelessFactory( context, json );
- }
- else
- {
- throw new JsonSyntaxException( "Applied Energistics 2 was given a custom recipe that it does not know how to handle!\n" + "Type should either be '" + AppEng.MOD_ID + ":shapeless' or '" + AppEng.MOD_ID + ":shaped', got '" + type + "'!" );
- }
- }
-
- public static ItemStack getResult( JsonObject json, JsonContext context )
- {
- return getResult( json, context, "result" );
- }
-
- public static ItemStack getResult( JsonObject json, JsonContext context, String name )
- {
- JsonObject resultObject = JSONUtils.getJsonObject( json, name );
-
- if( resultObject.has( "part" ) )
- {
- return getPart( resultObject );
- }
- else if( resultObject.has( "item" ) )
- {
- return CraftingHelper.getItemStack( resultObject, context );
- }
- else
- {
- throw new JsonSyntaxException( "Result has no 'part' or 'item' property." );
- }
- }
-
- private static ItemStack getPart( JsonObject resultObject )
- {
- String ingredient = JSONUtils.getString( resultObject, "part" );
- Object result = Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, ingredient );
- if( result instanceof ResolverResult )
- {
- ResolverResult resolverResult = (ResolverResult) result;
-
- Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
-
- if( item == null )
- {
- AELog.warn( "item was null for " + resolverResult.itemName + " ( " + ingredient + " )!" );
- throw new JsonSyntaxException( "Got a null item for " + resolverResult.itemName + " ( " + ingredient + " ). This should never happen!" );
- }
-
- return new ItemStack( item, JSONUtils.getInt( resultObject, "count", 1 ), resolverResult.damageValue, resolverResult.compound );
- }
- else
- {
- throw new JsonSyntaxException( "Couldn't find the resulting item in AE. This means AE was provided a recipe that it shouldn't be handling.\n" + "Was looking for : '" + ingredient + "'." );
- }
- }
-
- // Copied from ShapedOreRecipe.java, modified a bit.
- private static ShapedOreRecipe shapedFactory( JsonContext context, JsonObject json )
- {
- String group = JSONUtils.getString( json, "group", "" );
-
- Map ingMap = Maps.newHashMap();
- for( Map.Entry entry : JSONUtils.getJsonObject( json, "key" ).entrySet() )
- {
- if( entry.getKey().length() != 1 )
- {
- throw new JsonSyntaxException( "Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)." );
- }
- if( " ".equals( entry.getKey() ) )
- {
- throw new JsonSyntaxException( "Invalid key entry: ' ' is a reserved symbol." );
- }
-
- ingMap.put( entry.getKey().toCharArray()[0], CraftingHelper.getIngredient( entry.getValue(), context ) );
- }
-
- ingMap.put( ' ', net.minecraft.item.crafting.Ingredient.EMPTY );
-
- JsonArray patternJ = JSONUtils.getJsonArray( json, "pattern" );
-
- if( patternJ.size() == 0 )
- {
- throw new JsonSyntaxException( "Invalid pattern: empty pattern not allowed" );
- }
-
- String[] pattern = new String[patternJ.size()];
- for( int x = 0; x < pattern.length; ++x )
- {
- String line = JSONUtils.getString( patternJ.get( x ), "pattern[" + x + "]" );
- if( x > 0 && pattern[0].length() != line.length() )
- {
- throw new JsonSyntaxException( "Invalid pattern: each row must be the same width" );
- }
- pattern[x] = line;
- }
-
- CraftingHelper.ShapedPrimer primer = new CraftingHelper.ShapedPrimer();
- primer.width = pattern[0].length();
- primer.height = pattern.length;
- primer.mirrored = JSONUtils.getBoolean( json, "mirrored", true );
- primer.input = NonNullList.withSize( primer.width * primer.height, net.minecraft.item.crafting.Ingredient.EMPTY );
-
- Set keys = Sets.newHashSet( ingMap.keySet() );
- keys.remove( ' ' );
-
- int x = 0;
- for( String line : pattern )
- {
- for( char chr : line.toCharArray() )
- {
- net.minecraft.item.crafting.Ingredient ing = ingMap.get( chr );
- if( ing == null )
- {
- throw new JsonSyntaxException( "Pattern references symbol '" + chr + "' but it's not defined in the key" );
- }
- primer.input.set( x++, ing );
- keys.remove( chr );
- }
- }
-
- if( !keys.isEmpty() )
- {
- throw new JsonSyntaxException( "Key defines symbols that aren't used in pattern: " + keys );
- }
-
- return new ShapedOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), getResult( json, context ), primer );
- }
-
- // Copied from ShapelessOreRecipe.java, modified a bit.
- private static ShapelessOreRecipe shapelessFactory( JsonContext context, JsonObject json )
- {
- String group = JSONUtils.getString( json, "group", "" );
-
- NonNullList ings = NonNullList.create();
- for( JsonElement ele : JSONUtils.getJsonArray( json, "ingredients" ) )
- {
- ings.add( CraftingHelper.getIngredient( ele, context ) );
- }
-
- if( ings.isEmpty() )
- {
- throw new JsonParseException( "No ingredients for shapeless recipe" );
- }
-
- return new ShapelessOreRecipe( group.isEmpty() ? null : new ResourceLocation( group ), ings, getResult( json, context ) );
- }
-}
diff --git a/src/main/java/appeng/recipes/game/DisassembleRecipe.java b/src/main/java/appeng/recipes/game/DisassembleRecipe.java
index 1d12028d4..ee5e2db68 100644
--- a/src/main/java/appeng/recipes/game/DisassembleRecipe.java
+++ b/src/main/java/appeng/recipes/game/DisassembleRecipe.java
@@ -19,42 +19,46 @@
package appeng.recipes.game;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import net.minecraft.inventory.IInventory;
-import net.minecraft.inventory.CraftingInventory;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.crafting.IRecipe;
-import net.minecraft.util.NonNullList;
-import net.minecraft.world.World;
-import net.minecraftforge.common.ForgeHooks;
-
-import appeng.api.AEApi;
-import appeng.api.definitions.IBlocks;
-import appeng.api.definitions.IDefinitions;
-import appeng.api.definitions.IItemDefinition;
-import appeng.api.definitions.IItems;
-import appeng.api.definitions.IMaterials;
+import appeng.api.definitions.*;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
+import appeng.core.Api;
+import appeng.core.AppEng;
+import net.minecraft.inventory.CraftingInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.crafting.IRecipeSerializer;
+import net.minecraft.item.crafting.SpecialRecipe;
+import net.minecraft.item.crafting.SpecialRecipeSerializer;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+
+import javax.annotation.Nonnull;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
-public final class DisassembleRecipe extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe
+public final class DisassembleRecipe extends SpecialRecipe
{
+ public static final IRecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>( DisassembleRecipe::new );
+
+ static
+ {
+ SERIALIZER.setRegistryName( new ResourceLocation( AppEng.MOD_ID, "disassemble_recipe" ) );
+ }
+
private static final ItemStack MISMATCHED_STACK = ItemStack.EMPTY;
private final Map cellMappings;
private final Map nonCellMappings;
- public DisassembleRecipe()
+ public DisassembleRecipe( ResourceLocation id )
{
+ super( id );
+
final IDefinitions definitions = Api.INSTANCE.definitions();
final IBlocks blocks = definitions.blocks();
final IItems items = definitions.items();
@@ -76,12 +80,12 @@ public final class DisassembleRecipe extends net.minecraftforge.registries.IForg
}
@Override
- public boolean matches(final CraftingInventory inv, final World w )
+ public boolean matches( @Nonnull final CraftingInventory inv, @Nonnull final World w )
{
return !this.getOutput( inv ).isEmpty();
}
- @Nullable
+ @Nonnull
private ItemStack getOutput( final IInventory inventory )
{
int itemCount = 0;
@@ -159,9 +163,9 @@ public final class DisassembleRecipe extends net.minecraftforge.registries.IForg
return Optional.empty();
}
- @Nullable
+ @Nonnull
@Override
- public ItemStack getCraftingResult( final CraftingInventory inv )
+ public ItemStack getCraftingResult( @Nonnull final CraftingInventory inv )
{
return this.getOutput( inv );
}
@@ -172,16 +176,11 @@ public final class DisassembleRecipe extends net.minecraftforge.registries.IForg
return false;
}
- @Nullable
+ @Nonnull
@Override
- public ItemStack getRecipeOutput() // no default output..
+ public IRecipeSerializer getSerializer()
{
- return ItemStack.EMPTY;
+ return SERIALIZER;
}
- @Override
- public NonNullList getRemainingItems( final CraftingInventory inv )
- {
- return ForgeHooks.defaultRecipeGetRemainingItems( inv );
- }
}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/game/FacadeRecipe.java b/src/main/java/appeng/recipes/game/FacadeRecipe.java
index 8e6f9d757..ee2fd86d6 100644
--- a/src/main/java/appeng/recipes/game/FacadeRecipe.java
+++ b/src/main/java/appeng/recipes/game/FacadeRecipe.java
@@ -19,29 +19,33 @@
package appeng.recipes.game;
-import javax.annotation.Nullable;
-
-import net.minecraft.inventory.IInventory;
-import net.minecraft.inventory.CraftingInventory;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.crafting.IRecipe;
-import net.minecraft.util.NonNullList;
-import net.minecraft.world.World;
-import net.minecraftforge.common.ForgeHooks;
-
-import appeng.api.AEApi;
import appeng.api.definitions.IComparableDefinition;
import appeng.api.definitions.IDefinitions;
+import appeng.core.Api;
+import appeng.core.AppEng;
import appeng.items.parts.ItemFacade;
+import net.minecraft.inventory.CraftingInventory;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.crafting.IRecipeSerializer;
+import net.minecraft.item.crafting.SpecialRecipe;
+import net.minecraft.item.crafting.SpecialRecipeSerializer;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+
+import javax.annotation.Nonnull;
-public final class FacadeRecipe extends net.minecraftforge.registries.IForgeRegistryEntry.Impl implements IRecipe
+public final class FacadeRecipe extends SpecialRecipe
{
+ public static SpecialRecipeSerializer SERIALIZER = null;
+
private final IComparableDefinition anchor;
private final ItemFacade facade;
- public FacadeRecipe( ItemFacade facade )
+ public FacadeRecipe( ResourceLocation id, ItemFacade facade )
{
+ super( id );
this.facade = facade;
final IDefinitions definitions = Api.INSTANCE.definitions();
@@ -49,12 +53,12 @@ public final class FacadeRecipe extends net.minecraftforge.registries.IForgeRegi
}
@Override
- public boolean matches(final CraftingInventory inv, final World w )
+ public boolean matches( @Nonnull final CraftingInventory inv, @Nonnull final World w )
{
return !this.getOutput( inv, false ).isEmpty();
}
- @Nullable
+ @Nonnull
private ItemStack getOutput( final IInventory inv, final boolean createFacade )
{
if( inv.getStackInSlot( 0 ).isEmpty() && inv.getStackInSlot( 2 ).isEmpty() && inv.getStackInSlot( 6 ).isEmpty() && inv.getStackInSlot( 8 ).isEmpty() )
@@ -75,7 +79,7 @@ public final class FacadeRecipe extends net.minecraftforge.registries.IForgeRegi
}
@Override
- public ItemStack getCraftingResult( final CraftingInventory inv )
+ public ItemStack getCraftingResult( @Nonnull final CraftingInventory inv )
{
return this.getOutput( inv, true );
}
@@ -86,15 +90,21 @@ public final class FacadeRecipe extends net.minecraftforge.registries.IForgeRegi
return false;
}
+ @Nonnull
@Override
- public ItemStack getRecipeOutput() // no default output..
+ public IRecipeSerializer getSerializer()
{
- return ItemStack.EMPTY;
+ return getSerializer( facade );
}
- @Override
- public NonNullList getRemainingItems( final CraftingInventory inv )
+ public static IRecipeSerializer getSerializer( ItemFacade facade )
{
- return ForgeHooks.defaultRecipeGetRemainingItems( inv );
+ if( SERIALIZER == null )
+ {
+ SERIALIZER = new SpecialRecipeSerializer<>( id -> new FacadeRecipe( id, facade ) );
+ SERIALIZER.setRegistryName( new ResourceLocation( AppEng.MOD_ID, "facade_recipe" ) );
+ }
+ return SERIALIZER;
}
+
}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/handlers/SmeltingHandler.java b/src/main/java/appeng/recipes/handlers/SmeltingHandler.java
deleted file mode 100644
index 3acf83b46..000000000
--- a/src/main/java/appeng/recipes/handlers/SmeltingHandler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-
-package appeng.recipes.handlers;
-
-
-import com.google.gson.JsonObject;
-
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.JSONUtils;
-import net.minecraftforge.common.crafting.CraftingHelper;
-import net.minecraftforge.common.crafting.JsonContext;
-import net.minecraftforge.fml.common.registry.GameRegistry;
-
-import appeng.recipes.IAERecipeFactory;
-import appeng.recipes.factories.recipes.PartRecipeFactory;
-
-
-public class SmeltingHandler implements IAERecipeFactory
-{
- @Override
- public void register( JsonObject json, JsonContext ctx )
- {
- ItemStack result = PartRecipeFactory.getResult( json, ctx );
- ItemStack[] input = CraftingHelper.getIngredient( json.get( "input" ), ctx ).getMatchingStacks();
- float xp = 0.0f;
- if( json.has( "xp" ) )
- {
- xp = JSONUtils.getFloat( json, "xp" );
- }
-
- for( int i = 0; i < input.length; ++i )
- {
- GameRegistry.addSmelting( input[i], result, xp );
- }
- }
-
-}
diff --git a/src/main/java/appeng/recipes/ingredients/PartIngredient.java b/src/main/java/appeng/recipes/ingredients/PartIngredient.java
new file mode 100644
index 000000000..6bb3f1101
--- /dev/null
+++ b/src/main/java/appeng/recipes/ingredients/PartIngredient.java
@@ -0,0 +1,35 @@
+package appeng.recipes.ingredients;
+
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.crafting.Ingredient;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+
+public class PartIngredient extends Ingredient
+{
+ private final String partName;
+
+ protected PartIngredient( String partName, Stream extends IItemList> itemLists )
+ {
+ super( itemLists );
+ this.partName = partName;
+ }
+
+ public static PartIngredient fromStacks(String partName, ItemStack... stacks) {
+ return new PartIngredient( partName, Arrays.stream( stacks ).map( SingleItemList::new ) );
+ }
+
+ public static PartIngredient empty( String partName )
+ {
+ return new PartIngredient( partName, Stream.empty() );
+ }
+
+ public String getPartName()
+ {
+ return partName;
+ }
+
+}
diff --git a/src/main/java/appeng/recipes/factories/ingredients/PartIngredientFactory.java b/src/main/java/appeng/recipes/ingredients/PartIngredientSerializer.java
similarity index 57%
rename from src/main/java/appeng/recipes/factories/ingredients/PartIngredientFactory.java
rename to src/main/java/appeng/recipes/ingredients/PartIngredientSerializer.java
index c3d3ab43d..7ff5ffe69 100644
--- a/src/main/java/appeng/recipes/factories/ingredients/PartIngredientFactory.java
+++ b/src/main/java/appeng/recipes/ingredients/PartIngredientSerializer.java
@@ -16,53 +16,79 @@
* along with Applied Energistics 2. If not, see .
*/
-package appeng.recipes.factories.ingredients;
+package appeng.recipes.ingredients;
-import javax.annotation.Nonnull;
-
-import com.google.gson.JsonObject;
-
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraftforge.common.crafting.IIngredientFactory;
-import net.minecraftforge.common.crafting.JsonContext;
-
import appeng.api.recipes.ResolverResult;
import appeng.api.recipes.ResolverResultSet;
import appeng.core.AELog;
import appeng.core.Api;
import appeng.core.AppEng;
+import com.google.gson.JsonObject;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.PacketBuffer;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.crafting.IIngredientSerializer;
+import net.minecraftforge.registries.ForgeRegistries;
+
+import javax.annotation.Nonnull;
-public class PartIngredientFactory implements IIngredientFactory
+public class PartIngredientSerializer implements IIngredientSerializer
{
+ public static PartIngredientSerializer INSTANCE = new PartIngredientSerializer();
+
+ private PartIngredientSerializer()
+ {
+ }
@Nonnull
@Override
- public net.minecraft.item.crafting.Ingredient parse( JsonContext context, JsonObject json )
+ public PartIngredient parse( JsonObject json )
{
final String partName = json.get( "part" ).getAsString();
+ return getPart( partName );
+ }
+
+ @Nonnull
+ @Override
+ public PartIngredient parse( PacketBuffer buffer )
+ {
+ return getPart( buffer.readString() );
+ }
+
+ @Override
+ public void write( @Nonnull PacketBuffer buffer, @Nonnull PartIngredient ingredient )
+ {
+ buffer.writeString( ingredient.getPartName() );
+ }
+
+ private PartIngredient getPart( String partName )
+ {
final Object result = Api.INSTANCE.registries().recipes().resolveItem( AppEng.MOD_ID, partName );
if( result instanceof ResolverResultSet )
{
final ResolverResultSet resolverResultSet = (ResolverResultSet) result;
- return net.minecraft.item.crafting.Ingredient
- .fromStacks( resolverResultSet.results.toArray( new ItemStack[resolverResultSet.results.size()] ) );
+ return PartIngredient
+ .fromStacks( partName, resolverResultSet.results.toArray( new ItemStack[0] ) );
}
else if( result instanceof ResolverResult )
{
final ResolverResult resolverResult = (ResolverResult) result;
- final Item item = Item.getByNameOrId( AppEng.MOD_ID + ":" + resolverResult.itemName );
- final ItemStack itemStack = new ItemStack( item, 1, resolverResult.damageValue, resolverResult.compound );
+ final Item item = ForgeRegistries.ITEMS.getValue( new ResourceLocation( AppEng.MOD_ID, resolverResult.itemName ) );
+ final ItemStack itemStack = new ItemStack( item, 1, resolverResult.compound );
- return net.minecraft.item.crafting.Ingredient.fromStacks( itemStack );
+ itemStack.setDamage( resolverResult.damageValue );
+
+ return PartIngredient.fromStacks( partName, itemStack );
}
AELog.warn( "Looking for ingredient with name '" + partName + "' ended up with a null item!" );
- return net.minecraft.item.crafting.Ingredient.EMPTY;
+ return PartIngredient.empty( partName );
}
+
}
\ No newline at end of file
diff --git a/src/main/java/appeng/recipes/ores/IOreListener.java b/src/main/java/appeng/recipes/ores/IOreListener.java
deleted file mode 100644
index 404883719..000000000
--- a/src/main/java/appeng/recipes/ores/IOreListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes.ores;
-
-
-import net.minecraft.item.ItemStack;
-
-
-public interface IOreListener
-{
-
- /**
- * Called with various items registered in the dictionary.
- * AppEng.oreDictionary.observe(...) to register them.
- *
- * @param name name of ore
- * @param item item with name
- */
- void oreRegistered( String name, ItemStack item );
-}
diff --git a/src/main/java/appeng/recipes/ores/OreDictionaryHandler.java b/src/main/java/appeng/recipes/ores/OreDictionaryHandler.java
deleted file mode 100644
index a294df76d..000000000
--- a/src/main/java/appeng/recipes/ores/OreDictionaryHandler.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This file is part of Applied Energistics 2.
- * Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
- *
- * Applied Energistics 2 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Applied Energistics 2 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Applied Energistics 2. If not, see .
- */
-
-package appeng.recipes.ores;
-
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.minecraft.item.ItemStack;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.oredict.OreDictionary;
-
-
-public class OreDictionaryHandler
-{
-
- public static final OreDictionaryHandler INSTANCE = new OreDictionaryHandler();
-
- private final List oreListeners = new ArrayList<>();
-
- @SubscribeEvent
- public void onOreDictionaryRegister( final OreDictionary.OreRegisterEvent event )
- {
- if( event.getName() == null || event.getOre().isEmpty() )
- {
- return;
- }
-
- if( this.shouldCare( event.getName() ) )
- {
- for( final IOreListener v : this.oreListeners )
- {
- v.oreRegistered( event.getName(), event.getOre() );
- }
- }
- }
-
- /**
- * Just limit what items are sent to the final listeners, I got sick of strange items showing up...
- *
- * @param name name about cared item
- *
- * @return true if it should care
- */
- private boolean shouldCare( final String name )
- {
- return true;
- }
-
- /**
- * Adds a new IOreListener and immediately notifies it of any previous ores, any ores added latter will be added at
- * that point.
- *
- * @param n to be added ore listener
- */
- public void observe( final IOreListener n )
- {
- this.oreListeners.add( n );
-
- // notify the listener of any ore already in existence.
- for( final String name : OreDictionary.getOreNames() )
- {
- if( name != null && this.shouldCare( name ) )
- {
- for( final ItemStack item : OreDictionary.getOres( name ) )
- {
- if( !item.isEmpty() )
- {
- n.oreRegistered( name, item );
- }
- }
- }
- }
- }
-}
diff --git a/src/main/java/appeng/server/subcommands/ChunkLogger.java b/src/main/java/appeng/server/subcommands/ChunkLogger.java
index d3f4489de..33730fa6f 100644
--- a/src/main/java/appeng/server/subcommands/ChunkLogger.java
+++ b/src/main/java/appeng/server/subcommands/ChunkLogger.java
@@ -28,7 +28,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import appeng.core.AEConfig;
import appeng.core.AELog;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.server.ISubCommand;
diff --git a/src/main/java/appeng/util/Platform.java b/src/main/java/appeng/util/Platform.java
index 91fa01e52..904e67865 100644
--- a/src/main/java/appeng/util/Platform.java
+++ b/src/main/java/appeng/util/Platform.java
@@ -22,30 +22,19 @@ package appeng.util;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
-import appeng.api.config.SecurityPermissions;
import appeng.api.definitions.IItemDefinition;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.api.implementations.items.IAEWrench;
-import appeng.api.networking.IGrid;
-import appeng.api.networking.IGridNode;
-import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
-import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.IActionSource;
-import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventory;
-import appeng.api.storage.IMEMonitorHandlerReceiver;
-import appeng.api.storage.IStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
-import appeng.api.storage.data.IItemList;
import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord;
-import appeng.core.AEConfig;
-import appeng.core.AELog;
import appeng.core.Api;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.stats.AeStats;
import appeng.fluids.util.AEFluidStack;
import appeng.util.helpers.ItemComparisonHelper;
@@ -76,15 +65,11 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.thread.SidedThreadGroups;
import net.minecraftforge.fml.loading.FMLEnvironment;
-import java.security.InvalidParameterException;
import java.util.*;
import com.google.common.base.Preconditions;
import net.minecraftforge.registries.ForgeRegistries;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
/**
* @author AlgorithmX2
diff --git a/src/main/java/appeng/worldgen/MeteoritePlacer.java b/src/main/java/appeng/worldgen/MeteoritePlacer.java
index 50b1dcc46..71ea36233 100644
--- a/src/main/java/appeng/worldgen/MeteoritePlacer.java
+++ b/src/main/java/appeng/worldgen/MeteoritePlacer.java
@@ -36,12 +36,11 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
-import appeng.api.AEApi;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.definitions.IBlocks;
import appeng.api.definitions.IMaterials;
import appeng.core.AEConfig;
-import appeng.core.features.AEFeature;
+import appeng.api.features.AEFeature;
import appeng.core.worlddata.WorldData;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;