From 73cd8593df7270afd0d2b39dfe13d816f0da29a5 Mon Sep 17 00:00:00 2001 From: Micle Date: Mon, 26 May 2025 21:36:14 +0100 Subject: [PATCH 1/6] Created mixin for geologist pick usage method. --- .../mixin/IGMineralTestingItemMixin.java | 22 +++++++++++++++++++ .../geologist_pick_tweaks.mixins.json | 1 + 2 files changed, 23 insertions(+) create mode 100644 src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java diff --git a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java new file mode 100644 index 0000000..54ea54d --- /dev/null +++ b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java @@ -0,0 +1,22 @@ +package dev.micle.geologistpicktweaks.mixin; + +import com.igteam.immersivegeology.common.item.IGMineralTestingItem; +import dev.micle.geologistpicktweaks.GeologistPickTweaks; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.context.UseOnContext; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(IGMineralTestingItem.class) +public abstract class IGMineralTestingItemMixin { + /** + * @author Micle + * @reason Improving geologist pick usage logic. + */ + @Overwrite + public InteractionResult useOn(UseOnContext context) { + GeologistPickTweaks.LOGGER.debug("HELLO WORLD"); + + return InteractionResult.SUCCESS; + } +} diff --git a/src/main/resources/geologist_pick_tweaks.mixins.json b/src/main/resources/geologist_pick_tweaks.mixins.json index 12208a1..28d68ad 100644 --- a/src/main/resources/geologist_pick_tweaks.mixins.json +++ b/src/main/resources/geologist_pick_tweaks.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_8", "refmap": "geologist_pick_tweaks.refmap.json", "mixins": [ + "IGMineralTestingItemMixin" ], "client": [ ], From a8a00c6e74c0aa23e01718467d5d46c8c9b2788f Mon Sep 17 00:00:00 2001 From: Micle Date: Tue, 27 May 2025 00:53:18 +0100 Subject: [PATCH 2/6] Implemented original geologist pick logic into the mixin as a starting point. Overwriting the useOn method while creating a unique getMessage alternative method. Also made a separate MineralCacheEntry class as originally it is marked private. --- .../mixin/IGMineralTestingItemMixin.java | 131 +++++++++++++++++- .../util/MineralCacheEntry.java | 15 ++ 2 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/main/java/dev/micle/geologistpicktweaks/util/MineralCacheEntry.java diff --git a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java index 54ea54d..69335db 100644 --- a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java +++ b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java @@ -1,22 +1,145 @@ package dev.micle.geologistpicktweaks.mixin; +import com.igteam.immersivegeology.common.block.helper.IOreBlock; +import com.igteam.immersivegeology.common.item.IGGenericItem; import com.igteam.immersivegeology.common.item.IGMineralTestingItem; -import dev.micle.geologistpicktweaks.GeologistPickTweaks; +import com.igteam.immersivegeology.common.item.helper.IGFlagItem; +import com.igteam.immersivegeology.core.material.helper.flags.BlockCategoryFlags; +import com.igteam.immersivegeology.core.material.helper.flags.ItemCategoryFlags; +import com.igteam.immersivegeology.core.material.helper.material.MaterialInterface; +import dev.micle.geologistpicktweaks.util.MineralCacheEntry; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.tags.TagKey; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunkSection; +import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Unique; + +import java.util.*; @Mixin(IGMineralTestingItem.class) -public abstract class IGMineralTestingItemMixin { +public abstract class IGMineralTestingItemMixin extends IGGenericItem implements IGFlagItem { + @Unique + public final HashMap geologist_pick_tweaks_1_20_1$mineralCache = new HashMap<>(); + + public IGMineralTestingItemMixin(ItemCategoryFlags flag, MaterialInterface material) { + super(flag, material); + } + /** * @author Micle - * @reason Improving geologist pick usage logic. + * @reason Tweaking geologist pick usage logic. */ @Overwrite public InteractionResult useOn(UseOnContext context) { - GeologistPickTweaks.LOGGER.debug("HELLO WORLD"); + Player player = context.getPlayer(); + ItemStack stack = context.getItemInHand(); + if (player == null || !stack.getItem().equals(this)) { + return InteractionResult.FAIL; + } + + Level level = context.getLevel(); + BlockPos usedPos = context.getClickedPos(); + ChunkPos centerChunkPos = new ChunkPos(usedPos); + + stack.hurtAndBreak(1, player, (p) -> {}); + + MineralCacheEntry cachedEntry = geologist_pick_tweaks_1_20_1$mineralCache.get(centerChunkPos); + if (cachedEntry != null) { + long currentTimestamp = System.currentTimeMillis(); + if ((currentTimestamp - cachedEntry.timestamp) > MineralCacheEntry.CACHE_EXPIRY) { + geologist_pick_tweaks_1_20_1$mineralCache.clear(); + } else { + player.displayClientMessage(Component.literal(cachedEntry.message), true); + return InteractionResult.SUCCESS; + } + } + + int centerChunkX = centerChunkPos.x; + int centerChunkZ = centerChunkPos.z; + int minBuildHeight = level.getMinBuildHeight(); + int maxBuildHeight = level.getMaxBuildHeight(); + int sectionMin = level.getSectionIndex(minBuildHeight); + int sectionMax = level.getSectionIndex(maxBuildHeight); + + Set> oreSet = new HashSet<>(); + TagKey allOresTag = BlockCategoryFlags.ORE_BLOCK.getCategoryTag(); + chunkScan: for (int dx = -1; dx <= 1; dx++) { + for (int dz = -1; dz <= 1; dz++) { + ChunkAccess chunk = level.getChunk(centerChunkX + dx, centerChunkZ + dz); + + for (int sectionIndex = sectionMin; sectionIndex < sectionMax; sectionIndex++) { + LevelChunkSection section = chunk.getSection(sectionIndex); + + if (section.hasOnlyAir()) { + continue; + } + + if (!section.maybeHas(b -> b.is(allOresTag))) { + continue; + } + + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + BlockState blockState = section.getBlockState(x, y, z); + if (blockState.is(allOresTag)) { + IOreBlock ore = (IOreBlock) blockState.getBlock(); + oreSet.add(ore.getOreMaterial()); + if (oreSet.size() >= 3) { + break chunkScan; + } + } + } + } + } + } + } + } + + Component message = geologist_pick_tweaks_1_20_1$getMessage(oreSet); + + player.displayClientMessage(message, true); + geologist_pick_tweaks_1_20_1$mineralCache.put(centerChunkPos, cachedEntry); return InteractionResult.SUCCESS; } + + @Unique + private static @NotNull Component geologist_pick_tweaks_1_20_1$getMessage(Set> oreSet) { + Component message; + if (oreSet.isEmpty()) { + message = Component.translatable("immersivegeology.prospecting_pick.nothing"); + } else { + List> found = new ArrayList<>(oreSet); + String messageKey = "immersivegeology.prospecting_pick.found"; + String materialsText; + + switch (found.size()) { + case 1: + materialsText = "Found Traces of " + found.get(0); + break; + case 2: + materialsText = "Found Traces of " + found.get(0) + " and " + found.get(1); + break; + default: // 3 or more + materialsText = "Found Cluster of " + found.get(0) + ", " + found.get(1) + " and " + found.get(2); + break; + } + + message = Component.translatable(messageKey, materialsText); + } + return message; + } } diff --git a/src/main/java/dev/micle/geologistpicktweaks/util/MineralCacheEntry.java b/src/main/java/dev/micle/geologistpicktweaks/util/MineralCacheEntry.java new file mode 100644 index 0000000..d2cffc5 --- /dev/null +++ b/src/main/java/dev/micle/geologistpicktweaks/util/MineralCacheEntry.java @@ -0,0 +1,15 @@ +package dev.micle.geologistpicktweaks.util; + +/** + * @author muddykat + */ +public class MineralCacheEntry { + public static final long CACHE_EXPIRY = 10 * 1000; + public final String message; + public final long timestamp; + + public MineralCacheEntry(String message) { + this.message = message; + this.timestamp = System.currentTimeMillis(); + } +} From c9cee49e8ebc41bbf9ef9d8cd820a953b87bfe64 Mon Sep 17 00:00:00 2001 From: Micle Date: Tue, 27 May 2025 00:59:58 +0100 Subject: [PATCH 3/6] Changed ore Set to a HashMap and now keeping track of how many ore blocks there are. Removed Unique getMessage and instead just Shadowing the original. --- .../mixin/IGMineralTestingItemMixin.java | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java index 69335db..92e87fc 100644 --- a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java +++ b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java @@ -24,6 +24,7 @@ import net.minecraft.world.level.chunk.LevelChunkSection; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import java.util.*; @@ -42,7 +43,7 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements * @reason Tweaking geologist pick usage logic. */ @Overwrite - public InteractionResult useOn(UseOnContext context) { + public @NotNull InteractionResult useOn(UseOnContext context) { Player player = context.getPlayer(); ItemStack stack = context.getItemInHand(); if (player == null || !stack.getItem().equals(this)) { @@ -73,9 +74,9 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements int sectionMin = level.getSectionIndex(minBuildHeight); int sectionMax = level.getSectionIndex(maxBuildHeight); - Set> oreSet = new HashSet<>(); + HashMap, Integer> oreMap = new HashMap<>(); TagKey allOresTag = BlockCategoryFlags.ORE_BLOCK.getCategoryTag(); - chunkScan: for (int dx = -1; dx <= 1; dx++) { + for (int dx = -1; dx <= 1; dx++) { for (int dz = -1; dz <= 1; dz++) { ChunkAccess chunk = level.getChunk(centerChunkX + dx, centerChunkZ + dz); @@ -96,10 +97,7 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements BlockState blockState = section.getBlockState(x, y, z); if (blockState.is(allOresTag)) { IOreBlock ore = (IOreBlock) blockState.getBlock(); - oreSet.add(ore.getOreMaterial()); - if (oreSet.size() >= 3) { - break chunkScan; - } + oreMap.put(ore.getOreMaterial(), oreMap.getOrDefault(ore.getOreMaterial(), 0) + 1); } } } @@ -108,7 +106,7 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements } } - Component message = geologist_pick_tweaks_1_20_1$getMessage(oreSet); + Component message = getMessage(oreMap.keySet()); player.displayClientMessage(message, true); geologist_pick_tweaks_1_20_1$mineralCache.put(centerChunkPos, cachedEntry); @@ -116,30 +114,9 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements return InteractionResult.SUCCESS; } - @Unique - private static @NotNull Component geologist_pick_tweaks_1_20_1$getMessage(Set> oreSet) { - Component message; - if (oreSet.isEmpty()) { - message = Component.translatable("immersivegeology.prospecting_pick.nothing"); - } else { - List> found = new ArrayList<>(oreSet); - String messageKey = "immersivegeology.prospecting_pick.found"; - String materialsText; - - switch (found.size()) { - case 1: - materialsText = "Found Traces of " + found.get(0); - break; - case 2: - materialsText = "Found Traces of " + found.get(0) + " and " + found.get(1); - break; - default: // 3 or more - materialsText = "Found Cluster of " + found.get(0) + ", " + found.get(1) + " and " + found.get(2); - break; - } - - message = Component.translatable(messageKey, materialsText); - } - return message; + @Shadow + @NotNull + private static Component getMessage(Set> oreSet) { + return Component.empty(); } } From b951c3c016426200032722d8ed03e110428d2e79 Mon Sep 17 00:00:00 2001 From: Micle Date: Tue, 27 May 2025 01:10:05 +0100 Subject: [PATCH 4/6] Added config option for deposit threshold. --- .../dev/micle/geologistpicktweaks/config/Config.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/micle/geologistpicktweaks/config/Config.java b/src/main/java/dev/micle/geologistpicktweaks/config/Config.java index cd0c56e..1840066 100644 --- a/src/main/java/dev/micle/geologistpicktweaks/config/Config.java +++ b/src/main/java/dev/micle/geologistpicktweaks/config/Config.java @@ -61,7 +61,15 @@ public final class Config { } public static class Server { - Server(ForgeConfigSpec.Builder builder) {} + public static ForgeConfigSpec.IntValue geologistPickDepositThreshold; + + Server(ForgeConfigSpec.Builder builder) { + builder.comment("Settings for geologist pick").push("geologist_pick"); + geologistPickDepositThreshold = builder + .comment("The ore block quantity needed for an ore to be recognised as a deposit.") + .defineInRange("geologistPickDepositThreshold", 500, 0, Integer.MAX_VALUE); + builder.pop(); + } private static void onConfigReload() {} } From 12ac80eec3f4941abc27d68eae9cdd864e4f32d3 Mon Sep 17 00:00:00 2001 From: Micle Date: Tue, 27 May 2025 01:11:20 +0100 Subject: [PATCH 5/6] Applying the deposit threshold. --- .../geologistpicktweaks/mixin/IGMineralTestingItemMixin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java index 92e87fc..b19fb8e 100644 --- a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java +++ b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java @@ -7,6 +7,7 @@ import com.igteam.immersivegeology.common.item.helper.IGFlagItem; import com.igteam.immersivegeology.core.material.helper.flags.BlockCategoryFlags; import com.igteam.immersivegeology.core.material.helper.flags.ItemCategoryFlags; import com.igteam.immersivegeology.core.material.helper.material.MaterialInterface; +import dev.micle.geologistpicktweaks.config.Config; import dev.micle.geologistpicktweaks.util.MineralCacheEntry; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -106,6 +107,9 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements } } + // Apply deposit threshold + oreMap.values().removeIf(value -> value < Config.Server.geologistPickDepositThreshold.get()); + Component message = getMessage(oreMap.keySet()); player.displayClientMessage(message, true); From f7fffac3730e9ea8cb80ef7e280f6fcef29c875d Mon Sep 17 00:00:00 2001 From: Micle Date: Tue, 27 May 2025 01:15:06 +0100 Subject: [PATCH 6/6] Sorting ores by most abundant first. --- .../mixin/IGMineralTestingItemMixin.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java index b19fb8e..3fabe8e 100644 --- a/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java +++ b/src/main/java/dev/micle/geologistpicktweaks/mixin/IGMineralTestingItemMixin.java @@ -29,6 +29,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import java.util.*; +import java.util.stream.Collectors; @Mixin(IGMineralTestingItem.class) public abstract class IGMineralTestingItemMixin extends IGGenericItem implements IGFlagItem { @@ -110,6 +111,11 @@ public abstract class IGMineralTestingItemMixin extends IGGenericItem implements // Apply deposit threshold oreMap.values().removeIf(value -> value < Config.Server.geologistPickDepositThreshold.get()); + // Sort ore map + oreMap = oreMap.entrySet().stream() + .sorted((k1, k2) -> -k1.getValue().compareTo(k2.getValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + Component message = getMessage(oreMap.keySet()); player.displayClientMessage(message, true);