diff options
| author | Rime <81419447+Emirlol@users.noreply.github.com> | 2024-12-24 06:44:05 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-23 22:44:05 -0500 |
| commit | 6cf640e935c300ed7252f9f593387b945242404b (patch) | |
| tree | 5763e85268b0d2eb364b2ca53473bad8d02c80b6 /src/main/java/de/hysky | |
| parent | 23f986b6807eaecefb0cf4709b2dec67bd7eb1f2 (diff) | |
| download | Skyblocker-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')
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(); + } +} |
