aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin <92656833+kevinthegreat1@users.noreply.github.com>2024-02-14 14:55:13 -0500
committerGitHub <noreply@github.com>2024-02-14 14:55:13 -0500
commit1486efaca25f1c2ca55e6428cb87c378969fd5d7 (patch)
tree4d8a3c3ea244cb8e0bb1181aac089cb7b1c654d6 /src
parent5e52750ee03f3a972eaabfcfbe2d6271ba50c13b (diff)
parent16e94a9643cf3f75f8a0804d3c0ea85cbb6534f4 (diff)
downloadSkyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.tar.gz
Skyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.tar.bz2
Skyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.zip
Merge pull request #519 from AzureAaron/kuudra
Kuudra Features
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java34
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java1
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java85
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/PlayerInventoryMixin.java21
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/ArrowPoisonWarning.java54
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java51
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/KuudraWaypoints.java161
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/PosUtils.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java5
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java4
-rw-r--r--src/main/resources/assets/skyblocker/crimson/kuudra/pearl_waypoints.json96
-rw-r--r--src/main/resources/assets/skyblocker/crimson/kuudra/safe_spot_waypoints.json19
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json17
-rw-r--r--src/main/resources/skyblocker.mixins.json1
15 files changed, 558 insertions, 2 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index c11e4c86..a438419b 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -5,6 +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.crimson.kuudra.Kuudra;
import de.hysky.skyblocker.skyblock.dungeon.*;
import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen;
import de.hysky.skyblocker.skyblock.dungeon.puzzle.CreeperBeams;
@@ -137,6 +138,7 @@ public class SkyblockerMod implements ClientModInitializer {
SecretsTracker.init();
ApiUtils.init();
Debug.init();
+ Kuudra.init();
RenderHelper.init();
containerSolverManager.init();
statusBarTracker.init();
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
index 4acb8064..51c34343 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
@@ -608,6 +608,9 @@ public class SkyblockerConfig {
public Barn barn = new Barn();
@SerialEntry
+ public CrimsonIsle crimsonIsle = new CrimsonIsle();
+
+ @SerialEntry
public Dungeons dungeons = new Dungeons();
@SerialEntry
@@ -956,6 +959,37 @@ public class SkyblockerConfig {
public boolean solveTreasureHunter = true;
}
+ public static class CrimsonIsle {
+ @SerialEntry
+ public Kuudra kuudra = new Kuudra();
+ }
+
+ public static class Kuudra {
+ @SerialEntry
+ public boolean supplyWaypoints = true;
+
+ @SerialEntry
+ public boolean fuelWaypoints = true;
+
+ @SerialEntry
+ public Waypoint.Type suppliesAndFuelWaypointType = Waypoint.Type.WAYPOINT;
+
+ @SerialEntry
+ public boolean ballistaBuildWaypoints = true;
+
+ @SerialEntry
+ public boolean safeSpotWaypoints = true;
+
+ @SerialEntry
+ public boolean pearlWaypoints = true;
+
+ @SerialEntry
+ public boolean noArrowPoisonWarning = true;
+
+ @SerialEntry
+ public int arrowPoisonThreshold = 16;
+ }
+
public static class Rift {
@SerialEntry
public boolean mirrorverseWaypoints = true;
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
index 3a2601ad..70578822 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
@@ -73,6 +73,7 @@ public class SkyblockerConfigManager {
.category(GeneralCategory.create(defaults, config))
.category(DungeonsCategory.create(defaults, config))
.category(DwarvenMinesCategory.create(defaults, config))
+ .category(CrimsonIsleCategory.create(defaults, config))
.category(LocationsCategory.create(defaults, config))
.category(SlayersCategory.create(defaults, config))
.category(QuickNavigationCategory.create(defaults, config))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java
new file mode 100644
index 00000000..3c2dc3b6
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java
@@ -0,0 +1,85 @@
+package de.hysky.skyblocker.config.categories;
+
+import de.hysky.skyblocker.config.ConfigUtils;
+import de.hysky.skyblocker.config.SkyblockerConfig;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
+import dev.isxander.yacl3.api.ConfigCategory;
+import dev.isxander.yacl3.api.Option;
+import dev.isxander.yacl3.api.OptionDescription;
+import dev.isxander.yacl3.api.OptionGroup;
+import dev.isxander.yacl3.api.controller.IntegerFieldControllerBuilder;
+import net.minecraft.text.Text;
+
+public class CrimsonIsleCategory {
+
+ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
+ return ConfigCategory.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.category.crimsonIsle"))
+
+ //Kuudra
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra"))
+ .collapsed(false)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.supplyWaypoints"))
+ .binding(defaults.locations.crimsonIsle.kuudra.supplyWaypoints,
+ () -> config.locations.crimsonIsle.kuudra.supplyWaypoints,
+ newValue -> config.locations.crimsonIsle.kuudra.supplyWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.fuelWaypoints"))
+ .binding(defaults.locations.crimsonIsle.kuudra.fuelWaypoints,
+ () -> config.locations.crimsonIsle.kuudra.fuelWaypoints,
+ newValue -> config.locations.crimsonIsle.kuudra.fuelWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Waypoint.Type>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip")))
+ .binding(defaults.locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType,
+ () -> config.locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType,
+ newValue -> config.locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.ballistaBuildWaypoints"))
+ .binding(defaults.locations.crimsonIsle.kuudra.ballistaBuildWaypoints,
+ () -> config.locations.crimsonIsle.kuudra.ballistaBuildWaypoints,
+ newValue -> config.locations.crimsonIsle.kuudra.ballistaBuildWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.safeSpotWaypoints"))
+ .binding(defaults.locations.crimsonIsle.kuudra.safeSpotWaypoints,
+ () -> config.locations.crimsonIsle.kuudra.safeSpotWaypoints,
+ newValue -> config.locations.crimsonIsle.kuudra.safeSpotWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.pearlWaypoints"))
+ .binding(defaults.locations.crimsonIsle.kuudra.pearlWaypoints,
+ () -> config.locations.crimsonIsle.kuudra.pearlWaypoints,
+ newValue -> config.locations.crimsonIsle.kuudra.pearlWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.noArrowPoisonWarning"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.noArrowPoisonWarning.@Tooltip")))
+ .binding(defaults.locations.crimsonIsle.kuudra.noArrowPoisonWarning,
+ () -> config.locations.crimsonIsle.kuudra.noArrowPoisonWarning,
+ newValue -> config.locations.crimsonIsle.kuudra.noArrowPoisonWarning = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Integer>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.arrowPoisonThreshold"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.arrowPoisonThreshold.@Tooltip")))
+ .binding(defaults.locations.crimsonIsle.kuudra.arrowPoisonThreshold,
+ () -> config.locations.crimsonIsle.kuudra.arrowPoisonThreshold,
+ newValue -> config.locations.crimsonIsle.kuudra.arrowPoisonThreshold = newValue)
+ .controller(IntegerFieldControllerBuilder::create)
+ .build())
+ .build())
+ .build();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/PlayerInventoryMixin.java b/src/main/java/de/hysky/skyblocker/mixin/PlayerInventoryMixin.java
new file mode 100644
index 00000000..4795a28b
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/mixin/PlayerInventoryMixin.java
@@ -0,0 +1,21 @@
+package de.hysky.skyblocker.mixin;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import de.hysky.skyblocker.skyblock.crimson.kuudra.ArrowPoisonWarning;
+import net.minecraft.entity.player.PlayerInventory;
+
+@Mixin(PlayerInventory.class)
+public class PlayerInventoryMixin {
+ @Shadow
+ public int selectedSlot;
+
+ @Inject(method = "scrollInHotbar", at = @At("TAIL"))
+ private void skyblocker$onHotbarScroll(CallbackInfo ci) {
+ ArrowPoisonWarning.tryWarn(selectedSlot);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/ArrowPoisonWarning.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/ArrowPoisonWarning.java
new file mode 100644
index 00000000..7ddbeb99
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/ArrowPoisonWarning.java
@@ -0,0 +1,54 @@
+package de.hysky.skyblocker.skyblock.crimson.kuudra;
+
+import java.util.function.Supplier;
+
+import de.hysky.skyblocker.config.SkyblockerConfig;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra.KuudraPhase;
+import de.hysky.skyblocker.utils.ItemUtils;
+import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.render.title.Title;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.item.BowItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class ArrowPoisonWarning {
+ private static final Supplier<SkyblockerConfig.Kuudra> CONFIG = () -> SkyblockerConfigManager.get().locations.crimsonIsle.kuudra;
+ private static final int THREE_SECONDS = 20 * 3;
+ private static final Title NONE_TITLE = new Title(Text.translatable("skyblocker.crimson.kuudra.noArrowPoison").formatted(Formatting.GREEN));
+ private static final Title LOW_TITLE = new Title(Text.translatable("skyblocker.crimson.kuudra.lowArrowPoison").formatted(Formatting.GREEN));
+
+ public static void tryWarn(int newSlot) {
+ //Exclude skyblock menu
+ if (Utils.isInKuudra() && CONFIG.get().noArrowPoisonWarning && Kuudra.phase == KuudraPhase.DPS && newSlot != 8) {
+ MinecraftClient client = MinecraftClient.getInstance();
+ PlayerInventory inventory = client.player.getInventory();
+ ItemStack heldItem = inventory.getStack(newSlot);
+
+ if (heldItem.getItem() instanceof BowItem) {
+ boolean hasToxicArrowPoison = false;
+ int arrowPoisonAmount = 0;
+
+ for (int i = 0; i < inventory.size(); ++i) {
+ ItemStack stack = inventory.getStack(i);
+ String itemId = ItemUtils.getItemId(stack);
+
+ if (itemId.equals("TOXIC_ARROW_POISON")) {
+ hasToxicArrowPoison = true;
+ arrowPoisonAmount += stack.getCount();
+ }
+ }
+
+ if (!hasToxicArrowPoison) {
+ RenderHelper.displayInTitleContainerAndPlaySound(NONE_TITLE, THREE_SECONDS);
+ } else if (arrowPoisonAmount < CONFIG.get().arrowPoisonThreshold) {
+ RenderHelper.displayInTitleContainerAndPlaySound(LOW_TITLE, THREE_SECONDS);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java
new file mode 100644
index 00000000..033a919d
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java
@@ -0,0 +1,51 @@
+package de.hysky.skyblocker.skyblock.crimson.kuudra;
+
+import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+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.networking.v1.ClientPlayConnectionEvents;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class Kuudra {
+ public static final String LOCATION = "kuudra";
+ static KuudraPhase phase = KuudraPhase.OTHER;
+
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(KuudraWaypoints::render);
+ ClientLifecycleEvents.CLIENT_STARTED.register(KuudraWaypoints::load);
+ ClientPlayConnectionEvents.JOIN.register((_handler, _sender, _client) -> reset());
+ ClientReceiveMessageEvents.GAME.register(Kuudra::onMessage);
+ Scheduler.INSTANCE.scheduleCyclic(KuudraWaypoints::tick, 20);
+ }
+
+ private static void onMessage(Text text, boolean overlay) {
+ if (Utils.isInKuudra() && !overlay) {
+ String message = Formatting.strip(text.getString());
+
+ if (message.equals("[NPC] Elle: ARGH! All of the supplies fell into the lava! You need to retrieve them quickly!")) {
+ phase = KuudraPhase.RETRIEVE_SUPPLIES;
+ }
+
+ if (message.equals("[NPC] Elle: Phew! The Ballista is finally ready! It should be strong enough to tank Kuudra's blows now!")) {
+ phase = KuudraPhase.DPS;
+ }
+
+ if (message.equals("[NPC] Elle: POW! SURELY THAT'S IT! I don't think he has any more in him!")) {
+ phase = KuudraPhase.OTHER;
+ }
+ }
+ }
+
+ private static void reset() {
+ phase = KuudraPhase.OTHER;
+ }
+
+ enum KuudraPhase {
+ OTHER,
+ RETRIEVE_SUPPLIES,
+ DPS;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/KuudraWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/KuudraWaypoints.java
new file mode 100644
index 00000000..790d434a
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/KuudraWaypoints.java
@@ -0,0 +1,161 @@
+package de.hysky.skyblocker.skyblock.crimson.kuudra;
+
+import java.io.BufferedReader;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.slf4j.Logger;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.mojang.logging.LogUtils;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.JsonOps;
+
+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.waypoint.Waypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint.Type;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.entity.decoration.ArmorStandEntity;
+import net.minecraft.entity.mob.GiantEntity;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.math.MathHelper;
+
+public class KuudraWaypoints {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final float[] SUPPLIES_COLOR = { 255f / 255f, 0f, 0f };
+ private static final float[] PEARL_COLOR = { 57f / 255f, 117f / 255f, 125f / 255f };
+ private static final float[] SAFE_SPOT_COLOR = { 255f / 255f, 85f / 255f, 255f / 255f };
+ private static final Supplier<Type> SUPPLIES_AND_FUEL_TYPE = () -> SkyblockerConfigManager.get().locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType;
+ private static final ObjectArrayList<Waypoint> SAFE_SPOT_WAYPOINTS = new ObjectArrayList<>();
+ private static final ObjectArrayList<Waypoint> PEARL_WAYPOINTS = new ObjectArrayList<>();
+ private static final Function<float[], Codec<List<Waypoint>>> CODEC = cc -> PosUtils.ALT_BLOCK_POS_CODEC.xmap(
+ pos -> new Waypoint(pos, () -> Waypoint.Type.HIGHLIGHT, cc, false),
+ waypoint -> waypoint.pos)
+ .listOf();
+
+ //Use non final lists and swap them out to avoid ConcurrentModificationExceptions
+ private static ObjectArrayList<Waypoint> supplyWaypoints = ObjectArrayList.of();
+ private static ObjectArrayList<Waypoint> ballistaBuildWaypoints = ObjectArrayList.of();
+ private static ObjectArrayList<Waypoint> fuelWaypoints = ObjectArrayList.of();
+ private static boolean loaded;
+
+ static void load(MinecraftClient client) {
+ CompletableFuture<Void> safeSpots = loadWaypoints(client, new Identifier(SkyblockerMod.NAMESPACE, "crimson/kuudra/safe_spot_waypoints.json"), SAFE_SPOT_WAYPOINTS, SAFE_SPOT_COLOR);
+ CompletableFuture<Void> pearls = loadWaypoints(client, new Identifier(SkyblockerMod.NAMESPACE, "crimson/kuudra/pearl_waypoints.json"), PEARL_WAYPOINTS, PEARL_COLOR);
+
+ CompletableFuture.allOf(safeSpots, pearls).whenComplete((_result, _throwable) -> loaded = true);
+ }
+
+ private static CompletableFuture<Void> loadWaypoints(MinecraftClient client, Identifier file, ObjectArrayList<Waypoint> list, float[] colorComponents) {
+ return CompletableFuture.supplyAsync(() -> {
+ try (BufferedReader reader = client.getResourceManager().openAsReader(file)) {
+ return CODEC.apply(colorComponents).parse(JsonOps.INSTANCE, getWaypoints(reader)).result().orElseThrow();
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Kuudra Waypoints] Failed to load kuudra waypoints from: {}", file, e);
+
+ return List.<Waypoint>of();
+ }
+ }).thenAccept(list::addAll);
+ }
+
+ private static JsonElement getWaypoints(BufferedReader reader) {
+ return JsonParser.parseReader(reader).getAsJsonObject().getAsJsonArray("waypoints");
+ }
+
+ static void tick() {
+ MinecraftClient client = MinecraftClient.getInstance();
+ SkyblockerConfig.Kuudra config = SkyblockerConfigManager.get().locations.crimsonIsle.kuudra;
+
+ if (Utils.isInKuudra() && (config.supplyWaypoints || config.fuelWaypoints || config.ballistaBuildWaypoints)) {
+ Box searchBox = client.player.getBoundingBox().expand(500d);
+ ObjectArrayList<Waypoint> supplies = new ObjectArrayList<>();
+ ObjectArrayList<Waypoint> fuelCells = new ObjectArrayList<>();
+
+ if (config.supplyWaypoints || config.fuelWaypoints) {
+ List<GiantEntity> giants = client.world.getEntitiesByClass(GiantEntity.class, searchBox, giant -> giant.getY() < 67);
+
+ for (GiantEntity giant : giants) {
+ double yawOffset = giant.getYaw() + 115;
+
+ double x = giant.getX() + 4.5 * Math.cos((yawOffset) * MathHelper.RADIANS_PER_DEGREE);
+ double y = 75;
+ double z = giant.getZ() + 4.5 * Math.sin((yawOffset) * MathHelper.RADIANS_PER_DEGREE);
+
+ Waypoint waypoint = new Waypoint(BlockPos.ofFloored(x, y, z), SUPPLIES_AND_FUEL_TYPE, SUPPLIES_COLOR, false);
+
+ switch (Kuudra.phase) {
+ case RETRIEVE_SUPPLIES -> supplies.add(waypoint);
+ case DPS -> fuelCells.add(waypoint);
+ default -> supplies.add(waypoint);
+ }
+ }
+ }
+
+ ObjectArrayList<Waypoint> ballistaBuildSpots = new ObjectArrayList<>();
+
+ if (config.ballistaBuildWaypoints) {
+ List<ArmorStandEntity> armorStands = client.world.getEntitiesByClass(ArmorStandEntity.class, searchBox, ArmorStandEntity::hasCustomName);
+
+ for (ArmorStandEntity armorStand : armorStands) {
+ String name = armorStand.getName().getString();
+
+ if (config.ballistaBuildWaypoints && name.contains("SNEAK + PUNCH")) {
+ ballistaBuildSpots.add(new Waypoint(armorStand.getBlockPos(), () -> Waypoint.Type.WAYPOINT, SUPPLIES_COLOR, false));
+ }
+ }
+ }
+
+ supplyWaypoints = supplies;
+ ballistaBuildWaypoints = ballistaBuildSpots;
+ fuelWaypoints = fuelCells;
+ }
+ }
+
+ static void render(WorldRenderContext context) {
+ SkyblockerConfig.Kuudra config = SkyblockerConfigManager.get().locations.crimsonIsle.kuudra;
+
+ if (Utils.isInKuudra() && loaded) {
+ if (config.supplyWaypoints) {
+ for (Waypoint waypoint : supplyWaypoints) {
+ waypoint.render(context);
+ }
+ }
+
+ if (config.ballistaBuildWaypoints) {
+ for (Waypoint waypoint : ballistaBuildWaypoints) {
+ waypoint.render(context);
+ }
+ }
+
+ if (config.fuelWaypoints) {
+ for (Waypoint waypoint : fuelWaypoints) {
+ waypoint.render(context);
+ }
+ }
+
+ if (config.safeSpotWaypoints) {
+ for (Waypoint waypoint : SAFE_SPOT_WAYPOINTS) {
+ waypoint.render(context);
+ }
+ }
+
+ //TODO maybe have "dynamic" waypoints that draw a line to the actual spot
+ if (config.pearlWaypoints) {
+ for (Waypoint waypoint : PEARL_WAYPOINTS) {
+ waypoint.render(context);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/PosUtils.java b/src/main/java/de/hysky/skyblocker/utils/PosUtils.java
index 6a34b060..73ada889 100644
--- a/src/main/java/de/hysky/skyblocker/utils/PosUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/PosUtils.java
@@ -1,8 +1,17 @@
package de.hysky.skyblocker.utils;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.codecs.RecordCodecBuilder;
+
import net.minecraft.util.math.BlockPos;
public final class PosUtils {
+ public static final Codec<BlockPos> ALT_BLOCK_POS_CODEC = RecordCodecBuilder.create(instance -> instance.group(
+ Codec.INT.fieldOf("x").forGetter(BlockPos::getX),
+ Codec.INT.fieldOf("y").forGetter(BlockPos::getY),
+ Codec.INT.fieldOf("z").forGetter(BlockPos::getZ))
+ .apply(instance, BlockPos::new));
+
public static BlockPos parsePosString(String posData) {
String[] posArray = posData.split(",");
return new BlockPos(Integer.parseInt(posArray[0]), Integer.parseInt(posArray[1]), Integer.parseInt(posArray[2]));
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index 0c95985e..cd739a0c 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -3,6 +3,7 @@ package de.hysky.skyblocker.utils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.hysky.skyblocker.events.SkyblockEvents;
+import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra;
import de.hysky.skyblocker.skyblock.item.MuseumItemCache;
import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip;
import de.hysky.skyblocker.skyblock.rift.TheRift;
@@ -110,6 +111,10 @@ public class Utils {
return getLocationRaw().equals("combat_3");
}
+ public static boolean isInKuudra() {
+ return getLocationRaw().equals(Kuudra.LOCATION);
+ }
+
public static boolean isInjected() {
return isInjected;
}
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 2f9c9f63..7f3d4eda 100644
--- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
@@ -1,13 +1,14 @@
package de.hysky.skyblocker.utils.waypoint;
import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.render.Renderable;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import java.util.function.Supplier;
-public class Waypoint {
+public class Waypoint implements Renderable {
protected static final float DEFAULT_HIGHLIGHT_ALPHA = 0.5f;
protected static final float DEFAULT_LINE_WIDTH = 5f;
public final BlockPos pos;
@@ -74,6 +75,7 @@ public class Waypoint {
return colorComponents;
}
+ @Override
public void render(WorldRenderContext context) {
switch (typeSupplier.get()) {
case WAYPOINT -> RenderHelper.renderFilledWithBeaconBeam(context, pos, getColorComponents(), alpha, throughWalls);
diff --git a/src/main/resources/assets/skyblocker/crimson/kuudra/pearl_waypoints.json b/src/main/resources/assets/skyblocker/crimson/kuudra/pearl_waypoints.json
new file mode 100644
index 00000000..6bba7576
--- /dev/null
+++ b/src/main/resources/assets/skyblocker/crimson/kuudra/pearl_waypoints.json
@@ -0,0 +1,96 @@
+{
+ "waypoints": [
+ {
+ "x": -43,
+ "y": 120,
+ "z": -149
+ },
+ {
+ "x": -97,
+ "y": 157,
+ "z": -112
+ },
+ {
+ "x": -70,
+ "y": 79,
+ "z": -134
+ },
+ {
+ "x": -110,
+ "y": 155,
+ "z": -106
+ },
+ {
+ "x": -105,
+ "y": 157,
+ "z": -100
+ },
+ {
+ "x": -106,
+ "y": 165,
+ "z": -101
+ },
+ {
+ "x": -134,
+ "y": 77,
+ "z": -138
+ },
+ {
+ "x": -113,
+ "y": 77,
+ "z": -68
+ },
+ {
+ "x": -67,
+ "y": 77,
+ "z": -122
+ }
+ ,
+ {
+ "x": -85,
+ "y": 78,
+ "z": -128
+ },
+ {
+ "x": -95,
+ "y": 161,
+ "z": -105
+ }
+ ,
+ {
+ "x": -26,
+ "y": 126,
+ "z": -111
+ },
+ {
+ "x": -103,
+ "y": 160,
+ "z": -109
+ },
+ {
+ "x": -65,
+ "y": 76,
+ "z": -87
+ },
+ {
+ "x": -140,
+ "y": 78,
+ "z": -90
+ },
+ {
+ "x": -130,
+ "y": 79,
+ "z": -113
+ },
+ {
+ "x": -45,
+ "y": 135,
+ "z": -138
+ },
+ {
+ "x": -35,
+ "y": 138,
+ "z": -124
+ }
+ ]
+} \ No newline at end of file
diff --git a/src/main/resources/assets/skyblocker/crimson/kuudra/safe_spot_waypoints.json b/src/main/resources/assets/skyblocker/crimson/kuudra/safe_spot_waypoints.json
new file mode 100644
index 00000000..ce693886
--- /dev/null
+++ b/src/main/resources/assets/skyblocker/crimson/kuudra/safe_spot_waypoints.json
@@ -0,0 +1,19 @@
+{
+ "waypoints": [
+ {
+ "x": -141,
+ "y": 77,
+ "z": -91
+ },
+ {
+ "x": -141,
+ "y": 76,
+ "z": -90
+ },
+ {
+ "x": -90,
+ "y": 77,
+ "z": -128
+ }
+ ]
+} \ No newline at end of file
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index f17f109e..91d3ad37 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -164,6 +164,18 @@
"text.autoconfig.skyblocker.option.locations.barn": "Barn",
"text.autoconfig.skyblocker.option.locations.barn.solveHungryHiker": "Solve Hungry Hiker",
"text.autoconfig.skyblocker.option.locations.barn.solveTreasureHunter": "Solve Treasure Hunter",
+ "text.autoconfig.skyblocker.category.crimsonIsle": "Crimson Isle",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra": "Kuudra",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.supplyWaypoints": "Supply Waypoints",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.fuelWaypoints": "Fuel Waypoints",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.suppliesAndFuelWaypointType": "Supplies/Fuel Waypoint Type",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.ballistaBuildWaypoints": "Ballista Build Spot Waypoints",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.safeSpotWaypoints": "Safe Spot Waypoints",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.pearlWaypoints": "Pearl Waypoints",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.noArrowPoisonWarning": "No Arrow Poison Warning",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.noArrowPoisonWarning.@Tooltip": "Warns you when you pull out a bow and have no Toxic Arrow Poison in your inventory. Only works during the DPS phase.",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.arrowPoisonThreshold": "Arrow Poison Warning Threshold",
+ "text.autoconfig.skyblocker.option.locations.crimsonIsle.kuudra.arrowPoisonThreshold.@Tooltip": "If the amount of Toxic Arrow Poison you have in your inventory is below the set threshold then you will receive a warning.",
"text.autoconfig.skyblocker.option.locations.spidersDen": "Spider's Den",
"text.autoconfig.skyblocker.option.locations.spidersDen.relics": "Hidden Relics Helper",
"text.autoconfig.skyblocker.option.locations.spidersDen.relics.enableRelicsHelper": "Enable Hidden Relics Helper",
@@ -249,7 +261,7 @@
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Enable Livid Color Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Send the livid color in the chat during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorTitle": "Enable Livid Color Title",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorTitle.@Tooltip": "Display the livid color in the title during the Livid boss fight.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorTitle.@Tooltip": "Display the livid color in the title during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Livid Color Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Text which will be sent in the chat during the Livid boss fight. The string \"[color]\" will be replaced with the livid color.",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Terminal Solvers",
@@ -471,6 +483,9 @@
"skyblocker.partyFinder.yourParty": "Your party",
"skyblocker.partyFinder.deList": "Click to de-list",
"skyblocker.partyFinder.join": "Click to join",
+
+ "skyblocker.crimson.kuudra.noArrowPoison": "No Arrow Poison!",
+ "skyblocker.crimson.kuudra.lowArrowPoison": "Low on Arrow Poison!",
"emi.category.skyblocker.skyblock": "Skyblock"
}
diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json
index 29f7fb11..fd7364ce 100644
--- a/src/main/resources/skyblocker.mixins.json
+++ b/src/main/resources/skyblocker.mixins.json
@@ -25,6 +25,7 @@
"LeverBlockMixin",
"LivingEntityRendererMixin",
"MinecraftClientMixin",
+ "PlayerInventoryMixin",
"PlayerListHudMixin",
"PlayerSkinProviderMixin",
"PlayerSkinTextureMixin",