Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unbreakable carpet highlighter #1034

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import de.hysky.skyblocker.config.configs.MiningConfig;
import de.hysky.skyblocker.skyblock.dwarven.CrystalsHudConfigScreen;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHudConfigScreen;
import de.hysky.skyblocker.skyblock.dwarven.CarpetHighlighter;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.api.controller.ColorControllerBuilder;
import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder;
Expand Down Expand Up @@ -54,6 +55,25 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig
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())

//Dwarven HUD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public static class DwarvenMines {

@SerialEntry
public boolean solvePuzzler = true;

@SerialEntry
public boolean enableCarpetHighlighter = true;

@SerialEntry
public Color carpetHighlightColor = new Color(255, 0, 0, 76);
}

public static class DwarvenHud {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
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 int tickCounter = 0;
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, carpetLocation, CARPET_BOUNDING_BOX, colorComponents, colorComponents[3], false);
}
}

public void onLocationChange(Location location) {
isLocationValid = location == Location.DWARVEN_MINES;
}

public void tick() {
if (!isLocationValid || MinecraftClient.getInstance().world == null || MinecraftClient.getInstance().player == null) return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also check for whether the feature is enabled or not so that we are not locating carpets unnecessarily.

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();
}
}
5 changes: 5 additions & 0 deletions src/main/resources/assets/skyblocker/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@
"skyblocker.config.mining.dwarvenMines": "Dwarven Mines",
"skyblocker.config.mining.dwarvenMines.solveFetchur": "Solve Fetchur",
"skyblocker.config.mining.dwarvenMines.solvePuzzler": "Solve Puzzler Puzzle",
"skyblocker.config.mining.dwarvenMines.enableCarpetHighlight": "Enable Unbreakable Carpet Highlighter",
"skyblocker.config.mining.dwarvenMines.enableCarpetHighlight.@Tooltip": "Highlights unbreakable carpets within ore veins in the Dwarven Mines.",
"skyblocker.config.mining.dwarvenMines.carpetHighlightColor": "Carpet Highlight Color",
"skyblocker.config.mining.dwarvenMines.carpetHighlightColor.@Tooltip": "Sets the color of the highlight for the unbreakable carpets.",


"skyblocker.config.mining.enableDrillFuel": "Enable Drill Fuel",

Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/skyblocker.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ extendable method net/minecraft/client/gui/screen/recipebook/RecipeBookWidget re
extendable method net/minecraft/client/gui/screen/recipebook/RecipeBookWidget refreshTabButtons (Z)V
extendable method net/minecraft/client/gui/screen/recipebook/RecipeBookWidget refreshSearchResults ()V
extendable method net/minecraft/client/gui/screen/recipebook/RecipeBookWidget triggerPirateSpeakEasterEgg (Ljava/lang/String;)V

# Block Shapes
accessible field net/minecraft/block/CarpetBlock SHAPE Lnet/minecraft/util/shape/VoxelShape;