1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
package lv.enes.mc.eris_alchemy;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.Level;
import org.quiltmc.qsl.recipe.api.serializer.QuiltRecipeSerializer;
import java.util.ArrayList;
import java.util.Arrays;
public class CovalenceRepair extends CustomRecipe {
static class Serializer implements QuiltRecipeSerializer<CovalenceRepair> {
private static class Json {
CraftingBookCategory category = CraftingBookCategory.MISC;
JsonElement dust;
JsonElement materials = new JsonObject();
JsonElement tools = new JsonObject();
}
private Serializer() {}
public static final Serializer INSTANCE = new Serializer();
public static final ResourceLocation ID = new ResourceLocation(ErisAlchemy.ID, "covalence_repair");
@Override
public JsonObject toJson(CovalenceRepair recipe) {
var res = new JsonObject();
res.addProperty("category", recipe.category().toString());
res.add("dust", recipe.dust.toJson());
res.add("materials", recipe.materials.toJson());
res.add("tools", recipe.tools.toJson());
return res;
}
@Override
public CovalenceRepair fromJson(ResourceLocation id, JsonObject json) {
var recipeJson = new Gson().fromJson(json, Json.class);
if (recipeJson.dust == null) {
throw new JsonSyntaxException("A required attribute is missing");
}
var dust = Ingredient.fromJson(recipeJson.dust);
var materials = Ingredient.fromJson(recipeJson.materials);
var tools = Ingredient.fromJson(recipeJson.tools);
return new CovalenceRepair(id, recipeJson.category, dust, materials, tools);
}
@Override
public void toNetwork(FriendlyByteBuf buf, CovalenceRepair recipe) {
buf.writeEnum(recipe.category());
recipe.dust.toNetwork(buf);
recipe.materials.toNetwork(buf);
recipe.tools.toNetwork(buf);
}
@Override
public CovalenceRepair fromNetwork(ResourceLocation id, FriendlyByteBuf buf) {
var category = buf.readEnum(CraftingBookCategory.class);
var dust = Ingredient.fromNetwork(buf);
var materials = Ingredient.fromNetwork(buf);
var tools = Ingredient.fromNetwork(buf);
return new CovalenceRepair(id, category, dust, materials, tools);
}
}
private record Inputs(ItemStack toolStack, int dustCount) {}
private final static int DUSTS_TO_FIX = 8;
/** What dust do we use to repair. */
private final Ingredient dust;
/** What materials this dust can repair. */
private final Ingredient materials;
/** What tools can this dust repair. */
private final Ingredient tools;
public CovalenceRepair(ResourceLocation id, CraftingBookCategory category, Ingredient dust, Ingredient materials, Ingredient tools) {
super(id, category);
this.dust = dust;
this.materials = materials;
this.tools = tools;
}
@Override
public boolean canCraftInDimensions(int width, int height) {
return width * height > 2;
}
@Override
public boolean matches(CraftingContainer inventory, Level world) {
return getInputs(inventory) != null;
}
@Override
public ItemStack assemble(CraftingContainer inventory, RegistryAccess registryManager) {
var inputs = getInputs(inventory);
if (inputs == null) {
return ItemStack.EMPTY;
}
var newToolStack = inputs.toolStack.copy();
var repairedAmount = inputs.toolStack.getItem().getMaxDamage() * inputs.dustCount / DUSTS_TO_FIX;
newToolStack.setDamageValue(inputs.toolStack.getDamageValue() - repairedAmount);
return newToolStack;
}
@Override
public RecipeSerializer<?> getSerializer() {
return Serializer.INSTANCE;
}
private boolean isTool(ItemStack stack) {
if (!stack.isDamageableItem() || !stack.isDamaged() || stack.getCount() != 1) {
return false;
}
if (tools.test(stack)) {
return true;
}
var item = stack.getItem();
return Arrays.stream(materials.getItems()).anyMatch(material -> item.isValidRepairItem(stack, material));
}
private boolean isDust(ItemStack stack) {
return dust.test(stack);
}
/** @return null if recipe isn't correct. */
private Inputs getInputs(CraftingContainer inventory) {
ItemStack toolStack = null;
var dustStacks = new ArrayList<ItemStack>();
for (var i = 0; i < inventory.getContainerSize(); i++) {
var stack = inventory.getItem(i);
if (stack.isEmpty()) {
continue;
}
if (isDust(stack) && (dustStacks.isEmpty() || ItemStack.isSameItemSameTags(dustStacks.get(0), stack))) {
dustStacks.add(stack);
} else if (toolStack == null) {
toolStack = stack;
} else {
return null;
}
}
if (toolStack == null || dustStacks.isEmpty() || !isTool(toolStack)) {
return null;
}
return new Inputs(toolStack, dustStacks.size());
}
}
|