aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/moulberry/repo/NEURecipeCache.java56
-rw-r--r--src/main/java/io/github/moulberry/repo/NEURepository.java7
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java72
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java37
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUIngredient.java63
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUItem.java3
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java72
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java30
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEURecipe.java13
-rw-r--r--src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java20
-rw-r--r--src/test/java/TestMain.java10
11 files changed, 380 insertions, 3 deletions
diff --git a/src/main/java/io/github/moulberry/repo/NEURecipeCache.java b/src/main/java/io/github/moulberry/repo/NEURecipeCache.java
new file mode 100644
index 0000000..50e0481
--- /dev/null
+++ b/src/main/java/io/github/moulberry/repo/NEURecipeCache.java
@@ -0,0 +1,56 @@
+package io.github.moulberry.repo;
+
+import io.github.moulberry.repo.data.NEUIngredient;
+import io.github.moulberry.repo.data.NEUItem;
+import io.github.moulberry.repo.data.NEURecipe;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class NEURecipeCache implements IReloadable {
+
+ private NEURecipeCache() {
+ }
+
+ /**
+ * Create a recipe cache.
+ *
+ * @param repository the repository for which to create a recipe cache
+ *
+ * @return an unitialized repository cache, that can be initialized by calling {@link NEURepository#reload()}, or by
+ * manually {{@link #reload}ing it.}
+ */
+ public static NEURecipeCache forRepo(NEURepository repository) {
+ NEURecipeCache neuRecipeCache = new NEURecipeCache();
+ repository.registerReloadListener(neuRecipeCache);
+ return neuRecipeCache;
+ }
+
+
+ @Getter
+ Map<String, Set<NEURecipe>> recipes = new HashMap<>();
+ @Getter
+ Map<String, Set<NEURecipe>> usages = new HashMap<>();
+
+
+ @Override
+ public void reload(NEURepository repository) throws NEURepositoryException {
+ Map<String, Set<NEURecipe>> recipes = new HashMap<>();
+ Map<String, Set<NEURecipe>> usages = new HashMap<>();
+ for (NEUItem item : repository.getItems().getItems().values()) {
+ for (NEURecipe recipe : item.getRecipes()) {
+ for (NEUIngredient input : recipe.getAllInputs()) {
+ usages.computeIfAbsent(input.getItemId(), ignored -> new HashSet<>()).add(recipe);
+ }
+ for (NEUIngredient output : recipe.getAllOutputs()) {
+ recipes.computeIfAbsent(output.getItemId(), ignored -> new HashSet<>()).add(recipe);
+ }
+ }
+ }
+ this.recipes = recipes;
+ this.usages = usages;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/repo/NEURepository.java b/src/main/java/io/github/moulberry/repo/NEURepository.java
index b5f942c..122ef24 100644
--- a/src/main/java/io/github/moulberry/repo/NEURepository.java
+++ b/src/main/java/io/github/moulberry/repo/NEURepository.java
@@ -23,14 +23,21 @@ public final class NEURepository {
final Gson gson = new GsonBuilder()
.setPrettyPrinting()
+ .registerTypeAdapter(new TypeToken<NEUIngredient>() {
+ }.getType(), new NEUIngredient.Serializer())
.registerTypeAdapter(new TypeToken<Coordinate>() {
}.getType(), new Coordinate.CoordinateSerializer())
+ .registerTypeAdapter(new TypeToken<NEUMobDropRecipe.Drop>() {
+ }.getType(), new NEUMobDropRecipe.Drop.Serializer())
+ .registerTypeAdapter(new TypeToken<NEUCraftingRecipe>() {
+ }.getType(), new NEUCraftingRecipe.Serializer())
.registerTypeAdapterFactory(
RuntimeTypeAdapterFactory.of(NEURecipe.class, "type")
.registerSubtype(NEUForgeRecipe.class, "forge")
.registerSubtype(NEUTradeRecipe.class, "trade")
.registerSubtype(NEUCraftingRecipe.class, "crafting")
.registerSubtype(NEUMobDropRecipe.class, "drops")
+ .registerSubtype(NEUNpcShopRecipe.class, "npc_shop")
.setDefaultTypeTag("crafting")
)
.create();
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java
index cf025d4..420fad7 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEUCraftingRecipe.java
@@ -1,4 +1,76 @@
package io.github.moulberry.repo.data;
+import com.google.gson.*;
+import lombok.Getter;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+@Getter
public class NEUCraftingRecipe implements NEURecipe {
+
+ NEUIngredient[] inputs;
+ @Nullable
+ String extraText;
+ NEUIngredient output;
+ int outputCount;
+
+ public static class Serializer implements JsonDeserializer<NEUCraftingRecipe> {
+
+ @Override
+ public NEUCraftingRecipe deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ NEUCraftingRecipe cr = new NEUCraftingRecipe();
+ JsonObject recipe = json.getAsJsonObject();
+ String[] x = {"1", "2", "3"};
+ String[] y = {"A", "B", "C"};
+ cr.inputs = new NEUIngredient[9];
+ for (int i = 0; i < 9; i++) {
+ String name = y[i / 3] + x[i % 3];
+ if (!recipe.has(name)) continue;
+ String item = recipe.get(name).getAsString();
+ if (item == null || item.isEmpty()) {
+ cr.inputs[i] = NEUIngredient.SENTINEL_EMPTY;
+ } else {
+ cr.inputs[i] = NEUIngredient.fromString(item);
+ }
+ }
+ cr.outputCount = -1;
+ if (recipe.has("count"))
+ cr.outputCount = recipe.get("count").getAsInt();
+ if (recipe.has("crafttext"))
+ cr.extraText = recipe.get("crafttext").getAsString();
+ if (recipe.has("overrideOutputId"))
+ cr.output = NEUIngredient.fromString(recipe.get("overrideOutputId").getAsString());
+ return cr;
+ }
+ }
+
+ @Override
+ public void fillItemInfo(NEUItem item) {
+ if (this.extraText == null)
+ this.extraText = item.crafttext;
+ if (this.output == null)
+ this.output = NEUIngredient.fromString(item.skyblockItemId);
+ if (outputCount > 0)
+ this.output.amount = outputCount;
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllOutputs() {
+ return Collections.singletonList(output);
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllInputs() {
+ List<NEUIngredient> ingredientList = new ArrayList<>();
+ for (NEUIngredient ingredient : inputs) {
+ if (ingredient != null)
+ ingredientList.add(ingredient);
+ }
+ return ingredientList;
+ }
}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java
index 6dbed06..05c2943 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEUForgeRecipe.java
@@ -1,5 +1,42 @@
package io.github.moulberry.repo.data;
+import lombok.Getter;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
public class NEUForgeRecipe implements NEURecipe {
+ @Getter
+ List<NEUIngredient> inputs;
+ int count;
+ String overrideOutputId;
+ @Getter
+ int duration;
+ @Getter
+ transient NEUIngredient outputStack;
+
+
+ @Override
+ public void fillItemInfo(NEUItem item) {
+ if (overrideOutputId == null) {
+ outputStack = NEUIngredient.fromString(item.skyblockItemId);
+ } else {
+ outputStack = NEUIngredient.fromString(overrideOutputId);
+ }
+ if (count > 0) {
+ outputStack.amount = count;
+ }
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllOutputs() {
+ return Collections.singletonList(outputStack);
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllInputs() {
+ return inputs;
+ }
}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java b/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java
new file mode 100644
index 0000000..9f7d62c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/repo/data/NEUIngredient.java
@@ -0,0 +1,63 @@
+package io.github.moulberry.repo.data;
+
+import com.google.gson.*;
+import lombok.Getter;
+
+import java.lang.reflect.Type;
+
+@Getter
+public class NEUIngredient {
+ String itemId;
+ int amount;
+ public static final String NEU_SENTINEL_EMPTY = "NEU_SENTINEL_EMPTY";
+ public static final NEUIngredient SENTINEL_EMPTY = new NEUIngredient();
+
+ static {
+ SENTINEL_EMPTY.itemId = NEU_SENTINEL_EMPTY;
+ SENTINEL_EMPTY.amount = 0;
+ }
+
+ private NEUIngredient() {
+ }
+
+ public static NEUIngredient fromItem(NEUItem item, int count) {
+ NEUIngredient ingredient = new NEUIngredient();
+ ingredient.amount = count;
+ ingredient.itemId = item.getSkyblockItemId();
+ return ingredient;
+ }
+
+ public static NEUIngredient fromString(String string) {
+ String[] parts = string.split(":");
+ NEUIngredient ingredient = new NEUIngredient();
+ if (parts.length == 2) {
+ ingredient.amount = Integer.parseInt(parts[1]);
+ } else if (parts.length == 1) {
+ ingredient.amount = 1;
+ } else {
+ throw new IllegalArgumentException("Could not parse ingredient " + string);
+ }
+ ingredient.itemId = parts[0];
+ if (NEU_SENTINEL_EMPTY.equals(ingredient.itemId))
+ return SENTINEL_EMPTY;
+ return ingredient;
+ }
+
+ public static class Serializer implements JsonDeserializer<NEUIngredient> {
+
+ @Override
+ public NEUIngredient deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+
+ if (!json.isJsonPrimitive()) throw new JsonParseException("Expected string for ingredient, found " + json);
+ JsonPrimitive p = json.getAsJsonPrimitive();
+ if (!p.isString()) throw new JsonParseException("Expected string for ingredient, found " + json);
+ String asString = json.getAsString();
+ return fromString(asString);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("NEUIngredient{%s:%d}", itemId, amount);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUItem.java b/src/main/java/io/github/moulberry/repo/data/NEUItem.java
index 61d08aa..94de529 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEUItem.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEUItem.java
@@ -49,6 +49,9 @@ public class NEUItem {
if (singletonRecipe != null)
newRecipes.add(singletonRecipe);
recipes = newRecipes;
+ for (NEURecipe recipe : recipes) {
+ recipe.fillItemInfo(this);
+ }
}
}
}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java
index 6b5dfeb..cf192d4 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEUMobDropRecipe.java
@@ -1,4 +1,76 @@
package io.github.moulberry.repo.data;
+import com.google.gson.*;
+import com.google.gson.annotations.SerializedName;
+import com.google.gson.reflect.TypeToken;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+@Getter
public class NEUMobDropRecipe implements NEURecipe {
+ @SerializedName("combat_xp")
+ int combatExperience;
+ int coins;
+ @SerializedName("xp")
+ int enchantingExperience;
+ String name;
+ String render;
+ String panorama;
+ int level;
+ List<String> extra;
+ List<Drop> drops;
+ transient NEUItem dropsFrom;
+
+ @Data
+ @AllArgsConstructor
+ public static class Drop {
+ NEUIngredient dropItem;
+ @Nullable
+ String chance;
+ List<String> extra;
+
+ public static class Serializer implements JsonDeserializer<Drop> {
+
+ @Override
+ public Drop deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ if (json.isJsonPrimitive()) {
+ return new Drop(NEUIngredient.fromString(json.getAsString()), null, Collections.emptyList());
+ }
+ JsonObject d = json.getAsJsonObject();
+ return new Drop(
+ NEUIngredient.fromString(d.get("id").getAsString()),
+ d.has("chance") ? d.get("chance").getAsString() : null,
+ d.has("extra") ? context.deserialize(d.get("extra"), new TypeToken<List<String>>() {
+ }.getType()) : Collections.emptyList()
+ );
+ }
+ }
+ }
+
+ @Override
+ public void fillItemInfo(NEUItem item) {
+ dropsFrom = item;
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllInputs() {
+ return Collections.singletonList(NEUIngredient.fromItem(dropsFrom, 1));
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllOutputs() {
+ List<NEUIngredient> l = new ArrayList<>();
+ for (Drop drop : drops) {
+ l.add(drop.getDropItem());
+ }
+ return l;
+ }
}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java
new file mode 100644
index 0000000..df8bf73
--- /dev/null
+++ b/src/main/java/io/github/moulberry/repo/data/NEUNpcShopRecipe.java
@@ -0,0 +1,30 @@
+package io.github.moulberry.repo.data;
+
+import lombok.Getter;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+@Getter
+public class NEUNpcShopRecipe implements NEURecipe {
+
+ List<NEUIngredient> cost;
+ NEUIngredient result;
+ NEUItem isSoldBy;
+
+ @Override
+ public void fillItemInfo(NEUItem item) {
+ isSoldBy = item;
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllInputs() {
+ return cost;
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllOutputs() {
+ return Collections.singletonList(result);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEURecipe.java b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java
index 4a49f17..28df4b7 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEURecipe.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEURecipe.java
@@ -1,4 +1,17 @@
package io.github.moulberry.repo.data;
+import java.util.Collection;
+
public interface NEURecipe {
+ /**
+ * This is to be called once, after deserialization by the item that contains this recipe. This will be done
+ * automatically by {@link NEUItem#getRecipes()}.
+ */
+ @Deprecated
+ default void fillItemInfo(NEUItem item) {
+ }
+
+ Collection<NEUIngredient> getAllInputs();
+
+ Collection<NEUIngredient> getAllOutputs();
}
diff --git a/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java
index 7fd22f7..e1435d4 100644
--- a/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java
+++ b/src/main/java/io/github/moulberry/repo/data/NEUTradeRecipe.java
@@ -1,4 +1,24 @@
package io.github.moulberry.repo.data;
+import lombok.Getter;
+
+import java.util.Collection;
+import java.util.Collections;
+
+@Getter
public class NEUTradeRecipe implements NEURecipe {
+ NEUIngredient cost;
+ int min;
+ int max;
+ NEUIngredient result;
+
+ @Override
+ public Collection<NEUIngredient> getAllInputs() {
+ return Collections.singletonList(cost);
+ }
+
+ @Override
+ public Collection<NEUIngredient> getAllOutputs() {
+ return Collections.singletonList(result);
+ }
}
diff --git a/src/test/java/TestMain.java b/src/test/java/TestMain.java
index faf04ca..e3c05ec 100644
--- a/src/test/java/TestMain.java
+++ b/src/test/java/TestMain.java
@@ -1,6 +1,8 @@
+import io.github.moulberry.repo.NEURecipeCache;
import io.github.moulberry.repo.NEURepository;
import io.github.moulberry.repo.NEURepositoryException;
import io.github.moulberry.repo.NEURepositoryVersion;
+import io.github.moulberry.repo.data.NEUForgeRecipe;
import java.nio.file.Paths;
@@ -10,6 +12,7 @@ public class TestMain {
System.out.printf("Schema %d.%d%n", NEURepositoryVersion.REPOSITORY_SCHEMA_VERSION_MAJOR, NEURepositoryVersion.REPOSITORY_SCHEMA_VERSION_MINOR);
NEURepository repository = NEURepository.of(Paths.get("NotEnoughUpdates-REPO"));
+ NEURecipeCache recipes = NEURecipeCache.forRepo(repository);
repository.reload();
System.out.println("pet mf (115): " + repository.getConstants().getBonuses().getPetRewards(115));
System.out.println("skill reward (combat 60): " + repository.getConstants().getBonuses().getAccumulativeLevelingRewards("skill_combat", 60));
@@ -19,8 +22,9 @@ public class TestMain {
System.out.println("upgrade cost for HOT_CRIMSON_HELMET: " + repository.getConstants().getEssenceCost().getCosts().get("HOT_CRIMSON_HELMET"));
System.out.println("first fairy soul in the hub: " + repository.getConstants().getFairySouls().getSoulLocations().get("hub").get(0));
System.out.println("soul total: " + repository.getConstants().getFairySouls().getMaxSouls());
- System.out.println("minecraft item of ASPECT_OF_THE_END: "+repository.getItems().getItemBySkyblockId("ASPECT_OF_THE_END").getMinecraftItemId());
- System.out.println("is vanilla ASPECT_OF_THE_END: "+repository.getItems().getItemBySkyblockId("ASPECT_OF_THE_END").isVanilla());
- System.out.println("is vanilla DIAMOND: "+repository.getItems().getItemBySkyblockId("DIAMOND").isVanilla());
+ System.out.println("minecraft item of ASPECT_OF_THE_END: " + repository.getItems().getItemBySkyblockId("ASPECT_OF_THE_END").getMinecraftItemId());
+ System.out.println("is vanilla ASPECT_OF_THE_END: " + repository.getItems().getItemBySkyblockId("ASPECT_OF_THE_END").isVanilla());
+ System.out.println("is vanilla DIAMOND: " + repository.getItems().getItemBySkyblockId("DIAMOND").isVanilla());
+ System.out.println("crafting recipe of DIVAN DRILL: " + ((NEUForgeRecipe) recipes.getRecipes().get("DIVAN_DRILL").stream().findAny().get()).getInputs());
}
}