Skip to content

Commit 877ea9f

Browse files
authored
Tinker's Construct manuals, Dreamcraft edition (#797)
* Loading TiCo manuals in postinitialization to fix the font not being registered. * Decouple ShapedUniversalRecipe from boot loader * Added Recipe interface to represent any set of recipe arguments for use with recipe registries. * Added recipe resolving and flattening to Recipe * Added MantleManualRecipeRegistry * Added TiCo manuals to lang files unmodified * Added GT items required for seared bricks to Materials and You: Volume 1 * Updated oreberry description in Materials and You: Volume 1 * Removed unused content from manuals * Adjusted TiCo manual recipes * Adjusted TiCo manual text * Updated cast description * Replace Paper Stack recipe in TiCo manuals * Redirected certain TiCo manual recipes to the Thauminomicon * Updated Materials and You: Volume 2 intro * Override Stencil Table recipe definition to not have lava fences * Ingredients flattener doesn't need to be public at this time * Reusing a safe missing item constant * Lock down member visibility in the recipes package * Documented usage of package private classes * Made GameRegistryProxy partially public
1 parent eca05a2 commit 877ea9f

29 files changed

+2599
-2192
lines changed

src/main/java/com/dreammaster/gthandler/GT_CraftingRecipeLoader.java

+42-9
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,37 @@
11
package com.dreammaster.gthandler;
22

3-
import static gregtech.api.enums.Mods.*;
3+
import static gregtech.api.enums.Mods.AdventureBackpack;
4+
import static gregtech.api.enums.Mods.BartWorks;
5+
import static gregtech.api.enums.Mods.BuildCraftFactory;
6+
import static gregtech.api.enums.Mods.Chisel;
7+
import static gregtech.api.enums.Mods.Computronics;
8+
import static gregtech.api.enums.Mods.ExtraUtilities;
9+
import static gregtech.api.enums.Mods.Forestry;
10+
import static gregtech.api.enums.Mods.GalacticraftCore;
11+
import static gregtech.api.enums.Mods.GalacticraftMars;
12+
import static gregtech.api.enums.Mods.GalaxySpace;
13+
import static gregtech.api.enums.Mods.GoodGenerator;
14+
import static gregtech.api.enums.Mods.IguanaTweaksTinkerConstruct;
15+
import static gregtech.api.enums.Mods.IndustrialCraft2;
16+
import static gregtech.api.enums.Mods.NewHorizonsCoreMod;
17+
import static gregtech.api.enums.Mods.OpenComputers;
18+
import static gregtech.api.enums.Mods.OpenPrinters;
19+
import static gregtech.api.enums.Mods.ProjectRedIllumination;
20+
import static gregtech.api.enums.Mods.Railcraft;
21+
import static gregtech.api.enums.Mods.TinkerConstruct;
22+
import static gregtech.api.enums.Mods.ZTones;
423
import static gregtech.api.enums.OrePrefixes.screw;
524
import static gregtech.api.util.GT_ModHandler.RecipeBits.DELETE_ALL_OTHER_RECIPES;
625

26+
import java.util.function.Consumer;
27+
728
import net.minecraft.init.Blocks;
829
import net.minecraft.init.Items;
930
import net.minecraft.item.ItemStack;
1031

1132
import com.dreammaster.main.NHItems;
33+
import com.dreammaster.mantle.MantleManualRecipeRegistry;
34+
import com.dreammaster.recipes.Recipe;
1235
import com.github.bartimaeusnek.bartworks.common.loaders.ItemRegistry;
1336
import com.github.bartimaeusnek.bartworks.system.material.WerkstoffLoader;
1437

@@ -29,6 +52,7 @@
2952

3053
public class GT_CraftingRecipeLoader extends gregtech.loaders.postload.GT_CraftingRecipeLoader implements Runnable {
3154

55+
private static final MantleManualRecipeRegistry MANTLE = MantleManualRecipeRegistry.getInstance();
3256
private static final String aTextMachineBeta = "machine.beta";
3357
private static final String aTextMachineAlpha = "machine.alpha";
3458
private static final String aTextIron1 = "X X";
@@ -746,22 +770,24 @@ public void run() {
746770
new Object[] { new ItemStack(Items.clay_ball, 1, 0),
747771
new ItemStack(NHItems.WOODEN_BRICK_FORM.get(), 1, GT_Values.W) });
748772
if (TinkerConstruct.isModLoaded()) {
749-
GT_ModHandler.addShapelessCraftingRecipe(
773+
Recipe.of(
750774
new ItemStack(NHItems.WOODEN_BRICK_FORM.get(), 1, GT_Values.W),
751-
GT_ModHandler.RecipeBits.NOT_REMOVABLE,
752-
new Object[] { ToolDictNames.craftingToolKnife,
753-
GT_ModHandler.getModItem(aTextTConstruct, "blankPattern", 1L, 0) });
775+
ToolDictNames.craftingToolKnife,
776+
GT_ModHandler.getModItem(aTextTConstruct, "blankPattern", 1L, 0))
777+
.provideTo(shapelessUnremovableGtRecipes())
778+
.provideTo(MANTLE.manualShapedCraftingRecipeNamed("woodenformbrick"));
754779
GT_ModHandler.addCraftingRecipe(
755780
CustomItemList.UnfiredSearedBrick.get(8L),
756781
GT_ModHandler.RecipeBits.NOT_REMOVABLE,
757782
new Object[] { "GGG", "GFG", "GGG", 'G',
758783
GT_ModHandler.getModItem(aTextTConstruct, "CraftedSoil", 1L, 1), 'F',
759784
new ItemStack(NHItems.WOODEN_BRICK_FORM.get(), 1, GT_Values.W) });
760-
GT_ModHandler.addShapelessCraftingRecipe(
785+
Recipe.of(
761786
CustomItemList.UnfiredSearedBrick.get(1L),
762-
GT_ModHandler.RecipeBits.NOT_REMOVABLE,
763-
new Object[] { GT_ModHandler.getModItem(aTextTConstruct, "CraftedSoil", 1L, 1),
764-
new ItemStack(NHItems.WOODEN_BRICK_FORM.get(), 1, GT_Values.W) });
787+
GT_ModHandler.getModItem(aTextTConstruct, "CraftedSoil", 1L, 1),
788+
new ItemStack(NHItems.WOODEN_BRICK_FORM.get(), 1, GT_Values.W))
789+
.provideTo(shapelessUnremovableGtRecipes())
790+
.provideTo(MANTLE.manualShapedCraftingRecipeNamed("unfiredsearedbrick"));
765791
GT_ModHandler.addCraftingRecipe(
766792
CustomItemList.UnfiredSlimeSoulBrick.get(8L),
767793
GT_ModHandler.RecipeBits.NOT_REMOVABLE,
@@ -1822,4 +1848,11 @@ public void run() {
18221848
new Object[] { " C", "W ", " ", 'W', ToolDictNames.craftingToolKnife, 'C', aBlankClayCast });
18231849
}
18241850
}
1851+
1852+
private Consumer<Recipe> shapelessUnremovableGtRecipes() {
1853+
return craft -> GT_ModHandler.addShapelessCraftingRecipe(
1854+
craft.getResult(),
1855+
GT_ModHandler.RecipeBits.NOT_REMOVABLE,
1856+
craft.getIngredients());
1857+
}
18251858
}

src/main/java/com/dreammaster/main/MainRegistry.java

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import com.dreammaster.recipes.RecipeRemover;
7373
import com.dreammaster.scripts.ScriptLoader;
7474
import com.dreammaster.thaumcraft.TCLoader;
75+
import com.dreammaster.tinkersConstruct.TiCoLoader;
7576
import com.dreammaster.witchery.WitcheryPlugin;
7677
import com.github.bartimaeusnek.bartworks.system.material.WerkstoffLoader;
7778

@@ -485,6 +486,8 @@ public void PostLoad(FMLPostInitializationEvent PostEvent) {
485486
}
486487

487488
if (Thaumcraft.isModLoaded()) TCLoader.run();
489+
490+
if (TinkerConstruct.isModLoaded()) TiCoLoader.doPostInitialization();
488491
}
489492

490493
@Mod.EventHandler

src/main/java/com/dreammaster/mantle/BookDataReader.java

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
/**
1515
* This class doesn't support loading different XML documents based on Minecraft's currently configured language. Books
1616
* are instead intended to be translated through lang files.
17+
* <p>
18+
* This is an implementation class. Use it through BookLoader::of
1719
*/
1820
class BookDataReader {
1921

src/main/java/com/dreammaster/mantle/BookDataStoreProxy.java

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
/**
1212
* This class helps us avoid issues with books already loaded by another mod.
13+
* <p>
14+
* Implementation class. Use it through BookLoader::of
1315
*/
1416
class BookDataStoreProxy {
1517

src/main/java/com/dreammaster/mantle/MantleBookLoader.java

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import gregtech.api.interfaces.internal.IGT_Mod;
1414
import mantle.books.BookData;
1515

16+
/**
17+
* Implementation class. Use it through BookLoader::of
18+
*/
1619
final class MantleBookLoader implements BookLoader {
1720

1821
private static final BookDataReader BOOK_DATA_READER = new BookDataReader();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.dreammaster.mantle;
2+
3+
import java.util.Arrays;
4+
import java.util.Objects;
5+
import java.util.function.Consumer;
6+
import java.util.function.UnaryOperator;
7+
8+
import javax.annotation.Nonnull;
9+
10+
import net.minecraft.item.ItemStack;
11+
12+
import com.dreammaster.recipes.Recipe;
13+
import com.dreammaster.recipes.ShapedIngredientsResolver;
14+
import com.dreammaster.recipes.ShapelessIngredientsResolver;
15+
16+
import mantle.lib.client.MantleClientRegistry;
17+
18+
/**
19+
* Implementation class. Access it through MantleManualRecipeRegistry::getInstance
20+
*/
21+
class MantleClientRegistryProxy implements MantleManualRecipeRegistry {
22+
23+
private static final UnaryOperator<Object[]> SHAPED_INGREDIENTS_RESOLVER = new ShapedIngredientsResolver();
24+
private static final UnaryOperator<Object[]> SHAPELESS_INGREDIENTS_RESOLVER = new ShapelessIngredientsResolver();
25+
26+
@Override
27+
@Nonnull
28+
public Consumer<Recipe> manualShapedCraftingRecipeNamed(String manualRecipeName) {
29+
Objects.requireNonNull(manualRecipeName);
30+
return (recipe) -> setTicoManualRecipe(
31+
manualRecipeName,
32+
recipe.getResult(),
33+
recipe.flattenWith(SHAPED_INGREDIENTS_RESOLVER));
34+
}
35+
36+
@Nonnull
37+
@Override
38+
public Consumer<Recipe> manualShapelessCraftingRecipeNamed(String manualRecipeName) {
39+
Objects.requireNonNull(manualRecipeName);
40+
return (recipe) -> setTicoManualRecipe(
41+
manualRecipeName,
42+
recipe.getResult(),
43+
recipe.flattenWith(SHAPELESS_INGREDIENTS_RESOLVER));
44+
}
45+
46+
private void setTicoManualRecipe(String name, ItemStack result, ItemStack[] recipe) {
47+
if (recipe.length <= 4) {
48+
MantleClientRegistry.registerManualSmallRecipe(name, result, Arrays.copyOf(recipe, 4));
49+
} else if (recipe.length <= 9) {
50+
MantleClientRegistry.registerManualLargeRecipe(name, result, Arrays.copyOf(recipe, 9));
51+
} else {
52+
throw new IllegalArgumentException("Recipe has too many ingredients: " + Arrays.toString(recipe));
53+
}
54+
}
55+
56+
@Override
57+
@Nonnull
58+
public Consumer<Recipe> manualSmeltingRecipeNamed(String manualRecipeName) {
59+
Objects.requireNonNull(manualRecipeName);
60+
return (recipe) -> MantleClientRegistry
61+
.registerManualFurnaceRecipe(manualRecipeName, recipe.getResult(), recipe.flatten()[0]);
62+
}
63+
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.dreammaster.mantle;
2+
3+
import java.util.function.Consumer;
4+
5+
import javax.annotation.Nonnull;
6+
7+
import com.dreammaster.recipes.Recipe;
8+
9+
public interface MantleManualRecipeRegistry {
10+
11+
@Nonnull
12+
static MantleManualRecipeRegistry getInstance() {
13+
return new MantleClientRegistryProxy();
14+
}
15+
16+
@Nonnull
17+
Consumer<Recipe> manualShapedCraftingRecipeNamed(String manualRecipeName);
18+
19+
@Nonnull
20+
Consumer<Recipe> manualShapelessCraftingRecipeNamed(String manualRecipeName);
21+
22+
@Nonnull
23+
Consumer<Recipe> manualSmeltingRecipeNamed(String manualRecipeName);
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.dreammaster.recipes;
2+
3+
import net.minecraft.item.ItemStack;
4+
5+
interface IngredientsFlattener {
6+
7+
ItemStack[] flatten(Object[] ingredients);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.dreammaster.recipes;
2+
3+
import java.util.function.Consumer;
4+
import java.util.function.UnaryOperator;
5+
6+
import javax.annotation.Nonnull;
7+
8+
import net.minecraft.item.ItemStack;
9+
10+
public interface Recipe {
11+
12+
@Nonnull
13+
static Recipe of(@Nonnull ItemStack result, @Nonnull Object... ingredients) {
14+
return new RecipeArgs(result, ingredients);
15+
}
16+
17+
@Nonnull
18+
ItemStack getResult();
19+
20+
@Nonnull
21+
Object[] getIngredients();
22+
23+
@Nonnull
24+
Recipe provideTo(@Nonnull Consumer<Recipe> recipeUser);
25+
26+
@Nonnull
27+
ItemStack[] flatten();
28+
29+
@Nonnull
30+
ItemStack[] flattenWith(UnaryOperator<Object[]> ingredientsResolver);
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.dreammaster.recipes;
2+
3+
import java.util.Arrays;
4+
import java.util.Objects;
5+
import java.util.function.Consumer;
6+
import java.util.function.UnaryOperator;
7+
8+
import javax.annotation.Nonnull;
9+
10+
import net.minecraft.item.ItemStack;
11+
12+
/**
13+
* Implementation class. Access it through Recipe::of
14+
*/
15+
class RecipeArgs implements Recipe {
16+
17+
// Hardcoded dependency for now
18+
private final UnaryOperator<Object[]> defaultIngredientsResolver = new ShapedIngredientsResolver();
19+
// Hardcoded dependency for now
20+
private final IngredientsFlattener ingredientsFlattener = new ResolvedIngredientsFlattener();
21+
22+
protected final ItemStack result;
23+
protected final Object[] ingredients;
24+
private Object[] resolvedIngredients;
25+
26+
RecipeArgs(ItemStack result, Object... ingredients) {
27+
if (Objects.isNull(result)) throw new NullPointerException("Craft created with null result!");
28+
if (Objects.isNull(ingredients)) throw new NullPointerException("Craft created with null ingredients!");
29+
if (ingredients.length == 0) throw new IllegalArgumentException("Craft created with no ingredients!");
30+
this.result = result.copy();
31+
this.ingredients = Arrays.copyOf(ingredients, ingredients.length);
32+
}
33+
34+
/**
35+
* Flattens the recipe to only have up to one ItemStack per slot.
36+
*
37+
* @return A non-empty array of ItemStack or null values.
38+
*/
39+
@Nonnull
40+
@Override
41+
public ItemStack[] flatten() {
42+
return ingredientsFlattener.flatten(getResolvedIngredients());
43+
}
44+
45+
/**
46+
* Flattens the recipe to only have up to one ItemStack per slot.
47+
*
48+
* @param ingredientsResolver Transforms the ingredients to only contain null, ItemStack or List&lt;ItemStack&gt;
49+
* @return A non-empty array of ItemStack or null values.
50+
*/
51+
@Nonnull
52+
@Override
53+
public ItemStack[] flattenWith(@Nonnull UnaryOperator<Object[]> ingredientsResolver) {
54+
return ingredientsFlattener.flatten(ingredientsResolver.apply(ingredients));
55+
}
56+
57+
private Object[] getResolvedIngredients() {
58+
if (resolvedIngredients == null) {
59+
resolvedIngredients = defaultIngredientsResolver.apply(ingredients);
60+
}
61+
return resolvedIngredients;
62+
}
63+
64+
@Nonnull
65+
@Override
66+
public ItemStack getResult() {
67+
return result;
68+
}
69+
70+
@Nonnull
71+
@Override
72+
public Object[] getIngredients() {
73+
return ingredients;
74+
}
75+
76+
@Override
77+
public @Nonnull Recipe provideTo(@Nonnull Consumer<Recipe> recipeUser) {
78+
recipeUser.accept(this);
79+
return this;
80+
}
81+
82+
@Override
83+
public String toString() {
84+
return "Recipe{result=" + result + ", ingredients=" + Arrays.toString(ingredients) + '}';
85+
}
86+
87+
@Override
88+
public boolean equals(Object o) {
89+
if (this == o) return true;
90+
if (o == null || getClass() != o.getClass()) return false;
91+
RecipeArgs that = (RecipeArgs) o;
92+
return result.isItemEqual(that.result) && Arrays.equals(ingredients, that.ingredients);
93+
}
94+
95+
@Override
96+
public int hashCode() {
97+
int result1 = Objects.hash(result);
98+
result1 = 31 * result1 + Arrays.hashCode(ingredients);
99+
return result1;
100+
}
101+
}

0 commit comments

Comments
 (0)