diff options
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java')
-rw-r--r-- | src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java | 1460 |
1 files changed, 1460 insertions, 0 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java new file mode 100644 index 00000000..c54a0218 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/CalendarOverlay.java @@ -0,0 +1,1460 @@ +package io.github.moulberry.notenoughupdates.miscgui; + +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.NotEnoughUpdates; +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.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.util.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 boolean drawTimerForeground = false; + + private static long spookyStart = 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.config.calendar.eventNotificationSounds) { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create( + new ResourceLocation("notenoughupdates:calendar_notif_jingle") + )); + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create( + new ResourceLocation("notenoughupdates:calendar_notif_in") + )); + } + jingleIndex = -15*20; + } else if(jingleIndex >= 1) { + if (NotEnoughUpdates.INSTANCE.config.calendar.eventNotificationSounds) { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create( + new ResourceLocation("notenoughupdates:calendar_notif_in") + )); + } + jingleIndex = -15*20; + } else if(jingleIndex < -1) { + jingleIndex++; + } + if(jingleIndex == -20*6-10) { + if(NotEnoughUpdates.INSTANCE.config.calendar.eventNotificationSounds) { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create( + new ResourceLocation("notenoughupdates:calendar_notif_out") + )); + } + } + + 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.config.calendar.showEventTimerInInventory && + 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.config.hidden.eventFavourites; + 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); + } + } + } 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.config.hidden.eventFavourites; + 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); + } + } + } 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.config.hidden.eventFavourites; + if (eventFavourites.contains(id)) { + eventFavourites.remove(id); + } else { + eventFavourites.add(id); + } + } + } + } + } + } + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onGuiDraw(RenderGameOverlayEvent.Post event) { + if(NotEnoughUpdates.INSTANCE.config.calendar.eventNotifications && + 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.config.hidden.eventFavourites; + + //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.config.calendar.eventNotifications) { + return false; + } + + long currentTime = System.currentTimeMillis(); + if(currentTime - spookyStart > 0 && currentTime - spookyStart < HOUR && + NotEnoughUpdates.INSTANCE.config.calendar.spookyNightNotification) { + long delta = (currentTime - SKYBLOCK_START) % (20*MINUTE) - 19*50*SECOND - 10*SECOND; + if(delta < 500 && delta > -8500) { + event = new SBEvent("spooky_festival_7pm", "Spooky Festival 7pm", new ItemStack(Items.bone), null); + timeUntil = delta; + } + } + + 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.config.calendar.startingSoonTime; + + 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 onGuiScreenDrawTimer(GuiScreenEvent.BackgroundDrawnEvent event) { + blurBackground(); + if(!drawTimerForeground) { + drawTimer(); + } + GlStateManager.color(1, 1, 1, 1); + GlStateManager.enableBlend(); + } + + @SubscribeEvent + public void onGuiScreenDrawTimer(GuiScreenEvent.DrawScreenEvent.Post event) { + if(drawTimerForeground) { + drawTimer(); + } + } + + public void drawTimer() { + 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.config.hidden.eventFavourites; + + 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(sbEvent.id.equals("spooky_festival")) { + if(sbEvents.getKey() > currentTime-HOUR && (sbEvents.getKey() < spookyStart || spookyStart == 0)) { + spookyStart = sbEvents.getKey(); + } + } + + 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.config.calendar.showEventTimerInInventory) { + List<String> tooltipToDisplay = null; + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.disableFog(); + GlStateManager.disableLighting(); + GlStateManager.disableColorMaterial(); + + 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)); + } + } + + + } + } + + drawTimerForeground = false; + if(tooltipToDisplay != null) { + drawTimerForeground = true; + GlStateManager.translate(0, 0, 100); + Utils.drawHoveringText(tooltipToDisplay, mouseX, Math.max(17, mouseY), width, height, -1, fr); + GlStateManager.translate(0, 0, -100); + } + } + } + } + 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); + + 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.config.hidden.eventFavourites; + + //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(sbEvent.id.equals("spooky_festival")) { + if(sbEvents.getKey() > currentTime-HOUR && (sbEvents.getKey() < spookyStart || spookyStart == 0)) { + spookyStart = sbEvents.getKey(); + } + } + + 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.config.hidden.eventFavourites.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.config.hidden.eventFavourites.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; + + GlStateManager.depthMask(false); + blurOutputVert.bindFramebufferTexture(); + GlStateManager.color(1f, 1f, 1f, 1f); + Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax); + blurOutputVert.unbindFramebufferTexture(); + GlStateManager.depthMask(true); + } + +} |