aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky
diff options
context:
space:
mode:
authorRime <81419447+Emirlol@users.noreply.github.com>2024-12-24 06:44:05 +0300
committerGitHub <noreply@github.com>2024-12-23 22:44:05 -0500
commit6cf640e935c300ed7252f9f593387b945242404b (patch)
tree5763e85268b0d2eb364b2ca53473bad8d02c80b6 /src/main/java/de/hysky
parent23f986b6807eaecefb0cf4709b2dec67bd7eb1f2 (diff)
downloadSkyblocker-6cf640e935c300ed7252f9f593387b945242404b.tar.gz
Skyblocker-6cf640e935c300ed7252f9f593387b945242404b.tar.bz2
Skyblocker-6cf640e935c300ed7252f9f593387b945242404b.zip
Add unbreakable carpet highlighter (#1034)
* Add mithril carpet highlighter * Make mithril carpet highlighter configurable * Halve the required getBlockState calls * Add light blue carpet as a possible carpet block * Add tungsten carpets and rename carpet highlighter Because apparently it's not limited to mithril * AVLTreeSet instead of ArraySet * Use scheduleCyclic instead of END_CLIENT_TICK event * Check if the feature is enabled before ticking * Fix rebase artifacts * Remove unused variable
Diffstat (limited to 'src/main/java/de/hysky')
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java20
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/CarpetHighlighter.java103
3 files changed, 129 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java
index 4fc05692..34364368 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/MiningCategory.java
@@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.configs.MiningConfig;
import de.hysky.skyblocker.skyblock.dwarven.CrystalsHudWidget;
+import de.hysky.skyblocker.skyblock.dwarven.CarpetHighlighter;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.api.controller.ColorControllerBuilder;
import de.hysky.skyblocker.skyblock.tabhud.config.WidgetsConfigurationScreen;
@@ -55,6 +56,25 @@ public class MiningCategory {
newValue -> config.mining.dwarvenMines.solvePuzzler = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.mining.dwarvenMines.enableCarpetHighlight"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.dwarvenMines.enableCarpetHighlight.@Tooltip")))
+ .binding(defaults.mining.dwarvenMines.enableCarpetHighlighter,
+ () -> config.mining.dwarvenMines.enableCarpetHighlighter,
+ newValue -> config.mining.dwarvenMines.enableCarpetHighlighter = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Color>createBuilder()
+ .name(Text.translatable("skyblocker.config.mining.dwarvenMines.carpetHighlightColor"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.mining.dwarvenMines.carpetHighlightColor.@Tooltip")))
+ .binding(defaults.mining.dwarvenMines.carpetHighlightColor,
+ () -> config.mining.dwarvenMines.carpetHighlightColor,
+ newValue -> {
+ config.mining.dwarvenMines.carpetHighlightColor = newValue;
+ CarpetHighlighter.INSTANCE.configCallback(newValue);
+ })
+ .controller(opt -> ColorControllerBuilder.create(opt).allowAlpha(true))
+ .build())
.build())
//Crystal Hollows
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java
index 4691047c..0eb76f22 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/MiningConfig.java
@@ -39,6 +39,12 @@ public class MiningConfig {
@SerialEntry
public boolean solvePuzzler = true;
+
+ @SerialEntry
+ public boolean enableCarpetHighlighter = true;
+
+ @SerialEntry
+ public Color carpetHighlightColor = new Color(255, 0, 0, 76);
}
@Deprecated
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CarpetHighlighter.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CarpetHighlighter.java
new file mode 100644
index 00000000..6395e704
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/CarpetHighlighter.java
@@ -0,0 +1,103 @@
+package de.hysky.skyblocker.skyblock.dwarven;
+
+import de.hysky.skyblocker.annotations.Init;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.events.SkyblockEvents;
+import de.hysky.skyblocker.utils.Boxes;
+import de.hysky.skyblocker.utils.Location;
+import de.hysky.skyblocker.utils.Resettable;
+import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.render.Renderable;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet;
+import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.CarpetBlock;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Vec3d;
+
+import java.awt.*;
+
+/**
+ * Highlights unbreakable carpets within ore veins in the Dwarven Mines.
+ */
+public final class CarpetHighlighter implements Renderable, Resettable {
+ public static final CarpetHighlighter INSTANCE = new CarpetHighlighter();
+
+ private static final Vec3d CARPET_BOUNDING_BOX = Boxes.getLengthVec(CarpetBlock.SHAPE.getBoundingBox());
+ private static final int SEARCH_RADIUS = 15;
+ private static final int TICK_INTERVAL = 15;
+ private static final ObjectAVLTreeSet<BlockPos> CARPET_LOCATIONS = new ObjectAVLTreeSet<>();
+ private static float[] colorComponents;
+ private static boolean isLocationValid = false;
+
+ @Init
+ public static void init() {
+ INSTANCE.configCallback(SkyblockerConfigManager.get().mining.dwarvenMines.carpetHighlightColor);
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(INSTANCE::render);
+ SkyblockEvents.LOCATION_CHANGE.register(INSTANCE::onLocationChange);
+ Scheduler.INSTANCE.scheduleCyclic(INSTANCE::tick, TICK_INTERVAL);
+ ClientPlayConnectionEvents.JOIN.register(INSTANCE);
+ }
+
+ @Override
+ public void render(WorldRenderContext context) {
+ if (!isLocationValid || !SkyblockerConfigManager.get().mining.dwarvenMines.enableCarpetHighlighter) return;
+ for (BlockPos carpetLocation : CARPET_LOCATIONS) {
+ RenderHelper.renderFilled(context, Vec3d.of(carpetLocation), CARPET_BOUNDING_BOX, colorComponents, colorComponents[3], false);
+ }
+ }
+
+ public void onLocationChange(Location location) {
+ isLocationValid = location == Location.DWARVEN_MINES;
+ }
+
+ public void tick() {
+ if (!isLocationValid || !SkyblockerConfigManager.get().mining.dwarvenMines.enableCarpetHighlighter || MinecraftClient.getInstance().world == null || MinecraftClient.getInstance().player == null) return;
+ Iterable<BlockPos> iterable = BlockPos.iterateOutwards(MinecraftClient.getInstance().player.getBlockPos(), SEARCH_RADIUS, SEARCH_RADIUS, SEARCH_RADIUS);
+ for (BlockPos blockPos : iterable) {
+ //The iterator contains a BlockPos.Mutable that it changes the position of to iterate over blocks,
+ // so it has to be converted to an immutable BlockPos or the position will change based on the player's position && the search radius
+ if (checkForCarpet(blockPos)) CARPET_LOCATIONS.add(blockPos.toImmutable());
+ }
+ }
+
+ /**
+ * @param blockPos The position to check for a carpet
+ * @return Whether the block at the given position is a gray carpet with a sea lantern below it, which is how all unbreakable carpets are placed
+ * @implNote <p>getBlockState is a heavy method, so this method will become a hot spot as the search radius increases || the tick interval decreases.</p>
+ * <p>Consider profiling this method if either of those values are changed.</p>
+ */
+ private boolean checkForCarpet(BlockPos blockPos) {
+ @SuppressWarnings("DataFlowIssue") // Null check is already done in the run method
+ BlockState actualBlock = MinecraftClient.getInstance().world.getBlockState(blockPos);
+ // Gray/light blue - mithril
+ // Light gray - tungsten
+ // There are other colors for some ores in the royal mines,
+ // but since the actual ores don't include wool blocks
+ // they're not easily confused as ores so they are not accounted for here
+ if (!(actualBlock.isOf(Blocks.GRAY_CARPET) ||
+ actualBlock.isOf(Blocks.LIGHT_BLUE_CARPET) ||
+ actualBlock.isOf(Blocks.LIGHT_GRAY_CARPET))) return false;
+ BlockState blockBelow = MinecraftClient.getInstance().world.getBlockState(blockPos.down());
+ return blockBelow.isOf(Blocks.SEA_LANTERN);
+ }
+
+ /**
+ * <p>Caches the color components from the given color for rendering to avoid recalculating them every frame.</p>
+ * <p>Called by the {@link de.hysky.skyblocker.config.categories.MiningCategory MiningCategory} > carpetHighlightColor when the color is updated.</p>
+ */
+ public void configCallback(Color color) {
+ colorComponents = color.getRGBComponents(null);
+ }
+
+ @Override
+ public void reset() {
+ isLocationValid = false;
+ CARPET_LOCATIONS.clear();
+ }
+}