aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java36
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java38
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java57
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java522
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java20
5 files changed, 375 insertions, 298 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
index 11c10ea0..691ccaae 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -2222,7 +2222,7 @@ public class GuiProfileViewer extends GuiScreen {
}
Panorama.drawPanorama(-backgroundRotation, guiLeft + 212, guiTop + 44, 81, 108, -0.37f, 0.6f,
- getPanoramasForLocation(location == null ? "dynamic" : location, panoramaIdentifier)
+ Panorama.getPanoramasForLocation(location == null ? "dynamic" : location, panoramaIdentifier)
);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_pets);
@@ -3114,38 +3114,6 @@ public class GuiProfileViewer extends GuiScreen {
return entityPlayer;
}
- public ResourceLocation[] getPanoramasForLocation(String location, String identifier) {
- if (panoramasMap.containsKey(location + identifier)) return panoramasMap.get(location + identifier);
- try {
- ResourceLocation[] panoramasArray = new ResourceLocation[6];
- for (int i = 0; i < 6; i++) {
- panoramasArray[i] =
- new ResourceLocation("notenoughupdates:panoramas/" + location + "_" + identifier + "/panorama_" + i + ".jpg");
- Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]);
- }
- panoramasMap.put(location + identifier, panoramasArray);
- return panoramasArray;
- } catch (IOException e) {
- try {
- ResourceLocation[] panoramasArray = new ResourceLocation[6];
- for (int i = 0; i < 6; i++) {
- panoramasArray[i] =
- new ResourceLocation("notenoughupdates:panoramas/" + location + "/panorama_" + i + ".jpg");
- Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]);
- }
- panoramasMap.put(location + identifier, panoramasArray);
- return panoramasArray;
- } catch (IOException e2) {
- ResourceLocation[] panoramasArray = new ResourceLocation[6];
- for (int i = 0; i < 6; i++) {
- panoramasArray[i] = new ResourceLocation("notenoughupdates:panoramas/unknown/panorama_" + i + ".jpg");
- }
- panoramasMap.put(location + identifier, panoramasArray);
- return panoramasArray;
- }
- }
- }
-
private void drawExtraPage(int mouseX, int mouseY, float partialTicks) {
FontRenderer fr = Minecraft.getMinecraft().fontRendererObj;
@@ -4717,7 +4685,7 @@ public class GuiProfileViewer extends GuiScreen {
}
Panorama.drawPanorama(-backgroundRotation - extraRotation, guiLeft + 23, guiTop + 44, 81, 108, 0.37f, 0.8f,
- getPanoramasForLocation(location == null ? "unknown" : location, panoramaIdentifier)
+ Panorama.getPanoramasForLocation(location == null ? "unknown" : location, panoramaIdentifier)
);
Minecraft.getMinecraft().getTextureManager().bindTexture(pv_basic);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
index ac117bc2..a2d297f5 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/Panorama.java
@@ -15,6 +15,9 @@ import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Project;
+import java.io.IOException;
+import java.util.HashMap;
+
public class Panorama {
private static final TexLoc tl = new TexLoc(97, 19, Keyboard.KEY_P);
private static final TexLoc tl2 = new TexLoc(37, 80, Keyboard.KEY_L);
@@ -24,6 +27,41 @@ public class Panorama {
private static int lastWidth = 0;
private static int lastHeight = 0;
+
+ private static final HashMap<String, ResourceLocation[]> panoramasMap = new HashMap<>();
+
+ public static synchronized ResourceLocation[] getPanoramasForLocation(String location, String identifier) {
+ if (panoramasMap.containsKey(location + identifier)) return panoramasMap.get(location + identifier);
+ try {
+ ResourceLocation[] panoramasArray = new ResourceLocation[6];
+ for (int i = 0; i < 6; i++) {
+ panoramasArray[i] =
+ new ResourceLocation("notenoughupdates:panoramas/" + location + "_" + identifier + "/panorama_" + i + ".jpg");
+ Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]);
+ }
+ panoramasMap.put(location + identifier, panoramasArray);
+ return panoramasArray;
+ } catch (IOException e) {
+ try {
+ ResourceLocation[] panoramasArray = new ResourceLocation[6];
+ for (int i = 0; i < 6; i++) {
+ panoramasArray[i] =
+ new ResourceLocation("notenoughupdates:panoramas/" + location + "/panorama_" + i + ".jpg");
+ Minecraft.getMinecraft().getResourceManager().getResource(panoramasArray[i]);
+ }
+ panoramasMap.put(location + identifier, panoramasArray);
+ return panoramasArray;
+ } catch (IOException e2) {
+ ResourceLocation[] panoramasArray = new ResourceLocation[6];
+ for (int i = 0; i < 6; i++) {
+ panoramasArray[i] = new ResourceLocation("notenoughupdates:panoramas/unknown/panorama_" + i + ".jpg");
+ }
+ panoramasMap.put(location + identifier, panoramasArray);
+ return panoramasArray;
+ }
+ }
+ }
+
public static void drawPanorama(
float angle,
int x,
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java
index 5cc32528..0e210e42 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobLootRecipe.java
@@ -1,5 +1,6 @@
package io.github.moulberry.notenoughupdates.recipes;
+import com.google.common.collect.Sets;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -8,10 +9,12 @@ import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.miscfeatures.entityviewer.EntityViewer;
import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
import io.github.moulberry.notenoughupdates.profileviewer.Panorama;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.JsonUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
@@ -23,31 +26,35 @@ import java.util.stream.Collectors;
public class MobLootRecipe implements NeuRecipe {
private static final int MOB_POS_X = 38, MOB_POS_Y = 100;
- private static final int SLOT_POS_X = 82, SLOT_POS_Y = 23;
+ private static final int SLOT_POS_X = 82, SLOT_POS_Y = 24;
public static class MobDrop {
public final Ingredient drop;
public final String chance;
public final List<String> extra;
+ private ItemStack itemStack;
+
public MobDrop(Ingredient drop, String chance, List<String> extra) {
this.drop = drop;
this.chance = chance;
this.extra = extra;
}
- }
-
- public static ResourceLocation[] PANORAMAS = new ResourceLocation[6];
- static {
- for (int i = 0; i < 6; i++)
- PANORAMAS[i] = new ResourceLocation("notenoughupdates:panoramas/unknown/panorama_" + i + ".jpg");
+ public ItemStack getItemStack() {
+ if (itemStack == null) {
+ itemStack = drop.getItemStack().copy();
+ ItemUtils.appendLore(itemStack, extra);
+ }
+ return itemStack;
+ }
}
public static ResourceLocation BACKGROUND = new ResourceLocation(
"notenoughupdates",
"textures/gui/mob_loot_tall.png"
);
+ private final Ingredient mobIngredient;
private final List<MobDrop> drops;
private final int coins;
private final int combatXp;
@@ -58,7 +65,12 @@ public class MobLootRecipe implements NeuRecipe {
private final List<String> extra;
private EntityLivingBase entityLivingBase;
+ private final String panoName;
+
+ private ResourceLocation[] panos = null;
+
public MobLootRecipe(
+ Ingredient mobIngredient,
List<MobDrop> drops,
int level,
int coins,
@@ -66,8 +78,10 @@ public class MobLootRecipe implements NeuRecipe {
int combatXp,
String name,
String render,
- List<String> extra
+ List<String> extra,
+ String panoName
) {
+ this.mobIngredient = mobIngredient;
this.drops = drops;
this.level = level;
this.coins = coins;
@@ -76,6 +90,7 @@ public class MobLootRecipe implements NeuRecipe {
this.combatXp = combatXp;
this.name = name;
this.render = render;
+ this.panoName = panoName;
}
public String getName() {
@@ -94,6 +109,10 @@ public class MobLootRecipe implements NeuRecipe {
return combatXp;
}
+ public Ingredient getMob() {
+ return mobIngredient;
+ }
+
public int getXp() {
return xp;
}
@@ -116,7 +135,7 @@ public class MobLootRecipe implements NeuRecipe {
@Override
public Set<Ingredient> getIngredients() {
- return Collections.emptySet();
+ return Sets.newHashSet(mobIngredient);
}
@Override
@@ -134,7 +153,7 @@ public class MobLootRecipe implements NeuRecipe {
slots.add(new RecipeSlot(
SLOT_POS_X + x * 16,
SLOT_POS_Y + y * 16,
- mobDrop.drop.getItemStack()
+ mobDrop.getItemStack()
));
}
return slots;
@@ -162,6 +181,9 @@ public class MobLootRecipe implements NeuRecipe {
@Override
public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
+ if (panos == null) {
+ panos = Panorama.getPanoramasForLocation(panoName, "day");
+ }
Panorama.drawPanorama(
((System.nanoTime() / 20000000000F) % 1) * 360,
gui.guiLeft + PANORAMA_POS_X,
@@ -170,7 +192,7 @@ public class MobLootRecipe implements NeuRecipe {
PANORAMA_HEIGHT,
0F,
0F,
- PANORAMAS
+ panos
);
if (getRenderEntity() != null)
EntityViewer.renderEntity(entityLivingBase, gui.guiLeft + MOB_POS_X, gui.guiTop + MOB_POS_Y, mouseX, mouseY);
@@ -187,7 +209,7 @@ public class MobLootRecipe implements NeuRecipe {
PANORAMA_HEIGHT
)) {
List<String> stuff = new ArrayList<>(extra);
- stuff.add(0, "[Lvl " + level + "] " + name);
+ stuff.add(0, (level > 0 ? "[Lv " + level + "] " : "") + name);
Utils.drawHoveringText(
stuff,
mouseX,
@@ -215,15 +237,12 @@ public class MobLootRecipe implements NeuRecipe {
recipe.addProperty("name", name);
recipe.addProperty("render", render);
recipe.addProperty("type", getType().getId());
+ recipe.addProperty("panorama", "unknown");
recipe.add("extra", JsonUtils.transformListToJsonArray(extra, JsonPrimitive::new));
recipe.add("drops", JsonUtils.transformListToJsonArray(drops, drop -> {
JsonObject dropObject = new JsonObject();
dropObject.addProperty("id", drop.drop.serialize());
- JsonArray extraText = new JsonArray();
- for (String extraLine : drop.extra) {
- extraText.add(new JsonPrimitive(extraLine));
- }
- dropObject.add("extra", extraText);
+ dropObject.add("extra", JsonUtils.transformListToJsonArray(drop.extra, JsonPrimitive::new));
dropObject.addProperty("chance", drop.chance);
return dropObject;
}));
@@ -252,6 +271,7 @@ public class MobLootRecipe implements NeuRecipe {
}
return new MobLootRecipe(
+ new Ingredient(manager, outputItemJson.get("internalname").getAsString(), 1),
drops,
recipe.has("level") ? recipe.get("level").getAsInt() : 0,
recipe.has("coins") ? recipe.get("coins").getAsInt() : 0,
@@ -259,7 +279,8 @@ public class MobLootRecipe implements NeuRecipe {
recipe.has("combat_xp") ? recipe.get("combat_xp").getAsInt() : 0,
recipe.get("name").getAsString(),
recipe.has("render") && !recipe.get("render").isJsonNull() ? recipe.get("render").getAsString() : null,
- JsonUtils.getJsonArrayOrEmpty(recipe, "extra", JsonElement::getAsString)
+ JsonUtils.getJsonArrayOrEmpty(recipe, "extra", JsonElement::getAsString),
+ recipe.has("panorama") ? recipe.get("panorama").getAsString() : "unknown"
);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
index 6c2d1102..e5028146 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
@@ -27,269 +27,299 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class RecipeGenerator {
- public static final String DURATION = "Duration: ";
- public static final String COINS_SUFFIX = " Coins";
+ public static final String DURATION = "Duration: ";
+ public static final String COINS_SUFFIX = " Coins";
- private final NotEnoughUpdates neu;
+ private final NotEnoughUpdates neu;
- private final Map<String, String> savedForgingDurations = new HashMap<>();
+ private final Map<String, String> savedForgingDurations = new HashMap<>();
- private final Debouncer debouncer = new Debouncer(1000 * 1000 * 50 /* 50 ms */);
- private final Debouncer durationDebouncer = new Debouncer(1000 * 1000 * 500);
+ private final Debouncer debouncer = new Debouncer(1000 * 1000 * 50 /* 50 ms */);
+ private final Debouncer durationDebouncer = new Debouncer(1000 * 1000 * 500);
+ public RecipeGenerator(NotEnoughUpdates neu) {
+ this.neu = neu;
+ }
- public RecipeGenerator(NotEnoughUpdates neu) {
- this.neu = neu;
- }
+ @SubscribeEvent
+ public void onTick(TickEvent event) {
+ if (!neu.config.hidden.enableItemEditing) return;
+ GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen;
+ if (currentScreen == null) return;
+ if (!(currentScreen instanceof GuiChest)) return;
+ analyzeUI((GuiChest) currentScreen);
+ }
- @SubscribeEvent
- public void onTick(TickEvent event) {
- if (!neu.config.hidden.enableItemEditing) return;
- GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen;
- if (currentScreen == null) return;
- if (!(currentScreen instanceof GuiChest)) return;
- analyzeUI((GuiChest) currentScreen);
- }
+ private boolean shouldSaveRecipe() {
+ return Keyboard.isKeyDown(Keyboard.KEY_O) && debouncer.trigger();
+ }
- private boolean shouldSaveRecipe() {
- return Keyboard.isKeyDown(Keyboard.KEY_O) && debouncer.trigger();
- }
+ public void analyzeUI(GuiChest gui) {
+ ContainerChest container = (ContainerChest) gui.inventorySlots;
+ IInventory menu = container.getLowerChestInventory();
+ String uiTitle = menu.getDisplayName().getUnformattedText();
+ EntityPlayerSP p = Minecraft.getMinecraft().thePlayer;
+ if (uiTitle.startsWith("Item Casting") || uiTitle.startsWith("Refine")) {
+ if (durationDebouncer.trigger())
+ parseAllForgeItemMetadata(menu);
+ }
+ boolean saveRecipe = shouldSaveRecipe();
+ if (uiTitle.equals("Confirm Process") && saveRecipe) {
+ ForgeRecipe recipe = parseSingleForgeRecipe(menu);
+ if (recipe == null) {
+ p.addChatMessage(new ChatComponentText(
+ "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI"));
+ } else {
+ p.addChatMessage(new ChatComponentText(
+ "" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:"));
+ p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Inputs:"));
+ for (Ingredient i : recipe.getInputs())
+ p.addChatMessage(new ChatComponentText(
+ " - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount()));
+ p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD +
+ recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount()));
+ p.addChatMessage(new ChatComponentText(
+ "" + EnumChatFormatting.AQUA + " Time: " + EnumChatFormatting.GRAY + recipe.getTimeInSeconds() +
+ " seconds (no QF) ."));
+ boolean saved = false;
+ try {
+ saved = saveRecipes(recipe.getOutput().getInternalItemId(), Collections.singletonList(recipe));
+ } catch (IOException e) {
+ }
+ if (!saved)
+ p.addChatMessage(new ChatComponentText("" +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
+ " Failed to save recipe. Does the item already exist?"));
+ }
+ }
+ if (saveRecipe) attemptToSaveBestiary(menu);
+ }
- public void analyzeUI(GuiChest gui) {
- ContainerChest container = (ContainerChest) gui.inventorySlots;
- IInventory menu = container.getLowerChestInventory();
- String uiTitle = menu.getDisplayName().getUnformattedText();
- EntityPlayerSP p = Minecraft.getMinecraft().thePlayer;
- if (uiTitle.startsWith("Item Casting") || uiTitle.startsWith("Refine")) {
- if (durationDebouncer.trigger())
- parseAllForgeItemMetadata(menu);
- }
- boolean saveRecipe = shouldSaveRecipe();
- if (uiTitle.equals("Confirm Process") && saveRecipe) {
- ForgeRecipe recipe = parseSingleForgeRecipe(menu);
- if (recipe == null) {
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "Could not parse recipe for this UI"));
- } else {
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + "Parsed recipe:"));
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Inputs:"));
- for (Ingredient i : recipe.getInputs())
- p.addChatMessage(new ChatComponentText(" - " + EnumChatFormatting.AQUA + i.getInternalItemId() + " x " + i.getCount()));
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Output: " + EnumChatFormatting.GOLD + recipe.getOutput().getInternalItemId() + " x " + recipe.getOutput().getCount()));
- p.addChatMessage(new ChatComponentText("" + EnumChatFormatting.AQUA + " Time: " + EnumChatFormatting.GRAY + recipe.getTimeInSeconds() + " seconds (no QF) ."));
- boolean saved = false;
- try {
- saved = saveRecipes(recipe.getOutput().getInternalItemId(), Collections.singletonList(recipe));
- } catch (IOException e) {
- }
- if (!saved)
- p.addChatMessage(new ChatComponentText("" +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " Failed to save recipe. Does the item already exist?"));
- }
- }
- if (saveRecipe) attemptToSaveBestiary(menu);
- }
+ private List<String> getLore(ItemStack item) {
+ NBTTagList loreTag = item.getTagCompound().getCompoundTag("display").getTagList("Lore", 8);
+ List<String> loreList = new ArrayList<>();
+ for (int i = 0; i < loreTag.tagCount(); i++) {
+ loreList.add(loreTag.getStringTagAt(i));
+ }
+ return loreList;
+ }
- private List<String> getLore(ItemStack item) {
- NBTTagList loreTag = item.getTagCompound().getCompoundTag("display").getTagList("Lore", 8);
- List<String> loreList = new ArrayList<>();
- for (int i = 0; i < loreTag.tagCount(); i++) {
- loreList.add(loreTag.getStringTagAt(i));
- }
- return loreList;
- }
+ // §8[§7Lv1§8] §fZombie Villager
+ private static final Pattern MOB_DISPLAY_NAME_PATTERN = Pattern.compile("^§8\\[§7Lv(?<level>\\d+)§8] (?<name>.*)$");
+ // §7Coins per Kill: §61
+ // §7Combat Exp: §3120
+ // §8 ■ §7§5Skeleton Grunt Helmet §8(§a5%§8)
+ // §8 ■ §7§fRotten Flesh
+ // §8 ■ Dragon Essence §8x3-5
+ private static final Pattern LORE_PATTERN = Pattern.compile("^(?:" +
+ "§7Coins per Kill: §6(?<coins>[,\\d]+)|" +
+ "§7Combat Exp: §3(?<combatxp>[,\\d]+)|" +
+ "§7XP Orbs: §3(?<xp>[,\\d]+)|" +
+ "§8 ■ (?:§7)?(?<dropName>(?:§.)?.+?)(?: §8\\(§a(?<dropChances>[\\d.<]+%)§8\\)| §8(?<dropCount>x.*))?|" +
+ "§7Kills: §a[,\\d]+|" +
+ "§.[a-zA-Z]+ Loot|" +
+ "§7Deaths: §a[,\\d]+|" +
+ " §8■ (?<missing>§c\\?\\?\\?)|" +
+ "" +
+ ")$");
- // §8[§7Lv1§8] §fZombie Villager
- private static final Pattern MOB_DISPLAY_NAME_PATTERN = Pattern.compile("^§8\\[§7Lv(?<level>\\d+)§8] (?<name>.*)$");
- // §7Coins per Kill: §61
- // §7Combat Exp: §3120
- // §8 ■ §7§5Skeleton Grunt Helmet §8(§a5%§8)
- // §8 ■ §7§fRotten Flesh
- // §8 ■ Dragon Essence §8x3-5
- private static final Pattern LORE_PATTERN = Pattern.compile("^(?:" +
- "§7Coins per Kill: §6(?<coins>[,\\d]+)|" +
- "§7Combat Exp: §3(?<combatxp>[,\\d]+)|" +
- "§7XP Orbs: §3(?<xp>[,\\d]+)|" +
- "§8 ■ (?:§7)?(?<dropName>(?:§.)?.+?)(?: §8\\(§a(?<dropChances>[\\d.<]+%)§8\\)| §8(?<dropCount>x.*))?|" +
- "§7Kills: §a[,\\d]+|" +
- "§.[a-zA-Z]+ Loot|" +
- "§7Deaths: §a[,\\d]+|" +
- " §8■ (?<missing>§c\\?\\?\\?)|" +
- "" +
- ")$");
+ private void attemptToSaveBestiary(IInventory menu) {
+ if (!menu.getDisplayName().getUnformattedText().contains("➜")) return;
+ ItemStack backArrow = menu.getStackInSlot(48);
+ if (backArrow == null || backArrow.getItem() != Items.arrow) return;
+ if (!getLore(backArrow).stream().anyMatch(it -> it.startsWith("§7To Bestiary ➜"))) return;
+ List<NeuRecipe> recipes = new ArrayList<>();
+ String internalMobName =
+ menu.getDisplayName().getUnformattedText().split("➜")[1].toUpperCase(Locale.ROOT).trim() + "_MONSTER";
+ for (int i = 9; i < 44; i++) {
+ ItemStack mobStack = menu.getStackInSlot(i);
+ if (mobStack == null || mobStack.getItem() != Items.skull) continue;
+ Matcher matcher = MOB_DISPLAY_NAME_PATTERN.matcher(mobStack.getDisplayName());
+ if (!matcher.matches()) continue;
+ String name = matcher.group("name");
+ int level = parseIntIgnoringCommas(matcher.group("level"));
+ List<String> mobLore = getLore(mobStack);
+ int coins = 0, xp = 0, combatXp = 0;
+ List<MobLootRecipe.MobDrop> drops = new ArrayList<>();
+ for (String loreLine : mobLore) {
+ Matcher loreMatcher = LORE_PATTERN.matcher(loreLine);
+ if (!loreMatcher.matches()) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
+ "[WARNING] Unknown lore line: " + loreLine));
+ continue;
+ }
+ if (loreMatcher.group("coins") != null)
+ coins = parseIntIgnoringCommas(loreMatcher.group("coins"));
+ if (loreMatcher.group("combatxp") != null)
+ combatXp = parseIntIgnoringCommas(loreMatcher.group("combatxp"));
+ if (loreMatcher.group("xp") != null)
+ xp = parseIntIgnoringCommas(loreMatcher.group("xp"));
+ if (loreMatcher.group("dropName") != null) {
+ String dropName = loreMatcher.group("dropName");
+ List<JsonObject> possibleItems = neu.manager.getItemInformation().values().stream().filter(it -> it.get(
+ "displayname").getAsString().equals(dropName)).collect(Collectors.toList());
+ if (possibleItems.size() != 1) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
+ "[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine));
+ continue;
+ }
+ Ingredient item = new Ingredient(neu.manager, possibleItems.get(0).get("internalname").getAsString());
+ String chance = loreMatcher.group("dropChances") != null
+ ? loreMatcher.group("dropChances")
+ : loreMatcher.group("dropCount");
+ drops.add(new MobLootRecipe.MobDrop(item, chance, new ArrayList<>()));
+ }
+ if (loreMatcher.group("missing") != null) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
+ "[WARNING] You are missing Bestiary levels for drop: " + loreLine));
- private void attemptToSaveBestiary(IInventory menu) {
- if (!menu.getDisplayName().getUnformattedText().contains("➜")) return;
- ItemStack backArrow = menu.getStackInSlot(48);
- if (backArrow == null || backArrow.getItem() != Items.arrow) return;
- if (!getLore(backArrow).stream().anyMatch(it -> it.startsWith("§7To Bestiary ➜"))) return;
- List<NeuRecipe> recipes = new ArrayList<>();
- for (int i = 9; i < 44; i++) {
- ItemStack mobStack = menu.getStackInSlot(i);
- if (mobStack == null || mobStack.getItem() != Items.skull) continue;
- Matcher matcher = MOB_DISPLAY_NAME_PATTERN.matcher(mobStack.getDisplayName());
- if (!matcher.matches()) continue;
- String name = matcher.group("name");
- int level = parseIntIgnoringCommas(matcher.group("level"));
- List<String> mobLore = getLore(mobStack);
- int coins = 0, xp = 0, combatXp = 0;
- List<MobLootRecipe.MobDrop> drops = new ArrayList<>();
+ }
+ }
+ recipes.add(new MobLootRecipe(
+ new Ingredient(neu.manager, internalMobName, 1),
+ drops,
+ level,
+ coins,
+ xp,
+ combatXp,
+ name,
+ null,
+ new ArrayList<>(),
+ "unknown"
+ ));
+ }
+ boolean saved = false;
+ try {
+ saved = saveRecipes(internalMobName, recipes);
+ } catch (IOException e) {
+ }
+ if (!saved)
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("" +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
+ EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
+ EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD +
+ " Failed to save recipe. Does the item already exist?")); // TODO: MERGE CODE OVER
+ }
- for (String loreLine : mobLore) {
- Matcher loreMatcher = LORE_PATTERN.matcher(loreLine);
- if (!loreMatcher.matches()) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("[WARNING] Unknown lore line: " + loreLine));
- continue;
- }
- if (loreMatcher.group("coins") != null)
- coins = parseIntIgnoringCommas(loreMatcher.group("coins"));
- if (loreMatcher.group("combatxp") != null)
- combatXp = parseIntIgnoringCommas(loreMatcher.group("combatxp"));
- if (loreMatcher.group("xp") != null)
- xp = parseIntIgnoringCommas(loreMatcher.group("xp"));
- if (loreMatcher.group("dropName") != null) {
- String dropName = loreMatcher.group("dropName");
- List<JsonObject> possibleItems = neu.manager.getItemInformation().values().stream().filter(it -> it.get("displayname").getAsString().equals(dropName)).collect(Collectors.toList());
- if (possibleItems.size() != 1) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("[WARNING] Could not parse drop, ambiguous or missing item information: " + loreLine));
- continue;
- }
- Ingredient item = new Ingredient(neu.manager, possibleItems.get(0).get("internalname").getAsString());
- String chance = loreMatcher.group("dropChances") != null ? loreMatcher.group("dropChances") : loreMatcher.group("dropCount");
- drops.add(new MobLootRecipe.MobDrop(item, chance, new ArrayList<>()));
- }
- if (loreMatcher.group("missing") != null) {
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("[WARNING] You are missing Bestiary levels for drop: " + loreLine));
+ private int parseIntIgnoringCommas(String text) {
+ return Integer.parseInt(text.replace(",", ""));
+ }
- }
- }
- recipes.add(new MobLootRecipe(drops, level, coins, xp, combatXp, name, null, new ArrayList<>()));
- }
- boolean saved = false;
- try {
- saved = saveRecipes(menu.getDisplayName().getUnformattedText().split("➜")[1].toUpperCase(Locale.ROOT).trim() + "_MONSTER", recipes);
- } catch (IOException e) {
- }
- if (!saved)
- Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("" +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " ERROR " +
- EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + EnumChatFormatting.OBFUSCATED + "#" +
- EnumChatFormatting.RESET + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + " Failed to save recipe. Does the item already exist?")); // TODO: MERGE CODE OVER
- }
-
- private int parseIntIgnoringCommas(String text) {
- return Integer.parseInt(text.replace(",", ""));
- }
-
- /*{
- id: "minecraft:skull",
- Count: 1b,
- tag: {
- overrideMeta: 1b,
- SkullOwner: {
- Id: "2005daad-730b-363c-abae-e6f3830816fb",
- Properties: {
- textures: [{
- Value: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTZjMGIzNmQ1M2ZmZjY5YTQ5YzdkNmYzOTMyZjJiMGZlOTQ4ZTAzMjIyNmQ1ZTgwNDVlYzU4NDA4YTM2ZTk1MSJ9fX0="
- }]
- }
- },
- display: {
- Lore: ["§7Coins per Kill: §610", "§7Combat Exp: §340", "§7XP Orbs: §312", "", "§7Kills: §a990", "§7Deaths: §a2", "", "§fCommon Loot", "§8 ■ §7§fEnder Pearl §8x1-3", "", "§9Rare Loot", "§8 ■ §7§aEnchanted Ender Pearl §8(§a1%§8)", "", "§6Legendary Loot", "§8 ■ §7§7[Lvl 1] §aEnderman §8(§a0.02%§8)", "§8 ■ §7§7[Lvl 1] §fEnderman §8(§a0.05%§8)", "§8 ■ §7§5Ender Helmet §8(§a0.1%§8)", "§8 ■ §7§5Ender Boots §8(§a0.1%§8)", "§8 ■ §7§5Ender Leggings §8(§a0.1%§8)", "§8 ■ §7§5Ender Chestplate §8(§a0.1%§8)", "", "§dRNGesus Loot", " §8■ §c???"],
- Name: "§8[§7Lv42§8] §fEnderman"
- },
- AttributeModifiers: []
- },
- Damage: 3s
+ /*{
+ id: "minecraft:skull",
+ Count: 1b,
+ tag: {
+ overrideMeta: 1b,
+ SkullOwner: {
+ Id: "2005daad-730b-363c-abae-e6f3830816fb",
+ Properties: {
+ textures: [{
+ Value: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTZjMGIzNmQ1M2ZmZjY5YTQ5YzdkNmYzOTMyZjJiMGZlOTQ4ZTAzMjIyNmQ1ZTgwNDVlYzU4NDA4YTM2ZTk1MSJ9fX0="
+ }]
+ }
+ },
+ display: {
+ Lore: ["§7Coins per Kill: §610", "§7Combat Exp: §340", "§7XP Orbs: §312", "", "§7Kills: §a990", "§7Deaths: §a2", "", "§fCommon Loot", "§8 ■ §7§fEnder Pearl §8x1-3", "", "§9Rare Loot", "§8 ■ §7§aEnchanted Ender Pearl §8(§a1%§8)", "", "§6Legendary Loot", "§8 ■ §7§7[Lvl 1] §aEnderman §8(§a0.02%§8)", "§8 ■ §7§7[Lvl 1] §fEnderman §8(§a0.05%§8)", "§8 ■ §7§5Ender Helmet §8(§a0.1%§8)", "§8 ■ §7§5Ender Boots §8(§a0.1%§8)", "§8 ■ §7§5Ender Leggings §8(§a0.1%§8)", "§8 ■ §7§5Ender Chestplate §8(§a0.1%§8)", "", "§dRNGesus Loot", " §8■ §c???"],
+ Name: "§8[§7Lv42§8] §fEnderman"
+ },
+ AttributeModifiers: []
+ },
+ Damage: 3s
}*/
- public boolean saveRecipes(String relevantItem, List<NeuRecipe> recipes) throws IOException {
- JsonObject outputJson = neu.manager.readJsonDefaultDir(relevantItem + ".json");
- if (outputJson == null) return false;
- outputJson.addProperty("clickcommand", "viewrecipe");
- JsonArray array = new JsonArray();
- for (NeuRecipe recipe : recipes) {
- array.add(recipe.serialize());
- }
- outputJson.add("recipes", array);
- neu.manager.writeJsonDefaultDir(outputJson, relevantItem + ".json");
- neu.manager.loadItem(relevantItem);
- return true;
- }
-
+ public boolean saveRecipes(String relevantItem, List<NeuRecipe> recipes) throws IOException {
+ JsonObject outputJson = neu.manager.readJsonDefaultDir(relevantItem + ".json");
+ if (outputJson == null) return false;
+ outputJson.addProperty("clickcommand", "viewrecipe");
+ JsonArray array = new JsonArray();
+ for (NeuRecipe recipe : recipes) {
+ array.add(recipe.serialize());
+ }
+ outputJson.add("recipes", array);
+ neu.manager.writeJsonDefaultDir(outputJson, relevantItem + ".json");
+ neu.manager.loadItem(relevantItem);
+ return true;
+ }
- public ForgeRecipe parseSingleForgeRecipe(IInventory chest) {
- int durationInSeconds = -1;
- List<Ingredient> inputs = new ArrayList<>();
- Ingredient output = null;
- for (int i = 0; i < chest.getSizeInventory(); i++) {
- int col = i % 9;
- ItemStack itemStack = chest.getStackInSlot(i);
- if (itemStack == null) continue;
- String name = Utils.cleanColour(itemStack.getDisplayName());
- String internalId = neu.manager.getInternalNameForItem(itemStack);
- Ingredient ingredient = null;
- if (itemStack.getDisplayName().endsWith(COINS_SUFFIX)) {
- int coinCost = Integer.parseInt(
- name.substring(0, name.length() - COINS_SUFFIX.length())
- .replace(",", ""));
- ingredient = Ingredient.coinIngredient(neu.manager, coinCost);
- } else if (internalId != null) {
- ingredient = new Ingredient(neu.manager, internalId, itemStack.stackSize);
- }
- if (ingredient == null) continue;
- if (col < 4) {
- inputs.add(ingredient);
- } else {
- output = ingredient;
- }
- }
- if (output == null || inputs.isEmpty()) return null;
- if (savedForgingDurations.containsKey(output.getInternalItemId()))
- durationInSeconds = parseDuration(savedForgingDurations.get(output.getInternalItemId()));
- return new ForgeRecipe(neu.manager, new ArrayList<>(Ingredient.mergeIngredients(inputs)), output, durationInSeconds, -1);
- }
+ public ForgeRecipe parseSingleForgeRecipe(IInventory chest) {
+ int durationInSeconds = -1;
+ List<Ingredient> inputs = new ArrayList<>();
+ Ingredient output = null;
+ for (int i = 0; i < chest.getSizeInventory(); i++) {
+ int col = i % 9;
+ ItemStack itemStack = chest.getStackInSlot(i);
+ if (itemStack == null) continue;
+ String name = Utils.cleanColour(itemStack.getDisplayName());
+ String internalId = neu.manager.getInternalNameForItem(itemStack);
+ Ingredient ingredient = null;
+ if (itemStack.getDisplayName().endsWith(COINS_SUFFIX)) {
+ int coinCost = Integer.parseInt(
+ name.substring(0, name.length() - COINS_SUFFIX.length())
+ .replace(",", ""));
+ ingredient = Ingredient.coinIngredient(neu.manager, coinCost);
+ } else if (internalId != null) {
+ ingredient = new Ingredient(neu.manager, internalId, itemStack.stackSize);
+ }
+ if (ingredient == null) continue;
+ if (col < 4) {
+ inputs.add(ingredient);
+ } else {
+ output = ingredient;
+ }
+ }
+ if (output == null || inputs.isEmpty()) return null;
+ if (savedForgingDurations.containsKey(output.getInternalItemId()))
+ durationInSeconds = parseDuration(savedForgingDurations.get(output.getInternalItemId()));
+ return new ForgeRecipe(
+ neu.manager,
+ new ArrayList<>(Ingredient.mergeIngredients(inputs)),
+ output,
+ durationInSeconds,
+ -1
+ );
+ }
- private static Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
- put('d', 60 * 60 * 24);
- put('h', 60 * 60);
- put('m', 60);
- put('s', 1);
- }};
+ private static Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
+ put('d', 60 * 60 * 24);
+ put('h', 60 * 60);
+ put('m', 60);
+ put('s', 1);
+ }};
- public int parseDuration(String durationString) {
- String[] parts = durationString.split(" ");
- int timeInSeconds = 0;
- for (String part : parts) {
- char signifier = part.charAt(part.length() - 1);
- int value = Integer.parseInt(part.substring(0, part.length() - 1));
- if (!durationSuffixLengthMap.containsKey(signifier)) {
- return -1;
- }
- timeInSeconds += value * durationSuffixLengthMap.get(signifier);
- }
- return timeInSeconds;
- }
+ public int parseDuration(String durationString) {
+ String[] parts = durationString.split(" ");
+ int timeInSeconds = 0;
+ for (String part : parts) {
+ char signifier = part.charAt(part.length() - 1);
+ int value = Integer.parseInt(part.substring(0, part.length() - 1));
+ if (!durationSuffixLengthMap.containsKey(signifier)) {
+ return -1;
+ }
+ timeInSeconds += value * durationSuffixLengthMap.get(signifier);
+ }
+ return timeInSeconds;
+ }
- private void parseAllForgeItemMetadata(IInventory chest) {
- for (int i = 0; i < chest.getSizeInventory(); i++) {
- ItemStack stack = chest.getStackInSlot(i);
- if (stack == null) continue;
- String internalName = neu.manager.getInternalNameForItem(stack);
- if (internalName == null) continue;
- List<String> tooltip = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
- String durationInfo = null;
- for (String s : tooltip) {
- String info = Utils.cleanColour(s);
- if (info.startsWith(DURATION)) {
- durationInfo = info.substring(DURATION.length());
- }
- }
- if (durationInfo != null)
- savedForgingDurations.put(internalName, durationInfo);
- }
- }
+ private void parseAllForgeItemMetadata(IInventory chest) {
+ for (int i = 0; i < chest.getSizeInventory(); i++) {
+ ItemStack stack = chest.getStackInSlot(i);
+ if (stack == null) continue;
+ String internalName = neu.manager.getInternalNameForItem(stack);
+ if (internalName == null) continue;
+ List<String> tooltip = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
+ String durationInfo = null;
+ for (String s : tooltip) {
+ String info = Utils.cleanColour(s);
+ if (info.startsWith(DURATION)) {
+ durationInfo = info.substring(DURATION.length());
+ }
+ }
+ if (durationInfo != null)
+ savedForgingDurations.put(internalName, durationInfo);
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
new file mode 100644
index 00000000..2244c5fc
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -0,0 +1,20 @@
+package io.github.moulberry.notenoughupdates.util;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.nbt.NBTTagString;
+
+import java.util.List;
+
+public class ItemUtils {
+ public static void appendLore(ItemStack is, List<String> moreLore) {
+ NBTTagCompound display = is.getTagCompound().getCompoundTag("display");
+ NBTTagList lore = display.getTagList("Lore", 8);
+ for (String s : moreLore) {
+ lore.appendTag(new NBTTagString(s));
+ }
+ display.setTag("Lore", lore);
+ is.getTagCompound().setTag("display", display);
+ }
+}