-
-
Notifications
You must be signed in to change notification settings - Fork 357
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support custom biomes with the unwanted biomes feature (#7540)
- Loading branch information
1 parent
6896a0f
commit 3eaa72a
Showing
1 changed file
with
54 additions
and
7 deletions.
There are no files selected for viewing
61 changes: 54 additions & 7 deletions
61
Towny/src/main/java/com/palmergames/bukkit/util/BiomeUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,84 @@ | ||
package com.palmergames.bukkit.util; | ||
|
||
import java.lang.invoke.MethodHandle; | ||
import java.util.HashSet; | ||
import java.util.Locale; | ||
import java.util.Set; | ||
import java.util.function.Predicate; | ||
|
||
import com.palmergames.bukkit.towny.Towny; | ||
import com.palmergames.util.JavaUtil; | ||
import org.bukkit.Bukkit; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.RegionAccessor; | ||
import org.bukkit.World; | ||
import org.bukkit.block.Biome; | ||
import com.palmergames.bukkit.towny.TownySettings; | ||
import com.palmergames.bukkit.towny.object.WorldCoord; | ||
|
||
@SuppressWarnings("deprecation") // UnsafeValues are "deprecated" | ||
public class BiomeUtil { | ||
|
||
private static Predicate<Biome> isOceanPredicate = (biome) -> biome.name().contains("OCEAN"); | ||
private static Predicate<Biome> isUnwantedBiomePredicate = (biome) -> TownySettings.getUnwantedBiomeNames().contains(biome.name().toLowerCase(Locale.ROOT)); | ||
private static final Set<NamespacedKey> UNWANTED_BIOME_KEYS = new HashSet<>(); | ||
|
||
private static final Predicate<NamespacedKey> IS_OCEAN = (biome) -> biome.getKey().contains("ocean"); | ||
private static final Predicate<NamespacedKey> IS_UNWANTED_BIOME = UNWANTED_BIOME_KEYS::contains; | ||
|
||
private static final MethodHandle GET_BIOME_KEY = JavaUtil.getMethodHandle(Bukkit.getUnsafe().getClass(), "getBiomeKey", RegionAccessor.class, int.class, int.class, int.class); | ||
|
||
static { | ||
TownySettings.addReloadListener(NamespacedKey.fromString("towny:unwanted_chunks"), () -> { | ||
UNWANTED_BIOME_KEYS.clear(); | ||
|
||
for (final String unwantedBiomeName : TownySettings.getUnwantedBiomeNames()) { | ||
NamespacedKey key = NamespacedKey.fromString(unwantedBiomeName.toLowerCase(Locale.ROOT)); | ||
if (key == null) { | ||
Towny.getPlugin().getLogger().warning("Unwanted biome name is not a valid key: " + unwantedBiomeName); | ||
continue; | ||
} | ||
|
||
UNWANTED_BIOME_KEYS.add(key); | ||
} | ||
}); | ||
} | ||
|
||
public static double getWorldCoordOceanBiomePercent(WorldCoord worldCoord) { | ||
return getWorldCoordBadBiomePercent(worldCoord, isOceanPredicate); | ||
return getWorldCoordBiomePercent(worldCoord, IS_OCEAN); | ||
} | ||
|
||
public static double getWorldCoordUnwantedBiomePercent(WorldCoord worldCoord) { | ||
return getWorldCoordBadBiomePercent(worldCoord, isUnwantedBiomePredicate); | ||
return getWorldCoordBiomePercent(worldCoord, IS_UNWANTED_BIOME); | ||
} | ||
|
||
public static double getWorldCoordBadBiomePercent(WorldCoord worldCoord, Predicate<Biome> biomePredicate) { | ||
public static double getWorldCoordBiomePercent(WorldCoord worldCoord, Predicate<NamespacedKey> biomePredicate) { | ||
World world = worldCoord.getBukkitWorld(); | ||
if (world == null) | ||
return 0; | ||
|
||
int plotSize = TownySettings.getTownBlockSize(); | ||
int worldX = worldCoord.getX() * plotSize, worldZ = worldCoord.getZ() * plotSize; | ||
|
||
int total = plotSize * plotSize; | ||
int badBiomeBlocks = 0; | ||
for (int z = 0; z < plotSize; z++) | ||
for (int x = 0; x < plotSize; x++) | ||
if (biomePredicate.test(world.getHighestBlockAt(worldX + x, worldZ + z).getBiome())) | ||
if (biomePredicate.test(getBiomeKey(world, worldX, world.getHighestBlockYAt(worldX + x, worldZ + z), worldZ))) | ||
badBiomeBlocks++; | ||
|
||
return (double) badBiomeBlocks / total; | ||
} | ||
|
||
public static NamespacedKey getBiomeKey(final World world, final int x, final int y, final int z) { | ||
if (GET_BIOME_KEY == null) | ||
return getBiomeKeyOld(world, x, y, z); | ||
|
||
try { | ||
return (NamespacedKey) GET_BIOME_KEY.invoke(Bukkit.getUnsafe(), world, x, y, z); | ||
} catch (Throwable throwable) { | ||
return getBiomeKeyOld(world, x, y, z); | ||
} | ||
} | ||
|
||
private static NamespacedKey getBiomeKeyOld(final World world, final int x, final int y, final int z) { | ||
return world.getBiome(x, y, z).getKey(); | ||
} | ||
} |