diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2023-10-22 23:35:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-22 23:35:00 -0400 |
commit | 90a47b7443de97b72082bd965c4fde888186a060 (patch) | |
tree | fd0b87ad088aee809060cc8ce143936af1d2e524 /src/main/java | |
parent | a96eb865678e178028493be597794bba8f503bde (diff) | |
parent | a9d8ff4284abe0342970e3a4b6a19c19d944564e (diff) | |
download | Skyblocker-90a47b7443de97b72082bd965c4fde888186a060.tar.gz Skyblocker-90a47b7443de97b72082bd965c4fde888186a060.tar.bz2 Skyblocker-90a47b7443de97b72082bd965c4fde888186a060.zip |
Merge pull request #383 from AzureAaron/enigma-souls
Enigma Soul Waypoints
Diffstat (limited to 'src/main/java')
5 files changed, 243 insertions, 32 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index 001c7506..51f3f098 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -743,6 +743,12 @@ public class SkyblockerConfig { public static class Rift { @SerialEntry public boolean mirrorverseWaypoints = true; + + @SerialEntry + public boolean enigmaSoulWaypoints = false; + + @SerialEntry + public boolean highlightFoundEnigmaSouls = true; @SerialEntry public int mcGrubberStacks = 0; diff --git a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java index 399bb9f6..5e662fcc 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java @@ -46,6 +46,21 @@ public class LocationsCategory { newValue -> config.locations.rift.mirrorverseWaypoints = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints.@Tooltip"))) + .binding(defaults.locations.rift.enigmaSoulWaypoints, + () -> config.locations.rift.enigmaSoulWaypoints, + newValue -> config.locations.rift.enigmaSoulWaypoints = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.highlightFoundEnigmaSouls")) + .binding(defaults.locations.rift.highlightFoundEnigmaSouls, + () -> config.locations.rift.highlightFoundEnigmaSouls, + newValue -> config.locations.rift.highlightFoundEnigmaSouls = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .option(Option.<Integer>createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.mcGrubberStacks")) .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.mcGrubberStacks.@Tooltip"))) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java new file mode 100644 index 00000000..744edd4c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java @@ -0,0 +1,183 @@ +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 net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; + +public class EnigmaSouls { + private static final Logger LOGGER = LoggerFactory.getLogger(EnigmaSouls.class); + 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 Path FOUND_SOULS_FILE = SkyblockerMod.CONFIG_DIR.resolve("found_enigma_souls.json"); + private static final Object2ObjectOpenHashMap<String, ObjectOpenHashSet<BlockPos>> FOUND_SOULS = new Object2ObjectOpenHashMap<>(); + private static final float[] GREEN = DyeColor.GREEN.getColorComponents(); + private static final float[] RED = DyeColor.RED.getColorComponents(); + + private static CompletableFuture<Void> soulsLoaded; + + static void load(MinecraftClient client) { + //Load waypoints + soulsLoaded = CompletableFuture.runAsync(() -> { + try (BufferedReader reader = client.getResourceManager().openAsReader(WAYPOINTS_JSON)) { + JsonObject file = JsonParser.parseReader(reader).getAsJsonObject(); + JsonArray waypoints = file.get("waypoints").getAsJsonArray(); + + 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()); + } + + } catch (IOException e) { + LOGGER.error("[Skyblocker] There was an error while loading enigma soul waypoints!", e); + } + + //Load found souls + try (BufferedReader reader = Files.newBufferedReader(FOUND_SOULS_FILE)) { + for (Map.Entry<String, JsonElement> profile : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) { + ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = new ObjectOpenHashSet<>(); + + for (JsonElement foundSoul : profile.getValue().getAsJsonArray().asList()) { + foundSoulsOnProfile.add(PosUtils.parsePosString(foundSoul.getAsString())); + } + + FOUND_SOULS.put(profile.getKey(), foundSoulsOnProfile); + } + } catch (NoSuchFileException ignored) { + } catch (IOException e) { + LOGGER.error("[Skyblocker] There was an error while loading found enigma souls!", e); + } + }); + } + + static void save(MinecraftClient client) { + JsonObject json = new JsonObject(); + + for (Map.Entry<String, ObjectOpenHashSet<BlockPos>> foundSoulsForProfile : FOUND_SOULS.entrySet()) { + JsonArray foundSoulsJson = new JsonArray(); + + for (BlockPos foundSoul : foundSoulsForProfile.getValue()) { + foundSoulsJson.add(PosUtils.getPosString(foundSoul)); + } + + json.add(foundSoulsForProfile.getKey(), foundSoulsJson); + } + + try (BufferedWriter writer = Files.newBufferedWriter(FOUND_SOULS_FILE)) { + SkyblockerMod.GSON.toJson(json, writer); + } catch (IOException e) { + LOGGER.error("[Skyblocker] There was an error while saving found enigma souls!", e); + } + } + + static void render(WorldRenderContext wrc) { + 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); + } else if (config.highlightFoundEnigmaSouls) { + RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, RED, 0.5f); + } + } + } + } + + static void onMessage(Text text, boolean overlay) { + 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(); + } + } + + static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("rift") + .then(literal("enigmaSouls") + .then(literal("markAllFound").executes(context -> { + markAllFound(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllFound"))); + + return Command.SINGLE_SUCCESS; + })) + .then(literal("markAllMissing").executes(context -> { + markAllMissing(); + context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllMissing"))); + + return Command.SINGLE_SUCCESS; + }))))); + } + + private static void markClosestSoulAsFound() { + ClientPlayerEntity player = MinecraftClient.getInstance().player; + + 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<BlockPos> 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<BlockPos> foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile()); + + if (foundSoulsOnProfile != null) foundSoulsOnProfile.clear(); + } +} 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 06181349..7dda741f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java @@ -17,61 +17,59 @@ import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; +import java.util.concurrent.CompletableFuture; public class MirrorverseWaypoints { private static final Logger LOGGER = LoggerFactory.getLogger("skyblocker"); - private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "mirrorverse_waypoints.json"); + 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 final float[] COLOR_COMPONENTS = DyeColor.RED.getColorComponents(); - static { - loadWaypoints(); - } + private static CompletableFuture<Void> waypointsLoaded; /** * Loads the waypoint locations into memory */ - private static void loadWaypoints() { - try (BufferedReader reader = CLIENT.getResourceManager().openAsReader(WAYPOINTS_JSON)) { - JsonObject file = JsonParser.parseReader(reader).getAsJsonObject(); - JsonArray sections = file.get("sections").getAsJsonArray(); + 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(); - /// Lava Path - JsonArray lavaPathWaypoints = sections.get(0).getAsJsonObject().get("waypoints").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()); - } + 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()); + } - /// Upside Down Parkour - JsonArray upsideDownParkourWaypoints = sections.get(1).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()); - } + 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()); + } - /// Turbulator Parkour - JsonArray turbulatorParkourWaypoints = sections.get(2).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()); + 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()); + } + } catch (IOException e) { + LOGGER.error("[Skyblocker] Mirrorverse Waypoints failed to load ;(", e); } - - } catch (IOException e) { - LOGGER.info("[Skyblocker] Mirrorverse Waypoints failed to load ;("); - e.printStackTrace(); - } + }); } 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) { + if (Utils.isInTheRift() && SkyblockerConfigManager.get().locations.rift.mirrorverseWaypoints && waypointsLoaded.isDone()) { for (BlockPos pos : LAVA_PATH_WAYPOINTS) { RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/TheRift.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/TheRift.java index b39151d3..02b694b6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/rift/TheRift.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/TheRift.java @@ -2,6 +2,9 @@ package de.hysky.skyblocker.skyblock.rift; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +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.WorldRenderEvents; public class TheRift { @@ -13,6 +16,12 @@ public class TheRift { public static void init() { WorldRenderEvents.AFTER_TRANSLUCENT.register(MirrorverseWaypoints::render); WorldRenderEvents.AFTER_TRANSLUCENT.register(EffigyWaypoints::render); + WorldRenderEvents.AFTER_TRANSLUCENT.register(EnigmaSouls::render); + ClientLifecycleEvents.CLIENT_STARTED.register(MirrorverseWaypoints::load); + ClientLifecycleEvents.CLIENT_STARTED.register(EnigmaSouls::load); + ClientLifecycleEvents.CLIENT_STOPPING.register(EnigmaSouls::save); + ClientReceiveMessageEvents.GAME.register(EnigmaSouls::onMessage); + ClientCommandRegistrationCallback.EVENT.register(EnigmaSouls::registerCommands); Scheduler.INSTANCE.scheduleCyclic(EffigyWaypoints::updateEffigies, SkyblockerConfigManager.get().slayer.vampireSlayer.effigyUpdateFrequency); Scheduler.INSTANCE.scheduleCyclic(TwinClawsIndicator::updateIce, SkyblockerConfigManager.get().slayer.vampireSlayer.holyIceUpdateFrequency); Scheduler.INSTANCE.scheduleCyclic(ManiaIndicator::updateMania, SkyblockerConfigManager.get().slayer.vampireSlayer.maniaUpdateFrequency); |