diff options
| author | Rime <81419447+Emirlol@users.noreply.github.com> | 2025-06-26 00:22:48 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-25 17:22:48 -0400 |
| commit | a13cdbb747ec30b137462fdaf6145b6b0c0fff5c (patch) | |
| tree | 5cbeb2a7df905a6b2ffc54c5e4a57ed216bf52b5 /src/main/java/de | |
| parent | 9c270c45bc87ad58d885f42551713960617c61b8 (diff) | |
| download | Skyblocker-a13cdbb747ec30b137462fdaf6145b6b0c0fff5c.tar.gz Skyblocker-a13cdbb747ec30b137462fdaf6145b6b0c0fff5c.tar.bz2 Skyblocker-a13cdbb747ec30b137462fdaf6145b6b0c0fff5c.zip | |
Add a minimum pickle count to sea lumies (#1395)
* Add a minimum pickle count to sea lumies
* Properly remove blocks on chunk unload
* Change allBlocks to a set
Diffstat (limited to 'src/main/java/de')
4 files changed, 135 insertions, 26 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 f17ab278..d3b44501 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/ForagingCategory.java @@ -2,10 +2,9 @@ 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.OptionDescription; -import dev.isxander.yacl3.api.OptionGroup; +import de.hysky.skyblocker.skyblock.galatea.SeaLumiesHighlighter; +import dev.isxander.yacl3.api.*; +import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder; import net.minecraft.text.Text; public class ForagingCategory { @@ -46,9 +45,23 @@ public class ForagingCategory { .description(OptionDescription.of(Text.translatable("skyblocker.config.foraging.galatea.enableSeaLumiesHighlighter.@Tooltip"))) .binding(defaults.foraging.galatea.enableSeaLumiesHighlighter, () -> config.foraging.galatea.enableSeaLumiesHighlighter, - newValue -> config.foraging.galatea.enableSeaLumiesHighlighter = newValue) + newValue -> { + config.foraging.galatea.enableSeaLumiesHighlighter = newValue; + SeaLumiesHighlighter.INSTANCE.configCallback(); + }) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.<Integer>createBuilder() + .name(Text.translatable("skyblocker.config.foraging.galatea.seaLumieMinCount")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.foraging.galatea.seaLumieMinCount.@Tooltip"))) + .binding(defaults.foraging.galatea.seaLumiesMinimumCount, + () -> config.foraging.galatea.seaLumiesMinimumCount, + newValue -> { + config.foraging.galatea.seaLumiesMinimumCount = newValue; + SeaLumiesHighlighter.INSTANCE.configCallback(); + }) + .controller(opt -> IntegerSliderControllerBuilder.create(opt).range(1, 4).step(1)) + .build()) .build()) .build(); } 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 b63cf4d1..09725750 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/ForagingConfig.java @@ -19,5 +19,8 @@ public class ForagingConfig { @SerialEntry public boolean enableSeaLumiesHighlighter = true; + + @SerialEntry + public int seaLumiesMinimumCount = 3; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/galatea/AbstractBlockHighlighter.java b/src/main/java/de/hysky/skyblocker/skyblock/galatea/AbstractBlockHighlighter.java index 8b03d1e6..90e9fef1 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/galatea/AbstractBlockHighlighter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/galatea/AbstractBlockHighlighter.java @@ -1,11 +1,8 @@ package de.hysky.skyblocker.skyblock.galatea; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - import de.hysky.skyblocker.utils.ColorUtils; import de.hysky.skyblocker.utils.render.RenderHelper; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientChunkEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; @@ -18,17 +15,35 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.WorldChunk; +import java.util.Iterator; +import java.util.Set; +import java.util.function.Predicate; + /** * Abstract class for a simple feature that highlights a certain type of block. */ //TODO Move this to a more generic package since this is not Galatea specific (maybe make a world rendering utility package?) public abstract class AbstractBlockHighlighter { - private final List<BlockPos> highlightedBlocks = new ArrayList<>(); - private final Block target; - private final float[] colour; + protected final Set<BlockPos> highlightedBlocks = new ObjectOpenHashSet<>(); + protected final float[] colour; + protected final Predicate<BlockState> statePredicate; + /** + * Convenience constructor for highlighting a specific block type. + * + * @param target Block to highlight. + * @param colour Color to use for highlighting. + */ protected AbstractBlockHighlighter(Block target, DyeColor colour) { - this.target = target; + this(state -> state.isOf(target), colour); + } + + /** + * @param statePredicate Predicate that the blockstate must match to be highlighted. + * @param colour Color to use for highlighting. + */ + protected AbstractBlockHighlighter(Predicate<BlockState> statePredicate, DyeColor colour) { + this.statePredicate = statePredicate; this.colour = ColorUtils.getFloatComponents(colour); } @@ -42,7 +57,7 @@ public abstract class AbstractBlockHighlighter { public void onBlockUpdate(BlockPos pos, BlockState state) { if (!shouldProcess()) return; - if (state.getBlock().equals(this.target)) { + if (this.statePredicate.test(state)) { this.highlightedBlocks.add(pos.toImmutable()); } else { this.highlightedBlocks.remove(pos); @@ -53,18 +68,16 @@ public abstract class AbstractBlockHighlighter { * Add initial highlights since {@link #onBlockUpdate(BlockPos, BlockState)} doesn't fire when the * server sends chunk data via the {@code ChunkDataS2CPacket}. */ - private void onChunkLoad(ClientWorld world, WorldChunk chunk) { + protected void onChunkLoad(ClientWorld world, WorldChunk chunk) { if (!shouldProcess()) return; - chunk.forEachBlockMatchingPredicate(state -> state.getBlock().equals(this.target), (pos, state) -> { - this.highlightedBlocks.add(pos.toImmutable()); - }); + chunk.forEachBlockMatchingPredicate(statePredicate, (pos, state) -> this.highlightedBlocks.add(pos.toImmutable())); } /** * Remove highlights in unloaded chunks. */ - private void onChunkUnload(ClientWorld world, WorldChunk chunk) { + protected void onChunkUnload(ClientWorld world, WorldChunk chunk) { if (!shouldProcess()) return; Iterator<BlockPos> iterator = this.highlightedBlocks.iterator(); @@ -82,13 +95,17 @@ public abstract class AbstractBlockHighlighter { if (!shouldProcess()) return; for (BlockPos highlight : this.highlightedBlocks) { - RenderHelper.renderFilled(context, highlight, this.colour, 0.5f, false); + RenderHelper.renderFilled(context, highlight, this.colour, 0.4f, false); } } - private void reset() { + public void reset() { this.highlightedBlocks.clear(); } + /** + * @return Whether this highlighter should try to process blocks. + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") protected abstract boolean shouldProcess(); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/galatea/SeaLumiesHighlighter.java b/src/main/java/de/hysky/skyblocker/skyblock/galatea/SeaLumiesHighlighter.java index c71ef87f..8005beb8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/galatea/SeaLumiesHighlighter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/galatea/SeaLumiesHighlighter.java @@ -3,15 +3,40 @@ package de.hysky.skyblocker.skyblock.galatea; import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Utils; -import net.minecraft.block.Block; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.block.SeaPickleBlock; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.world.ClientWorld; import net.minecraft.util.DyeColor; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.WorldChunk; + +import java.util.Iterator; +import java.util.Set; public class SeaLumiesHighlighter extends AbstractBlockHighlighter { - public static final SeaLumiesHighlighter INSTANCE = new SeaLumiesHighlighter(Blocks.SEA_PICKLE, DyeColor.CYAN); + private final Set<BlockPos> allBlocks = new ObjectOpenHashSet<>(); + + @Override + public void onBlockUpdate(BlockPos pos, BlockState state) { + if (!shouldProcess()) return; + + if (this.statePredicate.test(state)) { + this.allBlocks.add(pos.toImmutable()); + if (isEnoughPickles(state)) this.highlightedBlocks.add(pos.toImmutable()); + } else { + this.allBlocks.remove(pos); + this.highlightedBlocks.remove(pos); + } + } + + public static final SeaLumiesHighlighter INSTANCE = new SeaLumiesHighlighter(); - private SeaLumiesHighlighter(Block target, DyeColor colour) { - super(target, colour); + private SeaLumiesHighlighter() { + super(Blocks.SEA_PICKLE, DyeColor.CYAN); } @Init @@ -20,7 +45,58 @@ public class SeaLumiesHighlighter extends AbstractBlockHighlighter { } @Override + protected void onChunkUnload(ClientWorld world, WorldChunk chunk) { + if (!shouldProcess()) return; + Iterator<BlockPos> iterator = this.allBlocks.iterator(); + while (iterator.hasNext()) { + BlockPos pos = iterator.next(); + Chunk holder = world.getChunk(pos); + + if (holder.equals(chunk)) { + iterator.remove(); + highlightedBlocks.remove(pos); + } + } + } + + @Override + protected void onChunkLoad(ClientWorld world, WorldChunk chunk) { + if (!shouldProcess()) return; + + chunk.forEachBlockMatchingPredicate(statePredicate, (pos, state) -> { + this.allBlocks.add(pos.toImmutable()); + if (isEnoughPickles(state)) this.highlightedBlocks.add(pos.toImmutable()); + }); + } + + @Override protected boolean shouldProcess() { - return Utils.isInGalatea() && SkyblockerConfigManager.get().foraging.galatea.enableSeaLumiesHighlighter; + return Utils.isInGalatea(); // Process all blocks, just don't highlight them if the config is disabled. This way, changing the config has an immediate effect rather than waiting for a chunk reload. + } + + @Override + public void reset() { + this.allBlocks.clear(); + this.highlightedBlocks.clear(); + } + + // Called when either the min count or the enabled state changes. + public void configCallback() { + this.highlightedBlocks.clear(); + ClientWorld world = MinecraftClient.getInstance().world; + if (!shouldProcess() || world == null || !SkyblockerConfigManager.get().foraging.galatea.enableSeaLumiesHighlighter) { + return; + } + + for (BlockPos pos : this.allBlocks) { + BlockState state = world.getBlockState(pos); + if (this.statePredicate.test(state) && isEnoughPickles(state)) { + this.highlightedBlocks.add(pos); + } + } + } + + private boolean isEnoughPickles(BlockState state) { + return state.get(SeaPickleBlock.PICKLES) >= SkyblockerConfigManager.get().foraging.galatea.seaLumiesMinimumCount; } } |
