mirror of
https://github.com/AlmostReliable/almostunified.git
synced 2024-11-14 19:25:13 -05:00
shaped crafting pattern matching (#2)
This commit is contained in:
parent
b406724fd8
commit
1b8c5dc7eb
5 changed files with 175 additions and 16 deletions
|
@ -52,7 +52,7 @@ public class DuplicationConfig extends Config {
|
|||
|
||||
JsonCompare.CompareSettings defaultRules = safeGet(() -> createCompareSet(json.getAsJsonObject(
|
||||
DEFAULT_DUPLICATE_RULES)),
|
||||
defaultSet());
|
||||
defaultSettings());
|
||||
LinkedHashMap<ResourceLocation, JsonCompare.CompareSettings> overrideRules = safeGet(() -> json
|
||||
.getAsJsonObject(OVERRIDE_DUPLICATE_RULES)
|
||||
.entrySet()
|
||||
|
@ -60,13 +60,13 @@ public class DuplicationConfig extends Config {
|
|||
.collect(Collectors.toMap(entry -> new ResourceLocation(entry.getKey()),
|
||||
entry -> createCompareSet(entry.getValue().getAsJsonObject()),
|
||||
(a, b) -> b,
|
||||
LinkedHashMap::new)), new LinkedHashMap<>());
|
||||
LinkedHashMap::new)), defaultOverrides());
|
||||
boolean strictMode = safeGet(() -> json.get(STRICT_MODE).getAsBoolean(), false);
|
||||
|
||||
return new DuplicationConfig(defaultRules, overrideRules, ignoreRecipeTypes, ignoreRecipes, strictMode);
|
||||
}
|
||||
|
||||
private JsonCompare.CompareSettings defaultSet() {
|
||||
private JsonCompare.CompareSettings defaultSettings() {
|
||||
JsonCompare.CompareSettings result = new JsonCompare.CompareSettings();
|
||||
result.ignoreField("conditions");
|
||||
result.addRule("cookingtime", new JsonCompare.HigherRule());
|
||||
|
@ -75,6 +75,16 @@ public class DuplicationConfig extends Config {
|
|||
return result;
|
||||
}
|
||||
|
||||
private LinkedHashMap<ResourceLocation, JsonCompare.CompareSettings> defaultOverrides() {
|
||||
JsonCompare.CompareSettings result = new JsonCompare.CompareSettings();
|
||||
result.ignoreField("conditions");
|
||||
result.ignoreField("pattern");
|
||||
result.ignoreField("key");
|
||||
LinkedHashMap<ResourceLocation, JsonCompare.CompareSettings> resultMap = new LinkedHashMap<>();
|
||||
resultMap.put(new ResourceLocation("minecraft", "crafting_shaped"), result);
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
private JsonCompare.CompareSettings createCompareSet(JsonObject rules) {
|
||||
JsonCompare.CompareSettings result = new JsonCompare.CompareSettings();
|
||||
result.deserialize(rules);
|
||||
|
|
|
@ -44,21 +44,16 @@ public class RecipeLink {
|
|||
JsonObject selfActual = first.getActual();
|
||||
JsonObject toCompareActual = second.getActual();
|
||||
|
||||
if (JsonCompare.matches(selfActual, toCompareActual, compareSettings.getIgnoredFields())) {
|
||||
JsonObject compare = JsonCompare.compare(compareSettings.getRules(), selfActual, toCompareActual);
|
||||
if (compare == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (compare == selfActual) {
|
||||
return first;
|
||||
}
|
||||
|
||||
if (compare == toCompareActual) {
|
||||
return second;
|
||||
}
|
||||
JsonObject compare = null;
|
||||
if (first.getType().toString().equals("minecraft:crafting_shaped")) {
|
||||
compare = JsonCompare.compareShaped(selfActual, toCompareActual, compareSettings.getIgnoredFields());
|
||||
} else if (JsonCompare.matches(selfActual, toCompareActual, compareSettings.getIgnoredFields())) {
|
||||
compare = JsonCompare.compare(compareSettings.getRules(), selfActual, toCompareActual);
|
||||
}
|
||||
|
||||
if (compare == null) return null;
|
||||
if (compare == selfActual) return first;
|
||||
if (compare == toCompareActual) return second;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,54 @@ public final class JsonCompare {
|
|||
return unsorted.get(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JsonObject compareShaped(JsonObject first, JsonObject second, Collection<String> ignoredFields) {
|
||||
if (!matches(first, second, ignoredFields)) return null;
|
||||
|
||||
JsonArray firstPattern = JsonUtils.arrayOrSelf(first.get("pattern"));
|
||||
JsonArray secondPattern = JsonUtils.arrayOrSelf(second.get("pattern"));
|
||||
|
||||
if (firstPattern.size() != secondPattern.size()) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < firstPattern.size(); i++) {
|
||||
if (JsonUtils.stringOrSelf(firstPattern.get(i)).length() !=
|
||||
JsonUtils.stringOrSelf(secondPattern.get(i)).length()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var firstKeyMap = createShapedKeyMap(first);
|
||||
var secondKeyMap = createShapedKeyMap(second);
|
||||
|
||||
for (int i = 0; i < firstPattern.size(); i++) {
|
||||
String firstPatternString = JsonUtils.stringOrSelf(firstPattern.get(i));
|
||||
String secondPatternString = JsonUtils.stringOrSelf(secondPattern.get(i));
|
||||
|
||||
for (int j = 0; j < firstPatternString.length(); j++) {
|
||||
char firstChar = firstPatternString.charAt(j);
|
||||
char secondChar = secondPatternString.charAt(j);
|
||||
if (!firstKeyMap.containsKey(firstChar) || !secondKeyMap.containsKey(secondChar)) {
|
||||
return null;
|
||||
}
|
||||
if (!firstKeyMap.get(firstChar).equals(secondKeyMap.get(secondChar))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
private static Map<Character, JsonObject> createShapedKeyMap(JsonObject json) {
|
||||
JsonObject keys = JsonUtils.objectOrSelf(json.get("key"));
|
||||
Map<Character, JsonObject> keyMap = new HashMap<>();
|
||||
for (Map.Entry<String, JsonElement> patterKey : keys.entrySet()) {
|
||||
keyMap.put(patterKey.getKey().charAt(0), JsonUtils.objectOrSelf(patterKey.getValue()));
|
||||
}
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
public static boolean matches(JsonObject first, JsonObject second, Collection<String> ignoredProperties) {
|
||||
List<String> firstValidKeys = first
|
||||
.keySet()
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.almostreliable.unified.utils;
|
|||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
@ -36,6 +37,20 @@ public final class JsonUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static JsonObject objectOrSelf(@Nullable JsonElement element) {
|
||||
if (element instanceof JsonObject jsonObject) {
|
||||
return jsonObject;
|
||||
}
|
||||
return new JsonObject();
|
||||
}
|
||||
|
||||
public static String stringOrSelf(@Nullable JsonElement element) {
|
||||
if (element instanceof JsonPrimitive primitive) {
|
||||
return primitive.getAsString();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Loops through the array and applies the given callback to each element.
|
||||
* If the callback returns non-null, the element is replaced with the returned value.
|
||||
|
|
|
@ -112,4 +112,95 @@ public class JsonCompareTest {
|
|||
boolean matches = JsonCompare.matches(first, second, List.of("experience"));
|
||||
assertTrue(matches);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shapedNoMatch() {
|
||||
String recipe1 = """
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"iii",
|
||||
"ici",
|
||||
"iii"
|
||||
],
|
||||
"key": {
|
||||
"i": {
|
||||
"tag": "forge:raw_materials/iron"
|
||||
},
|
||||
"k": {
|
||||
"item": "minecraft:carrot"
|
||||
}
|
||||
},
|
||||
"result": "minecraft:iron_ingot"
|
||||
}
|
||||
""";
|
||||
String recipe2 = """
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"iii",
|
||||
"ici",
|
||||
"iii"
|
||||
],
|
||||
"key": {
|
||||
"i": {
|
||||
"tag": "forge:raw_materials/iron"
|
||||
},
|
||||
"k": {
|
||||
"item": "minecraft:pumpkin"
|
||||
}
|
||||
},
|
||||
"result": "minecraft:iron_ingot"
|
||||
}
|
||||
""";
|
||||
|
||||
JsonObject first = TestUtils.json(recipe1);
|
||||
JsonObject second = TestUtils.json(recipe2);
|
||||
JsonObject result = JsonCompare.compareShaped(first, second, List.of("pattern", "key"));
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shapedMatch() {
|
||||
String recipe1 = """
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"iii",
|
||||
"iii",
|
||||
"iii"
|
||||
],
|
||||
"key": {
|
||||
"i": {
|
||||
"tag": "forge:raw_materials/iron"
|
||||
}
|
||||
},
|
||||
"result": "minecraft:iron_ingot"
|
||||
}
|
||||
""";
|
||||
String recipe2 = """
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"iii",
|
||||
"iki",
|
||||
"iii"
|
||||
],
|
||||
"key": {
|
||||
"i": {
|
||||
"tag": "forge:raw_materials/iron"
|
||||
},
|
||||
"k": {
|
||||
"tag": "forge:raw_materials/iron"
|
||||
}
|
||||
},
|
||||
"result": "minecraft:iron_ingot"
|
||||
}
|
||||
""";
|
||||
|
||||
JsonObject first = TestUtils.json(recipe1);
|
||||
JsonObject second = TestUtils.json(recipe2);
|
||||
JsonObject result = JsonCompare.compareShaped(first, second, List.of("pattern", "key"));
|
||||
assertEquals(first, result);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue