diff options
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java')
| -rw-r--r-- | src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java | 1704 |
1 files changed, 1704 insertions, 0 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java new file mode 100644 index 00000000..e60ca14f --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -0,0 +1,1704 @@ +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.infopanes.*; +import io.github.moulberry.notenoughupdates.itemeditor.NEUItemEditor; +import io.github.moulberry.notenoughupdates.util.LerpingFloat; +import io.github.moulberry.notenoughupdates.util.LerpingInteger; +import io.github.moulberry.notenoughupdates.util.TexLoc; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.*; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.client.shader.Shader; +import net.minecraft.client.shader.ShaderGroup; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Matrix4f; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import org.apache.commons.lang3.StringUtils; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.text.NumberFormat; +import java.util.List; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import static io.github.moulberry.notenoughupdates.GuiTextures.*; + +public class NEUOverlay extends Gui { + + private NEUManager manager; + + private String mobRegex = ".*?((_MONSTER)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$"; + private String petRegex = ".*?;[0-4]$"; + + private ResourceLocation[] sortIcons = new ResourceLocation[] { + sort_all, sort_mob, sort_pet, sort_tool, sort_armor, sort_accessory + }; + private ResourceLocation[] sortIconsActive = new ResourceLocation[] { + sort_all_active, sort_mob_active, sort_pet_active, sort_tool_active, sort_armor_active, sort_accessory_active + }; + + private ResourceLocation[] orderIcons = new ResourceLocation[] { + order_alphabetical, order_rarity + }; + private ResourceLocation[] orderIconsActive = new ResourceLocation[] { + order_alphabetical_active, order_rarity_active + }; + + private int searchBarXSize = 200; + private final int searchBarYOffset = 10; + private final int searchBarYSize = 40; + private final int searchBarPadding = 2; + + public static final int BOX_PADDING = 15; + public static final int ITEM_PADDING = 4; + public static final int ITEM_SIZE = 16; + + private Color bg = new Color(90, 90, 140, 50); + private Color fg = new Color(100,100,100, 255); + + //private String informationPaneTitle; + //private ResourceLocation informationPaneImage = null; + //private String[] informationPane; + //private AtomicInteger webpageAwaitID = new AtomicInteger(-1); + //private boolean configOpen = false; + private InfoPane activeInfoPane = null; + + private TreeSet<JsonObject> searchedItems = null; + private JsonObject[] searchedItemsArr = null; + + private boolean itemPaneOpen = false; + private boolean hoveringItemPaneToggle = false; + + private int page = 0; + + private LerpingFloat itemPaneOffsetFactor = new LerpingFloat(1); + private LerpingInteger itemPaneTabOffset = new LerpingInteger(20, 50); + private LerpingFloat infoPaneOffsetFactor = new LerpingFloat(0); + + private boolean searchMode = false; + private long millisLastLeftClick = 0; + + boolean mouseDown = false; + + private boolean redrawItems = false; + + private boolean searchBarHasFocus = false; + GuiTextField textField = new GuiTextField(0, null, 0, 0, 0, 0); + + private static final int COMPARE_MODE_ALPHABETICAL = 0; + private static final int COMPARE_MODE_RARITY = 1; + + private static final int SORT_MODE_ALL = 0; + private static final int SORT_MODE_MOB = 1; + private static final int SORT_MODE_PET = 2; + private static final int SORT_MODE_TOOL = 3; + private static final int SORT_MODE_ARMOR = 4; + private static final int SORT_MODE_ACCESSORY = 5; + + private ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); + + public NEUOverlay(NEUManager manager) { + this.manager = manager; + textField.setFocused(true); + textField.setCanLoseFocus(false); + } + + public void reset() { + searchBarHasFocus = false; + if(!(searchMode || (manager.config.keepopen.value && itemPaneOpen))) { + itemPaneOpen = false; + itemPaneOffsetFactor.setValue(1); + itemPaneTabOffset.setValue(20); + } + } + + public void showInfo(JsonObject item) { + if(item.has("info") && item.has("infoType")) { + JsonArray lore = item.get("info").getAsJsonArray(); + String[] loreA = new String[lore.size()]; + for (int i = 0; i < lore.size(); i++) loreA[i] = lore.get(i).getAsString(); + String loreS = StringUtils.join(loreA, "\n"); + + String name = item.get("displayname").getAsString(); + switch(item.get("infoType").getAsString()) { + case "WIKI_URL": + displayInformationPane(HTMLInfoPane.createFromWikiUrl(this, manager, name, loreS)); + return; + case "WIKI": + displayInformationPane(HTMLInfoPane.createFromWiki(this, manager, name, loreS)); + return; + case "HTML": + displayInformationPane(new HTMLInfoPane(this, manager, name, loreS)); + return; + } + displayInformationPane(new TextInfoPane(this, manager, name, loreS)); + } + } + + /** + * Handles the mouse input, cancelling the forge event if a NEU gui element is clicked. + */ + public boolean mouseInput() { + int width = scaledresolution.getScaledWidth(); + int height = scaledresolution.getScaledHeight(); + + int mouseX = Mouse.getX() / scaledresolution.getScaleFactor(); + int mouseY = height - Mouse.getY() / scaledresolution.getScaleFactor(); + + if(Mouse.getEventButtonState()) { + mouseDown = true; + } else if(Mouse.getEventButton() != -1) { + mouseDown = false; + } + + //Unfocuses the search bar by default. Search bar is focused if the click is on the bar itself. + if(Mouse.getEventButtonState()) setSearchBarFocus(false); + + //Item selection (right) gui + if(mouseX > width*getItemPaneOffsetFactor()) { + if(!Mouse.getEventButtonState()) return true; //End early if the mouse isn't pressed, but still cancel event. + + AtomicBoolean clickedItem = new AtomicBoolean(false); + iterateItemSlots(new ItemSlotConsumer() { + public void consume(int x, int y, int id) { + if(mouseX >= x-1 && mouseX <= x+ITEM_SIZE+1) { + if(mouseY >= y-1 && mouseY <= y+ITEM_SIZE+1) { + clickedItem.set(true); + + JsonObject item = getSearchedItemPage(id); + if (item != null) { + if(Mouse.getEventButton() == 0) { + manager.showRecipe(item); + } else if(Mouse.getEventButton() == 1) { + showInfo(item); + } else if(Mouse.getEventButton() == 2) { + textField.setText("id:"+item.get("internalname").getAsString()); + updateSearch(); + searchMode = true; + } + } + } + } + } + }); + if(!clickedItem.get()) { + int paneWidth = (int)(width/3*getWidthMult()); + int leftSide = (int)(width*getItemPaneOffsetFactor()); + int rightSide = leftSide+paneWidth-BOX_PADDING-getItemBoxXPadding(); + leftSide = leftSide+BOX_PADDING+getItemBoxXPadding(); + + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + int maxPages = getMaxPages(); + String name = scaledresolution.getScaleFactor()<4?"Page: ":""; + float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD+name + maxPages + "/" + maxPages); + float maxButtonXSize = (rightSide-leftSide+2 - maxStrLen*0.5f - 10)/2f; + int buttonXSize = (int)Math.min(maxButtonXSize, getSearchBarYSize()*480/160f); + int ySize = (int)(buttonXSize/480f*160); + int yOffset = (int)((getSearchBarYSize()-ySize)/2f); + int top = BOX_PADDING+yOffset; + + if(mouseY >= top && mouseY <= top+ySize) { + int leftPrev = leftSide-1; + if(mouseX > leftPrev && mouseX < leftPrev+buttonXSize) { //"Previous" button + setPage(page-1); + } + int leftNext = rightSide+1-buttonXSize; + if(mouseX > leftNext && mouseX < leftNext+buttonXSize) { //"Next" button + setPage(page+1); + } + } + + float sortIconsMinX = (sortIcons.length+orderIcons.length)*(ITEM_SIZE+ITEM_PADDING)+ITEM_SIZE; + float availableX = rightSide-(leftSide+BOX_PADDING+getItemBoxXPadding()); + float sortOrderScaleFactor = Math.min(1, availableX / sortIconsMinX); + + int scaledITEM_SIZE = (int)(ITEM_SIZE*sortOrderScaleFactor); + int scaledItemPaddedSize = (int)((ITEM_SIZE+ITEM_PADDING)*sortOrderScaleFactor); + int iconTop = height-BOX_PADDING-(ITEM_SIZE+scaledITEM_SIZE)/2-1; + + if(mouseY >= iconTop && mouseY <= iconTop+scaledITEM_SIZE) { + for(int i=0; i<orderIcons.length; i++) { + int orderIconX = leftSide+BOX_PADDING+getItemBoxXPadding()+i*scaledItemPaddedSize; + if(mouseX >= orderIconX && mouseX <= orderIconX+scaledITEM_SIZE) { + if(Mouse.getEventButton() == 0) { + manager.config.compareMode.value = new Double(i); + updateSearch(); + } else if(Mouse.getEventButton() == 1) { + manager.config.compareAscending.value.set(i, !manager.config.compareAscending.value.get(i)); + updateSearch(); + } + } + } + + for(int i=0; i<sortIcons.length; i++) { + int sortIconX = rightSide-scaledITEM_SIZE-i*scaledItemPaddedSize; + if(mouseX >= sortIconX && mouseX <= sortIconX+scaledITEM_SIZE) { + manager.config.sortMode.value = new Double(i); + updateSearch(); + } + } + } + } + return true; + } + + if(Mouse.getEventButton() == 2) { + Slot slot = Utils.getSlotUnderMouse((GuiContainer)Minecraft.getMinecraft().currentScreen); + if(slot != null) { + ItemStack hover = slot.getStack(); + if(hover != null) { + textField.setText("id:"+manager.getInternalNameForItem(hover)); + updateSearch(); + searchMode = true; + return true; + } + } + } + + //Clicking on "close info pane" button + if(mouseX > width*getInfoPaneOffsetFactor()-22 && mouseX < width*getInfoPaneOffsetFactor()-6) { + if(mouseY > 7 && mouseY < 23) { + if(Mouse.getEventButtonState() && Mouse.getEventButton() < 2) { //Left or right click up + displayInformationPane(null); + return true; + } + } + } + + //Search bar + if(mouseX >= width/2 - getSearchBarXSize()/2 && mouseX <= width/2 + getSearchBarXSize()/2) { + if(mouseY >= height - searchBarYOffset - getSearchBarYSize() && + mouseY <= height - searchBarYOffset) { + if(Mouse.getEventButtonState()) { + setSearchBarFocus(true); + if(Mouse.getEventButton() == 1) { //Right mouse button down + textField.setText(""); + updateSearch(); + } else { + if(System.currentTimeMillis() - millisLastLeftClick < 300) { + searchMode = !searchMode; + } + textField.setCursorPosition(getClickedIndex(mouseX, mouseY)); + millisLastLeftClick = System.currentTimeMillis(); + } + } + return true; + } + } + + int paddingUnscaled = searchBarPadding/scaledresolution.getScaleFactor(); + int topTextBox = height - searchBarYOffset - getSearchBarYSize(); + int iconSize = getSearchBarYSize()+paddingUnscaled*2; + if(paddingUnscaled < 1) paddingUnscaled = 1; + + if(mouseY > topTextBox - paddingUnscaled && mouseY < topTextBox - paddingUnscaled + iconSize) { + if(mouseX > width/2 + getSearchBarXSize()/2 + paddingUnscaled*6 && + mouseX < width/2 + getSearchBarXSize()/2 + paddingUnscaled*6 + iconSize) { + if(Mouse.getEventButtonState()) { + displayInformationPane(HTMLInfoPane.createFromWikiUrl(this, manager, "Help", + "https://moulberry.github.io/files/neu_help.html")); + } + } else if(mouseX > width/2 - getSearchBarXSize()/2 - paddingUnscaled*6 - iconSize && + mouseX < width/2 - getSearchBarXSize()/2 - paddingUnscaled*6) { + if(Mouse.getEventButtonState()) { + if(activeInfoPane instanceof SettingsInfoPane) { + displayInformationPane(null); + } else { + displayInformationPane(new SettingsInfoPane(this, manager)); + } + } + } + } + + if(activeInfoPane != null) { + if(mouseX < width*getInfoPaneOffsetFactor()) { + activeInfoPane.mouseInput(width, height, mouseX, mouseY, mouseDown); + return true; + } + } + + return false; + } + + public int getSearchBarXSize() { + if(scaledresolution.getScaleFactor()==4) return (int)(searchBarXSize*0.8); + return searchBarXSize; + } + + public void displayInformationPane(InfoPane pane) { + if(pane == null) { + infoPaneOffsetFactor.setTarget(0); + } else { + infoPaneOffsetFactor.setTarget(1/3f); + } + infoPaneOffsetFactor.resetTimer(); + this.activeInfoPane = pane; + } + + public InfoPane getActiveInfoPane() { + return activeInfoPane; + } + + /*public void displayInformationPane(String title, String infoType, String[] info) { + scrollHeight.setValue(0); + informationPaneTitle = title; + informationPaneImage = null; + informationPane = null; + + configOpen = false; + + infoPaneOffsetFactor.setTarget(1/3f); + infoPaneOffsetFactor.resetTimer(); + + webpageAwaitID.incrementAndGet(); + + if(info == null || info.length == 0) { + informationPane = new String[]{"\u00A77No additional information."}; + } else { + String joined = StringUtils.join(info, "\n"); + String wiki = null; + String html = null; + if(infoType.equals("TEXT")) { + informationPane = info; + return; + } else if(infoType.equals("WIKI_URL")) { + File f = manager.getWebFile(joined); + if(f == null) { + informationPane = new String[] { EnumChatFormatting.RED+"Failed to load wiki url: "+joined }; + return; + }; + + StringBuilder sb = new StringBuilder(); + try(BufferedReader br = new BufferedReader(new InputStreamReader( + new FileInputStream(f), StandardCharsets.UTF_8))) { + String l; + while((l = br.readLine()) != null){ + sb.append(l).append("\n"); + } + } catch(IOException e) { + informationPane = new String[] { EnumChatFormatting.RED+"Failed to load wiki url: "+joined }; + return; + } + wiki = sb.toString(); + } + + if(infoType.equals("WIKI") || wiki != null) { + if(wiki == null) wiki = joined; + try { + String[] split = wiki.split("</infobox>"); + wiki = split[split.length - 1]; //Remove everything before infobox + wiki = wiki.split("<span class=\"navbox-vde\">")[0]; //Remove navbox + wiki = wiki.split("<table class=\"navbox mw-collapsible\"")[0]; + wiki = "__NOTOC__\n" + wiki; //Remove TOC + try (PrintWriter out = new PrintWriter(new File(manager.configLocation, "debug/parsed.txt"))) { + out.println(wiki); + } catch (IOException e) { + } + html = wikiModel.render(wiki); + try (PrintWriter out = new PrintWriter(new File(manager.configLocation, "debug/html.txt"))) { + out.println(html); + } catch (IOException e) { + } + } catch (Exception e) { + informationPane = new String[]{EnumChatFormatting.RED + "Failed to parse wiki: " + joined}; + return; + } + } + + if(infoType.equals("HTML") || html != null) { + if(html == null) html = joined; + processAndSetWebpageImage(html, title); + } + } + }*/ + + public int getClickedIndex(int mouseX, int mouseY) { + int width = scaledresolution.getScaledWidth(); + int height = scaledresolution.getScaledHeight(); + + int xComp = mouseX - (width/2 - getSearchBarXSize()/2 + 5); + + String trimmed = Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(textField.getText(), xComp); + int linePos = trimmed.length(); + if(linePos != textField.getText().length()) { + char after = textField.getText().charAt(linePos); + int trimmedWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(trimmed); + int charWidth = Minecraft.getMinecraft().fontRendererObj.getCharWidth(after); + if(trimmedWidth + charWidth/2 < xComp-5) { + linePos++; + } + } + return linePos; + } + + public void setSearchBarFocus(boolean focus) { + if(focus) { + itemPaneOpen = true; + } + searchBarHasFocus = focus; + } + + /** + * Handles the keyboard input, cancelling the forge event if the search bar has focus. + */ + public boolean keyboardInput(boolean hoverInv) { + if(Minecraft.getMinecraft().currentScreen == null) return false; + Keyboard.enableRepeatEvents(true); + + if(Keyboard.isKeyDown(Keyboard.KEY_Y)) { + displayInformationPane(new DevInfoPane(this, manager)); + //displayInformationPane(new QOLInfoPane(this, manager)); + } + + if(Keyboard.getEventKeyState()) { + if(searchBarHasFocus) { + if(Keyboard.getEventKey() == 1) { + searchBarHasFocus = false; + } else { + if(textField.textboxKeyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey())) { + updateSearch(); + } + } + } else { + if(activeInfoPane != null) { + activeInfoPane.keyboardInput(); + } + + AtomicReference<String> internalname = new AtomicReference<>(null); + AtomicReference<ItemStack> itemstack = new AtomicReference<>(null); + Slot slot = Utils.getSlotUnderMouse((GuiContainer)Minecraft.getMinecraft().currentScreen); + if(slot != null) { + ItemStack hover = slot.getStack(); + if(hover != null) { + internalname.set(manager.getInternalNameForItem(hover)); + itemstack.set(hover); + } + } else if(!hoverInv) { + int height = scaledresolution.getScaledHeight(); + + int mouseX = Mouse.getX() / scaledresolution.getScaleFactor(); + int mouseY = height - Mouse.getY() / scaledresolution.getScaleFactor(); + + iterateItemSlots(new ItemSlotConsumer() { + public void consume(int x, int y, int id) { + if (mouseX >= x - 1 && mouseX <= x + ITEM_SIZE + 1) { + if (mouseY >= y - 1 && mouseY <= y + ITEM_SIZE + 1) { + JsonObject json = getSearchedItemPage(id); + if (json != null) internalname.set(json.get("internalname").getAsString()); + } + } + } + }); + } + if(internalname.get() != null) { + if(itemstack.get() != null) { + if(manager.config.enableItemEditing.value && Keyboard.getEventCharacter() == 'k') { + Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager, + internalname.get(), manager.getJsonForItem(itemstack.get()))); + return true; + } + } + JsonObject item = manager.getItemInformation().get(internalname.get()); + if(item != null) { + if(Keyboard.getEventCharacter() == 'u') { + manager.displayGuiItemUsages(internalname.get(), ""); + return true; + } else if(Keyboard.getEventCharacter() == 'f') { + toggleRarity(item.get("internalname").getAsString()); + return true; + } else if(Keyboard.getEventCharacter() == 'r') { + manager.showRecipe(item); + return true; + } else if(Keyboard.getEventCharacter() == 'l') { + if(Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) { + Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory( + manager.jsonToStack(item)); + } + } else if(manager.config.enableItemEditing.value && Keyboard.getEventCharacter() == 'k') { + Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager, + internalname.get(), item)); + return true; + } + } + } + } + } + + return searchBarHasFocus; //Cancels keyboard events if the search bar has focus + } + + public void toggleRarity(String internalname) { + if(getFavourites().contains(internalname)) { + getFavourites().remove(internalname); + } else { + getFavourites().add(internalname); + } + updateSearch(); + } + + String[] rarityArr = new String[] { + EnumChatFormatting.WHITE+EnumChatFormatting.BOLD.toString()+"COMMON", + EnumChatFormatting.GREEN+EnumChatFormatting.BOLD.toString()+"UNCOMMON", + EnumChatFormatting.BLUE+EnumChatFormatting.BOLD.toString()+"RARE", + EnumChatFormatting.DARK_PURPLE+EnumChatFormatting.BOLD.toString()+"EPIC", + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD.toString()+"LEGENDARY", + EnumChatFormatting.LIGHT_PURPLE+EnumChatFormatting.BOLD.toString()+"SPECIAL", + }; + public int getRarity(JsonArray lore) { + for(int i=lore.size()-1; i>=0; i--) { + String line = lore.get(i).getAsString(); + + for(int j=0; j<rarityArr.length; j++) { + if(line.startsWith(rarityArr[j])) { + return j; + } + } + } + return -1; + } + + private int getCompareMode() { + return manager.config.compareMode.value.intValue(); + } + private int getSortMode() { + return manager.config.sortMode.value.intValue(); + } + private List<Boolean> getCompareAscending() { + return manager.config.compareAscending.value; + } + private List<String> getFavourites() { + return manager.config.favourites.value; + } + + private Comparator<JsonObject> getItemComparator() { + return (o1, o2) -> { + //1 (mult) if o1 should appear after o2 + //-1 (-mult) if o2 should appear after o1 + if(getFavourites().contains(o1.get("internalname").getAsString()) && !getFavourites().contains(o2.get("internalname").getAsString())) { + return -1; + } + if(!getFavourites().contains(o1.get("internalname").getAsString()) && getFavourites().contains(o2.get("internalname").getAsString())) { + return 1; + } + + int mult = getCompareAscending().get(getCompareMode()) ? 1 : -1; + if(getCompareMode() == COMPARE_MODE_RARITY) { + int rarity1 = getRarity(o1.get("lore").getAsJsonArray()); + int rarity2 = getRarity(o2.get("lore").getAsJsonArray()); + + if(rarity1 < rarity2) return mult; + if(rarity1 > rarity2) return -mult; + } + + String i1 = o1.get("internalname").getAsString(); + String[] split1 = i1.split("_"); + String last1 = split1[split1.length-1]; + String start1 = i1.substring(0, i1.length()-last1.length()); + + String i2 = o2.get("internalname").getAsString(); + String[] split2 = i2.split("_"); + String last2 = split2[split2.length-1]; + String start2 = i2.substring(0, i2.length()-last2.length()); + + mult = getCompareAscending().get(COMPARE_MODE_ALPHABETICAL) ? 1 : -1; + if(start1.equals(start2)) { + String[] order = new String[]{"HELMET","CHESTPLATE","LEGGINGS","BOOTS"}; + int type1 = checkItemType(o1.get("lore").getAsJsonArray(), order); + int type2 = checkItemType(o2.get("lore").getAsJsonArray(), order); + + + if(type1 < type2) return -mult; + if(type1 > type2) return mult; + } + + int nameComp = mult*o1.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", "") + .compareTo(o2.get("displayname").getAsString().replaceAll("(?i)\\u00A7.", "")); + if(nameComp != 0) { + return nameComp; + } + return mult*o1.get("internalname").getAsString().compareTo(o2.get("internalname").getAsString()); + }; + } + + public int checkItemType(JsonArray lore, String... typeMatches) { + for(int i=lore.size()-1; i>=0; i--) { + String line = lore.get(i).getAsString(); + + for(String rarity : rarityArr) { + for(int j=0; j<typeMatches.length; j++) { + if(line.trim().equals(rarity + " " + typeMatches[j])) { + return j; + } + } + } + } + return -1; + } + + public boolean checkMatchesSort(String internalname, JsonObject item) { + if(getSortMode() == SORT_MODE_ALL) { + return !internalname.matches(mobRegex); + } else if(getSortMode() == SORT_MODE_MOB) { + return internalname.matches(mobRegex); + } else if(getSortMode() == SORT_MODE_PET) { + return internalname.matches(petRegex); + } else if(getSortMode() == SORT_MODE_TOOL) { + return checkItemType(item.get("lore").getAsJsonArray(), + "SWORD", "BOW", "AXE", "PICKAXE", "FISHING ROD", "WAND", "SHOVEL", "HOE") >= 0; + } else if(getSortMode() == SORT_MODE_ARMOR) { + return checkItemType(item.get("lore").getAsJsonArray(), "HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS") >= 0; + } else if(getSortMode() == SORT_MODE_ACCESSORY) { + return checkItemType(item.get("lore").getAsJsonArray(), "ACCESSORY") >= 0; + } + return true; + } + + public void updateSearch() { + if(searchedItems==null) searchedItems = new TreeSet<>(getItemComparator()); + searchedItems.clear(); + searchedItemsArr = null; + redrawItems = true; + Set<String> itemsMatch = manager.search(textField.getText()); + for(String itemname : itemsMatch) { + JsonObject item = manager.getItemInformation().get(itemname); + if(checkMatchesSort(itemname, item)) { + searchedItems.add(item); + } + } + } + + public JsonObject[] getSearchedItems() { + if(searchedItems==null) { + updateSearch(); + } + if(searchedItemsArr==null) { + searchedItemsArr = new JsonObject[searchedItems.size()]; + int i=0; + for(JsonObject item : searchedItems) { + searchedItemsArr[i] = item; + i++; + } + } + return searchedItemsArr; + } + + public JsonObject getSearchedItemPage(int index) { + if(index < getSlotsXSize()*getSlotsYSize()) { + int actualIndex = index + getSlotsXSize()*getSlotsYSize()*page; + if(actualIndex < getSearchedItems().length) { + return getSearchedItems()[actualIndex]; + } else { + return null; + } + } else { + return null; + } + } + + public int getItemBoxXPadding() { + int width = scaledresolution.getScaledWidth(); + return (((int)(width/3*getWidthMult())-2*BOX_PADDING)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + } + + private abstract class ItemSlotConsumer { + public abstract void consume(int x, int y, int id); + } + + public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer) { + int width = scaledresolution.getScaledWidth(); + int itemBoxXPadding = getItemBoxXPadding(); + iterateItemSlots(itemSlotConsumer, (int)(width*getItemPaneOffsetFactor())+BOX_PADDING+itemBoxXPadding); + } + + /** + * Iterates through all the item slots in the right panel and calls a ItemSlotConsumer for each slot with + * arguments equal to the slot's x and y position respectively. This is used in order to prevent + * code duplication issues. + */ + public void iterateItemSlots(ItemSlotConsumer itemSlotConsumer, int xStart) { + int width = scaledresolution.getScaledWidth(); + int height = scaledresolution.getScaledHeight(); + + int paneWidth = (int)(width/3*getWidthMult()); + int itemBoxYPadding = ((height-getSearchBarYSize()-2*BOX_PADDING-ITEM_SIZE-2)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + + int yStart = BOX_PADDING+getSearchBarYSize()+itemBoxYPadding; + int itemBoxXPadding = getItemBoxXPadding(); + int xEnd = xStart+paneWidth-BOX_PADDING*2-ITEM_SIZE-itemBoxXPadding; + int yEnd = height-BOX_PADDING-ITEM_SIZE-2-itemBoxYPadding; + + //Render the items, displaying the tooltip if the cursor is over the item + int id = 0; + for(int y = yStart; y < yEnd; y+=ITEM_SIZE+ITEM_PADDING) { + for(int x = xStart; x < xEnd; x+=ITEM_SIZE+ITEM_PADDING) { + itemSlotConsumer.consume(x, y, id++); + } + } + } + + public float getWidthMult() { + float scaleFMult = 1; + if(scaledresolution.getScaleFactor()==4) scaleFMult = 0.9f; + return (float)Math.max(0.5, Math.min(1.5, manager.config.paneWidthMult.value.floatValue()))*scaleFMult; + } + + /** + * Calculates the number of horizontal item slots. + */ + public int getSlotsXSize() { + int width = scaledresolution.getScaledWidth(); + + int paneWidth = (int)(width/3*getWidthMult()); + int itemBoxXPadding = (((int)(width-width*getItemPaneOffsetFactor())-2*BOX_PADDING)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + int xStart = (int)(width*getItemPaneOffsetFactor())+BOX_PADDING+itemBoxXPadding; + int xEnd = (int)(width*getItemPaneOffsetFactor())+paneWidth-BOX_PADDING-ITEM_SIZE; + + return (int)Math.ceil((xEnd - xStart)/((float)(ITEM_SIZE+ITEM_PADDING))); + } + + /** + * Calculates the number of vertical item slots. + */ + public int getSlotsYSize() { + int height = scaledresolution.getScaledHeight(); + + int itemBoxYPadding = ((height-getSearchBarYSize()-2*BOX_PADDING-ITEM_SIZE-2)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + int yStart = BOX_PADDING+getSearchBarYSize()+itemBoxYPadding; + int yEnd = height-BOX_PADDING-ITEM_SIZE-2-itemBoxYPadding; + + return (int)Math.ceil((yEnd - yStart)/((float)(ITEM_SIZE+ITEM_PADDING))); + } + + public int getMaxPages() { + if(getSearchedItems().length == 0) return 1; + return (int)Math.ceil(getSearchedItems().length/(float)getSlotsYSize()/getSlotsXSize()); + } + + /** + * Takes in the x and y coordinates of a slot and returns the id of that slot. + */ + /*public int getSlotId(int x, int y) { + int width = scaledresolution.getScaledWidth(); + int height = scaledresolution.getScaledHeight(); + + int itemBoxXPadding = (((int)(width-width*getItemPaneOffsetFactor())-2*BOX_PADDING)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + int itemBoxYPadding = ((height-getSearchBarYSize()-2*BOX_PADDING-ITEM_SIZE-2)%(ITEM_SIZE+ITEM_PADDING)+ITEM_PADDING)/2; + + int xStart = (int)(width*getItemPaneOffsetFactor())+BOX_PADDING+itemBoxXPadding; + int yStart = BOX_PADDING+getSearchBarYSize()+itemBoxYPadding; + + int xIndex = (x-xStart)/(ITEM_SIZE+ITEM_PADDING); + int yIndex = (y-yStart)/(ITEM_SIZE+ITEM_PADDING); + return xIndex + yIndex*getSlotsXSize(); + }*/ + + public int getSearchBarYSize() { + return Math.max(searchBarYSize/scaledresolution.getScaleFactor(), ITEM_SIZE); + } + + public void renderNavElement(int leftSide, int rightSide, int maxPages, int page, String name) { + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + + String pageText = EnumChatFormatting.BOLD+name + page + "/" + maxPages; + + float maxStrLen = fr.getStringWidth(EnumChatFormatting.BOLD+name + maxPages + "/" + maxPages); + float maxButtonXSize = (rightSide-leftSide+2 - maxStrLen*0.5f - 10)/2f; + int buttonXSize = (int)Math.min(maxButtonXSize, getSearchBarYSize()*480/160f); + int ySize = (int)(buttonXSize/480f*160); + int yOffset = (int)((getSearchBarYSize()-ySize)/2f); + int top = BOX_PADDING+yOffset; + + /*drawRect(leftSide-1, top, + rightSide+1, + top+ySize, fg.getRGB());*/ + + int leftPressed = 0; + int rightPressed = 0; + + if(Mouse.isButtonDown(0) || Mouse.isButtonDown(1)) { + int height = scaledresolution.getScaledHeight(); + + int mouseX = Mouse.getX() / scaledresolution.getScaleFactor(); + int mouseY = height - Mouse.getY() / scaledresolution.getScaleFactor(); + + if(mouseY >= top && mouseY <= top+ySize) { + int leftPrev = leftSide-1; + if(mouseX > leftPrev && mouseX < leftPrev+buttonXSize) { //"Previous" button + leftPressed = 1; + } + int leftNext = rightSide+1-buttonXSize; + if(mouseX > leftNext && mouseX < leftNext+buttonXSize) { //"Next" button + rightPressed = 1; + } + } + } + + drawRect(leftSide-1, top, leftSide-1+buttonXSize, top+ySize, fg.getRGB()); + GlStateManager.color(1f, 1f, 1f, 1f); + Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow); + Utils.drawTexturedRect(leftSide-1+leftPressed, + top+leftPressed, + buttonXSize, ySize, 1, 0, 0, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay); + Utils.drawTexturedRect(leftSide-1, + top, + buttonXSize, ySize, 1-leftPressed, leftPressed, 1-leftPressed, leftPressed); + GlStateManager.bindTexture(0); + Utils.drawStringCenteredScaled(EnumChatFormatting.BOLD+"Prev", fr, + leftSide-1+buttonXSize*300/480f+leftPressed, + top+ySize/2f+leftPressed, false, + (int)(buttonXSize*240/480f), Color.BLACK.getRGB()); + + drawRect(rightSide+1-buttonXSize, top, rightSide+1, top+ySize, fg.getRGB()); + GlStateManager.color(1f, 1f, 1f, 1f); + Minecraft.getMinecraft().getTextureManager().bindTexture(ri |
