diff options
| author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2024-12-29 20:22:37 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-30 09:22:37 +0800 |
| commit | add261c2e2a3f10bec125421f1db9679add479db (patch) | |
| tree | 2d3e4209097b5496415afef23cadfe8312984dd0 /src/main/java | |
| parent | 19a1df637df912fc2a99170e7b74abed6338ac5a (diff) | |
| download | Skyblocker-add261c2e2a3f10bec125421f1db9679add479db.tar.gz Skyblocker-add261c2e2a3f10bec125421f1db9679add479db.tar.bz2 Skyblocker-add261c2e2a3f10bec125421f1db9679add479db.zip | |
Class-based player glow (#1113)
* Class-based player glow
* Change default + add doc to the new event
Diffstat (limited to 'src/main/java')
9 files changed, 162 insertions, 31 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index aaf09710..3fca9658 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -52,6 +52,14 @@ public class DungeonsCategory { .controller(ConfigUtils::createBooleanController) .build()) .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.dungeons.classBasedPlayerGlow")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.dungeons.classBasedPlayerGlow.@Tooltip"))) + .binding(defaults.dungeons.classBasedPlayerGlow, + () -> config.dungeons.classBasedPlayerGlow, + newValue -> config.dungeons.classBasedPlayerGlow = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.config.dungeons.starredMobGlow")) .description(OptionDescription.of(Text.translatable("skyblocker.config.dungeons.starredMobGlow.@Tooltip"))) .binding(defaults.dungeons.starredMobGlow, diff --git a/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java index d0e92293..90457eea 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java @@ -19,6 +19,9 @@ public class DungeonsConfig { public boolean playerSecretsTracker = false; @SerialEntry + public boolean classBasedPlayerGlow = true; + + @SerialEntry public boolean starredMobGlow = false; @SerialEntry diff --git a/src/main/java/de/hysky/skyblocker/events/DungeonEvents.java b/src/main/java/de/hysky/skyblocker/events/DungeonEvents.java index 9efa3607..aa8565b3 100644 --- a/src/main/java/de/hysky/skyblocker/events/DungeonEvents.java +++ b/src/main/java/de/hysky/skyblocker/events/DungeonEvents.java @@ -7,24 +7,39 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; public class DungeonEvents { - public static final Event<RoomMatched> PUZZLE_MATCHED = EventFactory.createArrayBacked(RoomMatched.class, callbacks -> room -> { - for (RoomMatched callback : callbacks) { - callback.onRoomMatched(room); - } - }); + public static final Event<RoomMatched> PUZZLE_MATCHED = EventFactory.createArrayBacked(RoomMatched.class, callbacks -> room -> { + for (RoomMatched callback : callbacks) { + callback.onRoomMatched(room); + } + }); - public static final Event<RoomMatched> ROOM_MATCHED = EventFactory.createArrayBacked(RoomMatched.class, callbacks -> room -> { - for (RoomMatched callback : callbacks) { - callback.onRoomMatched(room); - } - if (room.getType() == Room.Type.PUZZLE) { - PUZZLE_MATCHED.invoker().onRoomMatched(room); - } - }); + public static final Event<RoomMatched> ROOM_MATCHED = EventFactory.createArrayBacked(RoomMatched.class, callbacks -> room -> { + for (RoomMatched callback : callbacks) { + callback.onRoomMatched(room); + } + if (room.getType() == Room.Type.PUZZLE) { + PUZZLE_MATCHED.invoker().onRoomMatched(room); + } + }); - @Environment(EnvType.CLIENT) - @FunctionalInterface - public interface RoomMatched { - void onRoomMatched(Room room); - } + /** + * Note: This event fires after the tab has changed to include additional information about the run such as each player's class. + */ + public static final Event<DungeonStarted> DUNGEON_STARTED = EventFactory.createArrayBacked(DungeonStarted.class, callbacks -> () -> { + for (DungeonStarted callback : callbacks) { + callback.onDungeonStarted(); + } + }); + + @Environment(EnvType.CLIENT) + @FunctionalInterface + public interface RoomMatched { + void onRoomMatched(Room room); + } + + @Environment(EnvType.CLIENT) + @FunctionalInterface + public interface DungeonStarted { + void onDungeonStarted(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java new file mode 100644 index 00000000..9f52c414 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java @@ -0,0 +1,43 @@ +package de.hysky.skyblocker.skyblock.dungeon; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import de.hysky.skyblocker.skyblock.entity.MobGlow; + +public enum DungeonClass { + UNKNOWN("Unknown", MobGlow.NO_GLOW), + HEALER("Healer", 0x820dd1), + MAGE("Mage", 0x36c6e3), + BERSERK("Berserk", 0xfa5b16), + ARCHER("Archer", 0xed240e), + TANK("Tank", 0x138717); + + private static final Map<String, DungeonClass> CLASSES = Arrays.stream(values()) + .collect(Collectors.toUnmodifiableMap(DungeonClass::displayName, Function.identity())); + + private final String name; + private final int color; + + DungeonClass(String name, int colour) { + this.name = name; + this.color = colour; + } + + public String displayName() { + return this.name; + } + + /** + * @return The color of the class in RGB format. + */ + public int color() { + return this.color; + } + + public static DungeonClass from(String name) { + return CLASSES.getOrDefault(name, UNKNOWN); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java index e3e8e128..5727cda7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonScore.java @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.DungeonsConfig; +import de.hysky.skyblocker.events.DungeonEvents; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.utils.Constants; @@ -67,12 +68,11 @@ public class DungeonScore { public static void init() { Scheduler.INSTANCE.scheduleCyclic(DungeonScore::tick, 20); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset()); + DungeonEvents.DUNGEON_STARTED.register(DungeonScore::onDungeonStart); ClientReceiveMessageEvents.GAME.register((message, overlay) -> { if (overlay || !Utils.isInDungeons()) return; String str = message.getString(); - if (!dungeonStarted) { - checkMessageForMort(str); - } else { + if (dungeonStarted) { checkMessageForDeaths(str); checkMessageForWatcher(str); if (floorHasMimics) checkMessageForMimic(str); //Only called when the message is not cancelled & isn't on the action bar, complementing MimicFilter @@ -315,11 +315,6 @@ public class DungeonScore { if (message.equals("[BOSS] The Watcher: You have proven yourself. You may pass.")) bloodRoomCompleted = true; } - private static void checkMessageForMort(String message) { - if (!message.equals("§e[NPC] §bMort§f: You should find it useful if you get lost.")) return; - onDungeonStart(); - } - private static void checkMessageForMimic(String message) { if (!MIMIC_PATTERN.matcher(message).matches()) return; onMimicKill(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java index 86ef0828..52a1433e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java @@ -17,6 +17,7 @@ import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.DungeonsConfig; import de.hysky.skyblocker.debug.Debug; +import de.hysky.skyblocker.events.DungeonEvents; import de.hysky.skyblocker.skyblock.dungeon.DungeonBoss; import de.hysky.skyblocker.skyblock.dungeon.DungeonMap; import de.hysky.skyblocker.utils.Constants; @@ -677,6 +678,10 @@ public class DungeonManager { } } + if (message.equals("§e[NPC] §bMort§f: You should find it useful if you get lost.")) { + DungeonEvents.DUNGEON_STARTED.invoker().onDungeonStarted(); + } + var newBoss = DungeonBoss.fromMessage(message); if (!isInBoss() && newBoss.isInBoss()) { reset(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonPlayerManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonPlayerManager.java new file mode 100644 index 00000000..6a516007 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonPlayerManager.java @@ -0,0 +1,56 @@ +package de.hysky.skyblocker.skyblock.dungeon.secrets; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jetbrains.annotations.Range; + +import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.events.DungeonEvents; +import de.hysky.skyblocker.skyblock.dungeon.DungeonClass; +import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import it.unimi.dsi.fastutil.objects.Object2ReferenceMap; +import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap; +import net.minecraft.entity.player.PlayerEntity; + +public class DungeonPlayerManager { + /** + * @implNote Same as {@link de.hysky.skyblocker.skyblock.tabhud.widget.DungeonPlayerWidget#PLAYER_PATTERN} + */ + private static final Pattern PLAYER_TAB_PATTERN = Pattern.compile("\\[\\d*\\] (?:\\[[A-Za-z]+\\] )?(?<name>[A-Za-z0-9_]*) (?:.* )?\\((?<class>\\S*) ?(?<level>[LXVI]*)\\)"); + private static final Object2ReferenceMap<String, DungeonClass> PLAYER_CLASSES = new Object2ReferenceOpenHashMap<>(5); + + @Init + public static void init() { + DungeonEvents.DUNGEON_STARTED.register(DungeonPlayerManager::onDungeonStart); + } + + public static DungeonClass getClassFromPlayer(PlayerEntity player) { + String name = player.getGameProfile().getName(); + + return PLAYER_CLASSES.getOrDefault(name, DungeonClass.UNKNOWN); + } + + private static void onDungeonStart() { + reset(); + + for (int i = 0; i < 5; i++) { + Matcher matcher = getPlayerFromTab(i + 1); + + if (matcher != null) { + String name = matcher.group("name"); + DungeonClass dungeonClass = DungeonClass.from(matcher.group("class")); + + if (dungeonClass != DungeonClass.UNKNOWN) PLAYER_CLASSES.put(name, dungeonClass); + } + } + } + + private static void reset() { + PLAYER_CLASSES.clear(); + } + + private static Matcher getPlayerFromTab(@Range(from = 1, to = 5) int index) { + return PlayerListMgr.regexAt(1 + (index - 1) * 4, PLAYER_TAB_PATTERN); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretsTracker.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretsTracker.java index f9db5d72..31d0aba0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretsTracker.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretsTracker.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.events.DungeonEvents; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.skyblock.tabhud.widget.DungeonPlayerWidget; import de.hysky.skyblocker.utils.ApiUtils; @@ -41,6 +42,7 @@ public class SecretsTracker { @Init public static void init() { ClientReceiveMessageEvents.GAME.register(SecretsTracker::onMessage); + DungeonEvents.DUNGEON_STARTED.register(() -> calculate(RunPhase.START)); } private static void calculate(RunPhase phase) { @@ -101,7 +103,6 @@ public class SecretsTracker { } private static void sendResultMessage(String player, SecretData secretData, boolean success) { - @SuppressWarnings("resource") PlayerEntity playerEntity = MinecraftClient.getInstance().player; if (playerEntity != null) { if (success) { @@ -122,7 +123,6 @@ public class SecretsTracker { String message = Formatting.strip(text.getString()); try { - if (message.equals("[NPC] Mort: Here, I found this map when I first entered the dungeon.")) calculate(RunPhase.START); if (TEAM_SCORE_PATTERN.matcher(message).matches()) calculate(RunPhase.END); } catch (Exception e) { LOGGER.error("[Skyblocker] Encountered an unknown error while trying to track player secrets!", e); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java index 0a53b7fa..909eea7e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -6,8 +6,10 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.SlayersConfig; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; +import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; import de.hysky.skyblocker.skyblock.dungeon.LividColor; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonPlayerManager; import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.slayers.SlayerManager; import de.hysky.skyblocker.skyblock.slayers.SlayerType; @@ -32,6 +34,7 @@ import net.minecraft.world.World; import java.util.List; public class MobGlow { + public static final int NO_GLOW = 0; /** * The Nukekubi head texture id is eb07594e2df273921a77c101d0bfdfa1115abed5b9b2029eb496ceba9bdbb4b3. */ @@ -58,7 +61,7 @@ public class MobGlow { return true; } int color = computeMobGlow(entity); - if (color != 0) { + if (color != NO_GLOW) { CACHE.put(entity, color); return true; } @@ -93,6 +96,9 @@ public class MobGlow { case PlayerEntity p when SkyblockerConfigManager.get().dungeons.starredMobGlow && !DungeonManager.getBoss().isFloor(4) && name.equals("Diamond Guy") -> 0x57c2f7; case PlayerEntity p when entity.getId() == LividColor.getCorrectLividId() && LividColor.shouldGlow(name) -> LividColor.getGlowColor(name); + //Class-based glow + case PlayerEntity p when SkyblockerConfigManager.get().dungeons.classBasedPlayerGlow && DungeonScore.isDungeonStarted() -> DungeonPlayerManager.getClassFromPlayer(p).color(); + // Bats case BatEntity b when SkyblockerConfigManager.get().dungeons.starredMobGlow -> 0xf57738; @@ -104,7 +110,7 @@ public class MobGlow { // Regular Mobs case Entity e when SkyblockerConfigManager.get().dungeons.starredMobGlow && isStarred(entity) -> 0xf57738; - default -> 0; + default -> NO_GLOW; }; } @@ -137,7 +143,7 @@ public class MobGlow { case WitherSkeletonEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); case ZombifiedPiglinEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); - default -> 0; + default -> NO_GLOW; }; } |
