aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de')
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java17
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/galatea/ForestNodes.java168
4 files changed, 194 insertions, 1 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java
index d5c844b7..81e64ea4 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java
@@ -1,7 +1,10 @@
package de.hysky.skyblocker.config.categories;
+import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
import dev.isxander.yacl3.api.ConfigCategory;
+import dev.isxander.yacl3.api.Option;
+import dev.isxander.yacl3.api.OptionGroup;
import net.minecraft.text.Text;
public class ForagingCategory {
@@ -9,9 +12,21 @@ public class ForagingCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("skyblocker.config.foraging"))
-
//Modern Foraging island
+ //Galatea
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("skyblocker.config.foraging.galatea"))
+ .collapsed(false)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.foraging.galatea.enableForestNodeHelper"))
+ .binding(defaults.foraging.galatea.enableForestNodeHelper,
+ () -> config.foraging.galatea.enableForestNodeHelper,
+ newValue -> config.foraging.galatea.enableForestNodeHelper = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .build())
+
//Hunting - YACL doesn't like empty option groups
/*.group(OptionGroup.createBuilder()
.name(Text.translatable("skyblocker.config.foraging.hunting"))
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java
index 1a7c3598..aa4dcc6d 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java
@@ -5,8 +5,16 @@ import dev.isxander.yacl3.config.v2.api.SerialEntry;
public class ForagingConfig {
@SerialEntry
+ public Galatea galatea = new Galatea();
+
+ @SerialEntry
public Hunting hunting = new Hunting();
+ public static class Galatea {
+ @SerialEntry
+ public boolean enableForestNodeHelper = true;
+ }
+
public static class Hunting {
}
diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java
index 6372bd4d..22e921ff 100644
--- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java
@@ -24,6 +24,7 @@ import de.hysky.skyblocker.skyblock.end.TheEnd;
import de.hysky.skyblocker.skyblock.fishing.FishingHelper;
import de.hysky.skyblocker.skyblock.fishing.FishingHookDisplayHelper;
import de.hysky.skyblocker.skyblock.fishing.SeaCreatureTracker;
+import de.hysky.skyblocker.skyblock.galatea.ForestNodes;
import de.hysky.skyblocker.skyblock.slayers.SlayerManager;
import de.hysky.skyblocker.skyblock.slayers.boss.demonlord.FirePillarAnnouncer;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListManager;
@@ -186,6 +187,7 @@ public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkH
DojoManager.onParticle(packet);
CrystalsChestHighlighter.onParticle(packet);
EnderNodes.onParticle(packet);
+ ForestNodes.onParticle(packet);
WishingCompassSolver.onParticle(packet);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/galatea/ForestNodes.java b/src/main/java/de/hysky/skyblocker/skyblock/galatea/ForestNodes.java
new file mode 100644
index 00000000..01819f47
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/galatea/ForestNodes.java
@@ -0,0 +1,168 @@
+package de.hysky.skyblocker.skyblock.galatea;
+
+import de.hysky.skyblocker.annotations.Init;
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.utils.ColorUtils;
+import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
+import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
+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.minecraft.client.MinecraftClient;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.decoration.DisplayEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
+import net.minecraft.particle.ParticleType;
+import net.minecraft.particle.ParticleTypes;
+import net.minecraft.util.ActionResult;
+import net.minecraft.util.DyeColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class ForestNodes {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ForestNodes.class);
+ private static final MinecraftClient client = MinecraftClient.getInstance();
+ private static final Map<BlockPos, ForestNode> forestNodes = new HashMap<>();
+
+ @Init
+ public static void init() {
+ Scheduler.INSTANCE.scheduleCyclic(ForestNodes::update, 20);
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(ForestNodes::render);
+ AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
+ if (!shouldProcess()) {
+ return ActionResult.PASS;
+ }
+ forestNodes.remove(pos);
+ return ActionResult.PASS;
+ });
+ UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
+ if (!shouldProcess()) {
+ return ActionResult.PASS;
+ }
+ BlockPos pos = hitResult.getBlockPos();
+ forestNodes.remove(pos);
+ return ActionResult.PASS;
+ });
+ ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> reset());
+ }
+
+ public static void onParticle(ParticleS2CPacket packet) {
+ if (!shouldProcess()) {
+ return;
+ }
+
+ ParticleType<?> particleType = packet.getParameters().getType();
+ if (!ParticleTypes.HAPPY_VILLAGER.getType().equals(particleType)) {
+ return;
+ }
+
+ double x = packet.getX();
+ double y = packet.getY() - 1;
+ double z = packet.getZ();
+ BlockPos pos = BlockPos.ofFloored(x, y, z);
+
+ // Check for three ItemDisplayEntity with minecraft:string in the same block
+ if (client.world != null) {
+ int stringItemCount = countStringItemDisplays(pos);
+ if (stringItemCount == 3) {
+ forestNodes.computeIfAbsent(pos, ForestNode::new);
+ }
+ }
+ }
+
+ private static int countStringItemDisplays(BlockPos pos) {
+ ClientWorld world = client.world;
+ if (world == null) {
+ return 0;
+ }
+
+ // Get all ItemDisplayEntity within the same block
+ List<DisplayEntity.ItemDisplayEntity> entities = world.getEntitiesByClass(
+ DisplayEntity.ItemDisplayEntity.class,
+ Box.of(pos.toCenterPos(), 1.0, 1.0, 1.0),
+ entity -> true
+ );
+
+ // Count those with minecraft:string
+ return (int) entities.stream()
+ .filter(entity -> {
+ ItemStack stack = entity.getItemStack();
+ return !stack.isEmpty() && stack.getItem().equals(Items.STRING);
+ })
+ .count();
+ }
+
+ private static void update() {
+ if (!shouldProcess()) {
+ return;
+ }
+ Iterator<Map.Entry<BlockPos, ForestNode>> iterator = forestNodes.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<BlockPos, ForestNode> entry = iterator.next();
+ ForestNode forestNode = entry.getValue();
+ forestNode.updateWaypoint();
+ if (!forestNode.shouldRender()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ private static void render(WorldRenderContext context) {
+ if (!shouldProcess()) {
+ return;
+ }
+ for (ForestNode forestNode : forestNodes.values()) {
+ if (forestNode.shouldRender()) {
+ forestNode.render(context);
+ }
+ }
+ }
+
+ private static boolean shouldProcess() {
+ return SkyblockerConfigManager.get().foraging.galatea.enableForestNodeHelper && Utils.isInGalatea();
+ }
+
+ private static void reset() {
+ forestNodes.clear();
+ }
+
+ public static class ForestNode extends Waypoint {
+ private long lastConfirmed;
+
+ private ForestNode(BlockPos pos) {
+ super(pos,
+ () -> Type.HIGHLIGHT,
+ ColorUtils.getFloatComponents(DyeColor.ORANGE),
+ DEFAULT_HIGHLIGHT_ALPHA,
+ DEFAULT_LINE_WIDTH,
+ false
+ );
+ this.lastConfirmed = System.currentTimeMillis();
+ }
+
+ private void updateWaypoint() {
+ long currentTimeMillis = System.currentTimeMillis();
+ if (lastConfirmed + 2000 > currentTimeMillis || client.world == null) {
+ return;
+ }
+ int stringItemCount = countStringItemDisplays(pos);
+ if (stringItemCount == 3) {
+ lastConfirmed = System.currentTimeMillis();
+ }
+ }
+
+ @Override
+ public boolean shouldRender() {
+ return super.shouldRender() && lastConfirmed + 5000 > System.currentTimeMillis();
+ }
+ }
+}