From fc13eb15e17e5b3f6f3b1eaec68ae4608b479005 Mon Sep 17 00:00:00 2001 From: Onyx_i7 Date: Sun, 12 Jul 2026 15:40:55 -0400 Subject: [PATCH 1/3] Enhance ocean water detection logic Refactor ocean water check to ensure it's not coastal by adding a helper method that verifies sufficient water presence around the given position. --- .../util/internal/ThirstUtilInternal.java | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java index f18c67d..867e86b 100644 --- a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java +++ b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java @@ -9,6 +9,7 @@ import com.charles445.simpledifficulty.api.thirst.*; import com.charles445.simpledifficulty.config.ModConfig; import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; @@ -135,9 +136,9 @@ public ThirstEnumBlockPos traceWater(EntityPlayer player) if(traceBlock == Blocks.WATER) { - // Check if the water is in an ocean biome - if so, it's salt water - Biome biome = player.getEntityWorld().getBiome(blockPos); - if (isOceanBiome(biome)) { + // Check if the water is in an ocean biome AND has enough water around it to be considered ocean + // This prevents coastal water from being treated as salt water + if (isTrueOceanWater(player, blockPos)) { return new ThirstEnumBlockPos(ThirstEnum.SALT, blockPos); } return new ThirstEnumBlockPos(ThirstEnum.NORMAL, blockPos); @@ -160,6 +161,40 @@ else if(traceBlock == SDFluids.blockSaltWater) return null; } + // Helper method to check if water is truly ocean water (not coastal/lake water) + private boolean isTrueOceanWater(EntityPlayer player, BlockPos waterPos) { + // First check if it's in an ocean biome + Biome biome = player.getEntityWorld().getBiome(waterPos); + if (!isOceanBiome(biome)) { + return false; + } + + // Now check if there's enough water around to be considered ocean + // If there's land nearby, it's likely coastal water or a lake + int waterCount = 0; + int radius = 5; // Check 5 blocks in each direction + + for (int x = -radius; x <= radius; x++) { + for (int z = -radius; z <= radius; z++) { + BlockPos checkPos = waterPos.add(x, 0, z); + IBlockState state = player.getEntityWorld().getBlockState(checkPos); + + // Count water blocks at the same level + if (state.getBlock() == Blocks.WATER || state.getBlock() == SDFluids.blockSaltWater) { + waterCount++; + } + } + } + + // If there are many water blocks around, it's likely ocean + // A 5-block radius gives us 11x11 = 121 possible positions + // If more than 70% is water, it's ocean + int totalPositions = (radius * 2 + 1) * (radius * 2 + 1); + double waterPercentage = (double) waterCount / totalPositions; + + return waterPercentage > 0.7; + } + // Helper method to check if a biome is an ocean biome private boolean isOceanBiome(Biome biome) { if (biome == null) { From 4d6b44291f3a2efd2308073b7273ea2645d574c2 Mon Sep 17 00:00:00 2001 From: Onyx_i7 Date: Sun, 12 Jul 2026 15:54:42 -0400 Subject: [PATCH 2/3] Refactor ocean water detection logic --- .../util/internal/ThirstUtilInternal.java | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java index 867e86b..7ab0932 100644 --- a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java +++ b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java @@ -17,7 +17,6 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.biome.Biome; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; @@ -136,9 +135,9 @@ public ThirstEnumBlockPos traceWater(EntityPlayer player) if(traceBlock == Blocks.WATER) { - // Check if the water is in an ocean biome AND has enough water around it to be considered ocean - // This prevents coastal water from being treated as salt water - if (isTrueOceanWater(player, blockPos)) { + // Check if this is ocean water based on depth and surrounding water + // Ocean water is deep and has lots of water around it + if (isOceanWater(player, blockPos)) { return new ThirstEnumBlockPos(ThirstEnum.SALT, blockPos); } return new ThirstEnumBlockPos(ThirstEnum.NORMAL, blockPos); @@ -161,60 +160,44 @@ else if(traceBlock == SDFluids.blockSaltWater) return null; } - // Helper method to check if water is truly ocean water (not coastal/lake water) - private boolean isTrueOceanWater(EntityPlayer player, BlockPos waterPos) { - // First check if it's in an ocean biome - Biome biome = player.getEntityWorld().getBiome(waterPos); - if (!isOceanBiome(biome)) { + // Helper method to determine if water is ocean water based on depth and surrounding area + private boolean isOceanWater(EntityPlayer player, BlockPos waterPos) { + // Check water depth (how many blocks of water below) + int depth = 0; + BlockPos checkPos = waterPos.down(); + while (depth < 10 && player.getEntityWorld().getBlockState(checkPos).getBlock() == Blocks.WATER) { + depth++; + checkPos = checkPos.down(); + } + + // If water is very shallow (less than 3 blocks deep), it's likely a lake/river + if (depth < 3) { return false; } - // Now check if there's enough water around to be considered ocean - // If there's land nearby, it's likely coastal water or a lake + // Check how much water is around at the same level int waterCount = 0; - int radius = 5; // Check 5 blocks in each direction + int radius = 8; // Larger radius for ocean detection for (int x = -radius; x <= radius; x++) { for (int z = -radius; z <= radius; z++) { - BlockPos checkPos = waterPos.add(x, 0, z); - IBlockState state = player.getEntityWorld().getBlockState(checkPos); + BlockPos checkPos2 = waterPos.add(x, 0, z); + Block block = player.getEntityWorld().getBlockState(checkPos2).getBlock(); - // Count water blocks at the same level - if (state.getBlock() == Blocks.WATER || state.getBlock() == SDFluids.blockSaltWater) { + if (block == Blocks.WATER) { waterCount++; } } } - // If there are many water blocks around, it's likely ocean - // A 5-block radius gives us 11x11 = 121 possible positions - // If more than 70% is water, it's ocean + // If there's a lot of water around, it's ocean + // A 8-block radius gives us 17x17 = 289 possible positions + // If more than 80% is water, it's definitely ocean int totalPositions = (radius * 2 + 1) * (radius * 2 + 1); double waterPercentage = (double) waterCount / totalPositions; - return waterPercentage > 0.7; - } - - // Helper method to check if a biome is an ocean biome - private boolean isOceanBiome(Biome biome) { - if (biome == null) { - return false; - } - - // Check biome category/name for ocean types - String biomeName = biome.getRegistryName() != null ? biome.getRegistryName().toString() : ""; - - // Vanilla ocean biomes - return biomeName.contains("ocean") || - biomeName.equals("minecraft:frozen_ocean") || - biomeName.equals("minecraft:deep_ocean") || - biomeName.equals("minecraft:frozen_ocean") || - biomeName.equals("minecraft:cold_ocean") || - biomeName.equals("minecraft:deep_cold_ocean") || - biomeName.equals("minecraft:lukewarm_ocean") || - biomeName.equals("minecraft:deep_lukewarm_ocean") || - biomeName.equals("minecraft:warm_ocean") || - biomeName.equals("minecraft:deep_warm_ocean"); + // Ocean water must be deep AND have lots of water around + return waterPercentage > 0.8 && depth >= 3; } // Removed riverBlocks array - now using RIVER_BLOCKS_SET for O(1) lookups From 0e21ebc83e136724a4ebc1dd8cf4454d1ba420f5 Mon Sep 17 00:00:00 2001 From: Onyx_i7 Date: Sun, 12 Jul 2026 16:16:48 -0400 Subject: [PATCH 3/3] Refactor water type detection logic in ThirstUtilInternal --- .../util/internal/ThirstUtilInternal.java | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java index 7ab0932..8279aa7 100644 --- a/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java +++ b/src/main/java/com/charles445/simpledifficulty/util/internal/ThirstUtilInternal.java @@ -9,7 +9,6 @@ import com.charles445.simpledifficulty.api.thirst.*; import com.charles445.simpledifficulty.config.ModConfig; import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; @@ -17,6 +16,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.biome.Biome; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; @@ -135,12 +135,11 @@ public ThirstEnumBlockPos traceWater(EntityPlayer player) if(traceBlock == Blocks.WATER) { - // Check if this is ocean water based on depth and surrounding water - // Ocean water is deep and has lots of water around it - if (isOceanWater(player, blockPos)) { - return new ThirstEnumBlockPos(ThirstEnum.SALT, blockPos); + // LOGIC: Default to Salt Water. Only Fresh Water if it's a River or a small enclosed lake. + if (isFreshWater(player, blockPos)) { + return new ThirstEnumBlockPos(ThirstEnum.NORMAL, blockPos); } - return new ThirstEnumBlockPos(ThirstEnum.NORMAL, blockPos); + return new ThirstEnumBlockPos(ThirstEnum.SALT, blockPos); } else if(traceBlock == SDFluids.blockPurifiedWater) { @@ -160,44 +159,54 @@ else if(traceBlock == SDFluids.blockSaltWater) return null; } - // Helper method to determine if water is ocean water based on depth and surrounding area - private boolean isOceanWater(EntityPlayer player, BlockPos waterPos) { - // Check water depth (how many blocks of water below) - int depth = 0; - BlockPos checkPos = waterPos.down(); - while (depth < 10 && player.getEntityWorld().getBlockState(checkPos).getBlock() == Blocks.WATER) { - depth++; - checkPos = checkPos.down(); - } - - // If water is very shallow (less than 3 blocks deep), it's likely a lake/river - if (depth < 3) { - return false; + // Determines if water is fresh (drinkable without filter) + private boolean isFreshWater(EntityPlayer player, BlockPos waterPos) { + // 1. Check if it's a River biome + Biome biome = player.getEntityWorld().getBiome(waterPos); + if (biome != null && biome.getRegistryName() != null) { + String name = biome.getRegistryName().toString(); + if (name.contains("river")) { + return true; + } } - // Check how much water is around at the same level - int waterCount = 0; - int radius = 8; // Larger radius for ocean detection - - for (int x = -radius; x <= radius; x++) { - for (int z = -radius; z <= radius; z++) { - BlockPos checkPos2 = waterPos.add(x, 0, z); - Block block = player.getEntityWorld().getBlockState(checkPos2).getBlock(); + // 2. Check if it's a small enclosed lake/pond + // If land is found within 4 blocks in ALL 4 cardinal directions, it's a small lake. + // If ANY direction is open water, it's part of a large body (ocean/coast) -> Salt. + return isEnclosedLake(player.getEntityWorld(), waterPos); + } + + // Checks if the water body is small and enclosed by land + private boolean isEnclosedLake(net.minecraft.world.World world, BlockPos pos) { + int maxDist = 4; // Check up to 4 blocks away + int[] dirsX = {1, -1, 0, 0}; + int[] dirsZ = {0, 0, 1, -1}; + + for (int d = 0; d < 4; d++) { + boolean foundLand = false; + for (int i = 1; i <= maxDist; i++) { + BlockPos check = pos.add(dirsX[d] * i, 0, dirsZ[d] * i); + + // Prevent chunk loading + if (!world.isBlockLoaded(check)) { + foundLand = true; + break; + } - if (block == Blocks.WATER) { - waterCount++; + Block b = world.getBlockState(check).getBlock(); + // If it's not water, we hit land/edge + if (b != Blocks.WATER) { + foundLand = true; + break; } } + // If we didn't find land in this direction, it's open water (Ocean/Coast) + if (!foundLand) { + return false; + } } - - // If there's a lot of water around, it's ocean - // A 8-block radius gives us 17x17 = 289 possible positions - // If more than 80% is water, it's definitely ocean - int totalPositions = (radius * 2 + 1) * (radius * 2 + 1); - double waterPercentage = (double) waterCount / totalPositions; - - // Ocean water must be deep AND have lots of water around - return waterPercentage > 0.8 && depth >= 3; + // All 4 directions hit land -> Small enclosed lake/pond + return true; } // Removed riverBlocks array - now using RIVER_BLOCKS_SET for O(1) lookups