aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
diff options
context:
space:
mode:
authorRoman / Nea <roman.graef@gmail.com>2022-04-18 17:33:32 +0200
committerGitHub <noreply@github.com>2022-04-18 17:33:32 +0200
commit2692193e54e4dd6c0117dcdb85368dc83bb04f1a (patch)
tree96f01454c404ac04a46ea0d9bf684c7dc5619a57 /src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
parent9fe86ccb4d30b78826e513a6576027ca6e4c1600 (diff)
downloadnotenoughupdates-2692193e54e4dd6c0117dcdb85368dc83bb04f1a.tar.gz
notenoughupdates-2692193e54e4dd6c0117dcdb85368dc83bb04f1a.tar.bz2
notenoughupdates-2692193e54e4dd6c0117dcdb85368dc83bb04f1a.zip
Mob loot recipe PR (#81)
* entity renderer (somewhat functionaL) * more modifiers and entities * Fix cookie fuckup * add neu repo as resource pack, cause why not at this point * add tabs, because i can * add extra skin parts and make less tabs * hot tall men * fix texture offsets and also parts:true * some untested changes * still broken, but better (just like me (stop being edgy nea ( no u )))) * stuff (with er skeletons * niceities * skytils interop * horseys * horseys ouch * panos * stupid tests :angery: * NPE * add drop chance * colored leather armo * finish off * move shit into hover cause items look pretty terrible * Update 2.1.md * better recipe display name * always show mobs toggle * moving parts
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java169
1 files changed, 151 insertions, 18 deletions
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 46aff6c4..e5028146 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeGenerator.java
@@ -9,9 +9,11 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.init.Items;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -19,10 +21,10 @@ import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.input.Keyboard;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class RecipeGenerator {
public static final String DURATION = "Duration: ";
@@ -81,7 +83,7 @@ public class RecipeGenerator {
" seconds (no QF) ."));
boolean saved = false;
try {
- saved = saveRecipe(recipe);
+ saved = saveRecipes(recipe.getOutput().getInternalItemId(), Collections.singletonList(recipe));
} catch (IOException e) {
}
if (!saved)
@@ -93,21 +95,152 @@ public class RecipeGenerator {
" Failed to save recipe. Does the item already exist?"));
}
}
+ if (saveRecipe) attemptToSaveBestiary(menu);
}
- public boolean saveRecipe(NeuRecipe recipe) throws IOException {
- JsonObject recipeJson = recipe.serialize();
- for (Ingredient i : recipe.getOutputs()) {
- if (i.isCoins()) continue;
- JsonObject outputJson = neu.manager.readJsonDefaultDir(i.getInternalItemId() + ".json");
- if (outputJson == null) return false;
- outputJson.addProperty("clickcommand", "viewrecipe");
- JsonArray array = new JsonArray();
- array.add(recipeJson);
- outputJson.add("recipes", array);
- neu.manager.writeJsonDefaultDir(outputJson, i.getInternalItemId() + ".json");
- neu.manager.loadItem(i.getInternalItemId());
+ 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\\?\\?\\?)|" +
+ "" +
+ ")$");
+
+ 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));
+
+ }
+ }
+ 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
+ }
+
+ 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
+}*/
+ 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;
}
@@ -149,7 +282,7 @@ public class RecipeGenerator {
);
}
- private static final Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
+ private static Map<Character, Integer> durationSuffixLengthMap = new HashMap<Character, Integer>() {{
put('d', 60 * 60 * 24);
put('h', 60 * 60);
put('m', 60);