diff options
Diffstat (limited to 'src/main')
48 files changed, 2505 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) { |
