aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorKevin <92656833+kevinthegreat1@users.noreply.github.com>2025-01-25 12:58:23 -0500
committerGitHub <noreply@github.com>2025-01-26 01:58:23 +0800
commit23866b5e0e536b14f2e071bfe17bbe36a032bef1 (patch)
tree1d8f7cdf74dff774ce5fff9dc7d2a080eeafebfd /src/main/java
parent922313c645385901614a2642834d0276db73de27 (diff)
downloadSkyblocker-23866b5e0e536b14f2e071bfe17bbe36a032bef1.tar.gz
Skyblocker-23866b5e0e536b14f2e071bfe17bbe36a032bef1.tar.bz2
Skyblocker-23866b5e0e536b14f2e071bfe17bbe36a032bef1.zip
Add Teleport Maze Solver + small things (#1115)
* More dungeon class stuff * Player component * Add teleport maze solver * Fix quick nav button * Fix merge conflicts
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java5
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonClass.java24
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/TeleportMaze.java155
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretsTracker.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/quicknav/QuickNavButton.java47
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPlayerWidget.java29
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/component/PlayerComponent.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/container/ContainerSolverManager.java4
11 files changed, 246 insertions, 68 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 3fca9658..47abbb30 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 class DungeonsCategory {
newValue -> config.dungeons.puzzleSolvers.solveTrivia = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<Boolean>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 90457eea..27accd4a 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 class DungeonsConfig {
@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 75604f72..0bc9a393 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 @@ package de.hysky.skyblocker.mixins;
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.SmoothAOTE;
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.slayers.boss.demonlord.FirePillarAnnouncer;
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 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
* 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<BlockPos> 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<BlockPos> 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 d092de6e..6226fef1 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 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
@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 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen
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 9f52c414..285cc191 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.function.Function;
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<String, DungeonClass> 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 enum DungeonClass {
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 00000000..e9635bad
--- /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<BlockPos> 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<BlockPos> 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<BlockPos, RoomType> 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<RoomType> 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<BlockPos> 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<BlockPos, RoomType> 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<RoomType> 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 2cf700bb..e7e3230e 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 @@ public class SecretsTracker {
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 0512efd3..673538f4 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.Text;
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 class QuickNavButton extends ClickableWidget {
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 class QuickNavButton extends ClickableWidget {
} else {
MessageScheduler.INSTANCE.sendMessageAfterCooldown(command, true);
}
- this.alpha = 0.5f;
+ this.alpha = 0;
}
}
@@ -123,37 +134,25 @@ public class QuickNavButton extends ClickableWidget {
@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 ddda6924..14c06abc 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]+\\] )?(?<name>[A-Za-z0-9_]*) (?:.* )?\\((?<class>\\S*) ?(?<level>[LXVI]*)\\)");
- private static final HashMap<String, ItemStack> ICOS = new HashMap<>();
- private static final ArrayList<String> 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<String> 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 class DungeonPlayerWidget extends TabHudWidget {
} 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 class DungeonPlayerWidget extends TabHudWidget {
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 0cbf5e5f..e6586324 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 @@ package de.hysky.skyblocker.skyblock.tabhud.widget.component;
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 dbe1f94f..868264c8 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 class ContainerSolverManager {
public static void onDraw(DrawContext context, GenericContainerScreen genericContainerScreen, List<Slot> 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<ItemStack> slotMap(List<Slot> slots) {