From f73f535b75a558cbe44a9791058f4335ba3f4401 Mon Sep 17 00:00:00 2001 From: nea Date: Thu, 14 Apr 2022 03:51:14 +0200 Subject: panos --- .../profileviewer/GuiProfileViewer.java | 36 +- .../notenoughupdates/profileviewer/Panorama.java | 38 ++ .../notenoughupdates/recipes/MobLootRecipe.java | 57 ++- .../notenoughupdates/recipes/RecipeGenerator.java | 522 +++++++++++---------- .../moulberry/notenoughupdates/util/ItemUtils.java | 20 + 5 files changed, 375 insertions(+), 298 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java (limited to 'src/main') 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 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 extra; + private ItemStack itemStack; + public MobDrop(Ingredient drop, String chance, List 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 drops; private final int coins; private final int combatXp; @@ -58,7 +65,12 @@ public class MobLootRecipe implements NeuRecipe { private final List extra; private EntityLivingBase entityLivingBase; + private final String panoName; + + private ResourceLocation[] panos = null; + public MobLootRecipe( + Ingredient mobIngredient, List drops, int level, int coins, @@ -66,8 +78,10 @@ public class MobLootRecipe implements NeuRecipe { int combatXp, String name, String render, - List extra + List 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 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 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 savedForgingDurations = new HashMap<>(); + private final Map 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 getLore(ItemStack item) { + NBTTagList loreTag = item.getTagCompound().getCompoundTag("display").getTagList("Lore", 8); + List loreList = new ArrayList<>(); + for (int i = 0; i < loreTag.tagCount(); i++) { + loreList.add(loreTag.getStringTagAt(i)); + } + return loreList; + } - private List getLore(ItemStack item) { - NBTTagList loreTag = item.getTagCompound().getCompoundTag("display").getTagList("Lore", 8); - List 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(?\\d+)§8] (?.*)$"); + // §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(?[,\\d]+)|" + + "§7Combat Exp: §3(?[,\\d]+)|" + + "§7XP Orbs: §3(?[,\\d]+)|" + + "§8 ■ (?:§7)?(?(?:§.)?.+?)(?: §8\\(§a(?[\\d.<]+%)§8\\)| §8(?x.*))?|" + + "§7Kills: §a[,\\d]+|" + + "§.[a-zA-Z]+ Loot|" + + "§7Deaths: §a[,\\d]+|" + + " §8■ (?§c\\?\\?\\?)|" + + "" + + ")$"); - // §8[§7Lv1§8] §fZombie Villager - private static final Pattern MOB_DISPLAY_NAME_PATTERN = Pattern.compile("^§8\\[§7Lv(?\\d+)§8] (?.*)$"); - // §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(?[,\\d]+)|" + - "§7Combat Exp: §3(?[,\\d]+)|" + - "§7XP Orbs: §3(?[,\\d]+)|" + - "§8 ■ (?:§7)?(?(?:§.)?.+?)(?: §8\\(§a(?[\\d.<]+%)§8\\)| §8(?x.*))?|" + - "§7Kills: §a[,\\d]+|" + - "§.[a-zA-Z]+ Loot|" + - "§7Deaths: §a[,\\d]+|" + - " §8■ (?§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 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 mobLore = getLore(mobStack); + int coins = 0, xp = 0, combatXp = 0; + List 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 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 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 mobLore = getLore(mobStack); - int coins = 0, xp = 0, combatXp = 0; - List 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 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 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 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 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 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 durationSuffixLengthMap = new HashMap() {{ - put('d', 60 * 60 * 24); - put('h', 60 * 60); - put('m', 60); - put('s', 1); - }}; + private static Map durationSuffixLengthMap = new HashMap() {{ + 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 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 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 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); + } +} -- cgit