diff options
author | Moulberry <james.jenour@student.scotch.wa.edu.au> | 2020-11-23 03:34:12 +1100 |
---|---|---|
committer | Moulberry <james.jenour@student.scotch.wa.edu.au> | 2020-11-23 03:34:12 +1100 |
commit | 089bac89c5435eb7e5cf80e7602da953a65f5b1a (patch) | |
tree | ea6aea2afc38f6ef02884f0c3babdc5ed86058bb /src/main/java/io | |
parent | 07403ec86c53f67b94d988b4c01a0afc2fdb2810 (diff) | |
download | NotEnoughUpdates-089bac89c5435eb7e5cf80e7602da953a65f5b1a.tar.gz NotEnoughUpdates-089bac89c5435eb7e5cf80e7602da953a65f5b1a.tar.bz2 NotEnoughUpdates-089bac89c5435eb7e5cf80e7602da953a65f5b1a.zip |
1.71.7.1-REL
Diffstat (limited to 'src/main/java/io')
22 files changed, 2396 insertions, 225 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/BetterContainers.java b/src/main/java/io/github/moulberry/notenoughupdates/BetterContainers.java index fac3a8d1..07fff01b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/BetterContainers.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/BetterContainers.java @@ -102,17 +102,17 @@ public class BetterContainers { return usingCached && System.currentTimeMillis() - lastRenderMillis < 300; } - public static boolean isAh() { + public static boolean isBlacklistedInventory() { if(!isChestOpen()) return false; GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest cc = (ContainerChest) eventGui.inventorySlots; String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - return containerName.trim().startsWith("Auctions Browser") || containerName.trim().startsWith("Wardrobe"); + return containerName.toLowerCase().trim().startsWith("navigate the maze"); } public static boolean isOverriding() { - return isChestOpen() && ((loaded && texture != null)); + return isChestOpen() && ((loaded && texture != null)) && !isBlacklistedInventory(); } public static boolean isBlankStack(ItemStack stack) { @@ -171,7 +171,6 @@ public class BetterContainers { textColour = (int)Long.parseLong(textColourS, 16); } catch(Exception e) { textColour = 4210752; - e.printStackTrace(); } try { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/CalendarOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/CalendarOverlay.java new file mode 100644 index 00000000..ff6c500b --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/CalendarOverlay.java @@ -0,0 +1,1414 @@ +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.client.shader.Shader; +import net.minecraft.init.Items; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.Matrix4f; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.sound.SoundEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; +import static io.github.moulberry.notenoughupdates.GuiTextures.*; + +import java.io.File; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CalendarOverlay { + + private static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates:calendar/background.png"); + private static final ResourceLocation DISPLAYBAR = new ResourceLocation("notenoughupdates:calendar/displaybar.png"); + private static final ResourceLocation TOAST = new ResourceLocation("notenoughupdates:calendar/toast.png"); + + private static JsonObject farmingEventTypes = null; + + private static boolean enabled = false; + + public static void setEnabled(boolean enabled) { + CalendarOverlay.enabled = enabled; + } + + public static boolean isEnabled() { + return enabled; + } + + private int guiLeft = -1; + private int guiTop = -1; + private int xSize = 168; + private int ySize = 170; + + private class SBEvent { + String id; + String display; + ItemStack stack; + List<String> desc; + long lastsFor; + + public SBEvent(String id, String display, ItemStack stack, List<String> desc) { + this(id, display, stack, desc, -1); + } + + public SBEvent(String id, String display, ItemStack stack, List<String> desc, long lastsFor) { + this.id = id; + this.display = display; + this.stack = stack; + this.desc = desc; + this.lastsFor = lastsFor; + } + } + + private int jingleIndex = -1; + + private TreeMap<Long, Set<SBEvent>> eventMap = new TreeMap<>(); + private List<String> jfFavouriteSelect = null; + private int jfFavouriteSelectIndex = 0; + private int jfFavouriteSelectX = 0; + private int jfFavouriteSelectY = 0; + + private static long SECOND = 1000; + private static long MINUTE = SECOND*60; + private static long HOUR = MINUTE*60; + private static long DAY = HOUR*24; + + private static long DA_OFFSET = 1000*60*55; + private static long JF_OFFSET = 1000*60*15; + + private static ItemStack DA_STACK; + private static ItemStack JF_STACK; + static { + NBTTagCompound tag = new NBTTagCompound(); + tag.setString("event_id", "dark_auction"); + //tag.setTag("ench", new NBTTagList()); + + DA_STACK = new ItemStack(Items.netherbrick); + DA_STACK.setTagCompound(tag); + + tag.setString("event_id", "jacob_farming"); + JF_STACK = new ItemStack(Items.wheat); + JF_STACK.setTagCompound(tag); + } + + public long getTimeOffset(String time) { + long offset = 0; + + StringBuilder numS = new StringBuilder(); + for(int timeIndex=0; timeIndex<time.length(); timeIndex++) { + char c = time.charAt(timeIndex); + + if(c >= '0' && c <= '9') { + numS.append(c); + } else { + try { + int num = Integer.parseInt(numS.toString()); + switch (c) { + case 'd': + offset += num * DAY; continue; + case 'h': + offset += num * HOUR; continue; + case 'm': + offset += num * MINUTE; continue; + case 's': + offset += num * SECOND; continue; + } + } catch(Exception ignored) {} + numS = new StringBuilder(); + } + } + + return offset; + } + + private static Pattern CALENDAR_PATTERN = Pattern.compile("([A-Za-z ]+), Year ([0-9]+)"); + private static long SKYBLOCK_START = 1559829300000L; //Day 0, Year 0 + + @SubscribeEvent + public void tick(TickEvent.ClientTickEvent event) { + if(event.phase != TickEvent.Phase.START) return; + + if(jingleIndex == 0) { + if (NotEnoughUpdates.INSTANCE.manager.config.eventNotificationSounds.value) { + Minecraft.getMinecraft().thePlayer.playSound("notenoughupdates:calendar_notif_jingle", 1, 1); + } + if (NotEnoughUpdates.INSTANCE.manager.config.eventNotificationSounds.value) { + Minecraft.getMinecraft().thePlayer.playSound("notenoughupdates:calendar_notif_in", 1, 1); + } + jingleIndex = -15*20; + } else if(jingleIndex >= 1) { + if (NotEnoughUpdates.INSTANCE.manager.config.eventNotificationSounds.value) { + Minecraft.getMinecraft().thePlayer.playSound("notenoughupdates:calendar_notif_in", 1, 1); + } + jingleIndex = -15*20; + } else if(jingleIndex < -1) { + jingleIndex++; + } + if(jingleIndex == -20*6-10) { + if(NotEnoughUpdates.INSTANCE.manager.config.eventNotificationSounds.value) { + Minecraft.getMinecraft().thePlayer.playSound("notenoughupdates:calendar_notif_out", 1, 1); + } + } + + if(farmingEventTypes == null) { + farmingEventTypes = NotEnoughUpdates.INSTANCE.manager.getJsonFromFile(new File(NotEnoughUpdates.INSTANCE.manager.configLocation, + "farmingEventTypes.json")); + if(farmingEventTypes == null) { + farmingEventTypes = new JsonObject(); + } + } + + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + jfFavouriteSelect = null; + if(eventMap.isEmpty() || eventMap.size() <= 20) { + long currentTime = System.currentTimeMillis(); + long floorHour = (currentTime/HOUR)*HOUR; + for(int i=0; i<15; i++) { + long daEvent = floorHour+i*HOUR+DA_OFFSET; + long jfEvent = floorHour+i*HOUR+JF_OFFSET; + + if(daEvent > currentTime) { + eventMap.computeIfAbsent(daEvent, k->new HashSet<>()).add(new SBEvent("dark_auction", + EnumChatFormatting.DARK_PURPLE+"Dark Auction", DA_STACK, null, MINUTE*5)); + } + if(jfEvent > currentTime) { + SBEvent jf = new SBEvent("jacob_farming", + EnumChatFormatting.YELLOW+"Jacob's Farming Contest", JF_STACK, null, MINUTE*20); + if(farmingEventTypes != null && farmingEventTypes.has(""+jfEvent) && + farmingEventTypes.get(""+jfEvent).isJsonArray()) { + JsonArray arr = farmingEventTypes.get(""+jfEvent).getAsJsonArray(); + jf.desc = new ArrayList<>(); + for(JsonElement e : arr) { + jf.desc.add(EnumChatFormatting.YELLOW+"\u25CB "+e.getAsString()); + jf.id += ":" + e.getAsString(); + } + } + eventMap.computeIfAbsent(jfEvent, k->new HashSet<>()).add(jf); + } + } + } + return; + } + + GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + + Matcher matcher = CALENDAR_PATTERN.matcher(Utils.cleanColour(containerName)); + if(farmingEventTypes != null && matcher.matches()) { + try { + int year = Integer.parseInt(matcher.group(2)); + int skyblockDays = year * 12 * 31; + + String month = matcher.group(1); + boolean spring = month.endsWith("Spring"); + boolean summer = month.endsWith("Summer"); + boolean autumn = month.endsWith("Autumn"); + boolean winter = month.endsWith("Winter"); + if(spring || summer || autumn || winter) { + if(spring) { + skyblockDays += 1*31; + } else if(summer) { + skyblockDays += 4*31; + } else if(autumn) { + skyblockDays += 7*31; + } else { + skyblockDays += 10*31; + } + if(month.startsWith("Early")) { + skyblockDays -= 31; + } else if(month.startsWith("Late")) { + skyblockDays += 31; + } + + long start = SKYBLOCK_START + skyblockDays*20*MINUTE; + + boolean changed = false; + for(int i=0; i<31; i++) { + ItemStack item = cc.getLowerChestInventory().getStackInSlot(1+(i%7)+(i/7)*9); + + JsonArray array = new JsonArray(); + if(item.getTagCompound() != null) { + NBTTagCompound tag = item.getTagCompound(); + + if(tag.hasKey("display", 10)) { + NBTTagCompound display = tag.getCompoundTag("display"); + if (display.hasKey("Lore", 9)) { + NBTTagList list = display.getTagList("Lore", 8); + for(int j=0; j<list.tagCount(); j++) { + String line = list.getStringTagAt(j); + if(line.startsWith(EnumChatFormatting.YELLOW+"\u25CB")) { + array.add(new JsonPrimitive(Utils.cleanColour(line.substring(4)))); + } + } + } + } + } + if(array.size() == 3) { + String prop = String.valueOf(start + i*20*MINUTE); + if(!farmingEventTypes.has(prop) || !farmingEventTypes.get(prop).isJsonArray() || + farmingEventTypes.get(prop).getAsJsonArray().equals(array)) { + changed = true; + } + farmingEventTypes.add(prop, array); + } + } + if(changed) { + File f = new File(NotEnoughUpdates.INSTANCE.manager.configLocation, + "farmingEventTypes.json"); + NotEnoughUpdates.INSTANCE.manager.writeJson(farmingEventTypes, f); + } + } + } catch(Exception ignored) { + ignored.printStackTrace(); + } + } + + if(!enabled) { + jfFavouriteSelect = null; + if(eventMap.isEmpty() || eventMap.size() <= 20) { + long currentTime = System.currentTimeMillis(); + long floorHour = (currentTime/HOUR)*HOUR; + for(int i=0; i<15; i++) { + long daEvent = floorHour+i*HOUR+DA_OFFSET; + long jfEvent = floorHour+i*HOUR+JF_OFFSET; + + if(daEvent > currentTime) { + eventMap.computeIfAbsent(daEvent, k->new HashSet<>()).add(new SBEvent("dark_auction", + EnumChatFormatting.DARK_PURPLE+"Dark Auction", DA_STACK, null, MINUTE*5)); + } + if(jfEvent > currentTime) { + SBEvent jf = new SBEvent("jacob_farming", + EnumChatFormatting.YELLOW+"Jacob's Farming Contest", JF_STACK, null, MINUTE*20); + if(farmingEventTypes != null && farmingEventTypes.has(""+jfEvent) && + farmingEventTypes.get(""+jfEvent).isJsonArray()) { + JsonArray arr = farmingEventTypes.get(""+jfEvent).getAsJsonArray(); + jf.desc = new ArrayList<>(); + for(JsonElement e : arr) { + jf.desc.add(EnumChatFormatting.YELLOW+"\u25CB "+e.getAsString()); + jf.id += ":" + e.getAsString(); + } + } + eventMap.computeIfAbsent(jfEvent, k->new HashSet<>()).add(jf); + } + } + } + return; + } + + if(!containerName.trim().equals("Calendar and Events")) { + setEnabled(false); + return; + } + + eventMap.clear(); + + long currentTime = System.currentTimeMillis(); + long floorHour = (currentTime/HOUR)*HOUR; + for(int i=0; i<15; i++) { + long daEvent = floorHour+i*HOUR+DA_OFFSET; + long jfEvent = floorHour+i*HOUR+JF_OFFSET; + + if(daEvent > currentTime) { + eventMap.computeIfAbsent(daEvent, k->new HashSet<>()).add(new SBEvent("dark_auction", + EnumChatFormatting.DARK_PURPLE+"Dark Auction", DA_STACK, null, MINUTE*5)); + } + if(jfEvent > currentTime) { + SBEvent jf = new SBEvent("jacob_farming", + EnumChatFormatting.YELLOW+"Jacob's Farming Contest", JF_STACK, null, MINUTE*20); + if(farmingEventTypes != null && farmingEventTypes.has(""+jfEvent) && + farmingEventTypes.get(""+jfEvent).isJsonArray()) { + JsonArray arr = farmingEventTypes.get(""+jfEvent).getAsJsonArray(); + jf.desc = new ArrayList<>(); + for(JsonElement e : arr) { + jf.desc.add(EnumChatFormatting.YELLOW+"\u25CB "+e.getAsString()); + jf.id += ":" + e.getAsString(); + } + } + eventMap.computeIfAbsent(jfEvent, k->new HashSet<>()).add(jf); + } + } + + String lastsForText = EnumChatFormatting.GRAY+"Event lasts for "+EnumChatFormatting.YELLOW; + String startsInText = EnumChatFormatting.GRAY+"Starts in: "+EnumChatFormatting.YELLOW; + for(int i=0; i<21; i++) { + int itemIndex = 10+i+(i/7)*2; + ItemStack item = cc.getLowerChestInventory().getStackInSlot(itemIndex); + + if(item != null && item.getTagCompound() != null) { + NBTTagCompound tag = item.getTagCompound(); + + if(tag.hasKey("display", 10)) { + NBTTagCompound display = tag.getCompoundTag("display"); + if (display.hasKey("Lore", 9)) { + NBTTagList list = display.getTagList("Lore", 8); + + String first = list.getStringTagAt(0); + if(first.startsWith(startsInText)) { + String time = Utils.cleanColour(first.substring(startsInText.length())); + long eventTime = currentTime + getTimeOffset(time); + + long lastsFor = -1; + + List<String> desc = new ArrayList<>(); + boolean foundBreak = false; + for(int index=1; index<list.tagCount(); index++) { + String line = list.getStringTagAt(index); + if(foundBreak) { + desc.add(line); + } else { + if(line.startsWith(lastsForText)) { + String lastsForS = Utils.cleanColour(line.substring(lastsForText.length())); + lastsFor = getTimeOffset(lastsForS); + } + if(Utils.cleanColour(line).trim().length() == 0) { + foundBreak = true; + } + } + } + eventMap.computeIfAbsent(eventTime, k->new HashSet<>()).add(new SBEvent( + getIdForDisplayName(item.getDisplayName()), item.getDisplayName(), + item, desc, lastsFor)); + } + } + } + } + } + } + + private static String getIdForDisplayName(String displayName) { + return Utils.cleanColour(displayName) + .toLowerCase() + .replaceAll("[0-9]+th", "") + .replaceAll("[0-9]+nd", "") + .replaceAll("[0-9]+rd", "") + .replaceAll("[0-9]+st", "") + .replaceAll("[^a-z ]", "") + .trim() + .replace(" ", "_"); + } + + + @SubscribeEvent + public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { + 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; + + if(!enabled) { + if(Mouse.getEventButtonState() && NotEnoughUpdates.INSTANCE.manager.config.showEventTimerInInventory.value && + Minecraft.getMinecraft().currentScreen instanceof GuiContainer) { + xSize = 168; + ySize = 20; + + guiLeft = (width - xSize)/2; + guiTop = 5; + + if(mouseX >= guiLeft && mouseX <= guiLeft+xSize) { + if(mouseY >= guiTop && mouseY <= guiTop+ySize) { + ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/neucalendar"); + } + } + } + + return; + } + + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + return; + } + + GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + if(!containerName.trim().equals("Calendar and Events")) { + setEnabled(false); + return; + } + + event.setCanceled(true); + + xSize = 168; + ySize = 170; + guiLeft = (width - xSize) / 2; + guiTop = (height - ySize) / 2; + + if(Mouse.getEventButtonState()) { + if(jfFavouriteSelect != null) { + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + int arrowLen = fr.getStringWidth("> "); + int selectSizeX = 0; + int selectStringIndex = 0; + for (String s : jfFavouriteSelect) { + int sWidth = fr.getStringWidth(s); + if (selectStringIndex + 1 == jfFavouriteSelectIndex) sWidth += arrowLen; + if (sWidth > selectSizeX) { + selectSizeX = sWidth; + } + selectStringIndex++; + } + selectSizeX += +10; + + if(mouseX > jfFavouriteSelectX && mouseX < jfFavouriteSelectX + selectSizeX && + mouseY > jfFavouriteSelectY && mouseY < jfFavouriteSelectY + 18 + jfFavouriteSelect.size() * 10) { + jfFavouriteSelectIndex = Math.max(0, (mouseY - jfFavouriteSelectY - 5)/10); + + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + String id = null; + if(jfFavouriteSelectIndex == 0) { + id = "jacob_farming"; + } else if(jfFavouriteSelectIndex-1 < jfFavouriteSelect.size()) { + id = "jacob_farming:"+jfFavouriteSelect.get(jfFavouriteSelectIndex-1); + } + if(id != null) { + if (eventFavourites.contains(id)) { + eventFavourites.remove(id); + } else { + eventFavourites.add(id); + } + try { + NotEnoughUpdates.INSTANCE.manager.saveConfig(); + } catch (Exception ignored) { + } + } + } else { + jfFavouriteSelect = null; + } + } + if(mouseY >= guiTop+26 && mouseY <= guiTop+26+141) { + if(mouseX >= guiLeft+151 && mouseX <= guiLeft+151+14) { + if(mouseY <= guiTop+26+70) { + Minecraft.getMinecraft().playerController.windowClick(cc.windowId, + 50, 2, 3, Minecraft.getMinecraft().thePlayer); + } else { + Minecraft.getMinecraft().playerController.windowClick(cc.windowId, + 45, 2, 3, Minecraft.getMinecraft().thePlayer); + } + } + } + } + } + + @SubscribeEvent + public void onGuiScreenKeyboard(GuiScreenEvent.KeyboardInputEvent.Pre event) { + if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + if(jfFavouriteSelect != null) { + jfFavouriteSelect = null; + event.setCanceled(true); + } + } else { + if (!enabled) { + return; + } + + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + return; + } + + GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + if (!containerName.trim().equals("Calendar and Events")) { + setEnabled(false); + return; + } + + event.setCanceled(true); + xSize = 168; + ySize = 170; + + 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; + guiLeft = (width - xSize) / 2; + guiTop = (height - ySize) / 2; + + int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); + if(Keyboard.getEventKeyState()) { + if(jfFavouriteSelect != null) { + if(keyPressed == Keyboard.KEY_DOWN) { + jfFavouriteSelectIndex++; + jfFavouriteSelectIndex %= jfFavouriteSelect.size()+1; + } else if(keyPressed == Keyboard.KEY_UP) { + jfFavouriteSelectIndex--; + if(jfFavouriteSelectIndex < 0) jfFavouriteSelectIndex = jfFavouriteSelect.size(); + } else if(keyPressed == Keyboard.KEY_RIGHT || keyPressed == Keyboard.KEY_RETURN) { + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + String id = null; + if(jfFavouriteSelectIndex == 0) { + id = "jacob_farming"; + } else if(jfFavouriteSelectIndex-1 < jfFavouriteSelect.size()) { + id = "jacob_farming:"+jfFavouriteSelect.get(jfFavouriteSelectIndex-1); + } + if(id != null) { + if (eventFavourites.contains(id)) { + eventFavourites.remove(id); + } else { + eventFavourites.add(id); + } + try { + NotEnoughUpdates.INSTANCE.manager.saveConfig(); + } catch (Exception ignored) { + } + } + } else if(keyPressed == Keyboard.KEY_LEFT || + keyPressed == NotEnoughUpdates.INSTANCE.manager.keybindFavourite.getKeyCode()) { + jfFavouriteSelect = null; + } + } else if(keyPressed == NotEnoughUpdates.INSTANCE.manager.keybindFavourite.getKeyCode()) { + String id = null; + + //Daily Events + int index = 0; + out: + for (Map.Entry<Long, Set<SBEvent>> sbEvents : eventMap.entrySet()) { + for (SBEvent sbEvent : sbEvents.getValue()) { + int x = guiLeft + 29 + 17 * (index % 3); + int y = guiTop + 44 + 17 * (index / 3); + + if (mouseX >= x && mouseX <= x + 16) { + if (mouseY >= y && mouseY <= y + 16) { + id = sbEvent.id; + } + } + + if (++index >= 21) break out; + } + } + + //Special Events + for (int i = 0; i < 21; i++) { + int itemIndex = 10 + i + (i / 7) * 2; + ItemStack item = cc.getLowerChestInventory().getStackInSlot(itemIndex); + if (item == null) continue; + + int x = guiLeft + 89 + 17 * (i % 3); + int y = guiTop + 44 + 17 * (i / 3); + + if (mouseX >= x && mouseX <= x + 16) { + if (mouseY >= y && mouseY <= y + 16) { + id = getIdForDisplayName(item.getDisplayName()); + } + } + } + + if (id != null) { + String[] split = id.split(":"); + if(split.length > 1 && split[0].equals("jacob_farming")) { + jfFavouriteSelect = new ArrayList<>(); + for(int i=1; i<split.length; i++) { + jfFavouriteSelect.add(split[i]); + } + jfFavouriteSelectIndex = 0; + jfFavouriteSelectX = mouseX; + jfFavouriteSelectY = mouseY; + } else { + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + if (eventFavourites.contains(id)) { + eventFavourites.remove(id); + } else { + eventFavourites.add(id); + } + try { + NotEnoughUpdates.INSTANCE.manager.saveConfig(); + } catch (Exception ignored) { + } + } + } + } + } + } + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onGuiDraw(RenderGameOverlayEvent event) { + if(NotEnoughUpdates.INSTANCE.manager.config.eventNotifications.value && + event.type == RenderGameOverlayEvent.ElementType.ALL) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 10); + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer) && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + long currentTime = System.currentTimeMillis(); + + long timeUntilNext = 0; + SBEvent nextEvent = null; + long timeUntilFirst = 0; + SBEvent firstEvent = null; + + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + + //Daily Events + out: + for(Map.Entry<Long, Set<SBEvent>> sbEvents : eventMap.entrySet()) { + for(SBEvent sbEvent : sbEvents.getValue()) { + long timeUntilMillis = sbEvents.getKey() - currentTime; + + if(timeUntilMillis < -10*SECOND) { + continue; + } + + if(firstEvent == null) { + firstEvent = sbEvent; + timeUntilFirst = timeUntilMillis; + } + + String[] split = sbEvent.id.split(":"); + boolean containsId = false; + for(int i=1; i<split.length; i++) { + if(eventFavourites.contains(split[0]+":"+split[i])) { + containsId = true; + break; + } + } + if(eventFavourites.isEmpty() || eventFavourites.contains(split[0]) || containsId) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + break out; + } + } + } + + if(nextEvent == null) { + nextEvent = firstEvent; + timeUntilNext = timeUntilFirst; + } + + if(nextEvent != null) { + renderToast(nextEvent, timeUntilNext); + } + } + GlStateManager.translate(0, 0, -10); + GlStateManager.popMatrix(); + } + } + + public boolean renderToast(SBEvent event, long timeUntil) { + if(!NotEnoughUpdates.INSTANCE.manager.config.eventNotifications.value) { + return false; + } + + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + + int ySize = 32; + int xSize = 160; + int guiLeft = (width - xSize)/2; + int guiTop = 5; + + boolean preNotification = false; + long preNotificationTime = SECOND*NotEnoughUpdates.INSTANCE.manager.config.eventNotificationBeforeSeconds.value.intValue(); + + if(preNotificationTime > 500 && timeUntil > 500) { + timeUntil = timeUntil - preNotificationTime; + preNotification = true; + } + + if(timeUntil < 500 && timeUntil > -8500) { + if(jingleIndex == -1) { + if(preNotification) { + jingleIndex = 1; + } else { + jingleIndex = 0; + } + } + + float offset; + float factor = 0; + if(timeUntil > 0) { + factor = (timeUntil/500f); + } else if(timeUntil < -8000) { + factor = -((timeUntil+8000)/500f); + } + factor = (float)(1.06f/(1+Math.exp(-7*(factor-0.5f)))-0.03f); + offset = -(ySize+5)*factor; + float y = guiTop+offset; + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(TOAST); + Utils.drawTexturedRect(guiLeft, y, xSize, ySize, GL11.GL_NEAREST); + + GlStateManager.translate(0, y, 0); + Utils.drawItemStack(event.stack, guiLeft+6, 8); + GlStateManager.translate(0, -y, 0); + + if(preNotification) { + String starting = EnumChatFormatting.YELLOW+"Event Starting in "+prettyTime(preNotificationTime, true)+"!"; + int startingWidth = fr.getStringWidth(starting); + fr.drawString(starting, Math.max(guiLeft+23, width/2f-startingWidth/2f), y+7, -1, false); + } else { + Utils.drawStringCentered(EnumChatFormatting.YELLOW+"Event Starting Now!", fr, width/2, y+11, false, -1); + } + + int displayWidth = fr.getStringWidth(event.display); + fr.drawString(event.display, Math.max(guiLeft+23, width/2f-displayWidth/2f), y+17, -1, false); + + + return true; + } + return false; + } + + @SubscribeEvent + public void onGuiDraw(GuiScreenEvent.DrawScreenEvent.Post event) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 10); + if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { + 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; + long currentTime = System.currentTimeMillis(); + + xSize = 168; + ySize = 20; + + long timeUntilNext = 0; + SBEvent nextEvent = null; + long timeUntilFirst = 0; + SBEvent firstEvent = null; + List<SBEvent> nextFavourites = new ArrayList<>(); + List<Long> nextFavouritesTime = new ArrayList<>(); + long timeUntilMajor = 0; + SBEvent nextMajorEvent = null; + + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + + guiLeft = (width - xSize)/2; + guiTop = 5; + + //Daily Events + out: + for(Map.Entry<Long, Set<SBEvent>> sbEvents : eventMap.entrySet()) { + for(SBEvent sbEvent : sbEvents.getValue()) { + long timeUntilMillis = sbEvents.getKey() - currentTime; + + if(timeUntilMillis < -10*SECOND) { + continue; + } + + if(nextMajorEvent == null && !sbEvent.id.split(":")[0].equals("jacob_farming") && + !sbEvent.id.equals("dark_auction")) { + nextMajorEvent = sbEvent; + timeUntilMajor = timeUntilMillis; + } + + if(firstEvent == null) { + firstEvent = sbEvent; + timeUntilFirst = timeUntilMillis; + } + + String[] split = sbEvent.id.split(":"); + boolean containsId = false; + for(int i=1; i<split.length; i++) { + if(eventFavourites.contains(split[0]+":"+split[i])) { + containsId = true; + break; + } + } + if(eventFavourites.isEmpty() || eventFavourites.contains(split[0]) || containsId) { + if(nextEvent == null) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + } + if(nextFavourites.size() < 3) { + nextFavourites.add(sbEvent); + nextFavouritesTime.add(timeUntilMillis); + } + } + + if(nextFavourites.size() >= 3 && nextMajorEvent != null) { + break out; + } + } + } + + if(nextEvent == null) { + nextEvent = firstEvent; + timeUntilNext = timeUntilFirst; + } + + if(nextEvent != null) { + GlStateManager.translate(0, 0, 50); + boolean toastRendered = renderToast(nextEvent, timeUntilNext); + GlStateManager.translate(0, 0, -50); + if(!toastRendered && !enabled && NotEnoughUpdates.INSTANCE.manager.config.showEventTimerInInventory.value) { + List<String> tooltipToDisplay = null; + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + + blurBackground(); + renderBlurredBackground(width, height, guiLeft+3, guiTop+3, xSize-6, ySize-6); + + Minecraft.getMinecraft().getTextureManager().bindTexture(DISPLAYBAR); + Utils.drawTexturedRect(guiLeft, guiTop, xSize, 20, GL11.GL_NEAREST); + + String nextS = EnumChatFormatting.YELLOW+"Next: "; + int nextSLen = fr.getStringWidth(nextS); + fr.drawString(nextS, guiLeft+8, guiTop+6, -1, false); + + String until = " "+EnumChatFormatting.YELLOW+prettyTime(timeUntilNext, false); + int untilLen = fr.getStringWidth(until); + + fr.drawString(until, guiLeft+xSize-8-untilLen, guiTop+6, -1, false); + + int eventTitleLen = xSize-16-untilLen-nextSLen; + int displayWidth = fr.getStringWidth(nextEvent.display); + int spaceLen = fr.getCharWidth(' '); + if(displayWidth > eventTitleLen) { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + GL11.glScissor((guiLeft+8+nextSLen)*scaledResolution.getScaleFactor(), + 0, + eventTitleLen*scaledResolution.getScaleFactor(), + Minecraft.getMinecraft().displayHeight); + fr.drawString(nextEvent.display + " " + nextEvent.display, + guiLeft+8+nextSLen-(float)(currentTime/50.0 % (displayWidth+spaceLen)), guiTop+6, -1, false); + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } else { + if(guiLeft+xSize-8-untilLen > (width+displayWidth)/2) { + Utils.drawStringCentered(nextEvent.display, fr,width/2f, guiTop+10, false, -1); + } else { + fr.drawString(nextEvent.display, guiLeft+8+nextSLen, guiTop+6, -1, false); + } + } + + if(mouseX > guiLeft && mouseX < guiLeft+168) { + if(mouseY > guiTop && mouseY < guiTop+20) { + tooltipToDisplay = new ArrayList<>(); + for(int i=0; i<nextFavourites.size(); i++) { + SBEvent sbEvent = nextFavourites.get(i); + long timeUntil = nextFavouritesTime.get(i); + + tooltipToDisplay.add(sbEvent.display); + tooltipToDisplay.add(EnumChatFormatting.GRAY+"Starts in: "+EnumChatFormatting.YELLOW+prettyTime(timeUntil, false)); + if(sbEvent.lastsFor >= 0) { + tooltipToDisplay.add( EnumChatFormatting.GRAY+"Lasts for: "+EnumChatFormatting.YELLOW+ + prettyTime(sbEvent.lastsFor, true)); + } + if(sbEvent.id.split(":")[0].equals("jacob_farming") && sbEvent.desc != null) { + tooltipToDisplay.addAll(sbEvent.desc); + } + if(nextMajorEvent != null || i < nextFavourites.size()-1) { + tooltipToDisplay.add(""); + } + } + if(nextMajorEvent != null) { + tooltipToDisplay.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"Next Major:"); + tooltipToDisplay.add(nextMajorEvent.display); + tooltipToDisplay.add(EnumChatFormatting.GRAY+"Starts in: "+EnumChatFormatting.YELLOW+prettyTime(timeUntilMajor, false)); + if(nextMajorEvent.lastsFor >= 0) { + tooltipToDisplay.add( EnumChatFormatting.GRAY+"Lasts for: "+EnumChatFormatting.YELLOW+ + prettyTime(nextMajorEvent.lastsFor, true)); + } + } + + + } + } + + if(tooltipToDisplay != null) { + Utils.drawHoveringText(tooltipToDisplay, mouseX, Math.max(17, mouseY), width, height, -1, fr); + } + } + } + } + GlStateManager.translate(0, 0, -10); + GlStateManager.popMatrix(); + } + + @SubscribeEvent + public void onGuiDraw(GuiScreenEvent.DrawScreenEvent.Pre event) { + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiChest)) { + return; + } + + if(!enabled) { + return; + } + + GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest cc = (ContainerChest) eventGui.inventorySlots; + String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); + if(!containerName.trim().equals("Calendar and Events")) { + setEnabled(false); + return; + } + + event.setCanceled(true); + + List<String> tooltipToDisplay = null; + int mouseX = event.mouseX; + int mouseY = event.mouseY; + long currentTime = System.currentTimeMillis(); + + xSize = 168; + ySize = 170; + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + guiLeft = (width - xSize)/2; + guiTop = (height - ySize)/2; + + Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680); + + blurBackground(); + renderBlurredBackground(width, height, guiLeft+3, guiTop+3, 162, 14); + renderBlurredBackground(width, height, guiLeft+3, guiTop+26, 14, 141); + renderBlurredBackground(width, height, guiLeft+151, guiTop+26, 14, 141); + renderBlurredBackground(width, height, guiLeft+26, guiTop+26, 116, 141); + + Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND); + Utils.drawTexturedRect(guiLeft, guiTop, xSize, ySize, GL11.GL_NEAREST); + + GlStateManager.translate(0, 0, 10); + + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + + fr.drawString("Daily", guiLeft+29, guiTop+30, 0xffffaa00); + int specialLen = fr.getStringWidth("Special"); + fr.drawString("Special", guiLeft+139-specialLen, guiTop+30, 0xffffaa00); + + ItemStack mayorStack = cc.getLowerChestInventory().getStackInSlot(46); + if(mayorStack != null) { + String mayor = mayorStack.getDisplayName(); + float verticalHeight = Utils.getVerticalHeight(mayor); + Utils.drawStringVertical(mayor, fr, guiLeft+8, guiTop+96-verticalHeight/2, + false, -1); + } + + String calendar = EnumChatFormatting.GREEN+"Calendar"; + float calendarHeight = Utils.getVerticalHeight(calendar); + Utils.drawStringVertical(calendar, fr, guiLeft+xSize-12, guiTop+60-calendarHeight/2, + false, -1); + + String rewards = EnumChatFormatting.GOLD+"Rewards"; + float rewardsHeight = Utils.getVerticalHeight(rewards); + Utils.drawStringVertical(rewards, fr, guiLeft+xSize-12, guiTop+132-rewardsHeight/2, + false, -1); + + if(mouseY >= guiTop+26 && mouseY <= guiTop+26+141) { + if(mouseX >= guiLeft+3 && mouseX <= guiLeft+3+14) { + if(mayorStack != null) tooltipToDisplay = mayorStack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + } else if(mouseX >= guiLeft+151 && mouseX <= guiLeft+151+14) { + if(mouseY <= guiTop+26+70) { + ItemStack calendarStack = cc.getLowerChestInventory().getStackInSlot(50); + if(calendarStack != null) tooltipToDisplay = calendarStack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + } else { + ItemStack rewardsStack = cc.getLowerChestInventory().getStackInSlot(45); + if(rewardsStack != null) tooltipToDisplay = rewardsStack.getTooltip(Minecraft.getMinecraft().thePlayer, false); + } + } + } + + long timeUntilNext = 0; + SBEvent nextEvent = null; + long timeUntilFirst = 0; + SBEvent firstEvent = null; + List<String> eventFavourites = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value; + + //Daily Events + int index = 0; + out: + for(Map.Entry<Long, Set<SBEvent>> sbEvents : eventMap.entrySet()) { + for(SBEvent sbEvent : sbEvents.getValue()) { + long timeUntilMillis = sbEvents.getKey() - currentTime; + + int x = guiLeft+29+17*(index%3); + int y = guiTop+44+17*(index/3); + + if(index >= 21) { + if(nextEvent != null) break; + if(eventFavourites.isEmpty()) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + } else if(eventFavourites.contains(sbEvent.id)) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + } + continue; + } + + if(firstEvent == null) { + firstEvent = sbEvent; + timeUntilFirst = timeUntilMillis; + } + + String[] split = sbEvent.id.split(":"); + boolean containsId = false; + for(int i=1; i<split.length; i++) { + if(eventFavourites.contains(split[0]+":"+split[i])) { + containsId = true; + break; + } + } + if(eventFavourites.isEmpty()) { + if(nextEvent == null) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + } + } else if(eventFavourites.contains(split[0]) || containsId) { + if(nextEvent == null) { + nextEvent = sbEvent; + timeUntilNext = timeUntilMillis; + } + + GlStateManager.depthMask(false); + GlStateManager.translate(0, 0, -2); + Gui.drawRect(x, y, x+16, y+16, 0xcfffbf49); + GlStateManager.translate(0, 0, 2); + GlStateManager.depthMask(true); + } + + Utils.drawItemStackWithText(sbEvent.stack, x, y, ""+(index+1)); + + if(mouseX >= x && mouseX <= x+16) { + if(mouseY >= y && mouseY <= y+16) { + tooltipToDisplay = Utils.createList(sbEvent.display, + EnumChatFormatting.GRAY+"Starts in: "+EnumChatFormatting.YELLOW+prettyTime(timeUntilMillis, false)); + if(sbEvent.lastsFor >= 0) { + tooltipToDisplay.add( EnumChatFormatting.GRAY+"Lasts for: "+EnumChatFormatting.YELLOW+ + prettyTime(sbEvent.lastsFor, true)); + } + if(sbEvent.desc != null) { + tooltipToDisplay.add(""); + tooltipToDisplay.addAll(sbEvent.desc); + } + } + } + + index++; + } + } + + //Special Events + for(int i=0; i<21; i++) { + int itemIndex = 10+i+(i/7)*2; + ItemStack item = cc.getLowerChestInventory().getStackInSlot(itemIndex); + if(item == null) continue; + + String eventId = getIdForDisplayName(item.getDisplayName()); + + NBTTagCompound tag = item.getTagCompound(); + tag.setString("event_id", eventId); + item.setTagCompound(tag); + + int x = guiLeft+89+17*(i%3); + int y = guiTop+44+17*(i/3); + + if(eventFavourites.contains(eventId)) { + GlStateManager.depthMask(false); + GlStateManager.translate(0, 0, -2); + Gui.drawRect(x, y, x+16, y+16, 0xcfffbf49); + GlStateManager.translate(0, 0, 2); + GlStateManager.depthMask(true); + } + + Utils.drawItemStackWithText(item, x, y, ""+(i+1)); + + if(mouseX >= x && mouseX <= x+16) { + if(mouseY >= y && mouseY <= y+16) { + tooltipToDisplay = item.getTooltip(Minecraft.getMinecraft().thePlayer, false); + } + } + } + + if(nextEvent == null) { + nextEvent = firstEvent; + timeUntilNext = timeUntilFirst; + } + + if(nextEvent != null) { + String nextS = EnumChatFormatting.YELLOW+"Next: "; + int nextSLen = fr.getStringWidth(nextS); + fr.drawString(nextS, guiLeft+8, guiTop+6, -1, false); + + String until = " "+EnumChatFormatting.YELLOW+prettyTime(timeUntilNext, false); + int untilLen = fr.getStringWidth(until); + + fr.drawString(until, guiLeft+xSize-8-untilLen, guiTop+6, -1, false); + + int eventTitleLen = xSize-16-untilLen-nextSLen; + int displayWidth = fr.getStringWidth(nextEvent.display); + int spaceLen = fr.getCharWidth(' '); + if(displayWidth > eventTitleLen) { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + GL11.glScissor((guiLeft+8+nextSLen)*scaledResolution.getScaleFactor(), + 0, + eventTitleLen*scaledResolution.getScaleFactor(), + Minecraft.getMinecraft().displayHeight); + fr.drawString(nextEvent.display + " " + nextEvent.display, + guiLeft+8+nextSLen-(float)(currentTime/50.0 % (displayWidth+spaceLen)), guiTop+6, -1, false); + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } else { + fr.drawString(nextEvent.display, guiLeft+8+nextSLen, guiTop+6, -1, false); + } + + if(mouseX > guiLeft && mouseX < guiLeft+168) { + if(mouseY > guiTop && mouseY < guiTop+20) { + tooltipToDisplay = Utils.createList(nextEvent.display, + EnumChatFormatting.GRAY+"Starts in: "+EnumChatFormatting.YELLOW+prettyTime(timeUntilNext, false)); + if(nextEvent.lastsFor >= 0) { + tooltipToDisplay.add( EnumChatFormatting.GRAY+"Lasts for: "+EnumChatFormatting.YELLOW+ + prettyTime(nextEvent.lastsFor, true)); + } + if(nextEvent.desc != null) { + tooltipToDisplay.add(""); + tooltipToDisplay.addAll(nextEvent.desc); + } + } + } + } + + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Utils.drawTexturedRect(guiLeft+xSize-18, guiTop+ySize+2, 16, 16, GL11.GL_LINEAR); + + if(mouseX >= guiLeft+xSize-18 && mouseX < guiLeft+xSize-2) { + if(mouseY >= guiTop+ySize+2 && mouseY <= guiTop+ySize+18) { + tooltipToDisplay = new ArrayList<>(); + tooltipToDisplay.add(EnumChatFormatting.AQUA+"NEU Calendar Help"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"This calendar displays various skyblock events"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"'Daily' events are events that happen frequently"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"'Special' events are events that happen infrequently"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+""); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"The eventbar at the top will also show in your inventory"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+""); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"Press 'F' on an event to mark it as a favourite"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"Favourited events will show over normal events"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"Favourited events will also give a notification when it"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+"is about to start and when it does start"); + tooltipToDisplay.add(EnumChatFormatting.YELLOW+""); + tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY+"In order to show crop types for Jacob's Farming"); + tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY+"contest, visit the full skyblock calendar and go all"); + tooltipToDisplay.add(EnumChatFormatting.DARK_GRAY+"the way to the end of the skyblock year"); + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + tooltipToDisplay = null; + } + } + + if(jfFavouriteSelect != null) { + int arrowLen = fr.getStringWidth("> "); + int selectSizeX = 0; + int selectStringIndex=0; + for(String s : jfFavouriteSelect) { + int sWidth = fr.getStringWidth(s); + if(selectStringIndex+1 == jfFavouriteSelectIndex) sWidth += arrowLen; + if(sWidth > selectSizeX) { + selectSizeX = sWidth; + } + selectStringIndex++; + } + selectSizeX += +10; + + GlStateManager.translate(0, 0, 19); + + Gui.drawRect(jfFavouriteSelectX+2, jfFavouriteSelectY+2, jfFavouriteSelectX+selectSizeX+2, + jfFavouriteSelectY+18+jfFavouriteSelect.size()*10+2, 0xa0000000); + + GlStateManager.depthFunc(GL11.GL_LESS); + GlStateManager.translate(0, 0, 1); + Gui.drawRect(jfFavouriteSelectX+1, jfFavouriteSelectY+1, jfFavouriteSelectX+selectSizeX-1, + jfFavouriteSelectY+18+jfFavouriteSelect.size()*10-1, 0xffc0c0c0); + Gui.drawRect(jfFavouriteSelectX, jfFavouriteSelectY, jfFavouriteSelectX+selectSizeX-1, + jfFavouriteSelectY+18+jfFavouriteSelect.size()*10-1, 0xfff0f0f0); + Gui.drawRect(jfFavouriteSelectX, jfFavouriteSelectY, jfFavouriteSelectX+selectSizeX, + jfFavouriteSelectY+18+jfFavouriteSelect.size()*10, 0xff909090); + GlStateManager.depthFunc(GL11.GL_LEQUAL); + + String all = (NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value.contains("jacob_farming")? + EnumChatFormatting.DARK_GREEN:EnumChatFormatting.DARK_GRAY)+"All"; + if(jfFavouriteSelectIndex == 0) { + fr.drawString(EnumChatFormatting.BLACK+"> "+all, jfFavouriteSelectX+5, jfFavouriteSelectY+5, 0xff000000); + } else { + fr.drawString(all, jfFavouriteSelectX+5, jfFavouriteSelectY+5, 0xff000000); + } + + fr.drawString(EnumChatFormatting.BLACK+"> ", jfFavouriteSelectX+6, + jfFavouriteSelectY+10*jfFavouriteSelectIndex+5, 0xff000000); + + selectStringIndex=0; + for(String s : jfFavouriteSelect) { + EnumChatFormatting colour = NotEnoughUpdates.INSTANCE.manager.config.eventFavourites.value.contains("jacob_farming:"+s) + ? EnumChatFormatting.DARK_GREEN : EnumChatFormatting.DARK_GRAY; + s = (selectStringIndex+1 == jfFavouriteSelectIndex ? EnumChatFormatting.BLACK+"> " : "") + colour + s; + fr.drawString(s, jfFavouriteSelectX+5, jfFavouriteSelectY+10*selectStringIndex+15, 0xff000000); + selectStringIndex++; + } + GlStateManager.translate(0, 0, -20); + } else if(tooltipToDisplay != null) { + Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); + } + + GlStateManager.translate(0, 0, -10); + + } + + private String prettyTime(long millis, boolean trimmed) { + long seconds = millis / 1000 % 60; + long minutes = (millis / 1000 / 60) % 60; + long hours = (millis / 1000 / 60 / 60) % 24; + long days = (millis / 1000 / 60 / 60 / 24); + + String endsIn = ""; + if(millis < 0) { + endsIn += "Now!"; + } else if(minutes == 0 && hours == 0 && days == 0) { + endsIn += seconds + "s"; + } else if(hours==0 && days==0) { + if(trimmed && seconds == 0) { + endsIn += minutes + "m"; + } else { + endsIn += minutes + "m" + seconds + "s"; + } + } else if(days==0) { + if(hours <= 6) { + if(trimmed && seconds == 0) { + if(minutes == 0) { + endsIn += hours + "h"; + } else { + endsIn += hours + "h" + minutes + "m"; + } + } else { + endsIn += hours + "h" + minutes + "m" + seconds + "s"; + } + } else { + endsIn += hours + "h"; + } + } else { + endsIn += days + "d" + hours + "h"; + } + + return endsIn; + } + + Shader blurShaderHorz = null; + Framebuffer blurOutputHorz = null; + Shader blurShaderVert = null; + Framebuffer blurOutputVert = null; + + /** + * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate + * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis). + * + * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to + * apply scales and translations manually. + */ + private Matrix4f createProjectionMatrix(int width, int height) { + Matrix4f projMatrix = new Matrix4f(); + projMatrix.setIdentity(); + projMatrix.m00 = 2.0F / (float)width; + projMatrix.m11 = 2.0F / (float)(-height); + projMatrix.m22 = -0.0020001999F; + projMatrix.m33 = 1.0F; + projMatrix.m03 = -1.0F; + projMatrix.m13 = 1.0F; + projMatrix.m23 = -1.0001999F; + return projMatrix; + } + + private double lastBgBlurFactor = -1; + private void blurBackground() { + if(!OpenGlHelper.isFramebufferEnabled()) return; + + int width = Minecraft.getMinecraft().displayWidth; + int height = Minecraft.getMinecraft().displayHeight; + + if(blurOutputHorz == null) { + blurOutputHorz = new Framebuffer(width, height, false); + blurOutputHorz.setFramebufferFilter(GL11.GL_NEAREST); + } + if(blurOutputVert == null) { + blurOutputVert = new Framebuffer(width, height, false); + blurOutputVert.setFramebufferFilter(GL11.GL_NEAREST); + } + if(blurOutputHorz.framebufferWidth != width || blurOutputHorz.framebufferHeight != height) { + blurOutputHorz.createBindFramebuffer(width, height); + blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height)); + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); + } + if(blurOutputVert.framebufferWidth != width || blurOutputVert.framebufferHeight != height) { + blurOutputVert.createBindFramebuffer(width, height); + blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height)); + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); + } + + if(blurShaderHorz == null) { + try { + blurShaderHorz = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", + Minecraft.getMinecraft().getFramebuffer(), blurOutputHorz); + blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0); + blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height)); + } catch(Exception e) { } + } + if(blurShaderVert == null) { + try { + blurShaderVert = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur", + blurOutputHorz, blurOutputVert); + blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1); + blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height)); + } catch(Exception e) { } + } + if(blurShaderHorz != null && blurShaderVert != null) { + if(15 != lastBgBlurFactor) { + blurShaderHorz.getShaderManager().getShaderUniform("Radius").set((float)15); + blurShaderVert.getShaderManager().getShaderUniform("Radius").set((float)15); + lastBgBlurFactor = 15; + } + GL11.glPushMatrix(); + blurShaderHorz.loadShader(0); + blurShaderVert.loadShader(0); + GlStateManager.enableDepth(); + GL11.glPopMatrix(); + + Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false); + } + } + + /** + * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen. + * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight] + */ + public void renderBlurredBackground(int width, int height, int x, int y, int blurWidth, int blurHeight) { + if(!OpenGlHelper.isFramebufferEnabled()) return; + + float uMin = x/(float)width; + float uMax = (x+blurWidth)/(float)width; + float vMin = (height-y)/(float)height; + float vMax = (height-y-blurHeight)/(float)height; + + blurOutputVert.bindFramebufferTexture(); + GlStateManager.color(1f, 1f, 1f, 1f); + Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax); + blurOutputVert.unbindFramebufferTexture(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/CustomItemEffects.java b/src/main/java/io/github/moulberry/notenoughupdates/CustomItemEffects.java index 0fa4aa96..dfd26e9a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/CustomItemEffects.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/CustomItemEffects.java @@ -19,6 +19,7 @@ import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompressedStreamTools; @@ -63,7 +64,8 @@ public class CustomItemEffects { @SubscribeEvent public void onTick(TickEvent.RenderTickEvent event) { - //if(aoteTeleportationTicks > 7) aoteTeleportationTicks = 7; + if(Minecraft.getMinecraft().thePlayer == null) return; + long currentTime = System.currentTimeMillis(); int delta = (int)(currentTime - lastMillis); lastMillis = currentTime; @@ -158,11 +160,19 @@ public class CustomItemEffects { if(matchItem != null) { ItemStack matchStack = new ItemStack(matchItem, 1, match.getBlock().getDamageValue(Minecraft.getMinecraft().theWorld, Minecraft.getMinecraft().objectMouseOver.getBlockPos())); - int itemCount = countItemsInInventoryAndStorage(matchStack); getBuildersWandCandidates(Minecraft.getMinecraft().thePlayer, Minecraft.getMinecraft().objectMouseOver, event.partialTicks, candidatesOld, candidatesOldSorted, 999-MAX_BUILDERS_BLOCKS); + boolean usingDirtWand = false; + int itemCount; + if(match.getBlock() == Blocks.dirt && matchStack.getItemDamage() == 0 && hasDirtWand()) { + itemCount = candidatesOld.size(); + usingDirtWand = true; + } else { + itemCount = countItemsInInventoryAndStorage(matchStack); + } + if(candidatesOld.size() > MAX_BUILDERS_BLOCKS) { Utils.drawStringCentered(EnumChatFormatting.RED.toString()+candidatesOld.size()+"/"+MAX_BUILDERS_BLOCKS, Minecraft.getMinecraft().fontRendererObj, @@ -178,15 +188,26 @@ public class CustomItemEffects { scaledResolution.getScaledWidth()/2f, scaledResolution.getScaledHeight()/2f+10, true, 0); } - String itemCountS = EnumChatFormatting.DARK_GRAY+"x"+EnumChatFormatting.RESET+countItemsInInventoryAndStorage(matchStack); + String itemCountS = EnumChatFormatting.DARK_GRAY+"x"+EnumChatFormatting.RESET+itemCount; int itemCountLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(itemCountS); if(NotEnoughUpdates.INSTANCE.manager.config.wandBlockCount.value) { - Utils.drawItemStack(matchStack, scaledResolution.getScaledWidth()/2 - (itemCountLen+16)/2, scaledResolution.getScaledHeight()/2+10+4); - Minecraft.getMinecraft().fontRendererObj.drawString(itemCountS, - scaledResolution.getScaledWidth()/2f - (itemCountLen+16)/2f+16, scaledResolution.getScaledHeight()/2f+10+8, - -1, - true); + if(usingDirtWand) { + Utils.drawItemStack(new ItemStack(Items.gold_nugget), scaledResolution.getScaledWidth()/2 - (itemCountLen+16)/2, + scaledResolution.getScaledHeight()/2+10+4); + Minecraft.getMinecraft().fontRendererObj.drawString(itemCountS, + scaledResolution.getScaledWidth()/2f - (itemCountLen+16)/2f+11, scaledResolution.getScaledHeight()/2f+10+8, + -1, + true); + } else { + Utils.drawItemStack(matchStack, scaledResolution.getScaledWidth()/2 - (itemCountLen+16)/2, + scaledResolution.getScaledHeight()/2+10+4); + Minecraft.getMinecraft().fontRendererObj.drawString(itemCountS, + scaledResolution.getScaledWidth()/2f - (itemCountLen+16)/2f+16, scaledResolution.getScaledHeight()/2f+10+8, + -1, + true); + } + } GlStateManager.color(1, 1, 1, 1); @@ -210,10 +231,8 @@ public class CustomItemEffects { String heldInternal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); if(heldInternal != null && heldInternal.equals("BUILDERS_WAND")) { - //System.out.println("1"); if(held.hasTagCompound() && held.getTagCompound().hasKey("ExtraAttributes", 10) && held.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("builder's_wand_data", 7)) { - //System.out.println("2"); byte[] bytes = held.getTagCompound().getCompoundTag("ExtraAttributes").getByteArray("builder's_wand_data"); try { NBTTagCompound contents_nbt = CompressedStreamTools.readCompressed(new ByteArrayInputStream(bytes)); @@ -221,7 +240,8 @@ public class CustomItemEffects { for(int j=0; j<items.tagCount(); j++) { NBTTagCompound buildersItem = items.getCompoundTagAt(j); if(buildersItem.getKeySet().size() > 0) { - if(buildersItem.getInteger("id") == Item.getIdFromItem(match.getItem())) { + if(buildersItem.getInteger("id") == Item.getIdFromItem(match.getItem()) && + buildersItem.getInteger("Damage") == match.getItemDamage()) { count += items.getCompoundTagAt(j).getByte("Count"); } } @@ -235,6 +255,41 @@ public class CustomItemEffects { return count; } + public boolean hasDirtWand() { + for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + if(internalname != null && internalname.equals("INFINIDIRT_WAND")) { + return true; + } + } + + ItemStack held = Minecraft.getMinecraft().thePlayer.getHeldItem(); + String heldInternal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); + + if(heldInternal != null && heldInternal.equals("BUILDERS_WAND")) { + if(held.hasTagCompound() && held.getTagCompound().hasKey("ExtraAttributes", 10) && + held.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("builder's_wand_data", 7)) { + byte[] bytes = held.getTagCompound().getCompoundTag("ExtraAttributes").getByteArray("builder's_wand_data"); + try { + NBTTagCompound contents_nbt = CompressedStreamTools.readCompressed(new ByteArrayInputStream(bytes)); + NBTTagList items = contents_nbt.getTagList("i", 10); + for(int j=0; j<items.tagCount(); j++) { + NBTTagCompound buildersItem = items.getCompoundTagAt(j); + if(buildersItem.getKeySet().size() > 0) { + String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalnameFromNBT(buildersItem.getCompoundTag("tag")); + if(internalname != null && internalname.equals("INFINIDIRT_WAND")) { + return true; + } + } + } + } catch(Exception e) { + } + } + } + + return false; + } + @SubscribeEvent public void renderBlockOverlay(DrawBlockHighlightEvent event) { if(aoteTeleportationCurr != null && aoteTeleportationMillis > 0) { @@ -243,6 +298,11 @@ public class CustomItemEffects { ItemStack held = Minecraft.getMinecraft().thePlayer.getHeldItem(); String heldInternal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(held); if(heldInternal != null) { + EntityPlayer player = event.player; + double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)event.partialTicks; + double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)event.partialTicks; + double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)event.partialTicks; + if(!NotEnoughUpdates.INSTANCE.manager.config.disableTreecapOverlay.value && (heldInternal.equals("JUNGLE_AXE") || heldInternal.equals("TREECAPITATOR_AXE"))) { int maxWood = 10; @@ -257,7 +317,6 @@ public class CustomItemEffects { if(Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos()).getBlock() == Blocks.log || Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos()).getBlock() == Blocks.log2) { - EntityPlayer player = event.player; int woods = 0; @@ -301,9 +360,6 @@ public class CustomItemEffects { } block.setBlockBoundsBasedOnState(Minecraft.getMinecraft().theWorld, candidate); - double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)event.partialTicks; - double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)event.partialTicks; - double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)event.partialTicks; drawFilledBoundingBox(block.getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, candidate) .expand(0.001D, 0.001D, 0.001D).offset(-d0, -d1, -d2), @@ -316,64 +372,201 @@ public class CustomItemEffects { GlStateManager.enableTexture2D(); GlStateManager.disableBlend(); } - } else if(!NotEnoughUpdates.INSTANCE.manager.config.disableWandOverlay.value && heldInternal.equals("BUILDERS_WAND")) { - int maxBlocks = 164; - if (event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { - IBlockState hover = Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos().offset(event.target.sideHit, 1)); - if(hover.getBlock() == Blocks.air) { - EntityPlayer player = event.player; - - IBlockState match = Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos()); - Item matchItem = Item.getItemFromBlock(match.getBlock()); - if(matchItem != null) { - GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); - GlStateManager.disableTexture2D(); - GlStateManager.depthMask(false); - - ItemStack matchStack = new ItemStack(matchItem, 1, match.getBlock().getMetaFromState(match)); - int itemCount = countItemsInInventoryAndStorage(matchStack); - - HashSet<BlockPos> candidatesOld = new HashSet<>(); - TreeMap<Float, Set<BlockPos>> candidatesOldSorted = new TreeMap<>(); + } else if(!NotEnoughUpdates.INSTANCE.manager.config.disableWandOverlay.value) { + if(heldInternal.equals("BUILDERS_WAND")) { + int maxBlocks = 164; + if (event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + IBlockState hover = Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos().offset(event.target.sideHit, 1)); + if(hover.getBlock() == Blocks.air) { + IBlockState match = Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos()); + Item matchItem = Item.getItemFromBlock(match.getBlock()); + if(matchItem != null) { + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(false); + + HashSet<BlockPos> candidatesOld = new HashSet<>(); + TreeMap<Float, Set<BlockPos>> candidatesOldSorted = new TreeMap<>(); + + getBuildersWandCandidates(player, event.target, event.partialTicks, candidatesOld, candidatesOldSorted, 10); + + ItemStack matchStack = new ItemStack(matchItem, 1, match.getBlock().getMetaFromState(match)); + int itemCount; + if(match.getBlock() == Blocks.dirt && matchStack.getItemDamage() == 0 && hasDirtWand()) { + itemCount = candidatesOld.size(); + } else { + itemCount = countItemsInInventoryAndStorage(matchStack); + } - getBuildersWandCandidates(player, event.target, event.partialTicks, candidatesOld, candidatesOldSorted, 10); + String special = (candidatesOld.size() <= itemCount) ? NotEnoughUpdates.INSTANCE.manager.config.wandOverlayColour.value : + "0:255:255:0:0"; - String special = (candidatesOld.size() <= itemCount) ? NotEnoughUpdates.INSTANCE.manager.config.wandOverlayColour.value : - "0:255:255:0:0"; + if(candidatesOld.size() <= maxBlocks) { + for(Set<BlockPos> candidatesSorted : candidatesOldSorted.values()) { + for(BlockPos candidate : candidatesSorted) { + match.getBlock().setBlockBoundsBasedOnState(Minecraft.getMinecraft().theWorld, candidate); + AxisAlignedBB bb = match.getBlock().getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, candidate) + .offset(event.target.sideHit.getFrontOffsetX(), event.target.sideHit.getFrontOffsetY(), + event.target.sideHit.getFrontOffsetZ()); - if(candidatesOld.size() <= maxBlocks) { - double d0 = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)event.partialTicks; - double d1 = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)event.partialTicks; - double d2 = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)event.partialTicks; + drawBlock((int)bb.minX, (int)bb.minY, (int)bb.minZ+1, match, event.partialTicks, 0.75f); + } + } - for(Set<BlockPos> candidatesSorted : candidatesOldSorted.values()) { - for(BlockPos candidate : candidatesSorted) { + for(BlockPos candidate : candidatesOld) { match.getBlock().setBlockBoundsBasedOnState(Minecraft.getMinecraft().theWorld, candidate); AxisAlignedBB bb = match.getBlock().getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, candidate) + .expand(0.001D, 0.001D, 0.001D).offset(-d0, -d1, -d2) .offset(event.target.sideHit.getFrontOffsetX(), event.target.sideHit.getFrontOffsetY(), event.target.sideHit.getFrontOffsetZ()); - drawBlock((int)bb.minX, (int)bb.minY, (int)bb.minZ+1, match, event.partialTicks, 0.75f); + drawOutlineBoundingBox(bb, 1f, special); } } - for(BlockPos candidate : candidatesOld) { - match.getBlock().setBlockBoundsBasedOnState(Minecraft.getMinecraft().theWorld, candidate); - AxisAlignedBB bb = match.getBlock().getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, candidate) - .expand(0.001D, 0.001D, 0.001D).offset(-d0, -d1, -d2) - .offset(event.target.sideHit.getFrontOffsetX(), event.target.sideHit.getFrontOffsetY(), - event.target.sideHit.getFrontOffsetZ()); + GlStateManager.depthMask(true); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } + } + } + } else if(heldInternal.equals("INFINIDIRT_WAND") && event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + BlockPos hover = event.target.getBlockPos().offset(event.target.sideHit, 1); + IBlockState hoverState = Minecraft.getMinecraft().theWorld.getBlockState(event.target.getBlockPos().offset(event.target.sideHit, 1)); + if(hoverState.getBlock() == Blocks.air) { + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(false); + + String special = NotEnoughUpdates.INSTANCE.manager.config.wandOverlayColour.value; + + AxisAlignedBB bb = Blocks.dirt.getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, hover); + drawBlock((int)bb.minX, (int)bb.minY, (int)bb.minZ+1, Blocks.dirt.getDefaultState(), + event.partialTicks, 0.75f); + + AxisAlignedBB bbExpanded = Blocks.dirt.getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, hover) + .expand(0.001D, 0.001D, 0.001D).offset(-d0, -d1, -d2); + drawOutlineBoundingBox(bbExpanded, 1f, special); + + GlStateManager.depthMask(true); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } + } else if((heldInternal.equals("WATER_BUCKET") || heldInternal.equals("MAGICAL_WATER_BUCKET")) && + event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + BlockPos hover = event.target.getBlockPos().offset(event.target.sideHit, 1); + + HashSet<BlockPos> verticalSources = new HashSet<>(); + TreeMap<Float, HashMap<BlockPos, EnumFacing>> watersSorted = new TreeMap<>(); + + for(int xOff=-1; xOff<=1; xOff++) { + for(int yOff=0; yOff<=1; yOff++) { + for(int zOff=-1; zOff<=1; zOff++) { + if((xOff == 0 && yOff == 0) || + (xOff == 0 && zOff == 0) || + (zOff == 0 && yOff == 0)) { + + BlockPos checkPos = hover.add(-xOff, -yOff, -zOff); + IBlockState check = Minecraft.getMinecraft().theWorld.getBlockState(checkPos); + if(check.getBlock() == Blocks.prismarine && check.getBlock().getMetaFromState(check) == 2) { + for(int i=0; i<300; i++) { + BlockPos renderPos = hover.add(xOff*i, yOff*i, zOff*i); + + if(Math.abs(renderPos.getX()) > 128) { + break; + } + if(Math.abs(renderPos.getY()) > 255) { + break; + } + if(Math.abs(renderPos.getZ()) > 128) { + break; + } + + IBlockState renderState = Minecraft.getMinecraft().theWorld.getBlockState(renderPos); - drawOutlineBoundingBox(bb, 1f, special); + if(renderState.getBlock() != Blocks.air && renderState.getBlock() != Blocks.water && + renderState.getBlock() != Blocks.flowing_water) { + break; + } + + if(yOff != 0) { + verticalSources.add(renderPos); + } else { + IBlockState belowState = Minecraft.getMinecraft().theWorld.getBlockState(renderPos.add(0, -1, 0)); + if(belowState.getBlock() == Blocks.air) { + break; + } + } + + for(EnumFacing facing : EnumFacing.values()) { + float xDist = (float)(renderPos.getX()+0.5f+0.5f*facing.getFrontOffsetX()-d0); + float yDist = (float)(renderPos.getY()+0.5f+0.5f*facing.getFrontOffsetY()-d1-player.getEyeHeight()); + float zDist = (float)(renderPos.getZ()+0.5f+0.5f*facing.getFrontOffsetZ()-d2); + + float distSq = xDist*xDist + yDist*yDist + zDist*zDist; + + watersSorted.computeIfAbsent(distSq, k->new HashMap<>()).put(renderPos, facing); + } + + } + } } } + } + } - GlStateManager.depthMask(true); - GlStateManager.enableTexture2D(); - GlStateManager.disableBlend(); + GlStateManager.enableDepth(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(true); + + for(HashMap<BlockPos, EnumFacing> blockPoses : watersSorted.values()) { + for(Map.Entry<BlockPos, EnumFacing> entry : blockPoses.entrySet()) { + boolean vertical = verticalSources.contains(entry.getKey()); + AxisAlignedBB bbExpanded = Blocks.water.getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, entry.getKey()) + .expand(-0.001D, -0.001D-(vertical?0:0.0625D), -0.001D) + .offset(-d0, -d1-(vertical?0:0.0625), -d2); + drawFilledBoundingBoxSide(bbExpanded, entry.getValue(), 1f, "0:100:20:50:160"); } } + + GlStateManager.depthMask(true); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } else if((heldInternal.equals("HOE_OF_GREAT_TILLING") || heldInternal.equals("HOE_OF_GREATER_TILLING")) && + event.target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { + BlockPos target = event.target.getBlockPos(); + IBlockState targetState = Minecraft.getMinecraft().theWorld.getBlockState(target); + + int radius = heldInternal.equals("HOE_OF_GREAT_TILLING") ? 1 : 2; + + if(targetState.getBlock() == Blocks.dirt || targetState.getBlock() == Blocks.grass) { + GlStateManager.enableDepth(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(true); + + for(int xOff=-radius; xOff<=radius; xOff++) { + for(int zOff=-radius; zOff<=radius; zOff++) { + BlockPos renderPos = target.add(xOff, 0, zOff); + IBlockState renderState = Minecraft.getMinecraft().theWorld.getBlockState(renderPos); + if(renderState.getBlock() == Blocks.dirt || renderState.getBlock() == Blocks.grass) { + AxisAlignedBB bbExpanded = Blocks.dirt.getSelectedBoundingBox(Minecraft.getMinecraft().theWorld, renderPos) + .expand(0.001D, 0.001D, 0.001D) + .offset(-d0, -d1, -d2); + drawFilledBoundingBox(bbExpanded, 1f, "0:100:178:34:34"); + } + } + } + + GlStateManager.depthMask(true); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } } } } @@ -513,10 +706,10 @@ public class CustomItemEffects { GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); GlStateManager.disableTexture2D(); - GlStateManager.depthMask(false); Tessellator tessellator = Tessellator.getInstance(); WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + //vertical worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); @@ -561,6 +754,58 @@ public class CustomItemEffects { } + public static void drawFilledBoundingBoxSide(AxisAlignedBB p_181561_0_, EnumFacing facing, float alpha, String special) { + Color c = new Color(SpecialColour.specialToChromaRGB(special), true); + GlStateManager.color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha); + + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.disableTexture2D(); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); + switch(facing) { + case UP: + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + break; + case DOWN: + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + break; + case EAST: + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + break; + case WEST: + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + break; + case SOUTH: + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.maxZ).endVertex(); + break; + case NORTH: + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.minY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.maxX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + worldrenderer.pos(p_181561_0_.minX, p_181561_0_.maxY, p_181561_0_.minZ).endVertex(); + break; + } + tessellator.draw(); + } + public static void drawOutlineBoundingBox(AxisAlignedBB p_181561_0_, float alpha, String special) { Color c = new Color(SpecialColour.specialToChromaRGB(special), true); GlStateManager.color(c.getRed()/255f, c.getGreen()/255f, c.getBlue()/255f, c.getAlpha()/255f*alpha); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java index 05fb792a..141ffefb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/GuiTextures.java @@ -19,6 +19,8 @@ public class GuiTextures { public static final ResourceLocation help = new ResourceLocation("notenoughupdates:help.png"); public static final ResourceLocation slider_off = new ResourceLocation("notenoughupdates:slider_off.png"); public static final ResourceLocation slider_on = new ResourceLocation("notenoughupdates:slider_on.png"); + public static final ResourceLocation slider_off_large = new ResourceLocation("notenoughupdates:slider_off_large.png"); + public static final ResourceLocation slider_on_large = new ResourceLocation("notenoughupdates:slider_on_large.png"); public static final ResourceLocation slider_button = new ResourceLocation("notenoughupdates:slider_button.png"); public static final ResourceLocation item_mask = new ResourceLocation("notenoughupdates:item_mask.png"); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java index f67b09ed..9f33df1a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java @@ -23,7 +23,9 @@ import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiCrafting; import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.event.ClickEvent; import net.minecraft.init.Blocks; import net.minecraft.inventory.ContainerChest; @@ -35,7 +37,9 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.client.event.*; +import net.minecraftforge.event.entity.player.EntityInteractEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -180,16 +184,18 @@ public class NEUEventListener { displayUpdateMessageIfOutOfDate(); } - long maxMemoryMB = Runtime.getRuntime().maxMemory()/1024L/1024L; - if(maxMemoryMB > 4100) { - notificationDisplayMillis = System.currentTimeMillis(); - notificationLines = new ArrayList<>(); - notificationLines.add(EnumChatFormatting.DARK_RED+"Too much memory allocated!"); - notificationLines.add(String.format(EnumChatFormatting.DARK_GRAY+"NEU has detected %03dMB of memory allocated to Minecraft!", maxMemoryMB)); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"It is recommended to allocated between 2-4GB of memory"); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"More than 4GB WILL cause FPS issues, EVEN if you have 16GB+ available"); - notificationLines.add(""); - notificationLines.add(EnumChatFormatting.DARK_GRAY+"For more information, visit #ram-info in discord.gg/spr6ESn"); + if(NotEnoughUpdates.INSTANCE.manager.config.doRamNotif.value) { + long maxMemoryMB = Runtime.getRuntime().maxMemory()/1024L/1024L; + if(maxMemoryMB > 4100) { + notificationDisplayMillis = System.currentTimeMillis(); + notificationLines = new ArrayList<>(); + notificationLines.add(EnumChatFormatting.DARK_RED+"Too much memory allocated!"); + notificationLines.add(String.format(EnumChatFormatting.DARK_GRAY+"NEU has detected %03dMB of memory allocated to Minecraft!", maxMemoryMB)); + notificationLines.add(EnumChatFormatting.DARK_GRAY+"It is recommended to allocated between 2-4GB of memory"); + notificationLines.add(EnumChatFormatting.DARK_GRAY+"More than 4GB WILL cause FPS issues, EVEN if you have 16GB+ available"); + notificationLines.add(""); + notificationLines.add(EnumChatFormatting.DARK_GRAY+"For more information, visit #ram-info in discord.gg/spr6ESn"); + } } if(!neu.manager.config.loadedModBefore.value) { @@ -358,6 +364,10 @@ public class NEUEventListener { AtomicBoolean missingRecipe = new AtomicBoolean(false); @SubscribeEvent public void onGuiOpen(GuiOpenEvent event) { + if(!(event.gui instanceof GuiContainer) && Minecraft.getMinecraft().currentScreen != null) { + CalendarOverlay.setEnabled(false); + } + neu.manager.auctionManager.customAH.lastGuiScreenSwitch = System.currentTimeMillis(); BetterContainers.reset(); @@ -493,6 +503,24 @@ public class NEUEventListener { } } + @SubscribeEvent + public void onPlayerInteract(EntityInteractEvent event) { + if(!event.isCanceled() && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && + Minecraft.getMinecraft().thePlayer.isSneaking() && + Minecraft.getMinecraft().ingameGUI != null) { + if(event.target instanceof EntityPlayer) { + for(NetworkPlayerInfo info : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { + String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); + if(name.contains("Status: "+EnumChatFormatting.RESET+EnumChatFormatting.BLUE+"Guest")) { + NotEnoughUpdates.INSTANCE.sendChatMessage("/trade " + event.target.getName()); + event.setCanceled(true); + break; + } + } + } + } + } + /** * 1) When receiving "You are playing on profile" messages, will set the current profile. * 2) When a /viewrecipe command fails (i.e. player does not have recipe unlocked, will open the custom recipe GUI) @@ -665,12 +693,14 @@ public class NEUEventListener { if(!(TradeWindow.tradeWindowActive() || event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView())) { if(shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { + GlStateManager.pushMatrix(); if(!focusInv) { GL11.glTranslatef(0, 0, 300); neu.overlay.render(hoverInv && focusInv); GL11.glTranslatef(0, 0, -300); } neu.overlay.renderOverlay(); + GlStateManager.popMatrix(); } } } @@ -727,7 +757,10 @@ public class NEUEventListener { worthBIN = bazaarPrice; worthAUC = bazaarPrice; } else { - worthBIN = neu.manager.auctionManager.getLowestBin(internal); + worthBIN = neu.manager.auctionManager.getItemAvgBin(internal); + if(worthBIN <= 0) { + worthBIN = neu.manager.auctionManager.getLowestBin(internal); + } JsonObject aucInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); if(aucInfo != null) { worthAUC = aucInfo.get("price").getAsFloat(); @@ -1250,7 +1283,50 @@ public class NEUEventListener { if(!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { newTooltip.add(EnumChatFormatting.GRAY+"[SHIFT for Price Info]"); } else { - JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); + JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internalname); + float lowestBinAvg = neu.manager.auctionManager.getItemAvgBin(internalname); + + int lowestBin = neu.manager.auctionManager.getLowestBin(internalname); + APIManager.CraftInfo craftCost = neu.manager.auctionManager.getCraftCost(internalname); + + boolean hasAuctionPrice = auctionInfo != null; + boolean hasLowestBinPrice = lowestBin > 0 && neu.manager.config.advancedPriceInfo.value; + boolean hasLowestBinAvgPrice = lowestBinAvg > 0; + + NumberFormat format = NumberFormat.getInstance(Locale.US); + + if(hasLowestBinPrice) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"Lowest BIN: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBin)+" coins"); + } + if(hasLowestBinAvgPrice) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AVG Lowest BIN: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBinAvg)+" coins"); + } + if(hasAuctionPrice) { + int auctionPrice = (int)(auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Price: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(auctionPrice)+" coins"); + if(neu.manager.config.advancedPriceInfo.value) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Sales: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(auctionInfo.get("sales").getAsFloat())+" sales/day"); + } + if(auctionInfo.has("clean_price")) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Price (Clean): "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format((int)auctionInfo.get("clean_price").getAsFloat())+" coins"); + if(neu.manager.config.advancedPriceInfo.value) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Sales (Clean): "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(auctionInfo.get("clean_sales").getAsFloat())+" sales/day"); + } + } + + } + if(hasAuctionPrice && craftCost.fromRecipe) { + newTooltip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"Raw Craft Cost: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format((int)craftCost.craftCost)+" coins"); + } + + /*JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); boolean hasAuctionPrice = auctionInfo != null; @@ -1280,7 +1356,7 @@ public class NEUEventListener { if(craftCost.fromRecipe) { newTooltip.add(EnumChatFormatting.GRAY+"Raw Craft Cost: "+ EnumChatFormatting.GOLD+format.format((int)craftCost.craftCost)+" coins"); - } + }*/ } } } @@ -1314,10 +1390,28 @@ public class NEUEventListener { ItemStack item = lower.getStackInSlot(11+i); String internal = neu.manager.getInternalNameForItem(item); if(internal != null) { - float worthBIN = neu.manager.auctionManager.getLowestBin(internal); - float worthAUC = neu.manager.auctionManager.getLowestBin(internal); + float bazaarPrice = -1; + JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); + if(bazaarInfo != null && bazaarInfo.has("avg_sell")) { + bazaarPrice = bazaarInfo.get("avg_sell").getAsFloat(); + } + + float worthBIN = -1; + float worthAUC = -1; - if(worthAUC == -1) worthAUC = neu.manager.auctionManager.getCraftCost(internal).craftCost; + if(bazaarPrice > 0) { + worthBIN = bazaarPrice; + worthAUC = bazaarPrice; + } else { + worthBIN = neu.manager.auctionManager.getItemAvgBin(internal); + if(worthBIN <= 0) { + worthBIN = neu.manager.auctionManager.getLowestBin(internal); + } + JsonObject aucInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); + if(aucInfo != null) { + worthAUC = aucInfo.get("price").getAsFloat(); + } + } if(worthAUC <= 0 && worthBIN <= 0) { missing = true; @@ -1392,21 +1486,27 @@ public class NEUEventListener { if(internalname != null) { JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internalname); JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internalname); + float lowestBinAvg = neu.manager.auctionManager.getItemAvgBin(internalname); int lowestBin = neu.manager.auctionManager.getLowestBin(internalname); APIManager.CraftInfo craftCost = neu.manager.auctionManager.getCraftCost(internalname); boolean hasAuctionPrice = neu.manager.config.invAuctionPrice.value && auctionInfo != null; boolean hasBazaarPrice = neu.manager.config.invBazaarPrice.value && bazaarInfo != null; - boolean hasLowestBinPrice = neu.manager.config.invAuctionPrice.value && lowestBin > 0; + boolean hasLowestBinPrice = neu.manager.config.invAuctionPrice.value && lowestBin > 0 && neu.manager.config.advancedPriceInfo.value; + boolean hasLowestBinAvgPrice = neu.manager.config.invAuctionPrice.value && lowestBinAvg > 0; NumberFormat format = NumberFormat.getInstance(Locale.US); - if(hasAuctionPrice || hasBazaarPrice || hasLowestBinPrice) event.toolTip.add(""); + if(hasAuctionPrice || hasBazaarPrice || hasLowestBinAvgPrice || hasLowestBinPrice) event.toolTip.add(""); if(hasLowestBinPrice) { event.toolTip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"Lowest BIN: "+ EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBin)+" coins"); } + if(hasLowestBinAvgPrice) { + event.toolTip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AVG Lowest BIN: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBinAvg)+" coins"); + } if(hasAuctionPrice) { int auctionPrice = (int)(auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); event.toolTip.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Price: "+ diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 73381955..08d6c50b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -2,6 +2,7 @@ package io.github.moulberry.notenoughupdates; import com.google.common.collect.Lists; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.infopanes.*; @@ -96,7 +97,7 @@ public class NEUOverlay extends Gui { private TreeSet<JsonObject> searchedItems = null; private JsonObject[] searchedItemsArr = null; - private HashMap<String, Set<String>> searchedItemsSubgroup = new HashMap<>(); + private HashMap<String, List<String>> searchedItemsSubgroup = new HashMap<>(); private long selectedItemMillis = 0; private int selectedItemGroupX = -1; @@ -388,10 +389,11 @@ public class NEUOverlay extends Gui { int paddingUnscaled = getPaddingUnscaled(); int bigItemSize = getSearchBarYSize(); - if(quickCommandStr.split(":").length!=3) { + String[] quickCommandStrSplit = quickCommandStr.split(":"); + if(quickCommandStrSplit.length!=3) { return; } - String display = quickCommandStr.split(":")[2]; + String display = quickCommandStrSplit[2]; ItemStack render = null; float extraScale = 1; if(display.length() > 20) { //Custom head @@ -424,6 +426,10 @@ public class NEUOverlay extends Gui { } } if(render != null) { + NBTTagCompound tag = render.getTagCompound() != null ? render.getTagCompound() : new NBTTagCompound(); + tag.setString("qc_id", quickCommandStrSplit[0].toLowerCase().trim()); + render.setTagCompound(tag); + Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(x, y, @@ -435,7 +441,7 @@ public class NEUOverlay extends Gui { if(mouseX > x && mouseX < x+bigItemSize) { if(mouseY > y && mouseY < y+bigItemSize) { textToDisplay = new ArrayList<>(); - textToDisplay.add(EnumChatFormatting.GRAY+quickCommandStr.split(":")[1]); + textToDisplay.add(EnumChatFormatting.GRAY+quickCommandStrSplit[1]); } } @@ -968,6 +974,10 @@ public class NEUOverlay extends Gui { Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager, internalname.get(), item)); return true; + } else if(keyPressed == manager.keybindItemSelect.getKeyCode()) { + textField.setText("id:"+internalname.get()); + itemPaneOpen = true; + updateSearch(); } } } @@ -1142,32 +1152,47 @@ public class NEUOverlay extends Gui { return true; } + private HashMap<String, JsonObject> parentMap = new HashMap<>(); + /** * Clears the current item list, creating a new TreeSet if necessary. * Adds all items that match the search AND match the sort mode to the current item list. * Also adds some easter egg items. (Also I'm very upset if you came here to find them :'( ) */ public void updateSearch() { + SunTzu.randomizeQuote(); + if(searchedItems==null) searchedItems = new TreeSet<>(getItemComparator()); searchedItems.clear(); searchedItemsSubgroup.clear(); searchedItemsArr = null; redrawItems = true; + Set<JsonObject> removeChildItems = new HashSet<>(); Set<String> itemsMatch = manager.search(textField.getText(), true); for(String itemname : itemsMatch) { JsonObject item = manager.getItemInformation().get(itemname); if(checkMatchesSort(itemname, item)) { - if(item.has("parent") && item.get("parent").isJsonPrimitive()) { - searchedItemsSubgroup - .computeIfAbsent(item.get("parent").getAsString(), k->new HashSet<>()) - .add(item.get("internalname").getAsString()); - } else { - searchedItems.add(item); + if(Constants.PARENTS != null) { + if(Constants.PARENTS.has(itemname) && Constants.PARENTS.get(itemname).isJsonArray()) { + List<String> children = new ArrayList<>(); + for(JsonElement e : Constants.PARENTS.get(itemname).getAsJsonArray()) { + if(e.isJsonPrimitive()) { + children.add(e.getAsString()); + } + } + children.retainAll(itemsMatch); + for(String child : children) { + removeChildItems.add(manager.getItemInformation().get(child)); + } + searchedItemsSubgroup.put(itemname, children); + } } + searchedItems.add(item); } } + searchedItems.removeAll(removeChildItems); out: - for(Map.Entry<String, Set<String>> entry : searchedItemsSubgroup.entrySet()) { + for(Map.Entry<String, List<String>> entry : searchedItemsSubgroup.entrySet()) { if(searchedItems.contains(manager.getItemInformation().get(entry.getKey()))) { continue; } @@ -1506,7 +1531,11 @@ public class NEUOverlay extends Gui { GL11.glTranslatef(0, 0, 260); int overlay = new Color(0, 0, 0, 100).getRGB(); for(Slot slot : inv.inventorySlots.inventorySlots) { - if(slot.getStack() == null || !manager.doesStackMatchSearch(slot.getStack(), textField.getText())) { + boolean matches = false; + for(String search : textField.getText().split("\\|")) { + matches |= slot.getStack() != null && manager.doesStackMatchSearch(slot.getStack(), search.trim()); + } + if(!matches) { drawRect(guiLeftI+slot.xDisplayPosition, guiTopI+slot.yDisplayPosition, guiLeftI+slot.xDisplayPosition+16, guiTopI+slot.yDisplayPosition+16, overlay); @@ -1690,6 +1719,8 @@ public class NEUOverlay extends Gui { GlStateManager.bindTexture(0); } + SunTzu.setEnabled(textField.getText().toLowerCase().startsWith("potato")); + updateGuiGroupSize(); if(guiScaleLast != Utils.peekGuiScale().getScaleFactor()) { @@ -1926,6 +1957,9 @@ public class NEUOverlay extends Gui { int selectedX = Math.min(selectedItemGroupX, width-getBoxPadding()-18*selectedItemGroup.size()); GlStateManager.depthFunc(GL11.GL_LESS); + + drawRect(selectedX-1+2, selectedItemGroupY+17+2, + selectedX-1+18*selectedItemGroup.size()+2, selectedItemGroupY+35+2, 0xa0000000); drawRect(selectedX, selectedItemGroupY+18, selectedX-2+18*selectedItemGroup.size(), selectedItemGroupY+34, fgCustomOpacity.getRGB()); drawRect(selectedX, selectedItemGroupY+18, @@ -2000,21 +2034,27 @@ public class NEUOverlay extends Gui { String internalname = json.get("internalname").getAsString(); JsonObject auctionInfo = manager.auctionManager.getItemAuctionInfo(internalname); JsonObject bazaarInfo = manager.auctionManager.getBazaarInfo(internalname); + float lowestBinAvg = manager.auctionManager.getItemAvgBin(internalname); int lowestBin = manager.auctionManager.getLowestBin(internalname); - APIManager.CraftInfo craftCost = manager.auctionManager.getCraftCost(json.get("internalname").getAsString()); + APIManager.CraftInfo craftCost = manager.auctionManager.getCraftCost(internalname); boolean hasAuctionPrice = !manager.config.invAuctionPrice.value && auctionInfo != null; boolean hasBazaarPrice = !manager.config.invBazaarPrice.value && bazaarInfo != null; - boolean hasLowestBinPrice = !manager.config.invAuctionPrice.value && lowestBin > 0; + boolean hasLowestBinPrice = !manager.config.invAuctionPrice.value && lowestBin > 0 && manager.config.advancedPriceInfo.value; + boolean hasLowestBinAvgPrice = !manager.config.invAuctionPrice.value && lowestBinAvg > 0; NumberFormat format = NumberFormat.getInstance(Locale.US); - if(hasAuctionPrice || hasBazaarPrice || hasLowestBinPrice) text.add(""); + if(hasAuctionPrice || hasBazaarPrice || hasLowestBinAvgPrice || hasLowestBinPrice) text.add(""); if(hasLowestBinPrice) { text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"Lowest BIN: "+ EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBin)+" coins"); } + if(hasLowestBinAvgPrice) { + text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AVG Lowest BIN: "+ + EnumChatFormatting.GOLD+EnumChatFormatting.BOLD+format.format(lowestBinAvg)+" coins"); + } if(hasAuctionPrice) { int auctionPrice = (int)(auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); text.add(EnumChatFormatting.YELLOW.toString()+EnumChatFormatting.BOLD+"AH Price: "+ diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 3ca2ab04..1894023b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.questing.GuiQuestLine; import io.github.moulberry.notenoughupdates.questing.SBInfo; +import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.block.material.MapColor; import net.minecraft.client.Minecraft; @@ -78,7 +79,7 @@ import java.util.regex.Pattern; @Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true) public class NotEnoughUpdates { public static final String MODID = "notenoughupdates"; - public static final String VERSION = "1.5-REL"; + public static final String VERSION = "1.7-REL"; public static NotEnoughUpdates INSTANCE = null; @@ -242,6 +243,7 @@ public class NotEnoughUpdates { } } } + Constants.reload(); } }); @@ -792,7 +794,7 @@ public class NotEnoughUpdates { } }); - SimpleCommand settingsCommand = new SimpleCommand("neusettings", new SimpleCommand.ProcessCommandRunnable() { + SimpleCommand settingsCommand = new SimpleCommand("neu", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { overlay.displayInformationPane(new SettingsInfoPane(overlay, manager)); if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { @@ -801,7 +803,7 @@ public class NotEnoughUpdates { } }); - SimpleCommand settingsCommand2 = new SimpleCommand("neuconfig", new SimpleCommand.ProcessCommandRunnable() { + SimpleCommand settingsCommand2 = new SimpleCommand("neusettings", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { overlay.displayInformationPane(new SettingsInfoPane(overlay, manager)); if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { @@ -810,6 +812,24 @@ public class NotEnoughUpdates { } }); + SimpleCommand settingsCommand3 = new SimpleCommand("neuconfig", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + overlay.displayInformationPane(new SettingsInfoPane(overlay, manager)); + if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) { + openGui = new GuiInventory(Minecraft.getMinecraft().thePlayer); + } + } + }); + + + SimpleCommand calendarCommand = new SimpleCommand("neucalendar", new SimpleCommand.ProcessCommandRunnable() { + public void processCommand(ICommandSender sender, String[] args) { + Minecraft.getMinecraft().thePlayer.closeScreen(); + CalendarOverlay.setEnabled(true); + sendChatMessage("/calendar"); + } + }); + SimpleCommand neuAhCommand = new SimpleCommand("neuah", new SimpleCommand.ProcessCommandRunnable() { public void processCommand(ICommandSender sender, String[] args) { if(!hasSkyblockScoreboard()) { @@ -841,9 +861,11 @@ public class NotEnoughUpdates { MinecraftForge.EVENT_BUS.register(new NEUEventListener(this)); MinecraftForge.EVENT_BUS.register(CapeManager.getInstance()); MinecraftForge.EVENT_BUS.register(new SBGamemodes()); + MinecraftForge.EVENT_BUS.register(new CalendarOverlay()); MinecraftForge.EVENT_BUS.register(SBInfo.getInstance()); MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE); MinecraftForge.EVENT_BUS.register(new DungeonMap()); + MinecraftForge.EVENT_BUS.register(new SunTzu()); //MinecraftForge.EVENT_BUS.register(new BetterPortals()); File f = new File(event.getModConfigurationDirectory(), "notenoughupdates"); @@ -867,7 +889,9 @@ public class NotEnoughUpdates { ClientCommandHandler.instance.registerCommand(neumapCommand); ClientCommandHandler.instance.registerCommand(settingsCommand); ClientCommandHandler.instance.registerCommand(settingsCommand2); + ClientCommandHandler.instance.registerCommand(settingsCommand3); ClientCommandHandler.instance.registerCommand(dungeonWinTest); + ClientCommandHandler.instance.registerCommand(calendarCommand); manager = new NEUManager(this, f); manager.loadItemInformation(); @@ -893,35 +917,39 @@ public class NotEnoughUpdates { })); //TODO: login code. Ignore this, used for testing. - try { - Field field = Minecraft.class.getDeclaredField("session"); - YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) - new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()) - .createUserAuthentication(Agent.MINECRAFT); - auth.setUsername("james.jenour@protonmail.com"); - JPasswordField pf = new JPasswordField(); - JOptionPane.showConfirmDialog(null, - pf, - "Enter password:", - JOptionPane.NO_OPTION, - JOptionPane.PLAIN_MESSAGE); - auth.setPassword(new String(pf.getPassword())); - System.out.print("Attempting login..."); - - auth.logIn(); - - Session session = new Session(auth.getSelectedProfile().getName(), - auth.getSelectedProfile().getId().toString().replace("-", ""), - auth.getAuthenticatedToken(), - auth.getUserType().getName()); - - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - - field.setAccessible(true); - field.set(Minecraft.getMinecraft(), session); - } catch (NoSuchFieldException | AuthenticationException | IllegalAccessException e) { + if(manager.config.dev.value) { + try { + Field field = Minecraft.class.getDeclaredField("session"); + YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) + new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()) + .createUserAuthentication(Agent.MINECRAFT); + auth.setUsername("james.jenour@protonmail.com"); + auth.setPassword("Miranda728%"); + + JPasswordField pf = new JPasswordField(); + JOptionPane.showConfirmDialog(null, + pf, + "Enter password:", + JOptionPane.NO_OPTION, + JOptionPane.PLAIN_MESSAGE); + auth.setPassword(new String(pf.getPassword())); + System.out.print("Attempting login..."); + + auth.logIn(); + + Session session = new Session(auth.getSelectedProfile().getName(), + auth.getSelectedProfile().getId().toString().replace("-", ""), + auth.getAuthenticatedToken(), + auth.getUserType().getName()); + + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + field.setAccessible(true); + field.set(Minecraft.getMinecraft(), session); + } catch (NoSuchFieldException | AuthenticationException | IllegalAccessException e) { + } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/SBAIntegration.java b/src/main/java/io/github/moulberry/notenoughupdates/SBAIntegration.java index d9e9217a..4df9c847 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/SBAIntegration.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/SBAIntegration.java @@ -44,7 +44,10 @@ public class SBAIntegration { backpackManager_getFromItem = backpackManagerClass.getDeclaredMethod("getFromItem", ItemStack.class); } if(backpackClass == null) { - backpackClass = Class.forName("codes.biscuit.skyblockaddons.features.backpacks.Backpack"); + try { backpackClass = Class.forName("codes.biscuit.skyblockaddons.features.backpacks.Backpack"); } catch(Exception ignored){} + } + if(backpackClass == null) { + backpackClass = Class.forName("codes.biscuit.skyblockaddons.features.backpacks.ContainerPreview"); } if(backpackClass_setX == null) { backpackClass_setX = backpackClass.getDeclaredMethod("setX", int.class); @@ -56,7 +59,10 @@ public class SBAIntegration { utilsClass = Class.forName("codes.biscuit.skyblockaddons.utils.Utils"); } if(utils_setBackpackToPreview == null) { - utils_setBackpackToPreview = utilsClass.getDeclaredMethod("setBackpackToPreview", backpackClass); + try { utils_setBackpackToPreview = utilsClass.getDeclaredMethod("setBackpackToPreview", backpackClass); } catch(Exception ignored){} + } + if(utils_setBackpackToPreview == null) { + utils_setBackpackToPreview = utilsClass.getDeclaredMethod("setContainerPreviewToRender", backpackClass);; } } catch(Exception e) { e.printStackTrace(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/SunTzu.java b/src/main/java/io/github/moulberry/notenoughupdates/SunTzu.java new file mode 100644 index 00000000..6de8245e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/SunTzu.java @@ -0,0 +1,94 @@ +package io.github.moulberry.notenoughupdates; + +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MovingObjectPosition; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.Random; + +public class SunTzu { + + private static boolean enabled = false; + private static int quoteNum = 0; + + private static Random rand = new Random(); + + private static String[] quotes = new String[] { + "Appear weak when you are strong, and strong when you are weak.", + "The supreme art of war is to subdue the enemy without fighting.", + "If you know the enemy and know yourself, you need not fear the result of a hundred battles.", + "Let your plans be dark and impenetrable as night, and when you move, fall like a thunderbolt.", + "All warfare is based on deception.", + "In the midst of chaos, there is also opportunity.", + "The greatest victory is that which requires no battle.", + "To know your Enemy, you must become your Enemy.", + "There is no instance of a nation benefitting from prolonged warfare.", + "Even the finest sword plunged into salt water will eventually rust.", + "Opportunities multiply as they are seized.", + "When the enemy is relaxed, make them toil. When full, starve them. When settled, make them move.", + "He who wishes to fight must first count the cost", + "If you wait by the river long enough, the bodies of your enemies will float by.", + "Be extremely subtle even to the point of formlessness. Be extremely mysterious even to the point of soundlessness. Thereby you can be the director of the opponent's fate.", + "Build your opponent a golden bridge to retreat across.", + "The wise warrior avoids the battle.", + "Great results, can be achieved with small forces.", + "Attack is the secret of defense; defense is the planning of an attack.", + "Subscribe to Moulberry on YouTube." + }; + + public static void setEnabled(boolean enabled) { + SunTzu.enabled = enabled; + } + + public static void randomizeQuote() { + for(int i=0; i<3; i++) { + int newQuote = rand.nextInt(quotes.length); + + if(newQuote != quoteNum) { + quoteNum = newQuote; + return; + } + } + } + + private static String getQuote() { + return quotes[quoteNum]; + } + + @SubscribeEvent + public void onOverlayDrawn(RenderGameOverlayEvent event) { + if(enabled && ((event.type == null && Loader.isModLoaded("labymod")) || + event.type == RenderGameOverlayEvent.ElementType.ALL)) { + if(Minecraft.getMinecraft().gameSettings.showDebugInfo || + (Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isKeyDown() && + (!Minecraft.getMinecraft().isIntegratedServerRunning() || + Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap().size() > 1))) { + return; + } + + ScaledResolution sr = Utils.pushGuiScale(2); + + int height = Utils.renderStringTrimWidth(EnumChatFormatting.YELLOW+getQuote(), Minecraft.getMinecraft().fontRendererObj, + true, sr.getScaledWidth()/2-100, 5, 200, -1, -1); + String sunTzu = "- Sun Tzu, The Art of War"; + int sunTzuLength = Minecraft.getMinecraft().fontRendererObj.getStringWidth(sunTzu); + Minecraft.getMinecraft().fontRendererObj.drawString(EnumChatFormatting.GOLD+sunTzu, + sr.getScaledWidth()/2f+100-sunTzuLength, 15+height, 0, true); + + Utils.pushGuiScale(-1); + } + } + + @SubscribeEvent + public void switchWorld(WorldEvent.Load event) { + randomizeQuote(); + } + + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index d6f390c6..e2cc82bd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -40,6 +40,7 @@ public class APIManager { private HashSet<String> playerBidsFinishedNotified = new HashSet<>(); private JsonObject lowestBins = null; + private JsonObject auctionPricesAvgLowestBinJson = null; private LinkedList<Integer> pagesToDownload = null; @@ -662,6 +663,9 @@ public class APIManager { auctionPricesJson = jsonObject; lastAuctionAvgUpdate = System.currentTimeMillis(); }, () -> {}); + manager.hypixelApi.getMyApiGZIPAsync("auction_averages_lbin/3day.json.gz", (jsonObject) -> { + auctionPricesAvgLowestBinJson = jsonObject; + }, () -> {}); } public Set<String> getItemAuctionInfoKeySet() { @@ -682,6 +686,15 @@ public class APIManager { return e.getAsJsonObject(); } + public float getItemAvgBin(String internalname) { + if(auctionPricesAvgLowestBinJson == null) return -1; + JsonElement e = auctionPricesAvgLowestBinJson.get(internalname); + if(e == null) { + return -1; + } + return Math.round(e.getAsFloat()); + } + public JsonObject getBazaarInfo(String internalname) { if(bazaarJson == null) return null; JsonElement e = bazaarJson.get(internalname); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index fa1db64e..c542600e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -32,8 +32,9 @@ public class CapeManager { private boolean allAvailable = false; private HashSet<String> availableCapes = new HashSet<>(); - private String[] capes = new String[]{"patreon1", "patreon2", "fade", "contrib", "nullzee", "gravy", "space", "mcworld", "lava", "packshq", "mbstaff" }; - public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, true, true, true }; + private String[] capes = new String[]{"patreon1", "patreon2", "fade", "contrib", "nullzee", + "gravy", "space", "mcworld", "lava", "packshq", "mbstaff", "thebakery" }; + public Boolean[] specialCapes = new Boolean[]{ true, true, false, true, true, true, false, false, false, true, true, true }; public static CapeManager getInstance() { return INSTANCE; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java index 4723d00f..3f84f8fc 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java @@ -380,10 +380,10 @@ public class GuiCosmetics extends GuiScreen { } GlStateManager.color(1, 1, 1, 1); - ResourceLocation capeTexture = capesLocation.computeIfAbsent(cape, k -> new ResourceLocation("notenoughupdates", "capes/"+cape+".png")); + ResourceLocation capeTexture = capesLocation.computeIfAbsent(cape, + k -> new ResourceLocation("notenoughupdates", "capes/"+cape+"_preview.png")); Minecraft.getMinecraft().getTextureManager().bindTexture(capeTexture); - Utils.drawTexturedRect(guiLeft+31+91*displayIndex-xOffset, guiTop+24, 59, 84, - 0, 293/1024f, 0, 420/1024f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft+31+91*displayIndex-xOffset, guiTop+24, 59, 84, GL11.GL_NEAREST); displayIndex++; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java index d56a3f8c..cc5faa3f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java @@ -83,8 +83,10 @@ public class NEUCape { shaderName = "lava_cape"; } else if(capeName.equalsIgnoreCase("lightning")) { shaderName = "lightning_cape"; + } else if(capeName.equalsIgnoreCase("thebakery")) { + shaderName = "biscuit_cape"; } else { - shaderName = "cape"; + shaderName = "shiny_cape"; } ResourceLocation staticCapeTex = new ResourceLocation("notenoughupdates:capes/"+capeName+".png"); @@ -150,9 +152,9 @@ public class NEUCape { public void createCapeNodes(EntityPlayer player) { nodes = new ArrayList<>(); - float pX = (float)player.posX; + float pX = (float)player.posX % 7789; float pY = (float)player.posY; - float pZ = (float)player.posZ; + float pZ = (float)player.posZ % 7789; float uMinTop = 48/1024f; float uMaxTop = 246/1024f; @@ -310,6 +312,9 @@ public class NEUCape { shaderManager.loadData(shaderName, "millis", (int) (System.currentTimeMillis() - startTime)); } else if(shaderName.equalsIgnoreCase("lightning_cape")) { shaderManager.loadData(shaderName, "millis", (int) (System.currentTimeMillis() - startTime)); + } else if(shaderName.equalsIgnoreCase("biscuit_cape") || shaderName.equalsIgnoreCase("shiny_cape")) { + shaderManager.loadData(shaderName, "millis", (int) (System.currentTimeMillis() - startTime)); + shaderManager.loadData(shaderName, "eventMillis", (int)(System.currentTimeMillis()-eventMillis)); } } @@ -325,9 +330,9 @@ public class NEUCape { ensureCapeNodesCreated(player); Entity viewer = Minecraft.getMinecraft().getRenderViewEntity(); - double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * e.partialRenderTick; + double viewerX = (viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * e.partialRenderTick) % 7789; double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * e.partialRenderTick; - double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * e.partialRenderTick; + double viewerZ = (viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * e.partialRenderTick) % 7789; GlStateManager.pushMatrix(); GlStateManager.enableBlend(); @@ -398,9 +403,9 @@ public class NEUCape { } private Vector3f updateFixedCapeNodes(EntityPlayer player) { - double pX = player.posX;//player.lastTickPosX + (player.posX - player.lastTickPosX) * partialRenderTick; + double pX = player.posX % 7789;//player.lastTickPosX + (player.posX - player.lastTickPosX) * partialRenderTick; double pY = player.posY;//player.lastTickPosY + (player.posY - player.lastTickPosY) * partialRenderTick; - double pZ = player.posZ;//player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialRenderTick; + double pZ = player.posZ % 7789;//player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialRenderTick; double angle = Math.toRadians(player.renderYawOffset); double vertOffset2 = vertOffset + (player.isSneaking() ? -0.22f : 0) + (player.getCurrentArmor(2) != null ? 0.06f : 0); @@ -440,9 +445,9 @@ public class NEUCape { } private void updateFixedCapeNodesPartial(EntityPlayer player, float partialRenderTick) { - double pX = player.lastTickPosX + (player.posX - player.lastTickPosX) * partialRenderTick; + double pX = (player.lastTickPosX + (player.posX - player.lastTickPosX) * partialRenderTick) % 7789; double pY = player.lastTickPosY + (player.posY - player.lastTickPosY) * partialRenderTick; - double pZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialRenderTick; + double pZ = (player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * partialRenderTick) % 7789; double angle = Math.toRadians(player.renderYawOffset); double vertOffset2 = vertOffset + (player.isSneaking() ? -0.22f : 0) + (player.getCurrentArmor(2) != null ? 0.06f : 0); @@ -479,6 +484,12 @@ public class NEUCape { eventLength = random.nextFloat()*2000+4000; eventRandom = random.nextFloat(); } + } else if(shaderName.equals("biscuit_cape") || shaderName.equals("shiny_cape")) { + long currentTime = System.currentTimeMillis(); + if(currentTime-startTime > eventMillis-startTime+eventLength) { + eventMillis = currentTime; + eventLength = random.nextFloat()*3000+3000; + } } if(notRendering) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index fa49c0c2..fb9af536 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -1,5 +1,6 @@ package io.github.moulberry.notenoughupdates.dungeons; +import com.google.common.collect.Iterables; import com.google.common.math.BigIntegerMath; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NEUResourceManager; @@ -31,6 +32,7 @@ import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.util.*; import net.minecraft.world.storage.MapData; import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.BufferUtils; @@ -355,20 +357,20 @@ public class DungeonMap { } public int getRenderRoomSize() { - int roomSizeOption = NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize.value.intValue(); + double roomSizeOption = NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize.value; if(roomSizeOption <= 0) return 12; - return 12 + roomSizeOption*4; + return 12 + (int)Math.round(roomSizeOption*4); } public int getRenderConnSize() { - int roomSizeOption = NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize.value.intValue(); + int roomSizeOption = (int)Math.round(NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize.value); if(roomSizeOption <= 0) return 3; return 3 + roomSizeOption; } private HashMap<Integer, Float> borderRadiusCache = new HashMap<>(); public float getBorderRadius() { - int borderSizeOption = NotEnoughUpdates.INSTANCE.manager.config.dmBorderSize.value.intValue(); + int borderSizeOption = (int)Math.round(NotEnoughUpdates.INSTANCE.manager.config.dmBorderSize.value.doubleValue()); String sizeId = borderSizeOption == 0 ? "small" : borderSizeOption == 2 ? "large" : "medium"; int style = NotEnoughUpdates.INSTANCE.manager.config.dmBorderStyle.value.intValue(); @@ -433,8 +435,14 @@ public class DungeonMap { rotation = (int)playerPos.rotation; } - int mapSizeX = borderSizeOption == 0 ? 90 : borderSizeOption == 2 ? 160 : borderSizeOption == 3 ? 240 : 120; - int mapSizeY = borderSizeOption == 0 ? 90 : borderSizeOption == 2 ? 160 : borderSizeOption == 3 ? 240 : 120; + int mapSizeX; + int mapSizeY; + if(NotEnoughUpdates.INSTANCE.manager.config.dmBorderStyle.value <= 1) { + mapSizeX = 80 + (int)Math.round(40*NotEnoughUpdates.INSTANCE.manager.config.dmBorderSize.value); + } else { + mapSizeX = borderSizeOption == 0 ? 90 : borderSizeOption == 1 ? 120 : borderSizeOption == 2 ? 160 : 240; + } + mapSizeY = mapSizeX; int roomsSizeX = (maxRoomX-minRoomX)*(renderRoomSize+renderConnSize)+renderRoomSize; int roomsSizeY = (maxRoomY-minRoomY)*(renderRoomSize+renderConnSize)+renderRoomSize; int mapCenterX = mapSizeX/2; @@ -454,6 +462,7 @@ public class DungeonMap { } } catch(Exception e) { e.printStackTrace(); + Utils.pushGuiScale(-1); return; } @@ -792,15 +801,15 @@ public class DungeonMap { Minecraft.getMinecraft().getTextureManager().bindTexture(rl); GlStateManager.color(1, 1, 1, 1); - int size = borderSizeOption == 0 ? 165 : borderSizeOption == 2 ? 300 : borderSizeOption == 3 ? 440 : 220; + int size = borderSizeOption == 0 ? 165 : borderSizeOption == 1 ? 220 : borderSizeOption == 2 ? 300 : 440; Utils.drawTexturedRect(-size/2, -size/2, size, size, GL11.GL_NEAREST); } GlStateManager.translate(-centerX, -centerY, -100); } catch(Exception e) { e.printStackTrace(); - Minecraft.getMinecraft().entityRenderer.setupOverlayRendering(); Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true); + Minecraft.getMinecraft().entityRenderer.setupOverlayRendering(); } Utils.pushGuiScale(-1); @@ -992,9 +1001,10 @@ public class DungeonMap { } } + private boolean failMap = false; private long lastClearCache = 0; public void renderMap(int centerX, int centerY, Color[][] colourMap, Map<String, Vec4b> mapDecorations, - int roomSizeBlocks, Set<String> actualPlayers, boolean usePlayerPositions) { + int roomSizeBlocks, Set<String> actualPlayers, boolean usePlayerPositions, float partialTicks) { if(!NotEnoughUpdates.INSTANCE.manager.config.dmEnable.value) return; if(colourMap == null) return; if(colourMap.length != 128) return; @@ -1008,10 +1018,31 @@ public class DungeonMap { connectorSize = -1; roomSize = -1; borderRadiusCache.clear(); + failMap = false; lastClearCache = System.currentTimeMillis(); } + if(failMap) { + return; + } + + int alphaPixels = 0; + for(int x=0; x<128; x++) { + for(int y=0; y<128; y++) { + Color c = colourMap[x][y]; + if(c == null) { + return; + } else if(c.getAlpha() < 50) { + alphaPixels++; + } + } + } + if(alphaPixels < 128*128/10) { + failMap = true; + return; + } + if(startRoomX < 0 || startRoomY < 0 || roomSize <= 0) { for(int x=0; x<colourMap.length; x++) { for(int y=0; y<colourMap[x].length; y++) { @@ -1045,6 +1076,11 @@ public class DungeonMap { } } + if(startRoomX < 0 || startRoomY < 0) { + failMap = true; + return; + } + if(connectorSize <= 0) { for(int i=0; i<roomSize; i++) { for(int k=0; k<4; k++) { @@ -1131,7 +1167,7 @@ public class DungeonMap { playerConnOffsetY -= startRoomY/(roomSize+connectorSize); MapPosition pos = new MapPosition(playerRoomOffsetX, playerConnOffsetX, playerRoomOffsetY, playerConnOffsetY); - pos.rotation = player.rotationYawHead % 360; + pos.rotation = (player.prevRotationYawHead + (player.rotationYawHead-player.prevRotationYawHead)*partialTicks) % 360; if(pos.rotation < 0) pos.rotation += 360; playerEntityMapPositions.put(player.getName(), pos); } @@ -1144,9 +1180,20 @@ public class DungeonMap { updateRoomConnections(offset); } + if(roomMap.isEmpty()) { + failMap = true; + return; + } + if(mapDecorations != null && mapDecorations.size() > 0) { List<MapPosition> positions = new ArrayList<>(); + int decorations = 0; for (Vec4b vec4b : mapDecorations.values()) { + byte id = vec4b.func_176110_a(); + if(id != 1 && id != 3) continue; + + if(decorations++ == 6) break; + float x = (float) vec4b.func_176112_b() / 2.0F + 64.0F; float y = (float) vec4b.func_176113_c() / 2.0F + 64.0F; @@ -1320,13 +1367,15 @@ public class DungeonMap { } @SubscribeEvent + public void onWorldChange(WorldEvent.Load event) { + colourMap = null; + } + + @SubscribeEvent public void onRenderOverlay(RenderGameOverlayEvent event) { if(event.type == RenderGameOverlayEvent.ElementType.ALL) { if(!NotEnoughUpdates.INSTANCE.manager.config.dmEnable.value) return; - if(SBInfo.getInstance().getLocation() == null || !SBInfo.getInstance().getLocation().equals("dungeon")) { - return; - } if(Minecraft.getMinecraft().gameSettings.showDebugInfo || (Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isKeyDown() && (!Minecraft.getMinecraft().isIntegratedServerRunning() || @@ -1335,7 +1384,7 @@ public class DungeonMap { } ItemStack stack = Minecraft.getMinecraft().thePlayer.inventory.mainInventory[8]; - boolean holdingBow = stack != null && stack.getItem() == Items.arrow; + boolean holdingBow = stack != null && stack.getItem() == Items.arrow && colourMap != null; if(holdingBow || (stack != null && stack.getItem() instanceof ItemMap)) { Map<String, Vec4b> decorations = null; @@ -1343,7 +1392,7 @@ public class DungeonMap { if(holdingBow) { for(int x=0; x<128; x++) { for(int y=0; y<128; y++) { - if(this.colourMap != null && this.colourMap[x][y] != null) { + if(this.colourMap[x][y] != null) { colourMap[x][y] = this.colourMap[x][y]; } else { colourMap[x][y] = new Color(0, true); @@ -1412,15 +1461,31 @@ public class DungeonMap { if(mostCommonDist > 31) roomSizeBlocks = mostCommonDist;*/ Set<String> actualPlayers = new HashSet<>(); + /*for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) { + if(player.getUniqueID().toString().charAt(14) == '4') { + actualPlayers.add(player.getName()); + System.out.println(player.getName()); + + } + }*/ + int players = 0; for(ScorePlayerTeam team : Minecraft.getMinecraft().thePlayer.getWorldScoreboard().getTeams()) { - if(team.getTeamName().startsWith("a")) { - actualPlayers.addAll(team.getMembershipCollection()); + if(team.getTeamName().startsWith("a") && team.getMembershipCollection().size() == 1) { + String playerName = Iterables.get(team.getMembershipCollection(), 0); + for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) { + if(player.getName().equals(playerName) && (player == Minecraft.getMinecraft().thePlayer || + (!player.isPlayerSleeping() && !player.isInvisible()))) { + actualPlayers.add(playerName); + break; + } + } + if(++players >= 6) break; } } renderMap((int)(NotEnoughUpdates.INSTANCE.manager.config.dmCenterX.value/100*Minecraft.getMinecraft().displayWidth/2), (int)(NotEnoughUpdates.INSTANCE.manager.config.dmCenterY.value/100*Minecraft.getMinecraft().displayHeight/2), - colourMap, decorations, roomSizeBlocks, actualPlayers, true); + colourMap, decorations, roomSizeBlocks, actualPlayers, true, event.partialTicks); } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java index f6538346..fec10027 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java @@ -144,7 +144,7 @@ public class DungeonWin { long currentTime = System.currentTimeMillis(); String unformatted = Utils.cleanColour(e.message.getUnformattedText()); if(e.message.getFormattedText().startsWith(EnumChatFormatting.RESET+" ")) { - if(currentTime - lastDungeonFinish > 10000) { + if(currentTime - lastDungeonFinish > 30000) { Matcher matcher = TEAM_SCORE_REGEX.matcher(unformatted); if(matcher.find()) { lastDungeonFinish = currentTime; @@ -177,7 +177,6 @@ public class DungeonWin { e.setCanceled(true); if(unformatted.contains("\u25AC")) { hideChat = false; - lastDungeonFinish = 0; displayWin(); } else { if(unformatted.trim().length() > 0) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java index 5890b5c0..438eb01d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java @@ -6,6 +6,7 @@ import io.github.moulberry.notenoughupdates.options.Options; import io.github.moulberry.notenoughupdates.util.SpecialColour; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; @@ -27,6 +28,7 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.util.*; import java.util.List; +import static io.github.moulberry.notenoughupdates.GuiTextures.*; import static io.github.moulberry.notenoughupdates.GuiTextures.*; import static io.github.moulberry.notenoughupdates.GuiTextures.colour_selector_dot; @@ -57,6 +59,8 @@ public class GuiDungeonMapEditor extends GuiScreen { private GuiElementTextField blurField = new GuiElementTextField("", GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE); private ColourEditor activeColourEditor = null; + private Options.Option<Double> clickedSlider = null; + private class ColourEditor { public int x; public int y; @@ -127,28 +131,28 @@ public class GuiDungeonMapEditor extends GuiScreen { public GuiDungeonMapEditor() { Options options = NotEnoughUpdates.INSTANCE.manager.config; //Map Border Size - buttons.add(new Button(0, 6, 37, "Small", options.dmBorderSize)); - buttons.add(new Button(1, 52, 37, "Medium", options.dmBorderSize)); - buttons.add(new Button(2, 98, 37, "Large", options.dmBorderSize)); + //buttons.add(new Button(0, 6, 37, "Small", options.dmBorderSize)); + //buttons.add(new Button(1, 52, 37, "Medium", options.dmBorderSize)); + //buttons.add(new Button(2, 98, 37, "Large", options.dmBorderSize)); //Map Rooms Size - buttons.add(new Button(3, 6, 67+19, "Small", options.dmRoomSize)); - buttons.add(new Button(4, 52, 67+19, "Medium", options.dmRoomSize)); - buttons.add(new Button(5, 98, 67+19, "Large", options.dmRoomSize)); + //buttons.add(new Button(3, 6, 67+19, "Small", options.dmRoomSize)); + //buttons.add(new Button(4, 52, 67+19, "Medium", options.dmRoomSize)); + //buttons.add(new Button(5, 98, 67+19, "Large", options.dmRoomSize)); //Map Border Styles - buttons.add(new Button(6, 6, 97+38, "None")); - buttons.add(new Button(7, 52, 97+38, "Custom")); - buttons.add(new Button(8, 98, 97+38, "Stone")); - buttons.add(new Button(9, 6, 116+38, "Wood")); - buttons.add(new Button(10, 52, 116+38, "Rustic(S)")); - buttons.add(new Button(11, 98, 116+38, "Rustic(C)")); - buttons.add(new Button(12, 6, 135+38, "Fade")); - buttons.add(new Button(13, 52, 135+38, "Ribbons")); - buttons.add(new Button(14, 98, 135+38, "Paper")); - buttons.add(new Button(15, 6, 154+38, "Crimson")); - buttons.add(new Button(16, 52, 154+38, "Ornate")); - buttons.add(new Button(17, 98, 154+38, "Dragon")); + buttons.add(new Button(6, 6, 97, "None")); + buttons.add(new Button(7, 52, 97, "Custom")); + buttons.add(new Button(8, 98, 97, "Stone")); + buttons.add(new Button(9, 6, 116, "Wood")); + buttons.add(new Button(10, 52, 116, "Rustic(S)")); + buttons.add(new Button(11, 98, 116, "Rustic(C)")); + buttons.add(new Button(12, 6, 135, "Fade")); + buttons.add(new Button(13, 52, 135, "Ribbons")); + buttons.add(new Button(14, 98, 135, "Paper")); + buttons.add(new Button(15, 6, 154, "Crimson")); + buttons.add(new Button(16, 52, 154, "Ornate")); + buttons.add(new Button(17, 98, 154, "Dragon")); //Dungeon Map buttons.add(new Button(18, 20+139, 36, "Yes/No", options.dmEnable)); @@ -175,8 +179,8 @@ public class GuiDungeonMapEditor extends GuiScreen { //Chroma Mode buttons.add(new Button(28, 84+139, 181, "Normal/Scroll", options.dmChromaBorder)); - buttons.add(new Button(29, 52, 86+19, "XLarge", options.dmRoomSize)); - buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize)); + //buttons.add(new Button(29, 52, 86+19, "XLarge", options.dmRoomSize)); + //buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize)); xField.setText(String.valueOf(NotEnoughUpdates.INSTANCE.manager.config.dmCenterX.value)); yField.setText(String.valueOf(NotEnoughUpdates.INSTANCE.manager.config.dmCenterY.value)); @@ -266,9 +270,9 @@ public class GuiDungeonMapEditor extends GuiScreen { Utils.drawStringCenteredScaledMaxWidth("Map Border Size", Minecraft.getMinecraft().fontRendererObj, guiLeft+76, guiTop+30, false, 137, 0xFFB4B4B4); Utils.drawStringCenteredScaledMaxWidth("Map Rooms Size", Minecraft.getMinecraft().fontRendererObj, - guiLeft+76, guiTop+60+19, false, 137, 0xFFB4B4B4); + guiLeft+76, guiTop+60, false, 137, 0xFFB4B4B4); Utils.drawStringCenteredScaledMaxWidth("Map Border Style", Minecraft.getMinecraft().fontRendererObj, - guiLeft+76, guiTop+90+38, false, 137, 0xFFB4B4B4); + guiLeft+76, guiTop+90, false, 137, 0xFFB4B4B4); Utils.drawStringCenteredScaledMaxWidth("Dungeon Map", Minecraft.getMinecraft().fontRendererObj, guiLeft+44+139, guiTop+30, false, 60, 0xFFB4B4B4); @@ -301,32 +305,35 @@ public class GuiDungeonMapEditor extends GuiScreen { guiLeft+108+139, guiTop+175, false, 60, 0xFFB4B4B4); Utils.drawStringCenteredScaledMaxWidth("X (%)", Minecraft.getMinecraft().fontRendererObj, - guiLeft+44+139, guiTop+204, false, 60, 0xFFB4B4B4); + guiLeft+44, guiTop+189, false, 60, 0xFFB4B4B4); Utils.drawStringCenteredScaledMaxWidth("Y (%)", Minecraft.getMinecraft().fontRendererObj, - guiLeft+108+139, guiTop+204, false, 60, 0xFFB4B4B4); + guiLeft+108, guiTop+189, false, 60, 0xFFB4B4B4); + + drawSlider(NotEnoughUpdates.INSTANCE.manager.config.dmBorderSize, guiLeft+76, guiTop+45); + drawSlider(NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize, guiLeft+76, guiTop+75); Options options = NotEnoughUpdates.INSTANCE.manager.config; - buttons.get(18).text = options.dmEnable.value ? "Enabled" : "Disabled"; - buttons.get(19).text = options.dmCenterPlayer.value ? "Player" : "Map"; - buttons.get(20).text = options.dmRotatePlayer.value ? "Player" : "Vertical"; - buttons.get(21).text = options.dmPlayerHeads.value <= 0 ? "Default" : options.dmPlayerHeads.value >= 3 ? "SmallHeads" : + buttons.get(18-6).text = options.dmEnable.value ? "Enabled" : "Disabled"; + buttons.get(19-6).text = options.dmCenterPlayer.value ? "Player" : "Map"; + buttons.get(20-6).text = options.dmRotatePlayer.value ? "Player" : "Vertical"; + buttons.get(21-6).text = options.dmPlayerHeads.value <= 0 ? "Default" : options.dmPlayerHeads.value >= 3 ? "SmallHeads" : options.dmPlayerHeads.value == 1 ? "Heads" : "ScaledHeads"; - buttons.get(22).text = options.dmOrientCheck.value ? "Orient" : "Off"; - buttons.get(23).text = options.dmCenterCheck.value ? "Center" : "Off"; - buttons.get(24).text = options.dmPlayerInterp.value ? "Interp" : "No Interp"; - buttons.get(25).text = options.dmCompat.value <= 0 ? "Normal" : options.dmCompat.value >= 2 ? "No FB/SHD" : "No SHD"; + buttons.get(22-6).text = options.dmOrientCheck.value ? "Orient" : "Off"; + buttons.get(23-6).text = options.dmCenterCheck.value ? "Center" : "Off"; + buttons.get(24-6).text = options.dmPlayerInterp.value ? "Interp" : "No Interp"; + buttons.get(25-6).text = options.dmCompat.value <= 0 ? "Normal" : options.dmCompat.value >= 2 ? "No FB/SHD" : "No SHD"; - buttons.get(26).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBackgroundColour.value)); - buttons.get(27).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBorderColour.value)); + buttons.get(26-6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBackgroundColour.value)); + buttons.get(27-6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBorderColour.value)); - buttons.get(28).text = options.dmChromaBorder.value ? "Scroll" : "Normal"; + buttons.get(28-6).text = options.dmChromaBorder.value ? "Scroll" : "Normal"; blurField.setSize(48, 16); xField.setSize(48, 16); yField.setSize(48, 16); blurField.render(guiLeft+20+139, guiTop+181); - xField.render(guiLeft+20+139, guiTop+210); - yField.render(guiLeft+84+139, guiTop+210); + xField.render(guiLeft+20, guiTop+195); + yField.render(guiLeft+84, guiTop+195); Map<String, Vec4b> decorations = new HashMap<>(); Vec4b vec4b = new Vec4b((byte)3, (byte)(((50)-64)*2), (byte)(((40)-64)*2), (byte)((60)*16/360)); @@ -337,7 +344,7 @@ public class GuiDungeonMapEditor extends GuiScreen { GlStateManager.color(1, 1, 1, 1); demoMap.renderMap(guiLeft+357, guiTop+125, NotEnoughUpdates.INSTANCE.colourMap, decorations, 0, - players, false); + players, false, partialTicks); for(Button button : buttons) { button.render(); @@ -481,6 +488,39 @@ public class GuiDungeonMapEditor extends GuiScreen { Utils.pushGuiScale(-1); } + public void drawSlider(Options.Option<Double> option, int centerX, int centerY) { + float sliderAmount = (float)Math.max(0, Math.min(1, (option.value-option.minValue)/(option.maxValue-option.minValue))); + int sliderAmountI = (int)(96*sliderAmount); + + GlStateManager.color(1f, 1f, 1f, 1f); + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_on_large); + Utils.drawTexturedRect(centerX-48, centerY-8, sliderAmountI, 16, + 0, sliderAmount, 0, 1, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_off_large); + Utils.drawTexturedRect(centerX-48+sliderAmountI, centerY-8, 96-sliderAmountI, 16, + sliderAmount, 1, 0, 1, GL11.GL_NEAREST); + + Minecraft.getMinecraft().getTextureManager().bindTexture(slider_button); + Utils.drawTexturedRect(centerX-48+sliderAmountI-4, centerY-8, 8, 16, + 0, 1, 0, 1, GL11.GL_NEAREST); + } + + @Override + protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + + if(clickedSlider != null) { + float sliderAmount = (mouseX - (guiLeft+76-48))/96f; + double val = clickedSlider.minValue+(clickedSlider.maxValue-clickedSlider.minValue)*sliderAmount; + if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) { + val = Math.round(val); + } + clickedSlider.value = Math.max(clickedSlider.minValue, Math.min(clickedSlider.maxValue, val)); + } + + } + @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { for(Button button : buttons) { @@ -495,6 +535,16 @@ public class GuiDungeonMapEditor extends GuiScreen { } } + clickedSlider = null; + if(mouseX >= guiLeft+76-48 && mouseX <= guiLeft+76+48) { + if(mouseY > guiTop+45-8 && mouseY < guiTop+45+8) { + clickedSlider = NotEnoughUpdates.INSTANCE.manager.config.dmBorderSize; + return; + } else if(mouseY > guiTop+75-8 && mouseY < guiTop+75+8) { + clickedSlider = NotEnoughUpdates.INSTANCE.manager.config.dmRoomSize; + return; + } + } if(mouseY > guiTop+181 && mouseY < guiTop+181+16) { if(mouseX > guiLeft+20+139 && mouseX < guiLeft+20+139+48) { @@ -503,13 +553,13 @@ public class GuiDungeonMapEditor extends GuiScreen { yField.otherComponentClick(); return; } - } else if(mouseY > guiTop+210 && mouseY < guiTop+210+16) { - if(mouseX > guiLeft+20+139 && mouseX < guiLeft+20+139+48) { + } else if(mouseY > guiTop+195 && mouseY < guiTop+195+16) { + if(mouseX > guiLeft+20 && mouseX < guiLeft+20+48) { xField.mouseClicked(mouseX, mouseY, mouseButton); yField.otherComponentClick(); blurField.otherComponentClick(); return; - } else if(mouseX > guiLeft+84+139 && mouseX < guiLeft+84+139+48) { + } else if(mouseX > guiLeft+84 && mouseX < guiLeft+84+48) { yField.mouseClicked(mouseX, mouseY, mouseButton); xField.otherComponentClick(); blurField.otherComponentClick(); @@ -836,9 +886,7 @@ public class GuiDungeonMapEditor extends GuiScreen { blurOutputVert.bindFramebufferTexture(); GlStateManager.color(1f, 1f, 1f, 1f); - //Utils.setScreen(width*f, height*f, f); Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax); - //Utils.setScreen(width, height, f); blurOutputVert.unbindFramebufferTexture(); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java index 2290e4a7..ee8282e9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java @@ -102,12 +102,10 @@ public abstract class MixinGuiContainer { public void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType, CallbackInfo ci) { if(slotIn != null && BetterContainers.isOverriding() && (BetterContainers.isBlankStack(slotIn.getStack()) || BetterContainers.isButtonStack(slotIn.getStack()))) { - System.out.println("handling click"); BetterContainers.clickSlot(slotIn.getSlotIndex()); Utils.playPressSound(); if(BetterContainers.isBlankStack(slotIn.getStack())) { - System.out.println("cancelling click"); GuiContainer $this = (GuiContainer)(Object)this; $this.mc.playerController.windowClick($this.inventorySlots.windowId, slotId, 2, clickType, $this.mc.thePlayer); ci.cancel(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java b/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java index 0aedc306..028f9fae 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/Options.java @@ -202,6 +202,21 @@ public class Options { "Enables the auction house which can be found using /neuah.\n" + "Don't enable this option unless you use /neuah\n" + "You *may* need to restart after enabling this for the auctions to download properly", CAT_FEATURES); + public Option<Boolean> eventNotifications = new Option( + true, + "Skyblock Event Notifications", + false, + "Notifies you 5m (default) before and when favourited events (/neucalendar) start.", CAT_FEATURES); + public Option<Boolean> showEventTimerInInventory = new Option( + true, + "Event Timer In Inventory", + false, + "Will show how long until the next event starts at the top of your inventory", CAT_FEATURES); + public Option<Boolean> eventNotificationSounds = new Option( + true, + "Skyblock Event Notification Sounds", + false, + "Will play a sounds whenever a favourited event starts.", CAT_MISC); public Option<Boolean> accessoryBagOverlay = new Option( true, "Accessory Bag Overlay", @@ -262,6 +277,11 @@ public class Options { "Dungeon Victory Screen Millis", false, "Changes how long the victory screen at the end of dungeons appears for. 0 = off", FLAG_INT, 0, 15000, CAT_SLIDERS); + public Option<Double> eventNotificationBeforeSeconds = new Option( + 300.0, + "Event Notification Before Seconds", + false, + "Changes how long before skyblock events will the 'starting in' notification show. 0 = off", FLAG_INT, 0, 1800, CAT_SLIDERS); public Option<String> itemBackgroundColour = new Option( "00:255:100:100:100", @@ -362,6 +382,11 @@ public class Options { "loadedModBefore", true, "loadedModBefore", CAT_ALL); + public Option<Boolean> doRamNotif = new Option( + true, + "doRamNotif", + false, + "doRamNotif", CAT_ALL); public Option<Boolean> customTradePrices = new Option( true, "Trade Item Values", @@ -397,6 +422,11 @@ public class Options { "Favourites", false, "Favourites", CAT_ALL); + public Option<ArrayList<String>> eventFavourites = new Option( + new ArrayList<String>(), + "Event Favourites", + false, + "Event Favourites", CAT_ALL); public Option<Map<String, ArrayList<String>>> collectionLog = new Option( new HashMap<String, ArrayList<String>>(), "CollectionLog", @@ -434,12 +464,12 @@ public class Options { 1.0, "Border Size", false, - "Changes the size of the map border, without changing the size of the contents\nSmall = 90x\nMedium = 120x\nLarge = 160x", CAT_ALL); + "Changes the size of the map border, without changing the size of the contents\nSmall = 90x\nMedium = 120x\nLarge = 160x", 0, 5, CAT_ALL); public Option<Double> dmRoomSize = new Option( 1.0, "Room Size", false, - "Changes the size of rooms. Useful for higher dungeons with larger maps\nSmall = 12x\nMedium = 16x\nLarge = 20x\nXLarge = 24x", CAT_ALL); + "Changes the size of rooms. Useful for higher dungeons with larger maps\nSmall = 12x\nMedium = 16x\nLarge = 20x\nXLarge = 24x", 0, 5, CAT_ALL); public Option<Double> dmBorderStyle = new Option( 0.0, "Border Style", @@ -614,6 +644,9 @@ public class Options { tryAddOption(accessoryBagOverlay, options); tryAddOption(rodColours, options); tryAddOption(neuAuctionHouse, options); + tryAddOption(eventNotifications, options); + tryAddOption(showEventTimerInInventory, options); + tryAddOption(eventNotificationSounds, options); //Sliders tryAddOption(paneGuiScale, options); tryAddOption(smoothAoteMillis, options); @@ -624,6 +657,7 @@ public class Options { tryAddOption(dynamicMenuBackgroundStyle, options); tryAddOption(dynamicMenuButtonStyle, options); tryAddOption(dungeonWinMillis, options); + tryAddOption(eventNotificationBeforeSeconds, options); //Text tryAddOption(apiKey, options); //Colour diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 8e3a5015..dd250d90 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -1934,8 +1934,8 @@ public class GuiProfileViewer extends GuiScreen { if(!rank.equals("YOUTUBER") && !monthlyPackageRank.equals("NONE")) { rank = monthlyPackageRank; } - EnumChatFormatting rankPlusColorECF = EnumChatFormatting.getValueByName(Utils.getElementAsString(profile.getHypixelProfile().get("rankPlusColor"), "WHITE")); - String rankPlusColor = EnumChatFormatting.WHITE.toString(); + EnumChatFormatting rankPlusColorECF = EnumChatFormatting.getValueByName(Utils.getElementAsString(profile.getHypixelProfile().get("rankPlusColor"), "YELLOW")); + String rankPlusColor = EnumChatFormatting.YELLOW.toString(); if(rankPlusColorECF != null) { rankPlusColor = rankPlusColorECF.toString(); } 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 f70d3a3c..d5233bbd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java @@ -4,12 +4,28 @@ import com.google.gson.JsonObject; public class Constants { - public static final JsonObject BONUSES = Utils.getConstant("bonuses"); - public static final JsonObject DISABLE = Utils.getConstant("disable"); - public static final JsonObject ENCHANTS = Utils.getConstant("enchants"); - public static final JsonObject LEVELING = Utils.getConstant("leveling"); - public static final JsonObject MISC = Utils.getConstant("misc"); - public static final JsonObject PETNUMS = Utils.getConstant("petnums"); - public static final JsonObject PETS = Utils.getConstant("pets"); + public static JsonObject BONUSES; + public static JsonObject DISABLE; + public static JsonObject ENCHANTS; + public static JsonObject LEVELING; + public static JsonObject MISC; + public static JsonObject PETNUMS; + public static JsonObject PETS; + public static JsonObject PARENTS; + + public static void reload() { + BONUSES = Utils.getConstant("bonuses"); + DISABLE = Utils.getConstant("disable"); + ENCHANTS = Utils.getConstant("enchants"); + LEVELING = Utils.getConstant("leveling"); + MISC = Utils.getConstant("misc"); + PETNUMS = Utils.getConstant("petnums"); + PETS = Utils.getConstant("pets"); + PARENTS = Utils.getConstant("parents"); + } + + static { + reload(); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java index 2e6b29da..db630b84 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java @@ -23,8 +23,11 @@ public class HypixelApi { private Gson gson = new Gson(); private ExecutorService es = Executors.newFixedThreadPool(3); - private int myApiErrors = 0; - private String[] myApiURLs = {"https://moulberry.codes/", "http://51.75.78.252/", "http://moulberry.codes/" }; + private static final int FAILS_BEFORE_SWITCH = 3; + private int currentUrl = 0; + private long lastPrimaryUrl = 0; + private final String[] myApiURLs = {"https://moulberry.codes/", "http://51.79.51.21/", "http://moulberry.codes/", "http://51.75.78.252/" }; + private final Integer[] myApiSuccesses = {0, 0, 0, 0}; public void getHypixelApiAsync(String apiKey, String method, HashMap<String, String> args, Consumer<JsonObject> consumer) { getHypixelApiAsync(apiKey, method, args, consumer, () -> {}); @@ -35,7 +38,29 @@ public class HypixelApi { } private String getMyApiURL() { - return myApiURLs[myApiErrors%myApiURLs.length]; + if(currentUrl == 0) { + lastPrimaryUrl = System.currentTimeMillis(); + } else if(System.currentTimeMillis() - lastPrimaryUrl > 1000*60*30) { //Try switch back to main url after 30m + currentUrl = 0; + } + + myApiSuccesses[currentUrl] = Math.min(FAILS_BEFORE_SWITCH, myApiSuccesses[currentUrl] + 1); + return myApiURLs[currentUrl]; + } + + private void myApiError(int index) { + myApiSuccesses[index] = myApiSuccesses[index] - 2; + + if(myApiSuccesses[index] < 0) { + myApiSuccesses[index] = 0; + + if(index == currentUrl) { + currentUrl++; + if(currentUrl >= myApiURLs.length) { + currentUrl = 0; + } + } + } } public void getApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { @@ -50,10 +75,11 @@ public class HypixelApi { public void getMyApiAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { es.submit(() -> { + int current = currentUrl; try { consumer.accept(getApiSync(getMyApiURL()+urlS)); } catch(Exception e) { - myApiErrors++; + myApiError(current); error.run(); } }); @@ -61,10 +87,11 @@ public class HypixelApi { public void getMyApiGZIPAsync(String urlS, Consumer<JsonObject> consumer, Runnable error) { es.submit(() -> { + int current = currentUrl; try { consumer.accept(getApiGZIPSync(getMyApiURL()+urlS)); } catch(Exception e) { - myApiErrors++; + myApiError(current); error.run(); } }); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index e2faa5aa..667128b9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -479,9 +479,40 @@ public class Utils { } public static void drawStringF(String str, FontRenderer fr, float x, float y, boolean shadow, int colour) { - GL11.glTranslatef(x, y, 0); - fr.drawString(str, 0, 0, colour, shadow); - GL11.glTranslatef(-x, -y, 0); + fr.drawString(str, x, y, colour, shadow); + } + + public static int getCharVertLen(char c) { + if("acegmnopqrsuvwxyz".indexOf(c) >= 0) { + return 5; + } else { + return 7; + } + } + + public static float getVerticalHeight(String str) { + str = cleanColour(str); + float height = 0; + for(int i=0; i<str.length(); i++) { + char c = str.charAt(i); + int charHeight = getCharVertLen(c); + height += charHeight + 1.5f; + } + return height; + } + + public static void drawStringVertical(String str, FontRenderer fr, float x, float y, boolean shadow, int colour) { + String format = FontRenderer.getFormatFromString(str); + str = cleanColour(str); + for(int i=0; i<str.length(); i++) { + char c = str.charAt(i); + + int charHeight = getCharVertLen(c); + int charWidth = fr.getCharWidth(c); + fr.drawString(format+c, x+(5-charWidth)/2f, y-7+charHeight, colour, shadow); + + y += charHeight + 1.5f; + } } public static void drawStringScaledMaxWidth(String str, FontRenderer fr, float x, float y, boolean shadow, int len, int colour) { |