diff options
7 files changed, 153 insertions, 80 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f39611..41fd013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Disabled `M` keybinding in MC Options > Controls > Cowlection by default to avoid conflicts - `/moo config` sub-category explanations now default to "tooltip *without* darkened background", as the darkened background was more irritating than helpful - MC Log file search now skips large files to prevent huge log files from blocking the search +- Dungeon Party Finder: Each dungeon class can now also be blocked or blocked if duplicated (= red party background) ### Fixed - 'Show Dungeon item base stats' feature now works with HPB'd items and master stars diff --git a/src/main/java/de/cowtipper/cowlection/Cowlection.java b/src/main/java/de/cowtipper/cowlection/Cowlection.java index 3709172..fad3338 100644 --- a/src/main/java/de/cowtipper/cowlection/Cowlection.java +++ b/src/main/java/de/cowtipper/cowlection/Cowlection.java @@ -67,7 +67,7 @@ public class Cowlection { friendsHandler = new FriendsHandler(this, new File(configDir, "friends.json")); moo = new CredentialStorage(new Configuration(new File(configDir, "do-not-share-me-with-other-players.cfg"))); - config = new MooConfig(this, new Configuration(new File(configDir, MODID + ".cfg"), "0.13.0-pre")); + config = new MooConfig(this, new Configuration(new File(configDir, MODID + ".cfg"), "2")); } @EventHandler diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java index ba1c2dc..f37f19b 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java @@ -139,6 +139,7 @@ public class MooConfig { this.main = main; cfg = configuration; + // config version history: null > 1 > 0.12.0 > 0.13.0-pre > 2 String oldLoadedConfigVersion = cfg.getLoadedConfigVersion(); boolean configVersionChanged = oldLoadedConfigVersion == null || !oldLoadedConfigVersion.equals(cfg.getDefinedConfigVersion()); if (configVersionChanged) { @@ -175,6 +176,7 @@ public class MooConfig { } private void updateConfigPostInit(String oldVersion) { + boolean changedSomething = false; if ("1".equals(oldVersion)) { // config of Cowlection v1.8.9-0.12.0 and older ConfigCategory sbDungCategory = cfg.getCategory("skyblockdungeons"); @@ -184,19 +186,44 @@ public class MooConfig { sbDungCategory.get("dungOverlayTextBorder").set("no border"); } sbDungCategory.remove("dungOverlayTextShadow"); + changedSomething = true; } - for (String dungClass : new String[]{"Archer", "Berserk", "Healer", "Mage", "Tank"}) { String configKey = "dungFilterPartiesWith" + dungClass + "Dupes"; if (sbDungCategory.containsKey(configKey)) { boolean filterPartiesWithX = sbDungCategory.get(configKey).getBoolean(); - String configKeyNew = "dungMarkPartiesWith" + dungClass; if (filterPartiesWithX) { - sbDungCategory.get(configKeyNew).set("if duplicated"); + String configKeyNew = "dungMarkPartiesWith" + dungClass; + sbDungCategory.get(configKeyNew).set("if dupe: " + EnumChatFormatting.GOLD + "⬛"); } sbDungCategory.remove(configKey); + changedSomething = true; + } + } + } else if ("0.12.0".equals(oldVersion) || "0.13.0-pre".equals(oldVersion)) { // matches config versions pre mod version 0.14.0 + ConfigCategory sbDungCategory = cfg.getCategory("skyblockdungeons"); + for (String dungClass : new String[]{"Archer", "Berserk", "Healer", "Mage", "Tank"}) { + String configKey = "dungMarkPartiesWith" + dungClass; + if (sbDungCategory.containsKey(configKey)) { + String markPartiesWithXOld = sbDungCategory.get(configKey).getString(); + String markPartiesWithXNew; + switch (markPartiesWithXOld) { + case "always": + markPartiesWithXNew = "always: " + EnumChatFormatting.GOLD + "⬛"; + break; + case "if duplicated": + markPartiesWithXNew = "if dupe: " + EnumChatFormatting.GOLD + "⬛"; + break; + default: + continue; + } + sbDungCategory.get(configKey).set(markPartiesWithXNew); + changedSomething = true; } } + } + // else if (MathHelper.parseIntWithDefault(oldVersion, 9999) < newVersion) { // matches all versions >= 2 + if (changedSomething) { cfg.save(); syncFromFile(); } @@ -590,7 +617,7 @@ public class MooConfig { "to make it easier to find the perfect party:", "", "Marks parties...", - " ‣ you cannot join: " + EnumChatFormatting.RED + "⬛", + " ‣ you cannot join, or decided to filter out: " + EnumChatFormatting.RED + "⬛", " ‣ that do not meet all your criteria: " + EnumChatFormatting.GOLD + "⬛", " ‣ with \"Dungeon Level Required\" below a certain level " + EnumChatFormatting.GRAY + "(if present)" + EnumChatFormatting.RESET + ": " + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "ᐯ" + EnumChatFormatting.RESET, " ‣ with someone below a certain class level: " + EnumChatFormatting.RED + EnumChatFormatting.BOLD + "ᐯ" + EnumChatFormatting.RESET, @@ -636,23 +663,43 @@ public class MooConfig { new MooConfigPreview(new MooChatComponent("Marked with: " + EnumChatFormatting.AQUA + "hyper").gray())); Property propDungMarkPartiesWithArcher = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), - "dungMarkPartiesWithArcher", "if duplicated", "Mark parties with Archer class?", new String[]{"always", "if duplicated", "do not mark"}), + "dungMarkPartiesWithArcher", "if dupe: " + EnumChatFormatting.GOLD + "⬛", "Mark parties with Archer class?", + new String[]{ + "if dupe: " + EnumChatFormatting.GOLD + "⬛", "always: " + EnumChatFormatting.GOLD + "⬛", + "if dupe: " + EnumChatFormatting.RED + "⬛", "always: " + EnumChatFormatting.RED + "⬛", + "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.ARCHER)); Property propDungMarkPartiesWithBerserk = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), - "dungMarkPartiesWithBerserk", "do not mark", "Mark parties with Berserk class?", new String[]{"always", "if duplicated", "do not mark"}), + "dungMarkPartiesWithBerserk", "do not mark", "Mark parties with Berserk class?", + new String[]{ + "if dupe: " + EnumChatFormatting.GOLD + "⬛", "always: " + EnumChatFormatting.GOLD + "⬛", + "if dupe: " + EnumChatFormatting.RED + "⬛", "always: " + EnumChatFormatting.RED + "⬛", + "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.BERSERK)); Property propDungMarkPartiesWithHealer = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), - "dungMarkPartiesWithHealer", "do not mark", "Mark parties with Healer class?", new String[]{"always", "if duplicated", "do not mark"}), + "dungMarkPartiesWithHealer", "do not mark", "Mark parties with Healer class?", + new String[]{ + "if dupe: " + EnumChatFormatting.GOLD + "⬛", "always: " + EnumChatFormatting.GOLD + "⬛", + "if dupe: " + EnumChatFormatting.RED + "⬛", "always: " + EnumChatFormatting.RED + "⬛", + "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.HEALER)); Property propDungMarkPartiesWithMage = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), - "dungMarkPartiesWithMage", "do not mark", "Mark parties with Mage class?", new String[]{"always", "if duplicated", "do not mark"}), + "dungMarkPartiesWithMage", "do not mark", "Mark parties with Mage class?", + new String[]{ + "if dupe: " + EnumChatFormatting.GOLD + "⬛", "always: " + EnumChatFormatting.GOLD + "⬛", + "if dupe: " + EnumChatFormatting.RED + "⬛", "always: " + EnumChatFormatting.RED + "⬛", + "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.MAGE)); Property propDungMarkPartiesWithTank = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), - "dungMarkPartiesWithTank", "do not mark", "Mark parties with Tank class?", new String[]{"always", "if duplicated", "do not mark"}), + "dungMarkPartiesWithTank", "do not mark", "Mark parties with Tank class?", + new String[]{ + "if dupe: " + EnumChatFormatting.GOLD + "⬛", "always: " + EnumChatFormatting.GOLD + "⬛", + "if dupe: " + EnumChatFormatting.RED + "⬛", "always: " + EnumChatFormatting.RED + "⬛", + "do not mark"}), new MooConfigPreview(DataHelper.DungeonClass.TANK)); Property propDungSendWrongFloorWarning = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), @@ -1078,13 +1125,13 @@ public class MooConfig { case "unide": // "unideal " + EnumChatFormatting.GOLD + "⬛" return DataHelper.PartyType.UNIDEAL; case "block": // "block " + EnumChatFormatting.RED + "⬛" - return DataHelper.PartyType.UNJOINABLE; + return DataHelper.PartyType.UNJOINABLE_OR_BLOCK; default: // "do not mark" return DataHelper.PartyType.NONE; } } - public static Setting filterDungPartiesWithDupes(DataHelper.DungeonClass dungeonClass) { + public static Mark dungeonPartyMarker(DataHelper.DungeonClass dungeonClass) { String setting; switch (dungeonClass) { case ARCHER: @@ -1107,12 +1154,16 @@ public class MooConfig { break; } switch (setting) { - case "always": - return Setting.ALWAYS; - case "if duplicated": - return Setting.SPECIAL; + case "if dupe: §6⬛": + return Mark.UNIDEAL_DUPE; + case "always: §6⬛": + return Mark.UNIDEAL_ALWAYS; + case "if dupe: §c⬛": + return Mark.BLOCK_DUPE; + case "always: §c⬛": + return Mark.BLOCK_ALWAYS; default: // do not mark - return Setting.DISABLED; + return Mark.DO_NOT_MARK; } } @@ -1164,6 +1215,16 @@ public class MooConfig { } } + public enum Mark { + UNIDEAL_ALWAYS, UNIDEAL_DUPE, // + BLOCK_ALWAYS, BLOCK_DUPE, // + DO_NOT_MARK; + + public boolean ifDuped() { + return this == UNIDEAL_DUPE || this == BLOCK_DUPE; + } + } + public enum Setting { UNKNOWN, DISABLED, // ALWAYS, TOOLTIP, TEXT, // diff --git a/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigPreview.java b/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigPreview.java index 5afb052..570fa3b 100644 --- a/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigPreview.java +++ b/src/main/java/de/cowtipper/cowlection/config/gui/MooConfigPreview.java @@ -62,14 +62,20 @@ public class MooConfigPreview { @Override public IChatComponent getText() { String markWith; - switch (MooConfig.filterDungPartiesWithDupes(dungeonClass)) { - case ALWAYS: - markWith = "" + EnumChatFormatting.WHITE + dungeonClass.getShortName(); + switch (MooConfig.dungeonPartyMarker(dungeonClass)) { + case UNIDEAL_DUPE: + markWith = EnumChatFormatting.GOLD + "²⁺" + EnumChatFormatting.YELLOW + dungeonClass.getShortName() + EnumChatFormatting.GRAY + " + " + EnumChatFormatting.GOLD + "⬛ " + EnumChatFormatting.GRAY + "as background"; break; - case SPECIAL: - markWith = EnumChatFormatting.GOLD + "²⁺" + EnumChatFormatting.YELLOW + dungeonClass.getShortName(); + case UNIDEAL_ALWAYS: + markWith = "" + EnumChatFormatting.WHITE + dungeonClass.getShortName() + EnumChatFormatting.GRAY + " + " + EnumChatFormatting.GOLD + "⬛ " + EnumChatFormatting.GRAY + "as background"; break; - default: // disabled/"do not mark": + case BLOCK_DUPE: + markWith = EnumChatFormatting.RED + "⬛ " + EnumChatFormatting.GRAY + "as background if duplicated"; + break; + case BLOCK_ALWAYS: + markWith = EnumChatFormatting.RED + "⬛ " + EnumChatFormatting.GRAY + "as background"; + break; + default: // do not mark markWith = "" + EnumChatFormatting.DARK_GRAY + EnumChatFormatting.ITALIC + "not marked"; } return new MooChatComponent("Marked with: " + markWith).gray(); diff --git a/src/main/java/de/cowtipper/cowlection/data/DataHelper.java b/src/main/java/de/cowtipper/cowlection/data/DataHelper.java index 9320342..6956d1c 100644 --- a/src/main/java/de/cowtipper/cowlection/data/DataHelper.java +++ b/src/main/java/de/cowtipper/cowlection/data/DataHelper.java @@ -111,7 +111,7 @@ public final class DataHelper { public enum PartyType { SUITABLE(0xff22B14C, 240), UNIDEAL(0xffCD8032, 240), - UNJOINABLE(0xffEB6E6E, 279), + UNJOINABLE_OR_BLOCK(0xffEB6E6E, 279), CURRENT(0xff5FDE6C, 240), NONE(0xffFF0000, 279); 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 009d694..014c4c9 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/skyblock/DungeonsListener.java @@ -317,12 +317,12 @@ public class DungeonsListener { || lastToolTipLine.startsWith("Requires a Class at Level") || lastToolTipLine.startsWith("Requires Catacombs Level")) { // cannot enter dungeon - partyType = DataHelper.PartyType.UNJOINABLE; + partyType = DataHelper.PartyType.UNJOINABLE_OR_BLOCK; } else if (lastToolTipLine.endsWith("You are in this party!")) { partyType = DataHelper.PartyType.CURRENT; } else { Map<DungeonClass, AtomicInteger> dungClassesInParty = new LinkedHashMap<>(); - if (MooConfig.filterDungPartiesWithDupes(activeDungeonClass) == MooConfig.Setting.SPECIAL) { + if (MooConfig.dungeonPartyMarker(activeDungeonClass).ifDuped()) { // add our own class if we want to avoid dupes AtomicInteger classCounter = new AtomicInteger(); classCounter.incrementAndGet(); @@ -340,6 +340,11 @@ public class DungeonsListener { if (playerDetailMatcher.matches()) { String className = playerDetailMatcher.group(2); DungeonClass clazz = DungeonClass.get(className); + if (MooConfig.dungeonPartyMarker(clazz) == MooConfig.Mark.BLOCK_ALWAYS) { + // class is blocked -> block party + partyType = DataHelper.PartyType.UNJOINABLE_OR_BLOCK; + break; + } dungClassesInParty.putIfAbsent(clazz, new AtomicInteger(0)); dungClassesInParty.get(clazz).incrementAndGet(); @@ -356,12 +361,12 @@ public class DungeonsListener { // TODO make trigger words in party notes configurable if (partyTypeCarry != DataHelper.PartyType.NONE && (partyNote.contains("carry") || partyNote.contains("carries"))) { partyType = partyTypeCarry; - if (partyTypeCarry != DataHelper.PartyType.UNJOINABLE) { + if (partyTypeCarry != DataHelper.PartyType.UNJOINABLE_OR_BLOCK) { middleText = (partyNote.contains("free") ? EnumChatFormatting.GREEN : "") + "carry"; } } else if (partyTypeHyperion != DataHelper.PartyType.NONE && partyNote.contains("hyp")) { partyType = partyTypeHyperion; - if (partyTypeHyperion != DataHelper.PartyType.UNJOINABLE) { + if (partyTypeHyperion != DataHelper.PartyType.UNJOINABLE_OR_BLOCK) { middleText = "hyper"; } } @@ -373,7 +378,7 @@ public class DungeonsListener { } } FontRenderer font = Minecraft.getMinecraft().fontRendererObj; - if (partyType != DataHelper.PartyType.UNJOINABLE && middleText != null) { + if (partyType != DataHelper.PartyType.UNJOINABLE_OR_BLOCK && middleText != null) { GlStateManager.pushMatrix(); GlStateManager.translate(0, 0, 281); double scaleFactor = 0.5; @@ -381,7 +386,7 @@ public class DungeonsListener { font.drawStringWithShadow(middleText, (float) ((x + 1) / scaleFactor), (float) ((y + 5) / scaleFactor), new Color(85, 240, 240, 255).getRGB()); GlStateManager.popMatrix(); } - if (partyType != DataHelper.PartyType.UNJOINABLE) { + if (partyType != DataHelper.PartyType.UNJOINABLE_OR_BLOCK) { if (memberTooLowLevel || partyReqTooLowLevel) { // at least one party member is lower than the min class level or party min Dungeon level req is too low partyType = DataHelper.PartyType.UNIDEAL; @@ -393,49 +398,49 @@ public class DungeonsListener { StringBuilder unwantedClasses = new StringBuilder(); StringBuilder dupedClasses = new StringBuilder(); for (Map.Entry<DungeonClass, AtomicInteger> partyClassInfo : dungClassesInParty.entrySet()) { - switch (MooConfig.filterDungPartiesWithDupes(partyClassInfo.getKey())) { - case ALWAYS: - unwantedClasses.append(partyClassInfo.getKey().getShortName()); - break; - case SPECIAL: - if (partyClassInfo.getValue().get() > 1) { - // 2+ class - dupedClasses.append(partyClassInfo.getKey().getShortName()); - } - break; - default: // DISABLED - // do nothing + MooConfig.Mark dungeonPartyMarker = MooConfig.dungeonPartyMarker(partyClassInfo.getKey()); + if (dungeonPartyMarker == MooConfig.Mark.UNIDEAL_DUPE && partyClassInfo.getValue().get() > 1) { + // 2+ class + dupedClasses.append(partyClassInfo.getKey().getShortName()); + } else if (dungeonPartyMarker == MooConfig.Mark.UNIDEAL_ALWAYS) { + unwantedClasses.append(partyClassInfo.getKey().getShortName()); + } else if (dungeonPartyMarker == MooConfig.Mark.BLOCK_DUPE && partyClassInfo.getValue().get() > 1) { + // found blocked if duplicated class + partyType = DataHelper.PartyType.UNJOINABLE_OR_BLOCK; + break; } } - StringBuilder badClasses = new StringBuilder(); - if (unwantedClasses.length() > 0) { - badClasses.append(EnumChatFormatting.WHITE).append(unwantedClasses); - } - if (dupedClasses.length() > 0) { - badClasses.append(EnumChatFormatting.GOLD).append("²⁺").append(EnumChatFormatting.YELLOW).append(dupedClasses); // 2+ - } - - if (badClasses.length() > 0) { - // party has unwanted classes or class duplicates - partyType = DataHelper.PartyType.UNIDEAL; + if (partyType != DataHelper.PartyType.UNJOINABLE_OR_BLOCK) { + StringBuilder badClasses = new StringBuilder(); + if (unwantedClasses.length() > 0) { + badClasses.append(EnumChatFormatting.WHITE).append(unwantedClasses); + } + if (dupedClasses.length() > 0) { + badClasses.append(EnumChatFormatting.GOLD).append("²⁺").append(EnumChatFormatting.YELLOW).append(dupedClasses); // 2+ + } - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, 280); - double scaleFactor = 0.8; - GlStateManager.scale(scaleFactor, scaleFactor, 0); - font.drawStringWithShadow(badClasses.toString(), (float) (x / scaleFactor), (float) (y / scaleFactor), new Color(255, 170, 0, 255).getRGB()); - GlStateManager.popMatrix(); - } else if (!memberTooLowLevel && !partyReqTooLowLevel && middleText == null) { - // party matches our criteria! - partyType = DataHelper.PartyType.SUITABLE; - } - // add party size indicator - if (MooConfig.dungPartiesSize && partySize > 0) { - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, 280); - String partySizeIndicator = String.valueOf(partySize); - font.drawStringWithShadow(partySizeIndicator, x + 17 - font.getStringWidth(partySizeIndicator), y + 9, 0xffFFFFFF); - GlStateManager.popMatrix(); + if (badClasses.length() > 0) { + // party has unwanted classes or class duplicates + partyType = DataHelper.PartyType.UNIDEAL; + + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 280); + double scaleFactor = 0.8; + GlStateManager.scale(scaleFactor, scaleFactor, 0); + font.drawStringWithShadow(badClasses.toString(), (float) (x / scaleFactor), (float) (y / scaleFactor), new Color(255, 170, 0, 255).getRGB()); + GlStateManager.popMatrix(); + } else if (!memberTooLowLevel && !partyReqTooLowLevel && middleText == null) { + // party matches our criteria! + partyType = DataHelper.PartyType.SUITABLE; + } + // add party size indicator + if (MooConfig.dungPartiesSize && partySize > 0) { + GlStateManager.pushMatrix(); + GlStateManager.translate(0, 0, 280); + String partySizeIndicator = String.valueOf(partySize); + font.drawStringWithShadow(partySizeIndicator, x + 17 - font.getStringWidth(partySizeIndicator), y + 9, 0xffFFFFFF); + GlStateManager.popMatrix(); + } } } } diff --git a/src/main/resources/assets/cowlection/lang/en_US.lang b/src/main/resources/assets/cowlection/lang/en_US.lang index 7ec8977..2a124a4 100644 --- a/src/main/resources/assets/cowlection/lang/en_US.lang +++ b/src/main/resources/assets/cowlection/lang/en_US.lang @@ -134,16 +134,16 @@ cowlection.config.dungMarkPartiesWithCarry=Mark 'carry' parties? cowlection.config.dungMarkPartiesWithCarry.tooltip=Mark parties that have 'carry' in their notes? cowlection.config.dungMarkPartiesWithHyperion=Mark 'hyperion' parties? cowlection.config.dungMarkPartiesWithHyperion.tooltip=Mark parties that have 'hyperion' in their notes? -cowlection.config.dungMarkPartiesWithArcher=Mark parties with Archer class as unideal? -cowlection.config.dungMarkPartiesWithArcher.tooltip=Mark parties with Archer class as unideal (orange background)? -cowlection.config.dungMarkPartiesWithBerserk=Mark parties with Berserk class as unideal? -cowlection.config.dungMarkPartiesWithBerserk.tooltip=Mark parties with Berserk class as unideal (orange background)? -cowlection.config.dungMarkPartiesWithHealer=Mark parties with Healer class as unideal? -cowlection.config.dungMarkPartiesWithHealer.tooltip=Mark parties with Healer class as unideal (orange background)? -cowlection.config.dungMarkPartiesWithMage=Mark parties with Mage class as unideal? -cowlection.config.dungMarkPartiesWithMage.tooltip=Mark parties with Mage class as unideal (orange background)? -cowlection.config.dungMarkPartiesWithTank=Mark parties with Tank class as unideal? -cowlection.config.dungMarkPartiesWithTank.tooltip=Mark parties with Tank class as unideal (orange background)? +cowlection.config.dungMarkPartiesWithArcher=Mark parties with Archer class … +cowlection.config.dungMarkPartiesWithArcher.tooltip=Mark parties with Archer class either:\n ‣ always, or if duplicated: §c⬛ (blocked)\n ‣ always, or if duplicated: §6⬛ §e (unideal)\n ‣ do not mark +cowlection.config.dungMarkPartiesWithBerserk=Mark parties with Berserk class … +cowlection.config.dungMarkPartiesWithBerserk.tooltip=Mark parties with Berserk class either:\n ‣ always, or if duplicated: §c⬛ (blocked)\n ‣ always, or if duplicated: §6⬛ §e (unideal)\n ‣ do not mark +cowlection.config.dungMarkPartiesWithHealer=Mark parties with Healer class … +cowlection.config.dungMarkPartiesWithHealer.tooltip=Mark parties with Healer class either:\n ‣ always, or if duplicated: §c⬛ (blocked)\n ‣ always, or if duplicated: §6⬛ §e (unideal)\n ‣ do not mark +cowlection.config.dungMarkPartiesWithMage=Mark parties with Mage class … +cowlection.config.dungMarkPartiesWithMage.tooltip=Mark parties with Mage class either:\n ‣ always, or if duplicated: §c⬛ (blocked)\n ‣ always, or if duplicated: §6⬛ §e (unideal)\n ‣ do not mark +cowlection.config.dungMarkPartiesWithTank=Mark parties with Tank class … +cowlection.config.dungMarkPartiesWithTank.tooltip=Mark parties with Tank class either:\n ‣ always, or if duplicated: §c⬛ (blocked)\n ‣ always, or if duplicated: §6⬛ §e (unideal)\n ‣ do not mark cowlection.config.dungSendWrongFloorWarning=Warn if queued & entered floor are different cowlection.config.dungSendWrongFloorWarning.tooltip=Send a warning when entering a dungeons floor which is different from the originally queued floor? cowlection.commands.generic.exception=%s |