Handle recipe duplicates

This commit is contained in:
LLytho 2022-07-13 21:11:46 +02:00
parent 004b84290a
commit b9a4e8f26e
3 changed files with 141 additions and 23 deletions

View file

@ -0,0 +1,31 @@
package com.almostreliable.unified.recipe;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class DuplicateLink {
private RawRecipe currentMaster;
private final Set<RawRecipe> recipes = new HashSet<>();
public DuplicateLink(RawRecipe master) {
updateMaster(master);
}
void updateMaster(RawRecipe master) {
4 = {DuplicateLink@28142} Objects.requireNonNull(master);
addDuplicate(master);
this.currentMaster = master;
}
void addDuplicate(RawRecipe recipe) {
if(recipe == null) {
String s = "";
}
recipes.add(recipe);
}
public RawRecipe getMaster() {
return currentMaster;
}
}

View file

@ -1,16 +1,20 @@
package com.almostreliable.unified.recipe;
import com.almostreliable.unified.AlmostUnified;
import com.almostreliable.unified.utils.JsonCompare;
import com.google.gson.JsonObject;
import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
public class RawRecipe {
private final ResourceLocation id;
private final ResourceLocation type;
private final JsonObject originalRecipe;
private boolean isDuplicate = false;
@Nullable private DuplicateLink duplicateLink;
@Nullable private JsonObject transformedRecipe;
@ -37,17 +41,24 @@ public class RawRecipe {
return originalRecipe;
}
public void markAsDuplicate() {
isDuplicate = true;
void linkDuplicate(RawRecipe recipe) {
Objects.requireNonNull(recipe);
if(recipe.getDuplicateLink() != null) {
AlmostUnified.LOG.error("Recipe {} already linked", recipe.getId());
}
this.duplicateLink = new DuplicateLink(this);
this.duplicateLink.addDuplicate(recipe);
}
public boolean isDuplicate() {
return isDuplicate;
@Nullable
public DuplicateLink getDuplicateLink() {
return duplicateLink;
}
public void setTransformed(JsonObject transformedRecipe) {
Objects.requireNonNull(transformedRecipe);
if(isTransformed()) {
if (isTransformed()) {
throw new IllegalStateException("Recipe already transformed");
}
@ -62,4 +73,40 @@ public class RawRecipe {
public boolean isTransformed() {
return transformedRecipe != null;
}
private List<String> getIgnoredFields() {
return List.of("conditions");
}
private LinkedHashMap<String, JsonCompare.Rule> getRules() {
LinkedHashMap<String, JsonCompare.Rule> rules = new LinkedHashMap<>();
rules.put("experience", new JsonCompare.HigherRule());
rules.put("cookingtime", new JsonCompare.LowerRule());
return rules;
}
@Nullable
public RawRecipe compare(RawRecipe toCompare) {
JsonObject selfActual = getTransformed() != null ? getTransformed() : originalRecipe;
JsonObject toCompareActual = toCompare.getTransformed() != null ? toCompare.getTransformed()
: toCompare.getOriginal();
if (JsonCompare.matches(selfActual, toCompareActual, getIgnoredFields())) {
JsonObject compare = JsonCompare.compare(getRules(), selfActual, toCompareActual);
if (compare == null) {
return null;
}
if (compare == selfActual) {
return this;
}
if (compare == toCompareActual) {
return toCompare;
}
}
return null;
}
}

View file

@ -9,9 +9,9 @@ import com.google.gson.JsonPrimitive;
import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
@ -50,26 +50,28 @@ public class RecipeTransformer {
recipeTransformationResult.track(curRecipe.getId(), curRecipe.getOriginal(), result); // TODO remove
curRecipe.setTransformed(result);
for (int compareIndex = 0; compareIndex < curIndex; compareIndex++) { // TODO extract
RawRecipe toCompare = rawRecipes.get(compareIndex);
if(toCompare.isDuplicate()) continue;
JsonObject json = toCompare.isTransformed() ? toCompare.getTransformed() : toCompare.getOriginal();
if(result.equals(json)) { // TODO replace with cool equal which has additional compare rules
toCompare.markAsDuplicate();
}
}
handleDuplicate(curRecipe, rawRecipes);
}
}
List<DuplicateLink> duplicateLinks = rawRecipes
.stream()
.map(RawRecipe::getDuplicateLink)
.filter(Objects::nonNull)
.distinct()
.toList();
String s = "";
});
Map<ResourceLocation, List<RawRecipe>> duplicates = new HashMap<>();
rawRecipesByType.forEach((type, rawRecipes) -> {
List<RawRecipe> duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList());
if(!duplicatesForType.isEmpty()) {
duplicates.put(type, duplicatesForType);
}
});
// Map<ResourceLocation, List<RawRecipe>> duplicates = new HashMap<>();
// rawRecipesByType.forEach((type, rawRecipes) -> {
// List<RawRecipe> duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList());
// if(!duplicatesForType.isEmpty()) {
// duplicates.put(type, duplicatesForType);
// }
// });
recipeTransformationResult.end();
@ -89,6 +91,43 @@ public class RecipeTransformer {
return recipeTransformationResult;
}
private void handleDuplicate(RawRecipe curRecipe, List<RawRecipe> rawRecipes) {
if(curRecipe.getDuplicateLink() != null) {
AlmostUnified.LOG.error("Duplication already handled for recipe {}", curRecipe.getId());
return;
}
for (RawRecipe rawRecipe : rawRecipes) {
if (rawRecipe == curRecipe) {
return;
}
if (handleDuplicate(curRecipe, rawRecipe)) {
return;
}
}
}
private boolean handleDuplicate(RawRecipe curRecipe, RawRecipe rawRecipe) {
DuplicateLink link = rawRecipe.getDuplicateLink();
if(link != null) {
RawRecipe master = link.getMaster();
RawRecipe compare = curRecipe.compare(master);
if(compare != null) {
link.updateMaster(compare);
return true;
}
} else {
RawRecipe compare = curRecipe.compare(rawRecipe);
if(compare != null) {
rawRecipe.linkDuplicate(compare);
return true;
}
}
return false;
}
@Nullable
public JsonObject transformRecipe(ResourceLocation recipeId, JsonObject json) {
try {
@ -107,4 +146,5 @@ public class RecipeTransformer {
}
return null;
}
}