Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
package dev.u9g.minecraftdatagenerator.generators;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import dev.u9g.minecraftdatagenerator.mixin.ShapedRecipeTypeAccessor;
import dev.u9g.minecraftdatagenerator.mixin.ShapelessRecipeTypeAccessor;
import dev.u9g.minecraftdatagenerator.util.Registries;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.itemgroup.ItemGroup;
import net.minecraft.recipe.RecipeDispatcher;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.ShapedRecipeType;
import net.minecraft.recipe.ShapelessRecipeType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class RecipeDataGenerator implements IDataGenerator {
private static final int WILDCARD_DAMAGE = 32767;

@Override
public String getDataName() {
Expand All @@ -12,113 +33,86 @@ public String getDataName() {

@Override
public JsonElement generateDataJson() {
// JsonObject finalObj = new JsonObject();
// Multimap<Integer, JsonObject> recipes = ArrayListMultimap.create();
// for (Recipe<?> recipe : Objects.requireNonNull(DGU.getWorld()).getRecipeManager().values()) {
// if (recipe instanceof ShapedRecipe sr) {
// var ingredients = sr.getIngredients();
// List<Integer> ingr = new ArrayList<>();
// for (int i = 0; i < 9; i++) {
// if (i >= ingredients.size()) {
// ingr.add(-1);
// continue;
// }
// var stacks = ingredients.get(i);
//// var matching = stacks.getMatchingStacks();
//// if (matching.length == 0) {
//// ingr.add(-1);
//// } else {
//// ingr.add(getRawIdFor(matching[0].getItem()));
//// }
// }
// Lists.reverse(ingr);
//
// JsonArray inShape = new JsonArray();
//
// var iter = ingr.iterator();
// for (int y = 0; y < 3; y++) {
// var jsonRow = new JsonArray();
// int one = iter.next();
// int two = iter.next();
// int three = iter.next();
// if (y > 0 && one == -1 && two == -1 && three == -1) continue;
// jsonRow.add(one);
// jsonRow.add(two);
// jsonRow.add(three);
// inShape.add(jsonRow);
// }
//
// JsonObject finalRecipe = new JsonObject();
// finalRecipe.add("inShape", inShape);
//
// var resultObject = new JsonObject();
// resultObject.addProperty("id", getRawIdFor(sr.getOutput().getItem()));
// resultObject.addProperty("count", sr.getOutput().getCount());
// finalRecipe.add("result", resultObject);
//
// String id = ((Integer) getRawIdFor(sr.getOutput().getItem())).toString();
//
// if (!finalObj.has(id)) {
// finalObj.add(id, new JsonArray());
// }
// finalObj.get(id).getAsJsonArray().add(finalRecipe);
//// var input = new JsonArray();
//// var ingredients = sr.getIngredients().stream().toList();
//// for (int y = 0; y < sr.getHeight(); y++) {
//// var arr = new JsonArray();
//// for (int x = 0; x < sr.getWidth(); x++) {
//// if ((y*3)+x >= ingredients.size()) {
//// arr.add(JsonNull.INSTANCE);
//// continue;
//// }
//// var ingredient = ingredients.get((y*3)+x).getMatchingStacks(); // FIXME: fix when there are more than one matching stack
//// if (ingredient.length == 0) {
//// arr.add(JsonNull.INSTANCE);
//// } else {
//// arr.add(getRawIdFor(ingredient[0].getItem()));
//// }
//// }
//// input.add(arr);
//// }
//// var rootRecipeObject = new JsonObject();
//// rootRecipeObject.add("inShape", input);
//// var resultObject = new JsonObject();
//// resultObject.addProperty("id", getRawIdFor(sr.getOutput().getItem()));
//// resultObject.addProperty("count", sr.getOutput().getCount());
//// rootRecipeObject.add("result", resultObject);
//// recipes.put(getRawIdFor(sr.getOutput().getItem()), rootRecipeObject);
// } else if (recipe instanceof ShapelessRecipe sl) {
Map<Integer, JsonArray> recipesByResult = new TreeMap<>();
for (RecipeType recipe : RecipeDispatcher.getInstance().getAllRecipes()) {
ItemStack output = recipe.getOutput();
if (isEmpty(output)) continue;
JsonObject json;
// Subclasses (map extending) compute their real output at craft time.
if (recipe.getClass() == ShapedRecipeType.class) {
json = generateShaped((ShapedRecipeType) recipe);
} else if (recipe.getClass() == ShapelessRecipeType.class) {
json = generateShapeless((ShapelessRecipeType) recipe);
} else {
continue;
}
int resultId = Registries.ITEMS.getRawId(output.getItem());
recipesByResult.computeIfAbsent(resultId, k -> new JsonArray()).add(json);
}
JsonObject result = new JsonObject();
recipesByResult.forEach((id, recipes) -> result.add(id.toString(), recipes));
return result;
}

// var ingredients = new JsonArray();
// for (Ingredient ingredient : sl.getIngredients()) {
// if (ingredient.isEmpty()) continue;
//// ingredients.add(getRawIdFor(ingredient.getMatchingStacks()[0].getItem()));
// }
// var rootRecipeObject = new JsonObject();
// rootRecipeObject.add("ingredients", ingredients);
// var resultObject = new JsonObject();
// resultObject.addProperty("id", getRawIdFor(sl.getOutput().getItem()));
// resultObject.addProperty("count", sl.getOutput().getCount());
// rootRecipeObject.add("result", resultObject);
// recipes.put(getRawIdFor(sl.getOutput().getItem()), rootRecipeObject);
// }
// }
// recipes.forEach((a, b) -> {
// if (!finalObj.has(a.toString())) {
// finalObj.add(a.toString(), new JsonArray());
// }
// finalObj.get(a.toString()).getAsJsonArray().add(b);
// });
// return finalObj;
return JsonNull.INSTANCE;
private static JsonObject generateShaped(ShapedRecipeType recipe) {
ShapedRecipeTypeAccessor accessor = (ShapedRecipeTypeAccessor) recipe;
int width = accessor.getWidth();
int height = accessor.getHeight();
ItemStack[] ingredients = accessor.getIngredients();
JsonArray inShape = new JsonArray();
for (int y = 0; y < height; y++) {
JsonArray row = new JsonArray();
for (int x = 0; x < width; x++) row.add(cellFor(ingredients[y * width + x]));
inShape.add(row);
}
JsonObject json = new JsonObject();
json.add("inShape", inShape);
json.add("result", resultFor(recipe.getOutput()));
return json;
}

@Override
public boolean isEnabled() {
return false; // TODO: Implement this
private static JsonObject generateShapeless(ShapelessRecipeType recipe) {
JsonArray ingredients = new JsonArray();
for (ItemStack stack : ((ShapelessRecipeTypeAccessor) recipe).getStacks()) {
if (!isEmpty(stack)) ingredients.add(cellFor(stack));
}
JsonObject json = new JsonObject();
json.add("ingredients", ingredients);
json.add("result", resultFor(recipe.getOutput()));
return json;
}

private static JsonObject resultFor(ItemStack output) {
JsonObject result = new JsonObject();
result.addProperty("id", Registries.ITEMS.getRawId(output.getItem()));
result.addProperty("metadata", output.getDamage());
result.addProperty("count", output.count);
return result;
}

// A bare id means any metadata of that item: the vanilla wildcard damage, or an item
// that only exists with one metadata value.
private static JsonElement cellFor(ItemStack stack) {
if (isEmpty(stack)) return JsonNull.INSTANCE;
int id = Registries.ITEMS.getRawId(stack.getItem());
if (stack.getDamage() == WILDCARD_DAMAGE || variantsOf(stack.getItem()).size() <= 1 && stack.getDamage() == 0) {
return new JsonPrimitive(id);
}
JsonObject cell = new JsonObject();
cell.addProperty("id", id);
cell.addProperty("metadata", stack.getDamage());
return cell;
}

private static Set<Integer> variantsOf(Item item) {
List<ItemStack> stacks = new ArrayList<>();
item.appendItemStacks(item, ItemGroup.SEARCH, stacks);
Set<Integer> variants = new HashSet<>();
for (ItemStack stack : stacks) variants.add(stack.getDamage());
return variants;
}

private static boolean isEmpty(ItemStack stack) {
return stack == null;
}
//
// private static int getRawIdFor (Item item) {
// return Registry.ITEM.getRawId(item);
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.u9g.minecraftdatagenerator.mixin;

import net.minecraft.item.ItemStack;
import net.minecraft.recipe.ShapedRecipeType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(ShapedRecipeType.class)
public interface ShapedRecipeTypeAccessor {
@Accessor("width")
int getWidth();

@Accessor("height")
int getHeight();

@Accessor("ingredients")
ItemStack[] getIngredients();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.u9g.minecraftdatagenerator.mixin;

import net.minecraft.item.ItemStack;
import net.minecraft.recipe.ShapelessRecipeType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

import java.util.List;

@Mixin(ShapelessRecipeType.class)
public interface ShapelessRecipeTypeAccessor {
@Accessor("stacks")
List<ItemStack> getStacks();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"MiningToolItemAccessor",
"NoteBlockAccessor",
"ReadyMixin",
"ShapedRecipeTypeAccessor",
"ShapelessRecipeTypeAccessor",
"StatusEffectAccessor"
],
"injectors": {
Expand Down
Loading
Loading