diff options
Diffstat (limited to 'src/main/java/de/cowtipper')
6 files changed, 356 insertions, 28 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java index d47617a..91d1932 100644 --- a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java +++ b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java @@ -5,6 +5,7 @@ import de.cowtipper.cowlection.Cowlection; import de.cowtipper.cowlection.command.exception.ApiContactException; import de.cowtipper.cowlection.command.exception.InvalidPlayerNameException; import de.cowtipper.cowlection.command.exception.MooCommandException; +import de.cowtipper.cowlection.config.DungeonOverlayGuiConfig; import de.cowtipper.cowlection.config.MooConfig; import de.cowtipper.cowlection.config.MooGuiConfig; import de.cowtipper.cowlection.data.*; @@ -150,13 +151,19 @@ public class MooCommand extends CommandBase { .append(EnumChatFormatting.RED).append("Unknown minion ").append(EnumChatFormatting.YELLOW).append("(new or with minion skin) ").append(tierColor).append(minionTier); }); main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, analysisResults.toString()); - } else if (args[0].equalsIgnoreCase("deaths")) { + } else if (args[0].equalsIgnoreCase("dungeon") || args[0].equalsIgnoreCase("dung")) { DungeonCache dungeonCache = main.getDungeonCache(); - if (dungeonCache.isInDungeon()) { - dungeonCache.sendDeathCounts(); + if (args.length == 2 && args[1].equalsIgnoreCase("gui")) { + // edit dungeon gui + new TickDelay(() -> Minecraft.getMinecraft().displayGuiScreen(new DungeonOverlayGuiConfig(main)), 1); // delay by 1 tick, because the chat closing would close the new gui instantly as well. + } else if (dungeonCache.isInDungeon()) { + dungeonCache.sendDungeonPerformance(); } else { - throw new MooCommandException(EnumChatFormatting.DARK_RED + "Looks like you're not in a dungeon..."); + throw new MooCommandException(EnumChatFormatting.DARK_RED + "Looks like you're not in a dungeon... However, you can edit the Dungeon Performance overlay with " + EnumChatFormatting.RED + "/" + getCommandName() + " dungeon gui"); } + } else if (args[0].equalsIgnoreCase("dungeonGui") || args[0].equalsIgnoreCase("guiDungeon") + || args[0].equalsIgnoreCase("guiDung") || args[0].equalsIgnoreCase("dungGui")) { + new TickDelay(() -> Minecraft.getMinecraft().displayGuiScreen(new DungeonOverlayGuiConfig(main)), 1); // delay by 1 tick, because the chat closing would close the new gui instantly as well. } else if (args[0].equalsIgnoreCase("add")) { handleBestFriendAdd(args); } else if (args[0].equalsIgnoreCase("remove")) { @@ -524,7 +531,6 @@ public class MooCommand extends CommandBase { } else if (main.getFriendsHandler().getBestFriends().size() >= 100) { throw new MooCommandException(EnumChatFormatting.RED + "The best friends list is limited to 100 players. Remove some with " + EnumChatFormatting.WHITE + "/" + getCommandName() + " remove <name> " + EnumChatFormatting.RED + "first"); } else { - // TODO Add check if 'best friend' is on normal friend list main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, "Fetching " + EnumChatFormatting.YELLOW + args[1] + EnumChatFormatting.GOLD + "'s unique user id. This may take a few seconds..."); // add friend async main.getFriendsHandler().addBestFriend(args[1]); @@ -594,7 +600,8 @@ public class MooCommand extends CommandBase { .appendSibling(createCmdHelpEntry("stalk", "Get info of player's status")) .appendSibling(createCmdHelpEntry("stalkskyblock", "Get info of player's SkyBlock stats")) .appendSibling(createCmdHelpEntry("analyzeIsland", "Analyze a SkyBlock private island")) - .appendSibling(createCmdHelpEntry("deaths", "SkyBlock Dungeons: death counts")) + .appendSibling(createCmdHelpEntry("dungeon", "SkyBlock Dungeons: display current dungeon performance")) + .appendSibling(createCmdHelpEntry("dungeonGui", "SkyBlock Dungeons: edit dungeon performance GUI")) .appendSibling(createCmdHelpEntry("add", "Add best friends")) .appendSibling(createCmdHelpEntry("remove", "Remove best friends")) .appendSibling(createCmdHelpEntry("list", "View list of best friends")) @@ -635,7 +642,7 @@ public class MooCommand extends CommandBase { public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { if (args.length == 1) { return getListOfStringsMatchingLastWord(args, - /* friends & other players */ "stalk", "askPolitelyWhereTheyAre", "stalkskyblock", "skyblockstalk", "askPolitelyAboutTheirSkyBlockProgress", "analyzeIsland", "deaths", "add", "remove", "list", "online", "nameChangeCheck", "toggle", + /* friends & other players */ "stalk", "askPolitelyWhereTheyAre", "stalkskyblock", "skyblockstalk", "askPolitelyAboutTheirSkyBlockProgress", "analyzeIsland", "dungeon", "dungeonGui", "guiDungeon", "add", "remove", "list", "online", "nameChangeCheck", "toggle", /* miscellaneous */ "config", "search", "guiscale", "rr", "shrug", "apikey", /* update mod */ "update", "updateHelp", "version", "directory", /* help */ "help"); diff --git a/src/main/java/de/cowtipper/cowlection/config/DungeonOverlayGuiConfig.java b/src/main/java/de/cowtipper/cowlection/config/DungeonOverlayGuiConfig.java new file mode 100644 index 0000000..18478f5 --- /dev/null +++ b/src/main/java/de/cowtipper/cowlection/config/DungeonOverlayGuiConfig.java @@ -0,0 +1,129 @@ +package de.cowtipper.cowlection.config; + +import de.cowtipper.cowlection.Cowlection; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.EnumChatFormatting; +import net.minecraftforge.fml.client.config.GuiButtonExt; +import net.minecraftforge.fml.client.config.GuiCheckBox; +import net.minecraftforge.fml.client.config.GuiSlider; +import org.apache.commons.lang3.StringUtils; +import org.lwjgl.input.Keyboard; + +import java.io.IOException; + +public class DungeonOverlayGuiConfig extends GuiScreen { + private final Cowlection main; + private GuiCheckBox checkBoxShowOverlay; + private GuiSlider sliderX; + private GuiSlider sliderY; + private GuiSlider sliderGuiScale; + private GuiButtonExt buttonCancel; + private GuiButtonExt buttonSave; + private final boolean wasDungOverlayEnabled; + private final int previousPositionX; + private final int previousPositionY; + private final int previousGuiScale; + + public DungeonOverlayGuiConfig(Cowlection main) { + this.main = main; + wasDungOverlayEnabled = MooConfig.dungOverlayEnabled; + previousPositionX = MooConfig.dungOverlayPositionX; + previousPositionY = MooConfig.dungOverlayPositionY; + previousGuiScale = MooConfig.dungOverlayGuiScale; + } + + @Override + public void initGui() { + int maxX = this.width - fontRendererObj.getStringWidth(StringUtils.repeat('#', 15)); + int maxY = this.height - fontRendererObj.FONT_HEIGHT * 5; // 5 = max lines output + int startX = Math.min(maxX, this.previousPositionX); + int startY = Math.min(maxY, this.previousPositionY); + + this.buttonList.add(this.checkBoxShowOverlay = new GuiCheckBox(30, this.width / 2 - 50, this.height / 2 - 30, " Show overlay", MooConfig.dungOverlayEnabled)); + this.buttonList.add(sliderX = new GuiSlider(20, this.width / 2 - 150, this.height / 2 - 12, 300, 20, "x = ", "", 0, maxX, startX, false, true)); + this.buttonList.add(sliderY = new GuiSlider(21, this.width / 2 - 150, this.height / 2 + 12, 300, 20, "y = ", "", 0, maxY, startY, false, true)); + this.buttonList.add(sliderGuiScale = new GuiSlider(22, this.width / 2 - 100, this.height / 2 + 37, 200, 20, "GUI scale: ", "%", 50, 200, MooConfig.dungOverlayGuiScale, false, true)); + this.buttonList.add(this.buttonCancel = new GuiButtonExt(31, this.width / 2 - 150, this.height / 2 + 65, 80, 20, EnumChatFormatting.RED + "Cancel")); + this.buttonList.add(this.buttonSave = new GuiButtonExt(32, this.width / 2 + 70, this.height / 2 + 65, 80, 20, EnumChatFormatting.GREEN + "Save")); + if (!MooConfig.dungOverlayEnabled) { + sliderX.enabled = false; + sliderY.enabled = false; + sliderGuiScale.enabled = false; + } + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + // draw background + int padding = 20; + this.drawGradientRect(this.width / 2 - 150 - padding, this.height / 2 - 40 - fontRendererObj.FONT_HEIGHT - padding, + this.width / 2 + 150 + padding, this.height / 2 + 65 + 20 + fontRendererObj.FONT_HEIGHT + padding, + -1072689136, -804253680); + + // draw gui elements + String title = "Dungeon Performance Overlay Settings"; + this.drawCenteredString(this.fontRendererObj, EnumChatFormatting.BOLD + title, this.width / 2, this.height / 2 - 40 - fontRendererObj.FONT_HEIGHT, 0x00ffffff); + + GlStateManager.pushMatrix(); + float scaleFactor = 0.75f; + GlStateManager.scale(scaleFactor, scaleFactor, 0); + String hint = "(" + EnumChatFormatting.GOLD + EnumChatFormatting.ITALIC + "Note: " + EnumChatFormatting.RESET + "Destroyed Crypts can only be detected up to ~50 blocks away from the player)"; + this.drawCenteredString(this.fontRendererObj, hint, (int) ((this.width / 2) * (1 / scaleFactor)), (int) ((this.height / 2 + 95) * (1 / scaleFactor)), 0x00cccccc); + GlStateManager.popMatrix(); + + super.drawScreen(mouseX, mouseY, partialTicks); + + if (checkBoxShowOverlay.enabled) { + MooConfig.dungOverlayPositionX = sliderX.getValueInt(); + MooConfig.dungOverlayPositionY = sliderY.getValueInt(); + MooConfig.dungOverlayGuiScale = sliderGuiScale.getValueInt(); + } + } + + @Override + protected void keyTyped(char typedChar, int keyCode) throws IOException { + if (keyCode == Keyboard.KEY_ESCAPE) { + resetDungeonOverlayPosition(); + } + super.keyTyped(typedChar, keyCode); + } + + @Override + protected void actionPerformed(GuiButton button) throws IOException { + if (button == buttonCancel) { + resetDungeonOverlayPosition(); + closeGui(); + } else if (button == buttonSave) { + if (wasDungOverlayEnabled != checkBoxShowOverlay.isChecked() || previousPositionX != sliderX.getValueInt() || previousPositionY != sliderY.getValueInt() || previousGuiScale != sliderGuiScale.getValueInt()) { + main.getConfig().syncFromFields(); + if (wasDungOverlayEnabled != checkBoxShowOverlay.isChecked()) { + main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "The dungeon performance overlay is now " + (checkBoxShowOverlay.isChecked() ? EnumChatFormatting.DARK_GREEN + "enabled" : EnumChatFormatting.DARK_RED + "disabled")); + } else { + main.getChatHelper().sendMessage(EnumChatFormatting.GREEN, "Saved new size and position of the dungeon performance overlay!"); + } + } + closeGui(); + } else if (button == checkBoxShowOverlay) { + sliderX.enabled = checkBoxShowOverlay.isChecked(); + sliderY.enabled = checkBoxShowOverlay.isChecked(); + sliderGuiScale.enabled = checkBoxShowOverlay.isChecked(); + MooConfig.dungOverlayEnabled = checkBoxShowOverlay.isChecked(); + } + } + + private void resetDungeonOverlayPosition() { + MooConfig.dungOverlayEnabled = wasDungOverlayEnabled; + MooConfig.dungOverlayPositionX = previousPositionX; + MooConfig.dungOverlayPositionY = previousPositionY; + MooConfig.dungOverlayGuiScale = previousGuiScale; + } + + private void closeGui() { + this.mc.displayGuiScreen(null); + if (this.mc.currentScreen == null) { + this.mc.setIngameFocus(); + } + } +} diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java index 9cbe1b9..628850b 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java @@ -46,6 +46,10 @@ public class MooConfig { public static int[] dungClassRange; public static boolean dungFilterPartiesWithDupes; public static String dungItemQualityPos; + public static boolean dungOverlayEnabled; + public static int dungOverlayGuiScale; + public static int dungOverlayPositionX; + public static int dungOverlayPositionY; // logs search config public static String[] logsDirs; private static String defaultStartDate; @@ -153,7 +157,14 @@ public class MooConfig { "dungFilterPartiesWithDupes", false, "Mark parties with duplicated classes?"), true); Property propDungItemQualityPos = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, "dungItemQualityPos", "top", "Position of item quality in tooltip", new String[]{"top", "bottom"}), true); - + Property propDungOverlayEnabled = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, + "dungOverlayEnabled", true, "Enable Dungeon performance overlay?"), false); + Property propDungOverlayPositionX = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, + "dungGuiPositionX", 5, "Dungeon performance overlay position: x value", -1, 10000), false); + Property propDungOverlayPositionY = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, + "dungGuiPositionY", 5, "Dungeon performance overlay position: y value", -1, 5000), false); + Property propDungOverlayGuiScale = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT, + "dungOverlayGuiScale", 100, "Dungeon performance overlay GUI scale", 50, 200), false); cfg.setCategoryPropertyOrder(Configuration.CATEGORY_CLIENT, propOrderGeneral); // config section: log files search @@ -187,6 +198,10 @@ public class MooConfig { dungClassRange = propDungClassRange.getIntList(); dungFilterPartiesWithDupes = propDungFilterPartiesWithDupes.getBoolean(); dungItemQualityPos = propDungItemQualityPos.getString(); + dungOverlayEnabled = propDungOverlayEnabled.getBoolean(); + dungOverlayPositionX = propDungOverlayPositionX.getInt(); + dungOverlayPositionY = propDungOverlayPositionY.getInt(); + dungOverlayGuiScale = propDungOverlayGuiScale.getInt(); // logs search config logsDirs = propLogsDirs.getStringList(); @@ -212,6 +227,10 @@ public class MooConfig { propDungClassRange.set(dungClassRange); propDungFilterPartiesWithDupes.set(dungFilterPartiesWithDupes); propDungItemQualityPos.set(dungItemQualityPos); + propDungOverlayEnabled.set(dungOverlayEnabled); + propDungOverlayPositionX.set(dungOverlayPositionX); + propDungOverlayPositionY.set(dungOverlayPositionY); + propDungOverlayGuiScale.set(dungOverlayGuiScale); // logs search config propLogsDirs.set(logsDirs); diff --git a/src/main/java/de/cowtipper/cowlection/config/MooGuiConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooGuiConfig.java index 3c650b8..3db7cf3 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooGuiConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooGuiConfig.java @@ -2,7 +2,6 @@ package de.cowtipper.cowlection.config; import de.cowtipper.cowlection.Cowlection; import de.cowtipper.cowlection.search.GuiTooltip; -import de.cowtipper.cowlection.util.Utils; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; @@ -31,7 +30,7 @@ public class MooGuiConfig extends GuiConfig { false, false, EnumChatFormatting.BOLD + "Configuration for " + Cowlection.MODNAME); - titleLine2 = EnumChatFormatting.GRAY + Utils.toRealPath(MooConfig.getConfig().getConfigFile()); + titleLine2 = EnumChatFormatting.GRAY + GuiConfig.getAbridgedConfigPath(MooConfig.getConfig().toString()); } private static List<IConfigElement> getConfigElements() { diff --git a/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java b/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java index 7cef4cd..5c868c9 100644 --- a/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java +++ b/src/main/java/de/cowtipper/cowlection/handler/DungeonCache.java @@ -2,51 +2,148 @@ package de.cowtipper.cowlection.handler; import de.cowtipper.cowlection.Cowlection; import de.cowtipper.cowlection.util.TickDelay; +import net.minecraft.client.Minecraft; +import net.minecraft.scoreboard.Score; +import net.minecraft.scoreboard.ScoreObjective; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.EnumChatFormatting; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; public class DungeonCache { - private boolean isInDungeon; - private final Map<String, Integer> deathCounter; private final Cowlection main; + private final Map<String, Integer> deathCounter; + private final Set<String> failedPuzzles; + private final Set<UUID> destroyedCrypts; + + private boolean isInDungeon; + private int elapsedMinutes; + private long lastScoreboardCheck; public DungeonCache(Cowlection main) { this.main = main; deathCounter = new HashMap<>(); + failedPuzzles = new HashSet<>(); + destroyedCrypts = new HashSet<>(); + } + + public boolean isInDungeon() { + return isInDungeon; } public void onDungeonEntered() { isInDungeon = true; - deathCounter.clear(); + resetCounters(); } public void onDungeonLeft() { isInDungeon = false; - deathCounter.clear(); + resetCounters(); + } + + public void sendDungeonPerformance() { + String dungeonPerformance; + boolean hasPointPenalty = false; + if (deathCounter.isEmpty()) { + dungeonPerformance = EnumChatFormatting.GOLD + "☠ Deaths: " + EnumChatFormatting.WHITE + "none \\o/"; + } else { + hasPointPenalty = true; + String deaths = deathCounter.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(deathEntry -> " " + EnumChatFormatting.WHITE + deathEntry.getKey() + ": " + EnumChatFormatting.LIGHT_PURPLE + deathEntry.getValue()) + .collect(Collectors.joining("\n")); + dungeonPerformance = EnumChatFormatting.RED + "☠ " + EnumChatFormatting.BOLD + "Deaths: " + EnumChatFormatting.DARK_RED + "-" + (getTotalDeaths() * 2) + " Skill points\n" + deaths; + } + if (failedPuzzles.size() > 0) { + hasPointPenalty = true; + dungeonPerformance += "\n" + EnumChatFormatting.RED + "Failed puzzles: " + EnumChatFormatting.LIGHT_PURPLE + failedPuzzles.size() + EnumChatFormatting.RED + " (" + EnumChatFormatting.DARK_RED + "-" + failedPuzzles.size() * 14 + " Skill points" + EnumChatFormatting.RED + ")"; + } + + if (hasPointPenalty) { + dungeonPerformance += "\n" + EnumChatFormatting.LIGHT_PURPLE + "➜ " + EnumChatFormatting.RED + EnumChatFormatting.BOLD + "Skill " + EnumChatFormatting.RED + "score penalty: " + EnumChatFormatting.DARK_RED + getSkillScorePenalty() + " points"; + } + main.getChatHelper().sendMessage(EnumChatFormatting.WHITE, dungeonPerformance); + } + + public void updateElapsedMinutesFromScoreboard() { + long now = System.currentTimeMillis(); + if (now - lastScoreboardCheck > 10000) { // run every 10 seconds + lastScoreboardCheck = now; + Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); + ScoreObjective scoreboardSidebar = scoreboard.getObjectiveInDisplaySlot(1); + if (scoreboardSidebar != null) { + Collection<Score> scoreboardLines = scoreboard.getSortedScores(scoreboardSidebar); + for (Score line : scoreboardLines) { + ScorePlayerTeam scorePlayerTeam = scoreboard.getPlayersTeam(line.getPlayerName()); + if (scorePlayerTeam != null) { + String lineWithoutFormatting = EnumChatFormatting.getTextWithoutFormattingCodes(scorePlayerTeam.getColorPrefix() + scorePlayerTeam.getColorSuffix()); + + if (lineWithoutFormatting.startsWith("Time Elapsed:")) { + // dungeon timer: 05m22s + String timeString = lineWithoutFormatting.substring(lineWithoutFormatting.lastIndexOf(' ') + 1); + try { + elapsedMinutes = (Integer.parseInt(timeString.substring(0, timeString.indexOf('m')))); + } catch (NumberFormatException ex) { + // couldn't parse dungeon time from scoreboard + ex.printStackTrace(); + } + } + } + } + } + } } + // setter/adder public void addDeath(String playerName) { int previousPlayerDeaths = deathCounter.getOrDefault(playerName, 0); deathCounter.put(playerName, previousPlayerDeaths + 1); - new TickDelay(this::sendDeathCounts, 1); + new TickDelay(this::sendDungeonPerformance, 1); } - public boolean isInDungeon() { - return isInDungeon; + public void addFailedPuzzle(String text) { + failedPuzzles.add(text); } - public void sendDeathCounts() { - if (deathCounter.isEmpty()) { - main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, "☠ Deaths: " + EnumChatFormatting.WHITE + "none \\o/"); - } else { - String deaths = deathCounter.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(deathEntry -> " " + EnumChatFormatting.WHITE + deathEntry.getKey() + ": " + EnumChatFormatting.LIGHT_PURPLE + deathEntry.getValue()) - .collect(Collectors.joining("\n")); - main.getChatHelper().sendMessage(EnumChatFormatting.RED, "☠ " + EnumChatFormatting.BOLD + "Deaths:\n" + deaths); + public boolean addDestroyedCrypt(UUID uuid) { + return destroyedCrypts.add(uuid); + } + + // getter + public int getMaxSkillScore() { + return 100 - getSkillScorePenalty(); + } + + private int getSkillScorePenalty() { + return getTotalDeaths() * 2 + failedPuzzles.size() * 14; + } + + public int getTotalDeaths() { + int totalDeaths = 0; + for (int deathCount : deathCounter.values()) { + totalDeaths += deathCount; } + return totalDeaths; + } + + public int getFailedPuzzles() { + return failedPuzzles.size(); + } + + public int getDestroyedCrypts() { + return destroyedCrypts.size(); + } + + public int getElapsedMinutes() { + return elapsedMinutes; + } + + // resetter + private void resetCounters() { + deathCounter.clear(); + failedPuzzles.clear(); + destroyedCrypts.clear(); + elapsedMinutes = 0; } } diff --git a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java index 02d221e..8ba2354 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java @@ -1,9 +1,12 @@ package de.cowtipper.cowlection.listener.skyblock; import de.cowtipper.cowlection.Cowlection; +import de.cowtipper.cowlection.config.DungeonOverlayGuiConfig; import de.cowtipper.cowlection.config.MooConfig; +import de.cowtipper.cowlection.handler.DungeonCache; import de.cowtipper.cowlection.util.TickDelay; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.Container; @@ -20,11 +23,14 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.MathHelper; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.common.util.Constants; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.PlayerSetSpawnEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; import org.apache.commons.lang3.StringUtils; import org.lwjgl.input.Keyboard; @@ -363,6 +369,7 @@ public class DungeonsListener { String lineWithoutFormatting = EnumChatFormatting.getTextWithoutFormattingCodes(scorePlayerTeam.getColorPrefix() + scorePlayerTeam.getColorSuffix()); if (lineWithoutFormatting.startsWith(" ⏣")) { + // current location: dungeon or outside? boolean isInDungeonNow = lineWithoutFormatting.startsWith(" ⏣ The Catacombs"); if (!wasInDungeon && isInDungeonNow) { @@ -392,7 +399,77 @@ public class DungeonsListener { main.getDungeonCache().addDeath(playerName); } else if (text.trim().equals("> EXTRA STATS <")) { // dungeon "end screen" - new TickDelay(() -> main.getDungeonCache().sendDeathCounts(), 5); + new TickDelay(() -> main.getDungeonCache().sendDungeonPerformance(), 5); + } else if (text.startsWith("PUZZLE FAIL!")) { + // Skill: failed puzzle + main.getDungeonCache().addFailedPuzzle(text); + } + } + } + + + @SubscribeEvent + public void onPlayerTick(TickEvent.PlayerTickEvent e) { + if (e.phase != TickEvent.Phase.END && e.side != Side.CLIENT && e.type != TickEvent.Type.PLAYER) { + return; + } + if ("Crypt Undead".equals(e.player.getName())) { + boolean isNewDestroyedCrypt = main.getDungeonCache().addDestroyedCrypt(e.player.getUniqueID()); + if (isNewDestroyedCrypt) { + main.getLogger().info("[Dungeon Bonus Score] Crypt Undead spawned @ " + e.player.getPosition() + " - distance to player: " + Math.sqrt(e.player.getPosition().distanceSq(Minecraft.getMinecraft().thePlayer.getPosition()))); + } + } + } + + @SubscribeEvent + public void onRenderGameOverlay(RenderGameOverlayEvent.Post e) { + if (e.type == RenderGameOverlayEvent.ElementType.EXPERIENCE) { + DungeonCache dungeonCache = main.getDungeonCache(); + + if (dungeonCache.isInDungeon()) { + dungeonCache.updateElapsedMinutesFromScoreboard(); + } + + boolean isConfigGui = Minecraft.getMinecraft().currentScreen instanceof DungeonOverlayGuiConfig; + if (MooConfig.dungOverlayEnabled && dungeonCache.isInDungeon() || isConfigGui) { + ArrayList<String> dungeonPerformanceEntries = new ArrayList<>(); + int maxSkillScore = dungeonCache.getMaxSkillScore(); + int totalDeaths = dungeonCache.getTotalDeaths(); + int failedPuzzles = dungeonCache.getFailedPuzzles(); + int destroyedCrypts = dungeonCache.getDestroyedCrypts(); + int elapsedMinutes = dungeonCache.getElapsedMinutes(); + + dungeonPerformanceEntries.add("Max Skill score: " + (maxSkillScore == 100 ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) + maxSkillScore + " / 100"); + if (totalDeaths > 0 || isConfigGui) { + dungeonPerformanceEntries.add(" Deaths: " + EnumChatFormatting.RED + totalDeaths); + } + if (failedPuzzles > 0 || isConfigGui) { + dungeonPerformanceEntries.add(" Failed Puzzles: " + EnumChatFormatting.RED + failedPuzzles); + } + dungeonPerformanceEntries.add("Destroyed Crypts: " + (destroyedCrypts >= 5 ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) + destroyedCrypts + " / 5"); + EnumChatFormatting color = EnumChatFormatting.GREEN; + if (elapsedMinutes > 20) { + color = EnumChatFormatting.DARK_RED; + } else if (elapsedMinutes > 18) { + color = EnumChatFormatting.RED; + } else if (elapsedMinutes > 15) { + color = EnumChatFormatting.YELLOW; + } + dungeonPerformanceEntries.add("Elapsed Minutes: " + color + elapsedMinutes + (elapsedMinutes > 15 && elapsedMinutes <= 20 ? EnumChatFormatting.RED + " (> 20 mins = point penalty)" : "")); + if (elapsedMinutes > 20) { + dungeonPerformanceEntries.add(EnumChatFormatting.GOLD + " Time penalty: " + EnumChatFormatting.RED + ((int) (2.2 * (elapsedMinutes - 20))) + " points"); + } + + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRendererObj; + GlStateManager.pushMatrix(); + float scaleFactor = MooConfig.dungOverlayGuiScale / 100f; + GlStateManager.scale(scaleFactor, scaleFactor, 0); + for (int line = 0; line < dungeonPerformanceEntries.size(); line++) { + String dungeonPerformanceEntry = dungeonPerformanceEntries.get(line); + int yPos = MooConfig.dungOverlayPositionY + fontRenderer.FONT_HEIGHT * line + 2; + fontRenderer.drawString(dungeonPerformanceEntry, MooConfig.dungOverlayPositionX, yPos, 0xffFFAA00); + } + GlStateManager.popMatrix(); } } } |