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 3fca965847..47abbb30c9 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -189,6 +189,13 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.dungeons.puzzleSolvers.solveTrivia = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.dungeons.puzzle.solveTeleportMaze")) + .binding(defaults.dungeons.puzzleSolvers.solveTeleportMaze, + () -> config.dungeons.puzzleSolvers.solveTeleportMaze, + newValue -> config.dungeons.puzzleSolvers.solveTeleportMaze = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .build()) // The Professor (F3/M3) 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 90457eea58..27accd4aeb 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java @@ -110,6 +110,9 @@ public static class PuzzleSolvers { @SerialEntry public boolean solveTrivia = true; + + @SerialEntry + public boolean solveTeleportMaze = true; } public static class TheProfessor { diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 75604f72d8..0bc9a3936e 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -3,6 +3,8 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.SlayersConfig; import de.hysky.skyblocker.config.configs.UIAndVisualsConfig; @@ -12,6 +14,7 @@ import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; +import de.hysky.skyblocker.skyblock.dungeon.puzzle.TeleportMaze; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.dwarven.CorpseFinder; import de.hysky.skyblocker.skyblock.dwarven.CrystalsChestHighlighter; @@ -23,16 +26,21 @@ import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListManager; import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual; import de.hysky.skyblocker.utils.Utils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientCommonNetworkHandler; +import net.minecraft.client.network.ClientConnectionState; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityStatuses; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.network.ClientConnection; import net.minecraft.network.packet.s2c.play.*; import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -46,7 +54,7 @@ * All mixins in this file should be arranged in the order of the methods they inject into. */ @Mixin(ClientPlayNetworkHandler.class) -public abstract class ClientPlayNetworkHandlerMixin { +public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkHandler { @Shadow private ClientWorld world; @@ -54,6 +62,10 @@ public abstract class ClientPlayNetworkHandlerMixin { @Final private static Logger LOGGER; + protected ClientPlayNetworkHandlerMixin(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) { + super(client, connection, connectionState); + } + @Inject(method = "onEntityTrackerUpdate", at = @At("TAIL")) private void skyblocker$onEntityTrackerUpdate(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) { if (!(entity instanceof ArmorStandEntity armorStandEntity)) return; @@ -78,10 +90,17 @@ public abstract class ClientPlayNetworkHandlerMixin { } } - @Inject(method = "onPlayerPositionLook", at = @At("TAIL")) - private void onPlayerTeleported(PlayerPositionLookS2CPacket packet, CallbackInfo ci) { - //player has been teleported by the server tell the smooth AOTE this + @Inject(method = "onPlayerPositionLook", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", shift = At.Shift.AFTER)) + private void skyblocker$beforeTeleport(PlayerPositionLookS2CPacket packet, CallbackInfo ci, @Share("playerBeforeTeleportBlockPos") LocalRef beforeTeleport) { + beforeTeleport.set(client.player.getBlockPos().toImmutable()); + } + + @Inject(method = "onPlayerPositionLook", at = @At(value = "RETURN")) + private void skyblocker$onTeleport(PlayerPositionLookS2CPacket packet, CallbackInfo ci, @Share("playerBeforeTeleportBlockPos") LocalRef beforeTeleport) { + //player has been teleported by the server, tell the smooth AOTE this SmoothAOTE.playerTeleported(); + + TeleportMaze.INSTANCE.onTeleport(client, beforeTeleport.get(), client.player.getBlockPos().toImmutable()); } @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V", ordinal = 0)) diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index d092de6e2e..6226fef15f 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -165,7 +165,9 @@ protected HandledScreenMixin(Text title) { @Inject(method = "renderBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V")) private void skyblocker$drawUnselectedQuickNavButtons(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (quickNavButtons != null) for (QuickNavButton quickNavButton : quickNavButtons) { - if (!quickNavButton.toggled()) { + // Render the button behind the main inventory background if it's not toggled or if it's still fading in + if (!quickNavButton.toggled() || quickNavButton.getAlpha() < 255) { + quickNavButton.setRenderInFront(false); quickNavButton.render(context, mouseX, mouseY, delta); } } @@ -178,6 +180,7 @@ protected HandledScreenMixin(Text title) { private void skyblocker$drawSelectedQuickNavButtons(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (quickNavButtons != null) for (QuickNavButton quickNavButton : quickNavButtons) { if (quickNavButton.toggled()) { + quickNavButton.setRenderInFront(true); quickNavButton.render(context, mouseX, mouseY, delta); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java index 9f52c414ad..285cc19117 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java @@ -6,24 +6,28 @@ import java.util.stream.Collectors; import de.hysky.skyblocker.skyblock.entity.MobGlow; +import de.hysky.skyblocker.skyblock.tabhud.util.Ico; +import net.minecraft.item.ItemStack; public enum DungeonClass { - UNKNOWN("Unknown", MobGlow.NO_GLOW), - HEALER("Healer", 0x820dd1), - MAGE("Mage", 0x36c6e3), - BERSERK("Berserk", 0xfa5b16), - ARCHER("Archer", 0xed240e), - TANK("Tank", 0x138717); + UNKNOWN("Unknown", MobGlow.NO_GLOW, Ico.BARRIER), + HEALER("Healer", 0x820dd1, Ico.POTION), + MAGE("Mage", 0x36c6e3, Ico.B_ROD), + BERSERK("Berserk", 0xfa5b16, Ico.DIASWORD), + ARCHER("Archer", 0xed240e, Ico.BOW), + TANK("Tank", 0x138717, Ico.CHESTPLATE); private static final Map CLASSES = Arrays.stream(values()) .collect(Collectors.toUnmodifiableMap(DungeonClass::displayName, Function.identity())); private final String name; private final int color; + private final ItemStack icon; - DungeonClass(String name, int colour) { + DungeonClass(String name, int color, ItemStack icon) { this.name = name; - this.color = colour; + this.color = color; + this.icon = icon; } public String displayName() { @@ -37,6 +41,10 @@ public int color() { return this.color; } + public ItemStack icon() { + return icon; + } + public static DungeonClass from(String name) { return CLASSES.getOrDefault(name, UNKNOWN); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/TeleportMaze.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/TeleportMaze.java new file mode 100644 index 0000000000..e9635bad7a --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/TeleportMaze.java @@ -0,0 +1,155 @@ +package de.hysky.skyblocker.skyblock.dungeon.puzzle; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.utils.ColorUtils; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.util.DyeColor; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class TeleportMaze extends DungeonPuzzle { + private static final Set ROOM_CENTERS = Set.of( + new BlockPos(7, 68, 9), + new BlockPos(23, 68, 9), + new BlockPos(7, 68, 17), + new BlockPos(23, 68, 17), + new BlockPos(7, 68, 25), + new BlockPos(15, 68, 25), + new BlockPos(23, 68, 25) + ); + private static final Set TELEPORT_PADS = Set.of( + new BlockPos(15, 69, 12), // Start + new BlockPos(4, 69, 6), + new BlockPos(10, 69, 6), + new BlockPos(20, 69, 6), + new BlockPos(26, 69, 6), + new BlockPos(4, 69, 12), + new BlockPos(10, 69, 12), + new BlockPos(20, 69, 12), + new BlockPos(26, 69, 12), + new BlockPos(4, 69, 14), + new BlockPos(10, 69, 14), + new BlockPos(20, 69, 14), + new BlockPos(26, 69, 14), + new BlockPos(4, 69, 20), + new BlockPos(10, 69, 20), + new BlockPos(20, 69, 20), + new BlockPos(26, 69, 20), + new BlockPos(4, 69, 22), + new BlockPos(10, 69, 22), + new BlockPos(12, 69, 22), + new BlockPos(18, 69, 22), + new BlockPos(20, 69, 22), + new BlockPos(26, 69, 22), + new BlockPos(4, 69, 28), + new BlockPos(10, 69, 28), + new BlockPos(12, 69, 28), + new BlockPos(18, 69, 28), + new BlockPos(20, 69, 28), + new BlockPos(26, 69, 28), + new BlockPos(15, 69, 14) // End + ); + public static final TeleportMaze INSTANCE = new TeleportMaze(); + /** + * The actual coordinate of pads that have been detected and the room type they teleport to. + */ + private final Map pads = new HashMap<>(); + /** + * The actual coordinate of the final pad. + */ + @Nullable + private BlockPos finalPad; + + private TeleportMaze() { + super("teleport-maze", "teleport-pad-room"); + } + + public void onTeleport(MinecraftClient client, BlockPos from, BlockPos to) { + if (!shouldSolve() || !DungeonManager.isCurrentRoomMatched() || client.player == null || client.world == null) return; + + BlockPos prevPlayer = DungeonManager.getCurrentRoom().actualToRelative(from.withY(69)); + BlockPos player = DungeonManager.getCurrentRoom().actualToRelative(to.withY(69)); + if (prevPlayer.equals(player) || !TELEPORT_PADS.contains(prevPlayer)) return; + + // Process the teleport from the previous pad to the current pad + processTeleport(client.world, prevPlayer, player); + // Find the pad closest to the player, which is the current pad they teleported to + BlockPos nearestPad = TELEPORT_PADS.stream().min(Comparator.comparingDouble(pad -> pad.getSquaredDistance(player))).orElse(null); + // Also process the teleport from the current pad to the previous pad + processTeleport(client.world, nearestPad, prevPlayer); + } + + private void processTeleport(World world, BlockPos from, BlockPos to) { + getRoomType(world, to).ifPresent(type -> pads.put(DungeonManager.getCurrentRoom().relativeToActual(from), type)); + } + + private Optional getRoomType(World world, BlockPos pos) { + // Special processing for the entrance + if (pos.getX() == 15 && pos.getZ() == 12) return Optional.of(RoomType.ENTRANCE); + // Check if the position is in a room and return the room type by checking the ore block + return ROOM_CENTERS.stream().filter(center -> center.getX() - 3 <= pos.getX() && pos.getX() <= center.getX() + 3 && + center.getZ() - 3 <= pos.getZ() && pos.getZ() <= center.getZ() + 3).findAny() + .map(DungeonManager.getCurrentRoom()::relativeToActual).map(world::getBlockState).map(BlockState::getBlock).flatMap(RoomType::fromBlock); + } + + @Override + public void tick(MinecraftClient client) { + if (!SkyblockerConfigManager.get().dungeons.puzzleSolvers.solveTeleportMaze || !shouldSolve() || finalPad != null) return; + // Mark the last unused pad that's not the start or the end as the final pad + List finalPads = TELEPORT_PADS.stream().filter(pad -> pad.getX() != 15) // Filter out the start and end pads + .map(DungeonManager.getCurrentRoom()::relativeToActual).filter(pad -> !pads.containsKey(pad)).toList(); // Filter out used pads + if (finalPads.size() == 1) finalPad = finalPads.getFirst(); // If there's only one left, mark it as the final pad + } + + @Override + public void render(WorldRenderContext context) { + if (!SkyblockerConfigManager.get().dungeons.puzzleSolvers.solveTeleportMaze || !shouldSolve()) return; + for (Map.Entry entry : pads.entrySet()) { + RenderHelper.renderFilled(context, entry.getKey(), entry.getValue().colorComponents, 0.5f, true); + } + if (finalPad != null) { + RenderHelper.renderFilled(context, finalPad, ColorUtils.getFloatComponents(DyeColor.LIME), 1f, true); + RenderHelper.renderLineFromCursor(context, Vec3d.ofCenter(finalPad), ColorUtils.getFloatComponents(DyeColor.LIME), 1f, 2f); + } + } + + @Override + public void reset() { + super.reset(); + pads.clear(); + finalPad = null; + } + + private enum RoomType { + ENTRANCE(Blocks.BARRIER, DyeColor.GRAY), + COAL(Blocks.COAL_ORE, DyeColor.BLACK), + IRON(Blocks.IRON_ORE, DyeColor.LIGHT_GRAY), + REDSTONE(Blocks.REDSTONE_ORE, DyeColor.RED), + LAPIS(Blocks.LAPIS_ORE, DyeColor.BLUE), + GOLD(Blocks.GOLD_ORE, DyeColor.YELLOW), + DIAMOND(Blocks.DIAMOND_ORE, DyeColor.CYAN), + EMERALD(Blocks.EMERALD_ORE, DyeColor.LIME); + + private final Block block; + private final float[] colorComponents; + + RoomType(Block block, DyeColor dyeColor) { + this.block = block; + this.colorComponents = ColorUtils.getFloatComponents(dyeColor); + } + + private static Optional fromBlock(Block block) { + return Arrays.stream(values()).filter(type -> type.block == block).findFirst(); + } + } +} 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 2cf700bb5f..e7e3230eb8 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 @@ -106,7 +106,7 @@ private static void sendResultMessage(String player, SecretData secretData, bool PlayerEntity playerEntity = MinecraftClient.getInstance().player; if (playerEntity != null) { if (success) { - playerEntity.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secretsTracker.feedback", Text.literal(player).withColor(0xf57542), "§7" + secretData.secrets(), getCacheText(secretData.cached(), secretData.cacheAge()))), false); + playerEntity.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secretsTracker.feedback", Text.literal(player).append(" (" + DungeonPlayerManager.getClassFromPlayer(playerEntity).displayName() + ")").withColor(0xf57542), "§7" + secretData.secrets(), getCacheText(secretData.cached(), secretData.cacheAge()))), false); } else { playerEntity.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.dungeons.secretsTracker.failFeedback")), false); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java b/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java index 0512efd33f..673538f4e7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java @@ -1,7 +1,6 @@ package de.hysky.skyblocker.skyblock.quicknav; import com.google.gson.JsonElement; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.serialization.JsonOps; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; @@ -22,21 +21,25 @@ import net.minecraft.text.TextCodecs; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; +import net.minecraft.util.math.ColorHelper; import java.time.Duration; @Environment(value = EnvType.CLIENT) public class QuickNavButton extends ClickableWidget { + private static final long TOGGLE_DURATION = 1000; + private final int index; private final boolean toggled; - private boolean temporaryToggled = false; private final String command; private final ItemStack icon; - private static final long TOGGLE_DURATION = 1000; + private boolean temporaryToggled = false; private long toggleTime; - private float alpha = 1.0f; + // Stores whether the button is currently rendering in front of the main inventory background. + private boolean renderInFront; + private int alpha = 255; /** * Checks if the current tab is a top tab based on its index. @@ -51,6 +54,14 @@ public boolean toggled() { return toggled || temporaryToggled; } + public void setRenderInFront(boolean renderInFront) { + this.renderInFront = renderInFront; + } + + public int getAlpha() { + return alpha; + } + /** * Constructs a new QuickNavButton with the given parameters. * @@ -106,7 +117,7 @@ public void onClick(double mouseX, double mouseY) { } else { MessageScheduler.INSTANCE.sendMessageAfterCooldown(command, true); } - this.alpha = 0.5f; + this.alpha = 0; } } @@ -123,37 +134,25 @@ public void onClick(double mouseX, double mouseY) { @Override public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { this.updateCoordinates(); - RenderSystem.disableDepthTest(); + // Note that this changes the return value of `toggled()`, so do not call it after this point. + // Instead, use `renderInFront` to determine whether the button is currently rendering in front of the main inventory background. if (this.temporaryToggled && System.currentTimeMillis() - this.toggleTime >= TOGGLE_DURATION) { this.temporaryToggled = false; // Reset toggled state } //"animation" - if (this.alpha < 1.0f) { - this.alpha += 0.05f; - if (this.alpha > 1.0f) { - this.alpha = 1.0f; - } + if (alpha < 255) { + alpha = Math.min(alpha + 10, 255); } - //"animation" - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, this.alpha); - // Construct the texture identifier based on the index and toggled state - Identifier tabTexture = Identifier.ofVanilla("container/creative_inventory/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (toggled() ? "selected" : "unselected") + "_" + (index % 7 + 1)); + Identifier tabTexture = Identifier.ofVanilla("container/creative_inventory/tab_" + (isTopTab() ? "top" : "bottom") + "_" + (renderInFront ? "selected" : "unselected") + "_" + (index % 7 + 1)); - // Render the button texture - context.drawGuiTexture(RenderLayer::getGuiTextured, tabTexture, this.getX(), this.getY(), this.width, this.height); + // Render the button texture, always with full alpha if it's not rendering in front + context.drawGuiTexture(RenderLayer::getGuiTextured, tabTexture, this.getX(), this.getY(), this.width, this.height, renderInFront ? ColorHelper.withAlpha(alpha, -1) : -1); // Render the button icon int yOffset = this.index < 7 ? 1 : -1; context.drawItem(this.icon, this.getX() + 5, this.getY() + 8 + yOffset); - //prevent "fading animation" on not quicknav stuff - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderSystem.disableBlend(); - - RenderSystem.enableDepthTest(); } @Override diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java index ddda692429..14c06abcf5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java @@ -1,16 +1,16 @@ package de.hysky.skyblocker.skyblock.tabhud.widget; +import de.hysky.skyblocker.skyblock.dungeon.DungeonClass; import de.hysky.skyblocker.skyblock.tabhud.util.Ico; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListManager; import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent; +import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlayerComponent; import net.minecraft.item.ItemStack; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,22 +31,7 @@ public class DungeonPlayerWidget extends TabHudWidget { public static final Pattern PLAYER_PATTERN = Pattern .compile("\\[\\d*\\] (?:\\[[A-Za-z]+\\] )?(?[A-Za-z0-9_]*) (?:.* )?\\((?\\S*) ?(?[LXVI]*)\\)"); - private static final HashMap ICOS = new HashMap<>(); - private static final ArrayList MSGS = new ArrayList<>(); - - static { - ICOS.put("Tank", Ico.CHESTPLATE); - ICOS.put("Mage", Ico.B_ROD); - ICOS.put("Berserk", Ico.DIASWORD); - ICOS.put("Archer", Ico.BOW); - ICOS.put("Healer", Ico.POTION); - - MSGS.add("???"); - MSGS.add("PRESS A TO JOIN"); - MSGS.add("Invite a friend!"); - MSGS.add("But nobody came."); - MSGS.add("More is better!"); - } + private static final List MSGS = List.of("???", "PRESS A TO JOIN", "Invite a friend!", "But nobody came.", "More is better!"); private final int player; @@ -74,7 +59,7 @@ public void updateContent(List ignored) { } else { Text name = Text.literal("Name: ").append(Text.literal(m.group("name")).formatted(Formatting.YELLOW)); - this.addComponent(new IcoTextComponent(Ico.PLAYER, name)); + this.addComponent(new PlayerComponent(PlayerListManager.getRaw(start), name)); String cl = m.group("class"); String level = m.group("level"); @@ -84,11 +69,11 @@ public void updateContent(List ignored) { Text.literal("Player is dead").formatted(Formatting.RED)); this.addComponent(ptc); } else { + DungeonClass dungeonClass = DungeonClass.from(cl); Formatting clf = Formatting.GRAY; - ItemStack cli = Ico.BARRIER; - if (!cl.equals("EMPTY")) { - cli = ICOS.get(cl); + ItemStack cli = dungeonClass.icon(); + if (dungeonClass != DungeonClass.UNKNOWN) { clf = Formatting.LIGHT_PURPLE; cl += " " + m.group("level"); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java index 0cbf5e5f06..e6586324fe 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java @@ -3,9 +3,9 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.PlayerSkinDrawer; import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.scoreboard.Team; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; /** * Component that consists of a player's skin icon and their name @@ -18,11 +18,14 @@ public class PlayerComponent extends Component { private final Identifier tex; public PlayerComponent(PlayerListEntry ple) { + this(ple, null); + } - name = ple.getDisplayName(); - tex = ple.getSkinTextures().texture(); + public PlayerComponent(PlayerListEntry ple, @Nullable Text name) { + this.name = name == null ? ple.getDisplayName() : name; + this.tex = ple.getSkinTextures().texture(); - this.width = SKIN_ICO_DIM + PAD_S + txtRend.getWidth(name); + this.width = SKIN_ICO_DIM + PAD_S + txtRend.getWidth(this.name); this.height = txtRend.fontHeight; } diff --git a/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java index dbe1f94f0b..868264c88b 100644 --- a/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.utils.container; -import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; @@ -133,14 +132,11 @@ public static boolean onSlotClick(int slot, ItemStack stack) { public static void onDraw(DrawContext context, GenericContainerScreen genericContainerScreen, List slots) { if (currentSolver == null) return; if (highlights == null) highlights = currentSolver.getColors(slotMap(currentSolver instanceof ContainerAndInventorySolver ? slots : slots.subList(0, genericContainerScreen.getScreenHandler().getRows() * 9))); - RenderSystem.enableDepthTest(); - RenderSystem.colorMask(true, true, true, false); for (ColorHighlight highlight : highlights) { Slot slot = slots.get(highlight.slot()); int color = highlight.color(); context.fill(slot.x, slot.y, slot.x + 16, slot.y + 16, color); } - RenderSystem.colorMask(true, true, true, true); } public static Int2ObjectMap slotMap(List slots) { diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 0a7dac78c4..3079ae8629 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -188,6 +188,7 @@ "skyblocker.config.dungeons.puzzle.solveBoulder.@Tooltip": "Draws a line to the chest and highlight button", "skyblocker.config.dungeons.puzzle.solveIceFill": "Solve Ice Fill Puzzle", "skyblocker.config.dungeons.puzzle.solveSilverfish": "Solve Silverfish Puzzle", + "skyblocker.config.dungeons.puzzle.solveTeleportMaze": "Solve Teleport Maze Puzzle", "skyblocker.config.dungeons.puzzle.solveThreeWeirdos": "Solve Three Weirdos Puzzle", "skyblocker.config.dungeons.puzzle.solveTicTacToe": "Solve Tic Tac Toe Puzzle", "skyblocker.config.dungeons.puzzle.solveTicTacToe.@Tooltip": "Puts a red box around the next best move for you to make!",