From bd3f0329d0e391bd84b5f9e3ff207d9dd9815853 Mon Sep 17 00:00:00 2001 From: Yasin Date: Mon, 9 Oct 2023 12:58:02 +0200 Subject: new pr because fixing merge conflict would take too long --- .../skyblocker/skyblock/spidersden/Relics.java | 171 +++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java (limited to 'src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java new file mode 100644 index 00000000..e5223874 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java @@ -0,0 +1,171 @@ +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.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.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 = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) { + 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 (FileNotFoundException ignored) { + } catch (IOException e) { + LOGGER.error("[Skyblocker] Failed to load found relics", e); + } + }); + } + + private static void saveFoundRelics(MinecraftClient client) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) { + 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(Text.translatable("skyblocker.relics.markAllFound")); + return 1; + })) + .then(literal("markAllMissing").executes(context -> { + Relics.markAllMissing(); + context.getSource().sendFeedback(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(); + } + } +} -- cgit