diff options
| author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2025-06-02 17:14:22 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-02 17:14:22 -0400 |
| commit | 5638f2601d59791bbe802824ee14e1ecd7a547d3 (patch) | |
| tree | f09c3caf806e62f907ef9da9680b89cf21b36eca /src/main/java | |
| parent | 40469b22c22bec1af3517ec59d70575c91419c60 (diff) | |
| download | Skyblocker-5638f2601d59791bbe802824ee14e1ecd7a547d3.tar.gz Skyblocker-5638f2601d59791bbe802824ee14e1ecd7a547d3.tar.bz2 Skyblocker-5638f2601d59791bbe802824ee14e1ecd7a547d3.zip | |
Things (#1285)
* Generalize the Date Calculator
It should now be much easier to add other timers to this.
* Cylinder Rendering
* Add BaseRenderState
The beginning of a massive refactor
* Remove room matching option
This option only sparked confusion when people disabled it and wondered
why a lot of features stopped working.
* Changes
Diffstat (limited to 'src/main/java')
12 files changed, 167 insertions, 66 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 45356c01..200745bc 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -363,15 +363,6 @@ public class DungeonsCategory { .name(Text.translatable("skyblocker.config.dungeons.secretWaypoints")) .collapsed(true) .option(Option.<Boolean>createBuilder() - .name(Text.translatable("skyblocker.config.dungeons.secretWaypoints.enableRoomMatching")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.dungeons.secretWaypoints.enableRoomMatching.@Tooltip"))) - .binding(defaults.dungeons.secretWaypoints.enableRoomMatching, - () -> config.dungeons.secretWaypoints.enableRoomMatching, - newValue -> config.dungeons.secretWaypoints.enableRoomMatching = newValue) - .controller(ConfigUtils::createBooleanController) - .flag(OptionFlag.GAME_RESTART) - .build()) - .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.config.dungeons.secretWaypoints.enableSecretWaypoints")) .binding(defaults.dungeons.secretWaypoints.enableSecretWaypoints, () -> config.dungeons.secretWaypoints.enableSecretWaypoints, 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 4b2bf8c1..8b80f5ac 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/DungeonsConfig.java @@ -177,8 +177,8 @@ public class DungeonsConfig { } public static class SecretWaypoints { - @SerialEntry - public boolean enableRoomMatching = true; + @Deprecated + public transient boolean enableRoomMatching = true; @SerialEntry public boolean enableSecretWaypoints = true; diff --git a/src/main/java/de/hysky/skyblocker/debug/SnapshotDebug.java b/src/main/java/de/hysky/skyblocker/debug/SnapshotDebug.java index ba89d942..fb876bb4 100644 --- a/src/main/java/de/hysky/skyblocker/debug/SnapshotDebug.java +++ b/src/main/java/de/hysky/skyblocker/debug/SnapshotDebug.java @@ -6,13 +6,16 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; +import net.minecraft.util.Colors; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ColorHelper; import net.minecraft.util.math.Vec3d; public class SnapshotDebug { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); private static final float[] RED = { 1.0f, 0.0f, 0.0f }; private static final float ALPHA = 0.5f; + private static final int CYAN = ColorHelper.withAlpha(ColorHelper.channelFromFloat(ALPHA), Colors.CYAN); private static final float LINE_WIDTH = 8f; public static final long AARON_WORLD_SEED = 5629719634239627355L; @@ -32,6 +35,7 @@ public class SnapshotDebug { RenderHelper.renderLinesFromPoints(wrc, new Vec3d[] { new Vec3d(173, 66, -7.5), new Vec3d(178, 66, -7.5) }, RED, ALPHA, LINE_WIDTH, false); RenderHelper.renderQuad(wrc, new Vec3d[] { new Vec3d(183, 66, -16), new Vec3d(183, 63, -16), new Vec3d(183, 63, -14), new Vec3d(183, 66, -14) }, RED, ALPHA, false); RenderHelper.renderText(wrc, Text.of("Skyblocker on " + SharedConstants.getGameVersion().getName() + "!"), new Vec3d(175.5, 67.5, -7.5), false); + RenderHelper.renderCylinder(wrc, new BlockPos(172, 78, 44).toCenterPos(), 12, 12, 32, CYAN); } else if (isInSnapshot()) { RenderHelper.renderFilledWithBeaconBeam(wrc, new BlockPos(-3, 63, 5), RED, ALPHA, true); RenderHelper.renderOutline(wrc, new BlockPos(-3, 63, 5), RED, 5, true); // Use waypoint default line width 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 ba3d481a..3f425091 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 @@ -241,9 +241,7 @@ public class DungeonManager { @Init public static void init() { CUSTOM_WAYPOINTS_DIR = SkyblockerMod.CONFIG_DIR.resolve("custom_secret_waypoints.json"); - if (!SkyblockerConfigManager.get().dungeons.secretWaypoints.enableRoomMatching) { - return; - } + // Execute with MinecraftClient as executor since we need to wait for MinecraftClient#resourceManager to be set CompletableFuture.runAsync(DungeonManager::load, MinecraftClient.getInstance()).exceptionally(e -> { LOGGER.error("[Skyblocker Dungeon Secrets] Failed to load dungeon secrets", e); @@ -790,12 +788,12 @@ public class DungeonManager { } /** - * Checks if {@link DungeonsConfig.SecretWaypoints#enableRoomMatching room matching} is enabled and the player is in a dungeon. + * Checks if the player is in a dungeon. * * @return whether room matching and dungeon secrets should be processed */ private static boolean shouldProcess() { - return SkyblockerConfigManager.get().dungeons.secretWaypoints.enableRoomMatching && Utils.isInDungeons(); + return Utils.isInDungeons(); } /** diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java index 32ccf8e3..6c0d93ed 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java @@ -46,7 +46,7 @@ public class TooltipManager { new MuseumTooltip(11), new ColorTooltip(12), new AccessoryTooltip(13), - new CalendarStartTimeTooltip(14) + new DateCalculatorTooltip(14) }; private static final ArrayList<TooltipAdder> currentScreenAdders = new ArrayList<>(); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CalendarStartTimeTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CalendarStartTimeTooltip.java deleted file mode 100644 index d3c0aa1e..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CalendarStartTimeTooltip.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.hysky.skyblocker.skyblock.item.tooltip.adders; - -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.item.tooltip.SimpleTooltipAdder; -import de.hysky.skyblocker.utils.Formatters; -import de.hysky.skyblocker.utils.RegexUtils; -import net.minecraft.item.ItemStack; -import net.minecraft.screen.slot.Slot; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import org.jetbrains.annotations.Nullable; - -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class CalendarStartTimeTooltip extends SimpleTooltipAdder { - private static final Pattern TIMER_PATTERN = Pattern.compile(".*(Starts in: |\\()((?<days>\\d+)d)? ?((?<hours>\\d+)h)? ?((?<minutes>\\d+)m)? ?((?<seconds>\\d+)s)?\\)?"); - - public CalendarStartTimeTooltip(int priority) { - super("(Calendar and Events|.*?, Year \\d+.*)", priority); - } - - @Override - public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { - for (int i = 1; i < lines.size(); i++) { - Matcher matcher = TIMER_PATTERN.matcher(lines.get(i).getString()); - if (matcher.matches()) { - Instant instant = Instant.now() - .plus(RegexUtils.parseOptionalIntFromMatcher(matcher, "days").orElse(0), ChronoUnit.DAYS) - .plus(RegexUtils.parseOptionalIntFromMatcher(matcher, "hours").orElse(0), ChronoUnit.HOURS) - .plus(RegexUtils.parseOptionalIntFromMatcher(matcher, "minutes").orElse(0), ChronoUnit.MINUTES) - .plusSeconds(RegexUtils.parseOptionalIntFromMatcher(matcher, "seconds").orElse(0)) - .plusSeconds(30) // Add 30 seconds to round to the nearest minute - .truncatedTo(ChronoUnit.MINUTES); - - lines.add(++i, Text.literal(Formatters.DATE_FORMATTER.format(instant)).formatted(Formatting.ITALIC, Formatting.DARK_GRAY)); - } - } - } - - @Override - public boolean isEnabled() { - return SkyblockerConfigManager.get().helpers.enableDateCalculator; - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DateCalculatorTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DateCalculatorTooltip.java new file mode 100644 index 00000000..2de35a46 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/DateCalculatorTooltip.java @@ -0,0 +1,101 @@ +package de.hysky.skyblocker.skyblock.item.tooltip.adders; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.item.tooltip.SimpleTooltipAdder; +import de.hysky.skyblocker.utils.Formatters; +import de.hysky.skyblocker.utils.RegexUtils; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.function.Predicate; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DateCalculatorTooltip extends SimpleTooltipAdder { + //((?<days>\d+)d)? ?((?<hours>\d+)h)? ?((?<minutes>\d+)m)? ?((?<seconds>\d+)s)? + private static final Pattern TIMER_PATTERN = Pattern.compile("((?<days>\\d+)d)? ?((?<hours>\\d+)h)? ?((?<minutes>\\d+)m)? ?((?<seconds>\\d+)s)?"); + private Timer currentTimer; + + public DateCalculatorTooltip(int priority) { + super(priority); + } + + @Override + public boolean test(@NotNull Screen screen) { + for (Timer timer : Timer.values()) { + Matcher matcher = timer.titlePattern.matcher(screen.getTitle().getString()); + + if (matcher.matches()) { + currentTimer = timer; + return true; + } + } + + currentTimer = null; + return false; + } + + @Override + public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) { + if (currentTimer == null) return; + + for (int i = 1; i < lines.size(); i++) { + String text = lines.get(i).getString(); + + //Only attempt to look for a timer if the line contains the qualifying text + if (!currentTimer.qualifier.test(text)) continue; + + MatchResult result = TIMER_PATTERN.matcher(text).results() + .filter(DateCalculatorTooltip::hasAnyGroup) //Look for the first match that has what we're looking for + .findFirst() + .orElse(null); + + if (result != null) { + Instant instant = Instant.now() + .plus(RegexUtils.parseOptionalIntFromMatcher(result, "days").orElse(0), ChronoUnit.DAYS) + .plus(RegexUtils.parseOptionalIntFromMatcher(result, "hours").orElse(0), ChronoUnit.HOURS) + .plus(RegexUtils.parseOptionalIntFromMatcher(result, "minutes").orElse(0), ChronoUnit.MINUTES) + .plusSeconds(RegexUtils.parseOptionalIntFromMatcher(result, "seconds").orElse(0)) + .plusSeconds(30) // Add 30 seconds to round to the nearest minute + .truncatedTo(ChronoUnit.MINUTES); + + lines.add(++i, Text.literal(Formatters.DATE_FORMATTER.format(instant)).formatted(Formatting.ITALIC, Formatting.DARK_GRAY)); + } + } + } + + private static boolean hasAnyGroup(MatchResult result) { + for (String group : result.namedGroups().keySet()) { + if (result.group(group) != null) return true; + } + + return false; + } + + @Override + public boolean isEnabled() { + return SkyblockerConfigManager.get().helpers.enableDateCalculator; + } + + private enum Timer { + CALENDAR("(Calendar and Events|.*?, Year \\d+.*)", l -> l.contains("Starts in:") || l.contains(" (")); //Calendar start time + + private final Pattern titlePattern; + private final Predicate<String> qualifier; + + Timer(String title, Predicate<String> qualifier) { + this.titlePattern = Pattern.compile(title); + this.qualifier = qualifier; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/RegexUtils.java b/src/main/java/de/hysky/skyblocker/utils/RegexUtils.java index 866d510e..4fe4b047 100644 --- a/src/main/java/de/hysky/skyblocker/utils/RegexUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/RegexUtils.java @@ -3,6 +3,7 @@ package de.hysky.skyblocker.utils; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; +import java.util.regex.MatchResult; import java.util.regex.Matcher; public class RegexUtils { @@ -42,7 +43,7 @@ public class RegexUtils { return OptionalInt.of(Integer.parseInt(s.replace(",", ""))); } - public static OptionalInt parseOptionalIntFromMatcher(Matcher matcher, String group) { + public static OptionalInt parseOptionalIntFromMatcher(MatchResult matcher, String group) { String s = matcher.group(group); if (s == null) return OptionalInt.empty(); return OptionalInt.of(Integer.parseInt(s.replace(",", ""))); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java index 6e9f0363..f43d0af9 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java @@ -310,6 +310,36 @@ public class RenderHelper { } /** + * Renders a cylinder without the top or bottom faces. + * + * @param pos The position that the cylinder will be centred around. + * @param height The total height of the cylinder with {@code pos} as the midpoint. + * @param segments The amount of triangles used to approximate the circle. + */ + public static void renderCylinder(WorldRenderContext context, Vec3d centre, float radius, float height, int segments, int color) { + MatrixStack matrices = context.matrixStack(); + Vec3d camera = context.camera().getPos(); + + matrices.push(); + matrices.translate(-camera.x, -camera.y, -camera.z); + + VertexConsumer buffer = context.consumers().getBuffer(SkyblockerRenderLayers.CYLINDER); + Matrix4f positionMatrix = matrices.peek().getPositionMatrix(); + float halfHeight = height / 2.0f; + + for (int i = 0; i <= segments; i++) { + double angle = Math.TAU * i / segments; + float dx = (float) Math.cos(angle) * radius; + float dz = (float) Math.sin(angle) * radius; + + buffer.vertex(positionMatrix, (float) centre.getX() + dx, (float) centre.getY() + halfHeight, (float) centre.getZ() + dz).color(color); + buffer.vertex(positionMatrix, (float) centre.getX() + dx, (float) centre.getY() - halfHeight, (float) centre.getZ() + dz).color(color); + } + + matrices.pop(); + } + + /** * This is called after all {@link WorldRenderEvents#AFTER_TRANSLUCENT} listeners have been called so that we can draw all remaining render layers. */ private static void drawTranslucents(WorldRenderContext context) { diff --git a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java index 3299c538..a87d9cbc 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java @@ -58,6 +58,9 @@ public class SkyblockerRenderLayers { .texture(new RenderPhase.Texture(texture, TriState.FALSE, false)) .layering(RenderPhase.VIEW_OFFSET_Z_LAYERING) .build(false)); + public static final MultiPhase CYLINDER = RenderLayer.of("cylinder", RenderLayer.DEFAULT_BUFFER_SIZE, false, true, SkyblockerRenderPipelines.CYLINDER, MultiPhaseParameters.builder() + .layering(RenderPhase.VIEW_OFFSET_Z_LAYERING) + .build(false)); public static MultiPhase getLines(double lineWidth) { return LINES_LAYERS.computeIfAbsent(lineWidth, LINES); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderPipelines.java b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderPipelines.java index e992c3be..cbd73e1c 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderPipelines.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderPipelines.java @@ -38,6 +38,11 @@ public class SkyblockerRenderPipelines { .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) .withCull(false) .build()); + static final RenderPipeline CYLINDER = RenderPipelines.register(RenderPipeline.builder(RenderPipelines.POSITION_COLOR_SNIPPET) + .withLocation(Identifier.of(SkyblockerMod.NAMESPACE, "pipeline/cylinder")) + .withVertexFormat(VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP) + .withCull(false) + .build()); @Init public static void init() {} //Ensure that pipelines are pre-compiled instead of compiled on demand diff --git a/src/main/java/de/hysky/skyblocker/utils/render/state/SkyblockerRenderState.java b/src/main/java/de/hysky/skyblocker/utils/render/state/SkyblockerRenderState.java new file mode 100644 index 00000000..3f3139c8 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/state/SkyblockerRenderState.java @@ -0,0 +1,16 @@ +package de.hysky.skyblocker.utils.render.state; + +/** + * Render states define the necessary properties for a subject to be rendered. + * + * Each field inside of a render state must be: + * - Immutable (until the subject is rendered) + * - Thread safe + * - Fast to create (ideally just settings and properties, no code or anything too complex) + * + * Render states may be reused and updated after the subject has completed rendering provided the conditions + * listed above always remain true. + */ +public class SkyblockerRenderState { + public boolean enabled; +} |
