diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2024-02-14 14:55:13 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-14 14:55:13 -0500 |
commit | 1486efaca25f1c2ca55e6428cb87c378969fd5d7 (patch) | |
tree | 4d8a3c3ea244cb8e0bb1181aac089cb7b1c654d6 /src/main/java/de/hysky/skyblocker/skyblock | |
parent | 5e52750ee03f3a972eaabfcfbe2d6271ba50c13b (diff) | |
parent | 16e94a9643cf3f75f8a0804d3c0ea85cbb6534f4 (diff) | |
download | Skyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.tar.gz Skyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.tar.bz2 Skyblocker-1486efaca25f1c2ca55e6428cb87c378969fd5d7.zip |
Merge pull request #519 from AzureAaron/kuudra
Kuudra Features
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock')
3 files changed, 266 insertions, 0 deletions
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); + } + } + } + } +} |