From e440bb72d80da655d99a35a618230036883b6e0b Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 12 Nov 2023 18:00:44 -0500 Subject: Add waypoint tests --- .../java/de/hysky/skyblocker/utils/waypoint/Waypoint.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java index e7858f05..a8e62a94 100644 --- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java +++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java @@ -11,12 +11,12 @@ 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 typeSupplier; - private final float[] colorComponents; - private final float alpha; - private final float lineWidth; - private final boolean throughWalls; + final Box box; + final Supplier typeSupplier; + final float[] colorComponents; + final float alpha; + final float lineWidth; + final boolean throughWalls; private boolean shouldRender; protected Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents) { -- cgit From 4f04a35ae3300656a4ef92e0a62304d58aa582a2 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:28:15 -0500 Subject: Add Profile Aware Waypoint --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 5 +- .../hysky/skyblocker/config/SkyblockerConfig.java | 41 ++-- .../config/categories/DungeonsCategory.java | 4 +- .../config/categories/GeneralCategory.java | 22 +++ .../mixin/ClientPlayNetworkHandlerMixin.java | 2 +- .../de/hysky/skyblocker/skyblock/FairySouls.java | 213 --------------------- .../skyblock/diana/MythologicalRitual.java | 213 --------------------- .../hysky/skyblocker/skyblock/dungeon/Trivia.java | 2 +- .../skyblocker/skyblock/spidersden/Relics.java | 174 ----------------- .../skyblocker/skyblock/waypoint/FairySouls.java | 203 ++++++++++++++++++++ .../skyblock/waypoint/MythologicalRitual.java | 213 +++++++++++++++++++++ .../hysky/skyblocker/skyblock/waypoint/Relics.java | 174 +++++++++++++++++ .../utils/waypoint/ProfileAwareWaypoint.java | 44 +++++ .../hysky/skyblocker/utils/waypoint/Waypoint.java | 12 +- .../resources/assets/skyblocker/lang/en_us.json | 6 +- .../utils/waypoint/ProfileAwareWaypointTest.java | 38 ++++ .../skyblocker/utils/waypoint/WaypointTest.java | 17 +- 17 files changed, 749 insertions(+), 634 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java create mode 100644 src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java (limited to 'src/main/java/de') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index ad3b6318..cbe82667 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.skyblock.*; -import de.hysky.skyblocker.skyblock.diana.MythologicalRitual; +import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual; import de.hysky.skyblocker.skyblock.dungeon.*; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets; import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker; @@ -18,10 +18,11 @@ import de.hysky.skyblocker.skyblock.quicknav.QuickNav; import de.hysky.skyblocker.skyblock.rift.TheRift; import de.hysky.skyblocker.skyblock.shortcut.Shortcuts; import de.hysky.skyblocker.skyblock.special.SpecialEffects; -import de.hysky.skyblocker.skyblock.spidersden.Relics; +import de.hysky.skyblocker.skyblock.waypoint.Relics; import de.hysky.skyblocker.skyblock.tabhud.TabHud; import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; +import de.hysky.skyblocker.skyblock.waypoint.FairySouls; import de.hysky.skyblocker.utils.ApiUtils; import de.hysky.skyblocker.utils.NEURepoManager; import de.hysky.skyblocker.utils.Utils; diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 6f3a8e4a..59203269 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -188,6 +188,9 @@ public class SkyblockerConfig { @SerialEntry public Shortcuts shortcuts = new Shortcuts(); + @SerialEntry + public Waypoints waypoints = new Waypoints(); + @SerialEntry public QuiverWarning quiverWarning = new QuiverWarning(); @@ -254,8 +257,8 @@ public class SkyblockerConfig { @Override public String toString() { return switch (this) { - case DEFAULT -> "Default"; - case ALPHABETICAL -> "Alphabetical"; + case DEFAULT -> "Default"; + case ALPHABETICAL -> "Alphabetical"; }; } } @@ -293,10 +296,10 @@ public class SkyblockerConfig { public int toInt() { return switch (this) { - case LAYER1 -> 0; - case LAYER2 -> 1; - case RIGHT -> 2; - case NONE -> -1; + case LAYER1 -> 0; + case LAYER2 -> 1; + case RIGHT -> 2; + case NONE -> -1; }; } } @@ -349,6 +352,14 @@ public class SkyblockerConfig { public boolean enableCommandArgShortcuts = true; } + public static class Waypoints { + @SerialEntry + public boolean enableWaypoints = true; + + @SerialEntry + public Waypoint.Type waypointType = Waypoint.Type.WAYPOINT; + } + public static class QuiverWarning { @SerialEntry public boolean enableQuiverWarning = true; @@ -419,8 +430,8 @@ public class SkyblockerConfig { @Override public String toString() { return switch (this) { - case HORIZONTAL -> "Horizontal"; - case VERTICAL -> "Vertical"; + case HORIZONTAL -> "Horizontal"; + case VERTICAL -> "Vertical"; }; } } @@ -431,9 +442,9 @@ public class SkyblockerConfig { @Override public String toString() { return switch (this) { - case LEFT -> "Left"; - case RIGHT -> "Right"; - case MIDDLE -> "Middle"; + case LEFT -> "Left"; + case RIGHT -> "Right"; + case MIDDLE -> "Middle"; }; } } @@ -515,7 +526,7 @@ public class SkyblockerConfig { public final Identifier tex; - private RarityBackgroundStyle(Identifier tex) { + RarityBackgroundStyle(Identifier tex) { this.tex = tex; } @@ -743,9 +754,9 @@ public class SkyblockerConfig { @Override public String toString() { return switch (this) { - case SIMPLE -> "Simple"; - case FANCY -> "Fancy"; - case CLASSIC -> "Classic"; + case SIMPLE -> "Simple"; + case FANCY -> "Fancy"; + case CLASSIC -> "Classic"; }; } } 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 007d974c..7bb6414c 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -45,8 +45,8 @@ public class DungeonsCategory { .flag(OptionFlag.GAME_RESTART) .build()) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip"))) + .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"))) .binding(defaults.locations.dungeons.secretWaypoints.waypointType, () -> config.locations.dungeons.secretWaypoints.waypointType, newValue -> config.locations.dungeons.secretWaypoints.waypointType = newValue) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 7e7a91fd..0f49be7b 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.skyblock.shortcut.ShortcutsConfigScreen; import de.hysky.skyblocker.utils.render.title.TitleContainerConfigScreen; +import de.hysky.skyblocker.utils.waypoint.Waypoint; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder; import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder; @@ -261,6 +262,27 @@ public class GeneralCategory { .build()) .build()) + //Waypoints + .group(OptionGroup.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints")) + .binding(defaults.general.waypoints.enableWaypoints, + () -> config.general.waypoints.enableWaypoints, + newValue -> config.general.waypoints.enableWaypoints = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"))) + .binding(defaults.general.waypoints.waypointType, + () -> config.general.waypoints.waypointType, + newValue -> config.general.waypoints.waypointType = newValue) + .controller(ConfigUtils::createEnumCyclingListController) + .build()) + .build()) + //Quiver Warning .group(OptionGroup.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.general.quiverWarning")) diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java index f68a4e94..384986ae 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java @@ -3,7 +3,7 @@ package de.hysky.skyblocker.mixin; import com.llamalad7.mixinextras.injector.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.skyblock.FishingHelper; -import de.hysky.skyblocker.skyblock.diana.MythologicalRitual; +import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets; import de.hysky.skyblocker.utils.Utils; import dev.cbyrne.betterinject.annotations.Inject; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java deleted file mode 100644 index e9bc3ebd..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java +++ /dev/null @@ -1,213 +0,0 @@ -package de.hysky.skyblocker.skyblock; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.mojang.brigadier.CommandDispatcher; -import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.config.SkyblockerConfig; -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.Constants; -import de.hysky.skyblocker.utils.NEURepoManager; -import de.hysky.skyblocker.utils.PosUtils; -import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.Text; -import net.minecraft.util.DyeColor; -import net.minecraft.util.math.BlockPos; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; - -public class FairySouls { - private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class); - private static CompletableFuture fairySoulsLoaded; - private static int maxSouls = 0; - private static final Map> fairySouls = new HashMap<>(); - private static final Map>> foundFairies = new HashMap<>(); - - @SuppressWarnings("UnusedReturnValue") - public static CompletableFuture runAsyncAfterFairySoulsLoad(Runnable runnable) { - if (fairySoulsLoaded == null) { - LOGGER.error("Fairy Souls have not being initialized yet! Please ensure the Fairy Souls module is initialized before modules calling this method in SkyblockerMod#onInitializeClient. This error can be safely ignore in a test environment."); - return CompletableFuture.completedFuture(null); - } - return fairySoulsLoaded.thenRunAsync(runnable); - } - - public static int getFairySoulsSize(@Nullable String location) { - return location == null ? maxSouls : fairySouls.get(location).size(); - } - - public static void init() { - loadFairySouls(); - ClientLifecycleEvents.CLIENT_STOPPING.register(FairySouls::saveFoundFairySouls); - ClientCommandRegistrationCallback.EVENT.register(FairySouls::registerCommands); - WorldRenderEvents.AFTER_TRANSLUCENT.register(FairySouls::render); - ClientReceiveMessageEvents.GAME.register(FairySouls::onChatMessage); - } - - private static void loadFairySouls() { - fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> { - maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls(); - NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairySoulsForLocation) -> fairySouls.put(location, fairySoulsForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableSet()))); - LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size()); - - try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { - for (Map.Entry foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { - Map> foundFairiesForProfile = new HashMap<>(); - for (Map.Entry foundFairiesForLocationJson : foundFairiesForProfileJson.getValue().getAsJsonObject().asMap().entrySet()) { - Set foundFairiesForLocation = new HashSet<>(); - for (JsonElement foundFairy : foundFairiesForLocationJson.getValue().getAsJsonArray().asList()) { - foundFairiesForLocation.add(PosUtils.parsePosString(foundFairy.getAsString())); - } - foundFairiesForProfile.put(foundFairiesForLocationJson.getKey(), foundFairiesForLocation); - } - foundFairies.put(foundFairiesForProfileJson.getKey(), foundFairiesForProfile); - } - LOGGER.debug("[Skyblocker] Loaded found fairy souls"); - } catch (NoSuchFileException ignored) { - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to load found fairy souls", e); - } - LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations and {} found fairy souls across {} locations in {} profiles", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size(), foundFairies.values().stream().map(Map::values).flatMap(Collection::stream).mapToInt(Set::size).sum(), foundFairies.values().stream().mapToInt(Map::size).sum(), foundFairies.size()); - }); - } - - private static void saveFoundFairySouls(MinecraftClient client) { - try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { - JsonObject foundFairiesJson = new JsonObject(); - for (Map.Entry>> foundFairiesForProfile : foundFairies.entrySet()) { - JsonObject foundFairiesForProfileJson = new JsonObject(); - for (Map.Entry> foundFairiesForLocation : foundFairiesForProfile.getValue().entrySet()) { - JsonArray foundFairiesForLocationJson = new JsonArray(); - for (BlockPos foundFairy : foundFairiesForLocation.getValue()) { - foundFairiesForLocationJson.add(PosUtils.getPosString(foundFairy)); - } - foundFairiesForProfileJson.add(foundFairiesForLocation.getKey(), foundFairiesForLocationJson); - } - foundFairiesJson.add(foundFairiesForProfile.getKey(), foundFairiesForProfileJson); - } - SkyblockerMod.GSON.toJson(foundFairiesJson, writer); - LOGGER.info("[Skyblocker] Saved found fairy souls"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to write found fairy souls to file", e); - } - } - - private static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { - dispatcher.register(literal(SkyblockerMod.NAMESPACE) - .then(literal("fairySouls") - .then(literal("markAllInCurrentIslandFound").executes(context -> { - FairySouls.markAllFairiesOnCurrentIslandFound(); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.fairySouls.markAllFound"))); - return 1; - })) - .then(literal("markAllInCurrentIslandMissing").executes(context -> { - FairySouls.markAllFairiesOnCurrentIslandMissing(); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.fairySouls.markAllMissing"))); - return 1; - })))); - } - - private static void render(WorldRenderContext context) { - SkyblockerConfig.FairySouls fairySoulsConfig = SkyblockerConfigManager.get().general.fairySouls; - - if (fairySoulsConfig.enableFairySoulsHelper && fairySoulsLoaded.isDone() && fairySouls.containsKey(Utils.getLocationRaw())) { - for (BlockPos fairySoulPos : fairySouls.get(Utils.getLocationRaw())) { - boolean fairySoulNotFound = isFairySoulMissing(fairySoulPos); - if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoulPos.getSquaredDistance(context.camera().getPos()) > 2500) { - continue; - } - float[] colorComponents = fairySoulNotFound ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents(); - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F); - } - } - } - - private static void onChatMessage(Text text, boolean overlay) { - String message = text.getString(); - if (message.equals("You have already found that Fairy Soul!") || message.equals("§d§lSOUL! §fYou found a §dFairy Soul§f!")) { - markClosestFairyFound(); - } - } - - private static void markClosestFairyFound() { - if (!fairySoulsLoaded.isDone()) return; - - PlayerEntity player = MinecraftClient.getInstance().player; - if (player == null) { - LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because player is null"); - return; - } - - Set fairiesOnCurrentIsland = fairySouls.get(Utils.getLocationRaw()); - if (fairiesOnCurrentIsland == null) { - LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because there are no fairy souls loaded on the current island. NEU repo probably failed to load."); - return; - } - - fairiesOnCurrentIsland.stream() - .filter(FairySouls::isFairySoulMissing) - .min(Comparator.comparingDouble(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos()))) - .filter(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos()) <= 16) - .ifPresent(fairySoulPos -> { - initializeFoundFairiesForCurrentProfileAndLocation(); - foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).add(fairySoulPos); - }); - } - - private static boolean isFairySoulMissing(BlockPos fairySoulPos) { - Map> foundFairiesForProfile = foundFairies.get(Utils.getProfile()); - if (foundFairiesForProfile == null) { - return true; - } - Set foundFairiesForProfileAndLocation = foundFairiesForProfile.get(Utils.getLocationRaw()); - if (foundFairiesForProfileAndLocation == null) { - return true; - } - return !foundFairiesForProfileAndLocation.contains(fairySoulPos); - } - - public static void markAllFairiesOnCurrentIslandFound() { - if (fairySouls.get(Utils.getLocationRaw()) != null) { - initializeFoundFairiesForCurrentProfileAndLocation(); - foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).addAll(fairySouls.get(Utils.getLocationRaw())); - } - } - - public static void markAllFairiesOnCurrentIslandMissing() { - Map> foundFairiesForProfile = foundFairies.get(Utils.getProfile()); - if (foundFairiesForProfile != null) { - foundFairiesForProfile.remove(Utils.getLocationRaw()); - } - } - - private static void initializeFoundFairiesForCurrentProfileAndLocation() { - initializeFoundFairiesForProfileAndLocation(Utils.getProfile(), Utils.getLocationRaw()); - } - - private static void initializeFoundFairiesForProfileAndLocation(String profile, String location) { - foundFairies.computeIfAbsent(profile, profileKey -> new HashMap<>()); - foundFairies.get(profile).computeIfAbsent(location, locationKey -> new HashSet<>()); - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java b/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java deleted file mode 100644 index f36a8a24..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java +++ /dev/null @@ -1,213 +0,0 @@ -package de.hysky.skyblocker.skyblock.diana; - -import com.mojang.brigadier.Command; -import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.ItemUtils; -import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; -import de.hysky.skyblocker.utils.waypoint.Waypoint; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; -import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; -import net.fabricmc.fabric.api.event.player.AttackBlockCallback; -import net.fabricmc.fabric.api.event.player.UseBlockCallback; -import net.fabricmc.fabric.api.event.player.UseItemCallback; -import net.fabricmc.fabric.api.util.TriState; -import net.minecraft.block.Blocks; -import net.minecraft.client.MinecraftClient; -import net.minecraft.command.argument.BlockPosArgumentType; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; -import net.minecraft.particle.ParticleTypes; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.DyeColor; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import org.apache.commons.math3.stat.regression.SimpleRegression; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; - -public class MythologicalRitual { - private static final Pattern GRIFFIN_BURROW_DUG = Pattern.compile("(?You dug out a Griffin Burrow!|You finished the Griffin burrow chain!) \\((?\\d)/4\\)"); - private static final float[] ORANGE_COLOR_COMPONENTS = DyeColor.ORANGE.getColorComponents(); - private static long lastEchoTime; - private static final Map griffinBurrows = new HashMap<>(); - @Nullable - private static BlockPos lastDugBurrowPos; - private static GriffinBurrow previousBurrow = new GriffinBurrow(BlockPos.ORIGIN); - - public static void init() { - WorldRenderEvents.AFTER_TRANSLUCENT.register(MythologicalRitual::render); - AttackBlockCallback.EVENT.register(MythologicalRitual::onAttackBlock); - UseBlockCallback.EVENT.register(MythologicalRitual::onUseBlock); - UseItemCallback.EVENT.register(MythologicalRitual::onUseItem); - ClientReceiveMessageEvents.GAME.register(MythologicalRitual::onChatMessage); - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("diana") - .then(literal("clearGriffinBurrows").executes(context -> { - griffinBurrows.clear(); - return Command.SINGLE_SUCCESS; - })) - .then(literal("clearGriffinBurrow") - .then(argument("pos", BlockPosArgumentType.blockPos()).executes(context -> { - griffinBurrows.remove(context.getArgument("pos", BlockPos.class)); - return Command.SINGLE_SUCCESS; - })) - ) - ))); - - // Put a root burrow so echo detection works without a previous burrow - previousBurrow.confirmed = TriState.DEFAULT; - griffinBurrows.put(BlockPos.ORIGIN, previousBurrow); - } - - public static void onParticle(ParticleS2CPacket packet) { - if (isActive()) { - if (ParticleTypes.CRIT.equals(packet.getParameters().getType()) || ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) { - BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down(); - if (MinecraftClient.getInstance().world == null || !MinecraftClient.getInstance().world.getBlockState(pos).isOf(Blocks.GRASS_BLOCK)) { - return; - } - GriffinBurrow burrow = griffinBurrows.computeIfAbsent(pos, GriffinBurrow::new); - if (ParticleTypes.CRIT.equals(packet.getParameters().getType())) burrow.critParticle++; - if (ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) burrow.enchantParticle++; - if (burrow.critParticle >= 5 && burrow.enchantParticle >= 5 && burrow.confirmed == TriState.FALSE) { - griffinBurrows.get(pos).init(); - } - } else if (ParticleTypes.DUST.equals(packet.getParameters().getType())) { - BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down(2); - GriffinBurrow burrow = griffinBurrows.get(pos); - if (burrow == null) { - return; - } - burrow.regression.addData(packet.getX(), packet.getZ()); - double slope = burrow.regression.getSlope(); - if (Double.isNaN(slope)) { - return; - } - Vec3d nextBurrowDirection = new Vec3d(100, 0, slope * 100).normalize().multiply(100); - if (burrow.nextBurrowPlane == null) { - burrow.nextBurrowPlane = new Vec3d[4]; - } - burrow.nextBurrowPlane[0] = Vec3d.of(pos).add(nextBurrowDirection).subtract(0, 50, 0); - burrow.nextBurrowPlane[1] = Vec3d.of(pos).subtract(nextBurrowDirection).subtract(0, 50, 0); - burrow.nextBurrowPlane[2] = burrow.nextBurrowPlane[1].add(0, 100, 0); - burrow.nextBurrowPlane[3] = burrow.nextBurrowPlane[0].add(0, 100, 0); - } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType()) && packet.getCount() == 2) { - if (System.currentTimeMillis() > lastEchoTime + 10_000) { - return; - } - if (previousBurrow.echoBurrowDirection == null) { - previousBurrow.echoBurrowDirection = new Vec3d[2]; - } - previousBurrow.echoBurrowDirection[0] = previousBurrow.echoBurrowDirection[1]; - previousBurrow.echoBurrowDirection[1] = new Vec3d(packet.getX(), packet.getY(), packet.getZ()); - if (previousBurrow.echoBurrowDirection[0] == null || previousBurrow.echoBurrowDirection[1] == null) { - return; - } - Vec3d echoBurrowDirection = previousBurrow.echoBurrowDirection[1].subtract(previousBurrow.echoBurrowDirection[0]).normalize().multiply(100); - if (previousBurrow.echoBurrowPlane == null) { - previousBurrow.echoBurrowPlane = new Vec3d[4]; - } - previousBurrow.echoBurrowPlane[0] = previousBurrow.echoBurrowDirection[0].add(echoBurrowDirection).subtract(0, 50, 0); - previousBurrow.echoBurrowPlane[1] = previousBurrow.echoBurrowDirection[0].subtract(echoBurrowDirection).subtract(0, 50, 0); - previousBurrow.echoBurrowPlane[2] = previousBurrow.echoBurrowPlane[1].add(0, 100, 0); - previousBurrow.echoBurrowPlane[3] = previousBurrow.echoBurrowPlane[0].add(0, 100, 0); - } - } - } - - public static void render(WorldRenderContext context) { - if (isActive()) { - for (GriffinBurrow burrow : griffinBurrows.values()) { - if (burrow.shouldRender()) { - burrow.render(context); - } - if (burrow.confirmed != TriState.FALSE) { - if (burrow.nextBurrowPlane != null) { - RenderHelper.renderQuad(context, burrow.nextBurrowPlane, ORANGE_COLOR_COMPONENTS, 0.25F, true); - } - if (burrow.echoBurrowPlane != null) { - RenderHelper.renderQuad(context, burrow.echoBurrowPlane, ORANGE_COLOR_COMPONENTS, 0.25F, true); - } - } - } - } - } - - public static ActionResult onAttackBlock(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) { - return onInteractBlock(pos); - } - - public static ActionResult onUseBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) { - return onInteractBlock(hitResult.getBlockPos()); - } - - @NotNull - private static ActionResult onInteractBlock(BlockPos pos) { - if (isActive() && griffinBurrows.containsKey(pos)) { - lastDugBurrowPos = pos; - } - return ActionResult.PASS; - } - - public static TypedActionResult onUseItem(PlayerEntity player, World world, Hand hand) { - ItemStack stack = player.getStackInHand(hand); - if (isActive() && ItemUtils.getItemId(stack).equals("ANCESTRAL_SPADE")) { - lastEchoTime = System.currentTimeMillis(); - } - return TypedActionResult.pass(stack); - } - - public static void onChatMessage(Text message, boolean overlay) { - if (isActive() && GRIFFIN_BURROW_DUG.matcher(message.getString()).matches()) { - previousBurrow.confirmed = TriState.FALSE; - previousBurrow = griffinBurrows.get(lastDugBurrowPos); - previousBurrow.confirmed = TriState.DEFAULT; - } - } - - private static boolean isActive() { - return SkyblockerConfigManager.get().general.mythologicalRitual.enableMythologicalRitualHelper && Utils.getLocationRaw().equals("hub"); - } - - private static class GriffinBurrow extends Waypoint { - private int critParticle; - private int enchantParticle; - private TriState confirmed = TriState.FALSE; - private final SimpleRegression regression = new SimpleRegression(); - private Vec3d[] nextBurrowPlane; - @Nullable - private Vec3d[] echoBurrowDirection; - private Vec3d[] echoBurrowPlane; - - private GriffinBurrow(BlockPos pos) { - super(pos, Type.WAYPOINT, ORANGE_COLOR_COMPONENTS, 0.25F); - } - - private void init() { - confirmed = TriState.TRUE; - regression.clear(); - } - - @Override - public boolean shouldRender() { - return super.shouldRender() && confirmed == TriState.TRUE; - } - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java index 262d4a4e..53368c14 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java @@ -1,7 +1,7 @@ package de.hysky.skyblocker.skyblock.dungeon; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.FairySouls; +import de.hysky.skyblocker.skyblock.waypoint.FairySouls; import de.hysky.skyblocker.utils.chat.ChatFilterResult; import de.hysky.skyblocker.utils.chat.ChatPatternListener; import net.minecraft.client.MinecraftClient; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java deleted file mode 100644 index df68c57b..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java +++ /dev/null @@ -1,174 +0,0 @@ -package de.hysky.skyblocker.skyblock.spidersden; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.mojang.brigadier.CommandDispatcher; -import de.hysky.skyblocker.SkyblockerMod; -import de.hysky.skyblocker.config.SkyblockerConfig; -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.utils.Constants; -import de.hysky.skyblocker.utils.PosUtils; -import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; -import net.minecraft.client.MinecraftClient; -import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.Text; -import net.minecraft.util.DyeColor; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.util.*; -import java.util.concurrent.CompletableFuture; - -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; - -public class Relics { - private static final Logger LOGGER = LoggerFactory.getLogger(Relics.class); - private static CompletableFuture relicsLoaded; - @SuppressWarnings({"unused", "FieldCanBeLocal"}) - private static int totalRelics = 0; - private static final List relics = new ArrayList<>(); - private static final Map> foundRelics = new HashMap<>(); - - public static void init() { - ClientLifecycleEvents.CLIENT_STARTED.register(Relics::loadRelics); - ClientLifecycleEvents.CLIENT_STOPPING.register(Relics::saveFoundRelics); - ClientCommandRegistrationCallback.EVENT.register(Relics::registerCommands); - WorldRenderEvents.AFTER_TRANSLUCENT.register(Relics::render); - ClientReceiveMessageEvents.GAME.register(Relics::onChatMessage); - } - - private static void loadRelics(MinecraftClient client) { - relicsLoaded = CompletableFuture.runAsync(() -> { - try (BufferedReader reader = client.getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "spidersden/relics.json"))) { - for (Map.Entry json : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { - if (json.getKey().equals("total")) { - totalRelics = json.getValue().getAsInt(); - } else if (json.getKey().equals("locations")) { - for (JsonElement locationJson : json.getValue().getAsJsonArray().asList()) { - JsonObject posData = locationJson.getAsJsonObject(); - relics.add(new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt())); - } - } - } - LOGGER.info("[Skyblocker] Loaded relics locations"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to load relics locations", e); - } - - try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { - for (Map.Entry profileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { - Set foundRelicsForProfile = new HashSet<>(); - for (JsonElement foundRelicsJson : profileJson.getValue().getAsJsonArray().asList()) { - foundRelicsForProfile.add(PosUtils.parsePosString(foundRelicsJson.getAsString())); - } - foundRelics.put(profileJson.getKey(), foundRelicsForProfile); - } - LOGGER.debug("[Skyblocker] Loaded found relics"); - } catch (NoSuchFileException ignored) { - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to load found relics", e); - } - }); - } - - private static void saveFoundRelics(MinecraftClient client) { - try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { - JsonObject json = new JsonObject(); - for (Map.Entry> foundRelicsForProfile : foundRelics.entrySet()) { - JsonArray foundRelicsJson = new JsonArray(); - for (BlockPos foundRelic : foundRelicsForProfile.getValue()) { - foundRelicsJson.add(PosUtils.getPosString(foundRelic)); - } - json.add(foundRelicsForProfile.getKey(), foundRelicsJson); - } - SkyblockerMod.GSON.toJson(json, writer); - LOGGER.debug("[Skyblocker] Saved found relics"); - } catch (IOException e) { - LOGGER.error("[Skyblocker] Failed to write found relics to file", e); - } - } - - private static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { - dispatcher.register(literal(SkyblockerMod.NAMESPACE) - .then(literal("relics") - .then(literal("markAllFound").executes(context -> { - Relics.markAllFound(); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllFound"))); - return 1; - })) - .then(literal("markAllMissing").executes(context -> { - Relics.markAllMissing(); - context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllMissing"))); - return 1; - })))); - } - - private static void render(WorldRenderContext context) { - SkyblockerConfig.Relics config = SkyblockerConfigManager.get().locations.spidersDen.relics; - - if (config.enableRelicsHelper && relicsLoaded.isDone() && Utils.getLocationRaw().equals("combat_1")) { - for (BlockPos fairySoulPos : relics) { - boolean isRelicMissing = isRelicMissing(fairySoulPos); - if (!isRelicMissing && !config.highlightFoundRelics) continue; - float[] colorComponents = isRelicMissing ? DyeColor.YELLOW.getColorComponents() : DyeColor.BROWN.getColorComponents(); - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F); - } - } - } - - private static void onChatMessage(Text text, boolean overlay) { - String message = text.getString(); - if (message.equals("You've already found this relic!") || message.startsWith("+10,000 Coins! (") && message.endsWith("/28 Relics)")) { - markClosestRelicFound(); - } - } - - private static void markClosestRelicFound() { - if (!relicsLoaded.isDone()) return; - PlayerEntity player = MinecraftClient.getInstance().player; - if (player == null) { - LOGGER.warn("[Skyblocker] Failed to mark closest relic as found because player is null"); - return; - } - relics.stream() - .filter(Relics::isRelicMissing) - .min(Comparator.comparingDouble(relicPos -> relicPos.getSquaredDistance(player.getPos()))) - .filter(relicPos -> relicPos.getSquaredDistance(player.getPos()) <= 16) - .ifPresent(relicPos -> { - foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); - foundRelics.get(Utils.getProfile()).add(relicPos); - }); - } - - private static boolean isRelicMissing(BlockPos relicPos) { - Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); - return foundRelicsForProfile == null || !foundRelicsForProfile.contains(relicPos); - } - - private static void markAllFound() { - foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); - foundRelics.get(Utils.getProfile()).addAll(relics); - } - - private static void markAllMissing() { - Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); - if (foundRelicsForProfile != null) { - foundRelicsForProfile.clear(); - } - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java new file mode 100644 index 00000000..c3cd6fe2 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java @@ -0,0 +1,203 @@ +package de.hysky.skyblocker.skyblock.waypoint; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.brigadier.CommandDispatcher; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.NEURepoManager; +import de.hysky.skyblocker.utils.PosUtils; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint; +import de.hysky.skyblocker.utils.waypoint.Waypoint; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class FairySouls { + private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class); + private static final Supplier TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType; + private static CompletableFuture fairySoulsLoaded; + private static int maxSouls = 0; + private static final Map> fairySouls = new HashMap<>(); + + @SuppressWarnings("UnusedReturnValue") + public static CompletableFuture runAsyncAfterFairySoulsLoad(Runnable runnable) { + if (fairySoulsLoaded == null) { + LOGGER.error("Fairy Souls have not being initialized yet! Please ensure the Fairy Souls module is initialized before modules calling this method in SkyblockerMod#onInitializeClient. This error can be safely ignore in a test environment."); + return CompletableFuture.completedFuture(null); + } + return fairySoulsLoaded.thenRunAsync(runnable); + } + + public static int getFairySoulsSize(@Nullable String location) { + return location == null ? maxSouls : fairySouls.get(location).size(); + } + + public static void init() { + loadFairySouls(); + ClientLifecycleEvents.CLIENT_STOPPING.register(FairySouls::saveFoundFairySouls); + ClientCommandRegistrationCallback.EVENT.register(FairySouls::registerCommands); + WorldRenderEvents.AFTER_TRANSLUCENT.register(FairySouls::render); + ClientReceiveMessageEvents.GAME.register(FairySouls::onChatMessage); + } + + private static void loadFairySouls() { + fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> { + maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls(); + NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairiesForLocation) -> fairySouls.put(location, fairiesForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableMap(pos -> pos, pos -> new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.GREEN.getColorComponents(), DyeColor.RED.getColorComponents()))))); + LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size()); + + try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { + for (Map.Entry foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + for (Map.Entry foundFairiesForLocationJson : foundFairiesForProfileJson.getValue().getAsJsonObject().asMap().entrySet()) { + String profile = foundFairiesForLocationJson.getKey(); + Map fairiesForLocation = fairySouls.get(profile); + for (JsonElement foundFairy : foundFairiesForLocationJson.getValue().getAsJsonArray().asList()) { + fairiesForLocation.get(PosUtils.parsePosString(foundFairy.getAsString())).setFound(profile); + } + } + } + LOGGER.debug("[Skyblocker] Loaded found fairy souls"); + } catch (NoSuchFileException ignored) { + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to load found fairy souls", e); + } + LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size()); + }); + } + + private static void saveFoundFairySouls(MinecraftClient client) { + try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { + Map>> foundFairies = new HashMap<>(); + for (Map.Entry> fairiesForLocation : fairySouls.entrySet()) { + for (ProfileAwareWaypoint fairySoul : fairiesForLocation.getValue().values()) { + for (String profile : fairySoul.foundProfiles) { + foundFairies.putIfAbsent(profile, new HashMap<>()); + foundFairies.get(profile).putIfAbsent(fairiesForLocation.getKey(), new HashSet<>()); + foundFairies.get(profile).get(fairiesForLocation.getKey()).add(fairySoul.pos); + } + } + } + + JsonObject foundFairiesJson = new JsonObject(); + for (Map.Entry>> foundFairiesForProfile : foundFairies.entrySet()) { + JsonObject foundFairiesForProfileJson = new JsonObject(); + for (Map.Entry> foundFairiesForLocation : foundFairiesForProfile.getValue().entrySet()) { + JsonArray foundFairiesForLocationJson = new JsonArray(); + for (BlockPos foundFairy : foundFairiesForLocation.getValue()) { + foundFairiesForLocationJson.add(PosUtils.getPosString(foundFairy)); + } + foundFairiesForProfileJson.add(foundFairiesForLocation.getKey(), foundFairiesForLocationJson); + } + foundFairiesJson.add(foundFairiesForProfile.getKey(), foundFairiesForProfileJson); + } + SkyblockerMod.GSON.toJson(foundFairiesJson, writer); + LOGGER.info("[Skyblocker] Saved found fairy souls"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to write found fairy souls to file", e); + } + } + + private static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("fairySouls") + .then(literal("markAllInCurrentIslandFound").executes(context -> { + FairySouls.markAllFairiesOnCurrentIslandFound(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.fairySouls.markAllFound"))); + return 1; + })) + .then(literal("markAllInCurrentIslandMissing").executes(context -> { + FairySouls.markAllFairiesOnCurrentIslandMissing(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.fairySouls.markAllMissing"))); + return 1; + })))); + } + + private static void render(WorldRenderContext context) { + SkyblockerConfig.FairySouls fairySoulsConfig = SkyblockerConfigManager.get().general.fairySouls; + + if (fairySoulsConfig.enableFairySoulsHelper && fairySoulsLoaded.isDone() && fairySouls.containsKey(Utils.getLocationRaw())) { + for (Waypoint fairySoul : fairySouls.get(Utils.getLocationRaw()).values()) { + boolean fairySoulNotFound = fairySoul.shouldRender(); + if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoul.pos.getSquaredDistance(context.camera().getPos()) > 2500) { + continue; + } + float[] colorComponents = fairySoulNotFound ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents(); + RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoul.pos, colorComponents, 0.5F); + } + } + } + + private static void onChatMessage(Text text, boolean overlay) { + String message = text.getString(); + if (message.equals("You have already found that Fairy Soul!") || message.equals("§d§lSOUL! §fYou found a §dFairy Soul§f!")) { + markClosestFairyFound(); + } + } + + private static void markClosestFairyFound() { + if (!fairySoulsLoaded.isDone()) return; + + PlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) { + LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because player is null"); + return; + } + + Map fairiesOnCurrentIsland = fairySouls.get(Utils.getLocationRaw()); + if (fairiesOnCurrentIsland == null) { + LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because there are no fairy souls loaded on the current island. NEU repo probably failed to load."); + return; + } + + fairiesOnCurrentIsland.values().stream() + .filter(Waypoint::shouldRender) + .min(Comparator.comparingDouble(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()))) + .filter(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()) <= 16) + .ifPresent(ProfileAwareWaypoint::setFound); + } + + public static void markAllFairiesOnCurrentIslandFound() { + Map fairiesForLocation = fairySouls.get(Utils.getLocationRaw()); + if (fairiesForLocation != null) { + fairiesForLocation.values().forEach(ProfileAwareWaypoint::setFound); + } + } + + public static void markAllFairiesOnCurrentIslandMissing() { + Map fairiesForLocation = fairySouls.get(Utils.getLocationRaw()); + if (fairiesForLocation != null) { + fairiesForLocation.values().forEach(ProfileAwareWaypoint::setMissing); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java new file mode 100644 index 00000000..5b5f4715 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java @@ -0,0 +1,213 @@ +package de.hysky.skyblocker.skyblock.waypoint; + +import com.mojang.brigadier.Command; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.Waypoint; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.event.player.AttackBlockCallback; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.fabricmc.fabric.api.event.player.UseItemCallback; +import net.fabricmc.fabric.api.util.TriState; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.command.argument.BlockPosArgumentType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.ParticleS2CPacket; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import org.apache.commons.math3.stat.regression.SimpleRegression; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class MythologicalRitual { + private static final Pattern GRIFFIN_BURROW_DUG = Pattern.compile("(?You dug out a Griffin Burrow!|You finished the Griffin burrow chain!) \\((?\\d)/4\\)"); + private static final float[] ORANGE_COLOR_COMPONENTS = DyeColor.ORANGE.getColorComponents(); + private static long lastEchoTime; + private static final Map griffinBurrows = new HashMap<>(); + @Nullable + private static BlockPos lastDugBurrowPos; + private static GriffinBurrow previousBurrow = new GriffinBurrow(BlockPos.ORIGIN); + + public static void init() { + WorldRenderEvents.AFTER_TRANSLUCENT.register(MythologicalRitual::render); + AttackBlockCallback.EVENT.register(MythologicalRitual::onAttackBlock); + UseBlockCallback.EVENT.register(MythologicalRitual::onUseBlock); + UseItemCallback.EVENT.register(MythologicalRitual::onUseItem); + ClientReceiveMessageEvents.GAME.register(MythologicalRitual::onChatMessage); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("diana") + .then(literal("clearGriffinBurrows").executes(context -> { + griffinBurrows.clear(); + return Command.SINGLE_SUCCESS; + })) + .then(literal("clearGriffinBurrow") + .then(argument("pos", BlockPosArgumentType.blockPos()).executes(context -> { + griffinBurrows.remove(context.getArgument("pos", BlockPos.class)); + return Command.SINGLE_SUCCESS; + })) + ) + ))); + + // Put a root burrow so echo detection works without a previous burrow + previousBurrow.confirmed = TriState.DEFAULT; + griffinBurrows.put(BlockPos.ORIGIN, previousBurrow); + } + + public static void onParticle(ParticleS2CPacket packet) { + if (isActive()) { + if (ParticleTypes.CRIT.equals(packet.getParameters().getType()) || ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) { + BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down(); + if (MinecraftClient.getInstance().world == null || !MinecraftClient.getInstance().world.getBlockState(pos).isOf(Blocks.GRASS_BLOCK)) { + return; + } + GriffinBurrow burrow = griffinBurrows.computeIfAbsent(pos, GriffinBurrow::new); + if (ParticleTypes.CRIT.equals(packet.getParameters().getType())) burrow.critParticle++; + if (ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) burrow.enchantParticle++; + if (burrow.critParticle >= 5 && burrow.enchantParticle >= 5 && burrow.confirmed == TriState.FALSE) { + griffinBurrows.get(pos).init(); + } + } else if (ParticleTypes.DUST.equals(packet.getParameters().getType())) { + BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down(2); + GriffinBurrow burrow = griffinBurrows.get(pos); + if (burrow == null) { + return; + } + burrow.regression.addData(packet.getX(), packet.getZ()); + double slope = burrow.regression.getSlope(); + if (Double.isNaN(slope)) { + return; + } + Vec3d nextBurrowDirection = new Vec3d(100, 0, slope * 100).normalize().multiply(100); + if (burrow.nextBurrowPlane == null) { + burrow.nextBurrowPlane = new Vec3d[4]; + } + burrow.nextBurrowPlane[0] = Vec3d.of(pos).add(nextBurrowDirection).subtract(0, 50, 0); + burrow.nextBurrowPlane[1] = Vec3d.of(pos).subtract(nextBurrowDirection).subtract(0, 50, 0); + burrow.nextBurrowPlane[2] = burrow.nextBurrowPlane[1].add(0, 100, 0); + burrow.nextBurrowPlane[3] = burrow.nextBurrowPlane[0].add(0, 100, 0); + } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType()) && packet.getCount() == 2) { + if (System.currentTimeMillis() > lastEchoTime + 10_000) { + return; + } + if (previousBurrow.echoBurrowDirection == null) { + previousBurrow.echoBurrowDirection = new Vec3d[2]; + } + previousBurrow.echoBurrowDirection[0] = previousBurrow.echoBurrowDirection[1]; + previousBurrow.echoBurrowDirection[1] = new Vec3d(packet.getX(), packet.getY(), packet.getZ()); + if (previousBurrow.echoBurrowDirection[0] == null || previousBurrow.echoBurrowDirection[1] == null) { + return; + } + Vec3d echoBurrowDirection = previousBurrow.echoBurrowDirection[1].subtract(previousBurrow.echoBurrowDirection[0]).normalize().multiply(100); + if (previousBurrow.echoBurrowPlane == null) { + previousBurrow.echoBurrowPlane = new Vec3d[4]; + } + previousBurrow.echoBurrowPlane[0] = previousBurrow.echoBurrowDirection[0].add(echoBurrowDirection).subtract(0, 50, 0); + previousBurrow.echoBurrowPlane[1] = previousBurrow.echoBurrowDirection[0].subtract(echoBurrowDirection).subtract(0, 50, 0); + previousBurrow.echoBurrowPlane[2] = previousBurrow.echoBurrowPlane[1].add(0, 100, 0); + previousBurrow.echoBurrowPlane[3] = previousBurrow.echoBurrowPlane[0].add(0, 100, 0); + } + } + } + + public static void render(WorldRenderContext context) { + if (isActive()) { + for (GriffinBurrow burrow : griffinBurrows.values()) { + if (burrow.shouldRender()) { + burrow.render(context); + } + if (burrow.confirmed != TriState.FALSE) { + if (burrow.nextBurrowPlane != null) { + RenderHelper.renderQuad(context, burrow.nextBurrowPlane, ORANGE_COLOR_COMPONENTS, 0.25F, true); + } + if (burrow.echoBurrowPlane != null) { + RenderHelper.renderQuad(context, burrow.echoBurrowPlane, ORANGE_COLOR_COMPONENTS, 0.25F, true); + } + } + } + } + } + + public static ActionResult onAttackBlock(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction direction) { + return onInteractBlock(pos); + } + + public static ActionResult onUseBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) { + return onInteractBlock(hitResult.getBlockPos()); + } + + @NotNull + private static ActionResult onInteractBlock(BlockPos pos) { + if (isActive() && griffinBurrows.containsKey(pos)) { + lastDugBurrowPos = pos; + } + return ActionResult.PASS; + } + + public static TypedActionResult onUseItem(PlayerEntity player, World world, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + if (isActive() && ItemUtils.getItemId(stack).equals("ANCESTRAL_SPADE")) { + lastEchoTime = System.currentTimeMillis(); + } + return TypedActionResult.pass(stack); + } + + public static void onChatMessage(Text message, boolean overlay) { + if (isActive() && GRIFFIN_BURROW_DUG.matcher(message.getString()).matches()) { + previousBurrow.confirmed = TriState.FALSE; + previousBurrow = griffinBurrows.get(lastDugBurrowPos); + previousBurrow.confirmed = TriState.DEFAULT; + } + } + + private static boolean isActive() { + return SkyblockerConfigManager.get().general.mythologicalRitual.enableMythologicalRitualHelper && Utils.getLocationRaw().equals("hub"); + } + + private static class GriffinBurrow extends Waypoint { + private int critParticle; + private int enchantParticle; + private TriState confirmed = TriState.FALSE; + private final SimpleRegression regression = new SimpleRegression(); + private Vec3d[] nextBurrowPlane; + @Nullable + private Vec3d[] echoBurrowDirection; + private Vec3d[] echoBurrowPlane; + + private GriffinBurrow(BlockPos pos) { + super(pos, Type.WAYPOINT, ORANGE_COLOR_COMPONENTS, 0.25F); + } + + private void init() { + confirmed = TriState.TRUE; + regression.clear(); + } + + @Override + public boolean shouldRender() { + return super.shouldRender() && confirmed == TriState.TRUE; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java new file mode 100644 index 00000000..f25b7497 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java @@ -0,0 +1,174 @@ +package de.hysky.skyblocker.skyblock.waypoint; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.brigadier.CommandDispatcher; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.PosUtils; +import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.client.MinecraftClient; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.util.*; +import java.util.concurrent.CompletableFuture; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class Relics { + private static final Logger LOGGER = LoggerFactory.getLogger(Relics.class); + private static CompletableFuture relicsLoaded; + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private static int totalRelics = 0; + private static final List relics = new ArrayList<>(); + private static final Map> foundRelics = new HashMap<>(); + + public static void init() { + ClientLifecycleEvents.CLIENT_STARTED.register(Relics::loadRelics); + ClientLifecycleEvents.CLIENT_STOPPING.register(Relics::saveFoundRelics); + ClientCommandRegistrationCallback.EVENT.register(Relics::registerCommands); + WorldRenderEvents.AFTER_TRANSLUCENT.register(Relics::render); + ClientReceiveMessageEvents.GAME.register(Relics::onChatMessage); + } + + private static void loadRelics(MinecraftClient client) { + relicsLoaded = CompletableFuture.runAsync(() -> { + try (BufferedReader reader = client.getResourceManager().openAsReader(new Identifier(SkyblockerMod.NAMESPACE, "spidersden/relics.json"))) { + for (Map.Entry json : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + if (json.getKey().equals("total")) { + totalRelics = json.getValue().getAsInt(); + } else if (json.getKey().equals("locations")) { + for (JsonElement locationJson : json.getValue().getAsJsonArray().asList()) { + JsonObject posData = locationJson.getAsJsonObject(); + relics.add(new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt())); + } + } + } + LOGGER.info("[Skyblocker] Loaded relics locations"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to load relics locations", e); + } + + try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { + for (Map.Entry profileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + Set foundRelicsForProfile = new HashSet<>(); + for (JsonElement foundRelicsJson : profileJson.getValue().getAsJsonArray().asList()) { + foundRelicsForProfile.add(PosUtils.parsePosString(foundRelicsJson.getAsString())); + } + foundRelics.put(profileJson.getKey(), foundRelicsForProfile); + } + LOGGER.debug("[Skyblocker] Loaded found relics"); + } catch (NoSuchFileException ignored) { + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to load found relics", e); + } + }); + } + + private static void saveFoundRelics(MinecraftClient client) { + try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { + JsonObject json = new JsonObject(); + for (Map.Entry> foundRelicsForProfile : foundRelics.entrySet()) { + JsonArray foundRelicsJson = new JsonArray(); + for (BlockPos foundRelic : foundRelicsForProfile.getValue()) { + foundRelicsJson.add(PosUtils.getPosString(foundRelic)); + } + json.add(foundRelicsForProfile.getKey(), foundRelicsJson); + } + SkyblockerMod.GSON.toJson(json, writer); + LOGGER.debug("[Skyblocker] Saved found relics"); + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to write found relics to file", e); + } + } + + private static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("relics") + .then(literal("markAllFound").executes(context -> { + Relics.markAllFound(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllFound"))); + return 1; + })) + .then(literal("markAllMissing").executes(context -> { + Relics.markAllMissing(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllMissing"))); + return 1; + })))); + } + + private static void render(WorldRenderContext context) { + SkyblockerConfig.Relics config = SkyblockerConfigManager.get().locations.spidersDen.relics; + + if (config.enableRelicsHelper && relicsLoaded.isDone() && Utils.getLocationRaw().equals("combat_1")) { + for (BlockPos fairySoulPos : relics) { + boolean isRelicMissing = isRelicMissing(fairySoulPos); + if (!isRelicMissing && !config.highlightFoundRelics) continue; + float[] colorComponents = isRelicMissing ? DyeColor.YELLOW.getColorComponents() : DyeColor.BROWN.getColorComponents(); + RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F); + } + } + } + + private static void onChatMessage(Text text, boolean overlay) { + String message = text.getString(); + if (message.equals("You've already found this relic!") || message.startsWith("+10,000 Coins! (") && message.endsWith("/28 Relics)")) { + markClosestRelicFound(); + } + } + + private static void markClosestRelicFound() { + if (!relicsLoaded.isDone()) return; + PlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) { + LOGGER.warn("[Skyblocker] Failed to mark closest relic as found because player is null"); + return; + } + relics.stream() + .filter(Relics::isRelicMissing) + .min(Comparator.comparingDouble(relicPos -> relicPos.getSquaredDistance(player.getPos()))) + .filter(relicPos -> relicPos.getSquaredDistance(player.getPos()) <= 16) + .ifPresent(relicPos -> { + foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); + foundRelics.get(Utils.getProfile()).add(relicPos); + }); + } + + private static boolean isRelicMissing(BlockPos relicPos) { + Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); + return foundRelicsForProfile == null || !foundRelicsForProfile.contains(relicPos); + } + + private static void markAllFound() { + foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); + foundRelics.get(Utils.getProfile()).addAll(relics); + } + + private static void markAllMissing() { + Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); + if (foundRelicsForProfile != null) { + foundRelicsForProfile.clear(); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java new file mode 100644 index 00000000..7aa99d14 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java @@ -0,0 +1,44 @@ +package de.hysky.skyblocker.utils.waypoint; + +import de.hysky.skyblocker.utils.Utils; +import net.minecraft.util.math.BlockPos; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Supplier; + +public class ProfileAwareWaypoint extends Waypoint { + public final Set foundProfiles = new HashSet<>(); + private final float[] missingColor; + private final float[] foundColor; + + public ProfileAwareWaypoint(BlockPos pos, Supplier typeSupplier, float[] missingColor, float[] foundColor) { + super(pos, typeSupplier, null); + this.missingColor = missingColor; + this.foundColor = foundColor; + } + + @Override + public boolean shouldRender() { + return !foundProfiles.contains(Utils.getProfile()); + } + + @Override + public void setFound() { + foundProfiles.add(Utils.getProfile()); + } + + public void setFound(String profile) { + foundProfiles.add(profile); + } + + @Override + public void setMissing() { + foundProfiles.remove(Utils.getProfile()); + } + + @Override + protected float[] getColorComponents() { + return foundProfiles.contains(Utils.getProfile()) ? foundColor : missingColor; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java index a8e62a94..f65e20f7 100644 --- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java +++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java @@ -62,19 +62,25 @@ public class Waypoint { this.shouldRender = true; } + protected float[] getColorComponents() { + return colorComponents; + } + public void render(WorldRenderContext context) { switch (typeSupplier.get()) { - case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha); + case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, getColorComponents(), alpha); case OUTLINED_WAYPOINT -> { + float[] colorComponents = getColorComponents(); RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha); RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls); } - case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha); + case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, getColorComponents(), alpha); case OUTLINED_HIGHLIGHT -> { + float[] colorComponents = getColorComponents(); RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha); RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls); } - case OUTLINE -> RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls); + case OUTLINE -> RenderHelper.renderOutline(context, box, getColorComponents(), lineWidth, throughWalls); } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 063b7255..1cba3f80 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -50,6 +50,10 @@ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts": "Enable Command Argument Shortcuts", "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts.@Tooltip": "Shortcuts that replace one or more word(s)/argument(s) of a command which has multiple words/arguments. Edit shortcuts with \"/skyblocker shortcuts\". Shortcuts must be enabled for this to take effect.", "text.autoconfig.skyblocker.option.general.shortcuts.config": "Shortcuts Config...", + "text.autoconfig.skyblocker.option.general.waypoints": "Waypoints", + "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "Enable Waypoints", + "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "Waypoint Type", + "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Outlines the secret in a box.", "text.autoconfig.skyblocker.option.general.quiverWarning": "Quiver Warning", "text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarning": "Enable Quiver Warning", "text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningInDungeons": "Enable Quiver Warning In Dungeons", @@ -156,8 +160,6 @@ "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSecretWaypoints": "Enable Dungeon Secret Waypoints", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.", - "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType": "Waypoint Type", - "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Outlines the secret in a box.", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.showSecretText": "Show Secret Text", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableEntranceWaypoints" : "Enable Entrance Waypoints", "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSuperboomWaypoints" : "Enable Superboom Waypoints", diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java new file mode 100644 index 00000000..9dc5b2b9 --- /dev/null +++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java @@ -0,0 +1,38 @@ +package de.hysky.skyblocker.utils.waypoint; + +import net.minecraft.util.math.BlockPos; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ProfileAwareWaypointTest { + @Test + void testShouldRender() { + ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, null, null); + waypoint.setFound("profile"); + Assertions.assertTrue(waypoint.shouldRender()); + waypoint.setFound(""); + Assertions.assertFalse(waypoint.shouldRender()); + waypoint.setMissing(); + Assertions.assertTrue(waypoint.shouldRender()); + } + + @Test + void testGetColorComponents() { + ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, new float[]{0f, 0.5f, 1f}, new float[]{1f, 0.5f, 0f}); + waypoint.setFound("profile"); + float[] colorComponents = waypoint.getColorComponents(); + Assertions.assertEquals(0f, colorComponents[0]); + Assertions.assertEquals(0.5f, colorComponents[1]); + Assertions.assertEquals(1f, colorComponents[2]); + waypoint.setFound(""); + colorComponents = waypoint.getColorComponents(); + Assertions.assertEquals(1f, colorComponents[0]); + Assertions.assertEquals(0.5f, colorComponents[1]); + Assertions.assertEquals(0f, colorComponents[2]); + waypoint.setMissing(); + colorComponents = waypoint.getColorComponents(); + Assertions.assertEquals(0f, colorComponents[0]); + Assertions.assertEquals(0.5f, colorComponents[1]); + Assertions.assertEquals(1f, colorComponents[2]); + } +} diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java index 41f5a530..b3be64b7 100644 --- a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java +++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java @@ -7,10 +7,11 @@ import org.junit.jupiter.api.Test; public class WaypointTest { private Waypoint.Type type; + private final float[] colorComponents = new float[]{0f, 0.5f, 1f}; @Test void testDefaultConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0f, 0.5f, 1f}); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents); Assertions.assertEquals(BlockPos.ORIGIN, waypoint.pos); Assertions.assertEquals(new Box(BlockPos.ORIGIN), waypoint.box); Assertions.assertEquals(type, waypoint.typeSupplier.get()); @@ -25,37 +26,37 @@ public class WaypointTest { @Test void testTypeConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, Waypoint.Type.WAYPOINT, new float[]{0, 0, 0}, Waypoint.DEFAULT_HIGHLIGHT_ALPHA); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, Waypoint.Type.WAYPOINT, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA); Assertions.assertEquals(Waypoint.Type.WAYPOINT, waypoint.typeSupplier.get()); } @Test void testAlphaConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}, 1f); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, 1f); Assertions.assertEquals(1f, waypoint.alpha); } @Test void testLineWidthConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, 10f); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, 10f); Assertions.assertEquals(10f, waypoint.lineWidth); } @Test void testThroughWallsConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, false); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, false); Assertions.assertFalse(waypoint.throughWalls); } @Test void testShouldRenderConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, true, false); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, true, false); Assertions.assertFalse(waypoint.shouldRender()); } @Test void testFound() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents); Assertions.assertTrue(waypoint.shouldRender()); waypoint.setFound(); Assertions.assertFalse(waypoint.shouldRender()); @@ -65,7 +66,7 @@ public class WaypointTest { @Test void testType() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, new float[]{0, 0, 0}); + Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents); Assertions.assertEquals(type, waypoint.typeSupplier.get()); type = Waypoint.Type.WAYPOINT; Assertions.assertEquals(type, waypoint.typeSupplier.get()); -- cgit From cf18647e45afd41995bf1a06d1a0f9862e56e5fc Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 13 Nov 2023 18:45:18 -0500 Subject: Refactor Relics --- .../skyblocker/skyblock/waypoint/FairySouls.java | 24 ++++---- .../hysky/skyblocker/skyblock/waypoint/Relics.java | 68 +++++++++------------- 2 files changed, 40 insertions(+), 52 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java index c3cd6fe2..f0e94770 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java @@ -12,7 +12,6 @@ import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.NEURepoManager; import de.hysky.skyblocker.utils.PosUtils; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint; import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; @@ -97,18 +96,18 @@ public class FairySouls { } private static void saveFoundFairySouls(MinecraftClient client) { - try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { - Map>> foundFairies = new HashMap<>(); - for (Map.Entry> fairiesForLocation : fairySouls.entrySet()) { - for (ProfileAwareWaypoint fairySoul : fairiesForLocation.getValue().values()) { - for (String profile : fairySoul.foundProfiles) { - foundFairies.putIfAbsent(profile, new HashMap<>()); - foundFairies.get(profile).putIfAbsent(fairiesForLocation.getKey(), new HashSet<>()); - foundFairies.get(profile).get(fairiesForLocation.getKey()).add(fairySoul.pos); - } + Map>> foundFairies = new HashMap<>(); + for (Map.Entry> fairiesForLocation : fairySouls.entrySet()) { + for (ProfileAwareWaypoint fairySoul : fairiesForLocation.getValue().values()) { + for (String profile : fairySoul.foundProfiles) { + foundFairies.computeIfAbsent(profile, profile_ -> new HashMap<>()); + foundFairies.get(profile).computeIfAbsent(fairiesForLocation.getKey(), location_ -> new HashSet<>()); + foundFairies.get(profile).get(fairiesForLocation.getKey()).add(fairySoul.pos); } } + } + try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) { JsonObject foundFairiesJson = new JsonObject(); for (Map.Entry>> foundFairiesForProfile : foundFairies.entrySet()) { JsonObject foundFairiesForProfileJson = new JsonObject(); @@ -152,8 +151,7 @@ public class FairySouls { if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoul.pos.getSquaredDistance(context.camera().getPos()) > 2500) { continue; } - float[] colorComponents = fairySoulNotFound ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents(); - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoul.pos, colorComponents, 0.5F); + fairySoul.render(context); } } } @@ -184,7 +182,7 @@ public class FairySouls { .filter(Waypoint::shouldRender) .min(Comparator.comparingDouble(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()))) .filter(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()) <= 16) - .ifPresent(ProfileAwareWaypoint::setFound); + .ifPresent(Waypoint::setFound); } public static void markAllFairiesOnCurrentIslandFound() { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java index f25b7497..952f2f59 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java @@ -11,7 +11,8 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.PosUtils; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint; +import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; @@ -28,21 +29,24 @@ import net.minecraft.util.math.BlockPos; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; public class Relics { private static final Logger LOGGER = LoggerFactory.getLogger(Relics.class); + private static final Supplier TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType; private static CompletableFuture relicsLoaded; @SuppressWarnings({"unused", "FieldCanBeLocal"}) private static int totalRelics = 0; - private static final List relics = new ArrayList<>(); - private static final Map> foundRelics = new HashMap<>(); + private static final Map relics = new HashMap<>(); public static void init() { ClientLifecycleEvents.CLIENT_STARTED.register(Relics::loadRelics); @@ -61,7 +65,8 @@ public class Relics { } else if (json.getKey().equals("locations")) { for (JsonElement locationJson : json.getValue().getAsJsonArray().asList()) { JsonObject posData = locationJson.getAsJsonObject(); - relics.add(new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt())); + BlockPos pos = new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt()); + relics.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.YELLOW.getColorComponents(), DyeColor.BROWN.getColorComponents())); } } } @@ -72,11 +77,9 @@ public class Relics { try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { for (Map.Entry profileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { - Set foundRelicsForProfile = new HashSet<>(); for (JsonElement foundRelicsJson : profileJson.getValue().getAsJsonArray().asList()) { - foundRelicsForProfile.add(PosUtils.parsePosString(foundRelicsJson.getAsString())); + relics.get(PosUtils.parsePosString(foundRelicsJson.getAsString())).setFound(profileJson.getKey()); } - foundRelics.put(profileJson.getKey(), foundRelicsForProfile); } LOGGER.debug("[Skyblocker] Loaded found relics"); } catch (NoSuchFileException ignored) { @@ -87,6 +90,14 @@ public class Relics { } private static void saveFoundRelics(MinecraftClient client) { + Map> foundRelics = new HashMap<>(); + for (ProfileAwareWaypoint relic : relics.values()) { + for (String profile : relic.foundProfiles) { + foundRelics.computeIfAbsent(profile, profile_ -> new HashSet<>()); + foundRelics.get(profile).add(relic.pos); + } + } + try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) { JsonObject json = new JsonObject(); for (Map.Entry> foundRelicsForProfile : foundRelics.entrySet()) { @@ -107,12 +118,12 @@ public class Relics { dispatcher.register(literal(SkyblockerMod.NAMESPACE) .then(literal("relics") .then(literal("markAllFound").executes(context -> { - Relics.markAllFound(); + relics.values().forEach(ProfileAwareWaypoint::setFound); context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllFound"))); return 1; })) .then(literal("markAllMissing").executes(context -> { - Relics.markAllMissing(); + relics.values().forEach(ProfileAwareWaypoint::setMissing); context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllMissing"))); return 1; })))); @@ -122,11 +133,10 @@ public class Relics { SkyblockerConfig.Relics config = SkyblockerConfigManager.get().locations.spidersDen.relics; if (config.enableRelicsHelper && relicsLoaded.isDone() && Utils.getLocationRaw().equals("combat_1")) { - for (BlockPos fairySoulPos : relics) { - boolean isRelicMissing = isRelicMissing(fairySoulPos); + for (ProfileAwareWaypoint relic : relics.values()) { + boolean isRelicMissing = relic.shouldRender(); if (!isRelicMissing && !config.highlightFoundRelics) continue; - float[] colorComponents = isRelicMissing ? DyeColor.YELLOW.getColorComponents() : DyeColor.BROWN.getColorComponents(); - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F); + relic.render(context); } } } @@ -145,30 +155,10 @@ public class Relics { LOGGER.warn("[Skyblocker] Failed to mark closest relic as found because player is null"); return; } - relics.stream() - .filter(Relics::isRelicMissing) - .min(Comparator.comparingDouble(relicPos -> relicPos.getSquaredDistance(player.getPos()))) - .filter(relicPos -> relicPos.getSquaredDistance(player.getPos()) <= 16) - .ifPresent(relicPos -> { - foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); - foundRelics.get(Utils.getProfile()).add(relicPos); - }); - } - - private static boolean isRelicMissing(BlockPos relicPos) { - Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); - return foundRelicsForProfile == null || !foundRelicsForProfile.contains(relicPos); - } - - private static void markAllFound() { - foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>()); - foundRelics.get(Utils.getProfile()).addAll(relics); - } - - private static void markAllMissing() { - Set foundRelicsForProfile = foundRelics.get(Utils.getProfile()); - if (foundRelicsForProfile != null) { - foundRelicsForProfile.clear(); - } + relics.values().stream() + .filter(Waypoint::shouldRender) + .min(Comparator.comparingDouble(relic -> relic.pos.getSquaredDistance(player.getPos()))) + .filter(relic -> relic.pos.getSquaredDistance(player.getPos()) <= 16) + .ifPresent(Waypoint::setFound); } } -- cgit From 9a86f3c5297c0e597abce80222db8ef9c42fbe8e Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 13 Nov 2023 20:45:27 -0500 Subject: Refactor more waypoints --- .../hysky/skyblocker/skyblock/TeleportOverlay.java | 2 +- .../skyblocker/skyblock/rift/EffigyWaypoints.java | 6 +- .../skyblocker/skyblock/rift/EnigmaSouls.java | 108 +++++++++------------ .../skyblock/rift/MirrorverseWaypoints.java | 55 +++++------ .../skyblocker/utils/render/RenderHelper.java | 22 ++--- .../hysky/skyblocker/utils/waypoint/Waypoint.java | 20 ++-- .../skyblocker/utils/waypoint/WaypointTest.java | 6 -- 7 files changed, 94 insertions(+), 125 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java index c290e5b8..e572d9dc 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java @@ -102,7 +102,7 @@ public class TeleportOverlay { @SuppressWarnings("DataFlowIssue") BlockState state = client.world.getBlockState(pos); if (!state.isAir() && client.world.getBlockState(pos.up()).isAir() && client.world.getBlockState(pos.up(2)).isAir()) { - RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f); + RenderHelper.renderFilled(wrc, pos, COLOR_COMPONENTS, 0.5f, false); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java index 7ebf44b0..95e08c80 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java @@ -58,11 +58,11 @@ public class EffigyWaypoints { for (BlockPos effigy : UNBROKEN_EFFIGIES) { float[] colorComponents = DyeColor.RED.getColorComponents(); if (SkyblockerConfigManager.get().slayer.vampireSlayer.compactEffigyWaypoints) { - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F); + RenderHelper.renderFilledWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F, true); } else { - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy, colorComponents, 0.5F); + RenderHelper.renderFilledWithBeaconBeam(context, effigy, colorComponents, 0.5F, true); for (int i = 1; i < 6; i++) { - RenderHelper.renderFilledThroughWalls(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i)); + RenderHelper.renderFilled(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i), true); } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java index 744edd4c..aa55a4e3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java @@ -1,38 +1,19 @@ package de.hysky.skyblocker.skyblock.rift; -import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; - import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.PosUtils; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint; +import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.minecraft.client.MinecraftClient; @@ -43,13 +24,27 @@ import net.minecraft.util.DyeColor; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; public class EnigmaSouls { private static final Logger LOGGER = LoggerFactory.getLogger(EnigmaSouls.class); + private static final Supplier TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType; private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/enigma_soul_waypoints.json"); - private static final BlockPos[] SOUL_WAYPOINTS = new BlockPos[42]; + private static final Map SOUL_WAYPOINTS = new HashMap<>(42); private static final Path FOUND_SOULS_FILE = SkyblockerMod.CONFIG_DIR.resolve("found_enigma_souls.json"); - private static final Object2ObjectOpenHashMap> FOUND_SOULS = new Object2ObjectOpenHashMap<>(); private static final float[] GREEN = DyeColor.GREEN.getColorComponents(); private static final float[] RED = DyeColor.RED.getColorComponents(); @@ -64,7 +59,8 @@ public class EnigmaSouls { for (int i = 0; i < waypoints.size(); i++) { JsonObject waypoint = waypoints.get(i).getAsJsonObject(); - SOUL_WAYPOINTS[i] = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt()); + BlockPos pos = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt()); + SOUL_WAYPOINTS.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, GREEN, RED)); } } catch (IOException e) { @@ -74,13 +70,9 @@ public class EnigmaSouls { //Load found souls try (BufferedReader reader = Files.newBufferedReader(FOUND_SOULS_FILE)) { for (Map.Entry profile : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { - ObjectOpenHashSet foundSoulsOnProfile = new ObjectOpenHashSet<>(); - for (JsonElement foundSoul : profile.getValue().getAsJsonArray().asList()) { - foundSoulsOnProfile.add(PosUtils.parsePosString(foundSoul.getAsString())); + SOUL_WAYPOINTS.get(PosUtils.parsePosString(foundSoul.getAsString())).setFound(); } - - FOUND_SOULS.put(profile.getKey(), foundSoulsOnProfile); } } catch (NoSuchFileException ignored) { } catch (IOException e) { @@ -90,9 +82,16 @@ public class EnigmaSouls { } static void save(MinecraftClient client) { - JsonObject json = new JsonObject(); + Map> foundSouls = new HashMap<>(); + for (ProfileAwareWaypoint soul : SOUL_WAYPOINTS.values()) { + for (String profile : soul.foundProfiles) { + foundSouls.computeIfAbsent(profile, profile_ -> new HashSet<>()); + foundSouls.get(profile).add(soul.pos); + } + } - for (Map.Entry> foundSoulsForProfile : FOUND_SOULS.entrySet()) { + JsonObject json = new JsonObject(); + for (Map.Entry> foundSoulsForProfile : foundSouls.entrySet()) { JsonArray foundSoulsJson = new JsonArray(); for (BlockPos foundSoul : foundSoulsForProfile.getValue()) { @@ -109,15 +108,15 @@ public class EnigmaSouls { } } - static void render(WorldRenderContext wrc) { + static void render(WorldRenderContext context) { SkyblockerConfig.Rift config = SkyblockerConfigManager.get().locations.rift; if (Utils.isInTheRift() && config.enigmaSoulWaypoints && soulsLoaded.isDone()) { - for (BlockPos pos : SOUL_WAYPOINTS) { - if (isSoulMissing(pos)) { - RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, GREEN, 0.5f); + for (Waypoint soul : SOUL_WAYPOINTS.values()) { + if (soul.shouldRender()) { + soul.render(context); } else if (config.highlightFoundEnigmaSouls) { - RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, RED, 0.5f); + soul.render(context); } } } @@ -127,7 +126,8 @@ public class EnigmaSouls { if (Utils.isInTheRift() && !overlay) { String message = text.getString(); - if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!")) markClosestSoulAsFound(); + if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!")) + markClosestSoulAsFound(); } } @@ -136,13 +136,13 @@ public class EnigmaSouls { .then(literal("rift") .then(literal("enigmaSouls") .then(literal("markAllFound").executes(context -> { - markAllFound(); + SOUL_WAYPOINTS.values().forEach(Waypoint::setFound); context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllFound"))); return Command.SINGLE_SUCCESS; })) .then(literal("markAllMissing").executes(context -> { - markAllMissing(); + SOUL_WAYPOINTS.values().forEach(Waypoint::setMissing); context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllMissing"))); return Command.SINGLE_SUCCESS; @@ -154,30 +154,10 @@ public class EnigmaSouls { if (!soulsLoaded.isDone() || player == null) return; - Arrays.stream(SOUL_WAYPOINTS) - .filter(EnigmaSouls::isSoulMissing) - .min(Comparator.comparingDouble(soulPos -> soulPos.getSquaredDistance(player.getPos()))) - .filter(soulPos -> soulPos.getSquaredDistance(player.getPos()) <= 16) - .ifPresent(soulPos -> { - FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>()); - FOUND_SOULS.get(Utils.getProfile()).add(soulPos); - }); - } - - private static boolean isSoulMissing(BlockPos soulPos) { - ObjectOpenHashSet foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile()); - - return foundSoulsOnProfile == null || !foundSoulsOnProfile.contains(soulPos); - } - - private static void markAllFound() { - FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>()); - FOUND_SOULS.get(Utils.getProfile()).addAll(List.of(SOUL_WAYPOINTS)); - } - - private static void markAllMissing() { - ObjectOpenHashSet foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile()); - - if (foundSoulsOnProfile != null) foundSoulsOnProfile.clear(); + SOUL_WAYPOINTS.values().stream() + .filter(Waypoint::shouldRender) + .min(Comparator.comparingDouble(soul -> soul.pos.getSquaredDistance(player.getPos()))) + .filter(soul -> soul.pos.getSquaredDistance(player.getPos()) <= 16) + .ifPresent(Waypoint::setFound); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java index 7dda741f..83199e99 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java @@ -6,7 +6,7 @@ import com.google.gson.JsonParser; import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Utils; -import de.hysky.skyblocker.utils.render.RenderHelper; +import de.hysky.skyblocker.utils.waypoint.Waypoint; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; import net.minecraft.client.MinecraftClient; import net.minecraft.util.DyeColor; @@ -18,13 +18,15 @@ import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; public class MirrorverseWaypoints { private static final Logger LOGGER = LoggerFactory.getLogger("skyblocker"); + private static final Supplier WAYPOINT_TYPE = () -> Waypoint.Type.HIGHLIGHT; private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/mirrorverse_waypoints.json"); - private static final BlockPos[] LAVA_PATH_WAYPOINTS = new BlockPos[107]; - private static final BlockPos[] UPSIDE_DOWN_WAYPOINTS = new BlockPos[66]; - private static final BlockPos[] TURBULATOR_WAYPOINTS = new BlockPos[27]; + private static Waypoint[] LAVA_PATH_WAYPOINTS; + private static Waypoint[] UPSIDE_DOWN_WAYPOINTS; + private static Waypoint[] TURBULATOR_WAYPOINTS; private static final float[] COLOR_COMPONENTS = DyeColor.RED.getColorComponents(); private static CompletableFuture waypointsLoaded; @@ -35,51 +37,44 @@ public class MirrorverseWaypoints { static void load(MinecraftClient client) { waypointsLoaded = CompletableFuture.runAsync(() -> { try (BufferedReader reader = client.getResourceManager().openAsReader(WAYPOINTS_JSON)) { - JsonObject file = JsonParser.parseReader(reader).getAsJsonObject(); - JsonArray sections = file.get("sections").getAsJsonArray(); + JsonArray sections = JsonParser.parseReader(reader).getAsJsonObject().get("sections").getAsJsonArray(); /// Lava Path - JsonArray lavaPathWaypoints = sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray(); - - for (int i = 0; i < lavaPathWaypoints.size(); i++) { - JsonObject point = lavaPathWaypoints.get(i).getAsJsonObject(); - LAVA_PATH_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()); - } + LAVA_PATH_WAYPOINTS = loadWaypoints(sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray()); /// Upside Down Parkour - JsonArray upsideDownParkourWaypoints = sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray(); - - for (int i = 0; i < upsideDownParkourWaypoints.size(); i++) { - JsonObject point = upsideDownParkourWaypoints.get(i).getAsJsonObject(); - UPSIDE_DOWN_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()); - } + UPSIDE_DOWN_WAYPOINTS = loadWaypoints(sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray()); /// Turbulator Parkour - JsonArray turbulatorParkourWaypoints = sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray(); - - for (int i = 0; i < turbulatorParkourWaypoints.size(); i++) { - JsonObject point = turbulatorParkourWaypoints.get(i).getAsJsonObject(); - TURBULATOR_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()); - } + TURBULATOR_WAYPOINTS = loadWaypoints(sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray()); } catch (IOException e) { LOGGER.error("[Skyblocker] Mirrorverse Waypoints failed to load ;(", e); } }); } + private static Waypoint[] loadWaypoints(JsonArray waypointsJson) { + Waypoint[] waypoints = new Waypoint[waypointsJson.size()]; + for (int i = 0; i < waypointsJson.size(); i++) { + JsonObject point = waypointsJson.get(i).getAsJsonObject(); + waypoints[i] = new Waypoint(new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()), WAYPOINT_TYPE, COLOR_COMPONENTS, false); + } + return waypoints; + } + protected static void render(WorldRenderContext wrc) { //I would also check for the mirrorverse location but the scoreboard stuff is not performant at all... if (Utils.isInTheRift() && SkyblockerConfigManager.get().locations.rift.mirrorverseWaypoints && waypointsLoaded.isDone()) { - for (BlockPos pos : LAVA_PATH_WAYPOINTS) { - RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f); + for (Waypoint waypoint : LAVA_PATH_WAYPOINTS) { + waypoint.render(wrc); } - for (BlockPos pos : UPSIDE_DOWN_WAYPOINTS) { - RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f); + for (Waypoint waypoint : UPSIDE_DOWN_WAYPOINTS) { + waypoint.render(wrc); } - for (BlockPos pos : TURBULATOR_WAYPOINTS) { - RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f); + for (Waypoint waypoint : TURBULATOR_WAYPOINTS) { + waypoint.render(wrc); } } } 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 3d8213fe..43d595a5 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java @@ -46,20 +46,20 @@ public class RenderHelper { WorldRenderEvents.AFTER_TRANSLUCENT.register(TRANSLUCENT_DRAW, RenderHelper::drawTranslucents); } - public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) { - renderFilledThroughWalls(context, pos, colorComponents, alpha); + public static void renderFilledWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) { + renderFilled(context, pos, colorComponents, alpha, throughWalls); renderBeaconBeam(context, pos, colorComponents); } - 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)) { - 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, Vec3d.of(pos), ONE, colorComponents, alpha, false); + public static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) { + if (throughWalls) { + if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) { + renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true); + } + } else { + if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) { + renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false); + } } } diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java index f65e20f7..eb30cf8d 100644 --- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java +++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java @@ -20,21 +20,21 @@ public class Waypoint { private boolean shouldRender; protected Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents) { - this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA); + this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH); } protected Waypoint(BlockPos pos, Type type, float[] colorComponents, float alpha) { - this(pos, () -> type, colorComponents, alpha); - } - - protected Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents, float alpha) { - this(pos, typeSupplier, colorComponents, alpha, DEFAULT_LINE_WIDTH); + this(pos, () -> type, colorComponents, alpha, DEFAULT_LINE_WIDTH); } protected Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents, float alpha, float lineWidth) { this(pos, typeSupplier, colorComponents, alpha, lineWidth, true); } + public Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents, boolean throughWalls) { + this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH, throughWalls); + } + protected Waypoint(BlockPos pos, Supplier typeSupplier, float[] colorComponents, float alpha, float lineWidth, boolean throughWalls) { this(pos, typeSupplier, colorComponents, alpha, lineWidth, throughWalls, true); } @@ -68,16 +68,16 @@ public class Waypoint { public void render(WorldRenderContext context) { switch (typeSupplier.get()) { - case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, getColorComponents(), alpha); + case WAYPOINT -> RenderHelper.renderFilledWithBeaconBeam(context, pos, getColorComponents(), alpha, throughWalls); case OUTLINED_WAYPOINT -> { float[] colorComponents = getColorComponents(); - RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha); + RenderHelper.renderFilledWithBeaconBeam(context, pos, colorComponents, alpha, throughWalls); RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls); } - case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, getColorComponents(), alpha); + case HIGHLIGHT -> RenderHelper.renderFilled(context, pos, getColorComponents(), alpha, throughWalls); case OUTLINED_HIGHLIGHT -> { float[] colorComponents = getColorComponents(); - RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha); + RenderHelper.renderFilled(context, pos, colorComponents, alpha, throughWalls); RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls); } case OUTLINE -> RenderHelper.renderOutline(context, box, getColorComponents(), lineWidth, throughWalls); diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java index b3be64b7..d8839951 100644 --- a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java +++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java @@ -30,12 +30,6 @@ public class WaypointTest { Assertions.assertEquals(Waypoint.Type.WAYPOINT, waypoint.typeSupplier.get()); } - @Test - void testAlphaConstructor() { - Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, 1f); - Assertions.assertEquals(1f, waypoint.alpha); - } - @Test void testLineWidthConstructor() { Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, 10f); -- cgit From 8ac3fd07f712ddc45cc8477a5de9bd543a29e166 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Fri, 17 Nov 2023 10:26:51 -0500 Subject: Add note --- .../java/de/hysky/skyblocker/config/categories/GeneralCategory.java | 2 +- src/main/resources/assets/skyblocker/lang/en_us.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index 0f49be7b..be5f0665 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -275,7 +275,7 @@ public class GeneralCategory { .build()) .option(Option.createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"))) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote"))) .binding(defaults.general.waypoints.waypointType, () -> config.general.waypoints.waypointType, newValue -> config.general.waypoints.waypointType = newValue) diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 1cba3f80..d8cba6f4 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -53,7 +53,8 @@ "text.autoconfig.skyblocker.option.general.waypoints": "Waypoints", "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "Enable Waypoints", "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "Waypoint Type", - "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Outlines the secret in a box.", + "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and a beacon beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Only displays an outline.", + "text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote": "\n\n\nThis option does not apply to all waypoints. Some waypoints such as secret waypoints have their own waypoint type option.", "text.autoconfig.skyblocker.option.general.quiverWarning": "Quiver Warning", "text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarning": "Enable Quiver Warning", "text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningInDungeons": "Enable Quiver Warning In Dungeons", -- cgit