aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornea <romangraef@gmail.com>2022-02-22 11:22:38 +0100
committernea <romangraef@gmail.com>2022-04-14 04:10:06 +0200
commit3644e419bf9f0a55a5c249bd94999a1c29795e6d (patch)
tree042e5b186744c357717bfd3bbb000189851a0227 /src
parentd7d60efccd99bd5f97d3a6957e9c24b67ce9b2e6 (diff)
downloadNotEnoughUpdates-3644e419bf9f0a55a5c249bd94999a1c29795e6d.tar.gz
NotEnoughUpdates-3644e419bf9f0a55a5c249bd94999a1c29795e6d.tar.bz2
NotEnoughUpdates-3644e419bf9f0a55a5c249bd94999a1c29795e6d.zip
add tabs, because i can
Diffstat (limited to 'src')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java485
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java257
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java442
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/MobDropRecipe.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java57
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java55
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java256
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/gui/tab.pngbin0 -> 1247 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/icons/recipe_crafting.pngbin0 -> 580 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/icons/recipe_forge.pngbin0 -> 580 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/textures/icons/recipe_trade.pngbin0 -> 580 bytes
11 files changed, 807 insertions, 749 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
index 63a4d6d8..8e013bbb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.recipes.NeuRecipe;
import io.github.moulberry.notenoughupdates.recipes.RecipeSlot;
+import io.github.moulberry.notenoughupdates.recipes.RecipeType;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -12,242 +13,268 @@ import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
-import java.awt.*;
+import java.awt.Color;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
public class GuiItemRecipe extends GuiScreen {
- public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png");
-
- public static final int SLOT_SIZE = 16;
- public static final int SLOT_SPACING = SLOT_SIZE + 2;
- public static final int BUTTON_WIDTH = 7;
- public static final int BUTTON_HEIGHT = 11;
- public static final int BUTTON_POSITION_Y = 63;
- public static final int BUTTON_POSITION_LEFT_X = 110;
- public static final int BUTTON_POSITION_RIGHT_X = 147;
- public static final int PAGE_STRING_X = 132;
- public static final int PAGE_STRING_Y = 69;
- public static final int TITLE_X = 28;
- public static final int TITLE_Y = 6;
- public static final int HOTBAR_SLOT_X = 8;
- public static final int HOTBAR_SLOT_Y = 142;
- public static final int PLAYER_INVENTORY_X = 8;
- public static final int PLAYER_INVENTORY_Y = 84;
-
- private int currentIndex = 0;
-
- private final String title;
- private final List<NeuRecipe> craftingRecipes;
- private final NEUManager manager;
-
- public int guiLeft = 0;
- public int guiTop = 0;
- public int xSize = 176;
- public int ySize = 166;
-
- public GuiItemRecipe(String title, List<NeuRecipe> craftingRecipes, NEUManager manager) {
- this.craftingRecipes = craftingRecipes;
- this.manager = manager;
- this.title = title;
- }
-
- public NeuRecipe getCurrentRecipe() {
- currentIndex = MathHelper.clamp_int(currentIndex, 0, craftingRecipes.size());
- return craftingRecipes.get(currentIndex);
- }
-
- public boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) {
- return topLeftX <= x && x <= topLeftX + width
- && topLeftY <= y && y <= topLeftY + height;
- }
-
- private ImmutableList<RecipeSlot> getAllRenderedSlots() {
- return ImmutableList.<RecipeSlot>builder()
- .addAll(getPlayerInventory())
- .addAll(getCurrentRecipe().getSlots()).build();
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- drawDefaultBackground();
- FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj;
-
- this.guiLeft = (width - this.xSize) / 2;
- this.guiTop = (height - this.ySize) / 2;
-
- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
-
- NeuRecipe currentRecipe = getCurrentRecipe();
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(currentRecipe.getBackground());
- this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize);
-
- currentRecipe.drawExtraBackground(this, mouseX, mouseY);
-
- List<RecipeSlot> slots = getAllRenderedSlots();
- for (RecipeSlot slot : slots) {
- Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this));
- }
-
- if (craftingRecipes.size() > 1) drawArrows(mouseX, mouseY);
-
- Utils.drawStringScaledMaxWidth(
- title,
- fontRendererObj,
- guiLeft + TITLE_X,
- guiTop + TITLE_Y,
- false,
- xSize - 38,
- 0x404040
- );
-
- currentRecipe.drawExtraInfo(this, mouseX, mouseY);
-
- for (RecipeSlot slot : slots) {
- if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
- if (slot.getItemStack() == null) continue;
- Utils.drawHoveringText(
- slot.getItemStack().getTooltip(Minecraft.getMinecraft().thePlayer, false),
- mouseX,
- mouseY,
- width,
- height,
- -1,
- fontRendererObj
- );
- }
- }
- currentRecipe.drawHoverInformation(this, mouseX, mouseY);
- }
-
- private void drawArrows(int mouseX, int mouseY) {
- boolean leftSelected = isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- BUTTON_POSITION_LEFT_X,
- BUTTON_POSITION_Y,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- );
- boolean rightSelected = isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- BUTTON_POSITION_RIGHT_X,
- BUTTON_POSITION_Y,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- );
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture);
-
- Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_LEFT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT,
- 34 / 256f, 48 / 256f,
- leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f
- );
- Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_RIGHT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT,
- 10 / 256f, 24 / 256f,
- rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f
- );
- GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
-
- String selectedPage = (currentIndex + 1) + "/" + craftingRecipes.size();
-
- Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj,
- guiLeft + PAGE_STRING_X, guiTop + PAGE_STRING_Y, false, 24, Color.BLACK.getRGB()
- );
- }
-
- public List<RecipeSlot> getPlayerInventory() {
- List<RecipeSlot> slots = new ArrayList<>();
- ItemStack[] inventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory;
- int hotbarSize = InventoryPlayer.getHotbarSize();
- for (int i = 0; i < inventory.length; i++) {
- ItemStack item = inventory[i];
- if (item == null || item.stackSize == 0) continue;
- int row = i / hotbarSize;
- int col = i % hotbarSize;
- if (row == 0)
- slots.add(new RecipeSlot(HOTBAR_SLOT_X + i * SLOT_SPACING, HOTBAR_SLOT_Y, item));
- else
- slots.add(new RecipeSlot(
- PLAYER_INVENTORY_X + col * SLOT_SPACING,
- PLAYER_INVENTORY_Y + (row - 1) * SLOT_SPACING,
- item
- ));
- }
- return slots;
- }
-
- @Override
- public void handleKeyboardInput() throws IOException {
- super.handleKeyboardInput();
-
- ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
- int width = scaledResolution.getScaledWidth();
- int height = scaledResolution.getScaledHeight();
- int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
- int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
- int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey();
-
- for (RecipeSlot slot : getAllRenderedSlots()) {
- if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
- ItemStack itemStack = slot.getItemStack();
- if (keyPressed == manager.keybindViewRecipe.getKeyCode()) { // TODO: rework this so it doesnt skip recipe chains
- manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), "");
- } else if (keyPressed == manager.keybindViewUsages.getKeyCode()) {
- manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack));
- }
- }
- }
- }
-
- @Override
- protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
- super.mouseClicked(mouseX, mouseY, mouseButton);
-
- if (isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- BUTTON_POSITION_LEFT_X,
- BUTTON_POSITION_Y,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- )) {
- currentIndex = currentIndex == 0 ? 0 : currentIndex - 1;
- Utils.playPressSound();
- return;
- }
-
- if (isWithinRect(
- mouseX - guiLeft,
- mouseY - guiTop,
- BUTTON_POSITION_RIGHT_X,
- BUTTON_POSITION_Y,
- BUTTON_WIDTH,
- BUTTON_HEIGHT
- )) {
- currentIndex = currentIndex == craftingRecipes.size() - 1 ? currentIndex : currentIndex + 1;
- Utils.playPressSound();
- return;
- }
-
- for (RecipeSlot slot : getAllRenderedSlots()) {
- if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
- ItemStack itemStack = slot.getItemStack();
- if (mouseButton == 0) {
- manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), "");
- } else if (mouseButton == 1) {
- manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack));
- }
- }
- }
- }
+ public static final ResourceLocation resourcePacksTexture = new ResourceLocation("textures/gui/resource_packs.png");
+ public static final ResourceLocation tabsTexture = new ResourceLocation("notenoughupdates", "textures/gui/tab.png");
+
+ public static final int SLOT_SIZE = 16;
+ public static final int SLOT_SPACING = SLOT_SIZE + 2;
+ public static final int BUTTON_WIDTH = 7;
+ public static final int BUTTON_HEIGHT = 11;
+ public static final int BUTTON_POSITION_Y = 63;
+ public static final int BUTTON_POSITION_LEFT_X = 110;
+ public static final int BUTTON_POSITION_RIGHT_X = 147;
+ public static final int PAGE_STRING_X = 132;
+ public static final int PAGE_STRING_Y = 69;
+ public static final int TITLE_X = 28;
+ public static final int TITLE_Y = 6;
+ public static final int HOTBAR_SLOT_X = 8;
+ public static final int HOTBAR_SLOT_Y = 142;
+ public static final int PLAYER_INVENTORY_X = 8;
+ public static final int PLAYER_INVENTORY_Y = 84;
+ public static final int TAB_POS_X = -26;
+ public static final int TAB_POS_Y = 8;
+ public static final int TAB_OFFSET_Y = 30;
+ public static final int TAB_SIZE_X = 26;
+ public static final int TAB_SIZE_Y = 30;
+ public static final int TAB_TEXTURE_SIZE_X = 29;
+
+
+ private int currentIndex = 0;
+ private int currentTab = 0;
+
+ private final String title;
+ private final Map<RecipeType, List<NeuRecipe>> craftingRecipes = new HashMap<>();
+ private final List<RecipeType> tabs = new ArrayList<>();
+ private final NEUManager manager;
+
+ public int guiLeft = 0;
+ public int guiTop = 0;
+ public int xSize = 176;
+ public int ySize = 166;
+
+ public GuiItemRecipe(String title, List<NeuRecipe> unsortedRecipes, NEUManager manager) {
+ this.manager = manager;
+ this.title = title;
+
+ for (NeuRecipe recipe : unsortedRecipes) {
+ craftingRecipes.computeIfAbsent(recipe.getType(), ignored -> new ArrayList<>()).add(recipe);
+ if (!tabs.contains(recipe.getType()))
+ tabs.add(recipe.getType());
+ }
+ }
+
+ public NeuRecipe getCurrentRecipe() {
+ List<NeuRecipe> currentRecipes = getCurrentRecipeList();
+ currentIndex = MathHelper.clamp_int(currentIndex, 0, currentRecipes.size() - 1);
+ return currentRecipes.get(currentIndex);
+ }
+
+ public List<NeuRecipe> getCurrentRecipeList() {
+ return craftingRecipes.get(getCurrentTab());
+ }
+
+ public RecipeType getCurrentTab() {
+ currentTab = MathHelper.clamp_int(currentTab, 0, tabs.size() - 1);
+ return tabs.get(currentTab);
+ }
+
+
+ public boolean isWithinRect(int x, int y, int topLeftX, int topLeftY, int width, int height) {
+ return topLeftX <= x && x <= topLeftX + width
+ && topLeftY <= y && y <= topLeftY + height;
+ }
+
+ private ImmutableList<RecipeSlot> getAllRenderedSlots() {
+ return ImmutableList.<RecipeSlot>builder()
+ .addAll(getPlayerInventory())
+ .addAll(getCurrentRecipe().getSlots()).build();
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ drawDefaultBackground();
+ FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRendererObj;
+
+ this.guiLeft = (width - this.xSize) / 2;
+ this.guiTop = (height - this.ySize) / 2;
+
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+
+ NeuRecipe currentRecipe = getCurrentRecipe();
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(currentRecipe.getBackground());
+ this.drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize);
+
+ drawTabs();
+
+ currentRecipe.drawExtraBackground(this, mouseX, mouseY);
+
+ List<RecipeSlot> slots = getAllRenderedSlots();
+ for (RecipeSlot slot : slots) {
+ Utils.drawItemStack(slot.getItemStack(), slot.getX(this), slot.getY(this));
+ }
+
+ drawArrows(mouseX, mouseY);
+
+ Utils.drawStringScaledMaxWidth(title, fontRendererObj, guiLeft + TITLE_X, guiTop + TITLE_Y, false, xSize - 38, 0x404040);
+
+ currentRecipe.drawExtraInfo(this, mouseX, mouseY);
+
+ for (RecipeSlot slot : slots) {
+ if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
+ if (slot.getItemStack() == null) continue;
+ Utils.drawHoveringText(slot.getItemStack().getTooltip(Minecraft.getMinecraft().thePlayer, false), mouseX, mouseY, width, height, -1, fontRendererObj);
+ }
+ }
+ currentRecipe.drawHoverInformation(this, mouseX, mouseY);
+ drawTabHoverInformation(mouseX, mouseY);
+ }
+
+ private void drawTabHoverInformation(int mouseX, int mouseY) {
+ for (int i = 0; i < tabs.size(); i++) {
+ if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, TAB_POS_X, TAB_POS_Y + TAB_OFFSET_Y * i, TAB_SIZE_X, TAB_SIZE_Y)) {
+ RecipeType type = tabs.get(i);
+ Utils.drawHoveringText(
+ Arrays.asList(
+ "" + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + type.getLabel(),
+ "" + EnumChatFormatting.RESET + EnumChatFormatting.GRAY + craftingRecipes.get(type).size() + " Recipes"
+ ),
+ mouseX, mouseY, width, height, -1, Minecraft.getMinecraft().fontRendererObj);
+ }
+ }
+ }
+
+ private void drawTabs() {
+ for (int i = 0; i < tabs.size(); i++) {
+ RecipeType recipeType = tabs.get(i);
+ int tabPosX = guiLeft + TAB_POS_X, tabPosY = guiTop + TAB_OFFSET_Y * i + TAB_POS_Y;
+ int textureOffset = 0;
+ if (currentTab == i) {
+ textureOffset = 30;
+ }
+ Minecraft.getMinecraft().getTextureManager().bindTexture(tabsTexture);
+ drawTexturedModalRect(
+ tabPosX, tabPosY,
+ 0, textureOffset,
+ TAB_TEXTURE_SIZE_X, TAB_SIZE_X
+ );
+ Minecraft.getMinecraft().getTextureManager().bindTexture(recipeType.getIcon());
+ drawTexturedModalRect(tabPosX + 7, tabPosY + 6, 6, 0, 16, 16);
+ }
+ }
+
+ private void drawArrows(int mouseX, int mouseY) {
+ int recipeCount = getCurrentRecipeList().size();
+ if (recipeCount < 2) return;
+ boolean leftSelected = isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_LEFT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
+ boolean rightSelected = isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_RIGHT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(resourcePacksTexture);
+
+ if (currentIndex != 0)
+ Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_LEFT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT,
+ 34 / 256f, 48 / 256f,
+ leftSelected ? 37 / 256f : 5 / 256f, leftSelected ? 59 / 256f : 27 / 256f
+ );
+ if (currentIndex != recipeCount - 1)
+ Utils.drawTexturedRect(guiLeft + BUTTON_POSITION_RIGHT_X, guiTop + BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT,
+ 10 / 256f, 24 / 256f,
+ rightSelected ? 37 / 256f : 5 / 256f, rightSelected ? 59 / 256f : 27 / 256f
+ );
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
+
+ String selectedPage = (currentIndex + 1) + "/" + recipeCount;
+
+ Utils.drawStringCenteredScaledMaxWidth(selectedPage, fontRendererObj,
+ guiLeft + PAGE_STRING_X, guiTop + PAGE_STRING_Y, false, 24, Color.BLACK.getRGB());
+ }
+
+ public List<RecipeSlot> getPlayerInventory() {
+ List<RecipeSlot> slots = new ArrayList<>();
+ ItemStack[] inventory = Minecraft.getMinecraft().thePlayer.inventory.mainInventory;
+ int hotbarSize = InventoryPlayer.getHotbarSize();
+ for (int i = 0; i < inventory.length; i++) {
+ ItemStack item = inventory[i];
+ if (item == null || item.stackSize == 0) continue;
+ int row = i / hotbarSize;
+ int col = i % hotbarSize;
+ if (row == 0)
+ slots.add(new RecipeSlot(HOTBAR_SLOT_X + i * SLOT_SPACING, HOTBAR_SLOT_Y, item));
+ else
+ slots.add(new RecipeSlot(PLAYER_INVENTORY_X + col * SLOT_SPACING, PLAYER_INVENTORY_Y + (row - 1) * SLOT_SPACING, item));
+ }
+ return slots;
+ }
+
+ @Override
+ public void handleKeyboardInput() throws IOException {
+ super.handleKeyboardInput();
+
+ ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft());
+ int width = scaledResolution.getScaledWidth();
+ int height = scaledResolution.getScaledHeight();
+ int mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth;
+ int mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1;
+ int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter()+256 : Keyboard.getEventKey();
+ if (Keyboard.getEventKeyState()) return;
+ for (RecipeSlot slot : getAllRenderedSlots()) {
+ if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
+ ItemStack itemStack = slot.getItemStack();
+ if (keyPressed == manager.keybindViewRecipe.getKeyCode()) { // TODO: rework this so it doesnt skip recipe chains
+ manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), "");
+ } else if (keyPressed == manager.keybindViewUsages.getKeyCode()) {
+ manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
+ super.mouseClicked(mouseX, mouseY, mouseButton);
+
+ if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_LEFT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT) &&
+ currentIndex > 0) {
+ currentIndex = currentIndex - 1;
+ Utils.playPressSound();
+ return;
+ }
+
+ if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, BUTTON_POSITION_RIGHT_X, BUTTON_POSITION_Y, BUTTON_WIDTH, BUTTON_HEIGHT) &&
+ currentIndex < getCurrentRecipeList().size()) {
+ currentIndex = currentIndex + 1;
+ Utils.playPressSound();
+ return;
+ }
+
+ for (int i = 0; i < tabs.size(); i++) {
+ if (isWithinRect(mouseX - guiLeft, mouseY - guiTop, TAB_POS_X, TAB_POS_Y + TAB_OFFSET_Y * i, TAB_SIZE_X, TAB_SIZE_Y)) {
+ currentTab = i;
+ Utils.playPressSound();
+ return;
+ }
+ }
+
+ for (RecipeSlot slot : getAllRenderedSlots()) {
+ if (isWithinRect(mouseX, mouseY, slot.getX(this), slot.getY(this), SLOT_SIZE, SLOT_SIZE)) {
+ ItemStack itemStack = slot.getItemStack();
+ if (mouseButton == 0) {
+ manager.displayGuiItemRecipe(manager.getInternalNameForItem(itemStack), "");
+ } else if (mouseButton == 1) {
+ manager.displayGuiItemUsages(manager.getInternalNameForItem(itemStack));
+ }
+ }
+ }
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java
index 576cbbd4..55c00f94 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/CraftingRecipe.java
@@ -17,130 +17,135 @@ import java.util.Set;
public class CraftingRecipe implements NeuRecipe {
- public static final ResourceLocation BACKGROUND = new ResourceLocation("textures/gui/container/crafting_table.png");
-
- private static final int EXTRA_STRING_X = 132;
- private static final int EXTRA_STRING_Y = 25;
-
- private final NEUManager manager;
- private final Ingredient[] inputs;
- private final String extraText;
- private final Ingredient outputIngredient;
- private List<RecipeSlot> slots;
-
- public CraftingRecipe(NEUManager manager, Ingredient[] inputs, Ingredient output, String extra) {
- this.manager = manager;
- this.inputs = inputs;
- this.outputIngredient = output;
- this.extraText = extra;
- if (inputs.length != 9)
- throw new IllegalArgumentException("Cannot construct crafting recipe with non standard crafting grid size");
- }
-
- @Override
- public Set<Ingredient> getIngredients() {
- Set<Ingredient> ingredients = Sets.newHashSet(inputs);
- ingredients.remove(null);
- return ingredients;
- }
-
- @Override
- public boolean hasVariableCost() {
- return false;
- }
-
- @Override
- public Set<Ingredient> getOutputs() {
- return Collections.singleton(getOutput());
- }
-
- public Ingredient getOutput() {
- return outputIngredient;
- }
-
- public Ingredient[] getInputs() {
- return inputs;
- }
-
- @Override
- public List<RecipeSlot> getSlots() {
- if (slots != null) return slots;
- slots = new ArrayList<>();
- for (int x = 0; x < 3; x++) {
- for (int y = 0; y < 3; y++) {
- Ingredient input = inputs[x + y * 3];
- if (input == null) continue;
- ItemStack item = input.getItemStack();
- if (item == null) continue;
- slots.add(new RecipeSlot(30 + x * GuiItemRecipe.SLOT_SPACING, 17 + y * GuiItemRecipe.SLOT_SPACING, item));
- }
- }
- slots.add(new RecipeSlot(124, 35, outputIngredient.getItemStack()));
- return slots;
- }
-
- public String getCraftText() {
- return extraText;
- }
-
- @Override
- public ResourceLocation getBackground() {
- return BACKGROUND;
- }
-
- @Override
- public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
-
- String craftingText = getCraftText();
- if (craftingText != null)
- Utils.drawStringCenteredScaledMaxWidth(craftingText, fontRenderer,
- gui.guiLeft + EXTRA_STRING_X, gui.guiTop + EXTRA_STRING_Y, false, 75, 0x404040
- );
- }
-
- @Override
- public JsonObject serialize() {
- JsonObject object = new JsonObject();
- object.addProperty("type", "crafting");
- object.addProperty("count", outputIngredient.getCount());
- object.addProperty("overrideOutputId", outputIngredient.getInternalItemId());
- for (int i = 0; i < 9; i++) {
- Ingredient ingredient = inputs[i];
- if (ingredient == null) continue;
- String[] x = {"1", "2", "3"};
- String[] y = {"A", "B", "C"};
- String name = x[i / 3] + y[i % 3];
- object.addProperty(name, ingredient.serialize());
- }
- if (extraText != null)
- object.addProperty("crafttext", extraText);
- return object;
- }
-
- public static CraftingRecipe parseCraftingRecipe(NEUManager manager, JsonObject recipe, JsonObject outputItem) {
- Ingredient[] craftMatrix = new Ingredient[9];
-
- String[] x = {"1", "2", "3"};
- String[] y = {"A", "B", "C"};
- for (int i = 0; i < 9; i++) {
- String name = y[i / 3] + x[i % 3];
- if (!recipe.has(name)) continue;
- String item = recipe.get(name).getAsString();
- if (item == null || item.isEmpty()) continue;
- craftMatrix[i] = new Ingredient(manager, item);
- }
- int resultCount = 1;
- if (recipe.has("count"))
- resultCount = recipe.get("count").getAsInt();
- String extra = null;
- if (outputItem.has("crafttext"))
- extra = outputItem.get("crafttext").getAsString();
- if (recipe.has("crafttext"))
- extra = recipe.get("crafttext").getAsString();
- String outputItemId = outputItem.get("internalname").getAsString();
- if (recipe.has("overrideOutputId"))
- outputItemId = recipe.get("overrideOutputId").getAsString();
- return new CraftingRecipe(manager, craftMatrix, new Ingredient(manager, outputItemId, resultCount), extra);
- }
+ public static final ResourceLocation BACKGROUND = new ResourceLocation("textures/gui/container/crafting_table.png");
+
+ private static final int EXTRA_STRING_X = 132;
+ private static final int EXTRA_STRING_Y = 25;
+
+ private final NEUManager manager;
+ private final Ingredient[] inputs;
+ private final String extraText;
+ private final Ingredient outputIngredient;
+ private List<RecipeSlot> slots;
+
+ public CraftingRecipe(NEUManager manager, Ingredient[] inputs, Ingredient output, String extra) {
+ this.manager = manager;
+ this.inputs = inputs;
+ this.outputIngredient = output;
+ this.extraText = extra;
+ if (inputs.length != 9)
+ throw new IllegalArgumentException("Cannot construct crafting recipe with non standard crafting grid size");
+ }
+
+ @Override
+ public Set<Ingredient> getIngredients() {
+ Set<Ingredient> ingredients = Sets.newHashSet(inputs);
+ ingredients.remove(null);
+ return ingredients;
+ }
+
+ @Override
+ public RecipeType getType() {
+ return RecipeType.CRAFTING;
+ }
+
+ @Override
+ public boolean hasVariableCost() {
+ return false;
+ }
+
+ @Override
+ public Set<Ingredient> getOutputs() {
+ return Collections.singleton(getOutput());
+ }
+
+ public Ingredient getOutput() {
+ return outputIngredient;
+ }
+
+ public Ingredient[] getInputs() {
+ return inputs;
+ }
+
+
+ @Override
+ public List<RecipeSlot> getSlots() {
+ if (slots != null) return slots;
+ slots = new ArrayList<>();
+ for (int x = 0; x < 3; x++) {
+ for (int y = 0; y < 3; y++) {
+ Ingredient input = inputs[x + y * 3];
+ if (input == null) continue;
+ ItemStack item = input.getItemStack();
+ if (item == null) continue;
+ slots.add(new RecipeSlot(30 + x * GuiItemRecipe.SLOT_SPACING, 17 + y * GuiItemRecipe.SLOT_SPACING, item));
+ }
+ }
+ slots.add(new RecipeSlot(124, 35, outputIngredient.getItemStack()));
+ return slots;
+ }
+
+ public String getCraftText() {
+ return extraText;
+ }
+
+ @Override
+ public ResourceLocation getBackground() {
+ return BACKGROUND;
+ }
+
+ @Override
+ public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
+ FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
+
+ String craftingText = getCraftText();
+ if (craftingText != null)
+ Utils.drawStringCenteredScaledMaxWidth(craftingText, fontRenderer,
+ gui.guiLeft + EXTRA_STRING_X, gui.guiTop + EXTRA_STRING_Y, false, 75, 0x404040);
+ }
+
+ @Override
+ public JsonObject serialize() {
+ JsonObject object = new JsonObject();
+ object.addProperty("type", "crafting");
+ object.addProperty("count", outputIngredient.getCount());
+ object.addProperty("overrideOutputId", outputIngredient.getInternalItemId());
+ for (int i = 0; i < 9; i++) {
+ Ingredient ingredient = inputs[i];
+ if (ingredient == null) continue;
+ String[] x = {"1", "2", "3"};
+ String[] y = {"A", "B", "C"};
+ String name = x[i / 3] + y[i % 3];
+ object.addProperty(name, ingredient.serialize());
+ }
+ if(extraText != null)
+ object.addProperty("crafttext", extraText);
+ return object;
+ }
+
+ public static CraftingRecipe parseCraftingRecipe(NEUManager manager, JsonObject recipe, JsonObject outputItem) {
+ Ingredient[] craftMatrix = new Ingredient[9];
+
+ String[] x = {"1", "2", "3"};
+ String[] y = {"A", "B", "C"};
+ for (int i = 0; i < 9; i++) {
+ String name = y[i / 3] + x[i % 3];
+ if (!recipe.has(name)) continue;
+ String item = recipe.get(name).getAsString();
+ if (item == null || item.isEmpty()) continue;
+ craftMatrix[i] = new Ingredient(manager, item);
+ }
+ int resultCount = 1;
+ if (recipe.has("count"))
+ resultCount = recipe.get("count").getAsInt();
+ String extra = null;
+ if (outputItem.has("crafttext"))
+ extra = outputItem.get("crafttext").getAsString();
+ if (recipe.has("crafttext"))
+ extra = recipe.get("crafttext").getAsString();
+ String outputItemId = outputItem.get("internalname").getAsString();
+ if (recipe.has("overrideOutputId"))
+ outputItemId = recipe.get("overrideOutputId").getAsString();
+ return new CraftingRecipe(manager, craftMatrix, new Ingredient(manager, outputItemId, resultCount), extra);
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java
index c971d82a..1e648865 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ForgeRecipe.java
@@ -19,238 +19,212 @@ import java.util.*;
public class ForgeRecipe implements NeuRecipe {
- private static final ResourceLocation BACKGROUND =
- new ResourceLocation("notenoughupdates", "textures/gui/forge_recipe.png");
-
- private static final int SLOT_IMAGE_U = 176;
- private static final int SLOT_IMAGE_V = 0;
- private static final int SLOT_IMAGE_SIZE = 18;
- private static final int SLOT_PADDING = 1;
- private static final int EXTRA_INFO_MAX_WIDTH = 75;
- public static final int EXTRA_INFO_X = 132;
- public static final int EXTRA_INFO_Y = 25;
-
- public enum ForgeType {
- REFINING, ITEM_FORGING
- }
-
- private final NEUManager manager;
- private final List<Ingredient> inputs;
- private final Ingredient output;
- private final int hotmLevel;
- private final int timeInSeconds; // TODO: quick forge
- private List<RecipeSlot> slots;
-
- public ForgeRecipe(
- NEUManager manager,
- List<Ingredient> inputs,
- Ingredient output,
- int durationInSeconds,
- int hotmLevel
- ) {
- this.manager = manager;
- this.inputs = inputs;
- this.output = output;
- this.hotmLevel = hotmLevel;
- this.timeInSeconds = durationInSeconds;
- }
-
- public List<Ingredient> getInputs() {
- return inputs;
- }
-
- public Ingredient getOutput() {
- return output;
- }
-
- public int getHotmLevel() {
- return hotmLevel;
- }
-
- public int getTimeInSeconds() {
- return timeInSeconds;
- }
-
- @Override
- public ResourceLocation getBackground() {
- return BACKGROUND;
- }
-
- @Override
- public Set<Ingredient> getIngredients() {
- return Sets.newHashSet(inputs);
- }
-
- @Override
- public boolean hasVariableCost() {
- return false;
- }
-
- @Override
- public Set<Ingredient> getOutputs() {
- return Collections.singleton(output);
- }
-
- @Override
- public List<RecipeSlot> getSlots() {
- if (slots != null) return slots;
- slots = new ArrayList<>();
- for (int i = 0; i < inputs.size(); i++) {
- Ingredient input = inputs.get(i);
- ItemStack itemStack = input.getItemStack();
- if (itemStack == null) continue;
- int[] slotCoordinates = getSlotCoordinates(i, inputs.size());
- slots.add(new RecipeSlot(slotCoordinates[0], slotCoordinates[1], itemStack));
- }
- slots.add(new RecipeSlot(124, 35, output.getItemStack()));
- return slots;
- }
-
- @Override
- public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
- for (int i = 0; i < inputs.size(); i++) {
- int[] slotCoordinates = getSlotCoordinates(i, inputs.size());
- gui.drawTexturedModalRect(
- gui.guiLeft + slotCoordinates[0] - SLOT_PADDING, gui.guiTop + slotCoordinates[1] - SLOT_PADDING,
- SLOT_IMAGE_U, SLOT_IMAGE_V,
- SLOT_IMAGE_SIZE, SLOT_IMAGE_SIZE
- );
- }
- }
-
- @Override
- public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- if (timeInSeconds > 0)
- Utils.drawStringCenteredScaledMaxWidth(
- formatDuration(timeInSeconds),
- fontRenderer,
- gui.guiLeft + EXTRA_INFO_X,
- gui.guiTop + EXTRA_INFO_Y,
- false,
- EXTRA_INFO_MAX_WIDTH,
- 0xff00ff
- );
- }
-
- @Override
- public void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) {
- manager.hotm.getInformationOnCurrentProfile().ifPresent(hotmTree -> {
- if (timeInSeconds > 0 && gui.isWithinRect(
- mouseX, mouseY,
- gui.guiLeft + EXTRA_INFO_X - EXTRA_INFO_MAX_WIDTH / 2,
- gui.guiTop + EXTRA_INFO_Y - 8,
- EXTRA_INFO_MAX_WIDTH, 16
- )) {
- int qf = hotmTree.getLevel("forge_time");
- int reducedTime = getReducedTime(qf);
- if (qf > 0) {
-
- Utils.drawHoveringText(
- Arrays.asList(
- EnumChatFormatting.YELLOW + formatDuration(reducedTime) + " with Quick Forge (Level " + qf + ")"),
- mouseX,
- mouseY,
- gui.width,
- gui.height,
- 500,
- Minecraft.getMinecraft().fontRendererObj
- );
- }
- }
- });
- }
-
- public int getReducedTime(int quickForgeUpgradeLevel) {
- return HotmInformation.getQuickForgeMultiplier(quickForgeUpgradeLevel) * timeInSeconds / 1000;
- }
-
- @Override
- public JsonObject serialize() {
- JsonObject object = new JsonObject();
- JsonArray ingredients = new JsonArray();
- for (Ingredient input : inputs) {
- ingredients.add(new JsonPrimitive(input.serialize()));
- }
- object.addProperty("type", "forge");
- object.add("inputs", ingredients);
- object.addProperty("count", output.getCount());
- object.addProperty("overrideOutputId", output.getInternalItemId());
- if (hotmLevel >= 0)
- object.addProperty("hotmLevel", hotmLevel);
- if (timeInSeconds >= 0)
- object.addProperty("duration", timeInSeconds);
- return object;
- }
-
- static ForgeRecipe parseForgeRecipe(NEUManager manager, JsonObject recipe, JsonObject output) {
- List<Ingredient> ingredients = new ArrayList<>();
- for (JsonElement element : recipe.getAsJsonArray("inputs")) {
- String ingredientString = element.getAsString();
- ingredients.add(new Ingredient(manager, ingredientString));
- }
- String internalItemId = output.get("internalname").getAsString();
- if (recipe.has("overrideOutputId"))
- internalItemId = recipe.get("overrideOutputId").getAsString();
- int resultCount = 1;
- if (recipe.has("count")) {
- resultCount = recipe.get("count").getAsInt();
- }
- int duration = -1;
- if (recipe.has("duration")) {
- duration = recipe.get("duration").getAsInt();
- }
- int hotmLevel = -1;
- if (recipe.has("hotmLevel")) {
- hotmLevel = recipe.get("hotmLevel").getAsInt();
- }
- return new ForgeRecipe(
- manager,
- ingredients,
- new Ingredient(manager, internalItemId, resultCount),
- duration,
- hotmLevel
- );
- }
-
- private static final int RECIPE_CENTER_X = 40;
- private static final int RECIPE_CENTER_Y = 34;
- private static final int SLOT_DISTANCE_FROM_CENTER = 22;
- private static final int RECIPE_FALLBACK_X = 20;
- private static final int RECIPE_FALLBACK_Y = 15;
-
- static int[] getSlotCoordinates(int slotNumber, int totalSlotCount) {
- if (totalSlotCount > 6) {
- return new int[]{
- RECIPE_FALLBACK_X + (slotNumber % 4) * GuiItemRecipe.SLOT_SPACING,
- RECIPE_FALLBACK_Y + (slotNumber / 4) * GuiItemRecipe.SLOT_SPACING,
- };
- }
- if (totalSlotCount == 1) {
- return new int[]{
- RECIPE_CENTER_X - GuiItemRecipe.SLOT_SIZE / 2,
- RECIPE_CENTER_Y - GuiItemRecipe.SLOT_SIZE / 2
- };
- }
- double rad = Math.PI * 2 * slotNumber / totalSlotCount;
- int x = (int) (Math.cos(rad) * SLOT_DISTANCE_FROM_CENTER);
- int y = (int) (Math.sin(rad) * SLOT_DISTANCE_FROM_CENTER);
- return new int[]{RECIPE_CENTER_X + x, RECIPE_CENTER_Y + y};
- }
-
- static String formatDuration(int seconds) {
- int minutes = seconds / 60;
- seconds %= 60;
- int hours = minutes / 60;
- minutes %= 60;
- int days = hours / 24;
- hours %= 24;
- StringBuilder sB = new StringBuilder();
- if (days != 0) sB.append(days).append("d ");
- if (hours != 0) sB.append(hours).append("h ");
- if (minutes != 0) sB.append(minutes).append("m ");
- if (seconds != 0) sB.append(seconds).append("s ");
- return sB.substring(0, sB.length() - 1);
- }
+ private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/forge_recipe.png");
+
+ private static final int SLOT_IMAGE_U = 176;
+ private static final int SLOT_IMAGE_V = 0;
+ private static final int SLOT_IMAGE_SIZE = 18;
+ private static final int SLOT_PADDING = 1;
+ private static final int EXTRA_INFO_MAX_WIDTH = 75;
+ public static final int EXTRA_INFO_X = 132;
+ public static final int EXTRA_INFO_Y = 25;
+
+ public enum ForgeType {
+ REFINING, ITEM_FORGING
+ }
+
+ private final NEUManager manager;
+ private final List<Ingredient> inputs;
+ private final Ingredient output;
+ private final int hotmLevel;
+ private final int timeInSeconds; // TODO: quick forge
+ private List<RecipeSlot> slots;
+
+ public ForgeRecipe(NEUManager manager, List<Ingredient> inputs, Ingredient output, int durationInSeconds, int hotmLevel) {
+ this.manager = manager;
+ this.inputs = inputs;
+ this.output = output;
+ this.hotmLevel = hotmLevel;
+ this.timeInSeconds = durationInSeconds;
+ }
+
+ public List<Ingredient> getInputs() {
+ return inputs;
+ }
+
+ public Ingredient getOutput() {
+ return output;
+ }
+
+ public int getHotmLevel() {
+ return hotmLevel;
+ }
+
+ public int getTimeInSeconds() {
+ return timeInSeconds;
+ }
+
+ @Override
+ public ResourceLocation getBackground() {
+ return BACKGROUND;
+ }
+
+ @Override
+ public RecipeType getType() {
+ return RecipeType.FORGE;
+ }
+
+ @Override
+ public Set<Ingredient> getIngredients() {
+ return Sets.newHashSet(inputs);
+ }
+
+ @Override
+ public boolean hasVariableCost() {
+ return false;
+ }
+
+ @Override
+ public Set<Ingredient> getOutputs() {
+ return Collections.singleton(output);
+ }
+
+ @Override
+ public List<RecipeSlot> getSlots() {
+ if (slots != null) return slots;
+ slots = new ArrayList<>();
+ for (int i = 0; i < inputs.size(); i++) {
+ Ingredient input = inputs.get(i);
+ ItemStack itemStack = input.getItemStack();
+ if (itemStack == null) continue;
+ int[] slotCoordinates = getSlotCoordinates(i, inputs.size());
+ slots.add(new RecipeSlot(slotCoordinates[0], slotCoordinates[1], itemStack));
+ }
+ slots.add(new RecipeSlot(124, 35, output.getItemStack()));
+ return slots;
+ }
+
+ @Override
+ public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
+ for (int i = 0; i < inputs.size(); i++) {
+ int[] slotCoordinates = getSlotCoordinates(i, inputs.size());
+ gui.drawTexturedModalRect(
+ gui.guiLeft + slotCoordinates[0] - SLOT_PADDING, gui.guiTop + slotCoordinates[1] - SLOT_PADDING,
+ SLOT_IMAGE_U, SLOT_IMAGE_V,
+ SLOT_IMAGE_SIZE, SLOT_IMAGE_SIZE);
+ }
+ }
+
+ @Override
+ public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
+ FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
+ if (timeInSeconds > 0)
+ Utils.drawStringCenteredScaledMaxWidth(formatDuration(timeInSeconds), fontRenderer, gui.guiLeft + EXTRA_INFO_X, gui.guiTop + EXTRA_INFO_Y, false, EXTRA_INFO_MAX_WIDTH, 0xff00ff);
+ }
+
+ @Override
+ public void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) {
+ manager.hotm.getInformationOnCurrentProfile().ifPresent(hotmTree -> {
+ if (timeInSeconds > 0 && gui.isWithinRect(
+ mouseX, mouseY,
+ gui.guiLeft + EXTRA_INFO_X - EXTRA_INFO_MAX_WIDTH / 2,
+ gui.guiTop + EXTRA_INFO_Y - 8,
+ EXTRA_INFO_MAX_WIDTH, 16
+ )) {
+ int qf = hotmTree.getLevel("forge_time");
+ int reducedTime = getReducedTime(qf);
+ if (qf > 0) {
+
+ Utils.drawHoveringText(Arrays.asList(EnumChatFormatting.YELLOW + formatDuration(reducedTime) + " with Quick Forge (Level " + qf + ")"), mouseX, mouseY, gui.width, gui.height, 500, Minecraft.getMinecraft().fontRendererObj);
+ }
+ }
+ });
+ }
+
+ public int getReducedTime(int quickForgeUpgradeLevel) {
+ return HotmInformation.getQuickForgeMultiplier(quickForgeUpgradeLevel) * timeInSeconds / 1000;
+ }
+
+ @Override
+ public JsonObject serialize() {
+ JsonObject object = new JsonObject();
+ JsonArray ingredients = new JsonArray();
+ for (Ingredient input : inputs) {
+ ingredients.add(new JsonPrimitive(input.serialize()));
+ }
+ object.addProperty("type", "forge");
+ object.add("inputs", ingredients);
+ object.addProperty("count", output.getCount());
+ object.addProperty("overrideOutputId", output.getInternalItemId());
+ if (hotmLevel >= 0)
+ object.addProperty("hotmLevel", hotmLevel);
+ if (timeInSeconds >= 0)
+ object.addProperty("duration", timeInSeconds);
+ return object;
+ }
+
+ static ForgeRecipe parseForgeRecipe(NEUManager manager, JsonObject recipe, JsonObject output) {
+ List<Ingredient> ingredients = new ArrayList<>();
+ for (JsonElement element : recipe.getAsJsonArray("inputs")) {
+ String ingredientString = element.getAsString();
+ ingredients.add(new Ingredient(manager, ingredientString));
+ }
+ String internalItemId = output.get("internalname").getAsString();
+ if (recipe.has("overrideOutputId"))
+ internalItemId = recipe.get("overrideOutputId").getAsString();
+ int resultCount = 1;
+ if (recipe.has("count")) {
+ resultCount = recipe.get("count").getAsInt();
+ }
+ int duration = -1;
+ if (recipe.has("duration")) {
+ duration = recipe.get("duration").getAsInt();
+ }
+ int hotmLevel = -1;
+ if (recipe.has("hotmLevel")) {
+ hotmLevel = recipe.get("hotmLevel").getAsInt();
+ }
+ return new ForgeRecipe(manager, ingredients, new Ingredient(manager, internalItemId, resultCount), duration, hotmLevel);
+ }
+
+ private static final int RECIPE_CENTER_X = 40;
+ private static final int RECIPE_CENTER_Y = 34;
+ private static final int SLOT_DISTANCE_FROM_CENTER = 22;
+ private static final int RECIPE_FALLBACK_X = 20;
+ private static final int RECIPE_FALLBACK_Y = 15;
+
+ static int[] getSlotCoordinates(int slotNumber, int totalSlotCount) {
+ if (totalSlotCount > 6) {
+ return new int[]{
+ RECIPE_FALLBACK_X + (slotNumber % 4) * GuiItemRecipe.SLOT_SPACING,
+ RECIPE_FALLBACK_Y + (slotNumber / 4) * GuiItemRecipe.SLOT_SPACING,
+ };
+ }
+ if (totalSlotCount == 1) {
+ return new int[] {
+ RECIPE_CENTER_X - GuiItemRecipe.SLOT_SIZE / 2,
+ RECIPE_CENTER_Y - GuiItemRecipe.SLOT_SIZE / 2
+ };
+ }
+ double rad = Math.PI * 2 * slotNumber / totalSlotCount;
+ int x = (int) (Math.cos(rad) * SLOT_DISTANCE_FROM_CENTER);
+ int y = (int) (Math.sin(rad) * SLOT_DISTANCE_FROM_CENTER);
+ return new int[]{RECIPE_CENTER_X + x, RECIPE_CENTER_Y + y};
+ }
+
+ static String formatDuration(int seconds) {
+ int minutes = seconds / 60;
+ seconds %= 60;
+ int hours = minutes / 60;
+ minutes %= 60;
+ int days = hours / 24;
+ hours %= 24;
+ StringBuilder sB = new StringBuilder();
+ if (days != 0) sB.append(days).append("d ");
+ if (hours != 0) sB.append(hours).append("h ");
+ if (minutes != 0) sB.append(minutes).append("m ");
+ if (seconds != 0) sB.append(seconds).append("s ");
+ return sB.substring(0, sB.length() - 1);
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobDropRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobDropRecipe.java
new file mode 100644
index 00000000..22888e5d
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/MobDropRecipe.java
@@ -0,0 +1,4 @@
+package io.github.moulberry.notenoughupdates.recipes;
+
+public class MobDropRecipe {
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java
index 3516f707..b14a724e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java
@@ -9,44 +9,43 @@ import java.util.List;
import java.util.Set;
public interface NeuRecipe {
- Set<Ingredient> getIngredients();
+ Set<Ingredient> getIngredients();
- Set<Ingredient> getOutputs();
+ Set<Ingredient> getOutputs();
- List<RecipeSlot> getSlots();
+ List<RecipeSlot> getSlots();
- default void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
- }
+ RecipeType getType();
- default void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
- }
+ default void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
+ }
- default void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) {
- }
+ default void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
+ }
- boolean hasVariableCost();
+ default void drawHoverInformation(GuiItemRecipe gui, int mouseX, int mouseY) {
+ }
- JsonObject serialize();
+ boolean hasVariableCost();
- ResourceLocation getBackground();
+ JsonObject serialize();
- static NeuRecipe parseRecipe(NEUManager manager, JsonObject recipe, JsonObject output) {
- if (recipe.has("type")) {
- switch (recipe.get("type").getAsString().intern()) {
- case "forge":
- return ForgeRecipe.parseForgeRecipe(manager, recipe, output);
- case "trade":
- return VillagerTradeRecipe.parseStaticRecipe(manager, recipe);
- }
- }
- return CraftingRecipe.parseCraftingRecipe(manager, recipe, output);
- }
+ ResourceLocation getBackground();
- default boolean shouldUseForCraftCost() {
- return true;
- }
+ static NeuRecipe parseRecipe(NEUManager manager, JsonObject recipe, JsonObject output) {
+ RecipeType recipeType = RecipeType.CRAFTING;
+ if (recipe.has("type")) {
+ recipeType = RecipeType.getRecipeTypeForId(recipe.get("type").getAsString());
+ }
+ if (recipeType == null) return null;
+ return recipeType.createRecipe(manager, recipe, output);
+ }
- default boolean isAvailable() {
- return true;
- }
+ default boolean shouldUseForCraftCost() {
+ return true;
+ }
+
+ default boolean isAvailable() {
+ return true;
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java
new file mode 100644
index 00000000..ae00c316
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java
@@ -0,0 +1,55 @@
+package io.github.moulberry.notenoughupdates.recipes;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NEUManager;
+import net.minecraft.util.ResourceLocation;
+
+public enum RecipeType {
+ CRAFTING("crafting", "Crafting", CraftingRecipe::parseCraftingRecipe),
+ FORGE("forge", "Forge", ForgeRecipe::parseForgeRecipe),
+ TRADE("trade", "Trade", VillagerTradeRecipe::parseStaticRecipe);
+
+ private final String id;
+ private final String label;
+ private final RecipeFactory recipeFactory;
+ private final ResourceLocation icon;
+
+ RecipeType(String id, String label, RecipeFactory recipeFactory) {
+ this.id = id;
+ this.label = label;
+ this.recipeFactory = recipeFactory;
+ this.icon = new ResourceLocation("notenoughupdates", "textures/icons/recipe_" + id + ".png");
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ResourceLocation getIcon() {
+ return icon;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public RecipeFactory getRecipeFactory() {
+ return recipeFactory;
+ }
+
+ public NeuRecipe createRecipe(NEUManager manager, JsonObject recipe, JsonObject outputItemJson) {
+ return recipeFactory.createRecipe(manager, recipe, outputItemJson);
+ }
+
+ public static RecipeType getRecipeTypeForId(String id) {
+ for (RecipeType value : values()) {
+ if (value.id.equals(id)) return value;
+ }
+ return null;
+ }
+
+ @FunctionalInterface
+ interface RecipeFactory {
+ NeuRecipe createRecipe(NEUManager manager, JsonObject recipe, JsonObject outputItemJson);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java
index 371d4f3c..2dab6976 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/VillagerTradeRecipe.java
@@ -21,136 +21,130 @@ import java.util.*;
public class VillagerTradeRecipe implements NeuRecipe {
- public static final int COST_SLOT_X = 51;
- public static final int COST_SLOT_Y = 34;
- public static final int RESULT_SLOT_Y = 35;
- public static final int RESULT_SLOT_X = 124;
-
- private static class Holder { // This holder object exists to defer initialization to first access
- private static final GameProfile DREAM_PROFILE =
- new GameProfile(UUID.fromString("ec70bcaf-702f-4bb8-b48d-276fa52a780c"), "Dream");
- private static final EntityLivingBase DEMO_DREAM = new AbstractClientPlayer(null, DREAM_PROFILE) {
- @Override
- protected NetworkPlayerInfo getPlayerInfo() {
- return new NetworkPlayerInfo(DREAM_PROFILE) {
- @Override
- public ResourceLocation getLocationSkin() {
- return new ResourceLocation("notenoughupdates", "dreamskin.png");
- }
- };
- }
- };
- private static final EntityLivingBase DEMO_VILLAGER = new EntityVillager(null);
-
- private static boolean isAprilFirst() {
- Calendar cal = Calendar.getInstance();
- return cal.get(Calendar.DAY_OF_MONTH) == 1 && cal.get(Calendar.MONTH) == Calendar.APRIL;
- }
-
- private static final EntityLivingBase DEMO_ENTITY = isAprilFirst() ? DEMO_DREAM : DEMO_VILLAGER;
-
- }
-
- private final static ResourceLocation BACKGROUND =
- new ResourceLocation("notenoughupdates", "textures/gui/villager_recipe.png");
-
- private final Ingredient result;
- private final Ingredient cost;
- private final int minCost, maxCost;
-
- public VillagerTradeRecipe(Ingredient result, Ingredient cost, int minCost, int maxCost) {
- this.result = result;
- this.cost = cost;
- this.minCost = minCost;
- this.maxCost = maxCost;
- }
-
- public VillagerTradeRecipe(Ingredient result, Ingredient cost) {
- this(result, cost, -1, -1);
- }
-
- public boolean hasVariableCost() {
- return minCost != -1 && maxCost != -1;
- }
-
- @Override
- public Set<Ingredient> getIngredients() {
- return Sets.newHashSet(cost);
- }
-
- @Override
- public Set<Ingredient> getOutputs() {
- return Sets.newHashSet(result);
- }
-
- @Override
- public List<RecipeSlot> getSlots() {
- return Arrays.asList(
- new RecipeSlot(COST_SLOT_X, COST_SLOT_Y, cost.getItemStack()),
- new RecipeSlot(RESULT_SLOT_X, RESULT_SLOT_Y, result.getItemStack())
- );
- }
-
- @Override
- public boolean shouldUseForCraftCost() {
- return false;
- }
-
- @Override
- public boolean isAvailable() {
- return SBInfo.getInstance().getCurrentMode() == SBInfo.Gamemode.STRANDED ||
- NotEnoughUpdates.INSTANCE.config.hidden.dev;
- }
-
- @Override
- public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
- if (hasVariableCost()) {
- FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
- Utils.drawStringCenteredScaledMaxWidth(
- minCost + " - " + maxCost, fontRenderer,
- gui.guiLeft + 50, gui.guiTop + 60, false, 75, 0xff00ff
- );
-
- }
- }
-
- @Override
- public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
- GuiInventory.drawEntityOnScreen(
- gui.guiLeft + 90,
- gui.guiTop + 75,
- 30,
- gui.guiLeft - mouseX + 80,
- gui.guiTop + 60 - mouseY,
- Holder.DEMO_ENTITY
- );
- }
-
- @Override
- public JsonObject serialize() {
- JsonObject jsonObject = new JsonObject();
- jsonObject.addProperty("type", "trade");
- jsonObject.addProperty("result", result.serialize());
- jsonObject.addProperty("cost", cost.getInternalItemId());
- if (minCost > 0)
- jsonObject.addProperty("min", minCost);
- if (maxCost > 0)
- jsonObject.addProperty("max", maxCost);
- return jsonObject;
- }
-
- @Override
- public ResourceLocation getBackground() {
- return BACKGROUND;
- }
-
- public static VillagerTradeRecipe parseStaticRecipe(NEUManager manager, JsonObject recipe) {
- return new VillagerTradeRecipe(
- new Ingredient(manager, recipe.get("result").getAsString()),
- new Ingredient(manager, recipe.get("cost").getAsString()),
- recipe.has("min") ? recipe.get("min").getAsInt() : -1,
- recipe.has("max") ? recipe.get("max").getAsInt() : -1
- );
- }
+ public static final int COST_SLOT_X = 51;
+ public static final int COST_SLOT_Y = 34;
+ public static final int RESULT_SLOT_Y = 35;
+ public static final int RESULT_SLOT_X = 124;
+
+ private static class Holder { // This holder object exists to defer initialization to first access
+ private static final GameProfile DREAM_PROFILE = new GameProfile(UUID.fromString("ec70bcaf-702f-4bb8-b48d-276fa52a780c"), "Dream");
+ private static final EntityLivingBase DEMO_DREAM = new AbstractClientPlayer(null, DREAM_PROFILE) {
+ @Override
+ protected NetworkPlayerInfo getPlayerInfo() {
+ return new NetworkPlayerInfo(DREAM_PROFILE) {
+ @Override
+ public ResourceLocation getLocationSkin() {
+ return new ResourceLocation("notenoughupdates", "dreamskin.png");
+ }
+ };
+ }
+ };
+ private static final EntityLivingBase DEMO_VILLAGER = new EntityVillager(null);
+
+ private static boolean isAprilFirst() {
+ Calendar cal = Calendar.getInstance();
+ return cal.get(Calendar.DAY_OF_MONTH) == 1 && cal.get(Calendar.MONTH) == Calendar.APRIL;
+ }
+
+ private static final EntityLivingBase DEMO_ENTITY = isAprilFirst() ? DEMO_DREAM : DEMO_VILLAGER;
+
+ }
+
+ private final static ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates", "textures/gui/villager_recipe.png");
+
+ private final Ingredient result;
+ private final Ingredient cost;
+ private final int minCost, maxCost;
+
+ public VillagerTradeRecipe(Ingredient result, Ingredient cost, int minCost, int maxCost) {
+ this.result = result;
+ this.cost = cost;
+ this.minCost = minCost;
+ this.maxCost = maxCost;
+ }
+
+ public VillagerTradeRecipe(Ingredient result, Ingredient cost) {
+ this(result, cost, -1, -1);
+ }
+
+ public boolean hasVariableCost() {
+ return minCost != -1 && maxCost != -1;
+ }
+
+ @Override
+ public RecipeType getType() {
+ return RecipeType.TRADE;
+ }
+
+ @Override
+ public Set<Ingredient> getIngredients() {
+ return Sets.newHashSet(cost);
+ }
+
+ @Override
+ public Set<Ingredient> getOutputs() {
+ return Sets.newHashSet(result);
+ }
+
+ @Override
+ public List<RecipeSlot> getSlots() {
+ return Arrays.asList(
+ new RecipeSlot(COST_SLOT_X, COST_SLOT_Y, cost.getItemStack()),
+ new RecipeSlot(RESULT_SLOT_X, RESULT_SLOT_Y, result.getItemStack())
+ );
+ }
+
+ @Override
+ public boolean shouldUseForCraftCost() {
+ return false;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return SBInfo.getInstance().getCurrentMode() == SBInfo.Gamemode.STRANDED || NotEnoughUpdates.INSTANCE.config.hidden.dev;
+ }
+
+ @Override
+ public void drawExtraInfo(GuiItemRecipe gui, int mouseX, int mouseY) {
+ if (hasVariableCost()) {
+ FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj;
+ Utils.drawStringCenteredScaledMaxWidth(
+ minCost + " - " + maxCost, fontRenderer,
+ gui.guiLeft + 50, gui.guiTop + 60, false, 75, 0xff00ff);
+
+ }
+ }
+
+ @Override
+ public void drawExtraBackground(GuiItemRecipe gui, int mouseX, int mouseY) {
+ GuiInventory.drawEntityOnScreen(gui.guiLeft + 90, gui.guiTop + 75, 30, gui.guiLeft - mouseX + 80, gui.guiTop + 60 - mouseY, Holder.DEMO_ENTITY);
+ }
+
+ @Override
+ public JsonObject serialize() {
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("type", "trade");
+ jsonObject.addProperty("result", result.serialize());
+ jsonObject.addProperty("cost", cost.getInternalItemId());
+ if (minCost > 0)
+ jsonObject.addProperty("min", minCost);
+ if (maxCost > 0)
+ jsonObject.addProperty("max", maxCost);
+ return jsonObject;
+ }
+
+ @Override
+ public ResourceLocation getBackground() {
+ return BACKGROUND;
+ }
+
+ public static VillagerTradeRecipe parseStaticRecipe(NEUManager manager, JsonObject recipe, JsonObject result) {
+ return new VillagerTradeRecipe(
+ new Ingredient(manager, recipe.get("result").getAsString()),
+ new Ingredient(manager, recipe.get("cost").getAsString()),
+ recipe.has("min") ? recipe.get("min").getAsInt() : -1,
+ recipe.has("max") ? recipe.get("max").getAsInt() : -1
+ );
+ }
}
diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/tab.png b/src/main/resources/assets/notenoughupdates/textures/gui/tab.png
new file mode 100644
index 00000000..91d317ca
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/gui/tab.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/textures/icons/recipe_crafting.png b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_crafting.png
new file mode 100644
index 00000000..dd1bd3e1
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_crafting.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/textures/icons/recipe_forge.png b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_forge.png
new file mode 100644
index 00000000..a9d54287
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_forge.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/textures/icons/recipe_trade.png b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_trade.png
new file mode 100644
index 00000000..7bbfd936
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/textures/icons/recipe_trade.png
Binary files differ