aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java29
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java13
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java81
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java18
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/EssenceUpgrades.java501
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java17
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java16
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/gui/essence_upgrades_tall.pngbin0 -> 884 bytes
15 files changed, 667 insertions, 31 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
index a773abdc..6811067f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java
@@ -49,7 +49,7 @@ import java.util.Set;
public class ItemPriceInformation {
private static File file;
- private static HashSet<String> auctionableItems = null;
+ private static HashSet<String> auctionableItems;
private static Gson gson;
private static final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US));
@@ -325,7 +325,32 @@ public class ItemPriceInformation {
if (shouldShow) {
tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Required Items:");
for (JsonElement item : itemsObject.get(nextStarLevelString).getAsJsonArray()) {
- tooltip.add(" - " + item.getAsString());
+ if (item.getAsString().contains("§")) {
+ //TODO show outdated repo notification when 2.1.1 releases
+ tooltip.add(" - " + item.getAsString());
+ continue;
+ }
+ String itemString = item.getAsString();
+ int colon = itemString.indexOf(':');
+ if (colon != -1) {
+ String amount = itemString.substring(colon + 1);
+ String requiredItem = itemString.substring(0, colon);
+ if (requiredItem.equals("SKYBLOCK_COIN")) {
+ tooltip.add(" - " + EnumChatFormatting.GOLD + amount + " Coins");
+ }
+
+ if (NotEnoughUpdates.INSTANCE.manager.isValidInternalName(requiredItem)) {
+ JsonObject itemObject = NotEnoughUpdates.INSTANCE.manager.
+ createItemResolutionQuery().
+ withKnownInternalName(requiredItem).
+ resolveToItemListJson();
+
+ if (itemObject != null && itemObject.has("displayname")) {
+ String displayName = itemObject.get("displayname").getAsString();
+ tooltip.add(" - " + displayName + EnumChatFormatting.DARK_GRAY + " x" + amount);
+ }
+ }
+ }
}
} else {
tooltip.add(EnumChatFormatting.DARK_GRAY + "[CTRL to show required items]");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
index 5fe902fb..a30ca08a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java
@@ -888,7 +888,11 @@ public class NEUManager {
break;
case "viewpotion":
neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT));
+ break;
+ default:
+ displayGuiItemRecipe(internalName);
}
+
}
public void showRecipe(String internalName) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index c1190b2b..4c8ac2b9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -319,7 +319,7 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(new SignCalculator());
MinecraftForge.EVENT_BUS.register(TrophyRewardOverlay.getInstance());
MinecraftForge.EVENT_BUS.register(PowerStoneStatsDisplay.getInstance());
- MinecraftForge.EVENT_BUS.register(new AntiCoopAdd());
+ MinecraftForge.EVENT_BUS.register(AntiCoopAdd.getInstance());
MinecraftForge.EVENT_BUS.register(AbiphoneWarning.getInstance());
MinecraftForge.EVENT_BUS.register(new BetterContainers());
MinecraftForge.EVENT_BUS.register(AuctionBINWarning.getInstance());
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
index 7ea9cd00..c19c4826 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java
@@ -118,4 +118,17 @@ public class StringUtils {
String firstLetter = ("" + text.charAt(0)).toUpperCase();
return firstLetter + text.substring(1);
}
+
+ public static boolean isNumeric(String string) {
+ if (string == null || string.isEmpty()) {
+ return false;
+ }
+
+ for (char c : string.toCharArray()) {
+ if (!Character.isDigit(c)) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
index 6a94c0b3..fcd320fa 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ChatListener.java
@@ -42,6 +42,7 @@ import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -125,7 +126,8 @@ public class ChatListener {
String startsWith = null;
boolean partyOrGuildChat = false;
- if (chatComponent.getSiblings().get(0).getChatStyle().getChatClickEvent().getValue().startsWith("/viewprofile")) {
+ List<IChatComponent> siblings = chatComponent.getSiblings();
+ if (!siblings.isEmpty() && siblings.get(0).getChatStyle().getChatClickEvent().getValue().startsWith("/viewprofile")) {
startsWith = "/viewprofile";
partyOrGuildChat = true;
} else {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
index 949358ad..ca841590 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -1254,11 +1254,13 @@ public class RenderListener {
if (stack.getTagCompound().getCompoundTag("display").hasKey("Lore", 9)) {
int stars = Utils.getNumberOfStars(stack);
if (stars == 0) continue;
- String starsStr = "" + stars;
NBTTagList lore = stack.getTagCompound().getCompoundTag("display").getTagList("Lore", 8);
int costIndex = 10000;
- id = NotEnoughUpdates.INSTANCE.manager.getInternalnameFromNBT(stack.getTagCompound());
+ id = NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withItemStack(stack)
+ .resolveInternalName();
if (jsonObject.has(id)) {
jsonObject.remove(id);
}
@@ -1267,39 +1269,72 @@ public class RenderListener {
if (entry.equals("§7Cost")) {
costIndex = j;
}
-
if (j > costIndex) {
entry = entry.trim();
-
- int countIndex = entry.lastIndexOf(" §8x");
-
- String upgradeName = entry;
- String amount = "1";
- if (countIndex != -1) {
- upgradeName = entry.substring(0, countIndex);
- // +4 to account for " §8x"
- amount = entry.substring(countIndex + 4);
+ int index = entry.lastIndexOf('x');
+ String item, amountString;
+ if (index < 0) {
+ item = entry.trim() + " x1";
+ amountString = "x1";
+ } else {
+ amountString = entry.substring(index);
+ item = entry.substring(0, index).trim();
}
-
- if (upgradeName.endsWith(" Essence")) {
- // First 2 chars are control code
- // [EssenceCount, EssenceType, "Essence"]
- String[] upgradeNameSplit = upgradeName.substring(2).split(" ");
- newEntry.addProperty("type", upgradeNameSplit[1]);
- newEntry.addProperty(starsStr, Integer.parseInt(upgradeNameSplit[0].replace(",", "")));
+ item = item.substring(0, item.length() - 3);
+ int amount = Integer.parseInt(amountString.trim().replace("x", "").replace(",", ""));
+ if (item.endsWith("Essence")) {
+ int index2 = entry.indexOf("Essence");
+ String typeAndAmount = item.substring(0, index2).trim().substring(2);
+ int whitespaceIndex = typeAndAmount.indexOf(' ');
+ int essenceAmount = Integer.parseInt(typeAndAmount
+ .substring(0, whitespaceIndex)
+ .replace(",", ""));
+ newEntry.add("type", new JsonPrimitive(typeAndAmount.substring(whitespaceIndex + 1)));
+ if (stars == -1) {
+ newEntry.add("dungeonize", new JsonPrimitive(essenceAmount));
+ } else {
+ newEntry.add(String.valueOf(stars), new JsonPrimitive(essenceAmount));
+ }
+ } else if (item.endsWith("Coins")) {
+ int index2 = entry.indexOf("Coins");
+ String coinsAmount = item.substring(0, index2).trim().substring(2);
+ if (!newEntry.has("items")) {
+ newEntry.add("items", new JsonObject());
+ }
+ if (!newEntry.get("items").getAsJsonObject().has(String.valueOf(stars))) {
+ newEntry.get("items").getAsJsonObject().add(String.valueOf(stars), new JsonArray());
+ }
+ newEntry
+ .get("items")
+ .getAsJsonObject()
+ .get(String.valueOf(stars))
+ .getAsJsonArray()
+ .add(new JsonPrimitive("SKYBLOCK_COIN:" + coinsAmount.replace(",", "")));
} else {
+ String itemString = "_";
+ for (Map.Entry<String, JsonObject> itemEntry : NotEnoughUpdates.INSTANCE.manager
+ .getItemInformation()
+ .entrySet()) {
+
+ if (itemEntry.getValue().has("displayname")) {
+ String name = itemEntry.getValue().get("displayname").getAsString();
+ if (name.equals(item)) {
+ itemString = itemEntry.getKey() + ":" + amount;
+ }
+ }
+ }
if (!newEntry.has("items")) {
newEntry.add("items", new JsonObject());
}
- if (!newEntry.get("items").getAsJsonObject().has(starsStr)) {
- newEntry.get("items").getAsJsonObject().add(starsStr, new JsonArray());
+ if (!newEntry.get("items").getAsJsonObject().has(String.valueOf(stars))) {
+ newEntry.get("items").getAsJsonObject().add(String.valueOf(stars), new JsonArray());
}
newEntry
.get("items")
.getAsJsonObject()
- .get(starsStr)
+ .get(String.valueOf(stars))
.getAsJsonArray()
- .add(new JsonPrimitive(upgradeName + (upgradeName.contains("Coins") ? "" : (" §8x" + amount))));
+ .add(new JsonPrimitive(itemString));
}
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
index 70ac4489..aaa13d39 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AntiCoopAdd.java
@@ -27,12 +27,19 @@ import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
+import net.minecraft.network.play.client.C01PacketChatMessage;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class AntiCoopAdd {
+ private static final AntiCoopAdd INSTANCE = new AntiCoopAdd();
+
+ public static AntiCoopAdd getInstance() {
+ return INSTANCE;
+ }
+
@SubscribeEvent
public void onMouseClick(SlotClickEvent event) {
if (!NotEnoughUpdates.INSTANCE.config.misc.coopWarning) return;
@@ -59,4 +66,15 @@ public class AntiCoopAdd {
event.setCanceled(true);
}
}
+
+ public Boolean onPacketChatMessage(C01PacketChatMessage packet) {
+ if (!NotEnoughUpdates.INSTANCE.config.misc.coopWarning) return false;
+
+ String message = packet.getMessage().toLowerCase();
+ if (message.startsWith("/hypixelcommand:coopadd")) {
+ Utils.addChatMessage("§e[NEU] You just entered a malicious looking Co-op add command! If you truly want to add someone to your coop, type §e/coopadd <name>");
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java
index 44d7eef6..4bb91109 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinNetHandlerPlayClient.java
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.mixins;
import io.github.moulberry.notenoughupdates.events.SpawnParticleEvent;
+import io.github.moulberry.notenoughupdates.miscfeatures.AntiCoopAdd;
import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns;
@@ -128,6 +129,9 @@ public class MixinNetHandlerPlayClient {
}
if (packet instanceof C01PacketChatMessage) {
NewApiKeyHelper.getInstance().hookPacketChatMessage((C01PacketChatMessage) packet);
+ if (AntiCoopAdd.getInstance().onPacketChatMessage((C01PacketChatMessage) packet)) {
+ ci.cancel();
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
index 78bb0f95..dbf79bce 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java
@@ -262,7 +262,7 @@ public class Misc {
@Expose
@ConfigOption(
name = "Enable Coop Warning",
- desc = "Asks for confirmation when clicking the coop diamond in profile menu"
+ desc = "Asks for confirmation when clicking the coop diamond in profile menu and prevents 'wrong' /coopadd commands"
)
@ConfigEditorBoolean
public boolean coopWarning = true;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/EssenceUpgrades.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/EssenceUpgrades.java
new file mode 100644
index 00000000..0c4bfbdf
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/EssenceUpgrades.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.recipes;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NEUManager;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.ItemUtils;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EssenceUpgrades implements NeuRecipe {
+
+ private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/essence_upgrades_tall.png");
+ private static final List<RenderLocation> buttonLocations = new ArrayList<RenderLocation>() {{
+ add(new RenderLocation(20, 20));
+ add(new RenderLocation(40, 20));
+ add(new RenderLocation(60, 20));
+ add(new RenderLocation(80, 20));
+ add(new RenderLocation(100, 20));
+ add(new RenderLocation(120, 20));
+ add(new RenderLocation(140, 20));
+
+ add(new RenderLocation(10, 40));
+ add(new RenderLocation(30, 40));
+ add(new RenderLocation(50, 40));
+ add(new RenderLocation(70, 40));
+ add(new RenderLocation(90, 40));
+ add(new RenderLocation(110, 40));
+ add(new RenderLocation(130, 40));
+ add(new RenderLocation(150, 40));
+ }};
+
+ private static final List<RenderLocation> slotLocations = new ArrayList<RenderLocation>() {{
+ add(new RenderLocation(20, 60));
+ add(new RenderLocation(45, 60));
+ add(new RenderLocation(70, 60));
+
+ add(new RenderLocation(20, 85));
+ add(new RenderLocation(45, 85));
+ add(new RenderLocation(70, 85));
+
+ add(new RenderLocation(20, 110));
+ add(new RenderLocation(45, 110));
+ add(new RenderLocation(70, 110));
+ }};
+
+ private static final Pattern loreStatPattern = Pattern.compile("^.+: §.\\+(?<value>[\\d.]+).*$");
+
+ private final Ingredient output;
+ private final ItemStack initialItemStack;
+ private final Map<Integer, TierUpgrade> tierUpgradeMap;
+ private final int amountOfTiers;
+ private int selectedTier;
+ private static final int outputX = 123;
+ private static final int outputY = 65;
+ private List<RecipeSlot> slots;
+ private GuiItemRecipe guiItemRecipe;
+
+ public EssenceUpgrades(Ingredient output, Map<Integer, TierUpgrade> tierUpgradeMap) {
+ this.output = output;
+ this.tierUpgradeMap = tierUpgradeMap;
+
+ initialItemStack = output.getItemStack().copy();
+ amountOfTiers = tierUpgradeMap.keySet().size();
+ selectedTier = amountOfTiers;
+ slots = new ArrayList<>();
+ }
+
+ /**
+ * Parses an entry from essencecosts.json to a NeuRecipe, containing information on how to upgrade the item with Essence
+ *
+ * @param entry Entry from essencecosts.json
+ * @return parsed NeuRecipe
+ * @see Constants#parseEssenceCosts()
+ */
+ public static @Nullable NeuRecipe parseFromEssenceCostEntry(Map.Entry<String, JsonElement> entry) {
+ NEUManager manager = NotEnoughUpdates.INSTANCE.manager;
+ if (!manager.isValidInternalName(entry.getKey())) {
+ System.err.println("Invalid internalname: " + entry.getKey());
+ return null;
+ }
+
+ String internalName = entry.getKey();
+ JsonObject jsonObject = entry.getValue().getAsJsonObject();
+
+ Ingredient output = new Ingredient(manager, internalName);
+
+ if (!jsonObject.has("type")) {
+ System.err.println("Invalid essence entry for: " + internalName);
+ System.err.println("Missing: Essence type");
+ return null;
+ }
+ String essenceType = jsonObject.get("type").getAsString();
+
+ Map<Integer, TierUpgrade> upgradeMap = new HashMap<>();
+ for (Map.Entry<String, JsonElement> entries : jsonObject.entrySet()) {
+ if (StringUtils.isNumeric(entries.getKey())) {
+ int tier = Integer.parseInt(entries.getKey());
+ int essenceCost = Integer.parseInt(entries.getValue().getAsString());
+ upgradeMap.put(tier, new TierUpgrade(tier, essenceType, essenceCost, null));
+ } else if (entries.getKey().equals("items")) {
+ for (Map.Entry<String, JsonElement> requiredItems : entries
+ .getValue()
+ .getAsJsonObject()
+ .entrySet()) {
+ Integer tier = Integer.parseInt(requiredItems.getKey());
+ Map<String, Integer> items = new HashMap<>();
+ for (JsonElement element : requiredItems.getValue().getAsJsonArray()) {
+ String itemString = element.getAsString();
+
+ int colon = itemString.indexOf(':');
+ if (colon != -1) {
+ String amount = itemString.substring(colon + 1);
+ String requiredItem = itemString.substring(0, colon);
+
+ items.put(requiredItem, Integer.parseInt(amount));
+ }
+ }
+ upgradeMap.get(tier).itemsRequired = items;
+ }
+ }
+ }
+ return new EssenceUpgrades(output, upgradeMap);
+ }
+
+ /**
+ * Builds a list containing all the RecipeSlots that should be rendered right now:
+ * <ul>
+ * <li>The output</li>
+ * <li>The ingredients</li>
+ * </ul>
+ *
+ * @return the list of RecipeSlots
+ * @see EssenceUpgrades#getSlots()
+ */
+ private List<RecipeSlot> buildSlotList() {
+ NEUManager manager = NotEnoughUpdates.INSTANCE.manager;
+ List<RecipeSlot> slotList = new ArrayList<>();
+
+ //output item
+ String internalName = output.getInternalItemId();
+ if (internalName == null) {
+ return slotList;
+ }
+ List<String> lore = ItemUtils.getLore(initialItemStack);
+ List<String> newLore = new ArrayList<>();
+
+ for (String loreEntry : lore) {
+ Matcher matcher = loreStatPattern.matcher(loreEntry);
+ if (matcher.matches()) {
+ String valueString = matcher.group("value");
+ if (valueString == null) {
+ newLore.add(loreEntry);
+ continue;
+ }
+
+ float value = Float.parseFloat(valueString);
+ int matchStart = matcher.start("value");
+ float newValue = value * (1 + (selectedTier / 50f));
+ StringBuilder newLine = new StringBuilder(loreEntry.substring(0, matchStart) + String.format("%.1f", newValue));
+ if (loreEntry.length() - 1 > matcher.end("value")) {
+ newLine.append(loreEntry, matcher.end("value"), loreEntry.length() - 1);
+ }
+
+ newLore.add(newLine.toString());
+ } else {
+ //simply append this entry to the new lore
+ newLore.add(loreEntry);
+ }
+ }
+ ItemUtils.setLore(output.getItemStack(), newLore);
+ output.getItemStack().setStackDisplayName(
+ initialItemStack.getDisplayName() + " " + Utils.getStarsString(selectedTier));
+ slotList.add(new RecipeSlot(outputX, outputY, output.getItemStack()));
+
+ //other required items and/or coins, if applicable
+ TierUpgrade tierUpgrade = tierUpgradeMap.get(selectedTier);
+ if (tierUpgrade == null) {
+ return slotList;
+ }
+
+ //required essence
+ String essenceInternalName = "ESSENCE_" + tierUpgrade.getEssenceType().toUpperCase(Locale.ROOT);
+ if (manager.isValidInternalName(essenceInternalName)) {
+ ItemStack essenceItemStack =
+ manager.createItemResolutionQuery().withKnownInternalName(essenceInternalName).resolveToItemStack();
+ if (essenceItemStack != null) {
+ essenceItemStack = essenceItemStack.copy();
+ essenceItemStack.setStackDisplayName(
+ EnumChatFormatting.AQUA.toString() + tierUpgrade.getEssenceRequired() + " " + EnumChatFormatting.DARK_GRAY +
+ tierUpgrade.getEssenceType() + " Essence");
+ RenderLocation renderLocation = slotLocations.get(0);
+ slotList.add(new RecipeSlot(renderLocation.getX() + 1, renderLocation.getY() + 1, essenceItemStack));
+ }
+ }
+
+ int i = 1;
+ if (tierUpgrade.getItemsRequired() != null) {
+ for (Map.Entry<String, Integer> requiredItem : tierUpgrade.getItemsRequired().entrySet()) {
+ ItemStack itemStack;
+ if (requiredItem.getKey().equals("SKYBLOCK_COIN")) {
+ Ingredient ingredient = Ingredient.coinIngredient(
+ manager,
+ requiredItem.getValue()
+ );
+ itemStack = ingredient.getItemStack();
+ } else {
+ itemStack = manager.createItemResolutionQuery().withKnownInternalName(
+ requiredItem.getKey()).resolveToItemStack();
+ if (itemStack != null) {
+ itemStack.stackSize = requiredItem.getValue();
+ }
+ }
+ if (itemStack != null) {
+ RenderLocation renderLocation = slotLocations.get(i++);
+ if (renderLocation != null) {
+ slotList.add(new RecipeSlot(renderLocation.getX() + 1, renderLocation.getY()+1, itemStack));
+ }
+ }
+ }
+ }
+
+ return slotList;
+ }
+
+ /**
+ * Draws an empty slot texture at the specified location
+ *
+ * @param x x location
+ * @param y y location
+ */
+ private void drawSlot(int x, int y) {
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
+ Utils.drawTexturedRect(
+ x,
+ y,
+ 18,
+ 18,
+ 176 / 256f,
+ 194 / 256f,
+ 0 / 256f,
+ 18 / 256f
+ );
+ }
+
+ /**
+ * Draws a button using a part of the texture
+ *
+ * @param x x location
+ * @param y y location
+ * @param selected whether the button should look like its pressed down or not
+ */
+ private void drawButton(int x, int y, boolean selected) {
+ if (selected) {
+ Utils.drawTexturedRect(
+ x,
+ y,
+ 16,
+ 16,
+ 176 / 256f,
+ 192 / 256f,
+ 34 / 256f,
+ 50 / 256f
+ );
+ } else {
+ Utils.drawTexturedRect(
+ x,
+ y,
+ 16,
+ 16,
+ 176 / 256f,
+ 192 / 256f,
+ 18 / 256f,
+ 34 / 256f
+ );
+ }
+ }
+
+ /**
+ * Draws all Buttons applicable for the item and checks if a button has been clicked on
+ *
+ * @see EssenceUpgrades#buttonLocations
+ */
+ private void drawButtons(int mouseX, int mouseY) {
+ for (int i = 0; i < amountOfTiers; i++) {
+ if (i >= buttonLocations.size()) {
+ Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
+ EnumChatFormatting.RED + "[NEU] Error: Item has more than " + buttonLocations.size() +
+ " possible star upgrades"));
+ break;
+ }
+ RenderLocation buttonLocation = buttonLocations.get(i);
+
+ int x = guiItemRecipe.guiLeft + buttonLocation.getX();
+ int y = guiItemRecipe.guiTop + buttonLocation.getY();
+
+ if (Mouse.getEventButtonState() && Utils.isWithinRect(mouseX, mouseY, x, y, 16, 16)) {
+ selectedTier = i + 1;
+ slots = buildSlotList();
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
+ GlStateManager.color(1, 1, 1, 1);
+ drawButton(x, y, i + 1 == selectedTier);
+ Utils.drawStringCentered(
+ String.valueOf(i + 1),
+ Minecraft.getMinecraft().fontRendererObj,
+ x + 8,
+ y + 9,
+ false,
+ 0x2d4ffc
+ );
+ }
+ }
+
+ private void drawSlots(int amount) {
+ //-1 to not count the output slot
+ for (int i = 0; i < amount - 1; i++) {
+ RenderLocation renderLocation = slotLocations.get(i);
+ if (renderLocation != null && guiItemRecipe != null) {
+ drawSlot(guiItemRecipe.guiLeft + renderLocation.getX(), guiItemRecipe.guiTop + renderLocation.getY());
+ }
+ }
+ }
+
+ @Override
+ public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
+ guiItemRecipe = gui;
+ if (slots.isEmpty()) {
+ slots = buildSlotList();
+ }
+ drawButtons(mouseX, mouseY);
+ }
+
+ @Override
+ public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
+ drawSlots(slots.size());
+ }
+
+ @Override
+ public void handleKeyboardInput() {
+ if (Keyboard.isRepeatEvent()) {
+ return;
+ }
+
+ if (Keyboard.isKeyDown(Keyboard.KEY_LEFT) && selectedTier > 1) {
+ selectedTier--;
+ slots = buildSlotList();
+ } else if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && selectedTier < amountOfTiers) {
+ selectedTier++;
+ slots = buildSlotList();
+ } else if (Keyboard.isKeyDown(Keyboard.KEY_0) || Keyboard.isKeyDown(Keyboard.KEY_NUMPAD0)) {
+ //cycle through tiers when pressing 0
+ if (selectedTier < amountOfTiers) {
+ selectedTier++;
+ } else {
+ selectedTier = 1;
+ }
+ }
+
+ char pressedKey = Keyboard.getEventCharacter();
+ if (Character.isDigit(pressedKey)) {
+ //convert to number from 1-9
+ pressedKey -= 48;
+ if (pressedKey > 0 && pressedKey <= amountOfTiers) {
+ selectedTier = pressedKey;
+ slots = buildSlotList();
+ }
+ }
+ }
+
+ @Override
+ public Set<Ingredient> getIngredients() {
+ return Collections.singleton(output);
+ }
+
+ @Override
+ public Set<Ingredient> getOutputs() {
+ return Collections.singleton(output);
+ }
+
+ @Override
+ public List<RecipeSlot> getSlots() {
+ return slots;
+ }
+
+ @Override
+ public RecipeType getType() {
+ return RecipeType.ESSENCE_UPGRADES;
+ }
+
+ @Override
+ public boolean hasVariableCost() {
+ return false;
+ }
+
+ @Override
+ public @Nullable JsonObject serialize() {
+ return null;
+ }
+
+ @Override
+ public ResourceLocation getBackground() {
+ return BACKGROUND;
+ }
+
+ /**
+ * Simple dataclass holding an x and y value to be used when describing the location of something to be rendered
+ */
+ private static class RenderLocation {
+ private final int x;
+ private final int y;
+
+ public RenderLocation(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public int getY() {
+ return y;
+ }
+ }
+
+ /**
+ * Dataclass holding information about the items and essence required to upgrade an item to a specific tier
+ */
+ public static class TierUpgrade {
+ private final int tier;
+ private final String essenceType;
+ private final int essenceRequired;
+ private Map<String, Integer> itemsRequired;
+
+ public TierUpgrade(int tier, String essenceType, int essenceRequired, Map<String, Integer> itemsRequired) {
+ this.tier = tier;
+ this.essenceType = essenceType;
+ this.essenceRequired = essenceRequired;
+ this.itemsRequired = itemsRequired;
+ }
+
+ public int getTier() {
+ return tier;
+ }
+
+ public String getEssenceType() {
+ return essenceType;
+ }
+
+ public int getEssenceRequired() {
+ return essenceRequired;
+ }
+
+ public Map<String, Integer> getItemsRequired() {
+ return itemsRequired;
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java
index de9c869f..087ec6c3 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java
@@ -30,7 +30,8 @@ public enum RecipeType {
FORGE("forge", "Forging", ForgeRecipe::parseForgeRecipe, new ItemStack(Blocks.anvil)),
TRADE("trade", "Trading", VillagerTradeRecipe::parseStaticRecipe, new ItemStack(Items.emerald)),
MOB_LOOT("drops", "Mob Loot", MobLootRecipe::parseRecipe, new ItemStack(Items.diamond_sword)),
- NPC_SHOP("npc_shop", "NPC Item Shop", ItemShopRecipe::parseItemRecipe, new ItemStack(Items.wheat_seeds));
+ NPC_SHOP("npc_shop", "NPC Item Shop", ItemShopRecipe::parseItemRecipe, new ItemStack(Items.wheat_seeds)),
+ ESSENCE_UPGRADES("", "Essence Upgrades", null, new ItemStack(Items.nether_star));
private final String id;
private final String label;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
index 221b5023..54636791 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Calculator.java
@@ -117,7 +117,7 @@ public class Calculator {
token.tokenLength = 1;
token.type = TokenType.LPAREN;
token.operatorValue = "(";
- } else if ('.' == c) {
+ } else if ('.' == c || ',' == c) {
token.tokenLength = 1;
token.type = TokenType.NUMBER;
readDigitsInto(token, source, true);
@@ -129,7 +129,7 @@ public class Calculator {
readDigitsInto(token, source, false);
if (i + token.tokenLength < source.length()) {
char p = source.charAt(i + token.tokenLength);
- if ('.' == p) {
+ if ('.' == p || ',' == p) {
token.tokenLength++;
readDigitsInto(token, source, true);
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
index ef030367..5a228dc4 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
@@ -29,10 +29,14 @@ import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
+import io.github.moulberry.notenoughupdates.recipes.EssenceUpgrades;
+import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.lang.reflect.Type;
+import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
@@ -94,10 +98,23 @@ public class Constants {
TROPHYFISH = Utils.getConstant("trophyfish", gson);
WEIGHT = Utils.getConstant("weight", gson);
RNGSCORE = Utils.getConstant("rngscore", gson);
+
+ parseEssenceCosts();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
+
+ public void parseEssenceCosts() {
+ for (Map.Entry<String, JsonElement> entry : ESSENCECOSTS.entrySet()) {
+ NeuRecipe parsed = EssenceUpgrades.parseFromEssenceCostEntry(entry);
+ if (parsed != null) {
+ NotEnoughUpdates.INSTANCE.manager.registerNeuRecipe(parsed);
+ } else {
+ System.out.println("NULL for: " + entry);
+ }
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
index 6187495c..6cc1bbe7 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -103,6 +103,22 @@ public class ItemUtils {
is.setTagCompound(tagCompound);
}
+ public static void setLore(ItemStack is, List<String> newLore) {
+ NBTTagCompound tagCompound = is.getTagCompound();
+ if (tagCompound == null) {
+ tagCompound = new NBTTagCompound();
+ }
+
+ NBTTagCompound display = tagCompound.getCompoundTag("display");
+ NBTTagList lore = new NBTTagList();
+ for (String s : newLore) {
+ lore.appendTag(new NBTTagString(s));
+ }
+ display.setTag("Lore", lore);
+ tagCompound.setTag("display", display);
+ is.setTagCompound(tagCompound);
+ }
+
public static List<String> getLore(ItemStack is) {
return getLore(is.getTagCompound());
}
diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/essence_upgrades_tall.png b/src/main/resources/assets/notenoughupdates/textures/gui/essence_upgrades_tall.png
new file mode 100644
index 00000000..2591e8c5
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/gui/essence_upgrades_tall.png
Binary files differ