aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils')
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ApiUtils.java53
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Constants.java48
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Http.java68
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java79
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java (renamed from src/main/java/de/hysky/skyblocker/utils/NEURepo.java)32
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java49
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java114
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java21
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java99
9 files changed, 453 insertions, 110 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
new file mode 100644
index 00000000..c0648eba
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
@@ -0,0 +1,53 @@
+package de.hysky.skyblocker.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.JsonParser;
+import com.mojang.util.UndashedUuid;
+
+import de.hysky.skyblocker.utils.Http.ApiResponse;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.session.Session;
+
+/*
+ * Contains only basic helpers for using Http APIs
+ */
+public class ApiUtils {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApiUtils.class);
+ /**
+ * Do not iterate over this map, it will be accessed and modified by multiple threads.
+ */
+ private static final Object2ObjectOpenHashMap<String, String> NAME_2_UUID_CACHE = new Object2ObjectOpenHashMap<>();
+
+ public static void init() {
+ //Clear cache every 20 minutes
+ Scheduler.INSTANCE.scheduleCyclic(NAME_2_UUID_CACHE::clear, 24_000, true);
+ }
+
+ /**
+ * Multithreading is to be handled by the method caller
+ */
+ public static String name2Uuid(String name) {
+ Session session = MinecraftClient.getInstance().getSession();
+
+ if (session.getUsername().equals(name)) return UndashedUuid.toString(session.getUuidOrNull());
+ if (NAME_2_UUID_CACHE.containsKey(name)) return NAME_2_UUID_CACHE.get(name);
+
+ try (ApiResponse response = Http.sendName2UuidRequest(name)) {
+ if (response.ok()) {
+ String uuid = JsonParser.parseString(response.content()).getAsJsonObject().get("id").getAsString();
+
+ NAME_2_UUID_CACHE.put(name, uuid);
+
+ return uuid;
+ }
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker] Name to uuid lookup failed! Name: {}", name, e);
+ }
+
+ return "";
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Constants.java b/src/main/java/de/hysky/skyblocker/utils/Constants.java
index fbeb448c..94eacf49 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Constants.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Constants.java
@@ -1,8 +1,56 @@
package de.hysky.skyblocker.utils;
+import java.util.List;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Style;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
/**
* Holds generic static constants
*/
public interface Constants {
String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u12DE";
+ IntFunction<UnaryOperator<Style>> WITH_COLOR = color -> style -> style.withColor(color);
+ Supplier<MutableText> PREFIX = () -> Text.empty()
+ .append(Text.literal("[").formatted(Formatting.GRAY))
+ .append(Text.literal("S").styled(WITH_COLOR.apply(0x00ff4c)))
+ .append(Text.literal("k").styled(WITH_COLOR.apply(0x02fa60)))
+ .append(Text.literal("y").styled(WITH_COLOR.apply(0x04f574)))
+ .append(Text.literal("b").styled(WITH_COLOR.apply(0x07ef88)))
+ .append(Text.literal("l").styled(WITH_COLOR.apply(0x09ea9c)))
+ .append(Text.literal("o").styled(WITH_COLOR.apply(0x0be5af)))
+ .append(Text.literal("c").styled(WITH_COLOR.apply(0x0de0c3)))
+ .append(Text.literal("k").styled(WITH_COLOR.apply(0x10dad7)))
+ .append(Text.literal("e").styled(WITH_COLOR.apply(0x12d5eb)))
+ .append(Text.literal("r").styled(WITH_COLOR.apply(0x14d0ff)))
+ .append(Text.literal("] ").formatted(Formatting.GRAY));
+
+
+ List<String> SEYMOUR_IDS = List.of("VELVET_TOP_HAT", "CASHMERE_JACKET", "SATIN_TROUSERS", "OXFORD_SHOES");
+
+ // Exotic Hexes
+ List<String> CRYSTAL_HEXES = List.of("1F0030", "46085E", "54146E", "5D1C78", "63237D", "6A2C82", "7E4196", "8E51A6", "9C64B3", "A875BD",
+ "B88BC9", "C6A3D4", "D9C1E3", "E5D1ED", "EFE1F5", "FCF3FF");
+ List<String> FAIRY_HEXES = List.of("330066", "4C0099", "660033", "660066", "6600CC", "7F00FF", "99004C", "990099", "9933FF", "B266FF",
+ "CC0066", "CC00CC", "CC99FF", "E5CCFF", "FF007F", "FF00FF", "FF3399", "FF33FF", "FF66B2", "FF66FF", "FF99CC", "FF99FF", "FFCCE5",
+ "FFCCFF");
+ List<String> OG_FAIRY_HEXES = List.of("FF99FF", "FFCCFF", "E5CCFF", "CC99FF", "CC00CC", "FF00FF", "FF33FF", "FF66FF",
+ "B266FF", "9933FF", "7F00FF", "660066", "6600CC", "4C0099", "330066", "990099", "660033", "99004C", "CC0066",
+ "660033", "99004C", "FFCCE5", "660033", "FFCCE5", "FF99CC", "FFCCE5", "FF99CC", "FF66B2");
+ List<String> GLITCHED = List.of("FFDC51", "F7DA33", "606060", "E7413C", "45413C", "4A14B7", "1793C4", "000000", "E75C3C", "65605A",
+ "5D2FB9", "17A8C4", "E76E3C", "88837E", "8969C8", "1CD4E4"); // Glitched through other means such as Shark Scale upgrade color
+ List<String> SPOOK = List.of("000000", "070008", "0E000F", "150017", "1B001F", "220027", "29002E", "300036", "37003E", "3E0046",
+ "45004D", "4C0055", "52005D", "590065", "60006C", "670074", "6E007C", "750084", "7C008B", "830093",
+ "89009B", "9000A3", "9700AA", "993399", "9E00B2");
+
+ // List of exceptions
+ List<String> RANCHERS = List.of("CC5500", "000000", "0");
+ List<String> REAPER = List.of("1B1B1B", "FF0000");
+ List<String> ADAPTIVE_CHEST = List.of("3ABE78", "82E3D8", "BFBCB2", "D579FF", "FF4242", "FFC234");
+ List<String> ADAPTIVE = List.of("169F57", "2AB5A5", "6E00A0", "BB0000", "BFBCB2", "FFF7E6");
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Http.java b/src/main/java/de/hysky/skyblocker/utils/Http.java
index e0b9ecf8..4c8a3ada 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Http.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Http.java
@@ -5,6 +5,7 @@ import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.http.HttpClient;
+import java.net.http.HttpClient.Redirect;
import java.net.http.HttpClient.Version;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
@@ -15,6 +16,8 @@ import java.time.Duration;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
+import org.jetbrains.annotations.NotNull;
+
import de.hysky.skyblocker.SkyblockerMod;
import net.minecraft.SharedConstants;
@@ -22,12 +25,19 @@ import net.minecraft.SharedConstants;
* @implNote All http requests are sent using HTTP 2
*/
public class Http {
+ private static final String NAME_2_UUID = "https://api.minecraftservices.com/minecraft/profile/lookup/name/";
+ private static final String HYPIXEL_PROXY = "https://hysky.de/api/hypixel/";
private static final String USER_AGENT = "Skyblocker/" + SkyblockerMod.VERSION + " (" + SharedConstants.getGameVersion().getName() + ")";
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
+ .followRedirects(Redirect.NORMAL)
.build();
public static String sendGetRequest(String url) throws IOException, InterruptedException {
+ return sendCacheableGetRequest(url).content();
+ }
+
+ private static ApiResponse sendCacheableGetRequest(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Accept", "application/json")
@@ -39,9 +49,11 @@ public class Http {
HttpResponse<InputStream> response = HTTP_CLIENT.send(request, BodyHandlers.ofInputStream());
InputStream decodedInputStream = getDecodedInputStream(response);
+
String body = new String(decodedInputStream.readAllBytes());
+ HttpHeaders headers = response.headers();
- return body;
+ return new ApiResponse(body, response.statusCode(), getCacheStatus(headers), getAge(headers));
}
public static HttpHeaders sendHeadRequest(String url) throws IOException, InterruptedException {
@@ -52,13 +64,26 @@ public class Http {
.uri(URI.create(url))
.build();
- HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
+ HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
return response.headers();
}
- private static InputStream getDecodedInputStream(HttpResponse<InputStream> response) {
- String encoding = getContentEncoding(response);
+ public static ApiResponse sendName2UuidRequest(String name) throws IOException, InterruptedException {
+ return sendCacheableGetRequest(NAME_2_UUID + name);
+ }
+ /**
+ * @param endpoint the endpoint - do not include any leading or trailing slashes
+ * @param query the query string - use empty string if n/a
+ * @return the requested data with zero pre-processing applied
+ */
+ public static ApiResponse sendHypixelRequest(String endpoint, @NotNull String query) throws IOException, InterruptedException {
+ return sendCacheableGetRequest(HYPIXEL_PROXY + endpoint + query);
+ }
+
+ private static InputStream getDecodedInputStream(HttpResponse<InputStream> response) {
+ String encoding = getContentEncoding(response.headers());
+
try {
switch (encoding) {
case "":
@@ -75,8 +100,8 @@ public class Http {
}
}
- private static String getContentEncoding(HttpResponse<InputStream> response) {
- return response.headers().firstValue("Content-Encoding").orElse("");
+ private static String getContentEncoding(HttpHeaders headers) {
+ return headers.firstValue("Content-Encoding").orElse("");
}
public static String getEtag(HttpHeaders headers) {
@@ -86,4 +111,35 @@ public class Http {
public static String getLastModified(HttpHeaders headers) {
return headers.firstValue("Last-Modified").orElse("");
}
+
+ /**
+ * Returns the cache status of the resource
+ *
+ * @see <a href="https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#cloudflare-cache-responses">Cloudflare Cache Docs</a>
+ */
+ private static String getCacheStatus(HttpHeaders headers) {
+ return headers.firstValue("CF-Cache-Status").orElse("UNKNOWN");
+ }
+
+ private static int getAge(HttpHeaders headers) {
+ return Integer.parseInt(headers.firstValue("Age").orElse("-1"));
+ }
+
+ //TODO If ever needed, we could just replace cache status with the response headers and go from there
+ public record ApiResponse(String content, int statusCode, String cacheStatus, int age) implements AutoCloseable {
+
+ public boolean ok() {
+ return statusCode == 200;
+ }
+
+ public boolean cached() {
+ return cacheStatus.equals("HIT");
+ }
+
+ @Override
+ public void close() {
+ //Allows for nice syntax when dealing with api requests in try catch blocks
+ //Maybe one day we'll have some resources to free
+ }
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
index fa04acf8..ed46677d 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.utils;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.ItemStack;
@@ -12,34 +12,34 @@ import net.minecraft.util.Formatting;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.function.Predicate;
import java.util.regex.Pattern;
public class ItemUtils {
- private final static Pattern WHITESPACES = Pattern.compile("^\\s*$");
public static final String EXTRA_ATTRIBUTES = "ExtraAttributes";
public static final String ID = "id";
public static final String UUID = "uuid";
+ public static final Pattern NOT_DURABILITY = Pattern.compile("[^0-9 /]");
+ public static final Predicate<String> FUEL_PREDICATE = line -> line.contains("Fuel: ");
- public static List<Text> getTooltip(ItemStack item) {
+ public static List<Text> getTooltips(ItemStack item) {
MinecraftClient client = MinecraftClient.getInstance();
return client.player == null || item == null ? Collections.emptyList() : item.getTooltip(client.player, TooltipContext.Default.BASIC);
}
- public static List<String> getTooltipStrings(ItemStack item) {
- List<Text> lines = getTooltip(item);
- List<String> list = new ArrayList<>();
-
- for (Text line : lines) {
+ @Nullable
+ public static String getTooltip(ItemStack item, Predicate<String> predicate) {
+ for (Text line : getTooltips(item)) {
String string = line.getString();
- if (!WHITESPACES.matcher(string).matches())
- list.add(string);
+ if (predicate.test(string)) {
+ return string;
+ }
}
- return list;
+ return null;
}
/**
@@ -98,49 +98,35 @@ public class ItemUtils {
* Gets the UUID of the item stack from the {@code ExtraAttributes} NBT tag.
*
* @param stack the item stack to get the UUID from
- * @return the UUID of the item stack, or null if the item stack is null or does not have a UUID
+ * @return the UUID of the item stack, or an empty string if the item stack is null or does not have a UUID
*/
public static String getItemUuid(@NotNull ItemStack stack) {
NbtCompound extraAttributes = getExtraAttributes(stack);
return extraAttributes != null ? extraAttributes.getString(UUID) : "";
}
+ public static boolean hasCustomDurability(@NotNull ItemStack stack) {
+ NbtCompound extraAttributes = getExtraAttributes(stack);
+ return extraAttributes != null && (extraAttributes.contains("drill_fuel") || extraAttributes.getString(ID).equals("PICKONIMBUS"));
+ }
+
@Nullable
- public static Durability getDurability(@NotNull ItemStack stack) {
- if (!Utils.isOnSkyblock() || !SkyblockerConfigManager.get().locations.dwarvenMines.enableDrillFuel || stack.isEmpty()) {
- return null;
- }
+ public static IntIntPair getDurability(@NotNull ItemStack stack) {
+ NbtCompound extraAttributes = getExtraAttributes(stack);
+ if (extraAttributes == null) return null;
+
+ // TODO Calculate drill durability based on the drill_fuel flag, fuel_tank flag, and hotm level
+ // TODO Cache the max durability and only update the current durability on inventory tick
- if (getExtraAttributesOptional(stack).filter(extraAttributes -> extraAttributes.contains("drill_fuel") || extraAttributes.getString(ItemUtils.ID).equals("PICKONIMBUS")).isEmpty()) {
- return null;
+ int pickonimbusDurability = extraAttributes.getInt("pickonimbus_durability");
+ if (pickonimbusDurability > 0) {
+ return IntIntPair.of(pickonimbusDurability, 5000);
}
- int current = 0;
- int max = 0;
- String clearFormatting;
-
- for (String line : ItemUtils.getTooltipStrings(stack)) {
- clearFormatting = Formatting.strip(line);
- if (line.contains("Fuel: ")) {
- if (clearFormatting != null) {
- String clear = Pattern.compile("[^0-9 /]").matcher(clearFormatting).replaceAll("").trim();
- String[] split = clear.split("/");
- current = Integer.parseInt(split[0]);
- max = Integer.parseInt(split[1]) * 1000;
- return new Durability(current, max);
- }
- } else if (line.contains("uses.")) {
- if (clearFormatting != null) {
- int startIndex = clearFormatting.lastIndexOf("after") + 6;
- int endIndex = clearFormatting.indexOf("uses", startIndex);
- if (startIndex >= 0 && endIndex > startIndex) {
- String usesString = clearFormatting.substring(startIndex, endIndex).trim();
- current = Integer.parseInt(usesString);
- max = 5000;
- }
- return new Durability(current, max);
- }
- }
+ String drillFuel = Formatting.strip(getTooltip(stack, FUEL_PREDICATE));
+ if (drillFuel != null) {
+ String[] drillFuelStrings = NOT_DURABILITY.matcher(drillFuel).replaceAll("").trim().split("/");
+ return IntIntPair.of(Integer.parseInt(drillFuelStrings[0]), Integer.parseInt(drillFuelStrings[1]) * 1000);
}
return null;
@@ -153,7 +139,4 @@ public class ItemUtils {
throw new RuntimeException(e);
}
}
-
- public record Durability(int current, int max) {
- }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepo.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
index 9bc6b245..6d78b3f3 100644
--- a/src/main/java/de/hysky/skyblocker/utils/NEURepo.java
+++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
@@ -1,7 +1,8 @@
package de.hysky.skyblocker.utils;
import de.hysky.skyblocker.SkyblockerMod;
-import de.hysky.skyblocker.skyblock.itemlist.ItemRegistry;
+import de.hysky.skyblocker.skyblock.itemlist.ItemRepository;
+import io.github.moulberry.repo.NEURepository;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.minecraft.client.MinecraftClient;
@@ -21,11 +22,15 @@ import java.util.concurrent.CompletableFuture;
/**
* Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized.
*/
-public class NEURepo {
- private static final Logger LOGGER = LoggerFactory.getLogger(NEURepo.class);
+public class NEURepoManager {
+ private static final Logger LOGGER = LoggerFactory.getLogger(NEURepoManager.class);
public static final String REMOTE_REPO_URL = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO.git";
- public static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo");
- private static final CompletableFuture<Void> REPO_INITIALIZED = initRepository();
+ /**
+ * Use {@link #NEU_REPO}.
+ */
+ private static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo"); // TODO rename to NotEnoughUpdates-REPO
+ private static final CompletableFuture<Void> REPO_INITIALIZED = loadRepository();
+ public static final NEURepository NEU_REPO = NEURepository.of(LOCAL_REPO_DIR);
/**
* Adds command to update repository manually from ingame.
@@ -41,18 +46,19 @@ public class NEURepo {
}))));
}
- private static CompletableFuture<Void> initRepository() {
+ private static CompletableFuture<Void> loadRepository() {
return CompletableFuture.runAsync(() -> {
try {
- if (Files.isDirectory(NEURepo.LOCAL_REPO_DIR)) {
- try (Git localRepo = Git.open(NEURepo.LOCAL_REPO_DIR.toFile())) {
+ if (Files.isDirectory(NEURepoManager.LOCAL_REPO_DIR)) {
+ try (Git localRepo = Git.open(NEURepoManager.LOCAL_REPO_DIR.toFile())) {
localRepo.pull().setRebase(true).call();
LOGGER.info("[Skyblocker] NEU Repository Updated");
}
} else {
- Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepo.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close();
+ Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepoManager.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close();
LOGGER.info("[Skyblocker] NEU Repository Downloaded");
}
+ NEU_REPO.reload();
} catch (TransportException e){
LOGGER.error("[Skyblocker] Transport operation failed. Most likely unable to connect to the remote NEU repo on github", e);
} catch (RepositoryNotFoundException e) {
@@ -67,15 +73,15 @@ public class NEURepo {
private static void deleteAndDownloadRepository() {
CompletableFuture.runAsync(() -> {
try {
- ItemRegistry.filesImported = false;
- File dir = NEURepo.LOCAL_REPO_DIR.toFile();
+ ItemRepository.setFilesImported(false);
+ File dir = NEURepoManager.LOCAL_REPO_DIR.toFile();
recursiveDelete(dir);
} catch (Exception ex) {
if (MinecraftClient.getInstance().player != null)
- MinecraftClient.getInstance().player.sendMessage(Text.translatable("skyblocker.updaterepository.failed"), false);
+ MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.updaterepository.failed")), false);
return;
}
- initRepository();
+ loadRepository();
});
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index c1b4223f..71e08865 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -3,7 +3,8 @@ package de.hysky.skyblocker.utils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.hysky.skyblocker.events.SkyblockEvents;
-import de.hysky.skyblocker.skyblock.item.PriceInfoTooltip;
+import de.hysky.skyblocker.skyblock.item.MuseumItemCache;
+import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip;
import de.hysky.skyblocker.skyblock.rift.TheRift;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@@ -19,6 +20,7 @@ import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.scoreboard.*;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
+import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,19 +33,32 @@ import java.util.List;
public class Utils {
private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class);
private static final String ALTERNATE_HYPIXEL_ADDRESS = System.getProperty("skyblocker.alternateHypixelAddress", "");
+ private static final String DUNGEONS_LOCATION = "dungeon";
private static final String PROFILE_PREFIX = "Profile: ";
private static boolean isOnHypixel = false;
private static boolean isOnSkyblock = false;
- private static boolean isInDungeons = false;
private static boolean isInjected = false;
/**
- * The following fields store data returned from /locraw: {@link #profile}, {@link #server}, {@link #gameType}, {@link #locationRaw}, and {@link #map}.
+ * The profile name parsed from the player list.
*/
- @SuppressWarnings("JavadocDeclaration")
+ @NotNull
private static String profile = "";
+ /**
+ * The profile id parsed from the chat.
+ */
+ @NotNull
+ private static String profileId = "";
+ /**
+ * The following fields store data returned from /locraw: {@link #server}, {@link #gameType}, {@link #locationRaw}, and {@link #map}.
+ */
+ @SuppressWarnings("JavadocDeclaration")
+ @NotNull
private static String server = "";
+ @NotNull
private static String gameType = "";
+ @NotNull
private static String locationRaw = "";
+ @NotNull
private static String map = "";
private static long clientWorldJoinTime = 0;
private static boolean sentLocRaw = false;
@@ -64,7 +79,7 @@ public class Utils {
}
public static boolean isInDungeons() {
- return isInDungeons;
+ return getLocationRaw().equals(DUNGEONS_LOCATION) || FabricLoader.getInstance().isDevelopmentEnvironment();
}
public static boolean isInTheRift() {
@@ -78,13 +93,20 @@ public class Utils {
/**
* @return the profile parsed from the player list.
*/
+ @NotNull
public static String getProfile() {
return profile;
}
+ @NotNull
+ public static String getProfileId() {
+ return profileId;
+ }
+
/**
* @return the server parsed from /locraw.
*/
+ @NotNull
public static String getServer() {
return server;
}
@@ -92,6 +114,7 @@ public class Utils {
/**
* @return the game type parsed from /locraw.
*/
+ @NotNull
public static String getGameType() {
return gameType;
}
@@ -99,6 +122,7 @@ public class Utils {
/**
* @return the location raw parsed from /locraw.
*/
+ @NotNull
public static String getLocationRaw() {
return locationRaw;
}
@@ -106,6 +130,7 @@ public class Utils {
/**
* @return the map parsed from /locraw.
*/
+ @NotNull
public static String getMap() {
return map;
}
@@ -139,7 +164,6 @@ public class Utils {
sidebar = Collections.emptyList();
} else {
isOnSkyblock = false;
- isInDungeons = false;
return;
}
}
@@ -155,7 +179,7 @@ public class Utils {
if (!isOnSkyblock) {
if (!isInjected) {
isInjected = true;
- ItemTooltipCallback.EVENT.register(PriceInfoTooltip::onInjectTooltip);
+ ItemTooltipCallback.EVENT.register(ItemTooltip::getTooltip);
}
isOnSkyblock = true;
SkyblockEvents.JOIN.invoker().onSkyblockJoin();
@@ -163,7 +187,6 @@ public class Utils {
} else {
onLeaveSkyblock();
}
- isInDungeons = fabricLoader.isDevelopmentEnvironment() || isOnSkyblock && string.contains("The Catacombs");
} else if (isOnHypixel) {
isOnHypixel = false;
onLeaveSkyblock();
@@ -180,7 +203,6 @@ public class Utils {
private static void onLeaveSkyblock() {
if (isOnSkyblock) {
isOnSkyblock = false;
- isInDungeons = false;
SkyblockEvents.LEAVE.invoker().onSkyblockLeave();
}
}
@@ -312,7 +334,7 @@ public class Utils {
}
/**
- * Parses the /locraw reply from the server
+ * Parses the /locraw reply from the server and updates the player's profile id
*
* @return not display the message in chat is the command is sent by the mod
*/
@@ -338,6 +360,13 @@ public class Utils {
return shouldFilter;
}
}
+
+ if (isOnSkyblock && message.startsWith("Profile ID: ")) {
+ profileId = message.replace("Profile ID: ", "");
+
+ MuseumItemCache.tick(profileId);
+ }
+
return true;
}
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 4630149c..064b564c 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
@@ -1,10 +1,7 @@
package de.hysky.skyblocker.utils.render;
-import com.mojang.blaze3d.platform.GlStateManager.DstFactor;
-import com.mojang.blaze3d.platform.GlStateManager.SrcFactor;
import com.mojang.blaze3d.systems.RenderSystem;
import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
-import me.x150.renderer.render.Renderer3d;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.title.Title;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
@@ -22,11 +19,8 @@ import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
-import org.joml.Vector3f;
import org.lwjgl.opengl.GL11;
-import java.awt.*;
-
public class RenderHelper {
private static final Vec3d ONE = new Vec3d(1, 1, 1);
private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
@@ -39,20 +33,46 @@ public class RenderHelper {
public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- Renderer3d.renderThroughWalls();
- renderFilled(context, pos, colorComponents, alpha);
- Renderer3d.stopRenderThroughWalls();
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true);
}
}
public static void renderFilledIfVisible(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- renderFilled(context, pos, colorComponents, alpha);
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false);
}
}
-
- private static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- Renderer3d.renderFilled(context.matrixStack(), new Color(colorComponents[0], colorComponents[1], colorComponents[2], alpha), Vec3d.of(pos), ONE);
+
+ private static void renderFilled(WorldRenderContext context, Vec3d pos, Vec3d dimensions, float[] colorComponents, float alpha, boolean throughWalls) {
+ MatrixStack matrices = context.matrixStack();
+ Vec3d camera = context.camera().getPos();
+ Tessellator tessellator = RenderSystem.renderThreadTesselator();
+ BufferBuilder buffer = tessellator.getBuffer();
+
+ matrices.push();
+ matrices.translate(-camera.x, -camera.y, -camera.z);
+
+ RenderSystem.setShader(GameRenderer::getPositionColorProgram);
+ RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
+ RenderSystem.polygonOffset(-1f, -10f);
+ RenderSystem.enablePolygonOffset();
+ RenderSystem.enableBlend();
+ RenderSystem.defaultBlendFunc();
+ RenderSystem.enableDepthTest();
+ RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
+ RenderSystem.disableCull();
+
+ buffer.begin(DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
+ WorldRenderer.renderFilledBox(matrices, buffer, pos.x, pos.y, pos.z, pos.x + dimensions.x, pos.y + dimensions.y, pos.z + dimensions.z, colorComponents[0], colorComponents[1], colorComponents[2], alpha);
+ tessellator.draw();
+
+ matrices.pop();
+ RenderSystem.polygonOffset(0f, 0f);
+ RenderSystem.disablePolygonOffset();
+ RenderSystem.disableBlend();
+ RenderSystem.disableDepthTest();
+ RenderSystem.depthFunc(GL11.GL_LEQUAL);
+ RenderSystem.enableCull();
}
private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
@@ -78,7 +98,7 @@ public class RenderHelper {
* Renders the outline of a box with the specified color components and line width.
* This does not use renderer since renderer draws outline using debug lines with a fixed width.
*/
- public static void renderOutline(WorldRenderContext context, Box box, float[] colorComponents, float lineWidth) {
+ public static void renderOutline(WorldRenderContext context, Box box, float[] colorComponents, float lineWidth, boolean throughWalls) {
if (FrustumUtils.isVisible(box)) {
MatrixStack matrices = context.matrixStack();
Vec3d camera = context.camera().getPos();
@@ -90,6 +110,7 @@ public class RenderHelper {
RenderSystem.lineWidth(lineWidth);
RenderSystem.disableCull();
RenderSystem.enableDepthTest();
+ RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
matrices.push();
matrices.translate(-camera.getX(), -camera.getY(), -camera.getZ());
@@ -102,6 +123,7 @@ public class RenderHelper {
RenderSystem.lineWidth(1f);
RenderSystem.enableCull();
RenderSystem.disableDepthTest();
+ RenderSystem.depthFunc(GL11.GL_LEQUAL);
}
}
@@ -109,6 +131,8 @@ public class RenderHelper {
* Draws lines from point to point.<br><br>
* <p>
* Tip: To draw lines from the center of a block, offset the X, Y and Z each by 0.5
+ * <p>
+ * Note: This is super messed up when drawing long lines. Tried different normals and {@link DrawMode#LINES} but nothing worked.
*
* @param context The WorldRenderContext which supplies the matrices and tick delta
* @param points The points from which to draw lines between
@@ -125,7 +149,7 @@ public class RenderHelper {
Tessellator tessellator = RenderSystem.renderThreadTesselator();
BufferBuilder buffer = tessellator.getBuffer();
- Matrix4f projectionMatrix = matrices.peek().getPositionMatrix();
+ Matrix4f positionMatrix = matrices.peek().getPositionMatrix();
Matrix3f normalMatrix = matrices.peek().getNormalMatrix();
GL11.glEnable(GL11.GL_LINE_SMOOTH);
@@ -135,21 +159,18 @@ public class RenderHelper {
RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
RenderSystem.lineWidth(lineWidth);
RenderSystem.enableBlend();
- RenderSystem.blendFunc(SrcFactor.SRC_ALPHA, DstFactor.ONE_MINUS_SRC_ALPHA);
+ RenderSystem.defaultBlendFunc();
RenderSystem.disableCull();
RenderSystem.enableDepthTest();
buffer.begin(DrawMode.LINE_STRIP, VertexFormats.LINES);
for (int i = 0; i < points.length; i++) {
- Vec3d point = points[i];
- Vec3d nextPoint = (i + 1 == points.length) ? points[i - 1] : points[i + 1];
- Vector3f normalVec = new Vector3f((float) nextPoint.getX(), (float) nextPoint.getY(), (float) nextPoint.getZ()).sub((float) point.getX(), (float) point.getY(), (float) point.getZ()).normalize();
-
+ Vec3d normalVec = points[(i + 1) % points.length].subtract(points[i]).normalize();
buffer
- .vertex(projectionMatrix, (float) point.getX(), (float) point.getY(), (float) point.getZ())
+ .vertex(positionMatrix, (float) points[i].getX(), (float) points[i].getY(), (float) points[i].getZ())
.color(colorComponents[0], colorComponents[1], colorComponents[2], alpha)
- .normal(normalMatrix, normalVec.x, normalVec.y, normalVec.z)
+ .normal(normalMatrix, (float) normalVec.x, (float) normalVec.y, (float) normalVec.z)
.next();
}
@@ -158,30 +179,57 @@ public class RenderHelper {
matrices.pop();
GL11.glDisable(GL11.GL_LINE_SMOOTH);
RenderSystem.lineWidth(1f);
- RenderSystem.disableBlend();
+ RenderSystem.enableCull();
+ }
+
+ public static void renderQuad(WorldRenderContext context, Vec3d[] points, float[] colorComponents, float alpha, boolean throughWalls) {
+ Vec3d camera = context.camera().getPos();
+ MatrixStack matrices = context.matrixStack();
+
+ matrices.push();
+ matrices.translate(-camera.x, -camera.y, -camera.z);
+
+ Tessellator tessellator = RenderSystem.renderThreadTesselator();
+ BufferBuilder buffer = tessellator.getBuffer();
+ Matrix4f positionMatrix = matrices.peek().getPositionMatrix();
+
+ RenderSystem.setShader(GameRenderer::getPositionColorProgram);
+ RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
+ RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
+ RenderSystem.disableCull();
+ RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
+
+ buffer.begin(DrawMode.QUADS, VertexFormats.POSITION_COLOR);
+ for (int i = 0; i < 4; i++) {
+ buffer.vertex(positionMatrix, (float) points[i].getX(), (float) points[i].getY(), (float) points[i].getZ()).color(colorComponents[0], colorComponents[1], colorComponents[2], alpha).next();
+ }
+ tessellator.draw();
+
RenderSystem.enableCull();
- RenderSystem.disableDepthTest();
+ RenderSystem.depthFunc(GL11.GL_LEQUAL);
+
+ matrices.pop();
}
- public static void renderText(WorldRenderContext context, Text text, Vec3d pos, boolean seeThrough) {
- renderText(context, text, pos, 1, seeThrough);
+ public static void renderText(WorldRenderContext context, Text text, Vec3d pos, boolean throughWalls) {
+ renderText(context, text, pos, 1, throughWalls);
}
- public static void renderText(WorldRenderContext context, Text text, Vec3d pos, float scale, boolean seeThrough) {
- renderText(context, text, pos, scale, 0, seeThrough);
+ public static void renderText(WorldRenderContext context, Text text, Vec3d pos, float scale, boolean throughWalls) {
+ renderText(context, text, pos, scale, 0, throughWalls);
}
- public static void renderText(WorldRenderContext context, Text text, Vec3d pos, float scale, float yOffset, boolean seeThrough) {
- renderText(context, text.asOrderedText(), pos, scale, yOffset, seeThrough);
+ public static void renderText(WorldRenderContext context, Text text, Vec3d pos, float scale, float yOffset, boolean throughWalls) {
+ renderText(context, text.asOrderedText(), pos, scale, yOffset, throughWalls);
}
/**
* Renders text in the world space.
*
- * @param seeThrough Whether the text should be able to be seen through walls or not.
+ * @param throughWalls whether the text should be able to be seen through walls or not.
*/
- public static void renderText(WorldRenderContext context, OrderedText text, Vec3d pos, float scale, float yOffset, boolean seeThrough) {
+ public static void renderText(WorldRenderContext context, OrderedText text, Vec3d pos, float scale, float yOffset, boolean throughWalls) {
MatrixStack matrices = context.matrixStack();
Vec3d camera = context.camera().getPos();
TextRenderer textRenderer = client.textRenderer;
@@ -201,7 +249,7 @@ public class RenderHelper {
BufferBuilder buffer = tessellator.getBuffer();
VertexConsumerProvider.Immediate consumers = VertexConsumerProvider.immediate(buffer);
- RenderSystem.depthFunc(seeThrough ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
+ RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
textRenderer.draw(text, xOffset, yOffset, 0xFFFFFFFF, false, positionMatrix, consumers, TextRenderer.TextLayerType.SEE_THROUGH, 0, LightmapTextureManager.MAX_LIGHT_COORDINATE);
consumers.draw();
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
index d824c546..cab18a50 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
@@ -3,8 +3,13 @@ package de.hysky.skyblocker.utils.render.title;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.render.RenderHelper;
+import dev.isxander.yacl3.api.ConfigCategory;
+import dev.isxander.yacl3.api.Option;
+import dev.isxander.yacl3.api.OptionGroup;
+import dev.isxander.yacl3.gui.YACLScreen;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.Vector2f;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -21,6 +26,7 @@ public class TitleContainerConfigScreen extends Screen {
private float hudX = SkyblockerConfigManager.get().general.titleContainer.x;
private float hudY = SkyblockerConfigManager.get().general.titleContainer.y;
private final Screen parent;
+ private boolean changedScale;
protected TitleContainerConfigScreen() {
this(null);
@@ -153,17 +159,32 @@ public class TitleContainerConfigScreen extends Screen {
}
if (keyCode == GLFW.GLFW_KEY_EQUAL) {
SkyblockerConfigManager.get().general.titleContainer.titleContainerScale += 10;
+ changedScale = true;
}
if (keyCode == GLFW.GLFW_KEY_MINUS) {
SkyblockerConfigManager.get().general.titleContainer.titleContainerScale -= 10;
+ changedScale = true;
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
+
@Override
public void close() {
SkyblockerConfigManager.get().general.titleContainer.x = (int) hudX;
SkyblockerConfigManager.get().general.titleContainer.y = (int) hudY;
+
+ //TODO Come up with a better, less hacky solution for this in the future (:
+ if (parent instanceof YACLScreen yaclScreen) {
+ ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.category.general"))).findFirst().orElseThrow();
+ OptionGroup group = category.groups().stream().filter(grp -> grp.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.option.general.titleContainer"))).findFirst().orElseThrow();
+
+ Option<?> scaleOpt = group.options().get(0);
+
+ // Refresh the value in the config with the bound value
+ if (changedScale) scaleOpt.forgetPendingValue();
+ }
+
SkyblockerConfigManager.save();
this.client.setScreen(parent);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
new file mode 100644
index 00000000..e7858f05
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
@@ -0,0 +1,99 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import de.hysky.skyblocker.utils.render.RenderHelper;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+
+import java.util.function.Supplier;
+
+public class Waypoint {
+ protected static final float DEFAULT_HIGHLIGHT_ALPHA = 0.5f;
+ protected static final float DEFAULT_LINE_WIDTH = 5f;
+ public final BlockPos pos;
+ private final Box box;
+ private final Supplier<Type> typeSupplier;
+ private final float[] colorComponents;
+ private final float alpha;
+ private final float lineWidth;
+ private final boolean throughWalls;
+ private boolean shouldRender;
+
+ protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents) {
+ this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA);
+ }
+
+ protected Waypoint(BlockPos pos, Type type, float[] colorComponents, float alpha) {
+ this(pos, () -> type, colorComponents, alpha);
+ }
+
+ protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha) {
+ this(pos, typeSupplier, colorComponents, alpha, DEFAULT_LINE_WIDTH);
+ }
+
+ protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth) {
+ this(pos, typeSupplier, colorComponents, alpha, lineWidth, true);
+ }
+
+ protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth, boolean throughWalls) {
+ this(pos, typeSupplier, colorComponents, alpha, lineWidth, throughWalls, true);
+ }
+
+ protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth, boolean throughWalls, boolean shouldRender) {
+ this.pos = pos;
+ this.box = new Box(pos);
+ this.typeSupplier = typeSupplier;
+ this.colorComponents = colorComponents;
+ this.alpha = alpha;
+ this.lineWidth = lineWidth;
+ this.throughWalls = throughWalls;
+ this.shouldRender = shouldRender;
+ }
+
+ public boolean shouldRender() {
+ return shouldRender;
+ }
+
+ public void setFound() {
+ this.shouldRender = false;
+ }
+
+ public void setMissing() {
+ this.shouldRender = true;
+ }
+
+ public void render(WorldRenderContext context) {
+ switch (typeSupplier.get()) {
+ case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ case OUTLINED_WAYPOINT -> {
+ RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
+ }
+ case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ case OUTLINED_HIGHLIGHT -> {
+ RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
+ }
+ case OUTLINE -> RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
+ }
+ }
+
+ public enum Type {
+ WAYPOINT,
+ OUTLINED_WAYPOINT,
+ HIGHLIGHT,
+ OUTLINED_HIGHLIGHT,
+ OUTLINE;
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case WAYPOINT -> "Waypoint";
+ case OUTLINED_WAYPOINT -> "Outlined Waypoint";
+ case HIGHLIGHT -> "Highlight";
+ case OUTLINED_HIGHLIGHT -> "Outlined Highlight";
+ case OUTLINE -> "Outline";
+ };
+ }
+ }
+}